diff --git a/Framework/API/inc/MantidAPI/IFunction.h b/Framework/API/inc/MantidAPI/IFunction.h index 9e0e35282b6bc100abf318ddaa75fc94723d5b3c..1290014e9b5b93a47ccfc872361a97940348444a 100644 --- a/Framework/API/inc/MantidAPI/IFunction.h +++ b/Framework/API/inc/MantidAPI/IFunction.h @@ -476,6 +476,8 @@ public: virtual bool removeTie(size_t i); /// Get the tie of i-th parameter virtual ParameterTie *getTie(size_t i) const; + /// Put all ties in order in which they will be applied correctly. + void sortTies(); /// Write a parameter tie to a string std::string writeTies() const; //@} @@ -593,6 +595,8 @@ protected: const API::IFunction::Attribute &value) const; /// Add a new tie. Derived classes must provide storage for ties virtual void addTie(std::unique_ptr<ParameterTie> tie); + bool hasOrderedTies() const; + void applyOrderedTies(); /// Writes itself into a string virtual std::string writeToString(const std::string &parentLocalAttributesStr = "") const; @@ -618,10 +622,12 @@ private: boost::shared_ptr<Kernel::Matrix<double>> m_covar; /// The chi-squared of the last fit double m_chiSquared; - /// Holds parameter ties as <parameter index,tie pointer> + /// Holds parameter ties std::vector<std::unique_ptr<ParameterTie>> m_ties; /// Holds the constraints added to function std::vector<std::unique_ptr<IConstraint>> m_constraints; + /// Ties ordered in order of correct application + std::vector<ParameterTie *> m_orderedTies; }; /// shared pointer to the function base class diff --git a/Framework/API/inc/MantidAPI/ParameterTie.h b/Framework/API/inc/MantidAPI/ParameterTie.h index 3c3586b0cbd8b21adafc61a0694bcb6fea4b33ab..992a7fedee110a7b8fa185e983a396f0153538ec 100644 --- a/Framework/API/inc/MantidAPI/ParameterTie.h +++ b/Framework/API/inc/MantidAPI/ParameterTie.h @@ -7,6 +7,7 @@ #include "MantidAPI/DllConfig.h" #include "MantidAPI/ParameterReference.h" #include <map> +#include <vector> namespace mu { class Parser; @@ -63,6 +64,8 @@ public: bool findParametersOf(const IFunction *fun) const; /// Check if the tie is a constant bool isConstant() const; + /// Get a list of parameters on the right-hand side of the equation + std::vector<ParameterReference> getRHSParameters() const; protected: mu::Parser *m_parser; ///< math parser diff --git a/Framework/API/src/Algorithm.cpp b/Framework/API/src/Algorithm.cpp index 0a1d58a5ae806f03941ea25b79be73cc0a900adb..0cf9d2f25a65f8ae89e8c5a86e7a9528a41bc4cf 100644 --- a/Framework/API/src/Algorithm.cpp +++ b/Framework/API/src/Algorithm.cpp @@ -433,7 +433,7 @@ void Algorithm::unlockWorkspaces() { * invoked for top level algorithms by the application manager. * This method invokes exec() method. * For Child Algorithms either the execute() method or exec() method - * must be EXPLICITLY invoked by the parent algorithm. + * must be EXPLICITLY invoked by the parent algorithm. * * @throw runtime_error Thrown if algorithm or Child Algorithm cannot be *executed @@ -595,7 +595,6 @@ bool Algorithm::execute() { if (m_alwaysStoreInADS) this->store(); - // RJT, 19/3/08: Moved this up from below the catch blocks setExecuted(true); // Log that execution has completed. diff --git a/Framework/API/src/CompositeFunction.cpp b/Framework/API/src/CompositeFunction.cpp index 0dac04cd1aa6e03a6accd5ba6614cbbd882a64dc..e7e0b92053eea7f7a083d79315691e6a04100a6b 100644 --- a/Framework/API/src/CompositeFunction.cpp +++ b/Framework/API/src/CompositeFunction.cpp @@ -614,10 +614,14 @@ std::string CompositeFunction::parameterLocalName(size_t i, * Apply the ties. */ void CompositeFunction::applyTies() { - for (size_t i = 0; i < nFunctions(); i++) { - getFunction(i)->applyTies(); + if (hasOrderedTies()) { + applyOrderedTies(); + } else { + for (size_t i = 0; i < nFunctions(); i++) { + getFunction(i)->applyTies(); + } + IFunction::applyTies(); } - IFunction::applyTies(); } /** diff --git a/Framework/API/src/IFunction.cpp b/Framework/API/src/IFunction.cpp index 46f58b966bafbdbce06c073bce16a02b75420b19..60734fb24e37db88048ab79dcb81f4bf0017368e 100644 --- a/Framework/API/src/IFunction.cpp +++ b/Framework/API/src/IFunction.cpp @@ -41,6 +41,20 @@ using namespace Geometry; namespace { /// static logger Kernel::Logger g_log("IFunction"); + +/// Struct that helps sort ties in correct order of application. +struct TieNode { + // Index of the tied parameter + size_t left; + // Indices of parameters on the right-hand-side of the expression + std::vector<size_t> right; + // This tie must be applied before the other if the RHS of the other + // contains this (left) parameter. + bool operator<(TieNode const &other) const { + return std::find(other.right.begin(), other.right.end(), left) != + other.right.end(); + } +}; } // namespace /** @@ -252,12 +266,24 @@ void IFunction::addTie(std::unique_ptr<ParameterTie> tie) { } } +bool IFunction::hasOrderedTies() const { return !m_orderedTies.empty(); } + +void IFunction::applyOrderedTies() { + for (auto &&tie : m_orderedTies) { + tie->eval(); + } +} + /** * Apply the ties. */ void IFunction::applyTies() { - for (auto &m_tie : m_ties) { - m_tie->eval(); + if (hasOrderedTies()) { + applyOrderedTies(); + } else { + for (auto &tie : m_ties) { + tie->eval(); + } } } @@ -1463,6 +1489,59 @@ std::vector<IFunction_sptr> IFunction::createEquivalentFunctions() const { 1, FunctionFactory::Instance().createInitialized(asString())); } +/// Put all ties in order in which they will be applied correctly. +void IFunction::sortTies() { + m_orderedTies.clear(); + std::list<TieNode> orderedTieNodes; + for (size_t i = 0; i < nParams(); ++i) { + auto const tie = getTie(i); + if (!tie) { + continue; + } + TieNode newNode; + newNode.left = getParameterIndex(*tie); + auto const rhsParameters = tie->getRHSParameters(); + newNode.right.reserve(rhsParameters.size()); + for (auto &&p : rhsParameters) { + newNode.right.emplace_back(this->getParameterIndex(p)); + } + if (newNode < newNode) { + throw std::runtime_error("Parameter is tied to itself: " + + tie->asString(this)); + } + bool before(false), after(false); + size_t indexBefore(0), indexAfter(0); + for (auto &&node : orderedTieNodes) { + if (newNode < node) { + before = true; + indexBefore = node.left; + } + if (node < newNode) { + after = true; + indexAfter = node.left; + } + } + if (before) { + if (after) { + std::string message = + "Circular dependency in ties:\n" + tie->asString(this) + '\n'; + message += getTie(indexBefore)->asString(this); + if (indexAfter != indexBefore) { + message += '\n' + getTie(indexAfter)->asString(this); + } + throw std::runtime_error(message); + } + orderedTieNodes.push_front(newNode); + } else { + orderedTieNodes.push_back(newNode); + } + } + for (auto &&node : orderedTieNodes) { + auto const tie = getTie(node.left); + m_orderedTies.emplace_back(tie); + } +} + } // namespace API } // namespace Mantid diff --git a/Framework/API/src/ParameterTie.cpp b/Framework/API/src/ParameterTie.cpp index 5daf50dae41a5aab49e2254d66d935f47978b62b..e49ac2711d4f5f97e58908d558400612bfb4fc33 100644 --- a/Framework/API/src/ParameterTie.cpp +++ b/Framework/API/src/ParameterTie.cpp @@ -194,5 +194,16 @@ bool ParameterTie::findParametersOf(const IFunction *fun) const { */ bool ParameterTie::isConstant() const { return m_varMap.empty(); } +/** Get a list of parameters on the right-hand side of the equation + */ +std::vector<ParameterReference> ParameterTie::getRHSParameters() const { + std::vector<ParameterReference> out; + out.reserve(m_varMap.size()); + for (auto &&varPair : m_varMap) { + out.emplace_back(varPair.second); + } + return out; +} + } // namespace API } // namespace Mantid diff --git a/Framework/API/test/ParameterTieTest.h b/Framework/API/test/ParameterTieTest.h index 3c105dd1ec62738826ff9dddf4f37a54e903f16d..1d20035c44b6afe86496b51e6679fd7a38fa3b81 100644 --- a/Framework/API/test/ParameterTieTest.h +++ b/Framework/API/test/ParameterTieTest.h @@ -256,6 +256,82 @@ public: TS_ASSERT(!mf->isFixed(3)); } + void test_circular_dependency() { + auto mf = makeFunction(); + mf->tie("f0.a", "f3.f1.hi"); + mf->tie("f0.b", "f2.sig + f0.a"); + mf->tie("f2.sig", "f3.f1.hi"); + mf->tie("f3.f1.hi", "f0.b"); + + TS_ASSERT_THROWS_EQUALS( + mf->sortTies(), std::runtime_error & e, std::string(e.what()), + "Circular dependency in " + "ties:\nf3.f1.hi=f0.b\nf0.a=f3.f1.hi\nf0.b=f2.sig + f0.a"); + } + + void test_circular_dependency_a_a() { + ParameterTieTest_Linear fun; + fun.tie("a", "2*a"); + TS_ASSERT_THROWS_EQUALS(fun.sortTies(), std::runtime_error & e, + std::string(e.what()), + "Parameter is tied to itself: a=2*a"); + } + + void test_circular_dependency_a_b_a() { + ParameterTieTest_Linear fun; + fun.tie("a", "2*b"); + fun.tie("b", "a/2"); + TS_ASSERT_THROWS_EQUALS(fun.sortTies(), std::runtime_error & e, + std::string(e.what()), + "Circular dependency in ties:\nb=a/2\na=2*b"); + } + + void test_circular_dependency_a_b_c_a() { + ParameterTieTest_Gauss fun; + fun.tie("cen", "2*hi"); + fun.tie("hi", "sig/2"); + fun.tie("sig", "cen + 1"); + TS_ASSERT_THROWS_EQUALS( + fun.sortTies(), std::runtime_error & e, std::string(e.what()), + "Circular dependency in ties:\nsig=cen + 1\nhi=sig/2\ncen=2*hi"); + } + + void test_ties_order() { + auto mf = makeFunction(); + mf->tie("f0.a", "f3.f1.hi"); + mf->tie("f0.b", "f2.sig + f0.a"); + mf->tie("f1.hi", "f1.cen*2"); + mf->tie("f2.sig", "f3.f1.hi"); + mf->tie("f3.f1.hi", "f1.sig"); + + mf->applyTies(); + // Unordered ties applied wrongly + TS_ASSERT(fabs(mf->getParameter("f0.a") - mf->getParameter("f3.f1.hi")) > + 1); + TS_ASSERT(fabs(mf->getParameter("f0.b") - (mf->getParameter("f2.sig") + + mf->getParameter("f0.a"))) > 1); + TS_ASSERT(fabs(mf->getParameter("f1.hi") - + mf->getParameter("f1.cen") * 2.0) < 1e-5); + TS_ASSERT(fabs(mf->getParameter("f2.sig") - mf->getParameter("f3.f1.hi")) > + 1); + TS_ASSERT(fabs(mf->getParameter("f3.f1.hi") - mf->getParameter("f2.sig")) > + 1); + TS_ASSERT_THROWS_NOTHING(mf->sortTies()); + mf->applyTies(); + // After ordering apply correctly + TS_ASSERT_DELTA(mf->getParameter("f0.a"), mf->getParameter("f3.f1.hi"), + 1e-5); + TS_ASSERT_DELTA(mf->getParameter("f0.b"), + mf->getParameter("f2.sig") + mf->getParameter("f0.a"), + 1e-5); + TS_ASSERT_DELTA(mf->getParameter("f1.hi"), mf->getParameter("f1.cen") * 2.0, + 1e-5); + TS_ASSERT_DELTA(mf->getParameter("f2.sig"), mf->getParameter("f3.f1.hi"), + 1e-5); + TS_ASSERT_DELTA(mf->getParameter("f3.f1.hi"), mf->getParameter("f2.sig"), + 1e-5); + } + private: void mustThrow1(CompositeFunction *fun) { ParameterTie tie(fun, "sig", "0"); } void mustThrow2(CompositeFunction *fun) { @@ -266,6 +342,27 @@ private: } void mustThrow4(IFunction *fun) { ParameterTie tie(fun, "f1.a", "0"); } void mustThrow5(IFunction *fun) { ParameterTie tie(fun, "cen", "0"); } + + IFunction_sptr makeFunction() { + CompositeFunction_sptr mf = CompositeFunction_sptr(new CompositeFunction); + IFunction_sptr bk = IFunction_sptr(new ParameterTieTest_Linear()); + IFunction_sptr g1 = IFunction_sptr(new ParameterTieTest_Gauss()); + IFunction_sptr g2 = IFunction_sptr(new ParameterTieTest_Gauss()); + CompositeFunction_sptr cf = CompositeFunction_sptr(new CompositeFunction); + IFunction_sptr g3 = IFunction_sptr(new ParameterTieTest_Gauss()); + IFunction_sptr g4 = IFunction_sptr(new ParameterTieTest_Gauss()); + cf->addFunction(g3); + cf->addFunction(g4); + + mf->addFunction(bk); + mf->addFunction(g1); + mf->addFunction(g2); + mf->addFunction(cf); + for (size_t i = 0; i < mf->nParams(); ++i) { + mf->setParameter(i, double(i + 1)); + } + return mf; + } }; #endif /*PARAMETERTIETEST_H_*/ diff --git a/Framework/Algorithms/CMakeLists.txt b/Framework/Algorithms/CMakeLists.txt index 98bc968f78a1b805ca7aac7a661194005a1feffb..d7c643cdd072ce4de5db4cbe7a9bfbbf3e7a9a29 100644 --- a/Framework/Algorithms/CMakeLists.txt +++ b/Framework/Algorithms/CMakeLists.txt @@ -188,6 +188,7 @@ set ( SRC_FILES src/MaxEnt/MaxentSpaceComplex.cpp src/MaxEnt/MaxentSpaceReal.cpp src/MaxEnt/MaxentTransformFourier.cpp + src/MaxEnt/MaxentTransformMultiFourier.cpp src/MaxMin.cpp src/MedianDetectorTest.cpp src/MergeRuns.cpp @@ -521,6 +522,7 @@ set ( INC_FILES inc/MantidAlgorithms/MaxEnt/MaxentSpaceReal.h inc/MantidAlgorithms/MaxEnt/MaxentTransform.h inc/MantidAlgorithms/MaxEnt/MaxentTransformFourier.h + inc/MantidAlgorithms/MaxEnt/MaxentTransformMultiFourier.h inc/MantidAlgorithms/MaxMin.h inc/MantidAlgorithms/MedianDetectorTest.h inc/MantidAlgorithms/MergeRuns.h @@ -854,6 +856,7 @@ set ( TEST_FILES MaxEnt/MaxentSpaceComplexTest.h MaxEnt/MaxentSpaceRealTest.h MaxEnt/MaxentTransformFourierTest.h + MaxEnt/MaxentTransformMultiFourierTest.h MaxEntTest.h MaxMinTest.h MayersSampleCorrectionStrategyTest.h diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaskDetectorsIf.h b/Framework/Algorithms/inc/MantidAlgorithms/MaskDetectorsIf.h index 7d0c55ed4799ddc073599f18562bccc766e6ff46..bd657d73c243fbdc9184d21bb0c2c04528354fb3 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MaskDetectorsIf.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MaskDetectorsIf.h @@ -51,14 +51,13 @@ public: const std::string name() const override { return "MaskDetectorsIf"; } /// Summary of algorithms purpose const std::string summary() const override { - return "Adjusts the selected field for a CalFile depending on the values " - "in the input workspace."; + return "Masks detectors depending on the values in the input workspace."; } /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } const std::vector<std::string> seeAlso() const override { - return {"MaskDetectors"}; + return {"MaskDetectors", "ClearMaskedSpectra"}; } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { @@ -66,28 +65,24 @@ public: } private: - /// Returns an allowed values statement to insert into decumentation - std::string allowedValuesStatement(const std::vector<std::string> &vals); - // Typedef for det to value map + /// Typedef for det to value map using udet2valuem = std::unordered_map<detid_t, bool>; - /// A map of detector numbers to mask boolean - udet2valuem umap; - /// Get the properties - void retrieveProperties(); - /// Create a new cal file - void createNewCalFile(const std::string &oldfile, const std::string &newfile); - /// The input workspace - API::MatrixWorkspace_const_sptr inputW; + /// A map from detid to selection + udet2valuem m_umap; + /// Whether select is on or off + bool m_select_on = false; /// The Value parameter - double value = 0.0; + double m_value = 0.0; + /// The input workspace + API::MatrixWorkspace_const_sptr m_inputW; /// A comparator function - boost::function<bool(double, double)> compar_f; - /// Whether select is on or off - bool select_on = false; - /// Overidden init + boost::function<bool(double, double)> m_compar_f; + void outputToWorkspace(); + void retrieveProperties(); + void createNewCalFile(); void init() override; - /// Overidden exec void exec() override; + std::map<std::string, std::string> validateInputs() override; }; } // namespace Algorithms diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt.h b/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt.h index 161ac6820f83c8d0d7e67ee6a79699492a69cbce..11188a5a898d9d740c2529423ae135c6b1f218a4 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt.h @@ -63,7 +63,8 @@ private: void exec() override; /// Returns spectrum 'spec' as a complex vector std::vector<double> toComplex(API::MatrixWorkspace_const_sptr &inWS, - size_t spec, bool errors); + size_t spec, bool errors, + bool concatenatedSpectra); // Calculates chi-square by solving the matrix equation A*x = b double calculateChi(const QuadraticCoefficients &coeffs, double a, std::vector<double> &beta); @@ -87,7 +88,8 @@ private: /// Populates the output workspace containing the reconstructed data void populateDataWS(API::MatrixWorkspace_const_sptr &inWS, size_t spec, size_t nspec, const std::vector<double> &result, - bool complex, API::MatrixWorkspace_sptr &outWS); + bool concatenatedSpectra, bool complex, + API::MatrixWorkspace_sptr &outWS); /// Populates the output workspace containing the reconstructed image void populateImageWS(API::MatrixWorkspace_const_sptr &inWS, size_t spec, size_t nspec, const std::vector<double> &result, diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentCalculator.h b/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentCalculator.h index bbb98db2ee896f28a76fc70cc8a5b53eef143388..ffb61196e25dfbe2df921475ea825a2c38851a27 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentCalculator.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentCalculator.h @@ -5,14 +5,10 @@ #include "MantidAlgorithms/MaxEnt/MaxentCoefficients.h" #include "MantidAlgorithms/MaxEnt/MaxentEntropy.h" #include "MantidAlgorithms/MaxEnt/MaxentTransform.h" -#include <memory> namespace Mantid { namespace Algorithms { -using MaxentEntropy_sptr = std::shared_ptr<MaxentEntropy>; -using MaxentTransform_sptr = std::shared_ptr<MaxentTransform>; - /** MaxentCalculator : This class performs one maxent iteration and calculates chi-sq, angle between gradient of S and gradient of chi-sq, search directions and quadratic coefficients. Calculations are based on J. Skilling and R. K. @@ -53,7 +49,9 @@ public: // Runs maxent iteration void iterate(const std::vector<double> &data, const std::vector<double> &errors, - const std::vector<double> &image, double background); + const std::vector<double> &image, double background, + const std::vector<double> &linearAdjustments, + const std::vector<double> &constAdjustments); // Getters // Returns the reconstructed (calculated) data diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentEntropy.h b/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentEntropy.h index a9a7a7c1802c34cde493014f9b204fcff3e25978..a3545f4a62472a88bffe6f0d3864019e6bfc25b2 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentEntropy.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentEntropy.h @@ -2,6 +2,7 @@ #define MANTID_ALGORITHMS_MAXENTENTROPY_H_ #include "MantidAlgorithms/DllConfig.h" +#include <boost/shared_ptr.hpp> #include <vector> namespace Mantid { @@ -48,6 +49,8 @@ public: double newValue) = 0; }; +using MaxentEntropy_sptr = boost::shared_ptr<MaxentEntropy>; + } // namespace Algorithms } // namespace Mantid diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentSpace.h b/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentSpace.h index 0552a84431278f64f6794cb4f6ba179bdf5d3f53..b7df67cd834bca327b8d612fad8c315a55151c1e 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentSpace.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentSpace.h @@ -2,6 +2,7 @@ #define MANTID_ALGORITHMS_MAXENTSPACE_H_ #include "MantidAlgorithms/DllConfig.h" +#include <boost/shared_ptr.hpp> #include <vector> namespace Mantid { @@ -46,6 +47,8 @@ public: fromComplex(const std::vector<double> &values) = 0; }; +using MaxentSpace_sptr = boost::shared_ptr<MaxentSpace>; + } // namespace Algorithms } // namespace Mantid diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentSpaceComplex.h b/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentSpaceComplex.h index 42240caa684c006baca7741fffbfa0c5bfca541b..20d6bafc65a3bcf3e14acdbcfbbc67b104a58129 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentSpaceComplex.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentSpaceComplex.h @@ -37,6 +37,9 @@ public: std::vector<double> fromComplex(const std::vector<double> &values) override; }; +using MaxentSpaceComplex_sptr = + boost::shared_ptr<Mantid::Algorithms::MaxentSpaceComplex>; + } // namespace Algorithms } // namespace Mantid diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentSpaceReal.h b/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentSpaceReal.h index 7de41897a8ddc2f7bc2c019579739909cb1b5320..989f37e0a0acba4e3b691c4b3aac07ecdc39133f 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentSpaceReal.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentSpaceReal.h @@ -37,6 +37,9 @@ public: std::vector<double> fromComplex(const std::vector<double> &values) override; }; +using MaxentSpaceReal_sptr = + boost::shared_ptr<Mantid::Algorithms::MaxentSpaceReal>; + } // namespace Algorithms } // namespace Mantid diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentTransform.h b/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentTransform.h index 30c8f67604fac95ef5cea4ccd6cb032b7c6ff499..ec3b2d0a20ff602bc4468d6d48630c3a420ba308 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentTransform.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentTransform.h @@ -2,6 +2,7 @@ #define MANTID_ALGORITHMS_MAXENTTRANSFORM_H_ #include "MantidAlgorithms/DllConfig.h" +#include <boost/shared_ptr.hpp> #include <vector> namespace Mantid { @@ -43,6 +44,8 @@ public: virtual std::vector<double> dataToImage(const std::vector<double> &data) = 0; }; +using MaxentTransform_sptr = boost::shared_ptr<MaxentTransform>; + } // namespace Algorithms } // namespace Mantid diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentTransformFourier.h b/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentTransformFourier.h index 1b91a936f4d43cf3cb2730dacf3e86b3d90051a3..bbd83966bdc43710814f98c985547eb9ab341783 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentTransformFourier.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentTransformFourier.h @@ -1,16 +1,13 @@ -#ifndef MANTID_ALGORITHMS_MAXENTTRANSFORM1DFOURIER_H_ -#define MANTID_ALGORITHMS_MAXENTTRANSFORM1DFOURIER_H_ +#ifndef MANTID_ALGORITHMS_MAXENTTRANSFORMFOURIER_H_ +#define MANTID_ALGORITHMS_MAXENTTRANSFORMFOURIER_H_ #include "MantidAlgorithms/MaxEnt/MaxentSpace.h" #include "MantidAlgorithms/MaxEnt/MaxentTransform.h" -#include <memory> namespace Mantid { namespace Algorithms { -using MaxentSpace_sptr = std::shared_ptr<MaxentSpace>; - -/** MaxentTransform1DFourier : Defines a transformation from data space to image +/** MaxentTransformFourier : Defines a transformation from data space to image space (and vice-versa) where spaces are related by a **1D** Fourier Transform. Copyright © 2016 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge @@ -54,4 +51,4 @@ private: } // namespace Algorithms } // namespace Mantid -#endif /* MANTID_ALGORITHMS_MAXENTTRANSFORM1DFOURIER_H_ */ +#endif /* MANTID_ALGORITHMS_MAXENTTRANSFORMFOURIER_H_ */ diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentTransformMultiFourier.h b/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentTransformMultiFourier.h new file mode 100644 index 0000000000000000000000000000000000000000..4b72d78c0ae29d787598c39c5b0e3e6dbfec6f9e --- /dev/null +++ b/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt/MaxentTransformMultiFourier.h @@ -0,0 +1,77 @@ +#ifndef MANTID_ALGORITHMS_MAXENTTRANSFORMMULTIFOURIER_H_ +#define MANTID_ALGORITHMS_MAXENTTRANSFORMMULTIFOURIER_H_ + +#include "MantidAlgorithms/MaxEnt/MaxentSpace.h" +#include "MantidAlgorithms/MaxEnt/MaxentSpaceComplex.h" +#include "MantidAlgorithms/MaxEnt/MaxentTransformFourier.h" + +namespace Mantid { +namespace Algorithms { + +using MaxentSpace_sptr = boost::shared_ptr<MaxentSpace>; +using MaxentSpaceComplex_sptr = boost::shared_ptr<MaxentSpaceComplex>; + +/** MaxentTransformMultiFourier : Defines a transformation from + data space to image space (and vice-versa) + where spaces are related by a **1D** Fourier Transform, + in which which the data has multiple spectra concatenatenated. + + In transforming from data to image, the spectra are added together + before tranforming to a single image. + In transforming the image to data, copies to the transformed data + (one for each spectrum) are concatenated and then have the supplied + adjustments applied. + + The concatenated format of the data is chosen to enable existing code + to calculate its chi squared. + + + Copyright © 2016 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class MANTID_ALGORITHMS_DLL MaxentTransformMultiFourier + : public MaxentTransformFourier { +public: + // Deleted default constructor + MaxentTransformMultiFourier() = delete; + // Constructor + MaxentTransformMultiFourier(MaxentSpaceComplex_sptr dataSpace, + MaxentSpace_sptr imageSpace, size_t numSpec); + // Transfoms form image space to data space + std::vector<double> imageToData(const std::vector<double> &image) override; + // Transforms from data space to image space + std::vector<double> dataToImage(const std::vector<double> &data) override; + // Set the adjustments to be applie to data when converted from image + void setAdjustments(const std::vector<double> &linAdj, + const std::vector<double> &constAdj); + +private: + MaxentSpace_sptr m_dataSpace; + MaxentSpace_sptr m_imageSpace; + size_t m_numSpec; + std::vector<double> m_linearAdjustments; + std::vector<double> m_constAdjustments; +}; + +} // namespace Algorithms +} // namespace Mantid + +#endif /* MANTID_ALGORITHMS_MAXENTTRANSFORMMULTIFOURIER_H_ */ diff --git a/Framework/Algorithms/inc/MantidAlgorithms/PolarizationCorrectionFredrikze.h b/Framework/Algorithms/inc/MantidAlgorithms/PolarizationCorrectionFredrikze.h index c3863161326e45270419234230d681e2cbcc4728..dfe01f99b725bc541a3b8dec8cb0c756a86b3092 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/PolarizationCorrectionFredrikze.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/PolarizationCorrectionFredrikze.h @@ -16,7 +16,7 @@ namespace Algorithms { /** PolarizationCorrectionFredrikze : Algorithm to perform polarisation corrections on multi-period group workspaces that implements the Fredrikze (Dutch) method. - Fredrikze, H, et al. “Calibration of a polarized neutron reflectometer” Physica + Fredrikze, H, et al. "Calibration of a polarized neutron reflectometer" Physica B 297 (2001) Copyright © 2014 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RebinToWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/RebinToWorkspace.h index 4ca034ea697ad363499b4af25422f3abef0135ef..0483c8ba902d6f5832bdd47a9e8ca3589278051a 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/RebinToWorkspace.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/RebinToWorkspace.h @@ -20,9 +20,6 @@ namespace Algorithms { <LI>OutputWorkspace - The name of the output workspace</LI> </UL> - @author Martyn Gigg, Tessella Support Services plc - @date 19/01/2009 - Copyright © 2009 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source @@ -69,14 +66,20 @@ protected: const override; private: + bool m_preserveEvents{true}; + bool m_isEvents{true}; + /// Initialisation code void init() override; /// Execution code void exec() override; - /// Create the rebin paraeters - std::vector<double> - createRebinParameters(Mantid::API::MatrixWorkspace_sptr toMatch); + bool needToRebin(const API::MatrixWorkspace_sptr &left, + const API::MatrixWorkspace_sptr &rght); + void rebin(API::MatrixWorkspace_sptr &toRebin, + API::MatrixWorkspace_sptr &toMatch); + void histogram(API::MatrixWorkspace_sptr &toRebin, + API::MatrixWorkspace_sptr &toMatch); }; } // namespace Algorithms } // namespace Mantid diff --git a/Framework/Algorithms/src/ConvertToMatrixWorkspace.cpp b/Framework/Algorithms/src/ConvertToMatrixWorkspace.cpp index 41f179a671d1b75ae08e52209b147841d9c50ce1..6cc1f8b98d04d0a2774b1d30c83c7de1aaeaf8c8 100644 --- a/Framework/Algorithms/src/ConvertToMatrixWorkspace.cpp +++ b/Framework/Algorithms/src/ConvertToMatrixWorkspace.cpp @@ -63,10 +63,17 @@ void ConvertToMatrixWorkspace::exec() { } PARALLEL_CHECK_INTERUPT_REGION } else { - g_log.information() << "Input workspace does not need converting. Pointing " - "OutputWorkspace property to input.\n"; - outputWorkspace = - boost::const_pointer_cast<MatrixWorkspace>(inputWorkspace); + outputWorkspace = getProperty("OutputWorkspace"); + if (inputWorkspace == outputWorkspace) { + g_log.information("InputWorkspace does not need converting. Pointing " + "OutputWorkspace property to input."); + outputWorkspace = + boost::const_pointer_cast<MatrixWorkspace>(inputWorkspace); + } else { + g_log.information( + "InputWorkspace does not need converting. Cloning InputWorkspace."); + outputWorkspace = inputWorkspace->clone(); + } } setProperty("OutputWorkspace", outputWorkspace); diff --git a/Framework/Algorithms/src/DirectILLTubeBackground.cpp b/Framework/Algorithms/src/DirectILLTubeBackground.cpp index 81447b6cd692b298110f1e73c475de7ed9ac8c6d..2847e6521160159f7a6461c16dddd1693727ae65 100644 --- a/Framework/Algorithms/src/DirectILLTubeBackground.cpp +++ b/Framework/Algorithms/src/DirectILLTubeBackground.cpp @@ -297,7 +297,7 @@ void DirectILLTubeBackground::exec() { std::vector<std::string> const componentNames = components(*instrument); API::Progress progress(this, 0.0, 1.0, componentNames.size()); PARALLEL_FOR_IF(Kernel::threadSafe(*ws)) - for (int64_t i = 0; static_cast<size_t>(i) < componentNames.size(); ++i) { + for (int64_t i = 0; i < static_cast<int64_t>(componentNames.size()); ++i) { PARALLEL_START_INTERUPT_REGION auto const &componentName = componentNames[static_cast<size_t>(i)]; progress.report("Processing " + componentName); diff --git a/Framework/Algorithms/src/MaskDetectorsIf.cpp b/Framework/Algorithms/src/MaskDetectorsIf.cpp index 015275479a9512f4fca205d2f42ef2a1cff60fa0..378e328612c16cce8bda7a43a43db9993e334855 100644 --- a/Framework/Algorithms/src/MaskDetectorsIf.cpp +++ b/Framework/Algorithms/src/MaskDetectorsIf.cpp @@ -1,6 +1,7 @@ #include "MantidAlgorithms/MaskDetectorsIf.h" #include "MantidAPI/FileProperty.h" #include "MantidAPI/MatrixWorkspace.h" +#include "MantidGeometry/Instrument/DetectorInfo.h" #include "MantidKernel/ListValidator.h" #include <fstream> @@ -15,123 +16,144 @@ DECLARE_ALGORITHM(MaskDetectorsIf) using namespace Kernel; /** Initialisation method. Declares properties to be used in algorithm. - * */ void MaskDetectorsIf::init() { using namespace Mantid::Kernel; declareProperty(make_unique<API::WorkspaceProperty<>>("InputWorkspace", "", Direction::Input), "A 1D Workspace that contains values to select against"); - std::vector<std::string> select_mode(2); - select_mode[0] = "SelectIf"; - select_mode[1] = "DeselectIf"; + const std::vector<std::string> select_mode{"SelectIf", "DeselectIf"}; declareProperty( "Mode", "SelectIf", boost::make_shared<StringListValidator>(select_mode), - "Mode to select or deselect detectors based on comparison with values. " + - allowedValuesStatement(select_mode)); - std::vector<std::string> select_operator(6); - select_operator[0] = "Equal"; - select_operator[1] = "NotEqual"; - select_operator[2] = "Greater"; - select_operator[3] = "GreaterEqual"; - select_operator[4] = "Less"; - select_operator[5] = "LessEqual"; + "Mode to select or deselect detectors based on comparison with values."); + const std::vector<std::string> select_operator{ + "Equal", "NotEqual", "Greater", "GreaterEqual", "Less", "LessEqual"}; declareProperty("Operator", "Equal", boost::make_shared<StringListValidator>(select_operator), - "Unary operator to compare to given values. " + - allowedValuesStatement(select_operator)); + "Unary operator to compare to given values."); declareProperty("Value", 0.0); declareProperty( make_unique<API::FileProperty>("InputCalFile", "", - API::FileProperty::Load, ".cal"), - "The name of the CalFile with grouping data. Allowed Values: .cal ."); + API::FileProperty::OptionalLoad, ".cal"), + "The name of the CalFile with grouping data."); declareProperty( make_unique<API::FileProperty>("OutputCalFile", "", API::FileProperty::OptionalSave, ".cal"), - "The name of the CalFile with grouping data. Allowed Values: .cal ."); + "The name of the CalFile with grouping data."); + declareProperty(make_unique<API::WorkspaceProperty<>>( + "OutputWorkspace", "", Direction::Output, + API::PropertyMode::Optional), + "The masked workspace."); +} + +/** + * Validates the algorithm's input properties. + * @return A map from property name to reported issue + */ +std::map<std::string, std::string> MaskDetectorsIf::validateInputs() { + std::map<std::string, std::string> issues; + const auto noInputFile = isDefault("InputCalFile"); + const auto noOutputFile = isDefault("OutputCalFile"); + if (!noInputFile && noOutputFile) { + issues["OutputCalFile"] = "Output file name is missing."; + } else if (noInputFile && !noOutputFile) { + issues["InputCalFile"] = "Input file name is missing."; + } + return issues; } /** Executes the algorithm - * - * @throw Exception::FileError If the grouping file cannot be opened or read - *successfully - * @throw std::runtime_error If the rebinning process fails */ void MaskDetectorsIf::exec() { retrieveProperties(); - const size_t nspec = inputW->getNumberHistograms(); + if (isDefault("InputCalFile") && isDefault("OutputWorkspace")) { + g_log.error() << "No InputCalFle or OutputWorkspace specified; the " + "algorithm will do nothing."; + return; + } + const size_t nspec = m_inputW->getNumberHistograms(); for (size_t i = 0; i < nspec; ++i) { // Get the list of udets contributing to this spectra - const auto &dets = inputW->getSpectrum(i).getDetectorIDs(); + const auto &dets = m_inputW->getSpectrum(i).getDetectorIDs(); if (dets.empty()) continue; else { - double val = inputW->y(i)[0]; - if (compar_f(val, value)) { - for (auto det : dets) { - umap.emplace(det, select_on); + const double val = m_inputW->y(i)[0]; + if (m_compar_f(val, m_value)) { + for (const auto det : dets) { + m_umap.emplace(det, m_select_on); } } } - double p = static_cast<double>(i) / static_cast<double>(nspec); + const double p = static_cast<double>(i) / static_cast<double>(nspec); progress(p, "Generating detector map"); } - std::string oldf = getProperty("InputCalFile"); - std::string newf = getProperty("OutputCalFile"); - progress(0.99, "Creating new cal file"); - createNewCalFile(oldf, newf); + + if (!isDefault("InputCalFile")) { + createNewCalFile(); + } + if (!isDefault("OutputWorkspace")) { + outputToWorkspace(); + } +} + +/** + * Create an output workspace masking/unmasking the selected/deselected spectra + */ +void MaskDetectorsIf::outputToWorkspace() { + API::MatrixWorkspace_sptr outputW = getProperty("OutputWorkspace"); + if (outputW != m_inputW) + outputW = m_inputW->clone(); + auto &detectorInfo = outputW->mutableDetectorInfo(); + for (const auto &selection : m_umap) { + detectorInfo.setMasked(detectorInfo.indexOf(selection.first), + selection.second); + } + setProperty("OutputWorkspace", outputW); } /** * Get the input properties and store them in the object variables */ void MaskDetectorsIf::retrieveProperties() { - inputW = getProperty("InputWorkspace"); - - // - value = getProperty("Value"); + m_inputW = getProperty("InputWorkspace"); + m_value = getProperty("Value"); // Get the selction mode (select if or deselect if) std::string select_mode = getProperty("Mode"); if (select_mode == "SelectIf") - select_on = true; + m_select_on = true; else - select_on = false; + m_select_on = false; // Select function object based on the type of comparison operator std::string select_operator = getProperty("Operator"); if (select_operator == "LessEqual") - compar_f = std::less_equal<double>(); + m_compar_f = std::less_equal<double>(); else if (select_operator == "Less") - compar_f = std::less<double>(); + m_compar_f = std::less<double>(); else if (select_operator == "GreaterEqual") - compar_f = std::greater_equal<double>(); + m_compar_f = std::greater_equal<double>(); else if (select_operator == "Greater") - compar_f = std::greater<double>(); + m_compar_f = std::greater<double>(); else if (select_operator == "Equal") - compar_f = std::equal_to<double>(); + m_compar_f = std::equal_to<double>(); else if (select_operator == "NotEqual") - compar_f = std::not_equal_to<double>(); - - std::string newf = getProperty("OutputCalFile"); - // MG 2012-10-01: A bug fixed the save file property to be invalid by default - // which would have moved the argument order. The property is now - // optional and checked here - if (newf.empty()) { - throw std::runtime_error("OutputCalFile is empty. Enter a filename"); - } + m_compar_f = std::not_equal_to<double>(); } /** * Create a new cal file based on the old file - * @param oldfile :: The old cal file path - * @param newfile :: The new cal file path + * @throw Exception::FileError If a grouping file cannot be opened or read + * successfully */ -void MaskDetectorsIf::createNewCalFile(const std::string &oldfile, - const std::string &newfile) { +void MaskDetectorsIf::createNewCalFile() { + const std::string oldfile = getProperty("InputCalFile"); + const std::string newfile = getProperty("OutputCalFile"); + progress(0.99, "Creating new cal file"); std::ifstream oldf(oldfile.c_str()); if (!oldf.is_open()) { g_log.error() << "Unable to open grouping file " << oldfile << '\n'; @@ -153,10 +175,10 @@ void MaskDetectorsIf::createNewCalFile(const std::string &oldfile, int n, udet, sel, group; double offset; istr >> n >> udet >> offset >> sel >> group; - auto it = umap.find(udet); + const auto it = m_umap.find(udet); bool selection; - if (it == umap.end()) + if (it == m_umap.end()) selection = sel != 0; else selection = (*it).second; @@ -169,16 +191,5 @@ void MaskDetectorsIf::createNewCalFile(const std::string &oldfile, oldf.close(); newf.close(); } - -std::string -MaskDetectorsIf::allowedValuesStatement(const std::vector<std::string> &vals) { - std::ostringstream statement; - statement << "Allowed Values: "; - for (const auto &val : vals) { - statement << val << ", "; - } - return statement.str(); -} - } // namespace Algorithms } // namespace Mantid diff --git a/Framework/Algorithms/src/MaxEnt.cpp b/Framework/Algorithms/src/MaxEnt.cpp index 7b00bc83f6b93845b2d4b75cbc8efb0b933d4fb4..011ba163a496d31bcb20176b086896857b1d7e5f 100644 --- a/Framework/Algorithms/src/MaxEnt.cpp +++ b/Framework/Algorithms/src/MaxEnt.cpp @@ -8,6 +8,7 @@ #include "MantidAlgorithms/MaxEnt/MaxentSpaceComplex.h" #include "MantidAlgorithms/MaxEnt/MaxentSpaceReal.h" #include "MantidAlgorithms/MaxEnt/MaxentTransformFourier.h" +#include "MantidAlgorithms/MaxEnt/MaxentTransformMultiFourier.h" #include "MantidHistogramData/LinearGenerator.h" #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/ListValidator.h" @@ -204,6 +205,32 @@ void MaxEnt::init() { 500, mustBePositive, Direction::Input), "Maximum number of iterations in alpha chop."); + declareProperty( + make_unique<WorkspaceProperty<>>( + "DataLinearAdj", "", Direction::Input, PropertyMode::Optional, + boost::make_shared<EqualBinSizesValidator>(errorLevel, warningLevel)), + "Adjusts the calculated data by multiplying each value by the " + "corresponding Y value of this workspace. " + "The data in this workspace is complex in the same manner as complex " + "input data."); + declareProperty( + make_unique<WorkspaceProperty<>>( + "DataConstAdj", "", Direction::Input, PropertyMode::Optional, + boost::make_shared<EqualBinSizesValidator>(errorLevel, warningLevel)), + "Adjusts the calculated data by adding to each value the corresponding Y " + "value of this workspace. " + "If DataLinearAdj is also specified, this addition is done after its " + "multiplication. " + "See equation in documentation for how DataLinearAdj and DataConstAdj " + "are applied. " + "The data in this workspace is complex in the same manner as complex " + "input data."); + declareProperty( + "PerSpectrumReconstruction", true, + "Reconstruction is done independently on each spectrum. " + "If false, all the spectra use one image and the reconstructions " + "differ only through their adjustments. " + "ComplexData must be set true, when this is false."); declareProperty( make_unique<WorkspaceProperty<>>("EvolChi", "", Direction::Output), @@ -229,17 +256,53 @@ std::map<std::string, std::string> MaxEnt::validateInputs() { MatrixWorkspace_sptr inWS = getProperty("InputWorkspace"); + size_t nHistograms = 0; if (inWS) { // If the input signal is complex, we expect an even number of histograms // in the input workspace - size_t nhistograms = inWS->getNumberHistograms(); + nHistograms = inWS->getNumberHistograms(); bool complex = getProperty("ComplexData"); - if (complex && (nhistograms % 2)) + if (complex && (nHistograms % 2)) result["InputWorkspace"] = "The number of histograms in the input " "workspace must be even for complex data"; + if (!complex) + nHistograms *= 2; // Double number of real histograms to compare with + // adjustments, which are always complex. } + // Check linear adjustments, we expect and even number of histograms + // and if any, they must be sufficient for all spectra in input workspace, + // if per spectrum reconstruction is done. + MatrixWorkspace_sptr linAdj = getProperty("DataLinearAdj"); + size_t nAHistograms = 0; + if (linAdj) + nAHistograms = linAdj->getNumberHistograms(); + if (nAHistograms % 2) + result["DataLinearAdj"] = + "The number of histograms in the linear " + "adjustments workspace must be even, because they are complex data"; + else if (nAHistograms > 0 && nAHistograms < nHistograms) + result["DataLinearAdj"] = + "The number of histograms in the linear " + "adjustments workspace is insufficient for the input workspace"; + + // Check constant adjustments, we expect and even number of histograms + // and if any, they must be sufficient for all spectra in input workspace, + // if per spectrum reconstruction is done. + MatrixWorkspace_sptr constAdj = getProperty("DataConstAdj"); + nAHistograms = 0; + if (constAdj) + nAHistograms = constAdj->getNumberHistograms(); + if (nAHistograms % 2) + result["DataConstAdj"] = + "The number of histograms in the constant " + "adjustments workspace must be even, because they are complex data"; + else if (nAHistograms > 0 && nAHistograms < nHistograms) + result["DataConstAdj"] = + "The number of histograms in the constant " + "adjustments workspace is insufficient for the input workspace"; + return result; } @@ -277,22 +340,30 @@ void MaxEnt::exec() { // Read input workspace MatrixWorkspace_const_sptr inWS = getProperty("InputWorkspace"); // Number of spectra - size_t nSpec = inWS->getNumberHistograms(); + size_t nHist = inWS->getNumberHistograms(); // Number of data points - assumed to be constant between spectra or // this will throw an exception size_t npoints = inWS->blocksize() * resolutionFactor; // Number of X bins const size_t npointsX = inWS->isHistogramData() ? npoints + 1 : npoints; + // Linear adjustment of calculated data + MatrixWorkspace_const_sptr dataLinearAdj = getProperty("DataLinearAdj"); + // Constant adjustment of calculated data + MatrixWorkspace_const_sptr dataConstAdj = getProperty("DataConstAdj"); + // Add spectra in reconstruction if false + const bool perSpectrumReconstruction = + getProperty("PerSpectrumReconstruction"); // For now have the requirement that data must have non-zero // (and positive!) errors - for (size_t s = 0; s < nSpec; s++) { + for (size_t s = 0; s < nHist; s++) { auto errors = inWS->e(s).rawData(); size_t npoints = errors.size(); for (size_t i = 0; i < npoints; i++) { if (errors[i] <= 0.0) { - throw std::invalid_argument("Input data must have non-zero errors."); + throw std::invalid_argument( + "Input data must have all errors non-zero."); } } } @@ -300,28 +371,36 @@ void MaxEnt::exec() { // Is our data space real or complex? MaxentSpace_sptr dataSpace; if (complexData) { - dataSpace = std::make_shared<MaxentSpaceComplex>(); + dataSpace = boost::make_shared<MaxentSpaceComplex>(); } else { - dataSpace = std::make_shared<MaxentSpaceReal>(); + dataSpace = boost::make_shared<MaxentSpaceReal>(); } // Is our image space real or complex? MaxentSpace_sptr imageSpace; if (complexImage) { - imageSpace = std::make_shared<MaxentSpaceComplex>(); + imageSpace = boost::make_shared<MaxentSpaceComplex>(); + } else { + imageSpace = boost::make_shared<MaxentSpaceReal>(); + } + // The type of transform. Currently a 1D Fourier Transform or Multiple ID + // Fourier transform + MaxentTransform_sptr transform; + if (perSpectrumReconstruction) { + transform = + boost::make_shared<MaxentTransformFourier>(dataSpace, imageSpace); } else { - imageSpace = std::make_shared<MaxentSpaceReal>(); + auto complexDataSpace = boost::make_shared<MaxentSpaceComplex>(); + transform = boost::make_shared<MaxentTransformMultiFourier>( + complexDataSpace, imageSpace, nHist / 2); } - // The type of transform. Currently a 1D Fourier Transform - MaxentTransform_sptr transform = - std::make_shared<MaxentTransformFourier>(dataSpace, imageSpace); // The type of entropy we are going to use (depends on the type of image, // positive only, or positive and/or negative) MaxentEntropy_sptr entropy; if (positiveImage) { - entropy = std::make_shared<MaxentEntropyPositiveValues>(); + entropy = boost::make_shared<MaxentEntropyPositiveValues>(); } else { - entropy = std::make_shared<MaxentEntropyNegativeValues>(); + entropy = boost::make_shared<MaxentEntropyNegativeValues>(); } // Entropy and transform is all we need to set up a calculator @@ -333,36 +412,65 @@ void MaxEnt::exec() { MatrixWorkspace_sptr outEvolChi; MatrixWorkspace_sptr outEvolTest; - nSpec = complexData ? nSpec / 2 : nSpec; - outImageWS = - WorkspaceFactory::Instance().create(inWS, 2 * nSpec, npoints, npoints); + size_t nDataSpec = complexData ? nHist / 2 : nHist; + size_t nImageSpec = nDataSpec; + size_t nSpecConcat = 1; + if (!perSpectrumReconstruction) { + nSpecConcat = nImageSpec; + nImageSpec = 1; + } + outImageWS = WorkspaceFactory::Instance().create(inWS, 2 * nImageSpec, + npoints, npoints); for (size_t i = 0; i < outImageWS->getNumberHistograms(); ++i) outImageWS->getSpectrum(i).setDetectorID(static_cast<detid_t>(i + 1)); - outDataWS = - WorkspaceFactory::Instance().create(inWS, 2 * nSpec, npointsX, npoints); + outDataWS = WorkspaceFactory::Instance().create(inWS, 2 * nDataSpec, npointsX, + npoints); for (size_t i = 0; i < outDataWS->getNumberHistograms(); ++i) outDataWS->getSpectrum(i).setDetectorID(static_cast<detid_t>(i + 1)); - outEvolChi = WorkspaceFactory::Instance().create(inWS, nSpec, nIter, nIter); - outEvolTest = WorkspaceFactory::Instance().create(inWS, nSpec, nIter, nIter); + outEvolChi = + WorkspaceFactory::Instance().create(inWS, nImageSpec, nIter, nIter); + outEvolTest = + WorkspaceFactory::Instance().create(inWS, nImageSpec, nIter, nIter); npoints = complexImage ? npoints * 2 : npoints; std::vector<size_t> iterationCounts; - iterationCounts.reserve(nSpec); + iterationCounts.reserve(nImageSpec); outEvolChi->setPoints(0, Points(nIter, LinearGenerator(0.0, 1.0))); - for (size_t spec = 0; spec < nSpec; spec++) { + size_t dataLength = complexData ? 2 * inWS->y(0).size() : inWS->y(0).size(); + dataLength *= nSpecConcat; + + for (size_t spec = 0; spec < nImageSpec; spec++) { // Start distribution (flat background) std::vector<double> image(npoints, background); - std::vector<double> data; - std::vector<double> errors; + std::vector<double> data(dataLength, 0.0); + std::vector<double> errors(dataLength, 0.0); if (complexData) { - data = toComplex(inWS, spec, false); // false -> data - errors = toComplex(inWS, spec, true); // true -> errors + data = toComplex(inWS, spec, false, + !perSpectrumReconstruction); // 3rd arg false -> data + errors = toComplex(inWS, spec, true, + !perSpectrumReconstruction); // 3rd arg true -> errors } else { - data = inWS->y(spec).rawData(); - errors = inWS->e(spec).rawData(); + if (!perSpectrumReconstruction) { + throw std::invalid_argument( + "ComplexData must be true, if PerSpectrumReconstruction is false."); + } else { + data = inWS->y(spec).rawData(); + errors = inWS->e(spec).rawData(); + } + } + + std::vector<double> linearAdjustments; + std::vector<double> constAdjustments; + if (dataLinearAdj) { + linearAdjustments = + toComplex(dataLinearAdj, spec, false, !perSpectrumReconstruction); + } + if (dataConstAdj) { + constAdjustments = + toComplex(dataConstAdj, spec, false, !perSpectrumReconstruction); } // To record the algorithm's progress @@ -373,11 +481,13 @@ void MaxEnt::exec() { Progress progress(this, 0.0, 1.0, nIter); // Run maxent algorithm + bool converged = false; for (size_t it = 0; it < nIter; it++) { // Iterates one step towards the solution. This means calculating // quadratic coefficients, search directions, angle and chi-sq - maxentCalculator.iterate(data, errors, image, background); + maxentCalculator.iterate(data, errors, image, background, + linearAdjustments, constAdjustments); // Calculate delta to construct new image (SB eq. 25) double currChisq = maxentCalculator.getChisq(); @@ -396,14 +506,15 @@ void MaxEnt::exec() { evolChi[it] = currChisq; evolTest[it] = currAngle; - // Stop condition, solution found + // Stop condition for convergence, solution found if ((std::abs(currChisq / ChiTargetOverN - 1.) < chiEps) && (currAngle < angle)) { // it + 1 iterations have been done because we count from zero g_log.information() - << "Stopped after " << it + 1 << " iterations" << std::endl; + << "Converged after " << it + 1 << " iterations" << std::endl; iterationCounts.push_back(it + 1); + converged = true; break; } @@ -416,13 +527,19 @@ void MaxEnt::exec() { } // Next Iteration + // If we didn't converge, we still need to record the number of iterations + if (!converged) { + iterationCounts.push_back(nIter); + } + // Get calculated data auto solData = maxentCalculator.getReconstructedData(); auto solImage = maxentCalculator.getImage(); // Populate the output workspaces - populateDataWS(inWS, spec, nSpec, solData, complexData, outDataWS); - populateImageWS(inWS, spec, nSpec, solImage, complexImage, outImageWS, + populateDataWS(inWS, spec, nDataSpec, solData, !perSpectrumReconstruction, + complexData, outDataWS); + populateImageWS(inWS, spec, nImageSpec, solImage, complexImage, outImageWS, autoShift); // Populate workspaces recording the evolution of Chi and Test @@ -446,35 +563,45 @@ void MaxEnt::exec() { //---------------------------------------------------------------------------------------------- -/** Returns a given spectrum as a complex number +/** Returns a given spectrum or sum of spectra as a complex number * @param inWS :: [input] The input workspace containing all the spectra * @param spec :: [input] The spectrum of interest * @param errors :: [input] If true, returns the errors, otherwise returns the * counts + * @param concatSpec :: [input] If true, use concatenation of all spectra + * (ignoring spec) * @return : Spectrum 'spec' as a complex vector */ std::vector<double> MaxEnt::toComplex(API::MatrixWorkspace_const_sptr &inWS, - size_t spec, bool errors) { + size_t spec, bool errors, + bool concatSpec) { const size_t numBins = inWS->y(0).size(); - std::vector<double> result(numBins * 2); + size_t nSpec = inWS->getNumberHistograms() / 2; + std::vector<double> result; + result.reserve(2 * numBins); if (inWS->getNumberHistograms() % 2) throw std::invalid_argument( "Cannot convert input workspace to complex data"); - size_t nspec = inWS->getNumberHistograms() / 2; + size_t nSpecOfInterest = (concatSpec ? nSpec : 1); + size_t firstSpecOfInterest = (concatSpec ? 0 : spec); - if (!errors) { - for (size_t i = 0; i < numBins; i++) { - result[2 * i] = inWS->y(spec)[i]; - result[2 * i + 1] = inWS->y(spec + nspec)[i]; - } - } else { - for (size_t i = 0; i < numBins; i++) { - result[2 * i] = inWS->e(spec)[i]; - result[2 * i + 1] = inWS->e(spec + nspec)[i]; + for (size_t s = firstSpecOfInterest; + s < firstSpecOfInterest + nSpecOfInterest; s++) { + if (!errors) { + for (size_t i = 0; i < numBins; i++) { + result.emplace_back(inWS->y(s)[i]); + result.emplace_back(inWS->y(s + nSpec)[i]); + } + } else { + for (size_t i = 0; i < numBins; i++) { + result.emplace_back(inWS->e(s)[i]); + result.emplace_back(inWS->e(s + nSpec)[i]); + } } } + return result; } @@ -707,7 +834,7 @@ MaxEnt::updateImage(const std::vector<double> &image, return newImage; } -/** Populates the output workspaces +/** Populates the image output workspace * @param inWS :: [input] The input workspace * @param spec :: [input] The current spectrum being analyzed * @param nspec :: [input] The total number of histograms in the input workspace @@ -724,7 +851,8 @@ void MaxEnt::populateImageWS(MatrixWorkspace_const_sptr &inWS, size_t spec, bool autoShift) { if (complex && result.size() % 2) - throw std::invalid_argument("Cannot write results to output workspaces"); + throw std::invalid_argument( + "Cannot write image results to output workspaces"); int npoints = complex ? static_cast<int>(result.size() / 2) : static_cast<int>(result.size()); @@ -797,57 +925,86 @@ void MaxEnt::populateImageWS(MatrixWorkspace_const_sptr &inWS, size_t spec, outWS->setSharedE(nspec + spec, outWS->sharedE(spec)); } -/** Populates the output workspaces +/** Populates the data output workspace * @param inWS :: [input] The input workspace * @param spec :: [input] The current spectrum being analyzed * @param nspec :: [input] The total number of histograms in the input workspace * @param result :: [input] The reconstructed data to be written in the output * workspace (can be a real or complex vector) * @param complex :: [input] True if result is a complex vector, false otherwise + * @param concatenated :: [input] True if result is concatenated spectra, + * then all spectra are analyzed and spec must be 0. * @param outWS :: [input] The output workspace to populate */ void MaxEnt::populateDataWS(MatrixWorkspace_const_sptr &inWS, size_t spec, size_t nspec, const std::vector<double> &result, - bool complex, MatrixWorkspace_sptr &outWS) { + bool concatenated, bool complex, + MatrixWorkspace_sptr &outWS) { if (complex && result.size() % 2) - throw std::invalid_argument("Cannot write results to output workspaces"); - - int npoints = complex ? static_cast<int>(result.size() / 2) - : static_cast<int>(result.size()); - int npointsX = inWS->isHistogramData() ? npoints + 1 : npoints; - MantidVec X(npointsX); - MantidVec YR(npoints); - MantidVec YI(npoints); - MantidVec E(npoints, 0.); - + throw std::invalid_argument( + "Cannot write data results to output workspaces"); + if (concatenated && !complex) + throw std::invalid_argument("Concatenated data results must be complex"); + if (concatenated && result.size() % (nspec * 2)) + throw std::invalid_argument( + "Cannot write complex concatenated data results to output workspaces"); + if (concatenated && spec != 0) + throw std::invalid_argument("Cannot write concatenated data results to " + "output workspaces from non-first spectrum"); + + int resultLength = complex ? static_cast<int>(result.size() / 2) + : static_cast<int>(result.size()); + size_t spectrumLength = (concatenated ? resultLength / nspec : resultLength); + size_t spectrumLengthX = + inWS->isHistogramData() ? spectrumLength + 1 : spectrumLength; + size_t nSpecAnalyzed = (concatenated ? nspec : 1); + + // Here we assume equal constant binning for all spectra analyzed double x0 = inWS->x(spec)[0]; double dx = inWS->x(spec)[1] - x0; - // X values - for (int i = 0; i < npointsX; i++) { - X[i] = x0 + i * dx; - } + // Loop over each spectrum being analyzed - one spectrum unless concatenated + for (size_t specA = spec; specA < spec + nSpecAnalyzed; specA++) { - // Y values - if (complex) { - for (int i = 0; i < npoints; i++) { - YR[i] = result[2 * i]; - YI[i] = result[2 * i + 1]; + MantidVec X(spectrumLengthX); + MantidVec YR(spectrumLength); + MantidVec YI(spectrumLength); + MantidVec E(spectrumLength, 0.); + + // X values + for (size_t i = 0; i < spectrumLengthX; i++) { + X[i] = x0 + static_cast<double>(i) * dx; } - } else { - for (int i = 0; i < npoints; i++) { - YR[i] = result[i]; - YI[i] = 0.; + + // Y values + if (complex) { + if (concatenated) { + // note the spec=0, so specA starts from 0 in this case. + for (size_t i = 0; i < spectrumLength; i++) { + YR[i] = result[2 * i + 2 * specA * spectrumLength]; + YI[i] = result[2 * i + 1 + 2 * specA * spectrumLength]; + } + } else { + for (size_t i = 0; i < spectrumLength; i++) { + YR[i] = result[2 * i]; + YI[i] = result[2 * i + 1]; + } + } + } else { + for (size_t i = 0; i < spectrumLength; i++) { + YR[i] = result[i]; + YI[i] = 0.; + } } - } - outWS->mutableX(spec) = std::move(X); - outWS->mutableY(spec) = std::move(YR); - outWS->mutableE(spec) = std::move(E); - outWS->setSharedX(nspec + spec, outWS->sharedX(spec)); - outWS->mutableY(nspec + spec) = std::move(YI); - outWS->setSharedE(nspec + spec, outWS->sharedE(spec)); + outWS->mutableX(specA) = std::move(X); + outWS->mutableY(specA) = std::move(YR); + outWS->mutableE(specA) = std::move(E); + outWS->mutableY(nspec + specA) = std::move(YI); + outWS->setSharedX(nspec + specA, outWS->sharedX(spec)); + outWS->setSharedE(nspec + specA, outWS->sharedE(spec)); + } // Next spectrum if concatenated } } // namespace Algorithms diff --git a/Framework/Algorithms/src/MaxEnt/MaxentCalculator.cpp b/Framework/Algorithms/src/MaxEnt/MaxentCalculator.cpp index 0dd9eb40a0b702b3348c6a47d1131d6387141e53..6ad18faa225b0e202ffae2673eea1ba5c3743049 100644 --- a/Framework/Algorithms/src/MaxEnt/MaxentCalculator.cpp +++ b/Framework/Algorithms/src/MaxEnt/MaxentCalculator.cpp @@ -149,12 +149,15 @@ MaxentCalculator::calculateImage(const std::vector<double> &data) const { * @param errors : [input] The experimental errors as a vector (real or complex) * @param image : [input] The image as a vector (real or complex) * @param background : [input] The background + * @param linearAdjustments: [input] Optional linear adjustments (complex) + * @param constAdjustments: [input] Optional constant adjustments (complex) */ void MaxentCalculator::iterate(const std::vector<double> &data, const std::vector<double> &errors, const std::vector<double> &image, - double background) { - + double background, + const std::vector<double> &linearAdjustments, + const std::vector<double> &constAdjustments) { // Some checks if (data.empty() || errors.empty() || (data.size() != errors.size())) { throw std::invalid_argument( @@ -178,6 +181,31 @@ void MaxentCalculator::iterate(const std::vector<double> &data, m_angle = -1.; m_chisq = -1.; + // adjust calculated data, if required + if (!linearAdjustments.empty()) { + if (linearAdjustments.size() < m_dataCalc.size()) { + throw std::invalid_argument( + "Cannot adjust calculated data: too few linear adjustments"); + } + for (size_t j = 0; j < m_dataCalc.size() / 2; ++j) { + double yr = m_dataCalc[2 * j]; + double yi = m_dataCalc[2 * j + 1]; + m_dataCalc[2 * j] = + yr * linearAdjustments[2 * j] - yi * linearAdjustments[2 * j + 1]; + m_dataCalc[2 * j + 1] = + yi * linearAdjustments[2 * j] + yr * linearAdjustments[2 * j + 1]; + } + } + if (!constAdjustments.empty()) { + if (constAdjustments.size() < m_dataCalc.size()) { + throw std::invalid_argument( + "Cannot adjust calculated data: too few constant adjustments"); + } + for (size_t i = 0; i < m_dataCalc.size(); ++i) { + m_dataCalc[i] += constAdjustments[i]; + } + } + // Two search directions const size_t dim = 2; diff --git a/Framework/Algorithms/src/MaxEnt/MaxentTransformFourier.cpp b/Framework/Algorithms/src/MaxEnt/MaxentTransformFourier.cpp index 4d24949e76c88e9e8de823a1e3edb0c46e6db00c..ea641897a2d658f18bac54bd45413329587bd5b5 100644 --- a/Framework/Algorithms/src/MaxEnt/MaxentTransformFourier.cpp +++ b/Framework/Algorithms/src/MaxEnt/MaxentTransformFourier.cpp @@ -13,7 +13,12 @@ MaxentTransformFourier::MaxentTransformFourier(MaxentSpace_sptr dataSpace, /** * Transforms a 1D signal from image space to data space, performing an * inverse Fast Fourier Transform. See also GSL documentation on FFT. - * Assumes complex input. + * Input is assumed real or complex according to the type of image space + * given to the constructor. + * Return value is real or complex according to the type of data space + * given to the constructor. + * If complex, input & return vectors consist of real part immediately + * followed by imaginary part of each individual value. * @param image : [input] Image as a vector * @return : The vector in the data space */ @@ -42,8 +47,13 @@ MaxentTransformFourier::imageToData(const std::vector<double> &image) { /** * Transforms a 1D signal from data space to image space, performing a forward - * Fast Fourier Transform. See also GSL documentation on FFT. Assumes complex - * input. + * Fast Fourier Transform. See also GSL documentation on FFT. + * Input is assumed real or complex according to the type of data space + * given to the constructor. + * Return value is real or complex according to the type of image space + * given to the constructor. + * If complex, input & return vectors consist of real part immediately + * followed by imaginary part of each individual value. * @param data : [input] Data as a vector * @return : The vector in the image space */ diff --git a/Framework/Algorithms/src/MaxEnt/MaxentTransformMultiFourier.cpp b/Framework/Algorithms/src/MaxEnt/MaxentTransformMultiFourier.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c14d02b7748d0d0f39360a80d6f81bd433fcd86f --- /dev/null +++ b/Framework/Algorithms/src/MaxEnt/MaxentTransformMultiFourier.cpp @@ -0,0 +1,125 @@ +#include "MantidAlgorithms/MaxEnt/MaxentTransformMultiFourier.h" +#include <gsl/gsl_fft_complex.h> + +namespace Mantid { +namespace Algorithms { + +/** Constructor */ +MaxentTransformMultiFourier::MaxentTransformMultiFourier( + MaxentSpaceComplex_sptr dataSpace, MaxentSpace_sptr imageSpace, + size_t numSpec) + : MaxentTransformFourier(dataSpace, imageSpace), m_numSpec(numSpec), + m_linearAdjustments(), m_constAdjustments() {} + +/** + * Transforms a 1D signal from image space to data space, performing an + * a backward MaxentTransformFourier on it then creating a concatenated + * copy of the resulting data for each spectrum and applying the adjustments + * to them. + * Input is assumed real or complex according to the type of image space + * given to the constructor. + * Return value is real or complex according to the type of data space + * given to the constructor. + * If complex, input & return vectors consist of real part immediately + * followed by imaginary part of each individual value. + * @param image : [input] Image as a vector + * @return : The vector in the data space of concatenated spectra + */ +std::vector<double> +MaxentTransformMultiFourier::imageToData(const std::vector<double> &image) { + + std::vector<double> dataOneSpec = MaxentTransformFourier::imageToData(image); + + // Create concatenated copies of transformed data (one for each spectrum) + std::vector<double> data; + data.reserve(m_numSpec * dataOneSpec.size()); + for (size_t s = 0; s < m_numSpec; s++) { + for (size_t i = 0; i < dataOneSpec.size(); i++) { + data.emplace_back(dataOneSpec[i]); + } + } + + // Apply adjustments (we assume there are sufficient adjustments supplied) + double dataR = 0.123456789; + double dataI = 0.987654321; + if (!m_linearAdjustments.empty() && !m_constAdjustments.empty()) { + for (size_t i = 0; i < data.size(); i++) { + if (i % 2 == 0) { // Real part + dataR = data[i]; + dataI = data[i + 1]; + data[i] = m_linearAdjustments[i] * dataR - + m_linearAdjustments[i + 1] * dataI + m_constAdjustments[i]; + } else { // Imaginary part + data[i] = m_linearAdjustments[i] * dataR + + m_linearAdjustments[i - 1] * dataI + m_constAdjustments[i]; + } + } + } else if (!m_linearAdjustments.empty() && m_constAdjustments.empty()) { + for (size_t i = 0; i < data.size(); i++) { + if (i % 2 == 0) { // Real part + dataR = data[i]; + dataI = data[i + 1]; + data[i] = + m_linearAdjustments[i] * dataR - m_linearAdjustments[i + 1] * dataI; + } else { // Imaginary part + data[i] = + m_linearAdjustments[i] * dataR + m_linearAdjustments[i - 1] * dataI; + } + } + } else if (m_linearAdjustments.empty() && !m_constAdjustments.empty()) { + for (size_t i = 0; i < data.size(); i++) { + data[i] = data[i] + m_constAdjustments[i]; + } + } + + return data; +} + +/** + * Transforms a 1D signal from data space to image space, performing a forward + * Fast MexentTransformFourier on the sum of the spectra. + * Input is assumed real or complex according to the type of data space + * given to the constructor. + * Return value is real or complex according to the type of image space + * given to the constructor. + * If complex, input & return vectors consist of real part immediately + * followed by imaginary part of each individual value. + * @param data : [input] Data as a vector of concatenated spectra + * @return : The vector in the image space + */ +std::vector<double> +MaxentTransformMultiFourier::dataToImage(const std::vector<double> &data) { + + if (data.size() % m_numSpec) + throw std::invalid_argument( + "Size of data vector must be a multiple of number of spectra."); + + // Sum the concatenated spectra in data + size_t nData = data.size() / (m_numSpec); + std::vector<double> dataSum(nData, 0.0); + for (size_t s = 0; s < m_numSpec; s++) { + for (size_t i = 0; i < nData; i++) { + dataSum[i] += data[s * nData + i]; + } + } + // Then apply forward fourier transform to sum + std::vector<double> image = MaxentTransformFourier::dataToImage(dataSum); + + return image; +} + +/** + * Sets the adjustments to be applied to the data when converted from image. + * @param linAdj : [input] Linear adjustments as complex numbers for all spectra + * concatenated + * @param constAdj: [input] Constant adjustments as complex numbers for all + * spectra concatenated + */ +void MaxentTransformMultiFourier::setAdjustments( + const std::vector<double> &linAdj, const std::vector<double> &constAdj) { + m_linearAdjustments = linAdj; + m_constAdjustments = constAdj; +} + +} // namespace Algorithms +} // namespace Mantid diff --git a/Framework/Algorithms/src/RebinToWorkspace.cpp b/Framework/Algorithms/src/RebinToWorkspace.cpp index 6863f8cb7f57188e7bd8283b8ec491d2f4b0097c..3e96604f6bc0eaebbdc9e8adc36f00f14ff4bc70 100644 --- a/Framework/Algorithms/src/RebinToWorkspace.cpp +++ b/Framework/Algorithms/src/RebinToWorkspace.cpp @@ -1,11 +1,19 @@ #include "MantidAlgorithms/RebinToWorkspace.h" #include "MantidAPI/HistogramValidator.h" #include "MantidAPI/MatrixWorkspace.h" +#include "MantidDataObjects/EventWorkspace.h" +#include "MantidDataObjects/Workspace2D.h" +#include "MantidDataObjects/WorkspaceCreation.h" +#include "MantidHistogramData/Rebin.h" namespace Mantid { namespace Algorithms { using namespace API; +using DataObjects::EventWorkspace; +using DataObjects::EventWorkspace_const_sptr; +using HistogramData::CountStandardDeviations; +using HistogramData::Counts; // Register the algorithm into the AlgorithmFactory DECLARE_ALGORITHM(RebinToWorkspace) @@ -43,6 +51,31 @@ void RebinToWorkspace::init() { "Workspace2D histogram."); } +bool RebinToWorkspace::needToRebin(const MatrixWorkspace_sptr &left, + const MatrixWorkspace_sptr &rght) { + // converting from EventWorkspace to Workspace2D is a rebin + if (m_isEvents && (!m_preserveEvents)) + return true; + + // if pointers match they are the same object + if (left == rght) + return false; + + // see if there is the same number of histograms + const size_t numHist = left->getNumberHistograms(); + if (numHist != rght->getNumberHistograms()) + return true; + + // look for first non-equal x-axis between the workspaces + for (size_t i = 0; i < numHist; ++i) { + if (left->getSpectrum(i).x() != rght->getSpectrum(i).x()) { + return true; + } + } + // everything must be the same + return false; +} + /** * Execute the algorithm */ @@ -50,48 +83,101 @@ void RebinToWorkspace::exec() { // The input workspaces ... MatrixWorkspace_sptr toRebin = getProperty("WorkspaceToRebin"); MatrixWorkspace_sptr toMatch = getProperty("WorkspaceToMatch"); - bool PreserveEvents = getProperty("PreserveEvents"); - - // First we need to create the parameter vector from the workspace with which - // we are matching - std::vector<double> rb_params = createRebinParameters(toMatch); - - IAlgorithm_sptr runRebin = createChildAlgorithm("Rebin"); - runRebin->setProperty<MatrixWorkspace_sptr>("InputWorkspace", toRebin); - runRebin->setPropertyValue("OutputWorkspace", "rebin_out"); - runRebin->setProperty("params", rb_params); - runRebin->setProperty("PreserveEvents", PreserveEvents); - runRebin->setProperty("IgnoreBinErrors", true); - runRebin->executeAsChildAlg(); - progress(1); - MatrixWorkspace_sptr ws = runRebin->getProperty("OutputWorkspace"); - setProperty("OutputWorkspace", ws); + m_preserveEvents = getProperty("PreserveEvents"); + m_isEvents = bool(boost::dynamic_pointer_cast<const EventWorkspace>(toRebin)); + + if (needToRebin(toRebin, toMatch)) { + g_log.information("Rebinning"); + if (m_isEvents && (!m_preserveEvents)) { + this->histogram(toRebin, toMatch); + } else { + this->rebin(toRebin, toMatch); + } + } else { // don't need to rebin + g_log.information( + "WorkspaceToRebin and WorkspaceToMatch already have matched binning"); + + MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace"); + const bool inPlace = (toRebin == outputWS); + if (!inPlace) { + outputWS = toRebin->clone(); + } + this->setProperty("OutputWorkspace", outputWS); + } } -/** - * Create the vector of rebin parameters - * @param toMatch :: A shared pointer to the workspace with the desired binning - * @returns :: A vector to hold the rebin parameters once they have been - * calculated - */ -std::vector<double> RebinToWorkspace::createRebinParameters( - Mantid::API::MatrixWorkspace_sptr toMatch) { - using namespace Mantid::API; - - auto &matchXdata = toMatch->x(0); - // params vector should have the form [x_1, delta_1,x_2, ... - // ,x_n-1,delta_n-1,x_n), see Rebin.cpp - std::vector<double> rb_params; - int xsize = static_cast<int>(matchXdata.size()); - rb_params.reserve(xsize * 2); - for (int i = 0; i < xsize; ++i) { - // bin bound - rb_params.push_back(matchXdata[i]); - // Bin width - if (i < xsize - 1) - rb_params.push_back(matchXdata[i + 1] - matchXdata[i]); +// this follows closely what Rebin does except each x-axis is different +void RebinToWorkspace::rebin(MatrixWorkspace_sptr &toRebin, + MatrixWorkspace_sptr &toMatch) { + // create the output workspace + MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace"); + const bool inPlace = (toRebin == outputWS); + if (!inPlace) { + outputWS = toRebin->clone(); + } + auto outputWSEvents = boost::dynamic_pointer_cast<EventWorkspace>(outputWS); + + const int numHist = static_cast<int>(toRebin->getNumberHistograms()); + Progress prog(this, 0.5, 1.0, numHist); + + // everything gets the same bin boundaries as the first spectrum + const bool matchingX = + (toRebin->getNumberHistograms() != toMatch->getNumberHistograms()); + + // rebin + PARALLEL_FOR_IF(Kernel::threadSafe(*toMatch, *outputWS)) + for (int i = 0; i < numHist; ++i) { + PARALLEL_START_INTERUPT_REGION + const auto &edges = matchingX ? toMatch->histogram(0).binEdges() + : toMatch->histogram(i).binEdges(); + if (m_isEvents) { + outputWSEvents->getSpectrum(i).setHistogram(edges); + } else { + outputWS->setHistogram( + i, HistogramData::rebin(toRebin->histogram(i), edges)); + } + prog.report(); + PARALLEL_END_INTERUPT_REGION + } + PARALLEL_CHECK_INTERUPT_REGION + + setProperty("OutputWorkspace", outputWS); +} + +// handles the special case when binning from EventWorkspace to Workspace2D most +// efficiently by histogramming the events to the correct binning directly +void RebinToWorkspace::histogram(API::MatrixWorkspace_sptr &toRebin, + API::MatrixWorkspace_sptr &toMatch) { + const auto &inputWS = + boost::dynamic_pointer_cast<const EventWorkspace>(toRebin); + const int numHist = static_cast<int>(toRebin->getNumberHistograms()); + // everything gets the same bin boundaries as the first spectrum + const bool matchingX = + (toRebin->getNumberHistograms() != toMatch->getNumberHistograms()); + + auto outputWS = DataObjects::create<API::HistoWorkspace>(*toRebin); + Progress prog(this, 0.25, 1.0, numHist); + + // histogram + PARALLEL_FOR_IF(Kernel::threadSafe(*toMatch, *outputWS)) + for (int i = 0; i < numHist; ++i) { + PARALLEL_START_INTERUPT_REGION + const auto &edges = matchingX ? toMatch->histogram(0).binEdges() + : toMatch->histogram(i).binEdges(); + + // TODO this should be in HistogramData/Rebin + const auto &eventlist = inputWS->getSpectrum(i); + MantidVec y_data(edges.size() - 1), e_data(edges.size() - 1); + eventlist.generateHistogram(edges.rawData(), y_data, e_data); + + outputWS->setHistogram(i, edges, Counts(std::move(y_data)), + CountStandardDeviations(std::move(e_data))); + prog.report(); + PARALLEL_END_INTERUPT_REGION } - return rb_params; + PARALLEL_CHECK_INTERUPT_REGION + + setProperty("OutputWorkspace", std::move(outputWS)); } Parallel::ExecutionMode RebinToWorkspace::getParallelExecutionMode( diff --git a/Framework/Algorithms/src/SumOverlappingTubes.cpp b/Framework/Algorithms/src/SumOverlappingTubes.cpp index f7ec572b5d75f9ba15c5d5d264f0fbecc468029b..7524c91c5468d2c152dfa005c819450bef5adb0c 100644 --- a/Framework/Algorithms/src/SumOverlappingTubes.cpp +++ b/Framework/Algorithms/src/SumOverlappingTubes.cpp @@ -290,7 +290,7 @@ SumOverlappingTubes::performBinning(MatrixWorkspace_sptr &outputWS) { // loop over spectra const auto &specInfo = ws->spectrumInfo(); for (size_t i = 0; i < specInfo.size(); ++i) { - if (specInfo.isMonitor(i)) + if (specInfo.isMonitor(i) || specInfo.isMasked(i)) continue; const auto &pos = specInfo.position(i); @@ -366,9 +366,7 @@ SumOverlappingTubes::performBinning(MatrixWorkspace_sptr &outputWS) { yData[angleIndex] += counts; eData[angleIndex] = sqrt(eData[angleIndex] * eData[angleIndex] + error * error); - if (counts != 0.) { - normalisation[heightIndex][angleIndex]++; - } + normalisation[heightIndex][angleIndex]++; } } } diff --git a/Framework/Algorithms/test/MaskDetectorsIfTest.h b/Framework/Algorithms/test/MaskDetectorsIfTest.h index 59c889f05bb758018d344d69b76c9f32a7c86cfb..ef820dd109e02aea77ad68f46ad3bb2941899283 100644 --- a/Framework/Algorithms/test/MaskDetectorsIfTest.h +++ b/Framework/Algorithms/test/MaskDetectorsIfTest.h @@ -4,7 +4,9 @@ #include <cxxtest/TestSuite.h> #include "MantidAPI/MatrixWorkspace.h" +#include "MantidAPI/SpectrumInfo.h" #include "MantidAlgorithms/MaskDetectorsIf.h" +#include "MantidGeometry/Instrument/DetectorInfo.h" #include "MantidTestHelpers/ScopedFileHelper.h" #include "MantidTestHelpers/WorkspaceCreationHelper.h" #include <Poco/File.h> @@ -24,12 +26,13 @@ public: } static void destroySuite(MaskDetectorsIfTest *suite) { delete suite; } - void testDeselectIfNotEqual() { + void testCalFileDeselectIfNotEqual() { // setup and run the algorithm (includes basic checks) MaskDetectorsIf alg; - setupAlgorithm(alg, "DeselectIf", "NotEqual", 2.2); + // create the workspace + setupAlgorithmForCalFiles(alg, "DeselectIf", "NotEqual", 2.2); std::ifstream file; - runAlgorithm(alg, file); + runAlgorithmForCalFiles(alg, file); // specific checks if (file.is_open()) { @@ -41,12 +44,12 @@ public: } } - void testDeselectIfLess() { + void testCalFileDeselectIfLess() { // setup and run the algorithm (includes basic checks) MaskDetectorsIf alg; - setupAlgorithm(alg, "DeselectIf", "Less", 2.2); + setupAlgorithmForCalFiles(alg, "DeselectIf", "Less", 2.2); std::ifstream file; - runAlgorithm(alg, file); + runAlgorithmForCalFiles(alg, file); // specific checks if (file.is_open()) { @@ -58,12 +61,12 @@ public: } } - void testDeselectIfLessEqual() { + void testCalFileDeselectIfLessEqual() { // setup and run the algorithm (includes basic checks) MaskDetectorsIf alg; - setupAlgorithm(alg, "DeselectIf", "LessEqual", 2.2); + setupAlgorithmForCalFiles(alg, "DeselectIf", "LessEqual", 2.2); std::ifstream file; - runAlgorithm(alg, file); + runAlgorithmForCalFiles(alg, file); // specific checks if (file.is_open()) { @@ -75,12 +78,12 @@ public: } } - void testDeselectIfGreater() { + void testCalFileDeselectIfGreater() { // setup and run the algorithm (includes basic checks) MaskDetectorsIf alg; - setupAlgorithm(alg, "DeselectIf", "Greater", 2.2); + setupAlgorithmForCalFiles(alg, "DeselectIf", "Greater", 2.2); std::ifstream file; - runAlgorithm(alg, file); + runAlgorithmForCalFiles(alg, file); // specific checks if (file.is_open()) { @@ -92,12 +95,12 @@ public: } } - void testDeselectIfGreaterEqual() { + void testCalFileDeselectIfGreaterEqual() { // setup and run the algorithm (includes basic checks) MaskDetectorsIf alg; - setupAlgorithm(alg, "DeselectIf", "GreaterEqual", 2.2); + setupAlgorithmForCalFiles(alg, "DeselectIf", "GreaterEqual", 2.2); std::ifstream file; - runAlgorithm(alg, file); + runAlgorithmForCalFiles(alg, file); // specific checks if (file.is_open()) { @@ -109,16 +112,17 @@ public: } } - void testSelectIfEqual() { + void testCalFileSelectIfEqual() { // Create an input file where the detectors are all deselected // initially (so we can tell whether the SelectIf worked). ScopedFile inputFile = makeFakeInputFile(); // setup and run the algorithm (includes basic checks) MaskDetectorsIf alg; - setupAlgorithm(alg, "SelectIf", "Equal", 2.2, inputFile.getFileName()); + setupAlgorithmForCalFiles(alg, "SelectIf", "Equal", 2.2, + inputFile.getFileName()); std::ifstream file; - runAlgorithm(alg, file); + runAlgorithmForCalFiles(alg, file); // specific checks if (file.is_open()) { @@ -130,10 +134,78 @@ public: } } + void testMaskWorkspaceDeselectIfNotEqual() { + auto correctMasking = [](MatrixWorkspace const &ws, const size_t wsIndex) { + return ws.y(wsIndex).front() == 2.2; + }; + MaskDetectorsIf alg; + MatrixWorkspace_sptr inWS = makeFakeWorkspace(); + maskAllDetectors(inWS); + setupAlgorithmForOutputWorkspace(alg, inWS, "DeselectIf", "NotEqual", 2.2); + TS_ASSERT_THROWS_NOTHING(alg.execute()) + TS_ASSERT(alg.isExecuted()) + checkOutputWorkspace(alg, correctMasking); + } + + void testMaskWorkspaceSelectIfEqual() { + auto correctMasking = [](MatrixWorkspace const &ws, const size_t wsIndex) { + return ws.y(wsIndex).front() == 2.2; + }; + MaskDetectorsIf alg; + MatrixWorkspace_sptr inWS = makeFakeWorkspace(); + setupAlgorithmForOutputWorkspace(alg, inWS, "SelectIf", "Equal", 2.2); + TS_ASSERT_THROWS_NOTHING(alg.execute()) + TS_ASSERT(alg.isExecuted()) + checkOutputWorkspace(alg, correctMasking); + } + + void testMaskWorkspaceDeselectIfLess() { + auto correctMasking = [](MatrixWorkspace const &ws, const size_t wsIndex) { + return ws.y(wsIndex).front() >= 2.2; + }; + MaskDetectorsIf alg; + MatrixWorkspace_sptr inWS = makeFakeWorkspace(); + maskAllDetectors(inWS); + setupAlgorithmForOutputWorkspace(alg, inWS, "DeselectIf", "Less", 2.2); + TS_ASSERT_THROWS_NOTHING(alg.execute()) + TS_ASSERT(alg.isExecuted()) + checkOutputWorkspace(alg, correctMasking); + } + + void testMaskWorkspaceSelectIfGreater() { + auto correctMasking = [](MatrixWorkspace const &ws, const size_t wsIndex) { + return ws.y(wsIndex).front() > 2.2; + }; + MaskDetectorsIf alg; + MatrixWorkspace_sptr inWS = makeFakeWorkspace(); + setupAlgorithmForOutputWorkspace(alg, inWS, "SelectIf", "Greater", 2.2); + TS_ASSERT_THROWS_NOTHING(alg.execute()) + TS_ASSERT(alg.isExecuted()) + checkOutputWorkspace(alg, correctMasking); + } + private: + constexpr static int numBanks{1}; + constexpr static int numPixels{2}; + constexpr static int numBins{1}; + constexpr static int numHist{numBanks * numPixels * numPixels}; + + template <typename T> + void checkOutputWorkspace(MaskDetectorsIf &alg, T correctMasking) { + MatrixWorkspace_sptr inW = alg.getProperty("InputWorkspace"); + MatrixWorkspace_sptr mask = alg.getProperty("OutputWorkspace"); + TS_ASSERT(mask) + TS_ASSERT_EQUALS(mask->getNumberHistograms(), numHist) + const auto &spectrumInfo = mask->spectrumInfo(); + for (size_t i = 0; i < numHist; ++i) { + TS_ASSERT_EQUALS(spectrumInfo.isMasked(i), correctMasking(*inW, i)) + TS_ASSERT_EQUALS(mask->y(i).front(), inW->y(i).front()) + } + } + // Create a fake input file. This is the same as // 4detector_cal_example_file.cal but with all the detectors deselected. - ScopedFile makeFakeInputFile() { + static ScopedFile makeFakeInputFile() { std::ostringstream os; os << "# Ariel detector file, written Sat Nov 24 16:52:56 2007\n"; @@ -146,11 +218,11 @@ private: return ScopedFile(os.str(), "MaskDetectorsIfTestInput.cal"); } - const MatrixWorkspace_sptr makeFakeWorkspace() { + static const MatrixWorkspace_sptr makeFakeWorkspace() { // create the workspace MatrixWorkspace_sptr ws = WorkspaceCreationHelper::create2DWorkspaceWithRectangularInstrument( - 1, 2, 1); + numBanks, numPixels, numBins); // Default y values are all 2.0. Change them so they're different // for each spectrum (this gives us the values 2.0, 2.1, 2.2, ...) @@ -161,9 +233,16 @@ private: return ws; } + static void maskAllDetectors(MatrixWorkspace_sptr &ws) { + auto &detectorInfo = ws->mutableDetectorInfo(); + for (size_t i = 0; i < detectorInfo.size(); ++i) { + detectorInfo.setMasked(i, true); + } + } + // Initialise the algorithm and set the properties. Creates a fake // workspace for the input. - void setupAlgorithm( + static void setupAlgorithmForCalFiles( MaskDetectorsIf &alg, const std::string &mode, const std::string &op, const double value, const std::string &inputFile = "4detector_cal_example_file.cal") { @@ -173,6 +252,7 @@ private: // set up the algorithm if (!alg.isInitialized()) alg.initialize(); + alg.setRethrows(true); alg.setProperty("InputWorkspace", inWS); alg.setProperty("InputCalFile", inputFile); alg.setProperty("Mode", mode); @@ -181,9 +261,29 @@ private: alg.setProperty("OutputCalFile", "MaskDetectorsIfTestOutput.cal"); } + // Initialise the algorithm and set the properties. Creates a fake + // workspace for the input. + static void setupAlgorithmForOutputWorkspace(MaskDetectorsIf &alg, + const MatrixWorkspace_sptr &inWS, + const std::string &mode, + const std::string &op, + const double value) { + // set up the algorithm + if (!alg.isInitialized()) + alg.initialize(); + alg.setRethrows(true); + alg.setChild(true); + alg.setProperty("InputWorkspace", inWS); + alg.setProperty("Mode", mode); + alg.setProperty("Operator", op); + alg.setProperty("Value", value); + alg.setProperty("OutputWorkspace", "_unused_for_child"); + } + // Run the algorithm and do some basic checks. Opens the output file // stream if everything is ok (leaves it closed if not). - void runAlgorithm(MaskDetectorsIf &alg, std::ifstream &outFile) { + static void runAlgorithmForCalFiles(MaskDetectorsIf &alg, + std::ifstream &outFile) { // run the algorithm TS_ASSERT_THROWS_NOTHING(alg.execute()); TS_ASSERT(alg.isExecuted()); @@ -209,7 +309,7 @@ private: } } - void skipHeader(std::ifstream &file) { + static void skipHeader(std::ifstream &file) { // our test file has 2 lines in the header std::string line; for (int i = 0; i < 2 && !file.eof(); ++i) { @@ -219,9 +319,9 @@ private: // Read the next line from the given file and check // that the values match those given. - void readAndCheckLine(std::ifstream &file, const int num, const int udet, - const double offset, const int select, - const int group) { + static void readAndCheckLine(std::ifstream &file, const int num, + const int udet, const double offset, + const int select, const int group) { TS_ASSERT(!file.eof()); if (!file.eof()) { diff --git a/Framework/Algorithms/test/MaxEnt/MaxentCalculatorTest.h b/Framework/Algorithms/test/MaxEnt/MaxentCalculatorTest.h index 8685ab50532a292a3e93937d47dcb55adbc9c08f..dcb006e9dd6e7d8afbb1b773d6b1513b9196a6fd 100644 --- a/Framework/Algorithms/test/MaxEnt/MaxentCalculatorTest.h +++ b/Framework/Algorithms/test/MaxEnt/MaxentCalculatorTest.h @@ -30,7 +30,7 @@ public: MOCK_METHOD1(dataToImage, std::vector<double>(const std::vector<double> &)); }; GNU_DIAG_ON_SUGGEST_OVERRIDE -using MockEntropy_sptr = std::shared_ptr<MockEntropy>; +using MockEntropy_sptr = boost::shared_ptr<MockEntropy>; class MaxentCalculatorTest : public CxxTest::TestSuite { @@ -47,31 +47,35 @@ public: MockEntropy *entropy = new NiceMock<MockEntropy>(); MockTransform *transform = new NiceMock<MockTransform>(); MaxentCalculator calculator = - MaxentCalculator(std::shared_ptr<MockEntropy>(entropy), - std::shared_ptr<MockTransform>(transform)); + MaxentCalculator(boost::shared_ptr<MockEntropy>(entropy), + boost::shared_ptr<MockTransform>(transform)); std::vector<double> vec = {0, 1}; std::vector<double> emptyVec = {}; double bkg = 1; // Empty image - TS_ASSERT_THROWS(calculator.iterate(vec, vec, emptyVec, bkg), - std::invalid_argument); + TS_ASSERT_THROWS( + calculator.iterate(vec, vec, emptyVec, bkg, emptyVec, emptyVec), + std::invalid_argument); // Empty errors - TS_ASSERT_THROWS(calculator.iterate(vec, emptyVec, vec, bkg), - std::invalid_argument); + TS_ASSERT_THROWS( + calculator.iterate(vec, emptyVec, vec, bkg, emptyVec, emptyVec), + std::invalid_argument); // Empty data - TS_ASSERT_THROWS(calculator.iterate(emptyVec, vec, vec, bkg), - std::invalid_argument); + TS_ASSERT_THROWS( + calculator.iterate(emptyVec, vec, vec, bkg, emptyVec, emptyVec), + std::invalid_argument); // Bad background (should be positive) - TS_ASSERT_THROWS(calculator.iterate(vec, vec, vec, 0), + TS_ASSERT_THROWS(calculator.iterate(vec, vec, vec, 0, emptyVec, emptyVec), std::invalid_argument); // Size mismatch between data and errors std::vector<double> vec2 = {0, 1, 1}; - TS_ASSERT_THROWS(calculator.iterate(vec, vec2, vec, bkg), - std::invalid_argument); + TS_ASSERT_THROWS( + calculator.iterate(vec, vec2, vec, bkg, emptyVec, emptyVec), + std::invalid_argument); } void test_size_mismatch_data_image() { @@ -82,8 +86,8 @@ public: MockEntropy *entropy = new NiceMock<MockEntropy>(); MockTransform *transform = new NiceMock<MockTransform>(); MaxentCalculator calculator = - MaxentCalculator(std::shared_ptr<MaxentEntropy>(entropy), - std::shared_ptr<MaxentTransform>(transform)); + MaxentCalculator(boost::shared_ptr<MaxentEntropy>(entropy), + boost::shared_ptr<MaxentTransform>(transform)); // Input data // Vector in image space @@ -92,6 +96,8 @@ public: std::vector<double> vec2 = {1, 1, 1}; // Background double bkg = 1; + // No adjustments + std::vector<double> emptyVec = {}; EXPECT_CALL(*entropy, correctValues(vec2, 1)) .Times(1) @@ -100,8 +106,9 @@ public: EXPECT_CALL(*transform, dataToImage(vec2)).Times(0); EXPECT_CALL(*entropy, derivative(vec2, 1)).Times(0); EXPECT_CALL(*entropy, secondDerivative(vec2, bkg)).Times(0); - TS_ASSERT_THROWS(calculator.iterate(vec1, vec1, vec2, bkg), - std::runtime_error); + TS_ASSERT_THROWS( + calculator.iterate(vec1, vec1, vec2, bkg, emptyVec, emptyVec), + std::runtime_error); Mock::VerifyAndClearExpectations(entropy); Mock::VerifyAndClearExpectations(transform); @@ -117,8 +124,8 @@ public: MockEntropy *entropy = new NiceMock<MockEntropy>(); MockTransform *transform = new NiceMock<MockTransform>(); MaxentCalculator calculator = - MaxentCalculator(std::shared_ptr<MaxentEntropy>(entropy), - std::shared_ptr<MaxentTransform>(transform)); + MaxentCalculator(boost::shared_ptr<MaxentEntropy>(entropy), + boost::shared_ptr<MaxentTransform>(transform)); // Input data // Vector in data space @@ -127,6 +134,8 @@ public: std::vector<double> vec2 = {1, 1, 1, 1}; // Background double bkg = 1; + // No adjustments + std::vector<double> emptyVec = {}; EXPECT_CALL(*entropy, correctValues(vec2, 1)) .Times(1) @@ -139,7 +148,8 @@ public: EXPECT_CALL(*entropy, secondDerivative(vec2, bkg)) .Times(1) .WillOnce(Return(vec2)); - TS_ASSERT_THROWS_NOTHING(calculator.iterate(vec1, vec1, vec2, bkg)); + TS_ASSERT_THROWS_NOTHING( + calculator.iterate(vec1, vec1, vec2, bkg, emptyVec, emptyVec)); Mock::VerifyAndClearExpectations(entropy); Mock::VerifyAndClearExpectations(transform); @@ -157,8 +167,8 @@ public: MockEntropy *entropy = new NiceMock<MockEntropy>(); MockTransform *transform = new NiceMock<MockTransform>(); MaxentCalculator calculator = - MaxentCalculator(std::shared_ptr<MaxentEntropy>(entropy), - std::shared_ptr<MaxentTransform>(transform)); + MaxentCalculator(boost::shared_ptr<MaxentEntropy>(entropy), + boost::shared_ptr<MaxentTransform>(transform)); // Input data // Vector in data space @@ -167,6 +177,8 @@ public: std::vector<double> vec2 = {1, 1, 1, 1, 1, 1, 1, 1}; // Background double bkg = 1; + // No adjustments + std::vector<double> emptyVec = {}; EXPECT_CALL(*entropy, correctValues(vec2, 1)) .Times(1) @@ -180,7 +192,8 @@ public: .Times(1) .WillOnce(Return(vec2)); // This is OK: data.size() = N * image.size() - TS_ASSERT_THROWS_NOTHING(calculator.iterate(vec1, vec1, vec2, bkg)); + TS_ASSERT_THROWS_NOTHING( + calculator.iterate(vec1, vec1, vec2, bkg, emptyVec, emptyVec)); EXPECT_CALL(*entropy, correctValues(vec1, 1)) .Times(1) @@ -192,8 +205,9 @@ public: EXPECT_CALL(*entropy, derivative(_, _)).Times(0); EXPECT_CALL(*entropy, secondDerivative(_, _)).Times(0); // But this is not: N * data.size() = image.size() - TS_ASSERT_THROWS(calculator.iterate(vec2, vec2, vec1, bkg), - std::runtime_error); + TS_ASSERT_THROWS( + calculator.iterate(vec2, vec2, vec1, bkg, emptyVec, emptyVec), + std::runtime_error); Mock::VerifyAndClearExpectations(entropy); Mock::VerifyAndClearExpectations(transform); @@ -204,8 +218,8 @@ public: MockEntropy *entropy = new NiceMock<MockEntropy>(); MockTransform *transform = new NiceMock<MockTransform>(); MaxentCalculator calculator = - MaxentCalculator(std::shared_ptr<MockEntropy>(entropy), - std::shared_ptr<MockTransform>(transform)); + MaxentCalculator(boost::shared_ptr<MockEntropy>(entropy), + boost::shared_ptr<MockTransform>(transform)); // When data were not loaded public methods should throw an exception TS_ASSERT_THROWS(calculator.getReconstructedData(), std::runtime_error); @@ -221,14 +235,16 @@ public: MockEntropy *entropy = new NiceMock<MockEntropy>(); MockTransform *transform = new NiceMock<MockTransform>(); MaxentCalculator calculator = - MaxentCalculator(std::shared_ptr<MaxentEntropy>(entropy), - std::shared_ptr<MaxentTransform>(transform)); + MaxentCalculator(boost::shared_ptr<MaxentEntropy>(entropy), + boost::shared_ptr<MaxentTransform>(transform)); // Input data std::vector<double> dat = {1, 1}; std::vector<double> err = {1, 1}; std::vector<double> img = {0, 0, 0, 0}; double bkg = 1.; + // No adjustments + std::vector<double> emptyVec = {}; // Calc data std::vector<double> datC = {0, 0}; @@ -244,7 +260,8 @@ public: .Times(1) .WillOnce(Return(img)); - TS_ASSERT_THROWS_NOTHING(calculator.iterate(dat, err, img, bkg)); + TS_ASSERT_THROWS_NOTHING( + calculator.iterate(dat, err, img, bkg, emptyVec, emptyVec)); TS_ASSERT_DELTA(calculator.getChisq(), 1, 1e-8); TS_ASSERT_DELTA(calculator.getAngle(), 0.7071, 1e-4); @@ -257,14 +274,16 @@ public: MockEntropy *entropy = new NiceMock<MockEntropy>(); MockTransform *transform = new NiceMock<MockTransform>(); MaxentCalculator calculator = - MaxentCalculator(std::shared_ptr<MaxentEntropy>(entropy), - std::shared_ptr<MaxentTransform>(transform)); + MaxentCalculator(boost::shared_ptr<MaxentEntropy>(entropy), + boost::shared_ptr<MaxentTransform>(transform)); // Input data std::vector<double> dat = {1, 1}; std::vector<double> err = {1, 1}; std::vector<double> img = {1, 1, 1, 1}; double bkg = 1.; + // No adjustments + std::vector<double> emptyVec = {}; // Calc data std::vector<double> datC = {0, 0}; @@ -280,7 +299,8 @@ public: .Times(1) .WillOnce(Return(img)); - TS_ASSERT_THROWS_NOTHING(calculator.iterate(dat, err, img, bkg)); + TS_ASSERT_THROWS_NOTHING( + calculator.iterate(dat, err, img, bkg, emptyVec, emptyVec)); auto dirs = calculator.getSearchDirections(); TS_ASSERT_EQUALS(dirs[0].size(), 4); diff --git a/Framework/Algorithms/test/MaxEnt/MaxentTransformFourierTest.h b/Framework/Algorithms/test/MaxEnt/MaxentTransformFourierTest.h index 3a9a79fbc6f658ff350b786cfe40df9e17830d76..595336e525665b650383a2f850b415b420e9465e 100644 --- a/Framework/Algorithms/test/MaxEnt/MaxentTransformFourierTest.h +++ b/Framework/Algorithms/test/MaxEnt/MaxentTransformFourierTest.h @@ -6,19 +6,14 @@ #include "MantidAlgorithms/MaxEnt/MaxentSpaceComplex.h" #include "MantidAlgorithms/MaxEnt/MaxentSpaceReal.h" #include "MantidAlgorithms/MaxEnt/MaxentTransformFourier.h" +#include <boost/make_shared.hpp> #include <cmath> -#include <memory> using Mantid::Algorithms::MaxentSpaceComplex; using Mantid::Algorithms::MaxentSpaceReal; +using Mantid::Algorithms::MaxentSpace_sptr; using Mantid::Algorithms::MaxentTransformFourier; -using MaxentSpace_sptr = std::shared_ptr<Mantid::Algorithms::MaxentSpace>; -using MaxentSpaceComplex_sptr = - std::shared_ptr<Mantid::Algorithms::MaxentSpaceComplex>; -using MaxentSpaceReal_sptr = - std::shared_ptr<Mantid::Algorithms::MaxentSpaceReal>; - class MaxentTransformFourierTest : public CxxTest::TestSuite { public: // This pair of boilerplate methods prevent the suite being created statically @@ -30,8 +25,8 @@ public: void test_real_image_to_real_data() { - MaxentSpace_sptr dataSpace = std::make_shared<MaxentSpaceReal>(); - MaxentSpace_sptr imageSpace = std::make_shared<MaxentSpaceReal>(); + MaxentSpace_sptr dataSpace = boost::make_shared<MaxentSpaceReal>(); + MaxentSpace_sptr imageSpace = boost::make_shared<MaxentSpaceReal>(); MaxentTransformFourier transform(dataSpace, imageSpace); // cos (x) @@ -60,8 +55,8 @@ public: void test_real_image_to_complex_data() { - MaxentSpace_sptr dataSpace = std::make_shared<MaxentSpaceComplex>(); - MaxentSpace_sptr imageSpace = std::make_shared<MaxentSpaceReal>(); + MaxentSpace_sptr dataSpace = boost::make_shared<MaxentSpaceComplex>(); + MaxentSpace_sptr imageSpace = boost::make_shared<MaxentSpaceReal>(); MaxentTransformFourier transform(dataSpace, imageSpace); // cos (x) @@ -90,8 +85,8 @@ public: void test_complex_image_to_real_data() { - MaxentSpace_sptr dataSpace = std::make_shared<MaxentSpaceReal>(); - MaxentSpace_sptr imageSpace = std::make_shared<MaxentSpaceComplex>(); + MaxentSpace_sptr dataSpace = boost::make_shared<MaxentSpaceReal>(); + MaxentSpace_sptr imageSpace = boost::make_shared<MaxentSpaceComplex>(); MaxentTransformFourier transform(dataSpace, imageSpace); // cos (x) + i sin(x) @@ -155,8 +150,8 @@ public: void test_complex_image_to_complex_data() { - MaxentSpace_sptr dataSpace = std::make_shared<MaxentSpaceComplex>(); - MaxentSpace_sptr imageSpace = std::make_shared<MaxentSpaceComplex>(); + MaxentSpace_sptr dataSpace = boost::make_shared<MaxentSpaceComplex>(); + MaxentSpace_sptr imageSpace = boost::make_shared<MaxentSpaceComplex>(); MaxentTransformFourier transform(dataSpace, imageSpace); // sin (x) + i cos(x) @@ -220,8 +215,8 @@ public: void test_real_data_to_real_image() { - MaxentSpace_sptr dataSpace = std::make_shared<MaxentSpaceReal>(); - MaxentSpace_sptr imageSpace = std::make_shared<MaxentSpaceReal>(); + MaxentSpace_sptr dataSpace = boost::make_shared<MaxentSpaceReal>(); + MaxentSpace_sptr imageSpace = boost::make_shared<MaxentSpaceReal>(); MaxentTransformFourier transform(dataSpace, imageSpace); // cos(x) @@ -250,8 +245,8 @@ public: void test_real_data_to_complex_image() { - MaxentSpace_sptr dataSpace = std::make_shared<MaxentSpaceReal>(); - MaxentSpace_sptr imageSpace = std::make_shared<MaxentSpaceComplex>(); + MaxentSpace_sptr dataSpace = boost::make_shared<MaxentSpaceReal>(); + MaxentSpace_sptr imageSpace = boost::make_shared<MaxentSpaceComplex>(); MaxentTransformFourier transform(dataSpace, imageSpace); // cos (x) @@ -280,8 +275,8 @@ public: void test_complex_data_to_real_image() { - MaxentSpace_sptr dataSpace = std::make_shared<MaxentSpaceComplex>(); - MaxentSpace_sptr imageSpace = std::make_shared<MaxentSpaceReal>(); + MaxentSpace_sptr dataSpace = boost::make_shared<MaxentSpaceComplex>(); + MaxentSpace_sptr imageSpace = boost::make_shared<MaxentSpaceReal>(); MaxentTransformFourier transform(dataSpace, imageSpace); // cos (x) + i sin(x) @@ -344,8 +339,8 @@ public: } void test_complex_data_to_complex_image() { - MaxentSpace_sptr dataSpace = std::make_shared<MaxentSpaceComplex>(); - MaxentSpace_sptr imageSpace = std::make_shared<MaxentSpaceComplex>(); + MaxentSpace_sptr dataSpace = boost::make_shared<MaxentSpaceComplex>(); + MaxentSpace_sptr imageSpace = boost::make_shared<MaxentSpaceComplex>(); MaxentTransformFourier transform(dataSpace, imageSpace); // sin (x) + i cos(x) @@ -409,8 +404,8 @@ public: void test_forward_backward() { - MaxentSpace_sptr dataSpace = std::make_shared<MaxentSpaceComplex>(); - MaxentSpace_sptr imageSpace = std::make_shared<MaxentSpaceComplex>(); + MaxentSpace_sptr dataSpace = boost::make_shared<MaxentSpaceComplex>(); + MaxentSpace_sptr imageSpace = boost::make_shared<MaxentSpaceComplex>(); MaxentTransformFourier transform(dataSpace, imageSpace); // sin (x) + i cos(x) diff --git a/Framework/Algorithms/test/MaxEnt/MaxentTransformMultiFourierTest.h b/Framework/Algorithms/test/MaxEnt/MaxentTransformMultiFourierTest.h new file mode 100644 index 0000000000000000000000000000000000000000..bc2014edf28fe1f3fb0c8746d35122799179c41a --- /dev/null +++ b/Framework/Algorithms/test/MaxEnt/MaxentTransformMultiFourierTest.h @@ -0,0 +1,234 @@ +#ifndef MANTID_ALGORITHMS_MAXENTTRANSFORMMULTIFOURIERTEST_H_ +#define MANTID_ALGORITHMS_MAXENTTRANSFORMMULTIFOURIERTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidAlgorithms/MaxEnt/MaxentSpaceComplex.h" +#include "MantidAlgorithms/MaxEnt/MaxentSpaceReal.h" +#include "MantidAlgorithms/MaxEnt/MaxentTransformMultiFourier.h" +#include <boost/make_shared.hpp> +#include <boost/shared_ptr.hpp> +#include <cmath> + +using Mantid::Algorithms::MaxentSpaceComplex; +using Mantid::Algorithms::MaxentSpaceComplex_sptr; +using Mantid::Algorithms::MaxentSpaceReal; +using Mantid::Algorithms::MaxentSpace_sptr; +using Mantid::Algorithms::MaxentTransformFourier; +using Mantid::Algorithms::MaxentTransformMultiFourier; + +class MaxentTransformMultiFourierTest : 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 MaxentTransformMultiFourierTest *createSuite() { + return new MaxentTransformMultiFourierTest(); + } + static void destroySuite(MaxentTransformMultiFourierTest *suite) { + delete suite; + } + + void test_complex_data_to_real_image_against_fourier() { + + MaxentSpaceComplex_sptr dataSpaceMF = + boost::make_shared<MaxentSpaceComplex>(); + MaxentSpace_sptr imageSpaceMF = boost::make_shared<MaxentSpaceReal>(); + MaxentTransformMultiFourier transformMF(dataSpaceMF, imageSpaceMF, 3); + MaxentSpace_sptr dataSpaceF = boost::make_shared<MaxentSpaceComplex>(); + MaxentSpace_sptr imageSpaceF = boost::make_shared<MaxentSpaceReal>(); + MaxentTransformFourier transformF(dataSpaceF, imageSpaceF); + + // Three square waves that add up to a saw tooth wave + std::vector<double> realDataMF = {1, -1, 1, -1, 1, -1, 1, -1, + 2, 2, -2, -2, 2, 2, -2, -2, + 4, 4, 4, 4, -4, -4, -4, -4}; + std::vector<double> realDataF = {7, 5, 3, 1, -1, -3, -5, -7}; + + // Perform the transformation + auto result = transformMF.dataToImage(realDataMF); + // Perform Fourier transformation for comparison + auto resultF = transformF.dataToImage(realDataF); + + // Check both results are equal + TS_ASSERT_EQUALS(result.size(), resultF.size()); + if (result.size() == resultF.size()) { + for (size_t i = 0; i < result.size(); i++) { + TS_ASSERT_DELTA(result[i], resultF[i], 1e-4); + } + } + } + + void test_complex_data_to_complex_image_against_fourier() { + + MaxentSpaceComplex_sptr dataSpaceMF = + boost::make_shared<MaxentSpaceComplex>(); + MaxentSpace_sptr imageSpaceMF = boost::make_shared<MaxentSpaceComplex>(); + MaxentTransformMultiFourier transformMF(dataSpaceMF, imageSpaceMF, 3); + MaxentSpace_sptr dataSpaceF = boost::make_shared<MaxentSpaceComplex>(); + MaxentSpace_sptr imageSpaceF = boost::make_shared<MaxentSpaceComplex>(); + MaxentTransformFourier transformF(dataSpaceF, imageSpaceF); + + std::vector<double> realDataMF = {1, -1, 1, -1, 1, -1, 1, -1, + 2, 2, -2, -2, 2, 2, -2, -2, + 4, 4, 4, 4, -4, -4, -4, -4}; + std::vector<double> realDataF = {7, 5, 3, 1, -1, -3, -5, -7}; + + // Perform the transformation + auto result = transformMF.dataToImage(realDataMF); + // Perform Fourier transformation for comparison + auto resultF = transformF.dataToImage(realDataF); + + // Check both results are equal + TS_ASSERT_EQUALS(result.size(), resultF.size()); + if (result.size() == resultF.size()) { + for (size_t i = 0; i < result.size(); i++) { + TS_ASSERT_DELTA(result[i], resultF[i], 1e-4); + } + } + } + + void test_image_to_data_repeats_fourier() { + MaxentSpaceComplex_sptr dataSpaceMF = + boost::make_shared<MaxentSpaceComplex>(); + MaxentSpace_sptr imageSpaceMF = boost::make_shared<MaxentSpaceComplex>(); + MaxentTransformMultiFourier transformMF(dataSpaceMF, imageSpaceMF, 3); + MaxentSpace_sptr dataSpaceF = boost::make_shared<MaxentSpaceComplex>(); + MaxentSpace_sptr imageSpaceF = boost::make_shared<MaxentSpaceComplex>(); + MaxentTransformFourier transformF(dataSpaceF, imageSpaceF); + + std::vector<double> complexImage = {4.0, 3.0, 2.0, 1.0, 0.0, 0.0, 0.0, 0.0}; + + // Perform the transformation + auto result = transformMF.imageToData(complexImage); + // Perform Fourier transformation for comparison + auto resultF = transformF.imageToData(complexImage); + + // Check that result is a triple repetition of fourier + TS_ASSERT_EQUALS(result.size(), 3 * resultF.size()); + if (result.size() == 3 * resultF.size()) { + size_t n = resultF.size(); + for (size_t i = 0; i < n; i++) { + TS_ASSERT_DELTA(result[i], resultF[i], 1e-4); + TS_ASSERT_DELTA(result[i + n], resultF[i], 1e-4); + TS_ASSERT_DELTA(result[i + 2 * n], resultF[i], 1e-4); + } + } + } + + void test_image_to_data_with_real_adjustments() { + MaxentSpaceComplex_sptr dataSpaceMF = + boost::make_shared<MaxentSpaceComplex>(); + MaxentSpace_sptr imageSpaceMF = boost::make_shared<MaxentSpaceComplex>(); + MaxentTransformMultiFourier transformMF(dataSpaceMF, imageSpaceMF, 3); + MaxentSpace_sptr dataSpaceF = boost::make_shared<MaxentSpaceComplex>(); + MaxentSpace_sptr imageSpaceF = boost::make_shared<MaxentSpaceComplex>(); + MaxentTransformFourier transformF(dataSpaceF, imageSpaceF); + + std::vector<double> complexImage = {4.0, 3.0, 2.0, 1.0, 0.0, 0.0, 0.0, 0.0}; + std::vector<double> linearAdjustments = { + 1.0, 0.0, 2.0, 0.0, 3.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 2.0, 0.0, 3.0, 0.0, 4.0, 0.0}; + std::vector<double> constAdjustments = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 2.0, 0.0, + 3.0, 0.0, 4.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0}; + + // Set Adjustments + transformMF.setAdjustments(linearAdjustments, constAdjustments); + + // Perform the transformation + auto result = transformMF.imageToData(complexImage); + // Perform Fourier transformation for comparison + auto resultF = transformF.imageToData(complexImage); + + // Check that result is a triple repetition of fourier + // but with the adjustments applied + TS_ASSERT_EQUALS(result.size(), 3 * resultF.size()); + TS_ASSERT_EQUALS(result.size(), linearAdjustments.size()); + TS_ASSERT_EQUALS(result.size(), constAdjustments.size()); + + if (result.size() == 3 * resultF.size()) { + size_t n = resultF.size(); + for (size_t i = 0; i < n; i++) { + TS_ASSERT_DELTA(result[i], + linearAdjustments[i - i % 2] * resultF[i] + + constAdjustments[i], + 1e-4); + TS_ASSERT_DELTA(result[i + n], + linearAdjustments[i + n - i % 2] * resultF[i] + + constAdjustments[i + n], + 1e-4); + TS_ASSERT_DELTA(result[i + 2 * n], + linearAdjustments[i + 2 * n - i % 2] * resultF[i] + + constAdjustments[i + 2 * n], + 1e-4); + } + } + } + + void test_image_to_data_with_imaginary_adjustments() { + MaxentSpaceComplex_sptr dataSpaceMF = + boost::make_shared<MaxentSpaceComplex>(); + MaxentSpace_sptr imageSpaceMF = boost::make_shared<MaxentSpaceComplex>(); + MaxentTransformMultiFourier transformMF(dataSpaceMF, imageSpaceMF, 3); + MaxentSpace_sptr dataSpaceF = boost::make_shared<MaxentSpaceComplex>(); + MaxentSpace_sptr imageSpaceF = boost::make_shared<MaxentSpaceComplex>(); + MaxentTransformFourier transformF(dataSpaceF, imageSpaceF); + + std::vector<double> complexImage = {4.0, 3.0, 2.0, 1.0, 0.0, 0.0, 0.0, 0.0}; + std::vector<double> linearAdjustments = { + 0.0, 1.0, 0.0, 2.0, 0.0, 3.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 2.0, 0.0, 3.0, 0.0, 4.0}; + std::vector<double> constAdjustments = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 2.0, + 0.0, 3.0, 0.0, 4.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0}; + + // Set Adjustments + transformMF.setAdjustments(linearAdjustments, constAdjustments); + + // Perform the transformation + auto result = transformMF.imageToData(complexImage); + // Perform Fourier transformation for comparison + auto resultF = transformF.imageToData(complexImage); + + // Check that result is a triple repetition of fourier + // but with the adjustments applied + TS_ASSERT_EQUALS(result.size(), 3 * resultF.size()); + TS_ASSERT_EQUALS(result.size(), linearAdjustments.size()); + TS_ASSERT_EQUALS(result.size(), constAdjustments.size()); + + if (result.size() == 3 * resultF.size()) { + size_t n = resultF.size(); + for (size_t i = 0; i < n; i++) { + if (i % 2 == 0) { // Real part + TS_ASSERT_DELTA(result[i], + -linearAdjustments[i + 1] * resultF[i + 1] + + constAdjustments[i], + 1e-4); + TS_ASSERT_DELTA(result[i + n], + -linearAdjustments[i + n + 1] * resultF[i + 1] + + constAdjustments[i + n], + 1e-4); + TS_ASSERT_DELTA(result[i + 2 * n], + -linearAdjustments[i + 2 * n + 1] * resultF[i + 1] + + constAdjustments[i + 2 * n], + 1e-4); + } else { // Imaginary part + TS_ASSERT_DELTA(result[i], + linearAdjustments[i] * resultF[i - 1] + + constAdjustments[i], + 1e-4); + TS_ASSERT_DELTA(result[i + n], + linearAdjustments[i + n] * resultF[i - 1] + + constAdjustments[i + n], + 1e-4); + TS_ASSERT_DELTA(result[i + 2 * n], + linearAdjustments[i + 2 * n] * resultF[i - 1] + + constAdjustments[i + 2 * n], + 1e-4); + } + } + } + } +}; + +#endif /* MANTID_ALGORITHMS_MAXENTTRANSFORMMULTIFOURIERTEST_H_ */ \ No newline at end of file diff --git a/Framework/Algorithms/test/MaxEntTest.h b/Framework/Algorithms/test/MaxEntTest.h index 0d808f8b70ae7138f61fabbd5af36f8d9f995b03..bd0a05adbb6ece3107bac0124f3b795e91d72ada 100644 --- a/Framework/Algorithms/test/MaxEntTest.h +++ b/Framework/Algorithms/test/MaxEntTest.h @@ -41,7 +41,7 @@ public: TS_ASSERT(alg->isInitialized()) } - void test_real_data() { + void test_sizes_for_real_data() { // Run one iteration, we just want to test the output workspaces' dimensions int nHist = 5; int nBins = 10; @@ -75,7 +75,7 @@ public: TS_ASSERT_EQUALS(angle->blocksize(), 1); } - void test_complex_data() { + void test_sizes_for_complex_data() { // Run one iteration, we just want to test the output workspaces' dimensions int nHist = 6; int nBins = 10; @@ -110,6 +110,80 @@ public: TS_ASSERT_EQUALS(angle->blocksize(), 1); } + void test_sizes_for_complex_data_adjustments() { + // Run one iteration, we just want to test the output workspaces' dimensions + int nHist = 6; + int nBins = 10; + auto ws = WorkspaceCreationHelper::create2DWorkspace(nHist, nBins); + + IAlgorithm_sptr alg = AlgorithmManager::Instance().create("MaxEnt"); + alg->initialize(); + alg->setChild(true); + alg->setProperty("InputWorkspace", ws); + alg->setProperty("ComplexData", true); + alg->setPropertyValue("MaxIterations", "1"); + alg->setProperty("DataLinearAdj", ws); + alg->setProperty("DataConstAdj", ws); + alg->setPropertyValue("ReconstructedImage", "image"); + alg->setPropertyValue("ReconstructedData", "data"); + alg->setPropertyValue("EvolChi", "evolChi"); + alg->setPropertyValue("EvolAngle", "evolAngle"); + + TS_ASSERT_THROWS_NOTHING(alg->execute()); + + MatrixWorkspace_sptr data = alg->getProperty("ReconstructedData"); + MatrixWorkspace_sptr image = alg->getProperty("ReconstructedImage"); + MatrixWorkspace_sptr chi = alg->getProperty("EvolChi"); + MatrixWorkspace_sptr angle = alg->getProperty("EvolAngle"); + + TS_ASSERT_EQUALS(data->getNumberHistograms(), nHist); + TS_ASSERT_EQUALS(image->getNumberHistograms(), nHist); + TS_ASSERT_EQUALS(chi->getNumberHistograms(), nHist / 2); + TS_ASSERT_EQUALS(angle->getNumberHistograms(), nHist / 2); + + TS_ASSERT_EQUALS(data->blocksize(), nBins); + TS_ASSERT_EQUALS(image->blocksize(), nBins); + TS_ASSERT_EQUALS(chi->blocksize(), 1); + TS_ASSERT_EQUALS(angle->blocksize(), 1); + } + + void test_sizes_for_complex_data_adjustments_together() { + int nHist = 6; + int nBins = 10; + auto ws = WorkspaceCreationHelper::create2DWorkspace(nHist, nBins); + + IAlgorithm_sptr alg = AlgorithmManager::Instance().create("MaxEnt"); + alg->initialize(); + alg->setChild(true); + alg->setProperty("InputWorkspace", ws); + alg->setProperty("ComplexData", true); + alg->setPropertyValue("MaxIterations", "1"); + alg->setProperty("DataLinearAdj", ws); + alg->setProperty("DataConstAdj", ws); + alg->setProperty("PerSpectrumReconstruction", false); + alg->setPropertyValue("ReconstructedImage", "image"); + alg->setPropertyValue("ReconstructedData", "data"); + alg->setPropertyValue("EvolChi", "evolChi"); + alg->setPropertyValue("EvolAngle", "evolAngle"); + + TS_ASSERT_THROWS_NOTHING(alg->execute()); + + MatrixWorkspace_sptr data = alg->getProperty("ReconstructedData"); + MatrixWorkspace_sptr image = alg->getProperty("ReconstructedImage"); + MatrixWorkspace_sptr chi = alg->getProperty("EvolChi"); + MatrixWorkspace_sptr angle = alg->getProperty("EvolAngle"); + + TS_ASSERT_EQUALS(data->getNumberHistograms(), nHist); + TS_ASSERT_EQUALS(image->getNumberHistograms(), 2); + TS_ASSERT_EQUALS(chi->getNumberHistograms(), 1); + TS_ASSERT_EQUALS(angle->getNumberHistograms(), 1); + + TS_ASSERT_EQUALS(data->blocksize(), nBins); + TS_ASSERT_EQUALS(image->blocksize(), nBins); + TS_ASSERT_EQUALS(chi->blocksize(), 1); + TS_ASSERT_EQUALS(angle->blocksize(), 1); + } + void test_bad_complex_data() { auto ws = WorkspaceCreationHelper::create2DWorkspace(5, 10); @@ -125,12 +199,193 @@ public: alg->setPropertyValue("EvolChi", "evolChi"); alg->setPropertyValue("EvolAngle", "evolAngle"); - TS_ASSERT_THROWS_ANYTHING(alg->execute()); + TS_ASSERT_THROWS(alg->execute(), std::runtime_error); + } + + void test_bad_linear_adjustment() { + + auto ws = WorkspaceCreationHelper::create2DWorkspace(5, 10); + + IAlgorithm_sptr alg = AlgorithmManager::Instance().create("MaxEnt"); + alg->initialize(); + alg->setChild(true); + alg->setProperty("InputWorkspace", ws); + alg->setProperty("ComplexData", false); + alg->setPropertyValue("MaxIterations", "1"); + alg->setProperty("DataLinearAdj", ws); + alg->setPropertyValue("ReconstructedImage", "image"); + alg->setPropertyValue("ReconstructedData", "data"); + alg->setPropertyValue("EvolChi", "evolChi"); + alg->setPropertyValue("EvolAngle", "evolAngle"); + + TS_ASSERT_THROWS(alg->execute(), std::runtime_error); + } + + void test_bad_const_adjustment() { + + auto ws = WorkspaceCreationHelper::create2DWorkspace(5, 10); + + IAlgorithm_sptr alg = AlgorithmManager::Instance().create("MaxEnt"); + alg->initialize(); + alg->setChild(true); + alg->setProperty("InputWorkspace", ws); + alg->setProperty("ComplexData", false); + alg->setPropertyValue("MaxIterations", "1"); + alg->setProperty("DataConstAdj", ws); + alg->setPropertyValue("ReconstructedImage", "image"); + alg->setPropertyValue("ReconstructedData", "data"); + alg->setPropertyValue("EvolChi", "evolChi"); + alg->setPropertyValue("EvolAngle", "evolAngle"); + + TS_ASSERT_THROWS(alg->execute(), std::runtime_error); + } + + void test_linear_adjustment_with_too_few_spectra() { + + auto ws = WorkspaceCreationHelper::create2DWorkspace(6, 10); + + IAlgorithm_sptr alg = AlgorithmManager::Instance().create("MaxEnt"); + alg->initialize(); + alg->setChild(true); + alg->setProperty("InputWorkspace", ws); + alg->setProperty("ComplexData", false); + alg->setPropertyValue("MaxIterations", "1"); + alg->setProperty("DataLinearAdj", ws); // We need twice as many histograms + alg->setPropertyValue("ReconstructedImage", "image"); + alg->setPropertyValue("ReconstructedData", "data"); + alg->setPropertyValue("EvolChi", "evolChi"); + alg->setPropertyValue("EvolAngle", "evolAngle"); + + TS_ASSERT_THROWS(alg->execute(), std::runtime_error); + } + + void test_const_adjustment_with_too_few_spectra() { + + auto ws = WorkspaceCreationHelper::create2DWorkspace(6, 10); + + IAlgorithm_sptr alg = AlgorithmManager::Instance().create("MaxEnt"); + alg->initialize(); + alg->setChild(true); + alg->setProperty("InputWorkspace", ws); + alg->setProperty("ComplexData", false); + alg->setPropertyValue("MaxIterations", "1"); + alg->setProperty("DataConstAdj", ws); // We need twice as many histograms + alg->setPropertyValue("ReconstructedImage", "image"); + alg->setPropertyValue("ReconstructedData", "data"); + alg->setPropertyValue("EvolChi", "evolChi"); + alg->setPropertyValue("EvolAngle", "evolAngle"); + + TS_ASSERT_THROWS(alg->execute(), std::runtime_error); + } + + void test_adjustments_together_too_few_spectra() { + + auto ws = WorkspaceCreationHelper::create2DWorkspace(6, 10); + auto ws1 = WorkspaceCreationHelper::create2DWorkspace(2, 10); + + IAlgorithm_sptr alg = AlgorithmManager::Instance().create("MaxEnt"); + alg->initialize(); + alg->setChild(true); + alg->setProperty("InputWorkspace", ws); + alg->setProperty("ComplexData", true); + alg->setPropertyValue("MaxIterations", "1"); + // We need as many spectra in the adjustments as + // in the input workspace even though images are summed. + alg->setProperty("DataLinearAdj", ws1); + alg->setProperty("DataConstAdj", ws1); + alg->setProperty("perSpectrumReconstruction", false); + alg->setPropertyValue("ReconstructedImage", "image"); + alg->setPropertyValue("ReconstructedData", "data"); + alg->setPropertyValue("EvolChi", "evolChi"); + alg->setPropertyValue("EvolAngle", "evolAngle"); + + TS_ASSERT_THROWS(alg->execute(), std::runtime_error); + } + + void test_adjustments_together_real_data_not_supported() { + + auto ws = WorkspaceCreationHelper::create2DWorkspace(3, 10); + auto ws1 = WorkspaceCreationHelper::create2DWorkspace(6, 10); + + IAlgorithm_sptr alg = AlgorithmManager::Instance().create("MaxEnt"); + alg->initialize(); + alg->setChild(true); + alg->setProperty("InputWorkspace", ws); + alg->setPropertyValue("MaxIterations", "1"); + alg->setProperty("DataLinearAdj", ws1); + alg->setProperty("DataConstAdj", ws1); + // Complex data needed for this + alg->setProperty("perSpectrumReconstruction", false); + alg->setPropertyValue("ReconstructedImage", "image"); + alg->setPropertyValue("ReconstructedData", "data"); + alg->setPropertyValue("EvolChi", "evolChi"); + alg->setPropertyValue("EvolAngle", "evolAngle"); + + TS_ASSERT_THROWS(alg->execute(), std::invalid_argument); + } + + void test_adjustment_arithmetic() { + // Workspace has two spectra of three values all 3+3i + std::vector<double> wsVal(12, 3.0); + auto ws = createWorkspaceWithYValues(4, 3, wsVal); + + // First spectrum has no adjustments + // Second spectrum has mixed adjustments + + // Linear adjustments 2nd spectrum + // 1, 2i, 2i + std::vector<double> linAdjVal(12, 0.0); + linAdjVal[0] = 1.0; + linAdjVal[1] = 1.0; + linAdjVal[2] = 1.0; + linAdjVal[3] = 1.0; + linAdjVal[10] = 2.0; + linAdjVal[11] = 2.0; + auto linAdj = createWorkspaceWithYValues(4, 3, linAdjVal); + + // Const adjustments 2nd spectrum + // 1-i, 0, 1-i + std::vector<double> constAdjVal(12, 0.0); + constAdjVal[3] = 1.0; + constAdjVal[9] = -1.0; + constAdjVal[5] = 1.0; + constAdjVal[11] = -1.0; + auto constAdj = createWorkspaceWithYValues(4, 3, constAdjVal); + + IAlgorithm_sptr alg = AlgorithmManager::Instance().create("MaxEnt"); + alg->initialize(); + alg->setChild(true); + alg->setProperty("InputWorkspace", ws); + alg->setProperty("ComplexData", true); + alg->setPropertyValue("MaxIterations", "1"); + alg->setProperty("DataLinearAdj", linAdj); + alg->setProperty("DataConstAdj", constAdj); + alg->setProperty("perSpectrumReconstruction", false); + alg->setPropertyValue("ReconstructedImage", "image"); + alg->setPropertyValue("ReconstructedData", "data"); + alg->setPropertyValue("EvolChi", "evolChi"); + alg->setPropertyValue("EvolAngle", "evolAngle"); + + TS_ASSERT_THROWS_NOTHING(alg->execute()); + + MatrixWorkspace_sptr data = alg->getProperty("ReconstructedData"); + TS_ASSERT(data); + + // Compare adjusted second spectrum with non-adjust first spectrum + // linear 1, const 1-i + TS_ASSERT_DELTA(data->y(1)[0], data->y(0)[0] + 1.0, 0.001); + TS_ASSERT_DELTA(data->y(3)[0], data->y(2)[0] - 1.0, 0.001); + // linear 2i, const 0 + TS_ASSERT_DELTA(data->y(1)[1], -2.0 * data->y(2)[1], 0.001); + TS_ASSERT_DELTA(data->y(3)[1], 2.0 * data->y(0)[1], 0.001); + // linear 2i, const 1-i + TS_ASSERT_DELTA(data->y(1)[2], -2.0 * data->y(2)[2] + 1.0, 0.001); + TS_ASSERT_DELTA(data->y(3)[2], 2.0 * data->y(0)[2] - 1.0, 0.001); } void test_cosine() { - auto ws = createWorkspaceReal(50, 0.0); + auto ws = createWorkspaceReal(50, 0.0, 1); IAlgorithm_sptr alg = AlgorithmManager::Instance().create("MaxEnt"); alg->initialize(); @@ -167,7 +422,7 @@ public: void test_sine() { - auto ws = createWorkspaceReal(50, M_PI / 2.); + auto ws = createWorkspaceReal(50, M_PI / 2.0, 1); IAlgorithm_sptr alg = AlgorithmManager::Instance().create("MaxEnt"); alg->initialize(); @@ -201,6 +456,51 @@ public: // seg faults after these tests..... } + void test_cosine_three_spectra() { + + auto ws = createWorkspaceReal(10, 0.0, 3); + + IAlgorithm_sptr alg = AlgorithmManager::Instance().create("MaxEnt"); + alg->initialize(); + alg->setChild(true); + alg->setProperty("InputWorkspace", ws); + alg->setProperty("A", 0.01); + alg->setPropertyValue("ReconstructedImage", "image"); + alg->setPropertyValue("ReconstructedData", "data"); + alg->setPropertyValue("EvolChi", "evolChi"); + alg->setPropertyValue("EvolAngle", "evolAngle"); + + TS_ASSERT_THROWS_NOTHING(alg->execute()); + + MatrixWorkspace_sptr data = alg->getProperty("ReconstructedData"); + MatrixWorkspace_sptr image = alg->getProperty("ReconstructedImage"); + MatrixWorkspace_sptr chi = alg->getProperty("EvolChi"); + MatrixWorkspace_sptr angle = alg->getProperty("EvolAngle"); + + TS_ASSERT(data); + TS_ASSERT(image); + TS_ASSERT(chi); + TS_ASSERT(angle); + + // Test some values + TS_ASSERT_EQUALS(data->y(0).size(), 10); + TS_ASSERT_EQUALS(data->y(1).size(), 10); + TS_ASSERT_EQUALS(data->y(2).size(), 10); + TS_ASSERT_EQUALS(data->y(5).size(), 10); + TS_ASSERT_DELTA(data->y(0)[5], 0.261, 0.001); + TS_ASSERT_DELTA(data->y(1)[5], 0.665, 0.001); + TS_ASSERT_DELTA(data->y(2)[5], 0.898, 0.001); + TS_ASSERT_DELTA(data->y(5)[5], 0.000, 0.001); + + // Test that the algorithm converged + TS_ASSERT_DELTA(chi->y(0).back(), 1.000, 0.001); + TS_ASSERT_DELTA(angle->y(0).back(), 0.001, 0.001); + TS_ASSERT_DELTA(chi->y(1).back(), 1.000, 0.001); + TS_ASSERT_DELTA(angle->y(1).back(), 0.001, 0.001); + TS_ASSERT_DELTA(chi->y(2).back(), 1.000, 0.001); + TS_ASSERT_DELTA(angle->y(2).back(), 0.001, 0.001); + } + void test_sine_cosine_neg() { // Complex signal: cos(w * x) + i sin(w * x) // PosNeg images @@ -302,7 +602,7 @@ public: size_t npoints = 50; - auto ws = createWorkspaceReal(npoints, 0.0); + auto ws = createWorkspaceReal(npoints, 0.0, 1); IAlgorithm_sptr alg = AlgorithmManager::Instance().create("MaxEnt"); alg->initialize(); @@ -338,12 +638,278 @@ public: TS_ASSERT_DELTA(image->y(1)[79], 0.448, 0.001); } + void test_adjustments() { + + auto ws = createWorkspaceReal(20, 0.0, 1); + auto linAdj = createWorkspaceAdjustments(20, 1.05, 0.00, 0.0, 1); + auto constAdj = createWorkspaceAdjustments(20, 0.0, 0.1, 0.2, 1); + + IAlgorithm_sptr alg = AlgorithmManager::Instance().create("MaxEnt"); + alg->initialize(); + alg->setChild(true); + alg->setProperty("InputWorkspace", ws); + alg->setProperty("A", 0.01); + alg->setProperty("DataLinearAdj", linAdj); + alg->setProperty("DataConstAdj", constAdj); + alg->setPropertyValue("ReconstructedImage", "image"); + alg->setPropertyValue("ReconstructedData", "data"); + alg->setPropertyValue("EvolChi", "evolChi"); + alg->setPropertyValue("EvolAngle", "evolAngle"); + + TS_ASSERT_THROWS_NOTHING(alg->execute()); + + MatrixWorkspace_sptr data = alg->getProperty("ReconstructedData"); + MatrixWorkspace_sptr image = alg->getProperty("ReconstructedImage"); + MatrixWorkspace_sptr chi = alg->getProperty("EvolChi"); + MatrixWorkspace_sptr angle = alg->getProperty("EvolAngle"); + + TS_ASSERT(data); + TS_ASSERT(image); + TS_ASSERT(chi); + TS_ASSERT(angle); + + // Test some values + TS_ASSERT_EQUALS(data->y(0).size(), 20); + TS_ASSERT_DELTA(data->y(0)[15], 0.245, 0.001); + TS_ASSERT_DELTA(data->y(0)[16], -0.146, 0.001); + TS_ASSERT_DELTA(data->y(0)[17], -0.602, 0.001); + + // Test that the algorithm converged + TS_ASSERT_DELTA(chi->y(0).back(), 1.000, 0.001); + TS_ASSERT_DELTA(angle->y(0).back(), 0.001, 0.001); + } + + void test_adjustments_three_spectra() { + + auto ws = createWorkspaceReal(10, 0.0, 3); + auto linAdj = createWorkspaceAdjustments(10, 1.05, 0.00, 0.0, 3); + auto constAdj = createWorkspaceAdjustments(10, 0.0, 0.1, 0.2, 3); + + IAlgorithm_sptr alg = AlgorithmManager::Instance().create("MaxEnt"); + alg->initialize(); + alg->setChild(true); + alg->setProperty("InputWorkspace", ws); + alg->setProperty("A", 0.01); + alg->setProperty("DataLinearAdj", linAdj); + alg->setProperty("DataConstAdj", constAdj); + alg->setPropertyValue("ReconstructedImage", "image"); + alg->setPropertyValue("ReconstructedData", "data"); + alg->setPropertyValue("EvolChi", "evolChi"); + alg->setPropertyValue("EvolAngle", "evolAngle"); + + TS_ASSERT_THROWS_NOTHING(alg->execute()); + + MatrixWorkspace_sptr data = alg->getProperty("ReconstructedData"); + MatrixWorkspace_sptr image = alg->getProperty("ReconstructedImage"); + MatrixWorkspace_sptr chi = alg->getProperty("EvolChi"); + MatrixWorkspace_sptr angle = alg->getProperty("EvolAngle"); + + TS_ASSERT(data); + TS_ASSERT(image); + TS_ASSERT(chi); + TS_ASSERT(angle); + + // Test some values + TS_ASSERT_EQUALS(data->y(0).size(), 10); + TS_ASSERT_DELTA(data->y(0)[5], 0.237, 0.001); + TS_ASSERT_DELTA(data->y(1)[5], 0.664, 0.001); + TS_ASSERT_DELTA(data->y(2)[5], 0.895, 0.001); + TS_ASSERT_EQUALS(data->y(5).size(), 10); + TS_ASSERT_DELTA(data->y(5)[5], 0.0, 0.001); + + // Test that the algorithm converged + TS_ASSERT_DELTA(chi->y(0).back(), 1.000, 0.001); + TS_ASSERT_DELTA(angle->y(0).back(), 0.001, 0.001); + TS_ASSERT_DELTA(chi->y(1).back(), 1.000, 0.001); + TS_ASSERT_DELTA(angle->y(1).back(), 0.001, 0.001); + TS_ASSERT_DELTA(chi->y(2).back(), 1.000, 0.001); + TS_ASSERT_DELTA(angle->y(2).back(), 0.001, 0.001); + } + + void test_adjustments_three_spectra_complex() { + + auto ws = createWorkspaceComplex(10, 0.0, 3, 0.0); + auto linAdj = createWorkspaceAdjustments(10, 1.05, 0.00, 0.0, 3); + auto constAdj = createWorkspaceAdjustments(10, 0.0, 0.1, 0.2, 3); + + IAlgorithm_sptr alg = AlgorithmManager::Instance().create("MaxEnt"); + alg->initialize(); + alg->setChild(true); + alg->setProperty("InputWorkspace", ws); + alg->setProperty("ComplexData", true); + alg->setProperty("A", 0.01); + alg->setProperty("DataLinearAdj", linAdj); + alg->setProperty("DataConstAdj", constAdj); + alg->setPropertyValue("ReconstructedImage", "image"); + alg->setPropertyValue("ReconstructedData", "data"); + alg->setPropertyValue("EvolChi", "evolChi"); + alg->setPropertyValue("EvolAngle", "evolAngle"); + + TS_ASSERT_THROWS_NOTHING(alg->execute()); + + MatrixWorkspace_sptr data = alg->getProperty("ReconstructedData"); + MatrixWorkspace_sptr image = alg->getProperty("ReconstructedImage"); + MatrixWorkspace_sptr chi = alg->getProperty("EvolChi"); + MatrixWorkspace_sptr angle = alg->getProperty("EvolAngle"); + + TS_ASSERT(data); + TS_ASSERT(image); + TS_ASSERT(chi); + TS_ASSERT(angle); + + // Test some values + TS_ASSERT_EQUALS(data->y(0).size(), 10); + TS_ASSERT_DELTA(data->y(0)[5], -0.720, 0.001); + TS_ASSERT_DELTA(data->y(1)[5], -0.742, 0.001); + TS_ASSERT_DELTA(data->y(2)[5], -0.766, 0.001); + TS_ASSERT_EQUALS(data->y(5).size(), 10); + TS_ASSERT_DELTA(data->y(5)[5], 0.060, 0.001); + + // Test that the algorithm converged + TS_ASSERT_DELTA(chi->y(0).back(), 1.000, 0.001); + TS_ASSERT_DELTA(angle->y(0).back(), 0.001, 0.001); + TS_ASSERT_DELTA(chi->y(1).back(), 1.000, 0.001); + TS_ASSERT_DELTA(angle->y(1).back(), 0.001, 0.001); + TS_ASSERT_DELTA(chi->y(2).back(), 1.000, 0.001); + TS_ASSERT_DELTA(angle->y(2).back(), 0.001, 0.001); + } + + void test_three_spectra_apart() { + + auto ws = createWorkspaceComplex(20, 0.0, 3, 0.0); + + IAlgorithm_sptr alg = AlgorithmManager::Instance().create("MaxEnt"); + alg->initialize(); + alg->setChild(true); + alg->setProperty("InputWorkspace", ws); + alg->setProperty("ComplexData", true); + alg->setProperty("A", 0.01); + alg->setPropertyValue("ReconstructedImage", "image"); + alg->setPropertyValue("ReconstructedData", "data"); + alg->setPropertyValue("EvolChi", "evolChi"); + alg->setPropertyValue("EvolAngle", "evolAngle"); + + TS_ASSERT_THROWS_NOTHING(alg->execute()); + + MatrixWorkspace_sptr data = alg->getProperty("ReconstructedData"); + MatrixWorkspace_sptr image = alg->getProperty("ReconstructedImage"); + MatrixWorkspace_sptr chi = alg->getProperty("EvolChi"); + MatrixWorkspace_sptr angle = alg->getProperty("EvolAngle"); + + TS_ASSERT(data); + TS_ASSERT(image); + TS_ASSERT(chi); + TS_ASSERT(angle); + + // Test some values + TS_ASSERT_EQUALS(data->y(0).size(), 20); + TS_ASSERT_DELTA(data->y(0)[9], -0.422, 0.001); + TS_ASSERT_DELTA(data->y(1)[9], -0.422, 0.001); + TS_ASSERT_DELTA(data->y(2)[9], -0.422, 0.001); + TS_ASSERT_EQUALS(data->y(5).size(), 20); + TS_ASSERT_DELTA(data->y(5)[9], 0.580, 0.001); + + // Test that the algorithm converged + TS_ASSERT_DELTA(chi->y(0).back(), 1.000, 0.001); + TS_ASSERT_DELTA(angle->y(0).back(), 0.001, 0.001); + TS_ASSERT_DELTA(chi->y(1).back(), 1.000, 0.001); + TS_ASSERT_DELTA(angle->y(1).back(), 0.001, 0.001); + TS_ASSERT_DELTA(chi->y(2).back(), 1.000, 0.001); + TS_ASSERT_DELTA(angle->y(2).back(), 0.001, 0.001); + } + + void test_three_spectra_together() { + + auto ws = createWorkspaceComplex(20, 0.0, 3, 0.0); + + IAlgorithm_sptr alg = AlgorithmManager::Instance().create("MaxEnt"); + alg->initialize(); + alg->setChild(true); + alg->setProperty("InputWorkspace", ws); + alg->setProperty("ComplexData", true); + alg->setProperty("A", 0.01); + alg->setProperty("perSpectrumReconstruction", false); + alg->setPropertyValue("ReconstructedImage", "image"); + alg->setPropertyValue("ReconstructedData", "data"); + alg->setPropertyValue("EvolChi", "evolChi"); + alg->setPropertyValue("EvolAngle", "evolAngle"); + + TS_ASSERT_THROWS_NOTHING(alg->execute()); + + MatrixWorkspace_sptr data = alg->getProperty("ReconstructedData"); + MatrixWorkspace_sptr image = alg->getProperty("ReconstructedImage"); + MatrixWorkspace_sptr chi = alg->getProperty("EvolChi"); + MatrixWorkspace_sptr angle = alg->getProperty("EvolAngle"); + + TS_ASSERT(data); + TS_ASSERT(image); + TS_ASSERT(chi); + TS_ASSERT(angle); + + // Test some values + TS_ASSERT_EQUALS(data->y(0).size(), 20); + TS_ASSERT_DELTA(data->y(0)[9], -0.421, 0.001); + TS_ASSERT_DELTA(data->y(1)[9], -0.421, 0.001); + TS_ASSERT_DELTA(data->y(2)[9], -0.421, 0.001); + TS_ASSERT_EQUALS(data->y(5).size(), 20); + TS_ASSERT_DELTA(data->y(5)[9], 0.580, 0.001); + + // Test that the algorithm converged + TS_ASSERT_DELTA(chi->y(0).back(), 1.000, 0.001); + TS_ASSERT_DELTA(angle->y(0).back(), 0.001, 0.001); + } + + void test_adjustments_three_spectra_together() { + + auto ws = createWorkspaceComplex(20, 0.0, 3, 0.0); + auto linAdj = createWorkspaceAdjustments(20, 1.00, 0.05, 0.0, 3); + auto constAdj = createWorkspaceAdjustments(20, 0.0, 0.10, 0.0, 3); + + IAlgorithm_sptr alg = AlgorithmManager::Instance().create("MaxEnt"); + alg->initialize(); + alg->setChild(true); + alg->setProperty("InputWorkspace", ws); + alg->setProperty("ComplexData", true); + alg->setProperty("A", 0.01); + alg->setProperty("DataLinearAdj", linAdj); + alg->setProperty("DataConstAdj", constAdj); + alg->setProperty("perSpectrumReconstruction", false); + alg->setPropertyValue("ReconstructedImage", "image"); + alg->setPropertyValue("ReconstructedData", "data"); + alg->setPropertyValue("EvolChi", "evolChi"); + alg->setPropertyValue("EvolAngle", "evolAngle"); + + TS_ASSERT_THROWS_NOTHING(alg->execute()); + + MatrixWorkspace_sptr data = alg->getProperty("ReconstructedData"); + MatrixWorkspace_sptr image = alg->getProperty("ReconstructedImage"); + MatrixWorkspace_sptr chi = alg->getProperty("EvolChi"); + MatrixWorkspace_sptr angle = alg->getProperty("EvolAngle"); + + TS_ASSERT(data); + TS_ASSERT(image); + TS_ASSERT(chi); + TS_ASSERT(angle); + + // Test some values + TS_ASSERT_EQUALS(data->y(0).size(), 20); + TS_ASSERT_DELTA(data->y(0)[9], -0.370, 0.001); + TS_ASSERT_DELTA(data->y(1)[9], -0.407, 0.001); + TS_ASSERT_DELTA(data->y(2)[9], -0.449, 0.001); + TS_ASSERT_EQUALS(data->y(5).size(), 20); + TS_ASSERT_DELTA(data->y(5)[9], 0.665, 0.001); + + // Test that the algorithm converged + TS_ASSERT_DELTA(chi->y(0).back(), 1.000, 0.001); + TS_ASSERT_DELTA(angle->y(0).back(), 0.001, 0.001); + } + void test_output_label() { // Test the output label size_t npoints = 2; - auto ws = createWorkspaceReal(npoints, 0.0); + auto ws = createWorkspaceReal(npoints, 0.0, 1); IAlgorithm_sptr alg = AlgorithmManager::Instance().create("MaxEnt"); alg->initialize(); @@ -479,7 +1045,7 @@ public: } void test_unevenlySpacedInputData() { - auto ws = createWorkspaceReal(3, 0.0); + auto ws = createWorkspaceReal(3, 0.0, 1); Points xData{0, 1, 5}; ws->setPoints(0, xData); IAlgorithm_sptr alg = AlgorithmManager::Instance().create("MaxEnt"); @@ -493,10 +1059,12 @@ public: const size_t size = 10; MatrixWorkspace_sptr ws = boost::dynamic_pointer_cast<MatrixWorkspace>( WorkspaceFactory::Instance().create("Workspace2D", 1, size + 1, size)); - // We don't care about values, we just want to test the number of - // X points in the image + // We don't care about values, except to check they are transferred + // to data after one iteration. + // Otherwise, we just want to test the number of + // X points in the image. // For histogram input workspaces we should get the original number - // of points minus one + // of points minus one. for (size_t i = 0; i < size; i++) { double value = static_cast<double>(i); ws->dataX(0)[i] = value; @@ -530,10 +1098,12 @@ public: const size_t size = 10; MatrixWorkspace_sptr ws = boost::dynamic_pointer_cast<MatrixWorkspace>( WorkspaceFactory::Instance().create("Workspace2D", 1, size, size)); - // We don't care about values, we just want to test the number of - // X points in the image - // For histogram input workspaces we should get the original number - // of points minus one + // We don't care about values, except to check they are transferred + // to data after one iteration. + // Otherwise, we just want to test the number of + // X points in the image. + // For pointdata input workspaces we should get the original number + // of points. for (size_t i = 0; i < size; i++) { double value = static_cast<double>(i); ws->dataX(0)[i] = value; @@ -562,21 +1132,96 @@ public: TS_ASSERT_EQUALS(data->readX(0), ws->readX(0)); } - MatrixWorkspace_sptr createWorkspaceReal(size_t maxt, double phase) { + MatrixWorkspace_sptr + createWorkspaceWithYValues(size_t nHist, size_t length, + std::vector<double> const &YVal) { + + size_t nPts = length * nHist; + TS_ASSERT_EQUALS(nPts, YVal.size()); + MantidVec X(nPts); + MantidVec Y(nPts); + MantidVec E(nPts); + for (size_t t = 0; t < length; t++) { + double x = static_cast<double>(t); + for (size_t s = 0; s < nHist; s++) { + X[t + s * length] = x; + Y[t + s * length] = YVal[t + s * length]; + E[t + s * length] = 0.1; + } + } + auto createWS = AlgorithmManager::Instance().create("CreateWorkspace"); + createWS->initialize(); + createWS->setChild(true); + createWS->setProperty("DataX", X); + createWS->setProperty("DataY", Y); + createWS->setProperty("DataE", E); + createWS->setProperty("NSpec", static_cast<int>(nHist)); + createWS->setPropertyValue("OutputWorkspace", "ws"); + createWS->execute(); + MatrixWorkspace_sptr ws = createWS->getProperty("OutputWorkspace"); + + return ws; + } + + MatrixWorkspace_sptr createWorkspaceReal(size_t maxt, double phase, + size_t nSpec) { // Create cosine with phase 'phase' // Frequency of the oscillations double w = 1.6; + // phase shift between spectra + double shift = 0.5; + + size_t nPts = maxt * nSpec; + MantidVec X(nPts); + MantidVec Y(nPts); + MantidVec E(nPts); + for (size_t t = 0; t < maxt; t++) { + double x = 2. * M_PI * static_cast<double>(t) / static_cast<double>(maxt); + for (size_t s = 0; s < nSpec; s++) { + X[t + s * maxt] = x; + Y[t + s * maxt] = cos(w * x + phase + static_cast<double>(s) * shift); + E[t + s * maxt] = 0.1; + } + } + auto createWS = AlgorithmManager::Instance().create("CreateWorkspace"); + createWS->initialize(); + createWS->setChild(true); + createWS->setProperty("DataX", X); + createWS->setProperty("DataY", Y); + createWS->setProperty("DataE", E); + createWS->setProperty("NSpec", static_cast<int>(nSpec)); + createWS->setPropertyValue("OutputWorkspace", "ws"); + createWS->execute(); + MatrixWorkspace_sptr ws = createWS->getProperty("OutputWorkspace"); + + return ws; + } + + MatrixWorkspace_sptr createWorkspaceComplex(size_t maxt, double phase, + size_t nSpec, double shift) { + + // Create cosine with phase 'phase' + + // Frequency of the oscillations + double w = 3.0; - MantidVec X(maxt); - MantidVec Y(maxt); - MantidVec E(maxt); + size_t nPts = maxt * nSpec; + MantidVec X(2 * nPts); + MantidVec Y(2 * nPts); + MantidVec E(2 * nPts); for (size_t t = 0; t < maxt; t++) { double x = 2. * M_PI * static_cast<double>(t) / static_cast<double>(maxt); - X[t] = x; - Y[t] = cos(w * x + phase); - E[t] = 0.1; + for (size_t s = 0; s < nSpec; s++) { + X[t + s * maxt] = x; + Y[t + s * maxt] = cos(w * x + phase + static_cast<double>(s) * shift); + E[t + s * maxt] = 0.2; + X[t + s * maxt + nPts] = x; + Y[t + s * maxt + nPts] = + sin(w * x + phase + static_cast<double>(s) * shift); + E[t + s * maxt + nPts] = 0.2; + } } auto createWS = AlgorithmManager::Instance().create("CreateWorkspace"); createWS->initialize(); @@ -584,6 +1229,7 @@ public: createWS->setProperty("DataX", X); createWS->setProperty("DataY", Y); createWS->setProperty("DataE", E); + createWS->setProperty("NSpec", static_cast<int>(2 * nSpec)); createWS->setPropertyValue("OutputWorkspace", "ws"); createWS->execute(); MatrixWorkspace_sptr ws = createWS->getProperty("OutputWorkspace"); @@ -634,6 +1280,49 @@ public: return ws; } + + MatrixWorkspace_sptr createWorkspaceAdjustments(size_t maxt, double base, + double magnitude, + double phase, size_t nSpec) { + + // Frequency of the oscillations + double w = 2.4; + // phase shift between spectra + double shift = 0.5; + + size_t nPts = maxt * nSpec; + MantidVec X(2 * nPts); + MantidVec Y(2 * nPts); + MantidVec E(2 * nPts); + for (size_t t = 0; t < maxt; t++) { + double x = 2. * M_PI * static_cast<double>(t) / static_cast<double>(maxt); + for (size_t s = 0; s < nSpec; s++) { + // Real + X[t + s * maxt] = 0.0; + Y[t + s * maxt] = + base + + magnitude * cos(w * x + phase + static_cast<double>(s) * shift); + E[t + s * maxt] = 0.0; + // Imaginary + X[t + s * maxt + nPts] = 0.0; + Y[t + s * maxt + nPts] = + magnitude * sin(w * x + phase + static_cast<double>(s) * shift); + E[t + s * maxt + nPts] = 0.0; + } + } + auto createWS = AlgorithmManager::Instance().create("CreateWorkspace"); + createWS->initialize(); + createWS->setChild(true); + createWS->setProperty("DataX", X); + createWS->setProperty("DataY", Y); + createWS->setProperty("DataE", E); + createWS->setProperty("NSpec", 2 * static_cast<int>(nSpec)); + createWS->setPropertyValue("OutputWorkspace", "ws"); + createWS->execute(); + MatrixWorkspace_sptr ws = createWS->getProperty("OutputWorkspace"); + + return ws; + } }; class MaxEntTestPerformance : public CxxTest::TestSuite { diff --git a/Framework/Crystal/src/PeakStatisticsTools.cpp b/Framework/Crystal/src/PeakStatisticsTools.cpp index be199079e7e902278585080dd166f15aa84e3699..4ab4f2d0e98e7894d9971fdb2518531cb196db1c 100644 --- a/Framework/Crystal/src/PeakStatisticsTools.cpp +++ b/Framework/Crystal/src/PeakStatisticsTools.cpp @@ -283,11 +283,6 @@ void PeaksStatistics::calculatePeaksStatistics( // Collect sum of intensities for R-value calculation intensitySumRValues += std::accumulate(intensities.begin(), intensities.end(), 0.0); - - // The original algorithm sets the intensities and sigmas to the mean. - double sqrtOfMeanSqrSigma = getRMS(sigmas); - outliersRemoved.setPeaksIntensityAndSigma(meanIntensity, - sqrtOfMeanSqrSigma); } const std::vector<Peak> &reflectionPeaks = outliersRemoved.getPeaks(); diff --git a/Framework/CurveFitting/src/IFittingAlgorithm.cpp b/Framework/CurveFitting/src/IFittingAlgorithm.cpp index 417a7765d42f9460b63d99022d08f4e4a33703b0..2c1fb620f60ce147c62b6c067ed8a72ecb46e876 100644 --- a/Framework/CurveFitting/src/IFittingAlgorithm.cpp +++ b/Framework/CurveFitting/src/IFittingAlgorithm.cpp @@ -303,6 +303,7 @@ void IFittingAlgorithm::declareCostFunctionProperty() { boost::shared_ptr<CostFunctions::CostFuncFitting> IFittingAlgorithm::getCostFunctionInitialized() const { // Function may need some preparation. + m_function->sortTies(); m_function->setUpForFit(); API::FunctionDomain_sptr domain; diff --git a/Framework/DataHandling/src/MaskDetectors.cpp b/Framework/DataHandling/src/MaskDetectors.cpp index 861730dd88cdbc34d927418303061fbca4cb68db..f4a62f10ba4f8b359efb083391da38182ac0f593 100644 --- a/Framework/DataHandling/src/MaskDetectors.cpp +++ b/Framework/DataHandling/src/MaskDetectors.cpp @@ -57,12 +57,11 @@ void MaskDetectors::init() { "The name of the input and output workspace on which to perform the " "algorithm."); declareProperty(make_unique<ArrayProperty<specnum_t>>("SpectraList"), - "An ArrayProperty containing a list of spectra to mask"); - declareProperty( - make_unique<ArrayProperty<detid_t>>("DetectorList"), - "An ArrayProperty containing a list of detector ID's to mask"); + "A list of spectra to mask"); + declareProperty(make_unique<ArrayProperty<detid_t>>("DetectorList"), + "A list of detector ID's to mask"); declareProperty(make_unique<ArrayProperty<size_t>>("WorkspaceIndexList"), - "An ArrayProperty containing the workspace indices to mask"); + "A list of the workspace indices to mask"); declareProperty(make_unique<WorkspaceProperty<>>("MaskedWorkspace", "", Direction::Input, PropertyMode::Optional), @@ -95,9 +94,8 @@ void MaskDetectors::init() { "Default is number of histograms in target workspace if other masks are" " present " "or ignored if not."); - declareProperty( - make_unique<ArrayProperty<std::string>>("ComponentList"), - "An ArrayProperty containing a list of component names to mask"); + declareProperty(make_unique<ArrayProperty<std::string>>("ComponentList"), + "A list names of components to mask"); } /* @@ -119,7 +117,9 @@ void MaskDetectors::exec() { EventWorkspace_sptr eventWS = boost::dynamic_pointer_cast<EventWorkspace>(WS); // Is it a Mask Workspace ? - MaskWorkspace_sptr isMaskWS = boost::dynamic_pointer_cast<MaskWorkspace>(WS); + MaskWorkspace_sptr inputAsMaskWS = + boost::dynamic_pointer_cast<MaskWorkspace>(WS); + const auto isMaskWS = static_cast<bool>(inputAsMaskWS); std::vector<size_t> indexList = getProperty("WorkspaceIndexList"); auto spectraList = @@ -214,13 +214,15 @@ void MaskDetectors::exec() { } if (isMaskWS) { - // If the input was a mask workspace, then extract the mask to ensure - // we are returning the correct thing. - IAlgorithm_sptr alg = createChildAlgorithm("ExtractMask"); - alg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", WS); - alg->executeAsChildAlg(); - MatrixWorkspace_sptr ws = alg->getProperty("OutputWorkspace"); - setProperty("Workspace", ws); + // When input is a MaskWorkspace, some special handling is needed. + auto &spectrumInfo = inputAsMaskWS->mutableSpectrumInfo(); + for (size_t i = 0; i < inputAsMaskWS->getNumberHistograms(); ++i) { + const bool mask = + inputAsMaskWS->isMaskedIndex(i) || spectrumInfo.isMasked(i); + inputAsMaskWS->setMaskedIndex(i, mask); + // Always clear the mask flag from MaskWorkspace + spectrumInfo.setMasked(i, false); + } } } diff --git a/Framework/DataHandling/test/MaskDetectorsTest.h b/Framework/DataHandling/test/MaskDetectorsTest.h index ced4df118d05716637aa16b87d2837c6d024ede4..35046e553f2e55835706b9a4473e25465b7f27e2 100644 --- a/Framework/DataHandling/test/MaskDetectorsTest.h +++ b/Framework/DataHandling/test/MaskDetectorsTest.h @@ -49,8 +49,8 @@ public: * Generate a Workspace which can be (1) EventWorkspace, (2) Workspace2D, and * (3) SpecialWorkspace2D */ - void setUpWS(bool event, const std::string &name = "testSpace", - bool asMaskWorkspace = false, int numspec = 9) { + static void setUpWS(bool event, const std::string &name = "testSpace", + bool asMaskWorkspace = false, int numspec = 9) { // 1. Instrument int num_banks = numspec / 9; if (num_banks < 1) @@ -781,6 +781,38 @@ public: } } + void test_MaskingMaskWorkspace() { + const auto &ads = AnalysisDataService::Instance(); + const std::string inputWSName("inputWS"); + constexpr int numInputSpec(5); + constexpr int maskedIndex{numInputSpec / 2}; + setUpWS(false, inputWSName, true, numInputSpec); + auto inputWS = ads.retrieveWS<MatrixWorkspace>(inputWSName); + MaskDetectors masker; + masker.initialize(); + masker.setChild(true); + masker.setProperty("Workspace", inputWS); + masker.setPropertyValue("WorkspaceIndexList", std::to_string(maskedIndex)); + masker.setRethrows(true); + TS_ASSERT_THROWS_NOTHING(masker.execute()); + // Check that the workspace has not suddenly changed. + // Guards against a bug where the Workspace property was set to another + // workspace breaking some Python scripts. + Workspace_sptr outputWS = masker.getProperty("Workspace"); + TS_ASSERT_EQUALS(inputWS, outputWS) + // MaskWorkspaces don't have masks, but communicate the mask state by + // nonzero numbers. + const auto &spectrumInfo = inputWS->spectrumInfo(); + for (size_t i = 0; i < inputWS->getNumberHistograms(); ++i) { + TS_ASSERT(!spectrumInfo.isMasked(i)) + if (i == maskedIndex) { + TS_ASSERT_EQUALS(inputWS->y(i)[0], 1.) + } else { + TS_ASSERT_EQUALS(inputWS->y(i)[0], 0.) + } + } + } + private: MaskDetectors marker; }; diff --git a/Framework/DataObjects/src/Peak.cpp b/Framework/DataObjects/src/Peak.cpp index d8cd676ff9723ee41d4947d36a026274e258c118..09adc11ed63dc371b23706c11140d331e0817f61 100644 --- a/Framework/DataObjects/src/Peak.cpp +++ b/Framework/DataObjects/src/Peak.cpp @@ -1027,6 +1027,7 @@ Peak &Peak::operator=(const Peak &other) { m_orig_L = other.m_orig_L; m_detIDs = other.m_detIDs; convention = other.convention; + m_peakNumber = other.m_peakNumber; m_peakShape.reset(other.m_peakShape->clone()); } return *this; diff --git a/Framework/Doxygen/Mantid_template.doxyfile b/Framework/Doxygen/Mantid_template.doxyfile index 70e2f9874059f387a9bebfb12c896cfb46d39849..74a92257d2e06bfdf8307806b3e79a658987363b 100644 --- a/Framework/Doxygen/Mantid_template.doxyfile +++ b/Framework/Doxygen/Mantid_template.doxyfile @@ -5,18 +5,18 @@ #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = @CMAKE_PROJECT_NAME@ -PROJECT_NUMBER = +PROJECT_NUMBER = OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@/../../doxygen CREATE_SUBDIRS = YES OUTPUT_LANGUAGE = English BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES -ABBREVIATE_BRIEF = +ABBREVIATE_BRIEF = ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO FULL_PATH_NAMES = YES STRIP_FROM_PATH = @CMAKE_SOURCE_DIR@ -STRIP_FROM_INC_PATH = +STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = YES QT_AUTOBRIEF = YES @@ -24,7 +24,7 @@ MULTILINE_CPP_IS_BRIEF = NO INHERIT_DOCS = YES SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 8 -ALIASES = +ALIASES = OPTIMIZE_OUTPUT_FOR_C = NO OPTIMIZE_OUTPUT_JAVA = NO BUILTIN_STL_SUPPORT = YES @@ -58,11 +58,11 @@ GENERATE_TODOLIST = YES GENERATE_TESTLIST = YES GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES -ENABLED_SECTIONS = +ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES SHOW_FILES = YES -FILE_VERSION_FILTER = +FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- @@ -72,7 +72,7 @@ WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = YES WARN_FORMAT = @DOXY_WARN_FORMAT@ -WARN_LOGFILE = +WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- @@ -99,8 +99,10 @@ INPUT = @CMAKE_CURRENT_SOURCE_DIR@/../Algorithms/inc \ @CMAKE_CURRENT_SOURCE_DIR@/../MDAlgorithms/src \ @CMAKE_CURRENT_SOURCE_DIR@/../Nexus/inc \ @CMAKE_CURRENT_SOURCE_DIR@/../Nexus/src \ + @CMAKE_CURRENT_SOURCE_DIR@/../PythonInterface/core/inc/MantidPythonInterface/core \ @CMAKE_CURRENT_SOURCE_DIR@/../PythonInterface/inc/MantidPythonInterface/kernel \ @CMAKE_CURRENT_SOURCE_DIR@/../PythonInterface/inc/MantidPythonInterface/api \ + @CMAKE_CURRENT_SOURCE_DIR@/../PythonInterface/core/src \ @CMAKE_CURRENT_SOURCE_DIR@/../PythonInterface/mantid/kernel/src \ @CMAKE_CURRENT_SOURCE_DIR@/../PythonInterface/mantid/geometry/src \ @CMAKE_CURRENT_SOURCE_DIR@/../PythonInterface/mantid/api/src \ @@ -139,7 +141,7 @@ INPUT = @CMAKE_CURRENT_SOURCE_DIR@/../Algorithms/inc \ INPUT_ENCODING = UTF-8 -FILE_PATTERNS = +FILE_PATTERNS = RECURSIVE = YES #Note: The NeXus API docs are there temporarily and cause lots of (unnecessary) doxygen warnings. @@ -158,14 +160,14 @@ EXCLUDE = @CMAKE_CURRENT_SOURCE_DIR@/../ICat/src/GSoapGenerated \ @CMAKE_CURRENT_SOURCE_DIR@/../../qt/paraview_ext/PVPlugins EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = -EXCLUDE_SYMBOLS = -EXAMPLE_PATH = -EXAMPLE_PATTERNS = +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = EXAMPLE_RECURSIVE = NO IMAGE_PATH = @CMAKE_CURRENT_BINARY_DIR@/../../doxygen/html/ -INPUT_FILTER = -FILTER_PATTERNS = +INPUT_FILTER = +FILTER_PATTERNS = FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing @@ -183,7 +185,7 @@ VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = YES COLS_IN_ALPHA_INDEX = 5 -IGNORE_PREFIX = +IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- @@ -191,13 +193,13 @@ GENERATE_HTML = YES HTML_OUTPUT = html HTML_FILE_EXTENSION = .html HTML_HEADER = @CMAKE_CURRENT_BINARY_DIR@/doxy_header.html -HTML_FOOTER = -HTML_STYLESHEET = +HTML_FOOTER = +HTML_STYLESHEET = HTML_TIMESTAMP = YES GENERATE_HTMLHELP = NO HTML_DYNAMIC_SECTIONS = NO -CHM_FILE = -HHC_LOCATION = +CHM_FILE = +HHC_LOCATION = GENERATE_CHI = NO BINARY_TOC = NO TOC_EXPAND = NO @@ -214,8 +216,8 @@ LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO PAPER_TYPE = a4wide -EXTRA_PACKAGES = -LATEX_HEADER = +EXTRA_PACKAGES = +LATEX_HEADER = PDF_HYPERLINKS = NO USE_PDFLATEX = NO LATEX_BATCHMODE = NO @@ -227,8 +229,8 @@ GENERATE_RTF = NO RTF_OUTPUT = rtf COMPACT_RTF = NO RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- @@ -252,7 +254,7 @@ GENERATE_AUTOGEN_DEF = NO GENERATE_PERLMOD = NO PERLMOD_LATEX = NO PERLMOD_PRETTY = YES -PERLMOD_MAKEVAR_PREFIX = +PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the qtcreator output #--------------------------------------------------------------------------- @@ -262,31 +264,31 @@ QHP_NAMESPACE = "mantidproject.org" QHP_VIRTUAL_FOLDER = "mantidQtHelp" QHG_LOCATION = @QHELP_EXECUTABLE@ #--------------------------------------------------------------------------- -# Configuration options related to the preprocessor +# Configuration options related to the preprocessor #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = YES SEARCH_INCLUDES = YES -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = PREDEFINED = "TMDE(decl)=decl" \ "INSTANTIATE(TYPE)=template MANTID_KERNEL_DLL Statistics getStatistics<TYPE> (const vector<TYPE> &, const bool);\template MANTID_KERNEL_DLL std::vector<double> getZscore<TYPE> (const vector<TYPE> &, const bool);\template MANTID_KERNEL_DLL std::vector<double> getModifiedZscore<TYPE> (const vector<TYPE> &, const bool);" -EXPAND_AS_DEFINED = +EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- -# Configuration::additions related to external references +# Configuration::additions related to external references #--------------------------------------------------------------------------- -TAGFILES = -GENERATE_TAGFILE = +TAGFILES = +GENERATE_TAGFILE = ALLEXTERNALS = NO EXTERNAL_GROUPS = YES PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- -# Configuration options related to the dot tool +# Configuration options related to the dot tool #--------------------------------------------------------------------------- CLASS_DIAGRAMS = YES -MSCGEN_PATH = +MSCGEN_PATH = HIDE_UNDOC_RELATIONS = YES HAVE_DOT = @HAVE_DOT@ CLASS_GRAPH = YES @@ -302,7 +304,7 @@ GRAPHICAL_HIERARCHY = NO # YES DIRECTORY_GRAPH = YES DOT_IMAGE_FORMAT = png DOT_PATH = @DOXYGEN_DOT_PATH@ -DOTFILE_DIRS = +DOTFILE_DIRS = DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 2 DOT_TRANSPARENT = NO @@ -310,6 +312,6 @@ DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES DOT_CLEANUP = YES #--------------------------------------------------------------------------- -# Configuration::additions related to the search engine +# Configuration::additions related to the search engine #--------------------------------------------------------------------------- SEARCHENGINE = YES diff --git a/Framework/HistogramData/inc/MantidHistogramData/FixedLengthVector.h b/Framework/HistogramData/inc/MantidHistogramData/FixedLengthVector.h index 53cb5f7dc9b564ea7f6104a00a589ad8651e1c46..76c0a60cfe4dc817702e23600dfeb0f23361b8d3 100644 --- a/Framework/HistogramData/inc/MantidHistogramData/FixedLengthVector.h +++ b/Framework/HistogramData/inc/MantidHistogramData/FixedLengthVector.h @@ -109,6 +109,10 @@ public: return this->rawData() == rhs.rawData(); } + bool operator!=(const FixedLengthVector<T> &rhs) const { + return !(*this == rhs); + } + bool empty() const { return m_data.empty(); } size_t size() const { return m_data.size(); } diff --git a/Framework/HistogramData/test/HistogramMathTest.h b/Framework/HistogramData/test/HistogramMathTest.h index aa4a7d40bf933c53cb87030e52f7ab807b3af87e..d71481d228ec6e27fbaaee8a8725c16e6e8078dc 100644 --- a/Framework/HistogramData/test/HistogramMathTest.h +++ b/Framework/HistogramData/test/HistogramMathTest.h @@ -5,6 +5,7 @@ #include "MantidHistogramData/Histogram.h" #include "MantidHistogramData/HistogramMath.h" +#include "MantidKernel/WarningSuppressions.h" using namespace Mantid::HistogramData; @@ -148,7 +149,9 @@ public: void test_minus_histogram_self() { BinEdges edges{1, 2, 3}; Histogram hist(edges, Counts{4, 9}); + GNU_DIAG_OFF("self-assign-overloaded") hist -= hist; + GNU_DIAG_ON("self-assign-overloaded") TS_ASSERT_EQUALS(hist.sharedX(), edges.cowData()); TS_ASSERT_EQUALS(hist.y()[0], 0.0); TS_ASSERT_EQUALS(hist.y()[1], 0.0); @@ -281,7 +284,9 @@ public: void test_divide_histogram_self() { BinEdges edges{1, 2, 3}; Histogram hist(edges, Frequencies{4, 9}); + GNU_DIAG_OFF("self-assign-overloaded") hist /= hist; + GNU_DIAG_ON("self-assign-overloaded") TS_ASSERT_EQUALS(hist.sharedX(), edges.cowData()); TS_ASSERT_EQUALS(hist.y()[0], 1.0); TS_ASSERT_EQUALS(hist.y()[1], 1.0); diff --git a/Framework/Kernel/inc/MantidKernel/SingletonHolder.h b/Framework/Kernel/inc/MantidKernel/SingletonHolder.h index 6321775214b05c16bf383e8a75a96a1630e87839..8d1310ffb143534591a2648ed1daf8a0a16c0ed1 100644 --- a/Framework/Kernel/inc/MantidKernel/SingletonHolder.h +++ b/Framework/Kernel/inc/MantidKernel/SingletonHolder.h @@ -48,16 +48,12 @@ public: static T &Instance(); private: - static T *instance; - static std::once_flag once; #ifndef NDEBUG static bool destroyed; #endif }; // Static field initializers -template <typename T> T *SingletonHolder<T>::instance = nullptr; -template <typename T> std::once_flag SingletonHolder<T>::once; #ifndef NDEBUG template <typename T> bool SingletonHolder<T>::destroyed = false; #endif @@ -80,17 +76,33 @@ template <typename T> struct CreateUsingNew { /// Return a reference to the Singleton instance, creating it if it does not /// already exist -/// Creation is done using the CreateUsingNew policy at the moment -template <typename T> inline T &SingletonHolder<T>::Instance() { - std::call_once(once, []() { - instance = CreateUsingNew<T>::create(); +/// Creation is done using the CreateUsingNew policy. Held types need +/// to make CreateUsingNew<T> a friend. +/// This method cannot be inlined due to the presence of a local static +/// variable. Inlining causes each call site to receive a different +/// copy of the static instance variable. +template <typename T> +#if defined(_MSC_VER) +__declspec(noinline) +#endif + T & +#if defined(__GNUC__) // covers clang too + __attribute__((noinline)) +#endif + SingletonHolder<T>::Instance() { + // Initialiazing a local static is thread-safe in C++11 + // The inline lambda call is used to create the singleton once + // and register an atexit function to delete it + static T *instance = []() { + auto local = CreateUsingNew<T>::create(); deleteOnExit(SingletonDeleterFn([]() { #ifndef NDEBUG destroyed = true; #endif CreateUsingNew<T>::destroy(instance); })); - }); + return local; + }(); #ifndef NDEBUG assert(!destroyed); #endif diff --git a/Framework/Kernel/inc/MantidKernel/Strings.h b/Framework/Kernel/inc/MantidKernel/Strings.h index a98fc5e178ba860d692e13e22a4cfa9ef662ef47..bbc0694f470538b887b739f55f021373c62c8daa 100644 --- a/Framework/Kernel/inc/MantidKernel/Strings.h +++ b/Framework/Kernel/inc/MantidKernel/Strings.h @@ -160,7 +160,6 @@ join(ITERATOR_TYPE begin, ITERATOR_TYPE end, const std::string &separator, { nThreads = static_cast<int>(PARALLEL_NUMBER_OF_THREADS); int idThread = static_cast<int>(PARALLEL_THREAD_NUMBER); - ITERATOR_TYPE it; // Initialise ostringstream std::ostringstream thread_stream; diff --git a/Framework/Kernel/inc/MantidKernel/V3D.h b/Framework/Kernel/inc/MantidKernel/V3D.h index a588308314a71e5fcabc6a91b9a839c737c98911..8bcc9d50447629e463d92df63db3f614059343cd 100644 --- a/Framework/Kernel/inc/MantidKernel/V3D.h +++ b/Framework/Kernel/inc/MantidKernel/V3D.h @@ -2,6 +2,8 @@ #define MANTID_KERNEL_V3D_H_ #include "MantidKernel/DllConfig.h" +#include "MantidKernel/Exception.h" +#include "MantidKernel/Tolerance.h" #include <cmath> #include <iosfwd> #include <vector> @@ -58,52 +60,264 @@ public: return tmp; } - // Arithemetic operators overloaded - V3D operator+(const V3D &v) const; - V3D &operator+=(const V3D &v); - V3D operator-(const V3D &v) const; - V3D &operator-=(const V3D &v); - // Inner product - V3D operator*(const V3D &v) const; - V3D &operator*=(const V3D &v); - // Inner division - V3D operator/(const V3D &v) const; - V3D &operator/=(const V3D &v); - // Scale - V3D operator*(const double D) const; - V3D &operator*=(const double D); - V3D operator/(const double D) const; - V3D &operator/=(const double D); - // Negation - V3D operator-() const noexcept; - // Simple Comparison - bool operator==(const V3D &) const; - bool operator!=(const V3D &) const; - bool operator<(const V3D &) const; - bool operator>(const V3D &rhs) const; + /** + Addtion operator + @param v :: Vector to add + @return *this+v; + */ + V3D operator+(const V3D &v) const { + V3D out(*this); + out += v; + return out; + } + + /** + Subtraction operator + @param v :: Vector to sub. + @return *this-v; + */ + V3D operator-(const V3D &v) const { + V3D out(*this); + out -= v; + return out; + } + + /** + Inner product + @param v :: Vector to sub. + @return *this * v; + */ + V3D operator*(const V3D &v) const { + V3D out(*this); + out *= v; + return out; + } + + /** + Inner division + @param v :: Vector to divide + @return *this * v; + */ + V3D operator/(const V3D &v) const { + V3D out(*this); + out /= v; + return out; + } + + /** + Self-Addition operator + @param v :: Vector to add. + @return *this+=v; + */ + V3D &operator+=(const V3D &v) { + x += v.x; + y += v.y; + z += v.z; + return *this; + } + + /** + Self-Subtraction operator + @param v :: Vector to sub. + @return *this-v; + */ + V3D &operator-=(const V3D &v) { + x -= v.x; + y -= v.y; + z -= v.z; + return *this; + } + + /** + Self-Inner product + @param v :: Vector to multiply + @return *this*=v; + */ + V3D &operator*=(const V3D &v) { + x *= v.x; + y *= v.y; + z *= v.z; + return *this; + } + + /** + Self-Inner division + @param v :: Vector to divide + @return *this*=v; + */ + V3D &operator/=(const V3D &v) { + x /= v.x; + y /= v.y; + z /= v.z; + return *this; + } + + /** + Scalar product + @param D :: value to scale + @return this * D + */ + V3D operator*(const double D) const { + V3D out(*this); + out *= D; + return out; + } + + /** + Scalar divsion + @param D :: value to scale + @return this / D + */ + V3D operator/(const double D) const { + V3D out(*this); + out /= D; + return out; + } + + /** + Scalar product + @param D :: value to scale + @return this *= D + */ + V3D &operator*=(const double D) { + x *= D; + y *= D; + z *= D; + return *this; + } + + /** + Scalar division + @param D :: value to scale + @return this /= D + \todo ADD TOLERANCE + */ + V3D &operator/=(const double D) { + if (D != 0.0) { + x /= D; + y /= D; + z /= D; + } + return *this; + } + + /** + Negation + * @return a vector with same magnitude but in opposite direction + */ + V3D operator-() const { return V3D(-x, -y, -z); } + + /** + Equals operator with tolerance factor + @param v :: V3D for comparison + @return true if the items are equal + */ + bool operator==(const V3D &v) const { + using namespace std; + return !(fabs(x - v.x) > Tolerance || fabs(y - v.y) > Tolerance || + fabs(z - v.z) > Tolerance); + } + + /** Not equals operator with tolerance factor. + * @param other :: The V3D to compare against + * @returns True if the vectors are different + */ + bool operator!=(const V3D &other) const { return !(this->operator==(other)); } + + /** + compare + @return true if V is greater + */ + bool operator<(const V3D &V) const { + if (x != V.x) + return x < V.x; + if (y != V.y) + return y < V.y; + return z < V.z; + } + + /// Comparison operator greater than. + bool operator>(const V3D &rhs) const { return rhs < *this; } + + /** + Sets the vector position from a triplet of doubles x,y,z + @param xx :: The X coordinate + @param yy :: The Y coordinate + @param zz :: The Z coordinate + */ + void operator()(const double xx, const double yy, const double zz) { + x = xx; + y = yy; + z = zz; + } // Access // Setting x, y and z values - void operator()(const double xx, const double yy, const double zz); void spherical(const double &R, const double &theta, const double &phi); void spherical_rad(const double &R, const double &polar, const double &azimuth); void azimuth_polar_SNS(const double &R, const double &azimuth, const double &polar); - void setX(const double xx); - void setY(const double yy); - void setZ(const double zz); + /** + Set is x position + @param xx :: The X coordinate + */ + void setX(const double xx) { x = xx; } + + /** + Set is y position + @param yy :: The Y coordinate + */ + void setY(const double yy) { y = yy; } + + /** + Set is z position + @param zz :: The Z coordinate + */ + void setZ(const double zz) { z = zz; } const double &X() const { return x; } ///< Get x const double &Y() const { return y; } ///< Get y const double &Z() const { return z; } ///< Get z - const double &operator[](const size_t Index) const; - double &operator[](const size_t Index); + /** + Returns the axis value based in the index provided + @param Index :: 0=x, 1=y, 2=z + @return a double value of the requested axis + */ + const double &operator[](const size_t Index) const { + switch (Index) { + case 0: + return x; + case 1: + return y; + case 2: + return z; + default: + throw Kernel::Exception::IndexError(Index, 2, "operator[] range error"); + } + } + + /** + Returns the axis value based in the index provided + @param Index :: 0=x, 1=y, 2=z + @return a double value of the requested axis + */ + double &operator[](const size_t Index) { + switch (Index) { + case 0: + return x; + case 1: + return y; + case 2: + return z; + default: + throw Kernel::Exception::IndexError(Index, 2, "operator[] range error"); + } + } void getSpherical(double &R, double &theta, double &phi) const; - // void rotate(const V3D&,const V3D&,const double); void rotate(const Matrix<double> &); void round(); diff --git a/Framework/Kernel/src/ConfigService.cpp b/Framework/Kernel/src/ConfigService.cpp index f8c2487b85da404362b80f9bce9a81f43b7e5381..d1f8795929e737341536d9c4904b0fa0b8778a74 100644 --- a/Framework/Kernel/src/ConfigService.cpp +++ b/Framework/Kernel/src/ConfigService.cpp @@ -2069,8 +2069,11 @@ template DLLExport boost::optional<int> ConfigServiceImpl::getValue(const std::string &); template DLLExport boost::optional<size_t> ConfigServiceImpl::getValue(const std::string &); +#ifdef _MSC_VER template DLLExport boost::optional<bool> ConfigServiceImpl::getValue(const std::string &); +#endif + /// \endcond TEMPLATE } // namespace Kernel diff --git a/Framework/Kernel/src/V3D.cpp b/Framework/Kernel/src/V3D.cpp index 3ad2e04207c92141aa332ddcf5ad406a5f7ae566..73a2d50acfbf9e5f41a862221f8fc194510d621b 100644 --- a/Framework/Kernel/src/V3D.cpp +++ b/Framework/Kernel/src/V3D.cpp @@ -107,255 +107,6 @@ void V3D::azimuth_polar_SNS(const double &R, const double &azimuth, z = 0.0; } -/** - Addtion operator - @param v :: Vector to add - @return *this+v; -*/ -V3D V3D::operator+(const V3D &v) const { - V3D out(*this); - out += v; - return out; -} - -/** - Subtraction operator - @param v :: Vector to sub. - @return *this-v; -*/ -V3D V3D::operator-(const V3D &v) const { - V3D out(*this); - out -= v; - return out; -} - -/** - Inner product - @param v :: Vector to sub. - @return *this * v; -*/ -V3D V3D::operator*(const V3D &v) const { - V3D out(*this); - out *= v; - return out; -} - -/** - Inner division - @param v :: Vector to divide - @return *this * v; -*/ -V3D V3D::operator/(const V3D &v) const { - V3D out(*this); - out /= v; - return out; -} - -/** - Self-Addition operator - @param v :: Vector to add. - @return *this+=v; -*/ -V3D &V3D::operator+=(const V3D &v) { - x += v.x; - y += v.y; - z += v.z; - return *this; -} - -/** - Self-Subtraction operator - @param v :: Vector to sub. - @return *this-v; -*/ -V3D &V3D::operator-=(const V3D &v) { - x -= v.x; - y -= v.y; - z -= v.z; - return *this; -} - -/** - Self-Inner product - @param v :: Vector to multiply - @return *this*=v; -*/ -V3D &V3D::operator*=(const V3D &v) { - x *= v.x; - y *= v.y; - z *= v.z; - return *this; -} - -/** - Self-Inner division - @param v :: Vector to divide - @return *this*=v; -*/ -V3D &V3D::operator/=(const V3D &v) { - x /= v.x; - y /= v.y; - z /= v.z; - return *this; -} - -/** - Scalar product - @param D :: value to scale - @return this * D - */ -V3D V3D::operator*(const double D) const { - V3D out(*this); - out *= D; - return out; -} - -/** - Scalar divsion - @param D :: value to scale - @return this / D -*/ -V3D V3D::operator/(const double D) const { - V3D out(*this); - out /= D; - return out; -} - -/** - Scalar product - @param D :: value to scale - @return this *= D -*/ -V3D &V3D::operator*=(const double D) { - x *= D; - y *= D; - z *= D; - return *this; -} - -/** - Scalar division - @param D :: value to scale - @return this /= D - \todo ADD TOLERANCE -*/ -V3D &V3D::operator/=(const double D) { - if (D != 0.0) { - x /= D; - y /= D; - z /= D; - } - return *this; -} - -/** - Negation - * @return a vector with same magnitude but in opposite direction - */ -V3D V3D::operator-() const noexcept { return V3D(-x, -y, -z); } - -/** - Equals operator with tolerance factor - @param v :: V3D for comparison - @return true if the items are equal -*/ -bool V3D::operator==(const V3D &v) const { - using namespace std; - return !(fabs(x - v.x) > Tolerance || fabs(y - v.y) > Tolerance || - fabs(z - v.z) > Tolerance); -} - -/** Not equals operator with tolerance factor. - * @param other :: The V3D to compare against - * @returns True if the vectors are different - */ -bool V3D::operator!=(const V3D &other) const { - return !(this->operator==(other)); -} - -/** - compare - @return true if V is greater - */ -bool V3D::operator<(const V3D &V) const { - if (x != V.x) - return x < V.x; - if (y != V.y) - return y < V.y; - return z < V.z; -} - -/// Comparison operator greater than. -bool V3D::operator>(const V3D &rhs) const { return rhs < *this; } - -/** - Sets the vector position from a triplet of doubles x,y,z - @param xx :: The X coordinate - @param yy :: The Y coordinate - @param zz :: The Z coordinate -*/ -void V3D::operator()(const double xx, const double yy, const double zz) { - x = xx; - y = yy; - z = zz; -} - -/** - Set is x position - @param xx :: The X coordinate -*/ -void V3D::setX(const double xx) { x = xx; } - -/** - Set is y position - @param yy :: The Y coordinate -*/ -void V3D::setY(const double yy) { y = yy; } - -/** - Set is z position - @param zz :: The Z coordinate -*/ -void V3D::setZ(const double zz) { z = zz; } - -/** - Returns the axis value based in the index provided - @param Index :: 0=x, 1=y, 2=z - @return a double value of the requested axis -*/ -const double &V3D::operator[](const size_t Index) const { - switch (Index) { - case 0: - return x; - case 1: - return y; - case 2: - return z; - default: - throw Kernel::Exception::IndexError(Index, 2, - "V3D::operator[] range error"); - } -} - -/** - Returns the axis value based in the index provided - @param Index :: 0=x, 1=y, 2=z - @return a double value of the requested axis -*/ -double &V3D::operator[](const size_t Index) { - switch (Index) { - case 0: - return x; - case 1: - return y; - case 2: - return z; - default: - throw Kernel::Exception::IndexError(Index, 2, - "V3D::operator[] range error"); - } -} - /** Return the vector's position in spherical coordinates * @param R :: Returns the radial distance * @param theta :: Returns the theta angle in degrees diff --git a/Framework/Kernel/test/V3DTest.h b/Framework/Kernel/test/V3DTest.h index ebe35c0e971bda50a8048ba58a10d2c241b9a444..96ba04a01e20da3285e901b10dac50743ec0f7c9 100644 --- a/Framework/Kernel/test/V3DTest.h +++ b/Framework/Kernel/test/V3DTest.h @@ -577,11 +577,13 @@ public: m_rotx[1][2] = -sin(theta); m_rotx[2][2] = cos(theta); m_rotx[2][1] = sin(theta); + + m_sampleSize = 100000000; } void testRotate() { V3D direction(1.0, 1.0, 1.0); - for (size_t i = 0; i < 100000; ++i) { + for (size_t i = 0; i < m_sampleSize; ++i) { direction = V3D(1.0, 1.0, 1.0); direction.rotate(m_rotx); } @@ -589,8 +591,181 @@ public: TS_ASSERT_DELTA(direction.Y(), 0.0, 1e-08); } + void testElementAccessOperator() { + V3D direction(1.0, 1.0, 1.0); + double sum = 0; + for (size_t i = 0; i < m_sampleSize; i++) { + sum += direction[0] + direction[1] + direction[2]; + } + TS_ASSERT_EQUALS(sum, 3 * m_sampleSize); + } + + void testAddAssignOperatorV3D() { + V3D direction(1.0, 1.0, 1.0); + V3D sum(0, 0, 0); + for (size_t i = 0; i < m_sampleSize; i++) { + sum += direction; + } + TS_ASSERT_DELTA(sum.Y(), m_sampleSize, 1e-08); + } + + void testSubAssignOperatorV3D() { + V3D direction(1.0, 1.0, 1.0); + V3D sum(0, 0, 0); + for (size_t i = 0; i < m_sampleSize; i++) { + sum -= direction; + } + TS_ASSERT_DELTA(sum.Y(), -static_cast<int>(m_sampleSize), 1e-08); + } + + void testMultiplyAssignOperatorV3D() { + V3D direction(1.0, 1.0, 1.0); + V3D sum(0, 0, 0); + for (size_t i = 0; i < m_sampleSize; i++) { + sum *= direction; + } + TS_ASSERT_DELTA(sum.Y(), 0.0, 1e-08); + } + + void testDivideAssignOperatorV3D() { + V3D direction(1.0, 1.0, 1.0); + V3D sum(0, 0, 0); + for (size_t i = 0; i < m_sampleSize; i++) { + sum /= direction; + } + TS_ASSERT_DELTA(sum.Y(), 0.0, 1e-08); + } + + void testAddOperatorV3D() { + V3D direction1(1.0, 1.0, 1.0); + V3D direction2(2.0, 2.0, 2.0); + V3D sum(0, 0, 0); + for (size_t i = 0; i < m_sampleSize; i++) { + sum = direction1 + direction2; + } + TS_ASSERT_DELTA(sum.Y(), 3.0, 1e-08); + } + + void testSubOperatorV3D() { + V3D direction1(1.0, 1.0, 1.0); + V3D direction2(2.0, 2.0, 2.0); + V3D sum(0, 0, 0); + for (size_t i = 0; i < m_sampleSize; i++) { + sum = direction1 - direction2; + } + TS_ASSERT_DELTA(sum.Y(), -1.0, 1e-08); + } + + void testMultiplyOperatorV3D() { + V3D direction1(1.0, 1.0, 1.0); + V3D direction2(2.0, 2.0, 2.0); + V3D sum(0, 0, 0); + for (size_t i = 0; i < m_sampleSize; i++) { + sum = direction1 * direction2; + } + TS_ASSERT_DELTA(sum.Y(), 2.0, 1e-08); + } + + void testDivideOperatorV3D() { + V3D direction1(1.0, 1.0, 1.0); + V3D direction2(2.0, 2.0, 2.0); + V3D sum(0, 0, 0); + for (size_t i = 0; i < m_sampleSize; i++) { + sum = direction1 / direction2; + } + TS_ASSERT_DELTA(sum.Y(), 0.5, 1e-08); + } + + void testMultiplyAssignOperatorScalar() { + V3D direction(1.0, 1.0, 1.0); + double scalar = 1.0; + for (size_t i = 0; i < m_sampleSize; i++) { + direction *= scalar; + } + TS_ASSERT_DELTA(direction.Y(), 1.0, 1e-08); + } + + void testDivideAssignOperatorScalar() { + V3D direction(1.0, 1.0, 1.0); + double scalar = 1.0; + for (size_t i = 0; i < m_sampleSize; i++) { + direction /= scalar; + } + TS_ASSERT_DELTA(direction.Y(), 1.0, 1e-08); + } + + void testMultiplyOperatorScalar() { + V3D direction1(1.0, 1.0, 1.0); + double scalar = 0.1; + V3D sum(0, 0, 0); + for (size_t i = 0; i < m_sampleSize; i++) { + sum = direction1 * scalar; + } + TS_ASSERT_DELTA(sum.Y(), 0.1, 1e-08); + } + + void testDivideOperatorScalar() { + V3D direction1(1.0, 1.0, 1.0); + double scalar = 0.1; + V3D sum(0, 0, 0); + for (size_t i = 0; i < m_sampleSize; i++) { + sum = direction1 / scalar; + } + TS_ASSERT_DELTA(sum.Y(), 10, 1e-08); + } + + void testNegationOperator() { + V3D direction1(1.0, 1.0, 1.0); + V3D sum(0, 0, 0); + for (size_t i = 0; i < m_sampleSize; i++) { + sum = -direction1; + } + TS_ASSERT_DELTA(sum.Y(), -1.0, 1e-08); + } + + void testEqualityOperator() { + V3D direction1(1.0, 1.0, 1.0); + V3D direction2(1.0, 1.0, 1.0); + bool out = false; + for (size_t i = 0; i < m_sampleSize; i++) { + out = direction1 == direction2; + } + TS_ASSERT(out) + } + + void testInequalityOperator() { + V3D direction1(1.0, 1.0, 1.0); + V3D direction2(1.0, 1.0, 1.0); + bool out = false; + for (size_t i = 0; i < m_sampleSize; i++) { + out = direction1 != direction2; + } + TS_ASSERT(!out) + } + + void testLessThanOperator() { + V3D direction1(1.0, 1.0, 1.0); + V3D direction2(1.0, 1.0, 1.0); + bool out = false; + for (size_t i = 0; i < m_sampleSize; i++) { + out = direction1 < direction2; + } + TS_ASSERT(!out) + } + + void testGreaterThanOperator() { + V3D direction1(1.0, 1.0, 1.0); + V3D direction2(1.0, 1.0, 1.0); + bool out = false; + for (size_t i = 0; i < m_sampleSize; i++) { + out = direction1 > direction2; + } + TS_ASSERT(!out) + } + private: Mantid::Kernel::Matrix<double> m_rotx; + size_t m_sampleSize; }; #endif diff --git a/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp b/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp index 3bfe457e09cd1dd2463d2635d5fc5f6ab3d811c0..b6da15e974436e2e2fadff1f042b00b8a70572c1 100644 --- a/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp +++ b/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp @@ -261,8 +261,17 @@ void CalculateCoverageDGS::exec() { // Qmax is at kf=kfmin or kf=kfmax m_ki = std::sqrt(energyToK * m_Ei); - m_kfmin = std::sqrt(energyToK * (m_Ei - m_dEmin)); - m_kfmax = std::sqrt(energyToK * (m_Ei - m_dEmax)); + if (m_Ei > m_dEmin) { + m_kfmin = std::sqrt(energyToK * (m_Ei - m_dEmin)); + } else { + m_kfmin = 0.; + } + if (m_Ei > m_dEmax) { + m_kfmax = std::sqrt(energyToK * (m_Ei - m_dEmax)); + } else { + m_kfmax = 0; + } + double QmaxTemp = sqrt(m_ki * m_ki + m_kfmin * m_kfmin - 2 * m_ki * m_kfmin * cos(ttmax)); double Qmax = QmaxTemp; diff --git a/Framework/MDAlgorithms/src/LoadDNSSCD.cpp b/Framework/MDAlgorithms/src/LoadDNSSCD.cpp index 3592d4f9b650734bbc5b661c52bd2cda239033b3..607010072f0537cff2d1237499fa060a16ec5191 100644 --- a/Framework/MDAlgorithms/src/LoadDNSSCD.cpp +++ b/Framework/MDAlgorithms/src/LoadDNSSCD.cpp @@ -554,7 +554,7 @@ void LoadDNSSCD::fillOutputWorkspace(double wavelength) { int64_t nchannels = static_cast<int64_t>(ds.signal[i].size()); if ((theta > theta_min) && (theta < theta_max)) { PARALLEL_FOR_IF(Kernel::threadSafe(*m_OutWS, *normWS)) - for (auto channel = 0; channel < nchannels; channel++) { + for (int64_t channel = 0; channel < nchannels; channel++) { PARALLEL_START_INTERUPT_REGION double signal = ds.signal[i][channel]; signal_t error = std::sqrt(signal); diff --git a/Framework/Properties/Mantid.properties.template b/Framework/Properties/Mantid.properties.template index c0857286c9c631fa49f572eff2c55e19fea19300..36893c2f6af0bedfd0b10c412818a0e42924d328 100644 --- a/Framework/Properties/Mantid.properties.template +++ b/Framework/Properties/Mantid.properties.template @@ -20,7 +20,7 @@ default.instrument = Q.convention = Inelastic # Set of PyQt interfaces to add to the Interfaces menu, separated by a space. Interfaces are seperated from their respective categories by a "/". -mantidqt.python_interfaces = Direct/DGS_Reduction.py Direct/DGSPlanner.py Direct/PyChop.py Direct/MSlice.py SANS/ORNL_SANS.py Utility/TofConverter.py Reflectometry/ISIS_Reflectometry_Old.py Diffraction/Powder_Diffraction_Reduction.py Utility/FilterEvents.py Diffraction/HFIR_Powder_Diffraction_Reduction.py Diffraction/HFIR_4Circle_Reduction.py Utility/QECoverage.py SANS/ISIS_SANS_v2_experimental.py Muon/Frequency_Domain_Analysis.py Muon/Elemental_Analysis.py +mantidqt.python_interfaces = Direct/DGS_Reduction.py Direct/DGSPlanner.py Direct/PyChop.py Direct/MSlice.py SANS/ORNL_SANS.py Utility/TofConverter.py Reflectometry/ISIS_Reflectometry_Old.py Diffraction/Powder_Diffraction_Reduction.py Utility/FilterEvents.py Diffraction/HFIR_4Circle_Reduction.py Utility/QECoverage.py SANS/ISIS_SANS_v2_experimental.py Muon/Frequency_Domain_Analysis.py Muon/Elemental_Analysis.py # Directory containing the above startup scripts mantidqt.python_interfaces_directory = @MANTID_ROOT@/scripts diff --git a/Framework/PythonInterface/CMakeLists.txt b/Framework/PythonInterface/CMakeLists.txt index a11c63f55b1035c004a6e49e7116eaf51f1d6046..959fd20f4b05c09a3608187f64db10777981c223 100644 --- a/Framework/PythonInterface/CMakeLists.txt +++ b/Framework/PythonInterface/CMakeLists.txt @@ -7,19 +7,21 @@ ########################################################################### # Set local dependencies ########################################################################### +# boost python set ( old_boost ${Boost_LIBRARIES} ) set ( Boost_LIBRARIES ) # Empty out the variable after previous use - find_package ( BoostPython REQUIRED ) - set ( Boost_LIBRARIES ${Boost_LIBRARIES} ${old_boost}) -include_directories ( SYSTEM ${PYTHON_INCLUDE_PATH} ) - +# NumPy find_package ( Numpy REQUIRED ) +include_directories ( SYSTEM ${PYTHON_INCLUDE_PATH} ) include_directories ( SYSTEM ${PYTHON_NUMPY_INCLUDE_DIR} ) + +# Base of the subproject include dir set ( HEADER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/inc/MantidPythonInterface ) -include_directories ( inc ) + +# Common definitions add_definitions ( -DBOOST_PYTHON_NO_LIB -DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION ) if ( CMAKE_COMPILER_IS_GNUCXX AND Boost_MAJOR_VERSION EQUAL "1" AND Boost_MINOR_VERSION GREATER "63" AND Boost_MINOR_VERSION LESS "66" ) @@ -27,8 +29,12 @@ if ( CMAKE_COMPILER_IS_GNUCXX AND Boost_MAJOR_VERSION EQUAL "1" AND # this definition: https://github.com/boostorg/python/issues/131 add_definitions ( -DBOOST_PYTHON_USE_GCC_SYMBOL_VISIBILITY ) endif () + set ( PYTHON_DEPS ${MPI_CXX_LIBRARIES} ) +# First, common Python code +add_subdirectory ( core ) + #################################################################################### # A function for generating the exports # - MODULE_TEMPLATE: The file containing the @EXPORT_FUNCTIONS@ and @EXPORT_DECLARE@ flags to replace @@ -89,6 +95,11 @@ endfunction() ########################################################################### # mantid package ########################################################################### +# All targets can see these includes +include_directories ( core/inc ) +# TODO: Move all common code to the core library to +# remove the need for linking submodules together +include_directories ( inc ) add_subdirectory ( mantid ) ########################################################################### diff --git a/Framework/PythonInterface/core/CMakeLists.txt b/Framework/PythonInterface/core/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..47afc4f136343346e0614ffa93dca8697ce828fa --- /dev/null +++ b/Framework/PythonInterface/core/CMakeLists.txt @@ -0,0 +1,56 @@ +########################################################################### +# Core Python/C++ code used by all layers accessing the Python C API. +# It contains functionality such as classes for GIL management, conversion +# of Python errors to exceptions etc. +# +# It should not link to any other Mantid libraries. +########################################################################### +set ( SRC_FILES + src/Converters/NDArrayTypeIndex.cpp + src/Converters/WrapWithNDArray.cpp + src/ErrorHandling.cpp + src/GlobalInterpreterLock.cpp + src/NDArray.cpp + src/ReleaseGlobalInterpreterLock.cpp + src/WrapperHelpers.cpp +) + +set ( INC_FILES + inc/MantidPythonInterface/core/Converters/NDArrayTypeIndex.h + inc/MantidPythonInterface/core/Converters/VectorToNDArray.h + inc/MantidPythonInterface/core/Converters/WrapWithNDArray.h + inc/MantidPythonInterface/core/CallMethod.h + inc/MantidPythonInterface/core/DllConfig.h + inc/MantidPythonInterface/core/ErrorHandling.h + inc/MantidPythonInterface/core/GlobalInterpreterLock.h + inc/MantidPythonInterface/core/NDArray.h + inc/MantidPythonInterface/core/ReleaseGlobalInterpreterLock.h + inc/MantidPythonInterface/core/VersionCompat.h + inc/MantidPythonInterface/core/WrapperHelpers.h +) + +# Add the target for this directory +set ( _target_name PythonInterfaceCore ) +add_library ( ${_target_name} ${SRC_FILES} ${INC_FILES} ) +target_include_directories( ${_target_name} PUBLIC inc ) +# Set the name of the generated library +set_target_properties ( ${_target_name} PROPERTIES OUTPUT_NAME MantidPythonInterfaceCore + COMPILE_DEFINITIONS IN_MANTID_PYTHONINTERFACE_CORE ) + +# Dependencies +target_link_libraries ( ${_target_name} PRIVATE + ${TCMALLOC_LIBRARIES_LINKTIME} Types ${Boost_LIBRARIES} ${PYTHON_LIBRARIES} ) + +# Add to the 'Framework/Python' group in MSVS +set_property ( TARGET ${_target_name} PROPERTY FOLDER "MantidFramework/Python" ) + +# rpath settings +if (OSX_VERSION VERSION_GREATER 10.8) + set_target_properties ( ${_target_name} PROPERTIES INSTALL_RPATH "@loader_path/../MacOS" ) +elseif ( ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" ) + set_target_properties ( ${_target_name} PROPERTIES INSTALL_RPATH "\$ORIGIN/../${LIB_DIR}" ) +endif () + +# Installation +install ( TARGETS PythonInterfaceCore ${SYSTEM_PACKAGE_TARGET} DESTINATION + ${LIB_DIR} ) diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Environment/CallMethod.h b/Framework/PythonInterface/core/inc/MantidPythonInterface/core/CallMethod.h similarity index 91% rename from Framework/PythonInterface/inc/MantidPythonInterface/kernel/Environment/CallMethod.h rename to Framework/PythonInterface/core/inc/MantidPythonInterface/core/CallMethod.h index 9ca4595fd9b83ccd3c62b7cd9811897b32d652c7..77a7740558e12bab50e0ce49d8ac348d20379808 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Environment/CallMethod.h +++ b/Framework/PythonInterface/core/inc/MantidPythonInterface/core/CallMethod.h @@ -21,16 +21,15 @@ File change history is stored at: <https://github.com/mantidproject/mantid> */ -#include "MantidPythonInterface/kernel/Environment/ErrorHandling.h" -#include "MantidPythonInterface/kernel/Environment/GlobalInterpreterLock.h" -#include "MantidPythonInterface/kernel/Environment/WrapperHelpers.h" +#include "MantidPythonInterface/core/ErrorHandling.h" +#include "MantidPythonInterface/core/GlobalInterpreterLock.h" +#include "MantidPythonInterface/core/WrapperHelpers.h" #include <boost/python/call_method.hpp> #include <boost/python/class.hpp> namespace Mantid { namespace PythonInterface { -namespace Environment { /// Defines an exception for an undefined attribute struct UndefinedAttributeError { @@ -79,7 +78,7 @@ ReturnType callMethodImpl(PyObject *obj, const char *methodName, template <typename ReturnType, typename... Args> ReturnType callMethodNoCheck(PyObject *obj, const char *methodName, const Args &... args) { - Environment::GlobalInterpreterLock gil; + GlobalInterpreterLock gil; return detail::callMethodImpl<ReturnType, Args...>(obj, methodName, args...); } @@ -97,14 +96,13 @@ template <typename ReturnType, typename... Args> ReturnType callMethod(PyObject *obj, const char *methodName, const Args &... args) { GlobalInterpreterLock gil; - if (Environment::typeHasAttribute(obj, methodName)) { + if (typeHasAttribute(obj, methodName)) { return detail::callMethodImpl<ReturnType, Args...>(obj, methodName, args...); } else { throw UndefinedAttributeError(); } } -} // namespace Environment } // namespace PythonInterface } // namespace Mantid diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/NDArrayTypeIndex.h b/Framework/PythonInterface/core/inc/MantidPythonInterface/core/Converters/NDArrayTypeIndex.h similarity index 92% rename from Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/NDArrayTypeIndex.h rename to Framework/PythonInterface/core/inc/MantidPythonInterface/core/Converters/NDArrayTypeIndex.h index 32d34146d82b579a6303de9b95bcbeaf87912822..8bd5fc35a0c1b71150898bff7b7b6a2c39b8b6e2 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/NDArrayTypeIndex.h +++ b/Framework/PythonInterface/core/inc/MantidPythonInterface/core/Converters/NDArrayTypeIndex.h @@ -22,7 +22,7 @@ File change history is stored at: <https://github.com/mantidproject/mantid> Code Documentation is available at: <http://doxygen.mantidproject.org> */ -#include "MantidPythonInterface/kernel/DllConfig.h" +#include "MantidPythonInterface/core/DllConfig.h" namespace Mantid { namespace PythonInterface { @@ -38,7 +38,7 @@ namespace Converters { * contain a static const NPY_TYPES definition giving * the result of the mapping */ -template <typename T> struct PYTHON_KERNEL_DLL NDArrayTypeIndex { +template <typename T> struct MANTID_PYTHONINTERFACE_CORE_DLL NDArrayTypeIndex { static int typenum; static char typecode; }; diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/VectorToNDArray.h b/Framework/PythonInterface/core/inc/MantidPythonInterface/core/Converters/VectorToNDArray.h similarity index 57% rename from Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/VectorToNDArray.h rename to Framework/PythonInterface/core/inc/MantidPythonInterface/core/Converters/VectorToNDArray.h index 43b3d4089d31d78011536c46b722b77060a0a57b..3cde4ac8083b6e6ee98c726fc41445b37bb0bc2e 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/VectorToNDArray.h +++ b/Framework/PythonInterface/core/inc/MantidPythonInterface/core/Converters/VectorToNDArray.h @@ -1,26 +1,26 @@ #ifndef MANTID_PYTHONINTERFACE_VECTORTONDARRAY_H_ #define MANTID_PYTHONINTERFACE_VECTORTONDARRAY_H_ /** - Copyright © 2012 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge - National Laboratory & European Spallation Source + Copyright © 2012 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source - This file is part of Mantid. + This file is part of Mantid. - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. - File change history is stored at: <https://github.com/mantidproject/mantid> - Code Documentation is available at: <http://doxygen.mantidproject.org> + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> */ #include "MantidKernel/System.h" diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/WrapWithNumpy.h b/Framework/PythonInterface/core/inc/MantidPythonInterface/core/Converters/WrapWithNDArray.h similarity index 95% rename from Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/WrapWithNumpy.h rename to Framework/PythonInterface/core/inc/MantidPythonInterface/core/Converters/WrapWithNDArray.h index 2662a8f14ce563fd664b50993410b734fc2cb3ab..f0f439099edc3272af77d792104ecf7ffdb99ce0 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/WrapWithNumpy.h +++ b/Framework/PythonInterface/core/inc/MantidPythonInterface/core/Converters/WrapWithNDArray.h @@ -1,8 +1,8 @@ -#ifndef MANTID_PYTHONINTERFACE_NUMPYWRAPMODE_H_ -#define MANTID_PYTHONINTERFACE_NUMPYWRAPMODE_H_ +#ifndef MANTID_PYTHONINTERFACE_WRAPWITHNDARRAY_H_ +#define MANTID_PYTHONINTERFACE_WRAPWITHNDARRAY_H_ /** Copyright © 2012 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge - National Laboratory & European Spallation Source + National Laboratory & European Spallation Source This file is part of Mantid. @@ -113,4 +113,4 @@ struct WrapReadWrite { } // namespace PythonInterface } // namespace Mantid -#endif +#endif // MANTID_PYTHONINTERFACE_WRAPWITHNDARRAY_H_ diff --git a/Framework/PythonInterface/core/inc/MantidPythonInterface/core/DllConfig.h b/Framework/PythonInterface/core/inc/MantidPythonInterface/core/DllConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..0abcaab61f6c56456931608f2dd21bb5710b8824 --- /dev/null +++ b/Framework/PythonInterface/core/inc/MantidPythonInterface/core/DllConfig.h @@ -0,0 +1,36 @@ +#ifndef MANTID_PYTHONINTERFACE_CORE_DLLCONFIG_H_ +#define MANTID_PYTHONINTERFACE_CORE_DLLCONFIG_H_ +/* + This file contains the DLLExport/DLLImport linkage configuration for the + PythonInterfaceCore library + + Copyright © 2018 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +#include "MantidKernel/System.h" + +#ifdef IN_MANTID_PYTHONINTERFACE_CORE +#define MANTID_PYTHONINTERFACE_CORE_DLL DLLExport +#else +#define MANTID_PYTHONINTERFACE_CORE_DLL DLLImport +#endif // IN_MANTID_PYTHONINTERFACE_CORE + +#endif // MANTID_PYTHONINTERFACE_CORE_DLLCONFIG_H_ diff --git a/Framework/PythonInterface/core/inc/MantidPythonInterface/core/ErrorHandling.h b/Framework/PythonInterface/core/inc/MantidPythonInterface/core/ErrorHandling.h new file mode 100644 index 0000000000000000000000000000000000000000..6462813ffee0572983f8b9c5e2ea87a7586eeeeb --- /dev/null +++ b/Framework/PythonInterface/core/inc/MantidPythonInterface/core/ErrorHandling.h @@ -0,0 +1,60 @@ +#ifndef MANTID_PYTHONINTERFACE_ERRORHANDLING_H +#define MANTID_PYTHONINTERFACE_ERRORHANDLING_H +/** +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 <http://www.gnu.org/licenses/>. + +File change history is stored at: <https://github.com/mantidproject/mantid> +*/ +#include "MantidPythonInterface/core/DllConfig.h" +#include <stdexcept> +#include <string> + +/** + * This file defines error handling code that transforms + * a Python error state to C++ exceptions. + */ +namespace Mantid { +namespace PythonInterface { + +/** + * Exception type that captures the current Python error state + * as a generic C++ exception for any general Python exception + */ +class MANTID_PYTHONINTERFACE_CORE_DLL PythonException : public std::exception { +public: + PythonException(bool withTrace = true); + + const char *what() const noexcept override { return m_msg.c_str(); } + +private: + std::string m_msg; +}; + +/// Exception type that captures the current Python error state +/// as a C++ std::runtime exception +class MANTID_PYTHONINTERFACE_CORE_DLL PythonRuntimeError + : public std::runtime_error { +public: + PythonRuntimeError(bool withTrace = true); +}; + +} // namespace PythonInterface +} // namespace Mantid + +#endif /* MANTID_PYTHONINTERFACE_ERRORHANDLING_H_ */ diff --git a/Framework/PythonInterface/core/inc/MantidPythonInterface/core/GlobalInterpreterLock.h b/Framework/PythonInterface/core/inc/MantidPythonInterface/core/GlobalInterpreterLock.h new file mode 100644 index 0000000000000000000000000000000000000000..884626ffdee2ea400b95e6ba21864433d01c8e3f --- /dev/null +++ b/Framework/PythonInterface/core/inc/MantidPythonInterface/core/GlobalInterpreterLock.h @@ -0,0 +1,65 @@ +#ifndef MANTID_PYTHONINTERFACE_GLOBALINTERPRETERLOCK_H_ +#define MANTID_PYTHONINTERFACE_GLOBALINTERPRETERLOCK_H_ +/** + 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 <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +#include "MantidPythonInterface/core/DllConfig.h" +#include <boost/python/detail/wrap_python.hpp> + +namespace Mantid { +namespace PythonInterface { + +struct MANTID_PYTHONINTERFACE_CORE_DLL GILState { + PyGILState_STATE m_state; +}; + +/** + * Defines a structure for acquiring/releasing the Python GIL + * using the RAII pattern. + */ +class MANTID_PYTHONINTERFACE_CORE_DLL GlobalInterpreterLock { +public: + /// @name Static Helpers + ///@{ + /// Check state of lock + static bool locked(); + /// Call PyGILState_Ensure + static PyGILState_STATE acquire(); + /// Call PyGILState_Release + static void release(PyGILState_STATE tstate); + ///@} + + /// Default constructor + GlobalInterpreterLock(); + /// Destructor + ~GlobalInterpreterLock(); + +private: + GlobalInterpreterLock(const GlobalInterpreterLock &); + /// Current GIL state + PyGILState_STATE m_state; +}; + +} // namespace PythonInterface +} // namespace Mantid + +#endif /* MANTID_PYTHONINTERFACE_GLOBALINTERPRETERLOCK_H_ */ diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/NdArray.h b/Framework/PythonInterface/core/inc/MantidPythonInterface/core/NDArray.h similarity index 55% rename from Framework/PythonInterface/inc/MantidPythonInterface/kernel/NdArray.h rename to Framework/PythonInterface/core/inc/MantidPythonInterface/core/NDArray.h index e5cd8702ffac9f5e111ccd6d1b61b2228fea2da3..9939e5d5f57ee5aa6643629513a5dbde1246c11b 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/NdArray.h +++ b/Framework/PythonInterface/core/inc/MantidPythonInterface/core/NDArray.h @@ -1,12 +1,20 @@ -#ifndef PYTHONINTERFACE_KERNEL_NDARRAY_H_ -#define PYTHONINTERFACE_KERNEL_NDARRAY_H_ -#include "MantidPythonInterface/kernel/DllConfig.h" +#ifndef PYTHONINTERFACE_CORE_NDARRAY_H_ +#define PYTHONINTERFACE_CORE_NDARRAY_H_ +#include "MantidPythonInterface/core/DllConfig.h" #include <boost/python/object.hpp> namespace Mantid { namespace PythonInterface { -namespace NumPy { + +// It is important that the numpy/arrayobject header +// does not appear in any of our headers as it +// contains some static definitions that cannot be +// allowed to be defined in other translation units + +MANTID_PYTHONINTERFACE_CORE_DLL void importNumpy(); + +MANTID_PYTHONINTERFACE_CORE_DLL PyTypeObject *ndarrayType(); /** * Thin object wrapper around a numpy array. This is intended to take the place @@ -15,21 +23,20 @@ namespace NumPy { * * Only minimal functionality has been ported here. */ -class PYTHON_KERNEL_DLL NdArray : public boost::python::object { +class MANTID_PYTHONINTERFACE_CORE_DLL NDArray : public boost::python::object { public: static bool check(const boost::python::object &obj); - NdArray(const boost::python::object &obj); - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(NdArray, boost::python::object); + NDArray(const boost::python::object &obj); + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(NDArray, boost::python::object); Py_intptr_t const *get_shape() const; int get_nd() const; void *get_data() const; - NdArray astype(char dtype, bool copy = true) const; + NDArray astype(char dtype, bool copy = true) const; }; -} // end namespace NumPy } // end namespace PythonInterface } // end namespace Mantid @@ -40,8 +47,8 @@ namespace converter { * Register ndarray as a type that manages a PyObject* internally. */ template <> -struct PYTHON_KERNEL_DLL - object_manager_traits<Mantid::PythonInterface::NumPy::NdArray> { +struct MANTID_PYTHONINTERFACE_CORE_DLL + object_manager_traits<Mantid::PythonInterface::NDArray> { BOOST_STATIC_CONSTANT(bool, is_specialized = true); static bool check(PyObject *obj); static python::detail::new_reference adopt(PyObject *obj); @@ -51,4 +58,4 @@ struct PYTHON_KERNEL_DLL } // end namespace python } // end namespace boost -#endif // PYTHONINTERFACE_KERNEL_NDARRAY_H_ +#endif // PYTHONINTERFACE_CORE_NDARRAY_H_ diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Environment/ReleaseGlobalInterpreterLock.h b/Framework/PythonInterface/core/inc/MantidPythonInterface/core/ReleaseGlobalInterpreterLock.h similarity index 67% rename from Framework/PythonInterface/inc/MantidPythonInterface/kernel/Environment/ReleaseGlobalInterpreterLock.h rename to Framework/PythonInterface/core/inc/MantidPythonInterface/core/ReleaseGlobalInterpreterLock.h index c1f45931c66f02c8eb85548a111f042f50274070..b53b9d9231bf8a1d4859a0f3a88887ee331a9bb6 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Environment/ReleaseGlobalInterpreterLock.h +++ b/Framework/PythonInterface/core/inc/MantidPythonInterface/core/ReleaseGlobalInterpreterLock.h @@ -1,19 +1,18 @@ #ifndef MANTID_PYTHONINTERFACE_RELEASEGLOBALINTERPRETERLOCK_H_ #define MANTID_PYTHONINTERFACE_RELEASEGLOBALINTERPRETERLOCK_H_ -#include "MantidPythonInterface/kernel/DllConfig.h" +#include "MantidPythonInterface/core/DllConfig.h" #include <boost/python/detail/wrap_python.hpp> namespace Mantid { namespace PythonInterface { -namespace Environment { /** - * Defines a structure for releaseing the Python GIL + * Defines a structure for releasing the Python GIL * using the RAII pattern. This releases the Python GIL * for the duration of the current scope. */ -class PYTHON_KERNEL_DLL ReleaseGlobalInterpreterLock { +class MANTID_PYTHONINTERFACE_CORE_DLL ReleaseGlobalInterpreterLock { public: /// Default constructor ReleaseGlobalInterpreterLock(); @@ -21,15 +20,11 @@ public: ~ReleaseGlobalInterpreterLock(); private: - // Stores the current python trace used to track where in - // a python script you are. Py_tracefunc m_tracefunc; PyObject *m_tracearg; - /// Saved thread state PyThreadState *m_saved; }; -} // namespace Environment } // namespace PythonInterface } // namespace Mantid diff --git a/Framework/PythonInterface/core/inc/MantidPythonInterface/core/VersionCompat.h b/Framework/PythonInterface/core/inc/MantidPythonInterface/core/VersionCompat.h new file mode 100644 index 0000000000000000000000000000000000000000..e879bc0969c44bea9bf018a4b48548661a6d7a8c --- /dev/null +++ b/Framework/PythonInterface/core/inc/MantidPythonInterface/core/VersionCompat.h @@ -0,0 +1,47 @@ +#ifndef MANTID_PYTHONINTERFACE_CORE_PYTHONCOMPAT_H +#define MANTID_PYTHONINTERFACE_CORE_PYTHONCOMPAT_H +/* + Copyright © 2018 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +#include <boost/python/detail/wrap_python.hpp> + +// Macros for 2/3 compatability +#if PY_VERSION_HEX >= 0x03000000 +#define IS_PY3K +#define INT_CHECK PyLong_Check +#define TO_LONG PyLong_AsLong +#define FROM_LONG PyLong_FromLong +#define STR_CHECK PyUnicode_Check +#define TO_CSTRING _PyUnicode_AsString +#define FROM_CSTRING PyUnicode_FromString +#define CODE_OBJECT(x) x +#else +#define INT_CHECK PyInt_Check +#define TO_LONG PyInt_AsLong +#define STR_CHECK PyString_Check +#define TO_CSTRING PyString_AsString +#define FROM_CSTRING PyString_FromString +#define CODE_OBJECT(x) (PyCodeObject *)x +#define FROM_LONG PyInt_FromLong +#endif + +#endif // MANTID_PYTHONINTERFACE_CORE_PYTHONCOMPAT_H diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Environment/WrapperHelpers.h b/Framework/PythonInterface/core/inc/MantidPythonInterface/core/WrapperHelpers.h similarity index 87% rename from Framework/PythonInterface/inc/MantidPythonInterface/kernel/Environment/WrapperHelpers.h rename to Framework/PythonInterface/core/inc/MantidPythonInterface/core/WrapperHelpers.h index 952b887222f9d46f73b7dc04945907845cde9b03..d5b8245562a4ecdc5d1007b9ce9e1b27cbc80c65 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Environment/WrapperHelpers.h +++ b/Framework/PythonInterface/core/inc/MantidPythonInterface/core/WrapperHelpers.h @@ -4,13 +4,12 @@ //----------------------------------------------------------------------------- // Includes //----------------------------------------------------------------------------- -#include "MantidKernel/System.h" +#include "MantidPythonInterface/core/DllConfig.h" #include <boost/python/wrapper.hpp> -#include <stdexcept> namespace Mantid { namespace PythonInterface { -namespace Environment { + /** This namespace contains helper functions for classes that are overridden in Python @@ -38,11 +37,12 @@ Code Documentation is available at: <http://doxygen.mantidproject.org> */ /// Checks whether the given object's type dictionary contains the named /// attribute. -bool DLLExport typeHasAttribute(PyObject *obj, const char *attr); +bool MANTID_PYTHONINTERFACE_CORE_DLL typeHasAttribute(PyObject *obj, + const char *attr); /// An overload for the above taking a wrapper reference -bool DLLExport typeHasAttribute( +bool MANTID_PYTHONINTERFACE_CORE_DLL typeHasAttribute( const boost::python::detail::wrapper_base &wrapper, const char *attr); -} // namespace Environment + } // namespace PythonInterface } // namespace Mantid diff --git a/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayTypeIndex.cpp b/Framework/PythonInterface/core/src/Converters/NDArrayTypeIndex.cpp similarity index 91% rename from Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayTypeIndex.cpp rename to Framework/PythonInterface/core/src/Converters/NDArrayTypeIndex.cpp index 5e12b48087b10c48ab2863e759a62d419278ec05..49a294658e8c46e60d52526ac3b69e159031e085 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayTypeIndex.cpp +++ b/Framework/PythonInterface/core/src/Converters/NDArrayTypeIndex.cpp @@ -1,17 +1,14 @@ //----------------------------------------------------------------------------- // Includes //----------------------------------------------------------------------------- -#include "MantidPythonInterface/kernel/Converters/NDArrayTypeIndex.h" +#include "MantidPythonInterface/core/Converters/NDArrayTypeIndex.h" +#include "MantidTypes/Core/DateAndTime.h" #include <boost/python/detail/prefix.hpp> // Safe include of Python.h #define PY_ARRAY_UNIQUE_SYMBOL KERNEL_ARRAY_API #define NO_IMPORT_ARRAY -#include "MantidTypes/Core/DateAndTime.h" #include <numpy/arrayobject.h> -#include <boost/python/type_id.hpp> -#include <stdexcept> - namespace Mantid { namespace PythonInterface { namespace Converters { diff --git a/Framework/PythonInterface/mantid/kernel/src/Converters/WrapWithNumpy.cpp b/Framework/PythonInterface/core/src/Converters/WrapWithNDArray.cpp similarity index 94% rename from Framework/PythonInterface/mantid/kernel/src/Converters/WrapWithNumpy.cpp rename to Framework/PythonInterface/core/src/Converters/WrapWithNDArray.cpp index 871320aedd9309008edda3ee195d2786c8ed8560..16b169967f3643e3146a4f87e49bdf6a62f16a06 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Converters/WrapWithNumpy.cpp +++ b/Framework/PythonInterface/core/src/Converters/WrapWithNDArray.cpp @@ -1,11 +1,11 @@ //----------------------------------------------------------------------------- // Includes //----------------------------------------------------------------------------- -#include "MantidPythonInterface/kernel/Converters/WrapWithNumpy.h" -#include "MantidPythonInterface/kernel/Converters/NDArrayTypeIndex.h" +#include "MantidPythonInterface/core/Converters/WrapWithNDArray.h" +#include "MantidPythonInterface/core/Converters/NDArrayTypeIndex.h" #include <boost/python/list.hpp> -#define PY_ARRAY_UNIQUE_SYMBOL KERNEL_ARRAY_API +#define PY_ARRAY_UNIQUE_SYMBOL CORE_ARRAY_API #define NO_IMPORT_ARRAY #include <numpy/arrayobject.h> diff --git a/Framework/PythonInterface/mantid/kernel/src/Environment/ErrorHandling.cpp b/Framework/PythonInterface/core/src/ErrorHandling.cpp similarity index 93% rename from Framework/PythonInterface/mantid/kernel/src/Environment/ErrorHandling.cpp rename to Framework/PythonInterface/core/src/ErrorHandling.cpp index fe4e80e0cb0183d078a5a33b537446ad89bc89a3..852ca0b0059c2130bdcc5282e94a9cd65baf9017 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Environment/ErrorHandling.cpp +++ b/Framework/PythonInterface/core/src/ErrorHandling.cpp @@ -1,12 +1,12 @@ //------------------------------------------- // Includes //------------------------------------------- -#include "MantidPythonInterface/kernel/Environment/ErrorHandling.h" -#include "MantidPythonInterface/kernel/Environment/GlobalInterpreterLock.h" +#include "MantidPythonInterface/core/ErrorHandling.h" +#include "MantidPythonInterface/core/GlobalInterpreterLock.h" #include <boost/python/extract.hpp> #include <boost/python/object.hpp> -#include <frameobject.h> //Python +#include <frameobject.h> #include <sstream> #include <stdexcept> @@ -15,7 +15,7 @@ using boost::python::extract; namespace Mantid { namespace PythonInterface { -namespace Environment { + namespace { /** @@ -104,6 +104,6 @@ PythonException::PythonException(bool withTrace) */ PythonRuntimeError::PythonRuntimeError(bool withTrace) : std::runtime_error(exceptionToString(withTrace)) {} -} // namespace Environment + } // namespace PythonInterface } // namespace Mantid diff --git a/Framework/PythonInterface/mantid/kernel/src/Environment/GlobalInterpreterLock.cpp b/Framework/PythonInterface/core/src/GlobalInterpreterLock.cpp similarity index 73% rename from Framework/PythonInterface/mantid/kernel/src/Environment/GlobalInterpreterLock.cpp rename to Framework/PythonInterface/core/src/GlobalInterpreterLock.cpp index e9caab035be88eaf8ec272ca4561f829ecb1b3ee..4cbf57acd28a972744429f18062fca165dbf333f 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Environment/GlobalInterpreterLock.cpp +++ b/Framework/PythonInterface/core/src/GlobalInterpreterLock.cpp @@ -1,13 +1,26 @@ -#include "MantidPythonInterface/kernel/Environment/GlobalInterpreterLock.h" +#include "MantidPythonInterface/core/GlobalInterpreterLock.h" +#include "MantidPythonInterface/core/VersionCompat.h" namespace Mantid { namespace PythonInterface { -namespace Environment { //------------------------------------------------------------------------------ // GlobalInterpreterLock Static helpers //------------------------------------------------------------------------------ +/** + * Check if the current thread has the lock + * @return True if the current thread holds the GIL, false otherwise + */ +bool GlobalInterpreterLock::locked() { +#if defined(IS_PY3K) + return (PyGILState_Check() == 1); +#else + PyThreadState *ts = _PyThreadState_Current; + return (ts && ts == PyGILState_GetThisThreadState()); +#endif +} + /** * @return A handle to the Python threadstate before the acquire() call. */ @@ -39,6 +52,6 @@ GlobalInterpreterLock::GlobalInterpreterLock() : m_state(this->acquire()) {} * this object was created. */ GlobalInterpreterLock::~GlobalInterpreterLock() { this->release(m_state); } -} // namespace Environment + } // namespace PythonInterface } // namespace Mantid diff --git a/Framework/PythonInterface/mantid/kernel/src/NdArray.cpp b/Framework/PythonInterface/core/src/NDArray.cpp similarity index 59% rename from Framework/PythonInterface/mantid/kernel/src/NdArray.cpp rename to Framework/PythonInterface/core/src/NDArray.cpp index f923d753bc9edf84911a7fc76daa2184d953499b..c60d4b9f2503529080282b63db170a136d8f3e0b 100644 --- a/Framework/PythonInterface/mantid/kernel/src/NdArray.cpp +++ b/Framework/PythonInterface/core/src/NDArray.cpp @@ -1,62 +1,80 @@ -#include "MantidPythonInterface/kernel/NdArray.h" -#include "MantidPythonInterface/kernel/Converters/PyArrayType.h" +#include "MantidPythonInterface/core/NDArray.h" #include <boost/python/detail/prefix.hpp> // Safe include of Python.h #include <boost/python/tuple.hpp> -#define PY_ARRAY_UNIQUE_SYMBOL KERNEL_ARRAY_API -#define NO_IMPORT_ARRAY +#define PY_ARRAY_UNIQUE_SYMBOL CORE_ARRAY_API #include <numpy/arrayobject.h> -using Mantid::PythonInterface::Converters::getNDArrayType; using namespace boost::python; namespace Mantid { namespace PythonInterface { -namespace NumPy { -namespace { -inline PyArrayObject *rawArray(const NdArray &obj) { - return (PyArrayObject *)obj.ptr(); +/** + * Initialize the numpy array api for this DLL. + * @throws runtime_error if Python is not initialized + */ +void importNumpy() { + if (!Py_IsInitialized()) { + throw std::runtime_error( + "Library requires an active Python interpreter.\n" + "Call Py_Initialize at an appropriate point in the application."); + } + + if (_import_array() < 0) { + PyErr_Print(); + PyErr_SetString(PyExc_ImportError, + "numpy.core.multiarray failed to import"); + } } -} // namespace + +/** + * @brief Return the type object for a numpy.NDArray + * @return PyTypeObject* to the Python C-type of nump.NDArray + */ +PyTypeObject *ndarrayType() { return &PyArray_Type; } // ----------------------------------------------------------------------------- -// NdArray - public methods +// NDArray // ----------------------------------------------------------------------------- /** * Check if a python object points to an array type object * @param obj A pointer to an arbitrary python object - * @returns True if the underlying object is an ndarray, false otherwise + * @returns True if the underlying object is an NDArray, false otherwise */ -bool NdArray::check(const object &obj) { return PyArray_Check(obj.ptr()); } +bool NDArray::check(const object &obj) { return PyArray_Check(obj.ptr()); } /** * Construction from a plain object. Assumes the array is actually a * a numpy array * @param obj A wrapper around a Python object pointing to a numpy array */ -NdArray::NdArray(const object &obj) +NDArray::NDArray(const object &obj) : object(detail::borrowed_reference(obj.ptr())) {} /** * @return Return the shape of the array */ -Py_intptr_t const *NdArray::get_shape() const { - return PyArray_DIMS(rawArray(*this)); +Py_intptr_t const *NDArray::get_shape() const { + return PyArray_DIMS(reinterpret_cast<PyArrayObject *>(this->ptr())); } /** * @return Return the number of dimensions of the array */ -int NdArray::get_nd() const { return PyArray_NDIM(rawArray(*this)); } +int NDArray::get_nd() const { + return PyArray_NDIM(reinterpret_cast<PyArrayObject *>(this->ptr())); +} /** * This returns char so stride math works properly on it. It's pretty much * expected that the user will have to reinterpret_cast it. * @return The array's raw data pointer */ -void *NdArray::get_data() const { return PyArray_DATA(rawArray(*this)); } +void *NDArray::get_data() const { + return PyArray_DATA(reinterpret_cast<PyArrayObject *>(this->ptr())); +} /** * Casts (and copies if necessary) the array to the given data type @@ -66,34 +84,36 @@ void *NdArray::get_data() const { return PyArray_DATA(rawArray(*this)); } * the returned array will only be copied if necessary * @return A numpy array with values of the requested type */ -NdArray NdArray::astype(char dtype, bool copy) const { +NDArray NDArray::astype(char dtype, bool copy) const { auto callable = object(handle<>( PyObject_GetAttrString(this->ptr(), const_cast<char *>("astype")))); auto args = tuple(); auto kwargs = object(handle<>(Py_BuildValue( const_cast<char *>("{s:c,s:i}"), "dtype", dtype, "copy", copy ? 1 : 0))); - return NdArray(boost::python::detail::new_reference( + return NDArray(boost::python::detail::new_reference( PyObject_Call(callable.ptr(), args.ptr(), kwargs.ptr()))); } -} // namespace NumPy + } // namespace PythonInterface } // namespace Mantid // ----------------------------------------------------------------------------- -// object_manager_traits specialisation for NdArray +// object_manager_traits specialisation for NDArray // ----------------------------------------------------------------------------- namespace boost { namespace python { namespace converter { +using Mantid::PythonInterface::ndarrayType; + /** * Check if the given object is an instance of the array type * @param obj A python object instance - * @return True if the type matches numpy.ndarray + * @return True if the type matches numpy.NDArray */ -bool object_manager_traits<Mantid::PythonInterface::NumPy::NdArray>::check( +bool object_manager_traits<Mantid::PythonInterface::NDArray>::check( PyObject *obj) { - return ::PyObject_IsInstance(obj, (PyObject *)getNDArrayType()); + return ::PyObject_IsInstance(obj, (PyObject *)ndarrayType()); } /** @@ -104,10 +124,9 @@ bool object_manager_traits<Mantid::PythonInterface::NumPy::NdArray>::check( * or a nullptr if the types don't match */ python::detail::new_reference -object_manager_traits<Mantid::PythonInterface::NumPy::NdArray>::adopt( - PyObject *obj) { +object_manager_traits<Mantid::PythonInterface::NDArray>::adopt(PyObject *obj) { return python::detail::new_reference( - python::pytype_check(getNDArrayType(), obj)); + python::pytype_check(ndarrayType(), obj)); } /** @@ -115,8 +134,8 @@ object_manager_traits<Mantid::PythonInterface::NumPy::NdArray>::adopt( * @return A pointer to the PyTypeObject defining the Python type */ PyTypeObject const * -object_manager_traits<Mantid::PythonInterface::NumPy::NdArray>::get_pytype() { - return getNDArrayType(); +object_manager_traits<Mantid::PythonInterface::NDArray>::get_pytype() { + return ndarrayType(); } } // namespace converter } // namespace python diff --git a/Framework/PythonInterface/mantid/kernel/src/Environment/ReleaseGlobalInterpreterLock.cpp b/Framework/PythonInterface/core/src/ReleaseGlobalInterpreterLock.cpp similarity index 84% rename from Framework/PythonInterface/mantid/kernel/src/Environment/ReleaseGlobalInterpreterLock.cpp rename to Framework/PythonInterface/core/src/ReleaseGlobalInterpreterLock.cpp index 89d8b4c56a0d437bb77a961f8d0faf1bc045eea5..c17a79a68726711a98fbd38d19cbc62ae2ec5fc5 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Environment/ReleaseGlobalInterpreterLock.cpp +++ b/Framework/PythonInterface/core/src/ReleaseGlobalInterpreterLock.cpp @@ -1,8 +1,7 @@ -#include "MantidPythonInterface/kernel/Environment/ReleaseGlobalInterpreterLock.h" +#include "MantidPythonInterface/core/ReleaseGlobalInterpreterLock.h" namespace Mantid { namespace PythonInterface { -namespace Environment { /** * Ensures this thread releases the Python GIL also save trace information @@ -27,6 +26,5 @@ ReleaseGlobalInterpreterLock::~ReleaseGlobalInterpreterLock() { Py_XDECREF(m_tracearg); } -} // namespace Environment } // namespace PythonInterface -} // namespace Mantid \ No newline at end of file +} // namespace Mantid diff --git a/Framework/PythonInterface/mantid/kernel/src/Environment/WrapperHelpers.cpp b/Framework/PythonInterface/core/src/WrapperHelpers.cpp similarity index 93% rename from Framework/PythonInterface/mantid/kernel/src/Environment/WrapperHelpers.cpp rename to Framework/PythonInterface/core/src/WrapperHelpers.cpp index becd296bcb765cc004d141ae8bdb2566881994e0..e76e80a10cf5fe5a7d21b4888661f201ad19cf7b 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Environment/WrapperHelpers.cpp +++ b/Framework/PythonInterface/core/src/WrapperHelpers.cpp @@ -1,13 +1,13 @@ //----------------------------------------------------------------------------- // Includes //----------------------------------------------------------------------------- -#include "MantidPythonInterface/kernel/Environment/WrapperHelpers.h" +#include "MantidPythonInterface/core/WrapperHelpers.h" using namespace boost::python; namespace Mantid { namespace PythonInterface { -namespace Environment { + /** Checks whether the given object's type dictionary contains the named *attribute. * @@ -40,6 +40,6 @@ bool typeHasAttribute(const boost::python::detail::wrapper_base &wrapper, using namespace boost::python::detail; return typeHasAttribute(wrapper_base_::get_owner(wrapper), attr); } -} // namespace Environment + } // namespace PythonInterface } // namespace Mantid diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/api/FitFunctions/IFunctionAdapter.h b/Framework/PythonInterface/inc/MantidPythonInterface/api/FitFunctions/IFunctionAdapter.h index f93dc9e67627f8bad065a0c28ddddf577787debe..b2401b1669b7eef5e428638425e91b3c9c9a1948 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/api/FitFunctions/IFunctionAdapter.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/api/FitFunctions/IFunctionAdapter.h @@ -27,6 +27,7 @@ //----------------------------------------------------------------------------- #include "MantidAPI/IFunction.h" +#include <boost/python/list.hpp> #include <boost/python/object.hpp> namespace Mantid { @@ -69,7 +70,7 @@ public: void setAttribute(const std::string &attName, const API::IFunction::Attribute &attr) override; /// Split this function (if needed) into a list of independent functions - static boost::python::object createPythonEquivalentFunctions(IFunction &self); + static boost::python::list createPythonEquivalentFunctions(IFunction &self); // Each overload of declareParameter requires a different name as we // can't use a function pointer with a virtual base class diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/MatrixToNDArray.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/MatrixToNDArray.h index 8b0795b370f67c1e687ab66d9382a26fe4822fdb..28fdb0ca2a7b08ca7020390cf1df7ecac3e29aae 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/MatrixToNDArray.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/MatrixToNDArray.h @@ -23,8 +23,7 @@ Code Documentation is available at: <http://doxygen.mantidproject.org> */ #include "MantidKernel/Matrix.h" -#include "MantidKernel/System.h" -#include "MantidPythonInterface/kernel/Converters/WrapWithNumpy.h" +#include "MantidPythonInterface/core/Converters/WrapWithNDArray.h" #include <boost/python/detail/prefix.hpp> namespace Mantid { diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/NDArrayToVector.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/NDArrayToVector.h index aa2035c5fa7ca1f2a9c5d56e067b3d7340ba9962..602ee86baf40cf36ee9da8e7c791039ffc9c42fb 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/NDArrayToVector.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/NDArrayToVector.h @@ -23,7 +23,7 @@ Code Documentation is available at: <http://doxygen.mantidproject.org> */ #include "MantidKernel/System.h" -#include "MantidPythonInterface/kernel/NdArray.h" +#include "MantidPythonInterface/core/NDArray.h" #include <vector> namespace Mantid { @@ -39,7 +39,7 @@ template <typename DestElementType> struct DLLExport NDArrayToVector { using TypedVectorIterator = typename std::vector<DestElementType>::iterator; /// Constructor - NDArrayToVector(const NumPy::NdArray &value); + NDArrayToVector(const NDArray &value); /// Create a new vector from the contents of the array const TypedVector operator()(); /// Fill the container with data from the array @@ -49,7 +49,7 @@ private: void throwIfSizeMismatched(const TypedVector &dest) const; // reference to the held array - NumPy::NdArray m_arr; + NDArray m_arr; }; } // namespace Converters } // namespace PythonInterface diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/PyArrayType.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/PyArrayType.h deleted file mode 100644 index aa88003884a2a4341e0ae3f918af3bbb28ed004c..0000000000000000000000000000000000000000 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/PyArrayType.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef MANTID_PYTHONINTERFACE_CONVERTERS_PYARRAYTYPE_H_ -#define MANTID_PYTHONINTERFACE_CONVERTERS_PYARRAYTYPE_H_ -/** - 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 <http://www.gnu.org/licenses/>. - - File change history is stored at: <https://github.com/mantidproject/mantid> - Code Documentation is available at: <http://doxygen.mantidproject.org> - */ -#include "MantidKernel/System.h" -#include <boost/python/detail/prefix.hpp> - -namespace Mantid { -namespace PythonInterface { -namespace Converters { -// -// It is important that the numpy/arrayobject header -// does not appear in any of our headers as it -// contains some static definitions that cannot be -// allowed to be defined in other translation units - -// Numpy array type -DLLExport PyTypeObject *getNDArrayType(); -} // namespace Converters -} // namespace PythonInterface -} // namespace Mantid - -#endif /* PYARRAYTYPE_H_ */ diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/DataServiceExporter.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/DataServiceExporter.h index a5749d99a2bf8606fe20d7f323c92af0cf3ab2f1..247f1f78983937e1a5dc4271539e530bf83a5269 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/DataServiceExporter.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/DataServiceExporter.h @@ -198,7 +198,7 @@ template <typename SvcType, typename SvcPtrType> struct DataServiceExporter { * @param self :: A reference to the ADS object that called this method * @returns A python list created from the set of strings */ - static boost::python::object getObjectNamesAsList(SvcType &self) { + static boost::python::list getObjectNamesAsList(SvcType &self) { boost::python::list names; const auto keys = self.getObjectNames(); for (auto itr = keys.begin(); itr != keys.end(); ++itr) { diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Environment/ErrorHandling.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Environment/ErrorHandling.h deleted file mode 100644 index f4ac9b89a64c26b7c8fffd69c56e2ce989f5c805..0000000000000000000000000000000000000000 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Environment/ErrorHandling.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef MANTID_PYTHONINTERFACE_ERRORHANDLING_H -#define MANTID_PYTHONINTERFACE_ERRORHANDLING_H -/** - 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 <http://www.gnu.org/licenses/>. - - File change history is stored at: <https://github.com/mantidproject/mantid> -*/ -#include "MantidKernel/System.h" -#include <stdexcept> -#include <string> - -/** - * This file defines error handling code that transforms - * a Python error state to C++ exceptions. - */ -namespace Mantid { -namespace PythonInterface { -namespace Environment { - -/** - * Exception type that captures the current Python error state - * as a generic C++ exception for any general Python exception - */ -class DLLExport PythonException : public std::exception { -public: - PythonException(bool withTrace = true); - - const char *what() const noexcept override { return m_msg.c_str(); } - -private: - std::string m_msg; -}; - -/// Exception type that captures the current Python error state -/// as a C++ std::runtime exception -class DLLExport PythonRuntimeError : public std::runtime_error { -public: - PythonRuntimeError(bool withTrace = true); -}; -} // namespace Environment -} // namespace PythonInterface -} // namespace Mantid - -#endif /* MANTID_PYTHONINTERFACE_ERRORHANDLING_H_ */ diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Environment/GlobalInterpreterLock.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Environment/GlobalInterpreterLock.h deleted file mode 100644 index 5a84d1df51967fef13aae5978c978a3a0132763f..0000000000000000000000000000000000000000 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Environment/GlobalInterpreterLock.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef MANTID_PYTHONINTERFACE_GLOBALINTERPRETERLOCK_H_ -#define MANTID_PYTHONINTERFACE_GLOBALINTERPRETERLOCK_H_ -/** - Defines an RAII class for dealing with the Python GIL in non-python - created C-threads - - 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 <http://www.gnu.org/licenses/>. - - File change history is stored at: <https://github.com/mantidproject/mantid> - Code Documentation is available at: <http://doxygen.mantidproject.org> -*/ -#include "MantidPythonInterface/kernel/DllConfig.h" -#include <boost/python/detail/wrap_python.hpp> - -namespace Mantid { -namespace PythonInterface { -namespace Environment { - -/** - * Defines a structure for acquiring/releasing the Python GIL - * using the RAII pattern. - * - * This class is copied in - * MantidQt/API/inc/MantidQtAPI/PythonThreading.h as we have no good - * way to share code with that without tight coupling the GUI layer - * to PythonInterface - */ -class PYTHON_KERNEL_DLL GlobalInterpreterLock { -public: - /// @name Static Helpers - ///@{ - /// Call PyGILState_Ensure - static PyGILState_STATE acquire(); - /// Call PyGILState_Release - static void release(PyGILState_STATE tstate); - ///@} - - /// Default constructor - GlobalInterpreterLock(); - /// Destructor - ~GlobalInterpreterLock(); - -private: - GlobalInterpreterLock(const GlobalInterpreterLock &); - /// Current GIL state - PyGILState_STATE m_state; -}; -} // namespace Environment -} // namespace PythonInterface -} // namespace Mantid - -#endif /* MANTID_PYTHONINTERFACE_GLOBALINTERPRETERLOCK_H_ */ diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/MatrixToNumpy.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/MatrixToNumpy.h index c0f74ad11488eaf658ca2c01d24f2bbf5d31af37..7cbec014a6b6aa009f54988629aafe7518163a80 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/MatrixToNumpy.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/MatrixToNumpy.h @@ -24,9 +24,9 @@ */ #include "MantidKernel/Matrix.h" #include "MantidKernel/System.h" +#include "MantidPythonInterface/core/NDArray.h" #include "MantidPythonInterface/kernel/Converters/CloneToNumpy.h" #include "MantidPythonInterface/kernel/Converters/MatrixToNDArray.h" -#include "MantidPythonInterface/kernel/Converters/PyArrayType.h" #include <type_traits> @@ -64,9 +64,7 @@ struct MatrixRefToNumpyImpl { ConversionPolicy>()(cmatrix); } - inline PyTypeObject const *get_pytype() const { - return Converters::getNDArrayType(); - } + inline PyTypeObject const *get_pytype() const { return ndarrayType(); } }; template <typename T> @@ -113,9 +111,7 @@ template <typename MatrixType> struct MatrixToNumpyImpl { Converters::Clone>()(cvector); } - inline PyTypeObject const *get_pytype() const { - return Converters::getNDArrayType(); - } + inline PyTypeObject const *get_pytype() const { return ndarrayType(); } }; template <typename T> struct MatrixToNumpy_Requires_Matrix_Return_By_Value {}; diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/VectorToNumpy.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/VectorToNumpy.h index d0ad7d472af55c0332563f28a89d5265dc503145..f2502f4318ea0974c15dd4d445cedb16689735d7 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/VectorToNumpy.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/VectorToNumpy.h @@ -23,9 +23,9 @@ Code Documentation is available at: <http://doxygen.mantidproject.org> */ #include "MantidKernel/System.h" +#include "MantidPythonInterface/core/Converters/VectorToNDArray.h" +#include "MantidPythonInterface/core/NDArray.h" #include "MantidPythonInterface/kernel/Converters/CloneToNumpy.h" -#include "MantidPythonInterface/kernel/Converters/PyArrayType.h" -#include "MantidPythonInterface/kernel/Converters/VectorToNDArray.h" #include <boost/mpl/and.hpp> #include <boost/mpl/if.hpp> @@ -62,9 +62,7 @@ struct VectorRefToNumpyImpl { ConversionPolicy>()(cvector); } - inline PyTypeObject const *get_pytype() const { - return Converters::getNDArrayType(); - } + inline PyTypeObject const *get_pytype() const { return ndarrayType(); } }; template <typename T> @@ -110,9 +108,7 @@ template <typename VectorType> struct VectorToNumpyImpl { Converters::Clone>()(cvector); } - inline PyTypeObject const *get_pytype() const { - return Converters::getNDArrayType(); - } + inline PyTypeObject const *get_pytype() const { return ndarrayType(); } }; template <typename T> diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/PythonObjectInstantiator.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/PythonObjectInstantiator.h index 3fc43779843e01fadab80a4bb34818e2182cb8ec..c6af60a551527f5c10b3c67028bdd35a967e6b0f 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/PythonObjectInstantiator.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/PythonObjectInstantiator.h @@ -3,7 +3,7 @@ /* Copyright © 2011 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge - National Laboratory & European Spallation Source + National Laboratory & European Spallation Source This file is part of Mantid. @@ -28,7 +28,7 @@ // Includes //----------------------------------------------------------------------------- #include "MantidKernel/Instantiator.h" -#include "MantidPythonInterface/kernel/Environment/GlobalInterpreterLock.h" +#include "MantidPythonInterface/core/GlobalInterpreterLock.h" #include <boost/python/extract.hpp> #include <boost/python/object.hpp> @@ -52,7 +52,7 @@ struct GILSharedPtrDeleter { * @param data A pointer to the data to be deleted */ void operator()(void const *data) { - Environment::GlobalInterpreterLock gil; + GlobalInterpreterLock gil; m_deleter(data); } /// Main deleter object @@ -88,7 +88,7 @@ private: template <typename Base> boost::shared_ptr<Base> PythonObjectInstantiator<Base>::createInstance() const { using namespace boost::python; - Environment::GlobalInterpreterLock gil; + GlobalInterpreterLock gil; object instance = m_classObject(); // The instantiator assumes that the exported type uses a diff --git a/Framework/PythonInterface/mantid/CMakeLists.txt b/Framework/PythonInterface/mantid/CMakeLists.txt index 70a8653a97e6f3d8c4d7c6e48f923d94a5d6bc26..a1eb4791b5fe645da2fc7e3118074050f3c2d014 100644 --- a/Framework/PythonInterface/mantid/CMakeLists.txt +++ b/Framework/PythonInterface/mantid/CMakeLists.txt @@ -46,7 +46,7 @@ add_subdirectory ( _plugins ) add_subdirectory ( plots ) # Create an overall target -add_custom_target ( PythonInterface DEPENDS PythonKernelModule +add_custom_target ( PythonInterface DEPENDS PythonInterfaceCore PythonKernelModule PythonGeometryModule PythonAPIModule PythonDataObjectsModule PythonCurveFittingModule PythonPlotsModule ) set_property ( TARGET PythonInterface PROPERTY FOLDER "MantidFramework/Python" ) diff --git a/Framework/PythonInterface/mantid/_plugins/CMakeLists.txt b/Framework/PythonInterface/mantid/_plugins/CMakeLists.txt index 8a7afcaeb06c630e0aa29d1b29fb259b95e9414a..0b1fd0e1346bba88c238136742dbc0554895caaa 100644 --- a/Framework/PythonInterface/mantid/_plugins/CMakeLists.txt +++ b/Framework/PythonInterface/mantid/_plugins/CMakeLists.txt @@ -51,6 +51,7 @@ set_target_output_directory ( PythonCurveFittingModule ${OUTPUT_DIR} .pyd ) # Add the required dependencies target_link_libraries ( PythonCurveFittingModule LINK_PRIVATE ${TCMALLOC_LIBRARIES_LINKTIME} + PythonInterfaceCore PythonAPIModule PythonGeometryModule PythonKernelModule diff --git a/Framework/PythonInterface/mantid/api/CMakeLists.txt b/Framework/PythonInterface/mantid/api/CMakeLists.txt index a62a1ba221047bcd987cb9e52f64cf776c7d640a..0555fbc2c9f40f3c29ad3d37d03b077a572977c5 100644 --- a/Framework/PythonInterface/mantid/api/CMakeLists.txt +++ b/Framework/PythonInterface/mantid/api/CMakeLists.txt @@ -149,7 +149,8 @@ set_python_properties( PythonAPIModule _api ) set_target_output_directory ( PythonAPIModule ${OUTPUT_DIR} .pyd ) # Add the required dependencies -target_link_libraries ( PythonAPIModule LINK_PRIVATE ${TCMALLOC_LIBRARIES_LINKTIME} +target_link_libraries ( PythonAPIModule PRIVATE ${TCMALLOC_LIBRARIES_LINKTIME} + PythonInterfaceCore PythonGeometryModule PythonKernelModule API diff --git a/Framework/PythonInterface/mantid/api/src/Algorithms/AlgorithmObserverAdapter.cpp b/Framework/PythonInterface/mantid/api/src/Algorithms/AlgorithmObserverAdapter.cpp index 91a77d12741c742d95123a6ee442cc0180757cce..3454faf23afae776c4c6876246de156ac7a0507a 100644 --- a/Framework/PythonInterface/mantid/api/src/Algorithms/AlgorithmObserverAdapter.cpp +++ b/Framework/PythonInterface/mantid/api/src/Algorithms/AlgorithmObserverAdapter.cpp @@ -1,10 +1,8 @@ #include "MantidPythonInterface/api/Algorithms/AlgorithmObserverAdapter.h" -#include "MantidPythonInterface/kernel/Environment/CallMethod.h" +#include "MantidPythonInterface/core/CallMethod.h" namespace Mantid { namespace PythonInterface { -using Environment::UndefinedAttributeError; -using Environment::callMethod; AlgorithmObserverAdapter::AlgorithmObserverAdapter(PyObject *self) : API::AlgorithmObserver(), m_self(self) {} diff --git a/Framework/PythonInterface/mantid/api/src/Algorithms/RunPythonScript.cpp b/Framework/PythonInterface/mantid/api/src/Algorithms/RunPythonScript.cpp index f95fcfd5afe024162f1852cd7701d14407833a23..27712624cb2ce11ce105441b93eda1d5c82d478b 100644 --- a/Framework/PythonInterface/mantid/api/src/Algorithms/RunPythonScript.cpp +++ b/Framework/PythonInterface/mantid/api/src/Algorithms/RunPythonScript.cpp @@ -3,8 +3,8 @@ #include "MantidAPI/FileProperty.h" #include "MantidKernel/MandatoryValidator.h" #include "MantidPythonInterface/api/ExtractWorkspace.h" -#include "MantidPythonInterface/kernel/Environment/ErrorHandling.h" -#include "MantidPythonInterface/kernel/Environment/GlobalInterpreterLock.h" +#include "MantidPythonInterface/core/ErrorHandling.h" +#include "MantidPythonInterface/core/GlobalInterpreterLock.h" #include "MantidPythonInterface/kernel/IsNone.h" #include <boost/python/call_method.hpp> @@ -169,7 +169,7 @@ RunPythonScript::executeScript(const std::string &script) const { using namespace boost::python; // Execution - Environment::GlobalInterpreterLock gil; + GlobalInterpreterLock gil; auto locals = doExecuteScript(script); return extractOutputWorkspace(locals); } @@ -192,7 +192,7 @@ RunPythonScript::doExecuteScript(const std::string &script) const { try { boost::python::exec(script.c_str(), globals, locals); } catch (boost::python::error_already_set &) { - throw Environment::PythonException(); + throw PythonException(); } return locals; } diff --git a/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmHistory.cpp b/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmHistory.cpp index 542165aff051a04c6f77059b2e338a0a428c7fb9..f4846915c807d073c9521c922918dfdfdaab1383 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmHistory.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmHistory.cpp @@ -20,12 +20,12 @@ using namespace boost::python; * @param self :: A reference to the AlgorithmHistory that called this method * @returns A python list created from the set of child algorithm histories */ -boost::python::object +boost::python::list getChildrenAsList(boost::shared_ptr<AlgorithmHistory> self) { boost::python::list names; const auto histories = self->getChildHistories(); - for (const auto &historie : histories) { - names.append(historie); + for (const auto &history : histories) { + names.append(history); } return names; } @@ -36,11 +36,11 @@ getChildrenAsList(boost::shared_ptr<AlgorithmHistory> self) { * @param self :: A reference to the AlgorithmHistory that called this method * @returns A python list created from the set of property histories */ -boost::python::object getPropertiesAsList(AlgorithmHistory &self) { +boost::python::list getPropertiesAsList(AlgorithmHistory &self) { boost::python::list names; const auto &histories = self.getProperties(); - for (const auto &historie : histories) { - names.append(historie); + for (const auto &history : histories) { + names.append(history); } return names; } diff --git a/Framework/PythonInterface/mantid/api/src/Exports/CatalogManager.cpp b/Framework/PythonInterface/mantid/api/src/Exports/CatalogManager.cpp index a523a52be2433a1f6425dbc27bef35befb1edf85..b4e03d12e243cedc426d107a333498e354917720 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/CatalogManager.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/CatalogManager.cpp @@ -13,7 +13,7 @@ using namespace boost::python; GET_POINTER_SPECIALIZATION(CatalogManagerImpl) -boost::python::object getActiveSessionsAsList(CatalogManagerImpl &self) { +boost::python::list getActiveSessionsAsList(CatalogManagerImpl &self) { boost::python::list sessions; const auto vecSessions = self.getActiveSessions(); for (const auto &vecSession : vecSessions) { diff --git a/Framework/PythonInterface/mantid/api/src/Exports/FileFinder.cpp b/Framework/PythonInterface/mantid/api/src/Exports/FileFinder.cpp index 73b769c2b9d66da22484a14cf7aaa7757f30725f..240df590e29f5798bba58c234fcd71289bf12977 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/FileFinder.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/FileFinder.cpp @@ -1,6 +1,6 @@ #include "MantidAPI/FileFinder.h" #include "MantidKernel/WarningSuppressions.h" -#include "MantidPythonInterface/kernel/Environment/ReleaseGlobalInterpreterLock.h" +#include "MantidPythonInterface/core/ReleaseGlobalInterpreterLock.h" #include <boost/python/class.hpp> #include <boost/python/overloads.hpp> #include <boost/python/reference_existing_object.hpp> @@ -33,7 +33,7 @@ std::vector<std::string> runFinderProxy(FileFinderImpl &self, // drop the Python threadstate and reset anything installed // via PyEval_SetTrace while we execute the C++ code - // ReleaseGlobalInterpreter does this for us - Mantid::PythonInterface::Environment::ReleaseGlobalInterpreterLock + Mantid::PythonInterface::ReleaseGlobalInterpreterLock releaseGlobalInterpreterLock; return self.findRuns(hinstr); } diff --git a/Framework/PythonInterface/mantid/api/src/Exports/FunctionFactory.cpp b/Framework/PythonInterface/mantid/api/src/Exports/FunctionFactory.cpp index 1b0b867fcc1adc7e5086bfb8226dfcaddc33ce27..b1694bf1a3264554f0b8f7d64347065ca7cf90d2 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/FunctionFactory.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/FunctionFactory.cpp @@ -38,7 +38,7 @@ template <> boost::shared_ptr<IFunction> PythonObjectInstantiator<IFunction>::createInstance() const { using namespace boost::python; - Environment::GlobalInterpreterLock gil; + GlobalInterpreterLock gil; // The class may instantiate different objects depending on whether // it is being created by the function factory or not diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp index 9e50a3c7b85d9bec70d72c76b2cd0354e3add2da..7006bd7fb99b64ef8ed88ec99bdd7b8cce7fc970 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp @@ -9,8 +9,8 @@ #pragma warning(default : 4250) #endif #include "MantidKernel/Strings.h" +#include "MantidPythonInterface/core/GlobalInterpreterLock.h" #include "MantidPythonInterface/kernel/Converters/MapToPyDictionary.h" -#include "MantidPythonInterface/kernel/Environment/GlobalInterpreterLock.h" #include "MantidPythonInterface/kernel/GetPointer.h" #include "MantidPythonInterface/kernel/IsNone.h" #include "MantidPythonInterface/kernel/Policies/VectorToNumpy.h" @@ -34,9 +34,9 @@ using Mantid::Kernel::Direction; using Mantid::Kernel::IPropertyManager; using Mantid::Kernel::Property; using Mantid::PythonInterface::AlgorithmIDProxy; +using Mantid::PythonInterface::GlobalInterpreterLock; using Mantid::PythonInterface::Policies::VectorToNumpy; using Mantid::PythonInterface::isNone; -namespace Environment = Mantid::PythonInterface::Environment; using namespace boost::python; GET_POINTER_SPECIALIZATION(IAlgorithm) @@ -124,10 +124,10 @@ PropertyVector apiOrderedProperties(const IAlgorithm &propMgr) { * @return A Python list of strings */ -object getInputPropertiesWithMandatoryFirst(IAlgorithm &self) { +list getInputPropertiesWithMandatoryFirst(IAlgorithm &self) { PropertyVector properties(apiOrderedProperties(self)); - Environment::GlobalInterpreterLock gil; + GlobalInterpreterLock gil; list names; ToPyString toPyStr; for (const auto &prop : properties) { @@ -145,10 +145,10 @@ object getInputPropertiesWithMandatoryFirst(IAlgorithm &self) { * @param self :: A pointer to the python object wrapping and Algorithm. * @return A Python list of strings */ -object getAlgorithmPropertiesOrdered(IAlgorithm &self) { +list getAlgorithmPropertiesOrdered(IAlgorithm &self) { PropertyVector properties(apiOrderedProperties(self)); - Environment::GlobalInterpreterLock gil; + GlobalInterpreterLock gil; list names; ToPyString toPyStr; for (const auto &prop : properties) { @@ -162,10 +162,10 @@ object getAlgorithmPropertiesOrdered(IAlgorithm &self) { * @param self :: A pointer to the python object wrapping and Algorithm. * @return A Python list of strings */ -object getOutputProperties(IAlgorithm &self) { +list getOutputProperties(IAlgorithm &self) { const PropertyVector &properties(self.getProperties()); // No copy - Environment::GlobalInterpreterLock gil; + GlobalInterpreterLock gil; list names; ToPyString toPyStr; for (const auto &p : properties) { @@ -181,10 +181,10 @@ object getOutputProperties(IAlgorithm &self) { * @param self :: A pointer to the python object wrapping and Algorithm. * @return A Python list of strings */ -object getInOutProperties(IAlgorithm &self) { +list getInOutProperties(IAlgorithm &self) { const PropertyVector &properties(self.getProperties()); // No copy - Environment::GlobalInterpreterLock gil; + GlobalInterpreterLock gil; list names; ToPyString toPyStr; for (const auto &p : properties) { @@ -346,7 +346,7 @@ std::string getWikiSummary(IAlgorithm &self) { * @param self Reference to the calling object * @return validation error dictionary */ -boost::python::object validateInputs(IAlgorithm &self) { +boost::python::dict validateInputs(IAlgorithm &self) { auto map = self.validateInputs(); using MapToPyDictionary = Mantid::PythonInterface::Converters::MapToPyDictionary<std::string, diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IMDHistoWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IMDHistoWorkspace.cpp index 3f2264b8a25392c036225315050482d811ccd3ca..cd7a3884501ef446bcea09370900351eb188e7dd 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/IMDHistoWorkspace.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/IMDHistoWorkspace.cpp @@ -1,8 +1,8 @@ #include "MantidAPI/IMDHistoWorkspace.h" #include "MantidGeometry/MDGeometry/IMDDimension.h" -#include "MantidPythonInterface/kernel/Converters/NDArrayTypeIndex.h" +#include "MantidPythonInterface/core/Converters/NDArrayTypeIndex.h" +#include "MantidPythonInterface/core/NDArray.h" #include "MantidPythonInterface/kernel/GetPointer.h" -#include "MantidPythonInterface/kernel/NdArray.h" #include "MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h" #include <boost/python/class.hpp> @@ -12,9 +12,9 @@ #include <numpy/arrayobject.h> using namespace Mantid::API; +using Mantid::PythonInterface::NDArray; using Mantid::PythonInterface::Registry::RegisterWorkspacePtrToPython; namespace Converters = Mantid::PythonInterface::Converters; -namespace NumPy = Mantid::PythonInterface::NumPy; using namespace boost::python; GET_POINTER_SPECIALIZATION(IMDHistoWorkspace) @@ -115,7 +115,7 @@ PyObject *getNumEventsArrayAsNumpyArray(IMDHistoWorkspace &self) { * @param signal :: The new values * @param fnLabel :: A message prefix to pass if the sizes are incorrect */ -void throwIfSizeIncorrect(IMDHistoWorkspace &self, const NumPy::NdArray &signal, +void throwIfSizeIncorrect(IMDHistoWorkspace &self, const NDArray &signal, const std::string &fnLabel) { auto wsShape = countDimensions(self); const size_t ndims = wsShape.size(); @@ -149,8 +149,7 @@ void throwIfSizeIncorrect(IMDHistoWorkspace &self, const NumPy::NdArray &signal, * the sizes are not * correct */ -void setSignalArray(IMDHistoWorkspace &self, - const NumPy::NdArray &signalValues) { +void setSignalArray(IMDHistoWorkspace &self, const NDArray &signalValues) { throwIfSizeIncorrect(self, signalValues, "setSignalArray"); object rav = signalValues.attr("ravel")("F"); object flattened = rav.attr("flat"); @@ -168,7 +167,7 @@ void setSignalArray(IMDHistoWorkspace &self, * correct */ void setErrorSquaredArray(IMDHistoWorkspace &self, - const NumPy::NdArray &errorSquared) { + const NDArray &errorSquared) { throwIfSizeIncorrect(self, errorSquared, "setErrorSquaredArray"); object rav = errorSquared.attr("ravel")("F"); object flattened = rav.attr("flat"); diff --git a/Framework/PythonInterface/mantid/api/src/Exports/ITableWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/Exports/ITableWorkspace.cpp index ce542bc221ee966e4033c21f659b6f8f9d8fafd3..cba17838e2a65b592bed4ef0e3f17faeb9243a92 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/ITableWorkspace.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/ITableWorkspace.cpp @@ -5,11 +5,11 @@ #include "MantidAPI/WorkspaceFactory.h" #include "MantidAPI/WorkspaceProperty.h" #include "MantidKernel/V3D.h" +#include "MantidPythonInterface/core/NDArray.h" #include "MantidPythonInterface/kernel/Converters/CloneToNumpy.h" #include "MantidPythonInterface/kernel/Converters/NDArrayToVector.h" #include "MantidPythonInterface/kernel/Converters/PySequenceToVector.h" #include "MantidPythonInterface/kernel/GetPointer.h" -#include "MantidPythonInterface/kernel/NdArray.h" #include "MantidPythonInterface/kernel/Policies/VectorToNumpy.h" #include "MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h" @@ -30,16 +30,15 @@ #include <numpy/arrayobject.h> using namespace Mantid::API; -using namespace Mantid::PythonInterface::Policies; +using Mantid::PythonInterface::NDArray; using Mantid::PythonInterface::Registry::RegisterWorkspacePtrToPython; +namespace Policies = Mantid::PythonInterface::Policies; +namespace Converters = Mantid::PythonInterface::Converters; using namespace boost::python; GET_POINTER_SPECIALIZATION(ITableWorkspace) namespace { -namespace bpl = boost::python; -namespace Converters = Mantid::PythonInterface::Converters; -namespace NumPy = Mantid::PythonInterface::NumPy; // Numpy PyArray_IsIntegerScalar is broken for Python 3 for numpy < 1.11 #if PY_MAJOR_VERSION >= 3 @@ -121,13 +120,12 @@ PyObject *getValue(Mantid::API::Column_const_sptr column, * @param row :: The index of the row * @param value :: The value to set */ -void setValue(const Column_sptr column, const int row, - const bpl::object &value) { +void setValue(const Column_sptr column, const int row, const object &value) { const auto &typeID = column->get_type_info(); // Special case: Treat Mantid Boolean as normal bool if (typeID.hash_code() == typeid(Mantid::API::Boolean).hash_code()) { - column->cell<Mantid::API::Boolean>(row) = bpl::extract<bool>(value)(); + column->cell<Mantid::API::Boolean>(row) = extract<bool>(value)(); return; } @@ -142,11 +140,11 @@ void setValue(const Column_sptr column, const int row, // Macros for all other types #define SET_CELL(R, _, T) \ else if (typeID.hash_code() == typeid(T).hash_code()) { \ - column->cell<T>(row) = bpl::extract<T>(value)(); \ + column->cell<T>(row) = extract<T>(value)(); \ } #define SET_VECTOR_CELL(R, _, T) \ else if (typeID.hash_code() == typeid(T).hash_code()) { \ - if (!NumPy::NdArray::check(value)) { \ + if (!NDArray::check(value)) { \ column->cell<T>(row) = \ Converters::PySequenceToVector<T::value_type>(value)(); \ } else { \ @@ -207,7 +205,7 @@ bool addColumnSimple(ITableWorkspace &self, const std::string &type, * @param column Name or index of column * @return PlotType: 0=None, 1=X, 2=Y, 3=Z, 4=xErr, 5=yErr, 6=Label */ -int getPlotType(ITableWorkspace &self, const bpl::object &column) { +int getPlotType(ITableWorkspace &self, const object &column) { // Find the column Mantid::API::Column_const_sptr colptr; if (STR_CHECK(column.ptr())) { @@ -225,7 +223,7 @@ int getPlotType(ITableWorkspace &self, const bpl::object &column) { * @param column Name or index of column * @param ptype PlotType: 0=None, 1=X, 2=Y, 3=Z, 4=xErr, 5=yErr, 6=Label */ -void setPlotType(ITableWorkspace &self, const bpl::object &column, int ptype) { +void setPlotType(ITableWorkspace &self, const object &column, int ptype) { // Find the column Mantid::API::Column_sptr colptr; if (STR_CHECK(column.ptr())) { @@ -243,7 +241,7 @@ void setPlotType(ITableWorkspace &self, const bpl::object &column, int ptype) { * called on * @param value A python object containing a column name or index */ -PyObject *column(const ITableWorkspace &self, const bpl::object &value) { +PyObject *column(const ITableWorkspace &self, const object &value) { // Find the column and row Mantid::API::Column_const_sptr column; if (STR_CHECK(value.ptr())) { @@ -300,10 +298,10 @@ PyObject *row(ITableWorkspace &self, int row) { * @param self :: A reference to the ITableWorkspace object * @param rowItems :: A dictionary defining the items in the row */ -void addRowFromDict(ITableWorkspace &self, const bpl::dict &rowItems) { +void addRowFromDict(ITableWorkspace &self, const dict &rowItems) { // rowItems must contain an entry for every column - bpl::ssize_t nitems = boost::python::len(rowItems); - if (nitems != static_cast<bpl::ssize_t>(self.columnCount())) { + auto nitems = boost::python::len(rowItems); + if (nitems != static_cast<decltype(nitems)>(self.columnCount())) { throw std::invalid_argument( "Number of values given does not match the number of columns. " "Expected: " + @@ -316,7 +314,7 @@ void addRowFromDict(ITableWorkspace &self, const bpl::dict &rowItems) { // Declared in this scope so we can access them in catch block Column_sptr column; // Column in table - bpl::object value; // Value from dictionary + object value; // Value from dictionary try { // Retrieve and set the value for each column @@ -326,7 +324,7 @@ void addRowFromDict(ITableWorkspace &self, const bpl::dict &rowItems) { value = rowItems[iter]; setValue(column, rowIndex, value); } - } catch (bpl::error_already_set &) { + } catch (error_already_set &) { // One of the columns wasn't found in the dictionary if (PyErr_ExceptionMatches(PyExc_KeyError)) { std::ostringstream msg; @@ -340,7 +338,7 @@ void addRowFromDict(ITableWorkspace &self, const bpl::dict &rowItems) { std::ostringstream msg; msg << "Wrong datatype <"; msg << std::string( - bpl::extract<std::string>(value.attr("__class__").attr("__name__"))); + extract<std::string>(value.attr("__class__").attr("__name__"))); msg << "> for column <" << column->name() << "> "; msg << "(expected <" << column->type() << ">)"; PyErr_SetString(PyExc_TypeError, msg.str().c_str()); @@ -360,10 +358,10 @@ void addRowFromDict(ITableWorkspace &self, const bpl::dict &rowItems) { * @param self :: A reference to the ITableWorkspace object * @param rowItems :: A sequence containing the column values in the row */ -void addRowFromSequence(ITableWorkspace &self, const bpl::object &rowItems) { +void addRowFromSequence(ITableWorkspace &self, const object &rowItems) { // rowItems must contain an entry for every column - bpl::ssize_t nitems = boost::python::len(rowItems); - if (nitems != static_cast<bpl::ssize_t>(self.columnCount())) { + auto nitems = boost::python::len(rowItems); + if (nitems != static_cast<decltype(nitems)>(self.columnCount())) { throw std::invalid_argument( "Number of values given does not match the number of columns. " "Expected: " + @@ -375,19 +373,19 @@ void addRowFromSequence(ITableWorkspace &self, const bpl::object &rowItems) { self.appendRow(); // Loop over sequence and set each column value in same order - for (bpl::ssize_t i = 0; i < nitems; ++i) { + for (decltype(nitems) i = 0; i < nitems; ++i) { auto column = self.getColumn(i); auto value = rowItems[i]; try { setValue(column, rowIndex, value); - } catch (bpl::error_already_set &) { + } catch (error_already_set &) { // Wrong type of data for one of the columns if (PyErr_ExceptionMatches(PyExc_TypeError)) { std::ostringstream msg; msg << "Wrong datatype <"; - msg << std::string(bpl::extract<std::string>( - value.attr("__class__").attr("__name__"))); + msg << std::string( + extract<std::string>(value.attr("__class__").attr("__name__"))); msg << "> for column <" << column->name() << "> "; msg << "(expected <" << column->type() << ">)"; PyErr_SetString(PyExc_TypeError, msg.str().c_str()); @@ -409,7 +407,7 @@ void addRowFromSequence(ITableWorkspace &self, const bpl::object &rowItems) { * @param column [Out]:: The column pointer will be stored here * @param rowIndex [Out]:: The row index will be stored here */ -void getCellLoc(ITableWorkspace &self, const bpl::object &col_or_row, +void getCellLoc(ITableWorkspace &self, const object &col_or_row, const int row_or_col, Column_sptr &column, int &rowIndex) { if (STR_CHECK(col_or_row.ptr())) { column = self.getColumn(extract<std::string>(col_or_row)()); @@ -428,8 +426,7 @@ void getCellLoc(ITableWorkspace &self, const bpl::object &col_or_row, * @param row_or_col An integer giving the row if value is a string or the * column if value is an index */ -PyObject *cell(ITableWorkspace &self, const bpl::object &value, - int row_or_col) { +PyObject *cell(ITableWorkspace &self, const object &value, int row_or_col) { // Find the column and row Mantid::API::Column_sptr column; int row(-1); @@ -446,8 +443,8 @@ PyObject *cell(ITableWorkspace &self, const bpl::object &value, * @param row_or_col An integer giving the row if value is a string or the * column if value is an index */ -void setCell(ITableWorkspace &self, const bpl::object &col_or_row, - const int row_or_col, const bpl::object &value) { +void setCell(ITableWorkspace &self, const object &col_or_row, + const int row_or_col, const object &value) { Mantid::API::Column_sptr column; int row(-1); getCellLoc(self, col_or_row, row_or_col, column, row); @@ -464,12 +461,12 @@ void setCell(ITableWorkspace &self, const bpl::object &col_or_row, * @returns a boost python dictionary object with keys that are column names and * values which are lists of the column values. */ -bpl::dict toDict(const ITableWorkspace &self) { - bpl::dict result; +dict toDict(const ITableWorkspace &self) { + dict result; for (const auto &name : self.getColumnNames()) { - bpl::handle<> handle(column(self, bpl::object(name))); - bpl::object values(handle); + handle<> handle(column(self, object(name))); + object values(handle); result[name] = values; } @@ -525,8 +522,8 @@ private: const auto &columnNames = metaData["column_names"]; const auto &columnTypes = metaData["column_types"]; - const bpl::ssize_t numColumns = len(columnNames); - for (bpl::ssize_t colIndex = 0; colIndex < numColumns; ++colIndex) { + auto numColumns = len(columnNames); + for (decltype(numColumns) colIndex = 0; colIndex < numColumns; ++colIndex) { const auto &key = columnNames[colIndex]; const auto &value = columnTypes[colIndex]; const auto &name = extract<std::string>(key); @@ -548,7 +545,7 @@ private: return; } - bpl::ssize_t numRows = len(data[names[0]]); + auto numRows = len(data[names[0]]); for (int rowIndex = 0; rowIndex < numRows; ++rowIndex) { ws.appendRow(); for (const auto &name : names) { diff --git a/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp index 8e2d24fd21375b276a6e14bd727234c5fb54bc3a..8d37a079ce160c1ab0a0de8114c97f4d823d4c00 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp @@ -6,11 +6,11 @@ #include "MantidKernel/WarningSuppressions.h" #include "MantidPythonInterface/api/CloneMatrixWorkspace.h" +#include "MantidPythonInterface/core/Converters/WrapWithNDArray.h" +#include "MantidPythonInterface/core/NDArray.h" #include "MantidPythonInterface/kernel/Converters/NDArrayToVector.h" #include "MantidPythonInterface/kernel/Converters/PySequenceToVector.h" -#include "MantidPythonInterface/kernel/Converters/WrapWithNumpy.h" #include "MantidPythonInterface/kernel/GetPointer.h" -#include "MantidPythonInterface/kernel/NdArray.h" #include "MantidPythonInterface/kernel/Policies/RemoveConst.h" #include "MantidPythonInterface/kernel/Policies/VectorToNumpy.h" #include "MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h" @@ -28,10 +28,10 @@ using namespace Mantid::API; using namespace Mantid::Geometry; using namespace Mantid::Kernel; +using namespace Mantid::PythonInterface; using namespace Mantid::PythonInterface::Converters; using namespace Mantid::PythonInterface::Policies; using namespace Mantid::PythonInterface::Registry; -namespace NumPy = Mantid::PythonInterface::NumPy; using namespace boost::python; GET_POINTER_SPECIALIZATION(MatrixWorkspace) @@ -71,7 +71,7 @@ GNU_DIAG_ON("unused-local-typedef") void setSpectrumFromPyObject(MatrixWorkspace &self, data_modifier accessor, const size_t wsIndex, const boost::python::object &values) { - if (NumPy::NdArray::check(values)) { + if (NDArray::check(values)) { NDArrayToVector<double> converter(values); converter.copyTo((self.*accessor)(wsIndex)); } else { @@ -140,7 +140,7 @@ void setYFromPyObject(MatrixWorkspace &self, const size_t wsIndex, * @param values :: A numpy array. The length must match the size of the */ void setEFromPyObject(MatrixWorkspace &self, const size_t wsIndex, - const NumPy::NdArray &values) { + const NDArray &values) { setSpectrumFromPyObject(self, &MatrixWorkspace::dataE, wsIndex, values); } diff --git a/Framework/PythonInterface/mantid/api/src/Exports/MultipleFileProperty.cpp b/Framework/PythonInterface/mantid/api/src/Exports/MultipleFileProperty.cpp index 5fba8a1d5cb7b0beebc762eb26a983161888e5b0..e07c57edd00feb6a0817294811932a2eb78e172a 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/MultipleFileProperty.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/MultipleFileProperty.cpp @@ -26,7 +26,7 @@ using HeldType = std::vector<std::vector<std::string>>; * @returns A string is there is only a single string in the Property's value, * and a list if there are multiple ones */ -boost::python::object valueAsPyObject(MultipleFileProperty &self) { +boost::python::list valueAsPyObject(MultipleFileProperty &self) { const HeldType &propValue = self(); // Build a list of lists to mimic the behaviour of MultipleFileProperty diff --git a/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceHistory.cpp b/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceHistory.cpp index ada4060c095776b0647cd27beb0ba3dedf97541b..a7617386642ace77691a5e0939b86fc9b9a0687f 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceHistory.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceHistory.cpp @@ -23,7 +23,7 @@ GET_POINTER_SPECIALIZATION(WorkspaceHistory) * @param self :: A reference to the WorkspaceHistory that called this method * @returns A python list created from the set of algorithm histories */ -boost::python::object getHistoriesAsList(WorkspaceHistory &self) { +boost::python::list getHistoriesAsList(WorkspaceHistory &self) { boost::python::list names; const auto &histories = self.getAlgorithmHistories(); for (const auto &historie : histories) { diff --git a/Framework/PythonInterface/mantid/api/src/FitFunctions/IFunction1DAdapter.cpp b/Framework/PythonInterface/mantid/api/src/FitFunctions/IFunction1DAdapter.cpp index b16b8876dff5eb232c090bb9c7f65ed24bbdcf9d..b419e48328d932041d45ee5a8b88451cf6ef090e 100644 --- a/Framework/PythonInterface/mantid/api/src/FitFunctions/IFunction1DAdapter.cpp +++ b/Framework/PythonInterface/mantid/api/src/FitFunctions/IFunction1DAdapter.cpp @@ -1,5 +1,5 @@ #include "MantidPythonInterface/api/FitFunctions/IFunction1DAdapter.h" -#include "MantidPythonInterface/kernel/Environment/CallMethod.h" +#include "MantidPythonInterface/core/CallMethod.h" #define PY_ARRAY_UNIQUE_SYMBOL API_ARRAY_API #define NO_IMPORT_ARRAY @@ -10,7 +10,6 @@ //----------------------------------------------------------------------------- namespace Mantid { namespace PythonInterface { -using Environment::callMethodNoCheck; using namespace boost::python; /** diff --git a/Framework/PythonInterface/mantid/api/src/FitFunctions/IFunctionAdapter.cpp b/Framework/PythonInterface/mantid/api/src/FitFunctions/IFunctionAdapter.cpp index 8cb5b3b9cf36ee99ad3e9d8767dacc77224fcfa1..bac996d2fd20c564d7eb44e80fb4df24f06f6eff 100644 --- a/Framework/PythonInterface/mantid/api/src/FitFunctions/IFunctionAdapter.cpp +++ b/Framework/PythonInterface/mantid/api/src/FitFunctions/IFunctionAdapter.cpp @@ -1,6 +1,6 @@ #include "MantidPythonInterface/api/FitFunctions/IFunctionAdapter.h" -#include "MantidPythonInterface/kernel/Converters/WrapWithNumpy.h" -#include "MantidPythonInterface/kernel/Environment/CallMethod.h" +#include "MantidPythonInterface/core/CallMethod.h" +#include "MantidPythonInterface/core/Converters/WrapWithNDArray.h" #include <boost/python/class.hpp> #include <boost/python/list.hpp> @@ -12,9 +12,9 @@ namespace Mantid { namespace PythonInterface { using API::IFunction; -using PythonInterface::Environment::UndefinedAttributeError; -using PythonInterface::Environment::callMethod; -using PythonInterface::Environment::callMethodNoCheck; +using PythonInterface::UndefinedAttributeError; +using PythonInterface::callMethod; +using PythonInterface::callMethodNoCheck; using namespace boost::python; namespace { @@ -74,11 +74,11 @@ IFunction::Attribute createAttributeFromPythonValue(const object &value) { IFunctionAdapter::IFunctionAdapter(PyObject *self, std::string functionMethod, std::string derivMethod) : m_self(self), m_functionName(std::move(functionMethod)), - m_derivName(derivMethod), m_derivOveridden(Environment::typeHasAttribute( - self, m_derivName.c_str())) { - if (!Environment::typeHasAttribute(self, "init")) + m_derivName(derivMethod), + m_derivOveridden(typeHasAttribute(self, m_derivName.c_str())) { + if (!typeHasAttribute(self, "init")) throw std::runtime_error("Function does not define an init method."); - if (!Environment::typeHasAttribute(self, m_functionName.c_str())) + if (!typeHasAttribute(self, m_functionName.c_str())) throw std::runtime_error("Function does not define a " + m_functionName + " method."); } @@ -198,7 +198,7 @@ void IFunctionAdapter::setAttribute(const std::string &attName, * For a single domain function it should have a single element (self). * @return A python list of IFunction_sprs. */ -boost::python::object +boost::python::list IFunctionAdapter::createPythonEquivalentFunctions(IFunction &self) { auto functions = self.createEquivalentFunctions(); boost::python::list list; @@ -249,7 +249,7 @@ void IFunctionAdapter::evaluateFunction(double *out, const double *xValues, using namespace Converters; // GIL must be held while numpy wrappers are destroyed as they access Python // state information - Environment::GlobalInterpreterLock gil; + GlobalInterpreterLock gil; Py_intptr_t dims[1] = {static_cast<Py_intptr_t>(nData)}; PyObject *xvals = @@ -267,7 +267,7 @@ void IFunctionAdapter::evaluateFunction(double *out, const double *xValues, Py_DECREF(xvals); if (PyErr_Occurred()) { Py_XDECREF(result); - throw Environment::PythonException(); + throw PythonException(); } if (PyArray_Check(result)) { auto nparray = reinterpret_cast<PyArrayObject *>(result); @@ -307,7 +307,7 @@ void IFunctionAdapter::evaluateDerivative(API::Jacobian *out, using namespace Converters; // GIL must be held while numpy wrappers are destroyed as they access Python // state information - Environment::GlobalInterpreterLock gil; + GlobalInterpreterLock gil; Py_intptr_t dims[1] = {static_cast<Py_intptr_t>(nData)}; PyObject *xvals = @@ -322,7 +322,7 @@ void IFunctionAdapter::evaluateDerivative(API::Jacobian *out, PyObject_CallMethod(getSelf(), const_cast<char *>(m_derivName.c_str()), const_cast<char *>("(OO)"), xvals, jacobian); if (PyErr_Occurred()) - throw Environment::PythonRuntimeError(); + throw PythonRuntimeError(); } } // namespace PythonInterface } // namespace Mantid diff --git a/Framework/PythonInterface/mantid/api/src/FitFunctions/IPeakFunctionAdapter.cpp b/Framework/PythonInterface/mantid/api/src/FitFunctions/IPeakFunctionAdapter.cpp index d32a5e3ac5077bd02fc3db557d8b60b5777afa6d..ac354dfee214e9a787d363ca01f831e35c624dd2 100644 --- a/Framework/PythonInterface/mantid/api/src/FitFunctions/IPeakFunctionAdapter.cpp +++ b/Framework/PythonInterface/mantid/api/src/FitFunctions/IPeakFunctionAdapter.cpp @@ -1,12 +1,11 @@ #include "MantidPythonInterface/api/FitFunctions/IPeakFunctionAdapter.h" -#include "MantidPythonInterface/kernel/Environment/CallMethod.h" +#include "MantidPythonInterface/core/CallMethod.h" //----------------------------------------------------------------------------- // IPeakFunction definition //----------------------------------------------------------------------------- namespace Mantid { namespace PythonInterface { -using Environment::callMethodNoCheck; using namespace boost::python; /** diff --git a/Framework/PythonInterface/mantid/api/src/PythonAlgorithm/AlgorithmAdapter.cpp b/Framework/PythonInterface/mantid/api/src/PythonAlgorithm/AlgorithmAdapter.cpp index b36f073ac49290792f636d924277e9cf7a2378a5..f36bed40ba1262c62c001b0347e5a40ed38f7f5c 100644 --- a/Framework/PythonInterface/mantid/api/src/PythonAlgorithm/AlgorithmAdapter.cpp +++ b/Framework/PythonInterface/mantid/api/src/PythonAlgorithm/AlgorithmAdapter.cpp @@ -4,10 +4,10 @@ #include "MantidAPI/ParallelAlgorithm.h" #include "MantidAPI/SerialAlgorithm.h" #include "MantidKernel/WarningSuppressions.h" +#include "MantidPythonInterface/core/CallMethod.h" +#include "MantidPythonInterface/core/GlobalInterpreterLock.h" +#include "MantidPythonInterface/core/WrapperHelpers.h" #include "MantidPythonInterface/kernel/Converters/PySequenceToVector.h" -#include "MantidPythonInterface/kernel/Environment/CallMethod.h" -#include "MantidPythonInterface/kernel/Environment/GlobalInterpreterLock.h" -#include "MantidPythonInterface/kernel/Environment/WrapperHelpers.h" #include "MantidPythonInterface/kernel/Registry/PropertyWithValueFactory.h" #include <boost/python/class.hpp> @@ -19,8 +19,6 @@ namespace Mantid { namespace PythonInterface { using namespace boost::python; -using Environment::UndefinedAttributeError; -using Environment::callMethod; /** * Construct the "wrapper" and stores the reference to the PyObject @@ -33,7 +31,7 @@ AlgorithmAdapter<BaseAlgorithm>::AlgorithmAdapter(PyObject *self) // Only cache the isRunning attribute if it is overridden by the // inheriting type otherwise we end up with an infinite recursive call // as isRunning always exists from the interface - if (Environment::typeHasAttribute(self, "isRunning")) + if (typeHasAttribute(self, "isRunning")) m_isRunningObj = PyObject_GetAttrString(self, "isRunning"); } @@ -104,7 +102,7 @@ AlgorithmAdapter<BaseAlgorithm>::seeAlso() const { try { // The GIL is required so that the the reference count of the // list object can be decremented safely - Environment::GlobalInterpreterLock gil; + GlobalInterpreterLock gil; return Converters::PySequenceToVector<std::string>( callMethod<list>(getSelf(), "seeAlso"))(); } catch (UndefinedAttributeError &) { @@ -145,12 +143,12 @@ bool AlgorithmAdapter<BaseAlgorithm>::isRunning() const { if (!m_isRunningObj) { return SuperClass::isRunning(); } else { - Environment::GlobalInterpreterLock gil; + GlobalInterpreterLock gil; GNU_DIAG_OFF("parentheses-equality") PyObject *result = PyObject_CallObject(m_isRunningObj, nullptr); if (PyErr_Occurred()) - throw Environment::PythonException(); + throw PythonException(); if (PyBool_Check(result)) { #if PY_MAJOR_VERSION >= 3 @@ -187,7 +185,7 @@ AlgorithmAdapter<BaseAlgorithm>::validateInputs() { std::map<std::string, std::string> resultMap; try { - Environment::GlobalInterpreterLock gil; + GlobalInterpreterLock gil; dict resultDict = callMethod<dict>(getSelf(), "validateInputs"); // convert to a map<string,string> boost::python::list keys = resultDict.keys(); diff --git a/Framework/PythonInterface/mantid/dataobjects/CMakeLists.txt b/Framework/PythonInterface/mantid/dataobjects/CMakeLists.txt index d07d831a7c3edc8b4c208557dcf86f8dd0b53070..be9fd123dd24e43432bde62d64619e7b1a7a4cfb 100644 --- a/Framework/PythonInterface/mantid/dataobjects/CMakeLists.txt +++ b/Framework/PythonInterface/mantid/dataobjects/CMakeLists.txt @@ -67,6 +67,7 @@ set_target_output_directory ( PythonDataObjectsModule ${OUTPUT_DIR} .pyd ) # Add the required dependencies target_link_libraries ( PythonDataObjectsModule LINK_PRIVATE ${TCMALLOC_LIBRARIES_LINKTIME} + PythonInterfaceCore PythonAPIModule PythonGeometryModule PythonKernelModule diff --git a/Framework/PythonInterface/mantid/dataobjects/src/Exports/Workspace2D.cpp b/Framework/PythonInterface/mantid/dataobjects/src/Exports/Workspace2D.cpp index f12cba8d0e2a26fdd219098af87b5213df9a981f..0264d0e7373b401e1768d02004d9ce02011988a5 100644 --- a/Framework/PythonInterface/mantid/dataobjects/src/Exports/Workspace2D.cpp +++ b/Framework/PythonInterface/mantid/dataobjects/src/Exports/Workspace2D.cpp @@ -11,10 +11,10 @@ #include "MantidKernel/Logger.h" #include "MantidKernel/OptionalBool.h" #include "MantidKernel/Unit.h" +#include "MantidPythonInterface/core/Converters/VectorToNDArray.h" +#include "MantidPythonInterface/core/Converters/WrapWithNDArray.h" #include "MantidPythonInterface/kernel/Converters/CloneToNumpy.h" #include "MantidPythonInterface/kernel/Converters/NDArrayToVector.h" -#include "MantidPythonInterface/kernel/Converters/VectorToNDArray.h" -#include "MantidPythonInterface/kernel/Converters/WrapWithNumpy.h" #include "MantidPythonInterface/kernel/GetPointer.h" #include "MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h" #include "MantidTypes/SpectrumDefinition.h" diff --git a/Framework/PythonInterface/mantid/geometry/CMakeLists.txt b/Framework/PythonInterface/mantid/geometry/CMakeLists.txt index 92b38c4322bb0b7ce34a67de32d5bafc936ac439..a3249fbb7f4d087d629c6f56400e665a9fa7b583 100644 --- a/Framework/PythonInterface/mantid/geometry/CMakeLists.txt +++ b/Framework/PythonInterface/mantid/geometry/CMakeLists.txt @@ -85,7 +85,8 @@ add_library ( PythonGeometryModule ${EXPORT_FILES} ${MODULE_DEFINITION} ${SRC_FI set_python_properties( PythonGeometryModule _geometry ) set_target_output_directory ( PythonGeometryModule ${OUTPUT_DIR} .pyd ) # Add the required dependencies -target_link_libraries ( PythonGeometryModule LINK_PRIVATE ${TCMALLOC_LIBRARIES_LINKTIME} +target_link_libraries ( PythonGeometryModule PRIVATE ${TCMALLOC_LIBRARIES_LINKTIME} + PythonInterfaceCore PythonKernelModule Geometry Beamline diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/ComponentInfo.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/ComponentInfo.cpp index fcd1ace029e11e42a9dad11caa84a5c80b75d9a8..10051c79b90d7305274994ec2e429d9ac440fa1e 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/ComponentInfo.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/ComponentInfo.cpp @@ -2,7 +2,7 @@ #include "MantidGeometry/Objects/IObject.h" #include "MantidKernel/Quat.h" #include "MantidKernel/V3D.h" -#include "MantidPythonInterface/kernel/Converters/WrapWithNumpy.h" +#include "MantidPythonInterface/core/Converters/WrapWithNDArray.h" #include "MantidPythonInterface/kernel/Policies/VectorToNumpy.h" #include <boost/python/class.hpp> diff --git a/Framework/PythonInterface/mantid/kernel/CMakeLists.txt b/Framework/PythonInterface/mantid/kernel/CMakeLists.txt index f78be07e854e006d2e3c425723db81b549d7bbba..3525553a96359bd64cda42dc425d49de3a02a24b 100644 --- a/Framework/PythonInterface/mantid/kernel/CMakeLists.txt +++ b/Framework/PythonInterface/mantid/kernel/CMakeLists.txt @@ -70,31 +70,22 @@ create_module ( ${MODULE_TEMPLATE} ${MODULE_DEFINITION} ${EXPORT_FILES} ) # Helper code ############################################################################################# set ( SRC_FILES - src/NdArray.cpp src/Converters/CloneToNumpy.cpp src/Converters/DateAndTime.cpp src/Converters/NDArrayToVector.cpp - src/Converters/NDArrayTypeIndex.cpp src/Converters/NumpyFunctions.cpp - src/Converters/PyArrayType.cpp src/Converters/PyObjectToMatrix.cpp src/Converters/PyObjectToString.cpp src/Converters/PyObjectToV3D.cpp src/Converters/PyObjectToVMD.cpp - src/Converters/WrapWithNumpy.cpp src/Registry/MappingTypeHandler.cpp src/Registry/PropertyManagerFactory.cpp src/Registry/PropertyWithValueFactory.cpp src/Registry/SequenceTypeHandler.cpp src/Registry/TypeRegistry.cpp - src/Environment/ErrorHandling.cpp - src/Environment/GlobalInterpreterLock.cpp - src/Environment/ReleaseGlobalInterpreterLock.cpp - src/Environment/WrapperHelpers.cpp ) set ( INC_FILES - ${HEADER_DIR}/kernel/NdArray.h ${HEADER_DIR}/kernel/Converters/CArrayToNDArray.h ${HEADER_DIR}/kernel/Converters/CloneToNumpy.h ${HEADER_DIR}/kernel/Converters/ContainerDtype.h @@ -103,19 +94,11 @@ set ( INC_FILES ${HEADER_DIR}/kernel/Converters/MatrixToNDArray.h ${HEADER_DIR}/kernel/Converters/NumpyFunctions.h ${HEADER_DIR}/kernel/Converters/NDArrayToVector.h - ${HEADER_DIR}/kernel/Converters/NDArrayTypeIndex.h - ${HEADER_DIR}/kernel/Converters/WrapWithNumpy.h - ${HEADER_DIR}/kernel/Converters/VectorToNDArray.h - ${HEADER_DIR}/kernel/Converters/PyArrayType.h ${HEADER_DIR}/kernel/Converters/PyObjectToMatrix.h ${HEADER_DIR}/kernel/Converters/PyObjectToString.h ${HEADER_DIR}/kernel/Converters/PyObjectToV3D.h ${HEADER_DIR}/kernel/Converters/PyObjectToVMD.h ${HEADER_DIR}/kernel/Converters/PySequenceToVector.h - ${HEADER_DIR}/kernel/Environment/CallMethod.h - ${HEADER_DIR}/kernel/Environment/ErrorHandling.h - ${HEADER_DIR}/kernel/Environment/GlobalInterpreterLock.h - ${HEADER_DIR}/kernel/Environment/WrapperHelpers.h ${HEADER_DIR}/kernel/Policies/MatrixToNumpy.h ${HEADER_DIR}/kernel/Policies/RemoveConst.h ${HEADER_DIR}/kernel/Policies/ToWeakPtr.h @@ -199,9 +182,9 @@ add_library ( PythonKernelModule ${EXPORT_FILES} ${MODULE_DEFINITION} ${SRC_FILE set_python_properties( PythonKernelModule _kernel ) set_target_output_directory ( PythonKernelModule ${OUTPUT_DIR} .pyd ) # Add the required dependencies -target_link_libraries ( PythonKernelModule LINK_PRIVATE ${TCMALLOC_LIBRARIES_LINKTIME} Types Kernel ${Boost_LIBRARIES} - ${PYTHON_LIBRARIES} ${PYTHON_DEPS} ${POCO_LIBRARIES} ${TBB_LIBRARIES} - ${TBB_MALLOC_LIBRARIES} ) +target_link_libraries ( PythonKernelModule PRIVATE ${TCMALLOC_LIBRARIES_LINKTIME} PythonInterfaceCore + Types Kernel ${Boost_LIBRARIES} ${PYTHON_LIBRARIES} ${PYTHON_DEPS} ${POCO_LIBRARIES} + ${TBB_LIBRARIES} ${TBB_MALLOC_LIBRARIES} ) if (OSX_VERSION VERSION_GREATER 10.8) set_target_properties(PythonKernelModule PROPERTIES INSTALL_RPATH "@loader_path/../../../MacOS") diff --git a/Framework/PythonInterface/mantid/kernel/src/Converters/CloneToNumpy.cpp b/Framework/PythonInterface/mantid/kernel/src/Converters/CloneToNumpy.cpp index c09b9c066b2d062523fd3960c566b21bfd9c05d1..4d06a78a75c0dc8d58cd13807b5d43dfba1b5ffd 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Converters/CloneToNumpy.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Converters/CloneToNumpy.cpp @@ -2,8 +2,8 @@ // Includes //----------------------------------------------------------------------------- #include "MantidPythonInterface/kernel/Converters/CloneToNumpy.h" +#include "MantidPythonInterface/core/Converters/NDArrayTypeIndex.h" #include "MantidPythonInterface/kernel/Converters/DateAndTime.h" -#include "MantidPythonInterface/kernel/Converters/NDArrayTypeIndex.h" #include "MantidPythonInterface/kernel/Converters/NumpyFunctions.h" #include "MantidTypes/Core/DateAndTime.h" #include <boost/python/list.hpp> diff --git a/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayToVector.cpp b/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayToVector.cpp index 3068360dd6548a191af66b2a87f9bef7661edc27..42585c69ed63191e76b818807463264d8fa20fdc 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayToVector.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayToVector.cpp @@ -2,7 +2,7 @@ // Includes //----------------------------------------------------------------------------- #include "MantidPythonInterface/kernel/Converters/NDArrayToVector.h" -#include "MantidPythonInterface/kernel/Converters/NDArrayTypeIndex.h" +#include "MantidPythonInterface/core/Converters/NDArrayTypeIndex.h" #include "MantidPythonInterface/kernel/Converters/NumpyFunctions.h" #include <boost/python/extract.hpp> @@ -93,7 +93,7 @@ template <> struct CopyToImpl<std::string> { * the object points to numpy array, no checking is performed */ template <typename DestElementType> struct CoerceType { - NumPy::NdArray operator()(const NumPy::NdArray &x) { + NDArray operator()(const NDArray &x) { return x.astype(Converters::NDArrayTypeIndex<DestElementType>::typecode, false); } @@ -104,7 +104,7 @@ template <typename DestElementType> struct CoerceType { * to convert the underlying representation */ template <> struct CoerceType<std::string> { - object operator()(const NumPy::NdArray &x) { return x; } + object operator()(const NDArray &x) { return x; } }; } // namespace @@ -118,7 +118,7 @@ namespace Converters { * @param value :: A boost python object wrapping a numpy.ndarray */ template <typename DestElementType> -NDArrayToVector<DestElementType>::NDArrayToVector(const NumPy::NdArray &value) +NDArrayToVector<DestElementType>::NDArrayToVector(const NDArray &value) : m_arr(CoerceType<DestElementType>()(value)) {} /** diff --git a/Framework/PythonInterface/mantid/kernel/src/Converters/PyArrayType.cpp b/Framework/PythonInterface/mantid/kernel/src/Converters/PyArrayType.cpp deleted file mode 100644 index 72a9aac9d4f5d8a7bad03de76119b21ce139a97f..0000000000000000000000000000000000000000 --- a/Framework/PythonInterface/mantid/kernel/src/Converters/PyArrayType.cpp +++ /dev/null @@ -1,23 +0,0 @@ -//----------------------------------------------------------------------------- -// Includes -//----------------------------------------------------------------------------- -#include "MantidPythonInterface/kernel/Converters/PyArrayType.h" - -// See -// http://docs.scipy.org/doc/numpy/reference/c-api.array.html#PY_ARRAY_UNIQUE_SYMBOL -#define PY_ARRAY_UNIQUE_SYMBOL KERNEL_ARRAY_API -#define NO_IMPORT_ARRAY -#include <numpy/arrayobject.h> - -namespace Mantid { -namespace PythonInterface { -namespace Converters { - -/** - * Returns a pointer to the PyArray_Type object - * @return - */ -PyTypeObject *getNDArrayType() { return &PyArray_Type; } -} // namespace Converters -} // namespace PythonInterface -} // namespace Mantid diff --git a/Framework/PythonInterface/mantid/kernel/src/Converters/PyObjectToMatrix.cpp b/Framework/PythonInterface/mantid/kernel/src/Converters/PyObjectToMatrix.cpp index 0acc70b84e487f6a23c636ce8dea77071eababf8..040c972ef17eaf4cc9711dc9645c8cc4d1043889 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Converters/PyObjectToMatrix.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Converters/PyObjectToMatrix.cpp @@ -2,7 +2,7 @@ // Includes //---------------------------------------------------------------------------- #include "MantidPythonInterface/kernel/Converters/PyObjectToMatrix.h" -#include "MantidPythonInterface/kernel/NdArray.h" +#include "MantidPythonInterface/core/NDArray.h" #include <boost/python/extract.hpp> @@ -16,7 +16,6 @@ using boost::python::extract; namespace Mantid { namespace PythonInterface { -using namespace NumPy; namespace Converters { /** @@ -35,7 +34,7 @@ PyObjectToMatrix::PyObjectToMatrix(const boost::python::object &p) return; } // Is it a 2D numpy array - if (!NumPy::NdArray::check(p)) { + if (!NDArray::check(p)) { std::ostringstream msg; msg << "Cannot convert object to Matrix. Expected numpy array, found " << p.ptr()->ob_type->tp_name; diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/ArrayProperty.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/ArrayProperty.cpp index 3dab4e7248a82d8072dc5f2f447cd629ad4d4d34..1f60bb8a0ffbc9f57def74f03cf5a9a01165faef 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Exports/ArrayProperty.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/ArrayProperty.cpp @@ -1,10 +1,10 @@ #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/NullValidator.h" +#include "MantidPythonInterface/core/NDArray.h" #include "MantidPythonInterface/kernel/Converters/ContainerDtype.h" #include "MantidPythonInterface/kernel/Converters/NDArrayToVector.h" #include "MantidPythonInterface/kernel/Converters/PySequenceToVector.h" -#include "MantidPythonInterface/kernel/NdArray.h" #include "MantidPythonInterface/kernel/Policies/VectorToNumpy.h" #include <boost/python/class.hpp> @@ -18,8 +18,8 @@ using Mantid::Kernel::Direction; using Mantid::Kernel::IValidator_sptr; using Mantid::Kernel::NullValidator; using Mantid::Kernel::PropertyWithValue; +using Mantid::PythonInterface::NDArray; namespace Converters = Mantid::PythonInterface::Converters; -namespace NumPy = Mantid::PythonInterface::NumPy; namespace Policies = Mantid::PythonInterface::Policies; using namespace boost::python; @@ -125,7 +125,7 @@ ArrayProperty<T> *createArrayPropertyFromList(const std::string &name, */ template <typename T> ArrayProperty<T> *createArrayPropertyFromNDArray(const std::string &name, - const NumPy::NdArray &values, + const NDArray &values, IValidator_sptr validator, const unsigned int direction) { return new ArrayProperty<T>(name, Converters::NDArrayToVector<T>(values)(), @@ -143,4 +143,4 @@ void export_ArrayProperty() { // Python can be seen also. Users shouldn't need this EXPORT_ARRAY_PROP(int, CInt); EXPORT_ARRAY_PROP(size_t, UnsignedInt); -} \ No newline at end of file +} diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigObserver.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigObserver.cpp index c28cfe13fde71b14fe621d44f4f89184612c34ac..ba0ae27dc571ec23e921640154d95accfff18a27 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigObserver.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigObserver.cpp @@ -1,13 +1,13 @@ #include "MantidKernel/ConfigObserver.h" -#include "MantidPythonInterface/kernel/Environment/CallMethod.h" -#include "MantidPythonInterface/kernel/Environment/GlobalInterpreterLock.h" +#include "MantidPythonInterface/core/CallMethod.h" +#include "MantidPythonInterface/core/GlobalInterpreterLock.h" #include <boost/python/class.hpp> #include <boost/python/def.hpp> #include <boost/python/pure_virtual.hpp> using namespace boost::python; using Mantid::Kernel::ConfigObserver; -using Mantid::PythonInterface::Environment::callMethod; +using Mantid::PythonInterface::callMethod; class ConfigObserverWrapper : public ConfigObserver { public: diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigPropertyObserver.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigPropertyObserver.cpp index 086acd86bd294c0c45c007fd027187a402952d01..f8f928c9cc994fd96e172710a8fabc9f2386968b 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigPropertyObserver.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigPropertyObserver.cpp @@ -1,13 +1,13 @@ #include "MantidKernel/ConfigPropertyObserver.h" -#include "MantidPythonInterface/kernel/Environment/CallMethod.h" -#include "MantidPythonInterface/kernel/Environment/GlobalInterpreterLock.h" +#include "MantidPythonInterface/core/CallMethod.h" +#include "MantidPythonInterface/core/GlobalInterpreterLock.h" #include <boost/python/class.hpp> #include <boost/python/def.hpp> #include <boost/python/pure_virtual.hpp> using namespace boost::python; using Mantid::Kernel::ConfigPropertyObserver; -using Mantid::PythonInterface::Environment::callMethod; +using Mantid::PythonInterface::callMethod; class ConfigPropertyObserverWrapper : public ConfigPropertyObserver { public: diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/Statistics.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/Statistics.cpp index 61f6545195557dae871e30ca82216651dca203c7..fbf9709067d96a406e762d6a3bda59da933e125f 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Exports/Statistics.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/Statistics.cpp @@ -1,7 +1,7 @@ #include "MantidKernel/Statistics.h" #include "MantidKernel/WarningSuppressions.h" +#include "MantidPythonInterface/core/NDArray.h" #include "MantidPythonInterface/kernel/Converters/NDArrayToVector.h" -#include "MantidPythonInterface/kernel/NdArray.h" #include "MantidPythonInterface/kernel/Policies/VectorToNumpy.h" #include <boost/python/class.hpp> @@ -81,8 +81,7 @@ public: * @param data Input data * @param sorted A boolean indicating whether the data is sorted */ -Statistics getStatisticsNumpy(const NumPy::NdArray &data, - const bool sorted = false) { +Statistics getStatisticsNumpy(const NDArray &data, const bool sorted = false) { using Converters::NDArrayToVector; using Mantid::Kernel::StatOptions; using Mantid::Kernel::getStatistics; @@ -115,7 +114,7 @@ GNU_DIAG_ON("unused-local-typedef") * @param zscoreFunc A function pointer to the required moments function * @param data Numpy array of data */ -std::vector<double> getZscoreNumpy(const NumPy::NdArray &data) { +std::vector<double> getZscoreNumpy(const NDArray &data) { using Converters::NDArrayToVector; using Mantid::Kernel::getZscore; @@ -131,7 +130,7 @@ std::vector<double> getZscoreNumpy(const NumPy::NdArray &data) { * @param data The input array * @param sorted True if the data is sorted (deprecated) */ -std::vector<double> getZscoreNumpyDeprecated(const NumPy::NdArray &data, +std::vector<double> getZscoreNumpyDeprecated(const NDArray &data, const bool sorted) { UNUSED_ARG(sorted); PyErr_Warn(PyExc_DeprecationWarning, @@ -143,7 +142,7 @@ std::vector<double> getZscoreNumpyDeprecated(const NumPy::NdArray &data, * Proxy for @see Mantid::Kernel::getModifiedZscore so that it can accept numpy * arrays, */ -std::vector<double> getModifiedZscoreNumpy(const NumPy::NdArray &data, +std::vector<double> getModifiedZscoreNumpy(const NDArray &data, const bool sorted = false) { using Converters::NDArrayToVector; using Mantid::Kernel::getModifiedZscore; @@ -186,8 +185,8 @@ using MomentsFunction = std::vector<double> (*)(const std::vector<double> &, * @param maxMoment Maximum number of moments to return */ std::vector<double> getMomentsNumpyImpl(MomentsFunction momentsFunc, - const NumPy::NdArray &indep, - const NumPy::NdArray &depend, + const NDArray &indep, + const NDArray &depend, const int maxMoment) { using Converters::NDArrayToVector; @@ -208,8 +207,8 @@ std::vector<double> getMomentsNumpyImpl(MomentsFunction momentsFunc, * Proxy for @see Mantid::Kernel::getMomentsAboutOrigin so that it can accept * numpy arrays */ -std::vector<double> getMomentsAboutOriginNumpy(const NumPy::NdArray &indep, - const NumPy::NdArray &depend, +std::vector<double> getMomentsAboutOriginNumpy(const NDArray &indep, + const NDArray &depend, const int maxMoment = 3) { using Mantid::Kernel::getMomentsAboutOrigin; return getMomentsNumpyImpl(&getMomentsAboutOrigin, indep, depend, maxMoment); @@ -228,8 +227,8 @@ GNU_DIAG_ON("unused-local-typedef") * Proxy for @see Mantid::Kernel::getMomentsAboutMean so that it can accept * numpy arrays */ -std::vector<double> getMomentsAboutMeanNumpy(const NumPy::NdArray &indep, - NumPy::NdArray &depend, +std::vector<double> getMomentsAboutMeanNumpy(const NDArray &indep, + NDArray &depend, const int maxMoment = 3) { using Mantid::Kernel::getMomentsAboutMean; return getMomentsNumpyImpl(&getMomentsAboutMean, indep, depend, maxMoment); diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/V3D.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/V3D.cpp index 1cac46dbb7a02dae660ba3abc68be47027657bb7..d1303782d74e2eb05beab8d7fc4058005e04d230 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Exports/V3D.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/V3D.cpp @@ -1,4 +1,5 @@ #include "MantidKernel/V3D.h" +#include "MantidKernel/WarningSuppressions.h" #include <boost/python/class.hpp> #include <boost/python/copy_const_reference.hpp> #include <boost/python/dict.hpp> @@ -88,6 +89,7 @@ public: void export_V3D() { // V3D class + GNU_DIAG_OFF("self-assign-overloaded") class_<V3D>("V3D", init<>("Construct a V3D at the origin")) .def_pickle(V3DPickleSuite()) .def(init<double, double, double>( @@ -166,4 +168,5 @@ void export_V3D() { "Calculate direction angles from direction cosines") .def("directionAngles", &directionAnglesDefault, arg("self"), "Calculate direction angles from direction cosines"); + GNU_DIAG_ON("self-assign-overloaded") } diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/VMD.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/VMD.cpp index a1df751a6a1c8bd9364394cc8267453a71b3ef2c..6e435f63423be417d326c5ccaa3b26c1189651f9 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Exports/VMD.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/VMD.cpp @@ -1,4 +1,5 @@ #include "MantidKernel/VMD.h" +#include "MantidKernel/WarningSuppressions.h" #include <boost/python/class.hpp> #include <boost/python/copy_const_reference.hpp> #include <boost/python/make_constructor.hpp> @@ -45,6 +46,7 @@ void setItem(VMD &self, const size_t index, const VMD_t value) { } } // namespace +GNU_DIAG_OFF("self-assign-overloaded") void export_VMD() { class_<VMD>("VMD", init<>(arg("self"), @@ -113,3 +115,5 @@ void export_VMD() { // cppcheck-suppress duplicateExpression .def(self /= self); } + +GNU_DIAG_ON("self-assign-overloaded") diff --git a/Framework/PythonInterface/mantid/kernel/src/Registry/SequenceTypeHandler.cpp b/Framework/PythonInterface/mantid/kernel/src/Registry/SequenceTypeHandler.cpp index abef235ee595aa642a8271f54208e3dbfd0f3a32..43cd1c0befae8e3e565ed27ba3c66e1b19240202 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Registry/SequenceTypeHandler.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Registry/SequenceTypeHandler.cpp @@ -52,9 +52,9 @@ void SequenceTypeHandler<ContainerType>::set( } // numpy arrays requires special handling to extract their types. Hand-off to // a more appropriate handler - else if (NumPy::NdArray::check(value)) { - alg->setProperty(name, Converters::NDArrayToVector<DestElementType>( - NumPy::NdArray(value))()); + else if (NDArray::check(value)) { + alg->setProperty( + name, Converters::NDArrayToVector<DestElementType>(NDArray(value))()); } else if (PySequence_Check(value.ptr())) { alg->setProperty(name, Converters::PySequenceToVector<DestElementType>(value)()); diff --git a/Framework/PythonInterface/mantid/kernel/src/kernel.cpp.in b/Framework/PythonInterface/mantid/kernel/src/kernel.cpp.in index e8c64d2134eb6a45c4a3672ec64f118fa75aaffe..26ba4609032e897f1766efb94e71c38f95abe7f1 100644 --- a/Framework/PythonInterface/mantid/kernel/src/kernel.cpp.in +++ b/Framework/PythonInterface/mantid/kernel/src/kernel.cpp.in @@ -7,6 +7,7 @@ #include <boost/python/def.hpp> #include "MantidKernel/MantidVersion.h" +#include "MantidPythonInterface/core/NDArray.h" #include "MantidPythonInterface/kernel/kernel.h" #include "MantidPythonInterface/kernel/Registry/TypeRegistry.h" @@ -30,7 +31,9 @@ BOOST_PYTHON_MODULE(_kernel) { // Doc string options - User defined, python arguments, C++ call signatures boost::python::docstring_options docstrings(true, true, false); - // Import numpy + // Import numpy for the core DLL + Mantid::PythonInterface::importNumpy(); + // Import numpy for this DLL _import_array(); def("version_str", &Mantid::Kernel::MantidVersion::version, diff --git a/Framework/PythonInterface/plugins/algorithms/AlignAndFocusPowderFromFiles.py b/Framework/PythonInterface/plugins/algorithms/AlignAndFocusPowderFromFiles.py index b8780a2067ff32aae20acc3a254ed99affc39bac..49d7a709ef704f78ccb21e360d88d750758941a0 100644 --- a/Framework/PythonInterface/plugins/algorithms/AlignAndFocusPowderFromFiles.py +++ b/Framework/PythonInterface/plugins/algorithms/AlignAndFocusPowderFromFiles.py @@ -208,12 +208,15 @@ class AlignAndFocusPowderFromFiles(DistributedDataProcessorAlgorithm): numSteps = 7 # one more for accumulating the unfocused workspace self.log().information('Processing \'{}\' in {:d} chunks'.format(filename, len(chunks))) prog_per_chunk_step = self.prog_per_file * 1./(numSteps*float(len(chunks))) + unfocusname_chunk = '' # inner loop is over chunks for (j, chunk) in enumerate(chunks): prog_start = file_prog_start + float(j) * float(numSteps - 1) * prog_per_chunk_step chunkname = '{}_c{:d}'.format(wkspname, j) - unfocusname_chunk = '{}_c{:d}'.format(unfocusname, j) + if unfocusname != '': # only create unfocus chunk if needed + unfocusname_chunk = '{}_c{:d}'.format(unfocusname, j) + Load(Filename=filename, OutputWorkspace=chunkname, startProgress=prog_start, endProgress=prog_start+prog_per_chunk_step, **chunk) diff --git a/Framework/PythonInterface/plugins/algorithms/MRGetTheta.py b/Framework/PythonInterface/plugins/algorithms/MRGetTheta.py index afa23e0d028e34c35b577b35c7dd5056baf8c5ff..680265808c61d313495a27ee3d5e7c6e1f42a58c 100644 --- a/Framework/PythonInterface/plugins/algorithms/MRGetTheta.py +++ b/Framework/PythonInterface/plugins/algorithms/MRGetTheta.py @@ -1,7 +1,7 @@ #pylint: disable=no-init,invalid-name from __future__ import (absolute_import, division, print_function) from mantid.api import PythonAlgorithm, AlgorithmFactory, WorkspaceProperty -from mantid.kernel import Direction, FloatBoundedValidator +from mantid.kernel import Direction, FloatBoundedValidator, Property import mantid.simpleapi import math @@ -27,8 +27,9 @@ class MRGetTheta(PythonAlgorithm): self.declareProperty("AngleOffset", 0.,FloatBoundedValidator(lower=0.), "Angle offset (rad)") self.declareProperty("UseSANGLE", False, doc="If True, use SANGLE as the scattering angle. If False, use DANGLE.") self.declareProperty("SpecularPixel", 0., doc="Pixel position of the specular reflectivity [optional]") - self.declareProperty("Theta", 0., direction=Direction.Output, doc="Scattering angle theta [rad]") - + self.declareProperty("DirectPixelOverwrite", Property.EMPTY_DBL, doc="DIRPIX overwrite value") + self.declareProperty("DAngle0Overwrite", Property.EMPTY_DBL, doc="DANGLE0 overwrite value (degrees)") + self.declareProperty("Theta", 0., direction=Direction.Output, doc="Scattering angle theta (rad)") return def PyExec(self): @@ -36,14 +37,23 @@ class MRGetTheta(PythonAlgorithm): _w=self.getProperty("Workspace").value angle_offset = self.getProperty("AngleOffset").value + dirpix_overwrite = self.getProperty("DirectPixelOverwrite").value + dangle0_overwrite = self.getProperty("DAngle0Overwrite").value + use_sangle = self.getProperty("UseSANGLE").value - if self.getProperty("UseSANGLE").value: + if use_sangle: theta = self.read_log(_w, 'SANGLE', target_units='rad', assumed_units='deg') else: dangle = self.read_log(_w, 'DANGLE', target_units='rad', assumed_units='deg') - dangle0 = self.read_log(_w, 'DANGLE0', target_units='rad', assumed_units='deg') + if dangle0_overwrite == Property.EMPTY_DBL: + dangle0 = self.read_log(_w, 'DANGLE0', target_units='rad', assumed_units='deg') + else: + dangle0 = dangle0_overwrite * math.pi / 180.0 det_distance = self.read_log(_w, 'SampleDetDis', target_units='m', assumed_units='mm') - direct_beam_pix = _w.getRun()['DIRPIX'].getStatistics().mean + if dirpix_overwrite == Property.EMPTY_DBL: + direct_beam_pix = _w.getRun()['DIRPIX'].getStatistics().mean + else: + direct_beam_pix = dirpix_overwrite ref_pix = self.getProperty("SpecularPixel").value if ref_pix == 0.: ref_pix = direct_beam_pix diff --git a/Framework/PythonInterface/plugins/algorithms/MRInspectData.py b/Framework/PythonInterface/plugins/algorithms/MRInspectData.py index 37e09844f44a50efd55dec4e4467e4c0d68cb611..7bf05aefaff7066f51d3a63fd4c2c1982ac3b660 100644 --- a/Framework/PythonInterface/plugins/algorithms/MRInspectData.py +++ b/Framework/PythonInterface/plugins/algorithms/MRInspectData.py @@ -58,6 +58,8 @@ class MRInspectData(PythonAlgorithm): "Pixel range defining the background") self.declareProperty("EventThreshold", 10000, "Minimum number of events needed to call a data set a valid direct beam") + self.declareProperty("DirectPixelOverwrite", Property.EMPTY_DBL, doc="DIRPIX overwrite value") + self.declareProperty("DAngle0Overwrite", Property.EMPTY_DBL, doc="DANGLE0 overwrite value (degrees)") def PyExec(self): nxs_data = self.getProperty("Workspace").value @@ -74,7 +76,9 @@ class MRInspectData(PythonAlgorithm): low_res_roi=self.getProperty("LowResPeakROI").value, force_bck_roi=self.getProperty("ForceBckROI").value, bck_roi=self.getProperty("BckROI").value, - event_threshold=self.getProperty("EventThreshold").value) + event_threshold=self.getProperty("EventThreshold").value, + dirpix_overwrite=self.getProperty("DirectPixelOverwrite").value, + dangle0_overwrite=self.getProperty("DAngle0Overwrite").value) # Store information in logs mantid.simpleapi.AddSampleLog(Workspace=nxs_data, LogName='calculated_scatt_angle', @@ -146,7 +150,8 @@ class DataInfo(object): def __init__(self, ws, cross_section='', use_roi=True, update_peak_range=False, use_roi_bck=False, use_tight_bck=False, bck_offset=3, force_peak_roi=False, peak_roi=[0,0], force_low_res_roi=False, low_res_roi=[0,0], - force_bck_roi=False, bck_roi=[0,0], event_threshold=10000): + force_bck_roi=False, bck_roi=[0,0], event_threshold=10000, + dirpix_overwrite=None, dangle0_overwrite=None): self.cross_section = cross_section self.run_number = ws.getRunNumber() self.is_direct_beam = False @@ -156,6 +161,8 @@ class DataInfo(object): self.low_res_range = [0,0] self.background = [0,0] self.n_events_cutoff = event_threshold + self.dangle0_overwrite = dangle0_overwrite + self.dirpix_overwrite = dirpix_overwrite # ROI information self.roi_peak = [0,0] @@ -406,7 +413,11 @@ class DataInfo(object): self.background = [int(max(0, bck_range[0])), int(min(bck_range[1], NY_PIXELS))] # Computed scattering angle - self.calculated_scattering_angle = 180.0 / math.pi * mantid.simpleapi.MRGetTheta(ws, SpecularPixel=self.peak_position) + self.calculated_scattering_angle = mantid.simpleapi.MRGetTheta(ws, + SpecularPixel=self.peak_position, + DirectPixelOverwrite=self.dirpix_overwrite, + DAngle0Overwrite=self.dangle0_overwrite) + self.calculated_scattering_angle *= 180.0 / math.pi # Determine whether we have a direct beam self.is_direct_beam = self.check_direct_beam(ws, self.peak_position) diff --git a/Framework/PythonInterface/plugins/algorithms/MagnetismReflectometryReduction.py b/Framework/PythonInterface/plugins/algorithms/MagnetismReflectometryReduction.py index 5edccba789462c2ad446b6d4746025754d8f3e74..448a0c65a3547bec54234eb60968249dc1f2227f 100644 --- a/Framework/PythonInterface/plugins/algorithms/MagnetismReflectometryReduction.py +++ b/Framework/PythonInterface/plugins/algorithms/MagnetismReflectometryReduction.py @@ -92,7 +92,6 @@ class MagnetismReflectometryReduction(PythonAlgorithm): self.declareProperty("QMin", 0.005, doc="Minimum Q-value") self.declareProperty("QStep", 0.02, doc="Step size in Q. Enter a negative value to get a log scale") self.declareProperty("AngleOffset", 0.0, doc="angle offset (rad)") - self.declareProperty(WorkspaceProperty("OutputWorkspace", "", Direction.Output), "Output workspace") self.declareProperty("TimeAxisStep", 40.0, doc="Binning step size for the time axis. TOF for detector binning, wavelength for constant Q") self.declareProperty("CropFirstAndLastPoints", True, doc="If true, we crop the first and last points") @@ -100,6 +99,9 @@ class MagnetismReflectometryReduction(PythonAlgorithm): doc="With const-Q binning, cut Q bins with contributions fewer than ConstQTrim of WL bins") self.declareProperty("SampleLength", 10.0, doc="Length of the sample in mm") self.declareProperty("ConstantQBinning", False, doc="If true, we convert to Q before summing") + self.declareProperty("DirectPixelOverwrite", Property.EMPTY_DBL, doc="DIRPIX overwrite value") + self.declareProperty("DAngle0Overwrite", Property.EMPTY_DBL, doc="DANGLE0 overwrite value (degrees)") + self.declareProperty(WorkspaceProperty("OutputWorkspace", "", Direction.Output), "Output workspace") #pylint: disable=too-many-locals def PyExec(self): @@ -554,9 +556,13 @@ class MagnetismReflectometryReduction(PythonAlgorithm): angle_offset = self.getProperty("AngleOffset").value use_sangle = self.getProperty("UseSANGLE").value ref_pix = self.getProperty("SpecularPixel").value + dirpix_overwrite = self.getProperty("DirectPixelOverwrite").value + dangle0_overwrite = self.getProperty("DAngle0Overwrite").value - _theta = MRGetTheta(Workspace=ws_event_data, AngleOffset = angle_offset, - UseSANGLE = use_sangle, SpecularPixel = ref_pix) + _theta = MRGetTheta(Workspace=ws_event_data, AngleOffset=angle_offset, + UseSANGLE=use_sangle, SpecularPixel=ref_pix, + DirectPixelOverwrite=dirpix_overwrite, + DAngle0Overwrite=dangle0_overwrite) return _theta diff --git a/Framework/PythonInterface/plugins/algorithms/MatchSpectra.py b/Framework/PythonInterface/plugins/algorithms/MatchSpectra.py new file mode 100644 index 0000000000000000000000000000000000000000..b5068797d588b535b8be80e7e9cef29cc7e09a91 --- /dev/null +++ b/Framework/PythonInterface/plugins/algorithms/MatchSpectra.py @@ -0,0 +1,230 @@ +from __future__ import (absolute_import, division, print_function) +from mantid.api import AlgorithmFactory, MatrixWorkspaceProperty, PythonAlgorithm +from mantid.kernel import Direction, FloatArrayProperty +from mantid.simpleapi import ConvertToMatrixWorkspace +import numpy as np + + +class MatchSpectra(PythonAlgorithm): + def category(self): + return 'Diffraction\\Reduction' + + #def seeAlso(self): + # return [''] + + def name(self): + return "MatchSpectra" + + def summary(self): + return "Calculate factors to most closely match all spectra to reference spectrum" + + def PyInit(self): + self.declareProperty(MatrixWorkspaceProperty('InputWorkspace', '', + Direction.Input), + doc='Workspace to match the spectra between') + self.declareProperty(MatrixWorkspaceProperty('OutputWorkspace', '', + Direction.Output), + doc='Workspace with the spectra matched') + self.declareProperty('ReferenceSpectrum', 1, + doc='Spectrum to match other spectra to') + self.declareProperty('CalculateOffset', True, + doc='Calculate vertical shift') + self.declareProperty('CalculateScale', True, + doc='Calculate scale factor') + + self.declareProperty(FloatArrayProperty('Offset', values=[], + direction=Direction.Output), + 'Additive factor from matching') + self.declareProperty(FloatArrayProperty('Scale', values=[], + direction=Direction.Output), + 'Multiplicitive factor from matching') + self.declareProperty(FloatArrayProperty('ChiSq', values=[], + direction=Direction.Output), + 'Unweighted ChiSq between the spectrum and the reference. ' + 'NaN means that the spectrum was not matched') + + def __getReferenceWsIndex(self): + refSpectrum = self.getProperty('ReferenceSpectrum').value + inputWS = self.getProperty('InputWorkspace').value + + for wkspIndex in range(inputWS.getNumberHistograms()): + if inputWS.getSpectrum(wkspIndex).getSpectrumNo() == refSpectrum: + return wkspIndex + + raise RuntimeError('Failed to find spectrum {} in workspace "{}"'.format(refSpectrum, inputWS)) + + def __createOutputWS(self): + '''Convert to a Workspace2D despite what the algorithm is named''' + outputWS = ConvertToMatrixWorkspace(InputWorkspace=self.getPropertyValue('InputWorkspace'), + OutputWorkspace=self.getPropertyValue("OutputWorkspace")) + return outputWS + + def __generateIndices(self, spectrumNum, reference, testing, binBoundaries): + '''Generates the indices for slicing by comparing x-axes + + A note about implementation: If numpy.searchsorted fails to find the + value, it returns the last index of the array. + ''' + BAD_RESULT = (False, (0, 0), (0, 0)) + # find the lower bounds + refLower = 0 + tstLower = 0 + if reference[0] == testing[0]: + pass # values are already set + elif reference[0] < testing[0]: + refLower = np.searchsorted(reference, testing[0]) + if refLower == reference.size: + msg = 'Falied to find {} in reference spectrum x-axis (spectrum={})'.format(testing[0], spectrumNum) + self.log().notice(msg) + return BAD_RESULT + else: + tstLower = np.searchsorted(testing, reference[0]) + if tstLower == testing.size: + msg = 'Falied to find {} in the x-axis of the spectrum being matched (spectrum={})'.format(reference[0], + spectrumNum) + self.log().notice(msg) + return BAD_RESULT + + # find the upper bounds + refUpper = reference.size-1 + tstUpper = testing.size-1 + if binBoundaries: + refUpper -= 1 + tstUpper -= 1 + if reference[refUpper] == testing[tstUpper]: + pass # values are already set + elif reference[refUpper] < testing[tstUpper]: + tstUpper = np.searchsorted(testing, reference[refUpper]) + if reference[refUpper] != testing[tstUpper]: + msg = 'Falied to find {} in the x-axis of the spectrum being matched (spectrum={})'.format(reference[-1], + spectrumNum) + self.log().notice(msg) + return BAD_RESULT + else: + refUpper = np.searchsorted(reference, testing[tstUpper]) + if reference[refUpper] != testing[tstUpper]: + msg = 'Falied to find {} in reference spectrum x-axis (spectrum={})'.format(testing[-1], spectrumNum) + self.log().notice(msg) + return BAD_RESULT + + if (reference[refLower:refUpper]).size != (testing[tstLower:tstUpper]).size: + self.log().notice(msg) + return BAD_RESULT + + return (True, (refLower, refUpper), (tstLower, tstUpper)) + + def __residual(self, X, Y1, Y2): + deltaX = np.diff(X) + deltaX = np.append(deltaX, deltaX[-1]) # add the last value to the end + return (np.square(Y1 - Y2)*deltaX).sum() / deltaX.sum() + + def PyExec(self): + referenceWkspIndex = self.__getReferenceWsIndex() + outputWS = self.__createOutputWS() + + # determine what to calculate + doScale = self.getProperty('CalculateScale').value + doOffset = self.getProperty('CalculateOffset').value + + referenceX = outputWS.readX(referenceWkspIndex) + referenceY = outputWS.readY(referenceWkspIndex) + referenceE = outputWS.readE(referenceWkspIndex) + + if not np.any(referenceE > 0.): + raise RuntimeError('None of the uncertainties in the reference spectrum ' + 'is greater than zero. No data would be used.') + + resultOffset = [] + resultScale = [] + resultResidual = [] + + # this is just gauss-markov theorem + for wkspIndex in range(outputWS.getNumberHistograms()): # in nb which appears to be number of banks + spectrumNum = outputWS.getSpectrum(wkspIndex).getSpectrumNo() + if wkspIndex == referenceWkspIndex: + resultOffset.append(0.) + resultScale.append(1.) + resultResidual.append(0.) + self.log().information('spectrum {} is the reference'.format(spectrumNum)) + continue + + X = outputWS.readX(wkspIndex) + Y = outputWS.readY(wkspIndex) + E = outputWS.readE(wkspIndex) + + if not np.any(E > 0.): + self.log().warning('None of the uncertainties in the reference spectrum {} is greater than zero'.format(spectrumNum)) + resultOffset.append(0.) + resultScale.append(1.) + resultResidual.append(np.nan) + continue + + hasOverlap, refIndices, tstIndices = self.__generateIndices(spectrumNum, referenceX, X, X.size == Y.size+1) + if not hasOverlap: + resultOffset.append(0.) + resultScale.append(1.) + resultResidual.append(np.nan) + continue + + mask = (E[tstIndices[0]:tstIndices[1]] > 0.) * (referenceE[refIndices[0]:refIndices[1]] > 0.) + if not np.any(mask): + resultOffset.append(0.) + resultScale.append(1.) + resultResidual.append(np.nan) + self.log().warning('The overlap region of spectrum {} has no uncertainties greater than zero'.format(spectrumNum)) + continue + totalBins = mask.sum() # number of bins being used + + # only calculate the terms that are needed + if doOffset: + sumRef = referenceY[refIndices[0]:refIndices[1]][mask].sum() + sumSpec = Y[tstIndices[0]:tstIndices[1]][mask].sum() + if doScale: + sumSpecSq = (Y[tstIndices[0]:tstIndices[1]][mask] * Y[tstIndices[0]:tstIndices[1]][mask]).sum() + sumRefSpec = (Y[tstIndices[0]:tstIndices[1]][mask] * referenceY[refIndices[0]:refIndices[1]][mask]).sum() + + # defaults are to do nothing + scale = 1. + offset = 0. + + if doScale and doOffset: # use both + # Cramar's rule for 2x2 matrix + denominator = totalBins * sumSpecSq - sumSpec * sumSpec + scale = (totalBins * sumRefSpec - sumRef * sumSpec) / denominator + offset = (sumRef * sumSpecSq - sumSpec * sumRefSpec) / denominator + elif doScale and not doOffset: # only scale + scale = sumRefSpec / sumSpecSq + elif doOffset and not doScale: # only shift + offset = (sumRef - sumSpec) / totalBins + + # calculate the residual of the fit - must be done before updating values + residual = self.__residual(X[tstIndices[0]:tstIndices[1]][mask], + Y[tstIndices[0]:tstIndices[1]][mask] * scale + offset, + referenceY[refIndices[0]:refIndices[1]][mask]) + resultResidual.append(residual) + + msg = 'spectrum {} chisq '.format(spectrumNum) \ + + 'before={} '.format(self.__residual(X[tstIndices[0]:tstIndices[1]][mask], + Y[tstIndices[0]:tstIndices[1]][mask], + referenceY[refIndices[0]:refIndices[1]][mask])) \ + + 'after={}'.format(residual) + self.log().information(msg) + + # update the values in the output workspace + Ynew = np.copy(Y) + Ynew[E > 0.] = Ynew[E > 0.] * scale + offset + outputWS.setY(wkspIndex, Ynew) + outputWS.setE(wkspIndex, E * scale) # background doesn't matter because there isn't uncertainty + + resultOffset.append(offset) + resultScale.append(scale) + + # set output properties + self.setProperty('OutputWorkspace', outputWS) + self.setProperty('Offset', resultOffset) + self.setProperty('Scale', resultScale) + self.setProperty('ChiSq', resultResidual) + + +# Register algorithm with Mantid. +AlgorithmFactory.subscribe(MatchSpectra) diff --git a/Framework/PythonInterface/plugins/algorithms/ReflectometrySliceEventWorkspace.py b/Framework/PythonInterface/plugins/algorithms/ReflectometrySliceEventWorkspace.py new file mode 100644 index 0000000000000000000000000000000000000000..a4553d070dde6e89b90ff47b6278b1b8d09c17b8 --- /dev/null +++ b/Framework/PythonInterface/plugins/algorithms/ReflectometrySliceEventWorkspace.py @@ -0,0 +1,154 @@ +from __future__ import (absolute_import, division, print_function) +from mantid.api import * +from mantid.kernel import * +from mantid.simpleapi import * + + +class ReflectometrySliceEventWorkspace(DataProcessorAlgorithm): + def category(self): + return "Reflectometry" + + def name(self): + return "ReflectometrySliceEventWorkspace" + + def summary(self): + return "Split an input workspace into multiple slices according to time or log values" + + def seeAlso(self): + return [ "GenerateEventsFilter","FilterEvents" ,"ReflectometryReductionOneAuto"] + + def PyInit(self): + # Add properties from child algorithm + self._filter_properties = [ + 'InputWorkspace', 'StartTime', 'StopTime','TimeInterval', + 'LogName','MinimumLogValue','MaximumLogValue', 'LogValueInterval'] + self.copyProperties('GenerateEventsFilter', self._filter_properties) + + # Add our own properties + self.declareProperty(MatrixWorkspaceProperty("MonitorWorkspace", "", direction=Direction.Input), + "Input monitor workspace") + self.declareProperty(WorkspaceGroupProperty('OutputWorkspace', '', + direction=Direction.Output), + doc='Group name for the output workspace(s).') + + def PyExec(self): + self._input_ws = self.getProperty("InputWorkspace").value + self._output_ws_group_name = self.getPropertyValue("OutputWorkspace") + + self._create_filter() + output_ws_group = self._slice_input_workspace() + self._scale_monitors_for_each_slice(output_ws_group) + output_ws_group = self._rebin_to_monitors() + output_ws_group = self._add_monitors_to_sliced_output() + + self.setProperty("OutputWorkspace", self._output_ws_group_name) + self._clean_up() + + def _create_filter(self): + """Generate the splitter workspace for performing the filtering for each required slice""" + alg = self.createChildAlgorithm("GenerateEventsFilter") + for property in self._filter_properties: + alg.setProperty(property, self.getPropertyValue(property)) + alg.setProperty("OutputWorkspace", '__split') + alg.setProperty("InformationWorkspace", '__info') + alg.execute() + self._split_ws = alg.getProperty("OutputWorkspace").value + self._info_ws = alg.getProperty("InformationWorkspace").value + + def _slice_input_workspace(self): + """Perform the slicing of the input workspace""" + alg = self.createChildAlgorithm("FilterEvents") + alg.setProperty("InputWorkspace", self._input_ws) + alg.setProperty("SplitterWorkspace", self._split_ws) + alg.setProperty("InformationWorkspace", self._info_ws) + alg.setProperty("OutputWorkspaceBaseName", self._output_ws_group_name) + alg.setProperty("GroupWorkspaces", True) + alg.setProperty("FilterByPulseTime", False) + alg.setProperty("OutputWorkspaceIndexedFrom1", True) + alg.setProperty("CorrectionToSample", "None") + alg.setProperty("SpectrumWithoutDetector", "Skip") + alg.setProperty("SplitSampleLogs", False) + alg.setProperty("OutputTOFCorrectionWorkspace", "__mock") + alg.setProperty("ExcludeSpecifiedLogs", False) + alg.setProperty("TimeSeriesPropertyLogs", 'proton_charge') + alg.execute() + return mtd[self._output_ws_group_name] + + def _scale_monitors_for_each_slice(self, sliced_ws_group): + """Create a group workspace which contains a copy of the monitors workspace for + each slice, scaled by the relative proton charge for that slice""" + input_monitor_ws = self.getProperty("MonitorWorkspace").value + total_proton_charge = self._total_proton_charge() + monitors_ws_list = [] + i=1 + for slice in sliced_ws_group: + slice_monitor_ws_name = input_monitor_ws.getName() + '_'+str(i) + slice_monitor_ws = self._clone_workspace(input_monitor_ws, slice_monitor_ws_name) + scale_factor = slice.run().getProtonCharge() / total_proton_charge + slice_monitor_ws = self._scale_workspace(slice_monitor_ws, slice_monitor_ws_name, + scale_factor) + # The workspace must be in the ADS for grouping + mtd.addOrReplace(slice_monitor_ws_name, slice_monitor_ws) + monitors_ws_list.append(slice_monitor_ws_name) + i+=1 + + self._monitor_ws_group_name = input_monitor_ws.getName() + '_sliced' + self._monitor_ws_group = self._group_workspaces(monitors_ws_list, self._monitor_ws_group_name) + mtd.addOrReplace(self._monitor_ws_group_name, self._monitor_ws_group) + + def _clone_workspace(self, ws_to_clone, output_ws_name): + alg = self.createChildAlgorithm("CloneWorkspace") + alg.setProperty("InputWorkspace", ws_to_clone) + alg.setProperty("OutputWorkspace", output_ws_name) + alg.execute() + return alg.getProperty("OutputWorkspace").value + + def _scale_workspace(self, ws_to_scale, output_ws_name, scale_factor): + alg = self.createChildAlgorithm("Scale") + alg.setProperty("InputWorkspace", ws_to_scale) + alg.setProperty("OutputWorkspace", output_ws_name) + alg.setProperty("Factor", scale_factor) + alg.execute() + return alg.getProperty("OutputWorkspace").value + + def _group_workspaces(self, ws_list, output_ws_name): + alg = self.createChildAlgorithm("GroupWorkspaces") + alg.setProperty("InputWorkspaces", ws_list) + alg.setProperty("OutputWorkspace", output_ws_name) + alg.execute() + return alg.getProperty("OutputWorkspace").value + + def _total_proton_charge(self): + """Get the proton charge for the input workspace""" + return self._input_ws.run().getProtonCharge() + + def _rebin_to_monitors(self): + """Rebin the output workspace group to the monitors workspace group""" + alg = self.createChildAlgorithm("RebinToWorkspace") + alg.setProperty("WorkspaceToRebin", self._output_ws_group_name) + alg.setProperty("WorkspaceToMatch", self._monitor_ws_group_name) + alg.setProperty("OutputWorkspace", self._output_ws_group_name) + alg.setProperty("PreserveEvents", False) + alg.execute() + return alg.getProperty("OutputWorkspace").value + + def _add_monitors_to_sliced_output(self): + """Add the monitors for each slice to the output workspace for each slice""" + alg = self.createChildAlgorithm("AppendSpectra") + alg.setProperty("InputWorkspace1", self._monitor_ws_group_name) + alg.setProperty("InputWorkspace2", self._output_ws_group_name) + alg.setProperty("MergeLogs", True) + alg.setProperty("OutputWorkspace", self._output_ws_group_name) + alg.execute() + return alg.getProperty("OutputWorkspace").value + + def _clean_up(self): + """Remove worspaces added to the ADS""" + monitor_ws_names = [ws.getName() for ws in self._monitor_ws_group] + alg = self.createChildAlgorithm("UnGroupWorkspace") + alg.setProperty("InputWorkspace", self._monitor_ws_group_name) + alg.execute() + for ws_name in monitor_ws_names: + mtd.remove(ws_name) + +AlgorithmFactory.subscribe(ReflectometrySliceEventWorkspace()) diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLDetScanReduction.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLDetScanReduction.py index 323f6f868ed98708d45d5e07db2074d4966c8f49..571d54cb069c75bd0cf158456cf8c3aa3b109903 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLDetScanReduction.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLDetScanReduction.py @@ -21,7 +21,7 @@ class PowderDiffILLDetScanReduction(DataProcessorAlgorithm): return 'Performs powder diffraction data reduction for D2B and D20 (when doing a detector scan).' def seeAlso(self): - return [ "PowderDiffILLReduction" ] + return [ "PowderDiffILLReduction", "PowderDiffILLDetEffCorr" ] def name(self): return "PowderDiffILLDetScanReduction" diff --git a/Framework/PythonInterface/test/cpp/CMakeLists.txt b/Framework/PythonInterface/test/cpp/CMakeLists.txt index 86c0bb1b595b3b63fa4b9a4a89f7a7c64885da7e..9249ab8a5cd9fde9e04e446862dd6f039783f7c2 100644 --- a/Framework/PythonInterface/test/cpp/CMakeLists.txt +++ b/Framework/PythonInterface/test/cpp/CMakeLists.txt @@ -13,8 +13,9 @@ set ( TEST_FILES if ( CXXTEST_FOUND ) include_directories ( SYSTEM ${CXXTEST_INCLUDE_DIR} ) - + set ( CXXTEST_EXTRA_HEADER_INCLUDE "${CMAKE_CURRENT_LIST_DIR}/GlobalInitialization.h" ) cxxtest_add_test ( PythonInterfaceCppTest ${TEST_FILES} ) + if ( WIN32 ) set_target_properties( PythonInterfaceCppTest PROPERTIES COMPILE_FLAGS "/w44244" ) endif () @@ -22,6 +23,7 @@ if ( CXXTEST_FOUND ) API Geometry Kernel + PythonInterfaceCore PythonKernelModule PythonAPIModule ${Boost_LIBRARIES} diff --git a/Framework/PythonInterface/test/cpp/GlobalInitialization.h b/Framework/PythonInterface/test/cpp/GlobalInitialization.h new file mode 100644 index 0000000000000000000000000000000000000000..91456a10c8230f4cae049d31c13dfcc21949032f --- /dev/null +++ b/Framework/PythonInterface/test/cpp/GlobalInitialization.h @@ -0,0 +1,63 @@ +#ifndef PYTHONINTERFACECPP_GLOBALINITIALIZATION_H +#define PYTHONINTERFACECPP_GLOBALINITIALIZATION_H + +#include "MantidKernel/ConfigService.h" +#include "MantidPythonInterface/core/NDArray.h" +#include "MantidPythonInterface/core/VersionCompat.h" +#ifdef _WIN32 +#include "MantidPythonInterface/kernel/kernel.h" +#endif +#include "cxxtest/GlobalFixture.h" +#include <boost/algorithm/string/trim.hpp> +/** + * PythonInterpreter + * + * Uses setUpWorld/tearDownWorld to initialize & finalize + * Python + */ +class PythonInterpreter : CxxTest::GlobalFixture { +public: + bool setUpWorld() override { + using Mantid::Kernel::ConfigService; + using Mantid::PythonInterface::importNumpy; + using boost::algorithm::trim_right_copy_if; + + Py_Initialize(); + importNumpy(); + // add location of mantid module to sys.path + std::string propDir = + trim_right_copy_if(ConfigService::Instance().getPropertiesDir(), + [](char c) { return (c == '/' || c == '\\'); }); + const std::string appendMantidToPath = "import sys\n" + "sys.path.insert(0, '" + + propDir + "')"; + PyRun_SimpleString(appendMantidToPath.c_str()); +#ifdef _WIN32 + // See kernel.h for the explanation + kernel_dll_import_numpy_capi_for_unittest(); +#endif + + return Py_IsInitialized(); + } + + bool tearDown() override { + // Some test methods may leave the Python error handler with an error + // set that confuse other tests when the executable is run as a whole + // Clear the errors after each suite method is run + PyErr_Clear(); + return CxxTest::GlobalFixture::tearDown(); + } + + bool tearDownWorld() override { + Py_Finalize(); + return true; + } +}; + +//------------------------------------------------------------------------------ +// We rely on cxxtest only including this file once so that the following +// statements do not cause multiple-definition errors. +//------------------------------------------------------------------------------ +static PythonInterpreter PYTHON_INTERPRETER; + +#endif // PYTHONINTERFACECPP_GLOBALINITIALIZATION_H diff --git a/Framework/PythonInterface/test/cpp/PythonAlgorithmInstantiatorTest.h b/Framework/PythonInterface/test/cpp/PythonAlgorithmInstantiatorTest.h index c836aa5ae85c97d24470a619a8f95dd762355d76..2d3f05ec71ada991e53e3a8dacd074b24983ffba 100644 --- a/Framework/PythonInterface/test/cpp/PythonAlgorithmInstantiatorTest.h +++ b/Framework/PythonInterface/test/cpp/PythonAlgorithmInstantiatorTest.h @@ -4,64 +4,10 @@ #include "MantidAPI/IAlgorithm.h" #include "MantidKernel/make_unique.h" #include "MantidPythonInterface/kernel/PythonObjectInstantiator.h" -#include "MantidPythonInterface/kernel/kernel.h" -#include <cxxtest/GlobalFixture.h> #include <cxxtest/TestSuite.h> -#include "MantidKernel/ConfigService.h" -#include <boost/algorithm/string/trim.hpp> #include <boost/python/object.hpp> -// ---------- Test world initialization --------------------------------- - -/** - * The cxxtest code ensures that the setup/tearDownWorld methods - * are called exactly once per test-process. We use this - * to initialize/shutdown the python interpreter - */ -class PythonProcessHandler : CxxTest::GlobalFixture { -public: - bool setUpWorld() override { - using Mantid::Kernel::ConfigService; - using boost::algorithm::trim_right_copy_if; - Py_Initialize(); - // add location of mantid module to sys.path - std::string propDir = - trim_right_copy_if(ConfigService::Instance().getPropertiesDir(), - [](char c) { return (c == '/' || c == '\\'); }); - const std::string appendMantidToPath = "import sys\n" - "sys.path.insert(0, '" + - propDir + "')"; - PyRun_SimpleString(appendMantidToPath.c_str()); - PyRun_SimpleString("import mantid"); -#ifdef _WIN32 - // See kernel.h for the explanation - kernel_dll_import_numpy_capi_for_unittest(); -#endif - return true; - } - - bool tearDown() override { - // Some test methods leave the Python error handler with an error - // set that confuse other tests when the executable is run as a whole - // Clear the errors after each suite method is run - PyErr_Clear(); - return CxxTest::GlobalFixture::tearDown(); - } - - bool tearDownWorld() override { - Py_Finalize(); - return true; - } -}; - -// From the cxxtest manual: -// -// We can rely on this file being included exactly once -// and declare this global variable in the header file. -// -static PythonProcessHandler pythonProcessHandler; - //------------------------------------------------------------------------- using Mantid::API::IAlgorithm; diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/CMakeLists.txt b/Framework/PythonInterface/test/python/plugins/algorithms/CMakeLists.txt index aff4e032c58eb38c018a4967a9065c8eb2abaff1..e43ec3186865819907ed935a97b3f8f9d11865a7 100644 --- a/Framework/PythonInterface/test/python/plugins/algorithms/CMakeLists.txt +++ b/Framework/PythonInterface/test/python/plugins/algorithms/CMakeLists.txt @@ -66,6 +66,7 @@ set ( TEST_PY_FILES LoadNMoldyn4AsciiTest.py LoadWANDSCDTest.py LRPeakSelectionTest.py + MatchSpectraTest.py MaskAngleTest.py MaskBTPTest.py MaskWorkspaceToCalFileTest.py @@ -78,6 +79,7 @@ set ( TEST_PY_FILES NMoldyn4InterpolationTest.py NormaliseSpectraTest.py ReflectometryReductionOneLiveDataTest.py + ReflectometrySliceEventWorkspaceTest.py RetrieveRunInfoTest.py SANSWideAngleCorrectionTest.py SaveGEMMAUDParamFileTest.py diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/MatchSpectraTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/MatchSpectraTest.py new file mode 100644 index 0000000000000000000000000000000000000000..362b767eb1026447b7019da7a0686dc5cddbe20d --- /dev/null +++ b/Framework/PythonInterface/test/python/plugins/algorithms/MatchSpectraTest.py @@ -0,0 +1,176 @@ +from __future__ import (absolute_import, division, print_function) + +from mantid.simpleapi import CreateWorkspace, DeleteWorkspace, DeleteWorkspaces, MatchSpectra, mtd +import numpy as np +import unittest + + +class MatchSpectraTest(unittest.TestCase): + numhist = 4 + numpoints = 100 + + def __createWorkspace(self, name, histogram, uncertainties): + if histogram: + x = np.arange(self.numpoints + 1, dtype=np.float) + else: + x = np.arange(self.numpoints, dtype=np.float) + x = np.tile(x, self.numhist) + y = np.arange(self.numpoints, dtype=np.float) + y = np.tile(y, self.numhist) + y[self.numpoints:2 * self.numpoints] += 10 # for offset test + y[2 * self.numpoints:3 * self.numpoints] *= 10 # for scale test + y[3 * self.numpoints:] = y[3 * self.numpoints:] * 10 + 10 # for scale and offset test + dy = np.zeros(y.size, dtype=np.float) + 1 + + if uncertainties: + CreateWorkspace(OutputWorkspace=name, + DataX=x, + DataY=y, + DataE=dy, + NSpec=self.numhist) + else: + CreateWorkspace(OutputWorkspace=name, + DataX=x, + DataY=y, + NSpec=self.numhist) + + def __createRaggedWorkspace(self, name, histogram): + xlen = self.numpoints + if histogram: + xlen += 1 + x = np.arange(xlen, dtype=np.float) + x = np.tile(x, self.numhist) + shifts = (0., 10., 20., 30.) + # shift x-values so they are not common + for i, shift in enumerate(shifts): + x[i*xlen:(i+1)*xlen] += shift + + y = np.zeros(self.numhist * self.numpoints, dtype=np.float) + for i, shift in enumerate(shifts): + # follow shift from above + newY = np.arange(self.numpoints, dtype=np.float)+shift + if i == 1: + newY += 10. + elif i == 2: + newY *= 10. + elif i == 3: + newY = newY * 10 + 10 + # otherwise do nothing + y[i * self.numpoints:(i + 1) * self.numpoints] = newY + + dy = np.zeros(y.size, dtype=np.float) + 1 + + CreateWorkspace(OutputWorkspace=name, + DataX=x, + DataY=y, + DataE=dy, + NSpec=self.numhist) + + def __checkValues(self, results, index, scale, offset): + self.assertEqual(results.Scale[index], scale, + 'wksp index {} scale exp={} found={}'.format(index, scale, results.Scale[index])) + self.assertEqual(results.Offset[index], offset, + 'wksp index {} offset exp={} found={}'.format(index, offset, results.Offset[index])) + self.assertEqual(results.ChiSq[index], 0., 'wksp index {} chisq'.format(index)) + + def __checkReference(self, results, index): + self.assertEqual(results.Scale[index], 1., 'reference scale') + self.assertEqual(results.Offset[index], 0., 'reference offset') + self.assertEqual(results.ChiSq[index], 0., 'reference chisq') + + def testWithoutUncertainties(self): + inwsname = 'MatchSpectraTest_withoutUncertainties' + outwsname = inwsname + '_out' # never gets created + + for histogram in (True, False): + self.__createWorkspace(inwsname, histogram, False) + + with self.assertRaises(RuntimeError): + results = MatchSpectra(InputWorkspace=inwsname, OutputWorkspace=outwsname, + ReferenceSpectrum=1, + CalculateOffset=True, CalculateScale=True) + + DeleteWorkspace(Workspace=inwsname) + + def __testCommonBoundaries(self, histogram): + inwsname = 'MatchSpectraTest_commonBoundaries' + if histogram: + inwsname += 'Histogram' + else: + inwsname += 'Frequency' + outwsname = inwsname + '_out' + self.__createWorkspace(inwsname, histogram, True) + + ##### offset only + results = MatchSpectra(InputWorkspace=inwsname, OutputWorkspace=outwsname, + ReferenceSpectrum=2, + CalculateOffset=True, CalculateScale=False) + self.__checkReference(results, 1) + self.__checkValues(results, 0, 1., 10.) + self.assertTrue(np.alltrue(mtd[outwsname].readY(0) == mtd[outwsname].readY(1))) + + ##### scale only + results = MatchSpectra(InputWorkspace=inwsname, OutputWorkspace=outwsname, + ReferenceSpectrum=3, + CalculateOffset=False, CalculateScale=True) + self.__checkReference(results, 2) + self.__checkValues(results, 0, 10., 0.) + self.assertTrue(np.alltrue(mtd[outwsname].readY(0) == mtd[outwsname].readY(2))) + + ##### both + results = MatchSpectra(InputWorkspace=inwsname, OutputWorkspace=outwsname, + ReferenceSpectrum=4, + CalculateOffset=True, CalculateScale=True) + self.__checkReference(results, 3) + self.__checkValues(results, 0, 10., 10.) + self.assertTrue(np.alltrue(mtd[outwsname].readY(0) == mtd[outwsname].readY(3))) + + DeleteWorkspaces(WorkspaceList=[inwsname, outwsname]) + + def testCommonBoundariesHistogram(self): + self.__testCommonBoundaries(True) + + def testCommonBoundariesFrequency(self): + self.__testCommonBoundaries(False) + + def __testRaggedBoundaries(self, histogram): + inwsname = 'MatchSpectraTest_raggedBoundaries' + if histogram: + inwsname += 'Histogram' + else: + inwsname += 'Frequency' + outwsname = inwsname + '_out' + self.__createRaggedWorkspace(inwsname, histogram) + + ##### offset only + results = MatchSpectra(InputWorkspace=inwsname, OutputWorkspace=outwsname, + ReferenceSpectrum=2, + CalculateOffset=True, CalculateScale=False) + self.__checkReference(results, 1) + self.__checkValues(results, 0, 1., 10.) + + ##### scale only + results = MatchSpectra(InputWorkspace=inwsname, OutputWorkspace=outwsname, + ReferenceSpectrum=3, + CalculateOffset=False, CalculateScale=True) + self.__checkReference(results, 2) + self.__checkValues(results, 0, 10., 0.) + + ##### both + results = MatchSpectra(InputWorkspace=inwsname, OutputWorkspace=outwsname, + ReferenceSpectrum=4, + CalculateOffset=True, CalculateScale=True) + self.__checkReference(results, 3) + self.__checkValues(results, 0, 10., 10.) + + DeleteWorkspaces(WorkspaceList=[inwsname, outwsname]) + + def testRaggedBoundariesHistogram(self): + self.__testRaggedBoundaries(True) + + def testRaggedBoundariesFrequency(self): + self.__testRaggedBoundaries(False) + + +if __name__ == '__main__': + unittest.main() diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/ReflectometrySliceEventWorkspaceTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/ReflectometrySliceEventWorkspaceTest.py new file mode 100644 index 0000000000000000000000000000000000000000..fc6b0859602bc66e04e4b656d801020aa255d68c --- /dev/null +++ b/Framework/PythonInterface/test/python/plugins/algorithms/ReflectometrySliceEventWorkspaceTest.py @@ -0,0 +1,208 @@ +from __future__ import (absolute_import, division, print_function) + +import unittest + +from mantid.kernel import * +from mantid.api import * +from mantid.simpleapi import * +from testhelpers import (assertRaisesNothing, create_algorithm) + + +class ReflectometrySliceEventWorkspace(unittest.TestCase): + def setUp(self): + self.__class__._input_ws = self._create_test_workspace() + self.__class__._input_ws_group = self._create_test_workspace_group() + self.__class__._monitor_ws = self._create_monitor_workspace() + self.__class__._monitor_ws_group = self._create_monitor_workspace_group() + self._default_args = { + 'InputWorkspace' : 'input_ws', + 'MonitorWorkspace' : 'monitor_ws', + 'OutputWorkspace': 'output' + } + + def tearDown(self): + mtd.clear() + + def test_missing_input_workspace(self): + self._assert_run_algorithm_throws() + + def test_missing_monitors(self): + self._assert_run_algorithm_throws({'InputWorkspace' : 'input_ws'}) + + def test_missing_output_ws(self): + self._assert_run_algorithm_throws({'InputWorkspace' : 'input_ws', + 'MonitorWorkspace' : 'monitor_ws'}) + + def test_default_inputs_return_single_slice(self): + output = self._assert_run_algorithm_succeeds(self._default_args) + self.assertEquals(output.getNumberOfEntries(), 1) + first_slice = output[0] + self.assertEquals(first_slice.getNumberHistograms(), 5) + self.assertEquals(first_slice.dataX(0).size, 101) + self._assert_delta(first_slice.dataY(3)[0], 14) + self._assert_delta(first_slice.dataY(3)[51], 16) + self._assert_delta(first_slice.dataY(3)[99], 8) + + def test_setting_time_interval(self): + args = self._default_args + args['TimeInterval'] = 600 + output = self._assert_run_algorithm_succeeds(args) + self.assertEquals(output.getNumberOfEntries(), 7) + first_slice = output[0] + self.assertEquals(first_slice.dataX(0).size, 101) + self._assert_delta(first_slice.dataY(3)[0], 2) + self._assert_delta(first_slice.dataY(3)[51], 6) + self._assert_delta(first_slice.dataY(3)[99], 1) + + def test_setting_time_interval_and_limits(self): + args = self._default_args + args['TimeInterval'] = 600 + args['StartTime'] = '1800' + args['StopTime'] = '3300' + output = self._assert_run_algorithm_succeeds(args) + self.assertEquals(output.getNumberOfEntries(), 3) + first_slice = output[0] + self.assertEquals(first_slice.dataX(0).size, 101) + self._assert_delta(first_slice.dataY(3)[0], 4) + self._assert_delta(first_slice.dataY(3)[51], 2) + self._assert_delta(first_slice.dataY(3)[99], 2) + + def test_setting_log_interval_without_log_name_produces_single_slice(self): + args = self._default_args + args['LogValueInterval'] = 600 + output = self._assert_run_algorithm_succeeds(args) + self.assertEquals(output.getNumberOfEntries(), 1) + first_slice = output[0] + self.assertEquals(first_slice.getNumberHistograms(), 5) + self.assertEquals(first_slice.dataX(0).size, 101) + self._assert_delta(first_slice.dataY(3)[0], 14) + self._assert_delta(first_slice.dataY(3)[51], 16) + self._assert_delta(first_slice.dataY(3)[99], 8) + + def test_setting_log_interval_and_limits(self): + args = self._default_args + args['LogName'] = 'proton_charge' + args['LogValueInterval'] = 20 + args['MinimumLogValue'] = '75' + args['MaximumLogValue'] = '110' + output = self._assert_run_algorithm_succeeds(args) + self.assertEquals(output.getNumberOfEntries(), 2) + first_slice = output[0] + self.assertEquals(first_slice.dataX(0).size, 101) + self._assert_delta(first_slice.dataY(3)[0], 4) + self._assert_delta(first_slice.dataY(3)[51], 5) + self._assert_delta(first_slice.dataY(3)[99], 2) + + def test_when_input_is_a_workspace_group(self): + args = self._default_args + args['TimeInterval'] = 600 + args['InputWorkspace'] = 'input_ws_group' + output = self._assert_run_algorithm_succeeds(args) + self.assertEquals(output.getNumberOfEntries(), 3) + first_subgroup = output[0] + self.assertEquals(first_subgroup.getNumberOfEntries(), 7) + first_slice = first_subgroup[0] + self.assertEquals(first_slice.dataX(0).size, 101) + self._assert_delta(first_slice.dataY(3)[0], 2) + self._assert_delta(first_slice.dataY(3)[51], 6) + self._assert_delta(first_slice.dataY(3)[99], 1) + + def test_when_input_and_monitors_are_both_workspace_groups(self): + args = self._default_args + args['TimeInterval'] = 600 + args['InputWorkspace'] = 'input_ws_group' + args['MonitorWorkspace'] = 'monitor_ws_group' + output = self._assert_run_algorithm_succeeds(args) + self.assertEquals(output.getNumberOfEntries(), 3) + first_subgroup = output[0] + self.assertEquals(first_subgroup.getNumberOfEntries(), 7) + first_slice = first_subgroup[0] + self.assertEquals(first_slice.dataX(0).size, 101) + self._assert_delta(first_slice.dataY(3)[0], 2) + self._assert_delta(first_slice.dataY(3)[51], 6) + self._assert_delta(first_slice.dataY(3)[99], 1) + + def test_fails_when_input_groups_are_different_sizes(self): + group = self._create_monitor_workspace_group_with_two_members() + args = self._default_args + args['TimeInterval'] = 600 + args['InputWorkspace'] = 'input_ws_group' + args['MonitorWorkspace'] = 'test_monitor_ws_group' + self._assert_run_algorithm_fails(args) + mtd.remove('test_monitor_ws_group') + + def _create_test_workspace(self): + input_ws = CreateSampleWorkspace("Event",BankPixelWidth=1, BinWidth=20000) + AddTimeSeriesLog(input_ws, Name="proton_charge", Time="2010-01-01T00:00:00", Value=100) + AddTimeSeriesLog(input_ws, Name="proton_charge", Time="2010-01-01T00:10:00", Value=100) + AddTimeSeriesLog(input_ws, Name="proton_charge", Time="2010-01-01T00:20:00", Value=80) + AddTimeSeriesLog(input_ws, Name="proton_charge", Time="2010-01-01T00:30:00", Value=80) + AddTimeSeriesLog(input_ws, Name="proton_charge", Time="2010-01-01T00:40:00", Value=15) + AddTimeSeriesLog(input_ws, Name="proton_charge", Time="2010-01-01T00:50:00", Value=100) + return input_ws + + def _create_test_workspace_group(self): + ws1 = CloneWorkspace(self.__class__._input_ws) + ws2 = CloneWorkspace(self.__class__._input_ws) + ws3 = CloneWorkspace(self.__class__._input_ws) + mtd.addOrReplace('ws1', ws1) + mtd.addOrReplace('ws2', ws2) + mtd.addOrReplace('ws3', ws3) + group = GroupWorkspaces(InputWorkspaces='ws1,ws2,ws3') + mtd.addOrReplace('input_ws_group', group) + return group + + def _create_monitor_workspace(self): + monitor_ws = CreateSampleWorkspace(OutputWorkspace='monitor_ws', NumBanks=0, NumMonitors=3, + BankPixelWidth=1, NumEvents=10000, Random=True) + return monitor_ws + + def _create_monitor_workspace_group(self): + mon1 = CloneWorkspace(self.__class__._monitor_ws) + mon2 = CloneWorkspace(self.__class__._monitor_ws) + mon3 = CloneWorkspace(self.__class__._monitor_ws) + mtd.addOrReplace('mon1', mon1) + mtd.addOrReplace('mon2', mon2) + mtd.addOrReplace('mon3', mon3) + group = GroupWorkspaces(InputWorkspaces='mon1,mon2,mon3') + mtd.addOrReplace('monitor_ws_group', group) + return group + + def _create_monitor_workspace_group_with_two_members(self): + testmon1 = CloneWorkspace(self.__class__._monitor_ws) + testmon2 = CloneWorkspace(self.__class__._monitor_ws) + mtd.addOrReplace('testmon1', testmon1) + mtd.addOrReplace('testmon2', testmon2) + group = GroupWorkspaces(InputWorkspaces='testmon1,testmon2') + mtd.addOrReplace('test_monitor_ws_group', group) + return group + + def _assert_run_algorithm_succeeds(self, args): + """Run the algorithm with the given args and check it succeeds""" + alg = create_algorithm('ReflectometrySliceEventWorkspace', **args) + assertRaisesNothing(self, alg.execute) + self.assertEquals(mtd.doesExist('output'), True) + return mtd['output'] + + def _assert_run_algorithm_fails(self, args): + """Run the algorithm with the given args and check it fails to produce output""" + alg = create_algorithm('ReflectometrySliceEventWorkspace', **args) + assertRaisesNothing(self, alg.execute) + self.assertEquals(mtd.doesExist('output'), False) + + def _assert_run_algorithm_throws(self, args = {}): + """Run the algorithm with the given args and check it throws""" + throws = False + alg = create_algorithm('ReflectometrySliceEventWorkspace', **args) + try: + alg.execute() + except: + throws = True + self.assertEquals(throws, True) + + def _assert_delta(self, value1, value2): + self.assertEquals(round(value1, 6), round(value2, 6)) + + +if __name__ == '__main__': + unittest.main() diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/CMakeLists.txt b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/CMakeLists.txt index fdeda3031eafefbec645e2a0fe579b34e229d325..f2be3b341491d482dd28a42dd2c9c0d5b33e579c 100644 --- a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/CMakeLists.txt +++ b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/CMakeLists.txt @@ -41,6 +41,7 @@ set ( TEST_PY_FILES MSDFitTest.py OSIRISDiffractionReductionTest.py PowderDiffILLReductionTest.py + PowderDiffILLDetScanReductionTest.py ReflectometryILLConvertToQTest.py ReflectometryILLPolarizationCorTest.py ReflectometryILLPreprocessTest.py diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLDetScanReductionTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLDetScanReductionTest.py new file mode 100644 index 0000000000000000000000000000000000000000..a486a541d22ebc0218edd123c1180567284c1fd4 --- /dev/null +++ b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLDetScanReductionTest.py @@ -0,0 +1,42 @@ +from __future__ import (absolute_import, division, print_function) + +import unittest +from mantid.api import MatrixWorkspace, WorkspaceGroup +from mantid.simpleapi import PowderDiffILLDetScanReduction, config, mtd + + +# This is just a light test for the default options. +# More options are covered by system tests, since it takes too long for a unit test. +class PowderDiffILLDetScanReductionTest(unittest.TestCase): + + def setUp(self): + config['default.facility'] = 'ILL' + config['default.instrument'] = 'D2B' + config.appendDataSearchSubDir('ILL/D2B/') + + def tearDown(self): + mtd.clear() + + def test_default_options_d2b(self): + red = PowderDiffILLDetScanReduction(Run='508093') + self.assertTrue(red) + self.assertTrue(isinstance(red, WorkspaceGroup)) + self.assertEquals(red.getNumberOfEntries(), 1) + item = red.getItem(0) + self.assertTrue(item) + self.assertTrue(isinstance(item, MatrixWorkspace)) + self.assertTrue(item.isHistogramData()) + self.assertTrue(not item.isDistribution()) + self.assertEquals(item.getNumberHistograms(),1) + self.assertEquals(item.blocksize(),2975) + xaxis = item.getAxis(0).extractValues() + xunit = item.getAxis(0).getUnit().label() + self.assertEquals(xunit,'degrees') + self.assertAlmostEqual(xaxis[0],-0.029,3) + self.assertAlmostEqual(xaxis[1],0.021,3) + self.assertAlmostEqual(xaxis[-1],148.721,3) + spectrumaxis = item.getAxis(1).extractValues() + self.assertEquals(spectrumaxis[0],0) + +if __name__ == '__main__': + unittest.main() diff --git a/MantidPlot/CMakeLists.txt b/MantidPlot/CMakeLists.txt index 5d7f3c504519b8bae926831f8904148eac52cc9b..b6d215007ee8a6e5888fa2e0d8a6c8829a3c2b17 100644 --- a/MantidPlot/CMakeLists.txt +++ b/MantidPlot/CMakeLists.txt @@ -409,12 +409,6 @@ include ( UseQt4 ) include_directories ( ${PYTHON_INCLUDE_PATH} ) -set ( SIP_SPEC ${CMAKE_CURRENT_SOURCE_DIR}/src/qti.sip ) -set ( SIP_SRC_IN ${CMAKE_CURRENT_SOURCE_DIR}/src/sipqti.cpp.in ) -set ( SIP_SRC ${CMAKE_CURRENT_BINARY_DIR}/sipqti.cpp ) -set ( SIP_SRC_AUTO sip_qtipart0.cpp ) - - # We need to manually add all the headers that are in qti.sip # so that the dependencies are known to CMake set ( QTI_SIP_HDRS src/MdiSubWindow.h @@ -444,14 +438,11 @@ set( SRC_UNITY_IGNORE_FILES ) ########################################################################### # Sip generated files ########################################################################### +set ( SIP_SPEC ${CMAKE_CURRENT_SOURCE_DIR}/src/qti.sip ) +set ( SIP_SRC_AUTO sip_qtipart0.cpp ) -# The code generated by sip causes compiler warnings therefore the -# generated file is wrapped by ${SIP_SRC} and these warnings are -# disabled. In order for VS2010 to to this correctly the second -# custom command below is required along with the committed -# src/sipqti.cpp.rule file. set ( MANTIDQTPYTHON_SIP_INCLUDES -I ${CMAKE_CURRENT_BINARY_DIR}/../qt/python/mantidqtpython -I ${CMAKE_CURRENT_SOURCE_DIR}/../qt/python/mantidqtpython ) -add_custom_command ( OUTPUT ${SIP_SRC_AUTO} +add_custom_command ( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${SIP_SRC_AUTO} COMMAND ${SIP_EXECUTABLE} -I ${PYQT4_SIP_DIR} ${MANTIDQTPYTHON_SIP_INCLUDES} ${PYQT4_SIP_FLAGS} -c ${CMAKE_CURRENT_BINARY_DIR} -j1 -w -o @@ -460,12 +451,6 @@ add_custom_command ( OUTPUT ${SIP_SRC_AUTO} COMMENT "Generating python bindings using sip" ) -add_custom_command ( OUTPUT ${SIP_SRC} - COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${SIP_SRC_IN} ${SIP_SRC} - DEPENDS ${SIP_SRC_AUTO} - COMMENT "" -) - # Needed for sip.h header that can end up in a different place to to the main Python include directory include_directories ( SYSTEM ${SIP_INCLUDE_DIR} ) # Needed for sip generated files to find includes in src @@ -646,7 +631,7 @@ set_source_files_properties ( ${CMAKE_CURRENT_BINARY_DIR}/qtcolorpicker.moc PROPERTIES HEADER_FILE_ONLY true ) set ( MOCCED_FILES ${MOCCED_FILES} ${CMAKE_CURRENT_BINARY_DIR}/qtcolorpicker.moc ) -set ( SRC_FILES ${QTIPLOT_SRCS} ${MANTID_SRCS} ${SIP_SRC} ) +set ( SRC_FILES ${QTIPLOT_SRCS} ${MANTID_SRCS} ${SIP_SRC_AUTO} ) set ( INC_FILES ${QTIPLOT_HDRS} ${MANTID_HDRS} ) if ( WIN32 ) set ( MANIFEST_FILES MantidPlot.manifest ) @@ -792,12 +777,14 @@ target_include_directories ( MantidPlot PRIVATE ../qt/widgets/sliceviewer/inc ../qt/widgets/spectrumviewer/inc ../qt/widgets/factory/inc + ../Framework/PythonInterface/inc ) # Library dependencies target_link_libraries ( MantidPlot LINK_PRIVATE ${TCMALLOC_LIBRARIES_LINKTIME} ${CORE_MANTIDLIBS} + PythonInterfaceCore MantidQtWidgetsCommonQt4 MantidQtWidgetsLegacyQwtQt4 MantidQtWidgetsFactoryQt4 @@ -904,6 +891,7 @@ set ( MANTIDPLOT_TEST_PY_FILES MantidPlotMdiSubWindowTest.py MantidPlotTiledWindowTest.py MantidPlotInputArgsCheck.py + TSVSerialiserTest.py ) if ( MAKE_VATES ) @@ -921,7 +909,7 @@ endif () # Add an environment property MANTID_SOURCE so that the script can find the source of xmlrunner if ( ${CMAKE_SYSTEM_NAME} STREQUAL "Windows" ) set ( _python_path $ENV{PYTHONPATH};${PYTHON_XMLRUNNER_DIR} ) - # cmake list separator and Windows environment seprator are the same so escape the cmake one + # cmake list separator and Windows environment separator are the same so escape the cmake one string ( REPLACE ";" "\\;" _python_path "${_python_path}" ) else() set ( _python_path $ENV{PYTHONPATH}:${PYTHON_XMLRUNNER_DIR} ) diff --git a/MantidPlot/mantidplotrc.py b/MantidPlot/mantidplotrc.py index 918c8ab26472827b118f0159bb3840a8224321bf..9076197161ca8fbbe02a1233444fdad67fd645cd 100644 --- a/MantidPlot/mantidplotrc.py +++ b/MantidPlot/mantidplotrc.py @@ -38,7 +38,7 @@ if __name__ == '__main__': from mantid.api import * from mantid.simpleapi import * - # Common imports (here for backwards compatability) + # Common imports (here for backwards compatibility) import os import sys diff --git a/MantidPlot/src/ApplicationWindow.cpp b/MantidPlot/src/ApplicationWindow.cpp index 9ae8be7325fdcfc55efd1055a2fa71fdbbce174e..d17cb9f527b1906fd62128aacd16947dfc95d2c0 100644 --- a/MantidPlot/src/ApplicationWindow.cpp +++ b/MantidPlot/src/ApplicationWindow.cpp @@ -91,7 +91,6 @@ #include "PlotWizard.h" #include "PolynomFitDialog.h" #include "PolynomialFit.h" -#include "Process.h" #include "ProjectRecovery.h" #include "ProjectSerialiser.h" #include "QwtErrorPlotCurve.h" @@ -184,6 +183,8 @@ #include <boost/regex.hpp> #include <boost/scoped_ptr.hpp> +#include <Poco/Path.h> + // Mantid #include "Mantid/FirstTimeSetup.h" #include "Mantid/ManageCustomMenus.h" @@ -3130,7 +3131,7 @@ Table *ApplicationWindow::newHiddenTable(const QString &name, return w; } -/* Perfom initialization on a Table? +/* Perform initialization on a Table? * @param w :: table that was created * @param caption :: title to set */ @@ -4404,7 +4405,7 @@ void ApplicationWindow::open() { QString pn = fi.absoluteFilePath(); if (fn == pn) { QMessageBox::warning( - this, tr("MantidPlot - File openning error"), // Mantid + this, tr("MantidPlot - File opening error"), // Mantid tr("The file: <b>%1</b> is the current file!").arg(fn)); return; } @@ -4421,7 +4422,7 @@ void ApplicationWindow::open() { fn.endsWith(".mantid~", Qt::CaseInsensitive)) { if (!fi.exists()) { QMessageBox::critical(this, - tr("MantidPlot - File openning error"), // Mantid + tr("MantidPlot - File opening error"), // Mantid tr("The file: <b>%1</b> doesn't exist!").arg(fn)); return; } @@ -4440,7 +4441,7 @@ void ApplicationWindow::open() { } } else { QMessageBox::critical( - this, tr("MantidPlot - File openning error"), // Mantid + this, tr("MantidPlot - File opening error"), // Mantid tr("The file: <b>%1</b> is not a MantidPlot or Origin project file!") .arg(fn)); return; @@ -5276,7 +5277,7 @@ void ApplicationWindow::readSettings() { settings.endGroup(); } - // Mantid - Remember which interfaces the user explicitely removed + // Mantid - Remember which interfaces the user explicitly removed // from the Interfaces menu removed_interfaces = settings.value("RemovedInterfaces").toStringList(); @@ -5652,7 +5653,7 @@ void ApplicationWindow::saveSettings() { settings.endGroup(); } - // Mantid - Remember which interfaces the user explicitely removed + // Mantid - Remember which interfaces the user explicitly removed // from the Interfaces menu settings.setValue("RemovedInterfaces", removed_interfaces); @@ -9187,7 +9188,7 @@ void ApplicationWindow::closeWindow(MdiSubWindow *window) { * @param window :: the window to add */ void ApplicationWindow::addSerialisableWindow(QObject *window) { - // Here we must store the window as a QObject to avoid multiple inheritence + // Here we must store the window as a QObject to avoid multiple inheritance // issues with Qt and the IProjectSerialisable class as well as being able // to respond to the destroyed signal // We can still check here that the window conforms to the interface and @@ -9196,8 +9197,8 @@ void ApplicationWindow::addSerialisableWindow(QObject *window) { return; m_serialisableWindows.push_back(window); - // Note that destoryed is emitted directly before the QObject itself - // is destoryed. This means the destructor of the specific window type + // Note that destroyed is emitted directly before the QObject itself + // is destroyed. This means the destructor of the specific window type // will have already been called. connect(window, SIGNAL(destroyed(QObject *)), this, SLOT(removeSerialisableWindow(QObject *))); @@ -9814,7 +9815,8 @@ void ApplicationWindow::closeEvent(QCloseEvent *ce) { // Stop background saving thread, so it doesn't try to use a destroyed // resource m_projectRecovery.stopProjectSaving(); - m_projectRecovery.clearAllCheckpoints(); + m_projectRecovery.clearAllCheckpoints( + Poco::Path(m_projectRecovery.getRecoveryFolderOutputPR())); } // Close the remaining MDI windows. The Python API is required to be active @@ -11583,7 +11585,7 @@ void ApplicationWindow::setUpdateCurvesFromTable(Table *table, bool on) { } } -/** Fixes the colour pallete so that the hints are readable. +/** Fixes the colour palette so that the hints are readable. On Linux Fedora 26+ and Ubuntu 14.4+ the palette colour for ToolTipBase has no effect on the colour of tooltips, but does change @@ -11591,7 +11593,7 @@ void ApplicationWindow::setUpdateCurvesFromTable(Table *table, bool on) { colour for ToolTipText on the other hand affects all three of these. - The default pallete shows light text on a pale background which, although + The default palette shows light text on a pale background which, although not affecting tooltips, makes LineEdit hints and 'What's This' boxes difficuilt if not impossible to read. @@ -13850,7 +13852,7 @@ void ApplicationWindow::showBugTracker() { /* @param arg: command argument -@return TRUE if argument suggests execution and quiting +@return TRUE if argument suggests execution and quitting */ bool ApplicationWindow::shouldExecuteAndQuit(const QString &arg) { return arg.endsWith("--execandquit") || arg.endsWith("-xq"); @@ -15943,7 +15945,7 @@ void ApplicationWindow::tileMdiWindows() { shakeViewport(); // QMdiArea::tileSubWindows() aranges the windows and enables automatic // tiling after subsequent resizing of the mdi area until a window is moved - // or resized separatly. Unfortunately Graph behaves badly during this. The + // or resized separately. Unfortunately Graph behaves badly during this. The // following code disables automatic tiling. auto winList = d_workspace->subWindowList(); if (!winList.isEmpty()) { @@ -16025,8 +16027,8 @@ void ApplicationWindow::customMultilayerToolButtons(MultiLayer *w) { btnPointer->setChecked(true); } /** save workspace data in nexus format - * @param wsName :: name of the ouput file. - * @param fileName :: name of the ouput file. + * @param wsName :: name of the output file. + * @param fileName :: name of the output file. */ void ApplicationWindow::savedatainNexusFormat(const std::string &wsName, const std::string &fileName) { @@ -16294,7 +16296,7 @@ QPoint ApplicationWindow::positionNewFloatingWindow(QSize sz) const { // Get window which was added last FloatingWindow *lastWindow = m_floatingWindows.last(); - if (lastWindow->isVisible()) { // If it is still visibile - can't use it's + if (lastWindow->isVisible()) { // If it is still visible - can't use it's // location, so need to find a new one QPoint diff = lastWindow->pos() - lastPoint; @@ -16665,21 +16667,9 @@ void ApplicationWindow::onAboutToStart() { // Make sure we see all of the startup messages resultsLog->scrollToTop(); - // Kick off project recovery iff we are able to determine if we are the only - // instance currently running - try { - if (!Process::isAnotherInstanceRunning()) { - g_log.debug("Starting project autosaving."); - checkForProjectRecovery(); - } else { - g_log.debug("Another MantidPlot process is running. Project recovery is " - "disabled."); - } - } catch (std::runtime_error &exc) { - g_log.warning("Unable to determine if other MantidPlot processes are " - "running. Project recovery is disabled. Error msg: " + - std::string(exc.what())); - } + // Kick off project recovery + g_log.debug("Starting project autosaving."); + checkForProjectRecovery(); } /** @@ -16816,6 +16806,9 @@ bool ApplicationWindow::saveProjectRecovery(std::string destination) { */ void ApplicationWindow::checkForProjectRecovery() { m_projectRecoveryRunOnStart = true; + + m_projectRecovery.removeOlderCheckpoints(); + if (!m_projectRecovery.checkForRecovery()) { m_projectRecovery.startProjectSaving(); return; @@ -16835,7 +16828,6 @@ void ApplicationWindow::checkForProjectRecovery() { "OK"); // Restart project recovery manually - m_projectRecovery.clearAllCheckpoints(); m_projectRecovery.startProjectSaving(); } } diff --git a/MantidPlot/src/ApplicationWindow.h b/MantidPlot/src/ApplicationWindow.h index e9592562040047376a4b47d14c3ab19be5b742f9..60b7fbb789d84942c762e87351e915aab8f37adf 100644 --- a/MantidPlot/src/ApplicationWindow.h +++ b/MantidPlot/src/ApplicationWindow.h @@ -279,7 +279,7 @@ public slots: /// Update application window post save void postSaveProject(); - //! Set the project status to modifed + //! Set the project status to modified void modifiedProject(); //! Set the project status to saved (not modified) void savedProject(); @@ -462,7 +462,7 @@ public slots: * @param label :: window label (compare MdiSubWindow::MdiSubWindow) * @param r :: number of rows * @param c :: number of columns - * @param text :: tab/newline - seperated initial content; may be empty + * @param text :: tab/newline - separated initial content; may be empty */ Table *newHiddenTable(const QString &name, const QString &label, int r, int c, const QString &text = QString()); @@ -974,11 +974,11 @@ public slots: //! Show the currently selected windows from the list view #lv. void showSelectedWindows(); - //! Sets all items in the folders list view to be desactivated (QPixmap = + //! Sets all items in the folders list view to be deactivated (QPixmap = // folder_closed_xpm) void desactivateFolders(); - //! Changes the current folder. Returns true if successfull + //! Changes the current folder. Returns true if successful bool changeFolder(Folder *newFolder, bool force = false); //! Changes the current folder when the user changes the current item in the @@ -1009,7 +1009,7 @@ public slots: // depending on the user's viewing policy void showAllFolderWindows(); - //! forces hidding all windows in the current folder and subfolders, + //! forces hiding all windows in the current folder and subfolders, // depending on the user's viewing policy void hideAllFolderWindows(); @@ -1428,7 +1428,7 @@ public: ImageMarker *d_image_copy; //@} - //! Equals true if an automatical search for updates was performed on start-up + //! Equals true if an automatic search for updates was performed on start-up // otherwise is set to false; bool autoSearchUpdatesRequest; diff --git a/MantidPlot/src/AxesDialog.cpp b/MantidPlot/src/AxesDialog.cpp index f4bd1cc622284fc3a9b521dffd353f4f18269323..f904ae0dc2c4044efb35fed40e96c8c2bdb26fe8 100644 --- a/MantidPlot/src/AxesDialog.cpp +++ b/MantidPlot/src/AxesDialog.cpp @@ -1494,7 +1494,7 @@ Mantid::Kernel::Logger g_log("AxisDialog"); * scale of an axis. * @param app :: the containing application window * @param g :: the graph the dialog is settign the options for - * @param fl :: The QT flags fro thsi window + * @param fl :: The QT flags for this window */ AxesDialog::AxesDialog(ApplicationWindow *app, Graph *g, Qt::WFlags fl) : QDialog(g, fl), m_app(app), m_graph(g) { @@ -1512,8 +1512,8 @@ AxesDialog::AxesDialog(ApplicationWindow *app, Graph *g, Qt::WFlags fl) initGridPage(); initGeneralPage(); - // Connect scale details to axis details in order to diable scale options when - // an axis is not shown + // Connect scale details to axis details in order to disable scale options + // when an axis is not shown auto scaleIter = m_Scale_list.begin(); auto axisIter = m_Axis_list.begin(); while ((scaleIter != m_Scale_list.end()) && (axisIter != m_Axis_list.end())) { @@ -1562,7 +1562,7 @@ void AxesDialog::accept() { if (pressToGraph()) close(); } -/** Applys the changes to the graph without closing the window +/** Applies the changes to the graph without closing the window * */ void AxesDialog::apply() { diff --git a/MantidPlot/src/AxisDetails.cpp b/MantidPlot/src/AxisDetails.cpp index 3c5b79f6258b1cb8430a6db688758f30bdbaa051..65752a7153f4e04ab7a090f39bdbb8bbeaedf292 100644 --- a/MantidPlot/src/AxisDetails.cpp +++ b/MantidPlot/src/AxisDetails.cpp @@ -39,7 +39,7 @@ * @param graph :: the graph the dialog is settign the options for * @param mappedaxis :: the QwtPlot::axis value that corresponds to this axis * @param parent :: the QWidget that acts as this widget's parent in the - * hierachy + * hierarchy */ AxisDetails::AxisDetails(ApplicationWindow *app, Graph *graph, int mappedaxis, QWidget *parent) @@ -336,7 +336,7 @@ void AxisDetails::initWidgets() { } } -/** Sets the modifed flag to true so that the changes may be applied. +/** Sets the modified flag to true so that the changes may be applied. * */ void AxisDetails::setModified() { m_modified = true; } @@ -374,7 +374,7 @@ bool AxisDetails::valid() { !w); } -/** Applies the grid paremeters to the graphs +/** Applies the grid parameters to the graphs * */ void AxisDetails::apply() { @@ -413,7 +413,7 @@ void AxisDetails::apply() { } } -/** Applies the grid paremeters to the graphs +/** Applies the grid parameters to the graphs * */ void AxisDetails::showAxis() { @@ -431,7 +431,7 @@ void AxisDetails::showAxis() { m_txtFormula->setEnabled(labels); // this should so the work of the below IF but on one line and slightly more - // efficently as i assume setDisabled negates that given to it + // efficiently as i assume setDisabled negates that given to it m_spnAngle->setEnabled( (m_mappedaxis == QwtPlot::xBottom || m_mappedaxis == QwtPlot::xTop) && labels); @@ -445,7 +445,7 @@ void AxisDetails::showAxis() { emit axisShowChanged(shown); } -/** Enables, Disables, Hides or Shows widgets apropriate to the current Axis +/** Enables, Disables, Hides or Shows widgets appropriate to the current Axis *Format * */ diff --git a/MantidPlot/src/Bar.cpp b/MantidPlot/src/Bar.cpp index 17b3733aefa22f140a3124f74a3773a87c73ada0..cf7eb99e6eb9605eb9435438304c10e4e8c8b8e1 100644 --- a/MantidPlot/src/Bar.cpp +++ b/MantidPlot/src/Bar.cpp @@ -5,7 +5,7 @@ Copyright : (C) 2006 by Ion Vasilief, Tilman Hoener zu Siederdissen Email (use @ for *) : ion_vasilief*yahoo.fr, thzs*gmx.net - Description : 3D bars (modifed enrichment from QwtPlot3D) + Description : 3D bars (modified enrichment from QwtPlot3D) ***************************************************************************/ diff --git a/MantidPlot/src/Bar.h b/MantidPlot/src/Bar.h index 2094dc6d8beb70cacfa6c9ea10c1bfa0d7705526..0a3b63f8c0a3d6ca1f8f8d999cc75037bfe13253 100644 --- a/MantidPlot/src/Bar.h +++ b/MantidPlot/src/Bar.h @@ -5,7 +5,7 @@ Copyright : (C) 2006 by Ion Vasilief, Tilman Hoener zu Siederdissen Email (use @ for *) : ion_vasilief*yahoo.fr, thzs*gmx.net - Description : 3D bars (modifed enrichment from QwtPlot3D) + Description : 3D bars (modified enrichment from QwtPlot3D) ***************************************************************************/ @@ -32,7 +32,7 @@ #include <qwt3d_plot.h> -//! 3D bars (modifed enrichment from QwtPlot3D) +//! 3D bars (modified enrichment from QwtPlot3D) class Bar : public Qwt3D::VertexEnrichment { public: Bar(); diff --git a/MantidPlot/src/CanvasPicker.h b/MantidPlot/src/CanvasPicker.h index a068b9db7b73970c959650bf5dc261f21b5aa9b7..dad880bf56b31771cba4251cabde2092f30f0990 100644 --- a/MantidPlot/src/CanvasPicker.h +++ b/MantidPlot/src/CanvasPicker.h @@ -93,7 +93,7 @@ signals: private: bool pointSelected; /**\brief The marker that is currently being edited, or NULL. - * Editing does explicitly _not_ inlude moving and resizing, which are being + * Editing does explicitly _not_ include moving and resizing, which are being * handled by SelectionMoveResizer (see Graph::d_markers_selector). * Currently, only ArrowMarker provides any other form of editing, but this * really diff --git a/MantidPlot/src/ConfigDialog.cpp b/MantidPlot/src/ConfigDialog.cpp index 3762e44c455af5ef97c2b5a8484773559ecc977b..e56d72069ca0f2130a1ecb0b4d9d67bcbd11c966 100644 --- a/MantidPlot/src/ConfigDialog.cpp +++ b/MantidPlot/src/ConfigDialog.cpp @@ -1192,7 +1192,7 @@ void ConfigDialog::populateProgramTree() { void ConfigDialog::updateProgramTree() { // Store into a map ready to go into config service when apply is clicked for (const auto &itr : m_sendToSettings) { - // creating the map of kvps needs to happen first as createing the item + // creating the map of kvps needs to happen first as creating the item // requires them. std::map<std::string, std::string> programKeysAndDetails = itr.second; @@ -2436,9 +2436,10 @@ void ConfigDialog::languageChange() { mdPlottingGeneralFrame->setTitle( "Use same default color map for Slice Viewer and VSI"); - mdPlottingGeneralFrame->setToolTip("The specifed color map will be available " - "for the Slice Viewer and the VSI when a " - "new instance of either is started."); + mdPlottingGeneralFrame->setToolTip( + "The specified color map will be available " + "for the Slice Viewer and the VSI when a " + "new instance of either is started."); } void ConfigDialog::accept() { diff --git a/MantidPlot/src/Convolution.h b/MantidPlot/src/Convolution.h index 8bbd0a178a9057625edbdfda8270c7634776bed6..38d85225d199b62a15841ffd1d996da109464fab 100644 --- a/MantidPlot/src/Convolution.h +++ b/MantidPlot/src/Convolution.h @@ -49,7 +49,7 @@ public: protected: //! Handles the graphical output void addResultCurve(); - //! Performes the convolution of the two data sets and stores the result in + //! Performs the convolution of the two data sets and stores the result in // the signal data set void convlv(double *sig, int n, double *dres, int m, int sign); diff --git a/MantidPlot/src/CurvesDialog.cpp b/MantidPlot/src/CurvesDialog.cpp index 3be594a490b19e2a3d51f3c6c8394e370a5a8151..d8d2f20db99cebc2df8a8a19d6a21bdd46418a84 100644 --- a/MantidPlot/src/CurvesDialog.cpp +++ b/MantidPlot/src/CurvesDialog.cpp @@ -476,8 +476,8 @@ void CurvesDialog::enableAddBtn() { !available->selectedItems().isEmpty()); } -/** Enables or disables the button when appopriate number of graphs are in graph - *contents +/** Enables or disables the button when appropriate number of graphs are in + *graph contents * */ void CurvesDialog::enableRemoveBtn() { diff --git a/MantidPlot/src/DataPickerTool.h b/MantidPlot/src/DataPickerTool.h index fc555442bb29f7db4e6a3658bca93e88a9288aa5..8d60ce086c7394652de852a98837b00ef4710a8d 100644 --- a/MantidPlot/src/DataPickerTool.h +++ b/MantidPlot/src/DataPickerTool.h @@ -59,8 +59,8 @@ public: signals: /** Emitted whenever a new message should be presented to the user. * - * You don't have to connect to this signal if you alreay specified a reciever - *during initialization. + * You don't have to connect to this signal if you already specified a + *receiver during initialization. */ void statusText(const QString &); //! Emitted whenever a new data point has been selected. diff --git a/MantidPlot/src/FFTFilter.cpp b/MantidPlot/src/FFTFilter.cpp index 9e130860b1f3c95e6eb573f4c3efab343b430d69..86f582d647bafb3053ea634c60155a9a8e3ad18e 100644 --- a/MantidPlot/src/FFTFilter.cpp +++ b/MantidPlot/src/FFTFilter.cpp @@ -157,7 +157,7 @@ void FFTFilter::calculateOutputData(double *x, double *y) { d_explanation += tr("Band Block FFT Filter"); if (!d_offset) - y[0] = 0; // substract DC offset + y[0] = 0; // subtract DC offset for (int i = 1; i < d_n; i++) y[i] = ((i * df > d_low_freq) && (i * df < d_high_freq)) ? 0 : y[i]; diff --git a/MantidPlot/src/FFTFilter.h b/MantidPlot/src/FFTFilter.h index a1ef98b44798f4153058cddb0f8fa9d8b2e1f10b..907e35885d9ae15b9d6ea666e9d27a8260d249d7 100644 --- a/MantidPlot/src/FFTFilter.h +++ b/MantidPlot/src/FFTFilter.h @@ -72,7 +72,7 @@ private: //! Upper edge of the band for Band Pass and Band block filters. double d_high_freq; - //! Flag telling if the DC offset must be added/substracted when applying a + //! Flag telling if the DC offset must be added/subtracted when applying a // Band Pass/Band block filter respectively. bool d_offset; }; diff --git a/MantidPlot/src/FilterDialog.cpp b/MantidPlot/src/FilterDialog.cpp index 4a28991e3812067f7f51b62416b56bde18e0c9f2..43dfe6aba9a0e79dc245f10e53fb787d3732ed27 100644 --- a/MantidPlot/src/FilterDialog.cpp +++ b/MantidPlot/src/FilterDialog.cpp @@ -79,7 +79,7 @@ FilterDialog::FilterDialog(int type, QWidget *parent, Qt::WFlags fl) if (type == FFTFilter::BandPass) gl1->addWidget(new QLabel(tr("Add DC Offset")), 3, 0); else - gl1->addWidget(new QLabel(tr("Substract DC Offset")), 3, 0); + gl1->addWidget(new QLabel(tr("Subtract DC Offset")), 3, 0); boxOffset = new QCheckBox(); gl1->addWidget(boxOffset, 3, 1); diff --git a/MantidPlot/src/Fit.h b/MantidPlot/src/Fit.h index bd6a6bf2efdaf03b5d87d324be1f1c3257585251..35c32d835dddeac56565cf8fe4d33357b583225f 100644 --- a/MantidPlot/src/Fit.h +++ b/MantidPlot/src/Fit.h @@ -122,7 +122,7 @@ public: //! Returns R^2 double rSquare(); - //! Specifies wheather the errors must be scaled with sqrt(chi_2/dof) + //! Specifies whether the errors must be scaled with sqrt(chi_2/dof) void scaleErrors(bool yes = true) { d_scale_errors = yes; }; Table *parametersTable(const QString &tableName); @@ -239,7 +239,7 @@ protected: //! The sum of squares of the residuals from the best-fit line double chi_2; - //! Specifies wheather the errors must be scaled with sqrt(chi_2/dof) + //! Specifies whether the errors must be scaled with sqrt(chi_2/dof) bool d_scale_errors; //! Table window used for the output of fit parameters diff --git a/MantidPlot/src/FloatingWindow.cpp b/MantidPlot/src/FloatingWindow.cpp index a3a418944efd19eb542d2f3c5db962df56ca8e98..3a254089fbe0b69732e962eeb363342a56464dfa 100644 --- a/MantidPlot/src/FloatingWindow.cpp +++ b/MantidPlot/src/FloatingWindow.cpp @@ -84,7 +84,7 @@ bool FloatingWindow::event(QEvent *e) { } else if (e->type() == QEvent::WindowStateChange) { if (this->isMinimized()) { #ifdef Q_OS_WIN - // set parent to NULL wich makes it minimize nicely into a program bar + // set parent to NULL which makes it minimize nicely into a program bar // icon this->setParent(NULL); this->showMinimized(); diff --git a/MantidPlot/src/Folder.h b/MantidPlot/src/Folder.h index 2761fc2ecb6c74618358555059c07a46c4eb857a..351e8af31055d61cfdafd52a6c70d7b3c50be41a 100644 --- a/MantidPlot/src/Folder.h +++ b/MantidPlot/src/Folder.h @@ -134,7 +134,7 @@ private: /// Recursively save subwindows and subfolders QString saveFolderSubWindows(ApplicationWindow *app, Folder *, int &windowCount); - /// Save footer infromation about the folder + /// Save footer information about the folder QString saveFolderFooter(); public slots: diff --git a/MantidPlot/src/FunctionCurve.cpp b/MantidPlot/src/FunctionCurve.cpp index c424f9f6d0bc13d274d3dfd7c33e2ac0b1fce9c5..f49d13bf97cd8aeb933c881b2611bb96f4be4055 100644 --- a/MantidPlot/src/FunctionCurve.cpp +++ b/MantidPlot/src/FunctionCurve.cpp @@ -50,7 +50,7 @@ FunctionCurve::FunctionCurve(const FunctionType &t, const QString &name) } /** - * This constractor creates a function curve from a Mantid IFunction and uses a + * This constructor creates a function curve from a Mantid IFunction and uses a * workspace for x values * @param fun :: A pointer to a Mantid function * @param wsName :: A name of a workspace to provide x values and to be passed diff --git a/MantidPlot/src/Graph.cpp b/MantidPlot/src/Graph.cpp index b1b4392251b3f6abf744476adb8a188c596a6f52..5cc523b7e1871613f9abad675412cd8a9f31b19d 100644 --- a/MantidPlot/src/Graph.cpp +++ b/MantidPlot/src/Graph.cpp @@ -2644,7 +2644,7 @@ bool Graph::addCurves(Table *w, const QStringList &names, int style, // If X column is given - use it xColName = xColNameGiven; else - // Otherise, use associated one + // Otherwise, use associated one xColName = w->colName(w->colX(colIndex)); if (xColName.isEmpty() || yColName.isEmpty()) diff --git a/MantidPlot/src/Graph.h b/MantidPlot/src/Graph.h index 90a8a68bbf809f09b8ae87ed36aa60aad99144a8..b93f8f45805e7d6328719006981661ac58cc2c23 100644 --- a/MantidPlot/src/Graph.h +++ b/MantidPlot/src/Graph.h @@ -668,7 +668,7 @@ public slots: void setCurveTitle(int index, const QString &title); //@} - //! \name Modifing insertCurve Data + //! \name Modifying insertCurve Data //@{ int selectedCurveID(); int selectedCurveIndex() { return curveIndex(selectedCurveID()); } diff --git a/MantidPlot/src/Graph3D.cpp b/MantidPlot/src/Graph3D.cpp index bd48e3aba56fd9377187d46f0d3ea373becc5c01..61cd140cb99f52aff5fda7c34c8850fe76e728cf 100644 --- a/MantidPlot/src/Graph3D.cpp +++ b/MantidPlot/src/Graph3D.cpp @@ -687,7 +687,7 @@ void Graph3D::resetNonEmptyStyle() { if (sp->plotStyle() != Qwt3D::NOPLOT) return; // the plot was not previousely emptied - if (style_ == Qwt3D::USER) { // reseting the right user plot style + if (style_ == Qwt3D::USER) { // resetting the right user plot style switch (pointStyle) { case None: break; @@ -2868,7 +2868,7 @@ int Graph3D::read3DPlotStyle(MantidQt::API::TSVSerialiser &tsv) { Graph3D::SurfaceFunctionParams Graph3D::readSurfaceFunction(MantidQt::API::TSVSerialiser &tsv) { - // We cant use {0} to zero initialise as GCC incorrectly thinks + // We can't use {0} to zero initialise as GCC incorrectly thinks // the members are still uninitialised SurfaceFunctionParams params = SurfaceFunctionParams(); tsv >> params.formula; @@ -2922,7 +2922,7 @@ Graph3D::readSurfaceFunctionType(const std::string &formula) { QString func = QString::fromStdString(formula); if (func.endsWith("(Y)", Qt::CaseSensitive)) type = SurfaceFunctionType::Plot3D; - else if (func.contains("(Z)", Qt::CaseSensitive) > nullptr) + else if (func.contains("(Z)", Qt::CaseSensitive)) type = SurfaceFunctionType::XYZ; else if (func.startsWith("matrix<", Qt::CaseSensitive) && func.endsWith(">", Qt::CaseInsensitive)) diff --git a/MantidPlot/src/GridDetails.cpp b/MantidPlot/src/GridDetails.cpp index 3d9b3acf05b97c24b1cb0cebf9cee0f150479303..0ed8c70a38bd9dc9a129f3db44c71b63f199fcd6 100644 --- a/MantidPlot/src/GridDetails.cpp +++ b/MantidPlot/src/GridDetails.cpp @@ -20,12 +20,12 @@ #include <QWidget> /** The constructor for a single set of widgets containing parameters for a - * sigle direction of gridlines. + * single direction of gridlines. * @param app :: the containing application window * @param graph :: the graph the dialog is settign the options for * @param mappedaxis :: the QwtPlot::axis value that corresponds to this axis * @param parent :: the QWidget that acts as this widget's parent in the - * hierachy + * hierarchy */ GridDetails::GridDetails(ApplicationWindow *app, Graph *graph, int alignment, QWidget *parent) @@ -202,14 +202,14 @@ void GridDetails::initWidgets() { } } -/** Sets the modifed flag to true so that the changes may be applied. +/** Sets the modified flag to true so that the changes may be applied. * */ void GridDetails::setModified() { m_modified = true; } -/** Applies the grid paremeters to the graphs +/** Applies the grid parameters to the graphs * -@param grid :: the gird to apply this formatting to +@param grid :: the grid to apply this formatting to @bool antialias :: apply antialias to this formatting or not @bool multirun :: this will run multiple times for this dialog, and forces even if no modified diff --git a/MantidPlot/src/GridDetails.h b/MantidPlot/src/GridDetails.h index 6f9a590a20472c1cacee7800aae810922c933770..48ca3681ee67aa53cbc68794431d33a2fac9e40e 100644 --- a/MantidPlot/src/GridDetails.h +++ b/MantidPlot/src/GridDetails.h @@ -68,6 +68,7 @@ private: ApplicationWindow *m_app; Graph *m_graph; - int m_alignment; // 0 = horzontal, 1 = vertical, anything else sets this to 0; + int m_alignment; // 0 = horizontal, 1 = vertical, anything else sets this to + // 0; }; #endif /* GRIDDETAILS_H_ */ \ No newline at end of file diff --git a/MantidPlot/src/ImageExportDialog.h b/MantidPlot/src/ImageExportDialog.h index 047ff80993914e75a7e698553574cf91d6dd133a..5c0fc78825bda3416c5d04eac09e4060ed9def8b 100644 --- a/MantidPlot/src/ImageExportDialog.h +++ b/MantidPlot/src/ImageExportDialog.h @@ -79,7 +79,7 @@ public: //! For vector formats: returns the output resolution the user selected, // defaulting to the screen resolution. int resolution() const { return d_resolution->value(); } - //! For vector formats: returns whether colors should be enabled for ouput + //! For vector formats: returns whether colors should be enabled for output //(default: true). bool color() const { return d_color->isChecked(); } //! For vector formats: returns whether the output should preserve aspect diff --git a/MantidPlot/src/ImportASCIIDialog.cpp b/MantidPlot/src/ImportASCIIDialog.cpp index 2a05708f611264790bd57fd1fe72a6633ebc4a08..bd87d3897dbd421bb4982e6e918116252cceaa32 100644 --- a/MantidPlot/src/ImportASCIIDialog.cpp +++ b/MantidPlot/src/ImportASCIIDialog.cpp @@ -431,9 +431,10 @@ void ImportASCIIDialog::displayHelp() { "whitespaces (including the TAB character) will be replaced with a " "single space."); - s += "\n\n" + - tr("Warning: using these two last options leads to column overlaping if " - "the columns in the ASCII file don't have the same number of rows."); + s += + "\n\n" + + tr("Warning: using these two last options leads to column overlapping if " + "the columns in the ASCII file don't have the same number of rows."); s += "\n" + tr("To avoid this problem you should precisely define the column " "separator using TAB and SPACE characters."); @@ -577,7 +578,7 @@ void ImportASCIIDialog::changePreviewFile(const QString &path) { if (!fi.isReadable()) { QMessageBox::critical( - this, tr("MantidPlot - File openning error"), + this, tr("MantidPlot - File opening error"), tr("You don't have the permission to open this file: <b>%1</b>") .arg(path)); return; diff --git a/MantidPlot/src/ImportASCIIDialog.h b/MantidPlot/src/ImportASCIIDialog.h index 49f176681e4fb84dacdc19eca68b6b2bcd784a4c..2ddd8a8ed9167a952b5fa605e925cd92066d1196 100644 --- a/MantidPlot/src/ImportASCIIDialog.h +++ b/MantidPlot/src/ImportASCIIDialog.h @@ -132,7 +132,7 @@ public: int ignoredLines() const { return d_ignored_lines->value(); } //! Whether to rename columns based on the first (non-skipped) line. bool renameColumns() const { return d_rename_columns->isChecked(); } - //! Whether to replace sequences of whitespace charecters with a single space. + //! Whether to replace sequences of whitespace characters with a single space. bool simplifySpaces() const { return d_simplify_spaces->isChecked(); } //! Whether to remove whitespace from beginning and end of lines. bool stripSpaces() const { return d_strip_spaces->isChecked(); } diff --git a/MantidPlot/src/LineProfileTool.h b/MantidPlot/src/LineProfileTool.h index ee99e3e551b97e4962c4185943153a379abb7c0e..2f821a206cd915aff982cbf44b8e9dac56ad8ea5 100644 --- a/MantidPlot/src/LineProfileTool.h +++ b/MantidPlot/src/LineProfileTool.h @@ -82,8 +82,8 @@ public: signals: /** Emitted whenever a new message should be presented to the user. * - * You don't have to connect to this signal if you alreay specified a reciever - *during initialization. + * You don't have to connect to this signal if you already specified a + *receiver during initialization. */ void statusText(const QString &); diff --git a/MantidPlot/src/Mantid/AlgorithmHistoryWindow.cpp b/MantidPlot/src/Mantid/AlgorithmHistoryWindow.cpp index 4dd333856304d8b15f8811043dfec5a474e4088a..94254afc95fd00301834ee1eecdb1348bd1fda10 100644 --- a/MantidPlot/src/Mantid/AlgorithmHistoryWindow.cpp +++ b/MantidPlot/src/Mantid/AlgorithmHistoryWindow.cpp @@ -449,7 +449,7 @@ void AlgorithmHistoryWindow::updateAlgHistoryProperties( void AlgorithmHistoryWindow::updateExecSummaryGrpBox( AlgorithmHistory_const_sptr algHistory) { - // getting the selcted algorithm at pos from History vector + // getting the selected algorithm at pos from History vector double duration = algHistory->executionDuration(); Mantid::Types::Core::DateAndTime date = algHistory->executionDate(); if (m_execSumGrpBox) diff --git a/MantidPlot/src/Mantid/FirstTimeSetup.cpp b/MantidPlot/src/Mantid/FirstTimeSetup.cpp index e80c604866f993965585f5bca1f51cb98f07f442..df2f81d7c28ed7c63b02b4449a8791a49da930d6 100644 --- a/MantidPlot/src/Mantid/FirstTimeSetup.cpp +++ b/MantidPlot/src/Mantid/FirstTimeSetup.cpp @@ -86,7 +86,7 @@ void FirstTimeSetup::initLayout() { QString stlyeName = QApplication::style()->metaObject()->className(); if ((stlyeName == "QMotifStyle") || (stlyeName == "QCDEStyle")) { - // add stylesheet formatting for other environemnts + // add stylesheet formatting for other environments QString ss = this->styleSheet(); ss += "\n" "QDialog#FirstTimeSetup QCommandLinkButton {" diff --git a/MantidPlot/src/Mantid/FitParameterTie.cpp b/MantidPlot/src/Mantid/FitParameterTie.cpp index d51c05a2719e20af3a1a3b23ed5faa1892044965..b3a616d13623f3aec9adbbb35af0342389c8565e 100644 --- a/MantidPlot/src/Mantid/FitParameterTie.cpp +++ b/MantidPlot/src/Mantid/FitParameterTie.cpp @@ -106,10 +106,10 @@ QString FitParameterTie::exprRHS() const { } /** - * When a new function is added the function indeces in the tying expression + * When a new function is added the function indices in the tying expression * must * be changed. - * @param i :: The index at wich the function is inserted. All old indeces + * @param i :: The index at which the function is inserted. All old indices * starting * from i (inclusive) must be incremented. */ @@ -122,10 +122,10 @@ void FitParameterTie::functionInserted(int i) { } /** - * When a function is deleted the function indeces in the tying expression must + * When a function is deleted the function indices in the tying expression must * be changed or the tie may become invalid if the deleted function is used in * the tie. - * @param i :: The index of the deleted function. All old indeces starting + * @param i :: The index of the deleted function. All old indices starting * from i+1 must be decremented. * @return true if the tie remains valid and false otherwise. */ diff --git a/MantidPlot/src/Mantid/FitParameterTie.h b/MantidPlot/src/Mantid/FitParameterTie.h index f74b147f3c6d7af2010cfc98c9d9fd447fa49fdf..2cc6133b9a0bca8c5701eb39f634502c883cd3f1 100644 --- a/MantidPlot/src/Mantid/FitParameterTie.h +++ b/MantidPlot/src/Mantid/FitParameterTie.h @@ -31,11 +31,11 @@ public: QString parName() const; /// Returns the right-hand side of the expression QString exprRHS() const; - /// Mofifies the function indeces in response to insertion of a new function + /// Modifies the function indeces in response to insertion of a new function /// into /// the composite function void functionInserted(int i); - /// Mofifies the function indeces in response to deletion of a function from + /// Modifies the function indeces in response to deletion of a function from /// the composite function bool functionDeleted(int i); /// Set property diff --git a/MantidPlot/src/Mantid/IFunctionWrapper.h b/MantidPlot/src/Mantid/IFunctionWrapper.h index cc5d801a56984800e4110c85fb000f185d8dfcac..017b57f9a15c2456f78a0955617de41b594c37e7 100644 --- a/MantidPlot/src/Mantid/IFunctionWrapper.h +++ b/MantidPlot/src/Mantid/IFunctionWrapper.h @@ -14,7 +14,7 @@ class IPeakFunction; /** * IFunctionWrapper is a wrapper for IFunction pointer which is a QObject - * and can send and recieve signals. + * and can send and receive signals. */ class IFunctionWrapper : public QObject { Q_OBJECT diff --git a/MantidPlot/src/Mantid/MantidCurve.h b/MantidPlot/src/Mantid/MantidCurve.h index 851ac1a6f164e9c4303f40e4334735c99adbefca..cc4661e575a5a24d4de4545b74609963a1633f57 100644 --- a/MantidPlot/src/Mantid/MantidCurve.h +++ b/MantidPlot/src/Mantid/MantidCurve.h @@ -48,7 +48,7 @@ public: virtual const MantidQwtWorkspaceData *mantidData() const = 0; /// Get mantid data virtual MantidQwtWorkspaceData *mantidData() = 0; - /// Overriden virtual method + /// Overridden virtual method void itemChanged() override; /// Returns whether the curve has error bars diff --git a/MantidPlot/src/Mantid/MantidMDCurve.h b/MantidPlot/src/Mantid/MantidMDCurve.h index 0e50b63804e486a5104dba53b4a258ba3302c7d0..3d4fe4761537bdee0b9275e14dc0711f81e2cbce 100644 --- a/MantidPlot/src/Mantid/MantidMDCurve.h +++ b/MantidPlot/src/Mantid/MantidMDCurve.h @@ -107,7 +107,7 @@ private: const std::string &wsName, const boost::shared_ptr<Mantid::API::Workspace> ws) override; - /// Handle an ADS clear notificiation + /// Handle an ADS clear notification void clearADSHandle() override { emit removeMe(this); } signals: diff --git a/MantidPlot/src/Mantid/MantidMatrix.cpp b/MantidPlot/src/Mantid/MantidMatrix.cpp index df747167c7b1167cf3fb8c9609dad3645f553e0d..193f49df0c70964a939b8b2ed1fad78310f4430e 100644 --- a/MantidPlot/src/Mantid/MantidMatrix.cpp +++ b/MantidPlot/src/Mantid/MantidMatrix.cpp @@ -41,7 +41,7 @@ Logger g_log("MantidMatrix"); namespace { /** - * Converts an interger value to the corrsponding enum + * Converts an integer value to the corrsponding enum * @param i: the integer to check * @returns the corresponding model type */ @@ -133,7 +133,7 @@ MantidMatrix::MantidMatrix(Mantid::API::MatrixWorkspace_const_sptr ws, setWidget(m_tabs); // for synchronizing the views - // index is zero for the defualt view + // index is zero for the default view m_PrevIndex = 0; // install event filter on these objects m_table_viewY->installEventFilter(this); @@ -445,7 +445,7 @@ void MantidMatrix::copySelection() { } /** Returns minimum and maximum values in the matrix. -If setRange(...) has not been called it returns the true smalles ang largest +If setRange(...) has not been called it returns the true smallest and largest Y-values in the matrix, otherwise the values set with setRange(...) are returned. These are needed in plotGraph2D to set diff --git a/MantidPlot/src/Mantid/MantidMatrix.h b/MantidPlot/src/Mantid/MantidMatrix.h index bbf89d8762b7331ba66df469dfd2d94f4cb828b0..cd9f649abe8ac98943afab0a1e3f5e28630c6bb9 100644 --- a/MantidPlot/src/Mantid/MantidMatrix.h +++ b/MantidPlot/src/Mantid/MantidMatrix.h @@ -326,7 +326,7 @@ private: /// Update the existing extensions void updateExtensions(Mantid::API::MatrixWorkspace_sptr ws); - /// ExtensioRequest handleer + /// ExtensioRequest handler MantidMatrixExtensionRequest m_extensionRequest; friend class MantidMatrixFunction; diff --git a/MantidPlot/src/Mantid/MantidMatrixCurve.h b/MantidPlot/src/Mantid/MantidMatrixCurve.h index ed052aa441b84203c7095e0cc1cc11994e159a52..b8dd4473b8e645926063f47baa835cd194d02695 100644 --- a/MantidPlot/src/Mantid/MantidMatrixCurve.h +++ b/MantidPlot/src/Mantid/MantidMatrixCurve.h @@ -112,7 +112,7 @@ public: void draw(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRect &) const override; - /// Overriden virtual method + /// Overridden virtual method void itemChanged() override; /// saves the MantidMatrixCurve details to project file. @@ -147,7 +147,7 @@ private: const std::string &wsName, const boost::shared_ptr<Mantid::API::Workspace> ws) override; - /// Handle an ADS clear notificiation + /// Handle an ADS clear notification void clearADSHandle() override { emit removeMe(this); } signals: diff --git a/MantidPlot/src/Mantid/MantidMatrixExtensionRequest.cpp b/MantidPlot/src/Mantid/MantidMatrixExtensionRequest.cpp index 06fad084801ca37b93a8a620f5f6737a0a74331d..a181886a6f4064b318323cebd90f82276778a809 100644 --- a/MantidPlot/src/Mantid/MantidMatrixExtensionRequest.cpp +++ b/MantidPlot/src/Mantid/MantidMatrixExtensionRequest.cpp @@ -116,7 +116,7 @@ QChar MantidMatrixExtensionRequest::getFormat( * Get the preicson for the requested type * @param type: the type * @param extensions: the extensions - * @param defaultValue: a defaut value + * @param defaultValue: a default value * @returns the precision */ int MantidMatrixExtensionRequest::getPrecision( diff --git a/MantidPlot/src/Mantid/MantidMatrixModel.cpp b/MantidPlot/src/Mantid/MantidMatrixModel.cpp index 35fe98c3e18a6cd3114dd7fd09d76f281881ff15..cf88271fb20a3936b1a8a65779af240348b309a3 100644 --- a/MantidPlot/src/Mantid/MantidMatrixModel.cpp +++ b/MantidPlot/src/Mantid/MantidMatrixModel.cpp @@ -235,7 +235,7 @@ QVariant MantidMatrixModel::headerData(int section, Qt::Orientation orientation, } Qt::ItemFlags MantidMatrixModel::flags(const QModelIndex &index) const { - // MG: For item selection to work correclty in later Qt versions it must be + // MG: For item selection to work correctly in later Qt versions it must be // marked as enabled if (index.isValid()) return Qt::ItemIsSelectable | Qt::ItemIsEnabled; diff --git a/MantidPlot/src/Mantid/MantidMatrixModel.h b/MantidPlot/src/Mantid/MantidMatrixModel.h index 6fd23ed79fc1f7e7328526e8cde64fe876e692d5..969db18f73cf7e3852a9c03b07aacfea53e6cd8a 100644 --- a/MantidPlot/src/Mantid/MantidMatrixModel.h +++ b/MantidPlot/src/Mantid/MantidMatrixModel.h @@ -68,10 +68,10 @@ public slots: private: bool checkMonitorCache( - int row) const; // check the monitor cache and add to it if neccessary + int row) const; // check the monitor cache and add to it if necessary bool checkMaskedCache( - int row) const; // check the masked cache and add to it if neccessary + int row) const; // check the masked cache and add to it if necessary bool checkMaskedBinCache(int row, int bin) const; diff --git a/MantidPlot/src/Mantid/MantidUI.cpp b/MantidPlot/src/Mantid/MantidUI.cpp index c23e6a1074c23fb102533da74820cdf2759b1aa5..32239380f7c9e1b1e1d9d26d03eaad0f683ebf9e 100644 --- a/MantidPlot/src/Mantid/MantidUI.cpp +++ b/MantidPlot/src/Mantid/MantidUI.cpp @@ -1,9 +1,4 @@ -// Python header must go first -// clang-format off -#include "MantidQtWidgets/Common/PythonThreading.h" -// clang-format on -#include "MantidQtWidgets/Common/DropEventHelper.h" - +#include "MantidUI.h" #include "AlgorithmDockWidget.h" #include "AlgorithmHistoryWindow.h" #include "AlgorithmMonitor.h" @@ -12,13 +7,13 @@ #include "MantidMDCurveDialog.h" #include "MantidMatrix.h" #include "MantidMatrixCurve.h" +#include "MantidQtWidgets/Common/DropEventHelper.h" #include "MantidQtWidgets/Common/FitPropertyBrowser.h" #include "MantidQtWidgets/Common/MantidWSIndexDialog.h" #include "MantidSampleLogDialog.h" #include "MantidSampleMaterialDialog.h" #include "MantidSurfaceContourPlotGenerator.h" #include "MantidTable.h" -#include "MantidUI.h" #include "ProjectSerialiser.h" #include "../Folder.h" @@ -40,6 +35,11 @@ #include "MantidKernel/TimeSeriesProperty.h" #include "MantidKernel/UnitConversion.h" +#pragma push_macro("slots") +#undef slots +#include "MantidPythonInterface/core/GlobalInterpreterLock.h" +#pragma pop_macro("slots") + #include "InstrumentWidget/InstrumentWindow.h" #include "MantidQtWidgets/Common/AlgorithmInputHistory.h" @@ -102,6 +102,7 @@ using namespace std; using namespace Mantid::API; using namespace MantidQt::API; using namespace MantidQt::MantidWidgets; +using Mantid::PythonInterface::GlobalInterpreterLock; using Mantid::Types::Core::DateAndTime; using Mantid::Types::Core::time_duration; using MantidQt::MantidWidgets::MantidWSIndexDialog; @@ -226,7 +227,7 @@ MantidUI::MantidUI(ApplicationWindow *aw) qRegisterMetaType<Mantid::API::Workspace_sptr>(); qRegisterMetaType<Mantid::API::MatrixWorkspace_sptr>(); qRegisterMetaType<Mantid::API::MatrixWorkspace_const_sptr>(); - // Register std::string as well as we use it alot + // Register std::string as well as we use it a lot qRegisterMetaType<std::string>(); } @@ -429,7 +430,7 @@ void MantidUI::shutdown() { // If any python objects need to be cleared away then the GIL needs to be // held. - ScopedPythonGIL lock; + GlobalInterpreterLock lock; // Relevant notifications are connected to signals that will close all // dependent windows Mantid::API::FrameworkManager::Instance().shutdown(); @@ -1628,7 +1629,7 @@ void MantidUI::executeSaveNexus() { * * @param algName :: name of the algorithm * @param version :: version number, -1 for latest - * @return true if sucessful. + * @return true if successful. */ void MantidUI::showAlgorithmDialog(const QString &algName, int version) { Mantid::API::IAlgorithm_sptr alg = this->createAlgorithm(algName, version); @@ -1881,7 +1882,7 @@ void MantidUI::groupWorkspaces() { // get selected workspaces auto selectedItems = m_exploreMantid->getSelectedWorkspaceNames(); if (selectedItems.size() < 2) { - throw std::runtime_error("Select atleast two workspaces to group "); + throw std::runtime_error("Select at least two workspaces to group "); } if (Mantid::API::AnalysisDataService::Instance().doesExist(sgrpName)) { if (QMessageBox::question( @@ -2209,7 +2210,7 @@ void MantidUI::clearAllMemory(const bool prompt) { // If any python objects need to be cleared away then the GIL needs to be // held. This doesn't feel like // it is in the right place but it will do no harm - ScopedPythonGIL lock; + GlobalInterpreterLock lock; // Relevant notifications are connected to signals that will close all // dependent windows Mantid::API::FrameworkManager::Instance().clear(); @@ -2393,7 +2394,7 @@ void MantidUI::importString(const QString &logName, const QString &data) { /** Displays a string in a Qtiplot table * @param logName :: the title of the table is based on this * @param data :: the string to display - * @param sep :: the seperator character + * @param sep :: the separator character * @param wsName :: add workspace name to the table window title bar, defaults * to logname if left blank */ @@ -3213,7 +3214,7 @@ MultiLayer *MantidUI::plot1D(const QMultiMap<QString, int> &toPlot, /* Get the log values and put into a curve spec list in preparation of * the creation of the curves - * @param curveSpecList :: list of curve specs to recieve the logs + * @param curveSpecList :: list of curve specs to receive the logs * @param toPlot :: workspaces to plot * @param log :: log value * @param customLogValues :: custom log values @@ -3886,7 +3887,7 @@ struct mem_block { int state; }; -/// Assess the virtual memeory of the current process. +/// Assess the virtual memory of the current process. void countVirtual(vector<mem_block> &mem, int &total) { MEMORYSTATUSEX memStatus; @@ -3898,14 +3899,14 @@ void countVirtual(vector<mem_block> &mem, int &total) { char *addr = 0; size_t free = 0; // total free space size_t reserved = 0; // total reserved space - size_t committed = 0; // total commited (used) space + size_t committed = 0; // total committed (used) space size_t size = 0; size_t free_max = 0; // maximum contiguous block of free memory size_t reserved_max = 0; // maximum contiguous block of reserved memory size_t committed_max = 0; // maximum contiguous block of committed memory size_t GB2 = - memStatus.ullTotalVirtual; // Maximum memeory available to the process + memStatus.ullTotalVirtual; // Maximum memory available to the process total = static_cast<int>(GB2); // Loop over all virtual memory to find out the status of every block. @@ -4023,7 +4024,7 @@ void MantidUI::memoryImage2() { #endif //======================================================================= - // End of Windows specfic stuff + // End of Windows specific stuff //======================================================================= #include "MantidGeometry/Instrument.h" diff --git a/MantidPlot/src/Mantid/MantidUI.h b/MantidPlot/src/Mantid/MantidUI.h index 29017acb913ce51aaeb0a216ad4a47f4e4b5c673..793dd255c5e87b05dd57c60367dd87111526183c 100644 --- a/MantidPlot/src/Mantid/MantidUI.h +++ b/MantidPlot/src/Mantid/MantidUI.h @@ -579,7 +579,7 @@ public: #endif private slots: - // respond to the global Mantid properties being modifed + // respond to the global Mantid properties being modified void configModified(); // slot for file open dialogs created from the main app menu, or the diff --git a/MantidPlot/src/Mantid/PeakPickerTool.h b/MantidPlot/src/Mantid/PeakPickerTool.h index 6b344b283aa08d7e6533bb20d1cd0a1ad3672740..9b2cf92b59a3695ebdccb2794ce18a10704077c3 100644 --- a/MantidPlot/src/Mantid/PeakPickerTool.h +++ b/MantidPlot/src/Mantid/PeakPickerTool.h @@ -94,7 +94,7 @@ public: Graph *graph() const { return d_graph; } /// Prepare a context menu void prepareContextMenu(QMenu &menu); - /// Was the tool created successfuly? + /// Was the tool created successfully? bool isInitialized() const { return m_init; } public slots: diff --git a/MantidPlot/src/Mantid/SampleLogDialogBase.h b/MantidPlot/src/Mantid/SampleLogDialogBase.h index 90dda4e5b3790c9c5951dde638e71d7c1d111c61..b4638f438ef3cd6aed6d879b8632b7f85e6efb9d 100644 --- a/MantidPlot/src/Mantid/SampleLogDialogBase.h +++ b/MantidPlot/src/Mantid/SampleLogDialogBase.h @@ -91,7 +91,7 @@ protected slots: protected: /// This function is not virtual because it is called from derived classes /// without overriding - /// This function initalises everything in the tree widget + /// This function initialises everything in the tree widget void init(); /// Sets the dialog's window title @@ -144,7 +144,7 @@ protected: /// these values are used to specify the format of the log file, all of which /// are stored as strings enum logType { - string, ///< indicates the log is a string, no other known formating + string, ///< indicates the log is a string, no other known formatting numTSeries, ///< for time series properties that contain numbers stringTSeries, ///< for logs that are string time series properties numeric, ///< for logs that are single numeric values (int or double) diff --git a/MantidPlot/src/Mantid/UserFitFunctionDialog.cpp b/MantidPlot/src/Mantid/UserFitFunctionDialog.cpp index cf33aae2ae89aaca2aa938bed35a70a847cc68b0..c1c10b0ba4347bbd2a94e208d14373e3f5ba503d 100644 --- a/MantidPlot/src/Mantid/UserFitFunctionDialog.cpp +++ b/MantidPlot/src/Mantid/UserFitFunctionDialog.cpp @@ -43,7 +43,7 @@ void UserFitFunctionDialog::addFunction(const QString &op, bool brackets) { QTreeWidgetItem *parentItem = item->parent(); if (parentItem == nullptr) - return; // this sould never happen, just in case + return; // this should never happen, just in case if (parentItem->parent() != nullptr) item = parentItem; diff --git a/MantidPlot/src/Matrix.h b/MantidPlot/src/Matrix.h index 672c2045815a7f5bd4f258d4c8fcada57ea31fb5..1ec3e2f0fe7dad37ecdca8ae1afe16207b27625c 100644 --- a/MantidPlot/src/Matrix.h +++ b/MantidPlot/src/Matrix.h @@ -252,7 +252,7 @@ public slots: //! Return the matrix formula QString formula() { return formula_str; }; - //! Set the matrix forumla + //! Set the matrix formula void setFormula(const QString &s) { formula_str = s; }; //! Load the matrix from a string list (i.e. lines from a project file) @@ -284,7 +284,7 @@ public slots: //! Insert a column before the current cell void insertColumn(); - //! Delte the selected columns + //! Delete the selected columns void deleteSelectedColumns(); //! Return the number of selected columns int numSelectedColumns(); diff --git a/MantidPlot/src/MdPlottingCmapsProvider.h b/MantidPlot/src/MdPlottingCmapsProvider.h index d52db3d7ac07f9fd3f865c190baffea5c002d46a..c1fcd6241439ec16dedefb366070453eb148afbb 100644 --- a/MantidPlot/src/MdPlottingCmapsProvider.h +++ b/MantidPlot/src/MdPlottingCmapsProvider.h @@ -73,7 +73,7 @@ private: /** * Compare the colormap names of the Slice Viewer and the VSI and extract all - * indicees of the list of Slice Viewer color maps + * indices 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. diff --git a/MantidPlot/src/MdiSubWindow.h b/MantidPlot/src/MdiSubWindow.h index 1832bc397476de5838566710fe656694aa78a561..e7e5e672fb9cbc210920b7ac9f5f4552b3d16919 100644 --- a/MantidPlot/src/MdiSubWindow.h +++ b/MantidPlot/src/MdiSubWindow.h @@ -136,7 +136,7 @@ public: //! Possible window captions. enum CaptionPolicy { Name = 0, //!< caption determined by the window name - Label = 1, //!< caption detemined by the window label + Label = 1, //!< caption determined by the window label Both = 2 //!< caption = "name - label" }; enum Status { Hidden = -1, Normal = 0, Minimized = 1, Maximized = 2 }; @@ -234,7 +234,7 @@ public slots: * lines to be ignored. * It creates a temporary file with '\n' terminated lines which can be * correctly read by QTextStream - * and returnes a path to this file. + * and returns a path to this file. */ static QString parseAsciiFile(const QString &fname, const QString &commentString, int endLine, @@ -307,7 +307,7 @@ signals: void dockToMDIArea(MdiSubWindow *); //! Emitted when the window wants to undock void undockFromMDIArea(MdiSubWindow *); - /// Emited to detach this window from any parent - docked or floating + /// Emitted to detach this window from any parent - docked or floating void detachFromParent(MdiSubWindow *); void dragMousePress(QPoint); diff --git a/MantidPlot/src/MultiLayer.cpp b/MantidPlot/src/MultiLayer.cpp index 205d11107e3b321a6c81b30fef0f85263d71127d..a7a0ae6493adb1616251869214a377fc2b52f032 100644 --- a/MantidPlot/src/MultiLayer.cpp +++ b/MantidPlot/src/MultiLayer.cpp @@ -1298,7 +1298,7 @@ void MultiLayer::dropEvent(QDropEvent *event) { } } -/** Drop a workspace onto an exisiting MantidMDCurve (plot of a MDWorkspace) +/** Drop a workspace onto an existing MantidMDCurve (plot of a MDWorkspace) @param g : Graph object @param originalCurve : the original MantidMDCurve onto which the new workspace(s) are to be dropped @@ -1350,7 +1350,7 @@ void MultiLayer::dropOntoMDCurve(Graph *g, MantidMDCurve *originalCurve, } /* -Drop a workspace onto an exisiting matrix curve +Drop a workspace onto an existing matrix curve @param g : Graph object @param originalCurve : the original MantidMatrixCurve onto which the new workspace(s) are to be dropped @@ -1477,7 +1477,7 @@ void MultiLayer::convertToWaterfall() { } /** - * Assume we have a waterfall 1D plot and convert it to a standard overlayed + * Assume we have a waterfall 1D plot and convert it to a standard overlaid * layout */ void MultiLayer::convertFromWaterfall() { @@ -1788,7 +1788,7 @@ MultiLayer::loadFromProject(const std::string &lines, ApplicationWindow *app, multiLayer->setLayerCanvasSize(width, height); } - if (tsv.selectLine("Alignement")) { + if (tsv.selectLine("Alignment")) { int hor = 0, vert = 0; tsv >> hor >> vert; multiLayer->setAlignement(hor, vert); @@ -1851,7 +1851,7 @@ std::string MultiLayer::saveToProject(ApplicationWindow *app) { << bottom_margin; tsv.writeLine("Spacing") << rowsSpace << colsSpace; tsv.writeLine("LayerCanvasSize") << l_canvas_width << l_canvas_height; - tsv.writeLine("Alignement") << hor_align << vert_align; + tsv.writeLine("Alignment") << hor_align << vert_align; foreach (Graph *g, graphsList) tsv.writeSection("graph", g->saveToProject()); diff --git a/MantidPlot/src/MultiPeakFitTool.h b/MantidPlot/src/MultiPeakFitTool.h index cbe2472b9758575a479418c6752a2aeb7ebebe12..625e6d48f81790163af3ad6c7dcf6827c0ec86f2 100644 --- a/MantidPlot/src/MultiPeakFitTool.h +++ b/MantidPlot/src/MultiPeakFitTool.h @@ -61,8 +61,8 @@ public: signals: /** Emitted whenever a new message should be presented to the user. * - * You don't have to connect to this signal if you alreay specified a reciever - *during initialization. + * You don't have to connect to this signal if you already specified a + *receiver during initialization. */ void statusText(const QString &); protected slots: diff --git a/MantidPlot/src/MultiTabScriptInterpreter.cpp b/MantidPlot/src/MultiTabScriptInterpreter.cpp index 094ca563d3721d98b68821615bea56910600ce89..5fe168182a1c721f69e1916021d0c47478f3271a 100644 --- a/MantidPlot/src/MultiTabScriptInterpreter.cpp +++ b/MantidPlot/src/MultiTabScriptInterpreter.cpp @@ -660,7 +660,7 @@ void MultiTabScriptInterpreter::contextMenuEvent(QContextMenuEvent *event) { /** * A custom event handler, which in this case monitors for ScriptChangeEvent * signals - * @param event :: The custome event + * @param event :: The custom event */ void MultiTabScriptInterpreter::customEvent(QEvent *event) { if (!isExecuting() && event->type() == SCRIPTING_CHANGE_EVENT) { diff --git a/MantidPlot/src/PlotDialog.cpp b/MantidPlot/src/PlotDialog.cpp index 73db59f3e90175b7bcd4744ec2b7ad62dacc6cbe..aa78aa019dc26e3412a17da93c6ed9caa237d41b 100644 --- a/MantidPlot/src/PlotDialog.cpp +++ b/MantidPlot/src/PlotDialog.cpp @@ -449,7 +449,7 @@ void PlotDialog::changePlotType(int plotType) { } /** - * Changes the graph's plot stlye from somewhere other than the plot dialog. + * Changes the graph's plot style from somewhere other than the plot dialog. * * @params plotType :: This is the plot style number. i.e line is 0 and scatter *is 1. @@ -2820,11 +2820,11 @@ void PlotDialog::customVectorsPage(bool angleMag) { } /** - This slot gets called on clicking slect colormap button + This slot gets called on clicking select colormap button */ void PlotDialog::changeColormap(const QString &filename) { // loads the settings to get the colormap file name. - // as theres is no spectrgram valid pointer here i'm directly using Qsetting + // as there's no spectrgram valid pointer here i'm directly using Qsetting // instead of Spectrogram::loadSettings() // mCurrentColorMap gives the last selected colormap file name QSettings settings; diff --git a/MantidPlot/src/PlotToolInterface.h b/MantidPlot/src/PlotToolInterface.h index 70918cb24a87c46626dfd4e284a4e485e064ffe3..72655bb2fbeb101784aa579f023954ff6c78e497 100644 --- a/MantidPlot/src/PlotToolInterface.h +++ b/MantidPlot/src/PlotToolInterface.h @@ -57,7 +57,7 @@ class Graph; * when they are finished and to generalize the statusText signal provided by *most tools, but having * PlotToolInterface inherit from QObject would make it impossible for - * plot tools to also inherit from other QObject decendants (such as + * plot tools to also inherit from other QObject descendants (such as *QwtPlotPicker). * As a workaround, plot tools can call Graph::setActiveTool(), carefully noting *that they are deleted diff --git a/MantidPlot/src/Process.cpp b/MantidPlot/src/Process.cpp index cb600b4ae187e9bfa1a21dbb0d9653e392758409..00eada6aff926855c4bff47759aa909d800ff83b 100644 --- a/MantidPlot/src/Process.cpp +++ b/MantidPlot/src/Process.cpp @@ -34,7 +34,6 @@ bool isOtherInstance(int64_t otherPID, QString otherExeName) { } // namespace namespace Process { - /** * Returns true is another instance of Mantid is running * on this machine @@ -42,12 +41,10 @@ namespace Process { * @throws std::runtime_error if this cannot be determined */ #ifdef Q_OS_LINUX -bool isAnotherInstanceRunning() { - // Inspired by psutil._pslinux.Process.exe: - // https://github.com/giampaolo/psutil/blob/master/psutil/_pslinux.py +unsigned int numberOfMantids() { QDir procfs{"/proc"}; - bool otherIsRunning(false); + int counter = 0; const QStringList entries{procfs.entryList(QDir::Dirs)}; for (const auto &pidStr : entries) { bool isDigit(false); @@ -61,14 +58,13 @@ bool isAnotherInstanceRunning() { continue; if (isOtherInstance(pid, QFileInfo(exe.symLinkTarget()).fileName())) { - otherIsRunning = true; - break; + ++counter; } } - return otherIsRunning; + return counter; } #elif defined(Q_OS_WIN) -bool isAnotherInstanceRunning() { +unsigned int numberOfMantids() { using MantidQt::API::toQStringInternal; // Inspired by psutil.psutil_get_pids at // https://github.com/giampaolo/psutil/blob/master/psutil/arch/windows/process_info.c @@ -92,7 +88,7 @@ bool isAnotherInstanceRunning() { // Set the vector back to the appropriate size processes.resize(enumReturnSz / sizeof(DWORD)); - bool otherIsRunning(false); + int counter = 0; wchar_t exe[MAX_PATH]; for (const auto pid : processes) { // system-idle process @@ -105,15 +101,13 @@ bool isAnotherInstanceRunning() { CloseHandle(procHandle); if (exeSz > 0 && isOtherInstance(pid, QFileInfo(toQStringInternal(exe)).fileName())) { - otherIsRunning = true; - break; + ++counter; } } - return otherIsRunning; + return counter; } - #elif defined(Q_OS_MAC) -bool isAnotherInstanceRunning() { +unsigned int numberOfMantids() { kinfo_proc *processes[] = {nullptr}; size_t processesLength(0); int sysctlQuery[3] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL}; @@ -163,7 +157,7 @@ bool isAnotherInstanceRunning() { kinfo_proc *processListBegin = processes[0]; kinfo_proc *processIter = processListBegin; char exePath[PATH_MAX]; - auto otherIsRunning = false; + int counter = 0; for (size_t i = 0; i < processesLength; ++i) { const auto pid = processIter->kp_proc.p_pid; if (proc_pidpath(pid, exePath, PATH_MAX) <= 0) { @@ -172,15 +166,14 @@ bool isAnotherInstanceRunning() { } if (isOtherInstance(pid, QFileInfo(QString::fromAscii(exePath)).fileName())) { - otherIsRunning = true; - break; + ++counter; } - processIter++; + ++processIter; } free(processListBegin); - return otherIsRunning; + return counter; } #endif - +long long getProcessID() { return QCoreApplication::applicationPid(); } } // namespace Process diff --git a/MantidPlot/src/Process.h b/MantidPlot/src/Process.h index a34de63c26a7d809ca9b9efb4359f3150210f088..802e978b3db72ffa4b99d87609ba8e3c04609793 100644 --- a/MantidPlot/src/Process.h +++ b/MantidPlot/src/Process.h @@ -29,6 +29,7 @@ Code Documentation is available at: <http://doxygen.mantidproject.org> namespace Process { -bool isAnotherInstanceRunning(); -} +unsigned int numberOfMantids(); +long long getProcessID(); +} // namespace Process #endif // PROCESS_H_ diff --git a/MantidPlot/src/ProjectRecovery.cpp b/MantidPlot/src/ProjectRecovery.cpp index d6bfdc130383242dc545390158f9e86106226eff..0f7fecb68f583c292ec2bfa8fe17f2c14f40d7bd 100644 --- a/MantidPlot/src/ProjectRecovery.cpp +++ b/MantidPlot/src/ProjectRecovery.cpp @@ -2,6 +2,7 @@ #include "ApplicationWindow.h" #include "Folder.h" +#include "Process.h" #include "ProjectSerialiser.h" #include "ScriptingWindow.h" @@ -13,15 +14,15 @@ #include "MantidKernel/Logger.h" #include "MantidKernel/UsageService.h" -#include "boost/algorithm/string/classification.hpp" -#include "boost/optional.hpp" -#include "boost/range/algorithm_ext/erase.hpp" +#include <boost/algorithm/string/classification.hpp> +#include <boost/optional.hpp> +#include <boost/range/algorithm_ext/erase.hpp> -#include "Poco/DirectoryIterator.h" -#include "Poco/Environment.h" -#include "Poco/NObserver.h" -#include "Poco/Path.h" -#include "Poco/Process.h" +#include <Poco/DirectoryIterator.h> +#include <Poco/Environment.h> +#include <Poco/NObserver.h> +#include <Poco/Path.h> +#include <Poco/Process.h> #include <QMessageBox> #include <QMetaObject> @@ -34,9 +35,13 @@ #include <iomanip> #include <iostream> #include <mutex> +#include <signal.h> #include <string> #include <thread> +#ifdef _WIN32 +#define pid_t int +#endif namespace { Mantid::Kernel::Logger g_log("ProjectRecovery"); @@ -50,8 +55,20 @@ boost::optional<bool> getConfigBool(const std::string &key) { return Mantid::Kernel::ConfigService::Instance().getValue<bool>(key); } +/// Returns a string to the folder it should output to +std::string getRecoveryFolderOutput() { + static std::string appData = + Mantid::Kernel::ConfigService::Instance().getAppDataDir(); + static std::string hostname = Poco::Environment::nodeName(); + static std::string pid = std::to_string(Process::getProcessID()); + + static std::string recoverFolder = + appData + "/recovery/" + hostname + '/' + pid + '/'; + return recoverFolder; +} + /// Returns a string to the current top level recovery folder -std::string getRecoveryFolder() { +std::string getRecoveryFolderCheck() { static std::string appData = Mantid::Kernel::ConfigService::Instance().getAppDataDir(); static std::string hostname = Poco::Environment::nodeName(); @@ -60,6 +77,100 @@ std::string getRecoveryFolder() { return recoverFolder; } +/// Determines if a process ID is being used +bool isPIDused(pid_t pID) { + if (pID <= 0) { + return false; + } +// For Windows: +#if defined(_WIN32) || defined(_WIN64) + HANDLE handle = OpenProcess(SYNCHRONIZE, false, pID); + if (!handle) { + return false; + } else { + CloseHandle(handle); + return true; + } +#endif +// For Linux: +#if defined(__linux__) || defined(__APPLE__) + // check if pid exists + return (0 == kill(pID, 0)); +#endif +} + +std::vector<Poco::Path> +getListOfFoldersInDirectory(const std::string &recoveryFolderPath) { + Poco::Path recoveryPath; + + if (!recoveryPath.tryParse(recoveryFolderPath) || + !Poco::File(recoveryPath).exists()) { + // Folder may not exist yet + g_log.debug("Project Saving: Working folder does not exist"); + return {}; + } + + std::vector<Poco::Path> folderPaths; + + Poco::DirectoryIterator dirIterator(recoveryFolderPath); + Poco::DirectoryIterator end; + // Find all the folders which exist in this folder + while (dirIterator != end) { + std::string iterPath = recoveryFolderPath + dirIterator.name() + '/'; + Poco::Path foundPath(iterPath); + + if (foundPath.isDirectory()) { + folderPaths.emplace_back(std::move(foundPath)); + } + ++dirIterator; + } + + return folderPaths; +} + +std::vector<int> orderProcessIDs(std::vector<Poco::Path> paths) { + std::vector<int> returnValues; + // Sort the paths by last modified + std::sort(paths.begin(), paths.end(), + [](const Poco::Path &a, const Poco::Path &b) { + Poco::File a1(a); + Poco::File b1(b); + // Last modified is first! + return a1.getLastModified() > b1.getLastModified(); + }); + + for (auto c : paths) { + returnValues.emplace_back(std::stoi(c.directory(c.depth() - 1))); + } + return returnValues; +} + +/// Returns a string to the folder that should be recovered +std::string getRecoveryFolderLoad() { + std::string recoverFolder = getRecoveryFolderCheck(); + // Get the PIDS + std::vector<Poco::Path> possiblePidsPaths = + getListOfFoldersInDirectory(recoverFolder); + if (possiblePidsPaths.size() == 0) { + throw std::runtime_error( + "Project Recovery: Load failed attempted to find potential unused pid " + "but none were found after successful check"); + } + // Order pids based on date last modified descending + std::vector<int> possiblePids = orderProcessIDs(possiblePidsPaths); + // check if pid exists + for (auto c : possiblePids) { + if (!isPIDused(c)) { + // It doesn't exist so return + return recoverFolder.append(std::to_string(c) + "/"); + } + } + // Throw if it gets to this point and hasn't found one. + throw std::runtime_error( + "Project Recovery: Load failed attempted to find potential unused pid " + "but none were found after successful check"); +} + /// Gets a formatted timestamp std::string getTimeStamp() { const char *formatSpecifier = "%Y-%m-%dT%H-%M-%S"; @@ -86,36 +197,15 @@ std::string getTimeStamp() { Poco::Path getOutputPath() { auto timestamp = getTimeStamp(); - auto timestampedPath = getRecoveryFolder().append(timestamp); + auto timestampedPath = getRecoveryFolderOutput().append(timestamp); return Poco::Path{timestampedPath}; } std::vector<Poco::Path> getRecoveryFolderCheckpoints(const std::string &recoveryFolderPath) { - Poco::Path recoveryPath; - - if (!recoveryPath.tryParse(recoveryFolderPath) || - !Poco::File(recoveryPath).exists()) { - // Folder may not exist yet - g_log.debug("Project Saving: Working folder does not exist"); - return {}; - } - - std::vector<Poco::Path> folderPaths; - - Poco::DirectoryIterator dirIterator(recoveryFolderPath); - Poco::DirectoryIterator end; - // Find all the folders which exist in this folder - while (dirIterator != end) { - std::string iterPath = recoveryFolderPath + dirIterator.name() + '/'; - Poco::Path foundPath(iterPath); - - if (foundPath.isDirectory()) { - folderPaths.push_back(std::move(foundPath)); - } - ++dirIterator; - } + std::vector<Poco::Path> folderPaths = + getListOfFoldersInDirectory(recoveryFolderPath); // Ensure the oldest is first in the vector std::sort(folderPaths.begin(), folderPaths.end(), @@ -175,13 +265,14 @@ void ProjectRecovery::attemptRecovery() { if (userChoice == 1) { // User selected no + clearAllUnusedCheckpoints(); this->startProjectSaving(); return; } - const auto checkpointPaths = - getRecoveryFolderCheckpoints(getRecoveryFolder()); - auto &mostRecentCheckpoint = checkpointPaths.back(); + auto beforeRecoveryFolder = getRecoveryFolderLoad(); + auto checkpointPaths = getRecoveryFolderCheckpoints(beforeRecoveryFolder); + auto mostRecentCheckpoint = checkpointPaths.back(); auto destFilename = Poco::Path(Mantid::Kernel::ConfigService::Instance().getAppDataDir()); @@ -197,7 +288,7 @@ void ProjectRecovery::attemptRecovery() { } else if (userChoice == 2) { openInEditor(mostRecentCheckpoint, destFilename); // Restart project recovery as we stay synchronous - clearAllCheckpoints(); + clearAllCheckpoints(beforeRecoveryFolder); startProjectSaving(); } else { throw std::runtime_error("Unknown choice in ProjectRecovery"); @@ -207,9 +298,9 @@ void ProjectRecovery::attemptRecovery() { bool ProjectRecovery::checkForRecovery() const noexcept { try { const auto checkpointPaths = - getRecoveryFolderCheckpoints(getRecoveryFolder()); - return checkpointPaths.size() != - 0; // Non zero indicates recovery is pending + getRecoveryFolderCheckpoints(getRecoveryFolderCheck()); + return checkpointPaths.size() != 0 && + (checkpointPaths.size() > Process::numberOfMantids()); } catch (...) { g_log.warning("Project Recovery: Caught exception whilst attempting to " "check for existing recovery"); @@ -228,6 +319,28 @@ bool ProjectRecovery::clearAllCheckpoints() const noexcept { } } +bool ProjectRecovery::clearAllCheckpoints(Poco::Path path) const noexcept { + try { + Poco::File(path).remove(true); + return true; + } catch (...) { + g_log.warning("Project Recovery: Caught exception whilst attempting to " + "clear existing checkpoints."); + return false; + } +} + +bool ProjectRecovery::clearAllUnusedCheckpoints() const noexcept { + try { + deleteExistingUnusedCheckpoints(0); + return true; + } catch (...) { + g_log.warning("Project Recovery: Caught exception whilst attempting to " + "clear existing checkpoints."); + return false; + } +} + /// Returns a background thread with the current object captured inside it std::thread ProjectRecovery::createBackgroundThread() { // Using a lambda helps the compiler deduce the this pointer @@ -273,7 +386,44 @@ void ProjectRecovery::compileRecoveryScript(const Poco::Path &inputFolder, */ void ProjectRecovery::deleteExistingCheckpoints( size_t checkpointsToKeep) const { - const auto folderPaths = getRecoveryFolderCheckpoints(getRecoveryFolder()); + const auto folderPaths = + getRecoveryFolderCheckpoints(getRecoveryFolderOutput()); + + size_t numberOfDirsPresent = folderPaths.size(); + if (numberOfDirsPresent <= checkpointsToKeep) { + // Nothing to do + return; + } + + size_t checkpointsToRemove = numberOfDirsPresent - checkpointsToKeep; + bool recurse = true; + for (size_t i = 0; i < checkpointsToRemove; i++) { + Poco::File(folderPaths[i]).remove(recurse); + } +} + +void ProjectRecovery::deleteExistingUnusedCheckpoints( + size_t checkpointsToKeep) const { + std::string recoverFolder = getRecoveryFolderCheck(); + // Get the PIDS + std::vector<Poco::Path> possiblePidsPaths = + getListOfFoldersInDirectory(recoverFolder); + if (possiblePidsPaths.size() == 0) { + throw std::runtime_error( + "Project Recovery: Load failed attempted to find potential unused pid " + "but none were found after successful check"); + } + // Order pids based on date last modified descending + std::vector<int> possiblePids = orderProcessIDs(possiblePidsPaths); + // check if pid exists + std::vector<std::string> folderPaths; + for (auto i = 0u; i < possiblePids.size(); ++i) { + if (!isPIDused(possiblePids[i])) { + std::string folder = recoverFolder; + folder.append(std::to_string(possiblePids[i]) + "/"); + folderPaths.emplace_back(folder); + } + } size_t numberOfDirsPresent = folderPaths.size(); if (numberOfDirsPresent <= checkpointsToKeep) { @@ -343,7 +493,6 @@ void ProjectRecovery::loadRecoveryCheckpoint(const Poco::Path &recoveryFolder) { // exception g_log.error("Project recovery script did not finish. Your work has been " "partially recovered."); - this->clearAllCheckpoints(); this->startProjectSaving(); return; } @@ -357,8 +506,8 @@ void ProjectRecovery::loadRecoveryCheckpoint(const Poco::Path &recoveryFolder) { Q_RETURN_ARG(bool, loadCompleted), Q_ARG(const std::string, projectFile.toString()))) { this->startProjectSaving(); - throw std::runtime_error( - "Project Recovery: Failed to load project windows - Qt binding failed"); + throw std::runtime_error("Project Recovery: Failed to load project " + "windows - Qt binding failed"); } if (!loadCompleted) { @@ -369,7 +518,7 @@ void ProjectRecovery::loadRecoveryCheckpoint(const Poco::Path &recoveryFolder) { g_log.notice("Project Recovery finished"); // Restart project recovery when the async part finishes - clearAllCheckpoints(); + clearAllCheckpoints(Poco::Path(recoveryFolder).popDirectory()); startProjectSaving(); } // namespace MantidQt @@ -394,7 +543,6 @@ void ProjectRecovery::openInEditor(const Poco::Path &inputFolder, throw std::runtime_error("Could not get handle to scripting window"); } - startProjectSaving(); scriptWindow->open(QString::fromStdString(historyDest.toString())); } @@ -509,10 +657,42 @@ void ProjectRecovery::saveWsHistories(const Poco::Path &historyDestFolder) { } } +void ProjectRecovery::removeOlderCheckpoints() { + // Currently set to a month in microseconds + const int64_t timeToDeleteAfter = 2592000000000; + std::string recoverFolder = getRecoveryFolderCheck(); + // Get the PIDS + std::vector<Poco::Path> possiblePidsPaths = + getListOfFoldersInDirectory(recoverFolder); + // Order pids based on date last modified descending + std::vector<int> possiblePids = orderProcessIDs(possiblePidsPaths); + // check if pid exists + std::vector<std::string> folderPaths; + for (auto i = 0u; i < possiblePids.size(); ++i) { + if (!isPIDused(possiblePids[i])) { + std::string folder = recoverFolder; + folder.append(std::to_string(possiblePids[i]) + "/"); + if (olderThanAGivenTime(Poco::Path(folder), timeToDeleteAfter)) { + folderPaths.emplace_back(folder); + } + } + } + + bool recurse = true; + for (size_t i = 0; i < folderPaths.size(); i++) { + Poco::File(folderPaths[i]).remove(recurse); + } +} + +bool ProjectRecovery::olderThanAGivenTime(const Poco::Path &path, + int64_t elapsedTime) { + return Poco::File(path).getLastModified().isElapsed(elapsedTime); +} + /** - * @brief A function that brings the two seperate save methods together + * @brief A function that brings the two separate save methods together * This won't run if it is locked by the background thread but then it saving - * Anyway so thats no issue. + * Anyway so that's no issue. */ void ProjectRecovery::saveAll(bool autoSave) { // "Timeout" - Save out again @@ -536,4 +716,7 @@ void ProjectRecovery::saveAll(bool autoSave) { g_log.debug("Project Recovery: Saving finished"); } +std::string ProjectRecovery::getRecoveryFolderOutputPR() { + return getRecoveryFolderOutput(); +} } // namespace MantidQt diff --git a/MantidPlot/src/ProjectRecovery.h b/MantidPlot/src/ProjectRecovery.h index 2f6ef3f8f186e6197c8c62119c45e55502af7d7c..8ccf89a13a638dae0b69ad9f6fa57634c3e47be4 100644 --- a/MantidPlot/src/ProjectRecovery.h +++ b/MantidPlot/src/ProjectRecovery.h @@ -62,14 +62,26 @@ public: /// Clears all checkpoints in the existing folder bool clearAllCheckpoints() const noexcept; + /// Clears all checkpoints in the existing folder at the given path + bool clearAllCheckpoints(Poco::Path path) const noexcept; + + /// Clears all checkpoints in the existing folder at the given path + bool clearAllUnusedCheckpoints() const noexcept; + /// Starts the background thread void startProjectSaving(); /// Stops the background thread void stopProjectSaving(); + /// Removes checkpoints should they be older than a month old. + void removeOlderCheckpoints(); + /// Saves a project recovery checkpoint void saveAll(bool autoSave = true); + /// get Recovery Folder location + std::string getRecoveryFolderOutputPR(); + private: /// Captures the current object in the background thread std::thread createBackgroundThread(); @@ -84,6 +96,13 @@ private: /// Deletes oldest checkpoints beyond the maximum number to keep void deleteExistingCheckpoints(size_t checkpointsToKeep) const; + /// Deletes oldest checkpoints beyond the maximum number to keep at the path + void deleteExistingCheckpoints(size_t checkpointsToKeep, + Poco::Path path) const; + + /// Deletes oldest "unused" checkpoints beyond the maximum number to keep + void deleteExistingUnusedCheckpoints(size_t checkpointsToKeep) const; + /// Loads a recovery checkpoint in the given folder void loadRecoveryCheckpoint(const Poco::Path &path); @@ -104,6 +123,9 @@ private: /// Saves the current workspace's histories from Mantid void saveWsHistories(const Poco::Path &projectDestFile); + // Return true if the folder at the end of the path is older than a month. + bool olderThanAGivenTime(const Poco::Path &path, int64_t elapsedTime); + /// Background thread which runs the saving body std::thread m_backgroundSavingThread; diff --git a/MantidPlot/src/ProjectSaveView.cpp b/MantidPlot/src/ProjectSaveView.cpp index 77812c53e9bdcc00a3c5c407ca5436359c39e38f..0f6a1a2e11d47db07620f34338f5c8c7cbceacfa 100644 --- a/MantidPlot/src/ProjectSaveView.cpp +++ b/MantidPlot/src/ProjectSaveView.cpp @@ -231,7 +231,7 @@ void ProjectSaveView::workspaceItemChanged(QTreeWidgetItem *item, int column) { * then only a subset of the workspaces/windows will be passed to the project * serialiser. * - * @param checked :: unused arguement + * @param checked :: unused argument */ void ProjectSaveView::save(bool checked) { UNUSED_ARG(checked); diff --git a/MantidPlot/src/ProjectSaveView.h b/MantidPlot/src/ProjectSaveView.h index 5957f2748562bec33ad969edca6fafd9b8eb4bcb..d65053ac11534d60bbb82c2b5f88ff0730e4e25e 100644 --- a/MantidPlot/src/ProjectSaveView.h +++ b/MantidPlot/src/ProjectSaveView.h @@ -18,7 +18,7 @@ namespace MantidWidgets { /** @class ProjectSaveView -ProjectSaveView is the interaces for defining the functions that the project +ProjectSaveView is the interfaces for defining the functions that the project save view needs to implement. Copyright © 2011-14 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge @@ -117,7 +117,7 @@ private: bool checkIfNewProject(const QString &projectName) const; /// Resize a QTreeWidgets columns to fit text correctly void resizeWidgetColumns(QTreeWidget *widget); - /// Connect up signals to the interface on initilisation + /// Connect up signals to the interface on initialisation void connectSignals(); /// Update the checked state of the tree when an item is updated void updateWorkspaceListCheckState(QTreeWidgetItem *item); diff --git a/MantidPlot/src/ProjectSerialiser.cpp b/MantidPlot/src/ProjectSerialiser.cpp index acf15284a25c1eadf1be5aabed411105bf4ff018..945c6c9ae27cc4b20060433e1ba22370510448fe 100644 --- a/MantidPlot/src/ProjectSerialiser.cpp +++ b/MantidPlot/src/ProjectSerialiser.cpp @@ -19,10 +19,10 @@ #include "MantidAPI/AnalysisDataService.h" #include "MantidAPI/MatrixWorkspace.h" #include "MantidAPI/WorkspaceGroup.h" +#include "MantidPythonInterface/core/VersionCompat.h" #include "MantidKernel/Logger.h" #include "MantidKernel/MantidVersion.h" #include "MantidQtWidgets/Common/PlotAxis.h" -#include "MantidQtWidgets/Common/PythonThreading.h" #include "MantidQtWidgets/Common/VatesViewerInterface.h" #include "MantidQtWidgets/SliceViewer/SliceViewerWindow.h" #include "MantidQtWidgets/SpectrumViewer/SpectrumView.h" @@ -37,6 +37,7 @@ #include <vector> using namespace Mantid::API; +namespace Python = Mantid::PythonInterface; using namespace MantidQt::API; using Mantid::Kernel::Logger; @@ -750,7 +751,7 @@ QString ProjectSerialiser::savePythonInterfaces() { QString ProjectSerialiser::savePythonInterface(const QString &launcherModuleName) { assert(!launcherModuleName.isEmpty()); - ScopedGIL<PythonGIL> gil; + Python::GlobalInterpreterLock gil; auto state = callPythonModuleAttr(launcherModuleName.toLatin1().data(), "saveToProject", nullptr); if (!STR_CHECK(state)) { @@ -1079,7 +1080,7 @@ void ProjectSerialiser::loadPythonInterface( throw std::runtime_error("Interface not whitelisted as saveable."); } - ScopedGIL<PythonGIL> gil; + Python::GlobalInterpreterLock gil; PyObject *fnArg = Py_BuildValue("(s)", pySection.c_str()); PyObject *result(nullptr); try { diff --git a/MantidPlot/src/PythonScript.cpp b/MantidPlot/src/PythonScript.cpp index f3afe506e9fe8c8c742e053b3865983dc1fb98ce..eabd1d8f727092cd87c2a7d2a83282a855aa8eb3 100644 --- a/MantidPlot/src/PythonScript.cpp +++ b/MantidPlot/src/PythonScript.cpp @@ -37,8 +37,17 @@ #include "sipAPI_qti.h" +// Python +#include "MantidPythonInterface/core/VersionCompat.h" +#include <compile.h> +#include <eval.h> +#include <frameobject.h> +#include <traceback.h> + #include <stdexcept> +using Mantid::PythonInterface::GlobalInterpreterLock; + namespace { // Avoids a compiler warning about implicit 'const char *'->'char*' conversion // under clang @@ -82,7 +91,7 @@ PythonScript::PythonScript(PythonScripting *env, const QString &name, : Script(env, name, interact, context), m_interp(env), localDict(nullptr), stdoutSave(nullptr), stderrSave(nullptr), m_codeFileObject(nullptr), m_threadID(-1), isFunction(false), m_isInitialized(false), - m_pathHolder(name), m_recursiveAsyncGIL() { + m_pathHolder(name), m_recursiveAsyncGIL(PyGILState_UNLOCKED) { initialize(name, context); } @@ -90,7 +99,7 @@ PythonScript::PythonScript(PythonScripting *env, const QString &name, * Destructor */ PythonScript::~PythonScript() { - ScopedPythonGIL lock; + GlobalInterpreterLock lock; this->abort(); observeAdd(false); observeAfterReplace(false); @@ -139,11 +148,11 @@ PyObject *PythonScript::createSipInstanceFromMe() { /** * @param code A lump of python code - * @return True if the code forms a complete statment + * @return True if the code forms a complete statement */ bool PythonScript::compilesToCompleteStatement(const QString &code) const { bool result(false); - ScopedPythonGIL lock; + GlobalInterpreterLock lock; PyObject *compiledCode = Py_CompileString(code.toAscii(), "", Py_file_input); if (PyObject *exception = PyErr_Occurred()) { // Certain exceptions still mean the code is complete @@ -187,7 +196,7 @@ void PythonScript::sendLineChangeSignal(int lineNo, bool error) { * Create a list autocomplete keywords */ void PythonScript::generateAutoCompleteList() { - ScopedPythonGIL lock; + GlobalInterpreterLock lock; PyObject *keywords = PyObject_CallFunctionObjArgs( PyDict_GetItemString(m_interp->globalDict(), "_ScopeInspector_GetFunctionAttributes"), @@ -207,7 +216,7 @@ void PythonScript::generateAutoCompleteList() { */ void PythonScript::emit_error() { // gil is necessary so other things don't continue - ScopedPythonGIL lock; + GlobalInterpreterLock lock; // return early if nothing happened if (!PyErr_Occurred()) { @@ -254,7 +263,7 @@ void PythonScript::emit_error() { filename = TO_CSTRING(tb->tb_frame->f_code->co_filename); } - // the error message is the full (formated) traceback + // the error message is the full (formatted) traceback PyObject *str_repr = PyObject_Str(value); QString message; QTextStream msgStream(&message); @@ -381,7 +390,7 @@ void PythonScript::setContext(QObject *context) { * the dictionary context back to the default set */ void PythonScript::clearLocals() { - ScopedPythonGIL lock; + GlobalInterpreterLock lock; PyObject *mainModule = PyImport_AddModule("__main__"); PyObject *cleanLocals = PyDict_Copy(PyModule_GetDict(mainModule)); @@ -407,7 +416,7 @@ void PythonScript::clearLocals() { void PythonScript::initialize(const QString &name, QObject *context) { clearLocals(); // holds and releases GIL - ScopedPythonGIL lock; + GlobalInterpreterLock lock; PythonScript::setIdentifier(name); setContext(context); @@ -455,8 +464,8 @@ void PythonScript::endStdoutRedirect() { * @return True if the lock was released by this call, false otherwise */ bool PythonScript::recursiveAsyncSetup() { - if (PythonGIL::locked()) { - m_recursiveAsyncGIL.release(); + if (GlobalInterpreterLock::locked()) { + GlobalInterpreterLock::release(m_recursiveAsyncGIL); return true; } return false; @@ -470,7 +479,7 @@ bool PythonScript::recursiveAsyncSetup() { */ void PythonScript::recursiveAsyncTeardown(bool relock) { if (relock) { - m_recursiveAsyncGIL.acquire(); + m_recursiveAsyncGIL = GlobalInterpreterLock::acquire(); } } @@ -490,7 +499,7 @@ bool PythonScript::compileImpl() { * @return */ QVariant PythonScript::evaluateImpl() { - ScopedPythonGIL lock; + GlobalInterpreterLock lock; PyObject *compiledCode = this->compileToByteCode(true); if (!compiledCode) { return QVariant(""); @@ -618,7 +627,7 @@ void PythonScript::abortImpl() { // hasn't implemented cancel() checking so that when control returns the // Python the // interrupt should be picked up. - ScopedPythonGIL lock; + GlobalInterpreterLock lock; m_interp->raiseAsyncException(m_threadID, PyExc_KeyboardInterrupt); PyObject *curAlg = PyObject_CallFunction(m_algorithmInThread, STR_LITERAL("l"), m_threadID); @@ -633,7 +642,7 @@ void PythonScript::abortImpl() { * @return A long int giving a unique ID for the thread */ long PythonScript::getThreadID() { - ScopedPythonGIL lock; + GlobalInterpreterLock lock; return PyThreadState_Get()->thread_id; } @@ -641,7 +650,7 @@ long PythonScript::getThreadID() { bool PythonScript::executeString() { emit started(MSG_STARTED); bool success(false); - ScopedPythonGIL lock; + GlobalInterpreterLock lock; PyObject *compiledCode = compileToByteCode(false); PyObject *result(nullptr); diff --git a/MantidPlot/src/PythonScript.h b/MantidPlot/src/PythonScript.h index 7daa247c4a9af83ad2f3e64dd72a1a7408d3d147..61634ccd52612e8c88e9292a380f46a5ad9831ee 100644 --- a/MantidPlot/src/PythonScript.h +++ b/MantidPlot/src/PythonScript.h @@ -29,10 +29,7 @@ #ifndef PYTHON_SCRIPT_H #define PYTHON_SCRIPT_H -// Python headers have to go first! -#include "MantidQtWidgets/Common/PythonSystemHeader.h" -#include "MantidQtWidgets/Common/PythonThreading.h" - +#include "MantidPythonInterface/core/GlobalInterpreterLock.h" #include "MantidQtWidgets/Common/WorkspaceObserver.h" #include "Script.h" @@ -125,14 +122,14 @@ private: } void appendPath(const QString &path) { - ScopedPythonGIL lock; + Mantid::PythonInterface::GlobalInterpreterLock lock; QString code = "if r'%1' not in sys.path:\n" " sys.path.append(r'%1')"; code = code.arg(path); PyRun_SimpleString(code.toAscii().constData()); } void removePath(const QString &path) { - ScopedPythonGIL lock; + Mantid::PythonInterface::GlobalInterpreterLock lock; QString code = "if r'%1' in sys.path:\n" " sys.path.remove(r'%1')"; code = code.arg(path); @@ -144,7 +141,6 @@ private: }; inline PythonScripting *interp() const { return m_interp; } - PythonGIL &gil() const; void initialize(const QString &name, QObject *context); void beginStdoutRedirect(); void endStdoutRedirect(); @@ -165,7 +161,7 @@ private: // mantidplot.runPythonScript('test=CreateSampleWorkspace()', True) // // To circumvent this we must release the GIL on the main thread - // before starting the async thread and then reaquire it when that thread + // before starting the async thread and then reacquire it when that thread // has finished and the main thread must keep executing. These methods // are used for this purpose and are NOT used by the general executeAsync // methods where the GILState API functions can cope and there is no @@ -208,7 +204,7 @@ private: PythonPathHolder m_pathHolder; /// This must only be used by the recursiveAsync* methods /// as they need to store state between calls. - PythonGIL m_recursiveAsyncGIL; + PyGILState_STATE m_recursiveAsyncGIL; }; #endif diff --git a/MantidPlot/src/PythonScripting.cpp b/MantidPlot/src/PythonScripting.cpp index 5a07ce0a7d05098084f84570f32d2259a7b5e1e6..ba0d0aaeab928aaea1004f96b321e98eaed0b5ff 100644 --- a/MantidPlot/src/PythonScripting.cpp +++ b/MantidPlot/src/PythonScripting.cpp @@ -38,6 +38,8 @@ #include "MantidKernel/ConfigService.h" #include "MantidKernel/Logger.h" #include "MantidKernel/StringTokenizer.h" +#include "MantidPythonInterface/core/GlobalInterpreterLock.h" +#include "MantidPythonInterface/core/VersionCompat.h" #include <QApplication> #include <Qsci/qscilexerpython.h> @@ -58,6 +60,8 @@ PyMODINIT_FUNC PyInit__qti(); PyMODINIT_FUNC init_qti(); #endif +using Mantid::PythonInterface::GlobalInterpreterLock; + namespace { Mantid::Kernel::Logger g_log("PythonScripting"); @@ -86,7 +90,7 @@ PythonScripting::~PythonScripting() {} * @param args A list of strings that denoting command line arguments */ void PythonScripting::setSysArgs(const QStringList &args) { - ScopedPythonGIL lock; + GlobalInterpreterLock lock; PyObject *argv = toPyList(args); if (argv && m_sys) { PyDict_SetItemString(m_sys, "argv", argv); @@ -146,9 +150,13 @@ bool PythonScripting::start() { #else PyImport_AppendInittab("_qti", &init_qti); #endif - PythonInterpreter::initialize(); - ScopedPythonGIL lock; + Py_Initialize(); + // Acquires the GIL + PyEval_InitThreads(); + // Release GIL so that we can use our scoped lock types for management + PyEval_SaveThread(); + GlobalInterpreterLock lock; // Keep a hold of the globals, math and sys dictionary objects PyObject *mainmod = PyImport_AddModule("__main__"); if (!mainmod) { @@ -218,10 +226,9 @@ bool PythonScripting::start() { void PythonScripting::shutdown() { // The scoped lock cannot be used here as after the // finalize call no Python code can execute. - PythonGIL gil; - gil.acquire(); + GlobalInterpreterLock::acquire(); Py_XDECREF(m_math); - PythonInterpreter::finalize(); + Py_Finalize(); } void PythonScripting::setupPythonPath() { diff --git a/MantidPlot/src/PythonScripting.h b/MantidPlot/src/PythonScripting.h index 3aadc1bf38f582e2533616993cd8b623d054f61f..45bb6be45b1704d0764c2d1f5833c9717e6d680b 100644 --- a/MantidPlot/src/PythonScripting.h +++ b/MantidPlot/src/PythonScripting.h @@ -64,7 +64,7 @@ public: /// Set the argv attribute on the sys module void setSysArgs(const QStringList &args) override; - /// Create a new script object that can execute code within this enviroment + /// Create a new script object that can execute code within this environment Script *newScript(const QString &name, QObject *context, const Script::InteractionType interact) const override; @@ -77,7 +77,7 @@ public: /// Does this support abort requests? bool supportsAbortRequests() const override { return true; } - /// Return a string represenation of the given object + /// Return a string representation of the given object QString toString(PyObject *object, bool decref = false); /// Convert a Python list object to a Qt QStringList QStringList toStringList(PyObject *py_seq); @@ -139,8 +139,6 @@ private: PyObject *m_sys; /// Pointer to the main threads state PyThreadState *m_mainThreadState; - /// Wrap's acquisition of the GIL - PythonGIL m_gil; }; #endif diff --git a/MantidPlot/src/RangeSelectorTool.h b/MantidPlot/src/RangeSelectorTool.h index 5213e7246393ae1b0e7448f16d590f63df026d79..cd41a66d0392e808674dd752b6fed3ea1579781b 100644 --- a/MantidPlot/src/RangeSelectorTool.h +++ b/MantidPlot/src/RangeSelectorTool.h @@ -49,7 +49,7 @@ class QEvent; * active in parallel and possibly depending on each other should be generalized *somehow. * - * In any case, gathering the code specific to range selection in a seperate + * In any case, gathering the code specific to range selection in a separate *class makes Graph/CanvasPicker * more manageable; maybe something similar can be done for zooming. */ @@ -88,8 +88,8 @@ public slots: signals: /** Emitted whenever a new message should be presented to the user. * - * You don't have to connect to this signal if you alreay specified a reciever - *during initialization. + * You don't have to connect to this signal if you already specified a + *receiver during initialization. */ void statusText(const QString &); //! Emitted whenever the selected curve and/or range have changed. diff --git a/MantidPlot/src/ScaleDetails.cpp b/MantidPlot/src/ScaleDetails.cpp index fb985a41723cdaa7afac9459839cb3cc1180e60d..d1d447621d44d46e4f7c40a614c729274bf2733e 100644 --- a/MantidPlot/src/ScaleDetails.cpp +++ b/MantidPlot/src/ScaleDetails.cpp @@ -28,7 +28,7 @@ Mantid::Kernel::Logger g_log("ScaleDetails"); * @param graph :: the graph the dialog is settign the options for * @param mappedaxis :: the QwtPlot::axis value that corresponds to this axis * @param parent :: the QWidget that acts as this widget's parent in the - * hierachy + * hierarchy */ ScaleDetails::ScaleDetails(ApplicationWindow *app, Graph *graph, int mappedaxis, QWidget *parent) @@ -581,7 +581,7 @@ void ScaleDetails::apply() { } } -/** Sets the modifed flag to true so that the changes may be applied. +/** Sets the modified flag to true so that the changes may be applied. * */ void ScaleDetails::setModified() { m_modified = true; } diff --git a/MantidPlot/src/ScreenPickerTool.h b/MantidPlot/src/ScreenPickerTool.h index f9243ce7ce3972350fe5e1bec9be169ec2236265..d3710be8fa1813787c16c878953cc4c4a80cf57d 100644 --- a/MantidPlot/src/ScreenPickerTool.h +++ b/MantidPlot/src/ScreenPickerTool.h @@ -56,8 +56,8 @@ public: signals: /** Emitted whenever a new message should be presented to the user. * - * You don't have to connect to this signal if you alreay specified a reciever - *during initialization. + * You don't have to connect to this signal if you already specified a + *receiver during initialization. */ void statusText(const QString &); diff --git a/MantidPlot/src/Script.h b/MantidPlot/src/Script.h index cbd9c96eb15bd9d95bc1e0c23c6314acc4ac0a7f..797694c119c6d0d94aaaced4ec817003646de25a 100644 --- a/MantidPlot/src/Script.h +++ b/MantidPlot/src/Script.h @@ -65,7 +65,7 @@ public: QObject *context = nullptr); /// Destructor ~Script() override; - /// Returns the envirnoment this script is tied to + /// Returns the environment this script is tied to inline ScriptingEnv *environment() { return m_env; } /// Returns the identifier for the script. inline const std::string &identifier() const { return m_name; } diff --git a/MantidPlot/src/ScriptingEnv.h b/MantidPlot/src/ScriptingEnv.h index 5912dac29b913cb4f8bb21ad4d0ff7152fc4c0a2..5907c5f4c2a504910f60a2d5659c2a8df0ce2003 100644 --- a/MantidPlot/src/ScriptingEnv.h +++ b/MantidPlot/src/ScriptingEnv.h @@ -71,7 +71,8 @@ public: virtual Script *newScript(const QString &name, QObject *context, const Script::InteractionType interact) const = 0; - //! If an exception / error occured, return a nicely formated stack backtrace. + //! If an exception / error occurred, return a nicely formatted stack + //! backtrace. virtual QString stackTraceString() { return QString::null; } /// Return a list of supported mathematical functions. These should be /// imported into the global namespace. diff --git a/MantidPlot/src/ScriptingWindow.cpp b/MantidPlot/src/ScriptingWindow.cpp index bb583969c9a89e2cfc4fc1cb2730dce33b079050..1eeebc31ba3c6ab7961cb3d29b553c93f341b1c2 100644 --- a/MantidPlot/src/ScriptingWindow.cpp +++ b/MantidPlot/src/ScriptingWindow.cpp @@ -183,7 +183,7 @@ void ScriptingWindow::showEvent(QShowEvent *event) { } /** - * Open a script directly. This is here for backwards compatability with the old + * Open a script directly. This is here for backwards compatibility with the old * ScriptWindow * class * @param filename :: The file name diff --git a/MantidPlot/src/ScriptingWindow.h b/MantidPlot/src/ScriptingWindow.h index 5b332da0085e9228f7a5197735aa17dfd1e79902..45a7a0f63c7b571b5912068269679bb89696bd69 100644 --- a/MantidPlot/src/ScriptingWindow.h +++ b/MantidPlot/src/ScriptingWindow.h @@ -25,7 +25,7 @@ class QShowEvent; class QHideEvent; /** @class ScriptingWindow - This class displays a seperate window for editing and executing scripts + This class displays a separate window for editing and executing scripts */ class ScriptingWindow : public QMainWindow { /// Qt macro diff --git a/MantidPlot/src/SelectionMoveResizer.h b/MantidPlot/src/SelectionMoveResizer.h index e8024b187be08986b96a36f300e26d2e8e04cb41..4ba757d015ad370518418410cc5fecf4511d8ccf 100644 --- a/MantidPlot/src/SelectionMoveResizer.h +++ b/MantidPlot/src/SelectionMoveResizer.h @@ -73,7 +73,7 @@ class ImageMarker; * * \section design Design Ideas * - Keep as much of the select/move/resize code as possible in one class to - *ease maintanance. + *ease maintenance. * - Use the same class for layer and marker handling to avoid duplicating *code. * Good for bugfixing and for maintaining a consistent user interface. @@ -144,16 +144,16 @@ public slots: //! Add target to the list of items to be moved/resized together. void add(QWidget *target); //! Remove target from the list of items to be moved/resized together and - // returns the number of occurences removed. + // returns the number of occurrences removed. int removeAll(LegendWidget *target); //! Remove target from the list of items to be moved/resized together and - // returns the number of occurences removed. + // returns the number of occurrences removed. int removeAll(ArrowMarker *target); //! Remove target from the list of items to be moved/resized together and - // returns the number of occurences removed. + // returns the number of occurrences removed. int removeAll(ImageMarker *target); //! Remove target from the list of items to be moved/resized together and - // returns the number of occurences removed. + // returns the number of occurrences removed. int removeAll(QWidget *target); //! Calculate #d_bounding_rect based on the bounding rectangles of all // targets. diff --git a/MantidPlot/src/Spectrogram.cpp b/MantidPlot/src/Spectrogram.cpp index 949e75e1703cd11dd1db418f9051b4d2efe7e6fe..e63b40512147256faa56d97ebfedfe9c934d5420 100644 --- a/MantidPlot/src/Spectrogram.cpp +++ b/MantidPlot/src/Spectrogram.cpp @@ -883,7 +883,7 @@ void Spectrogram::updateLabels( } } /** - for setting the lables color on contour lines + for setting the labels color on contour lines */ void Spectrogram::setLabelsColor(const QColor &c) { if (c == d_labels_color) diff --git a/MantidPlot/src/Spectrogram.h b/MantidPlot/src/Spectrogram.h index 7dcc605bb773787b7e71ea3a8fb2b8130df08e8f..a3ef8acc9f0bc8fc74282b774baca6e369ed9e49 100644 --- a/MantidPlot/src/Spectrogram.h +++ b/MantidPlot/src/Spectrogram.h @@ -84,7 +84,7 @@ public: void afterReplaceHandle( const std::string &wsName, const boost::shared_ptr<Mantid::API::Workspace> ws) override; - /// Handle an ADS clear notificiation + /// Handle an ADS clear notification void clearADSHandle() override; enum ColorMapPolicy { GrayScale, Default, Custom }; diff --git a/MantidPlot/src/Table.cpp b/MantidPlot/src/Table.cpp index a9ddc745fe7dd85ecb6d5e75c2cc3679450dbc23..b80bf6d063377df29d87833ba6c966304a088887 100644 --- a/MantidPlot/src/Table.cpp +++ b/MantidPlot/src/Table.cpp @@ -758,7 +758,7 @@ void Table::setColName(int col, const QString &text, bool enumerateRight) { if (enumerateRight) newLabel += QString::number(n); - if (col_label.contains(newLabel) > nullptr) { + if (col_label.contains(newLabel)) { auto msg = "There is already a column called : <b>" + newLabel + "</b> in table <b>" + caption + "</b>!<p>Please choose another name!"; @@ -1078,7 +1078,7 @@ void Table::clearSelection() { } if (lstReadOnly.count() > 0) { QMessageBox::warning(this, tr("MantidPlot - Error"), - tr("The folowing columns") + ":\n" + + tr("The following columns") + ":\n" + lstReadOnly.join("\n") + "\n" + tr("are read only!")); } @@ -1115,7 +1115,7 @@ void Table::clearSelection() { } if (lstReadOnly.count() > 0) { QMessageBox::warning(this, tr("MantidPlot - Error"), - tr("The folowing columns") + ":\n" + + tr("The following columns") + ":\n" + lstReadOnly.join("\n") + "\n" + tr("are read only!")); } @@ -1234,7 +1234,7 @@ void Table::pasteSelection() { } if (lstReadOnly.count() > 0) { QMessageBox::warning(this, tr("MantidPlot - Error"), - tr("The folowing columns") + ":\n" + + tr("The following columns") + ":\n" + lstReadOnly.join("\n") + "\n" + tr("are read only!")); } @@ -1289,7 +1289,7 @@ void Table::removeCol(const QStringList &list) { if (lstReadOnly.count() > 0) { QMessageBox::warning(this, tr("MantidPlot - Error"), - tr("The folowing columns") + ":\n" + + tr("The following columns") + ":\n" + lstReadOnly.join("\n") + "\n" + tr("are read only!")); } @@ -1339,7 +1339,7 @@ void Table::normalizeSelection() { if (lstReadOnly.count() > 0) { QMessageBox::warning(this, tr("MantidPlot - Error"), - tr("The folowing columns") + ":\n" + + tr("The following columns") + ":\n" + lstReadOnly.join("\n") + "\n" + tr("are read only!")); } @@ -1359,7 +1359,7 @@ void Table::normalize() { if (lstReadOnly.count() > 0) { QMessageBox::warning(this, tr("MantidPlot - Error"), - tr("The folowing columns") + ":\n" + + tr("The following columns") + ":\n" + lstReadOnly.join("\n") + "\n" + tr("are read only!")); } @@ -1936,7 +1936,7 @@ void Table::setRandomValues() { if (lstReadOnly.count() > 0) { QMessageBox::warning(this, tr("MantidPlot - Error"), - tr("The folowing columns") + ":\n" + + tr("The following columns") + ":\n" + lstReadOnly.join("\n") + "\n" + tr("are read only!")); } @@ -2091,7 +2091,7 @@ void Table::setAscValues() { if (lstReadOnly.count() > 0) { QMessageBox::warning(this, tr("MantidPlot - Error"), - tr("The folowing columns") + ":\n" + + tr("The following columns") + ":\n" + lstReadOnly.join("\n") + "\n" + tr("are read only!")); } @@ -2398,7 +2398,7 @@ bool Table::exportASCII(const QString &fname, const QString &separator, text += "C" + header[cols - 1] + eol; } } - } // finished writting labels + } // finished writing labels if (exportComments) { if (exportSelection) { diff --git a/MantidPlot/src/Table.h b/MantidPlot/src/Table.h index 48db93f77a1f59d123222d939f2d52b0a6ac4c1d..cebc085edd078646cc2edf11fb466bf44250b5f7 100644 --- a/MantidPlot/src/Table.h +++ b/MantidPlot/src/Table.h @@ -85,7 +85,7 @@ private: * * \section future Future Plans * Port to the Model/View approach used in Qt4 and get rid of the Qt3Support - * dependancy. + * dependency. * [ assigned to thzs ] */ class Table : public MdiSubWindow, public Scripted { diff --git a/MantidPlot/src/TextDialog.cpp b/MantidPlot/src/TextDialog.cpp index b82d0ae098a41ae3e7d1e649f14971b057ab2ea7..62a2da5fb0e8b64486dd526d26d28c7841d57f60 100644 --- a/MantidPlot/src/TextDialog.cpp +++ b/MantidPlot/src/TextDialog.cpp @@ -110,7 +110,7 @@ TextDialog::TextDialog(TextType type, QWidget *parent, Qt::WFlags fl) buttonDefault = nullptr; boxBackgroundTransparency = nullptr; if (textType == TextMarker) { // TODO: Sometime background features for axes - // lables should be implemented + // labels should be implemented topLayout->addWidget(new QLabel(tr("Opacity")), 3, 0); boxBackgroundTransparency = new QSpinBox(); boxBackgroundTransparency->setRange(0, 255); diff --git a/MantidPlot/src/TiledWindow.cpp b/MantidPlot/src/TiledWindow.cpp index 430290708cf3103901e920b18f1533ba97389d68..cbe16160523600e340e80e802c9cb63d6e7fd6cc 100644 --- a/MantidPlot/src/TiledWindow.cpp +++ b/MantidPlot/src/TiledWindow.cpp @@ -728,7 +728,7 @@ void TiledWindow::addToSelection(Tile *tile, bool append) { } /** - * Add a range of tiles to the selection. One of the ends of tha range + * Add a range of tiles to the selection. One of the ends of the range * is given by an already selected tile with the lowest flat index (see * calcFlatIndex). * The other end is the tile in the argument. @@ -912,7 +912,7 @@ void TiledWindow::removeSelectionTo(TiledWindow::RemoveDestination to) { foreach (Tile *tile, m_selection) { MdiSubWindow *widget = removeTile(tile); if (widget == nullptr) { - throw std::logic_error("TiledWindow: Empty tile is found in slection."); + throw std::logic_error("TiledWindow: Empty tile is found in selection."); } sendWidgetTo(widget, to); } diff --git a/MantidPlot/src/TranslateCurveTool.h b/MantidPlot/src/TranslateCurveTool.h index f96bbb9d57f21eb8f1775cb57ff9d82491cf5709..ed2ca7261cf5c84ba793e4cbab52564a53668d05 100644 --- a/MantidPlot/src/TranslateCurveTool.h +++ b/MantidPlot/src/TranslateCurveTool.h @@ -66,8 +66,8 @@ public: signals: /**\brief Emitted whenever a new message should be presented to the user. * - * You don't have to connect to this signal if you alreay specified a reciever - *during initialization. + * You don't have to connect to this signal if you already specified a + *receiver during initialization. */ void statusText(const QString &); public slots: diff --git a/MantidPlot/src/cursors.h b/MantidPlot/src/cursors.h index a2074eacf69eedc283ff0ce5be98ea25b0935c2b..4e0e7d286d925d08afd37500a2683b4c49864240 100644 --- a/MantidPlot/src/cursors.h +++ b/MantidPlot/src/cursors.h @@ -2,7 +2,7 @@ File : cursors.h Project : QtiPlot -------------------------------------------------------------------- - This file has been superceded by pixmaps.h, which holds ALL xpm + This file has been superseded by pixmaps.h, which holds ALL xpm char arrays. ***************************************************************************/ diff --git a/MantidPlot/src/importOPJ.cpp b/MantidPlot/src/importOPJ.cpp index deea55a6d38c68768e1e010a679222a2b3cf62b2..2f56cb8b28d64250587628ec1cde2b81490f9bde 100644 --- a/MantidPlot/src/importOPJ.cpp +++ b/MantidPlot/src/importOPJ.cpp @@ -253,7 +253,7 @@ bool ImportOPJ::importTables(const OPJFile &opj) { case 1: // Scientific f = 2; break; - case 2: // Engeneering + case 2: // Engineering case 3: // Decimal 1,000 f = 0; break; @@ -460,7 +460,7 @@ bool ImportOPJ::importTables(const OPJFile &opj) { case 1: // Scientific format = 'e'; break; - case 2: // Engeneering + case 2: // Engineering case 3: // Decimal 1,000 format = 'g'; break; @@ -1073,7 +1073,7 @@ bool ImportOPJ::importGraphs(const OPJFile &opj) { case 1: // Scientific format = 2; break; - case 2: // Engeneering + case 2: // Engineering case 3: // Decimal 1,000 format = 0; break; @@ -1107,7 +1107,7 @@ bool ImportOPJ::importGraphs(const OPJFile &opj) { case 1: // Scientific format = 2; break; - case 2: // Engeneering + case 2: // Engineering case 3: // Decimal 1,000 format = 0; break; @@ -1461,4 +1461,4 @@ QString ImportOPJ::parseOriginTags(const QString &str) { // TODO: bug in grid dialog // scale/minor ticks checkbox // histogram: autobin export -// if prec not setted - automac+4digits +// if prec not set - automac+4digits diff --git a/MantidPlot/src/lib/include/TextFormatButtons.h b/MantidPlot/src/lib/include/TextFormatButtons.h index 78ee1bc0032ff9e75758d994b18e4e338012c126..7cb4793d7a5cb3625882bb33026ce66a75092aeb 100644 --- a/MantidPlot/src/lib/include/TextFormatButtons.h +++ b/MantidPlot/src/lib/include/TextFormatButtons.h @@ -63,19 +63,19 @@ private: void init(Buttons btns); private slots: - //! Format seleted text to fraction + //! Format selected text to fraction void addFraction(); - //! Format seleted text to square root + //! Format selected text to square root void addSquareRoot(); - //! Format seleted text to subscript + //! Format selected text to subscript void addSubscript(); - //! Format seleted text to superscript + //! Format selected text to superscript void addSuperscript(); - //! Format seleted text to underlined + //! Format selected text to underlined void addUnderline(); - //! Format seleted text to italics + //! Format selected text to italics void addItalics(); - //! Format seleted text to bold + //! Format selected text to bold void addBold(); //! Insert curve marker into the text void addCurve(); diff --git a/MantidPlot/src/main.cpp b/MantidPlot/src/main.cpp index 2899f1a807c6eeb49d200e1fdb143ebbe9f6e956..cb2d43e4292e1e0d0645fb2bb287ee0ba9bfe288 100644 --- a/MantidPlot/src/main.cpp +++ b/MantidPlot/src/main.cpp @@ -114,7 +114,7 @@ scripts. %Note about modularization: this is mainly about internal reorganizations. Most of the current features should remain part of the main executable, but use interfaces similar or - identical to those used by plug-ins. This should ease maintanance and make + identical to those used by plug-ins. This should ease maintenance and make adding new features to the core application a no-brainer once they're available as plug-ins. Support for Python, liborigin and zlib could be real, external plug-ins since diff --git a/MantidPlot/src/origin/OPJFile.cpp b/MantidPlot/src/origin/OPJFile.cpp index ffafd630ec02eefd396e6cb4cd8037188dcb37d6..7c226b7582fe53d8bc172b418dec3f10e094603b 100644 --- a/MantidPlot/src/origin/OPJFile.cpp +++ b/MantidPlot/src/origin/OPJFile.cpp @@ -1576,8 +1576,8 @@ void OPJFile::readSpreadInfo(FILE *f, int file_size, FILE *debug) { case 0x09: // Text&Numeric - Dec1000 case 0x10: // Numeric - Scientific case 0x19: // Text&Numeric - Scientific - case 0x20: // Numeric - Engeneering - case 0x29: // Text&Numeric - Engeneering + case 0x20: // Numeric - Engineering + case 0x29: // Text&Numeric - Engineering case 0x30: // Numeric - Dec1,000 case 0x39: // Text&Numeric - Dec1,000 SPREADSHEET[spread].column[col_index].value_type = @@ -1825,8 +1825,8 @@ void OPJFile::readExcelInfo(FILE *f, int file_size, FILE *debug) { case 0x09: // Text&Numeric - Dec1000 case 0x10: // Numeric - Scientific case 0x19: // Text&Numeric - Scientific - case 0x20: // Numeric - Engeneering - case 0x29: // Text&Numeric - Engeneering + case 0x20: // Numeric - Engineering + case 0x29: // Text&Numeric - Engineering case 0x30: // Numeric - Dec1,000 case 0x39: // Text&Numeric - Dec1,000 EXCEL[iexcel].sheet[isheet].column[col_index].value_type = diff --git a/MantidPlot/src/origin/readme b/MantidPlot/src/origin/readme index 97b9efcdd3f268f70d8f293125191bc1b41c7ba9..14041f4fe7901dfbf2e9c41abc8fcb4107080ac3 100644 --- a/MantidPlot/src/origin/readme +++ b/MantidPlot/src/origin/readme @@ -48,7 +48,7 @@ Changelog : 06-07-06 * read size of matrix 06-02-06 * replaced arrays with vectors and char* with strings -06-01-06 * fixed convertion of 4.1 projects +06-01-06 * fixed conversion of 4.1 projects 05-30-06 * read matrix tables (testing) 05-29-06 * read column type if names are not matching (seems to be ok) 05-26-06 * compare only 11 chars of col label in header section diff --git a/MantidPlot/src/qti.sip b/MantidPlot/src/qti.sip index 9942964ee97ac8efc0e59ee78079bc9330abc2de..8b981b19ef60da666026f2015ad2219152f59551 100644 --- a/MantidPlot/src/qti.sip +++ b/MantidPlot/src/qti.sip @@ -32,9 +32,11 @@ %Module _qti %UnitCode - #if defined(__GNUC__) && !(defined(__INTEL_COMPILER)) - #pragma GCC system_header - #endif +#include "MantidKernel/WarningSuppressions.h" +#include "MantidPythonInterface/core/VersionCompat.h" +GNU_DIAG_OFF("cast-align") +GNU_DIAG_OFF("conversion") +GNU_DIAG_OFF("suggest-override") %End %Import QtCore/QtCoremod.sip @@ -1241,7 +1243,7 @@ public: QString stemPlot(Table *t, const QString& colName, int power = 1001, int startRow = 0, int endRow = -1); void saveRecoveryCheckpoint(); - + //---- Mantid MantidUI* mantidUI; void addUserMenu(const QString &); diff --git a/MantidPlot/src/sipqti.cpp.in b/MantidPlot/src/sipqti.cpp.in deleted file mode 100644 index 9fef642114ce1e1091723df1ff9144e1b346c20d..0000000000000000000000000000000000000000 --- a/MantidPlot/src/sipqti.cpp.in +++ /dev/null @@ -1,13 +0,0 @@ -//------------------------------------------------------------------------------ -// A wrapper for the auto-generated sipqtipart?.cpp files to disable warnings -// that we can't control. The warnings are actually suppressed in qti.sip -// with '#pragma GCC system_header' but that pragma only works if it occurs -// in a file that has been included with '#include' -//------------------------------------------------------------------------------ -// This file serves as a wrapper around <Python.h> which allows it to be -// compiled with GCC 2.95.2 under Win32 and which disables the default MSVC -// behavior so that a program may be compiled in debug mode without requiring a -// special debugging build of the Python library. -#include <boost/python/detail/wrap_python.hpp> - -#include "sip_qtipart0.cpp" diff --git a/MantidPlot/test/MantidPlotProjectSerialiseTest.py b/MantidPlot/test/MantidPlotProjectSerialiseTest.py index 1072275736fcfb3f2d61b83f7ec2b8250f821ffb..02474d59457d64795a08b01108bec7d665e77f8e 100644 --- a/MantidPlot/test/MantidPlotProjectSerialiseTest.py +++ b/MantidPlot/test/MantidPlotProjectSerialiseTest.py @@ -55,7 +55,7 @@ class MantidPlotProjectSerialiseTest(unittest.TestCase): self.assert_project_files_saved(workspace_name) contents = read_project_file(self._project_folder) - # Check corrent number of windows + # Check current number of windows self.assertEqual(int(contents['<windows>']), 1) # Check workspace list was written @@ -86,7 +86,7 @@ class MantidPlotProjectSerialiseTest(unittest.TestCase): self.assert_project_files_saved(workspace_name) contents = read_project_file(self._project_folder) - # Check corrent number of windows + # Check current number of windows self.assertEqual(int(contents['<windows>']), 1) # Check plot title is correct diff --git a/MantidPlot/test/TSVSerialiserTest.py b/MantidPlot/test/TSVSerialiserTest.py new file mode 100644 index 0000000000000000000000000000000000000000..eb101e6aa76d6db2798e8889fb0cf43488bc864b --- /dev/null +++ b/MantidPlot/test/TSVSerialiserTest.py @@ -0,0 +1,68 @@ +import mantidqtpython +import mantidplottests +from mantidplottests import * + + +class TSVSerialiserTest(unittest.TestCase): + + def genLines(self): + tmp = mantidqtpython.MantidQt.API.TSVSerialiser() + tmp.writeLine("test") + tmp.storeDouble(1.1) + tmp.storeInt(2) + + tmp.writeLine("line2") + tmp.storeString("Hello World") + tmp.storeBool(True) + + return tmp.outputLines() + + def test_lines(self): + lines = self.genLines() + load = mantidqtpython.MantidQt.API.TSVSerialiser(lines) + self.assertEqual(load.values("test")[0], "test") + self.assertEqual(load.values("test")[1], "1.1") + self.assertEqual(load.values("test")[2], "2") + + def test_numbers(self): + lines = self.genLines() + load = mantidqtpython.MantidQt.API.TSVSerialiser(lines) + load.selectLine("test") + self.assertEqual(load.readDouble(), 1.1) + self.assertEqual(load.readInt(), 2) + + def test_stringAndBool(self): + lines = self.genLines() + load = mantidqtpython.MantidQt.API.TSVSerialiser(lines) + load.selectLine("line2") + self.assertEqual(load.readString(), "Hello World") + self.assertEqual(load.readBool(), True) + + def test_sections(self): + lines = self.genLines() + tmp = mantidqtpython.MantidQt.API.TSVSerialiser() + tmp.writeSection("Section", lines) + lines = tmp.outputLines() + + tmp2 = mantidqtpython.MantidQt.API.TSVSerialiser() + tmp2.writeSection("Big", lines) + lines = tmp2.outputLines() + + # read the sections back + load = mantidqtpython.MantidQt.API.TSVSerialiser(lines) + secs = load.sections("Big") + load = mantidqtpython.MantidQt.API.TSVSerialiser(secs[0]) + + secs = load.sections("Section") + load = mantidqtpython.MantidQt.API.TSVSerialiser(secs[0]) + + load.selectLine("test") + self.assertEqual(load.readDouble(), 1.1) + self.assertEqual(load.readInt(), 2) + + load.selectLine("line2") + self.assertEqual(load.readString(), "Hello World") + self.assertEqual(load.readBool(), True) + + +mantidplottests.runTests(TSVSerialiserTest) diff --git a/MantidPlot/test/squish_test_suites/refl_gui_tests/tst_basic_operation/test.py b/MantidPlot/test/squish_test_suites/refl_gui_tests/tst_basic_operation/test.py index 1149f504992a2ba344a0c424693cd213e0aaf8da..4f7845c9c798d4a004e24f846eb6a8b6356f6666 100644 --- a/MantidPlot/test/squish_test_suites/refl_gui_tests/tst_basic_operation/test.py +++ b/MantidPlot/test/squish_test_suites/refl_gui_tests/tst_basic_operation/test.py @@ -215,7 +215,7 @@ def do_test_three_runs(test_harness): # Set the second run number tbl.item(row_index, 5).setText(str(run_number2)) - # Set the thrid run number + # Set the third run number tbl.item(row_index, 10).setText(str(run_number3)) # Give the third run a theta value tbl.item(row_index, 11).setText(str(1.0)) diff --git a/Testing/Data/DocTest/ILL/IN4/085801.nxs.md5 b/Testing/Data/DocTest/ILL/IN4/085801.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..b12bd3e9057e5cb81573ba55d507d46bd70b73c6 --- /dev/null +++ b/Testing/Data/DocTest/ILL/IN4/085801.nxs.md5 @@ -0,0 +1 @@ +c4fff5a3c2920d983bc1d3f4b609bf99 diff --git a/Testing/Data/DocTest/ILL/IN4/085802.nxs.md5 b/Testing/Data/DocTest/ILL/IN4/085802.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..84fbf54eee9c11aeba78128cfcf01d26a0485853 --- /dev/null +++ b/Testing/Data/DocTest/ILL/IN4/085802.nxs.md5 @@ -0,0 +1 @@ +2df26222ed6a99fa02f1538c6bf9b068 diff --git a/Testing/Data/DocTest/ILL/IN4/087283.nxs.md5 b/Testing/Data/DocTest/ILL/IN4/087283.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..0e87648397b9ffc1944d50eab8aac5be2f3edf20 --- /dev/null +++ b/Testing/Data/DocTest/ILL/IN4/087283.nxs.md5 @@ -0,0 +1 @@ +2fc5a0fcf31654fc08171fb9ca3e0770 diff --git a/Testing/Data/DocTest/ILL/IN4/087284.nxs.md5 b/Testing/Data/DocTest/ILL/IN4/087284.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..e4a9da65ce11b64b0a58fbc9262ecf7d62f396ef --- /dev/null +++ b/Testing/Data/DocTest/ILL/IN4/087284.nxs.md5 @@ -0,0 +1 @@ +20f422ece1e65a6a59462bf34e71feda diff --git a/Testing/Data/DocTest/ILL/IN4/087285.nxs.md5 b/Testing/Data/DocTest/ILL/IN4/087285.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..69a04f811f9ecbc298a3709fd1d482bff3fc1209 --- /dev/null +++ b/Testing/Data/DocTest/ILL/IN4/087285.nxs.md5 @@ -0,0 +1 @@ +c59570cd00a9d251d9ad8ab82d57b003 diff --git a/Testing/Data/DocTest/ILL/IN4/087286.nxs.md5 b/Testing/Data/DocTest/ILL/IN4/087286.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..d9c956eb4d4f252315c1f61501eb839a4a8ccb96 --- /dev/null +++ b/Testing/Data/DocTest/ILL/IN4/087286.nxs.md5 @@ -0,0 +1 @@ +7439652edb9ac093ba6fe36390365f46 diff --git a/Testing/Data/DocTest/ILL/IN4/087287.nxs.md5 b/Testing/Data/DocTest/ILL/IN4/087287.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..babb6d282fc2e03e08be8f116161744ec9675924 --- /dev/null +++ b/Testing/Data/DocTest/ILL/IN4/087287.nxs.md5 @@ -0,0 +1 @@ +e43ab8d36ffac0a17bb0f6283b2aada1 diff --git a/Testing/Data/DocTest/ILL/IN4/087288.nxs.md5 b/Testing/Data/DocTest/ILL/IN4/087288.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..b08e6f88d47e501caba7001103cbfe7a312791f4 --- /dev/null +++ b/Testing/Data/DocTest/ILL/IN4/087288.nxs.md5 @@ -0,0 +1 @@ +423bb15c213ea33954e82e8ef2e03c31 diff --git a/Testing/Data/DocTest/ILL/IN4/087289.nxs.md5 b/Testing/Data/DocTest/ILL/IN4/087289.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..9b89681bbf7b55c9908d3c9be4a38dc4d6cc0487 --- /dev/null +++ b/Testing/Data/DocTest/ILL/IN4/087289.nxs.md5 @@ -0,0 +1 @@ +2b26d073254019b901f2a8494e005320 diff --git a/Testing/Data/DocTest/ILL/IN4/087290.nxs.md5 b/Testing/Data/DocTest/ILL/IN4/087290.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..2c9f11c487b612e49d47b2c98b813270f956fe78 --- /dev/null +++ b/Testing/Data/DocTest/ILL/IN4/087290.nxs.md5 @@ -0,0 +1 @@ +e806765ea1574541688f30b19a2233a1 diff --git a/Testing/Data/DocTest/ILL/IN4/087294.nxs.md5 b/Testing/Data/DocTest/ILL/IN4/087294.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..3928c2286d7abe8d0f6f774b50de33ec9cd9ddbc --- /dev/null +++ b/Testing/Data/DocTest/ILL/IN4/087294.nxs.md5 @@ -0,0 +1 @@ +07e987f4bf5156c6f5c6bf49e4b706d8 diff --git a/Testing/Data/DocTest/ILL/IN4/087295.nxs.md5 b/Testing/Data/DocTest/ILL/IN4/087295.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..14d97241fc74d4cd2003bcca81c3e6ffef135604 --- /dev/null +++ b/Testing/Data/DocTest/ILL/IN4/087295.nxs.md5 @@ -0,0 +1 @@ +9ad7754872d2bea091bc1e1a1583b0f2 diff --git a/Testing/Data/DocTest/ILL/IN4/087306.nxs.md5 b/Testing/Data/DocTest/ILL/IN4/087306.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..96c6725e2c353afdca908a35341cc8e5346026ff --- /dev/null +++ b/Testing/Data/DocTest/ILL/IN4/087306.nxs.md5 @@ -0,0 +1 @@ +bba04b40e49c4041702eab9d36897c98 diff --git a/Testing/Data/DocTest/ILL/IN4/087307.nxs.md5 b/Testing/Data/DocTest/ILL/IN4/087307.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..0cbf012833309aae77ef737e236d489a689ca0e7 --- /dev/null +++ b/Testing/Data/DocTest/ILL/IN4/087307.nxs.md5 @@ -0,0 +1 @@ +b873d22cbcb106caf6022fd10d745ee6 diff --git a/Testing/Data/DocTest/ILL/IN4/087308.nxs.md5 b/Testing/Data/DocTest/ILL/IN4/087308.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..5498816b4878d2077cc8897525d39b6994ae3309 --- /dev/null +++ b/Testing/Data/DocTest/ILL/IN4/087308.nxs.md5 @@ -0,0 +1 @@ +7268b7a620ecb0c0d0a1b79b7e2b1a05 diff --git a/Testing/Data/DocTest/ILL/IN4/087309.nxs.md5 b/Testing/Data/DocTest/ILL/IN4/087309.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..e6936abd3911fab49d7955bd245abad1983f5ba6 --- /dev/null +++ b/Testing/Data/DocTest/ILL/IN4/087309.nxs.md5 @@ -0,0 +1 @@ +4382528e7a60a07a672f5d51ca4c576d diff --git a/Testing/Data/DocTest/ILL/IN4/087311.nxs.md5 b/Testing/Data/DocTest/ILL/IN4/087311.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..ed96b8c3648b6248fb416f99178843bdc429f6db --- /dev/null +++ b/Testing/Data/DocTest/ILL/IN4/087311.nxs.md5 @@ -0,0 +1 @@ +6c5dc216a97823a7023be494b6bba3d6 diff --git a/Testing/Data/DocTest/ILL/IN4/087312.nxs.md5 b/Testing/Data/DocTest/ILL/IN4/087312.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..5ec56788b40c2a64a2af4a302fa0278c68bcb8bd --- /dev/null +++ b/Testing/Data/DocTest/ILL/IN4/087312.nxs.md5 @@ -0,0 +1 @@ +e23ac03d4b78090a7de9cea19ea1e464 diff --git a/Testing/Data/DocTest/ILL/IN4/087313.nxs.md5 b/Testing/Data/DocTest/ILL/IN4/087313.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..78c6ed18b4e84200f24c8f6c5a08026f5982b4fe --- /dev/null +++ b/Testing/Data/DocTest/ILL/IN4/087313.nxs.md5 @@ -0,0 +1 @@ +e141cad2ac7fc48f31d4cc8ef71d1db0 diff --git a/Testing/Data/DocTest/ILL/IN4/087314.nxs.md5 b/Testing/Data/DocTest/ILL/IN4/087314.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..b5aa5029618e1e2e2752b799b2e96f43a093e894 --- /dev/null +++ b/Testing/Data/DocTest/ILL/IN4/087314.nxs.md5 @@ -0,0 +1 @@ +88a0b6604903c21e48a08ce97c99d940 diff --git a/Testing/Data/SystemTest/ILL/D2B/540162.nxs.md5 b/Testing/Data/SystemTest/ILL/D2B/540162.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..674e6cf36139fe0b8b21f36c2d43bc4d5c22ea34 --- /dev/null +++ b/Testing/Data/SystemTest/ILL/D2B/540162.nxs.md5 @@ -0,0 +1 @@ +dd93fd4885d81aaf0feb0299b08ff9e4 diff --git a/Testing/Data/UnitTest/74044-add.nxs.md5 b/Testing/Data/UnitTest/74044-add.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..d55250951b2e09c69b7bb9a282188a776f0ae4f0 --- /dev/null +++ b/Testing/Data/UnitTest/74044-add.nxs.md5 @@ -0,0 +1 @@ +9ff026d9d98e050694ec7097e0193432 diff --git a/Testing/PerformanceTests/Mantid.systemtests.properties.template b/Testing/PerformanceTests/Mantid.systemtests.properties.template index 9ddf844c3ce9c1179b0fbaa5a72a50c5688d08be..34b6d068615ff9d34b230113d4ca7524c923618a 100644 --- a/Testing/PerformanceTests/Mantid.systemtests.properties.template +++ b/Testing/PerformanceTests/Mantid.systemtests.properties.template @@ -1,6 +1,6 @@ # This file can be used to override any properties for this installation. # Any properties found in this file will override any that are found in the Mantid.Properties file -# As this file will not be replaced with futher installations of Mantid it is a safe place to put +# As this file will not be replaced with further installations of Mantid it is a safe place to put # properties that suit your particular installation. # Where to find mantid plugin libraries diff --git a/Testing/PerformanceTests/analysis.py b/Testing/PerformanceTests/analysis.py index 427f7c3f22fe7c87568508fc15a01d7da078cf0d..c401c79159bb04eb62a0c943ff462fb41b17aac1 100644 --- a/Testing/PerformanceTests/analysis.py +++ b/Testing/PerformanceTests/analysis.py @@ -1,5 +1,5 @@ """ Module containing functions for test -performance analyis, plotting, and saving +performance analysis, plotting, and saving to other formats (CSV, PDF) """ import testresult diff --git a/Testing/PerformanceTests/analysis_mpl.py b/Testing/PerformanceTests/analysis_mpl.py index fcc7a4e59d982dbfeb3eafc387d5086436252572..db7f8eefeb24ea9ede3be3ff78e565fa15708681 100644 --- a/Testing/PerformanceTests/analysis_mpl.py +++ b/Testing/PerformanceTests/analysis_mpl.py @@ -1,5 +1,5 @@ """ Module containing functions for test -performance analyis, plotting, and saving +performance analysis, plotting, and saving to other formats (CSV, PDF) """ from __future__ import (absolute_import, division, print_function) from six.moves import range diff --git a/Testing/PerformanceTests/make_report.py b/Testing/PerformanceTests/make_report.py index e0ce687ae68da0f6896b2e8c38cca45e6eb2dbdc..331ae44f396f07dec6b4265f0996af412ec91a09 100755 --- a/Testing/PerformanceTests/make_report.py +++ b/Testing/PerformanceTests/make_report.py @@ -48,7 +48,7 @@ if __name__ == "__main__": parser.add_argument('--path', dest='path', default="./Report", - help='Path to the ouput HTML. Default "./Report".') + help='Path to the output HTML. Default "./Report".') parser.add_argument('--x_field', dest='x_field', default="revision", diff --git a/Testing/PerformanceTests/sqlresults.py b/Testing/PerformanceTests/sqlresults.py index 2e7d5d841446fc08274bb7bb616af35c2185217c..c7539cdb57a96fb90f46ba161f82acdb47c28fac 100644 --- a/Testing/PerformanceTests/sqlresults.py +++ b/Testing/PerformanceTests/sqlresults.py @@ -260,7 +260,7 @@ class SQLResultReporter(reporters.ResultReporter): def dispatchResults(self, result): ''' - Construct the SQL commands and send them to the databse + Construct the SQL commands and send them to the database ''' dbcxn = SQLgetConnection() cur = dbcxn.cursor() diff --git a/Testing/SystemTests/lib/systemtests/stresstesting.py b/Testing/SystemTests/lib/systemtests/stresstesting.py index 20f59221078bdeadce4ecf9155a0a74e9f2ca129..990418af32b98da320c559e7f68fb125ca5fa51a 100644 --- a/Testing/SystemTests/lib/systemtests/stresstesting.py +++ b/Testing/SystemTests/lib/systemtests/stresstesting.py @@ -295,7 +295,7 @@ class MantidStressTest(unittest.TestCase): def validateWorkspaces(self, valNames=None, mismatchName=None): ''' - Performs a check that two workspaces are equal using the CheckWorkspacesMatch + Performs a check that two workspaces are equal using the CompareWorkspaces algorithm. Loads one workspace from a nexus file if appropriate. Returns true if: the workspaces match OR the validate method has not been overridden. @@ -304,7 +304,7 @@ class MantidStressTest(unittest.TestCase): if valNames is None: valNames = self.validate() - checker = AlgorithmManager.create("CheckWorkspacesMatch") + checker = AlgorithmManager.create("CompareWorkspaces") checker.setLogging(True) checker.setPropertyValue("Workspace1", valNames[0]) checker.setPropertyValue("Workspace2", valNames[1]) @@ -521,7 +521,10 @@ class ResultReporter(object): self._total_number_of_tests) console_output += '{:.<{}} ({}: {}s)'.format(result.name+" ", self._maximum_name_length+2, result.status, time_taken) - if ((self._output_on_failure and (result.status.count('fail') > 0)) or (not self._quiet)): + if ((self._output_on_failure + and (result.status != 'success') + and (result.status != 'skipped')) + or (not self._quiet)): nstars = 80 console_output += '\n' + ('*' * nstars) + '\n' print_list = ['test_name', 'filename', 'test_date', 'host_name', 'environment', @@ -614,7 +617,7 @@ class TestRunner(object): ######################################################################### -# Encapsulate the script for runnning a single test +# Encapsulate the script for running a single test ######################################################################### class TestScript(object): @@ -775,7 +778,7 @@ class TestManager(object): self._skippedTests = 0 self._failedTests = 0 self._lastTestRun = 0 - + self._tests = list_of_tests def generateMasterTestList(self): @@ -1124,7 +1127,7 @@ class MantidFrameworkConfig: # datasearch if self.__datasearch: - # turn on for 'all' facilties, 'on' is only for default facility + # turn on for 'all' facilities, 'on' is only for default facility config["datasearch.searcharchive"] = 'all' config['network.default.timeout'] = '5' @@ -1178,7 +1181,7 @@ def testThreadsLoop(testDir, saveDir, dataDir, options, tests_dict, total_number_of_tests, maximum_name_length, tests_done, process_number, lock, required_files_dict, locked_files_dict): - + reporter = XmlResultReporter(showSkipped=options.showskipped, total_number_of_tests=total_number_of_tests, maximum_name_length=maximum_name_length) @@ -1186,7 +1189,7 @@ def testThreadsLoop(testDir, saveDir, dataDir, options, tests_dict, runner = TestRunner(executable=options.executable, exec_args=options.execargs, escape_quotes=True, clean=options.clean) - # Make sure the status is 1 to begin with as it will be replaced + # Make sure the status is 1 to begin with as it will be replaced res_array[process_number + 2*options.ncores] = 1 # Begin loop: as long as there are still some test modules that @@ -1253,7 +1256,7 @@ def testThreadsLoop(testDir, saveDir, dataDir, options, tests_dict, except KeyboardInterrupt: mgr.markSkipped("KeyboardInterrupt", tests_done.value) - # Update the test results in the array shared accross cores + # Update the test results in the array shared across cores res_array[process_number] += mgr._skippedTests res_array[process_number + options.ncores] += mgr._failedTests res_array[process_number + 2*options.ncores] = min(int(reporter.reportStatus()),\ diff --git a/Testing/SystemTests/scripts/performance/analysis.py b/Testing/SystemTests/scripts/performance/analysis.py index fc641fa9fdabc6f92d4445989ed1b00a0290064d..4a183825ea9e6c8ca4bd1c2a2ebcbf9e4cfec298 100644 --- a/Testing/SystemTests/scripts/performance/analysis.py +++ b/Testing/SystemTests/scripts/performance/analysis.py @@ -1,5 +1,5 @@ """ Module containing functions for test -performance analyis, plotting, and saving +performance analysis, plotting, and saving to other formats (CSV, PDF) """ from __future__ import (absolute_import, division, print_function) from six.moves import range diff --git a/Testing/SystemTests/scripts/performance/make_report.py b/Testing/SystemTests/scripts/performance/make_report.py index 1934d84e2a19893b7f0410ccc81d30e2382dc426..59b9da15fbe6df32ef7f09525233c04cabf883a8 100755 --- a/Testing/SystemTests/scripts/performance/make_report.py +++ b/Testing/SystemTests/scripts/performance/make_report.py @@ -48,7 +48,7 @@ if __name__ == "__main__": parser.add_argument('--path', dest='path', default="./Report", - help='Path to the ouput HTML. Default "./Report".' ) + help='Path to the output HTML. Default "./Report".' ) parser.add_argument('--x_field', dest='x_field', default="revision", diff --git a/Testing/SystemTests/scripts/performance/sqlresults.py b/Testing/SystemTests/scripts/performance/sqlresults.py index 0fb6a3f1678b2551b7c2fb6614426dfb520e5b17..31e5215f2ffabeeaa08e445a32ab484a2dd5478f 100644 --- a/Testing/SystemTests/scripts/performance/sqlresults.py +++ b/Testing/SystemTests/scripts/performance/sqlresults.py @@ -260,7 +260,7 @@ class SQLResultReporter(reporters.ResultReporter): def dispatchResults(self, result): ''' - Construct the SQL commands and send them to the databse + Construct the SQL commands and send them to the database ''' dbcxn = SQLgetConnection() cur = dbcxn.cursor() diff --git a/Testing/SystemTests/tests/analysis/ILLPowderDiffDetScanReductionTest.py b/Testing/SystemTests/tests/analysis/ILLPowderDiffDetScanReductionTest.py index 9b45d4800fa445bfe3091fdb474751b5868091d6..3a39206062f97dc6f228e76cc028cf9dc0525e66 100644 --- a/Testing/SystemTests/tests/analysis/ILLPowderDiffDetScanReductionTest.py +++ b/Testing/SystemTests/tests/analysis/ILLPowderDiffDetScanReductionTest.py @@ -1,83 +1,108 @@ +from __future__ import (absolute_import, division, print_function) + import stresstesting +from mantid.simpleapi import * -from mantid.simpleapi import PowderDiffILLDetScanReduction, \ - CompareWorkspaces, ExtractSpectra, GroupWorkspaces, CropWorkspace -from mantid import config +# A dummy test class to subclass from. +# Sets up the facility and data search directories. +class _DiffReductionTest(stresstesting.MantidStressTest): -class ILLPowderDiffDetScanReductionTest(stresstesting.MantidStressTest): + _facility = '' + _directories = '' + _instrument = '' + _tolerance = 0.00001 def __init__(self): - super(ILLPowderDiffDetScanReductionTest, self).__init__() + super(_DiffReductionTest, self).__init__() self.setUp() def setUp(self): + self._facility = config['default.facility'] + self._instrument = config['default.instrument'] + self._directories = config['datasearch.directories'] config['default.facility'] = 'ILL' config['default.instrument'] = 'D2B' config.appendDataSearchSubDir('ILL/D2B/') + config.appendDataSearchSubDir('ILL/D20/') + + def tearDown(self): + config['default.facility'] = self._facility + config['default.instrument'] = self._instrument + config['datasearch.directories'] = self._directories + mtd.clear() + + def runTest(self): + pass + + +class D2B_2DTubes_ReductionTest(_DiffReductionTest): + + def runTest(self): + PowderDiffILLDetScanReduction(Run='508093:508095', Output2DTubes = True, Output1D = False, OutputWorkspace='out') + + def validate(self): + return ['out_2DTubes', 'D2B_2DTubes.nxs'] + + +class D2B_2D_ReductionTest(_DiffReductionTest): + + def runTest(self): + PowderDiffILLDetScanReduction(Run='508093:508095', Output2D = True, Output1D = False, OutputWorkspace='out') + + def validate(self): + return ['out_2D', 'D2B_2D.nxs'] + + +class D2B_1D_ReductionTest(_DiffReductionTest): + + def runTest(self): + PowderDiffILLDetScanReduction(Run='508093:508095', OutputWorkspace='out') + + def validate(self): + return ['out_1D', 'D2B_1D.nxs'] + + +class D2B_LowCounts_ReductionTest(_DiffReductionTest): + + def runTest(self): + PowderDiffILLDetScanReduction(Run='540162', OutputWorkspace='out') + + def validate(self): + return ['out_1D', 'D2B_LowCounts.nxs'] + + +class D20_NoMask_ReductionTest(_DiffReductionTest): + + def runTest(self): + PowderDiffILLDetScanReduction(Run='967076', NormaliseTo='None', CropNegativeScatteringAngles=False, + UseCalibratedData=False, InitialMask=0, OutputWorkspace='out') + + def validate(self): + return ['out_1D', 'D20_NoMask.nxs'] + + +class D20_Mask_ReductionTest(_DiffReductionTest): + + def runTest(self): + ws = LoadILLDiffraction(Filename='967076') + MaskDetectors(ws, DetectorList='0-63') + SumOverlappingTubes(InputWorkspaces=ws, OutputType='1D', OutputWorkspace='red') - def requiredFiles(self): - return ["508093.nxs, 508094.nxs, 508095.nxs"] - - def d2b_2d_tubes_test(self): - ws_2d_tubes = PowderDiffILLDetScanReduction( - Run='508093:508095', - UseCalibratedData = False, - Output2DTubes = True, - Output2D = False, - Output1D = False, - OutputWorkspace='outWS_2d_tubes') - return ws_2d_tubes - - def d2b_2d_tubes_test_using_merge(self): - ws_2d_tubes_merge = PowderDiffILLDetScanReduction( - Run='508093-508095', - Output2DTubes = True, - Output2D = False, - Output1D = False, - OutputWorkspace='outWS_2d_tubes_merge') - return ws_2d_tubes_merge - - def d2b_2d_test(self): - ws_2d = PowderDiffILLDetScanReduction( - Run = '508093:508095', - UseCalibratedData = False, - NormaliseTo = 'None', - Output2DTubes = False, - Output2D = True, - Output1D = False, - OutputWorkspace='outWS_2d') - return ws_2d - - def d2b_2d_height_test(self): - ws_2d_height = PowderDiffILLDetScanReduction( - Run = '508093:508095', - UseCalibratedData = False, - NormaliseTo = 'None', - Output2DTubes = False, - Output2D = True, - Output1D = False, - HeightRange = '-0.05,0.05', - OutputWorkspace='outWS_2d_height') - return ws_2d_height - - def d2b_1d_test(self): - ws_1d = PowderDiffILLDetScanReduction( - Run='508093:508095', - Output2DTubes = False, - Output2D = False, - Output1D = True, - OutputWorkspace='outWS_1d') - return ws_1d - - def reduce_component_test(self): - PowderDiffILLDetScanReduction(Run='508093.nxs', + def validate(self): + return ['red', 'D20_Mask.nxs'] + + +class D2B_Component_ReductionTest(_DiffReductionTest): + + def runTest(self): + PowderDiffILLDetScanReduction(Run='508093', UseCalibratedData=False, Output2DTubes=True, Output1D=False, CropNegativeScatteringAngles=False, OutputWorkspace='alltubes', InitialMask='0', FinalMask='0') - PowderDiffILLDetScanReduction(Run='508093.nxs', + PowderDiffILLDetScanReduction(Run='508093', UseCalibratedData=False, Output2DTubes=True, Output1D=False, CropNegativeScatteringAngles=False, @@ -85,28 +110,27 @@ class ILLPowderDiffDetScanReductionTest(stresstesting.MantidStressTest): InitialMask='0', FinalMask='0', ComponentsToReduce='tube_128') CropWorkspace(InputWorkspace='alltubes_2DTubes', OutputWorkspace='alltubes_tube128', XMin=147.471) - match = CompareWorkspaces(Workspace1='tube128_2DTubes', Workspace2='alltubes_tube128', Tolerance=0.000001) + match = CompareWorkspaces(Workspace1='tube128_2DTubes', Workspace2='alltubes_tube128', Tolerance=self._tolerance) self.assertTrue(match[0]) - def runTest(self): - ws_2d_tubes = self.d2b_2d_tubes_test() - ws_2d = self.d2b_2d_test() - ws_1d = self.d2b_1d_test() - self.reduce_component_test() - # Check loading and merging, and keeping files separate gives the same results - ws_2d_merge = self.d2b_2d_tubes_test_using_merge() - result_merge = CompareWorkspaces(Workspace1=ws_2d, Workspace2=ws_2d_merge) - self.assertTrue(result_merge) +class D2B_HeightRange_ReductionTest(_DiffReductionTest): - # Check height range given is a subset of a full 2D option - ws_2d_height = self.d2b_2d_height_test() - ws_2d_cropped = ExtractSpectra(InputWorkspace=ws_2d[0], StartWorkspaceIndex=43, EndWorkspaceIndex=84) - result_height = CompareWorkspaces(Workspace1=ws_2d_cropped, Workspace2=ws_2d_height) - self.assertTrue(result_height) + def runTest(self): + PowderDiffILLDetScanReduction(Run='508093:508095', Output2D=True, Output1D=False, InitialMask=0, FinalMask=0, + UseCalibratedData= False, NormaliseTo='None', OutputWorkspace='out') + PowderDiffILLDetScanReduction(Run='508093:508095', Output2D=True, Output1D=False, InitialMask=0, FinalMask=0, + UseCalibratedData= False, NormaliseTo='None', OutputWorkspace='out_height', + HeightRange='-0.05,0.05') + ExtractSpectra(InputWorkspace='out_2D', StartWorkspaceIndex=43, EndWorkspaceIndex=84, OutputWorkspace='cropped') + match = CompareWorkspaces(Workspace1='cropped', Workspace2='out_height_2D', CheckSpectraMap=False, Tolerance=self._tolerance) + self.assertTrue(match[0]) - GroupWorkspaces([ws_2d_tubes[0], ws_2d[0], ws_1d[0]], OutputWorkspace='grouped_output') - def validate(self): - self.tolerance = 0.0001 - return 'grouped_output', 'D2B_scan_test.nxs' +class D2B_Merge_ReductionTest(_DiffReductionTest): + + def runTest(self): + PowderDiffILLDetScanReduction(Run='508093:508095', OutputWorkspace='out') + PowderDiffILLDetScanReduction(Run='508093-508095', OutputWorkspace='sum') + match = CompareWorkspaces(Workspace1='out_1D', Workspace2='sum_1D') + self.assertTrue(match[0]) diff --git a/Testing/SystemTests/tests/analysis/ISISIndirectInelastic.py b/Testing/SystemTests/tests/analysis/ISISIndirectInelastic.py index eafaa00637e80403882ca22a1766d0c535119ab4..49dcbfcf06c128029fe90cab1c9e5f89ceb22af9 100644 --- a/Testing/SystemTests/tests/analysis/ISISIndirectInelastic.py +++ b/Testing/SystemTests/tests/analysis/ISISIndirectInelastic.py @@ -412,7 +412,7 @@ class ISISIndirectInelasticResolution(with_metaclass(ABCMeta, ISISIndirectInelas 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.instrument: a string giving the instrument 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 diff --git a/Testing/SystemTests/tests/analysis/ISISLoadingEventData.py b/Testing/SystemTests/tests/analysis/ISISLoadingEventData.py index 667f45a7aeae19d3e18a4e0779dbdac9df7cd420..762eecca7757e0c631fab84d24459769873b99c1 100644 --- a/Testing/SystemTests/tests/analysis/ISISLoadingEventData.py +++ b/Testing/SystemTests/tests/analysis/ISISLoadingEventData.py @@ -17,7 +17,7 @@ class ISISLoadingEventData(stresstesting.MantidStressTest): ev_ws = LoadEventNexus('LET00006278.nxs') # isis_vms_compat/SPB[2] self.assertEqual(ev_ws.sample().getGeometryFlag(), 1, - "Geometry flag mimatch. vms_compat block not read correctly") + "Geometry flag mismatch. vms_compat block not read correctly") # Isis correct the tof using loadTimeOfFlight method. self.assertDelta(ev_ws.getSpectrum(10).getTofs()[1], 1041.81, 0.01, "The ISIS event correction is incorrect (check LoadEventNexus::loadTimeOfFlight)") diff --git a/Testing/SystemTests/tests/analysis/ISISReflectometryAutoreductionTest.py b/Testing/SystemTests/tests/analysis/ISISReflectometryAutoreductionTest.py index a3feff9f2a78934c45a751cffcdd1c87c15cccbc..86accad581670c2aa08ce3dc486768e938b46d5b 100644 --- a/Testing/SystemTests/tests/analysis/ISISReflectometryAutoreductionTest.py +++ b/Testing/SystemTests/tests/analysis/ISISReflectometryAutoreductionTest.py @@ -373,7 +373,7 @@ def MakeTuples(rlist): def SortRuns(tupsort): - # sort tuples of runs into groups beloning to one sample title + # sort tuples of runs into groups belonging to one sample title row = 0 complete_list = [] for _key, group in itertools.groupby( diff --git a/Testing/SystemTests/tests/analysis/ISIS_PowderGemTest.py b/Testing/SystemTests/tests/analysis/ISIS_PowderGemTest.py index dec4d3df2bcbd34b2b0bb1fb73678c8842f6ca9d..728b68404b5aec0b0720d9df085563c5c8d3314c 100644 --- a/Testing/SystemTests/tests/analysis/ISIS_PowderGemTest.py +++ b/Testing/SystemTests/tests/analysis/ISIS_PowderGemTest.py @@ -77,7 +77,7 @@ class FocusTest(stresstesting.MantidStressTest): self.focus_results = run_focus() def validate(self): - return self.focus_results.getName(), "ISIS_Powder-GEM83605_FocusSempty.nxs" + return self.focus_results.name(), "ISIS_Powder-GEM83605_FocusSempty.nxs" def cleanup(self): try: diff --git a/Testing/SystemTests/tests/analysis/LOQTransFitWorkspace2D.py b/Testing/SystemTests/tests/analysis/LOQTransFitWorkspace2D.py index dd845beff7dde389f6b9e0a78870ad734746b781..3f416c062f18af863fbbb2f92cf3a07411c46f96 100644 --- a/Testing/SystemTests/tests/analysis/LOQTransFitWorkspace2D.py +++ b/Testing/SystemTests/tests/analysis/LOQTransFitWorkspace2D.py @@ -23,7 +23,7 @@ class LOQTransFitWorkspace2D(stresstesting.MantidStressTest): #run the reduction WavRangeReduction(3, 4, False, '_suff') - #save the results, we'll use them later, remove the other tempory workspaces + #save the results, we'll use them later, remove the other temporary 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') diff --git a/Testing/SystemTests/tests/analysis/LoadMuonNexusTest.py b/Testing/SystemTests/tests/analysis/LoadMuonNexusTest.py index 59fa324f78d0ff0c176cc02050e65b95c53e2c79..21cc03d013ebd2b3d5faa838559c6df5f4841dff 100644 --- a/Testing/SystemTests/tests/analysis/LoadMuonNexusTest.py +++ b/Testing/SystemTests/tests/analysis/LoadMuonNexusTest.py @@ -7,7 +7,7 @@ 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) + # Checked specifically because stores resolution (used to calculate FirstGoodData) # as NX_FLOAT32 opposed to NX_INT32 in other Muon files. loadResult = LoadMuonNexus(Filename = "EMU03087.nxs", OutputWorkspace = "EMU03087") diff --git a/Testing/SystemTests/tests/analysis/MagnetismReflectometryReductionTest.py b/Testing/SystemTests/tests/analysis/MagnetismReflectometryReductionTest.py index 51bd049584033b7a5663fed56b5da0aca86bba42..42c15fc1b55514d2f750a417919ba44e5ab1f13b 100644 --- a/Testing/SystemTests/tests/analysis/MagnetismReflectometryReductionTest.py +++ b/Testing/SystemTests/tests/analysis/MagnetismReflectometryReductionTest.py @@ -230,6 +230,98 @@ class MRNormaWorkspaceTest(stresstesting.MantidStressTest): return "r_24949", 'MagnetismReflectometryReductionTest.nxs' +class MRDIRPIXTest(stresstesting.MantidStressTest): + """ Test data loading and cross-section extraction """ + def runTest(self): + wsg = MRFilterCrossSections(Filename="REF_M_24949") + ws_norm = LoadEventNexus(Filename="REF_M_24945", + NXentryName="entry-Off_Off", + OutputWorkspace="r_24945") + #sc_angle = MRGetTheta(Workspace=wsg[0]) + # The logs have DANGLE0 = 4.50514 and DIRPIX = 204 + # Scatt angle = 0 + + # 131.9: 0.00989410349765 + MagnetismReflectometryReduction(InputWorkspace=wsg[0], + NormalizationWorkspace=ws_norm, + SignalPeakPixelRange=[125, 129], + SubtractSignalBackground=True, + SignalBackgroundPixelRange=[15, 105], + ApplyNormalization=True, + NormPeakPixelRange=[201, 205], + SubtractNormBackground=True, + NormBackgroundPixelRange=[10,127], + CutLowResDataAxis=True, + LowResDataAxisPixelRange=[91, 161], + CutLowResNormAxis=True, + LowResNormAxisPixelRange=[86, 174], + CutTimeAxis=True, + UseWLTimeAxis=False, + QMin=0.005, + QStep=-0.01, + TimeAxisStep=40, + TimeAxisRange=[25000, 54000], + SpecularPixel=136.9, + UseSANGLE=False, + DirectPixelOverwrite=214, + ConstantQBinning=False, + OutputWorkspace="r_24949") + + 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.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + return "r_24949", 'MagnetismReflectometryReductionTest.nxs' + + +class MRDANGLE0Test(stresstesting.MantidStressTest): + """ Test data loading and cross-section extraction """ + def runTest(self): + wsg = MRFilterCrossSections(Filename="REF_M_24949") + ws_norm = LoadEventNexus(Filename="REF_M_24945", + NXentryName="entry-Off_Off", + OutputWorkspace="r_24945") + theta = MRGetTheta(Workspace=wsg[0], UseSANGLE=False, SpecularPixel=127.9) + theta0 = MRGetTheta(Workspace=wsg[0], UseSANGLE=False, SpecularPixel=126.9) + dangle0 = wsg[0].getRun()['DANGLE0'].getStatistics().mean + dangle0 += (theta-theta0)*2.0*180./math.pi + + MagnetismReflectometryReduction(InputWorkspace=wsg[0], + NormalizationWorkspace=ws_norm, + SignalPeakPixelRange=[125, 129], + SubtractSignalBackground=True, + SignalBackgroundPixelRange=[15, 105], + ApplyNormalization=True, + NormPeakPixelRange=[201, 205], + SubtractNormBackground=True, + NormBackgroundPixelRange=[10,127], + CutLowResDataAxis=True, + LowResDataAxisPixelRange=[91, 161], + CutLowResNormAxis=True, + LowResNormAxisPixelRange=[86, 174], + CutTimeAxis=True, + UseWLTimeAxis=False, + QMin=0.005, + QStep=-0.01, + TimeAxisStep=40, + TimeAxisRange=[25000, 54000], + SpecularPixel=127.9, + UseSANGLE=False, + DAngle0Overwrite=dangle0, + ConstantQBinning=False, + OutputWorkspace="r_24949") + + 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.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + return "r_24949", 'MagnetismReflectometryReductionTest.nxs' + + class MROutputTest(stresstesting.MantidStressTest): """ Test the MR output algorithm """ def runTest(self): @@ -282,6 +374,18 @@ class MRInspectionTest(stresstesting.MantidStressTest): return mtd["r_24949"].getRun().getProperty("is_direct_beam").value == "False" +class MRInspectionOverwritesTest(stresstesting.MantidStressTest): + def runTest(self): + nxs_data = LoadEventNexus(Filename="REF_M_24949", + NXentryName="entry-Off_Off", + OutputWorkspace="r_24949") + MRInspectData(Workspace=nxs_data, DirectPixelOverwrite=208.0, DAngle0Overwrite=5.0) + + def validate(self): + # Simple test to verify that we flagged the data correctly + return mtd["r_24949"].getRun().getProperty("is_direct_beam").value == "False" + + class MRGetThetaTest(stresstesting.MantidStressTest): """ Test that the MRGetTheta algorithm produces correct results """ def runTest(self): @@ -294,5 +398,16 @@ class MRGetThetaTest(stresstesting.MantidStressTest): # In the present case, DANGLE = DANGLE0, so we expect 0 if nothing else is passed self.assertAlmostEqual(MRGetTheta(Workspace=nxs_data), 0.0) + # The logs have DANGLE0 = 4.50514 and DIRPIX = 204 + # Setting DIRPIX without setting a specular pixel shouldn't change anything + self.assertAlmostEqual(MRGetTheta(Workspace=nxs_data, DirectPixelOverwrite=145), 0.0) + + # Setting DIRPIX and the specular pixel with move things + # Move everything by 4 pixels and we should get the same answer (which depends only on the difference of the two) + self.assertAlmostEqual(MRGetTheta(Workspace=nxs_data, DirectPixelOverwrite=208, SpecularPixel=130.1), 0.61249193272/180.0*math.pi) + + dangle0 = nxs_data.getRun()['DANGLE0'].value[0] + self.assertAlmostEqual(MRGetTheta(Workspace=nxs_data, DAngle0Overwrite=dangle0+180.0), math.pi/2.0) + def validate(self): return True diff --git a/Testing/SystemTests/tests/analysis/PolrefExample.py b/Testing/SystemTests/tests/analysis/PolrefExample.py index 32c375a5afaefe2ae4bcd4d3da961b43d18e3871..1e932b4be1b8abaa064926857a0a898911059657 100644 --- a/Testing/SystemTests/tests/analysis/PolrefExample.py +++ b/Testing/SystemTests/tests/analysis/PolrefExample.py @@ -9,7 +9,7 @@ class PolrefExample(stresstesting.MantidStressTest): 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, + We may want to remove this test in the future 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. diff --git a/Testing/SystemTests/tests/analysis/ReflectometryISIS.py b/Testing/SystemTests/tests/analysis/ReflectometryISIS.py index df71e3672d0a801110cb377d9b9bb7fa8a19d275..113b6eac3e98e1e87d0b81c282e02d81af4e1de6 100644 --- a/Testing/SystemTests/tests/analysis/ReflectometryISIS.py +++ b/Testing/SystemTests/tests/analysis/ReflectometryISIS.py @@ -36,7 +36,7 @@ class ReflectometryISIS(with_metaclass(ABCMeta, stresstesting.MantidStressTest)) Io=mtd['Io'] D=mtd['D'] - # Peform the normaisation step + # Perform the normaisation step Divide(LHSWorkspace=D,RHSWorkspace=Io,OutputWorkspace='I', AllowDifferentNumberSpectra='1',ClearRHSWorkspace='1') I=mtd['I'][0] @@ -55,7 +55,7 @@ class ReflectometryISIS(with_metaclass(ABCMeta, stresstesting.MantidStressTest)) # 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) + # Check that signed two theta is being calculated correctly (not normalised) ws1 = mtd['SignedTheta_vs_Wavelength'] upperHistogram = ws1.getNumberHistograms()-1 for i in range(0, upperHistogram): diff --git a/Testing/SystemTests/tests/analysis/ReflectometryQuickCombineMulti.py b/Testing/SystemTests/tests/analysis/ReflectometryQuickCombineMulti.py index 644ca0789a99c4c41a112f29f448bb15a5d776af..4878952c6517ed660b1f9b5a2e46e17a1be9380d 100644 --- a/Testing/SystemTests/tests/analysis/ReflectometryQuickCombineMulti.py +++ b/Testing/SystemTests/tests/analysis/ReflectometryQuickCombineMulti.py @@ -48,7 +48,7 @@ class ReflectometryQuickCombineMulti(stresstesting.MantidStressTest): 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 + # Perform the stitching combineMulti.combineDataMulti([IvsQ1Binned.name(), IvsQ2Binned.name()], self.__stitchedWorkspaceName, [run1QLow, run2QLow], [run1QHigh, run2QHigh], run1QLow, run2QHigh, -step, 1) diff --git a/Testing/SystemTests/tests/analysis/SANS2DBatch.py b/Testing/SystemTests/tests/analysis/SANS2DBatch.py index 1c98adc868bf09291e944461519f31e949eab129..675e4e23fb7c95affd75830a803155905a4ba6da 100644 --- a/Testing/SystemTests/tests/analysis/SANS2DBatch.py +++ b/Testing/SystemTests/tests/analysis/SANS2DBatch.py @@ -52,11 +52,11 @@ class SANS2DNewSettingsCarriedAcrossInBatchMode(stresstesting.MantidStressTest): SANS2D() Set1D() Detector("rear-detector") - # This contains two MASKFILE commands, each resulting in a seperate call to MaskDetectors. + # This contains two MASKFILE commands, each resulting in a separate 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. + # This does 2 separate 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) @@ -78,7 +78,7 @@ class SANS2DTUBESBatchWithZeroErrorCorrection(stresstesting.MantidStressTest): SANS2DTUBES() Set1D() Detector("rear-detector") - # This contains two MASKFILE commands, each resulting in a seperate call to MaskDetectors. + # This contains two MASKFILE commands, each resulting in a separate call to MaskDetectors. MaskFile('SANS2DTube_ZerroErrorFreeTest.txt') # Saves a file which produces an output file which does not contain any zero errors diff --git a/Testing/SystemTests/tests/analysis/SANS2DBatchTest_V2.py b/Testing/SystemTests/tests/analysis/SANS2DBatchTest_V2.py index 650140bd212548ed5b9f41f42c636858e32d178d..68f85b4f4fce3d2d97736c5e9cd8724c8e817778 100644 --- a/Testing/SystemTests/tests/analysis/SANS2DBatchTest_V2.py +++ b/Testing/SystemTests/tests/analysis/SANS2DBatchTest_V2.py @@ -83,7 +83,7 @@ class SANS2DTUBESBatchWithZeroErrorCorrectionTest_V2(stresstesting.MantidStressT SANS2DTUBES() Set1D() Detector("rear-detector") - # This contains two MASKFILE commands, each resulting in a seperate call to MaskDetectors. + # This contains two MASKFILE commands, each resulting in a separate call to MaskDetectors. MaskFile('SANS2DTube_ZerroErrorFreeTest.txt') # Saves a file which produces an output file which does not contain any zero errors diff --git a/Testing/SystemTests/tests/analysis/SANS2DLOQReloadWorkspaces.py b/Testing/SystemTests/tests/analysis/SANS2DLOQReloadWorkspaces.py index 65ddfca395e2f97642496ca47c6bd42e0d64e332..a4e573769a4eff9e60a23db651aacbf698d13076 100644 --- a/Testing/SystemTests/tests/analysis/SANS2DLOQReloadWorkspaces.py +++ b/Testing/SystemTests/tests/analysis/SANS2DLOQReloadWorkspaces.py @@ -78,7 +78,7 @@ class LOQReductionShouldAcceptLoadedWorkspace(unittest.TestCase): 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. + # which, 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 @@ -97,7 +97,7 @@ class LOQReductionShouldAcceptLoadedWorkspace(unittest.TestCase): 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 + ## trying to assign it again to AssingSample must fail self.assertRaises(RuntimeError, AssignSample, my_workspace, False) diff --git a/Testing/SystemTests/tests/analysis/SANSDarkRunSubtractionTest.py b/Testing/SystemTests/tests/analysis/SANSDarkRunSubtractionTest.py index 9abe2f50c72ddbc67b4eb4634ae997b08cd9068f..c8c060d685bb2615da6eddf81bff47c75878f3ea 100644 --- a/Testing/SystemTests/tests/analysis/SANSDarkRunSubtractionTest.py +++ b/Testing/SystemTests/tests/analysis/SANSDarkRunSubtractionTest.py @@ -412,7 +412,7 @@ class DarkRunSubtractionTest(unittest.TestCase): # Execute the dark_run_subtractor - let exceptions flow to help track down errors start_spec = 9 - end_spec = 20 # Full specturm length + end_spec = 20 # Full spectrum length scatter_workspace, monitor_workspace = dark_run_subtractor.execute(scatter_workspace, monitor_workspace, start_spec, end_spec, is_input_event) diff --git a/Testing/SystemTests/tests/analysis/SEQUOIAreduction.py b/Testing/SystemTests/tests/analysis/SEQUOIAreduction.py index 618f003fc05dfa93f506970000857be8342ce171..9bf9c43aa877c542d18c0f524f1c42b328641d60 100644 --- a/Testing/SystemTests/tests/analysis/SEQUOIAreduction.py +++ b/Testing/SystemTests/tests/analysis/SEQUOIAreduction.py @@ -169,7 +169,7 @@ class DirectInelaticSNSTest(stresstesting.MantidStressTest): 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 + anglemin=0. #minimum angle anglemax=70. #maximum angle anglestep=1. #angle step - this can be fine tuned for pixel arc over detectors diff --git a/Testing/SystemTests/tests/analysis/SXDAnalysis.py b/Testing/SystemTests/tests/analysis/SXDAnalysis.py index c44058a458df6ec4159eab516e1476633e0ca8c3..577b98689479a2c2cae67cd9b09cb6e47dc450e2 100644 --- a/Testing/SystemTests/tests/analysis/SXDAnalysis.py +++ b/Testing/SystemTests/tests/analysis/SXDAnalysis.py @@ -40,16 +40,16 @@ class SXDAnalysis(stresstesting.MantidStressTest): unitcell_angle = 90 length_tolerance = 0.1 # - angle_tolelerance = 0.25 # Actual tolernce seems is 0.17 + angle_tolerance = 0.25 # Actual tolerance 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") + self.assertDelta( latt.alpha(), unitcell_angle, angle_tolerance, "alpha angle is different from expected") + self.assertDelta( latt.beta(), unitcell_angle, angle_tolerance, "beta angle is different from expected") + self.assertDelta( latt.gamma(), unitcell_angle, angle_tolerance, "gamma angle length is different from expected") def doValidation(self): # If we reach here, no validation failed diff --git a/Testing/SystemTests/tests/analysis/SortHKLTest.py b/Testing/SystemTests/tests/analysis/SortHKLTest.py index 2360e0f09ec889e2e8294a768afc36202ca4e1ab..5cb213613ff3f460bc619d7e02da6697f5925a9e 100644 --- a/Testing/SystemTests/tests/analysis/SortHKLTest.py +++ b/Testing/SystemTests/tests/analysis/SortHKLTest.py @@ -109,7 +109,8 @@ class SortHKLTest(HKLStatisticsTestMixin, stresstesting.MantidStressTest): reference_statistics = self._load_reference_statistics(space_group) self._compare_statistics(statistics, reference_statistics) - self._check_sorted_hkls_consistency(sorted_hkls, space_group) + # No need to check since intensities do no change + #self._check_sorted_hkls_consistency(sorted_hkls, space_group) def _run_sort_hkl(self, reflections, space_group): point_group_name = self._get_point_group(space_group).getName() diff --git a/Testing/SystemTests/tests/analysis/ValidateFacilitiesFile.py b/Testing/SystemTests/tests/analysis/ValidateFacilitiesFile.py index 0164a32b2b770a20c08151151e68b43870054459..7e5756a1e25d8a0df0a38781ca4cbb877177ca4a 100644 --- a/Testing/SystemTests/tests/analysis/ValidateFacilitiesFile.py +++ b/Testing/SystemTests/tests/analysis/ValidateFacilitiesFile.py @@ -41,4 +41,4 @@ class ValidateFacilitiesFile(stresstesting.MantidStressTest): print("SUMMARY OF FAILED FILES") raise RuntimeError("Failed Validation of Facilities.xml") else: - print("Succesfully Validated Facilities.xml") + print("Successfully Validated Facilities.xml") diff --git a/Testing/SystemTests/tests/analysis/ValidateGroupingFiles.py b/Testing/SystemTests/tests/analysis/ValidateGroupingFiles.py index 6f6259b260a7e4d36c45e9b344a09fac0505a13d..58c030ce39a65edf12e3d36e090bfa046ac91d8f 100644 --- a/Testing/SystemTests/tests/analysis/ValidateGroupingFiles.py +++ b/Testing/SystemTests/tests/analysis/ValidateGroupingFiles.py @@ -61,4 +61,4 @@ class ValidateGroupingFiles(stresstesting.MantidStressTest): raise RuntimeError("Failed Validation for %d of %d files" % (len(failed), len(files))) else: - print("Succesfully Validated %d files" % len(files)) + print("Successfully Validated %d files" % len(files)) diff --git a/Testing/SystemTests/tests/analysis/ValidateInstrumentDefinitionFiles.py b/Testing/SystemTests/tests/analysis/ValidateInstrumentDefinitionFiles.py index 9875d4f4a81b9fb84ee4d02bafbfc89e93548227..07d7722aad913f1db9f354b169466ca2ed743902 100644 --- a/Testing/SystemTests/tests/analysis/ValidateInstrumentDefinitionFiles.py +++ b/Testing/SystemTests/tests/analysis/ValidateInstrumentDefinitionFiles.py @@ -96,7 +96,7 @@ class ValidateInstrumentDefinitionFiles(stresstesting.MantidStressTest): raise RuntimeError("Failed Validation for %d of %d files" % (len(failed), len(files))) else: - print("Succesfully Validated %d files" % len(files)) + print("Successfully Validated %d files" % len(files)) if __name__ == '__main__': diff --git a/Testing/SystemTests/tests/analysis/ValidateParameterFiles.py b/Testing/SystemTests/tests/analysis/ValidateParameterFiles.py index 6eb63dcfe677035cd9943abfc321c66c707b398e..fe988e3eb385c6795b6319741b0a6582f973375e 100644 --- a/Testing/SystemTests/tests/analysis/ValidateParameterFiles.py +++ b/Testing/SystemTests/tests/analysis/ValidateParameterFiles.py @@ -62,7 +62,7 @@ class ValidateParameterFiles(stresstesting.MantidStressTest): raise RuntimeError("Failed Validation for %d of %d files" % (len(failed), len(files))) else: - print("Succesfully Validated %d files" % len(files)) + print("Successfully Validated %d files" % len(files)) if __name__ == '__main__': diff --git a/Testing/SystemTests/tests/analysis/WeightedLeastSquaresTest.py b/Testing/SystemTests/tests/analysis/WeightedLeastSquaresTest.py index 0233cac36fa657a346e04f0c7f06c4483775d46f..ac7d8f1130471b8c3eaf2244e38d8e514ef8c374 100644 --- a/Testing/SystemTests/tests/analysis/WeightedLeastSquaresTest.py +++ b/Testing/SystemTests/tests/analysis/WeightedLeastSquaresTest.py @@ -153,7 +153,7 @@ class SineLikeMuonExperimentAsymmetry(unittest.TestCase): rubbish results. This happens even with 0 noise. Initial values of w approximately <=5.25 or >=6.75 will make the minimizer fail. - This is very sensitive to inital conditions. The goodness of fit is highly non-convex on w. + This is very sensitive to initial conditions. The goodness of fit is highly non-convex on w. Any local minimizer should be very sensitive to the initial guess. """ filename = 'sine_fitting_test_muon_asymmetry.txt' diff --git a/Testing/SystemTests/tests/analysis/WishAnalysis.py b/Testing/SystemTests/tests/analysis/WishAnalysis.py index ed3470de2a40d36eb75653bc53bccac98cae984e..2fd434b3d14a98097094f9613b850486e136a1d4 100644 --- a/Testing/SystemTests/tests/analysis/WishAnalysis.py +++ b/Testing/SystemTests/tests/analysis/WishAnalysis.py @@ -51,7 +51,7 @@ class WishAnalysis(stresstesting.MantidStressTest): 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 + #convert back to TOF for output to GSAS/Fullprof ConvertUnits(InputWorkspace="w16748-1foc",OutputWorkspace="w16748-1foc",Target="TOF") def validate(self): diff --git a/Testing/SystemTests/tests/analysis/WishCalibrate.py b/Testing/SystemTests/tests/analysis/WishCalibrate.py index bbafc219e0c8c19ee17a43166656ee7088787da3..044aa44aa92e970c734fabc28171b357e16a8463 100644 --- a/Testing/SystemTests/tests/analysis/WishCalibrate.py +++ b/Testing/SystemTests/tests/analysis/WishCalibrate.py @@ -112,7 +112,7 @@ class WishCalibration(stresstesting.MantidStressTest): @param peakTable: the table containing fitted peak centers @param threshold: the tolerance on the difference from the mean value - @return A list of expected peak positions and a list of indicies of tubes + @return A list of expected peak positions and a list of indices of tubes to correct """ n = len(peaksTable) @@ -150,7 +150,7 @@ class WishCalibration(stresstesting.MantidStressTest): tube are recalculated. @param ws: the workspace to get the tube geometry from - @param calibrationTable: the calibration table ouput from running calibration + @param calibrationTable: the calibration table output from running calibration @param peaksTable: the table containing the fitted peak centers from calibration @param spec: the tube spec for the instrument @param idealTube: the ideal tube for the instrument diff --git a/Testing/SystemTests/tests/analysis/WishMasking.py b/Testing/SystemTests/tests/analysis/WishMasking.py index 6b0707231e1929e5db183b1b9c29b638365ba355..ba92d1e68f44a52f16dee2f604b580c8dcee1cb6 100644 --- a/Testing/SystemTests/tests/analysis/WishMasking.py +++ b/Testing/SystemTests/tests/analysis/WishMasking.py @@ -29,9 +29,9 @@ class WishMasking(stresstesting.MantidStressTest): 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. + # 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 according to the function inputs. #pylint: disable=too-many-arguments def do_test_cal_file(self, masked_workspace, should_invert, expected_masking_identifier, expected_not_masking_identifier, masking_edge): diff --git a/Testing/SystemTests/tests/analysis/reference/D20_Mask.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/D20_Mask.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..7e33e246e8005db0b525bec8b5c59ad0aab80e27 --- /dev/null +++ b/Testing/SystemTests/tests/analysis/reference/D20_Mask.nxs.md5 @@ -0,0 +1 @@ +4c22c284f0eae57a574a318a13128b70 diff --git a/Testing/SystemTests/tests/analysis/reference/D20_NoMask.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/D20_NoMask.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..bad26a2bdb658f0f33bf043dd7bedf66951fcb54 --- /dev/null +++ b/Testing/SystemTests/tests/analysis/reference/D20_NoMask.nxs.md5 @@ -0,0 +1 @@ +1011e182c95abc0b9b3abe9248448671 diff --git a/Testing/SystemTests/tests/analysis/reference/D2B_1D.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/D2B_1D.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..bb6e47b60f3cfb144b16d921266fc07e934e7e55 --- /dev/null +++ b/Testing/SystemTests/tests/analysis/reference/D2B_1D.nxs.md5 @@ -0,0 +1 @@ +be4e087c2be3da265efb46b8eb48bf1e diff --git a/Testing/SystemTests/tests/analysis/reference/D2B_2D.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/D2B_2D.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..0b07370c0cf7149ae76e438a3273db6aa11b0036 --- /dev/null +++ b/Testing/SystemTests/tests/analysis/reference/D2B_2D.nxs.md5 @@ -0,0 +1 @@ +d033d718099fd410cca9a4661ecc2fd6 diff --git a/Testing/SystemTests/tests/analysis/reference/D2B_2DTubes.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/D2B_2DTubes.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..42acfa3b21c7eefcb9ff8e31f6d6bb5d4c22aa0f --- /dev/null +++ b/Testing/SystemTests/tests/analysis/reference/D2B_2DTubes.nxs.md5 @@ -0,0 +1 @@ +ea46276d47f89178f48bc80058b29d39 diff --git a/Testing/SystemTests/tests/analysis/reference/D2B_DetEffCorr_Ref.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/D2B_DetEffCorr_Ref.nxs.md5 index 96c3bbb70801c22a618250190e7da0909fa3b4a8..d4f899a23544572c1f609d270f5361a4c450d173 100644 --- a/Testing/SystemTests/tests/analysis/reference/D2B_DetEffCorr_Ref.nxs.md5 +++ b/Testing/SystemTests/tests/analysis/reference/D2B_DetEffCorr_Ref.nxs.md5 @@ -1 +1 @@ -62a49515a946c03c44853f5f39e41b11 +f2f18e8f946b43cd6ed3ee9891fe31be diff --git a/Testing/SystemTests/tests/analysis/reference/D2B_LowCounts.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/D2B_LowCounts.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..eae7af78ee9af1163c6da5169abac167da85ec56 --- /dev/null +++ b/Testing/SystemTests/tests/analysis/reference/D2B_LowCounts.nxs.md5 @@ -0,0 +1 @@ +36aa0c84472a689ab52ae40e80d62c93 diff --git a/Testing/SystemTests/tests/analysis/reference/ISIS_Powder-GEM83605_FocusSempty.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/ISIS_Powder-GEM83605_FocusSempty.nxs.md5 index 48a4d3630e8a29cce7b37a2bb0e0999cfa048056..d85832bc0b8c0f62c13521c97ce5252854c46103 100644 --- a/Testing/SystemTests/tests/analysis/reference/ISIS_Powder-GEM83605_FocusSempty.nxs.md5 +++ b/Testing/SystemTests/tests/analysis/reference/ISIS_Powder-GEM83605_FocusSempty.nxs.md5 @@ -1 +1 @@ -b9e223cee8e0bb74f3e23e0427fdf578 +7fd06e065b645d51c69c248303f76265 diff --git a/Testing/SystemTests/tests/analysis/reference/ISIS_Powder-PEARL00098472_splined.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/ISIS_Powder-PEARL00098472_splined.nxs.md5 index 35f9b12b9251c978c1f95686a97f13efb4d7b86b..558a0594ee5876e22d38a9e3626e2a56d94351f4 100644 --- a/Testing/SystemTests/tests/analysis/reference/ISIS_Powder-PEARL00098472_splined.nxs.md5 +++ b/Testing/SystemTests/tests/analysis/reference/ISIS_Powder-PEARL00098472_splined.nxs.md5 @@ -1 +1 @@ -c5b691abe3186593fdc58a60feda5c72 +6ccffe477944b2140ea9613c16c164d7 diff --git a/Testing/SystemTests/tests/analysis/reference/ISIS_Powder-PEARL00098507_tt70_absorb.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/ISIS_Powder-PEARL00098507_tt70_absorb.nxs.md5 index fcb1372d7ea2ca16aa565f6e00e5dd48deb25a52..f7c5f189c329c82461e6ef7505072a022daf3c06 100644 --- a/Testing/SystemTests/tests/analysis/reference/ISIS_Powder-PEARL00098507_tt70_absorb.nxs.md5 +++ b/Testing/SystemTests/tests/analysis/reference/ISIS_Powder-PEARL00098507_tt70_absorb.nxs.md5 @@ -1 +1 @@ -5a009735b8a1c198d701badc811f648a \ No newline at end of file +fa6c586545f682d0661d2c9b65281bf7 diff --git a/Testing/SystemTests/tests/analysis/reference/ISIS_Powder_PRL98472_tt70_all.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/ISIS_Powder_PRL98472_tt70_all.nxs.md5 index 677b10df0f8ff22106e6166302916c009d1f89aa..2a55e6cbd8dfad9e8fab0c2654102331ed44dd5a 100644 --- a/Testing/SystemTests/tests/analysis/reference/ISIS_Powder_PRL98472_tt70_all.nxs.md5 +++ b/Testing/SystemTests/tests/analysis/reference/ISIS_Powder_PRL98472_tt70_all.nxs.md5 @@ -1 +1 @@ -a73cc08a8ef10ec1f66616cd04e8027b \ No newline at end of file +e2d4ccd733bcb6248f6f09afc178b117 diff --git a/Testing/SystemTests/tests/analysis/reference/ISIS_Powder_PRL98472_tt70_groups.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/ISIS_Powder_PRL98472_tt70_groups.nxs.md5 index b27d9e14c533aaa4659a0bcea99494352903f0c8..4f7781fad43773fa973bd1a9a0abdb25658ba31e 100644 --- a/Testing/SystemTests/tests/analysis/reference/ISIS_Powder_PRL98472_tt70_groups.nxs.md5 +++ b/Testing/SystemTests/tests/analysis/reference/ISIS_Powder_PRL98472_tt70_groups.nxs.md5 @@ -1 +1 @@ -fb7987032d216f69f4ea75643fd6366d \ No newline at end of file +a8160d86df1324a3e753f27c91eb2f92 diff --git a/Testing/SystemTests/tests/analysis/reference/ISIS_Powder_PRL98472_tt70_mods.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/ISIS_Powder_PRL98472_tt70_mods.nxs.md5 index e09cbb101db49bd1dc66a903253a71451075dc43..8ea2aab98f70d963850d2280d9258239703cefba 100644 --- a/Testing/SystemTests/tests/analysis/reference/ISIS_Powder_PRL98472_tt70_mods.nxs.md5 +++ b/Testing/SystemTests/tests/analysis/reference/ISIS_Powder_PRL98472_tt70_mods.nxs.md5 @@ -1 +1 @@ -9340bd56dc933b8a96739574bb86f59d \ No newline at end of file +feec8df0604e5eb593b75fc47c72064c diff --git a/Testing/SystemTests/tests/analysis/reference/ISIS_Powder_PRL98472_tt70_trans.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/ISIS_Powder_PRL98472_tt70_trans.nxs.md5 index 772c5ed81651ab4cdb2fcc18ecaac2cc4aa861fb..1929007b78590f63462e284b18022c20e99e6acf 100644 --- a/Testing/SystemTests/tests/analysis/reference/ISIS_Powder_PRL98472_tt70_trans.nxs.md5 +++ b/Testing/SystemTests/tests/analysis/reference/ISIS_Powder_PRL98472_tt70_trans.nxs.md5 @@ -1 +1 @@ -8b362d581e47e8a54772488c6215d965 \ No newline at end of file +0d05ff5759b7a15a8b3623c7479399b5 diff --git a/Testing/Tools/cxxtest/TODO b/Testing/Tools/cxxtest/TODO index 7a7f926e507bdc01de0c44868500b7c491616906..8979eefaa59d21b0bd2a42153e10800cb33e1ba2 100644 --- a/Testing/Tools/cxxtest/TODO +++ b/Testing/Tools/cxxtest/TODO @@ -8,7 +8,7 @@ It is not meant to be "human readable". Write some mocks *** Distribution -Seperate packages (w/ binaries)? How would that be used? +Separate packages (w/ binaries)? How would that be used? For Windows: .lib for "Real" and "Mock" parts. For Linux: Maybe. Different compilers etc. So probably only source release with Makefiles and .ds[pw]? Or just Win32 binary. diff --git a/Testing/Tools/cxxtest/cxxtest/Gui.h b/Testing/Tools/cxxtest/cxxtest/Gui.h index 6607fb4e88706ded68dfe5e94b9b116df0a6430f..593785b107bb04eda863ba9aa264b6b8e00ab719 100644 --- a/Testing/Tools/cxxtest/cxxtest/Gui.h +++ b/Testing/Tools/cxxtest/cxxtest/Gui.h @@ -2,7 +2,7 @@ #define __CXXTEST__GUI_H // -// GuiListener is a simple base class for the differes GUIs +// GuiListener is a simple base class for the different GUIs // GuiTuiRunner<GuiT, TuiT> combines a GUI with a text-mode error formatter // @@ -20,15 +20,15 @@ namespace CxxTest { enterGui( argc, argv ); TestRunner::runAllTests( listener ); - leaveGui(); + leaveGui(); } virtual void enterGui( int & /*argc*/, char ** /*argv*/ ) {} virtual void leaveGui() {} - + // // The easy way is to implement these functions: - // + // virtual void guiEnterWorld( unsigned /*numTotalTests*/ ) {} virtual void guiEnterSuite( const char * /*suiteName*/ ) {} virtual void guiEnterTest( const char * /*suiteName*/, const char * /*testName*/ ) {} @@ -44,22 +44,22 @@ namespace CxxTest void leaveTest( const TestDescription & ) {} void leaveSuite( const SuiteDescription & ) {} void leaveWorld( const WorldDescription & ) {} - + void warning( const char * /*file*/, unsigned /*line*/, const char * /*expression*/ ) { yellowBarSafe(); } - + void failedTest( const char * /*file*/, unsigned /*line*/, const char * /*expression*/ ) { redBarSafe(); } - + void failedAssert( const char * /*file*/, unsigned /*line*/, const char * /*expression*/ ) { redBarSafe(); } - + void failedAssertEquals( const char * /*file*/, unsigned /*line*/, const char * /*xStr*/, const char * /*yStr*/, const char * /*x*/, const char * /*y*/ ) @@ -74,55 +74,55 @@ namespace CxxTest { redBarSafe(); } - + void failedAssertDelta( const char * /*file*/, unsigned /*line*/, const char * /*xStr*/, const char * /*yStr*/, const char * /*dStr*/, const char * /*x*/, const char * /*y*/, const char * /*d*/ ) { redBarSafe(); } - + void failedAssertDiffers( const char * /*file*/, unsigned /*line*/, const char * /*xStr*/, const char * /*yStr*/, const char * /*value*/ ) { redBarSafe(); } - + void failedAssertLessThan( const char * /*file*/, unsigned /*line*/, const char * /*xStr*/, const char * /*yStr*/, const char * /*x*/, const char * /*y*/ ) { redBarSafe(); } - + void failedAssertLessThanEquals( const char * /*file*/, unsigned /*line*/, const char * /*xStr*/, const char * /*yStr*/, const char * /*x*/, const char * /*y*/ ) { redBarSafe(); } - + void failedAssertPredicate( const char * /*file*/, unsigned /*line*/, const char * /*predicate*/, const char * /*xStr*/, const char * /*x*/ ) { redBarSafe(); } - + void failedAssertRelation( const char * /*file*/, unsigned /*line*/, const char * /*relation*/, const char * /*xStr*/, const char * /*yStr*/, const char * /*x*/, const char * /*y*/ ) { redBarSafe(); } - + void failedAssertThrows( const char * /*file*/, unsigned /*line*/, const char * /*expression*/, const char * /*type*/, bool /*otherThrown*/ ) { redBarSafe(); } - + void failedAssertThrowsNot( const char * /*file*/, unsigned /*line*/, const char * /*expression*/ ) { @@ -145,7 +145,7 @@ namespace CxxTest _state = RED_BAR; } } - + private: enum { GREEN_BAR, YELLOW_BAR, RED_BAR } _state; }; @@ -157,12 +157,12 @@ namespace CxxTest char **_argv; GuiT _gui; TuiT _tui; - + public: GuiTuiRunner() : _argc(0), _argv(0) {} void process_commandline( int& argc, char** argv ) - { + { _argc=&argc; _argv=argv; setFirst( _gui ); @@ -182,4 +182,3 @@ namespace CxxTest // Copyright 2008 Sandia Corporation. Under the terms of Contract // DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government // retains certain rights in this software. - diff --git a/Testing/Tools/cxxtest/cxxtest/MantidFormatter.h b/Testing/Tools/cxxtest/cxxtest/MantidFormatter.h index 4f454265dc5792519efb56b8a65044617c312967..46b6744a53a830686803ee56341b461b5a67509a 100644 --- a/Testing/Tools/cxxtest/cxxtest/MantidFormatter.h +++ b/Testing/Tools/cxxtest/cxxtest/MantidFormatter.h @@ -57,7 +57,7 @@ namespace CxxTest std::ostringstream o; o << ticksElapsed; std::string s = o.str(); - //ouput it + //output it (*_o) << "Elapsed: " << s.c_str() << " seconds"<< endl; return tracker().failedTests(); } diff --git a/Testing/Tools/cxxtest/cxxtest/XmlFormatter.h b/Testing/Tools/cxxtest/cxxtest/XmlFormatter.h index a18e6fca2b2b9d4007d1e0d90888cbf33f8179bf..866d514ee81743193aa42d15b1c15323485096e5 100644 --- a/Testing/Tools/cxxtest/cxxtest/XmlFormatter.h +++ b/Testing/Tools/cxxtest/cxxtest/XmlFormatter.h @@ -230,7 +230,7 @@ namespace CxxTest // Add the CPU fraction measurement o << "> <measurement><name>CPUFraction</name><value>" << CPUFraction_stream.str().c_str() << "</value></measurement>"; - elts = true; // force there to alway be elements, since I just wrote one + elts = true; // force there to always be elements, since I just wrote one element_t curr = elements.begin(); element_t end = elements.end(); diff --git a/Testing/Tools/cxxtest/docs/guide.texi b/Testing/Tools/cxxtest/docs/guide.texi index 49d4c9f591a904a73ad0ec2bc054d2e51a2d9b88..9b29ff1bac9f32377c01175baefa418fb77fcbe8 100644 --- a/Testing/Tools/cxxtest/docs/guide.texi +++ b/Testing/Tools/cxxtest/docs/guide.texi @@ -278,7 +278,7 @@ Success rate: 50% @end smallexample -Fixing the bug is left as an excercise to the reader. +Fixing the bug is left as an exercise to the reader. @section Graphical user interface @@ -705,7 +705,7 @@ CxxTest comes with some samples in the @file{sample/} subdirectory of the distribution. If you look in that directory, you will see three Makefiles: @file{Makefile.unix}, @file{Makefile.msvc} and @file{Makefile.bcc32} which are for Linux/Unix, MS Visual C++ and -Borland C++, repectively. These files are provided as a starting point, +Borland C++, respectively. These files are provided as a starting point, and some options may need to be tweaked in them for your system. If you are running under Windows, a good guess would be to run @@ -1436,7 +1436,7 @@ Sometimes your code needs to call functions which are not available when testing. This happens for example when you test driver code using a user-mode test runner, and you need to call kernel functions. You can use CxxTest's mock framework to provide testable implementations for the -test code, while maintaing the original functions for the real code. +test code, while maintaining the original functions for the real code. This you do with @code{CXXTEST_SUPPLY_GLOBAL} (and @code{CXXTEST_SUPPLY_VOID_GLOBAL}). For example, say you want to supply your code with the Win32 kernel function @code{IoCallDriver}: @@ -1541,7 +1541,7 @@ test listener of your fancy. @subsubsection The @code{stdio} printer If the @code{ErrorPrinter}'s usage of @code{std::cout} clashes -with your environment or is unsupported by your compiler, don't dispair! +with your environment or is unsupported by your compiler, don't despair! You may still be able to use the @code{StdioPrinter}, which does the exact same thing but uses good old @code{printf()}. @@ -1637,7 +1637,7 @@ The currently available runners are: This is the standard error printer, which formats its output to @code{std::cout}. @item --runner=ParenPrinter -Identical to @code{ErrorPrinter} except that it prints line numbers in parantheses. +Identical to @code{ErrorPrinter} except that it prints line numbers in parentheses. This is the way Visual Studio expects it. @item --runner=StdioPrinter diff --git a/Testing/Tools/cxxtest/sample/SCons/SConstruct b/Testing/Tools/cxxtest/sample/SCons/SConstruct index cb394084f7ac01740bd765730cb859c4ca1e3a23..96aed5af26c3da811eca55e3a1e5d2dd0ddf47ce 100644 --- a/Testing/Tools/cxxtest/sample/SCons/SConstruct +++ b/Testing/Tools/cxxtest/sample/SCons/SConstruct @@ -17,18 +17,18 @@ env.Append(CPPPATH=['include']) libtested = env.StaticLibrary('build/embedded_platform/tested', env.Glob('build/embedded_platform/*.c')) -# Now create a seperate build environment for the tests so we can keep any -# options that are specific to testing seperate from the 'production' build +# Now create a separate build environment for the tests so we can keep any +# options that are specific to testing separate from the 'production' build # environment. For simplicity I am just copying the production environment. # If we are cross compiling for the "real" library, then this -# environement might be using the normal compiler. +# environment might be using the normal compiler. env_test = env.Clone() # Add the CxxTestBuilder to our testing build environment. cxxtest.generate(env_test, CXXTEST_INSTALL_DIR = cxxtest_path) # If we were working with an embedded platform we may want to create a -# seperate version of our library that runs on our development box in +# separate version of our library that runs on our development box in # order to do our initial unit testing. This version may also include # any special preprocessor defines needed for testing e.g. -DTESTING env_test.BuildDir('build/dev_platform', 'src') diff --git a/Testing/Tools/cxxtest/test/GoodSuite.h b/Testing/Tools/cxxtest/test/GoodSuite.h index e9ef87904d085dd358551d40777eeb5a33e42639..f34c65743770344bd0148cb7900f8d75817f753e 100644 --- a/Testing/Tools/cxxtest/test/GoodSuite.h +++ b/Testing/Tools/cxxtest/test/GoodSuite.h @@ -105,7 +105,7 @@ public: void testThrowsNothingMessage() { - TSM_ASSERT_THROWS_NOTHING( "Empty functions dosn't throw", throwNothing() ); + TSM_ASSERT_THROWS_NOTHING( "Empty functions doesn't throw", throwNothing() ); } void throwNothing() diff --git a/Testing/Tools/cxxtest/www/cn-project-pages/snippets/HtmlSnippet1.html b/Testing/Tools/cxxtest/www/cn-project-pages/snippets/HtmlSnippet1.html index b0e944055688602f8ce5d1fbde7b9a525e9faa89..7bd8f7702ffb6bcc9a6cbe1bb2b2b7a66d085a5d 100644 --- a/Testing/Tools/cxxtest/www/cn-project-pages/snippets/HtmlSnippet1.html +++ b/Testing/Tools/cxxtest/www/cn-project-pages/snippets/HtmlSnippet1.html @@ -15,12 +15,10 @@ <li>Doesn't require the user to manually register tests and test suites </ul> -<p>This makes it extremely portable and usable. +<p>This makes it extremely portable and usable. <p> Currently CxxTest is about to get a major update. The stable version (3.10.1) is available in the documents and files section. <p> For more information you may visit our <a href="http://cxxtest.com">wiki</a>. -If you are interested in helping this project you can start by <a href="http://cxxtest.tigris.org/source/browse/cxxtest/">browsing the code</a> and looking at the currently <a href="http://cxxtest.tigris.org/issues/buglist.cgi?issue_status=UNCONFIRMED&issue_status=NEW&issue_status=STARTED&issue_status=REOPENED">open issues</a>. - - \ No newline at end of file +If you are interested in helping this project you can start by <a href="http://cxxtest.tigris.org/source/browse/cxxtest/">browsing the code</a> and looking at the currently <a href="http://cxxtest.tigris.org/issues/buglist.cgi?issue_status=UNCONFIRMED&issue_status=NEW&issue_status=STARTED&issue_status=REOPENED">open issues</a>. diff --git a/Testing/Tools/generatetestmain.py b/Testing/Tools/generatetestmain.py index 6cfa2b0a0ab63ababa5b13a1b8cf361c53c4aea2..c615fa9a4655f6cdee64f7179c4f95bdc7f03aa6 100755 --- a/Testing/Tools/generatetestmain.py +++ b/Testing/Tools/generatetestmain.py @@ -80,7 +80,7 @@ if __name__ == "__main__": if len(args) <= 0: parser.error("Must specify an output file") if len(args) > 1: - parser.error("Can only produce a single ouput file") + parser.error("Can only produce a single output file") filename = args[0] if not filename.endswith(".cpp"): parser.error("Filename '%s' must end with '.cpp'" % filename) diff --git a/buildconfig/CMake/CppCheck_Suppressions.txt b/buildconfig/CMake/CppCheck_Suppressions.txt index d5e4c558b585e527c61ca98280cf2947b990ae66..5aca6a75e20d520f0c57f42d01092e0ff61077e5 100644 --- a/buildconfig/CMake/CppCheck_Suppressions.txt +++ b/buildconfig/CMake/CppCheck_Suppressions.txt @@ -5,7 +5,7 @@ // memsetClassFloat:/Users/builder/Jenkins/workspace/cppcheck-1.72/Framework/DataHandling/src/LoadRaw/isisraw.h -// suppress in all files - BE CAREFULL not to leave trailing spaces after the rule id. or empty lines +// suppress in all files - BE CAREFUL not to leave trailing spaces after the rule id. or empty lines // For a library this is not a problem per se // unusedFunction // cppcheck has problems handling the number of pre-processor definitions used in the DLL_EXPORTs diff --git a/buildconfig/CMake/DarwinSetup.cmake b/buildconfig/CMake/DarwinSetup.cmake index 093cc4fb0b9acbadbe2cf13aab4c0863fcd8784d..4906de643c4915b444dee907c8f637bf69f2efcd 100644 --- a/buildconfig/CMake/DarwinSetup.cmake +++ b/buildconfig/CMake/DarwinSetup.cmake @@ -93,7 +93,7 @@ if ( NOT TARGET mantidpython ) set ( PARAVIEW_PYTHON_PATHS "" ) endif () - configure_file ( ${CMAKE_MODULE_PATH}/Packaging/osx/mantidpython.in ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mantidpython_osx_install @ONLY ) + configure_file ( ${CMAKE_MODULE_PATH}/Packaging/osx/mantidpython.in ${CMAKE_BINARY_DIR}/mantidpython_osx_install @ONLY ) endif () diff --git a/buildconfig/CMake/FindCxxTest.cmake b/buildconfig/CMake/FindCxxTest.cmake index ad1d4dd2311ccaab711b50dcfbce65b8d0e84adb..27a63e368dcf78f342d72d897425637361471215 100644 --- a/buildconfig/CMake/FindCxxTest.cmake +++ b/buildconfig/CMake/FindCxxTest.cmake @@ -32,6 +32,9 @@ # The variable TESTHELPER_SRCS can be used to pass in extra (non-test) source files # that should be included in the test executable. # +# The variable CXXTEST_EXTRA_HEADER_INCLUDE can be used to pass an additional header +# to the --include optional of the cxxtestgen command. +# # The variable CXXTEST_OUTPUT_DIR can be used to specify the directory for the # generated files. The default is CMAKE_CURRENT_BINARY_DIR. # @@ -113,11 +116,16 @@ macro(CXXTEST_ADD_TEST _cxxtest_testname) endif() # determine the cpp filename set(_cxxtest_real_outfname ${_cxxtest_output_dir}/${_cxxtest_testname}_runner.cpp) + # add additional include if requested + if(CXXTEST_EXTRA_HEADER_INCLUDE) + set(_cxxtest_include --include ${CXXTEST_EXTRA_HEADER_INCLUDE}) + endif() + add_custom_command( OUTPUT ${_cxxtest_real_outfname} DEPENDS ${PATH_FILES} COMMAND ${PYTHON_EXECUTABLE} ${CXXTEST_TESTGEN_EXECUTABLE} --root - --xunit-printer --world ${_cxxtest_testname} -o ${_cxxtest_real_outfname} + --xunit-printer --world ${_cxxtest_testname} ${_cxxtest_include} -o ${_cxxtest_real_outfname} ) set_source_files_properties(${_cxxtest_real_outfname} PROPERTIES GENERATED true) diff --git a/buildconfig/CMake/FindLibRDKafka.cmake b/buildconfig/CMake/FindLibRDKafka.cmake index b4ecc516fbfa01a27d71215e63136da23b69f91d..615e9d2d6e888679f504e79d6ca940d136962ae4 100644 --- a/buildconfig/CMake/FindLibRDKafka.cmake +++ b/buildconfig/CMake/FindLibRDKafka.cmake @@ -37,7 +37,7 @@ macro(HEXCHAR2DEC VAR VAL) elseif(${VAL} MATCHES "[fF]") SET(${VAR} 15) else() - MESSAGE(FATAL_ERROR "Invalid format for hexidecimal character") + MESSAGE(FATAL_ERROR "Invalid format for hexadecimal character") endif() endmacro(HEXCHAR2DEC) diff --git a/buildconfig/CMake/FindOpenCL.cmake b/buildconfig/CMake/FindOpenCL.cmake index b8d7908c791c021519c0de68471f8154ce5ff1c0..85f02de90c2d89d708e63d4f42d3faa861e750c7 100644 --- a/buildconfig/CMake/FindOpenCL.cmake +++ b/buildconfig/CMake/FindOpenCL.cmake @@ -1,6 +1,6 @@ # - Try to find OpenCL # This module tries to find an OpenCL implementation on your system. It supports -# AMD / ATI, Apple and NVIDIA implementations, but shoudl work, too. +# AMD / ATI, Apple and NVIDIA implementations, but should work, too. # # Once done this will define # OPENCL_FOUND - system has OpenCL diff --git a/buildconfig/CMake/FindPoco.cmake b/buildconfig/CMake/FindPoco.cmake index ee63f6bd96ec1ff342a8c5b16bf02898e92f40d0..8b94035e77ebe06f90e980003effe27b769b5b0c 100644 --- a/buildconfig/CMake/FindPoco.cmake +++ b/buildconfig/CMake/FindPoco.cmake @@ -65,7 +65,7 @@ if( POCO_INCLUDE_DIR ) set ( POCO_VERSION "${POCO_VERSION_MAJOR}.${POCO_VERSION_MINOR}.${POCO_VERSION_PATCH}" ) endif() -# Also set a shared libarary version number. This is different to the main version number +# Also set a shared library version number. This is different to the main version number # and can form part of the package name on some Linux systems if( POCO_LIB_FOUNDATION ) set ( POCO_SOLIB_VERSION "" ) diff --git a/buildconfig/CMake/FindPyQt4.cmake b/buildconfig/CMake/FindPyQt4.cmake index 60c5d713a10a47a816408a706bb56982b2640cb9..3702ad6b5ad0a46344c1e9471901b020a1a70203 100644 --- a/buildconfig/CMake/FindPyQt4.cmake +++ b/buildconfig/CMake/FindPyQt4.cmake @@ -6,7 +6,7 @@ # Find the installed version of PyQt4. FindPyQt4 should only be called after # Python has been found. # -# This file defines the following variables, which can also be overriden by +# This file defines the following variables, which can also be overridden by # users: # # PYQT4_VERSION - The version of PyQt4 found expressed as a 6 digit hex number diff --git a/buildconfig/CMake/FindPyQt5.cmake b/buildconfig/CMake/FindPyQt5.cmake index 7e186d928699f6d250b510ff7ba5bb0231369159..0ac1930aed3cc5dd3b65f9a964be228c6a8a6e0a 100644 --- a/buildconfig/CMake/FindPyQt5.cmake +++ b/buildconfig/CMake/FindPyQt5.cmake @@ -6,7 +6,7 @@ # Find the installed version of PyQt5. FindPyQt5 should only be called after # Python has been found. # -# This file defines the following variables, which can also be overriden by +# This file defines the following variables, which can also be overridden by # users: # # PYQT5_VERSION - The version of PyQt5 found expressed as a 6 digit hex number diff --git a/buildconfig/CMake/FindPyUnitTest.cmake b/buildconfig/CMake/FindPyUnitTest.cmake index 0fd144eed16c3eb7898efc1a02c2721df3a86fb2..df9ad62931979d5f26a48b9e7840c96b936998aa 100644 --- a/buildconfig/CMake/FindPyUnitTest.cmake +++ b/buildconfig/CMake/FindPyUnitTest.cmake @@ -25,7 +25,7 @@ function ( PYUNITTEST_ADD_TEST _test_src_dir _testname_prefix ) # Environment if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") set ( _python_path ${PYTHON_XMLRUNNER_DIR};${_test_src_dir};$ENV{PYTHONPATH} ) - # cmake list separator and Windows environment seprator are the same so escape the cmake one + # cmake list separator and Windows environment separator are the same so escape the cmake one string ( REPLACE ";" "\\;" _python_path "${_python_path}" ) else() set ( _python_path ${PYTHON_XMLRUNNER_DIR}:${_test_src_dir}:$ENV{PYTHONPATH} ) diff --git a/buildconfig/CMake/FindSIP.cmake b/buildconfig/CMake/FindSIP.cmake index 997e4c06140b19cb126775f51d0d838ebc786ecc..2676f1559394d567d25e1663c83a7957151e6feb 100644 --- a/buildconfig/CMake/FindSIP.cmake +++ b/buildconfig/CMake/FindSIP.cmake @@ -9,7 +9,7 @@ # This file defines the following variables: # # SIP_VERSION - The version of SIP found expressed as a 6 digit hex number -# suitable for comparision as a string. +# suitable for comparison as a string. # # SIP_VERSION_STR - The version of SIP found as a human readable string. # diff --git a/buildconfig/CMake/FindTBB.cmake b/buildconfig/CMake/FindTBB.cmake index bf558b0fb9ccad8f1515c238ebefafe837b0bd55..99a7208ac65fe2eff615fa78b052c07f9fca0af5 100644 --- a/buildconfig/CMake/FindTBB.cmake +++ b/buildconfig/CMake/FindTBB.cmake @@ -160,7 +160,7 @@ endif () # will never adequately match the user's setup, so there is no feasible way # to detect the "best" version to use. The user will have to manually # select the right files. (Chances are the distributions are shipping their -# custom version of tbb, anyway, so the problem is probably nonexistant.) +# custom version of tbb, anyway, so the problem is probably nonexistent.) if (WIN32 AND MSVC) set(COMPILER_PREFIX "vc7.1") if (MSVC_VERSION EQUAL 1400) diff --git a/buildconfig/CMake/NSIS.template.in b/buildconfig/CMake/NSIS.template.in index 0d5065180d4c44a0e517c63f3efacb18b10cbdd6..66b73f1e04d2de030cf12b3120347f72d89ed10d 100644 --- a/buildconfig/CMake/NSIS.template.in +++ b/buildconfig/CMake/NSIS.template.in @@ -885,7 +885,7 @@ Section "Uninstall" @CPACK_NSIS_DELETE_ICONS@ @CPACK_NSIS_DELETE_ICONS_EXTRA@ - ;Delete empty start menu parent diretories + ;Delete empty start menu parent directories StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP" startMenuDeleteLoop: @@ -904,7 +904,7 @@ Section "Uninstall" Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk" @CPACK_NSIS_DELETE_ICONS_EXTRA@ - ;Delete empty start menu parent diretories + ;Delete empty start menu parent directories StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP" secondStartMenuDeleteLoop: diff --git a/buildconfig/CMake/PyQtFindImpl.cmake b/buildconfig/CMake/PyQtFindImpl.cmake index a84987b7e9ce582f568cd8dd2811b00f938a1f00..7b55edc0e583276093d49aec0cb3c7f59d0ecd25 100644 --- a/buildconfig/CMake/PyQtFindImpl.cmake +++ b/buildconfig/CMake/PyQtFindImpl.cmake @@ -45,7 +45,7 @@ function (find_pyqt major_version) "FindPyQt.py config gave:\n${_pyqt_config}") endif() else () - message (FATAL_ERROR "Error encountered while determing PyQt confguration:\n${_pyqt_config_err}") + message (FATAL_ERROR "Error encountered while determining PyQt confguration:\n${_pyqt_config_err}") endif() find_package_handle_standard_args( PyQt${major_version} diff --git a/buildconfig/CMake/PythonPackageTargetFunctions.cmake b/buildconfig/CMake/PythonPackageTargetFunctions.cmake index afcc9daed46436c60aec95292fcc6fc9ac41d0d0..82d11975cfd547a44f25daf5e9e88396fec62b6c 100644 --- a/buildconfig/CMake/PythonPackageTargetFunctions.cmake +++ b/buildconfig/CMake/PythonPackageTargetFunctions.cmake @@ -62,7 +62,7 @@ CustomInstallLib = patch_setuptools_command('install_lib') if ( ${PACKAGE_WORKBENCH} ) # setuptools by default wants to build into a directory called 'build' relative the to the working directory. We have overridden # commands in setup.py.in to force the build directory to take place out of source. The install directory is specified here and then - # --install-scripts=bin --install-lib=lib removes any of the plaform/distribution specific install directories so we can have a flat + # --install-scripts=bin --install-lib=lib removes any of the platform/distribution specific install directories so we can have a flat # structure install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} ${_setup_py} install -O1 --single-version-externally-managed --root=${_setup_py_build_root}/install --install-scripts=bin --install-lib=lib WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})") # register the "installed" components with cmake so it will carry them over diff --git a/buildconfig/CMake/QtTargetFunctions.cmake b/buildconfig/CMake/QtTargetFunctions.cmake index 01772f4b161f53eb6ef84cacfea6075cc3e8dbdb..3aa745101a191bbc4805768fce666b79b0868fb3 100644 --- a/buildconfig/CMake/QtTargetFunctions.cmake +++ b/buildconfig/CMake/QtTargetFunctions.cmake @@ -7,7 +7,7 @@ # is created. # The global ENABLE_WORKBENCH option controls if a Qt5 target # is created. -# To limit the Qt version for a specfic library use +# To limit the Qt version for a specific library use # QT_VERSION, e.g. # # mtd_add_qt_library ( QT_VERSION 5 @@ -35,7 +35,7 @@ endfunction() # is created. # The global ENABLE_WORKBENCH option controls if a Qt5 target # is created. -# To limit the Qt version for a specfic library use +# To limit the Qt version for a specific library use # QT_VERSION, e.g. # # mtd_add_qt_executable ( QT_VERSION 5 @@ -51,7 +51,7 @@ function (mtd_add_qt_executable) mtd_add_qt_target (EXECUTABLE QT_VERSION ${_ver} ${ARGN}) endif () if (_ver EQUAL 5 AND ENABLE_WORKBENCH) - mtd_add_qt_target (EXCUTABLE QT_VERSION ${_ver} ${ARGN}) + mtd_add_qt_target (EXECUTABLE QT_VERSION ${_ver} ${ARGN}) endif () endforeach() endfunction() diff --git a/buildconfig/CMake/SetMantidSubprojects.cmake b/buildconfig/CMake/SetMantidSubprojects.cmake index e23cab042dadffb01dba0b205f551c3c1fae046d..3070d564a8223bd0d542da3843f6beafb46172f6 100644 --- a/buildconfig/CMake/SetMantidSubprojects.cmake +++ b/buildconfig/CMake/SetMantidSubprojects.cmake @@ -7,7 +7,7 @@ # # EX: Framework/Kernel # -# Thie macro the calls include_directories for each path and creates the +# This macro calls include_directories for each path and creates the # MANTID_SUBPROJECT_LIBS variable with the given subproject library names. # ################################################################################ diff --git a/buildconfig/CMake/SipQtTargetFunctions.cmake b/buildconfig/CMake/SipQtTargetFunctions.cmake index 85c049f710054a0027fdd9698a5649090d320509..377131eb5cdb92fe4f55ea7ef6090b6b683501c7 100644 --- a/buildconfig/CMake/SipQtTargetFunctions.cmake +++ b/buildconfig/CMake/SipQtTargetFunctions.cmake @@ -54,7 +54,7 @@ function ( mtd_add_sip_module ) endforeach () # Add absolute paths for header dependencies - foreach ( _header ${PARSED_HEADER_DEPENDS} ) + foreach ( _header ${PARSED_HEADER_DEPS} ) if ( IS_ABSOLUTE ${_header} ) list ( APPEND _sip_include_deps "${_header}" ) else () diff --git a/buildconfig/Jenkins/pylint-buildscript b/buildconfig/Jenkins/pylint-buildscript index 387c1cefed26adf330f121209191dd4843568711..dc1c1eed2f29168d511fbf88b8a333a03bdc2857 100755 --- a/buildconfig/Jenkins/pylint-buildscript +++ b/buildconfig/Jenkins/pylint-buildscript @@ -24,7 +24,7 @@ then # Copy "reference" results from master to keep numbers stable across builds REF_RESULTS=$WORKSPACE/master_pylint-logs.zip if [[ -f "$REF_RESULTS" ]] && [[ -d "$PYLINT_OUTPUT_DIR" ]]; then - echo "extracting refererence results from master build" + echo "extracting reference results from master build" cd $PYLINT_OUTPUT_DIR unzip $REF_RESULTS fi diff --git a/buildconfig/doxygen_to_sip.py b/buildconfig/doxygen_to_sip.py index dcecd402992bc31e70116e8db537d61a744183a2..4bffcab7e1c9e3a9bed1f8016e02a9bb0d5678b6 100755 --- a/buildconfig/doxygen_to_sip.py +++ b/buildconfig/doxygen_to_sip.py @@ -72,7 +72,7 @@ def start_python_doc_section(out, line, look_for, section_header): def doxygen_to_docstring(doxygen, method): """ Takes an array of DOXYGEN lines, and converts them to a more pleasing python docstring format - @param doxygen :: list of strings contaning the doxygen + @param doxygen :: list of strings containing the doxygen @param method :: method declaration string """ out = [] if doxygen is None: diff --git a/buildconfig/move_class.py b/buildconfig/move_class.py index 9cd56d7d2bb6af6aa6b049fd77ae73aaae6c94e7..0eea18f7d6b7b0a6a5351c89a4752fe3daf0b379 100755 --- a/buildconfig/move_class.py +++ b/buildconfig/move_class.py @@ -40,7 +40,7 @@ def move_one(subproject, classname, newproject, newclassname, oldfilename, newfi # Replace the namespace declaration text = text.replace("namespace " + subproject, "namespace " + newproject) - # Replace the conents + # Replace the contents f = open(newfilename, 'w') f.write(text) except RuntimeError as err: diff --git a/buildconfig/python_export_maker.py b/buildconfig/python_export_maker.py index dac01cc423a84716557f4b5dbd00f0ab402f2a05..e3e4634c7de7c9b5ceb625836b4ded6f29a2880d 100644 --- a/buildconfig/python_export_maker.py +++ b/buildconfig/python_export_maker.py @@ -76,7 +76,7 @@ def get_include(headerfile): includefile = matches.group(2) else: raise RuntimeError("Unable to determine include path from given header") - # Make sure the include only has forward slases + # Make sure the include only has forward slashes includefile = includefile.replace("\\", "/") return includefile def get_modulepath(frameworkdir, submodule): diff --git a/buildconfig/wrap_pyui.py b/buildconfig/wrap_pyui.py index 103b7085c8bf211dcf8c0783f18bd056bef95992..dd4e5c3585b29cd7fa6d772169b17fb13587a61c 100644 --- a/buildconfig/wrap_pyui.py +++ b/buildconfig/wrap_pyui.py @@ -9,7 +9,7 @@ import sys def lines_to_pre_append(): lines = list() - # PYLINT ingnore flags + # PYLINT ignore flags lines.append(u"#pylint: skip-file\n") return lines diff --git a/dev-docs/source/AlgorithmMPISupport.rst b/dev-docs/source/AlgorithmMPISupport.rst index 74d750cf64dea9777b7e147ad1aceec2809a8892..56b45185385a2584fa187cd30a507df7ac3f6f3c 100644 --- a/dev-docs/source/AlgorithmMPISupport.rst +++ b/dev-docs/source/AlgorithmMPISupport.rst @@ -372,7 +372,7 @@ The consequences are as follows: It should not be logged, written as output, or used for branching execution paths since it is meaningless. If the total number of spectra in a workspace is required it can be accessed via ``MatrixWorkspace::indexInfo()::globalSize()``. - User input providing indices or spectrum numbers in one way or another must be translated into local indices by ``IndexInfo``. - The most common cases are a workspace property that also accepts indices, see `IndexProperty <../concepts/IndexProperty.html>`__. + The most common cases are a workspace property that also accepts indices, see :ref:`IndexProperty <IndexProperty>`. - The distinction between local and global indices must not be exposed to the user. In particular, the 'global' prefix should be omitted, i.e., for the user interface we keep referring to 'workspace index', even though it is internally not what used to be the workspace index but rather a global index. Indices provided by a user may never be interpreted as local indices, since a local index has no fixed meaning. diff --git a/dev-docs/source/GettingStartedWithPyCharm.rst b/dev-docs/source/GettingStartedWithPyCharm.rst index e9103cd4db6f2854a9c92f91f96365e90d4d14e4..6169cefea8ec0bf1891d458682a6502e4b0a96cb 100644 --- a/dev-docs/source/GettingStartedWithPyCharm.rst +++ b/dev-docs/source/GettingStartedWithPyCharm.rst @@ -5,7 +5,7 @@ Getting Started with PyCharm PyCharm can be installed from `here <https://jetbrains.com/pycharm/download/>`_. -This tutorial assumes you are familiar with the process of building Mantid (with separate source and build directories inside a root directory), and that you have built a working version. If you are unclear about this see `here <GettingStarted.html>`__ +This tutorial assumes you are familiar with the process of building Mantid (with separate source and build directories inside a root directory), and that you have built a working version. If you are unclear about this see :ref:`here <GettingStarted>`. .. contents:: :local: diff --git a/dev-docs/source/MVPTutorial/AddButton.rst b/dev-docs/source/MVPTutorial/AddButton.rst index f4a07fbdce9ad2d2ab49b912447d29462e058e96..02859664429033359b9dac90e9ef940157a6fcdb 100644 --- a/dev-docs/source/MVPTutorial/AddButton.rst +++ b/dev-docs/source/MVPTutorial/AddButton.rst @@ -1,3 +1,5 @@ +.. _AddButton: + =============== Adding a Button =============== @@ -10,7 +12,7 @@ The View The below code creates a QWidget containing a single button. When the button is pressed it will print a message to the terminal screen. It should be noted that in practice this should be avoided and will be -discussed in `this section <ReceivingSignalFromView.html>`_. +discussed in :ref:`this section <ReceivingSignalFromView>`. First we need to import the relevant packages, this includes PyQt. @@ -36,24 +38,24 @@ Next we create a layout and add a button to it .. code-block:: python - grid = QtGui.QGridLayout() - self.button = QtGui.QPushButton('Hi', self) - self.button.setStyleSheet("background-color:lightgrey") + grid = QtGui.QGridLayout() + self.button = QtGui.QPushButton('Hi', self) + self.button.setStyleSheet("background-color:lightgrey") - # connect button to signal - self.button.clicked.connect(self.btn_click) - # add button to layout - grid.addWidget(self.button) - # set the layout for the view widget - self.setLayout(grid) + # connect button to signal + self.button.clicked.connect(self.btn_click) + # add button to layout + grid.addWidget(self.button) + # set the layout for the view widget + self.setLayout(grid) The above connect statement means that when the button is pressed, the function ``btn_click`` is called: .. code-block:: python - def btn_click(self): - print("Hello world") + def btn_click(self): + print("Hello world") The Main ######## @@ -88,9 +90,9 @@ all been saved in ``view.py``, the ``main.py`` will contain: def qapp(): if QtGui.QApplication.instance(): _app = QtGui.QApplication.instance() - else: + else: _app = QtGui.QApplication(sys.argv) - return _app + return _app app = qapp() window = demo() diff --git a/dev-docs/source/MVPTutorial/AddComboBox.rst b/dev-docs/source/MVPTutorial/AddComboBox.rst index c7162460716359aa17f9c2dfe68f7254b97e3fc9..4789f4959444b9e477b03eee8cc48b912fe72d22 100644 --- a/dev-docs/source/MVPTutorial/AddComboBox.rst +++ b/dev-docs/source/MVPTutorial/AddComboBox.rst @@ -1,3 +1,5 @@ +.. _AddComboBox: + ============== Add a ComboBox ============== diff --git a/dev-docs/source/MVPTutorial/AddLineEdit.rst b/dev-docs/source/MVPTutorial/AddLineEdit.rst index b2c4cbfb978dbacb16ca1bf1b80c9b17705f9d32..d95e920c911b4c100a69c8c6e720c94235fed504 100644 --- a/dev-docs/source/MVPTutorial/AddLineEdit.rst +++ b/dev-docs/source/MVPTutorial/AddLineEdit.rst @@ -18,6 +18,6 @@ edit (useful for tables). Care should be taken before using a line edit as it can give a user too much freedom. If you know that the input is an integer then a -`spin box <AddSpinBox.html>`_ is better. If there is a finite list of -possible options then a `combo box <AddComboBox.html>`_ would be a +:ref:`spin box <AddSpinBox>` is better. If there is a finite list of +possible options then a :ref:`combo box <AddComboBox>` would be a better choice. diff --git a/dev-docs/source/MVPTutorial/AddSpinBox.rst b/dev-docs/source/MVPTutorial/AddSpinBox.rst index 86a3abb414f4dc0d0d10f248a4c31e28368465eb..7439e693d5f29eb3810b030e221886aa895cf2fc 100644 --- a/dev-docs/source/MVPTutorial/AddSpinBox.rst +++ b/dev-docs/source/MVPTutorial/AddSpinBox.rst @@ -1,3 +1,5 @@ +.. _AddSpinBox: + ============== Add a Spin Box ============== diff --git a/dev-docs/source/MVPTutorial/CompleteGUI.rst b/dev-docs/source/MVPTutorial/CompleteGUI.rst index c3e4ae7d61667851514f40fba3d81be7ff8145da..a9239d0edfbdb2a03cb737533f024eab5406056e 100644 --- a/dev-docs/source/MVPTutorial/CompleteGUI.rst +++ b/dev-docs/source/MVPTutorial/CompleteGUI.rst @@ -41,9 +41,9 @@ Main module def qapp(): if QtGui.QApplication.instance(): _app = QtGui.QApplication.instance() - else: - _app = QtGui.QApplication(sys.argv) - return _app + else: + _app = QtGui.QApplication(sys.argv) + return _app app = qapp() window = demo() @@ -82,10 +82,10 @@ Master View self.setLayout(grid) - def getOptionView(self): + def getOptionView(self): return self.options_view - def getPlotView(self): + def getPlotView(self): return self.plot_view Master Presenter @@ -114,13 +114,13 @@ Master Presenter # connect statements self.view.getOptionView().plotSignal.connect(self.updatePlot) - # handle signals - def updatePlot(self): - # only care about the colour if the button is pressed - colour, freq,phi = self.presenter.getPlotInfo() - grid_lines = self.presenter.getGridLines() + # handle signals + def updatePlot(self): + # only care about the colour if the button is pressed + colour, freq,phi = self.presenter.getPlotInfo() + grid_lines = self.presenter.getGridLines() - self.data_model.genData(freq,phi ) + self.data_model.genData(freq,phi ) x_data = self.data_model.getXData() y_data = self.data_model.getYData() @@ -140,13 +140,13 @@ Plot Presenter def __init__(self, view): self.view = view - def plot(self, x_data, y_data, grid_lines, colour_code): + def plot(self, x_data, y_data, grid_lines, colour_code): self.view.addData(x_data, y_data, grid_lines, colour_code, "x") PlotView ######## -Unchanged from `Matplotlib and MVP <Matplotlib.html>`_. +Unchanged from :ref:`Matplotlib and MVP <Matplotlib>`. Presenter ######### @@ -160,20 +160,20 @@ Presenter def __init__(self, view, colours): self.view = view - self.view.setColours(colours) + self.view.setColours(colours) - def getPlotInfo(self): + def getPlotInfo(self): return str(self.view.getColour()), self.view.getFreq(), self.view.getPhase() - def getGridLines(self): + def getGridLines(self): return self.view.getGridLines() View #### -Unchanged from `Model Exercise Solution <ModelExerciseSolution.html>`_. +Unchanged from :ref:`Model Exercise Solution <ModelExerciseSolution>`. Model ##### -Unchanged from `Model Exercise Solution <ModelExerciseSolution.html>`_. +Unchanged from :ref:`Model Exercise Solution <ModelExerciseSolution>`. diff --git a/dev-docs/source/MVPTutorial/ExtractInfoFromView.rst b/dev-docs/source/MVPTutorial/ExtractInfoFromView.rst index eed9386f820c81fdfccccef6942af7cc7d52e47c..df1935253571a129b343d176096aba7f2e4becc8 100644 --- a/dev-docs/source/MVPTutorial/ExtractInfoFromView.rst +++ b/dev-docs/source/MVPTutorial/ExtractInfoFromView.rst @@ -19,7 +19,7 @@ be used. doSomethingSignal = QtCore.pyqtSignal() - def __init__(self, parent=None): + def __init__(self, parent=None): super(view, self).__init__(parent) self.button = QtGui.QPushButton('Hi', self) @@ -45,12 +45,12 @@ be used. # set the layout for the view widget self.setLayout(grid) - #send signals - def btn_click(self): + #send signals + def btn_click(self): print ("hellow from view") - self.doSomethingSignal.emit() + self.doSomethingSignal.emit() - def getValue(self): + def getValue(self): return float(self.value.text()) The last function ``getValue`` returns the value of the line diff --git a/dev-docs/source/MVPTutorial/Layouts.rst b/dev-docs/source/MVPTutorial/Layouts.rst index 43a1bba04cb2032638c4c7493cfe7e90c15d987e..5ee72e115d3cace477be7116f50d9e599f08040a 100644 --- a/dev-docs/source/MVPTutorial/Layouts.rst +++ b/dev-docs/source/MVPTutorial/Layouts.rst @@ -19,15 +19,15 @@ In the View we will replace the ``__init__`` with the following: def __init__(self, parent=None): super(view, self).__init__(parent) - self.button = QtGui.QPushButton('Hi', self) - self.button.setStyleSheet("background-color:lightgrey") + self.button = QtGui.QPushButton('Hi', self) + self.button.setStyleSheet("background-color:lightgrey") - # connect button to signal - self.button.clicked.connect(self.btn_click) + # connect button to signal + self.button.clicked.connect(self.btn_click) self.label = QtGui.QLabel() self.label.setText("Button") - # add widgets to layout + # add widgets to layout self.sub_layout = QtGui.QHBoxLayout() self.sub_layout.addWidget(self.label) self.sub_layout.addWidget(self.button) @@ -36,4 +36,4 @@ In the View we will replace the ``__init__`` with the following: grid.addLayout(self.sub_layout) # set the layout for the view widget - self.setLayout(grid) + self.setLayout(grid) diff --git a/dev-docs/source/MVPTutorial/Matplotlib.rst b/dev-docs/source/MVPTutorial/Matplotlib.rst index 22972a4f8a83c403fd2c561d9e9517c48ae32514..8aebb04c8335fb36b260f28fadd87f275a99091f 100644 --- a/dev-docs/source/MVPTutorial/Matplotlib.rst +++ b/dev-docs/source/MVPTutorial/Matplotlib.rst @@ -1,3 +1,5 @@ +.. _Matplotlib: + ================== Matplotlib and MVP ================== @@ -43,29 +45,29 @@ the plot and creating an empty plot (no data). def __init__(self, parent=None): super(PlotView, self).__init__(parent) - self.figure = plt.figure() - grid = QtGui.QVBoxLayout(self) - self.draw() - self.canvas = self.getWidget() - grid.addWidget(self.canvas) - self.setLayout(grid) + self.figure = plt.figure() + grid = QtGui.QVBoxLayout(self) + self.draw() + self.canvas = self.getWidget() + grid.addWidget(self.canvas) + self.setLayout(grid) - def draw(self): + def draw(self): ax = self.figure.add_subplot(111) - ax.clear() - ax.set_xlim([0.0, 10.5]) - ax.set_ylim([-1.05, 1.05]) - ax.set_xlabel("time ($s$)") - ax.set_ylabel("$f(t)$") - return ax - - def getWidget(self): + ax.clear() + ax.set_xlim([0.0, 10.5]) + ax.set_ylim([-1.05, 1.05]) + ax.set_xlabel("time ($s$)") + ax.set_ylabel("$f(t)$") + return ax + + def getWidget(self): return FigureCanvas(self.figure) - def addData(self, xvalues, yvalues, colour, marker): + def addData(self, xvalues, yvalues, colour, marker): ax = self.draw() - ax.plot(xvalues, yvalues, color=colour, marker=marker, linestyle="--") - self.canvas.draw() + ax.plot(xvalues, yvalues, color=colour, marker=marker, linestyle="--") + self.canvas.draw() The ``draw`` method creates the plot area without any data. The widget is obtained from the ``getWidget`` function. The final method adds diff --git a/dev-docs/source/MVPTutorial/Mocking.rst b/dev-docs/source/MVPTutorial/Mocking.rst index 631779fc777d6831a48419696f10ddbfc372666e..30d902219d33b74a43699d1ee9447a13bd17612c 100644 --- a/dev-docs/source/MVPTutorial/Mocking.rst +++ b/dev-docs/source/MVPTutorial/Mocking.rst @@ -36,14 +36,14 @@ The test class is then initialised: class presenterTest(unittest.TestCase): def setUp(self): - self.view = mock.create_autospec(view.view) - - # mock view - self.view.doSomethingSignal = mock.Mock() - self.view.btn_click = mock.Mock() - self.view.getValue = mock.Mock(return_value=3.14) + self.view = mock.create_autospec(view.view) + + # mock view + self.view.doSomethingSignal = mock.Mock() + self.view.btn_click = mock.Mock() + self.view.getValue = mock.Mock(return_value=3.14) - self.presenter = presenter.Presenter(self.view) + self.presenter = presenter.Presenter(self.view) ``create_autospec`` mocks the class contained within the brackets. We then need to explicitly mock the methods using ``mock.Mock``. In diff --git a/dev-docs/source/MVPTutorial/MockingExercise.rst b/dev-docs/source/MVPTutorial/MockingExercise.rst index 1770a54c068c818bde111f9bcd4c8da033d74c87..d8af6726d7a8b7cb0f9250655c22161db255f96d 100644 --- a/dev-docs/source/MVPTutorial/MockingExercise.rst +++ b/dev-docs/source/MVPTutorial/MockingExercise.rst @@ -8,4 +8,4 @@ mocked and the return values should be present only when necessary (on this occasion the values do not matter). The ``updatePlot`` function should be tested to make sure that it calls the correct methods. -See `here <MockingExerciseSolution.html>`_ for the solution. +See :ref:`here <MockingExerciseSolution>` for the solution. diff --git a/dev-docs/source/MVPTutorial/MockingExerciseSolution.rst b/dev-docs/source/MVPTutorial/MockingExerciseSolution.rst index 14f8be65e83fc8d13e15fc7b36a982a4ef1222e9..36edb80de469c222f8d44c4792be91a5e0b4c010 100644 --- a/dev-docs/source/MVPTutorial/MockingExerciseSolution.rst +++ b/dev-docs/source/MVPTutorial/MockingExerciseSolution.rst @@ -1,3 +1,5 @@ +.. _MockingExerciseSolution: + ========================= Mocking Exercise Solution ========================= @@ -20,25 +22,25 @@ Mocking Exercise Solution def setUp(self): self.view = mock.create_autospec(view.view) - # mock view - self.view.plotSignal = mock.Mock() - self.view.getColour = mock.Mock(return_value="black") - self.view.getGridLines =mock.Mock(return_value=True) - self.view.getFreq =mock.Mock(return_value=3.14) - self.view.getPhase =mock.Mock(return_value=0.56) - self.view.buttonPressed = mock.Mock() - self.view.setTableRow = mock.Mock() - self.view.addWidgetToTable = mock.Mock() - self.view.addITemToTable = mock.Mock() - - self.presenter = presenter.Presenter(self.view) + # mock view + self.view.plotSignal = mock.Mock() + self.view.getColour = mock.Mock(return_value="black") + self.view.getGridLines =mock.Mock(return_value=True) + self.view.getFreq =mock.Mock(return_value=3.14) + self.view.getPhase =mock.Mock(return_value=0.56) + self.view.buttonPressed = mock.Mock() + self.view.setTableRow = mock.Mock() + self.view.addWidgetToTable = mock.Mock() + self.view.addITemToTable = mock.Mock() + + self.presenter = presenter.Presenter(self.view) def test_updatePlot(self): self.presenter.updatePlot() - assert(self.view.getColour.call_count == 1) - assert(self.view.getGridLines.call_count == 1) - assert(self.view.getFreq.call_count == 1) - assert(self.view.getPhase.call_count == 1) + assert(self.view.getColour.call_count == 1) + assert(self.view.getGridLines.call_count == 1) + assert(self.view.getFreq.call_count == 1) + assert(self.view.getPhase.call_count == 1) if __name__ == "__main__": unittest.main() diff --git a/dev-docs/source/MVPTutorial/Model.rst b/dev-docs/source/MVPTutorial/Model.rst index ea0df87b65c0d2471587feb8503150b35b961cbf..4585143ff7706ef8f4f3959bc907e1d07bdef2fa 100644 --- a/dev-docs/source/MVPTutorial/Model.rst +++ b/dev-docs/source/MVPTutorial/Model.rst @@ -17,15 +17,15 @@ The first model generates the data for the user: def __init__(self): self.x_data = np.linspace(0.0, 10.0, 100) - self.y_data = [] - - def genData(self, freq, phi): + self.y_data = [] + + def genData(self, freq, phi): self.y_data = np.sin(freq * self.x_data + phi) - def getXData(self): - return self.x_data + def getXData(self): + return self.x_data - def getYData(self): + def getYData(self): return self.y_data The model methods can be split into three types initialisation, a diff --git a/dev-docs/source/MVPTutorial/ModelExercise.rst b/dev-docs/source/MVPTutorial/ModelExercise.rst index c3559b53d9ea1a8c77e8b0452b3bfbb2d25f18b3..bb4a390d637428329683eef4470f05c0e9d4a3f4 100644 --- a/dev-docs/source/MVPTutorial/ModelExercise.rst +++ b/dev-docs/source/MVPTutorial/ModelExercise.rst @@ -15,4 +15,4 @@ input values 3. In the initialisation of the Presenter get the allowed colours from the Model and pass them to the View -See `here <ModelExerciseSolution.html>`_ for the solution. +See :ref:`here <ModelExerciseSolution>` for the solution. diff --git a/dev-docs/source/MVPTutorial/ModelExerciseSolution.rst b/dev-docs/source/MVPTutorial/ModelExerciseSolution.rst index 835bec9e2d275f6f43ac8f0710cab937f7c0dc8c..b360252a41f99ab5142108717e96c9552e23734e 100644 --- a/dev-docs/source/MVPTutorial/ModelExerciseSolution.rst +++ b/dev-docs/source/MVPTutorial/ModelExerciseSolution.rst @@ -1,3 +1,5 @@ +.. _ModelExerciseSolution: + ======================= Model Exercise Solution ======================= diff --git a/dev-docs/source/MVPTutorial/MultipleViews.rst b/dev-docs/source/MVPTutorial/MultipleViews.rst index 115cf9916ace43097508371df0095f1808c9dee2..001f2b7ed68f09b1157e2251d5bb074cfd71b639 100644 --- a/dev-docs/source/MVPTutorial/MultipleViews.rst +++ b/dev-docs/source/MVPTutorial/MultipleViews.rst @@ -1,3 +1,5 @@ +.. _MultipleViews: + ============== Multiple Views ============== @@ -72,12 +74,12 @@ The main only needs to import the masterView: self.setCentralWidget(my_view) self.setWindowTitle("view tutorial") - def qapp(): + def qapp(): if QtGui.QApplication.instance(): _app = QtGui.QApplication.instance() - else: - _app = QtGui.QApplication(sys.argv) - return _app + else: + _app = QtGui.QApplication(sys.argv) + return _app app = qapp() window = demo() diff --git a/dev-docs/source/MVPTutorial/PresenterExercise.rst b/dev-docs/source/MVPTutorial/PresenterExercise.rst index de947f2237034a7af584a484d8a31eda8905d417..657e40b682bc189669b0191d4979dc04ab5ae471 100644 --- a/dev-docs/source/MVPTutorial/PresenterExercise.rst +++ b/dev-docs/source/MVPTutorial/PresenterExercise.rst @@ -15,4 +15,4 @@ is pressed the following should be output: The ``main`` module will also need updating to handle these changes. -See `here <PresenterExerciseSolution.html>`_ for the solution. +See :ref:`here <PresenterExerciseSolution>` for the solution. diff --git a/dev-docs/source/MVPTutorial/PresenterExerciseSolution.rst b/dev-docs/source/MVPTutorial/PresenterExerciseSolution.rst index a0cb6caedd2c6f08524f767eb5aa2c322c2aef09..8f8876197f1a0e7a6ce5229f6a24ef83b0241912 100644 --- a/dev-docs/source/MVPTutorial/PresenterExerciseSolution.rst +++ b/dev-docs/source/MVPTutorial/PresenterExerciseSolution.rst @@ -1,3 +1,5 @@ +.. _PresenterExerciseSolution: + =========================== Presenter Exercise Solution =========================== @@ -16,7 +18,7 @@ View plotSignal = QtCore.pyqtSignal() - def __init__(self, parent=None): + def __init__(self, parent=None): super(view, self).__init__(parent) grid = QtGui.QVBoxLayout(self) @@ -52,37 +54,37 @@ View self.plot.clicked.connect(self.buttonPressed) - def getColour(self): + def getColour(self): return self.colours.currentText() - def getGridLines(self): + def getGridLines(self): return self.grid_lines.checkState() == QtCore.Qt.Checked - def getFreq(self): + def getFreq(self): return float(self.freq.text()) - def getPhase(self): + def getPhase(self): return float(self.phi.text()) - def buttonPressed(self): + def buttonPressed(self): self.plotSignal.emit() - def setTableRow(self, name, row): + def setTableRow(self, name, row): text = QtGui.QTableWidgetItem(name) text.setFlags(QtCore.Qt.ItemIsEnabled) col = 0 self.table.setItem(row, col, text) - def addWidgetToTable(self, name, widget, row): + def addWidgetToTable(self, name, widget, row): self.setTableRow(name, row) col = 1 self.table.setCellWidget(row, col, widget) - - def addItemToTable(self, name, widget, row): + + def addItemToTable(self, name, widget, row): self.setTableRow(name, row) col = 1 self.table.setItem(row, col, widget) - + Presenter ######### @@ -93,18 +95,18 @@ Presenter class Presenter(object): # pass the view and model into the presenter - def __init__(self, view): + def __init__(self, view): self.view = view - self.view.plotSignal.connect(self.updatePlot) + self.view.plotSignal.connect(self.updatePlot) - # handle signals - def updatePlot(self): + # handle signals + def updatePlot(self): print("The table settings are:") - print(" colour : " + str(self.view.getColour())) - print(" Grid lines : " + str(self.view.getGridLines())) - print(" Frequency : " + str(self.view.getFreq())) - print(" Phase : " + str(self.view.getPhase())) + print(" colour : " + str(self.view.getColour())) + print(" Grid lines : " + str(self.view.getGridLines())) + print(" Frequency : " + str(self.view.getFreq())) + print(" Phase : " + str(self.view.getPhase())) Main module ########### @@ -136,12 +138,12 @@ Main module self.setCentralWidget(my_view) self.setWindowTitle("view tutorial") - def qapp(): - if QtGui.QApplication.instance(): - _app = QtGui.QApplication.instance() - else: - _app = QtGui.QApplication(sys.argv) - return _app + def qapp(): + if QtGui.QApplication.instance(): + _app = QtGui.QApplication.instance() + else: + _app = QtGui.QApplication(sys.argv) + return _app app = qapp() window = demo() diff --git a/dev-docs/source/MVPTutorial/ReceivingSignalFromView.rst b/dev-docs/source/MVPTutorial/ReceivingSignalFromView.rst index 5a6beb71c3f33e6b276219c6ac27c7f922488fa6..c4e701e28d6b40d6142bc423772805fc8f0cb2d3 100644 --- a/dev-docs/source/MVPTutorial/ReceivingSignalFromView.rst +++ b/dev-docs/source/MVPTutorial/ReceivingSignalFromView.rst @@ -1,8 +1,10 @@ +.. _ReceivingSignalFromView: + ================================ Receiving a signal from the view ================================ -In the `Add Button <AddButton.html>`_ section we had the response to a button press +In the :ref:`Add Button <AddButton>` section we had the response to a button press within the View. In practice this is not a good implementation. If the response was more complicated then it would be difficult to maintain the View as it would become extremely long. Furthermore creating the @@ -23,7 +25,7 @@ pressed. First we will start with the View: doSomethingSignal = QtCore.pyqtSignal() - def __init__(self, parent=None): + def __init__(self, parent=None): super(view, self).__init__(parent) self.button = QtGui.QPushButton('Hi', self) @@ -44,10 +46,10 @@ pressed. First we will start with the View: # set the layout for the view widget self.setLayout(grid) - #send signals - def btn_click(self): + #send signals + def btn_click(self): print ("hellow from view") - self.doSomethingSignal.emit() + self.doSomethingSignal.emit() The above code has two new additions. The first is the creation of a custom signal on line eight. It is also possible to pass objects with @@ -67,13 +69,13 @@ custom signal from the View to its own function (``handleButton``). class Presenter(object): # pass the view and model into the presenter - def __init__(self, view): + def __init__(self, view): self.view = view - self.view.doSomethingSignal.connect(self.handleButton) + self.view.doSomethingSignal.connect(self.handleButton) - # handle signals - def handleButton(self): + # handle signals + def handleButton(self): print("hello world, from the presenter") The main is now: @@ -105,12 +107,12 @@ The main is now: self.setCentralWidget(my_view) self.setWindowTitle("view tutorial") - def qapp(): + def qapp(): if QtGui.QApplication.instance(): _app = QtGui.QApplication.instance() - else: - _app = QtGui.QApplication(sys.argv) - return _app + else: + _app = QtGui.QApplication(sys.argv) + return _app app = qapp() diff --git a/dev-docs/source/MVPTutorial/ViewExercise1.rst b/dev-docs/source/MVPTutorial/ViewExercise1.rst index d2311e122f03b45fea871d6b5d3eeab735c6de31..4a26bc22c789e6d038a56b0f7f671d668c91d239 100644 --- a/dev-docs/source/MVPTutorial/ViewExercise1.rst +++ b/dev-docs/source/MVPTutorial/ViewExercise1.rst @@ -17,7 +17,7 @@ plot. The table should include options for: The previous sections are not an exhaustive list of possible widgets. -The pages `Matplotlib and MVP <Matplotlib.html>`_ and `MultipleView -<MultipleViews.html>`_ will be useful for the exercise. +The pages :ref:`Matplotlib and MVP <Matplotlib>` and :ref:`MultipleView +<MultipleViews>` will be useful for the exercise. -The solution can be found `here <ViewExercise1Solution.html>`_. +The solution can be found :ref:`here <ViewExercise1Solution>`. diff --git a/dev-docs/source/MVPTutorial/ViewExercise1Solution.rst b/dev-docs/source/MVPTutorial/ViewExercise1Solution.rst index cc17fdfcdf3fe37e224e206f2951e23ae66a822a..c963551162ff1bec73d8bc9e78db38455d4f0c9a 100644 --- a/dev-docs/source/MVPTutorial/ViewExercise1Solution.rst +++ b/dev-docs/source/MVPTutorial/ViewExercise1Solution.rst @@ -1,3 +1,5 @@ +.. _ViewExercise1Solution: + ======================== View Exercise 1 Solution ======================== @@ -30,12 +32,12 @@ main.py self.setCentralWidget(my_view) self.setWindowTitle("view tutorial") - def qapp(): + def qapp(): if QtGui.QApplication.instance(): _app = QtGui.QApplication.instance() - else: - _app = QtGui.QApplication(sys.argv) - return _app + else: + _app = QtGui.QApplication(sys.argv) + return _app app = qapp() window = demo() diff --git a/dev-docs/source/Standards/AlgorithmDocumentation.rst b/dev-docs/source/Standards/AlgorithmDocumentation.rst index dc03d48a52c5f9caaebd04855dcdf63a71e309f0..0ee81e947ed4af8748f32518ac935e15d27184d9 100644 --- a/dev-docs/source/Standards/AlgorithmDocumentation.rst +++ b/dev-docs/source/Standards/AlgorithmDocumentation.rst @@ -10,7 +10,7 @@ Algorithm Documentation Summary ======= -This page deals with the specifics of how to document an algorithm. For a more general guide to the Mantid documentation system see `Documentation Guide For Devs <DocumentationGuideForDevs.html>`__. +This page deals with the specifics of how to document an algorithm. For a more general guide to the Mantid documentation system see :ref:`Documentation Guide For Devs <DocumentationGuideForDevs>`. How to Document an Algorithm ============================ @@ -18,7 +18,7 @@ How to Document an Algorithm Algorithm documentation is stored in two places. * The code (.cpp / .h / .py) files: For strings that are needed in the GUI for tooltips etc. -* The .rst file: For all other documentation, including the algorithm description and `usage examples <AlgorithmUsageExamples.html>`__. +* The .rst file: For all other documentation, including the algorithm description and :ref:`usage examples <AlgorithmUsageExamples>`. The Code Files -------------- @@ -69,7 +69,7 @@ For example: Workflow algorithms =================== -There should be a flow chart for workflow algorithms. See `here <FlowchartCreation.html>`__ on how to make one. +There should be a flow chart for workflow algorithms. See :ref:`here <FlowchartCreation>` on how to make one. Algorithm Directives ==================== @@ -84,7 +84,7 @@ As the **Description** and **Usage** of an algorithm *cannot* be obtained automa .. summary:: - .. alias:: + .. relatedalgorithms:: .. properties:: @@ -120,13 +120,16 @@ As the **Description** and **Usage** of an algorithm *cannot* be obtained automa return "Rebins data with new X bin boundaries. For EventWorkspaces, you can very quickly rebin in-place by keeping the same output name and PreserveEvents=true."; } -``.. alias::`` - This directive obtains aliases from the required ``alias`` method in the algorithm, for example, the following method is used in Rebin: +``.. relatedalgorithms::`` + This directive obtains a list of related algorithms from the ``seeAlso`` and ``alias`` methods in the algorithm, for example, the following ``seeAlso`` is used in Rebin: .. code-block:: c++ - /// Algorithm's aliases - const std::string alias() const override { return "rebin"; } + /// Algorithm's seeAlso + const std::vector<std::string> seeAlso() const override { + return {"RebinToWorkspace", "Rebin2D", "Rebunch", + "Regroup", "RebinByPulseTimes", "RebinByTimeAtSample"}; + } ``.. properties::`` As mentioned above, it is *critical* that you include a description for the properties of your algorithm. This directive obtains all of the algorithm's properties (set inside the algorithm's ``init`` method) and outputs in a table format. @@ -147,7 +150,7 @@ It is possible to add additional categories by passing the directive arguments, .. categories:: Algorithms, Transforms, Rebin, Example -``..sourcelink ::`` +``.. sourcelink::`` This directive adds links to the algorithms source code. Description @@ -175,7 +178,7 @@ where the first part outside the angle brackets defines the link text and the pa Usage ===== -This section *must* be manually entered. The usage is a 'code' example of the algorithm in use. The `testcode` directive must be used to verify the usage code you entered works correctly. See `here <AlgorithmUsageExamples>`__ for more information on how to write usage examples. +This section *must* be manually entered. The usage is a 'code' example of the algorithm in use. The ``.. testcode::`` directive must be used to verify the usage code you entered works correctly. See :ref:`here <AlgorithmUsageExamples>` for more information on how to write usage examples. Building the Documentation ========================== diff --git a/dev-docs/source/Standards/AlgorithmUsageExamples.rst b/dev-docs/source/Standards/AlgorithmUsageExamples.rst index 3c8ee85ebc3789e7b1a5f89e2d8815f158a3a4d0..f0cdc11c59ee57fe55b07abe133f8515691958c2 100644 --- a/dev-docs/source/Standards/AlgorithmUsageExamples.rst +++ b/dev-docs/source/Standards/AlgorithmUsageExamples.rst @@ -18,7 +18,7 @@ From a user's point of view, the main purposes of usage examples are: * Understanding the algorithm * Showing hints/comments etc. that help understand Mantid Python scripting in general -The usage examples are written in `reStructuredText <http://docutils.sourceforge.net/rst.html>`__, which can be converted to HTML and the code in the usage examples can be tested. The image below demonstrates an example of converting reStructuredText to HTML. +The usage examples are written in `reStructuredText <http://docutils.sourceforge.net/rst.html>`__, which can be converted to HTML and the code in the usage examples can be tested. Guide ===== @@ -75,7 +75,7 @@ What is worth keeping in mind is: * Use comments. * Use Python ``print`` to output results, which, where possible, helps to understand the algorithm. -A Jenkins job tests that the usage examples are not broken, i.e. that they continue to provide a working demonstration against the current build. It is vital to stress that the purpose of usage testing is *not to replace unit testing* (or system testing). The purpose of usage testing (better described as demonstration examples), is to provide some happy-path examples, which, where this is possible, can assist the user understanding of the Python code. This is very different from the purposes of testing in general, see `here <UnitTestGoodPractice.html>`__. +A Jenkins job tests that the usage examples are not broken, i.e. that they continue to provide a working demonstration against the current build. It is vital to stress that the purpose of usage testing is *not to replace unit testing* (or system testing). The purpose of usage testing (better described as demonstration examples), is to provide some happy-path examples, which, where this is possible, can assist the user understanding of the Python code. This is very different from the purposes of testing in general, see :ref:`here <UnitTestGoodPractice>`. Additional benefits of usage examples: @@ -181,7 +181,7 @@ For a more simple use of CreateSampleWorkspace see example below (note if no arg When needing to load a data file -------------------------------- -Instructions to add a new data file to the repository are available `here <DataFilesForTesting.html>`__. Files from the repository will be bundled up into a .zip file, and this .zip made available for download from the Mantid download page. +Instructions to add a new data file to the repository are available :ref:`here <DataFilesForTesting>`. Files from the repository will be bundled up into a .zip file, and this .zip made available for download from the Mantid download page. If you use files you must add the line @@ -221,4 +221,4 @@ as shown in the example below. This will generate a note to the user explaining Running the Tests ================= -See `here <DocumentationGuideForDevs.html>`__ for how to run and test the usage examples locally. +See :ref:`here <DocumentationGuideForDevs>` for how to run and test the usage examples locally. diff --git a/dev-docs/source/Standards/DocumentationGuideForDevs.rst b/dev-docs/source/Standards/DocumentationGuideForDevs.rst index 81dd7ba2e2264540719ab7110866631a9a65269d..e58444b22679d6159e8ef9bd0942ea0d0d82e361 100644 --- a/dev-docs/source/Standards/DocumentationGuideForDevs.rst +++ b/dev-docs/source/Standards/DocumentationGuideForDevs.rst @@ -96,12 +96,12 @@ If you wish to place comments in the reST file that will not be rendered anywher Algorithms ---------- -The algorithm documentation has a slightly more rigid structure and is described in more detail `here <AlgorithmDocumentation.html>`__ and `here <AlgorithmUsageExamples.html>`__. +The algorithm documentation has a slightly more rigid structure and is described in more detail :ref:`here <AlgorithmDocumentation>` and :ref:`here <AlgorithmUsageExamples>`. Interfaces ---------- -For documenting custom interfaces, it is recommended that you consult `this <InterfaceDocumentation.html>`__ page, which explains how to document them, and which directives may be used in more detail. +For documenting custom interfaces, it is recommended that you consult :ref:`this <InterfaceDocumentation>` page, which explains how to document them, and which directives may be used in more detail. How to define titles, sections etc. ----------------------------------- @@ -251,6 +251,6 @@ For multi-configuration generators such as Visual Studio or XCode you will need Building the HTML Development Documentation =========================================== -The developer documentation is written as `.rst` files in the mantid source folder under ``dev-docs/``, the html files can be built using the `dev-docs-html` target. This will build all the development documentation into the mantid build folder under ``dev-docs/html/``. +The developer documentation is written as ``.rst`` files in the mantid source folder under ``dev-docs/``, the html files can be built using the `dev-docs-html` target. This will build all the development documentation into the mantid build folder under ``dev-docs/html/``. -In Visual Studio, this can be found in the "Documentation" folder in the solution explorer for the Mantid solution. Simply right click `dev-docs-html` and select build. \ No newline at end of file +In Visual Studio, this can be found in the "Documentation" folder in the solution explorer for the Mantid solution. Simply right click `dev-docs-html` and select build. diff --git a/dev-docs/source/Standards/InterfaceDocumentation.rst b/dev-docs/source/Standards/InterfaceDocumentation.rst index 1e49cbb60f01c4148f95f1665f3a1f07918d55f5..eb60abd91477df67125490b83317a9806bccf1f7 100644 --- a/dev-docs/source/Standards/InterfaceDocumentation.rst +++ b/dev-docs/source/Standards/InterfaceDocumentation.rst @@ -10,7 +10,7 @@ Interface Documentation Summary ======= -This page deals with the specifics of how to document Custom Interfaces. For a more general guide to the Mantid documentation system see `Documentation Guide For Devs <DocumentationGuideForDevs.html>`__. +This page deals with the specifics of how to document Custom Interfaces. For a more general guide to the Mantid documentation system see :ref:`Documentation Guide For Devs <DocumentationGuideForDevs>`. The ``interface`` Directive =========================== diff --git a/dev-docs/source/Testing/ErrorReporter-ProjectRecovery/ProjectRecoveryTesting.rst b/dev-docs/source/Testing/ErrorReporter-ProjectRecovery/ProjectRecoveryTesting.rst index 46c05d1dea4960fcab9002dee73af4cf2bd92a21..162fa22bb54ee9554525d9df5ec0bb2ea19b29e1 100644 --- a/dev-docs/source/Testing/ErrorReporter-ProjectRecovery/ProjectRecoveryTesting.rst +++ b/dev-docs/source/Testing/ErrorReporter-ProjectRecovery/ProjectRecoveryTesting.rst @@ -12,7 +12,7 @@ Project Recovery test *Preparation* - Before running these tests, set project recovery to run every 2 seconds. The instructions for this - are on the `Project Recovery concepts page <http://docs.mantidproject.org/nightly/concepts/ProjectRecovery.html>`_. + are on the `Project Recovery concepts page <http://docs.mantidproject.org/nightly/concepts/ProjectRecovery.html>`__. - Get the ISIS sample dataset from the `Downloads page <http://download.mantidproject.org/>`_. - `TOPAZ_3132_event.nxs` - availabe in ``/Testing/Data/SystemTest/``, get this by building the `SystemTestData` target. It should be in ``ExternalData/Testing/Data/SystemTest/`` - The files `INTER000*` are in the ISIS sample data @@ -184,28 +184,22 @@ Project Recovery test 5. Test multiple instances of Mantid running -- Open MantidPlot - make sure no other instances of MantidPlot are running -- Run the script: +- Launch 2 instances of mantid +- Run the script on the first instance: .. code-block:: python - CreateWorkspace(DataX=range(12), DataY=range(12), DataE=range(12), NSpec=4, OutputWorkspace='NewWorkspace1') + CreateWorkspace(DataX=range(12), DataY=range(12), DataE=range(12), NSpec=4, OutputWorkspace='Instance 1') -- Make sure that Log level is set to `Debug` in the results log -- Open a second instance of Mantid -- In the results log it should say ``Another MantidPlot process is running. Project recovery is disabled.`` -- Run the script: +- Run this script on the other instance: .. code-block:: python - CreateWorkspace(DataX=range(12), DataY=range(12), DataE=range(12), NSpec=4, OutputWorkspace='NewWorkspace2') + CreateWorkspace(DataX=range(12), DataY=range(12), DataE=range(12), NSpec=4, OutputWorkspace='Instance 2') - Crash the first instance of Mantid with `Segfault`; choose `Do not share information` in the error dialog - Do not exit the second instance of Mantid - Restart Mantid -- In the results log it should say ``Another MantidPlot process is running. Project recovery is disabled.`` -- Close both instances of Mantid -- Restart Mantid - You should be presented with a dialog offering to attempt a recovery - choose `Yes` - `NewWorkspace1` should appear in the workspace dialog diff --git a/docs/README.md b/docs/README.md index 48345f2aa1372c4683bf4bc574be6150bf305336..2984a1dbe221d240205e0e544bdb726e91a31136 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,5 +1,5 @@ The Mantid documentation is written in [reStructuredText](http://docutils.sourceforge.net/rst.html) and processed using [Sphinx](http://sphinx.pocoo.org/). It uses a custom -boostrap theme for Sphinx and both are required to build the documentation. +bootstrap theme for Sphinx and both are required to build the documentation. To install Sphinx and the bootstrap theme use `easy_install`: diff --git a/docs/source/algorithms/AnvredCorrection-v1.rst b/docs/source/algorithms/AnvredCorrection-v1.rst index cc95d0cd3aeadb27079877365826133185ebcf43..17af3abafbbadf4d411a83bfc97a59f94a2cbb67 100644 --- a/docs/source/algorithms/AnvredCorrection-v1.rst +++ b/docs/source/algorithms/AnvredCorrection-v1.rst @@ -40,7 +40,7 @@ spectrum. The pixel efficiency and incident spectrum correction are NOT CURRENTLY USED. The absorption correction, trans, depends on both lamda and the -pixel, Which is a fairly expensive calulation when done for each event. +pixel, Which is a fairly expensive calculation when done for each event. Also see :ref:`algm-LorentzCorrection` diff --git a/docs/source/algorithms/AppendGeometryToSNSNexus-v1.rst b/docs/source/algorithms/AppendGeometryToSNSNexus-v1.rst index d7ad2395c19fb2f4fb23ad7ec84147b5214f0a9a..2ff5ead9498c6de0a19c0f571dc22b88ebfad8ab 100644 --- a/docs/source/algorithms/AppendGeometryToSNSNexus-v1.rst +++ b/docs/source/algorithms/AppendGeometryToSNSNexus-v1.rst @@ -14,7 +14,7 @@ NeXus file. It is initially for use only at the SNS, as it is needed for the currently upgrade program. But there is nothing preventing it being used elsewhere. -The algorithm takes the geometry information in the IDF togther with the +The algorithm takes the geometry information in the IDF together with the log values in a given NeXus file and calculates the resolved positions of all the detectors and then writes this into the NeXus file specified. diff --git a/docs/source/algorithms/ApplyPaalmanPingsCorrection-v1.rst b/docs/source/algorithms/ApplyPaalmanPingsCorrection-v1.rst index fe194338505a992a36790dc66ec5a62f24e526ad..d3b321a2a3894db1f41f510292ee882e52f06eaa 100644 --- a/docs/source/algorithms/ApplyPaalmanPingsCorrection-v1.rst +++ b/docs/source/algorithms/ApplyPaalmanPingsCorrection-v1.rst @@ -45,7 +45,7 @@ All workspaces are converted into wavelength using the appropriate mode of :ref:`ConvertUnits <algm-ConvertUnits>`. Then ``CanShiftFactor`` is added to wavelength of the ``CanWorkspace``. Then one of the two following equations is performed -(dependant on the number of correction factors provided): +(dependent on the number of correction factors provided): .. math:: I_s = \frac{1}{A_{s,sc}} \left( I_{sc}^E - I_c^E K_c \frac{A_{c,sc}}{A_{c,c}} \right) .. math:: I_s = \frac{1}{A_{s,s}} \left( I_{sc}^E \right) - \frac{1}{A_{c,c}} \left( I_{c}^E \right) @@ -134,7 +134,7 @@ Usage corrections_ws = Load('irs26176_graphite002_cyl_Abs.nxs') # Interpolate each of the correction factor workspaces to match the - # binning of the smaple + # binning of the sample # Required to use corrections from the old indirect calculate # corrections routines for factor_ws in corrections_ws: diff --git a/docs/source/algorithms/Authenticate-v2.rst b/docs/source/algorithms/Authenticate-v2.rst index ae46874065e54a33ee5a13cf1b393711c118de79..966115d25158ca3441c7d310561ce7877b55b83c 100644 --- a/docs/source/algorithms/Authenticate-v2.rst +++ b/docs/source/algorithms/Authenticate-v2.rst @@ -11,9 +11,9 @@ Description Authenticate to the remote compute resource. This must be executed before calling any other remote algorithms. The authentication method -and outcome of ths algorithm is dependent on the particular +and outcome of this algorithm is dependent on the particular implementation (job manager underlying the algorithm). But typically, -if the authentication is successfull, a cookie is received that is +if the authentication is successful, a cookie is received that is stored internally and re-used for all subsequent interactions with the compute resource. diff --git a/docs/source/algorithms/BayesQuasi-v1.rst b/docs/source/algorithms/BayesQuasi-v1.rst index 720e00dc3fa1b4f65dc2c7cf49d826c9f69619e6..58daf0d510c3235755d057bcf76140898ba74f6e 100644 --- a/docs/source/algorithms/BayesQuasi-v1.rst +++ b/docs/source/algorithms/BayesQuasi-v1.rst @@ -10,7 +10,7 @@ Description ----------- -**This algorith can only be run on windows due to f2py support and the underlying fortran code** +**This algorithm can only be run on windows due to f2py support and the underlying fortran code** The model that is being fitted is that of a \delta-function (elastic component) of amplitude A(0) and Lorentzians of amplitude A(j) and HWHM W(j) where j=1,2,3. The whole function is then convolved diff --git a/docs/source/algorithms/Bin2DPowderDiffraction-v1.rst b/docs/source/algorithms/Bin2DPowderDiffraction-v1.rst index ffba381cf64a0761fa0ce202118a399b1f79586e..d87ac7a038736eab5187fda6fdcbb25920449297 100644 --- a/docs/source/algorithms/Bin2DPowderDiffraction-v1.rst +++ b/docs/source/algorithms/Bin2DPowderDiffraction-v1.rst @@ -34,7 +34,7 @@ Restrictions on the input workspace - X-axis must have the wavelength units. - Only Histograms can be handled. -- Only :ref:`EventWorkspaces <EventWorkspace>` are suported for the moment. +- Only :ref:`EventWorkspaces <EventWorkspace>` are supported for the moment. - The input workspace must have an instrument set. - The input workspace must have a Spectrum axis as a Y-axis. diff --git a/docs/source/algorithms/CalculateCarpenterSampleCorrection-v1.rst b/docs/source/algorithms/CalculateCarpenterSampleCorrection-v1.rst index e4a8ef5f0914db023dd5be721ecf5e6209e5c3ab..8d2e6836c6a285d02b3221a949f24fda871afcd7 100644 --- a/docs/source/algorithms/CalculateCarpenterSampleCorrection-v1.rst +++ b/docs/source/algorithms/CalculateCarpenterSampleCorrection-v1.rst @@ -36,7 +36,7 @@ expansion coefficients: where the Chebyshev coefficients :math:`c_{s}(m,n)` up to m + n :math:`\leqslant` 5 have been tabulated and are stored as an array by the algorithm. -This version of the correction follows the implemenation in [1]_ in that it only calculates for the correction in-plane, unlike [2]_, [3]_ that generalizes the correction to out-of-plane. +This version of the correction follows the implementation in [1]_ in that it only calculates for the correction in-plane, unlike [2]_, [3]_ that generalizes the correction to out-of-plane. This algorithm calculates and outputs the absorption and/or multiple scattering correction workspaces to be applied to the InputWorkspace. Thus, there are, at most, two workspaces in the OutputWorkspaceBaseName group workspace. This allows for flexibility of applying either correction to a workspace without having to apply both (as is the case with :ref:`algm-CarpenterSampleCorrection`). For the case where both corrections are calculated, the output will be the following: @@ -94,7 +94,7 @@ To reproduce what :ref:`algm-CarpenterSampleCorrection` does, you can calculate # Apply absorption correction to workspace ws_abs_corrected = Divide(ws, absCorr) - # Apply multple scattering correction to workspace + # Apply multiple scattering correction to workspace ws_ms_corrected = Minus(ws, msCorr) # Apply both corrections @@ -139,7 +139,7 @@ Output: # Apply absorption correction to workspace ws_abs_corrected = Divide(ws, absCorr) - # Apply multple scattering correction to workspace + # Apply multiple scattering correction to workspace ws_ms_corrected = Minus(ws, msCorr) # Apply both corrections diff --git a/docs/source/algorithms/CalculateCoverageDGS-v1.rst b/docs/source/algorithms/CalculateCoverageDGS-v1.rst index 53b665d420b9598c1717284a7566200452be106d..0f492ac02eea1af10761e5726bf36a9c720a148a 100644 --- a/docs/source/algorithms/CalculateCoverageDGS-v1.rst +++ b/docs/source/algorithms/CalculateCoverageDGS-v1.rst @@ -25,7 +25,7 @@ If no minimum/maximum are set for DeltaE, these are chosen to be +/-Ei. If not specified, minimum/maximum for the Q dimensions are calculated based on the instrument geometry, incident energy, minimum/maximum for DeltaE, and lattice parameters. -The algorithm calculates detector trajectories in the reciprocal space and sets to 1 the coresponding points in the output workspace. +The algorithm calculates detector trajectories in the reciprocal space and sets to 1 the corresponding points in the output workspace. All other points are 0. Usage diff --git a/docs/source/algorithms/CarpenterSampleCorrection-v1.rst b/docs/source/algorithms/CarpenterSampleCorrection-v1.rst index aecb33d5be161ee1c10a66838a9161bb990f9376..33b7c4239994638cefc19b1c987be7c8ffd427c0 100644 --- a/docs/source/algorithms/CarpenterSampleCorrection-v1.rst +++ b/docs/source/algorithms/CarpenterSampleCorrection-v1.rst @@ -36,7 +36,7 @@ expansion coefficients: where the Chebyshev coefficients :math:`c_{s}(m,n)` up to m + n :math:`\leqslant` 5 have been tabulated and are stored as an array by the algorithm. -This version of the correction follows the implemenation in [1]_ in that it only calculates for the correction in-plane, unlike [2]_, [3]_ that generalizes the correction to out-of-plane. +This version of the correction follows the implementation in [1]_ in that it only calculates for the correction in-plane, unlike [2]_, [3]_ that generalizes the correction to out-of-plane. This algorithm calls :ref:`algm-CalculateCarpenterSampleCorrection` to calculate both absorption and multiple scattering corrections and then applies both to the sample workspace. diff --git a/docs/source/algorithms/CentroidPeaksMD-v2.rst b/docs/source/algorithms/CentroidPeaksMD-v2.rst index 98e01b64e9b252f3b0016d85c26517052e2b0e9b..1b813583a0eebdaf5b146190e70ebe953155728a 100644 --- a/docs/source/algorithms/CentroidPeaksMD-v2.rst +++ b/docs/source/algorithms/CentroidPeaksMD-v2.rst @@ -24,7 +24,7 @@ Usage The code iteslef works but disabled from doc tests as takes too long to complete. User should provide its own event nexus file instead of **TOPAZ_3132_event.nxs** used within this example. The original **TOPAZ_3132_event.nxs** -file is availible in `Mantid system tests repository <https://github.com/mantidproject/systemtests/tree/master/Data/TOPAZ_3132_event.nxs>`_. +file is available in `Mantid system tests repository <https://github.com/mantidproject/systemtests/tree/master/Data/TOPAZ_3132_event.nxs>`_. The example shows how applying centroid peaks changes the peak posisions previously calculated by FindPeaksMD algorithm. diff --git a/docs/source/algorithms/ChangeTimeZero-v1.rst b/docs/source/algorithms/ChangeTimeZero-v1.rst index bd81c0b1c160b10139233003e20a43c049ad7b92..8032701f1cad8f8d37ec2018f4a20bfb1a0905c6 100644 --- a/docs/source/algorithms/ChangeTimeZero-v1.rst +++ b/docs/source/algorithms/ChangeTimeZero-v1.rst @@ -15,7 +15,7 @@ alters the logs and in case of an :ref:`EventWorkspace <EventWorkspace>` the neu The time offset can be specified in one of the two following ways: * A time offset in seconds: In this case all time stamps in the workspace are shifted by the specified amount. A positive entry creates a shift into the future and a negative one creates a shift into the past relative to the original time. -* An ISO8601 time stamp (YYYY-MM-DDTHH:MM:SS, eg 2003-11-30T03:23:54). The logs need to contain a proton_charge time series property for this shift to work. The first time entry of the proton_charge time series is used as a reference time stamp and all times will be shifted according to the differnce between this time stamp and the newly specified value. +* An ISO8601 time stamp (YYYY-MM-DDTHH:MM:SS, eg 2003-11-30T03:23:54). The logs need to contain a proton_charge time series property for this shift to work. The first time entry of the proton_charge time series is used as a reference time stamp and all times will be shifted according to the difference between this time stamp and the newly specified value. Only one of the two ways of shifting the time can be specified. diff --git a/docs/source/algorithms/ChopData-v1.rst b/docs/source/algorithms/ChopData-v1.rst index 07a53ced0fad12ed8fde6c6499f81c982895c14e..28ead9b065820271d4c2ccdccadc577d2920f338 100644 --- a/docs/source/algorithms/ChopData-v1.rst +++ b/docs/source/algorithms/ChopData-v1.rst @@ -31,7 +31,7 @@ For example: looking at Figure 1 which shows an input workspace covering 100000 microseconds, we can see that the first frame covers forty thousand, and the other three cover twenty thousand each. -In order for Mantid to determine this programatically, it integrates +In order for Mantid to determine this programmatically, it integrates over a range (defined by IntegrationRangeLower and IntegrationRangeUpper) for each "chop" of the data. If the relative values for this integration fall within certain bounds, then the chop is @@ -63,7 +63,7 @@ Usage result = ChopData(ws, NChops=2, Step=time_diff/2) print("The time range of the original workspace was {:.0f}.".format(time_diff)) - print("The number of bins in the orginal workspace was {}.".format(ws.blocksize())) + print("The number of bins in the original workspace was {}.".format(ws.blocksize())) print("The number of bins in the 1st chop is {}.".format(result[0][0].blocksize())) print("The number of bins in the 2nd chop is {}.".format(result[0][1].blocksize())) @@ -72,7 +72,7 @@ Output: .. testoutput:: Ex The time range of the original workspace was 19800. - The number of bins in the orginal workspace was 100. + The number of bins in the original workspace was 100. The number of bins in the 1st chop is 48. The number of bins in the 2nd chop is 48. diff --git a/docs/source/algorithms/CleanFileCache-v1.rst b/docs/source/algorithms/CleanFileCache-v1.rst index 9e8c2fa0a757b678095873a689284b042d2a54c0..29aef4f7dc84dfe5083c0994f33436ebb2926f41 100644 --- a/docs/source/algorithms/CleanFileCache-v1.rst +++ b/docs/source/algorithms/CleanFileCache-v1.rst @@ -16,7 +16,7 @@ in the form of <prefix>_<sha1>.nxs or <sha1>.nxs. This algorithm delete all such files from the default cache directory or the user-defined cache directory, if supplied. -The name matching is done using regex (40 charaters of numbers plus +The name matching is done using regex (40 characters of numbers plus a-f letters). Therefore if a user created a file in the designated directory that happens to have the same pattern, it will be deleted. diff --git a/docs/source/algorithms/ClearInstrumentParameters-v1.rst b/docs/source/algorithms/ClearInstrumentParameters-v1.rst index 221189b6a350a7a9f2dc3ff263317872e02c2bb2..c347d2e0a1ec51d82d7025bff92b711400de89a3 100644 --- a/docs/source/algorithms/ClearInstrumentParameters-v1.rst +++ b/docs/source/algorithms/ClearInstrumentParameters-v1.rst @@ -43,7 +43,7 @@ Usage print("Clearing all parameters") ClearInstrumentParameters(ws) - #Check the parmaeters have been cleared correctly + #Check the parameters have been cleared correctly #Obtain instrument and banks again, to make sure they contain the updated parameters instrument = ws.getInstrument() bank1 = instrument.getComponentByName("bank1") diff --git a/docs/source/algorithms/CollectHB3AExperimentInfo-v1.rst b/docs/source/algorithms/CollectHB3AExperimentInfo-v1.rst index 075932fc57e96e1c13963f05b6579ad607a6aef2..5513e7e2378e0d1ce75a3a8401f3023ca09b58e7 100644 --- a/docs/source/algorithms/CollectHB3AExperimentInfo-v1.rst +++ b/docs/source/algorithms/CollectHB3AExperimentInfo-v1.rst @@ -19,7 +19,7 @@ Inputs The inputs required by algorithm *ConvertHB3AExperimentInfo* are the experiment number, scan numbers and selected Pt. numbers. By these parameters, the algorithm can determine the names of the data files and generate a list of -detectors for downstream algorithm to create virutal instrument. +detectors for downstream algorithm to create virtual instrument. OutputWorkspaces diff --git a/docs/source/algorithms/Comment-v1.rst b/docs/source/algorithms/Comment-v1.rst index c592f7a2642e70383d56c3ec4d79aa69f3136fe6..dcbd38878a8cb0d082d899a6870b4321bdd314f4 100644 --- a/docs/source/algorithms/Comment-v1.rst +++ b/docs/source/algorithms/Comment-v1.rst @@ -14,7 +14,7 @@ This simple algorithm just adds a comment record to the history of a workspace a It does not change the data within a workspace in any way. -When outputing the histroy to Python this comment will be rendered as a python comment. +When outputting the history to Python this comment will be rendered as a python comment. Usage diff --git a/docs/source/algorithms/ComputeCalibrationCoefVan-v1.rst b/docs/source/algorithms/ComputeCalibrationCoefVan-v1.rst index 0a224767475ad0b3f9fe28c3cfbb367f62aefaab..b8e71df999a258e4b42cacb49632f8dd4a88a95a 100644 --- a/docs/source/algorithms/ComputeCalibrationCoefVan-v1.rst +++ b/docs/source/algorithms/ComputeCalibrationCoefVan-v1.rst @@ -31,7 +31,7 @@ Algorithm creates a workspace with detector sensitivity correction coefficients :math:`S_i = \sum_{x = x_C - 3\,\mathrm{fwhm}}^{x_C + 3\,\mathrm{fwhm}} Y_i(x)` - where :math:`x_C` is the peak centre position and :math:`Y_i(x)` is the coresponding to :math:`x` :math:`Y` value for i-th detector. + where :math:`x_C` is the peak centre position and :math:`Y_i(x)` is the corresponding to :math:`x` :math:`Y` value for i-th detector. 3. Finally, the correction coefficients :math:`K_i` are calculated as diff --git a/docs/source/algorithms/ComputeSensitivity-v1.rst b/docs/source/algorithms/ComputeSensitivity-v1.rst index d8a46b16cef52f37f75fd3c66453c3f08858f148..1e910eebd9122b4ad97849c3476bdff8b1735754 100644 --- a/docs/source/algorithms/ComputeSensitivity-v1.rst +++ b/docs/source/algorithms/ComputeSensitivity-v1.rst @@ -21,7 +21,7 @@ in this patched pixel's tube. Usage ----- -This is a part of the EQSANS workflow algorithm and is not intended to be executed seperately. +This is a part of the EQSANS workflow algorithm and is not intended to be executed separately. .. categories:: diff --git a/docs/source/algorithms/ConjoinXRuns-v1.rst b/docs/source/algorithms/ConjoinXRuns-v1.rst index 72524c195fbf05108da8f62627e89c842481e8e8..11ffcd0a020b75fa954e7aeeee319a66ae2671be 100644 --- a/docs/source/algorithms/ConjoinXRuns-v1.rst +++ b/docs/source/algorithms/ConjoinXRuns-v1.rst @@ -10,7 +10,7 @@ Description ----------- -This algorithm joins the input workspaces into a single one by concatenating their spectra. The concatenation is done in the same order as in the input workspaces list. Consider using :ref:`SortXAxis <algm-SortXAxis>` afterwards, if necessary. The instrument and the units are copied from the first workspace. The sample logs are also copied from the first input, but the behaviour can be controlled by the instrument parameter file (IPF), as described in :ref:`MergeRuns <algm-MergeRuns>`. Furthermore, that behaviour can be overriden by providing input to the relevant optional properties of the algorithm. This algorithm joins Dx values, if present. +This algorithm joins the input workspaces into a single one by concatenating their spectra. The concatenation is done in the same order as in the input workspaces list. Consider using :ref:`SortXAxis <algm-SortXAxis>` afterwards, if necessary. The instrument and the units are copied from the first workspace. The sample logs are also copied from the first input, but the behaviour can be controlled by the instrument parameter file (IPF), as described in :ref:`MergeRuns <algm-MergeRuns>`. Furthermore, that behaviour can be overridden by providing input to the relevant optional properties of the algorithm. This algorithm joins Dx values, if present. InputWorkspaces --------------- @@ -24,7 +24,7 @@ This can be a mixed list of workspaces and workspace groups on AnalysisDataServi SampleLogAsXAxis ---------------- -If specified, this log values will constitute the x-axis of the resulting workspace. The log must exist in all the input workspaces and must be numeric (int or double), in which case the input workspaces must contain single bin only, or numeric time series, in which case the lenght of the series must match the number of points. +If specified, this log values will constitute the x-axis of the resulting workspace. The log must exist in all the input workspaces and must be numeric (int or double), in which case the input workspaces must contain single bin only, or numeric time series, in which case the length of the series must match the number of points. ConjoinX Operation ------------------ diff --git a/docs/source/algorithms/ConvertCWPDMDToSpectra-v1.rst b/docs/source/algorithms/ConvertCWPDMDToSpectra-v1.rst index 39f63591a78b8b7e4e8702dbe27c2d8662d24446..74588c765bdc9f437f95ed97f520c23dd61dfd62 100644 --- a/docs/source/algorithms/ConvertCWPDMDToSpectra-v1.rst +++ b/docs/source/algorithms/ConvertCWPDMDToSpectra-v1.rst @@ -23,7 +23,7 @@ One stores the detectors' counts; and the other stores the monitors' counts. These two MDEventWorkspaces are generated from algorithm ConvertSpiceToRealSpace. -Futhermore, the unit of the output matrix workspace can be converted to +Furthermore, the unit of the output matrix workspace can be converted to d-spacing and momentum transfer (:math:`Q`). @@ -83,7 +83,7 @@ Binning, Normalization and Error According to the input binning parameters, the bins in :math:`2\theta` are created as :math:`2\theta_{min}, 2\theta_{min}+\Delta, 2\theta_{min}+2\Delta, \cdots`. -If the unit of ouput workspace is specified as dSpacing or MomentrumTransfer, +If the unit of output workspace is specified as dSpacing or MomentrumTransfer, then the bins should be created as :math:`d_{min}, d_{min}+\Delta, d_{min}+2\Delta, \cdots, d_{max}` or :math:`q_{min}, q_{min}+\Delta, \cdots, q_{max}` respectively. @@ -92,7 +92,7 @@ For each detector, if its position falls between :math:`2\theta_i` and :math:`2\ then its counts is added to :math:`Y_i` and the corresponding monitor counts is added to :math:`M_i`. -The singals on these bins are normalized by its monitor counts, such that +The signals on these bins are normalized by its monitor counts, such that .. math:: y_i = \frac{Y_i}{M_i} diff --git a/docs/source/algorithms/ConvertCWSDExpToMomentum-v1.rst b/docs/source/algorithms/ConvertCWSDExpToMomentum-v1.rst index b369acddac2ee23d237e905a55effd097eb3293a..13de662912e95faa612de3a27e598b5c824a302d 100644 --- a/docs/source/algorithms/ConvertCWSDExpToMomentum-v1.rst +++ b/docs/source/algorithms/ConvertCWSDExpToMomentum-v1.rst @@ -18,7 +18,7 @@ In this algorithm's name, ConvertCWSDToMomentum, *CW* stands for constant wave This algorithm takes ??? as inputs. -Futhermore, the unit of the output matrix workspace can be converted to +Furthermore, the unit of the output matrix workspace can be converted to momentum transfer (Q). @@ -37,7 +37,7 @@ Outline of algorithm * From each row, (1) file name and (2) starting detector ID are read in. * Detector position in (virtual) instrument of MDEventWorkspace is compared with the position in MatrixWorkspace - * Momentum is calcualted by goniometry values + * Momentum is calculated by goniometry values Input Workspaces diff --git a/docs/source/algorithms/ConvertFitFunctionForMuonTFAsymmetry-v1.rst b/docs/source/algorithms/ConvertFitFunctionForMuonTFAsymmetry-v1.rst index 838bd05a26c7f09a10e8a921bbc1b1a0c2e7af36..23af311080550c7919afea03d985d6af0398a0c3 100644 --- a/docs/source/algorithms/ConvertFitFunctionForMuonTFAsymmetry-v1.rst +++ b/docs/source/algorithms/ConvertFitFunctionForMuonTFAsymmetry-v1.rst @@ -13,7 +13,7 @@ This algorithm can be run in two modes. The first is construct, which takes a us .. math:: N_0[1+f(t)] + A\exp(-\lambda t) -where :math:`N_0` is the normalisation constant, :math:`A` is fixed to zero by default and :math:`\lambda` is fixed to the Muon lifetime. The inital value for the normalisation constant is from the normalisation table. +where :math:`N_0` is the normalisation constant, :math:`A` is fixed to zero by default and :math:`\lambda` is fixed to the Muon lifetime. The initial value for the normalisation constant is from the normalisation table. The second mode is extract, if the TF normalisation function is given it will return the user function. diff --git a/docs/source/algorithms/ConvertSpectrumAxis-v2.rst b/docs/source/algorithms/ConvertSpectrumAxis-v2.rst index 862d0dae922c3de4a5a58ddb8ade800f56105328..d79df6c74e61bd57ff7edc9e67d9ea1db601169a 100644 --- a/docs/source/algorithms/ConvertSpectrumAxis-v2.rst +++ b/docs/source/algorithms/ConvertSpectrumAxis-v2.rst @@ -14,7 +14,7 @@ a matrix in MantidPlot) of a Workspace2D from its default of holding the spectrum number to the target unit given - theta, elastic Q, elastic Q^2 or elastic d-spacing. -The spectra will be reordered in increasing order by default, however this can be disbled by `OrderAxis=False`. +The spectra will be reordered in increasing order by default, however this can be disabled by `OrderAxis=False`. In the case of the latter, spectra will preserve correspondence to the original workspace. The new unit and duplicates will not be aggregated. Any spectrum for which a detector is not found (i.e. if the instrument definition is incomplete) will not diff --git a/docs/source/algorithms/ConvertSpiceDataToRealSpace-v1.rst b/docs/source/algorithms/ConvertSpiceDataToRealSpace-v1.rst index 7b9e4474db0125b7d8b842f4d5f00ff129682757..cac91b75b3568f7ef037cae6571eed1378be1344 100644 --- a/docs/source/algorithms/ConvertSpiceDataToRealSpace-v1.rst +++ b/docs/source/algorithms/ConvertSpiceDataToRealSpace-v1.rst @@ -43,7 +43,7 @@ The corrected counts is equal to :math:`counts^{raw}/f`. Outputs ####### -Two MDEventWorkspaces will be output from this algorith. +Two MDEventWorkspaces will be output from this algorithm. One MDWorkspaces stores the experimental data. Each MDEvent is a data point measured on one detector. diff --git a/docs/source/algorithms/ConvertToMD-v1.rst b/docs/source/algorithms/ConvertToMD-v1.rst index 35b37c45c04ab3534278b2bd2846e498c77d88e5..77b3ecf162017450d9319557ba98d8a00083fe93 100644 --- a/docs/source/algorithms/ConvertToMD-v1.rst +++ b/docs/source/algorithms/ConvertToMD-v1.rst @@ -128,7 +128,7 @@ Mantid for different testing tasks. **Example - Convert Set of Event Workspaces (Horace scan) to 4D MD workspace, direct mode:** -Meaningfull results can be obtained on the basis of CNCS\_7860\_event.nxs file, available in Mantid +Meaningful results can be obtained on the basis of CNCS\_7860\_event.nxs file, available in Mantid test folder. The script below simulates workspace loading but would produce meaningfill result if real experimental data obtained in an experiment and stored in nxspe files are provided to it. diff --git a/docs/source/algorithms/ConvertToMDMinMaxLocal-v1.rst b/docs/source/algorithms/ConvertToMDMinMaxLocal-v1.rst index 66bf54e4e013d7c439134451618c67febb5ff5f8..9fa209a18b66131258fb6ebcd52858fb447d5150 100644 --- a/docs/source/algorithms/ConvertToMDMinMaxLocal-v1.rst +++ b/docs/source/algorithms/ConvertToMDMinMaxLocal-v1.rst @@ -10,9 +10,9 @@ Description ----------- Calculate min-max input values for selected workspace and MD transformation, -choosen from `MD Transformation factory <http://www.mantidproject.org/MD_Transformation_factory>`_. +chosen from `MD Transformation factory <http://www.mantidproject.org/MD_Transformation_factory>`_. -Used as helper algorithm for :ref:`algm-ConvertToMD` but can aslo be deployed separately +Used as helper algorithm for :ref:`algm-ConvertToMD` but can also be deployed separately to evaluate the MD transformation limits for the current workspace. Initiates the same as :ref:`algm-ConvertToMD` algorithm transformation from the diff --git a/docs/source/algorithms/ConvertToReflectometryQ-v1.rst b/docs/source/algorithms/ConvertToReflectometryQ-v1.rst index 576361f497e586a40e95cc936001beb02aaf7c6f..04ffb1505064027341d47fe5d77d923d0e66abb8 100644 --- a/docs/source/algorithms/ConvertToReflectometryQ-v1.rst +++ b/docs/source/algorithms/ConvertToReflectometryQ-v1.rst @@ -106,7 +106,7 @@ Normalised Polygon Transformation Io=mtd['Io'] D=mtd['D'] - # Peform the normalisation step + # Perform the normalisation step Divide(LHSWorkspace=D,RHSWorkspace=Io,OutputWorkspace='I',AllowDifferentNumberSpectra='1',ClearRHSWorkspace='1') I=mtd['I'][0] @@ -183,7 +183,7 @@ achieved by running the algorithm below. polygon_vertexes = list() for vertex in vertex_table: - #Column of vertex i.e 'Qx' in this case, is dependant on the type of transform. + #Column of vertex i.e 'Qx' in this case, is dependent on the type of transform. #'Ki' and 'Kf' are used for the K transformation. #'Pi+Pf' and 'Pi-Pf' are used for the P transformation. polygon_vertexes.append((vertex['Qx'], vertex['Qy'] )) diff --git a/docs/source/algorithms/CopyInstrumentParameters-v1.rst b/docs/source/algorithms/CopyInstrumentParameters-v1.rst index 678de4f69682c3bb894a3bdb5eed3a841ab8e2dd..e813e74fcb3c5a1b153500dc9846ccbc877e0e09 100644 --- a/docs/source/algorithms/CopyInstrumentParameters-v1.rst +++ b/docs/source/algorithms/CopyInstrumentParameters-v1.rst @@ -52,7 +52,7 @@ Usage det.getPos().X(), det.getPos().Y(), det.getPos().Z())) - # Copy paremeters from 1st workspace to 2nd workspace + # Copy parameters from 1st workspace to 2nd workspace CopyInstrumentParameters( ws1, ws2 ) diff --git a/docs/source/algorithms/CreateCacheFilename-v1.rst b/docs/source/algorithms/CreateCacheFilename-v1.rst index c27b7b290bcdab9244d9fa899946a7d798b3602b..750a35b229b71fa66f7e22b2ceea6d584cfa9b23 100644 --- a/docs/source/algorithms/CreateCacheFilename-v1.rst +++ b/docs/source/algorithms/CreateCacheFilename-v1.rst @@ -52,7 +52,7 @@ result will be ``<location>/<sha1>.nxs``. no globbing here. * ``Prefix``: prefix to the output hash name. when it is empty, just the hash. when it is not empty, it will be ``<prefix>_<sha1>`` -* ``CacheDir``: the directory in which the cach file will be created. +* ``CacheDir``: the directory in which the cache file will be created. empty string means default as described above Usage diff --git a/docs/source/algorithms/CreateLogPropertyTable-v1.rst b/docs/source/algorithms/CreateLogPropertyTable-v1.rst index 6cddc1a741bbbc8b7ecd8b016bb5693a2bbef9d5..d80b49d1a6b29dbd6afe24feb72f2aa159228fcd 100644 --- a/docs/source/algorithms/CreateLogPropertyTable-v1.rst +++ b/docs/source/algorithms/CreateLogPropertyTable-v1.rst @@ -52,10 +52,10 @@ Example ------- .. figure:: /images/ConvertToEnergyInfoTable.png - :alt: Output workspace generated by loading TOSCA runs 12218-12229, and feeding the resuling workspace names into the algorithm, along with the property names "inst_abrv", "run_number", "user_name", "run_title" and "hd_dur". + :alt: Output workspace generated by loading TOSCA runs 12218-12229, and feeding the resulting workspace names into the algorithm, along with the property names "inst_abrv", "run_number", "user_name", "run_title" and "hd_dur". Output workspace generated by loading TOSCA runs 12218-12229, and - feeding the resuling workspace names into the algorithm, along with + feeding the resulting workspace names into the algorithm, along with the property names "inst\_abrv", "run\_number", "user\_name", "run\_title" and "hd\_dur". diff --git a/docs/source/algorithms/CreateLogTimeCorrection-v1.rst b/docs/source/algorithms/CreateLogTimeCorrection-v1.rst index dffd463ccc5519947f24035d44710cd44118d50c..98a3c85c5e43469c4463efd9051ce73e1fcbc65f 100644 --- a/docs/source/algorithms/CreateLogTimeCorrection-v1.rst +++ b/docs/source/algorithms/CreateLogTimeCorrection-v1.rst @@ -9,7 +9,7 @@ Description ----------- -For fast fequency sample logs, the time-of-flight of each neutron is +For fast frequency sample logs, the time-of-flight of each neutron is recorded at detector. As the sample log time is recorded at sample, each neutron's flight time must be corrected to sample to be filtered correctly by log value. diff --git a/docs/source/algorithms/CreateSampleWorkspace-v1.rst b/docs/source/algorithms/CreateSampleWorkspace-v1.rst index 088a661ce73ae44f711343fb99f382db15915c68..45e7ae8cd5f444cc096fe96bcda5ec1b8a3a1ee3 100644 --- a/docs/source/algorithms/CreateSampleWorkspace-v1.rst +++ b/docs/source/algorithms/CreateSampleWorkspace-v1.rst @@ -46,7 +46,7 @@ this. :width: 100% :alt: A labelled image of the instrument created by CreateSampleWorkspace -The sample is placed at the origin. The source is seperated from the sample in +The sample is placed at the origin. The source is separated from the sample in the negative direction by the value you specify in "SourceDistanceFromSample". The instrument has "NumBanks" detector banks, each bank is moved down the Z axis by "BankDistanceFromSample" from the sample or the previous bank. diff --git a/docs/source/algorithms/CuboidGaugeVolumeAbsorption-v1.rst b/docs/source/algorithms/CuboidGaugeVolumeAbsorption-v1.rst index 3bf69ee0e9bb222480be19c4ae2b6dcc96329989..46ef26dd4949bf776617b3c5fba71b45285db3c2 100644 --- a/docs/source/algorithms/CuboidGaugeVolumeAbsorption-v1.rst +++ b/docs/source/algorithms/CuboidGaugeVolumeAbsorption-v1.rst @@ -46,7 +46,7 @@ fully within the sample. Usage ----- -**Example: A simple spherical sample with a cuboid guage volume** +**Example: A simple spherical sample with a cuboid gauge volume** .. testcode:: ExCuboidGuageSimpleSpere diff --git a/docs/source/algorithms/CutMD-v1.rst b/docs/source/algorithms/CutMD-v1.rst index ee98fac154f646c824904ad91b6c1a63db495960..621d47d4ef3df47b6b71e0edf9cff4c53d47a226 100644 --- a/docs/source/algorithms/CutMD-v1.rst +++ b/docs/source/algorithms/CutMD-v1.rst @@ -12,7 +12,7 @@ Description This algorithm performs slicing of multiDimensional data according to a chosen projection, limits and binning steps. -The synax is similar to that used by `Horace <http://horace.isis.rl.ac.uk/Manipulating_and_extracting_data_from_SQW_files_and_objects#cut_sqw>`__. +The syntax is similar to that used by `Horace <http://horace.isis.rl.ac.uk/Manipulating_and_extracting_data_from_SQW_files_and_objects#cut_sqw>`__. Unlike most Mantid algorithms, CutMD can accept a list of workspaces as the input workspace, given as the name of a workspace in the analysis data service diff --git a/docs/source/algorithms/DSFinterp-v1.rst b/docs/source/algorithms/DSFinterp-v1.rst index cb029a2f452a608e86952d87e6e4117b28e9ec8c..49fbfc7251f98fa5d6b8812791618590be9a4b5a 100644 --- a/docs/source/algorithms/DSFinterp-v1.rst +++ b/docs/source/algorithms/DSFinterp-v1.rst @@ -30,7 +30,7 @@ with a cubic spline, which then can be invoked to obtain :math:`S(Q,E,T)` at any T value. Errors in the structure factor are incorporated when constructing the spline, so that the spline -need not neccessarily pass trough the :math:`(T_i, S_i)` points. +need not necessarily pass trough the :math:`(T_i, S_i)` points. This has the desirable effect of producing smooth spline curves when the variation of the structure factors versus :math:`T` contains significant noise. For more details on the construction of the spline, see `UnivariateSpline <http://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.UnivariateSpline.html>`_ diff --git a/docs/source/algorithms/DefineGaugeVolume-v1.rst b/docs/source/algorithms/DefineGaugeVolume-v1.rst index ac27a86068ba4fb7e57a5e5288c423d78a9f9725..4d57077e70a2a2321bc7dcd9de2b726ca28c3b67 100644 --- a/docs/source/algorithms/DefineGaugeVolume-v1.rst +++ b/docs/source/algorithms/DefineGaugeVolume-v1.rst @@ -26,7 +26,7 @@ object. Usage ----- -**Example: A simple spherical sample with a cuboid guage volume** +**Example: A simple spherical sample with a cuboid gauge volume** .. testcode:: ExSimpleSpereWithCuboidGuage @@ -41,7 +41,7 @@ Usage CreateSampleShape(ws,sphere) SetSampleMaterial(ws,ChemicalFormula="V") - #setup the guage volume + #setup the gauge volume cuboid = '''<cuboid id="shape"> <left-front-bottom-point x="0.01" y="-0.1" z="0.0" /> <left-front-top-point x="0.01" y="-0.1" z="0.02" /> diff --git a/docs/source/algorithms/DetectorEfficiencyCor-v1.rst b/docs/source/algorithms/DetectorEfficiencyCor-v1.rst index 339a831e674bf3c287e07a094344b21ce5a0ac45..d626ef6d819c898db83f916425da09adb322abf9 100644 --- a/docs/source/algorithms/DetectorEfficiencyCor-v1.rst +++ b/docs/source/algorithms/DetectorEfficiencyCor-v1.rst @@ -23,7 +23,7 @@ the :ref:`algm-ConvertUnits` algorithm. To estimate the true number of neutrons that entered the detector the counts in each bin are divided by the detector efficiency of that detector at that energy. The efficiency iteslef is calculated from -the forumula, tabulated within the algorithm. +the formula, tabulated within the algorithm. The numbers of counts are then multiplied by the value of :math:`k_i/k_f` for each bin. In that formula :math:`k_i` is the @@ -34,7 +34,7 @@ detector and energy bin). They're calculated, in angstrom\ :sup:`-1`, as | :math:`k_i = \sqrt{\frac{E_i}{2.07212466}}` | :math:`k_f = \sqrt{\frac{E_i - \Delta E}{2.07212466}}` -where :math:`E_i` and :math:`\Delta E` are energies in meV, the inital +where :math:`E_i` and :math:`\Delta E` are energies in meV, the initial neutron kinetic energy and the energy lost to the sample respectively. Note: it is not possible to use this :ref:`algorithm <algorithm>` to diff --git a/docs/source/algorithms/DgsAbsoluteUnitsReduction-v1.rst b/docs/source/algorithms/DgsAbsoluteUnitsReduction-v1.rst index 1b11f02914b57f8e12a1abad61492b3a6309db22..b47194f02205d27f537d59f8adbfac5a535a47eb 100644 --- a/docs/source/algorithms/DgsAbsoluteUnitsReduction-v1.rst +++ b/docs/source/algorithms/DgsAbsoluteUnitsReduction-v1.rst @@ -72,7 +72,7 @@ Usage .. warning:: - This algorithm is not really intented for use at the command line, but is used + This algorithm is not really intended for use at the command line, but is used within :ref:`DgsReduction <algm-DgsReduction>`. .. categories:: diff --git a/docs/source/algorithms/DgsConvertToEnergyTransfer-v1.rst b/docs/source/algorithms/DgsConvertToEnergyTransfer-v1.rst index 392c82d4ac4e0c89e912d7d376cbf5638ef116aa..4852a505680cd89528249b76770ac2ba964c7938 100644 --- a/docs/source/algorithms/DgsConvertToEnergyTransfer-v1.rst +++ b/docs/source/algorithms/DgsConvertToEnergyTransfer-v1.rst @@ -51,7 +51,7 @@ Usage .. warning:: - This algorithm is not really intented for use at the command line, but is used + This algorithm is not really intended for use at the command line, but is used within :ref:`DgsReduction <algm-DgsReduction>`. .. categories:: diff --git a/docs/source/algorithms/DgsDiagnose-v1.rst b/docs/source/algorithms/DgsDiagnose-v1.rst index e5670303700227e8a1426fcd017d8667bebc9d92..f916b8f0984b4784519a7a749fa760c09c8350dc 100644 --- a/docs/source/algorithms/DgsDiagnose-v1.rst +++ b/docs/source/algorithms/DgsDiagnose-v1.rst @@ -96,7 +96,7 @@ Usage .. warning:: - This algorithm is not really intented for use at the command line, but is used + This algorithm is not really intended for use at the command line, but is used within :ref:`DgsReduction <algm-DgsReduction>`. .. categories:: diff --git a/docs/source/algorithms/DgsPreprocessData-v1.rst b/docs/source/algorithms/DgsPreprocessData-v1.rst index 5a8946e19eb69cdadce0be3813c75a2e0dba1231..acb004040fd3e6cc9e3c31b607364c86b87ed8f4 100644 --- a/docs/source/algorithms/DgsPreprocessData-v1.rst +++ b/docs/source/algorithms/DgsPreprocessData-v1.rst @@ -43,7 +43,7 @@ Usage .. warning:: - This algorithm is not really intented for use at the command line, but is used + This algorithm is not really intended for use at the command line, but is used within :ref:`DgsReduction <algm-DgsReduction>`. .. categories:: diff --git a/docs/source/algorithms/DgsProcessDetectorVanadium-v1.rst b/docs/source/algorithms/DgsProcessDetectorVanadium-v1.rst index d64d655e8f4676c82db01c5c90bb032a5985e0e9..2d6e30ab4fcc9f6ff8a406cbd10a3dea20da36dd 100644 --- a/docs/source/algorithms/DgsProcessDetectorVanadium-v1.rst +++ b/docs/source/algorithms/DgsProcessDetectorVanadium-v1.rst @@ -44,7 +44,7 @@ Usage .. warning:: - This algorithm is not really intented for use at the command line, but is used + This algorithm is not really intended for use at the command line, but is used within :ref:`DgsReduction <algm-DgsReduction>`. .. categories:: diff --git a/docs/source/algorithms/DgsRemap-v1.rst b/docs/source/algorithms/DgsRemap-v1.rst index aab6dcabeef0ff60777fca85a721648dbd360ec7..8ea997618ae1790ebd661f5ab76a6849316e3e4f 100644 --- a/docs/source/algorithms/DgsRemap-v1.rst +++ b/docs/source/algorithms/DgsRemap-v1.rst @@ -23,7 +23,7 @@ Usage .. warning:: - This algorithm is not really intented for use at the command line, but is used + This algorithm is not really intended for use at the command line, but is used within :ref:`DgsReduction <algm-DgsReduction>`. .. categories:: diff --git a/docs/source/algorithms/DiffractionFocussing-v2.rst b/docs/source/algorithms/DiffractionFocussing-v2.rst index 52509fe68413ec16e61f39f3d4477889eec95400..71b73b3de9178f2e0e1dcc591d741113ff9bb6b0 100644 --- a/docs/source/algorithms/DiffractionFocussing-v2.rst +++ b/docs/source/algorithms/DiffractionFocussing-v2.rst @@ -65,7 +65,7 @@ Usage # specify groupping file, here using CalFile format cal_file = "hrpd_new_072_01_corr.cal" - # For HRPD data, perform a unit convertion TOF->d-spacing, taking into account detector position offsets + # For HRPD data, perform a unit conversion TOF->d-spacing, taking into account detector position offsets ws = AlignDetectors(InputWorkspace='ws',CalibrationFile=cal_file) # Focus the data ws = DiffractionFocussing(InputWorkspace='ws',GroupingFileName=cal_file) diff --git a/docs/source/algorithms/DirectILLApplySelfShielding-v1.rst b/docs/source/algorithms/DirectILLApplySelfShielding-v1.rst index 3da05ab45e00be5a4c6be52ab32d4dbfeb2abf97..97ca6bad859f45cc471f3e0df28a4b22bb6d0059 100644 --- a/docs/source/algorithms/DirectILLApplySelfShielding-v1.rst +++ b/docs/source/algorithms/DirectILLApplySelfShielding-v1.rst @@ -18,115 +18,7 @@ This algorithm is part of :ref:`ILL's direct geometry data reduction algorithms Usage ----- -**Example - Absorption corrections and empty container subtraction** - -.. testcode:: FakeIN4Example - - import numpy - import scipy.stats - - # Create a fake IN4 workspace. - # We need an instrument and a template first. - empty_IN4 = LoadEmptyInstrument(InstrumentName='IN4') - nHist = empty_IN4.getNumberHistograms() - # Make TOF bin edges. - xs = numpy.arange(530.0, 2420.0, 4.0) - # Make some Gaussian spectra. - ys = 1000.0 * scipy.stats.norm.pdf(xs[:-1], loc=970, scale=60) - # Repeat data for each histogram. - xs = numpy.tile(xs, nHist) - ys = numpy.tile(ys, nHist) - ws = CreateWorkspace( - DataX=xs, - DataY=ys, - NSpec=nHist, - UnitX='TOF', - ParentWorkspace=empty_IN4 - ) - # Manually correct monitor spectrum number as LoadEmptyInstrument does - # not know about such details. - SetInstrumentParameter( - Workspace=ws, - ParameterName='default-incident-monitor-spectrum', - ParameterType='Number', - Value=str(1) - ) - # Add incident energy information to sample logs. - AddSampleLog( - Workspace=ws, - LogName='Ei', - LogText=str(57), - LogType='Number', - LogUnit='meV', - NumberType='Double' - ) - # Elastic channel information is missing in the sample logs. - # It can be given as single valued workspace, as well. - elasticChannelWS = CreateSingleValuedWorkspace(107) - - # Create a fake 'empty container' workspace for background subtraction. - ecws = Scale( - InputWorkspace=ws, - Factor=0.1 - ) - - DirectILLCollectData( - InputWorkspace=ws, - OutputWorkspace='preprocessed', - ElasticChannelWorkspace=elasticChannelWS, - IncidentEnergyCalibration='Energy Calibration OFF', # Normally we would do this for IN4. - ) - - DirectILLCollectData( - InputWorkspace=ecws, - OutputWorkspace='preprocessed_ecws', - ElasticChannelWorkspace=elasticChannelWS, - IncidentEnergyCalibration='Energy Calibration OFF' - ) - - sampleGeometry = { - 'Shape': 'Cylinder', - 'Height': 8.0, - 'Radius': 1.5, - 'Center': [0.0, 0.0, 0.0] - } - sampleMaterial = { - 'ChemicalFormula': 'V', - 'SampleNumberDensity': 0.05 - } - SetSample( - InputWorkspace='preprocessed', - Geometry=sampleGeometry, - Material=sampleMaterial - ) - - DirectILLSelfShielding( - InputWorkspace='preprocessed', - OutputWorkspace='absorption_corrections', - SimulationInstrument='Full Instrument', # IN4 is small enough. - NumberOfSimulatedWavelengths=10 - ) - - DirectILLApplySelfShielding( - InputWorkspace='preprocessed', - OutputWorkspace='absorptionCorrected', - EmptyContainerWorkspace='preprocessed_ecws', - SelfShieldingCorrectionWorkspace='absorption_corrections' - ) - - preprocessed = mtd['preprocessed'] - maxY = numpy.amax(preprocessed.readY(0)) - print('Elastic peak maximum before corrections: {:.3}'.format(maxY)) - corrected = mtd['absorptionCorrected'] - maxY = numpy.amax(corrected.readY(0)) - print('After empty container subtraction and absorption corrections: {:.3}'.format(maxY)) - -Output: - -.. testoutput:: FakeIN4Example - - Elastic peak maximum before corrections: 26.7 - After empty container subtraction and absorption corrections: 51.5 +For usage of this algorithm, check the examples :ref:`here <DirectILL>`. .. categories:: diff --git a/docs/source/algorithms/DirectILLCollectData-v1.rst b/docs/source/algorithms/DirectILLCollectData-v1.rst index 02831a06eaf0f1fe3ebe1ec929e99be38dbfbb49..ee817e6a7207bd37ed8537855793e785cd4a637c 100644 --- a/docs/source/algorithms/DirectILLCollectData-v1.rst +++ b/docs/source/algorithms/DirectILLCollectData-v1.rst @@ -116,70 +116,45 @@ The following settings are used when the :literal:`AUTO` keyword is encountered: Usage ----- -**Example - Fake IN4 workspace as input** - -.. testcode:: FakeIN4Example - - import numpy - import scipy.stats - - # Create a fake IN4 workspace. - # We need an instrument and a template first. - empty_IN4 = LoadEmptyInstrument(InstrumentName='IN4') - nHist = empty_IN4.getNumberHistograms() - # Make TOF bin edges. - xs = numpy.arange(530.0, 2420.0, 4.0) - # Make some Gaussian spectra. - ys = 1000.0 * scipy.stats.norm.pdf(xs[:-1], loc=970, scale=60) - # Repeat data for each histogram. - xs = numpy.tile(xs, nHist) - ys = numpy.tile(ys, nHist) - ws = CreateWorkspace( - DataX=xs, - DataY=ys, - NSpec=nHist, - UnitX='TOF', - ParentWorkspace=empty_IN4 - ) - # Manually correct monitor spectrum number as LoadEmptyInstrument does - # not know about such details. - SetInstrumentParameter( - Workspace=ws, - ParameterName='default-incident-monitor-spectrum', - ParameterType='Number', - Value=str(1) - ) - # Add incident energy information to sample logs. - AddSampleLog( - Workspace=ws, - LogName='Ei', - LogText=str(57), - LogType='Number', - LogUnit='meV', - NumberType='Double' - ) - # Elastic channel information is missing in the sample logs. - # It can be given as single valued workspace, as well. - elasticChannelWS = CreateSingleValuedWorkspace(107) - - DirectILLCollectData( - InputWorkspace=ws, - OutputWorkspace='preprocessed', - ElasticChannelWorkspace=elasticChannelWS, - IncidentEnergyCalibration='Energy Calibration OFF', # Normally we would enable this for IN4. - ) - - # Notably, the TOF axis got adjusted in DirectILLCollectData - preprocessedWS = mtd['preprocessed'] - print('TOF offset without corrections: {:.4} microseconds'.format(ws.readX(0)[0])) - print('Corrected TOF offset: {:.4} microseconds'.format(preprocessedWS.readX(0)[0])) +For usage of this algorithm as part of the direct geometry data reduction, check the examples :ref:`here <DirectILL>`. + +.. include:: ../usagedata-note.txt + +**Example - Usage as an advanced loader** + +.. testsetup:: IN4Example + + config['default.facility'] = 'ILL' + config['default.instrument'] = 'IN4' + +.. testcode:: IN4Example + + # It is recommended to use DirectILLCollectData over the basic Load + preprocessed = DirectILLCollectData('ILL/IN4/087294+087295.nxs') + # Compare to simply loading the data + raw = Load('ILL/IN4/087294+087295.nxs') + # The workspace loaded by 'Load' includes monitor data which + # makes 2D plotting difficult + nRaw = raw.getNumberHistograms() + print("Number of histograms in 'raw': {}".format(raw.getNumberHistograms()) + + ", and in 'preprocessed': {}".format(preprocessed.getNumberHistograms())) + # Notably, DirectILLCollectData sets the workspace up such that conversion + # from TOF to wavelength produces the correct values + preprocessed_wl = ConvertUnits(preprocessed, 'Wavelength') + raw_wl = ConvertUnits(raw, 'Wavelength') + # Elastic peak is around channel 150 + print('Wavelength from sample logs: {:.3}A'.format(raw.run().getProperty('wavelength').value)) + print("'raw' wavelength at channel 150: {:.3}A (incorrect!)".format(raw_wl.readX(0)[149])) + print("'preprocessed' wavelength at channel 150: {:.3}A".format(preprocessed_wl.readX(0)[149])) Output: -.. testoutput:: FakeIN4Example +.. testoutput:: IN4Example - TOF offset without corrections: 530.0 microseconds - Corrected TOF offset: 380.1 microseconds + Number of histograms in 'raw': 397, and in 'preprocessed': 396 + Wavelength from sample logs: 3.06A + 'raw' wavelength at channel 150: 1.63A (incorrect!) + 'preprocessed' wavelength at channel 150: 3.05A .. categories:: diff --git a/docs/source/algorithms/DirectILLDiagnostics-v1.rst b/docs/source/algorithms/DirectILLDiagnostics-v1.rst index 8c67d95752d410c4becafcd0392e218ef24abcb2..5566069515ba93334355d646f3f36791e56f5328 100644 --- a/docs/source/algorithms/DirectILLDiagnostics-v1.rst +++ b/docs/source/algorithms/DirectILLDiagnostics-v1.rst @@ -47,8 +47,8 @@ The masking procedure proceeds as follows: #. Mark all spectra from the middle of the range to the threshold spectrum as masked. #. Repeat for the other half. -Defaul mask -########### +Default mask +############ The default mask file is defined by the 'Workflow.MaskFile' instrument parameter. @@ -101,97 +101,85 @@ The following settings are used when not explicitly overwritten by the algorithm Usage ----- -**Example - Diagnostics on fake IN4 workspace** +For usage of this algorithm as part of the direct geometry data reduction, check the examples :ref:`here <DirectILL>`. -.. testcode:: FakeIN4Example +.. include:: ../usagedata-note.txt + +**Example - Diagnostics on IN4 workspace** + +.. testsetup:: IN4Example + + config['default.facility'] = 'ILL' + config['default.instrument'] = 'IN4' + +.. testcode:: IN4Example - import numpy - import scipy.stats - - # Create a fake IN4 workspace. - # We need an instrument and a template first. - empty_IN4 = LoadEmptyInstrument(InstrumentName='IN4') - nHist = empty_IN4.getNumberHistograms() - # Make TOF bin edges. - xs = numpy.arange(530.0, 2420.0, 4.0) - # Make some Gaussian spectra. - ys = 1000.0 * scipy.stats.norm.pdf(xs[:-1], loc=970, scale=60) - # Repeat data for each histogram. - xs = numpy.tile(xs, nHist) - ys = numpy.tile(ys, nHist) - ws = CreateWorkspace( - DataX=xs, - DataY=ys, - NSpec=nHist, - UnitX='TOF', - ParentWorkspace=empty_IN4 - ) - # Set some histograms to zero to see if the diagnostics can catch them. - ys = ws.dataY(13) - ys *= 0.0 - ys = ws.dataY(101) - ys *= 0.0 - - # Manually correct monitor spectrum number as LoadEmptyInstrument does - # not know about such details. - SetInstrumentParameter( - Workspace=ws, - ParameterName='default-incident-monitor-spectrum', - ParameterType='Number', - Value=str(1) - ) - # Add incident energy information to sample logs. - AddSampleLog( - Workspace=ws, - LogName='Ei', - LogText=str(57), - LogType='Number', - LogUnit='meV', - NumberType='Double' - ) - # Elastic channel information is missing in the sample logs. - # It can be given as single valued workspace, as well. - elasticChannelWS = CreateSingleValuedWorkspace(107) - DirectILLCollectData( - InputWorkspace=ws, + Run='ILL/IN4/087283-087290.nxs', OutputWorkspace='preprocessed', - ElasticChannelWorkspace=elasticChannelWS, - IncidentEnergyCalibration='Energy Calibration OFF', # Normally we would do this for IN4. - OutputEPPWorkspace='epps' # Needed for the diagnostics. + OutputRawWorkspace='raw', # Needed for the diagnostics + OutputEPPWorkspace='epps' # Needed for the diagnostics ) diagnostics = DirectILLDiagnostics( - InputWorkspace='preprocessed', - OutputWorkspace='diagnosed', + InputWorkspace='raw', # Use 'raw' rather than 'preprocessed' for background diagnostics + OutputWorkspace='mask', # A special MaskWorkspace EPPWorkspace='epps', - NoisyBkgLowThreshold=0.01, + MaskedComponents='rosace', OutputReportWorkspace='diagnostics_report' ) - print(diagnostics.OutputReport) - print('Some small-angle detectors got diagnosed as bad due to detector solid angle corrections.') - report = mtd['diagnostics_report'] - I0 = report.cell('ElasticIntensity', 0) - I304 = report.cell('ElasticIntensity', 303) - print('Solid-angle corrected elastic intensity of spectrum 1: {:.8}'.format(I0)) - print('vs. corrected intensity of spectrum 304: {:.8}'.format(I304)) Output: -.. testoutput:: FakeIN4Example +.. testoutput:: IN4Example Spectra masked by default mask file: None Spectra masked by beam stop diagnostics: None Additional spectra marked as bad by elastic peak diagnostics: - 14, 102, 302-305, 314-317, 326-329, 338-341, 350-353, 362-365, 374-377, 386-389 + 13, 40, 51, 64, 72-73, 78-79, 81-83, 100-101, 139, 150-151, 165, 173, 180-181, 183-184, 213, 239-240, 264, 272-273, 278-279, 281-283, 300-308, 313-320, 325-331, 337-344, 348-354, 361-366, 373-376, 378, 385-391 Additional spectra marked as bad by flat background diagnostics: - 14, 102 - Some small-angle detectors got diagnosed as bad due to detector solid angle corrections. - Solid-angle corrected elastic intensity of spectrum 1: 555524.7 - vs. corrected intensity of spectrum 304: 1795774.9 + 13, 100-101, 132, 213, 300-309, 313-319, 321, 325-331, 337-343, 345, 348-357, 361-367, 373-378, 381, 385-391 + +**Example - Default and beam stop masks on IN5 workspace** + +.. testsetup:: IN5Example + + config['default.facility'] = 'ILL' + config['default.instrument'] = 'IN4' + +.. testcode:: IN5Example + + # On IN5 we don't usually diagnose the pixels, but apply + # a hark mask + beam stop mask. + DirectILLCollectData( + Run='ILL/IN5/104007.nxs', + OutputWorkspace='preprocessed', + ) + DirectILLDiagnostics( + InputWorkspace='preprocessed', # Any IN5 workspace goes, doesn't have to be 'raw' + OutputWorkspace='mask', # A special MaskWorkspace + OutputReportWorkspace='report' + ) + # Read some data from the report table workspace + report = mtd['report'] + default_column = report.column('DefaultMask') + beam_stop_column = report.column('BeamStopMask') + print('Total number of pixels masked by default mask: {}'.format(int(sum(default_column)))) + print('Total number of pixels masked under beam stop: {}'.format(int(sum(beam_stop_column)))) + +.. testoutput:: IN5Example + + Total number of pixels masked by default mask: 7261 + Total number of pixels masked under beam stop: 2457 + +The figure below shows the mask produced by the IN5 example script above. The green pixels show the default hard mask and the beam stop. + +.. figure:: ../images/DiagnosticsMaskIN5.png + :alt: Default and beam stop masks of IN5 spectrometer. + .. categories:: diff --git a/docs/source/algorithms/DirectILLIntegrateVanadium-v1.rst b/docs/source/algorithms/DirectILLIntegrateVanadium-v1.rst index e5b620a4f35b658f1449a59425bc6c0255f315f0..3ce3c3ec3cb58701d2d7281cf0e0f0d85cfc3075 100644 --- a/docs/source/algorithms/DirectILLIntegrateVanadium-v1.rst +++ b/docs/source/algorithms/DirectILLIntegrateVanadium-v1.rst @@ -22,84 +22,12 @@ The *InputWorkspace* should be loaded using the :ref:`DirectILLCollectData <algm Vanadium temperature #################### -A correction for the Debye-Waller factor is applied to the integrated vanadium, as explained in the documentation of :ref:`ComputeCalibrationCoefVan <algm-ComputeCalibrationCoefVan>`. The temperature for the DWF calculation is taken from the 'Sample.temperature' sample log of the *InputWorkspace*. This value can be overriden by the *Temperature* property, if needed. +A correction for the Debye-Waller factor is applied to the integrated vanadium, as explained in the documentation of :ref:`ComputeCalibrationCoefVan <algm-ComputeCalibrationCoefVan>`. The temperature for the DWF calculation is taken from the 'Sample.temperature' sample log of the *InputWorkspace*. This value can be overridden by the *Temperature* property, if needed. Usage ----- -**Example - Integrating fake IN4 workspace** - -.. testcode:: FakeIN4Example - - import numpy - import scipy.stats - - # Create a fake IN4 workspace. - # We need an instrument and a template first. - empty_IN4 = LoadEmptyInstrument(InstrumentName='IN4') - nHist = empty_IN4.getNumberHistograms() - # Make TOF bin edges. - xs = numpy.arange(530.0, 2420.0, 4.0) - # Make some Gaussian spectra. - ys = 1000.0 * scipy.stats.norm.pdf(xs[:-1], loc=970, scale=60) - # Repeat data for each histogram. - xs = numpy.tile(xs, nHist) - ys = numpy.tile(ys, nHist) - ws = CreateWorkspace( - DataX=xs, - DataY=ys, - NSpec=nHist, - UnitX='TOF', - ParentWorkspace=empty_IN4 - ) - # Manually correct monitor spectrum number as LoadEmptyInstrument does - # not know about such details. - SetInstrumentParameter( - Workspace=ws, - ParameterName='default-incident-monitor-spectrum', - ParameterType='Number', - Value=str(1) - ) - # Add incident energy information to sample logs. - AddSampleLog( - Workspace=ws, - LogName='Ei', - LogText=str(57), - LogType='Number', - LogUnit='meV', - NumberType='Double' - ) - # Elastic channel information is missing in the sample logs. - # It can be given as single valued workspace, as well. - elasticChannelWS = CreateSingleValuedWorkspace(107) - - # Prepare the workspace for integration. - # We also need the elastic peak position table (EPP). - DirectILLCollectData( - InputWorkspace=ws, - OutputWorkspace='preprocessed', - ElasticChannelWorkspace=elasticChannelWS, - IncidentEnergyCalibration='Energy Calibration OFF', # Normally enabled for IN4. - OutputEPPWorkspace='epps' - ) - - DirectILLIntegrateVanadium( - InputWorkspace='preprocessed', - OutputWorkspace='norm-factors', - EPPWorkspace='epps', - DebyeWallerCorrection='Correction OFF', - Temperature=293 - ) - - norms = mtd['norm-factors'] - print('Integrated vanadium contains {} bin in each of {} histograms.' - .format(norms.blocksize(), norms.getNumberHistograms())) - -Output: - -.. testoutput:: FakeIN4Example - - Integrated vanadium contains 1 bin in each of 396 histograms. +For usage of this algorithm, check the examples :ref:`here <DirectILL>`. .. categories:: diff --git a/docs/source/algorithms/DirectILLReduction-v1.rst b/docs/source/algorithms/DirectILLReduction-v1.rst index f55793e985d3de9d0618aad8fbeb0b5aeeb8556a..adcf1ac68ca6b21d74608697327f2fe29c930ca8 100644 --- a/docs/source/algorithms/DirectILLReduction-v1.rst +++ b/docs/source/algorithms/DirectILLReduction-v1.rst @@ -57,126 +57,7 @@ After conversion to momentum transfer, the vertical axis of the data is in units Usage ----- -**Example - Fake IN4 workspace reduction** - -.. testcode:: FakeIN4Example - - from mantid.kernel import DeltaEModeType, UnitConversion - import numpy - import scipy.stats - - # Create a fake IN4 workspace. - # We need an instrument and a template first. - empty_IN4 = LoadEmptyInstrument(InstrumentName='IN4') - nHist = empty_IN4.getNumberHistograms() - # Make TOF bin edges. - xs = numpy.arange(530.0, 2420.0, 4.0) - # Make some Gaussian spectra. - ys = 1000.0 * scipy.stats.norm.pdf(xs[:-1], loc=970, scale=60) - # Repeat data for each histogram. - xs = numpy.tile(xs, nHist) - ys = numpy.tile(ys, nHist) - ws = CreateWorkspace( - DataX=xs, - DataY=ys, - NSpec=nHist, - UnitX='TOF', - ParentWorkspace=empty_IN4 - ) - # Set some histograms to zero for detector diagnostics. - ys = ws.dataY(13) - ys *= 0.0 - ys = ws.dataY(101) - ys *= 0.0 - - # Manually correct monitor spectrum number as LoadEmptyInstrument does - # not know about such details. - SetInstrumentParameter( - Workspace=ws, - ParameterName='default-incident-monitor-spectrum', - ParameterType='Number', - Value=str(1) - ) - # Add incident energy information to sample logs. - AddSampleLog( - Workspace=ws, - LogName='Ei', - LogText=str(57), - LogType='Number', - LogUnit='meV', - NumberType='Double' - ) - # Add wavelength to sample logs - wl = UnitConversion.run('Energy', 'Wavelength', 57.0, 0.0, 0.0, 0.0, DeltaEModeType.Direct, 0.0) - AddSampleLog( - Workspace=ws, - LogName='wavelength', - LogText=str(wl), - LogType='Number', - LogUnit='Angstrom', - NumberType='Double' - ) - # Elastic channel information is missing in the sample logs. - # It can be given as single valued workspace, as well. - elasticChannelWS = CreateSingleValuedWorkspace(107) - - # Create a fake 'vanadium' reference workspace. - V_ws = Scale( - InputWorkspace=ws, - Factor=1.3 - ) - - # Process vanadium. - DirectILLCollectData( - InputWorkspace=V_ws, - OutputWorkspace='vanadium', - ElasticChannelWorkspace=elasticChannelWS, - IncidentEnergyCalibration='Energy Calibration OFF', # Normally we would do this for IN4. - OutputEPPWorkspace='epps' # Needed for diagnostics and integration. - ) - - DirectILLDiagnostics( - InputWorkspace='vanadium', - OutputWorkspace='diagnostics_mask', - EPPWorkspace='epps', - MaskedComponents='rosace', #Exclude small-angle detectors. - ) - - DirectILLIntegrateVanadium( - InputWorkspace='vanadium', - OutputWorkspace='vanadium_factors', - SubalgorithmLogging='Logging ON', - EPPWorkspace='epps', - Temperature=273.0 - ) - - # Process sample. - DirectILLCollectData( - InputWorkspace=ws, - OutputWorkspace='preprocessed', - ElasticChannelWorkspace=elasticChannelWS, - IncidentEnergyCalibration='Energy Calibration OFF' - ) - - # Absorption corrections and empty container subtractions could be added here. - - DirectILLReduction( - InputWorkspace='preprocessed', - OutputWorkspace='SofQW', - IntegratedVanadiumWorkspace='vanadium_factors', - DiagnosticsWorkspace='diagnostics_mask' - ) - - sofqw = mtd['SofQW'] - nHist = sofqw.getNumberHistograms() - nBin = sofqw.blocksize() - print('Size of the final S(q,w) workspace: {} histograms, {} bins'.format(nHist, nBin)) - -Output: - -.. testoutput:: FakeIN4Example - - Size of the final S(q,w) workspace: 177 histograms, 260 bins +For usage of this algorithm, check the examples :ref:`here <DirectILL>`. .. categories:: diff --git a/docs/source/algorithms/DirectILLSelfShielding-v1.rst b/docs/source/algorithms/DirectILLSelfShielding-v1.rst index 19f7c866da4e44d9c8fbc98ed030c2e0ea07909a..63fea876412c2289d15b7d7d0ac5b0aef293ab04 100644 --- a/docs/source/algorithms/DirectILLSelfShielding-v1.rst +++ b/docs/source/algorithms/DirectILLSelfShielding-v1.rst @@ -20,97 +20,7 @@ The correction factor contained within the *OutputWorkspace* can be further fed Usage ----- -**Example - Absorption corrections of fake IN4 workspace** - -.. testcode:: FakeIN4Example - - import numpy - import scipy.stats - - # Create a fake IN4 workspace. - # We need an instrument and a template first. - empty_IN4 = LoadEmptyInstrument(InstrumentName='IN4') - nHist = empty_IN4.getNumberHistograms() - # Make TOF bin edges. - xs = numpy.arange(530.0, 2420.0, 4.0) - # Make some Gaussian spectra. - ys = 1000.0 * scipy.stats.norm.pdf(xs[:-1], loc=970, scale=60) - # Repeat data for each histogram. - xs = numpy.tile(xs, nHist) - ys = numpy.tile(ys, nHist) - ws = CreateWorkspace( - DataX=xs, - DataY=ys, - NSpec=nHist, - UnitX='TOF', - ParentWorkspace=empty_IN4 - ) - # Manually correct monitor spectrum number as LoadEmptyInstrument does - # not know about such details. - SetInstrumentParameter( - Workspace=ws, - ParameterName='default-incident-monitor-spectrum', - ParameterType='Number', - Value=str(1) - ) - # Add incident energy information to sample logs. - AddSampleLog( - Workspace=ws, - LogName='Ei', - LogText=str(57), - LogType='Number', - LogUnit='meV', - NumberType='Double' - ) - # Elastic channel information is missing in the sample logs. - # It can be given as single valued workspace, as well. - elasticChannelWS = CreateSingleValuedWorkspace(107) - - DirectILLCollectData( - InputWorkspace=ws, - OutputWorkspace='preprocessed', - ElasticChannelWorkspace=elasticChannelWS, - IncidentEnergyCalibration='Energy Calibration OFF', # Normally we would do this for IN4. - ) - - sampleGeometry = { - 'Shape': 'Cylinder', - 'Height': 8.0, - 'Radius': 1.5, - 'Center': [0.0, 0.0, 0.0] - } - sampleMaterial = { - 'ChemicalFormula': 'V', - 'SampleNumberDensity': 0.05 - } - SetSample( - InputWorkspace='preprocessed', - Geometry=sampleGeometry, - Material=sampleMaterial - ) - - DirectILLSelfShielding( - InputWorkspace='preprocessed', - OutputWorkspace='absorption_corrections', - SimulationInstrument='Full Instrument', # IN4 is small enough. - NumberOfSimulatedWavelengths=10 - ) - # The correction factors should be applied using DirectILLApplySelfShielding. - corrections = mtd['absorption_corrections'] - f_short = corrections.readY(0)[0] - f_long = corrections.readY(0)[-1] - print('Absoprtion corrections factors for detector 1') - print('Short final wavelengths: {:.4f}'.format(f_short)) - print('Long final wavelengths: {:.4f}'.format(f_long)) - -Output: - -.. testoutput:: FakeIN4Example - :options: +ELLIPSIS +NORMALIZE_WHITESPACE - - Absoprtion corrections factors for detector 1 - Short final wavelengths: 0.4... - Long final wavelengths: 0.2... +For usage of this algorithm, check the examples :ref:`here <DirectILL>`. .. categories:: diff --git a/docs/source/algorithms/DownloadInstrument-v1.rst b/docs/source/algorithms/DownloadInstrument-v1.rst index 198d5a3d4861075cf03119eaa36cb67915038fa5..b4919af049803c8f7e8f2e7a01574397f55cbbce 100644 --- a/docs/source/algorithms/DownloadInstrument-v1.rst +++ b/docs/source/algorithms/DownloadInstrument-v1.rst @@ -21,7 +21,7 @@ Mantid Property Keys The code is configured using he following Mantid.Property, or Mantid.User.Property keys. UpdateInstrumentDefinitions.OnStartup = 1 - This controls wether this algorithm is run on startup of Mantid. 1 = Run on startup, 0 = don't. + This controls whether this algorithm is run on startup of Mantid. 1 = Run on startup, 0 = don't. UpdateInstrumentDefinitions.URL = https://api.github.com/repos/mantidproject/mantid/contents/instrument This stores the url used to access the contents of the Mantid Instrument Definition Repository. @@ -41,7 +41,7 @@ Internet Connection Failed - cannot update instrument definitions. The connection to the instrument Repository failed. This could be down to your network connection, proxy settings (we use the system proxy settings). More details will be logged as another message at information level. Instrument Definition Update: The Github API rate limit has been reached, try again after 19-Feb-2015 11:23:34 - There is a limit of how many calls we are allowed to make to Github per hour. Try again after the time specified. If this keeps occuring let the developement team know. + There is a limit of how many calls we are allowed to make to Github per hour. Try again after the time specified. If this keeps occurring let the development team know. The details ########### @@ -58,7 +58,7 @@ The instrument files within Mantid can be accessed in three locations. When running the algorithm the processing takes the following steps. 1. The description of the contents of the Instrument Repo is downloaded and stored in a file github.json to the Appdata Dir. -2. A file of the desription of xml files in Appdata Dir and Install Dir are updated or created and saved into AppData Dir as install.json and appdata.json. +2. A file of the description of xml files in Appdata Dir and Install Dir are updated or created and saved into AppData Dir as install.json and appdata.json. 3. The contents of all 3 are inspected and new or updated files (based on the git checksum) are added to a download list. 4. The list of files are downloaded to the Appdata Dir. 5. :ref:`algm-LoadInstrument` will load files in Appdata Dir in preference to those in the Install Dir if both are valid. diff --git a/docs/source/algorithms/EnggSaveGSASIIFitResultsToHDF5-v1.rst b/docs/source/algorithms/EnggSaveGSASIIFitResultsToHDF5-v1.rst index 59831dbbb9cb544b2e786560a1fe2b8612c6a6b8..5c48aa059b02ddc26f12e3e0f52aece0ddc7846f 100644 --- a/docs/source/algorithms/EnggSaveGSASIIFitResultsToHDF5-v1.rst +++ b/docs/source/algorithms/EnggSaveGSASIIFitResultsToHDF5-v1.rst @@ -31,7 +31,7 @@ Settings passed to :ref:`GSASIIRefineFitPeaks - **XMin** - the minimum TOF value used for refinement. Note this may not be the same as the **XMin** that you passed to GSASIIRefineFitPeaks, as **XMin** in GSASIIRefineFitPeaks will be - overriden by **PawleyDMin** if the latter corresponds to a greater + overridden by **PawleyDMin** if the latter corresponds to a greater TOF value - **XMax** - the maximum TOF value used for refinement diff --git a/docs/source/algorithms/EnggSaveSinglePeakFitResultsToHDF5-v1.rst b/docs/source/algorithms/EnggSaveSinglePeakFitResultsToHDF5-v1.rst index 7ebaa71f349dc76823c8bc00d77204baa8891164..3d94fbeebf92e2f2f780dbff824cf32c743ca391 100644 --- a/docs/source/algorithms/EnggSaveSinglePeakFitResultsToHDF5-v1.rst +++ b/docs/source/algorithms/EnggSaveSinglePeakFitResultsToHDF5-v1.rst @@ -43,7 +43,7 @@ Usage ----- Ordinarily, we'd get our peak parameters table from EnggFitPeaks, but -we just mock one up here. See :ref:`EnggFitPeaks documenation +we just mock one up here. See :ref:`EnggFitPeaks documentation <algm-EnggFitPeaks-v1>` for how to generate this table. **Example - Export fit params to a new HDF5 file:** diff --git a/docs/source/algorithms/EstimateFitParameters-v1.rst b/docs/source/algorithms/EstimateFitParameters-v1.rst index 6a4c58ed6eca43fc58f910ede21cb1ed22c728f8..b52d962ce0357db3f372d0c10c10e62f345eab80 100644 --- a/docs/source/algorithms/EstimateFitParameters-v1.rst +++ b/docs/source/algorithms/EstimateFitParameters-v1.rst @@ -30,7 +30,7 @@ The algorithm uses one of the two strategies (set via `Type` property): "Monte C Monte Carlo ########### -In this strategy a number (defined by `NSamples` property) of paramter sets are generated and the one that +In this strategy a number (defined by `NSamples` property) of parameter sets are generated and the one that gives the smallest cost function is considered the winner. These best parameters are set to `Function` property (it has the `InOut` direction). diff --git a/docs/source/algorithms/ExaminePowderDiffProfile-v1.rst b/docs/source/algorithms/ExaminePowderDiffProfile-v1.rst index 78612391ca1fa4705607cff6a41b85fe32f19292..26143b44ab996d835aaabff1cb55d09d81aeed5b 100644 --- a/docs/source/algorithms/ExaminePowderDiffProfile-v1.rst +++ b/docs/source/algorithms/ExaminePowderDiffProfile-v1.rst @@ -18,7 +18,7 @@ processing background and calculating peaks by Le Bail algorithm. Usage ----- -**Example - Calcualte peaks from input table workspaces** +**Example - Calculate peaks from input table workspaces** .. testcode:: ExExaminePG3Profile diff --git a/docs/source/algorithms/ExportExperimentLog-v1.rst b/docs/source/algorithms/ExportExperimentLog-v1.rst index 19be177823c599db598e6a58c0d6a1bb5fabae0e..6b13a6e6157381ee7329e0f8d4a16b5bb73783c2 100644 --- a/docs/source/algorithms/ExportExperimentLog-v1.rst +++ b/docs/source/algorithms/ExportExperimentLog-v1.rst @@ -70,7 +70,7 @@ File format ----------- There are two types of output file formats that are supported. They are -csv (comma seperated) file and tsv (tab separated) file. The csv file +csv (comma separated) file and tsv (tab separated) file. The csv file must have an extension as ".csv". If a user gives the name of a log file, which is in csv format, does not have an extension as .csv, the algorithm will correct it automatically. diff --git a/docs/source/algorithms/ExportGeometry-v1.rst b/docs/source/algorithms/ExportGeometry-v1.rst index 1318b1a78527ee8a9c5ad6b3d9836e303ad0c11e..4f48153a878ebbfdb40377644f22b1be8403ce9e 100644 --- a/docs/source/algorithms/ExportGeometry-v1.rst +++ b/docs/source/algorithms/ExportGeometry-v1.rst @@ -13,7 +13,7 @@ Description This algorithm is intended to write out portions of an instrument's geometry. The resulting file is mean to be copied by-hand into a geometry file. The main use of this is if the instrument geometry is -calibrated in mantid, this algorithm can be used ot help get the +calibrated in mantid, this algorithm can be used to help get the information back into the initial instrument definition file. Usage diff --git a/docs/source/algorithms/ExportSampleLogsToCSVFile-v1.rst b/docs/source/algorithms/ExportSampleLogsToCSVFile-v1.rst index 085c78f0e285edac366f336693663985c2356ec8..3a7f8b6f10502e5f82c9d4111385152850be9a74 100644 --- a/docs/source/algorithms/ExportSampleLogsToCSVFile-v1.rst +++ b/docs/source/algorithms/ExportSampleLogsToCSVFile-v1.rst @@ -12,7 +12,7 @@ Description 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. +be created by this algorithm in a separate *header* file. CSV File format ############### diff --git a/docs/source/algorithms/ExportTimeSeriesLog-v1.rst b/docs/source/algorithms/ExportTimeSeriesLog-v1.rst index 139228477de64cf180388fb5e03cda600e9f86e3..29e7fde322b7978b148052b56dc61482cf2fd27a 100644 --- a/docs/source/algorithms/ExportTimeSeriesLog-v1.rst +++ b/docs/source/algorithms/ExportTimeSeriesLog-v1.rst @@ -12,7 +12,7 @@ Description Export a sample log, which is of type TimeSeriesProperty, in a Workspace to a MatrixWorkspace. The output workspace can be either a MatrixWorkspace or an EventWorkspace. -If the output workspace is choosen to be an EventWorkspace, there are some limitations to it. +If the output workspace is chosen to be an EventWorkspace, there are some limitations to it. Output TimeSeries Log to MatrixWorkspace ######################################## diff --git a/docs/source/algorithms/ExtractFFTSpectrum-v1.rst b/docs/source/algorithms/ExtractFFTSpectrum-v1.rst index d87dd5f5888b8913878be7e2afecbd89c82967a0..9f57a8a8197c5ca98edd8ff8080359154c99b431 100644 --- a/docs/source/algorithms/ExtractFFTSpectrum-v1.rst +++ b/docs/source/algorithms/ExtractFFTSpectrum-v1.rst @@ -60,7 +60,7 @@ Usage from __future__ import print_function import numpy - # Funtions x and y defined over the time domain: z(t) = x(t) + i * y(t) + # Functions x and y defined over the time domain: z(t) = x(t) + i * y(t) dt=0.001 t=numpy.arange(-1,1,dt) diff --git a/docs/source/algorithms/FakeISISEventDAE-v1.rst b/docs/source/algorithms/FakeISISEventDAE-v1.rst index 34a928799ebb54bbf152812ac52ac01efaa304aa..728da060012c9600429455a6201dd6a623f9a3db 100644 --- a/docs/source/algorithms/FakeISISEventDAE-v1.rst +++ b/docs/source/algorithms/FakeISISEventDAE-v1.rst @@ -81,7 +81,7 @@ Usage # put back the facility ConfigService.setFacility(oldFacility) - #get the ouput workspace + #get the output workspace wsOut = mtd["wsOut"] print("The workspace contains %i events" % wsOut.getNumberEvents()) diff --git a/docs/source/algorithms/FakeISISHistoDAE-v1.rst b/docs/source/algorithms/FakeISISHistoDAE-v1.rst index 6cbe8c7711f5fc23fe8da78f72c276a675f400d0..95db339bfa08f9640bb12850fc6b8070a904e227 100644 --- a/docs/source/algorithms/FakeISISHistoDAE-v1.rst +++ b/docs/source/algorithms/FakeISISHistoDAE-v1.rst @@ -70,7 +70,7 @@ Usage # put back the facility ConfigService.setFacility(oldFacility) - #get the ouput workspace + #get the output workspace wsOut = mtd["wsOut"] print("The workspace contains %i histograms" % wsOut.getNumberHistograms()) diff --git a/docs/source/algorithms/FilterEvents-v1.rst b/docs/source/algorithms/FilterEvents-v1.rst index 3697e881b78c2552e5f2c8ebb64cd4b1baa6a620..b45de531098b1640271f410a12797f88f29a7f4a 100644 --- a/docs/source/algorithms/FilterEvents-v1.rst +++ b/docs/source/algorithms/FilterEvents-v1.rst @@ -98,7 +98,7 @@ Some events are not inside any splitters. They are put to a workspace name ended with '\_unfiltered'. If input property 'OutputWorkspaceIndexedFrom1' is set to True, then -this workspace shall not be outputed. +this workspace shall not be outputted. Using FilterEvents with fast-changing logs ########################################## diff --git a/docs/source/algorithms/FindPeaks-v1.rst b/docs/source/algorithms/FindPeaks-v1.rst index 7e0ca332f4876b2813bd9398f3a2da7756aa12fe..8cb7386be8f7cdc53b8a0ef93b6ca87ffa71a66d 100644 --- a/docs/source/algorithms/FindPeaks-v1.rst +++ b/docs/source/algorithms/FindPeaks-v1.rst @@ -46,7 +46,7 @@ recorded best background and peak parameters as the starting values. Criteria To Validate Peaks Found ################################ -FindPeaks finds peaks by fitting a Guassian with background to a certain +FindPeaks finds peaks by fitting a Gaussian with background to a certain range in the input histogram. :ref:`algm-Fit` may not give a correct result even if chi^2 is used as criteria alone. Thus some other criteria are provided as options to validate the result @@ -72,11 +72,11 @@ If FindPeaksBackground fails, then it is necessary to estimate a rough peak rang observed data. #. Assume the local background (within the given fitting window) is close to linear; -#. Take the first 3 and last 3 data points to calcualte the linear background; -#. Remove background (rougly) and calcualte peak's height, width, and centre; +#. Take the first 3 and last 3 data points to calculate the linear background; +#. Remove background (roughly) and calculate peak's height, width, and centre; #. If the peak centre (starting value) uses observed value, then set peakcentre to that value. Otherwise, set it to given value; #. Get the bin indexes of xmin, xmax and peakcentre; -#. Calcualte peak range, i.e., left and right boundary; +#. Calculate peak range, i.e., left and right boundary; #. If any peak boundary exceeds or too close to the boundary, there will be 2 methods to solve this issue; #. If peak centre is restricted to given value, then the peak range will be from 1/6 to 5/6 of the given data points; diff --git a/docs/source/algorithms/FindPeaksMD-v1.rst b/docs/source/algorithms/FindPeaksMD-v1.rst index 48f18985df86a044e7c1f615d2ce8d490ad3e582..453f7ea2021e6502196dc6737592f77fc7e719c7 100644 --- a/docs/source/algorithms/FindPeaksMD-v1.rst +++ b/docs/source/algorithms/FindPeaksMD-v1.rst @@ -46,7 +46,7 @@ is not accessible. It may give better results on For data which has originally been based on histogram-type data and that has been converted to -event-based data it migth be beneficial to select the NumberOfEventNormalization for the `PeakFindingStrategy` property instead of the VolumeNormalization which is the default. This +event-based data it might be beneficial to select the NumberOfEventNormalization for the `PeakFindingStrategy` property instead of the VolumeNormalization which is the default. This will disable the `DensityThresholdFactor` property and enable the `SignalThresholdFactor` property. The algorithmic steps remain the same as above but instead of using the signal density as the sorting quantity the signal count (total weighted event sum divided by the number of events) is used. If @@ -136,7 +136,7 @@ Usage The code iteslef works but disabled from doc tests as takes too long to complete. User should provide its own event nexus file instead of **TOPAZ_3132_event.nxs** used within this example. The original **TOPAZ_3132_event.nxs** -file is availible in `Mantid system tests repository <https://github.com/mantidproject/systemtests/tree/master/Data/TOPAZ_3132_event.nxs>`_. +file is available in `Mantid system tests repository <https://github.com/mantidproject/systemtests/tree/master/Data/TOPAZ_3132_event.nxs>`_. .. code-block:: python diff --git a/docs/source/algorithms/FindSatellitePeaks-v1.rst b/docs/source/algorithms/FindSatellitePeaks-v1.rst index 0919add7283f98eb3ff70e002e07d3ee396b762e..c157ea7a54c6aea666a656a55e782f76b302b9fb 100644 --- a/docs/source/algorithms/FindSatellitePeaks-v1.rst +++ b/docs/source/algorithms/FindSatellitePeaks-v1.rst @@ -28,7 +28,7 @@ and satellite are computed in the HKL frame. Peaks are then grouped according to euclidean distance using using the properties `NumOfQs` and `ClusterThreshold`. If `NumOfQs` is specified then each offset will be grouped into exactly `k` clusters. If `ClusterThreshold` is specified then offsets will -be grouped into clusters seperated by no more than a cophenetic distance below +be grouped into clusters separated by no more than a cophenetic distance below this threshold. The centroid of each cluster calculated for each group and is used as the offset to predict the location of fractional peaks everywhere in the :ref:`MDWorkspace <MDWorkspace>`. @@ -42,7 +42,7 @@ the :ref:`MDWorkspace <MDWorkspace>`. vary slightly. This algorithm calculates the `q` vectors for all peaks passed as starting points into distinct sets of `q` vectors. The centroid of each cluster is then taken as the "true" value of `q` and is used to predict the - postion of all other fractional peaks with this `q`. + position of all other fractional peaks with this `q`. For each predicted fractional peak, the local centroid (the radius of which is @@ -64,7 +64,7 @@ discarded if there I/sigma value is less than the parameter `IOverSigma`. satellite peak (orange). The area to search for the centroid is controlled by the `PeakRadius` parameter. All centroids are integrated a filtered by intensity and :math:`\frac{I}{\sigma}`. If the experimental satellite has - zero intesity or is below the :math:`\frac{I}{\sigma}` threshold then it is + zero intensity or is below the :math:`\frac{I}{\sigma}` threshold then it is discarded. @@ -90,7 +90,7 @@ For more information on superspace crystallography see: Related Algorithms ------------------ - :ref:`PredictFractionalPeaks <algm-PredictFractionalPeaks-v1>` predicts the - postion of fractional peaks given a :ref:`PeaksWorkspace <PeaksWorkspace>` of + position of fractional peaks given a :ref:`PeaksWorkspace <PeaksWorkspace>` of nuclear peaks and a set of HKL offsets. - :ref:`CentroidPeaksMD <algm-CentroidPeaksMD-v2>` is used to find the local diff --git a/docs/source/algorithms/FitGaussian-v1.rst b/docs/source/algorithms/FitGaussian-v1.rst index c6f36f47c7496eb5c14e9d951c260575a8aca6d6..08f2481c4ce517e2dc5066d4596e4234f0162baa 100644 --- a/docs/source/algorithms/FitGaussian-v1.rst +++ b/docs/source/algorithms/FitGaussian-v1.rst @@ -20,7 +20,7 @@ Input and Output ################ The input parameters are a histogram workspace and the index of the histogram. -The ouput parameters are the fitted peak centre and sigma. If the data could not +The output parameters are the fitted peak centre and sigma. If the data could not be fitted, 0.0 is returned as both the peak centre and sigma values and a warning message is logged. Errors in parameters raise RuntimeError. diff --git a/docs/source/algorithms/FitPeak-v1.rst b/docs/source/algorithms/FitPeak-v1.rst index 47a93d71844c2e5bc701033a6e5a8460e177eec7..7d314bd6cf99abae563eb421fe9ec118d8307eb9 100644 --- a/docs/source/algorithms/FitPeak-v1.rst +++ b/docs/source/algorithms/FitPeak-v1.rst @@ -68,7 +68,7 @@ FindPeaks uses a more complicated approach to fit peaks if '''HighBackground''' Simple fit ========== In the 'simple fit' mode, the algorithm will make a composite function including -peak and background function and fit it agains the observed data. +peak and background function and fit it against the observed data. It works well with good starting values of the peak and background function, especially when the peak is significant with low background. @@ -79,7 +79,7 @@ High background fit In the 'high background fit' mode, the background will be removed first; then the fitting is focussed on the 'pure' peak function; -and a composite function is fit agains the original data as the last step. +and a composite function is fit against the original data as the last step. This approach is developed due to the failure of 'simple fit' mode on the cases that background level is much higher than the peak height. @@ -91,13 +91,13 @@ Starting values of the peak function ==================================== * Peak height is estimated by the maximum value, with background removed, inside the peak range; -* Peak position can be set up either to the X value of the maximum Y value in the peak range, or to the vlaue specified by user accordin to user's selection. For example, in the case of calibrating the offsets of detectors of powder diffractometers, the peak positons are unknown. Then it is better to use the X value with the maximum Y value as the starting peak centre. While in the case of striping vanadium peaks, all peaks' centres should be exactly same as the theortical values. +* Peak position can be set up either to the X value of the maximum Y value in the peak range, or to the value specified by user accordin to user's selection. For example, in the case of calibrating the offsets of detectors of powder diffractometers, the peak positions are unknown. Then it is better to use the X value with the maximum Y value as the starting peak centre. While in the case of striping vanadium peaks, all peaks' centres should be exactly same as the theortical values. Criteria To Validate Peaks Found ================================ -FindPeaks finds peaks by fitting a Guassian with background to a certain +FindPeaks finds peaks by fitting a Gaussian with background to a certain range in the input histogram. :ref:`algm-Fit` may not give a correct result even if chi^2 is used as criteria alone. Thus some other criteria are provided as options to validate the result diff --git a/docs/source/algorithms/FitPeaks-v1.rst b/docs/source/algorithms/FitPeaks-v1.rst index 031e671192894e36205a85b65223ed920ef3ee91..13ae63122e895b635c29fc997521ef34c5472691 100644 --- a/docs/source/algorithms/FitPeaks-v1.rst +++ b/docs/source/algorithms/FitPeaks-v1.rst @@ -302,7 +302,7 @@ FittedPeaksWorkspace It is an optional output :py:obj:`MatrixWorkspace <mantid.api.MatrixWorkspace>`. -For each spectrum, in each fit window, the Y values will be replaced by the calcualted peak and background value. +For each spectrum, in each fit window, the Y values will be replaced by the calculated peak and background value. If fitting is bad, then only background is calculated. diff --git a/docs/source/algorithms/GenerateEventsFilter-v1.rst b/docs/source/algorithms/GenerateEventsFilter-v1.rst index 3bd3a0ede0018a5de42d7b73bb8bec6e9873ad78..0cb34fa7ebfc7e314ced1a60d3a53eefbef61fd2 100644 --- a/docs/source/algorithms/GenerateEventsFilter-v1.rst +++ b/docs/source/algorithms/GenerateEventsFilter-v1.rst @@ -105,7 +105,7 @@ If the size of the array is one, then all event splitters will have the same dur of time. In general if the array is composed as :math:`t_1, t_2, \cdots, t_n`, and :math:`T_0` is the run start time, -then the event splitters will have the time boudaries as +then the event splitters will have the time boundaries as .. math:: (T_0, T_0+t_1), (T_0+t_1, T_0+t_1+t_2), \cdots, (T_0+\sum_{i=1}^{n-1}t_i, T_0+\sum_{i=1}^nt_i), (T_0+\sum_{i=1}^nt_i, T_0+\sum_{i=1}^nt_i+t_1), \cdots @@ -197,7 +197,7 @@ Integer value log It is a little bit different for sample log recorded with integer. -- ``MinimumLogValue`` and ``MaximumLogValue`` can be same such that only entries with exacly the same log value +- ``MinimumLogValue`` and ``MaximumLogValue`` can be same such that only entries with exactly the same log value will be considered; - If ``LogValueInterval`` is not give (i.e., default value is used), then any log enetry with log value larger and equal to ``MinimumLogValue`` and smaller and equal to ``MaximumLogValue`` will be considered. diff --git a/docs/source/algorithms/GeneratePeaks-v1.rst b/docs/source/algorithms/GeneratePeaks-v1.rst index bd8e69b466f4b2762b3d68bfb1e67de27d79823c..cfdd2b1bd7aefe45eae7bdb6bc15fb0bf2188b79 100644 --- a/docs/source/algorithms/GeneratePeaks-v1.rst +++ b/docs/source/algorithms/GeneratePeaks-v1.rst @@ -1,4 +1,4 @@ -.. algorithm:: +.. algorithm:: .. summary:: diff --git a/docs/source/algorithms/GetDetOffsetsMultiPeaks-v1.rst b/docs/source/algorithms/GetDetOffsetsMultiPeaks-v1.rst index cf7c75e13ccfbc30b61cf18453b9aaf1c5087171..b44830d6381e9df6e399ebb92aaab90479c68b00 100644 --- a/docs/source/algorithms/GetDetOffsetsMultiPeaks-v1.rst +++ b/docs/source/algorithms/GetDetOffsetsMultiPeaks-v1.rst @@ -70,7 +70,7 @@ If neither of these 2 properties are correctly specified, then then there won't Uniform fit window ================== -By specifying a postive float, maxWidth, for 'FitWindowMaxWidth', +By specifying a positive float, maxWidth, for 'FitWindowMaxWidth', it is the definition of fit window for peaks indexed from 0 to N-1: - Peak 0: window = :math:`\min((X0_0-dmin), maxWidth)`, :math:`\min((X0_1-X0_0)/2,maxWidth)` @@ -134,7 +134,7 @@ Deviation of highest peaks We observed that in some situation, the calibrated peaks' positions of some spectra are far off to the targeted peak positions, while goodness -of fit such as :math:`\chi^2` are still good. It is usally caused by the +of fit such as :math:`\chi^2` are still good. It is usually caused by the bad fit of one or two peaks in that spectrum, which feeds some erroreous peak positions to peak offset fitting function. @@ -150,7 +150,7 @@ defined as: where :math:`X^{(o)}` is the fitted centre of the highest peak of spectrum i, and :math:`X^{(c)}` is the theoretical centre of this peak. -Collective quantities to illustrate goodness of fitting (still in developement) +Collective quantities to illustrate goodness of fitting (still in development) ############################################################################### Be noticed that the idea of this section is still under development and diff --git a/docs/source/algorithms/GetEiT0atSNS-v1.rst b/docs/source/algorithms/GetEiT0atSNS-v1.rst index d3872c02d6d9451e1fea3045f55deef7d6547924..3ac32da7387b2af289fc085a9ec1ba5051ee3c56 100644 --- a/docs/source/algorithms/GetEiT0atSNS-v1.rst +++ b/docs/source/algorithms/GetEiT0atSNS-v1.rst @@ -14,7 +14,7 @@ following: - in the ADARA framework, the monitors are in the first frame. - SEQUOIA has event based monitors. -- some data aquisition errors will create unphysical monitor IDs. This +- some data acquisition errors will create unphysical monitor IDs. This will be ignored - when vChTrans is 2, on ARCS and SEQUOIA there is no chopper in the beam (white beam). Will return not a number for both Ei and T0 diff --git a/docs/source/algorithms/GroupDetectors-v1.rst b/docs/source/algorithms/GroupDetectors-v1.rst index 248238931e76446716d42aa4c144e4515cef79d3..a9abcab27904a56dbb8e46caf7c5f3c87c9f265a 100644 --- a/docs/source/algorithms/GroupDetectors-v1.rst +++ b/docs/source/algorithms/GroupDetectors-v1.rst @@ -105,7 +105,7 @@ Example 1: specifying spectrum numbers group_index = GroupDetectors(ws,SpectraList=[1,3,5],Version=1) # The specified spectra are grouped and saved into the same workspace. - # The returned value is an index in ws wich contains the created group. + # The returned value is an index in ws which contains the created group. # Check the result print('The workspace still has {} spectra'.format(ws.getNumberHistograms())) @@ -162,7 +162,7 @@ Example 2: specifying detctor IDs group_index = GroupDetectors(ws,DetectorList=[100,102,104],Version=1) # The specified spectra are grouped and saved into the same workspace. - # The returned value is an index in ws wich contains the created group. + # The returned value is an index in ws which contains the created group. # Check the result print('The workspace still has {} spectra'.format(ws.getNumberHistograms())) @@ -219,7 +219,7 @@ Example 3: specifying workspace indices group_index = GroupDetectors(ws,WorkspaceIndexList=[0,2,4],Version=1) # The specified spectra are grouped and saved into the same workspace. - # The returned value is an index in ws wich contains the created group. + # The returned value is an index in ws which contains the created group. # Check the result print('The workspace still has {} spectra'.format(ws.getNumberHistograms())) diff --git a/docs/source/algorithms/GroupDetectors-v2.rst b/docs/source/algorithms/GroupDetectors-v2.rst index f38f6f30d05166d7ca92ee80addad1cd5f8ed14a..64303c1ce87c79458597136f28569d5a6fa0367a 100644 --- a/docs/source/algorithms/GroupDetectors-v2.rst +++ b/docs/source/algorithms/GroupDetectors-v2.rst @@ -50,7 +50,7 @@ incorrect, but other software may not. Mantid will warn you if the value given is incorrect. Each group's spectrum number is determined by the group's number. This -behaviour can be overriden by enabling the IgnoreGroupNumber property, in +behaviour can be overridden by enabling the IgnoreGroupNumber property, in which case the first group will be numbered 1, and the second 2, and so on. Blank lines and whitespace in the map file are ignored. Comments may be diff --git a/docs/source/algorithms/He3TubeEfficiency-v1.rst b/docs/source/algorithms/He3TubeEfficiency-v1.rst index 945e7a90023f2b45e7ca3e04292319cbb5c441f5..3bfca01791182cbe8406e1e04e1dd5cf019a11f7 100644 --- a/docs/source/algorithms/He3TubeEfficiency-v1.rst +++ b/docs/source/algorithms/He3TubeEfficiency-v1.rst @@ -28,7 +28,7 @@ following manner. If no input value is given, the detector parameter is pulled from the detector itself. If a single value is used as input, that value is applied to all detectors. If an array of values is used, that array *must* be the same size as the number of spectra in the -workspace. If it is not, the spectra indicies that do not have values +workspace. If it is not, the spectra indices that do not have values will be zeroed in the output workspace. Restrictions on Input Workspace diff --git a/docs/source/algorithms/IndexSXPeaks-v1.rst b/docs/source/algorithms/IndexSXPeaks-v1.rst index 189b1aee4184d36296a7f1ba8b1567c8d3b88f54..5a69e4ec6d14aabcd4dfad4f88a9cf311372bad3 100644 --- a/docs/source/algorithms/IndexSXPeaks-v1.rst +++ b/docs/source/algorithms/IndexSXPeaks-v1.rst @@ -20,7 +20,7 @@ This algorithm does not generate a :ref:`UB matrix <Lattice>`, it will only inde Run :ref:`CalculateUMatrix <algm-CalculateUMatrix>` algorithm after executing this algorithm in order to attach a :ref:`UB matrix <Lattice>` onto the sample. The :ref:`CopySample <algm-CopySample>` algorithm will allow this :ref:`UB matrix <Lattice>` -to be transfered between workspaces. +to be transferred between workspaces. Usage ----- diff --git a/docs/source/algorithms/IndirectCalibration-v1.rst b/docs/source/algorithms/IndirectCalibration-v1.rst index ada37e779c378cb18e2236640ce6afb859eb1472..e4256168b895a95dba91959fe0e6fe4da892bcda 100644 --- a/docs/source/algorithms/IndirectCalibration-v1.rst +++ b/docs/source/algorithms/IndirectCalibration-v1.rst @@ -18,7 +18,7 @@ algorithm which are then merged into a single run using :ref:`MergeRuns the output workspace. .. note:: - This algorithm only supports files containg histogram data. + This algorithm only supports files containing histogram data. Workflow -------- diff --git a/docs/source/algorithms/IntegrateEllipsoids-v1.rst b/docs/source/algorithms/IntegrateEllipsoids-v1.rst index 23b4caf1dabcb745cb863f338efea5efc52b76f7..836393846eeb5a1deaeeac6870c2349213adcfc5 100644 --- a/docs/source/algorithms/IntegrateEllipsoids-v1.rst +++ b/docs/source/algorithms/IntegrateEllipsoids-v1.rst @@ -219,7 +219,7 @@ Usage **Example - IntegrateEllipsoids:** User should provide their own event nexus file instead of **TOPAZ_3132_event.nxs** used within this example. The original **TOPAZ_3132_event.nxs** -file is availible in `Mantid system tests repository <https://github.com/mantidproject/systemtests/tree/master/Data/TOPAZ_3132_event.nxs>`_. +file is available in `Mantid system tests repository <https://github.com/mantidproject/systemtests/tree/master/Data/TOPAZ_3132_event.nxs>`_. .. .. testcode:: exIntegrateEllipsoids .. The code itself works but disabled from doc tests as takes too long to complete. diff --git a/docs/source/algorithms/IntegrateEllipsoidsTwoStep-v1.rst b/docs/source/algorithms/IntegrateEllipsoidsTwoStep-v1.rst index 3104a0cd27efdaac11e77ab48f90d29ff561f65a..87c2faa1f61b5fddd8029925f4818423200e643a 100644 --- a/docs/source/algorithms/IntegrateEllipsoidsTwoStep-v1.rst +++ b/docs/source/algorithms/IntegrateEllipsoidsTwoStep-v1.rst @@ -260,7 +260,7 @@ Usage User should provide their own event nexus file instead of **TOPAZ_3132_event.nxs** used within this example. The original **TOPAZ_3132_event.nxs** file is -availible in `Mantid system tests repository +available in `Mantid system tests repository <https://github.com/mantidproject/systemtests/tree/master/Data/TOPAZ_3132_event.nxs>`_. .. .. testcode:: exIntegrateEllipsoidsTwoStep diff --git a/docs/source/algorithms/IntegratePeaksCWSD-v1.rst b/docs/source/algorithms/IntegratePeaksCWSD-v1.rst index b6ec410b2a028573ee0353738140573bb8969feb..66a9ecf9b523306d8735786d3f0584416bf06d87 100644 --- a/docs/source/algorithms/IntegratePeaksCWSD-v1.rst +++ b/docs/source/algorithms/IntegratePeaksCWSD-v1.rst @@ -40,7 +40,7 @@ This *Pt*, i.e., workspace, contains at most one peak. Algorithm *FindPeaksMD* is able to find a peak in the MDEventWorkspace and output to a PeaksWorkspace. A :ref:`UB matrix <Lattice>` is set to this PeaksWorkspace as an option. -The **pseduo-code** of this algorith is: +The **pseduo-code** of this algorithm is: 1. Go over all the MDEvents; 2. For Pt. (aka, run number) i, its integrated intensity :math:`I_{i}` is calculated as :math:`I_{i} = \sum_{d=0}^{256\times 256}\frac{s_d}{m}`, where :math:`s_i` is the signal of detector i, diff --git a/docs/source/algorithms/IntegratePeaksHybrid-v1.rst b/docs/source/algorithms/IntegratePeaksHybrid-v1.rst index 6c76bddc5fb763d81adf1c2c60569d1bd425eb61..3931de47d523a1a8b84fd62348d8ea0d48323263 100644 --- a/docs/source/algorithms/IntegratePeaksHybrid-v1.rst +++ b/docs/source/algorithms/IntegratePeaksHybrid-v1.rst @@ -12,7 +12,7 @@ Description This is a hybrid between :ref:`algm-IntegratePeaksMD` and :ref:`algm-IntegratePeaksUsingClusters`. Each peak region is treated as a separate image and rebinned accordingly. The background threshold is automatically determined around each peak, by averaging over all pixels in that region. The NumberOfBins and BackgroundOuterRadius are global to all Peaks. The actual background threshold is calculated independently for each peak based on NumberOfBins, BackgroundOuterRadius and the signal values in that region. This algorithm is in general faster than :ref:`algm-IntegratePeaksUsingClusters` and has a better ability to distinguish peaks from the background because each peak is treated independently. -Integrates arbitary shaped single crystal peaks defined on an +Integrates arbitrary shaped single crystal peaks defined on an :ref:`MDHistoWorkspace <MDHistoWorkspace>` using connected component analysis to determine regions of interest around each peak of the :ref:`PeaksWorkspace <PeaksWorkspace>`. The output is an integrated @@ -21,7 +21,7 @@ labels assigned to each cluster for diagnostic and visualisation purposes. **The algorithm makes no assmptions about Peak shape or size** and can -therfore be used where integration over defined shapes +therefore be used where integration over defined shapes :ref:`algm-IntegratePeaksMD` and :ref:`algm-IntegrateEllipsoids`, for example, will not work. diff --git a/docs/source/algorithms/IntegratePeaksMD-v2.rst b/docs/source/algorithms/IntegratePeaksMD-v2.rst index 76b3bf4f930e09126a47f2847cdb83b4630200f9..25129781cf549e67142afbd517db2e88fb6695db 100644 --- a/docs/source/algorithms/IntegratePeaksMD-v2.rst +++ b/docs/source/algorithms/IntegratePeaksMD-v2.rst @@ -185,7 +185,7 @@ Usage User should provide its own event nexus file instead of **TOPAZ_3132_event.nxs** used within this example. The original **TOPAZ_3132_event.nxs** -file is availible in `Mantid system tests repository <https://github.com/mantidproject/systemtests/tree/master/Data/TOPAZ_3132_event.nxs>`_. +file is available in `Mantid system tests repository <https://github.com/mantidproject/systemtests/tree/master/Data/TOPAZ_3132_event.nxs>`_. .. The code itself works but disabled from doc tests as takes too long to complete. .. .. testcode:: exIntegratePeaksMD diff --git a/docs/source/algorithms/IntegratePeaksProfileFitting-v1.rst b/docs/source/algorithms/IntegratePeaksProfileFitting-v1.rst index 311972b7664e2c6cb7ba6ed8e0f04cad50a47723..e5c715ed8c79b2683b23636335616f99163b1679 100644 --- a/docs/source/algorithms/IntegratePeaksProfileFitting-v1.rst +++ b/docs/source/algorithms/IntegratePeaksProfileFitting-v1.rst @@ -39,7 +39,7 @@ Instrument-Defined Parameters In addition to the input parameters defined above, there are several other parameters to be aware of which are pre-defined for each instrument. The instrument is determined from the instrument that is loaded into PeaksWorkspace. If the instrument parameters file -does not contain paramters, the algorithm defaults to MaNDi parameters. Default +does not contain parameters, the algorithm defaults to MaNDi parameters. Default values are below: +--------------+----------------------------+----------+----------+---------+ diff --git a/docs/source/algorithms/IntegratePeaksUsingClusters-v1.rst b/docs/source/algorithms/IntegratePeaksUsingClusters-v1.rst index ed9b40a93dfab992a86676389c6d29bf01bbdff0..f10ad70fb459ff9824276030ed5fa380cca96c50 100644 --- a/docs/source/algorithms/IntegratePeaksUsingClusters-v1.rst +++ b/docs/source/algorithms/IntegratePeaksUsingClusters-v1.rst @@ -9,7 +9,7 @@ Description ----------- -Integrates arbitary shaped single crystal peaks defined on an +Integrates arbitrary shaped single crystal peaks defined on an :ref:`MDHistoWorkspace <MDHistoWorkspace>` using connected component analysis to determine regions of interest around each peak of the :ref:`PeaksWorkspace <PeaksWorkspace>`. The output is an integrated @@ -17,8 +17,8 @@ analysis to determine regions of interest around each peak of the labels assigned to each cluster for diagnostic and visualisation purposes. -**The algorithm makes no assmptions about Peak shape or size** and can -therfore be used where integration over defined shapes +**The algorithm makes no assumptions about Peak shape or size** and can +therefore be used where integration over defined shapes :ref:`algm-IntegratePeaksMD` and :ref:`algm-IntegrateEllipsoids`, for example, will not work. @@ -36,10 +36,10 @@ effective bin size do not affect the background filtering. This algorithm uses an imaging technique, and it is therefore important that the MDHistoWorkspace you are using is binned to a sufficient -resolution via :ref:`algm-BinMD`. You can overlay the intergrated peaks +resolution via :ref:`algm-BinMD`. You can overlay the integrated peaks workspace in the `Slice Viewer <MantidPlot:_SliceViewer#Viewing_Peaks_Workspaces>`__ over the -generated Cluster Labeled OutputWorkspaceMD to see what the interation +generated Cluster Labeled OutputWorkspaceMD to see what the iteration region used for each peak amounts to. Notes for running @@ -104,11 +104,11 @@ Usage # Predict peaks predicted = PredictPeaks(sxd) # Keep every 20th predicted peak for speed - rows_to_delete = set(range(predicted.getNumberPeaks())) - set([i for i in range(predicted.getNumberPeaks()) if i % 20 == 0]) + rows_to_delete = set(range(predicted.getNumberPeaks())) - set([i for i in range(predicted.getNumberPeaks()) if i % 20 == 0]) DeleteTableRows(predicted, Rows=list(rows_to_delete)) # Set the Frame to QLab - mdws = CreateMDWorkspace(Dimensions=3, Extents='-10,10,-10,10,-10,10', + mdws = CreateMDWorkspace(Dimensions=3, Extents='-10,10,-10,10,-10,10', Names='Q_lab_x,Q_lab_y,Q_lab_z', Frames = "QLab,QLab,QLab", Units='U,U,U') qlab = predicted.column('QLab') diff --git a/docs/source/algorithms/JoinISISPolarizationEfficiencies-v1.rst b/docs/source/algorithms/JoinISISPolarizationEfficiencies-v1.rst index 478a4a2603eba2df3f97ff90240bc59f13ce90ed..a04dc5a2770c23ceae1e10a2acd1687788e59c9c 100644 --- a/docs/source/algorithms/JoinISISPolarizationEfficiencies-v1.rst +++ b/docs/source/algorithms/JoinISISPolarizationEfficiencies-v1.rst @@ -10,7 +10,7 @@ Description ----------- The inputs to this algorithm are single-spectra workspaces containing polarization efficiencies. They are combined and interpolated if -neccessary to form a valid matrix workspace. The spectra of the output workspace are labeled with the names of the corresponding +necessary to form a valid matrix workspace. The spectra of the output workspace are labeled with the names of the corresponding input properties. diff --git a/docs/source/algorithms/LineProfile-v1.rst b/docs/source/algorithms/LineProfile-v1.rst index ad6a0926e3014e5b76f324fdd5930fd172c1308a..6aaff42833ce8f38acf97e4b8220122709d8503d 100644 --- a/docs/source/algorithms/LineProfile-v1.rst +++ b/docs/source/algorithms/LineProfile-v1.rst @@ -145,7 +145,7 @@ Output: Target='Theta' ) - # Lets assing NaNs to the lower left and upper right corners + # Lets assign NaNs to the lower left and upper right corners # of the workspace. for iVert in range(wsInTheta.getNumberHistograms()): for iHor in range(wsInTheta.blocksize()): diff --git a/docs/source/algorithms/LoadAscii-v2.rst b/docs/source/algorithms/LoadAscii-v2.rst index 7420d024b0730e3b85b8321ef7a3354be5168c83..01f53d12a5b61a1eabc8c604199d4e37de412d8c 100644 --- a/docs/source/algorithms/LoadAscii-v2.rst +++ b/docs/source/algorithms/LoadAscii-v2.rst @@ -20,11 +20,11 @@ such a file. The format must be: - A single integer or blank line to denote a new spectra -- For each bin, between two and four columns of delimted data in the +- For each bin, between two and four columns of delimited data in the following order: 1st column=X, 2nd column=Y, 3rd column=E, 4th column=DX (X error) - Comments can be included by prefixing the line with a non-numerical - character which must be consistant throughout the file and specified + character which must be consistent throughout the file and specified when you load the file. Defaults to "#" - The number of bins is defined by the number of rows and must be identical for each spectra diff --git a/docs/source/algorithms/LoadCalFile-v1.rst b/docs/source/algorithms/LoadCalFile-v1.rst index d96a583b525319f3b1c25067dcc13cc3edf58961..42d8a8673cdc6a138c4a2c23c0276c872721513b 100644 --- a/docs/source/algorithms/LoadCalFile-v1.rst +++ b/docs/source/algorithms/LoadCalFile-v1.rst @@ -30,7 +30,7 @@ create the necessary workspaces. .. testcode:: ExInstrumentBase # Grouping, offsets and masking workspaces are all made by default. - # WorkspaceName parameter is required inspite of docs not saying so. + # WorkspaceName parameter is required in spite of docs not saying so. ws = LoadCalFile(InstrumentName="GEM", CalFilename="offsets_2006_cycle064.cal", WorkspaceName="ws") print("Total number of workspaces = {}".format(len(ws))) diff --git a/docs/source/algorithms/LoadCanSAS1D-v1.rst b/docs/source/algorithms/LoadCanSAS1D-v1.rst index 827e5ec4d7b919900764fb2a7ae9dbe2609152e2..20284e48243988f597d80864c453cd6285831ec0 100644 --- a/docs/source/algorithms/LoadCanSAS1D-v1.rst +++ b/docs/source/algorithms/LoadCanSAS1D-v1.rst @@ -15,7 +15,7 @@ http://svn.smallangles.net/svn/canSAS/1dwg/trunk/cansas1d.xsd and creates output workspace. CANSAS has a Wiki page at http://www.smallangles.net/wgwiki/index.php/canSAS_Working_Groups -If the file contains mulitple SASentry elements a workspace group will +If the file contains multiple SASentry elements a workspace group will be created and each SASentry will be one workspace in the group. Loading multiple SASdata elements is not supported. diff --git a/docs/source/algorithms/LoadCanSAS1D-v2.rst b/docs/source/algorithms/LoadCanSAS1D-v2.rst index 94946cae452207dd0816d6b3ad698d8be7ff10c0..f4e689799c16137d7df7c5af4b784a0e66c87e3d 100644 --- a/docs/source/algorithms/LoadCanSAS1D-v2.rst +++ b/docs/source/algorithms/LoadCanSAS1D-v2.rst @@ -15,7 +15,7 @@ http://svn.smallangles.net/svn/canSAS/1dwg/trunk/cansas1d.xsd and creates output workspace. CANSAS has a Wiki page at http://www.smallangles.net/wgwiki/index.php/canSAS_Working_Groups -If the file contains mulitple SASentry elements a workspace group will +If the file contains multiple SASentry elements a workspace group will be created and each SASentry will be one workspace in the group. Loading multiple SASdata elements is not supported. diff --git a/docs/source/algorithms/LoadDNSLegacy-v1.rst b/docs/source/algorithms/LoadDNSLegacy-v1.rst index 7c513e8764585ba03efc0673d37d42d4101f9923..b8f4e4f71bb1cfd1efbdfad6c8f92bc1d9344844 100644 --- a/docs/source/algorithms/LoadDNSLegacy-v1.rst +++ b/docs/source/algorithms/LoadDNSLegacy-v1.rst @@ -28,7 +28,7 @@ in the position given in the data file. Since zero time channel is not specified, the algorithm can roll the TOF data to get elastic peak at the right position. For this the **ElasticChannel** - channel number where the elastic peak is observed without correction - should be specified. - For comissioning period, the algorithm ignores the elastic channel number given in the data file. + For commissioning period, the algorithm ignores the elastic channel number given in the data file. **Normalization** @@ -58,7 +58,7 @@ Alternatively, the text file with the coil currents table may be provided (optio | x | 7 | 0 | -2.1 | -0.97 | 2.21 | +--------------+----------+-------+-------+-------+-------+ -First row must contain the listed column headers, other rows contain coil currents for each polarisation. Rows with different currents for one polarisation are alowed. Columns are separated by tab symbols. +First row must contain the listed column headers, other rows contain coil currents for each polarisation. Rows with different currents for one polarisation are allowed. Columns are separated by tab symbols. This algorithm only supports DNS instrument in its configuration with one detector bank (polarisation analysis). diff --git a/docs/source/algorithms/LoadDNSSCD-v1.rst b/docs/source/algorithms/LoadDNSSCD-v1.rst index 28f2f8d005c83ead775b47e92b15c551ea79c1fc..3ad687c819e4e7166538aa4257ab373f9cc199f5 100644 --- a/docs/source/algorithms/LoadDNSSCD-v1.rst +++ b/docs/source/algorithms/LoadDNSSCD-v1.rst @@ -23,7 +23,7 @@ As a result, two workspaces are created: - `OutputWorkspace` contains the raw neutron counts. -- `NormalizationWorkspace` contains the choosen normalization data (either monitor counts or experiment duration time). +- `NormalizationWorkspace` contains the chosen normalization data (either monitor counts or experiment duration time). Both workspaces have :math:`(H,K,L,dE)` dimensions. The metadata are loaded into time series sample logs. diff --git a/docs/source/algorithms/LoadFITS-v1.rst b/docs/source/algorithms/LoadFITS-v1.rst index fbd48295ac5629612eb315ada358532e86da05ab..d5d0cb3f9c1c733869a8b7b0805133a4443d32f8 100644 --- a/docs/source/algorithms/LoadFITS-v1.rst +++ b/docs/source/algorithms/LoadFITS-v1.rst @@ -21,7 +21,7 @@ name and an appendix _1, _2, etc., incremented sequentially as new files are loaded with the same OutputWorkspace property. The way image pixels are loaded into the resulting workspaces depends -on the porperty LoadAsRectImg. If it is set as false, one spectrum +on the property LoadAsRectImg. If it is set as false, one spectrum will be created for every image pixel. Otherwise, one spectrum will be created for every image row. diff --git a/docs/source/algorithms/LoadIDFFromNexus-v1.rst b/docs/source/algorithms/LoadIDFFromNexus-v1.rst index b707b491405544426fb57c46772b698bdafc47c8..a133d05d647678f2e6f56d1aa38984166a8cd423 100644 --- a/docs/source/algorithms/LoadIDFFromNexus-v1.rst +++ b/docs/source/algorithms/LoadIDFFromNexus-v1.rst @@ -16,9 +16,9 @@ the instrument definition. It also looks to see if it contains a separate instrument parameter map. If yes this is loaded. If no, the algorithm will -attempt to load on paramter file on your disk from your instrument folder +attempt to load on parameter file on your disk from your instrument folder with the name INST_Parameters.xml. -This may be overriden by a parameter correction file, which can be +This may be overridden by a parameter correction file, which can be used to correct out of date embedded parameters. A parameter correction file contains a list of parameter files, diff --git a/docs/source/algorithms/LoadISISNexus-v2.rst b/docs/source/algorithms/LoadISISNexus-v2.rst index 051bafc40f6fb71f649166eb737e9124199b0549..065db60e111eb5820a352f9e68247108c5685822 100644 --- a/docs/source/algorithms/LoadISISNexus-v2.rst +++ b/docs/source/algorithms/LoadISISNexus-v2.rst @@ -111,7 +111,7 @@ Properties of the workspace :ref:`Run <Run>` object are loaded as follows: In the Nexus column, names of groups in capitals are in ``raw_data_1/isis_vms_compat`` and the other groups are in ``raw_data_1``. -(data) indicates that the number is got from the histogram data in an appropiate manner. +(data) indicates that the number is got from the histogram data in an appropriate manner. ``IRPB`` and ``RRPB`` point to the same data. In ``IRPB``, the data is seen as 32-bit integer and in RRPB it is seen as 32-bit floating point (same 32 bits). diff --git a/docs/source/algorithms/LoadInstrumentFromNexus-v1.rst b/docs/source/algorithms/LoadInstrumentFromNexus-v1.rst index d41423e0f7dbffef4e9e4201d4129d0750648b24..3abeea400bac981dc04d94eedb1f68b501b9b003 100644 --- a/docs/source/algorithms/LoadInstrumentFromNexus-v1.rst +++ b/docs/source/algorithms/LoadInstrumentFromNexus-v1.rst @@ -32,7 +32,7 @@ Usage source = inst.getSource() print("The name of the instrument is '{}'.".format(inst.getName().strip())) - print("The source postion is at: {}.".format(source.getPos())) + print("The source position is at: {}.".format(source.getPos())) Output: @@ -40,7 +40,7 @@ Output: .. testoutput:: ExLoadMUSR The name of the instrument is 'MUSR'. - The source postion is at: [0,-10,0]. + The source position is at: [0,-10,0]. .. categories:: diff --git a/docs/source/algorithms/LoadMappingTable-v1.rst b/docs/source/algorithms/LoadMappingTable-v1.rst index f485e532664cb26cea628849b513f90c7b4b4cce..d77554517ca4537642de39fbff1f9b1b3bc550f5 100644 --- a/docs/source/algorithms/LoadMappingTable-v1.rst +++ b/docs/source/algorithms/LoadMappingTable-v1.rst @@ -18,7 +18,7 @@ usually means it must be run after :ref:`algm-LoadInstrument` or The association is one to many, i.e. a spectrum can have one or many detectors contributing to it. Alternatively the same spectrum can -contribute to different spectra (for example in DAE2 (Data Aquisition +contribute to different spectra (for example in DAE2 (Data Acquisition Electronic) when a spectra containing electronically focussed data is created simultaneously with individual spectra). diff --git a/docs/source/algorithms/LoadMuonNexus-v2.rst b/docs/source/algorithms/LoadMuonNexus-v2.rst index 81fbbc40660a93f4d082691190b7d4849b9f2a50..52f8bfc0827f1bfa4321148e5c7a876f66f1391d 100644 --- a/docs/source/algorithms/LoadMuonNexus-v2.rst +++ b/docs/source/algorithms/LoadMuonNexus-v2.rst @@ -114,7 +114,7 @@ LoadMuonNexus does not run LoadNexusLogs to load run logs. Information is loaded +---------------------------+----------------------------------+ -(data) indicates that the number is got from the histogram data in an appropiate manner. +(data) indicates that the number is got from the histogram data in an appropriate manner. Spectra-detector mapping '''''''''''''''''''''''' diff --git a/docs/source/algorithms/LoadNMoldyn4Ascii-v1.rst b/docs/source/algorithms/LoadNMoldyn4Ascii-v1.rst index 3c7b6c43857e3dfdc80e2c42ef3cc3e5356d232d..9c10d00e43db44d6c3e34dc36ef07b1194dfc110 100644 --- a/docs/source/algorithms/LoadNMoldyn4Ascii-v1.rst +++ b/docs/source/algorithms/LoadNMoldyn4Ascii-v1.rst @@ -12,7 +12,7 @@ Description Loads data from version 4 of nMOLDYN saved in the ASCII format after being extracted from the ``.tar`` archive. -Functions can be provided with ot without the comma between multiple dependant +Functions can be provided with or without the comma between multiple dependent variables, for example a function names ``f(q,t_H)`` in nMOLDYN can be loaded using either ``f(q,t)_H`` or ``f(qt)_H`` as a function name in this algorithm. diff --git a/docs/source/algorithms/LoadSassena-v1.rst b/docs/source/algorithms/LoadSassena-v1.rst index a8978dffa8b0c5d13975ecc17d1119bd69132d4f..55038c756a38f1175e5091a9a4d50fa58c5745d7 100644 --- a/docs/source/algorithms/LoadSassena-v1.rst +++ b/docs/source/algorithms/LoadSassena-v1.rst @@ -15,7 +15,7 @@ This algorithm reads Sassena output and stores all data in workspaces of type :ref:`Workspace2D <Workspace2D>`, grouped under a single :ref:`WorkspaceGroup <WorkspaceGroup>`. -Sassena ouput files are in HDF5 format +Sassena output files are in HDF5 format `2 <http://www.hdfgroup.org/HDF5>`__, and can be made up of the following datasets: *qvectors*, *fq*, *fq0*, *fq2*, and *fqt* diff --git a/docs/source/algorithms/LoadSpiceAscii-v1.rst b/docs/source/algorithms/LoadSpiceAscii-v1.rst index 6bb9f483ea142b3685530b110d4024815b19ee97..4f3f2f6f15836644ff88fb778beb6032c3678cd0 100644 --- a/docs/source/algorithms/LoadSpiceAscii-v1.rst +++ b/docs/source/algorithms/LoadSpiceAscii-v1.rst @@ -29,7 +29,7 @@ The first item is an integer as the index of experimental data point. Output Worskpaces ################# -Two table worskpaces will be exported from the algorith. +Two table worskpaces will be exported from the algorithm. 'OutputWorkspace' is the table workspace containing the measured experimental data. Each row of it contains all the measured parameters of one data point. diff --git a/docs/source/algorithms/LoadVTK-v1.rst b/docs/source/algorithms/LoadVTK-v1.rst index d047f11c134ac535cf5cbdd1e6d3408cf1071eae..55fd4a2155ddfaeb7b30f4dc8052161abc1384cb 100644 --- a/docs/source/algorithms/LoadVTK-v1.rst +++ b/docs/source/algorithms/LoadVTK-v1.rst @@ -43,7 +43,7 @@ The MDEventWorkspace can be rebinned to a regular grid using SliceMD and BinMD b Usage ----- -These example is for illustation only. The file used is very large and not publically available. +These example is for illustation only. The file used is very large and not publicly available. **Example: Adaptive Binning** diff --git a/docs/source/algorithms/LoadWAND-v1.rst b/docs/source/algorithms/LoadWAND-v1.rst index c2229dcb094fd5b93a7606463463a411a8f44571..58a25df54b62fb022093c3bc48dabf4ea49239b8 100644 --- a/docs/source/algorithms/LoadWAND-v1.rst +++ b/docs/source/algorithms/LoadWAND-v1.rst @@ -28,7 +28,7 @@ If you need to do event filtering don't use this algorithm, simply use You can specify multiple files in the filename property or set the IPTS and RunNumbers, where RunNumbers can be a range or list of -numbers, see Usage example bellow. If multiple files are loaded they +numbers, see Usage example below. If multiple files are loaded they will be named 'OutputWorkspace'+'_runnumber' and be grouped in 'OutputWorkspace'. diff --git a/docs/source/algorithms/MaskDetectors-v1.rst b/docs/source/algorithms/MaskDetectors-v1.rst index 47ffae9c3c34f0e6f58f24db823fcb0c1ff59e40..7c24bacf82ebab2ab44aae90abdcde4116323241 100644 --- a/docs/source/algorithms/MaskDetectors-v1.rst +++ b/docs/source/algorithms/MaskDetectors-v1.rst @@ -104,7 +104,7 @@ will be masked in the input *Workspace*. If the input *MaskedWorkspace* is a `Matrix Workspace <http://docs.mantidproject.org/nightly/concepts/MatrixWorkspace.html#matrixworkspace>`_ and the number of spectra in the source *MaskedWorkspace* is equal to the number -of spectra in the target *Workspace*, then workspace indicies of the source are +of spectra in the target *Workspace*, then workspace indices of the source are used. If the numbers of spectra in *Workspace* and *MaskedWorkspace* are different, diff --git a/docs/source/algorithms/MaskDetectorsIf-v1.rst b/docs/source/algorithms/MaskDetectorsIf-v1.rst index a70292d2d40068dc2b5e49a96dc3515fa445c047..5c3bdbfb2f23ea3d2c3db7977ec3f988b3691270 100644 --- a/docs/source/algorithms/MaskDetectorsIf-v1.rst +++ b/docs/source/algorithms/MaskDetectorsIf-v1.rst @@ -9,10 +9,41 @@ Description ----------- -Iterates over the input workspace evaluating the test for each single -value spectrum. If the detectors should be masked it deselects all of -the contributing detectors in the output calfile. All other aspects of -the ``InputCalFile`` are copied over to the ``OutputCalFile``. +Iterates over the input workspace evaluating the test for the first bin in each spectrum. There are two output modes: + +Output to a calfile + For this mode the properties ``InputCalFile`` and ``OutputCalFile`` have to be set. + If the detectors should be masked it deselects all of + the contributing detectors in the output calfile. All other aspects of + the ``InputCalFile`` are copied over to the ``OutputCalFile``. + +Output to a workspace + For this mode the ``OutputWorkspace`` property has to be set. The algorithm masks the selected detectors (:literal:`Mode='SelectIf'`) or unmasks deselected ones (:literal:`Mode='DeselectIf'`) for the output workspace. Masking does not clear the data in the spectra under question. Use :ref:`ClearMaskedSpectra <algm-ClearMaskedSpectra>` to clear the masked data manually. + +Usage +----- + +**Example - mask spectra whose integral is below some limit** + +.. testcode:: MaskDetectorsIfEx + + ws = CreateSampleWorkspace() + # One spectrum has lower counts than the rest + badIndex = 3 + Ys = ws.dataY(badIndex) + Ys *= 0.01 + integral = Integration(ws) + MaskDetectorsIf(integral, Operator='Less', Value=10., OutputWorkspace=integral) + MaskDetectors(ws, MaskedWorkspace=integral) + # Inspect the result + isMasked = ws.spectrumInfo().isMasked(badIndex) + print('Spectrum at index {} is masked? {}'.format(badIndex, isMasked)) + +Output: + +.. testoutput:: MaskDetectorsIfEx + + Spectrum at index 3 is masked? True .. categories:: diff --git a/docs/source/algorithms/MatchSpectra-v1.rst b/docs/source/algorithms/MatchSpectra-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..c1876278a09d563f6ec33d06eb277929ff658260 --- /dev/null +++ b/docs/source/algorithms/MatchSpectra-v1.rst @@ -0,0 +1,73 @@ + +.. algorithm:: + +.. summary:: + +.. relatedalgorithms:: + +.. properties:: + +Description +----------- + +Calculate the factor(s) that best match the individual spectra to a +reference spectrum using `Gauss-Markov process +<https://en.wikipedia.org/wiki/Gauss%E2%80%93Markov_process>`_. This +is the same algorithm used by the "blend" step of `PDFgetN +<http://pdfgetn.sourceforge.net/>`_. The data undergoes the linear +transformation + +.. math:: + + scale * y_{spectrum} + offset + +such that the distance between :math:`y_{reference}` and the +transformed spectrum is minimized. Only the portions of the spectra +where the spectra overlap with the same x-values and the uncertainties +are greater than zero are considered. + +.. note:: + + Gauss-Markov does not take into account varying uncertainties when + calculating the ``scale`` and ``offset``. + +Usage +----- + +.. testcode:: MatchSpectra + + import numpy as np + x = np.arange(100, dtype=np.float) + x = np.tile(x, 2) + y = np.arange(100, dtype=np.float) + y = np.tile(y, 2) + y[100:200] += 10 + dy = np.zeros(y.size, dtype=np.float) + 1. + CreateWorkspace(OutputWorkspace='MatchSpectra_input', + DataX=x, + DataY=y, + DataE=dy, + NSpec=2) + _, offset, scale, chisq = MatchSpectra(InputWorkspace='MatchSpectra_input', + OutputWorkspace='MatchSpectra_output', + ReferenceSpectrum=2, + CalculateOffset=True, + CalculateScale=False) + for i in range(2): + print('spectra {}: {:.1f} * y + {:.1f}, chisq={:.1f}'.format(i+1, scale[i], offset[i], chisq[i])) + +.. testcleanup:: MatchSpectra + + DeleteWorkspaces(['MatchSpectra_input','MatchSpectra_output']) + + +Output: + +.. testoutput:: MatchSpectra + + spectra 1: 1.0 * y + 10.0, chisq=0.0 + spectra 2: 1.0 * y + 0.0, chisq=0.0 + +.. categories:: + +.. sourcelink:: diff --git a/docs/source/algorithms/MaxEnt-v1.rst b/docs/source/algorithms/MaxEnt-v1.rst index f3d4a78544dfbcc309cd0793b14dd88362c0375c..5bf997a36340fe8af645ca72c7b31914b9d05ea8 100644 --- a/docs/source/algorithms/MaxEnt-v1.rst +++ b/docs/source/algorithms/MaxEnt-v1.rst @@ -33,7 +33,7 @@ Note that even for real input data the reconstructed image can be complex, which imaginary parts will be taken into account for the calculations. This is the default behaviour, which can be changed by setting the input property *ComplexImage* to *False*. Note that the algorithm will fail to converge if the image is complex (i.e. the data does not satisfy Friedel's law) and this option is set to *False*. -For this reason, it is recomended to use the default when no prior knowledge is available. +For this reason, it is recommended to use the default when no prior knowledge is available. The entropy is defined on the image :math:`\{x_j\}` as: @@ -45,7 +45,7 @@ or .. math:: S = -\sum_j x_j \left(\log(x_j/A)-1\right) where :math:`A` is a constant and the formula which is used depends on the input property *PositiveImage*: when it is -set to *False* the first equation will be applied, whereas the latter expresion will be used if this property +set to *False* the first equation will be applied, whereas the latter expression will be used if this property is set to *True*. The sensitive of the reconstructed image to reconstructed image will vary depending on the data. In general a smaller value would preduce a sharper image. See section 4.7 in Ref. [1] for recommended strategy to selected :math:`A`. @@ -67,6 +67,20 @@ one step closer to the solution: .. math:: \mathbf{x} = \mathbf{x} + \delta \mathbf{x} +If *DataLinearAdj* :math:`l_m` and *DataConstAdj* :math:`c_m` are set +then the reconstructed data is adjusted to + +.. math:: d_m = \frac{l_m}{N} \sum_{j=0}^{N-1} x_j e^{i 2\pi m j / N} + c_m + +If *PerSpectrumImage* is set false, then chi squared is calculated for all spectra together to form a single image + +.. math:: \chi^2 = \frac{1}{N'}\sum_{m,k} \frac{\left(d_{m,k} - d_{m,k}^c\right)^2}{\sigma_{m,k}^2} \leq \chi^2_{target} + +then the reconstructed data are calculated from this single image and the adjustments are applied for each spectrum: + +.. math:: d_{m,k} = \frac{l_{m,k}}{N} \sum_{j=0}^{N-1} x_j e^{i 2\pi m j / N} + c_{m,k} + + Output Workspaces ----------------- @@ -185,6 +199,7 @@ Output: .. figure:: ../images/MaxEntFourierCoefficients.png :align: center + **Example - Reconstruct a real muon dataset** @@ -387,7 +402,7 @@ from converging. If the image is known to be real this property can be safely se Complex Data ------------ -If the input property "ComplexData* is set to *True*, the algorithm will assume complex data for the calculations with all the +If the input property *ComplexData* is set to *True*, the algorithm will assume complex data for the calculations with all the real parts listed before all the imaginary parts. This means that if you have workspaces where the imaginary part immediately follow the real part, such workspaces cannot be combined by using the :ref:`algm-AppendSpectra` algorithm because the resulting output will not order the real and imaginary parts corrected as needed for this algorithm. The following usage example @@ -494,7 +509,7 @@ Output: .. figure:: ../images/MaxEntResolutionFactor.png :align: center - + In the next example, we increased the density of points by factors of 10, 20 and 40. We show the reconstructed image (left) and a zoom into the region :math:`0.82 < x < 1.44` and :math:`-0.187 < y < 0.004`. @@ -526,6 +541,206 @@ Output: .. figure:: ../images/MaxEntResolutionFactor2.png :align: center + +Adjusting the Reconstructed Data +-------------------------------- +The reconstructed data can be adjusted by multiplying by the *DataLinearAdj* property and then adding the *DataConstAdj* property. +Each of these properties is a workspace with complex Y values, just like complex input workspaces. Each Y value is then applied to +the corresponding Y values in the reconstructed data at each iteration. + +These usage examples merely demonstrate how to use the adjustments and are not realistic use cases. + +.. testcode:: ExAdjustment + + from math import pi, sin, cos + from random import random, seed + + # Construct workspace (cosine + noise) over 3 spectra + X = [] + Y = [] + E = [] + N = 200 + w = 3 + for s in range(0,3): + seed(0) + for i in range(0,N): + x = 2*pi*i/N + X.append(x) + Y.append(cos(w*x)+(random()-0.5)*0.3) + E.append(0.2) + + CreateWorkspace(OutputWorkspace='inputws',DataX=X,DataY=Y,DataE=E,NSpec=3) + + # Construct linear adjustment workspace (real = 1, imaginary linear) + # no adjustment on first spectrum, double adjustment on third spectrum. + Zeroes = [] + Ylin = [] + Magnitude = - 0.1 + # Real values + for s in range(0,3): + for i in range(0,N): + Ylin.append(1.0) + Zeroes.append(0) + + # Imaginary values + for s in range(0,3): + for i in range(0,N): + X.append(X[i]) + Ylin.append(s*Magnitude*X[i]) + Zeroes.append(0) + + CreateWorkspace(OutputWorkspace='linadj', DataX=X, DataY=Ylin, DataE=Zeroes, NSpec=6) + + # Construct constant adjustment workspace (real = 0, imaginary linear) + # no adjustment on first spectrum, double adjustment on third spectrum. + Yconst = [] + Magnitude = 0.2 + # Real values + for s in range(0,3): + for i in range(0,N): + Yconst.append(0) + + # Imaginary values + for s in range(0,3): + for i in range(0,N): + Yconst.append(s*Magnitude*X[i]) + + CreateWorkspace(OutputWorkspace='constadj',DataX=X, DataY=Yconst, DataE=Zeroes, NSpec=6) + + evolChi, evolAngle, image, data = MaxEnt(InputWorkspace='inputws', DataLinearAdj='linadj', DataConstAdj='constadj',A=0.001) + + print("Reconstruction at 05 of first spectrum: {:.3f}".format(data.readY(0)[5])) + print("Reconstruction at 10 of first spectrum: {:.3f}".format(data.readY(0)[10])) + print("Reconstruction at 15 of first spectrum: {:.3f}".format(data.readY(0)[15])) + print("Reconstruction at 05 of third spectrum: {:.3f}".format(data.readY(2)[5])) + print("Reconstruction at 10 of third spectrum: {:.3f}".format(data.readY(2)[10])) + print("Reconstruction at 15 of third spectrum: {:.3f}".format(data.readY(2)[15])) + print("Number of iterations of first spectrum: "+str( len(evolAngle.readX(0)))) + print("Number of iterations of second spectrum: "+str( len(evolAngle.readX(1)))) + print("Number of iterations of third spectrum: "+str( len(evolAngle.readX(2)))) + +Output: + +.. testoutput:: ExAdjustment + + Reconstruction at 05 of first spectrum: 0.657 + Reconstruction at 10 of first spectrum: 0.433 + Reconstruction at 15 of first spectrum: 0.115 + Reconstruction at 05 of third spectrum: 0.522 + Reconstruction at 10 of third spectrum: 0.485 + Reconstruction at 15 of third spectrum: -0.019 + Number of iterations of first spectrum: 5 + Number of iterations of second spectrum: 37 + Number of iterations of third spectrum: 70 + +.. figure:: ../images/MaxEntAdjust.png + :align: center + + The first plot shows the reconstructed data and the second plot the corresponding image. + The first three spectra plotted are the real parts of the 3 spectra + and the other three spectra are the imaginary parts. + +This can also be done with the spectra of the data effectively concatenated and converted into a single image. +The reconstructed data is then obtained by converting the image back to data, copying for each spectrum and applying the adjustments. + +This is done by setting the *PerSpectrumImage* property to *false*. + +.. testcode:: ExAdjustmentTogether + + from math import pi, sin, cos + from random import random, seed + + # Construct workspace (real cosine + complex noise) over 3 spectra + X = [] + Y = [] + E = [] + N = 200 + w = 3 + for s in range(0,3): + # Real values + seed(0) + for i in range(0,N): + x = 2*pi*i/N + X.append(x) + Y.append(cos(w*x)+(random()-0.5)*0.3) + E.append(0.27) + + for s in range(0,3): + # Imaginary values + for i in range(0,N): + x = 2*pi*i/N + X.append(x) + Y.append((random()-0.5)*0.3) + E.append(0.27) + + CreateWorkspace(OutputWorkspace='inputws',DataX=X,DataY=Y,DataE=E,NSpec=6) + + # Construct linear adjustment workspace (real = 1, imaginary linear) + # no adjustment on first spectrum, double adjustment on third spectrum. + Zeroes = [] + Xlin = [] + Ylin = [] + Magnitude = - 0.14 + for s in range(0,3): + # Real values + for i in range(0,N): + Xlin.append(X[i]) + Ylin.append(1.0) + Zeroes.append(0) + + for s in range(0,3): + # Imaginary values + for i in range(0,N): + Xlin.append(X[i]) + Ylin.append(s*Magnitude*X[i]) + Zeroes.append(0) + + CreateWorkspace(OutputWorkspace='linadj', DataX=Xlin, DataY=Ylin, DataE=Zeroes, NSpec=6) + + # Construct constant adjustment workspace (real = 0, imaginary linear) + # no adjustment on first spectrum, double adjustment on third spectrum. + Yconst = [] + Magnitude = -0.05 + # Real values + for s in range(0,3): + for i in range(0,N): + Yconst.append(0) + + # Imaginary values + for s in range(0,3): + for i in range(0,N): + Yconst.append(s*Magnitude*X[i]) + + + CreateWorkspace(OutputWorkspace='constadj',DataX=Xlin, DataY=Yconst, DataE=Zeroes, NSpec=6) + + evolChi, evolAngle, image, data = MaxEnt(InputWorkspace='inputws', ComplexData=True, DataLinearAdj='linadj', DataConstAdj='constadj',A=0.001, PerSpectrumReconstruction=False) + + print("Reconstruction at 05 of first spectrum: {:.3f}".format(data.readY(0)[5])) + print("Reconstruction at 10 of first spectrum: {:.3f}".format(data.readY(0)[10])) + print("Reconstruction at 15 of first spectrum: {:.3f}".format(data.readY(0)[15])) + print("Reconstruction at 05 of third spectrum: {:.3f}".format(data.readY(2)[5])) + print("Reconstruction at 10 of third spectrum: {:.3f}".format(data.readY(2)[10])) + print("Reconstruction at 15 of third spectrum: {:.3f}".format(data.readY(2)[15])) + +Output: + +.. testoutput:: ExAdjustmentTogether + + Reconstruction at 05 of first spectrum: 0.679 + Reconstruction at 10 of first spectrum: 0.470 + Reconstruction at 15 of first spectrum: 0.158 + Reconstruction at 05 of third spectrum: 0.687 + Reconstruction at 10 of third spectrum: 0.481 + Reconstruction at 15 of third spectrum: 0.163 + +.. figure:: ../images/MaxEntAdjustTogether.png + :align: center + + The first plot shows the reconstructed data and the second plot the corresponding image. + In the data, the first three spectra plotted are the real parts of the 3 spectra + and the other three spectra are the imaginary parts. + In the image, the first spectrum is the real part and the second spectrum is the imaginary part. References ---------- diff --git a/docs/source/algorithms/MayersSampleCorrection-v1.rst b/docs/source/algorithms/MayersSampleCorrection-v1.rst index 20266639829d209f8e2f7868c0f590a642dbfa57..e9c35afe823345335263d6dc9eb9c2ed6530ddb9 100644 --- a/docs/source/algorithms/MayersSampleCorrection-v1.rst +++ b/docs/source/algorithms/MayersSampleCorrection-v1.rst @@ -33,7 +33,7 @@ numerical integration over the sample cylinder. The multiple scattering factor (if requested) is computed by simulating over a fixed number of second order scattering events and computing the ratio of second order and first order scattering. -Since we have assumed the ratio is the same between succesive orders, the :math:`\frac{1}{1-\beta}` +Since we have assumed the ratio is the same between successive orders, the :math:`\frac{1}{1-\beta}` factor simply comes from taking the sum of a geometric series. The cylinder radius :math:`r` combined with the inverse attenuation length :math:`\mu = \mu(E)` diff --git a/docs/source/algorithms/MedianDetectorTest-v1.rst b/docs/source/algorithms/MedianDetectorTest-v1.rst index dd467de839cedef559755656b5e0387f408f64f8..129f836f11ee703a1193c914871819a1f7179220 100644 --- a/docs/source/algorithms/MedianDetectorTest-v1.rst +++ b/docs/source/algorithms/MedianDetectorTest-v1.rst @@ -26,7 +26,7 @@ SignificanceTest will not be labelled bad. This test is particularly important when the number of counts is low, for example when examining the low count "background" parts of spectra. -Optionally, some might want to do median on a tube, or a bank. Fot that, +Optionally, some might want to do median on a tube, or a bank. For that, use the LevelsUp input. For example, in the CNCS instrument, the detector is called a pixel. The parent of a pixel is a tube, while an eightpack contains 8 tubes. To calculate the median of a tube, use diff --git a/docs/source/algorithms/MergeRuns-v1.rst b/docs/source/algorithms/MergeRuns-v1.rst index 1c41b77e816dcf0184a116e3d3cb247225e80e79..65c8c7ab87f958dd766a594ec1911872631ce79b 100644 --- a/docs/source/algorithms/MergeRuns-v1.rst +++ b/docs/source/algorithms/MergeRuns-v1.rst @@ -15,7 +15,7 @@ output workspace will cover the entire range of all the input workspaces, with the largest bin widths used in regions of overlap. The combination of each workspace is performed using the :ref:`algm-Plus` algorithm, -this does not preform any weighting based on the duration of collection, or proton charge. +this does not perform any weighting based on the duration of collection, or proton charge. If you wish to perform Merge runs that should not be equally weighted then they should be corrected individually prior to merging. @@ -57,7 +57,7 @@ Group Workspaces that are not multiperiod ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If group workspaces are provided that are not multi-period, this -algorithm will merge across all nested workspaces, to give a singe +algorithm will merge across all nested workspaces, to give a single output matrix workspace. Merging Sample Logs @@ -126,7 +126,7 @@ appended to the end of the first workspace. ChildAlgorithms used #################### -The :ref:`algm-Rebin` algorithm is used, if neccessary, to put all the +The :ref:`algm-Rebin` algorithm is used, if necessary, to put all the input workspaces onto a common binning. The :ref:`algm-Plus` algorithm is used to combine each of the workspaces diff --git a/docs/source/algorithms/ModeratorTzero-v1.rst b/docs/source/algorithms/ModeratorTzero-v1.rst index b03a405bd4bcc0966eb7e20ad4f85f2cff1f42eb..38fdafbe8a9cadea0ae7ba17a83fa03bacc16fa9 100644 --- a/docs/source/algorithms/ModeratorTzero-v1.rst +++ b/docs/source/algorithms/ModeratorTzero-v1.rst @@ -58,7 +58,7 @@ Here's the result of applying ModeratorTzero to both the event list and the histogrammed data of a run in the VISION beamline. The transformation of either events or histograms shifts the curve to smaller TOF's. The transformed curves are not supposed to be identical, -but similar and differenciated from the original curve. +but similar and differentiated from the original curve. .. figure:: /images/ModeratorTzero_Fig.1.jpeg :width: 400px diff --git a/docs/source/algorithms/ModeratorTzeroLinear-v1.rst b/docs/source/algorithms/ModeratorTzeroLinear-v1.rst index 7684fa4be21885922fa16171e24075d5d9fabce3..b2e0f04568129ac969707dc9412a3ccbe7041910 100644 --- a/docs/source/algorithms/ModeratorTzeroLinear-v1.rst +++ b/docs/source/algorithms/ModeratorTzeroLinear-v1.rst @@ -11,9 +11,9 @@ Description This algorithm Corrects the time of flight (TOF) of an indirect geometry instrument by substracting a time offset :math:`t_0` linearly dependent -on the wavelenght of the neutron when emitted through the moderator. +on the wavelength of the neutron when emitted through the moderator. This algorithm is suitable to data reduction of indirect instruments -featuring a neutron flux with a narrow distribution of wavelenghts. A +featuring a neutron flux with a narrow distribution of wavelengths. A empirical formula for the correction, stored in the instrument definition file, is taken as linear on the initial neutron wavelength :math:`\lambda_i`: :math:`t_0 = a * \lambda_i + b`, diff --git a/docs/source/algorithms/ModifyDetectorDotDatFile-v1.rst b/docs/source/algorithms/ModifyDetectorDotDatFile-v1.rst index 0df84923b53e80c8ee7397a411676493f1e32254..c6623032b6f97f6519210bc78e2f4a1d3adbe76f 100644 --- a/docs/source/algorithms/ModifyDetectorDotDatFile-v1.rst +++ b/docs/source/algorithms/ModifyDetectorDotDatFile-v1.rst @@ -28,7 +28,7 @@ A typical ISIS dot data file has a format like this::    .... Each row corresponds to a detector whose type is indicated in the -``code`` column. The algorithm will only modify values in colums ``l2``, +``code`` column. The algorithm will only modify values in columns ``l2``, ``theta`` and ``phi`` and only if the value in the ``code`` column is 3, which indicates a PSD gas tube. For more details about the detector dot data file see diff --git a/docs/source/algorithms/MuonMaxent-v1.rst b/docs/source/algorithms/MuonMaxent-v1.rst index 20acb267a569826647f006d404b6d08aabe2baa1..8ebe2cb209e7805ef115e7ae91a01579ed6a65fc 100644 --- a/docs/source/algorithms/MuonMaxent-v1.rst +++ b/docs/source/algorithms/MuonMaxent-v1.rst @@ -13,10 +13,10 @@ This algorithm calculates a single frequency spectrum from the time domain spect If a group contains zero counts (i.e. the detectors are dead) then they are excluded from the frequency calculation. In the outputs these groups record the phase and asymmetry as zero and :math:`999` respectively. -The time domian data :math:`D_k(t)`, where :math:`t` is time and :math:`k` is the spectrum number, has associated errors :math:`E_k(t)`. If the number of points chosen is greater than the number of time domain data points then extra points are +The time domain data :math:`D_k(t)`, where :math:`t` is time and :math:`k` is the spectrum number, has associated errors :math:`E_k(t)`. If the number of points chosen is greater than the number of time domain data points then extra points are added with infinite errors. The time domain data prior to :code:`FirstGoodTime` also have their errors set to infinity. The algorithm will produce the frequency spectra :math:`f(\omega)` and this is assumed to be real and positive. The upper limit of the frequency spectra is determined by :code:`MaxField`. The maximum frequency, :math:`\omega_\mathrm{max}` can be less than the Nyquist limit :math:`\frac{\pi}{\delta T}` if the instrumental frequency response function for -:math:`\omega>\omega_\mathrm{max}` is approximatley zero. The inital estimate of the frequency spectrum is flat. +:math:`\omega>\omega_\mathrm{max}` is approximatley zero. The initial estimate of the frequency spectrum is flat. The algorithm calculates an estimate of each time domain spectra, :math:`g_k(t)` by the equation diff --git a/docs/source/algorithms/NormaliseByDetector-v1.rst b/docs/source/algorithms/NormaliseByDetector-v1.rst index b7d8f7d19c444bfe9769827fca0974bc332e1edc..745205a1967ca9ab56378cadcdcc8fce7a8b4973 100644 --- a/docs/source/algorithms/NormaliseByDetector-v1.rst +++ b/docs/source/algorithms/NormaliseByDetector-v1.rst @@ -11,7 +11,7 @@ Description This algorithm is designed to normalise a workspace via detector efficiency functions. **For this algorithm to work, the Instrument -Defintion File `IDF <http://www.mantidproject.org/IDF>`_ must have fitting functions on the +Definition File `IDF <http://www.mantidproject.org/IDF>`_ must have fitting functions on the component tree**. The setup information for this, as well as some examples, are provided below. @@ -50,7 +50,7 @@ components, mean that fitting functions do not necessarily have to be assigned on a detector-by-detector basis. Applying a fit function to the instrument, will ensure that all subcomponents (including detectors), pick-up that function. However, functions assigned to lower-level -components (such as detectors) take precidence over and exising +components (such as detectors) take precedence over and existing functions that might exist on parent components (such as the instrument). You can even, have some parameters for a function provided against the detector, and pick up defaults from the bank, or instrument diff --git a/docs/source/algorithms/OneStepMDEW-v1.rst b/docs/source/algorithms/OneStepMDEW-v1.rst index dc1664119db75a31a79b519a58c319d74a401472..69bfee2d18b3cef815765299d2f182cf302dc456 100644 --- a/docs/source/algorithms/OneStepMDEW-v1.rst +++ b/docs/source/algorithms/OneStepMDEW-v1.rst @@ -22,7 +22,7 @@ with Lorentz correction, and default size/splitting behavior parameters. Usage ----- -Used internaly. See examples of :ref:`algm-LoadEventNexus` and :ref:`algm-ConvertToDiffractionMDWorkspace` algorithms +Used internally. See examples of :ref:`algm-LoadEventNexus` and :ref:`algm-ConvertToDiffractionMDWorkspace` algorithms for the details of the usage of these algorithms diff --git a/docs/source/algorithms/PDDetermineCharacterizations-v1.rst b/docs/source/algorithms/PDDetermineCharacterizations-v1.rst index 3bbf4814847a6404574a59735e923a5c76ce37b7..ac4f5017e3e81caf521c234f754fcf7e58ef6247 100644 --- a/docs/source/algorithms/PDDetermineCharacterizations-v1.rst +++ b/docs/source/algorithms/PDDetermineCharacterizations-v1.rst @@ -19,10 +19,10 @@ This algorithm is one of the workflow algorithms that helps :ref:`algm-SNSPowderReduction` and its child algorithm :ref:`algm-AlignAndFocusPowder`. -Determing Frequency and Wavelength -################################## +Determining Frequency and Wavelength +#################################### -The freqency is found by inspecting the logs (in order) +The frequency is found by inspecting the logs (in order) ``SpeedRequest1``, ``Speed1``, and ``frequency``. Whichever one has a nonzero value is used. Simlilarly, the wavelength is taken by inspecting ``LambdaRequest`` then ``Lambda``. If either the frequency diff --git a/docs/source/algorithms/PDFFourierTransform-v1.rst b/docs/source/algorithms/PDFFourierTransform-v1.rst index de892da208fd3652c62e6f89c070fe929689410a..d6e4d2cf8d75603895ddce1fc0f15caf3b650700 100644 --- a/docs/source/algorithms/PDFFourierTransform-v1.rst +++ b/docs/source/algorithms/PDFFourierTransform-v1.rst @@ -11,7 +11,7 @@ Description The algorithm transforms a single spectrum workspace containing spectral density :math:`S(Q)`, :math:`S(Q)-1`, or :math:`Q[S(Q)-1]` -(as a fuction of **MomentumTransfer** or **dSpacing** `units <http://www.mantidproject.org/Units>`_ ) to a PDF +(as a function of **MomentumTransfer** or **dSpacing** `units <http://www.mantidproject.org/Units>`_ ) to a PDF (pair distribution function) as described below. The input Workspace spectrum should be in the Q-space (\ **MomentumTransfer**\ ) `units <http://www.mantidproject.org/Units>`_ . @@ -22,7 +22,7 @@ References #. B. H. Toby and T. Egami, *Accuracy of Pair Distribution Functions Analysis Appliced to Crystalline and Non-Crystalline Materials*, Acta Cryst. (1992) A **48**, 336-346 `doi: 10.1107/S0108767391011327 <http://dx.doi.org/10.1107/S0108767391011327>`_ -#. B.H. Toby and S. Billinge, *Determination of Standard uncertainities in fits to pair distribution functions* Acta Cryst. (2004) A **60**, 315-317] +#. B.H. Toby and S. Billinge, *Determination of Standard uncertainties in fits to pair distribution functions* Acta Cryst. (2004) A **60**, 315-317] `doi: 10.1107/S0108767304011754 <http://dx.doi.org/10.1107/S0108767304011754>`_ .. The algorithm itself is able to identify the unit. -- not any more. TODO: should be investigated why this has been disabled diff --git a/docs/source/algorithms/PDLoadCharacterizations-v1.rst b/docs/source/algorithms/PDLoadCharacterizations-v1.rst index 48454d9e29068557729d8e4c6f0cb92a3475b81c..6e4666fa6a74a3eb5017ecfe685b54ffb46914aa 100644 --- a/docs/source/algorithms/PDLoadCharacterizations-v1.rst +++ b/docs/source/algorithms/PDLoadCharacterizations-v1.rst @@ -15,7 +15,7 @@ characterization information and a collection of output parameters for the focus positions to be used in :ref:`algm-EditInstrumentGeometry`. If a section is missing then those parameters will be empty. This includes an empty table (zero rows) if that information is missing. The resulting TableWorkspace -is intented to be used by :ref:`algm-PDDetermineCharacterizations` +is intended to be used by :ref:`algm-PDDetermineCharacterizations` This algorithm is one of the workflow algorithms that helps :ref:`algm-SNSPowderReduction`. diff --git a/docs/source/algorithms/PaddingAndApodization-v1.rst b/docs/source/algorithms/PaddingAndApodization-v1.rst index 365c47df7536082d55d39e1a1bc5170f3b35d1a3..283213a093d3eaae67946fc674a3ab776a5e6d4d 100644 --- a/docs/source/algorithms/PaddingAndApodization-v1.rst +++ b/docs/source/algorithms/PaddingAndApodization-v1.rst @@ -14,7 +14,7 @@ This algorithm can prepare data for Padding is when the input data is extended by adding extra measurments of zero at regular intervals. For real data this is only done after the end of the input data. However, for complex data the padding should be shared between the start and end of the input data. -`Apodization functions <http://mathworld.wolfram.com/ApodizationFunction.html>`_ can be used to remove data with large errors. These are usualy +`Apodization functions <http://mathworld.wolfram.com/ApodizationFunction.html>`_ can be used to remove data with large errors. These are usually found at large time scales. These take a decay constant (:math:`\tau` ) that determines the rate at which the data goes to zero. The time the function is evaluated at is denoted by :math:`t`. diff --git a/docs/source/algorithms/PeakIntensityVsRadius-v1.rst b/docs/source/algorithms/PeakIntensityVsRadius-v1.rst index 5bbcab8f5fefc6b06b3a35fca7f5f2fa07567113..20d90b1737e688e3dc2b50640490070b6e1594af 100644 --- a/docs/source/algorithms/PeakIntensityVsRadius-v1.rst +++ b/docs/source/algorithms/PeakIntensityVsRadius-v1.rst @@ -50,7 +50,7 @@ Usage The code itself works but disabled from doc tests as takes too long to complete. User should provide its own event nexus file instead of **TOPAZ_3132_event.nxs** used within this example. The original **TOPAZ_3132_event.nxs** -file is availible in `Mantid system tests repository <https://github.com/mantidproject/systemtests/tree/master/Data/TOPAZ_3132_event.nxs>`_. +file is available in `Mantid system tests repository <https://github.com/mantidproject/systemtests/tree/master/Data/TOPAZ_3132_event.nxs>`_. .. code-block:: python diff --git a/docs/source/algorithms/PlotPeakByLogValue-v1.rst b/docs/source/algorithms/PlotPeakByLogValue-v1.rst index aaa63fab9c676456901c90181d54fdc13e284435..db3af7c51363ec7d73d99a6dbd0a79bc3daa2531 100644 --- a/docs/source/algorithms/PlotPeakByLogValue-v1.rst +++ b/docs/source/algorithms/PlotPeakByLogValue-v1.rst @@ -81,7 +81,7 @@ The possible flags are: The index of the spectrum being fitted :code:`$basename` - A convinience flag for :code:`$wsname_$wsindex` (the same format the fit + A convenience flag for :code:`$wsname_$wsindex` (the same format the fit result and parameter output takes) :code:`$outputname` diff --git a/docs/source/algorithms/PlusMD-v1.rst b/docs/source/algorithms/PlusMD-v1.rst index 652d6a4f8b25871046c2dc629fcd72c0d71e862c..2b1cdbed7db09682d3dad6cf43b58b7c2588b13d 100644 --- a/docs/source/algorithms/PlusMD-v1.rst +++ b/docs/source/algorithms/PlusMD-v1.rst @@ -27,7 +27,7 @@ MDHistoWorkspaces MDEventWorkspaces ################# -This algorithm operates similary to calling Plus on two +This algorithm operates similarly to calling Plus on two :ref:`EventWorkspaces <EventWorkspace>`: it combines the events from the two workspaces together to form one large workspace. diff --git a/docs/source/algorithms/PoldiPeakSearch-v1.rst b/docs/source/algorithms/PoldiPeakSearch-v1.rst index 6051f20db58db298ad7dfc0518f281072bc0fe95..23cf305329edc04247023cf1397db723a7f18543 100644 --- a/docs/source/algorithms/PoldiPeakSearch-v1.rst +++ b/docs/source/algorithms/PoldiPeakSearch-v1.rst @@ -28,7 +28,7 @@ The algorithm store in peak-list. #. Split the list in two parts, :math:`[i_{0} + \Delta, i_{max} - \Delta)` and :math:`(i_{max} + \Delta, i_{n} - \Delta]`, - where :math:`\Delta` is the mininum number of data points between two peaks. + where :math:`\Delta` is the minimum number of data points between two peaks. #. If ranges are valid, perform algorithm on each of the sublists, append returned lists to peak-list. #. Return peak-list. diff --git a/docs/source/algorithms/PreprocessDetectorsToMD-v1.rst b/docs/source/algorithms/PreprocessDetectorsToMD-v1.rst index d1827a3046c21205f532febdb7cd5969b0ef233b..f993ec959f36c7359c013ba8e12492c2e35fc4bc 100644 --- a/docs/source/algorithms/PreprocessDetectorsToMD-v1.rst +++ b/docs/source/algorithms/PreprocessDetectorsToMD-v1.rst @@ -11,9 +11,9 @@ Description The algorithm calculates expensive part of the transformation from real to reciprocal space, calculating namely, detector positions, sample-detector distances, angular detectors positions, etc. These values can be slow to calculate -for composite detectors and other algorithms can substantially benifit from using preprocessed values. +for composite detectors and other algorithms can substantially benefit from using preprocessed values. -The algorithm places processed values into a table workspace with the following colums: +The algorithm places processed values into a table workspace with the following columns: +---------------+--------+------------------------------------------------------+ | Column Name : | Type | Description: | @@ -41,7 +41,7 @@ In addition to the preprocessed detectors intofmation, the following log entries - **L1** -- Source-sample distance. - **ActualDetectorsNum** -- total number of existing preprocessed detectors (number of rows in the table above). - **InstrumentName** -- the name of the source instrument. -- **FakeDetectors** -- if detectors posisions were not actually preprocessed but fake detectros were used instread +- **FakeDetectors** -- if detectors posisions were not actually preprocessed but fake detectros were used instead (InstrumentName==*FakeInstrument* in this case). diff --git a/docs/source/algorithms/RealFFT-v1.rst b/docs/source/algorithms/RealFFT-v1.rst index 65b63330ddc9784079b832a36bf754a077be142f..b9870dd914dbe7f56e6dc61a00956bf243e13af9 100644 --- a/docs/source/algorithms/RealFFT-v1.rst +++ b/docs/source/algorithms/RealFFT-v1.rst @@ -9,7 +9,7 @@ Description ----------- -This is an algorithm for Fourier transfom of real data. It uses the GSL +This is an algorithm for Fourier transform of real data. It uses the GSL routines gsl\_fft\_real\_transform and gsl\_fft\_halfcomplex\_inverse. The result of a forward transform is a three-spectra workspace with the real and imaginary parts of the transform in position 0 and 1 diff --git a/docs/source/algorithms/Rebin-v1.rst b/docs/source/algorithms/Rebin-v1.rst index 1da69119acfdeb25ff8b5ff0bb88a2e912f6b0fb..cd009d542abd8eb71323a266a6736c2c874c9a10 100644 --- a/docs/source/algorithms/Rebin-v1.rst +++ b/docs/source/algorithms/Rebin-v1.rst @@ -28,7 +28,7 @@ specified. In both cases, where a new bin only partially overlaps one or more input bins, the new counts are calculated as the sum of the old bins weighted -by the fractional overlaping widths of the new bin over the old bin: +by the fractional overlapping widths of the new bin over the old bin: .. math:: Y^{\mathrm{new}} = \sum_i Y^{\mathrm{old}}_i F_i .. math:: E^{\mathrm{new}} = \sqrt{\sum_i (E^{\mathrm{old}}_i)^2 F_i} diff --git a/docs/source/algorithms/ReflectometryILLPreprocess-v1.rst b/docs/source/algorithms/ReflectometryILLPreprocess-v1.rst index 13bca11bf47d9906f8d3957b993965540c024b8e..c44537b6c726103c3f4714c44442a2c13d586a8e 100644 --- a/docs/source/algorithms/ReflectometryILLPreprocess-v1.rst +++ b/docs/source/algorithms/ReflectometryILLPreprocess-v1.rst @@ -39,7 +39,7 @@ Foreground is a set of pixels intensities of which will be summed in :ref:`Refle Background, on the other hand, is a set of pixels which are be used for fitting a constant or linear background by :ref:`CalculatePolynomialBackground <algm-CalculatePolynomialBackground>`. -The foreground pixels are defined by the foreground centre and *ForegroundHalfWidth* property. In normal use cases, the foreground center (workspace index) is taken from the fitting in :ref:`LoadILLReflectometry <algm-LoadILLReflectometry>`. This can be overriden by giving the pixel as *BeamCentre*. Fractional values are rounded to nearest integer. The full process of deciding the foreground centre is as follows: +The foreground pixels are defined by the foreground centre and *ForegroundHalfWidth* property. In normal use cases, the foreground center (workspace index) is taken from the fitting in :ref:`LoadILLReflectometry <algm-LoadILLReflectometry>`. This can be overridden by giving the pixel as *BeamCentre*. Fractional values are rounded to nearest integer. The full process of deciding the foreground centre is as follows: * If *Run* is given then data is loaded using :ref:`LoadILLReflectometry <algm-LoadILLReflectometry>`: * If *BeamCentre* is set, it is passed over to :ref:`LoadILLReflectometry <algm-LoadILLReflectometry>`. diff --git a/docs/source/algorithms/ReflectometryILLSumForeground-v1.rst b/docs/source/algorithms/ReflectometryILLSumForeground-v1.rst index 5e9354f35fbca61565c846c973032af19dc4f863..c14d5cab93df239a8cfc18c171f45558e89f259f 100644 --- a/docs/source/algorithms/ReflectometryILLSumForeground-v1.rst +++ b/docs/source/algorithms/ReflectometryILLSumForeground-v1.rst @@ -35,7 +35,7 @@ Foreground pixels If *InputWorkspace* has been processed by :ref:`ReflectometryILLPreprocess <algm-ReflectometryILLPreprocess>`, the foreground information is available in the sample logs under the entries starting with ``foreground.``. By default these are used automatically. -The sample logs can be overriden using the *Foreground* property. It is a list of three integers defining the range and centre pixels as workspace indices: [start, centre, end]. The start and end values are inclusive. +The sample logs can be overridden using the *Foreground* property. It is a list of three integers defining the range and centre pixels as workspace indices: [start, centre, end]. The start and end values are inclusive. Usage ----- diff --git a/docs/source/algorithms/ReflectometryReductionOneAuto-v2.rst b/docs/source/algorithms/ReflectometryReductionOneAuto-v2.rst index 3adc63aa4ece2c409dd83a63096b559cb3d3eee7..591b502c901089f60b9b4123a2b97bdf743b172d 100644 --- a/docs/source/algorithms/ReflectometryReductionOneAuto-v2.rst +++ b/docs/source/algorithms/ReflectometryReductionOneAuto-v2.rst @@ -12,7 +12,7 @@ Description This algorithm is a facade over :ref:`algm-ReflectometryReductionOne` (see :ref:`algm-ReflectometryReductionOne` for more information on the wrapped algorithm). It optionally corrects the detector position and then pulls numeric parameters out of the instrument parameter file where possible. These automatically applied defaults -can be overriden by providing your own values. In addition, it outputs a rebinned workspace in Q, and it optionally +can be overridden by providing your own values. In addition, it outputs a rebinned workspace in Q, and it optionally performs polarization analysis if the input workspace is a workspace group. First, if :literal:`ThetaIn` is given the algorithm will try to correct the detector position. For this, it uses @@ -27,7 +27,7 @@ is inferred from other properties, depending on the value of :literal:`AnalysisM Note that ProcessingInstructions are workspace indices, not detector IDs. The first few workspaces may correspond to monitors, rather than detectors of interest. For the syntax of this property, see :ref:`algm-GroupDetectors`. -:literal:`theta` is calcualted using :literal:`SpecularReflectionCalculateTheta`. This is passed through to :literal:`ReflectometryReductionOne` and :literal:`2 * theta` is passed through to :literal:`CalculateResolution`. :literal:`theta` can be overridden by setting :literal:`ThetaIn` or :literal:`ThetaLogName` (:literal:`ThetaIn` takes precedence if both are given). If :literal:`CorrectDetectors` is also true, then the algorithm corrects the positions of the detectors of interest to :literal:`2 * theta` using :ref:`algm-SpecularReflectionPositionCorrect`. The detectors are moved either by shifting them vertically, or by rotating them around the sample position, as specified by :literal:`DetectorCorrectionType`. +:literal:`theta` is calculated using :literal:`SpecularReflectionCalculateTheta`. This is passed through to :literal:`ReflectometryReductionOne` and :literal:`2 * theta` is passed through to :literal:`CalculateResolution`. :literal:`theta` can be overridden by setting :literal:`ThetaIn` or :literal:`ThetaLogName` (:literal:`ThetaIn` takes precedence if both are given). If :literal:`CorrectDetectors` is also true, then the algorithm corrects the positions of the detectors of interest to :literal:`2 * theta` using :ref:`algm-SpecularReflectionPositionCorrect`. The detectors are moved either by shifting them vertically, or by rotating them around the sample position, as specified by :literal:`DetectorCorrectionType`. Next, the algorithm will try to populate input properties which have not been set. Specifically, it will search for :literal:`LambdaMin`, :literal:`LambdaMax`, :literal:`I0MonitorIndex`, :literal:`MonitorBackgroundMin`, :literal:`MonitorBackgroundMax`, diff --git a/docs/source/algorithms/ReflectometrySliceEventWorkspace-v1.rst b/docs/source/algorithms/ReflectometrySliceEventWorkspace-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..eff916942608aa13af65b4576f7267c3bf4a6d1e --- /dev/null +++ b/docs/source/algorithms/ReflectometrySliceEventWorkspace-v1.rst @@ -0,0 +1,75 @@ +.. algorithm:: + +.. summary:: + +.. relatedalgorithms:: + +.. properties:: + + +ReflectometrySliceEventWorkspace +-------------------------------- + +This algorithm slices an input workspace into one or more grouped output workspaces based on input filtering properties. + +It uses :ref:`algm-GenerateEventsFilter` to define the way splitting should be done and exposes the relevant input properties for that algorithm. It then performs the filtering using :ref:`algm-FilterEvents`. + +The sliced workspaces are then rebinned to histogram data and combined with the given monitor workspace, to produce a workspace suitable for input to :ref:`algm-ReflectometryReductionOneAuto`. The monitors for each slice are scaled according to the percentage of ``proton_charge`` in that slice. + +Usage +------- + +**Example: slice by time interval** + +.. testcode:: ExSliceByTime + + from __future__ import print_function + input_ws = CreateSampleWorkspace("Event",BankPixelWidth=1,BinWidth=20000) + AddTimeSeriesLog(input_ws, Name="proton_charge", Time="2010-01-01T00:00:00", Value=100) + AddTimeSeriesLog(input_ws, Name="proton_charge", Time="2010-01-01T00:10:00", Value=100) + AddTimeSeriesLog(input_ws, Name="proton_charge", Time="2010-01-01T00:20:00", Value=80) + AddTimeSeriesLog(input_ws, Name="proton_charge", Time="2010-01-01T00:30:00", Value=80) + AddTimeSeriesLog(input_ws, Name="proton_charge", Time="2010-01-01T00:40:00", Value=15) + AddTimeSeriesLog(input_ws, Name="proton_charge", Time="2010-01-01T00:50:00", Value=100) + monitor_ws = CreateSampleWorkspace(NumBanks=0, NumMonitors=3, BankPixelWidth=1, NumEvents=10000) + + output = ReflectometrySliceEventWorkspace(InputWorkspace=input_ws, MonitorWorkspace=monitor_ws, + TimeInterval=600, StartTime='1800', StopTime='3300') + + print(str(output.getNumberOfEntries()) + ' slices') + print(str(output[0].getNumberHistograms()) + ' spectra') + print('Y values for first bin:') + for i in range(output.getNumberOfEntries()): + print('Slice ' + str(i)) + for j in range(output[i].getNumberHistograms()): + print(output[i].dataY(j)[0]) + +Output: + +.. testoutput:: ExSliceByTime + + 3 slices + 5 spectra + Y values for first bin: + Slice 0 + 0.173684210526 + 0.173684210526 + 0.173684210526 + 4.0 + 4.0 + Slice 1 + 0.0726315789474 + 0.0726315789474 + 0.0726315789474 + 4.0 + 4.0 + Slice 2 + 0.0631578947368 + 0.0631578947368 + 0.0631578947368 + 1.0 + 1.0 + +.. categories:: + +.. sourcelink:: diff --git a/docs/source/algorithms/RemoveLowResTOF-v1.rst b/docs/source/algorithms/RemoveLowResTOF-v1.rst index 34a1c2c83c21000025d814bd65a2f95ef0940d65..e0fac7361d9628c73f367093b0563ee6c5eeb892 100644 --- a/docs/source/algorithms/RemoveLowResTOF-v1.rst +++ b/docs/source/algorithms/RemoveLowResTOF-v1.rst @@ -15,7 +15,7 @@ The selection is made based on whether or not ``MinWavelength`` is specified. MinWavelength ############# -If the minimum wavelength is specified, then the mimimum time-of-flight for each pixel is calculated by converting the ``MinWavelength`` to time-of-flight using the standard equation found in :ref:`algm-ConvertUnits`. +If the minimum wavelength is specified, then the minimum time-of-flight for each pixel is calculated by converting the ``MinWavelength`` to time-of-flight using the standard equation found in :ref:`algm-ConvertUnits`. Hodges Criteria ############### @@ -25,7 +25,7 @@ First is calculated the value of :math:`dspmap = 1/DIFC`. Then the value of :math:`sqrtdmin = \sqrt{T_{min} / DIFC_{ref}} + m_K * \log_{10}(dspmap * DIFC_{ref})` If this is a negative number then the minimum time-of-flight is set to zero. Otherwise -it is caculated as +it is calculated as :math:`tmin = sqrtdmin * sqrtdmin / dspmap` diff --git a/docs/source/algorithms/RemoveWorkspaceHistory-v1.rst b/docs/source/algorithms/RemoveWorkspaceHistory-v1.rst index afe1bcfe38d33e0917af9933dae402094769b6fe..1b089159a3350c37e9aa20f18a747e2dfd22e746 100644 --- a/docs/source/algorithms/RemoveWorkspaceHistory-v1.rst +++ b/docs/source/algorithms/RemoveWorkspaceHistory-v1.rst @@ -9,7 +9,7 @@ Description ----------- -Removes all algorithm history records from a given workspace. This includes all workflow and child algorithm history records. After this algorithm has been run, the workspace will not be reproducable +Removes all algorithm history records from a given workspace. This includes all workflow and child algorithm history records. After this algorithm has been run, the workspace will not be reproducible from its history. Note that this algorithm will not remove the environment history associated with a workspace. Usage diff --git a/docs/source/algorithms/ReplicateMD-v1.rst b/docs/source/algorithms/ReplicateMD-v1.rst index 46b5d35df5be0e6335508dc7e649430109a843b5..f73245b94b745b029fef097fa6b31e52b6b11a2b 100644 --- a/docs/source/algorithms/ReplicateMD-v1.rst +++ b/docs/source/algorithms/ReplicateMD-v1.rst @@ -10,7 +10,7 @@ Description ----------- -This algorithm creates a higher dimensional dataset by replicating along an additional axis. The synax is similar to that used by `Horace <http://horace.isis.rl.ac.uk/Reshaping_etc#replicate>`__. +This algorithm creates a higher dimensional dataset by replicating along an additional axis. The syntax is similar to that used by `Horace <http://horace.isis.rl.ac.uk/Reshaping_etc#replicate>`__. The *ShapeWorkspace* input defines the shape of the *OutputWorkspace*, but not the contents. The *DataWorkspace* provides the data contents in the lower dimensionality cut, which will be replicated over. This algorithm operates on :ref:`MDHistoWorkspace <MDHistoWorkspace>` inputs and provides a :ref:`MDHistoWorkspace <MDHistoWorkspace>` as an output. diff --git a/docs/source/algorithms/ResizeRectangularDetector-v1.rst b/docs/source/algorithms/ResizeRectangularDetector-v1.rst index 57bcc563f8e6f7ec81e96785e5b5e4fc4690e73e..cb2c7b4305a477898fa98b5e62ee8006f3a2696b 100644 --- a/docs/source/algorithms/ResizeRectangularDetector-v1.rst +++ b/docs/source/algorithms/ResizeRectangularDetector-v1.rst @@ -11,7 +11,7 @@ Description This algorithm will resize a :ref:`RectangularDetector <RectangularDetector>` by applying X and Y -scaling factors. Each pixel's position will be modifed relative to the +scaling factors. Each pixel's position will be modified relative to the 0,0 point of the detector by these factors. Typically, a RectangularDetector is constructed around its center, so this would scale the detector around its center. diff --git a/docs/source/algorithms/RunPythonScript-v1.rst b/docs/source/algorithms/RunPythonScript-v1.rst index 82c50218b7d9125ed68b74dd95ab34bb71ea588a..e20c00d2e409ef867482b8d39629837e9959f371 100644 --- a/docs/source/algorithms/RunPythonScript-v1.rst +++ b/docs/source/algorithms/RunPythonScript-v1.rst @@ -21,7 +21,7 @@ You are expected to create the output workspace yourself. Because of boilerplate code added to the python script being run, stack-traces for errors will be five (5) lines greater than where the -error occured in the supplied python code. +error occurred in the supplied python code. Usage ----- diff --git a/docs/source/algorithms/SANSDarkRunBackgroundCorrection-v1.rst b/docs/source/algorithms/SANSDarkRunBackgroundCorrection-v1.rst index 44245466bb056f4b1efb6dccad0ccca4dae1d509..337b14f2d3c04dc3012e76859e4d6e6ae6f0c736 100644 --- a/docs/source/algorithms/SANSDarkRunBackgroundCorrection-v1.rst +++ b/docs/source/algorithms/SANSDarkRunBackgroundCorrection-v1.rst @@ -11,7 +11,7 @@ Description This algorithm subtracts a dark run from a workspace. *InputWorkspace* and *DarkRun* have to be of type Workspace2D and need to contain the same spectra. -The user can choose to either subtract spectra which are assoicated with detecors +The user can choose to either subtract spectra which are associated with detecors (*ApplyToDetectors*) and/or monitors (*ApplyToMonitors*). In the case of monitors, the user can select specific monitors (*SelectedMonitors*) according to their detecotor IDs. diff --git a/docs/source/algorithms/SANSSliceEvent-v1.rst b/docs/source/algorithms/SANSSliceEvent-v1.rst index 77aad4d01d187986bed772ace25177d1cea50f73..5347f8173492cccbb22005c19f9ac6d872974c2d 100644 --- a/docs/source/algorithms/SANSSliceEvent-v1.rst +++ b/docs/source/algorithms/SANSSliceEvent-v1.rst @@ -10,7 +10,7 @@ Description ----------- This algorithm creates a sliced workspaces from an event-based SANS input workspace according to the settings in the state object. -The algorithm will extract a slice based on a start and end time which are set in the state object. In addtion the data type, ie +The algorithm will extract a slice based on a start and end time which are set in the state object. In addition the data type, ie if the slice is to be taken from a sample or a can workspace can be specified. Note that the monitor workspace is not being sliced but scaled by the ratio of the proton charge of the sliced worspace to the full workspace. Currently the mask mechanism is implemented for **SANS2D**, **LOQ** and **LARMOR**. diff --git a/docs/source/algorithms/SANSStitch-v1.rst b/docs/source/algorithms/SANSStitch-v1.rst index 9b20f09d4412a5f503bc02f60cb7622bd3d6d272..79768bca62a43b6b98d42def1586e5884d57bdcf 100644 --- a/docs/source/algorithms/SANSStitch-v1.rst +++ b/docs/source/algorithms/SANSStitch-v1.rst @@ -27,7 +27,7 @@ There are 4 available fit modes used to scale and shift the high angle bank data Can Runs ############ -When can runs are provided they are processed separately using the same merge forumla above, and then subtracted from the processed sample run. If can runs are provided as inputs then the scale and shift factors are determined as part of fitting by operating on a workspace calculated from: +When can runs are provided they are processed separately using the same merge formula above, and then subtracted from the processed sample run. If can runs are provided as inputs then the scale and shift factors are determined as part of fitting by operating on a workspace calculated from: .. math:: \frac{C_{sample}(Q)}{N_{sample}(Q)} - \frac{C_{can}(Q)}{N_{can}(Q)} diff --git a/docs/source/algorithms/SNSPowderReduction-v1.rst b/docs/source/algorithms/SNSPowderReduction-v1.rst index 5ce240037e53fe715998e25108ce92923d6c756d..fc48ade4678dc038c4cfbe28607a8a97105cf93c 100644 --- a/docs/source/algorithms/SNSPowderReduction-v1.rst +++ b/docs/source/algorithms/SNSPowderReduction-v1.rst @@ -40,7 +40,7 @@ created during the algorithm's execution. If specified, the ``CalibrationFile`` is loaded using :ref:`algm-LoadDiffCal`. If the ``GroupingFile`` is specified, the -grouping it specifies takes precidence over the one that is in the +grouping it specifies takes precedence over the one that is in the ``CalibrationFile``. :ref:`algm-LoadDetectorsGroupingFile` performs the loading. The order of preference in which to use is (first found wins): diff --git a/docs/source/algorithms/SassenaFFT-v1.rst b/docs/source/algorithms/SassenaFFT-v1.rst index 910dcc900dfb4ae363b1d8a9031fbdc136009515..bfecdf0357b5c9c922c6c9056253912b473263aa 100644 --- a/docs/source/algorithms/SassenaFFT-v1.rst +++ b/docs/source/algorithms/SassenaFFT-v1.rst @@ -16,7 +16,7 @@ type :ref:`Workspace2D <Workspace2D>`, grouped under a single :ref:`WorkspaceGroup <WorkspaceGroup>`. It is implied that the time unit is one **picosecond**. -Sassena ouput files are in `HDF5 <http://www.hdfgroup.org/HDF5>`__ format, and can be made up of the +Sassena output files are in `HDF5 <http://www.hdfgroup.org/HDF5>`__ format, and can be made up of the following datasets: *qvectors*, *fq*, *fq0*, *fq2*, and *fqt* The group workspace should contain workspaces **\_fqt.Re** and diff --git a/docs/source/algorithms/SaveCSV-v1.rst b/docs/source/algorithms/SaveCSV-v1.rst index 43c7a7253f02a5842d408d5b1e94e71823eba75a..ffcbb6d20156016119f7cf5f4fa276a2b3330f58 100644 --- a/docs/source/algorithms/SaveCSV-v1.rst +++ b/docs/source/algorithms/SaveCSV-v1.rst @@ -10,7 +10,7 @@ Description ----------- The format of the saved ascii CSV file for a 1D worksspace consists of -three columns where the numbers of each row are seperated by the +three columns where the numbers of each row are separated by the Separator and each line by the LineSeparator. The format of the saved CSV file for a 2D workspace is as follows:: diff --git a/docs/source/algorithms/SaveGSS-v1.rst b/docs/source/algorithms/SaveGSS-v1.rst index c6d2a2c0f8deb8710a184c42dba34026918c0952..09d796329807acfd3c4935b880369d6d0e2d9730 100644 --- a/docs/source/algorithms/SaveGSS-v1.rst +++ b/docs/source/algorithms/SaveGSS-v1.rst @@ -77,7 +77,7 @@ Output: removeFiles([file_name]) DeleteWorkspace("SaveGSSWorkspace") -**Example - an example using SaveGSS with additonal options.** +**Example - an example using SaveGSS with additional options.** .. testcode:: ExSaveGSSOptions diff --git a/docs/source/algorithms/SaveNexusPD-v1.rst b/docs/source/algorithms/SaveNexusPD-v1.rst index 475405a9e571cde8ff003789bdb3582e318b7aee..40cf5d75df97fb3a9e8b3f35e8d529598d755c2f 100644 --- a/docs/source/algorithms/SaveNexusPD-v1.rst +++ b/docs/source/algorithms/SaveNexusPD-v1.rst @@ -13,7 +13,7 @@ Description The file created by this algorithm saves a single workspace in a single ``NXentry`` of a `NeXus <http://www.nexusformat.org/>`_ file. The x-axes are saved in time-of-flight, d-spacing, and -(optionally) momentum transfer. The file is formated to support the +(optionally) momentum transfer. The file is formatted to support the rules for `NXdata <http://download.nexusformat.org/doc/html/classes/base_classes/NXdata.html>`_, `NXdetector @@ -27,7 +27,7 @@ same object. The format of the file (for a workspace with a single spectrum is d * ``NXmoderator`` - * ``distance`` - commonly refered to as ``L1`` in diffraction + * ``distance`` - commonly referred to as ``L1`` in diffraction * ``NXdetector`` @@ -42,9 +42,9 @@ same object. The format of the file (for a workspace with a single spectrum is d * ``Q`` - values are stored in reverse so they are parallel to the ``data`` array - * ``distance`` - commonly refered to as ``L2`` in diffraction + * ``distance`` - commonly referred to as ``L2`` in diffraction - * ``polar_angle`` - commonly refered to as two-theta in diffraction + * ``polar_angle`` - commonly referred to as two-theta in diffraction * ``azimuthal_angle`` - out of plane angle diff --git a/docs/source/algorithms/SaveNexusProcessed-v1.rst b/docs/source/algorithms/SaveNexusProcessed-v1.rst index 3f22356ced7371f7aa8236855b28422eca91d0ca..9c3bfca6e020f1d037d7c42625583d9ed42ef850 100644 --- a/docs/source/algorithms/SaveNexusProcessed-v1.rst +++ b/docs/source/algorithms/SaveNexusProcessed-v1.rst @@ -80,7 +80,7 @@ Output: removeFiles([file_name]) -**Example - an example using SaveNexusProcessed with additonal options.** +**Example - an example using SaveNexusProcessed with additional options.** .. testcode:: ExSaveNexusProcessedOptions diff --git a/docs/source/algorithms/SavePAR-v1.rst b/docs/source/algorithms/SavePAR-v1.rst index 78db4aa3108e0eefb62ffbc86170731967cb55e9..e6ff5e91f86a297e1f18c6dc418b2e0e2c133123 100644 --- a/docs/source/algorithms/SavePAR-v1.rst +++ b/docs/source/algorithms/SavePAR-v1.rst @@ -47,7 +47,7 @@ Usage .. testcode:: exSavePAR - # import os funcions to work with folders + # import os functions to work with folders import os # create sample workspace ws = CreateSampleWorkspace() diff --git a/docs/source/algorithms/SavePHX-v1.rst b/docs/source/algorithms/SavePHX-v1.rst index 09d5003a03a2f3eaef5a0ba78ec8c6ea9078fe64..b362dca83bd3568d29b5327e1d58d84cbf1f94f3 100644 --- a/docs/source/algorithms/SavePHX-v1.rst +++ b/docs/source/algorithms/SavePHX-v1.rst @@ -53,7 +53,7 @@ Usage .. testcode:: exSavePHX - # import os funcions to work with folders + # import os functions to work with folders import os # create sample workspace ws=CreateSampleWorkspace() diff --git a/docs/source/algorithms/SaveReflectometryAscii-v1.rst b/docs/source/algorithms/SaveReflectometryAscii-v1.rst index 8b86d415eea65b64b3d813663e54251562cb73b2..e3409a6f1f724c87c9f93b7cc4d2631b435df277 100644 --- a/docs/source/algorithms/SaveReflectometryAscii-v1.rst +++ b/docs/source/algorithms/SaveReflectometryAscii-v1.rst @@ -12,7 +12,7 @@ Description This algorithm saves the first spectrum of a workspace in ASCII format in order to be processed by software, e.g. Motofit. It is possible to provide a group of workspaces as input. In this case, each filename contains the corresponding workspace name. -The choice of the file extension (`.mft`, `.txt`, `.dat`) defines the file format and appends the `Filename` with the correponding extension except for the `custom` field, which represents a custom format where the `Filename` can be choosen freely. +The choice of the file extension (`.mft`, `.txt`, `.dat`) defines the file format and appends the `Filename` with the corresponding extension except for the `custom` field, which represents a custom format where the `Filename` can be chosen freely. In case of histogrammed input data, the resulting file will contain the bin centre for the x-values representing the quantity `q`. It is especially useful for saving reflectometry reduction data. A file can be loaded back into Mantid by :ref:`algm-LoadAscii`, which will not have an instrument defined and `Sample Logs` are missing. diff --git a/docs/source/algorithms/SetMDFrame-v1.rst b/docs/source/algorithms/SetMDFrame-v1.rst index c722fcadd94d7a619c1835679d0029dcc0c8a579..bf857c3780f5e104af19c9af13af050252366339 100644 --- a/docs/source/algorithms/SetMDFrame-v1.rst +++ b/docs/source/algorithms/SetMDFrame-v1.rst @@ -28,7 +28,7 @@ a Numpy-style array selection. Usage ----- -**Example - Sample useage of SetMDFrame** +**Example - Sample usage of SetMDFrame** .. testcode:: SetMDFrameExample diff --git a/docs/source/algorithms/SetSample-v1.rst b/docs/source/algorithms/SetSample-v1.rst index 9d7e6155da66eb0e672a2ef70814f158eb7807e6..ca36b085e2965ba238a672e63cf0ce0eeb73bf61 100644 --- a/docs/source/algorithms/SetSample-v1.rst +++ b/docs/source/algorithms/SetSample-v1.rst @@ -118,7 +118,7 @@ The following example uses a test file called ``CRYO-01.xml`` in the # A fake host workspace, replace this with your real one. ws = CreateSampleWorkspace() - # Use geometry as is from environment defintion + # Use geometry as is from environment definition SetSample(ws, Environment={'Name': 'CRYO-01', 'Container': '8mm'}, Material={'ChemicalFormula': '(Li7)2-C-H4-N-Cl6', 'SampleNumberDensity': 0.1}) @@ -129,7 +129,7 @@ The following example uses a test file called ``CRYO-01.xml`` in the # A fake host workspace, replace this with your real one. ws = CreateSampleWorkspace() - # Use geometry from environment but set differnet height for sample + # Use geometry from environment but set different height for sample SetSample(ws, Environment={'Name': 'CRYO-01', 'Container': '8mm'}, Geometry={'Height': 4.0}, Material={'ChemicalFormula': '(Li7)2-C-H4-N-Cl6', diff --git a/docs/source/algorithms/SetUB-v1.rst b/docs/source/algorithms/SetUB-v1.rst index ca951cb3b93c42a35675a27c456377dc32589800..c68b9b3ce8c73df6fbe08f9fe246af4b97b30a93 100644 --- a/docs/source/algorithms/SetUB-v1.rst +++ b/docs/source/algorithms/SetUB-v1.rst @@ -12,7 +12,7 @@ Description The algorithms will attach an OrientedLattice object to a sample in the workspace. For MD workspaces, you can select to which sample to attach it. If nothing entered, it will attach to all. If bad number is -enetered, it will attach to first sample. +entered, it will attach to first sample. If :ref:`UB matrix <Lattice>` elements are entered, lattice parameters and orientation vectors are ignored. The algorithm will throw an exception if the diff --git a/docs/source/algorithms/SimulatedDensityOfStates-v1.rst b/docs/source/algorithms/SimulatedDensityOfStates-v1.rst index 08639ea28bff8e51f9750639344621a43a61546e..b35837432f0a78c0d2aadc33db8848fa902f14bf 100644 --- a/docs/source/algorithms/SimulatedDensityOfStates-v1.rst +++ b/docs/source/algorithms/SimulatedDensityOfStates-v1.rst @@ -12,7 +12,7 @@ Description Calculates phonon densities of states, Raman and IR spectrum from the output of CASTEP code obtained in the form of *.phonon* and *.castep* files. -The PeakWidth property may be passed a function containg the variable "energy" +The PeakWidth property may be passed a function containing the variable "energy" (e.g. *0.1*energy*) to set the FWHM of the peak as a function of the energy (centre point of the peak). This can be useful for comparison with experimental data by allowing the peak width to change according to the resolution of the diff --git a/docs/source/algorithms/SmoothData-v1.rst b/docs/source/algorithms/SmoothData-v1.rst index c6058b2799a4162e020bbaacb1f63094d1b09e19..b6681361b9210fbdb06b03100220e379328a2bfe 100644 --- a/docs/source/algorithms/SmoothData-v1.rst +++ b/docs/source/algorithms/SmoothData-v1.rst @@ -41,7 +41,7 @@ Example 2: use different NPoints for groups of spectra # Create a workspace ws = CreateSampleWorkspace() - # Greate a grouping workspace to put detectors from banks + # Create a grouping workspace to put detectors from banks # bank1 and bank2 into two separate groups gr = CreateGroupingWorkspace(ws,GroupNames='bank1,bank2') diff --git a/docs/source/algorithms/SmoothNeighbours-v1.rst b/docs/source/algorithms/SmoothNeighbours-v1.rst index 83520295a0d204d444da6ec15a878b19a705b81e..7b7ebfdb1779186fb600eab899d6bdbdd911293d 100644 --- a/docs/source/algorithms/SmoothNeighbours-v1.rst +++ b/docs/source/algorithms/SmoothNeighbours-v1.rst @@ -149,7 +149,7 @@ Property Values of Examples How it Works ############ -The algorithm will fetch neigbours using the intesection of those inside +The algorithm will fetch neighbours using the intesection of those inside the radius cut-off and those less than the NumberOfNeighbours specified. *Fig. 1* illustrates this process. Searching is relative to the central detector, those constrained by both specified number of neighbours have diff --git a/docs/source/algorithms/SortByQVectors-v1.rst b/docs/source/algorithms/SortByQVectors-v1.rst index 1759811c40bcf4d54c2ad71ea21764e5b6ec3fdd..10ba613fc2c8f10d1912cd2abf789ec63dbfa4ce 100644 --- a/docs/source/algorithms/SortByQVectors-v1.rst +++ b/docs/source/algorithms/SortByQVectors-v1.rst @@ -10,7 +10,7 @@ Description ----------- This algorithm sorts a group workspace by the qvectors found in the -qvectors file. Workspaces will be tranformed if the qvectors dimension +qvectors file. Workspaces will be transformed if the qvectors dimension is in the bins. Used for output from LoadSassena. Usage diff --git a/docs/source/algorithms/SplineSmoothing-v1.rst b/docs/source/algorithms/SplineSmoothing-v1.rst index 074d3dc85985862b468274462a215ee44723f0ba..9a0a35b49827b18c8355669e0b04b9b12feb0f8c 100644 --- a/docs/source/algorithms/SplineSmoothing-v1.rst +++ b/docs/source/algorithms/SplineSmoothing-v1.rst @@ -27,9 +27,9 @@ period of time. The lower breaking points number is set the faster algorithm will execute the function but it will not produce high quality smoothing function. By inserting high number of breaking points, a detailed smoothing function can also be produced. By not providing -MaxNumberOfBreaks, the alogirthm will assume that user would like to +MaxNumberOfBreaks, the algorithm will assume that user would like to execute the maximum number of breaks possible. This comes with a risk -of alogirthm falling in to a very long loop. +of algorithm falling in to a very long loop. By providing MaxNumberOfBreaks as a parameter, the users are also will be able to successfully and efficiently apply the algorithm to a workspace diff --git a/docs/source/algorithms/StartLiveData-v1.rst b/docs/source/algorithms/StartLiveData-v1.rst index 354680430c8fde3b58ab061c2fd3e8b50a2390e3..8cb0d00fcc9d6a95c82974aed1311a57dba331b4 100644 --- a/docs/source/algorithms/StartLiveData-v1.rst +++ b/docs/source/algorithms/StartLiveData-v1.rst @@ -158,7 +158,7 @@ Usage # put back the facility ConfigService.setFacility(oldFacility) - #get the ouput workspace + #get the output workspace wsOut = mtd["wsOut"] print("The workspace contains %i events" % wsOut.getNumberEvents()) @@ -224,7 +224,7 @@ Output: # put back the facility ConfigService.setFacility(oldFacility) - #get the ouput workspace + #get the output workspace wsOut = mtd["wsOut"] print("The workspace contains %i periods" % wsOut.getNumberOfEntries()) print("Each period contains %i spectra" % wsOut.getItem(0).getNumberHistograms()) diff --git a/docs/source/algorithms/StepScan-v1.rst b/docs/source/algorithms/StepScan-v1.rst index 1bf845a392b374ce1fec3072e050a6fd07271f1b..68b4294389a09612bcc54b1a1bb372f9bcdb487a 100644 --- a/docs/source/algorithms/StepScan-v1.rst +++ b/docs/source/algorithms/StepScan-v1.rst @@ -23,14 +23,14 @@ resulting table pertaining to scan\_index=0 (which indicates 'not a scan point') is then removed. Before then it will call other algorithms as shown in the flowchart, -if the relevent inputs have been set. +if the relevant inputs have been set. :ref:`algm-MaskDetectors` will be called if a MaskWorkspace is supplied. If either Xmin or Xmax or both are supplied, then :ref:`algm-FilterByXValue` algorithm is run to restrict the region of data included and if RangeUnit is not TOF, :ref:`algm-ConvertUnits` is run beforehand. -If necessary, the imput workspace is cloned, to save it from being modified. +If necessary, the input workspace is cloned, to save it from being modified. .. image:: ../images/StepScanWorkflow.png diff --git a/docs/source/algorithms/StripVanadiumPeaks-v1.rst b/docs/source/algorithms/StripVanadiumPeaks-v1.rst index d3e4307fb67b2ac60db7eaab66236099c014489a..cad16910ccff160ebe068d0c6d72ab9cce414a41 100644 --- a/docs/source/algorithms/StripVanadiumPeaks-v1.rst +++ b/docs/source/algorithms/StripVanadiumPeaks-v1.rst @@ -18,7 +18,7 @@ Description - The PeakWidthPercent value is used to estimate the width of the peak (as a percentage of the d-spacing value). -- The algorithm performs a simple linear fit of the background exluding +- The algorithm performs a simple linear fit of the background excluding the peak. - It uses two use averaging regions of 1/2 width, centered at +- diff --git a/docs/source/algorithms/SumOverlappingTubes-v1.rst b/docs/source/algorithms/SumOverlappingTubes-v1.rst index f8b5d777d1f5ae0a72e960fe1544e8212b980770..0dcf7775d0131744f4968c8b873ab19993478f24 100644 --- a/docs/source/algorithms/SumOverlappingTubes-v1.rst +++ b/docs/source/algorithms/SumOverlappingTubes-v1.rst @@ -22,7 +22,7 @@ If the Normalise option is set then the counts for each point in the OutputWorks .. math:: C_{scaled, i} = \frac{C_i}{N_{i}} -where :math:`C_{scaled, i}` is the scaled counts, :math:`C_i` the raw counts, and :math:`N_{i}` is the number of tube pixels contributing to the point being scaled. +where :math:`C_{scaled, i}` is the scaled counts, :math:`C_i` the raw counts, and :math:`N_{i}` is the number of tube pixels contributing to the point being scaled. Note that pixels counting zero do enter the normalisation, however the masked pixels do not. 2DTubes Option ++++++++++++++ diff --git a/docs/source/algorithms/SumSpectra-v1.rst b/docs/source/algorithms/SumSpectra-v1.rst index e4782aa29ea45b091d388a407d2de87593ce94fb..6230d384cce3deea5d416cefef379ce71ba6cb9e 100644 --- a/docs/source/algorithms/SumSpectra-v1.rst +++ b/docs/source/algorithms/SumSpectra-v1.rst @@ -63,7 +63,7 @@ Output: Workspace has 200 spectra Workspace has 1 spectra -**Example - running SumSpectra with a list of indicies.** +**Example - running SumSpectra with a list of indices.** .. testcode:: ExSumSpectraListOfIndicies diff --git a/docs/source/algorithms/ThresholdMD-v1.rst b/docs/source/algorithms/ThresholdMD-v1.rst index d36b21dcb20717f7235fdc5bb4e4ac674aaf11ec..e94bbf5dc85cbcc9a534ab7e84310eb4c743ac34 100644 --- a/docs/source/algorithms/ThresholdMD-v1.rst +++ b/docs/source/algorithms/ThresholdMD-v1.rst @@ -14,7 +14,7 @@ This algorithm applies a simple linear transformation to a :ref:`MDHistoWorkspace <MDHistoWorkspace>`. This could be used, for example, to scale the Energy dimension to different units. -Each coordinate is tranformed so that :math:`x'_d = (x_d * s_d) + o_d` +Each coordinate is transformed so that :math:`x'_d = (x_d * s_d) + o_d` where: - d : index of the dimension, from 0 to the number of dimensions diff --git a/docs/source/algorithms/TransformHKL-v1.rst b/docs/source/algorithms/TransformHKL-v1.rst index c45332e0205fa886e625e1c02fe7676c1a65a8c4..2d6403ae9741734ee5ed7b8b36fed0b264592440 100644 --- a/docs/source/algorithms/TransformHKL-v1.rst +++ b/docs/source/algorithms/TransformHKL-v1.rst @@ -10,11 +10,11 @@ Description ----------- Given a PeaksWorkspace with a :ref:`UB matrix <Lattice>` stored with -the sample, this algoritm will accept a 3x3 transformation matrix M, +the sample, this algorithm will accept a 3x3 transformation matrix M, change UB to UB\*M-inverse and map each (HKL) vector to M\*(HKL). For example, the transformation with elements 0,1,0,1,0,0,0,0,-1 will interchange the H and K values and negate L. This algorithm should allow -the usr to perform any required transformation of the Miller indicies, +the usr to perform any required transformation of the Miller indices, provided that transformation has a positive determinant. If a transformation with a negative or zero determinant is entered, the algorithm with throw an exception. The 9 elements of the transformation must be specified as a diff --git a/docs/source/algorithms/TransformMD-v1.rst b/docs/source/algorithms/TransformMD-v1.rst index 30d35a37f53492a9eec02f234554802b3757c7c7..81232a6d3999e4904bf492464eedcf4cae0e2617 100644 --- a/docs/source/algorithms/TransformMD-v1.rst +++ b/docs/source/algorithms/TransformMD-v1.rst @@ -14,7 +14,7 @@ This algorithm applies a simple linear transformation to a :ref:`MDHistoWorkspace <MDHistoWorkspace>`. This could be used, for example, to scale the Energy dimension to different units. -Each coordinate is tranformed so that :math:`x'_d = (x_d * s_d) + o_d` +Each coordinate is transformed so that :math:`x'_d = (x_d * s_d) + o_d` where: - d : index of the dimension, from 0 to the number of dimensions diff --git a/docs/source/algorithms/Transpose-v1.rst b/docs/source/algorithms/Transpose-v1.rst index 84cf52e8f8dc154e84921d75be91276b63a8cf70..82df8dd1470ad3b4704e26edc466b908b9a5dd06 100644 --- a/docs/source/algorithms/Transpose-v1.rst +++ b/docs/source/algorithms/Transpose-v1.rst @@ -13,7 +13,7 @@ This algorithm transposes a workspace, so that an N1 x N2 workspace becomes N2 x N1. The X-vector values for the new workspace are taken from the axis values -of the old workspace, which is generaly the spectra number but can be +of the old workspace, which is generally the spectra number but can be other values, if say the workspace has gone through :ref:`ConvertSpectrumAxis <algm-ConvertSpectrumAxis>`. diff --git a/docs/source/algorithms/VelocityCrossCorrelations-v1.rst b/docs/source/algorithms/VelocityCrossCorrelations-v1.rst index 5dfdb25767afb3aeb69bbf466a4c07b50b0a4adf..2b8494768f873d14f86b3b50e986144afcb139e8 100644 --- a/docs/source/algorithms/VelocityCrossCorrelations-v1.rst +++ b/docs/source/algorithms/VelocityCrossCorrelations-v1.rst @@ -9,7 +9,7 @@ Description ------------ -Loads a netcdf file generated by nMoldyn containing MMTK format trajectories. The algorithm calculates velocity cross-correlations of each pair of particles, sums and averages the correlations into bins according to the type of pairing. The correlations are also scaled by coherent scattering lenghts of different atom types. +Loads a netcdf file generated by nMoldyn containing MMTK format trajectories. The algorithm calculates velocity cross-correlations of each pair of particles, sums and averages the correlations into bins according to the type of pairing. The correlations are also scaled by coherent scattering lengths of different atom types. Example ------------ diff --git a/docs/source/algorithms/VesuvioPreFit-v1.rst b/docs/source/algorithms/VesuvioPreFit-v1.rst index c58ca280e29318310e6b5fb7c847a7da74117438..397bce49105863162aa12a7dd70ea8aaa0db8ca0 100644 --- a/docs/source/algorithms/VesuvioPreFit-v1.rst +++ b/docs/source/algorithms/VesuvioPreFit-v1.rst @@ -10,10 +10,10 @@ Description ----------- -Applys the preprocessing steps to loaded vesuvio data before it is fitted. +Applies the preprocessing steps to loaded vesuvio data before it is fitted. These steps include: - Smoothing the data -- Masking bad detectors +- Masking bad detectors Usage ----- @@ -51,4 +51,3 @@ Usage .. categories:: .. sourcelink:: - diff --git a/docs/source/algorithms/WienerSmooth-v1.rst b/docs/source/algorithms/WienerSmooth-v1.rst index 6c71c5a4fd6a809b98e521df46fd6fd38586fb70..9c27d6dcb9eaf19b702eeffa1c526393ba777eee 100644 --- a/docs/source/algorithms/WienerSmooth-v1.rst +++ b/docs/source/algorithms/WienerSmooth-v1.rst @@ -21,7 +21,7 @@ WienerSmooth uses the power spectrum of the input signal :math:`s_i` to build th :math:`W(\nu)=\int_{-\infty}^\infty w(t)e^{-2\pi it\nu} dt` First the noise level is estimated from the higher frequencies of the power spectrum. -Then the fiter function is constructed out of three pieces. Ther first piece is at the +Then the fiter function is constructed out of three pieces. The first piece is at the lower frequencies where the power spectrum is well above the noise. At this region the the filter function is calculated with the formula: diff --git a/docs/source/algorithms/WorkflowAlgorithmRunner-v1.rst b/docs/source/algorithms/WorkflowAlgorithmRunner-v1.rst index 026912cf5675031185dec48001d3e30bcbfd7e96..8e471727226ce5d43f017dcf1818cd3c6535fb8e 100644 --- a/docs/source/algorithms/WorkflowAlgorithmRunner-v1.rst +++ b/docs/source/algorithms/WorkflowAlgorithmRunner-v1.rst @@ -11,7 +11,7 @@ Description This utility algorithm is used to control consecutive executions of another algorithm. After defining a table of desired input and output properties, ``WorkflowAlgorithmRunner`` connects the outputs to input properties, declares the order of execution, and runs the algorithm. It is mainly meant for managing the execution of workflow algorithms for data reduction purposes although it can run all types of algorithms. -The runs are specified in a `TableWorkspace` and given as the *SetupTable* input property to the algorihtm. The first column has to contain unique string identifiers for each row. The rest of the columns have to be named same as the input/output properties of the managed algorithm. +The runs are specified in a `TableWorkspace` and given as the *SetupTable* input property to the algorithm. The first column has to contain unique string identifiers for each row. The rest of the columns have to be named same as the input/output properties of the managed algorithm. Each row in the *SetupTable* corresponds to a single run of the managed algorithm. Its properties are set without modifications from the corresponding columns of the row except for special input/output columns declare in the *InputOutputMap*. For example, two independent runs of the :ref:`algm-Scale` would be specified as diff --git a/docs/source/api/python/mantid/geometry/ComponentInfo.rst b/docs/source/api/python/mantid/geometry/ComponentInfo.rst index 6beabf39ffff60578c3a5bd15873f8e70a930b99..53c85bf9d95a952c42194e637ba5e1f0d45df825 100644 --- a/docs/source/api/python/mantid/geometry/ComponentInfo.rst +++ b/docs/source/api/python/mantid/geometry/ComponentInfo.rst @@ -58,7 +58,7 @@ The ``relativePosition`` method takes in an integer ``index`` parameter which co The return value is a ``V3D`` object which denotes a point in 3D space. The ``setRotation()`` method takes in a ``Quat`` object which defines a rotation. The rotation is applied to the component. -Retriving the rotation after setting it may not always give the same ``Quat`` object back - i.e. the values could be changed. +Retrieving the rotation after setting it may not always give the same ``Quat`` object back - i.e. the values could be changed. The ``hasParent()`` method takes an integer ``index`` parameter which corresponds to a component. The return value is ``True`` if the component has a parent component or ``False`` otherwise. diff --git a/docs/source/api/python/mantid/plots/index.rst b/docs/source/api/python/mantid/plots/index.rst index 58b4b7d33a0d555cb905b49d718b914a7461479a..59534b3ec6d99a49ff3c6107cc222c5351918229 100644 --- a/docs/source/api/python/mantid/plots/index.rst +++ b/docs/source/api/python/mantid/plots/index.rst @@ -166,7 +166,7 @@ and :func:`~mantid.plots.MantidAxes.pcolorfast`: **axisaligned** keyword, and setting it to True * If the :class:`mantid.api.MatrixWorkspace` has different numbers of bins the above functions will automatically use the - **axisaligned** behavior (cannot be overriden). :func:`~mantid.plots.MantidAxes.contour` + **axisaligned** behavior (cannot be overridden). :func:`~mantid.plots.MantidAxes.contour` and the like cannot plot these type of workspaces. In addition to the ``mantid`` projection, there is also the ``mantid3d`` projection for 3d plots. @@ -195,7 +195,7 @@ Types of functions **1D Plotting** * :func:`~mantid.plots.MantidAxes.plot` - Plot lines and/or markers -* :func:`~mantid.plots.MantidAxes.errorbar` - Plot valuse with errorbars +* :func:`~mantid.plots.MantidAxes.errorbar` - Plot values with errorbars * :func:`~mantid.plots.MantidAxes.scatter` - Make a scatter plot **2D Plotting** diff --git a/docs/source/concepts/EventFiltering.rst b/docs/source/concepts/EventFiltering.rst index 66a033a6618c8ee27fbc0e66ad70857db113bd9c..d86f072e1dbd1578c81e99ca95cd0bd21b04c47a 100644 --- a/docs/source/concepts/EventFiltering.rst +++ b/docs/source/concepts/EventFiltering.rst @@ -57,7 +57,7 @@ Generating inexplicit filters * :ref:`algm-FilterEvents` is able to filter neutron events by either their pulse times or their absolute times. An neutron event's - abolute time is the summation of its pulse time and TOF. + absolute time is the summation of its pulse time and TOF. * :ref:`algm-FilterByLogValue` and :ref:`algm-FilterByTime` can only split neutron events by their pulse time. diff --git a/docs/source/concepts/EventWorkspace.rst b/docs/source/concepts/EventWorkspace.rst index fb1f39e492cd74d66cf877d132fcbf9ea093aeb6..35d4d5e44fb2587492792955cd71e23b4d0ee931 100644 --- a/docs/source/concepts/EventWorkspace.rst +++ b/docs/source/concepts/EventWorkspace.rst @@ -10,7 +10,7 @@ Event Workspace What is it for? ______________________ -Event Workspaces are specialised for time-of-flight neutron scattering. Event Workspaces are designed for sparse data storage of neutron events. Individual detector observations, including information about when that observation was made are stored as discrete items inside the workspace. The ability to keep more detailed information gives a number of advantages over coverting directly to a compressed form, such as allowing more powerful filtering operations to be used. +Event Workspaces are specialised for time-of-flight neutron scattering. Event Workspaces are designed for sparse data storage of neutron events. Individual detector observations, including information about when that observation was made are stored as discrete items inside the workspace. The ability to keep more detailed information gives a number of advantages over converting directly to a compressed form, such as allowing more powerful filtering operations to be used. Summary for Users ----------------------- @@ -39,7 +39,7 @@ maintained. For you as a user, this means that: Working with Event Workspaces in Python ---------------------------------------- -The python options for an Event Workspace are limitied - it is designed to be able to be read (but not written to) +The python options for an Event Workspace are limited - it is designed to be able to be read (but not written to) like a :ref:`MatrixWorkspace <MatrixWorkspace>`. You can look at the :ref:`Event Workspace API reference <mantid.api.IEventWorkspace>` for a full list of properties and operations, but here are some of the key ones. Accessing Workspaces diff --git a/docs/source/concepts/FABADA.rst b/docs/source/concepts/FABADA.rst index 3c783a848f3a610ec90bcfce8c0e1fddd5998cde..5da194bddb3ca513051eeb08f9ea9cd26fcbe1e9 100644 --- a/docs/source/concepts/FABADA.rst +++ b/docs/source/concepts/FABADA.rst @@ -78,7 +78,7 @@ Usage ws_res = Load(Filename='irs26173_graphite002_res.nxs') function_str = 'composite=Convolution,FixResolution=tue,NumDeriv=false;name=Resolution,Workspace=ws_res,WorkspaceIndex=0;(composite=CompositeFunction,NumDeriv=true;name=Lorentzian,Amplitude=1,PeakCentre=0.01,FWHM=0.5;name=Lorentzian,Amplitude=1,PeakCentre=0.01,FWHM=0.5)' - minimizer_str = "FABADA,Chain Lengh=1000000,Steps between values=10,Convergence Criteria=0.01,PDF=pdf,Chains=chain,Converged chain=conv,Cost Function Table=CostFunction,Parameter Erros =Errors" + minimizer_str = "FABADA,Chain Length=1000000,Steps between values=10,Convergence Criteria=0.01,PDF=pdf,Chains=chain,Converged chain=conv,Cost Function Table=CostFunction,Parameter Erros =Errors" Fit(Function = function_str,InputWorkspace=ws_data,WorkspaceIndex=3,StartX=-0.25,EndX=0.25,CreateOutput=True,Output = 'result',OutputCompositeMembers=True,MaxIterations=2000000, Minimizer=minimizer_str) diff --git a/docs/source/concepts/FrameworkManager.rst b/docs/source/concepts/FrameworkManager.rst index 49ac51a1b2a593ce1733d613e2018bab748668cf..675fc926d3af1895350875023ce86d6b67e8e23f 100644 --- a/docs/source/concepts/FrameworkManager.rst +++ b/docs/source/concepts/FrameworkManager.rst @@ -19,7 +19,7 @@ What does it allow you to do? ----------------------------- The frameworkManager allows you to create and execute algorithms as well -as retrieving workspaces, and deleteing them if they are no longer +as retrieving workspaces, and deleting them if they are no longer required. It is good practice to delete workspaces that are no longer required to diff --git a/docs/source/concepts/Geometry.rst b/docs/source/concepts/Geometry.rst index 3fe73da9a226bd848adc3a85e5712ffbfa4577bc..60ebb6b2b80e296bb3e88b26f2eb3cee8e18310e 100644 --- a/docs/source/concepts/Geometry.rst +++ b/docs/source/concepts/Geometry.rst @@ -13,15 +13,15 @@ rotations between them. Geometry in Mantid ------------------ -In Mantid we seperate the :ref:`Geometry of the shape <Geometry of Shape>` +In Mantid we separate the :ref:`Geometry of the shape <Geometry of Shape>` of an object from the :ref:`Geometry of it's position <Geometry of Position>`. This is done primarily to save on memory usage but also to improve performance. Many operations within Mantid need to know where for example a detector is, but do not need to -know what shape it is. By keeping the Geometry and Position seperate we +know what shape it is. By keeping the Geometry and Position separate we can keep the performance high. Also while in any one instrument we may have over 10,000 detector pixels all with different locations they will -all have the same shape, therefore by keeping the shape seperate we can +all have the same shape, therefore by keeping the shape separate we can greatly reduce the amount of memory required. Basics of Geometry diff --git a/docs/source/concepts/HistogramData.rst b/docs/source/concepts/HistogramData.rst index 4dee48b0d8d80178f052159793e019ed5fab025d..c380e63440d75f54cacd2305817ea0b0012a5720 100644 --- a/docs/source/concepts/HistogramData.rst +++ b/docs/source/concepts/HistogramData.rst @@ -235,7 +235,7 @@ Overview void setSharedE(const Kernel::cow_ptr<HistogramE> &e) &; }; -Note that there is also Dx-data, but it is not widely used and thus omited from this documentation. +Note that there is also Dx-data, but it is not widely used and thus omitted from this documentation. The interface for Dx is mostly equivalent to that for E. ``HistogramX``, ``HistogramY``, and ``HistogramE`` @@ -516,7 +516,7 @@ Working with the new ``MatrixWorkspace`` interface Legacy interface ################ -For compatibility reasons an interface to the internal data, equivalent to the old interace, is still available. Using it is discouraged, since it cannot enforce size checks! +For compatibility reasons an interface to the internal data, equivalent to the old interface, is still available. Using it is discouraged, since it cannot enforce size checks! .. code-block:: c++ :linenos: diff --git a/docs/source/concepts/Howtoresetdetectorscalibration.rst b/docs/source/concepts/Howtoresetdetectorscalibration.rst index 692f00dd91e98276a6d03faf661271acf3c38a5b..11861a2cd88af18acd96622627977f4f3dc8d868 100644 --- a/docs/source/concepts/Howtoresetdetectorscalibration.rst +++ b/docs/source/concepts/Howtoresetdetectorscalibration.rst @@ -31,7 +31,7 @@ This image is clearly calibrated. To reset the calibration, execute: empty_instr = LoadEmptyInstrument('MANTIDINSTALL/instrument/MERLIN_Definition.xml') CopyInstrumentParameters(empty_instr, mer12024) -The result is reseting the calibration of this workspace as you can see +The result is resetting the calibration of this workspace as you can see in the image below: .. image:: ../images/Merlin_uncalibrated.png diff --git a/docs/source/concepts/InstrumentAccessLayers.rst b/docs/source/concepts/InstrumentAccessLayers.rst index a0ab7c47262cb20bc6ad9e9c83a818cbaff2154b..65543664651ed6df60ae362c3e608b141c585e92 100644 --- a/docs/source/concepts/InstrumentAccessLayers.rst +++ b/docs/source/concepts/InstrumentAccessLayers.rst @@ -85,7 +85,7 @@ The following methods are useful helpers on ``ComponentInfo`` that allow the ext The ``ComponentInfo`` object is accessed by an index going from 0 to the number of components (including the instrument iteself). **The component index for a detector is EQUAL to the detector index**, this is an important point to understand. In other words, a detector with a Detector Index of 5, for the purposes of working with a ``DetectorInfo`` and will have a Component Index of 5, when working with a ``ComponentInfo``. Explained in yet another way: The first 0 - n components referenced in the ``ComponentInfo`` are detectors, where n is the total number of detectors. This guarantee can be leveraged to provide speedups, as some of the examples will show. -A ``ComponentID`` for compatiblity with older code, and be extracted from ``ComponentInfo::componentID(componentIndex)``, but such calls should be avoided where possible. +A ``ComponentID`` for compatibility with older code, and be extracted from ``ComponentInfo::componentID(componentIndex)``, but such calls should be avoided where possible. It is also possible to use the method ``componentInfo.indexOf(componentID)`` to get the index for a particular component ID. However, this is a call to a lookup in an unordered map, so is an expensive calculation which should be avoided where possible. diff --git a/docs/source/concepts/InstrumentDefinitionFile.rst b/docs/source/concepts/InstrumentDefinitionFile.rst index fa3dad94a26abe39c803d0eb88a12ee23c036d22..fbf14a9955c4fe85d2d0840497fa43acf400e206 100644 --- a/docs/source/concepts/InstrumentDefinitionFile.rst +++ b/docs/source/concepts/InstrumentDefinitionFile.rst @@ -1305,7 +1305,7 @@ shape is shape is shown here: CombineIntoOneShapeExample.png Note for this to work, a unique name for each component must be provided -and these names must be used in the algebra sting (here "A : B", see +and these names must be used in the algebra string (here "A : B", see :ref:`HowToDefineGeometricShape <HowToDefineGeometricShape>`). Further a bounding-box may optionally be added to the to the type. Note the above geometric shape can alternatively be defined with the XML diff --git a/docs/source/concepts/InstrumentParameterFile.rst b/docs/source/concepts/InstrumentParameterFile.rst index d68f2e92041937c335b2b69d3f1ec210ca9c2d85..ed8a6845a8b0e5ad3c026634f0ff50b92a0a31cd 100644 --- a/docs/source/concepts/InstrumentParameterFile.rst +++ b/docs/source/concepts/InstrumentParameterFile.rst @@ -17,7 +17,7 @@ Creating a Parameter File Using a Schema ~~~~~~~~~~~~~~ -To create a parameters file it is advisable to consult the parameter file schema, located in your mantid directory at mantid\code\instrument\Schema\ParameterFileSchema.xsd. Set up your editting program to validate your XML file against this schema following :ref:`these instructions <Using_XML_Schema>`. Once set up, the schema can be used to find any errors in the structure of your parameter file and suggest auto-fill options to help write your parameter file. +To create a parameters file it is advisable to consult the parameter file schema, located in your mantid directory at mantid\code\instrument\Schema\ParameterFileSchema.xsd. Set up your editing program to validate your XML file against this schema following :ref:`these instructions <Using_XML_Schema>`. Once set up, the schema can be used to find any errors in the structure of your parameter file and suggest auto-fill options to help write your parameter file. General Structure ~~~~~~~~~~~~~~~~~ diff --git a/docs/source/concepts/LETSampleIDF.rst b/docs/source/concepts/LETSampleIDF.rst index cd8fc2847fce37ab09664f9e6f6047a4ba4b9607..acaad1b19d3916941f93ee18611680e39c98437a 100644 --- a/docs/source/concepts/LETSampleIDF.rst +++ b/docs/source/concepts/LETSampleIDF.rst @@ -11,7 +11,7 @@ This page annotates the direct inelastic instrument LET, with the purpose of (ho Instrument view of LET ---------------------- -LET consists of doors (in the speach of LET scientists) where each door is made up of a number of tupes along the y-axis (green line in picture below), where each tube is made up of a sequence pixels (detectors). +LET consists of doors (in the speech of LET scientists) where each door is made up of a number of tupes along the y-axis (green line in picture below), where each tube is made up of a sequence pixels (detectors). The view of the instrument below is in the 'Full 3D' mode. diff --git a/docs/source/concepts/MDHistoWorkspace.rst b/docs/source/concepts/MDHistoWorkspace.rst index 3605823f5dfdc038f1502a9461b2a1f716a1b308..5e4862565e8efa4f368b2392a6e49b4ec15f778d 100644 --- a/docs/source/concepts/MDHistoWorkspace.rst +++ b/docs/source/concepts/MDHistoWorkspace.rst @@ -168,7 +168,7 @@ Accessing the Data print(ws.signalAt(index)) print(ws.errorSquaredAt(index)) - # To extract the whole signal aray + # To extract the whole signal array signalArray = ws.getSignalArray() # or the whole error squared array errorSquaredArray = ws.getErrorSquaredArray() diff --git a/docs/source/concepts/PointAndSpaceGroups.rst b/docs/source/concepts/PointAndSpaceGroups.rst index d31712c9e3d4bd900a56bd4ce49b8fddf2762db7..3f7a93d04be354da722106c058dd22950b27b39c 100644 --- a/docs/source/concepts/PointAndSpaceGroups.rst +++ b/docs/source/concepts/PointAndSpaceGroups.rst @@ -49,7 +49,7 @@ So by specifying one single symmetry operation as generator, all symmetry operat G' = G \cdot \left\{m^0, m^1\right\} = \left\{1, 4^{+}, 2, 4^{-}\right\} \cdot \left\{1, m\right\} = \left\{1, m, 4^{+}, \bar{4}^{+}, 2, \bar{1}, 4^{-}, \bar{4}^{-}\right\} -This means that :math:`4/m` contains an inversion center as well as a four fold rotoinversion axis which result from the combination of the operations of the two cyclic groups. It's also possible to use a different cyclic group to achive the same result (:math:`\bar{1}`). As mentioned above, for some point groups it's necessary to use three generators, which follows the same principle and is not shown here. +This means that :math:`4/m` contains an inversion center as well as a four fold rotoinversion axis which result from the combination of the operations of the two cyclic groups. It's also possible to use a different cyclic group to achieve the same result (:math:`\bar{1}`). As mentioned above, for some point groups it's necessary to use three generators, which follows the same principle and is not shown here. Space groups can be handled in a very similar way if translations are limited to the interval :math:`[0, 1)` so that screw-axes and glide-planes can also be used to generate cyclic groups. Without this limitation, the translational components would not be the same for :math:`S^k` and :math:`S^0`. @@ -629,7 +629,7 @@ Building on the example above which showed how to check whether a reflection is # (see the helper functions defined above). spaceGroupMatchList.append((sgSymbol, getValueFrequencies(conditionsMatchList))) - # Sort the list according to abscence violations and additional reflection conditions + # Sort the list according to absence violations and additional reflection conditions spaceGroupMatchList.sort(key=lambda x: (x[1].get(1, 0), x[1].get(-1, 0))) # Remove the second setting that exists for some groups diff --git a/docs/source/concepts/ProjectRecovery.rst b/docs/source/concepts/ProjectRecovery.rst index 7f42c8b39477ec757fdb8586c386514a7a4df9ed..8142b360cc8e2ce13603e005145428aa07fe92ad 100644 --- a/docs/source/concepts/ProjectRecovery.rst +++ b/docs/source/concepts/ProjectRecovery.rst @@ -27,7 +27,7 @@ If Mantid has crashed, then on the subsequent reboot you will be presented with You can choose to attempt a full recovery, to open a recovery script or not to attempt a recovery. Full recovery will attempt to recover all workspaces present at the time of the crash as well as additional dialogs like plots or data windows. Script mode will attempt to construct a script that contains the history of all workspaces at the time of the crash. -If full project recovery runs succesfully the scripting window will remain open in MantidPlot. It is safe to close this after a recovery. +If full project recovery runs successfully the scripting window will remain open in MantidPlot. It is safe to close this after a recovery. **NB** This is an early version of project recovery. We think that it is a lot better than nothing, but we know it won't always work. Known caveats are listed below. Moreover, we would sincerely appreciate feedback and input from users. Contact us at `mantid-help@mantidproject.org <mailto:mantid-help@mantidproject.org>`__. @@ -36,11 +36,6 @@ The settings for project recovery, including switiching the feature on/off, and Caveats ------- -* Multiple instances of Mantid - * Please allow first instance to start history writer before starting the next instance, otherwise it will not start for either. This usually means leaving Mantid until the GUI has opened fully. - * Only the first instance will have history writer enabled. There will be no project recovery for subsequent instances. - * All running instances of Mantid must be closed for project recovery to work after a crash. - * Interfaces * Muon - project recovery does not work at all with the existing Muon interfaces. * Indirect analysis - project recovery does not work when performing fitting routines within the indirect analysis interface. diff --git a/docs/source/concepts/PropertiesFile.rst b/docs/source/concepts/PropertiesFile.rst index 911f8a606caf0a65cd7a4109dac9093f2d6a1442..4ce4a005d910ea5facbe6c6add67c04905daf536 100644 --- a/docs/source/concepts/PropertiesFile.rst +++ b/docs/source/concepts/PropertiesFile.rst @@ -37,7 +37,7 @@ General properties | | algorithms that should be hidden in Mantid. | | +----------------------------------+--------------------------------------------------+-------------------+ | ``algorithms.retained`` | The Number of algorithms properties to retain in | ``50`` | -| | memory for refence in scripts. | | +| | memory for reference in scripts. | | +----------------------------------+--------------------------------------------------+-------------------+ | ``MultiThreaded.MaxCores`` | Sets the maximum number of cores available to be | ``0`` | | | used for threads for | | @@ -52,7 +52,7 @@ Facility and instrument properties |Property |Description |Example value | +==============================+====================================================+=====================+ | ``default.facility`` | The name of the default facility. The facility | ``ISIS`` | -| | must be defined within the facilites.xml file to | | +| | must be defined within the facilities.xml file to | | | | be considered valid. The file is described | | | | :ref:`here <Facilities file>`. | | +------------------------------+----------------------------------------------------+---------------------+ @@ -181,7 +181,7 @@ Network Properties | |operations (in seconds). | | +-------------------------------------------+---------------------------------------------------+---------------------------------+ | ``network.scriptrepo.timeout`` |The timeout for network operations in the script | ``5`` | -| |repository, this overrides the deafault timeout. | | +| |repository, this overrides the default timeout. | | +-------------------------------------------+---------------------------------------------------+---------------------------------+ | ``proxy.host`` | Allows the system proxy to be overridden, if not | ``http://www.proxy.org`` | | | set mantid will use the system proxy | | diff --git a/docs/source/concepts/RAWFile.rst b/docs/source/concepts/RAWFile.rst index 5fefc0167d9cd15a67ca38fee97de98dcfce9a49..18aa45a78e05f0b8c6ce307195e074b912ab3a97 100644 --- a/docs/source/concepts/RAWFile.rst +++ b/docs/source/concepts/RAWFile.rst @@ -61,7 +61,7 @@ least for RAW files. If a file with an alternate data stream is copied to an FAT file system the alternate data stream is lost. It has been reported that if a file with an ADS is copied using SAMBA to a unix file system the streams are -extracted into seperate files with automatically generates suffixes. +extracted into separate files with automatically generates suffixes. More information about Alternate Data Streams ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/source/concepts/Run.rst b/docs/source/concepts/Run.rst index ad972b48ab4dd19c34ce6a49d6f65897231dbc44..852a7f96c7c1114e7f784cbd5a982d8cb05154d0 100644 --- a/docs/source/concepts/Run.rst +++ b/docs/source/concepts/Run.rst @@ -10,7 +10,7 @@ Run What the Run object ------------------- - + A Run holds data related to the properties of the experimental run, e.g. good proton charge, total frames etc. It also holds all of the sample log files as sets of time-series data. Currently used properties within @@ -45,7 +45,7 @@ Run Properties ws = Load("MAR11060") .. testcode:: RunPropertiestest - + from mantid.kernel import DateAndTime run = ws.getRun() @@ -56,7 +56,7 @@ Run Properties # Get the start and end time of a run print(run.startTime()) print(run.endTime()) - + # Get the total good proton charge print(run.getProtonCharge()) @@ -64,8 +64,8 @@ Run Properties :hide: :options: +ELLIPSIS,+NORMALIZE_WHITESPACE - 2015-01-27T11:00:00 - 2015-01-27T11:57:51 + 2015-01-27T11:00:00 + 2015-01-27T11:57:51 121... Accessing Properties @@ -80,7 +80,7 @@ Listing all properties run = ws.getRun() - # Get a list of the property names + # Get a list of the property names print(run.keys()) # Loop over all of the Properties @@ -94,7 +94,7 @@ Listing all properties ['run_header', ... 'run_title'] run_header MAR 11060 Vanadium white beam 23-JUN-2005 10:18:46 121.5 ... - run_title Vanadium white beam jaws=50x50 nim=50 dsc=0 + run_title Vanadium white beam jaws=50x50 nim=50 dsc=0 Getting a specific property ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -105,7 +105,7 @@ Getting a specific property run = ws.getRun() - # Check a propetry exists + # Check if property exists print("Is runstart present: {0}".format(("run_start" in run.keys()))) # or print("Is runstart present: {0}".format(run.hasProperty("run_start"))) @@ -125,9 +125,9 @@ Getting a specific property Property value: 2010-01-01T00:00:00 The Gonioneter -############## +############## -If the instrument conatains a Goniometer it can be accessed from the run object. +If the instrument contains a Goniometer it can be accessed from the run object. .. testcode:: GetGoniometertest @@ -199,4 +199,4 @@ ISIS Muon data -.. categories:: Concepts \ No newline at end of file +.. categories:: Concepts diff --git a/docs/source/concepts/Workspace.rst b/docs/source/concepts/Workspace.rst index 6574a5231d257c9b485bd9c2983a3a7c0cb39edc..d8240494a5b0655f96f58ade2df11e305261facc 100644 --- a/docs/source/concepts/Workspace.rst +++ b/docs/source/concepts/Workspace.rst @@ -31,7 +31,7 @@ Workspaces Types dimensional histogram data in memory, this is the most commonly used workspace. - :ref:`Event Workspace <EventWorkspace>` - A workspace that retains the - individual neutron event data often including the pulse time correponding to the reading. + individual neutron event data often including the pulse time corresponding to the reading. - :ref:`Table Workspace <Table Workspaces>` - A workspace holding data in rows of columns having a particular type (e.g. text, integer, ...). @@ -81,7 +81,7 @@ This :ref:`page <WorkingWithWorkspaces>` describes how you can work with workspa Writing you own Workspace ------------------------- -:ref:`Table Workspace <Table Workspaces>` is the best solution at present for customising the data structures you need. Changes beyond that are at present not trivial. For specialisation of exisiting data structures, or new data requirements, please contact the Mantid Team for help. +:ref:`Table Workspace <Table Workspaces>` is the best solution at present for customising the data structures you need. Changes beyond that are at present not trivial. For specialisation of existing data structures, or new data requirements, please contact the Mantid Team for help. .. categories:: Concepts diff --git a/docs/source/concepts/calibration/PowderDiffractionCalibration.rst b/docs/source/concepts/calibration/PowderDiffractionCalibration.rst index 5eadf15a0c83fd2295649bda16b971ecb8f53aec..d8b7917cac7b43f6966c449167e936fd5b7e3a80 100644 --- a/docs/source/concepts/calibration/PowderDiffractionCalibration.rst +++ b/docs/source/concepts/calibration/PowderDiffractionCalibration.rst @@ -39,7 +39,7 @@ Steps for other instruments * **Multi Peak Calibration** (*This is less well tested*) If you do not have a single peak in all detectors, but a range of known peaks across detectors you can try this approach. Another possible approach is to perform the single peak calibration across sections of the instrument with different reference peaks and combine the output calibration. - 6. Run :ref:`GetDetOffsetsMultiPeaks <algm-GetDetOffsetsMultiPeaks>`, the Input workspace is the one from step 3 earlier. For DReference you can enter a comma seperated list of the d-spacing values of the known peaks. + 6. Run :ref:`GetDetOffsetsMultiPeaks <algm-GetDetOffsetsMultiPeaks>`, the Input workspace is the one from step 3 earlier. For DReference you can enter a comma separated list of the d-spacing values of the known peaks. 7. The output is an OffsetsWorspace, and a workspace with the number of peaks found in each spectra, The output offsets workspace that can be used directly in :ref:`DiffractionFocussing <algm-DiffractionFocussing>`, or saved using :ref:`SaveCalFile <algm-SaveCalFile>`. You can also save it as a :ref:`CalFile` from :ref:`GetDetOffsetsMultiPeaks <algm-GetDetOffsetsMultiPeaks>`, by defining the GroupingFileName parameter. diff --git a/docs/source/diagrams/AlignAndFocusPowder-v1_wkflw.dot b/docs/source/diagrams/AlignAndFocusPowder-v1_wkflw.dot index abcefcc9f49b68459bb28ccc308ae36f34192529..15bad437d5e8229bca02088af6eb332ac5b2a154 100644 --- a/docs/source/diagrams/AlignAndFocusPowder-v1_wkflw.dot +++ b/docs/source/diagrams/AlignAndFocusPowder-v1_wkflw.dot @@ -19,7 +19,7 @@ digraph AlignAndFocusPowder { params2 [label="Params"] } - subgraph algoritms { + subgraph algorithms { $algorithm_style removePromptPulse [label="RemovePromptPulse v1"] compressEvents [label="CompressEvents v1"] diff --git a/docs/source/diagrams/ApplyPaalmanPingsCorrection-v1_fullcorrection_wkflw.dot b/docs/source/diagrams/ApplyPaalmanPingsCorrection-v1_fullcorrection_wkflw.dot index 85491851353a3d05f79630c43c8ca91439eee066..458361345efd23b1a02ee8d0592d9850d7f2f09f 100644 --- a/docs/source/diagrams/ApplyPaalmanPingsCorrection-v1_fullcorrection_wkflw.dot +++ b/docs/source/diagrams/ApplyPaalmanPingsCorrection-v1_fullcorrection_wkflw.dot @@ -2,7 +2,7 @@ digraph ApplyPaalmanPingsCorrection_FullCorrection { label="ApplyPaalmanPingsCorrection Full Corrections Flowchart" $global_style - subgraph descision { + subgraph decision { $decision_style IsAccInWavelength [label="Is in Wavelength?"] IsAcscInWavelength [label="Is in Wavelength?"] diff --git a/docs/source/diagrams/ApplyPaalmanPingsCorrection-v1_samplecorrectiononly_wkflw.dot b/docs/source/diagrams/ApplyPaalmanPingsCorrection-v1_samplecorrectiononly_wkflw.dot index 0165f237a6e3a01129712e41b50702dcf4e34523..51b49235f40f057aeb460ec1b8b111bf9e360d17 100644 --- a/docs/source/diagrams/ApplyPaalmanPingsCorrection-v1_samplecorrectiononly_wkflw.dot +++ b/docs/source/diagrams/ApplyPaalmanPingsCorrection-v1_samplecorrectiononly_wkflw.dot @@ -2,7 +2,7 @@ digraph ApplyPaalmanPingsCorrection_SampleCorrectOnly { label="ApplyPaalmanPingsCorrection Sample Correct Only Flowchart" $global_style - subgraph descision { + subgraph decision { $decision_style IsAssInWavelength [label="Is in Wavelength?"] } diff --git a/docs/source/diagrams/ApplyPaalmanPingsCorrection-v1_twofactorcorrection_wkflw.dot b/docs/source/diagrams/ApplyPaalmanPingsCorrection-v1_twofactorcorrection_wkflw.dot index e4492299e13eb2daeb20f8dd09809b79aa2863a6..304598643eb4d2ceaca4bbd794c5c51adffa2df6 100644 --- a/docs/source/diagrams/ApplyPaalmanPingsCorrection-v1_twofactorcorrection_wkflw.dot +++ b/docs/source/diagrams/ApplyPaalmanPingsCorrection-v1_twofactorcorrection_wkflw.dot @@ -2,7 +2,7 @@ digraph ApplyPaalmanPingsCorrection_TwoFactorCorrection { label="ApplyPaalmanPingsCorrection Two Factor Corrections Flowchart" $global_style - subgraph descision { + subgraph decision { $decision_style IsAccInWavelength [label="Is in Wavelength?"] IsAssInWavelength [label="Is in Wavelength?"] diff --git a/docs/source/diagrams/ElasticWindow-v1_wkflw.dot b/docs/source/diagrams/ElasticWindow-v1_wkflw.dot index 07b6f921dcecdd57404b8538edcd48675454a1d0..7f272057b2854639674f652e9d52187310286926 100644 --- a/docs/source/diagrams/ElasticWindow-v1_wkflw.dot +++ b/docs/source/diagrams/ElasticWindow-v1_wkflw.dot @@ -9,7 +9,7 @@ digraph ElasticWindow { ConvertAxis_Q2_Target [label="ElasticQSquared"] } - subgraph descision { + subgraph decision { $decision_style HaveBackgroundRange [label="Have Background Range?"] VertAxisIsSpectraNumber [label="Vertical Axis is Spectra Number?"] diff --git a/docs/source/diagrams/ElasticWindowMultiple-v1_wkflw.dot b/docs/source/diagrams/ElasticWindowMultiple-v1_wkflw.dot index 8d46a407c60b4f90e68fdfa87e36525eec157c15..d418af3fc078bb4443370e7a3b56d85d944d0409 100644 --- a/docs/source/diagrams/ElasticWindowMultiple-v1_wkflw.dot +++ b/docs/source/diagrams/ElasticWindowMultiple-v1_wkflw.dot @@ -2,7 +2,7 @@ digraph ElasticWindowMultiple { label="ElasticWindowMultiple Flowchart" $global_style - subgraph descision { + subgraph decision { $decision_style HaveTemperatureLogs [label="Have Temperature Logs?"] } diff --git a/docs/source/diagrams/ISISIndirectDiffractionReduction-v1_wkflw.dot b/docs/source/diagrams/ISISIndirectDiffractionReduction-v1_wkflw.dot index 4548d2b54faaf6a476cfd527a28a79b207c3d815..3f5e9e5870fdbb16ce86ce8a729332bb5728a9e6 100644 --- a/docs/source/diagrams/ISISIndirectDiffractionReduction-v1_wkflw.dot +++ b/docs/source/diagrams/ISISIndirectDiffractionReduction-v1_wkflw.dot @@ -54,7 +54,7 @@ digraph ISISIndirectDiffractionReduction { dspacing_unit [label="dSpacing"] } - subgraph descision { + subgraph decision { $decision_style has_calib_file [label="Using Calibration File"] } diff --git a/docs/source/diagrams/IndirectCalibration-v1_wkflw.dot b/docs/source/diagrams/IndirectCalibration-v1_wkflw.dot index ae25a5130d9db0732205f64c83707438c6dfcad8..a5abef70a5d0573e5f947d3f47977a9f495fc12a 100644 --- a/docs/source/diagrams/IndirectCalibration-v1_wkflw.dot +++ b/docs/source/diagrams/IndirectCalibration-v1_wkflw.dot @@ -7,7 +7,7 @@ digraph IndirectCalibration { AutoScaleFactor [label="1 / (sum / (num_spectra / num_zero_spectra))"] } - subgraph descision { + subgraph decision { $decision_style UseAutoScale [label="ScaleFactor = 1?"] MultipleFiles [label="Multiple Files?"] diff --git a/docs/source/diagrams/IndirectILLEnergyTransfer-v1_wkflw.dot b/docs/source/diagrams/IndirectILLEnergyTransfer-v1_wkflw.dot index 19281073fecd5c100dcc094d6d089e6b146fd6bc..e2d281059cfafa26f01cdfaac87a2b83c95daa2f 100644 --- a/docs/source/diagrams/IndirectILLEnergyTransfer-v1_wkflw.dot +++ b/docs/source/diagrams/IndirectILLEnergyTransfer-v1_wkflw.dot @@ -7,7 +7,7 @@ digraph IndirectILLEnergyTransfer { OutputWorkspace } - subgraph descision { + subgraph decision { $decision_style CropDeadMonitorChannels } diff --git a/docs/source/diagrams/IndirectILLReduction-v1_wkflw.dot b/docs/source/diagrams/IndirectILLReduction-v1_wkflw.dot index aef33292a9f1e69b999e3a4abae69f95b6f51d1c..90ce2fe543bc575143eaa870ac640d2ecd65d796 100644 --- a/docs/source/diagrams/IndirectILLReduction-v1_wkflw.dot +++ b/docs/source/diagrams/IndirectILLReduction-v1_wkflw.dot @@ -9,7 +9,7 @@ digraph IndirectILLReduction { MM_ScaleFactor [label="0.5"] } - subgraph descision { + subgraph decision { $decision_style Save_Red [label="Save?"] Save_LeftRed [label="Save?"] diff --git a/docs/source/diagrams/IndirectILLReductionFWS-v1_wkflw.dot b/docs/source/diagrams/IndirectILLReductionFWS-v1_wkflw.dot index b113a2d11b4dc06a86cd199fc3460bba6e1f5959..1aa0d1620615edbe92bee63cdc98ab2ef87625a5 100644 --- a/docs/source/diagrams/IndirectILLReductionFWS-v1_wkflw.dot +++ b/docs/source/diagrams/IndirectILLReductionFWS-v1_wkflw.dot @@ -7,7 +7,7 @@ digraph IndirectILLReductionFWS { OutputWorkspace } - subgraph descision { + subgraph decision { $decision_style } diff --git a/docs/source/diagrams/IndirectILLReductionQENS-v1_wkflw.dot b/docs/source/diagrams/IndirectILLReductionQENS-v1_wkflw.dot index e77da4089a7d7b6d9de09a13ef9213ef8abfbfdf..4a70ed520396bc91c27cbf73c8a9fdc4eea2e2bf 100644 --- a/docs/source/diagrams/IndirectILLReductionQENS-v1_wkflw.dot +++ b/docs/source/diagrams/IndirectILLReductionQENS-v1_wkflw.dot @@ -7,7 +7,7 @@ digraph IndirectILLReductionQENS { OutputWorkspace } - subgraph descision { + subgraph decision { $decision_style } diff --git a/docs/source/diagrams/IndirectResolution-v1_wkflw.dot b/docs/source/diagrams/IndirectResolution-v1_wkflw.dot index 704a805195446a20989491600183d2d9acb318dd..23291de6cc96baf3985bc555efbe8b48df571c92 100644 --- a/docs/source/diagrams/IndirectResolution-v1_wkflw.dot +++ b/docs/source/diagrams/IndirectResolution-v1_wkflw.dot @@ -2,7 +2,7 @@ digraph IndirectResolution { label="IndirectResolution Flowchart" $global_style - subgraph descision { + subgraph decision { $decision_style ScaleFactorIsOne [label="ScaleFactor is 1?"] } diff --git a/docs/source/diagrams/IndirectTransmissionMonitor-v1_wkflw.dot b/docs/source/diagrams/IndirectTransmissionMonitor-v1_wkflw.dot index c333bc48f8c35b4878a5bd69573cc650b778d88d..49ce8dce5aa1ec9ac661870d4c3554f7740ca199 100644 --- a/docs/source/diagrams/IndirectTransmissionMonitor-v1_wkflw.dot +++ b/docs/source/diagrams/IndirectTransmissionMonitor-v1_wkflw.dot @@ -2,7 +2,7 @@ digraph IndirectTransmissionMonitor { label="IndirectTransmissionMonitor Flowchart" $global_style - subgraph descision { + subgraph decision { $decision_style ExtractMonitor_HaveMonitor2_1 [label="Have Monitor 2?"] ExtractMonitor_HaveMonitor2_2 [label="Have Monitor 2?"] diff --git a/docs/source/diagrams/LoadEventAndCompress-v1_wkflw.dot b/docs/source/diagrams/LoadEventAndCompress-v1_wkflw.dot index 83d40ad30b86907827ab4dac682369b6672a8950..fee81e154ea2a707570bbbc5e7f7a5c52ac8071b 100644 --- a/docs/source/diagrams/LoadEventAndCompress-v1_wkflw.dot +++ b/docs/source/diagrams/LoadEventAndCompress-v1_wkflw.dot @@ -11,7 +11,7 @@ digraph LoadEventAndCompress { FilterBadPulses } - subgraph algoritms { + subgraph algorithms { $algorithm_style loadEventNexus [label="LoadEventNexus v1"] compressEvents [label="CompressEvents v1"] diff --git a/docs/source/diagrams/MolDyn-v1_wkflw.dot b/docs/source/diagrams/MolDyn-v1_wkflw.dot index b787670e0079a9b5a985ecd742bae5994495b000..a92d9d7dd479e9aa45851fcc8afc3f62db0fabb5 100644 --- a/docs/source/diagrams/MolDyn-v1_wkflw.dot +++ b/docs/source/diagrams/MolDyn-v1_wkflw.dot @@ -2,7 +2,7 @@ digraph MolDyn { label="MolDyn Flowchart" $global_style - subgraph descision { + subgraph decision { $decision_style Version [label="nMoldyn version"] IfSave [label="Save?"] diff --git a/docs/source/diagrams/PDToGUDRUN-v1_wkflw.dot b/docs/source/diagrams/PDToGUDRUN-v1_wkflw.dot index 53010141096514bfaec5706069c3cd0c0e086dee..41f5a3bf72f2c95214b7c037956bd45fc6b0912f 100644 --- a/docs/source/diagrams/PDToGUDRUN-v1_wkflw.dot +++ b/docs/source/diagrams/PDToGUDRUN-v1_wkflw.dot @@ -7,7 +7,7 @@ digraph PDToGUDRUN { InputWorkspace } - subgraph algoritms { + subgraph algorithms { $algorithm_style loadChar [label="PDLoadCharacterizations v1"] loadEvent [label="LoadEventAndCompress v1"] diff --git a/docs/source/diagrams/PDToPDFgetN-v1_wkflw.dot b/docs/source/diagrams/PDToPDFgetN-v1_wkflw.dot index c1b7a92692be07bc04a993dd4097c4bd5affaf7b..58a223efcce50f1e18f91815382e156b6dc83b42 100644 --- a/docs/source/diagrams/PDToPDFgetN-v1_wkflw.dot +++ b/docs/source/diagrams/PDToPDFgetN-v1_wkflw.dot @@ -7,7 +7,7 @@ digraph PDToPDFgetN { InputWorkspace } - subgraph algoritms { + subgraph algorithms { $algorithm_style loadChar [label="PDLoadCharacterizations v1"] loadEvent [label="LoadEventAndCompress v1"] diff --git a/docs/source/diagrams/SANSBeamFluxCorrection-v1_wkflw.dot b/docs/source/diagrams/SANSBeamFluxCorrection-v1_wkflw.dot index da6f3a8ae59f7f64c1a49f85039c417d4433febb..680226c120c060ca35f6cd483e3385e45356a05f 100644 --- a/docs/source/diagrams/SANSBeamFluxCorrection-v1_wkflw.dot +++ b/docs/source/diagrams/SANSBeamFluxCorrection-v1_wkflw.dot @@ -15,7 +15,7 @@ digraph SANSBeamFluxCorrection { isEntryName [label="Has Entry Name?"] } - subgraph algoritms { + subgraph algorithms { $algorithm_style convertToHist [label="ConvertToHistogram v1"] rebinToWs [label="RebinToWorkspace v1"] @@ -26,7 +26,7 @@ digraph SANSBeamFluxCorrection { } isEntryName -> load [label="Yes"] - isEntryName -> flexRefWS [label="No. Emtpy Workspace"] + isEntryName -> flexRefWS [label="No. Empty Workspace"] load -> flexRefWS flexRefWS -> convertToHist convertToHist -> rebinToWs diff --git a/docs/source/diagrams/SingleCrystalDiffuseReduction-v1.dot b/docs/source/diagrams/SingleCrystalDiffuseReduction-v1.dot index 387b4b91b34885e7b357b2bd38731bfdb2db8411..a7f8905e6ae47ab0025fba14dd33dc63e5dd87c8 100644 --- a/docs/source/diagrams/SingleCrystalDiffuseReduction-v1.dot +++ b/docs/source/diagrams/SingleCrystalDiffuseReduction-v1.dot @@ -15,7 +15,7 @@ digraph SingleCrystalDiffuseReduction { subgraph decisions { $decision_style - Background [label="Subtracting backgroud?"] + Background [label="Subtracting background?"] isLastRunNumber [label="Is last Sample Run Number?"] moreSymmetry [label="Is last symmetries to use?"] } diff --git a/docs/source/diagrams/SofQWMoments-v1_wkflw.dot b/docs/source/diagrams/SofQWMoments-v1_wkflw.dot index 64830732daf0d8c0a86e989995c5774f115645d8..5ff597b9e458f2a5905f08d3432c2bd7e39f36c3 100644 --- a/docs/source/diagrams/SofQWMoments-v1_wkflw.dot +++ b/docs/source/diagrams/SofQWMoments-v1_wkflw.dot @@ -2,7 +2,7 @@ digraph SofQWMoments { label="SofQWMoments Flowchart" $global_style - subgraph descision { + subgraph decision { $decision_style NoScaleFactor [label="ScaleFactor is 1?"] Save [label="Save?"] diff --git a/docs/source/diagrams/TimeSlice-v1_wkflw.dot b/docs/source/diagrams/TimeSlice-v1_wkflw.dot index f3ce411548306b37e1a77c32892d30c92fda6f8a..54c5674abc974b5a48d6c3b0fefa3343d375b9d6 100644 --- a/docs/source/diagrams/TimeSlice-v1_wkflw.dot +++ b/docs/source/diagrams/TimeSlice-v1_wkflw.dot @@ -2,7 +2,7 @@ digraph TimeSlice { label="TimeSlice Flowchart" $global_style - subgraph descision { + subgraph decision { $decision_style HaveCalibration [label="Have calibration workspace?"] HaveBackgroundRange [label="Have background range?"] diff --git a/docs/source/diagrams/TransformToIqt-v1_wkflw.dot b/docs/source/diagrams/TransformToIqt-v1_wkflw.dot index 207c58ce8d8239e611466b580a8e06fb4a8f84bf..2e7ca1ad2603cae64f5b8845bb5cfb12cfa9b201 100644 --- a/docs/source/diagrams/TransformToIqt-v1_wkflw.dot +++ b/docs/source/diagrams/TransformToIqt-v1_wkflw.dot @@ -2,7 +2,7 @@ digraph TransformToIqt { label="TransformToIqt Flowchart" $global_style - subgraph descision { + subgraph decision { $decision_style IsDryRun [label="DryRun?"] } diff --git a/docs/source/fitting/fitfunctions/BSpline.rst b/docs/source/fitting/fitfunctions/BSpline.rst index 6639aeed69f090b290b3c2e1413bf50b974eeb08..febd998bb3a87efe3321e145107bb5026bcf7513 100644 --- a/docs/source/fitting/fitfunctions/BSpline.rst +++ b/docs/source/fitting/fitfunctions/BSpline.rst @@ -74,7 +74,7 @@ BSplines and Fitting Fitting with a BSpline is different to interpolation as it requires your number of breakpoints to be less than your number of data points. The reason being, the BSplines will attempt to fit close to the data points but might only pass through -some of the data points. It is not necessarily going to pass through all data points, only passing through breakpoints is gauranteed. +some of the data points. It is not necessarily going to pass through all data points, only passing through breakpoints is guaranteed. An example of a fit using BSplines of order 3 can be seen in the image below, our breakpoints have been highlighted in green. The original dataset is in black, while the calculated fit using a least-squares fit with 4 breakpoints is in red. diff --git a/docs/source/fitting/fitfunctions/BivariateGaussian.rst b/docs/source/fitting/fitfunctions/BivariateGaussian.rst index f1033bff6cad58db1637b313a2cba2fcdb293cbe..98b9b3dd88c06d38188d479cdcac2be4da3645d2 100644 --- a/docs/source/fitting/fitfunctions/BivariateGaussian.rst +++ b/docs/source/fitting/fitfunctions/BivariateGaussian.rst @@ -65,7 +65,7 @@ Here is an example of fitting a 2D histogram: # Now we declare our function - we create one separately # so that later we have access to functions which are not # accessible to Function1D (e.g. 2D and 3D versions of the - # function. The paramters we set here are an initial guess. + # function. The parameters we set here are an initial guess. bvg = BVG.BivariateGaussian() bvg.init() bvg['A'] = 1. diff --git a/docs/source/fitting/fitfunctions/FunctionQDepends.rst b/docs/source/fitting/fitfunctions/FunctionQDepends.rst index c94cf75a8f9218c18acad057bdcbca8f32f14284..c69885df4ed0e6027b1c8d72f0b5c23a32ae8dd6 100644 --- a/docs/source/fitting/fitfunctions/FunctionQDepends.rst +++ b/docs/source/fitting/fitfunctions/FunctionQDepends.rst @@ -16,7 +16,7 @@ This fitting function is the base class for all fitting functions that have: Fitting functions for QENS data depending on :math:`Q` should derive from this class. -There are two ways to update attribute :math:`Q` in the fit funtion: +There are two ways to update attribute :math:`Q` in the fit function: - The user inputs a particular value. - The spectrum contains :math:`Q` in addition to the range of energy transfers. @@ -27,4 +27,4 @@ in the spectrum. Here are some user cases: - User cannot override the value of attribute :math:`Q` if the spectrum contains a :math:`Q`-value. - User can set or update the value of of attribute :math:`Q` is the spectrum does not contain a :math:`Q`-value. - The value of attribute :math:`Q` will be updated everytime we pass a new spectrum containing a :math:`Q`-value. -- The value of attribute :math:`Q` will be erased if we pass a new spectrum not containing a :math:`Q`-value. In this case it is the responsability of the user to set the appropriate value. +- The value of attribute :math:`Q` will be erased if we pass a new spectrum not containing a :math:`Q`-value. In this case it is the responsibility of the user to set the appropriate value. diff --git a/docs/source/fitting/fitfunctions/GramCharlier.rst b/docs/source/fitting/fitfunctions/GramCharlier.rst index ea1b586dfe4cd77dd6249374b1073e2938bb68c8..327e233bb011d9c5506e2456028cec1e025c685c 100644 --- a/docs/source/fitting/fitfunctions/GramCharlier.rst +++ b/docs/source/fitting/fitfunctions/GramCharlier.rst @@ -14,9 +14,9 @@ This function implements the It finds its main usage in fitting broad mass peaks in Y space within Neutron Compton Scattering experiments such as on the `Vesuvio <http://www.isis.stfc.ac.uk/instruments/vesuvio/vesuvio4837.html>`_ instrument at ISIS. As such the expansion includes only the even numbered Hermite polynomials, up to order 10, with the exception of the 3rd order term where -it is useful to include a differnt amplitude factor. +it is useful to include a different amplitude factor. -The function defintion is given by: +The function definition is given by: .. math:: diff --git a/docs/source/fitting/fitfunctions/InelasticDiffSphere.rst b/docs/source/fitting/fitfunctions/InelasticDiffSphere.rst index 83276c06d224a6a600475c3f76bcb8497b2f98fd..89d53a30e8bf102707d7107cc70b6ded8e19b12f 100644 --- a/docs/source/fitting/fitfunctions/InelasticDiffSphere.rst +++ b/docs/source/fitting/fitfunctions/InelasticDiffSphere.rst @@ -28,7 +28,7 @@ is expressed in terms of the :math:`j_l(z)` The value of the momentum transfer can be obtained either through attribute :math:`Q`, or can be calculated from the input workspace using attribute :math:`WorkspaceIndex`. The value calculated -using the workspace is used whenever attibute :math:`Q` is set empty. +using the workspace is used whenever attribute :math:`Q` is set empty. .. attributes:: diff --git a/docs/source/fitting/fitfunctions/NeutronBk2BkExpConvPVoigt.rst b/docs/source/fitting/fitfunctions/NeutronBk2BkExpConvPVoigt.rst index 723e06d76c688d59cc46373080c2f15f04011ead..84a4f471b57a66421775f0569f5e1c44c0329464 100644 --- a/docs/source/fitting/fitfunctions/NeutronBk2BkExpConvPVoigt.rst +++ b/docs/source/fitting/fitfunctions/NeutronBk2BkExpConvPVoigt.rst @@ -37,10 +37,10 @@ Mantid. It is the peak shape No. 10 in Fullprof. See Refs. 1. Description ----------- -Thermal neutron back to back exponential convoluted with psuedo voigt -peak function is a back to back exponential convoluted with psuedo voigt +Thermal neutron back to back exponential convoluted with pseudo voigt +peak function is a back to back exponential convoluted with pseudo voigt peak function. Its difference to a regular back to back exponential -convoluted with psuedo voigt peak functiont is that it is a function for +convoluted with pseudo voigt peak functiont is that it is a function for all peaks in a TOF powder diffraction pattern, but not a single peak. Furthermore, the purpose to implement this function in Mantid is to diff --git a/docs/source/fitting/fitfunctions/SCDPanelErrors.rst b/docs/source/fitting/fitfunctions/SCDPanelErrors.rst index 1222954984a13298c27d4ba98615795e85da0cf9..825a57806b4411e2a18c4ac4c74384f57a132754 100644 --- a/docs/source/fitting/fitfunctions/SCDPanelErrors.rst +++ b/docs/source/fitting/fitfunctions/SCDPanelErrors.rst @@ -56,7 +56,7 @@ follows: SampleOffsets;Boolean;;A sample being off from the center of the goniometer can result in larger errors. - PeakWorkspaceName - This peak must be indexed by a UB matrix - whose lattice parametersare CLOSE to the above lattice paramters + whose lattice parametersare CLOSE to the above lattice parameters - BankNames - Names separated by "/" or a "!" if the next bank is in a different group. Bank names from the same group belong together("Requirement" for use with the Fit algorithm) diff --git a/docs/source/fitting/fitfunctions/ThermalNeutronBk2BkExpConvPVoigt.rst b/docs/source/fitting/fitfunctions/ThermalNeutronBk2BkExpConvPVoigt.rst index 03b64ec8318543cc850adb1d9a59088a57b84062..42e89950de551916f078f075e0b758aff66fd1d8 100644 --- a/docs/source/fitting/fitfunctions/ThermalNeutronBk2BkExpConvPVoigt.rst +++ b/docs/source/fitting/fitfunctions/ThermalNeutronBk2BkExpConvPVoigt.rst @@ -36,10 +36,10 @@ Mantid. It is the peak shape No. 10 in Fullprof. See Refs. 1. Description ----------- -Thermal neutron back to back exponential convoluted with psuedo voigt -peak function is a back to back exponential convoluted with psuedo voigt +Thermal neutron back to back exponential convoluted with pseudo voigt +peak function is a back to back exponential convoluted with pseudo voigt peak function. Its difference to a regular back to back exponential -convoluted with psuedo voigt peak functiont is that it is a function for +convoluted with pseudo voigt peak functiont is that it is a function for all peaks in a TOF powder diffraction pattern, but not a single peak. Furthermore, the purpose to implement this function in Mantid is to diff --git a/docs/source/images/DiagnosticsMaskIN5.png b/docs/source/images/DiagnosticsMaskIN5.png new file mode 100644 index 0000000000000000000000000000000000000000..44834d095375ad4e030a7099289a9cbc859eccff Binary files /dev/null and b/docs/source/images/DiagnosticsMaskIN5.png differ diff --git a/docs/source/images/MaxEntAdjust.png b/docs/source/images/MaxEntAdjust.png new file mode 100644 index 0000000000000000000000000000000000000000..badfebcd1f597522905d17c179cae587dabbdb8e Binary files /dev/null and b/docs/source/images/MaxEntAdjust.png differ diff --git a/docs/source/images/MaxEntAdjustTogether.png b/docs/source/images/MaxEntAdjustTogether.png new file mode 100644 index 0000000000000000000000000000000000000000..4174a1d6952dd3adfedc814d7e2a579820a6d215 Binary files /dev/null and b/docs/source/images/MaxEntAdjustTogether.png differ diff --git a/docs/source/interfaces/DGS Planner.rst b/docs/source/interfaces/DGS Planner.rst index c249b9d1df59b1f3ec0f4669a820567d6fe88b2b..6284f44196a7f2fdceb8967e6b9667e4ca4e6c5a 100644 --- a/docs/source/interfaces/DGS Planner.rst +++ b/docs/source/interfaces/DGS Planner.rst @@ -43,7 +43,7 @@ Sample settings Information about the sample can be introduced either in terms of **Lattice parameters** and orientation vectors, or the **UB matrix**. One can also load an ISAW UB matrix or load the UB matrix from the Nexus metadata. For -more informations, look at :ref:`SetUB <algm-SetUB>` +more information, look at :ref:`SetUB <algm-SetUB>` Viewing axes ------------ diff --git a/docs/source/interfaces/Data Comparison.rst b/docs/source/interfaces/Data Comparison.rst index ab2de0a702aa89928b07329cc9a166899518f0a8..3b54a9c0cfe5169208022bf571393d835ed3c71f 100644 --- a/docs/source/interfaces/Data Comparison.rst +++ b/docs/source/interfaces/Data Comparison.rst @@ -27,7 +27,7 @@ Add Data :align: right This allows new data to be added to the comparison, this can be added by either -selecting a :ref:`MatrixWorkspace <MatrixWorkspace>` alrady loaded into Mantid +selecting a :ref:`MatrixWorkspace <MatrixWorkspace>` already loaded into Mantid or by selecting a file to load. Alternatively you can select a :ref:`WorkspaceGroup <WorkspaceGroup>` to load @@ -54,7 +54,7 @@ the spectra that you want to compare do not have the same workspace index in eac workspace. The value of the offset for a workspace defines the workspace index that the -first spectum will line up to relative to the spectrum selection spin box. At +first spectrum will line up to relative to the spectrum selection spin box. At least one offset value must be zero (this is set check for automatically after an offset value has been changed). @@ -96,7 +96,7 @@ result spectra as a green curve on the plot. If either of the diff workspaces are removed then the diff will be cleared. If one of the workspaces can no longer be displayed as it is offset from the other -workspace then a messsage will be displayed in the diff tool and no plot will be +workspace then a message will be displayed in the diff tool and no plot will be shown, however the diff will continue to function once both workspaces can be displayed again. @@ -108,6 +108,6 @@ the difference. Note that if the two diffed workspaces have different binning, then the second one selected will be rebinned to match the first before the diff is created. -This will not modify the data in the otiginal workspace. +This will not modify the data in the original workspace. .. categories:: Interfaces General diff --git a/docs/source/interfaces/DataProcessorWidget.rst b/docs/source/interfaces/DataProcessorWidget.rst index 74b0b06d5e384e573391d4d4f9c96449110b6f93..884a72fc9ad0de7ed7fe0d7285591e6aa7f2f9e6 100644 --- a/docs/source/interfaces/DataProcessorWidget.rst +++ b/docs/source/interfaces/DataProcessorWidget.rst @@ -190,7 +190,7 @@ Processing Algorithm ^^^^^^^^^^^^^^^^^^^^ The processing algorithm refers to the main reduction algorithm that is used to reduce the runs. Processing -algorithms must satify the following conditions: +algorithms must satisfy the following conditions: - Only algorithms with at least one input workspace property are allowed. - Only algorithms with at least one output workspace property are allowed. @@ -292,7 +292,7 @@ Post-processing Algorithm ^^^^^^^^^^^^^^^^^^^^^^^^^ A post-processing algorithm defines the way in which a group of runs should be post-processed. As -an example, in Reflectometry at ISIS, a run typically constists in two or three runs measured +an example, in Reflectometry at ISIS, a run typically consists in two or three runs measured under the same conditions of temperature, magnetic field, etc, but at different incident angles. These runs belong to the same group and need to be stitched together. The post-processing algorithm is in this case :ref:`algm-Stitch1DMany`, and can be defined as: @@ -354,7 +354,7 @@ in Reflectometry at ISIS we use :ref:`algm-LoadISISNexus`). However, at the mome this is only possible if both pre-processing and post-processing algorithms are specified. The only reason for this is that it was requested by Reflectometry scientists at ISIS, who work with pre-processing and post-processing. However, if you need to implement this, all you need to do is add an optional -string argument to the relevant :literal:`GenericDataProcessorPresenter` constuctor. For instance, +string argument to the relevant :literal:`GenericDataProcessorPresenter` constructor. For instance, assuming that you don't need to pre-process and post-process groups of runs, the constructor: .. code-block:: c diff --git a/docs/source/interfaces/Engineering Diffraction Test Guide.rst b/docs/source/interfaces/Engineering Diffraction Test Guide.rst index 3cc0464e99c5b389477768fe3ef75a75cb20354b..27235d6edf6e9b91006fd5cc8eecd46f39b08944 100644 --- a/docs/source/interfaces/Engineering Diffraction Test Guide.rst +++ b/docs/source/interfaces/Engineering Diffraction Test Guide.rst @@ -114,7 +114,7 @@ Negative Testing Ideas Pre-processing ^^^^^^^^^^^^^^ Pre-processing is used to convert event data into histogram data which can be subsequently -focused. The optimal parameters for pre-processing are dependant on how the instrument was +focused. The optimal parameters for pre-processing are dependent on how the instrument was configured during the capture of the data. `Regular time binning` requires the bin width to be specified and will produce a histogram # diff --git a/docs/source/interfaces/Engineering Diffraction.rst b/docs/source/interfaces/Engineering Diffraction.rst index d4909e53c8108317d423bec84fedfdabe05406cf..c103695821470e701f5785a905224b8ec79dbcb7 100644 --- a/docs/source/interfaces/Engineering Diffraction.rst +++ b/docs/source/interfaces/Engineering Diffraction.rst @@ -513,7 +513,7 @@ To do a refinement, take the following steps: corresponding **Browse** button, then clicking **Load**. The run number and bank ID (for example ``123456_1``) should appear in the **Run Number** list in the **Preview** section. Click the label, - and the run willl be plotted + and the run will be plotted 2. Select your input files, and input any additional parameters in the **GSASIIRefineFitPeaks Controls** section 3. Click **Run Refinement**. Once complete, fitted peaks for the run diff --git a/docs/source/interfaces/HFIR Powder Reduction.rst b/docs/source/interfaces/HFIR Powder Reduction.rst deleted file mode 100644 index b87f31f0cbb9622de84fac7fa7675f68b15c3640..0000000000000000000000000000000000000000 --- a/docs/source/interfaces/HFIR Powder Reduction.rst +++ /dev/null @@ -1,179 +0,0 @@ -HFIR Powder Reduction Interface -=============================== - -.. contents:: Table of Contents - :local: - -Overview --------- - -HFIR powder reduction interface (HFIR-PDR-GUI) is a GUI to download, view and reduce data from HFIR's powder diffractometers -in SPICE format. - - -Use cases for tabs ------------------- - -1. **Raw Detectors**: Visualize the reading of detectors directly coming out of the raw data - - - Plot N lines for N Pts.; - - Highlight (make it thicker) the Pt that is interested; - - New from Mantid: *ReadRawSpiceSignal(Pts)*; - -2. **Individual Detector**: Visual the readings of one detector across an experiment - - - Plot the counts of any individual detector; - - Able to change the X-axis from 2theta to arbitrary sample environment log; - - New from Mantid: *ReadRawSpiceSignal(DetectorID, XLabel)*; - -3. **Normalized**: Reduce one scan each time - - - Plot the reduced data - - Automatically locate detector efficiency file - - New from Mantid: *ConvertCWPDMDToSpectra(ExcludedDetectors=[])* - - New from Mantid: *ConvertSpiceDataToRealSpace(DetectorEfficiencyTable)* - -4. **Multiple Scans**: Reduce a set of scans - - - Reduce a set of scans and plot in 2D/water-fall mode; - - Able to merge all the scans; - - New from Mantid: *ConvertCWPDMDToSpectra(ExcludedDetectors=[])* - -5. **Vanadium**: strip vanadium peaks - - - Strip vanadium peak with unit 'Degrees' because of the binning (range and step size) must be respected; - - Peaks' position should be calculated and indicated auotmatically; - - *Mantid::StripPeaks()* will be called instread of *StripVadadiumPeaks()* because - the later one only works in d-spacing; - -6. **Advanced Setup** - - - URL for raw data files; - - -Workflow for *Normalization* -============================ - -Here is a typical use case for reduce data via tab *Noramlization* - -1. User specifies *Exp No* and *Scan No* and push button *Load*; - - - HFIR-PDR-GUI loads SPICE data according to experiment number and scan number; - - HFIR-PDR-GUI checks whether vanadium correction file, i.e., detector efficiency file exists on server; - - HFIR-PDR-GUI checks whether excluded detectors file exists on server; - - HFIR-PDR-GUI checks log **m1** for wavelength and set to *Wavelength* ; - -2. User may specify detector efficient file; - -3. User specifies *Bin Size*; - -4. User pushes button *2Theta*, *dSpacng*, or *Q*; - - - HFIR-PDF-GUI reduce data in unit of *2theta* by taking accounting of - - - Detector efficiency; - - Excluded detectors; - -5. HFIR-PDR-GUI plots the reduced data; - -6. User may rebin by different binning parameters or unit; - -7. User may push button *Next Scan* or *Prev Scan* to load and reduce other scans with current setup; - -8. User may save the result by pushing button *Save*; - - -Workflow for *Raw Detectors* -============================ - -Here is a typical use case for reduce data via tab *Noramlization* - -1. User specifies *Exp No* and *Scan No* and push button *Load*; - - - HFIR-PDR-GUI loads SPICE data according to experiment number and scan number; - - HFIR-PDR-GUI checks whether vanadium correction file, i.e., detector efficiency file exists on server; - - HFIR-PDR-GUI checks whether excluded detectors file exists on server; - - HFIR-PDR-GUI checks log **m1** for wavelength and set to *Wavelength* ; - -2. User specifies a *Pt.* number and push button *Plot Raw Detector*; - - - HFIR-PDF-GUI plots the raw detector counts normalized by monitor count; - -3. User may push button *Previous Pt.* or *Next Pt.* for the other experiment points; - - - -Workflow for *Multiple Scans* -======================================= - -It might be confusing to use the functionalities in tab *Multiple Scans*. -Here is the suggested workflow to reduce multiple scans and possibly merge them. - -1. Set up *Exp No* and range of scan numbers; -2. Push button *Load All* to load and reduce all runs specified in previous step to single-spectrum diffraction pattern; -3. Plot all reduced scans in default; -4. Optinally plot all data in 2D fill plot; -5. User can delete some scans from the reduced scans via GUI or input text edit (not implemented yet); -6. Push button *Merge* to merge the scans; -7. Push button *Save All* to save all individual scans to files; -8. Push button *Save Merged* to save the merged scans to one file; - -HB2A Data Reduction -------------------- - -Raw experimental data are to be corrected by (1) detector efficiency, (2) vanadium spectrum and etc. -Experiments are done with neutrons with various wavelengthes. -There information can be retrieved from HB2A's data repository accessible from internet. - -Experiment setup and sample log -=============================== - -1. **Wavelength**: There are three settings for neutron wavelength, referenced by sample log *m1*. - - - Ge 113: :math:`\lambda = 2.41 \AA`, m1 = 9.45 (The **error** can be 0.05, such that in Exp 231 scan0001, m1=9.5) - - Ge 115: :math:`\lambda = 1.54 \AA`, m1 = 0 - - Ge 117 :math:`\lambda = 1.12 \AA`, No used - -2. **Collimator translation**: There are two status for collimator, which is specified by sample log *colltrans* - - - *IN*: colltrans = 0 - - *OUT*: colltrans = +/-80 - - -Raw data correction files -========================= - -1. **Detector efficiency**: - - - File name: *HB2A_exp0IJK__GE_abc_XY_vcorr.txt* where - - - IJK is the experiment number - - abc is the GE set up. It can be 113, 115 or 117 - - XY is either IN or OUT. - - Example: *HB2A_exp0400__Ge_113_IN_vcorr.txt* - - - Web address: *http://neutron.ornl.gov/user_data/hb2a/exp400/Datafiles/HB2A_exp0IJK__Ge_abc_IN_vcorr.txt* - - - IJK is the experiment number - - abc is the GE set up. It can be 113, 115 or 117 - - XY is either IN or OUT. - - Example: *http://neutron.ornl.gov/user_data/hb2a/exp400/Datafiles/HB2A_exp0400__Ge_113_IN_vcorr.txt* - -2. **Excluded detectors**: Some detectors might be exluded from the experiment for some reason. It is recorded in some excluded detectors' file. - - - File name: *HB2A_exp0IJK__exclude_detectors.txt* - - - IJK is the epxeriment number - - Example: *HB2A_exp0400__exclude_detectors.txt* - - - Web address: *http://neutron.ornl.gov/user_data/hb2a/expIJK/Datafiles/HB2A_exp0IJK__exclude_detectors.txt* - - - IJK is the experiment number - - Example: *http://neutron.ornl.gov/user_data/hb2a/exp400/Datafiles/HB2A_exp0400__exclude_detectors.txt* - -3. Detector gaps: The 2-theta gap (in unit degrees) can be changed among cycles. - - - Location example: *http://neutron.ornl.gov/user_data/hb2a/exp400/Datafiles/HB2A_exp0400__gaps.txt* - - -.. categories:: Interfaces diff --git a/docs/source/interfaces/HFIR Single Crystal Reduction.rst b/docs/source/interfaces/HFIR Single Crystal Reduction.rst index d152332983e771d7969dcb323672754074820128..cccd52f341aaaf33e46d0e638300907ad60a04b0 100644 --- a/docs/source/interfaces/HFIR Single Crystal Reduction.rst +++ b/docs/source/interfaces/HFIR Single Crystal Reduction.rst @@ -105,7 +105,7 @@ Here is a typical use case to calculate UB matrix after initial setup. 7. GUI finds the peak center and load HKL 8. User pushes button *Add peak* to add the peak to table 9. User repeats step 2 to 9 to add other peaks -10. User select the peaks that are linearly independent and pushes *Calcualte UB* +10. User select the peaks that are linearly independent and pushes *Calculate UB* 11. GUI calculates UB matrix and show the result 12. User may push *Index peak* to use the calculated UB matrix to index peaks in the table to check UB matrix; 13. User may refine the UB matrix and thus lattice parameters @@ -168,7 +168,7 @@ and scaled up by same factor (e.g, 1500). -UB Matrix Calcualtion and Refinement +UB Matrix Calculation and Refinement ------------------------------------ @@ -241,11 +241,11 @@ The error can be calculated as Estimating background ^^^^^^^^^^^^^^^^^^^^^ -For each measurment, the background :math:`B_i` is calculated as +For each measurement, the background :math:`B_i` is calculated as .. math:: B^{(e)} = \frac{\sum_i^{<pt>}C_i}{|<pt>|} -where :math:`<pt>` is a set of measurment points that are specified by users. +where :math:`<pt>` is a set of measurement points that are specified by users. Usually they are the first and last several measurements in a scan. Then this estimated **normalized** background value can be applied to each measuremnt, whose counts are normalized. @@ -346,7 +346,7 @@ normalization type of :math:`F_i`. Estimating background ^^^^^^^^^^^^^^^^^^^^^ -For each measurment, the background :math:`B_i` is calculated as +For each measurement, the background :math:`B_i` is calculated as .. math:: B_i = \frac{\sum^{(pt)}_{\{d_i\}}n_{d_i}}{F^{(a)}_{d_i}} diff --git a/docs/source/interfaces/ISIS Reflectometry.rst b/docs/source/interfaces/ISIS Reflectometry.rst index 0ae5b8df9c12ce68fc4aba0f8e355c60ef288e01..cc19a4e12687ad9876a8abb0ddbdcc7549208bda 100644 --- a/docs/source/interfaces/ISIS Reflectometry.rst +++ b/docs/source/interfaces/ISIS Reflectometry.rst @@ -484,7 +484,7 @@ monitoring. You can stop monitoring at any time using the `Stop monitor` button or by cancelling the algorithm from the *Algorithm progress* dialog. If you close the -interface, monitoring will continue running in the backgroud. You can cancel +interface, monitoring will continue running in the background. You can cancel the `MonitorLiveData` algorithm from the *Algorithm progress* dialog. If `MonitorLiveData` stops due to an error, the `Start monitor` button will be diff --git a/docs/source/interfaces/Indirect Corrections.rst b/docs/source/interfaces/Indirect Corrections.rst index 4e8efd538841269afa8a4c240c689edb4444b16e..3491ab6ccf57fe6704206b052404ccb795d013e6 100644 --- a/docs/source/interfaces/Indirect Corrections.rst +++ b/docs/source/interfaces/Indirect Corrections.rst @@ -135,7 +135,7 @@ Cylinder The calculation for a cylindrical geometry is performed by the :ref:`CylinderPaalmanPingsCorrection <algm-CylinderPaalmanPingsCorrection>` algorithm, this algorithm is currently only available on Windows as it uses -FORTRAN code dependant of F2Py. +FORTRAN code dependent of F2Py. Sample Inner Radius Radius of the inner wall of the sample in :math:`cm`. @@ -164,7 +164,7 @@ Annulus The calculation for an annular geometry is performed by the :ref:`CylinderPaalmanPingsCorrection <algm-CylinderPaalmanPingsCorrection>` algorithm, this algorithm is currently only available on Windows as it uses -FORTRAN code dependant of F2Py. +FORTRAN code dependent of F2Py. The options here are the same as for Cylinder. diff --git a/docs/source/interfaces/Indirect Data Analysis.rst b/docs/source/interfaces/Indirect Data Analysis.rst index 569a1c52b5ed0d6152c712197c5fee1f9562656b..93183a1838f8d8be13a8a1dc7b213d02dba30fde 100644 --- a/docs/source/interfaces/Indirect Data Analysis.rst +++ b/docs/source/interfaces/Indirect Data Analysis.rst @@ -90,7 +90,7 @@ SE log name SE log value The value to be taken from the "SE log name" data series (defaults to the - specified value in the intrument parameters file, and in the absence of such + specified value in the instrument parameters file, and in the absence of such specification, defaults to "last value") Plot Result @@ -133,7 +133,7 @@ reduces to a Gaussian at sigma equal to zero. Options ~~~~~~~ -.. seealso:: Common options are detailled in the :ref:`qens-fitting-features` section. +.. seealso:: Common options are detailed in the :ref:`qens-fitting-features` section. .. seealso:: Sequential fitting is available, options are detailed in the :ref:`sequential-fitting-section` section. @@ -217,7 +217,7 @@ are also available via the fit wizard. Options ~~~~~~~ -.. seealso:: Common options are detailled in the :ref:`qens-fitting-features` section. +.. seealso:: Common options are detailed in the :ref:`qens-fitting-features` section. .. seealso:: Sequential fitting is available, options are detailed in the :ref:`sequential-fitting-section` section. @@ -314,7 +314,7 @@ EISF. This is done by means of the Options ~~~~~~~ -.. seealso:: Common options are detailled in the :ref:`qens-fitting-features` section. +.. seealso:: Common options are detailed in the :ref:`qens-fitting-features` section. -Sample - A sample workspace created with either ConvFit or Quasi. diff --git a/docs/source/interfaces/Indirect Data Reduction.rst b/docs/source/interfaces/Indirect Data Reduction.rst index 11a42b5c4a58ed078b854c3ad1655fe4d4bcb7e8..632bc3a5508d58b526150aed59b26ff023de88d0 100644 --- a/docs/source/interfaces/Indirect Data Reduction.rst +++ b/docs/source/interfaces/Indirect Data Reduction.rst @@ -77,7 +77,7 @@ Sum Files treated as a single run. Load Log Files - If selected the sample logs will be laoded from each of the run files. + If selected the sample logs will be loaded from each of the run files. Efixed This option allows you to override the default fixed final energy for the @@ -105,7 +105,7 @@ Scale Gives the option to scale the output by a given factor. Spectra Min & Spectra Max - Selecte the range of detectors you are interested in, default values are + Select the range of detectors you are interested in, default values are chosen based on the instrument and analyser bank selected. Rebin Steps @@ -119,7 +119,7 @@ Plot Output Fold Multiple Frames This option is only relevant for TOSCA. If checked, then multiple-framed data - will be folded back into a single spectra, if unchecked the frames wil lbe + will be folded back into a single spectra, if unchecked the frames will be left as is with the frame number given at the end of the workspace name. Output in :math:`cm^{-1}` @@ -128,7 +128,7 @@ Output in :math:`cm^{-1}` Select Save Formats Allows you to select multiple output save formats to save the reduced data as, - in all cases the file will be saved in the defaut save directory. + in all cases the file will be saved in the default save directory. Grouping ~~~~~~~~ @@ -254,7 +254,7 @@ FWS-only Options ~~~~~~~~~~~~~~~~ Observable - This is the scanning ovservable, that will become the x-axis of the final result. + This is the scanning observable, that will become the x-axis of the final result. It can be any numeric sample parameter defined in Sample Logs (e.g. sample.*) or a time-stamp string (e.g. start_time). It can also be the run number. It can not be an instrument parameter. @@ -274,7 +274,7 @@ ISIS Calibration & Resolution This tab gives you the ability to create Calibration and Resolution files. -The calibrtion file is normalised to an average of 1. +The calibration file is normalised to an average of 1. Options ~~~~~~~ @@ -369,7 +369,7 @@ Input Transfer tab. Use Calibration - Allows you to select either a calibrtion file or workspace to apply to the raw + Allows you to select either a calibration file or workspace to apply to the raw files. Preview Spectrum @@ -390,7 +390,7 @@ Use Two Ranges If selected, enables subtraction of the background range. Background - An optional range denoting background noice that is to be removed from the raw + An optional range denoting background noise that is to be removed from the raw data before the integration is performed. A default starting value is generally provided from the instrument's parameter file. diff --git a/docs/source/interfaces/Indirect Simulation.rst b/docs/source/interfaces/Indirect Simulation.rst index 4c1cf715a647823f6737987379ca20cf2456dc5e..3107521e15b2e2a69984d489120c10a7422ba0a6 100644 --- a/docs/source/interfaces/Indirect Simulation.rst +++ b/docs/source/interfaces/Indirect Simulation.rst @@ -35,7 +35,7 @@ MolDyn The MolDyn interface is used to import simulation data created using nMOLDYN (by using the :ref:`MolDyn <algm-MolDyn>` algorithm), tab operates on either *.dat* or *.cdl* files for nMOLDYN 3 or a directory containing the files extracted from -the *.tar* archive crated by nMOLDYN 4. +the *.tar* archive created by nMOLDYN 4. Options ~~~~~~~ diff --git a/docs/source/interfaces/ManageUserDirectories.rst b/docs/source/interfaces/ManageUserDirectories.rst index 2f43a369fbb4d78352bb05a63b39de63bd97df6a..075a09ab49dc89d4aa8dfb714cc28b680b710f73 100644 --- a/docs/source/interfaces/ManageUserDirectories.rst +++ b/docs/source/interfaces/ManageUserDirectories.rst @@ -5,7 +5,7 @@ :align: right :width: 455 -This dialog allows you to adjust your settings (stored in the :ref:`Properties File`) for the data search directories which Mantid will search for data in, the option to also search the data archive, and the default save directory. It is accessable from the File menu, on the toolbar through it's icon |filefolder_icon| , through the "Help"->"First Time Setup" menu window, or from buttons on several custom user interfaces. +This dialog allows you to adjust your settings (stored in the :ref:`Properties File`) for the data search directories which Mantid will search for data in, the option to also search the data archive, and the default save directory. It is accessible from the File menu, on the toolbar through it's icon |filefolder_icon| , through the "Help"->"First Time Setup" menu window, or from buttons on several custom user interfaces. .. |filefolder_icon| image:: /images/MantidQtManageDirectoriesIcon.jpg diff --git a/docs/source/interfaces/Multi-dataset Fitting.rst b/docs/source/interfaces/Multi-dataset Fitting.rst index ee282c362704018cabdd63453cea08f158888f71..4d67bc5948b078cac9c7047c5c5bb7fd375cbc1f 100644 --- a/docs/source/interfaces/Multi-dataset Fitting.rst +++ b/docs/source/interfaces/Multi-dataset Fitting.rst @@ -143,7 +143,7 @@ parameters together. :width: 300px Right clicking on a parameter shows the context menu with the fix, tie, and - contraint options + constraint options .. figure:: ../images/multidataset-fitting/multidataset-set-tie.png :align: center diff --git a/docs/source/interfaces/Muon ALC.rst b/docs/source/interfaces/Muon ALC.rst index 8b6cbff193e7a8ae49154da9c7073946381c4f30..2784dee65d708b476e4726197ad7eb47ddee65b6 100644 --- a/docs/source/interfaces/Muon ALC.rst +++ b/docs/source/interfaces/Muon ALC.rst @@ -245,7 +245,7 @@ Add as many peaks as needed. To activate the peak picker tool, click on one of the functions in the browser and then left-click on the graph near the peak's center while holding the Shift key. This will move the picker tool associated with the highlighted function to the desired location. To set the peak width, -click and drag while holding Crtl. You can then tune the heigth by clicking on +click and drag while holding Crtl. You can then tune the height by clicking on the appropriate point in the graph while holding Shift. Repeat the same steps with the rest of the functions in the browser and hit **Fit** to fit the peaks. diff --git a/docs/source/interfaces/Muon Analysis.rst b/docs/source/interfaces/Muon Analysis.rst index 09d53ed6e08f0e217a559cd7de43abfac7f1015b..132ee189276f26cba014c70250ab2c61711cacd9 100644 --- a/docs/source/interfaces/Muon Analysis.rst +++ b/docs/source/interfaces/Muon Analysis.rst @@ -17,7 +17,7 @@ accessed from the main menu of MantidPlot, in *Interfaces → Muon → Muon Anal datasets, please visit `Muon - Downloads <http://www.isis.stfc.ac.uk/groups/muons/downloads/downloads4612.html>`_.# If the :ref:`Frequency_Domain_Analysis-ref` interfaces is opened it will import all of the data available for the current run in Muon Analysis. -This will include any custom groupings/pairs. +This will include any custom groupings/pairs. Home ---- @@ -132,7 +132,7 @@ Plot Data | | | - **AsymmetryCalc** For pairs- the result of | | | | :ref:`AsymmetryCalc <algm-AsymmetryCalc>` for the pair groups. | | | | For groups- the result of :ref:`RemoveExpDecay <algm-RemoveExpDecay>` applied | -| | | to the group. | +| | | to the group. | | | | | | | | - **Counts** *(groups only)*. Pure counts of the selected group. | | | | | @@ -268,8 +268,8 @@ Data Analysis This tab is designed for the user to make a fit against the data just plotted. Since Mantid 3.8 (upgraded in 3.10), this tab has been enhanced to include fits of multiple datasets at once. -Since Mantid 3.10 a Transverse field (TF) Asymmetry mode has been added and from Mantid 3.11 it is also available in -multiple fitting mode. +Since Mantid 3.10 a Transverse field (TF) Asymmetry mode has been added and from Mantid 3.11 it is also available in +multiple fitting mode. Default: multiple fitting disabled ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -290,11 +290,11 @@ The intention is that this mode could be useful for users who are accustomed to TF asymmetry enabled ^^^^^^^^^^^^^^^^^^^^^^^^ -The TF asymmetry mode can be enabled by checking the "TF Asymmetry" checkbox in the Settings table of the data analysis tab. Leaving the tab will deactivate +The TF asymmetry mode can be enabled by checking the "TF Asymmetry" checkbox in the Settings table of the data analysis tab. Leaving the tab will deactivate TF asymmetry. When TF Asymmetry is activated the user's function is updated by using :ref:`ConvertFitFunctionForMuonTFAsymmetry <algm-ConvertFitFunctionForMuonTFAsymmetry>` and populates the function browser. The ties and constraints are not preserved. The plot will also update. Running a fit will then use :ref:`CalculaterMuonAsymmetry <algm-CalculateMuonAsymmetry>`. This willupdate the normalized data. -It is adviced that when using this feature to have no binning. +It is advised that when using this feature to have no binning. When the user deactivates the "TF Asymmetry" checkbox the user function is returned with updated values. @@ -321,7 +321,7 @@ The function browser has three columns - property, value and global. The values shown are those of the currently selected/plotted dataset. The global column contains a checkbox for each function parameter which, when checked, sets this parameter to be shared between all fits. -Parameters can be fixed, tied and constrained by right-clicking. +Parameters can be fixed, tied and constrained by right-clicking. In addition, just as in the general multi dataset fitting interface, when highlighting a non-global function parameter, a small button will appear next to its value. This button will open the "Edit local parameter values" dialog, which offers greater control of function parameters for each dataset. @@ -346,15 +346,15 @@ Data Table ^^^^^^^^^^ The data table allows the user to modify the selected data for the fitting. This includes the start and end times, which can also -be updated by dragging the blue dashed lines in the plot. The "Groups/Pairs to fit" box provides a drop-down menu with three options (all groups, all pairs and custom). -Selecting custom will produce a pop-up box with tick boxes for each of the available groups and pairs. If a user wants to update the custom selection the -Groups/Pairs button can be pressed from the ReselectData_ section at the bottom ofthe tab (this is only enabled if a custom selection is set). Underneath displays the -"Selected Groups". +be updated by dragging the blue dashed lines in the plot. The "Groups/Pairs to fit" box provides a drop-down menu with three options (all groups, all pairs and custom). +Selecting custom will produce a pop-up box with tick boxes for each of the available groups and pairs. If a user wants to update the custom selection the +Groups/Pairs button can be pressed from the ReselectData_ section at the bottom of the tab (this is only enabled if a custom selection is set). Underneath displays the +"Selected Groups". The next row is the "Periods to fit" option, which is only displayed for multiple period data. This will automatically be populated with -each of the periods (e.g. 1,2,3) and a custom option. Selecting custom will produce a pop-up with checkboxes for all of the periods. Selecting custom will also enable the +each of the periods (e.g. 1,2,3) and a custom option. Selecting custom will produce a pop-up with checkboxes for all of the periods. Selecting custom will also enable the "Periods" button in the ReselectData_ section -and pressing this button will allow the user to alter their custom selection. +and pressing this button will allow the user to alter their custom selection. Examples/Use cases """""""""""""""""" @@ -402,12 +402,12 @@ Reselect data .. _ReselectData: -At the bottom of the tab is the "Reselect Data" section. This includes three buttons "Groups/Pairs", "Periods" and "Combine Periods". The "Groups/Pairs" and "Periods" -buttons are only when the relevant options in the data table are set to custom. Pressing the button will produce a pop-up that will allow the user to modify their selection. +At the bottom of the tab is the "Reselect Data" section. This includes three buttons "Groups/Pairs", "Periods" and "Combine Periods". The "Groups/Pairs" and "Periods" +buttons are only when the relevant options in the data table are set to custom. Pressing the button will produce a pop-up that will allow the user to modify their selection. -The "Combine Periods" button is only enabled if multiple periods are available. Pressing the button will generate a pop-up with two boxes. The top one is for adding periods -(as a comma seperated list or with "+") and the bottom box is for subtraction (as a comma sepearted list). Everything in the top and bottom boxes are summed seperatley -and the results are then used in the subtraction. +The "Combine Periods" button is only enabled if multiple periods are available. Pressing the button will generate a pop-up with two boxes. The top one is for adding periods +(as a comma separated list or with "+") and the bottom box is for subtraction (as a comma sepearted list). Everything in the top and bottom boxes are summed seperatley +and the results are then used in the subtraction. .. image:: ../images/MuonAnalysisCombinePeriods.png :align: right @@ -427,14 +427,14 @@ The dialog can be opened from the Fit menu in *Fit* → *Sequential Fit*. +-------+-----------------------+---------------------------------------------------------------------------+ | **1** | **Runs** | A list of run data files to fit. Two types of input are accepted: | -| | | | +| | | | | | | - List of files on the disk separated by comma. These can be specified | | | | using the *Browse* button. | -| | | | +| | | | | | | - Run numbers separated by comma. Specific files will then be searched | | | | in the archive for the instrument selected on the interface. Ranges | | | | are allowed, e.g. "15189-15199". | -| | | | +| | | | +-------+-----------------------+---------------------------------------------------------------------------+ | **2** | **Label** | Text label to use for the sequential fit. It is used to find the results | | | | on the ResultsTable_ tab. The resulting workspace group and the | @@ -452,7 +452,7 @@ The dialog can be opened from the Fit menu in *Fit* → *Sequential Fit*. | | | values of all the parameters. | +-------+-----------------------+---------------------------------------------------------------------------+ -After the options have been set and the *Start* button has been pressed, the dialog goes through **every** +After the options have been set and the *Start* button has been pressed, the dialog goes through **every** data file and does the following: 1. Loads the file @@ -641,7 +641,7 @@ General | | | | | | | NOTE: This can can cause speed and stability problems once the | | | | number of graphs managed by Mantidplot passes a few hundred | -| | | which can hapen if you run Mantid for a few days on an | +| | | which can happen if you run Mantid for a few days on an | | | | experiment. For long term stability we suggest you select | | | | **Use previous window**. | | | | | @@ -677,6 +677,6 @@ Feedback & Comments If you have any questions or comments about this interface or this help page, please contact the `Mantid team <http://www.mantidproject.org/Contact>`__ or the -`Muon group <http://www.isis.stfc.ac.uk/groups/muons/muons3385.html>`__. +`Muon group <http://www.isis.stfc.ac.uk/groups/muons/muons3385.html>`__. .. categories:: Interfaces Muon diff --git a/docs/source/interfaces/PyChop.rst b/docs/source/interfaces/PyChop.rst index 43980ad03c8c74281362faa02f5fd8695514a604..ff0ff2ab195be8e1fc3c0c33dd7cce0de837903f 100644 --- a/docs/source/interfaces/PyChop.rst +++ b/docs/source/interfaces/PyChop.rst @@ -56,7 +56,7 @@ if it detects that only the frequency has changed. If the instrument is LET (or MERLIN with the G chopper), the time-distance plot is enabled, and an additional option to change the phase of chopper 2 is -available. This chopper has a wide openning and can be used to suppress low +available. This chopper has a wide opening and can be used to suppress low energy reps. The time delay which is specified in the chopper 2 phase edit box is the time-of-flight in microseconds relative to the moderator pulse when the chopper first opens. diff --git a/docs/source/plotting/index.rst b/docs/source/plotting/index.rst index 2f20c2d4b2fc6b13a48e172309cd77a6f398957c..613dfc5844c304dca9e1486af3cfe601e03fd879 100644 --- a/docs/source/plotting/index.rst +++ b/docs/source/plotting/index.rst @@ -16,7 +16,7 @@ There are several advantages of using this software package: While Matplotlib is using data arrays for inputs in the plotting routines, it is now possible to also use several types on Mantid workspaces instead. -For a detailed list of functions that use workspaces, see the documentaion +For a detailed list of functions that use workspaces, see the documentation of the :ref:`mantid.plots <mantid.plots>` module. This page is intended to provide examples about how to use different diff --git a/docs/source/release/v3.10.0/reflectometry.rst b/docs/source/release/v3.10.0/reflectometry.rst index 1417e8b5f94b93d1cf152a3f83711ec3ce29596e..046a9fedc49160fa9479bfb4705f2aa9024b5855 100644 --- a/docs/source/release/v3.10.0/reflectometry.rst +++ b/docs/source/release/v3.10.0/reflectometry.rst @@ -5,7 +5,7 @@ Reflectometry Changes .. contents:: Table of Contents :local: -- Geometry for ``INTER`` has a small correction for the value of one of the attributes that was being intepreted as zero. +- Geometry for ``INTER`` has a small correction for the value of one of the attributes that was being interpreted as zero. Algorithms ---------- diff --git a/docs/source/release/v3.10.0/sans.rst b/docs/source/release/v3.10.0/sans.rst index 6bd96df3b4fd500c482aa70e588c474bf3cdc1fc..ad75f6bbd59f2afdafc336190599a5ace8122e89 100644 --- a/docs/source/release/v3.10.0/sans.rst +++ b/docs/source/release/v3.10.0/sans.rst @@ -11,7 +11,7 @@ ISIS SANS A new reduction backend was added. It improves considerably on performance, robustness and maintainability. Currently the new reduction backend can be used via a Python API. See `here <https://www.mantidproject.org/Scripting_SANS_Reductions_With_The_New_Reduction_Backend>`_ for more details on how to use the new reduction backend via this API. -One of the most noteable improvements of this new reduction backend is an enhanced performance which is most prominent when running batch reductions. +One of the most notable improvements of this new reduction backend is an enhanced performance which is most prominent when running batch reductions. .. figure:: ../../images/SANSNewReductionBackendPerformance.png :align: center diff --git a/docs/source/release/v3.10.0/ui.rst b/docs/source/release/v3.10.0/ui.rst index 2e2b5fe0fcb0c627db339697dcfe87eeb2ad9cfe..aac0435f16c6996824af44166b5a06698a509918 100644 --- a/docs/source/release/v3.10.0/ui.rst +++ b/docs/source/release/v3.10.0/ui.rst @@ -20,7 +20,7 @@ User Interface appropriately rather than being too small to be usable (Windows only). - A new Print button has been added to the MantidPlot help window. -.. figure:: ../../images/maskedbins.jpg +.. figure:: ../../images/maskedbins.jpg :class: screenshot :width: 500px :align: right @@ -49,12 +49,12 @@ Plotting Improvements + This allows a wider selection of plot types: Surface, Contour, Waterfall, 1D and Tiled plotting + If you have more than one workspace selected, either by using ctrl or shift, or by selecting a group workspace this enables multiple workspaces to be included in the plots + This interface also give you much better control over the labelling of the data in the plots - + * Log values can be used as labels, which is good for temperature or pressure ramps * Custom labels can be input if log data is not available * For Waterfall and 1D plots, the labelling appears in the legend - * For Surface plots the labels form the Z axis - + * For Surface plots the labels form the Z axis + - Curves where all(Y) <= 0 are now not plotted when the Y-scale is set to logarithmic. The previous behaviour assigned an arbitrary value of 0.1 which was confusing. @@ -87,8 +87,8 @@ SliceViewer Improvements - Fixed a bug where swapping the dimensions did not draw the axis scale correctly. - Fixed a bug where the normalization selection was not respected. -VSI Improvments -############### +VSI Improvements +################ - ParaView was updated to to `v5.3.0 <https://blog.kitware.com/paraview-5-3-0-release-notes/>`_. - The mapped array vtkMDHWSignalArray has been refactored to use the new vtkGenericDataArray class template. This interface minimizes virtual indirection and allows advanced compiler optimizations such as vectorization. - Minimize the number of times the workspace min and max values are calculated. diff --git a/docs/source/release/v3.11.0/framework.rst b/docs/source/release/v3.11.0/framework.rst index c334488a216a425f81cf5fc258d20facf3b6fbb6..ce75b93ac74f62e4ef2cc064337ab9243aeab607 100644 --- a/docs/source/release/v3.11.0/framework.rst +++ b/docs/source/release/v3.11.0/framework.rst @@ -29,7 +29,7 @@ Improved - :ref:`ConvertSpectrumAxis <algm-ConvertSpectrumAxis-v2>` is extended to support conversion to elastic d-spacing. - :ref:`SumSpectra <algm-SumSpectra-v1>`: Fixed a bug where a wrong fallback value would be used in case of invalid values being set for min/max worspace index, and improved input validation for those properties. -- :ref:`SetUncertainties <algm-SetUncertainties-v1>` now provides a "custom" mode, which lets the user specify both an arbitrary error value whose occurences are to be replaced in the input workspace, as well as the value to replace it with. +- :ref:`SetUncertainties <algm-SetUncertainties-v1>` now provides a "custom" mode, which lets the user specify both an arbitrary error value whose occurrences are to be replaced in the input workspace, as well as the value to replace it with. - :ref:`LoadBBY <algm-LoadBBY-v1>` is now better at handling sample information. - :ref:`ConjoinWorkspaces <algm-ConjoinWorkspaces-v1>` provides option to change Y axis unit and label. - :ref:`FilterEvents <algm-FilterEvents-v1>` has refactored on splitting sample logs. @@ -52,7 +52,7 @@ Improved - :ref:`SaveGSS <algm-SaveGSS-v1>` now supports saving in the legacy GSAS ALT format. This is useful for older tools however the default format FXYE should be used whenever possible. - :ref:`SaveMDWorkspaceToVTK <algm-SaveMDWorkspaceToVTK-v1>` and :ref:`LoadVTK <algm-LoadVTK-v1>` algorithms are now accessible from python. - :ref:`MergeRuns <algm-MergeRuns-v1>` will now merge workspaces with detector scans. -- :ref:`SetUncertainties <algm-SetUncertainties-v1>` now provides a "custom" mode, which lets the user specify both an arbitrary error value whose occurences are to be replaced in the input workspace, as well as the value to replace it with. +- :ref:`SetUncertainties <algm-SetUncertainties-v1>` now provides a "custom" mode, which lets the user specify both an arbitrary error value whose occurrences are to be replaced in the input workspace, as well as the value to replace it with. - :ref:`SimpleShapeMonteCarloAbsorption <algm-SimpleShapeMonteCarloAbsorption>` has been added to simplify sample environment inputs for MonteCarloAbsorption - :ref:`SumSpectra <algm-SumSpectra-v1>`: Fixed a bug where a wrong fallback value would be used in case of invalid values being set for min/max worspace index, and improved input validation for those properties. - :ref:`LoadBBY <algm-LoadBBY-v1>`: Fixed bug where the logManager did not work with sample_name, sample_aperture and source_aperture. Also added more information regarding the sample and the selected choppers. @@ -60,7 +60,7 @@ Improved - :ref:`MSDFit <algm-MSDFit>` now supports model selection. Currently has the option of 3 models: MsdGauss, MsdPeters and MsdYi. - :ref:`algm-LineProfile`: Fixed a bug which could cause crashes when the line extended over the right or bottom edge of a workspace. - :ref:`algm-Mean`: Added error messages if the data is not appropriate. -- :ref:`algm-LoadLiveData`: Fixed a bug affecting Live Data Processing in "Replace" mode. The bug meant that changes to Instrument position/rotation were overwitten by defaults on every load. Now fixed so that Instrument state is persistent across loads. +- :ref:`algm-LoadLiveData`: Fixed a bug affecting Live Data Processing in "Replace" mode. The bug meant that changes to Instrument position/rotation were overwritten by defaults on every load. Now fixed so that Instrument state is persistent across loads. - :ref:`CalMuonDetectorPhasees <algm-CalMuonDetectorPhases-v1>` now fits a cos instead of a sin function. Performance diff --git a/docs/source/release/v3.11.0/ui.rst b/docs/source/release/v3.11.0/ui.rst index ae12c0891cdf02860d6e3d27e374421a96fa03b6..f9be8348edde38cfd3c00be9fbf188803c591d1f 100644 --- a/docs/source/release/v3.11.0/ui.rst +++ b/docs/source/release/v3.11.0/ui.rst @@ -24,12 +24,12 @@ Workspace History Window :class: screenshot :align: right -- Algorithm proprties with long values are now shown in a shortened format both in this display and the log. The full history is still retained, and genereated python scripts will still work as before. +- Algorithm proprties with long values are now shown in a shortened format both in this display and the log. The full history is still retained, and generated python scripts will still work as before. Custom Interfaces ################# -- General > Multi dataset fitting interface and the general fitting dock now display the status string returned by the `Fit` algorithm. If an error occured during fitting it will be reported in this string. +- General > Multi dataset fitting interface and the general fitting dock now display the status string returned by the `Fit` algorithm. If an error occurred during fitting it will be reported in this string. - Indirect ILL calibration tab, deprecated since v3.9 is now dropped. - SANS > ISIS SANS v2 experimental interface has become available. It has basic reduction functionalities and makes use of the new reduction backend. diff --git a/docs/source/release/v3.12.0/diffraction.rst b/docs/source/release/v3.12.0/diffraction.rst index 9a97e27af40f309490fbabb27c2fe6042cefbf09..a23b10e188d15f0c46acf6a9605d97f1cf943160 100644 --- a/docs/source/release/v3.12.0/diffraction.rst +++ b/docs/source/release/v3.12.0/diffraction.rst @@ -53,7 +53,7 @@ Improvements - :ref:`ApplyDetectorScanEffCorr <algm-ApplyDetectorScanEffCorr>` applies the calibration file generated by :ref:`PowderDiffILLDetEffCorr <algm-PowderDiffILLDetEffCorr>` to detector scan workspaces. - :ref:`PowderDiffILLDetScanReduction <algm-PowderDiffILLDetScanReduction>` supports D2B and D20 (when doing a detector scan) powder diffraction reduction at the ILL. - :ref:`SaveGSS <algm-SaveGSS>` has been extended to allow user to specify GSAS general header, each bank's header and XYE decimal precision for SLOG. -- :ref:`SaveVulcanGSS <algm-SaveVulcanGSS>` has been moved to a workflow algorithm and largely rewritten by using recent change in histogram and Workspace2D. It is also improved such that there is no contraint on the number of spectra and number of various binning parameters on the workspace to be saved to a GSAS file for VULCAN. +- :ref:`SaveVulcanGSS <algm-SaveVulcanGSS>` has been moved to a workflow algorithm and largely rewritten by using recent change in histogram and Workspace2D. It is also improved such that there is no constraint on the number of spectra and number of various binning parameters on the workspace to be saved to a GSAS file for VULCAN. - :ref:`PDLoadCharacterizations <algm-PDLoadCharacterizations>` now allows for the azimuthal angles to be optionally specified in the file. Engineering Diffraction diff --git a/docs/source/release/v3.12.0/framework.rst b/docs/source/release/v3.12.0/framework.rst index 9f6b327512b07aae364f7cfe7504aadeadc7f190..e4d0fc9a4b5ce3b0a57a5c8766ae42fa0b8c43d8 100644 --- a/docs/source/release/v3.12.0/framework.rst +++ b/docs/source/release/v3.12.0/framework.rst @@ -84,7 +84,7 @@ Improved - The duration reported by a running algorithm now includes time spent for validation of properties and inputs. This fixes a discrepancy between observed and reported timings if validation is expensive, e.g., when checking if a file exists. More detailed timing information is now available when setting the log level to ``debug``. - The status of a fit in the fit window is now at the top of the of the dialog instead of the bottom. - Condition to check if a property is enabled when serializing. -- Workspace locking no longer prevents simple read operations required to display the workspace conext menu in Mantidplot. +- Workspace locking no longer prevents simple read operations required to display the workspace context menu in Mantidplot. - TableWorkspaces can now be converted to a Python dictionary by calling the ``table.toDict()`` function. - ``MultiFileProperty`` now accepts complex summation ranges for run numbers, such as ``111-113+115`` and ``111-115+123-132``. diff --git a/docs/source/release/v3.12.0/ui.rst b/docs/source/release/v3.12.0/ui.rst index 13cd8e3a1b42892aa5ba64c82f4e5c4f892d0c43..109be98e3530c14c4a807fab54d21dc9d5fb68f8 100644 --- a/docs/source/release/v3.12.0/ui.rst +++ b/docs/source/release/v3.12.0/ui.rst @@ -98,7 +98,7 @@ An error report will be sent to errorreports.mantidproject.org. It will contain - Operating System including version. - Mantid version including git Sha1. - System architecture. -- The date and time at which the crash occured. +- The date and time at which the crash occurred. - The mantid application you were using, currently this will always be mantidplot. - The default facility you have set. - The paraview version. diff --git a/docs/source/release/v3.12.1/index.rst b/docs/source/release/v3.12.1/index.rst index 8bd195ecd3b6f3a6d178ae7921f5dfeb30d5db55..0619f284f9e758282ef18d5b0fa4a509eed76f2b 100644 --- a/docs/source/release/v3.12.1/index.rst +++ b/docs/source/release/v3.12.1/index.rst @@ -13,7 +13,7 @@ The main changes are: * Several fixes to the Muon Analysis GUI, including to the results table and fit menu. * Several issues which caused mantid to crash have been fixed. -* Allowing the live listener funtionality to be used outside ISIS and from the python API. +* Allowing the live listener functionality to be used outside ISIS and from the python API. * Fixing the header for TOPAS files. * Removed version 1 of ``ReflectometryReductionOne`` and ``ReflectometryReductionOneAuto`` @@ -65,7 +65,7 @@ Summary of impact +-------+-----------------------------------------------------------------------------------------+---------------------------+--------------+ | 22194 | SofQW3 segfault no longer occurs | Indexing change | **medium** | +-------+-----------------------------------------------------------------------------------------+---------------------------+--------------+ -| 22190 | OSX Muon Interface data requirments fixed | GUI changes | **low** | +| 22190 | OSX Muon Interface data requirements fixed | GUI changes | **low** | +-------+-----------------------------------------------------------------------------------------+---------------------------+--------------+ | 22182 | Update mslice to fix issue with matplotlib < 1.5 | Update sha1 | **medium** | +-------+-----------------------------------------------------------------------------------------+---------------------------+--------------+ diff --git a/docs/source/release/v3.13.0/framework.rst b/docs/source/release/v3.13.0/framework.rst index 8cccf84295899d22a1f727f3f2c24d08f889825a..b17dc2272865c09aad13b45b49ceaf741ba6c71c 100644 --- a/docs/source/release/v3.13.0/framework.rst +++ b/docs/source/release/v3.13.0/framework.rst @@ -17,7 +17,7 @@ Stability --------- - We have introduced a Project Recovery mechanism for Mantidplot in order to be able to recover the lost state of the interface in the event of a crash or unexpected shutdown. There are more details in the UI section of the release notes. -- The error reporter can now catches hard crashes to desktop, allowing us to get more information on causes of hangs or crashes in Mantid. Since the last release error reports sent to us led directly to the identification of and fixes for 3 seperate bugs in Mantid. +- The error reporter can now catches hard crashes to desktop, allowing us to get more information on causes of hangs or crashes in Mantid. Since the last release error reports sent to us led directly to the identification of and fixes for 3 separate bugs in Mantid. - Mantid now handles poor network stability better when reading live data from the ISIS DAE. Mantid will now timeout after a couple of minutes of loss of network connectivity and remains responsive during this time. You can alter the duration of this timeout by adding a line to the mantid.user.properties file like: ``` diff --git a/docs/source/release/v3.13.0/sans.rst b/docs/source/release/v3.13.0/sans.rst index b5f40975a0053fbfe36cd116896193e23913850d..f7cd556735fb0349633b58bf5fd868b03a612d55 100644 --- a/docs/source/release/v3.13.0/sans.rst +++ b/docs/source/release/v3.13.0/sans.rst @@ -48,7 +48,7 @@ Bugfixes * Fixed a bug where save_format was not being specified if a user file was entered for a row. * Use gravity now defaulting to false. * MASK/TIME and TIME/MASK now both work in new backend. -* SET Centre/HAB command is now correctly parsed into a seperate variable to SET Centre. +* SET Centre/HAB command is now correctly parsed into a separate variable to SET Centre. Features Removed ################ diff --git a/docs/source/release/v3.14.0/diffraction.rst b/docs/source/release/v3.14.0/diffraction.rst index e9da71190301e10983557675396f750d8f65ce6d..80268902fdf209f08b2cdc8792677d52ed077fb1 100644 --- a/docs/source/release/v3.14.0/diffraction.rst +++ b/docs/source/release/v3.14.0/diffraction.rst @@ -8,16 +8,6 @@ Diffraction Changes .. warning:: **Developers:** Sort changes under appropriate heading putting new features at the top of the section, followed by improvements, followed by bug fixes. - -Powder Diffraction ------------------- -Improvements -############ -- Focusing in texture mode for Gem now properly saves - .gda files. -- Focusing on Gem now crops values that would be divided by very small or zero vanadium values -- Removed save_angles flag for Gem , as it was set by the texture mode -- Added save_all flag to Gem that is set to true by default, setting it to false disables the saving of .NXS files Improvements @@ -33,11 +23,6 @@ Improvements - Mask workspace option added to :ref:`WANDPowderReduction <algm-WANDPowderReduction>` -Bugfixes -######## -- multiple_scattering flag is now optional for Polaris focus when absorb_correction is true - - Single Crystal Diffraction -------------------------- @@ -59,6 +44,21 @@ Bugfixes Powder Diffraction ------------------ +Improvements +############ + +- Focusing in texture mode for Gem now properly saves .gda files. +- Focusing on Gem now crops values that would be divided by very small or zero vanadium values +- Removed save_angles flag for Gem , as it was set by the texture mode. +- Added save_all flag to Gem that is set to true by default, setting it to false disables the saving of .NXS files. +- Changed spline coefficient so that the default for long_mode on and long_mode off can be set separately. + +Bugfixes +######## + +- multiple_scattering flag is now optional for Polaris focus when absorb_correction is true. +- Normalisation is fixed in :ref:`SumOverlappingTubes <algm-SumOverlappingTubes>`, which was causing very low peak to background ratio for reduced D2B data. + New ### diff --git a/docs/source/release/v3.14.0/framework.rst b/docs/source/release/v3.14.0/framework.rst index a774d08d8c58cdcb360e23e1ac291ac7c72eedb3..b3be7fb40e2ad3f15e0335b2ecc29b75a2e5240b 100644 --- a/docs/source/release/v3.14.0/framework.rst +++ b/docs/source/release/v3.14.0/framework.rst @@ -12,7 +12,7 @@ Framework Changes Logging ------- -- We have changed the logging in Mantid to stop writing the a high level version of the log to a file. This had been causing numerous problems including inconsistent behaviour with multiple instances of Mantid, performance problems when logging at detailed levels, and excessive network usage in some scenarios. This does not change the rest of the logging that you see in the message display in Mantidplot or the console window. A warning message will appear if configuration for the removed componets of logging is found. +- We have changed the logging in Mantid to stop writing the high level version of the log to a file. This had been causing numerous problems including inconsistent behaviour with multiple instances of Mantid, performance problems when logging at detailed levels, and excessive network usage in some scenarios. This does not change the rest of the logging that you see in the message display in Mantidplot or the console window. A warning message will appear if configuration for the removed components of logging is found. - Associated with this we have also simplified the python methods used to control logging. @@ -39,7 +39,7 @@ Algorithms New Algorithms ############## - +- :ref:`MatchSpectra <algm-MatchSpectra>` is an algorithm that calculates factors to match all spectra to a reference spectrum. Improvements ############ @@ -49,8 +49,11 @@ Improvements - :ref:`SumOverlappingTubes <algm-SumOverlappingTubes>` will produce histogram data, and will not split the counts between bins by default. - :ref:`SumSpectra <algm-SumSpectra>` has an additional option, ``MultiplyBySpectra``, which controls whether or not the output spectra are multiplied by the number of bins. This property should be set to ``False`` for summing spectra as PDFgetN does. - :ref:`Live Data <algm-StartLiveData>` for events in PreserveEvents mode now produces workspaces that have bin boundaries which encompass the total x-range (TOF) for all events across all spectra. +- Bugfix in :ref:`ConvertToMatrixWorkspace <algm-ConvertToMatrixWorkspace>` with ``Workspace2D`` as the ``InputWorkspace`` not being cloned to the ``OutputWorkspace``. Added support for ragged workspaces. +- :ref:`RebinToWorkspace <algm-RebinToWorkspace>` now checks if the ``WorkspaceToRebin`` and ``WorkspaceToMatch`` already have the same binning. Added support for ragged workspaces. - :ref:`GroupWorkspaces <algm-GroupWorkspaces>` supports glob patterns for matching workspaces in the ADS. - :ref:`LoadSampleShape <algm-LoadSampleShape-v1>` now supports loading from binary .stl files. +- :ref:`MaskDetectorsIf <algm-MaskDetectorsIf>` now supports masking a workspace in addition to writing the masking information to a calfile. Bugfixes ######## @@ -61,7 +64,8 @@ Bugfixes - :ref:`FilterEvents <algm-FilterEvents-v1>` output workspaces now contain the goniometer. - Fixed an issue where if a workspace's history wouldn't update for some algorithms - Fixed a ``std::bad_cast`` error in :ref:`algm-LoadLiveData` when the data size changes. - +- :ref:`Fit <algm-Fit>` now applies the ties in correct order independently on the order they are set. If any circular dependencies are found Fit will give an error. +- Fixed a rare bug in :ref:`MaskDetectors <algm-MaskDetectors>` where a workspace could become invalidaded in Python if it was a ``MaskWorkspace``. Python diff --git a/docs/source/release/v3.14.0/indirect_inelastic.rst b/docs/source/release/v3.14.0/indirect_inelastic.rst index 38df5afb756980dfd8f7b7e03bc9df9d474fe99f..fd69d1e950e87059675838904f1d1992db9428fa 100644 --- a/docs/source/release/v3.14.0/indirect_inelastic.rst +++ b/docs/source/release/v3.14.0/indirect_inelastic.rst @@ -32,6 +32,8 @@ Improvements - When the InelasticDiffSphere, InelasticDiffRotDiscreteCircle, ElasticDiffSphere or ElasticDiffRotDiscreteCircle Fit Types are selected in the ConvFit Tab, the Q values are retrieved from the workspaces, preventing a crash when plotting a guess. +- The Plot Result buttons in MSDFit and F(Q)Fit are disabled after a Run when the result workspace only has one + data point to plot. - An option to skip the calculation of Monte Carlo Errors on the I(Q,t) Tab has been added. - During the calculation of Monte Carlo Errors, a progress bar is now shown. diff --git a/docs/source/release/v3.14.0/reflectometry.rst b/docs/source/release/v3.14.0/reflectometry.rst index b3544dcf202b8e297eaffbe61138bc372a471cf6..187922404c39af932bf13a0211d823c719a29652 100644 --- a/docs/source/release/v3.14.0/reflectometry.rst +++ b/docs/source/release/v3.14.0/reflectometry.rst @@ -28,6 +28,7 @@ New - Added algorithm :ref:`algm-CreateFloodWorkspace` which makes a workspace for subsequent flood corrections. - Added algorithm :ref:`algm-ApplyFloodWorkspace` which applies flood corrections to a workspace. - :ref:`FindReflectometryLines <algm-FindReflectometryLines-v2>` has been rewritten and updated to version 2. The new version finds a single line by a Gaussian fit. Version 1 has been deprecated and will be removed in a future release. +- Added algorithm :ref:`algm-ReflectometrySliceEventWorkspace` which slices an input event workspace into multiple slices, producing a histogram workspace suitable for use with :ref:`algm-ReflectometryReductionOneAuto`. Improved ######## @@ -44,6 +45,11 @@ Liquids Reflectometer - Default x-direction pixel range for the scaling factor calculation is now set to the full width of the detector as opposed to a restricted guess. +Magnetism Reflectometer +----------------------- + +- Added option to overwrite :literal:`DIRPIX` and :literal:`DANGLE0`. + ISIS Reflectometry Interface ---------------------------- diff --git a/docs/source/release/v3.14.0/sans.rst b/docs/source/release/v3.14.0/sans.rst index 4cc69c5cc03ce460f7fc88feaa2f92894a781a10..84bd51482f79a72e2bff93851864873852951891 100644 --- a/docs/source/release/v3.14.0/sans.rst +++ b/docs/source/release/v3.14.0/sans.rst @@ -12,7 +12,13 @@ New Improved ######## -* Updated workspace nameing scheme for new backend +* Updated workspace naming scheme for new backend. +* Added shortcut keys to copy/paste/cut rows of data. +* Added shortcut keys to delete or add rows. +* Added tabbing support to table. +* Added error notifications on a row by row basis. +* Updated file adding to prefix the instrument name +* Updated file finding to be able to find added runs withour instrument name prefix Bug fixes ######### diff --git a/docs/source/release/v3.14.0/ui.rst b/docs/source/release/v3.14.0/ui.rst index 30de3abc82009e5c54339997b68c3057eb22e8a6..6a760732e41cd8dacd0f5b9a2687e3305a2a25d4 100644 --- a/docs/source/release/v3.14.0/ui.rst +++ b/docs/source/release/v3.14.0/ui.rst @@ -22,16 +22,22 @@ Changes - Project Recovery will no longer save groups, this fixes an issue where it would cause crashes if you deleted a workspace from a group. - MantidPlot no longer checks for the existence of files in the "Recent Files" menu. Fixes case where files on slow mounted network drives can cause a lag on MantidPlot startup. - Workspaces now save locally as a number of how many workspaces have already been saved instead of workspace names +- Project Recovery will now attempt to recover multiple instances of mantid that are ran at the same time. Bugfixes ######## - Workspaces with a '#' in their name will no longer cause issues in the loading of a recovered project -- Project Recovery will actually recover fully cases where multiple workspaces were passed as a list to an algorithm (Fixes a known bug with GroupWorkspaces aswell) +- Project Recovery will actually recover fully cases where multiple workspaces were passed as a list to an algorithm (Fixes a known bug with GroupWorkspaces as well) - Project Recovery will now run normally when you select no or the recovery fails when recovering from a ungraceful exit. MantidPlot ---------- +Changes +####### + +- All File Browser dialog boxes will now (by default) display all valid file extensions as the first file filter. + BugFixes ######## diff --git a/docs/source/release/v3.6.0/sans.rst b/docs/source/release/v3.6.0/sans.rst index c676c923e16e06d69890d34f73ebeb3dbf2f849c..50ee30aa1c04abae7c6130bbe1dadf57148b1249 100644 --- a/docs/source/release/v3.6.0/sans.rst +++ b/docs/source/release/v3.6.0/sans.rst @@ -44,7 +44,7 @@ Extensions and Improvements for details - Handle cumulative sample logs for SANS: Adding files using the Add - Tabs GUI now ensures that cummulative sample log entries + Tabs GUI now ensures that cumulative sample log entries (``good_frames``, ``good_uah_log``, ...) are added up in a cumulative manner and not just concatenated and then sorted via time-stamp. diff --git a/docs/source/release/v3.7.1/reflectometry.rst b/docs/source/release/v3.7.1/reflectometry.rst index 66d61e7070587bcdf968fe61af06e8be1c3068aa..9654b27060b7784611489281c0bc7884aff408a3 100644 --- a/docs/source/release/v3.7.1/reflectometry.rst +++ b/docs/source/release/v3.7.1/reflectometry.rst @@ -48,9 +48,9 @@ ISIS Reflectometry (Polref) As a consequence there are some changes visible to users: a new progress bar that has been added to the *Search Runs* section, which shows the progress when transferring runs. The progress bar that existed before will only indicate the progress of processing that is in progress. A new section below the processing table has been added. It - summarises the algorithms used in the reduction and allows users to specify global options for them. Options to be applied to invidual rows can still + summarises the algorithms used in the reduction and allows users to specify global options for them. Options to be applied to individual rows can still be specified via the 'Options' column. User documentation has been updated accordingly. - The aim of this code refactoring is to have a General Data Processor Framework shared accross different technique areas that need to execute complex + The aim of this code refactoring is to have a General Data Processor Framework shared across different technique areas that need to execute complex batch-processing via DataProcessorAlgorithms. Standardisation across similar user interfaces will help avoid the maintenance effort involved in looking after specific user interfaces, making the wider project more robust to changes thanks to the introduction of fast, automated testing. Some of the target user interfaces that can benefit from this new design are SANS (both at ANSTO and ISIS), Powder at SNS and SCD at SNS. diff --git a/docs/source/release/v3.8.0/diffraction.rst b/docs/source/release/v3.8.0/diffraction.rst index b0ed134650284cc7919252d2aa4b8767ec6f830f..f377ad8488b91bf862dc7870f5b08c0f73aef95f 100644 --- a/docs/source/release/v3.8.0/diffraction.rst +++ b/docs/source/release/v3.8.0/diffraction.rst @@ -109,7 +109,7 @@ Powder Diffraction - :ref:`CalibrateRectangularDetectors <algm-CalibrateRectangularDetectors>` has been modified to output - ``.h5`` formated calibration files as well as the other versions it + ``.h5`` formatted calibration files as well as the other versions it already supported. - New algorithm :ref:`PDCalibration <algm-PDCalibration>` for diff --git a/docs/source/release/v3.8.0/direct_inelastic.rst b/docs/source/release/v3.8.0/direct_inelastic.rst index 1ccfefac1fb39833f2a7b630cb431a7346a72db1..e5b72ce1b7303eea57abc2c6a17806360ecfd28f 100644 --- a/docs/source/release/v3.8.0/direct_inelastic.rst +++ b/docs/source/release/v3.8.0/direct_inelastic.rst @@ -41,7 +41,7 @@ MLZ & TOFTOF - A workflow gui for TOFTOF data reduction (#17075). The gui is accessible through the ``Interfaces / Direct / DGS Reduction`` menu. - The first time the user is presented with a choice of facilites and instruments - + The first time the user is presented with a choice of facilities and instruments - choose MLZ / TOFTOF. The choice can be changed later from (any) reduction gui by ``Tools / Change instrument ...``. diff --git a/docs/source/release/v3.8.0/framework.rst b/docs/source/release/v3.8.0/framework.rst index e74e60b7f45311192fe5184a136904017fd6b04d..99ce3002366ca87df4600ddaf140d197c0ee8436 100644 --- a/docs/source/release/v3.8.0/framework.rst +++ b/docs/source/release/v3.8.0/framework.rst @@ -89,7 +89,7 @@ Improved now check if a Workspace with that name already exists in the ADS and gives the option to override it. -- :ref:`FindSXPeaks <algm-FindSXPeaks>`: Fixed a bug where peaks with an incorrect TOF would stored for some intrument geometries. +- :ref:`FindSXPeaks <algm-FindSXPeaks>`: Fixed a bug where peaks with an incorrect TOF would stored for some instrument geometries. - :ref:`LoadILL <algm-LoadILLTOF>` was renamed to :ref:`LoadILLTOF <algm-LoadILLTOF>` to better reflect what it does. The new algorithm can also handle cases where the monitor IDs are greater than the detector IDs. @@ -155,7 +155,7 @@ Performance CurveFitting ------------ -- Added a new minimizer belonging to the trust region family of algorithms developped for Mantid by the SCD +- Added a new minimizer belonging to the trust region family of algorithms developed for Mantid by the SCD Numerical Analysis Group at RAL. It has better performance characteristics compared to the existing minimizers especially when applied to the most difficult fitting problems. - Added new property `EvaluationType` to Fit algorithm. If set to "Histogram" and the input dataset diff --git a/docs/source/release/v3.8.0/indirect_inelastic.rst b/docs/source/release/v3.8.0/indirect_inelastic.rst index 32c7552d2daca1f4e126601db98235f37e5cf37d..7c229ff3bfb237f9c65db348ccbe881927ebfa23 100644 --- a/docs/source/release/v3.8.0/indirect_inelastic.rst +++ b/docs/source/release/v3.8.0/indirect_inelastic.rst @@ -75,7 +75,7 @@ VESUVIO ####### - Add the functionality for ties between internal parameters within each mass profile. This allows for the creation of a BivariateGaussian profile from the MultivariateGaussian profile. - Ties can be added within the defintion of the mass profile with the following: + Ties can be added within the definition of the mass profile with the following: *flags['masses'] = [{'value':1.0079, 'function': 'MultivariateGaussian', 'SigmaX': 5, 'SigmaY': 5, 'SigmaZ': 5, 'ties': 'SigmaX=SigmaY'}]* diff --git a/docs/source/release/v3.8.0/sans.rst b/docs/source/release/v3.8.0/sans.rst index 1112352317b67f929d693030a6cb1fa9b34feb28..c299721c1c7932d2a3e1fc7f127a5b423fd78e8b 100644 --- a/docs/source/release/v3.8.0/sans.rst +++ b/docs/source/release/v3.8.0/sans.rst @@ -10,7 +10,7 @@ Features - :ref:`CropToComponent <algm-CropToComponent>` allows for cropping a workspace to a list of component names. - Detect missing Bench_Rot for LARMOR and provide meaningful error message. -- Enable the CanSAS1D algorithms to handle geometry inforamtion. +- Enable the CanSAS1D algorithms to handle geometry information. - Add sort option to :ref:`CropToComponent <algm-CropToComponent>`. - Provide warning when users try to use a 2D reduction together with a merged reduction selection. - Processing of LOQ M4 in the SANS reduction was added. diff --git a/docs/source/release/v3.9.0/muon.rst b/docs/source/release/v3.9.0/muon.rst index 1f2785dd97f8707cb075f9bf61bf190b1ce2e9b1..6f98b13730795166f134effc2328a2ba98e5c70e 100644 --- a/docs/source/release/v3.9.0/muon.rst +++ b/docs/source/release/v3.9.0/muon.rst @@ -19,7 +19,7 @@ Muon Analysis - Fixed a bug where fitting data from "load current run" failed when the remote directory was not in Mantid's data search path. Now the remote directory for the relevant instrument is automatically added to this path when "load current run" is used. - Fixed a bug where stale plot guesses would be left on the graph in some situations. - Fixed a bug with load current run that meant it would be actually loading old data due to caching. Data from current run files is no longer cached behind the scenes. -- The default Plot Policy has been changed to **Use Previous Window**. This avoids the speed and stability issues that could occur with **Create New Window** once hundreds of graph windows had accumulated over several days of an experiement. +- The default Plot Policy has been changed to **Use Previous Window**. This avoids the speed and stability issues that could occur with **Create New Window** once hundreds of graph windows had accumulated over several days of an experiment. - Fixed a bug for the time averaging within the muon analysis. Now uses the time average function. diff --git a/docs/source/release/v3.9.1/index.rst b/docs/source/release/v3.9.1/index.rst index 321349ff821c1ebc21d6086cd222420bcd3472d0..9c53aceb58d45ab59358bd5ca651b2cb1257d67f 100644 --- a/docs/source/release/v3.9.1/index.rst +++ b/docs/source/release/v3.9.1/index.rst @@ -58,7 +58,7 @@ Summary of impact +-------+-----------------------------------------------------------------------------------+---------------------------------------------+--------------+ | 18833 | HKL axes now respect the non-orthogonal checkbox | Add check if button is in a checked state | **low** | +-------+-----------------------------------------------------------------------------------+---------------------------------------------+--------------+ -| 18857 | Diffraction reduction in diffonly mode does not crash fro OSIRIS | Only run OSIRIS-specific reduction | **low** | +| 18857 | Diffraction reduction in diffonly mode does not crash for OSIRIS | Only run OSIRIS-specific reduction | **low** | +-------+-----------------------------------------------------------------------------------+---------------------------------------------+--------------+ | 18865 | Correct behaviour when no transmission run is provided | Add check if runs are provided | **low** | +-------+-----------------------------------------------------------------------------------+---------------------------------------------+--------------+ diff --git a/docs/source/techniques/DirectILL.rst b/docs/source/techniques/DirectILL.rst index 781e62e257f91828217d4156966910d9a65e53b8..1b829460653086b10ebcb64e82516477fd88b323 100644 --- a/docs/source/techniques/DirectILL.rst +++ b/docs/source/techniques/DirectILL.rst @@ -44,6 +44,8 @@ Some algorithm properties have the word 'AUTO' in their default value. This mean Reduction basics ================ +.. include:: ../usagedata-note.txt + A very basic reduction would include a vanadium reference and a sample and follow the steps: #. Load vanadium data. @@ -58,44 +60,89 @@ A very basic reduction would include a vanadium reference and a sample and follo #. Reduce the data applying vanadium calibration coefficients and diagnostics mask. -These steps would translate to something like the following simple Python script: +On instruments like IN4 and IN6, these steps would translate to something like the following simple Python script: -.. code-block:: python +.. testsetup:: BasicIN4Reduction - # Add a temporary data search directory. - mantid.config.appendDataSearchDir('/data/') + config['default.facility'] = 'ILL' + config['default.instrument'] = 'IN4' +.. testcode:: BasicIN4Reduction + + # Uncomment to add a temporary data search directory. + #mantid.config.appendDataSearchDir('/data/') + # Vanadium DirectILLCollectData( - Run='0100-0109', + Run='ILL/IN4/085801-085802.nxs', OutputWorkspace='vanadium', OutputEPPWorkspace='vanadium-epps', # Elastic peak positions. OutputRawWorkspace='vanadium-raw' # 'Raw' data for diagnostics. ) - DirectILLIntegrateVanadium( InputWorkspace='vanadium', OutputWorkspace='integrated', EPPWorkspace='vanadium-epps' ) - DirectILLDiagnostics( InputWorkspace='vanadium-raw', OutputWorkspace='diagnostics', EPPWorkspace='vanadium-epps', - RawWorkspace='vanadium-raw' ) - # Sample DirectILLCollectData( - Run='0201+0205+0209-0210', + Run='ILL/IN4/087294+087295.nxs', OutputWorkspace='sample' ) + DirectILLReduction( + InputWorkspace='sample', + OutputWorkspace='SofQW', + IntegratedVanadiumWorkspace='integrated', + DiagnosticsWorkspace='diagnostics' + ) + SofQW = mtd['SofQW'] + qAxis = SofQW.readX(0) # Vertical axis + eAxis = SofQW.getAxis(1) # Horizontal axis + print('S(Q,W): Q range: {:.3}...{:.3}A; W range {:.3}...{:.3}meV'.format( + qAxis[0], qAxis[-1], eAxis.getMin(), eAxis.getMax())) + +Output: + +.. testoutput:: BasicIN4Reduction + + S(Q,W): Q range: 0.0...9.08A; W range -93.6...7.55meV +The basic reduction for IN5 differs slightly with regards to the diagnostics step. In this case, the "raw" workspace is not needed, and it is not necessary to pass the EPP workspace to :ref:`algm-DirectILLDiagnostics`: + +.. code-block:: python + + # Uncomment to add a temporary data search directory. + #mantid.config.appendDataSearchDir('/data/') + + # Vanadium + DirectILLCollectData( + Run='085801-085802', + OutputWorkspace='vanadium', + OutputEPPWorkspace='vanadium-epps', # Elastic peak positions. + ) + DirectILLIntegrateVanadium( + InputWorkspace='vanadium', + OutputWorkspace='integrated', + EPPWorkspace='vanadium-epps' + ) + DirectILLDiagnostics( + InputWorkspace='vanadium', + OutputWorkspace='diagnostics', + ) + # Sample + DirectILLCollectData( + Run='087294+087295', + OutputWorkspace='sample' + ) DirectILLReduction( InputWorkspace='sample', OutputWorkspace='SofQW', - IntegratedVanadiumWorkspace='integrated' + IntegratedVanadiumWorkspace='integrated', DiagnosticsWorkspace='diagnostics' ) @@ -107,18 +154,17 @@ Every ``DirectILL`` algorithm has an *OutputWorkspace* property which provides t .. code-block:: python ... - # Vanadium DirectILLCollectData( ... - OutputEPPWorkspace='vanadium-epps' # This workspace... + OutputEPPWorkspace='epps' # This workspace... ) DirectILLIntegrateVanadium( ... - EPPWorkspace='vanadium-epps' # ...is needed here... + EPPWorkspace='epps' # ...is needed here... ) DirectILLDiagnostics( ... - EPPWorkspace='vanadium-epps' # ...and here. + EPPWorkspace='epps' # ...and here. ) ... @@ -217,40 +263,40 @@ A more complete reduction example would include corrections for self-shielding: #. Reduce the data applying vanadium calibration coefficients and diagnostics mask. -The above workflow would translate to this kind of Python script: +The above workflow would translate to this kind of Python script for IN4 and IN6: -.. code-block:: python +.. testsetup:: SelfShieldingReduction - # Add a temporary data search directory. - mantid.config.appendDataSearchDir('/data/') + config['default.facility'] = 'ILL' + config['default.instrument'] = 'IN4' +.. testcode:: SelfShieldingReduction + + # Uncomment to add a temporary data search directory. + #mantid.config.appendDataSearchDir('/data/') + # Vanadium DirectILLCollectData( - Run='0100-0109', + Run='ILL/IN4/085801-085801.nxs', OutputWorkspace='vanadium', OutputEPPWorkspace='vanadium-epps', # Elastic peak positions. OutputRawWorkspace='vanadium-raw' # 'Raw' data for diagnostics. ) - DirectILLIntegrateVanadium( InputWorkspace='vanadium', OutputWorkspace='integrated', EPPWorkspace='vanadium-epps' ) - DirectILLDiagnostics( - InputWorkspace='vanadium-raw', + InputWorkspace='vanadium-raw', # For IN5, 'vanadium' could be used OutputWorkspace='diagnostics', - EPPWorkspace='vanadium-epps', - RawWorkspace='vanadium-raw' + EPPWorkspace='vanadium-epps', # Can be omitted for IN5 ) - # Sample DirectILLCollectData( - Run='0201+0205+0209-0210', + Run='ILL/IN4/087294+087295.nxs', OutputWorkspace='sample', ) - geometry = { 'Shape': 'FlatPlate', 'Width': 4.0, @@ -260,8 +306,8 @@ The above workflow would translate to this kind of Python script: 'Angle': 45.0 } material = { - 'ChemicalFormula': 'Ni Cr Fe', - 'SampleNumberDensity': 0.09 + 'ChemicalFormula': 'Cd S', + 'SampleNumberDensity': 0.01 } SetSample( InputWorkspace='sample', @@ -270,60 +316,73 @@ The above workflow would translate to this kind of Python script: ) DirectILLSelfShielding( InputWorkspace='sample', - OutputWorkspace='corrections' + OutputWorkspace='corrections', + NumberOfSimulatedWavelengths=10 ) DirectILLApplySelfShielding( InputWorkspace='sample', OutputWorkspace='sample-corrected', SelfShieldingCorrectionWorkspace='corrections', ) - DirectILLReduction( InputWorkspace='sample-corrected', OutputWorkspace='SofQW', - IntegratedVanadiumWorkspace='integrated' + IntegratedVanadiumWorkspace='integrated', DiagnosticsWorkspace='diagnostics' ) + SofQW = mtd['SofQW'] + qAxis = SofQW.readX(0) # Vertical axis + eAxis = SofQW.getAxis(1) # Horizontal axis + print('S(Q,W): Q range: {:.3}...{:.3}A; W range {:.3}...{:.3}meV'.format( + qAxis[0], qAxis[-1], eAxis.getMin(), eAxis.getMax())) + +Output: + +.. testoutput:: SelfShieldingReduction + + S(Q,W): Q range: 0.0...9.08A; W range -93.6...7.55meV Workspace compatibility ======================= -Mantid can be picky with binning when doing arithmetics between workspaces. This is an issue for the time-of-flight instruments at ILL as the time axis needs to be corrected to correspond to a physical flight distance. Even thought data is recorded with the same nominal wavelength, the actual value written in the NeXus files may differ between runs. Incident energy calibration further complicates matters. As the correction to the time-of-flight axis depends on the wavelength, two datasets loaded into Mantid with :ref:`algm-DirectILLCollectData` may have slightly different time-of-flight axis. This prevents arithmetics between the workspaces. The situation is most often encountered between sample and the corresponding empty container. +Mantid can be picky with binning when doing arithmetics between workspaces. This is an issue for the time-of-flight instruments at ILL as the time axis needs to be corrected to correspond to a physical flight distance. Even thought data is recorded with the same nominal wavelength, the actual value written in the NeXus files may differ between runs. Incident energy calibration further complicates matters. As the correction to the time-of-flight axis depends on the wavelength, two datasets loaded into Mantid with :ref:`algm-DirectILLCollectData` may have slightly different time-of-flight axis. This prevents arithmetics between the workspaces. The situation is most often encountered between a sample and the corresponding empty container. To alleviate the situation, the output workspaces of :ref:`algm-DirectILLCollectData` can be forced to use the same wavelength. The following Python script shows how to propagate the calibrated incident energy from the first loaded workspace into the rest: -.. code-block:: python +.. testsetup:: SampleContainerCompatibility + + config['default.facility'] = 'ILL' + config['default.instrument'] = 'IN4' + +.. testcode:: SampleContainerCompatibility + # Sample DirectILLCollectData( - Run='0100-0109', - OutputWorkspace='sample1', + Run='ILL/IN4/087294-087295.nxs', + OutputWorkspace='sample', OutputIncidentEnergyWorkspace='Ei' # Get a common incident energy. ) - # Empty container. DirectILLCollectData( - Run='0201-0205', + Run='ILL/IN4/087306-087309.nxs', OutputWorkspace='container', - IncidentEnergyWorkspace='Ei' # Empty container should have same TOF binning. - ) - - # More samples with same nominal wavelength and container as 'sample1'. - runs = ['0110-0119', '0253-0260'] - index = 1 - for run in runs: - DirectILLCollectData( - Run=run, - OutputWorkspace='sample{}'.format(index), - IncidentEnergyWorkspace='Ei' - ) - index += 1 - - # The empty container is now compatible with all the samples. + IncidentEnergyWorkspace='Ei' # Ensure same TOF binning. + ) + x_sample = mtd['sample'].readX(0) + x_container = mtd['container'].readX(0) + print("Sample's TOF axis starts at {:.4}mus, container's at {:.4}mus".format( + x_sample[0], x_container[0])) + +Output: + +.. testoutput:: SampleContainerCompatibility + + Sample's TOF axis starts at 974.8mus, container's at 974.8mus -Container background subtraction -================================ +Container subtraction +===================== -The container background subtraction is done perhaps a bit counterintuitively in :ref:`algm-DirectILLApplySelfShielding`. At the moment the self-shielding corrections and the empty container data do not have much to do with each other but this may change in the future if the so called Paalman-Pings corrections are used. +The container subtraction is done perhaps a bit counterintuitively in :ref:`algm-DirectILLApplySelfShielding`. At the moment the self-shielding corrections and the empty container data do not have much to do with each other but this may change in the future if the so called Paalman-Pings corrections are used. With empty container data, the steps to reduce the experimental data might look like this: @@ -349,138 +408,132 @@ With empty container data, the steps to reduce the experimental data might look A corresponding Python script follows. -.. code-block:: python +.. testsetup:: ContainerSubtraction - mantid.config.appendDataSearchDir('/data/') + config['default.facility'] = 'ILL' + config['default.instrument'] = 'IN4' + +.. testcode:: ContainerSubtraction + # Uncomment to add a temporary data search directory. + #mantid.config.appendDataSearchDir('/data/') + # Vanadium DirectILLCollectData( - Run='0100-0109', + Run='ILL/IN4/085801-085802.nxs', OutputWorkspace='vanadium', OutputEPPWorkspace='vanadium-epps', - OutputRawWorkspace='vanadium-raw' + OutputRawWorkspace='vanadium-raw' # Can be omitted for IN5 ) - DirectILLIntegrateVanadium( InputWorkspace='vanadium', OutputWorkspace='integrated', EPPWorkspace='vanadium-epps' ) - DirectILLDiagnostics( - InputWorkspace='vanadium-raw', + InputWorkspace='vanadium-raw', # IN5 can use 'vanadium' OutputWorkspace='diagnostics', - EPPWorkspace='vanadium-epps', - RawWorkspace='vanadium-raw' + EPPWorkspace='vanadium-epps', # Can be omitted for IN5 ) - # Sample DirectILLCollectData( - Run='0201+0205+0209-0210', + Run='ILL/IN4/087294+087295.nxs', OutputWorkspace='sample', - OutputIncidentEnergyWorkspace='Ei' + OutputIncidentEnergyWorkspace='Ei' # For empty container ) - # Container DirectILLCollectData( - Run='0333-0335', + Run='ILL/IN4/087306-087309.nxs', OutputWorkspace='container', - IncidentEnergyWorkspace='Ei' - ) - - # Container self-shielding. - # Geometry XML allows for very complex geometries. - containerShape = """ - <hollow-cylinder id="inner-ring"> - <centre-of-bottom-base x="0.0" y="-0.04" z="0.0" /> - <axis x="0.0" y="1.0" z="0.0" /> - <inner-radius val="0.017" /> - <outer-radius val="0.018" /> - <height val="0.08" /> - </hollow-cylinder> - <hollow-cylinder id="outer-ring"> - <centre-of-bottom-base x="0.0" y="-0.04" z="0.0" /> - <axis x="0.0" y="1.0" z="0.0" /> - <inner-radius val="0.02" /> - <outer-radius val="0.021" /> - <height val="0.08" /> - </hollow-cylinder> - <algebra val="inner-ring : outer-ring" /> - """ - geometry = { - 'Shape': 'CSG', - 'Value': containerShape - } - material = { - 'ChemicalFormula': 'Al', - 'SampleNumberDensity': 0.09 - } - SetSample( - InputWorkspace='container', - Geometry=geometry, - Material=material - ) - DirectILLSelfShielding( - InputWorkspace='container', - OutputWorkspace='container-corrections' + IncidentEnergyWorkspace='Ei' # Ensure common TOF axis ) - DirectILLApplySelfShielding( - InputWorkspace='container', - OutputWorkspace='container-corrected', - SelfShieldingCorrectionWorkspace='container-corrections', - ) - # Sample self-shielding and container subtraction. geometry = { 'Shape': 'HollowCylinder', - 'Height': 8.0, - 'InnerRadius': 1.8, - 'OuterRadium': 2.0, + 'Height': 4.0, + 'InnerRadius': 1.9, + 'OuterRadius': 2.0, 'Center': [0.0, 0.0, 0.0] } material = { - 'ChemicalFormula': 'C2 O D6', - 'SampleNumberDensity': 0.1 + 'ChemicalFormula': 'Cd S', + 'SampleNumberDensity': 0.01 } SetSample('sample', geometry, material) DirectILLSelfShielding( InputWorkspace='sample', - OutputWorkspace='sample-corrections' + OutputWorkspace='sample-corrections', + NumberOfSimulatedWavelengths=10 ) DirectILLApplySelfShielding( InputWorkspace='sample', OutputWorkspace='sample-corrected', SelfShieldingCorrectionWorkspace='sample-corrections', - EmptyContainerWorkspace='container-corrected' + EmptyContainerWorkspace='container' # Also subtract container ) - DirectILLReduction( InputWorkspace='sample-corrected', OutputWorkspace='SofQW', - IntegratedVanadiumWorkspace='integrated' + IntegratedVanadiumWorkspace='integrated', DiagnosticsWorkspace='diagnostics' ) + SofQW = mtd['SofQW'] + qAxis = SofQW.readX(0) # Vertical axis + eAxis = SofQW.getAxis(1) # Horizontal axis + print('S(Q,W): Q range: {:.3}...{:.3}A; W range {:.3}...{:.3}meV'.format( + qAxis[0], qAxis[-1], eAxis.getMin(), eAxis.getMax())) + +Output: + +.. testoutput:: ContainerSubtraction + + S(Q,W): Q range: 0.0...9.08A; W range -93.6...7.55meV Interpolation of container data to different temperatures --------------------------------------------------------- Sometimes the empty container is not measured at all the experiment's temperature points. One can use Mantid's workspace arithmetics to perform simple linear interpolation in temperature: -.. code-block:: python +.. testsetup:: ContainerInterpolation + + config['default.facility'] = 'ILL' + config['default.instrument'] = 'IN4' +.. testcode:: ContainerInterpolation + + import numpy + DirectILLCollectData( + Run='ILL/IN4/087283-087290.nxs', + OutputWorkspace='sample_50K', + OutputIncidentEnergyWorkspace='E_i' + ) + DirectILLCollectData( + Run='ILL/IN4/087306-087309.nxs', + OutputWorkspace='container_1.5K', + IncidentEnergyWorkspace='E_i' + ) + DirectILLCollectData( + Run='ILL/IN4/087311-087314.nxs', + OutputWorkspace='container_100K', + IncidentEnergyWorkspace='E_i' + ) # Container measurement temperatures. - T0 = 3.0 - T1 = 250.0 + T0 = 1.5 + T1 = 100.0 DT = T1 - T0 # Target sample temperature. - Ts = 190.0 + Ts = 50.0 # Linear interpolation. - container_190 = (T1 - Ts) / DT * mtd['container_3'] + (Ts - T0) / DT * mtd['container_250'] + container_50K = (T1 - Ts) / DT * mtd['container_1.5K'] + (Ts - T0) / DT * mtd['container_100K'] + T_sample_logs = container_50K.run().getProperty('sample.temperature').value + mean_T = numpy.mean(T_sample_logs) + print('Note, that the mean temperature from the sample logs is {:.4}K, a bit off.'.format(mean_T)) - DirectILLApplySelfShielding( - InputWorkspace='sample', - EmptyContainerWorkspace=container_190 - ) +Output: + +.. testoutput:: ContainerInterpolation + + Note, that the mean temperature from the sample logs is 51.0K, a bit off. As usual, care should be taken when extrapolating the container data outside the measured range. @@ -516,263 +569,128 @@ Lets put it all together into a complex Python script. The script below reduces * Vanadium reference. -* An empty vanadium container. +* Sample measured at 1.5 and 50K. - * Same shape as the sample container. - * Complex shape: has to be given as XML. + * Share time-independent backgrounds from the measurement at 1.5K. -* Sample measured at wavelength 1 at 50, 100 and 150K. +* Empty container measured at 1.5 and 100K. - * Share time-independent backgrounds from the measurement at 50K. + * Need to interpolate to 50K. -* Empty container measured at wavelength 1 at 50 and 150K. +.. testsetup:: FullExample - * Need to interpolate to 150K. + config['default.facility'] = 'ILL' + config['default.instrument'] = 'IN4' -* Sample measured at wavelength 2 at 50, 100 and 150K. - - * Share time-independent backgrounds from the measurement at 50K. - -* Empty container measured at wavelength 2. - - - -.. code-block:: python - - mantid.config.appendDataSearchDir('/data/') - - # Gather dataset information. - containerRuns = '96+97' - vanadiumRuns = '100-103' - # Samples at 50K, 100K and 150K. - # Wavelength 1 - containerRuns1 = { - 50: '131-137', - 150: '138-143' - } - runs1 = { - 50: '105+107-110', - 100: '112-117', - 150: '119-123+125' - } - # Wavelength 2 - containerRun2 = '166-170' - runs2 = { - 50: '146+148+150', - 100: '151-156', - 150: '160-165' - } - - # Vanadium & vanadium container. +.. testcode:: FullExample + # Uncomment to add a temporary data search directory. + #mantid.config.appendDataSearchDir('/data/') + + # Vanadium DirectILLCollectData( - Run=vanadiumRuns, + Run='ILL/IN4/085801-085802.nxs', OutputWorkspace='vanadium', - OutputEPPWorkspace='vanadium-epp', - OutputRawWorkspace='vanadium-raw', - OutputIncidentEnergyWorkspace='vanadium-Ei' # Use for container + OutputEPPWorkspace='vanadium-epps', + OutputRawWorkspace='vanadium-raw' # Can be omitted for IN5 ) - + DirectILLIntegrateVanadium( + InputWorkspace='vanadium', + OutputWorkspace='integrated', + EPPWorkspace='vanadium-epps' + ) + DirectILLDiagnostics( + InputWorkspace='vanadium-raw', # IN5 can use 'vanadium' + OutputWorkspace='diagnostics', + EPPWorkspace='vanadium-epps', # Can be omitted for IN5 + ) + # Samples DirectILLCollectData( - Run=containerRuns, - OutputWorkspace='vanadium-container', - IncidentEnergyWorkspace='vanadium-Ei' - ) - - containerShape = """ - <hollow-cylinder id="inner-ring"> - <centre-of-bottom-base x="0.0" y="-0.04" z="0.0" /> - <axis x="0.0" y="1.0" z="0.0" /> - <inner-radius val="0.017" /> - <outer-radius val="0.018" /> - <height val="0.08" /> - </hollow-cylinder> - <hollow-cylinder id="outer-ring"> - <centre-of-bottom-base x="0.0" y="-0.04" z="0.0" /> - <axis x="0.0" y="1.0" z="0.0" /> - <inner-radius val="0.02" /> - <outer-radius val="0.021" /> - <height val="0.08" /> - </hollow-cylinder> - <algebra val="inner-ring : outer-ring" /> - """ - containerGeometry = { - 'CSG': containerShape - } - containerMaterial = { - 'ChemicalFormula': 'Al', - 'SampleNumberDensity': 0.1 - } - SetSample('vanadium-container', containerGeometry, containerMaterial) - DirectILLSelfShielding( - InputWorkspace='vanadium-container', - OutputWorkspace='vanadium-container-self-shielding' + Run='ILL/IN4/087294+087295.nxs', + OutputWorkspace='sample_1.5K', + OutputIncidentEnergyWorkspace='Ei', # For other datasets + OutputFlatBkgWorkspace='bkgs' # For sample at 50K ) - DirectILLApplySelfShielding( - InputWorkspace='vanadium-container', - OutputWorkspace='vanadium-container-corrected' - SelfShieldingCorrectionWorkspace='vanadium-container-self-shielding' + DirectILLCollectData( + Run='ILL/IN4/087283-087290.nxs', + OutputWorkspace='sample_50K', + IncidentEnergyWorkspace='Ei', # Ensure common TOF axis + FlatBkgWorkspace='bkgs' # Use flat backgrounds from 1.5K ) - - sampleGeometry = { + # Containers + DirectILLCollectData( + Run='ILL/IN4/087306-087309.nxs', + OutputWorkspace='container_1.5K', + IncidentEnergyWorkspace='Ei' # Ensure common TOF axis + ) + DirectILLCollectData( + Run='ILL/IN4/087311-087314.nxs', + OutputWorkspace='container_100K', + IncidentEnergyWorkspace='Ei' # Ensure common TOF axis + ) + # Sample self-shielding and container subtraction. + geometry = { 'Shape': 'HollowCylinder', - 'Height': 8.0, - 'InnerRadius': 1.8, - 'OuterRadium': 2.0, + 'Height': 4.0, + 'InnerRadius': 1.9, + 'OuterRadius': 2.0, 'Center': [0.0, 0.0, 0.0] } - vanadiumMaterial = { - 'ChemicalFormula': 'V', - 'SampleNumberDensity': 0.15 + material = { + 'ChemicalFormula': 'Cd S', + 'SampleNumberDensity': 0.01 } - SetSample('vanadium', sampleGeometry, vanadiumMaterial) + SetSample('sample_1.5K', geometry, material) + SetSample('sample_50K', geometry, material) + # Self-shielding corrections need to be calculated only once. DirectILLSelfShielding( - InputWorkspace='vanadium', - OutputWorkspace='vanadium-self-shielding' + InputWorkspace='sample_1.5K', + OutputWorkspace='corrections', + NumberOfSimulatedWavelengths=10 ) DirectILLApplySelfShielding( - InputWorkspace='vanadium', - OutputWorkspace='vanadium-corrected', - SelfShieldingCorrectionWorkspace='vanadium-self-shielding', - EmptyContainerWorkspace='vanadium-container-corrected' - ) - - DirectILLIntegrateVanadium( - InputWorkspace='vanadium-corrected', - OutputWorkspace='vanadium-calibration', - EPPWorkspace='vanadium-epp' - ) - - diagnosticsResult = DirectILLDiagnoseDetectors( - InputWorkspace='vanadium-raw', - OutputWorkspace='mask', - EPPWorkspace='vanadium-epp', - OutputReportWorkspace='diagnostics-report' - ) - - # Sample and container at wavelength 1. - - DirectILLCollectData( - Run=runs1[50], - OutputWorkspace='run1-50K', - OutputIncidentEnergyWorkspace='Ei1', - OutputFlatBkgWorkspace='bkg1-50K' - ) - - DirectILLCollectData( - Run=containerRuns1[50], - OutputWorkspace='container1-50K', - IncidentEnergyWorkspace='Ei1' + InputWorkspace='sample_1.5K', + OutputWorkspace='corrected_1.5K', + SelfShieldingCorrectionWorkspace='corrections', + EmptyContainerWorkspace='container_1.5K' ) - - SetSample('container1-50K', containerGeometry, containerMaterial) - DirectILLSelfShielding( - InputWorkspace='container1-50K', - OutputWorkspace='container1-self-shielding' + # Need to interpolate container to 50K + T0 = 1.5 + T1 = 100.0 + DT = T1 - T0 + Ts = 50.0 # Target T + container_50K = (T1 - Ts) / DT * mtd['container_1.5K'] + (Ts - T0) / DT * mtd['container_100K'] + DirectILLApplySelfShielding( + InputWorkspace='sample_50K', + OutputWorkspace='corrected_50K', + SelfShieldingCorrectionWorkspace='corrections', + EmptyContainerWorkspace=container_50K ) - - DirectILLCollectData( - Run=containerRuns1[150], - OutputWorkspace='container1-150K', - IncidentEnergyWorkspace='Ei1' + DirectILLReduction( + InputWorkspace='corrected_1.5K', + OutputWorkspace='SofQW_1.5K', + IntegratedVanadiumWorkspace='integrated', + DiagnosticsWorkspace='diagnostics' ) - - interpolated = 0.5 * (mtd['container1-50K'] + mtd['container1-150K']) - RenameWorkspace(interpolated, 'container1-100K') - - for T in [50, 100, 150]: - DirectILLApplySelfShielding( - InputWorkspace='container1-{}K'.format(T), - OutputWorkspace='container1-{}K-corrected'.format(T), - SelfShieldingCorrectionWorkspace='container1-self-shielding' - ) - - sampleMaterial = { - 'ChemicalFormula': 'Fe 2 O 3', - 'SampleNumberDensity': 0.23 - } - SetSample('run1-50K', sampleGeometry, sampleMaterial) - DirectILLSelfShielding( - InputWorkspace='run1-50K', - OutputWorkspace='run1-self-shielding', - ) - - for T in runs1: - if T != 50: - # 50K data has been loaded already. - DirectILLCollectData( - Run=runs1[T], - OutputWorkspace='run1-{}K'.format(T), - IncidentEnergyWorkspace='Ei1', - FlatBkgWorkspace='bkg1-50K' - ) - DirectILLApplySelfShielding( - InputWorkspace='run1-{}K'.format(T), - OutputWorkspace='run1-{}K-corrected'.format(T), - SelfShieldingCorrectionWorkspace='run1-self-shielding', - EmptyContainerWorkspace='container1-{}K-corrected'.format(T) - ) - DirectILLReduction( - InputWorkspace='run1-{}K-corrected'.format(T), - OutputWorkspace='SofQW1-{}K'.format(T), - IntegratedVanadiumWorkspace='vanadium-calibration', - DiagnosticsWorkspace='mask' - ) - SaveNexus('SofQW1-{}K'.format(T), '/data/output2-{}.nxs'.format(T)) - - # Sample and container at wavelength 2. - - DirectILLCollectData( - Run=runs2[50], - OutputWorkspace='run2-50K', - OutputIncidentEnergyWorkspace=Ei2', - OutputFlatBkgWorkspace='bgk2-50K' + DirectILLReduction( + InputWorkspace='corrected_50K', + OutputWorkspace='SofQW_50K', + IntegratedVanadiumWorkspace='integrated', + DiagnosticsWorkspace='diagnostics' ) + outputs = ['SofQW_1.5K', 'SofQW_50K'] + for output in outputs: + SofQW = mtd[output] + qAxis = SofQW.readX(0) # Vertical axis + eAxis = SofQW.getAxis(1) # Horizontal axis + print('{}: Q range: {:.3}...{:.3}A; W range {:.3}...{:.3}meV'.format( + output, qAxis[0], qAxis[-1], eAxis.getMin(), eAxis.getMax())) - DirectILLCollectData( - Run=containerRun2, - OutputWorkspace='container2', - IncidentEnergyWorkspace='Ei2' - ) +Output: - SetSample('container2', containerGeometry, containerMaterial) - DirectILLSelfShielding( - InputWorkspace='container2', - OutputWorkspace='container2-self-shielding' - ) - DirectILLApplySelfShielding( - InputWorkspace='container2', - OutputWorkspace='container2-corrected', - SelfShieldingCorrectionWorkspace='container2-self-shielding' - ) +.. testoutput:: FullExample - SetSample('run2-50K', sampleGeometry, sampleMaterial) - DirectILLSelfShielding( - InputWorkspace='run2-50K', - OutputWorkspace='run2-self-shielding' - ) - - for T in runs2: - if T != 50: - # 50K data has been loaded already. - DirectILLCollectData( - Run=runs2[T] - OuputWorkspace='run2-{}K'.format(T), - IncidentEnergyWorkspace='Ei2', - FlatBkgWorkspace='bkg2-50K - ) - DirectILLApplySelfShielding( - InputWorkspace='run2-{}K'.format(T), - OutputWorkspace='run2-{}K-corrected'.format(T), - SelfShieldingCorrectionWorkspace='run2-self-shielding', - EmptyContainerWorkspace='container2' - ) - DirectILLReduction( - InputWorkspace='run2-{}K-corrected'.format(T), - OutputWorkspace='SofQW2-{}K'.format(T), - IntegratedVanadiumWorkspace='vanadium-calibration', - DiagnosticsWorkspace='mask' - ) - SaveNexus('SofQW2-{}K'.format(T), '/data/output2-{}.nxs'.format(T)) + SofQW_1.5K: Q range: 0.0...9.08A; W range -93.6...7.55meV + SofQW_50K: Q range: 0.0...9.08A; W range -93.6...7.55meV .. categories:: Techniques diff --git a/docs/source/techniques/ISISPowder-HRPD-v1.rst b/docs/source/techniques/ISISPowder-HRPD-v1.rst index d2f48075d072debd28c5ab6edafb949d3e9ba4f1..381c38dbc9d7cc37944aa9e72d934493d8b3b867 100644 --- a/docs/source/techniques/ISISPowder-HRPD-v1.rst +++ b/docs/source/techniques/ISISPowder-HRPD-v1.rst @@ -253,7 +253,7 @@ The full path to the YAML configuration file. This file is described in detail here: :ref:`configuration_files_isis-powder-diffraction-ref`. It is recommended to set this parameter at object creation instead of when -executing a method as it will warn if any parameters are overriden in +executing a method as it will warn if any parameters are overridden in the scripting window. *Note: This should be the full path to the file including extension* diff --git a/docs/source/techniques/ISISPowder-Pearl-v1.rst b/docs/source/techniques/ISISPowder-Pearl-v1.rst index f9b19bb3caa43c99c9d28be5c15df66209cf95f7..ee71f57ca966176d53511f2f2f6bd3eb7013df02 100644 --- a/docs/source/techniques/ISISPowder-Pearl-v1.rst +++ b/docs/source/techniques/ISISPowder-Pearl-v1.rst @@ -168,7 +168,7 @@ The PEARL object does not behave as described in :ref:`how_objects_hold_state_isis-powder-diffraction-ref`. For PEARL, any settings given in the constructor for the PEARL object, either explicitly or via a config file, are taken as defaults. If these are -overriden in a call to either +overridden in a call to either :ref:`focus_pearl_isis-powder-diffraction-ref`, :ref:`create_vanadium_pearl_isis-powder-diffraction-ref` or :ref:`create_cal_pearl_isis-powder-diffraction-ref`, then these diff --git a/docs/source/techniques/ISIS_Reflectometry.rst b/docs/source/techniques/ISIS_Reflectometry.rst index a18e6134a2826379f2dda41c8011c96b4a2826bf..87e8b29bbfcd560b2d6a82ab2e2ed73eda240263 100644 --- a/docs/source/techniques/ISIS_Reflectometry.rst +++ b/docs/source/techniques/ISIS_Reflectometry.rst @@ -32,7 +32,7 @@ A reflectivity measurement is made by shining a collimated beam (low angular div Further to this, there are two geometric modes of operation. By far the most common is specular reflectivity. In this case the angle of incidence is equal to the angle of reflection or :math:`\theta_i = \theta_f`. This is called the specular condition. It provides the SLD profile/information that is directly normal or perpendicular to the surface of the sample. Secondly there is off-specular reflectivity where the angle of incidence is not equal to the angle of reflection or :math:`\theta_i \ne \theta_f` . This provides structural information in the plane of the sample. -As a quick aside it is worth mentioning that there is an added complication in describing scattering geometries in that different techniques, sources and institutions use different notations for the same things. For instance the specular condition can also be referred to as the :math:`\frac{\theta}{2\theta}` (where :math:`2\theta` is the scattering/detector angle and :math:`\theta` the sample angle) or :math:`\frac{\omega}{\theta}` (where :math:`\theta` is not the scattering/detector angle and :math:`\omega` the sample angle) conditions. At ISIS reflectometers for historic reasons the detector angle is refered to as :math:`\theta` and the sample angle as :math:`\Phi`. +As a quick aside it is worth mentioning that there is an added complication in describing scattering geometries in that different techniques, sources and institutions use different notations for the same things. For instance the specular condition can also be referred to as the :math:`\frac{\theta}{2\theta}` (where :math:`2\theta` is the scattering/detector angle and :math:`\theta` the sample angle) or :math:`\frac{\omega}{\theta}` (where :math:`\theta` is not the scattering/detector angle and :math:`\omega` the sample angle) conditions. At ISIS reflectometers for historic reasons the detector angle is referred to as :math:`\theta` and the sample angle as :math:`\Phi`. For more information, see the `ISIS website <https://www.isis.stfc.ac.uk/Pages/Reflectometry.aspx>`__. diff --git a/docs/source/tutorials/mantid_basic_course/algorithms_workspaces_and_histories/04_algorith_histories.rst b/docs/source/tutorials/mantid_basic_course/algorithms_workspaces_and_histories/04_algorith_histories.rst index 05381b029c172b5ece984be2857a360edfb67df2..5b259ee3fa1c01466ad1ef59a36ce2d9a4508104 100644 --- a/docs/source/tutorials/mantid_basic_course/algorithms_workspaces_and_histories/04_algorith_histories.rst +++ b/docs/source/tutorials/mantid_basic_course/algorithms_workspaces_and_histories/04_algorith_histories.rst @@ -13,7 +13,7 @@ it also provides the means to extract a re-executable python script from the GUI. #. Right click on HYS_11388_event and select 'Show History'. This will - open up the Algorihm History window. In the left-hand side Algorithms + open up the Algorithm History window. In the left-hand side Algorithms panel click on the arrow in front of Rebin v.1 and should see the following: diff --git a/docs/source/tutorials/mantid_basic_course/live_data_analysis/04_examples.rst b/docs/source/tutorials/mantid_basic_course/live_data_analysis/04_examples.rst index 1a4dae94d244da7b09b4f802400385fb07da5305..0363af4569312aac70819d6abac08a642233ad98 100644 --- a/docs/source/tutorials/mantid_basic_course/live_data_analysis/04_examples.rst +++ b/docs/source/tutorials/mantid_basic_course/live_data_analysis/04_examples.rst @@ -124,7 +124,7 @@ Setup : ADARA Fake Event #. Instrument: ADARA_FakeEvent #. Start Time: now #. Update Every: 1 second -#. Processing: Algorthim +#. Processing: Algorithm #. Within the Processing step tab select the **Rebin** algorthm #. In the algorithm properties set **Params** to 40e3,1000,60e3 @@ -150,7 +150,7 @@ Setup : ADARA Fake Event #. Processing: Algorithm #. Within the Processing step tab select the **Rebin** algorthm - #. In the algorthim properties set **Params** to 40e3,500,60e3 + #. In the algorithm properties set **Params** to 40e3,500,60e3 #. PreserveEvents: Not Ticked #. Accumulation Method: Add diff --git a/docs/source/tutorials/mantid_basic_course/multi_dimensional_workspaces/02_multi_dimensional_visualisation.rst b/docs/source/tutorials/mantid_basic_course/multi_dimensional_workspaces/02_multi_dimensional_visualisation.rst index e09dfa6f269722779a424af940fb6d7f2743a6e7..b858899dcdc2614df37d601807474596ea1f650e 100644 --- a/docs/source/tutorials/mantid_basic_course/multi_dimensional_workspaces/02_multi_dimensional_visualisation.rst +++ b/docs/source/tutorials/mantid_basic_course/multi_dimensional_workspaces/02_multi_dimensional_visualisation.rst @@ -86,7 +86,7 @@ Dynamic Rebinning (4) The slice viewer allows you to interactively rebin the currently viewed slice to a regular grid. This will also result in the generation of a new rebinned workspace in Mantid. The icon labeled 4a has to be pressed -first to alow rebinning. 4c automatically rebins the current view. +first to allow rebinning. 4c automatically rebins the current view. The upper image below is before rebinning, the lower image is after rebinning. .. figure:: /images/RebinOff.png @@ -185,7 +185,7 @@ Example 3 MantidPlot, which produces a PeaksWorkspace. #. Load the PeaksWorkspace into the VSI, by right-clicking the workspace and selecting *Show Vates Simple Interface*. You should now see peak - positions as cross-hairs overlayed over the original MDWorkspace + positions as cross-hairs overlaid over the original MDWorkspace data. .. figure:: /images/MBC_VSI_Example3.png diff --git a/docs/sphinxext/mantiddoc/directives/base.py b/docs/sphinxext/mantiddoc/directives/base.py index 7d1884f27f21c33284b2b5059c1c61061a770c17..37bd46299dc99574a9fd9beb9ba606dceb54eef3 100644 --- a/docs/sphinxext/mantiddoc/directives/base.py +++ b/docs/sphinxext/mantiddoc/directives/base.py @@ -43,7 +43,7 @@ def algorithm_name_and_version(docname): return (str(match.groups()[0]), None) # fail now - raise RuntimeError("Faild to fine ame from document filename ") + raise RuntimeError("Failed to find name from document filename ") #---------------------------------------------------------------------------------------- class BaseDirective(Directive): @@ -95,16 +95,16 @@ class BaseDirective(Directive): str: ReST formatted header with algorithm_name as content. """ level_dict = {1:"=", 2:"-", 3:"#", 4:"^"} - + if pagetitle: level = 1 if level not in level_dict: env = self.state.document.settings.env env.app.warn('base.make_header - Did not understand level ' +str(level)) level = 2 - + line = "\n" + level_dict[level] * (len(name)) + "\n" - + if level == 1: return line + name + line else: @@ -149,7 +149,7 @@ class AlgorithmBaseDirective(BaseDirective): The default is to skip (and warn) if the algorithm is not known. Returns: - str: Return error mesage string if the directive should be skipped + str: Return error message string if the directive should be skipped """ from mantid.api import AlgorithmFactory, FunctionFactory @@ -190,7 +190,7 @@ class AlgorithmBaseDirective(BaseDirective): def create_mantid_algorithm_by_name(self, algorithm_name): """ - Create and initializes a Mantid algorithm using tha latest version. + Create and initializes a Mantid algorithm using the latest version. Args: algorithm_name (str): The name of the algorithm to use for the title. @@ -202,7 +202,7 @@ class AlgorithmBaseDirective(BaseDirective): alg = AlgorithmManager.createUnmanaged(algorithm_name) alg.initialize() return alg - + def create_mantid_algorithm(self, algorithm_name, version): """ Create and initializes a Mantid algorithm. @@ -218,7 +218,7 @@ class AlgorithmBaseDirective(BaseDirective): alg = AlgorithmManager.createUnmanaged(algorithm_name, version) alg.initialize() return alg - + def create_mantid_ifunction(self, function_name): """ Create and initiializes a Mantid IFunction. diff --git a/docs/sphinxext/mantiddoc/directives/categories.py b/docs/sphinxext/mantiddoc/directives/categories.py index 633f489273d9224657c7ec2e65afd206db7efbf6..2ddd1b36ff79ebf0548952b662a2181cb65683a6 100644 --- a/docs/sphinxext/mantiddoc/directives/categories.py +++ b/docs/sphinxext/mantiddoc/directives/categories.py @@ -126,7 +126,7 @@ class CategoriesDirective(AlgorithmBaseDirective): Subcategories can be given using the "\\" separator, e.g. Algorithms\\Transforms If the argument list is empty then the the file is assumed to be an algorithm file - and the lists is pulled from the algoritm object + and the lists is pulled from the algorithm object """ required_arguments = 0 @@ -146,7 +146,7 @@ class CategoriesDirective(AlgorithmBaseDirective): def skip(self): """ - Return error mesage if the directive should be skipped. + Return error message if the directive should be skipped. If there are no arguments, it calls the base class skip() method else it returns and empty string. diff --git a/docs/sphinxext/mantiddoc/directives/properties.py b/docs/sphinxext/mantiddoc/directives/properties.py index 1d72e9ac2abd3f3b7c63115af16f2fb030368715..c9e3e4a3c396476656b22b9a4e384e8e15d6bba2 100644 --- a/docs/sphinxext/mantiddoc/directives/properties.py +++ b/docs/sphinxext/mantiddoc/directives/properties.py @@ -113,12 +113,12 @@ class PropertiesDirective(AlgorithmBaseDirective): # col_sizes. table_content_formatted = [ formatter.format(*item) for item in table_content] - # Create a seperator for each column - seperator = formatter.format(*['=' * col for col in col_sizes]) + # Create a separator for each column + separator = formatter.format(*['=' * col for col in col_sizes]) # Build the table. - header = '\n' + seperator + '\n' + formatter.format(*header_content) + '\n' - content = seperator + '\n' + \ - '\n'.join(table_content_formatted) + '\n' + seperator + header = '\n' + separator + '\n' + formatter.format(*header_content) + '\n' + content = separator + '\n' + \ + '\n'.join(table_content_formatted) + '\n' + separator # Join the header and footer. return header + content @@ -253,7 +253,7 @@ class PropertiesDirective(AlgorithmBaseDirective): def _escape_subsitution_refs(self, desc): """ Find occurrences of text surrounded by vertical bars and assume they - are not docutils subsitution referencess by esacping them + are not docutils substitution referencess by esacping them """ def repl(match): return r'\|' + match.group(1) + r'\|' diff --git a/docs/sphinxext/mantiddoc/directives/sourcelink.py b/docs/sphinxext/mantiddoc/directives/sourcelink.py index 990bfbf995912c2bb821683ade0290edb47a2647..8e403cf1c4f3199505d6cc02862b798147053223 100644 --- a/docs/sphinxext/mantiddoc/directives/sourcelink.py +++ b/docs/sphinxext/mantiddoc/directives/sourcelink.py @@ -208,7 +208,7 @@ class SourceLinkDirective(AlgorithmBaseDirective): suggested_path = "os_agnostic_path_to_file_from_Code/Mantid" if not valid_ext_list: raise SourceLinkError("No file possibilities for " + file_name + " have been found\n" + - "Please specify a better one using the :filename: opiton or use the " + + "Please specify a better one using the :filename: option or use the " + str(list(self.file_types.keys())) + " options\n" + "e.g. \n" + ".. sourcelink:\n" + diff --git a/docs/sphinxext/mantiddoc/tools/git_last_modified.py b/docs/sphinxext/mantiddoc/tools/git_last_modified.py index d060d5b5be4473c4dacca945297261632eef98be..fbf2ea8aba6fe7858042edb4fa38ada62b512c8b 100644 --- a/docs/sphinxext/mantiddoc/tools/git_last_modified.py +++ b/docs/sphinxext/mantiddoc/tools/git_last_modified.py @@ -24,7 +24,7 @@ def cache_subtree(cache, root, path): # This line contains the date that the subsequent files were last modified current_date_str = line - # Only take the first (most recent) appearence of each file + # Only take the first (most recent) appearance of each file elif filename_regex.match(line) and line not in cache: # This line contains a file that was modified on the last mentioned date cache[line] = current_date_str diff --git a/qt/python/mantidqt/CMakeLists.txt b/qt/python/mantidqt/CMakeLists.txt index 6ca91e85bdc9c66d88074b58a1754ab417e5c70b..54590033f2b87e85f963873849ae11e22f593fcb 100644 --- a/qt/python/mantidqt/CMakeLists.txt +++ b/qt/python/mantidqt/CMakeLists.txt @@ -1,6 +1,6 @@ include ( SipQtTargetFunctions ) -set ( COMMON_INC_DIR ../../../widgets/common/inc ) +set ( COMMON_INC_DIR ../../widgets/common/inc ) set ( HEADER_DEPENDS ${COMMON_INC_DIR}/MantidQtWidgets/Common/AlgorithmDialog.h ${COMMON_INC_DIR}/MantidQtWidgets/Common/Message.h diff --git a/qt/python/mantidqt/widgets/algorithmprogress/model.py b/qt/python/mantidqt/widgets/algorithmprogress/model.py index af41327bf701a5541d2baed3163b7ee5cc1c1909..d533a7d63f9b049e8dd5088f6025c501f1a7e34b 100644 --- a/qt/python/mantidqt/widgets/algorithmprogress/model.py +++ b/qt/python/mantidqt/widgets/algorithmprogress/model.py @@ -12,7 +12,7 @@ class ProgressObserver(AlgorithmObserver): super(ProgressObserver, self).__init__() self.model = model self.algorithm = alg - self.message = None + self.message = '' self.progress = 0.0 def name(self): @@ -30,10 +30,7 @@ class ProgressObserver(AlgorithmObserver): def progressHandle(self, p, message): self.progress = p - if len(message) > 0: - self.message = message - else: - self.message = None + self.message = message self.model.update_progress(self) def errorHandle(self, message): diff --git a/qt/python/mantidqt/widgets/algorithmprogress/presenter.py b/qt/python/mantidqt/widgets/algorithmprogress/presenter.py index 433ae6de37ee8b85d53ba23ef194f9e76cdb4bd3..1c379e8362b49c3e83fe7383d98915e8b24617b8 100644 --- a/qt/python/mantidqt/widgets/algorithmprogress/presenter.py +++ b/qt/python/mantidqt/widgets/algorithmprogress/presenter.py @@ -23,7 +23,11 @@ class AlgorithmProgressPresenter(AlgorithmProgressPresenterBase): :param message: A message that may come from the algorithm. """ if algorithm is self.algorithm: - self.need_update_progress_bar.emit(self.view.progress_bar, progress, message) + if message is None: + message = '' + else: + message = str(message) + self.need_update_progress_bar.emit(self.view.progress_bar, float(progress), message) def update_gui(self): """ diff --git a/qt/python/mantidqt/widgets/codeeditor/execution.py b/qt/python/mantidqt/widgets/codeeditor/execution.py index e36cbb8105e6d708c7479a85e23222a7c5bb9241..4b0a4783309c3232d648c9ac3e6d1b4642fb8ad6 100644 --- a/qt/python/mantidqt/widgets/codeeditor/execution.py +++ b/qt/python/mantidqt/widgets/codeeditor/execution.py @@ -116,8 +116,8 @@ class PythonCodeExecution(QObject): self.reset_context() - if startup_code: - self.execute(startup_code) + # the code is not executed initially so code completion won't work + # on variables until part is executed @property def globals_ns(self): diff --git a/qt/python/mantidqt/widgets/codeeditor/test/test_execution.py b/qt/python/mantidqt/widgets/codeeditor/test/test_execution.py index f640e0081db5f096d9a8d8be49ad5d1c3775dd1d..0041c25e2baf1127326d8bf5623bd5b467209671 100644 --- a/qt/python/mantidqt/widgets/codeeditor/test/test_execution.py +++ b/qt/python/mantidqt/widgets/codeeditor/test/test_execution.py @@ -64,9 +64,9 @@ class PythonCodeExecutionTest(GuiTest): executor.reset_context() self.assertEqual(0, len(executor.globals_ns)) - def test_startup_code_executed_by_default(self): + def test_startup_code_not_executed_by_default(self): executor = PythonCodeExecution(startup_code="x=100") - self.assertEqual(100, executor.globals_ns['x']) + self.assertFalse('x' in executor.globals_ns) # --------------------------------------------------------------------------- # Successful execution tests diff --git a/qt/python/mantidqtpython/CMakeLists.txt b/qt/python/mantidqtpython/CMakeLists.txt index 1cfd56588f14350df9af899d777a0d77fa822145..85660f831f3ef74e3de958dbc72ab106a7aea00d 100644 --- a/qt/python/mantidqtpython/CMakeLists.txt +++ b/qt/python/mantidqtpython/CMakeLists.txt @@ -12,10 +12,12 @@ set ( SLICEVIEWER_INC ${WIDGETS_DIR}/sliceviewer/inc ) set ( REFVIEWER_INC ${WIDGETS_DIR}/refdetectorview/inc ) set ( HEADER_DEPENDS SIPVector.h + string.sip vector.sip + ../../../Framework/PythonInterface/core/inc/MantidPythonInterface/core/VersionCompat.h + ${FACTORY_INC}/MantidQtWidgets/Factory/WidgetFactory.h - ${WIDGETS_COMMON_INC}/MantidQtWidgets/Common/PythonSystemHeader.h ${WIDGETS_COMMON_INC}/MantidQtWidgets/Common/WorkspaceObserver.h ${WIDGETS_COMMON_INC}/MantidQtWidgets/Common/GraphOptions.h ${WIDGETS_COMMON_INC}/MantidQtWidgets/Common/AlgorithmDialog.h @@ -88,7 +90,9 @@ mtd_add_sip_module ( TARGET_NAME mantidqtpython SIP_SRCS mantidqtpython_def.sip HEADER_DEPS ${HEADER_DEPENDS} - INCLUDE_DIRS ${CMAKE_CURRENT_LIST_DIR} + INCLUDE_DIRS + ${CMAKE_CURRENT_LIST_DIR} + ../../../Framework/PythonInterface/core/inc PYQT_VERSION 4 LINK_LIBS ${TCMALLOC_LIBRARIES_LINKTIME} MantidQtWidgetsCommonQt4 diff --git a/qt/python/mantidqtpython/SIPVector.h b/qt/python/mantidqtpython/SIPVector.h index 7b2cc6938c7a5490243b83dc8e310c2afe64024d..516ff1745ac665ebc3395b5758f8cb8d6c0197af 100644 --- a/qt/python/mantidqtpython/SIPVector.h +++ b/qt/python/mantidqtpython/SIPVector.h @@ -1,5 +1,5 @@ #include "MantidKernel/make_unique.h" -#include "MantidQtWidgets/Common/PythonSystemHeader.h" +#include "MantidPythonInterface/core/VersionCompat.h" #include <boost/optional.hpp> #include <memory> #include <vector> diff --git a/qt/python/mantidqtpython/mantidqtpython_def.sip b/qt/python/mantidqtpython/mantidqtpython_def.sip index 4d40c4b68b260ac0ba61e5e8bac9158866abc085..020ee77372edabe511d97e084902a62872328aea 100644 --- a/qt/python/mantidqtpython/mantidqtpython_def.sip +++ b/qt/python/mantidqtpython/mantidqtpython_def.sip @@ -9,7 +9,7 @@ %Include string.sip %ModuleHeaderCode -#include "MantidQtWidgets/Common/PythonSystemHeader.h" +#include "MantidPythonInterface/core/VersionCompat.h" #include "MantidQtWidgets/Common/WorkspaceObserver.h" %End @@ -1607,16 +1607,16 @@ public: MantidQt::MantidWidgets::Batch::RowLocation insertChildRowOf(const MantidQt::MantidWidgets::Batch::RowLocation &parent, int beforeRow, const std::vector<MantidQt::MantidWidgets::Batch::Cell> &rowText); - MantidQt::MantidWidgets::Batch::RowLocation insertChildRowOf(const MantidQt::MantidWidgets::Batch::RowLocation + MantidQt::MantidWidgets::Batch::RowLocation insertChildRowOf(const MantidQt::MantidWidgets::Batch::RowLocation &parent, int beforeRow); - MantidQt::MantidWidgets::Batch::RowLocation appendChildRowOf(const MantidQt::MantidWidgets::Batch::RowLocation + MantidQt::MantidWidgets::Batch::RowLocation appendChildRowOf(const MantidQt::MantidWidgets::Batch::RowLocation &parent); - MantidQt::MantidWidgets::Batch::RowLocation appendChildRowOf(const MantidQt::MantidWidgets::Batch::RowLocation + MantidQt::MantidWidgets::Batch::RowLocation appendChildRowOf(const MantidQt::MantidWidgets::Batch::RowLocation &parentLocation, const std::vector<MantidQt::MantidWidgets::Batch::Cell> &rowText); void removeRowAt(const MantidQt::MantidWidgets::Batch::RowLocation &location); void removeRows(std::vector<MantidQt::MantidWidgets::Batch::RowLocation> rowsToRemove); - + void removeAllRows(); void replaceRows(std::vector<MantidQt::MantidWidgets::Batch::RowLocation> replacementPoints, std::vector<std::vector<MantidQt::MantidWidgets::Batch::Row>> replacementLocations); void appendSubtreesAt(const MantidQt::MantidWidgets::Batch::RowLocation& parent, @@ -1660,6 +1660,10 @@ public: const std::string &contentText() const; void setContentText(const std::string& contentText); + const std::string &toolTip() const; + void setToolTip(const std::string &toolTip); + + const std::string & borderColor() const; void setBorderColor(const std::string& borderColor); @@ -2298,6 +2302,43 @@ namespace MantidQt namespace API { +class TSVSerialiser +{ +%TypeHeaderCode +#include "MantidQtWidgets/Common/TSVSerialiser.h" +%End +private: +TSVSerialiser(const MantidQt::API::TSVSerialiser &); + +public: +TSVSerialiser(); +TSVSerialiser(const std::string &lines); + +void clear(); +std::string outputLines() const; +std::vector<std::string> sections(const std::string &name) const; + +MantidQt::API::TSVSerialiser &writeLine(const std::string &name); +void writeSection(const std::string &name, const std::string &body); + + +bool selectLine(const std::string &name); +bool selectSection(const std::string &name); + +void storeDouble(const double value); +void storeInt(const int value); +void storeString(const std::string value); +void storeBool(const bool value); + +double readDouble(); +int readInt(); +std::string readString(); +bool readBool(); + +std::string lineAsString(const std::string &name) const; +std::vector<std::string> values(const std::string &name) const; +}; + class WidgetScrollbarDecorator { %TypeHeaderCode diff --git a/qt/python/mantidqtpython/string.sip b/qt/python/mantidqtpython/string.sip index f7c849c8facd1c95a40403be2ba30423472863ce..45d7dd4cbb1fdc968f473e1822b6b25ccc1c8fa0 100644 --- a/qt/python/mantidqtpython/string.sip +++ b/qt/python/mantidqtpython/string.sip @@ -1,6 +1,5 @@ -// Acquired from the PyQt mailing list at +// Adapted from the PyQt mailing list at // https://riverbankcomputing.com/pipermail/pyqt/2005-February/009662.html -// on 9th April 2018. %MappedType std::string { @@ -9,37 +8,33 @@ %End %ConvertFromTypeCode - // convert an std::string to a Python (unicode) string - PyObject* newstring; - newstring = PyUnicode_DecodeUTF8(sipCpp->c_str(), sipCpp->length(), NULL); - if(newstring == NULL) { - PyErr_Clear(); - newstring = FROM_CSTRING(sipCpp->c_str()); - } - return newstring; +#if PY_VERSION_HEX >= 0x03000000 + return PyUnicode_FromString(sipCpp->c_str()); +#else + return PyString_FromString(sipCpp->c_str()); +#endif %End %ConvertToTypeCode - // Allow a Python string (or a unicode string) whenever a string is - // expected. - // If argument is a Unicode string, just decode it to UTF-8 - // If argument is a Python string, assume it's UTF-8 - if (sipIsErr == NULL) - return (STR_CHECK(sipPy) || PyUnicode_Check(sipPy)); - if (sipPy == Py_None) { - *sipCppPtr = new std::string; - return 1; - } - if (PyUnicode_Check(sipPy)) { - PyObject* s = PyUnicode_AsEncodedString(sipPy, "UTF-8", ""); - *sipCppPtr = new std::string(TO_CSTRING(s)); - Py_DECREF(s); - return 1; - } - if (STR_CHECK(sipPy)) { - *sipCppPtr = new std::string(TO_CSTRING(sipPy)); - return 1; - } + // Allow a Python string (or a unicode string) whenever a string is + // expected. + if (sipIsErr == NULL) + return (SIPBytes_Check(sipPy) || PyUnicode_Check(sipPy)); + if (sipPy == Py_None) { + *sipCppPtr = new std::string; + return 1; + } + if (PyUnicode_Check(sipPy)) { + // encode with UTF-8 to bytes object + PyObject* s = PyUnicode_AsUTF8String(sipPy); + *sipCppPtr = new std::string(SIPBytes_AS_STRING(s)); + Py_DECREF(s); + return 1; + } + if (SIPBytes_Check(sipPy)) { + *sipCppPtr = new std::string(SIPBytes_AS_STRING(sipPy)); + return 1; + } return 0; %End }; diff --git a/qt/scientific_interfaces/Indirect/ConvFit.cpp b/qt/scientific_interfaces/Indirect/ConvFit.cpp index 99a60d931ed4ad3b1924379e939e10686e3b36a4..cd5426d7d017810eac4704a94926be0e3c31e167 100644 --- a/qt/scientific_interfaces/Indirect/ConvFit.cpp +++ b/qt/scientific_interfaces/Indirect/ConvFit.cpp @@ -139,7 +139,9 @@ void ConvFit::saveClicked() { IndirectFitAnalysisTab::saveResult(); } * Handles plotting the workspace when plot is clicked */ void ConvFit::plotClicked() { + setPlotResultIsPlotting(true); IndirectFitAnalysisTab::plotResult(m_uiForm->cbPlotType->currentText()); + setPlotResultIsPlotting(false); } void ConvFit::updatePlotOptions() { @@ -170,19 +172,32 @@ std::string ConvFit::fitTypeString() const { return fitType; } +void ConvFit::setRunEnabled(bool enabled) { + m_uiForm->pbRun->setEnabled(enabled); +} + void ConvFit::setPlotResultEnabled(bool enabled) { m_uiForm->pbPlot->setEnabled(enabled); m_uiForm->cbPlotType->setEnabled(enabled); } +void ConvFit::setFitSingleSpectrumEnabled(bool enabled) { + m_uiForm->pvFitPlotView->enableFitSingleSpectrum(enabled); +} + void ConvFit::setSaveResultEnabled(bool enabled) { m_uiForm->pbSave->setEnabled(enabled); } -void ConvFit::setRunEnabled(bool enabled) { - m_uiForm->pvFitPlotView->enableFitSingleSpectrum(enabled); - m_uiForm->pbRun->setEnabled(enabled); - m_uiForm->pbRun->setText(!enabled ? "Running..." : "Run"); +void ConvFit::setRunIsRunning(bool running) { + m_uiForm->pbRun->setText(running ? "Running..." : "Run"); + setRunEnabled(!running); + setFitSingleSpectrumEnabled(!running); +} + +void ConvFit::setPlotResultIsPlotting(bool plotting) { + m_uiForm->pbPlot->setText(plotting ? "Plotting..." : "Plot"); + setPlotResultEnabled(!plotting); } void ConvFit::runClicked() { runTab(); } diff --git a/qt/scientific_interfaces/Indirect/ConvFit.h b/qt/scientific_interfaces/Indirect/ConvFit.h index 9a3a8477d284b4ff10fe9814381c3e8c20451789..fec248df1a69b688c75863a3de0de5e21b1797f9 100644 --- a/qt/scientific_interfaces/Indirect/ConvFit.h +++ b/qt/scientific_interfaces/Indirect/ConvFit.h @@ -18,15 +18,6 @@ class DLLExport ConvFit : public IndirectFitAnalysisTab { public: ConvFit(QWidget *parent = nullptr); -protected: - void setRunEnabled(bool enabled) override; - void setPlotResultEnabled(bool enabled) override; - void setSaveResultEnabled(bool enabled) override; - -private: - void setupFitTab() override; - void setupFit(Mantid::API::IAlgorithm_sptr fitAlgorithm) override; - protected slots: void setModelResolution(const QString &resolutionName); void runClicked(); @@ -35,7 +26,23 @@ protected slots: void updatePlotOptions() override; void fitFunctionChanged(); +protected: + bool shouldEnablePlotResult() override { return true; }; + + void setPlotResultEnabled(bool enabled) override; + void setSaveResultEnabled(bool enabled) override; + + void setRunIsRunning(bool running) override; + private: + void setupFitTab() override; + void setupFit(Mantid::API::IAlgorithm_sptr fitAlgorithm) override; + + void setRunEnabled(bool enabled); + void setFitSingleSpectrumEnabled(bool enabled); + + void setPlotResultIsPlotting(bool plotting); + std::string fitTypeString() const; std::unique_ptr<Ui::ConvFit> m_uiForm; diff --git a/qt/scientific_interfaces/Indirect/ConvFit.ui b/qt/scientific_interfaces/Indirect/ConvFit.ui index 80aa491a2c0c77abd61e5477f5d073a4c061e25c..c4313b319f25fd8353149c473b4591ec31215339 100644 --- a/qt/scientific_interfaces/Indirect/ConvFit.ui +++ b/qt/scientific_interfaces/Indirect/ConvFit.ui @@ -165,10 +165,16 @@ </property> <property name="minimumSize"> <size> - <width>120</width> + <width>100</width> <height>0</height> </size> </property> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> <item> <property name="text"> <string>All</string> diff --git a/qt/scientific_interfaces/Indirect/Elwin.cpp b/qt/scientific_interfaces/Indirect/Elwin.cpp index bdd80033d61df534c7446f6c757ded76df903b28..f0cf8374b4129ba8970b49d32666465e0905f693 100644 --- a/qt/scientific_interfaces/Indirect/Elwin.cpp +++ b/qt/scientific_interfaces/Indirect/Elwin.cpp @@ -117,7 +117,7 @@ void Elwin::setup() { } void Elwin::run() { - setRunEnabled(false); + setRunIsRunning(true); QStringList inputFilenames = m_uiForm.dsInputFiles->getFilenames(); inputFilenames.sort(); @@ -240,20 +240,19 @@ void Elwin::run() { void Elwin::unGroupInput(bool error) { disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(unGroupInput(bool))); - if (error) - return; - if (!m_uiForm.ckGroupInput->isChecked()) { - IAlgorithm_sptr ungroupAlg = - AlgorithmManager::Instance().create("UnGroupWorkspace"); - ungroupAlg->initialize(); - ungroupAlg->setProperty("InputWorkspace", "IDA_Elwin_Input"); - ungroupAlg->execute(); + setRunIsRunning(false); + + if (!error) { + if (!m_uiForm.ckGroupInput->isChecked()) { + IAlgorithm_sptr ungroupAlg = + AlgorithmManager::Instance().create("UnGroupWorkspace"); + ungroupAlg->initialize(); + ungroupAlg->setProperty("InputWorkspace", "IDA_Elwin_Input"); + ungroupAlg->execute(); + } + setPlotResultEnabled(true); + setSaveResultEnabled(true); } - - // Enable run, plot and save - setRunEnabled(true); - m_uiForm.pbPlot->setEnabled(true); - m_uiForm.pbSave->setEnabled(true); } bool Elwin::validate() { @@ -464,6 +463,7 @@ void Elwin::updateRS(QtProperty *prop, double val) { * Handles mantid plotting */ void Elwin::plotClicked() { + setPlotResultIsPlotting(true); auto workspaceBaseName = getWorkspaceBasename(QString::fromStdString(m_pythonExportWsName)); @@ -483,13 +483,14 @@ void Elwin::plotClicked() { if (checkADSForPlotSaveWorkspace((workspaceBaseName + "_elt").toStdString(), true, false)) plotSpectrum(workspaceBaseName + "_elt"); + + setPlotResultIsPlotting(false); } /** * Handles saving of workspaces */ void Elwin::saveClicked() { - auto workspaceBaseName = getWorkspaceBasename(QString::fromStdString(m_pythonExportWsName)); @@ -512,9 +513,24 @@ void Elwin::saveClicked() { m_batchAlgoRunner->executeBatchAsync(); } -void Elwin::setRunEnabled(bool enabled) { - m_uiForm.pbRun->setEnabled(enabled); - m_uiForm.pbRun->setText(!enabled ? "Running..." : "Run"); +void Elwin::setRunEnabled(bool enabled) { m_uiForm.pbRun->setEnabled(enabled); } + +void Elwin::setPlotResultEnabled(bool enabled) { + m_uiForm.pbPlot->setEnabled(enabled); +} + +void Elwin::setSaveResultEnabled(bool enabled) { + m_uiForm.pbSave->setEnabled(enabled); +} + +void Elwin::setRunIsRunning(bool running) { + m_uiForm.pbRun->setText(running ? "Running..." : "Run"); + setRunEnabled(!running); +} + +void Elwin::setPlotResultIsPlotting(bool plotting) { + m_uiForm.pbPlot->setText(plotting ? "Plotting..." : "Plot Result"); + setPlotResultEnabled(!plotting); } void Elwin::runClicked() { runTab(); } diff --git a/qt/scientific_interfaces/Indirect/Elwin.h b/qt/scientific_interfaces/Indirect/Elwin.h index e50c4f0f17fdfb39e890785c146eaadcd14b272f..c9eb91556d2ce4ea61e95283b7f984ea719b455c 100644 --- a/qt/scientific_interfaces/Indirect/Elwin.h +++ b/qt/scientific_interfaces/Indirect/Elwin.h @@ -14,9 +14,6 @@ class DLLExport Elwin : public IndirectDataAnalysisTab { public: Elwin(QWidget *parent = nullptr); -protected: - void setRunEnabled(bool enabled) override; - private: void run() override; void setup() override; @@ -26,6 +23,13 @@ private: const QPair<double, double> &range); void setDefaultSampleLog(Mantid::API::MatrixWorkspace_const_sptr ws); + void setRunEnabled(bool enabled); + void setPlotResultEnabled(bool enabled); + void setSaveResultEnabled(bool enabled); + + void setRunIsRunning(bool running); + void setPlotResultIsPlotting(bool plotting); + private slots: void newInputFiles(); void newPreviewFileSelected(int index); diff --git a/qt/scientific_interfaces/Indirect/ISISEnergyTransfer.cpp b/qt/scientific_interfaces/Indirect/ISISEnergyTransfer.cpp index 4b7e3ca5375a5009218264013c4415eb84f7cf2c..cecffddb47bdd1c98ca0ba1123a50a3137dcfea9 100644 --- a/qt/scientific_interfaces/Indirect/ISISEnergyTransfer.cpp +++ b/qt/scientific_interfaces/Indirect/ISISEnergyTransfer.cpp @@ -411,19 +411,34 @@ void ISISEnergyTransfer::algorithmComplete(bool error) { m_uiForm.ckSaveSPE->setEnabled(true); } -void ISISEnergyTransfer::removeGroupingOption(const QString &option) { +int ISISEnergyTransfer::getGroupingOptionIndex(QString const &option) { for (auto i = 0; i < m_uiForm.cbGroupingOptions->count(); ++i) - if (m_uiForm.cbGroupingOptions->itemText(i) == option) { - m_uiForm.cbGroupingOptions->removeItem(i); - return; - } + if (m_uiForm.cbGroupingOptions->itemText(i) == option) + return i; + return 0; +} + +bool ISISEnergyTransfer::isOptionHidden(QString const &option) { + for (auto i = 0; i < m_uiForm.cbGroupingOptions->count(); ++i) + if (m_uiForm.cbGroupingOptions->itemText(i) == option) + return false; + return true; +} + +void ISISEnergyTransfer::setCurrentGroupingOption(QString const &option) { + m_uiForm.cbGroupingOptions->setCurrentIndex(getGroupingOptionIndex(option)); +} + +void ISISEnergyTransfer::removeGroupingOption(QString const &option) { + m_uiForm.cbGroupingOptions->removeItem(getGroupingOptionIndex(option)); } void ISISEnergyTransfer::includeExtraGroupingOption(bool includeOption, - const QString &option) { - if (includeOption) + QString const &option) { + if (includeOption && isOptionHidden(option)) { m_uiForm.cbGroupingOptions->addItem(option); - else + setCurrentGroupingOption(option); + } else if (!includeOption && !isOptionHidden(option)) removeGroupingOption(option); } diff --git a/qt/scientific_interfaces/Indirect/ISISEnergyTransfer.h b/qt/scientific_interfaces/Indirect/ISISEnergyTransfer.h index 4b5a594eef5b5decd0a5bd06e47fb742a2fba9af..3908debd2ab4fee605486c383bc6ac5a3e474beb 100644 --- a/qt/scientific_interfaces/Indirect/ISISEnergyTransfer.h +++ b/qt/scientific_interfaces/Indirect/ISISEnergyTransfer.h @@ -50,8 +50,13 @@ public slots: private slots: void algorithmComplete(bool error); - void removeGroupingOption(const QString &option); - void includeExtraGroupingOption(bool includeOption, const QString &option); + + void setCurrentGroupingOption(QString const &option); + int getGroupingOptionIndex(QString const &option); + bool isOptionHidden(QString const &option); + void removeGroupingOption(QString const &option); + void includeExtraGroupingOption(bool includeOption, QString const &option); + void setInstrumentDefault(); ///< Sets default parameters for current instrument void mappingOptionSelected( diff --git a/qt/scientific_interfaces/Indirect/IndirectDataAnalysisTab.h b/qt/scientific_interfaces/Indirect/IndirectDataAnalysisTab.h index b68ba4a18933b8c6568b632e7f4f967c8b2791c4..9203a95d60f253a6e010f91ad1cf206367089f5d 100644 --- a/qt/scientific_interfaces/Indirect/IndirectDataAnalysisTab.h +++ b/qt/scientific_interfaces/Indirect/IndirectDataAnalysisTab.h @@ -111,8 +111,6 @@ protected: const QString &startRangePropName = "", const QString &endRangePropName = ""); - virtual void setRunEnabled(bool enabled) = 0; - /// DoubleEditorFactory DoubleEditorFactory *m_dblEdFac; /// QtCheckBoxFactory diff --git a/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTab.cpp b/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTab.cpp index 521a8d3a07082ce357414c78128dce74de58807c..2f2319bc2e9fff729ddcdd03c7383b984873e34d 100644 --- a/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTab.cpp +++ b/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTab.cpp @@ -664,9 +664,9 @@ void IndirectFitAnalysisTab::updateSingleFitOutput(bool error) { * and completed within this interface. */ void IndirectFitAnalysisTab::fitAlgorithmComplete(bool error) { + setRunIsRunning(false); + enablePlotResult(error); setSaveResultEnabled(!error); - setPlotResultEnabled(!error); - setRunEnabled(true); updateParameterValues(); m_spectrumPresenter->enableView(); m_plotPresenter->updatePlots(); @@ -741,30 +741,48 @@ void IndirectFitAnalysisTab::plotResult(const QString &plotType) { void IndirectFitAnalysisTab::plotAll( Mantid::API::WorkspaceGroup_sptr workspaces) { - for (auto &&workspace : *workspaces) - plotAll(boost::dynamic_pointer_cast<MatrixWorkspace>(workspace)); + for (auto index = 0u; index < workspaces->size(); ++index) + plotAll(boost::dynamic_pointer_cast<MatrixWorkspace>( + workspaces->getItem(index)), + index); } void IndirectFitAnalysisTab::plotParameter( Mantid::API::WorkspaceGroup_sptr workspaces, const std::string ¶meter) { - for (auto &&workspace : *workspaces) - plotParameter(boost::dynamic_pointer_cast<MatrixWorkspace>(workspace), - parameter); + for (auto index = 0u; index < workspaces->size(); ++index) + plotParameter(boost::dynamic_pointer_cast<MatrixWorkspace>( + workspaces->getItem(index)), + parameter, index); } void IndirectFitAnalysisTab::plotAll( - Mantid::API::MatrixWorkspace_sptr workspace) { - const auto name = QString::fromStdString(workspace->getName()); - for (auto i = 0u; i < workspace->getNumberHistograms(); ++i) - IndirectTab::plotSpectrum(name, static_cast<int>(i)); + Mantid::API::MatrixWorkspace_sptr workspace, const std::size_t &index) { + const std::size_t numberOfSpectra = + m_fittingModel->getWorkspace(index)->getNumberHistograms(); + if (numberOfSpectra > 1) + plotSpectrum(workspace); + else + showMessageBox(QString("Plotting the result of a workspace failed:\n\n " + "Workspace result has only one data point")); } void IndirectFitAnalysisTab::plotParameter( + Mantid::API::MatrixWorkspace_sptr workspace, + const std::string ¶meterToPlot, const std::size_t &index) { + const std::size_t numberOfSpectra = + m_fittingModel->getWorkspace(index)->getNumberHistograms(); + if (numberOfSpectra > 1) + plotSpectrum(workspace, parameterToPlot); + else + showMessageBox(QString("Plotting the result of a workspace failed:\n\n " + "Workspace result has only one data point")); +} + +void IndirectFitAnalysisTab::plotSpectrum( Mantid::API::MatrixWorkspace_sptr workspace, const std::string ¶meterToPlot) { const auto name = QString::fromStdString(workspace->getName()); const auto labels = IndirectTab::extractAxisLabels(workspace, 1); - for (const auto ¶meter : m_fittingModel->getFitParameterNames()) { if (boost::contains(parameter, parameterToPlot)) { auto it = labels.find(parameter); @@ -774,6 +792,13 @@ void IndirectFitAnalysisTab::plotParameter( } } +void IndirectFitAnalysisTab::plotSpectrum( + Mantid::API::MatrixWorkspace_sptr workspace) { + const auto name = QString::fromStdString(workspace->getName()); + for (auto i = 0u; i < workspace->getNumberHistograms(); ++i) + IndirectTab::plotSpectrum(name, static_cast<int>(i)); +} + /** * Executes the single fit algorithm defined in this indirect fit analysis tab. */ @@ -814,7 +839,7 @@ bool IndirectFitAnalysisTab::validate() { * Called when the 'Run' button is called in the IndirectTab. */ void IndirectFitAnalysisTab::run() { - setRunEnabled(false); + setRunIsRunning(true); runFitAlgorithm(m_fittingModel->getFittingAlgorithm()); } @@ -880,6 +905,10 @@ void IndirectFitAnalysisTab::updatePlotOptions(QComboBox *cbPlotType) { setPlotOptions(cbPlotType, m_fittingModel->getFitParameterNames()); } +void IndirectFitAnalysisTab::enablePlotResult(bool error) { + setPlotResultEnabled(!shouldEnablePlotResult() ? false : !error); +} + /** * Fills the specified combo box, with the specified parameters. * diff --git a/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTab.h b/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTab.h index 2e924f52492d676451e0308a75a82a8652a31f9a..9c573f51d8800dcb8ba91e765abfaa09141bd917 100644 --- a/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTab.h +++ b/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTab.h @@ -118,9 +118,13 @@ protected: void plotAll(Mantid::API::WorkspaceGroup_sptr workspaces); void plotParameter(Mantid::API::WorkspaceGroup_sptr workspace, const std::string ¶meter); - void plotAll(Mantid::API::MatrixWorkspace_sptr workspace); + void plotAll(Mantid::API::MatrixWorkspace_sptr workspace, + const std::size_t &index); void plotParameter(Mantid::API::MatrixWorkspace_sptr workspace, - const std::string ¶meter); + const std::string ¶meter, const std::size_t &index); + void plotSpectrum(Mantid::API::MatrixWorkspace_sptr workspace); + void plotSpectrum(Mantid::API::MatrixWorkspace_sptr workspace, + const std::string ¶meterToPlot); void setAlgorithmProperties(Mantid::API::IAlgorithm_sptr fitAlgorithm) const; void runFitAlgorithm(Mantid::API::IAlgorithm_sptr fitAlgorithm); @@ -128,6 +132,7 @@ protected: virtual void setupFit(Mantid::API::IAlgorithm_sptr fitAlgorithm); void updatePlotOptions(QComboBox *cbPlotType); + void enablePlotResult(bool error); void setPlotOptions(QComboBox *cbPlotType, const std::vector<std::string> ¶meters) const; @@ -135,9 +140,13 @@ protected: void setPlotOptions(QComboBox *cbPlotType, const QSet<QString> &options) const; + virtual bool shouldEnablePlotResult() = 0; + virtual void setPlotResultEnabled(bool enabled) = 0; virtual void setSaveResultEnabled(bool enabled) = 0; + virtual void setRunIsRunning(bool running) = 0; + signals: void functionChanged(); void parameterChanged(const Mantid::API::IFunction *); diff --git a/qt/scientific_interfaces/Indirect/Iqt.cpp b/qt/scientific_interfaces/Indirect/Iqt.cpp index aa87e853681901daf730664dc706a4c3c0232484..e63ce3d784d2b39f786221fe836a096d79fe93c3 100644 --- a/qt/scientific_interfaces/Indirect/Iqt.cpp +++ b/qt/scientific_interfaces/Indirect/Iqt.cpp @@ -136,7 +136,7 @@ void Iqt::setup() { void Iqt::run() { using namespace Mantid::API; - setRunEnabled(false); + setRunIsRunning(true); updateDisplayedBinParameters(); @@ -180,12 +180,12 @@ void Iqt::run() { * @param error If the algorithm failed */ void Iqt::algorithmComplete(bool error) { - if (error) - return; - setRunEnabled(true); - m_uiForm.pbPlot->setEnabled(true); - m_uiForm.pbSave->setEnabled(true); - m_uiForm.pbTile->setEnabled(true); + setRunIsRunning(false); + if (!error) { + setPlotResultEnabled(true); + setTiledPlotEnabled(true); + setSaveResultEnabled(true); + } } /** * Handle saving of workspace @@ -201,7 +201,9 @@ void Iqt::saveClicked() { */ void Iqt::plotClicked() { checkADSForPlotSaveWorkspace(m_pythonExportWsName, false); + setPlotResultIsPlotting(true); plotSpectrum(QString::fromStdString(m_pythonExportWsName)); + setPlotResultIsPlotting(false); } void Iqt::errorsClicked() { @@ -211,6 +213,8 @@ void Iqt::errorsClicked() { bool Iqt::isErrorsEnabled() { return m_uiForm.cbCalculateErrors->isChecked(); } void Iqt::plotTiled() { + setTiledPlotIsPlotting(true); + MatrixWorkspace_const_sptr outWs = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>( m_pythonExportWsName); @@ -262,6 +266,8 @@ void Iqt::plotTiled() { } pyInput += "])\n"; runPythonCode(pyInput); + + setTiledPlotIsPlotting(false); } /** @@ -452,9 +458,33 @@ void Iqt::updateRS(QtProperty *prop, double val) { xRangeSelector->setMaximum(val); } -void Iqt::setRunEnabled(bool enabled) { - m_uiForm.pbRun->setEnabled(enabled); - m_uiForm.pbRun->setText(!enabled ? "Running..." : "Run"); +void Iqt::setRunEnabled(bool enabled) { m_uiForm.pbRun->setEnabled(enabled); } + +void Iqt::setPlotResultEnabled(bool enabled) { + m_uiForm.pbPlot->setEnabled(enabled); +} + +void Iqt::setTiledPlotEnabled(bool enabled) { + m_uiForm.pbTile->setEnabled(enabled); +} + +void Iqt::setSaveResultEnabled(bool enabled) { + m_uiForm.pbSave->setEnabled(enabled); +} + +void Iqt::setRunIsRunning(bool running) { + m_uiForm.pbRun->setText(running ? "Running..." : "Run"); + setRunEnabled(!running); +} + +void Iqt::setPlotResultIsPlotting(bool plotting) { + m_uiForm.pbPlot->setText(plotting ? "Plotting..." : "Plot Result"); + setPlotResultEnabled(!plotting); +} + +void Iqt::setTiledPlotIsPlotting(bool plotting) { + m_uiForm.pbTile->setText(plotting ? "Plotting..." : "Tiled Plot"); + setTiledPlotEnabled(!plotting); } void Iqt::runClicked() { runTab(); } diff --git a/qt/scientific_interfaces/Indirect/Iqt.h b/qt/scientific_interfaces/Indirect/Iqt.h index 5b551480a3b7f5ee5aaff129dd0580721b521416..847b65f0e6e4991b1b6716f4f84cd697c6022476 100644 --- a/qt/scientific_interfaces/Indirect/Iqt.h +++ b/qt/scientific_interfaces/Indirect/Iqt.h @@ -13,9 +13,6 @@ class DLLExport Iqt : public IndirectDataAnalysisTab { public: Iqt(QWidget *parent = nullptr); -protected: - void setRunEnabled(bool enabled) override; - private: void run() override; void setup() override; @@ -24,6 +21,15 @@ private: bool isErrorsEnabled(); + void setRunEnabled(bool enabled); + void setPlotResultEnabled(bool enabled); + void setTiledPlotEnabled(bool enabled); + void setSaveResultEnabled(bool enabled); + + void setRunIsRunning(bool running); + void setPlotResultIsPlotting(bool plotting); + void setTiledPlotIsPlotting(bool plotting); + private slots: void algorithmComplete(bool error); void plotInput(const QString &wsname); diff --git a/qt/scientific_interfaces/Indirect/Iqt.ui b/qt/scientific_interfaces/Indirect/Iqt.ui index 522884e0fa57e856757fa00368a83edcf6cc3ed5..994211782a71fba5f972028349c7dbc26a972497 100644 --- a/qt/scientific_interfaces/Indirect/Iqt.ui +++ b/qt/scientific_interfaces/Indirect/Iqt.ui @@ -235,6 +235,32 @@ <property name="bottomMargin"> <number>7</number> </property> + <item> + <widget class="QCheckBox" name="cbCalculateErrors"> + <property name="text"> + <string>Calculate Errors</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_5"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>30</width> + <height>20</height> + </size> + </property> + </spacer> + </item> <item> <widget class="QLabel" name="label"> <property name="maximumSize"> @@ -280,16 +306,6 @@ </property> </spacer> </item> - <item> - <widget class="QCheckBox" name="cbCalculateErrors"> - <property name="text"> - <string>Calculate Errors</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> </layout> </widget> </item> diff --git a/qt/scientific_interfaces/Indirect/IqtFit.cpp b/qt/scientific_interfaces/Indirect/IqtFit.cpp index 2601a345e14cb078972bce21e860fcd0fb53d84f..89d6b83d0b35436d001634e08f58534106404e4f 100644 --- a/qt/scientific_interfaces/Indirect/IqtFit.cpp +++ b/qt/scientific_interfaces/Indirect/IqtFit.cpp @@ -117,15 +117,6 @@ void IqtFit::updatePlotOptions() { IndirectFitAnalysisTab::updatePlotOptions(m_uiForm->cbPlotType); } -void IqtFit::setPlotResultEnabled(bool enabled) { - m_uiForm->pbPlot->setEnabled(enabled); - m_uiForm->cbPlotType->setEnabled(enabled); -} - -void IqtFit::setSaveResultEnabled(bool enabled) { - m_uiForm->pbSave->setEnabled(enabled); -} - void IqtFit::setupFit(Mantid::API::IAlgorithm_sptr fitAlgorithm) { fitAlgorithm->setProperty("ExtractMembers", boolSettingValue("ExtractMembers")); @@ -133,13 +124,37 @@ void IqtFit::setupFit(Mantid::API::IAlgorithm_sptr fitAlgorithm) { } void IqtFit::plotResult() { + setPlotResultIsPlotting(true); IndirectFitAnalysisTab::plotResult(m_uiForm->cbPlotType->currentText()); + setPlotResultIsPlotting(false); } void IqtFit::setRunEnabled(bool enabled) { - m_uiForm->pvFitPlotView->enableFitSingleSpectrum(enabled); m_uiForm->pbRun->setEnabled(enabled); - m_uiForm->pbRun->setText(!enabled ? "Running..." : "Run"); +} + +void IqtFit::setPlotResultEnabled(bool enabled) { + m_uiForm->pbPlot->setEnabled(enabled); + m_uiForm->cbPlotType->setEnabled(enabled); +} + +void IqtFit::setFitSingleSpectrumEnabled(bool enabled) { + m_uiForm->pvFitPlotView->enableFitSingleSpectrum(enabled); +} + +void IqtFit::setSaveResultEnabled(bool enabled) { + m_uiForm->pbSave->setEnabled(enabled); +} + +void IqtFit::setRunIsRunning(bool running) { + m_uiForm->pbRun->setText(running ? "Running..." : "Run"); + setRunEnabled(!running); + setFitSingleSpectrumEnabled(!running); +} + +void IqtFit::setPlotResultIsPlotting(bool plotting) { + m_uiForm->pbPlot->setText(plotting ? "Plotting..." : "Plot"); + setPlotResultEnabled(!plotting); } void IqtFit::runClicked() { runTab(); } diff --git a/qt/scientific_interfaces/Indirect/IqtFit.h b/qt/scientific_interfaces/Indirect/IqtFit.h index 58656aa3d81a1ff78ffddb0792b096e4bf167f2d..341fab114a7096e87356ddd6b0f77ee86832dd35 100644 --- a/qt/scientific_interfaces/Indirect/IqtFit.h +++ b/qt/scientific_interfaces/Indirect/IqtFit.h @@ -27,14 +27,6 @@ class DLLExport IqtFit : public IndirectFitAnalysisTab { public: IqtFit(QWidget *parent = nullptr); -private: - void setupFitTab() override; - -protected: - void setRunEnabled(bool enabled) override; - void setPlotResultEnabled(bool enabled) override; - void setSaveResultEnabled(bool enabled) override; - protected slots: void setupFit(Mantid::API::IAlgorithm_sptr fitAlgorithm) override; void updatePlotOptions() override; @@ -43,10 +35,25 @@ protected slots: void plotResult(); void runClicked(); +protected: + bool shouldEnablePlotResult() override { return true; }; + + void setPlotResultEnabled(bool enabled) override; + void setSaveResultEnabled(bool enabled) override; + + void setRunIsRunning(bool running) override; + private: void setConstrainIntensitiesEnabled(bool enabled); std::string fitTypeString() const; + void setupFitTab() override; + + void setRunEnabled(bool enabled); + void setFitSingleSpectrumEnabled(bool enabled); + + void setPlotResultIsPlotting(bool plotting); + IqtFitModel *m_iqtFittingModel; std::unique_ptr<Ui::IqtFit> m_uiForm; QString m_tiedParameter; diff --git a/qt/scientific_interfaces/Indirect/IqtFit.ui b/qt/scientific_interfaces/Indirect/IqtFit.ui index 00095efd654e82d3040301af3bfbdc42a2f8478d..f839f4e2bc9255d23eaaafd95b631e30ff8a475e 100644 --- a/qt/scientific_interfaces/Indirect/IqtFit.ui +++ b/qt/scientific_interfaces/Indirect/IqtFit.ui @@ -127,7 +127,7 @@ <item> <widget class="QLabel" name="lbPlotType"> <property name="text"> - <string>Plot Output: </string> + <string>Plot Output:</string> </property> </widget> </item> @@ -136,6 +136,18 @@ <property name="enabled"> <bool>false</bool> </property> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> <item> <property name="text"> <string>Background</string> @@ -169,7 +181,7 @@ <bool>false</bool> </property> <property name="text"> - <string>Plot Result</string> + <string>Plot</string> </property> </widget> </item> diff --git a/qt/scientific_interfaces/Indirect/JumpFit.cpp b/qt/scientific_interfaces/Indirect/JumpFit.cpp index 52d9fd6fd410360f99d8fbc571ff86515a57d04a..41e2cbc5a62510ff521951e859bafa5434ec41d8 100644 --- a/qt/scientific_interfaces/Indirect/JumpFit.cpp +++ b/qt/scientific_interfaces/Indirect/JumpFit.cpp @@ -78,23 +78,45 @@ void JumpFit::updatePlotOptions() { IndirectFitAnalysisTab::updatePlotOptions(m_uiForm->cbPlotType); } +void JumpFit::plotClicked() { + setPlotResultIsPlotting(true); + IndirectFitAnalysisTab::plotResult(m_uiForm->cbPlotType->currentText()); + setPlotResultIsPlotting(false); +} + +bool JumpFit::shouldEnablePlotResult() { + for (auto i = 0u; i < m_jumpFittingModel->numberOfWorkspaces(); ++i) + if (m_jumpFittingModel->getNumberOfSpectra(i) > 1) + return true; + return false; +} + +void JumpFit::setRunEnabled(bool enabled) { + m_uiForm->pbRun->setEnabled(enabled); +} + void JumpFit::setPlotResultEnabled(bool enabled) { m_uiForm->pbPlot->setEnabled(enabled); m_uiForm->cbPlotType->setEnabled(enabled); } +void JumpFit::setFitSingleSpectrumEnabled(bool enabled) { + m_uiForm->pvFitPlotView->enableFitSingleSpectrum(enabled); +} + void JumpFit::setSaveResultEnabled(bool enabled) { m_uiForm->pbSave->setEnabled(enabled); } -void JumpFit::plotClicked() { - IndirectFitAnalysisTab::plotResult(m_uiForm->cbPlotType->currentText()); +void JumpFit::setRunIsRunning(bool running) { + m_uiForm->pbRun->setText(running ? "Running..." : "Run"); + setRunEnabled(!running); + setFitSingleSpectrumEnabled(!running); } -void JumpFit::setRunEnabled(bool enabled) { - m_uiForm->pvFitPlotView->enableFitSingleSpectrum(enabled); - m_uiForm->pbRun->setEnabled(enabled); - m_uiForm->pbRun->setText(!enabled ? "Running..." : "Run"); +void JumpFit::setPlotResultIsPlotting(bool plotting) { + m_uiForm->pbPlot->setText(plotting ? "Plotting..." : "Plot"); + setPlotResultEnabled(!plotting); } void JumpFit::runClicked() { runTab(); } diff --git a/qt/scientific_interfaces/Indirect/JumpFit.h b/qt/scientific_interfaces/Indirect/JumpFit.h index 5575de512e316fd166e4a63f72363de0a06c69c9..ced31820b90600b037181f7d6d67f03df18d82f1 100644 --- a/qt/scientific_interfaces/Indirect/JumpFit.h +++ b/qt/scientific_interfaces/Indirect/JumpFit.h @@ -26,11 +26,19 @@ protected slots: void runClicked(); protected: - void setRunEnabled(bool enabled) override; + bool shouldEnablePlotResult() override; + void setPlotResultEnabled(bool enabled) override; void setSaveResultEnabled(bool enabled) override; + void setRunIsRunning(bool running) override; + private: + void setRunEnabled(bool enabled); + void setFitSingleSpectrumEnabled(bool enabled); + + void setPlotResultIsPlotting(bool plotting); + JumpFitModel *m_jumpFittingModel; std::unique_ptr<Ui::JumpFit> m_uiForm; }; diff --git a/qt/scientific_interfaces/Indirect/JumpFit.ui b/qt/scientific_interfaces/Indirect/JumpFit.ui index d54d47eb25eff31007be9af5c97718e954d49213..ef209e03d90aaf89c227c9ce9bccbf222ee88508 100644 --- a/qt/scientific_interfaces/Indirect/JumpFit.ui +++ b/qt/scientific_interfaces/Indirect/JumpFit.ui @@ -223,6 +223,18 @@ </item> <item> <widget class="QComboBox" name="cbPlotType"> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> <item> <property name="text"> <string>All</string> diff --git a/qt/scientific_interfaces/Indirect/MSDFit.cpp b/qt/scientific_interfaces/Indirect/MSDFit.cpp index 892884be5d1439d9e4ff888e23a68c8fc8a164f8..74cea77e007797f6f8341e18fe5a645a1d0b235c 100644 --- a/qt/scientific_interfaces/Indirect/MSDFit.cpp +++ b/qt/scientific_interfaces/Indirect/MSDFit.cpp @@ -60,20 +60,44 @@ void MSDFit::updateModelFitTypeString() { void MSDFit::updatePlotOptions() {} -void MSDFit::plotClicked() { IndirectFitAnalysisTab::plotResult("All"); } +void MSDFit::plotClicked() { + setPlotResultIsPlotting(true); + IndirectFitAnalysisTab::plotResult("All"); + setPlotResultIsPlotting(false); +} + +bool MSDFit::shouldEnablePlotResult() { + for (auto i = 0u; i < m_msdFittingModel->numberOfWorkspaces(); ++i) + if (m_msdFittingModel->getNumberOfSpectra(i) > 1) + return true; + return false; +} + +void MSDFit::setRunEnabled(bool enabled) { + m_uiForm->pbRun->setEnabled(enabled); +} void MSDFit::setPlotResultEnabled(bool enabled) { m_uiForm->pbPlot->setEnabled(enabled); } +void MSDFit::setFitSingleSpectrumEnabled(bool enabled) { + m_uiForm->pvFitPlotView->enableFitSingleSpectrum(enabled); +} + void MSDFit::setSaveResultEnabled(bool enabled) { m_uiForm->pbSave->setEnabled(enabled); } -void MSDFit::setRunEnabled(bool enabled) { - m_uiForm->pvFitPlotView->enableFitSingleSpectrum(enabled); - m_uiForm->pbRun->setEnabled(enabled); - m_uiForm->pbRun->setText(!enabled ? "Running..." : "Run"); +void MSDFit::setRunIsRunning(bool running) { + m_uiForm->pbRun->setText(running ? "Running..." : "Run"); + setRunEnabled(!running); + setFitSingleSpectrumEnabled(!running); +} + +void MSDFit::setPlotResultIsPlotting(bool plotting) { + m_uiForm->pbPlot->setText(plotting ? "Plotting..." : "Plot Result"); + setPlotResultEnabled(!plotting); } void MSDFit::runClicked() { runTab(); } diff --git a/qt/scientific_interfaces/Indirect/MSDFit.h b/qt/scientific_interfaces/Indirect/MSDFit.h index 27e82480ff64a903ce83c6a8b276e8ba7830f70e..491f4b328d31a6ce851b230c6ee661f588e64d87 100644 --- a/qt/scientific_interfaces/Indirect/MSDFit.h +++ b/qt/scientific_interfaces/Indirect/MSDFit.h @@ -16,9 +16,6 @@ class DLLExport MSDFit : public IndirectFitAnalysisTab { public: MSDFit(QWidget *parent = nullptr); -private: - void setupFitTab() override; - protected slots: void plotClicked(); void runClicked(); @@ -26,11 +23,21 @@ protected slots: void updateModelFitTypeString(); protected: - void setRunEnabled(bool enabled) override; + bool shouldEnablePlotResult() override; + void setPlotResultEnabled(bool enabled) override; void setSaveResultEnabled(bool enabled) override; + void setRunIsRunning(bool running) override; + private: + void setupFitTab() override; + + void setRunEnabled(bool enabled); + void setFitSingleSpectrumEnabled(bool enabled); + + void setPlotResultIsPlotting(bool plotting); + MSDFitModel *m_msdFittingModel; std::unique_ptr<Ui::MSDFit> m_uiForm; }; diff --git a/qt/widgets/common/CMakeLists.txt b/qt/widgets/common/CMakeLists.txt index f5fd072d97902099ab517f99f9cfe68ba73bac28..a17058223221342c71f29d090149355b73b43182 100644 --- a/qt/widgets/common/CMakeLists.txt +++ b/qt/widgets/common/CMakeLists.txt @@ -33,7 +33,6 @@ set ( SRC_FILES src/PropertyWidget.cpp src/PropertyWidgetFactory.cpp src/PythonRunner.cpp - src/PythonThreading.cpp src/QScienceSpinBox.cpp src/QtSignalChannel.cpp src/RepoModel.cpp @@ -302,8 +301,6 @@ set ( INC_FILES inc/MantidQtWidgets/Common/PlotAxis.h inc/MantidQtWidgets/Common/PluginLibraries.h inc/MantidQtWidgets/Common/PropertyWidgetFactory.h - inc/MantidQtWidgets/Common/PythonSystemHeader.h - inc/MantidQtWidgets/Common/PythonThreading.h inc/MantidQtWidgets/Common/QScienceSpinBox.h inc/MantidQtWidgets/Common/QStringUtils.h inc/MantidQtWidgets/Common/ScriptRepositoryView.h @@ -471,7 +468,6 @@ set ( TARGET_LIBRARIES ${CORE_MANTIDLIBS} ${POCO_LIBRARIES} ${Boost_LIBRARIES} - ${PYTHON_LIBRARIES} ) if ( ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/Batch/Cell.h b/qt/widgets/common/inc/MantidQtWidgets/Common/Batch/Cell.h index 455cb1058dd98c0acc2522f90c37c82e713a9157..0f0eef83b3a023c0cfe703f0b6614bd5da06d487 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/Batch/Cell.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/Batch/Cell.h @@ -58,6 +58,9 @@ public: int borderThickness() const; void setBorderThickness(int borderThickness); + void setToolTip(std::string const &toolTip); + std::string const &toolTip() const; + bool isEditable() const; void setEditable(bool isEditable); void disableEditing(); @@ -71,6 +74,7 @@ private: std::string m_borderColor; std::string m_iconFilePath; bool m_isEditable; + std::string m_toolTip; }; EXPORT_OPT_MANTIDQT_COMMON std::ostream &operator<<(std::ostream &os, diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/Batch/IJobTreeView.h b/qt/widgets/common/inc/MantidQtWidgets/Common/Batch/IJobTreeView.h index ec76cdd86e1fd58bcaed9cf277b00ea059b802f1..6bfe5fac42024530b9b147aa8adf1afff0b0efad 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/Batch/IJobTreeView.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/Batch/IJobTreeView.h @@ -51,6 +51,8 @@ public: virtual void removeRowAt(RowLocation const &location) = 0; virtual void removeRows(std::vector<RowLocation> rowsToRemove) = 0; + virtual void removeAllRows() = 0; + virtual bool isOnlyChildOfRoot(RowLocation const &location) const = 0; virtual void replaceRows(std::vector<RowLocation> replacementPoints, diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/Batch/JobTreeView.h b/qt/widgets/common/inc/MantidQtWidgets/Common/Batch/JobTreeView.h index 86bbf0be9890f4f6564d9b2b7c6d2a567b914ceb..05ca990f4b5415ef3ac271e16d8b136deab12bf9 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/Batch/JobTreeView.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/Batch/JobTreeView.h @@ -69,6 +69,7 @@ public: std::vector<Cell> const &rowText) override; void removeRowAt(RowLocation const &location) override; + void removeAllRows() override; void removeRows(std::vector<RowLocation> rowsToRemove) override; bool isOnlyChildOfRoot(RowLocation const &location) const override; diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/FileDialogHandler.h b/qt/widgets/common/inc/MantidQtWidgets/Common/FileDialogHandler.h index 087e271fc8859d0762980af74d89b95ae0a211b3..3c32e8f9f04a6f959f13b48ffe5a0db1da28a23d 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/FileDialogHandler.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/FileDialogHandler.h @@ -58,8 +58,7 @@ getSaveFileName(QWidget *parent = nullptr, /** * For file dialogs. This will add the selected extension if an extension - * doesn't - * already exist. + * doesn't already exist. */ DLLExport QString addExtension(const QString &filename, const QString &selectedFilter); @@ -69,11 +68,16 @@ DLLExport QString getFilter(const Mantid::Kernel::Property *baseProp); /** For file dialogs * * @param exts :: vector of extensions - * @param defaultExt :: default extension to use * @return a string that filters files by extenstions */ -DLLExport QString getFilter(const std::vector<std::string> &exts, - const std::string &defaultExt); +DLLExport QString getFilter(const std::vector<std::string> &exts); + +/** Format extension into expected form (*.ext) + * + * @param extension :: extension to be formatted + * @return a QString of the expected form + */ +DLLExport QString formatExtension(const std::string &extension); DLLExport QString getCaption(const std::string &dialogName, const Mantid::Kernel::Property *prop); diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/PythonSystemHeader.h b/qt/widgets/common/inc/MantidQtWidgets/Common/PythonSystemHeader.h deleted file mode 100644 index c34ec1bb3175293255fcf8b0200b23ba6e0cec76..0000000000000000000000000000000000000000 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/PythonSystemHeader.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef PYTHONSYSTEMHEADER_H_ -#define PYTHONSYSTEMHEADER_H_ - -// This file serves as a wrapper around <Python.h> which allows it to be -// compiled with GCC 2.95.2 under Win32 and which disables the default MSVC -// behavior so that a program may be compiled in debug mode without requiring a -// special debugging build of the Python library. -#include <boost/python/detail/wrap_python.hpp> - -// A few more Python headers -#include <compile.h> -#include <eval.h> -#include <frameobject.h> -#include <traceback.h> - -// Macros for 2/3 compatability -#if PY_VERSION_HEX >= 0x03000000 -#define IS_PY3K -#define INT_CHECK PyLong_Check -#define TO_LONG PyLong_AsLong -#define FROM_LONG PyLong_FromLong -#define STR_CHECK PyUnicode_Check -#define TO_CSTRING _PyUnicode_AsString -#define FROM_CSTRING PyUnicode_FromString -#define CODE_OBJECT(x) x -#else -#define INT_CHECK PyInt_Check -#define TO_LONG PyInt_AsLong -#define STR_CHECK PyString_Check -#define TO_CSTRING PyString_AsString -#define FROM_CSTRING PyString_FromString -#define CODE_OBJECT(x) (PyCodeObject *)x -#define FROM_LONG PyInt_FromLong -#endif - -#endif // PYTHONSYSTEMHEADER_H_ diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/PythonThreading.h b/qt/widgets/common/inc/MantidQtWidgets/Common/PythonThreading.h deleted file mode 100644 index 881bacaeabf70a952ed0e6359fe6360e7653ec39..0000000000000000000000000000000000000000 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/PythonThreading.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef PYTHONTHREADING_H_ -#define PYTHONTHREADING_H_ - -#include "MantidQtWidgets/Common/DllOption.h" -#include "MantidQtWidgets/Common/PythonSystemHeader.h" // this needs to go first - -//------------------------------------------------------------------------------ -// Python Interpreter -//------------------------------------------------------------------------------ -class EXPORT_OPT_MANTIDQT_COMMON PythonInterpreter { -public: - static void initialize(); - static void finalize(); -}; - -//------------------------------------------------------------------------------ -// PythonGIL -//------------------------------------------------------------------------------ -/** - * Defines a structure for acquiring/releasing the Python GIL - * using the RAII pattern. Modeled after QMutex - * - */ -class EXPORT_OPT_MANTIDQT_COMMON PythonGIL { - -public: - static bool locked(); - -public: - PythonGIL(); - PythonGIL(const PythonGIL &) = delete; - PythonGIL &operator=(const PythonGIL &) = delete; - - void acquire(); - void release(); - -private: - PyGILState_STATE m_state; -}; - -//------------------------------------------------------------------------------ -// ScopedInterpreterLock -//------------------------------------------------------------------------------ - -/** - * Acquires a lock in the constructor and releases it in the destructor. - * @tparam T Templated on the lock type - */ -template <typename T> class ScopedGIL { -public: - ScopedGIL() : m_lock() { m_lock.acquire(); } - ~ScopedGIL() { m_lock.release(); } - -private: - T m_lock; -}; - -/// Typedef for scoped lock -using ScopedPythonGIL = ScopedGIL<PythonGIL>; - -#endif /* PYTHONTHREADING_H_ */ diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/TSVSerialiser.h b/qt/widgets/common/inc/MantidQtWidgets/Common/TSVSerialiser.h index 559bb49406703bb21e1a22835bc60813c47202b3..a4fb49291012a14a00a68bc7b55b154bc72dc041 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/TSVSerialiser.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/TSVSerialiser.h @@ -123,6 +123,16 @@ public: bool selectLine(const std::string &name, const size_t i = 0); bool selectSection(const std::string &name, const size_t i = 0); + void storeDouble(const double val); + void storeInt(const int val); + void storeString(const std::string val); + void storeBool(const bool val); + + double readDouble(); + int readInt(); + std::string readString(); + bool readBool(); + int asInt(const size_t i) const; size_t asSize_t(const size_t i) const; double asDouble(const size_t i) const; diff --git a/qt/widgets/common/src/Batch/Cell.cpp b/qt/widgets/common/src/Batch/Cell.cpp index 6dc6363fe0abcb22f8bdfa5e82079c36c98c71e4..f4988c877b8b14ba37f4957bd55b7d817236a14d 100644 --- a/qt/widgets/common/src/Batch/Cell.cpp +++ b/qt/widgets/common/src/Batch/Cell.cpp @@ -9,15 +9,18 @@ Cell::Cell(std::string const &contentText, std::string const &backgroundColor, int borderOpacity, bool isEditable) : m_contentText(contentText), m_backgroundColor(backgroundColor), m_borderThickness(borderThickness), m_borderOpacity(borderOpacity), - m_borderColor(borderColor), m_iconFilePath(), m_isEditable(isEditable) {} + m_borderColor(borderColor), m_iconFilePath(), m_isEditable(isEditable), + m_toolTip("") {} Cell::Cell(std::string const &contentText) : m_contentText(contentText), m_backgroundColor("white"), m_borderThickness(1), m_borderOpacity(255), m_borderColor("darkGrey"), - m_iconFilePath(), m_isEditable(true) {} + m_iconFilePath(), m_isEditable(true), m_toolTip("") {} std::string const &Cell::contentText() const { return m_contentText; } +std::string const &Cell::toolTip() const { return m_toolTip; } + bool Cell::isEditable() const { return m_isEditable; } int Cell::borderThickness() const { return m_borderThickness; } @@ -30,6 +33,8 @@ void Cell::setContentText(std::string const &contentText) { m_contentText = contentText; } +void Cell::setToolTip(std::string const &toolTip) { m_toolTip = toolTip; } + void Cell::setBorderThickness(int borderThickness) { m_borderThickness = borderThickness; } diff --git a/qt/widgets/common/src/Batch/CellStandardItem.cpp b/qt/widgets/common/src/Batch/CellStandardItem.cpp index 3d265b08edee29b141f0a33dda7852b175c066c9..560bc335056561d49a9b92c891c7b718a3a7c15a 100644 --- a/qt/widgets/common/src/Batch/CellStandardItem.cpp +++ b/qt/widgets/common/src/Batch/CellStandardItem.cpp @@ -6,6 +6,7 @@ namespace Batch { void applyCellPropertiesToItem(Cell const &cell, QStandardItem &item) { item.setText(QString::fromStdString(cell.contentText())); item.setEditable(cell.isEditable()); + item.setToolTip(QString::fromStdString(cell.toolTip())); setBorderThickness(item, cell.borderThickness()); setBackgroundColor(item, cell.backgroundColor()); setBorderColor(item, cell.borderColor(), cell.borderOpacity()); @@ -23,6 +24,7 @@ Cell extractCellPropertiesFromItem(QStandardItem const &item) { cell.setBorderOpacity(borderColor.alpha()); cell.setEditable(item.isEditable()); + cell.setToolTip(item.toolTip().toStdString()); return cell; } diff --git a/qt/widgets/common/src/Batch/JobTreeView.cpp b/qt/widgets/common/src/Batch/JobTreeView.cpp index 91b7ca0df210cc17502b0fb01c5fc20a725304bf..748dfddb813896b2383e5e71e58d40235885d6ac 100644 --- a/qt/widgets/common/src/Batch/JobTreeView.cpp +++ b/qt/widgets/common/src/Batch/JobTreeView.cpp @@ -345,6 +345,15 @@ void JobTreeView::removeRowAt(RowLocation const &location) { m_adaptedMainModel.removeRowFrom(indexToRemove); } +void JobTreeView::removeAllRows() { + appendChildRowOf({}); + auto firstChild = std::vector<int>{0}; + while (!isOnlyChildOfRoot(firstChild)) { + removeRowAt(firstChild); + } + clearSelection(); +} + RowLocation JobTreeView::insertChildRowOf(RowLocation const &parent, int beforeRow) { return rowLocation().atIndex(m_adaptedMainModel.insertEmptyChildRow( diff --git a/qt/widgets/common/src/FileDialogHandler.cpp b/qt/widgets/common/src/FileDialogHandler.cpp index 6119954e117274e949e943a1d8615c84f891033c..bc3a94bce8bcbe4704f96c5a2cac7e3d304bcd78 100644 --- a/qt/widgets/common/src/FileDialogHandler.cpp +++ b/qt/widgets/common/src/FileDialogHandler.cpp @@ -108,14 +108,14 @@ QString getFilter(const Mantid::Kernel::Property *baseProp) { const auto *multiProp = dynamic_cast<const Mantid::API::MultipleFileProperty *>(baseProp); if (bool(multiProp)) - return getFilter(multiProp->getExts(), multiProp->getDefaultExt()); + return getFilter(multiProp->getExts()); // regular file version const auto *singleProp = dynamic_cast<const Mantid::API::FileProperty *>(baseProp); // The allowed values in this context are file extensions if (bool(singleProp)) - return getFilter(singleProp->allowedValues(), singleProp->getDefaultExt()); + return getFilter(singleProp->allowedValues()); // otherwise only the all files exists return ALL_FILES; @@ -125,25 +125,28 @@ QString getFilter(const Mantid::Kernel::Property *baseProp) { * the first. * * @param exts :: vector of extensions - * @param defaultExt :: default extension to use * @return a string that filters files by extenstions */ -QString getFilter(const std::vector<std::string> &exts, - const std::string &defaultExt) { +QString getFilter(const std::vector<std::string> &exts) { QString filter(""); - if (!defaultExt.empty()) { - filter.append(QString::fromStdString(defaultExt) + " (*" + - QString::fromStdString(defaultExt) + ");;"); - } - if (!exts.empty()) { - // Push a wild-card onto the front of each file suffix - for (auto &itr : exts) { - if (itr != defaultExt) { - filter.append(QString::fromStdString(itr) + " (*" + - QString::fromStdString(itr) + ");;"); + // Generate the display all filter + if (exts.size() > 1) { + QString displayAllFilter = "Data Files ("; + for (auto &itr : exts) { + // Add a space to between each extension + displayAllFilter.append(" "); + displayAllFilter.append(formatExtension(itr)); } + displayAllFilter.append(" );;"); + filter.append(displayAllFilter); + } + + // Append individual file filters + for (auto &itr : exts) { + filter.append(QString::fromStdString(itr) + " (*" + + QString::fromStdString(itr) + ");;"); } filter = filter.trimmed(); } @@ -151,6 +154,27 @@ QString getFilter(const std::vector<std::string> &exts, return filter; } +/** Format extension into expected form (*.ext) + * + * @param extension :: extension to be formatted + * @return a QString of the expected form + */ +QString formatExtension(const std::string &extension) { + QString formattedExtension = QString::fromStdString(extension); + if (extension.at(0) == '*' && extension.at(1) == '.') { + return formattedExtension; + } else { + if (extension.at(0) == '*') { + formattedExtension.insert(1, "."); + } else if (extension.at(0) == '.') { + formattedExtension.prepend("*"); + } else { + formattedExtension.prepend("*."); + } + } + return formattedExtension; +} + QString getCaption(const std::string &dialogName, const Mantid::Kernel::Property *prop) { // generate the dialog title diff --git a/qt/widgets/common/src/PythonThreading.cpp b/qt/widgets/common/src/PythonThreading.cpp deleted file mode 100644 index 03c153e0a010ec96e44271f0d71e11f9b2153e04..0000000000000000000000000000000000000000 --- a/qt/widgets/common/src/PythonThreading.cpp +++ /dev/null @@ -1,57 +0,0 @@ -//------------------------------------------------------------------------------ -// Includes -//------------------------------------------------------------------------------ -#include "MantidQtWidgets/Common/PythonThreading.h" - -namespace { -PyThreadState *INITIAL_TS = nullptr; -} - -//------------------------------------------------------------------------------ -// PythonInterpreter Public members -//------------------------------------------------------------------------------ -void PythonInterpreter::initialize() { - Py_Initialize(); - PyEval_InitThreads(); - // Release GIL - INITIAL_TS = PyEval_SaveThread(); -} - -// Finalize the Python process. The GIL must be held to -// call this function but after it completes calling -// any python functions is undefined behaviour -void PythonInterpreter::finalize() { Py_Finalize(); } - -//------------------------------------------------------------------------------ -// PythonGIL Public members -//------------------------------------------------------------------------------ - -/** - * Check if the current thread has the lock - * @return True if the current thread holds the GIL, false otherwise - */ -bool PythonGIL::locked() { -#if PY_VERSION_HEX < 0x03000000 - PyThreadState *ts = _PyThreadState_Current; - return (ts && ts == PyGILState_GetThisThreadState()); -#else - return (PyGILState_Check() == 1); -#endif -} - -/** - * Leaves the lock unlocked. You are strongly encouraged to use - * the ScopedInterpreterLock class to control this - */ -PythonGIL::PythonGIL() : m_state(PyGILState_UNLOCKED) {} - -/** - * Calls PyGILState_Ensure. A call to this must be matched by a call to release - * on the same thread. - */ -void PythonGIL::acquire() { m_state = PyGILState_Ensure(); } - -/** - * Calls PyGILState_Release - */ -void PythonGIL::release() { PyGILState_Release(m_state); } diff --git a/qt/widgets/common/src/TSVSerialiser.cpp b/qt/widgets/common/src/TSVSerialiser.cpp index 7196097c1e058023d7237482d97e67f3ea6247f1..08676d3faeeb681358e0ad1c0236eba05a6577d9 100644 --- a/qt/widgets/common/src/TSVSerialiser.cpp +++ b/qt/widgets/common/src/TSVSerialiser.cpp @@ -316,6 +316,23 @@ QString TSVSerialiser::asQString(const size_t i) const { return QString::fromStdString(m_curValues.at(i)); } +void TSVSerialiser::storeDouble(const double val) { m_output << "\t" << val; } + +void TSVSerialiser::storeInt(const int val) { m_output << "\t" << val; } +void TSVSerialiser::storeString(const std::string val) { + m_output << "\t" << val; +} + +void TSVSerialiser::storeBool(const bool val) { m_output << "\t" << val; } + +double TSVSerialiser::readDouble() { return asDouble(m_curIndex++); } + +int TSVSerialiser::readInt() { return asInt(m_curIndex++); } + +std::string TSVSerialiser::readString() { return asString(m_curIndex++); } + +bool TSVSerialiser::readBool() { return asBool(m_curIndex++); } + TSVSerialiser &TSVSerialiser::operator>>(int &val) { val = asInt(m_curIndex++); return *this; @@ -384,7 +401,7 @@ TSVSerialiser &TSVSerialiser::writeLine(const std::string &name) { } TSVSerialiser &TSVSerialiser::operator<<(const std::string &val) { - m_output << "\t" << val; + storeString(val); return *this; } @@ -400,12 +417,12 @@ TSVSerialiser &TSVSerialiser::operator<<(const QString &val) { } TSVSerialiser &TSVSerialiser::operator<<(const double &val) { - m_output << "\t" << val; + storeDouble(val); return *this; } TSVSerialiser &TSVSerialiser::operator<<(const int &val) { - m_output << "\t" << val; + storeInt(val); return *this; } @@ -415,7 +432,7 @@ TSVSerialiser &TSVSerialiser::operator<<(const size_t &val) { } TSVSerialiser &TSVSerialiser::operator<<(const bool &val) { - m_output << "\t" << val; + storeBool(val); return *this; } diff --git a/qt/widgets/common/test/FileDialogHandlerTest.h b/qt/widgets/common/test/FileDialogHandlerTest.h index ab116a2f6799bf472de1b2f10d0a4ae17c59d090..826b8f4cb70673f7c56db1037ed8054112138b64 100644 --- a/qt/widgets/common/test/FileDialogHandlerTest.h +++ b/qt/widgets/common/test/FileDialogHandlerTest.h @@ -47,19 +47,38 @@ public: void test_getFileDialogFilter() { std::vector<std::string> exts({"*.h5", "*.nxs"}); - const auto result1 = MantidQt::API::FileDialogHandler::getFilter( - std::vector<std::string>(), std::string("")); + const auto result1 = + MantidQt::API::FileDialogHandler::getFilter(std::vector<std::string>()); TS_ASSERT_EQUALS(std::string("All Files (*)"), result1.toStdString()); - const auto result2 = - MantidQt::API::FileDialogHandler::getFilter(exts, std::string("")); - TS_ASSERT_EQUALS(std::string("*.h5 (**.h5);;*.nxs (**.nxs);;All Files (*)"), + const auto result2 = MantidQt::API::FileDialogHandler::getFilter(exts); + TS_ASSERT_EQUALS(std::string("Data Files ( *.h5 *.nxs );;*.h5 " + "(**.h5);;*.nxs (**.nxs);;All Files (*)"), result2.toStdString()); + } + + void test_formatExtension() { + const std::string bare_ext = "ext"; + const std::string no_star = ".ext"; + const std::string no_dot = "*ext"; + const std::string valid = "*.ext"; + const QString expected("*.ext"); + + const auto result1 = + MantidQt::API::FileDialogHandler::formatExtension(bare_ext); + TS_ASSERT_EQUALS(expected, result1); + + const auto result2 = + MantidQt::API::FileDialogHandler::formatExtension(no_star); + TS_ASSERT_EQUALS(expected, result2); const auto result3 = - MantidQt::API::FileDialogHandler::getFilter(exts, std::string("*.nxs")); - TS_ASSERT_EQUALS(std::string("*.nxs (**.nxs);;*.h5 (**.h5);;All Files (*)"), - result3.toStdString()); + MantidQt::API::FileDialogHandler::formatExtension(no_dot); + TS_ASSERT_EQUALS(expected, result3); + + const auto result4 = + MantidQt::API::FileDialogHandler::formatExtension(valid); + TS_ASSERT_EQUALS(expected, result4); } }; diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index 1a4bdba2e612261e20c8e5236209de83bf163c7c..36caf52dba761f6c94e0764b3a477da247b2b43c 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -1063,14 +1063,18 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin, /// Add a range of bins for masking void InstrumentActor::addMaskBinsData(const std::vector<size_t> &indices) { - std::vector<size_t> wsIndices; - wsIndices.reserve(indices.size()); + // Ensure we do not have duplicate workspace indices. + std::set<size_t> wi; for (auto det : indices) { auto index = getWorkspaceIndex(det); if (index == INVALID_INDEX) continue; - wsIndices.emplace_back(index); + wi.insert(index); } + + // We will be able to do this more efficiently in C++17 + std::vector<size_t> wsIndices(wi.cbegin(), wi.cend()); + if (!indices.empty()) { m_maskBinsData.addXRange(m_BinMinValue, m_BinMaxValue, wsIndices); auto workspace = getWorkspace(); diff --git a/scripts/AbinsModules/FrequencyPowderGenerator.py b/scripts/AbinsModules/FrequencyPowderGenerator.py index 1259070d87afa67bdbbfd1055911a5bc77bc4ac3..220cbe486a7763eef066fe5076c238af39fba4c7 100644 --- a/scripts/AbinsModules/FrequencyPowderGenerator.py +++ b/scripts/AbinsModules/FrequencyPowderGenerator.py @@ -30,12 +30,12 @@ class FrequencyPowderGenerator(object): len(fundamentals_array.shape) == 1 and fundamentals_array.dtype.num == AbinsModules.AbinsConstants.FLOAT_ID): - raise ValueError("Fundamentals in the form of one dimentional array are expected.") + raise ValueError("Fundamentals in the form of one dimensional array are expected.") if not (isinstance(fundamentals_coefficients, np.ndarray) and len(fundamentals_coefficients.shape) == 1 and fundamentals_coefficients.dtype.num == AbinsModules.AbinsConstants.INT_ID): - raise ValueError("Coefficients of fundamentals in the form of one dimentional array are expected.") + raise ValueError("Coefficients of fundamentals in the form of one dimensional array are expected.") if fundamentals_coefficients.size != fundamentals_array.size: raise ValueError("Inconsistent size of fundamentals and corresponding coefficients. " @@ -59,7 +59,7 @@ class FrequencyPowderGenerator(object): if not (isinstance(previous_array, np.ndarray) and len(previous_array.shape) == 1 and previous_array.dtype.num == AbinsModules.AbinsConstants.FLOAT_ID): - raise ValueError("One dimentional array is expected.") + raise ValueError("One dimensional array is expected.") if not (isinstance(previous_coefficients, np.ndarray) and len(previous_coefficients.shape) == min(2, quantum_order - 1) and diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index d811396c50bce8aa1d71608a9574d4c9c8f49336..e8f37ca00141f958e5504c2b3085d939c102d9d5 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -1,7 +1,6 @@ # Subdirectories from which ui files need processing to py files add_subdirectory(FilterEvents) -add_subdirectory(HFIRPowderReduction) add_subdirectory(Interface/ui) add_subdirectory(TofConverter) add_subdirectory(HFIR_4Circle_Reduction) @@ -10,7 +9,6 @@ add_subdirectory(ErrorReporter) # Chain all required interface custom targets into CompilePyUI add_custom_target(CompilePyUI DEPENDS CompileUIFilterEvents - CompileUIHFIRPowderReduction CompileUITofConverter CompileUIUI CompileUIHFIR_4Circle_Reduction @@ -20,7 +18,6 @@ add_custom_target(CompilePyUI DEPENDS # Put them into the 'CompileUI' folder or group in VS and the like, for convenience set_property ( TARGET CompilePyUI PROPERTY FOLDER "CompilePyUI" ) set_property ( TARGET CompileUIFilterEvents PROPERTY FOLDER "CompilePyUI" ) -set_property ( TARGET CompileUIHFIRPowderReduction PROPERTY FOLDER "CompilePyUI" ) set_property ( TARGET CompileUITofConverter PROPERTY FOLDER "CompilePyUI" ) set_property ( TARGET CompileUIUI PROPERTY FOLDER "CompilePyUI" ) set_property ( TARGET CompileUIHFIR_4Circle_Reduction PROPERTY FOLDER "CompilePyUI" ) diff --git a/scripts/Calibration/Examples/TubeCalibDemoMaps_All.py b/scripts/Calibration/Examples/TubeCalibDemoMaps_All.py index 524b4c95fe1b27c799fbabd5f613b2df4c947b23..d3b27ca938163cc5f94ebeb40c2dc2d50bed3e54 100644 --- a/scripts/Calibration/Examples/TubeCalibDemoMaps_All.py +++ b/scripts/Calibration/Examples/TubeCalibDemoMaps_All.py @@ -78,9 +78,9 @@ def minimalInput(filename): The minimal input for the calibration is the integrated workspace - and the knwon positions. + and the known positions. - Eventhough it is easy to call, the calibration performs well, but there are ways to improve + Even though it is easy to call, the calibration performs well, but there are ways to improve the results, as it is explored after. .. image:: /images/outputOfMinimalInput.png @@ -88,7 +88,7 @@ def minimalInput(filename): """ CalibInstWS = loadingStep(filename) # == Set parameters for calibration == - # Set what we want to calibrate (e.g whole intrument or one door ) + # Set what we want to calibrate (e.g whole instrument or one door ) CalibratedComponent = 'MAPS' # Calibrate all # define the known positions and function factor (edge, peak, peak, peak, edge) knownPos, funcFactor = [-0.50, -0.16, -0.00, 0.16, 0.50], [2, 1, 1, 1, 2] @@ -104,13 +104,13 @@ def provideTheExpectedValue(filename): Giving the expected value for the position of the peaks in pixel. The :func:`~Examples.minimalInput` let to the calibrate to guess the position of the pixels - among the tubes. Altough it works nicelly, providing these expected values may improve the results. + among the tubes. Although it works nicelly, providing these expected values may improve the results. This is done through the **fitPar** parameter. """ from tube_calib_fit_params import TubeCalibFitParams CalibInstWS = loadingStep(filename) # == Set parameters for calibration == - # Set what we want to calibrate (e.g whole intrument or one door ) + # Set what we want to calibrate (e.g whole instrument or one door ) CalibratedComponent = 'MAPS' # Calibrate all # define the known positions and function factor (edge, peak, peak, peak, edge) knownPos, funcFactor = [-0.50, -0.16, -0.00, 0.16, 0.50], [2, 1, 1, 1, 2] @@ -129,7 +129,7 @@ def provideTheExpectedValue(filename): def changeMarginAndExpectedValue(filename): """ - To fit correcly, it is important to have a good window around the peak. This windown is defined + To fit correctly, it is important to have a good window around the peak. This windown is defined by the **margin** parameter. This examples shows how the results worsen if we change the margin from its default value **15** @@ -152,7 +152,7 @@ def changeMarginAndExpectedValue(filename): from tube_calib_fit_params import TubeCalibFitParams CalibInstWS = loadingStep(filename) # == Set parameters for calibration == - # Set what we want to calibrate (e.g whole intrument or one door ) + # Set what we want to calibrate (e.g whole instrument or one door ) CalibratedComponent = 'MAPS' # Calibrate all # define the known positions and function factor (edge, peak, peak, peak, edge) knownPos, funcFactor = [-0.50, -0.16, -0.00, 0.16, 0.50], [2, 1, 1, 1, 2] @@ -183,7 +183,7 @@ def improvingCalibrationSingleTube(filename): From the outputs of provideTheExpectedValue, looking inside the instrument tree, it is possible to list all the tubes that are not so good. - Unfortunatelly, they do not have a single name identifier. + Unfortunately, they do not have a single name identifier. So, locating them it is a little bit trickier. The :func:`~Examples.findThoseTubesThatNeedSpecialCareForCalibration` shows one way of finding those tubes. The index is the position inside the PeakTable. @@ -201,7 +201,7 @@ def improvingCalibrationSingleTube(filename): from tube_calib_fit_params import TubeCalibFitParams CalibInstWS = loadingStep(filename) # == Set parameters for calibration == - # Set what we want to calibrate (e.g whole intrument or one door ) + # Set what we want to calibrate (e.g whole instrument or one door ) CalibratedComponent = 'MAPS' # Calibrate all # define the known positions and function factor (edge, peak, peak, peak, edge) knownPos, funcFactor = [-0.50, -0.16, -0.00, 0.16, 0.50], [2, 1, 1, 1, 2] @@ -228,7 +228,7 @@ def improvingCalibrationSingleTube(filename): overridePeaks = {19: [8.14, 80.9771, 123.221, 164.993, 245.717]} # == Get the calibration and put results into calibration table == - # we will not plot anymore, because it will not plot the overrided peaks + # we will not plot anymore, because it will not plot the overridden peaks calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, knownPos, funcFactor, fitPar=fitPar, outputPeak=True, rangeList=[18, 19, 20], overridePeaks=overridePeaks) @@ -256,7 +256,7 @@ def improvingCalibrationOfListOfTubes(filename): CalibInstWS = loadingStep(filename) # == Set parameters for calibration == - # Set what we want to calibrate (e.g whole intrument or one door ) + # Set what we want to calibrate (e.g whole instrument or one door ) CalibratedComponent = 'MAPS' # Calibrate all # define the known positions and function factor (edge, peak, peak, peak, edge) knownPos, funcFactor = [-0.50, -0.16, -0.00, 0.16, 0.50], [2, 1, 1, 1, 2] @@ -313,7 +313,7 @@ def calibrateB2Window(filename): CalibInstWS = loadingStep(filename) # == Set parameters for calibration == - # Set what we want to calibrate (e.g whole intrument or one door ) + # Set what we want to calibrate (e.g whole instrument or one door ) CalibratedComponent = 'MAPS' # Calibrate all # define the known positions and function factor (edge, peak, peak, peak, edge) knownPos, funcFactor = [-0.50, -0.16, 0.16, 0.50], [2, 1, 1, 2] @@ -344,7 +344,7 @@ def findThoseTubesThatNeedSpecialCareForCalibration(filename): them, it will process the **peakTable** output of the calibrate method when enabling the parameter **outputPeak**. - It them creates the Peaks workspace, that is the diffence of the peaks position from the + It them creates the Peaks workspace, that is the difference of the peaks position from the expected values of the peaks positions for all the tubes. This allows to spot what are the tubes whose fitting are outliers in relation to the others. @@ -356,7 +356,7 @@ def findThoseTubesThatNeedSpecialCareForCalibration(filename): from tube_calib_fit_params import TubeCalibFitParams CalibInstWS = loadingStep(filename) # == Set parameters for calibration == - # Set what we want to calibrate (e.g whole intrument or one door ) + # Set what we want to calibrate (e.g whole instrument or one door ) CalibratedComponent = 'MAPS' # Calibrate all # define the known positions and function factor (edge, peak, peak, peak, edge) knownPos, funcFactor = [-0.50, -0.16, -0.00, 0.16, 0.50], [2, 1, 1, 1, 2] @@ -397,7 +397,7 @@ def findThoseTubesThatNeedSpecialCareForCalibration(filename): # at most 12 pixels from the expected values. # so let's investigate those that differ more than 12 - # return an array with the indexes for the first axis which is the tube indentification + # return an array with the indexes for the first axis which is the tube identification check = numpy.where(distance_from_expected > 12)[0] # remove repeated values @@ -411,7 +411,7 @@ def findThoseTubesThatNeedSpecialCareForCalibration(filename): CalibInstWS = loadingStep(filename) tube.calibrate(CalibInstWS, CalibratedComponent, knownPos, funcFactor, fitPar=fitPar, rangeList=problematic_tubes, plotTube=problematic_tubes) - # plot the FittedTube agains TubePlot for each detector and you will see that there were problems on those tubes. + # plot the FittedTube against TubePlot for each detector and you will see that there were problems on those tubes. def completeCalibration(filename): @@ -421,7 +421,7 @@ def completeCalibration(filename): and improved in :func:`calibrateB2Window`, and :func:`improvingCalibrationOfListOfTubes`. It also improves the result of the calibration because it deals with the E door. The - aquired data cannot be used to calibrate the E door, and trying to do so, produces a bad + acquired data cannot be used to calibrate the E door, and trying to do so, produces a bad result. In this example, the tubes inside the E door are excluded to the calibration. Using the '''rangeList''' option. """ @@ -431,7 +431,7 @@ def completeCalibration(filename): CalibInstWS = loadingStep(filename) # == Set parameters for calibration == - # Set what we want to calibrate (e.g whole intrument or one door ) + # Set what we want to calibrate (e.g whole instrument or one door ) CalibratedComponent = 'MAPS' # Calibrate all # define the known positions and function factor (edge, peak, peak, peak, edge) @@ -443,7 +443,7 @@ def completeCalibration(filename): fitPar.setAutomatic(True) # execute the improvingCalibrationOfListOfTubes excluding the range of b2 window - # correct the definition of the peaks for the folowing indexes + # correct the definition of the peaks for the following indexes # define_peaks = {19:[10, 80.9771, 123.221, 164.993, 245.717], # the first one was bad # 37: [6.36, 80.9347, 122.941, 165.104, 248.32], # the first one was bad # 71: [8.62752, 85.074, 124.919, 164.116, 246.82 ], # the last one was bad - check if we can inprove diff --git a/scripts/Calibration/Examples/TubeCalibDemoMaps_B1.py b/scripts/Calibration/Examples/TubeCalibDemoMaps_B1.py index 15c1a6142dda307120ed79a7f54105fcb75095e1..e0f62e1261b73be4ab4a16a1a51ddfa36b3be96d 100644 --- a/scripts/Calibration/Examples/TubeCalibDemoMaps_B1.py +++ b/scripts/Calibration/Examples/TubeCalibDemoMaps_B1.py @@ -22,7 +22,7 @@ ExpectedWidth = 8.0 # Expected width of Gaussian peaks in pixels (initial valu ExpectedPositions = [4.0, 85.0, 128.0, 161.0, 252.0] # Expected positions of the edges and Gaussian peaks in pixels (initial values of fit parameters) -# Set what we want to calibrate (e.g whole intrument or one door ) +# Set what we want to calibrate (e.g whole instrument or one door ) CalibratedComponent = 'B1_window' # Calibrate B1 window # Get calibration raw file and integrate it diff --git a/scripts/Calibration/Examples/TubeCalibDemoMaps_C4C3.py b/scripts/Calibration/Examples/TubeCalibDemoMaps_C4C3.py index 65e4a5ec8dd49c6d83ad197a51a6be4dee6cafec..c4d0313e5b187099a9a79cc01d7a4520942a5d2a 100644 --- a/scripts/Calibration/Examples/TubeCalibDemoMaps_C4C3.py +++ b/scripts/Calibration/Examples/TubeCalibDemoMaps_C4C3.py @@ -18,7 +18,7 @@ filename = 'MAP14919.raw' # Name of calibration run rangeLower = 2000 # Integrate counts in each spectra from rangeLower to rangeUpper rangeUpper = 10000 # -# Set what we want to calibrate (e.g whole intrument or one door ) +# Set what we want to calibrate (e.g whole instrument or one door ) CalibratedComponent1 = 'C4_window' # Calibrate C4 window CalibratedComponent2 = 'C3_window' # Calibrate C3 window diff --git a/scripts/Calibration/Examples/TubeCalibDemoMaps_C4C3C2.py b/scripts/Calibration/Examples/TubeCalibDemoMaps_C4C3C2.py index a234317ce54673e3324aba0b3b0508be0d127c00..04e461eeeadfb6c49eab1eeec2f16182ac3ba8a4 100644 --- a/scripts/Calibration/Examples/TubeCalibDemoMaps_C4C3C2.py +++ b/scripts/Calibration/Examples/TubeCalibDemoMaps_C4C3C2.py @@ -16,8 +16,8 @@ filename = 'MAP14919.raw' # Name of calibration run rangeLower = 2000 # Integrate counts in each spectra from rangeLower to rangeUpper rangeUpper = 10000 # -# Set what we want to calibrate (e.g whole intrument or one door ) -# Set what we want to calibrate (e.g whole intrument or one door ) +# Set what we want to calibrate (e.g whole instrument or one door ) +# Set what we want to calibrate (e.g whole instrument or one door ) CalibratedComponents = ['C4_window', 'C3_window', 'C2_window'] # Calibrate three C windows # Get calibration raw file and integrate it diff --git a/scripts/Calibration/Examples/TubeCalibDemoMaps_D2.py b/scripts/Calibration/Examples/TubeCalibDemoMaps_D2.py index 5a638f55f1ea22edab84a105051d571a1c445321..54a0d0b4698bdb1beff659c7fd2082c18051724d 100644 --- a/scripts/Calibration/Examples/TubeCalibDemoMaps_D2.py +++ b/scripts/Calibration/Examples/TubeCalibDemoMaps_D2.py @@ -13,7 +13,7 @@ import mantid.simpleapi as mantid # == Set parameters for calibration == filename = 'MAP14919.raw' # Calibration run ( found in \\isis\inst$\NDXMAPS\Instrument\data\cycle_09_5 ) -# Set what we want to calibrate (e.g whole intrument or one door ) +# Set what we want to calibrate (e.g whole instrument or one door ) CalibratedComponent = 'D2_window' # Calibrate D2 window # Get calibration raw file and integrate it diff --git a/scripts/Calibration/Examples/TubeCalibDemoMaps_D2_WideMargins.py b/scripts/Calibration/Examples/TubeCalibDemoMaps_D2_WideMargins.py index 8d1364489e0df678020e9d5c950fab74d68e41ec..4bfaa57e5fd1b2cee5d3e2f487f16f65a778f9e9 100644 --- a/scripts/Calibration/Examples/TubeCalibDemoMaps_D2_WideMargins.py +++ b/scripts/Calibration/Examples/TubeCalibDemoMaps_D2_WideMargins.py @@ -15,7 +15,7 @@ filename = 'MAP14919.raw' # Name of calibration run rangeLower = 2000 # Integrate counts in each spectra from rangeLower to rangeUpper rangeUpper = 10000 # -# Set what we want to calibrate (e.g whole intrument or one door ) +# Set what we want to calibrate (e.g whole instrument or one door ) CalibratedComponent = 'D2_window' # Calibrate D2 window # Get calibration raw file and integrate it diff --git a/scripts/Calibration/Examples/TubeCalibDemoMaps_D4.py b/scripts/Calibration/Examples/TubeCalibDemoMaps_D4.py index bab3431cb800df735a5f8e55cdf8c80f50823535..85185918b646dcf7976fc2a9af30e9749ef24a29 100644 --- a/scripts/Calibration/Examples/TubeCalibDemoMaps_D4.py +++ b/scripts/Calibration/Examples/TubeCalibDemoMaps_D4.py @@ -13,7 +13,7 @@ import mantid.simpleapi as mantid # == Set parameters for calibration == filename = 'MAP14919.raw' # Calibration run ( found in \\isis\inst$\NDXMAPS\Instrument\data\cycle_09_5 ) -# Set what we want to calibrate (e.g whole intrument or one door ) +# Set what we want to calibrate (e.g whole instrument or one door ) CalibratedComponent = 'D4_window' # Calibrate D4 window # Get calibration raw file and integrate it diff --git a/scripts/Calibration/Examples/TubeCalibDemoMerlin.py b/scripts/Calibration/Examples/TubeCalibDemoMerlin.py index 79b467a4ab9ff27b9e94a99664fee8947ebb0cdb..faa2e89f085c4fc555755b374c154c86756de15d 100644 --- a/scripts/Calibration/Examples/TubeCalibDemoMerlin.py +++ b/scripts/Calibration/Examples/TubeCalibDemoMerlin.py @@ -144,7 +144,7 @@ def calibrateMerlin(filename): # For the tubes 2_x (smaller tube above, it is better to take the first part of known positions: edge1, edge2, peak1,peak2 # NOTE: the smaller tubes they have length = 1.22879882813, but 1024 detectors - # so we have to correct the known positiosn by multiplying by its lenght and dividing by the longer dimension + # so we have to correct the known positiosn by multiplying by its length and dividing by the longer dimension from tube_calib_fit_params import TubeCalibFitParams @@ -155,7 +155,7 @@ def calibrateMerlin(filename): 2.92713867188 - 1.22879882813) / 2 # difference among the expected center position for # both tubes here a little bit of attempts is necessary. - # The effective center position and lengh is different for the calibrated tube, that is the reason, + # The effective center position and length is different for the calibrated tube, that is the reason, # the calibrated values of the smaller tube does not seems aligned with the others. By, finding the # 'best' half_diff_center value, the alignment occurs nicely. half_diff_center = 0.835 # @@ -165,7 +165,7 @@ def calibrateMerlin(filename): doorpos = knownPositions[[5, 6, 7, 8]] - half_diff_center doorfunc = [1, 1, 2, 2] # for the smal tubes, automatically searching for the peak position in pixel was not working quite well, - # so we will give the aproximate position for these tubes through fitPar argument + # so we will give the approximate position for these tubes through fitPar argument fitPar = TubeCalibFitParams([216, 527, 826, 989]) fitPar.setAutomatic(True) @@ -185,7 +185,7 @@ def calibrateMerlin(filename): doorfunc = [2, 2, 1, 1] # for the smal tubes, automatically searching for the peak position in pixel was not working quite well, - # so we will give the aproximate position for these tubes through fitPar argument + # so we will give the approximate position for these tubes through fitPar argument fitPar = TubeCalibFitParams([50, 202, 664, 815]) fitPar.setAutomatic(True) diff --git a/scripts/Calibration/Examples/TubeCalibDemoMerlin_Simple.py b/scripts/Calibration/Examples/TubeCalibDemoMerlin_Simple.py index 4f1e0a43020aa42a11a37520637314390b081d62..559d10ae7ba7adb22e5722b6d554746e9bb6cce1 100644 --- a/scripts/Calibration/Examples/TubeCalibDemoMerlin_Simple.py +++ b/scripts/Calibration/Examples/TubeCalibDemoMerlin_Simple.py @@ -42,7 +42,7 @@ def CalibrateMerlin(RunNumber): ExpectedPositions = [35.0, 512.0, 989.0] # Expected positions of the edges and peak in pixels (initial values of fit parameters) - # Set what we want to calibrate (e.g whole intrument or one door ) + # Set what we want to calibrate (e.g whole instrument or one door ) CalibratedComponent = 'MERLIN' # Calibrate door 2 # Get calibration raw file and integrate it @@ -86,7 +86,7 @@ def CalibrateMerlin(RunNumber): # mantid.SaveNexusProcessed(CalibInstWS, 'TubeCalibDemoMerlinResult.nxs', "Result of Running TubeCalibDemoMerlin_Simple.py") # print("saved calibrated workspace (CalibInstWS) into Nexus file TubeCalibDemoMerlinResult.nxs") - # == Reset dafault instrument == + # == Reset default instrument == mantid.config['default.instrument'] = previousDefaultInstrument # ==== End of CalibrateMerlin() ==== diff --git a/scripts/Calibration/Examples/TubeCalibDemoWish_Simple.py b/scripts/Calibration/Examples/TubeCalibDemoWish_Simple.py index f403d36b3a5941a5474bd65130f45c72effec736..546de0806fbbcc4dd52d73718de4357ebd4ad67b 100644 --- a/scripts/Calibration/Examples/TubeCalibDemoWish_Simple.py +++ b/scripts/Calibration/Examples/TubeCalibDemoWish_Simple.py @@ -33,7 +33,7 @@ def CalibrateWish(RunNumber, PanelNumber): # Give y-positions of slit points (gotten for converting first tube's slit point to Y) # WISH instrument has a particularity. It is composed by a group of upper tubes and lower tubes, - # they are disposed 3 milimiters in difference one among the other + # they are disposed 3 millimeters in difference one among the other lower_tube = numpy.array([-0.41, -0.31, -0.21, -0.11, -0.02, 0.09, 0.18, 0.28, 0.39]) upper_tube = numpy.array(lower_tube + 0.003) funcForm = 9 * [1] # 9 gaussian peaks @@ -65,7 +65,7 @@ def CalibrateWish(RunNumber, PanelNumber): # mantid.SaveNexusProcessed(CalibInstWS, 'TubeCalibDemoWishResult.nxs', "Result of Running TubeCalibWishMerlin_Simple.py") # print("saved calibrated workspace (CalibInstWS) into Nexus file", nexusName) - # == Reset dafault instrument == + # == Reset default instrument == mantid.config['default.instrument'] = previousDefaultInstrument # ==== End of CalibrateWish() ==== diff --git a/scripts/Calibration/ideal_tube.py b/scripts/Calibration/ideal_tube.py index 4a265fd49d38253c9298822d630f27e965293a24..551a8468f85ef74e4e4f9f36d852d56e2ca78568 100644 --- a/scripts/Calibration/ideal_tube.py +++ b/scripts/Calibration/ideal_tube.py @@ -68,7 +68,7 @@ class IdealTube(object): :param activeTubeLen: Active tube length in metres """ - #Contruct Ideal tube for 3 point calibration of MERLIN standard tube (code could be put into a function) + #Construct Ideal tube for 3 point calibration of MERLIN standard tube (code could be put into a function) pixelLen = activeTubeLen/1024 # Pixel length # we then convert idealAP, idealCP and idealBP to Y coordinates and put into ideal tube array @@ -78,12 +78,12 @@ class IdealTube(object): def getArray( self ): """ - Reurn the array of of points where the peaks should be in Metres + Return the array of of points where the peaks should be in Metres """ return self.positions def getFunctionalForms( self ): """ - Reurn the array of of points where the peaks should be in Metres + Return the array of of points where the peaks should be in Metres """ return self.functionalForms diff --git a/scripts/Calibration/tube.py b/scripts/Calibration/tube.py index 1e2f216861f3a0fc1b6b0a53c00361b7eea63dc4..192fb0348499f2b40980c472c1e148f1d29e0e52 100644 --- a/scripts/Calibration/tube.py +++ b/scripts/Calibration/tube.py @@ -47,7 +47,7 @@ Among the examples, inside the :py:mod:`Examples` folder, the user is encouraged carry a calibration to the group of tubes. * :py:func:`~Examples.TubeCalibDemoMaps_All.completeCalibration` demonstrate how the **rangeList**, **overridePeaks**, may be used together to allow the calibration of the whole instrument, despite, its particularities in some cases. -* :py:func:`~Examples.TubeCalibDemoMaps_All.findThoseTubesThatNeedSpecialCareForCalibration` show an aproach to find the +* :py:func:`~Examples.TubeCalibDemoMaps_All.findThoseTubesThatNeedSpecialCareForCalibration` show an approach to find the tubes that will require special care on calibrating. It will also help to find detectors that are not working well. ======== @@ -92,7 +92,7 @@ def calibrate(ws, tubeSet, knownPositions, funcForm, **kwargs): The calibration follows the following steps 1. Finding the peaks on each tube - 2. Fitting the peaks agains the Known Positions + 2. Fitting the peaks against the Known Positions 3. Defining the new position for the pixels(detectors) Let's consider the simplest way of calling calibrate: @@ -182,7 +182,7 @@ def calibrate(ws, tubeSet, knownPositions, funcForm, **kwargs): Although the examples consider only Gaussian peaks, it is possible to change the function factors to edges by passing the index of the known_position through the **funcForm**. Hence, considering three special - points, where there are one gaussian peak and thow edges, the calibrate + points, where there are one gaussian peak and two edges, the calibrate could be configured as .. code-block:: python @@ -597,7 +597,7 @@ def findBadPeakFits(peaksTable, threshold=10): @param peakTable: the table containing fitted peak centers @param threshold: the tolerance on the difference from the mean value - @return A list of expected peak positions and a list of indicies of tubes + @return A list of expected peak positions and a list of indices of tubes to correct """ n = len(peaksTable) @@ -647,7 +647,7 @@ def correctMisalignedTubes(ws, calibrationTable, peaksTable, spec, idealTube, tube are recalculated. @param ws: the workspace to get the tube geometry from - @param calibrationTable: the calibration table ouput from running + @param calibrationTable: the calibration table output from running calibration @param peaksTable: the table containing the fitted peak centers from calibration @@ -819,7 +819,7 @@ class _CalibrationParameterHelper(object): raise RuntimeError( "Wrong argument {0}. " "It expects a number 1 for linear, 2 for quadratic, or 3 for 3rd polinomial order" - "when fitting the pixels positions agains the known positions".format(self.FITPOLIN)) + "when fitting the pixels positions against the known positions".format(self.FITPOLIN)) else: return polin_fit else: @@ -857,12 +857,12 @@ class _CalibrationParameterHelper(object): exclude_short_tubes = float(exclude_short_tubes) except: raise RuntimeError( - "Wrong argument {0}. It expects a float value for the minimun size of tubes to be calibrated". + "Wrong argument {0}. It expects a float value for the minimum size of tubes to be calibrated". format(self.EXCLUDESHORT)) else: return exclude_short_tubes else: - # a tube with length 0 can not be calibrated, this is the minimun value + # a tube with length 0 can not be calibrated, this is the minimum value return 0.0 def _get_plot_tube(self, args): diff --git a/scripts/Calibration/tube_calib.py b/scripts/Calibration/tube_calib.py index b36cf00f60926f25c689881696a3c4aaf4ca5363..d3a46e3d0ac6e985afe69c1e55ec683a99068e8e 100644 --- a/scripts/Calibration/tube_calib.py +++ b/scripts/Calibration/tube_calib.py @@ -411,7 +411,7 @@ def getCalibratedPixelPositions(ws, tube_positions, ideal_tube_positions, which_ for i in range(n_dets): deti = ws.getDetector(which_tube[i]) p_new = pixels[i] - # again, the opeartion float * v3d is not defined, but v3d * float is, + # again, the operation float * v3d is not defined, but v3d * float is, # so, I wrote the new pos as center + unit_vector * (float) new_pos = center + unit_vector * p_new @@ -475,7 +475,7 @@ def getCalibration(ws, tubeSet, calibTable, fitPar, iTube, peaksTable, :param fitPar: A :class:`~tube_calib_fit_params.TubeCalibFitParams` object for fitting the peaks :param iTube: The :class:`~ideal_tube.IdealTube` which contains the positions in metres of the shadows of the slits, bars or edges used for calibration. - :param peaksTable: Peaks table into wich the peaks positions will be put + :param peaksTable: Peaks table into which the peaks positions will be put :param overridePeaks: dictionary with tube indexes keys and an array of peaks in pixels to override those that would be fitted for one tube :param excludeShortTubes: Exlude tubes shorter than specified length from calibration diff --git a/scripts/Calibration/tube_calib_fit_params.py b/scripts/Calibration/tube_calib_fit_params.py index c96a2e235b08eaa676b5b4522e64fa7aa932e454..0458ad4bdecc63ad01554a7c2c4e9f084459a3b8 100644 --- a/scripts/Calibration/tube_calib_fit_params.py +++ b/scripts/Calibration/tube_calib_fit_params.py @@ -3,7 +3,7 @@ from __future__ import absolute_import, division, print_function class TubeCalibFitParams(object): -# This class is to take the fitting method and parameters for fitting the peaks crated by the calibration slits etc +# This class is to take the fitting method and parameters for fitting the peaks created by the calibration slits etc # and to deliver them to TubeCalib, so it can fit the peaks appropriately # Author: Karl Palmen ISIS diff --git a/scripts/Calibration/tube_spec.py b/scripts/Calibration/tube_spec.py index f17a35a541db0172752573fe738d832853c278d4..9a5959c1fd2b512e8b7fb636f5904806b49a1306 100644 --- a/scripts/Calibration/tube_spec.py +++ b/scripts/Calibration/tube_spec.py @@ -56,7 +56,7 @@ class TubeSpec: """ Define the sets of tube from the workspace. - Sets tube specification by string. The string specifies a component of the intrument + Sets tube specification by string. The string specifies a component of the instrument as in the instrument tree of its IDF file. This component may contain one or more tubes and possibly all the tunes in the instrument. If the tube specification is not empty this component is added to those already @@ -305,7 +305,7 @@ class TubeSpec: firstDet, numDet, step = self.getDetectorInfoFromTube( tubeIx ) wkIds = [] skipped = [] - # print " First dectector", firstDet," Last detector", firstDet+numDet-1, "Number of detectors", numDet + # print " First detector", firstDet," Last detector", firstDet+numDet-1, "Number of detectors", numDet # print "Histograms", self.ws.getNumberHistograms() # First check we have one detector per histogram/workpsaceID/spectrum diff --git a/scripts/DGSPlanner/DGSPlannerGUI.py b/scripts/DGSPlanner/DGSPlannerGUI.py index 3e7c25fc4046004d514b0c822e9cd5c0bd48efc2..2d6d430b207f37c19b4fb7bb004a95e5492e17ee 100644 --- a/scripts/DGSPlanner/DGSPlannerGUI.py +++ b/scripts/DGSPlanner/DGSPlannerGUI.py @@ -244,7 +244,7 @@ class DGSPlannerGUI(QtGui.QWidget): mantid.simpleapi.MaskDetectors(Workspace="__temp_instrument", MaskedWorkspace=__maskWS) except (ValueError, RuntimeError) as e: reply = QtGui.QMessageBox.critical(self, 'Error', - "The following error has occured in loading the mask:\n" + + "The following error has occurred in loading the mask:\n" + str(e) + "\nDo you want to continue without mask?", QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.No) diff --git a/scripts/DiamondAttenuationCorrection/FitTrans.py b/scripts/DiamondAttenuationCorrection/FitTrans.py index b4f024fa7007085fddbf5ed12f3ebb816b13de3e..4b83087034a9fc683eb1f6b294c7bb25ed79d03a 100644 --- a/scripts/DiamondAttenuationCorrection/FitTrans.py +++ b/scripts/DiamondAttenuationCorrection/FitTrans.py @@ -548,7 +548,7 @@ def showx3(x): ''' %showx displays all parameters for refinement in reasonably intelligible %form - Input : parameter vector and the sets of hkl indices for the diamons + Input : parameter vector and the sets of hkl indices for the diamonds ''' global hkl1, hkl2 global UB1, pkcalcint1 @@ -773,7 +773,7 @@ def SimTrans3(x): % multiplied. I've implemented the change...will see what difference it % makes. % - % M. Guthrie 9 April 2014, introduced possiblity to refine L2 and also a + % M. Guthrie 9 April 2014, introduced possibility to refine L2 and also a % scale factor for calculated dip wavelengths (to account for diamond % compressibility). ''' diff --git a/scripts/Diffraction/isis_powder/pearl.py b/scripts/Diffraction/isis_powder/pearl.py index ef5d8fc5fc4901c2431f94227741771b3e188916..7463e45414adeea5f7604633496b9f88b9777102 100644 --- a/scripts/Diffraction/isis_powder/pearl.py +++ b/scripts/Diffraction/isis_powder/pearl.py @@ -72,7 +72,8 @@ class Pearl(AbstractInst): @contextmanager def _apply_temporary_inst_settings(self, kwargs): - self._switch_long_mode_inst_settings(kwargs.get("long_mode")) + if not self._inst_settings.long_mode == bool(kwargs.get("long_mode")): + self._switch_long_mode_inst_settings(kwargs.get("long_mode")) self._inst_settings.update_attributes(kwargs=kwargs) yield self._inst_settings = copy.deepcopy(self._default_inst_settings) diff --git a/scripts/Diffraction/isis_powder/pearl_routines/pearl_advanced_config.py b/scripts/Diffraction/isis_powder/pearl_routines/pearl_advanced_config.py index 9e61b6e2038796ae2ce3b6a51966c7311d3f3f53..5afa4338b15ab657abe89739c2fbcb77197be287 100644 --- a/scripts/Diffraction/isis_powder/pearl_routines/pearl_advanced_config.py +++ b/scripts/Diffraction/isis_powder/pearl_routines/pearl_advanced_config.py @@ -5,8 +5,7 @@ general_params = { "monitor_mask_regions": array([[3.45, 2.96, 2.1, 1.73], [3.7, 3.2, 2.26, 1.98]]), "monitor_spectrum_number": 1, - "monitor_spline_coefficient": 20, - "spline_coefficient": 60, + "generate_absorb_corrections": False, "file_names": { @@ -41,7 +40,9 @@ long_mode_off_params = { (1500, 19900), # Bank 12 (1500, 19900), # Bank 13 (1500, 19900) # Bank 14 - ] + ], + "monitor_spline_coefficient": 20, + "spline_coefficient": 60 } long_mode_on_params = { @@ -67,7 +68,9 @@ long_mode_on_params = { (20300, 39990), # Bank 12 (20300, 39990), # Bank 13 (20300, 39990) # Bank 14 - ] + ], + "monitor_spline_coefficient": 20, + "spline_coefficient": 60 } calibration_params = { @@ -112,17 +115,17 @@ variable_help = { "raw data to 20,000 microseconds worth of data", "focused_cropping_values": "These values are used to determine the TOF range to crop a focused (not Vanadium " "calibration) workspace to. These are applied on a bank by bank basis. They must " - "be less than the values specified for raw_data_tof_cropping." - }, - - "general_params": { - "monitor_spectrum_number": "The spectrum number the monitor is located at in the workspace", + "be less than the values specified for raw_data_tof_cropping.", "monitor_spline_coefficient": "The coefficient to use whilst calculating a spline from the monitor." "workspace. This is used to normalise the workspace current.", "spline_coefficient": "The coefficient to use whilst calculating a spline for each bank during " "a vanadium calibration." }, + "general_params": { + "monitor_spectrum_number": "The spectrum number the monitor is located at in the workspace", + }, + "calibration_params": { "create_cal_rebin_1_params": "The parameters for the first rebin step used to create a calibration file", "create_cal_rebin_2_params": "The parameters for the second rebin step used to create a calibration file", diff --git a/scripts/Diffraction/isis_powder/pearl_routines/pearl_algs.py b/scripts/Diffraction/isis_powder/pearl_routines/pearl_algs.py index eb7b48d542606a3b932d98087ad5347f57327e4a..88fcc9b558b6df3a72b2945ff45ecb0ce23c1117 100644 --- a/scripts/Diffraction/isis_powder/pearl_routines/pearl_algs.py +++ b/scripts/Diffraction/isis_powder/pearl_routines/pearl_algs.py @@ -30,7 +30,7 @@ def apply_vanadium_absorb_corrections(van_ws, run_details, absorb_ws=None): if van_original_units != absorb_units: van_ws = mantid.ConvertUnits(InputWorkspace=van_ws, Target=absorb_units, OutputWorkspace=van_ws) - van_ws = mantid.RebinToWorkspace(WorkspaceToRebin=van_ws, WorkspaceToMatch=absorb_ws, OutputWorkspace=van_ws) + absorb_ws = mantid.RebinToWorkspace(WorkspaceToRebin=absorb_ws, WorkspaceToMatch=van_ws, OutputWorkspace=absorb_ws) van_ws = mantid.Divide(LHSWorkspace=van_ws, RHSWorkspace=absorb_ws, OutputWorkspace=van_ws) if van_original_units != absorb_units: diff --git a/scripts/FilterEvents/MplFigureCanvas.py b/scripts/FilterEvents/MplFigureCanvas.py index 41176d1e840bbeb0e842a26caf3899a005341d3c..b4ace37152335a82f2a8ab492881b4e3c81c52f7 100644 --- a/scripts/FilterEvents/MplFigureCanvas.py +++ b/scripts/FilterEvents/MplFigureCanvas.py @@ -43,6 +43,6 @@ class MplFigureCanvas(FigureCanvas): return def getPlot(self): - """ reture figure's axes to expose the matplotlib figure to PyQt client + """ return figure's axes to expose the matplotlib figure to PyQt client """ return self.axes diff --git a/scripts/FilterEvents/eventFilterGUI.py b/scripts/FilterEvents/eventFilterGUI.py index fa31ac99450110b946662140e5cc5bbd796c067b..bca40a52f17ecc2fcfaf56467f02df714c0fc7fd 100644 --- a/scripts/FilterEvents/eventFilterGUI.py +++ b/scripts/FilterEvents/eventFilterGUI.py @@ -78,7 +78,7 @@ class MainWindow(QtGui.QMainWindow): _errMsgWindow = None def __init__(self, parent=None): - """ Intialization and set up + """ Initialization and set up """ # Base class QtGui.QMainWindow.__init__(self,parent) @@ -882,7 +882,7 @@ class MainWindow(QtGui.QMainWindow): iname = filename.split("_")[0] str_runnumber = filename.split("_")[1] if str_runnumber.isdigit() is True and int(str_runnumber) > 0: - # Acccepted format + # Accepted format ishort = config.getInstrument(iname).shortName() wsname = "%s_%s_event" % (ishort, str_runnumber) else: @@ -927,7 +927,7 @@ class MainWindow(QtGui.QMainWindow): t0 = datetime.datetime.strptime(runstart, "%Y-%m-%dT%H:%M:%S") tf = datetime.datetime.strptime(runstop, "%Y-%m-%dT%H:%M:%S") - # Calcualte + # Calculate dt = tf-t0 timeduration = dt.days*3600*24 + dt.seconds diff --git a/scripts/HFIRPowderReduction/CMakeLists.txt b/scripts/HFIRPowderReduction/CMakeLists.txt deleted file mode 100644 index 7659c2d62c7d28473a3a67cbd051abf802083fb1..0000000000000000000000000000000000000000 --- a/scripts/HFIRPowderReduction/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -include(UiToPy) - -# List of UIs to Auto convert -set( UI_FILES - MainWindow.ui -) - -UiToPy( UI_FILES CompileUIHFIRPowderReduction) - diff --git a/scripts/HFIRPowderReduction/HfirPDReductionControl.py b/scripts/HFIRPowderReduction/HfirPDReductionControl.py deleted file mode 100644 index e61547b1baa3b131661dd3ebf27a914ab80f84d0..0000000000000000000000000000000000000000 --- a/scripts/HFIRPowderReduction/HfirPDReductionControl.py +++ /dev/null @@ -1,1140 +0,0 @@ -# pylint: disable=too-many-lines,relative-import,invalid-name,too-many-instance-attributes,too-many-arguments -############################################################################ -# -# HFIR powder reduction control class -# Key Words: FUTURE -# -############################################################################ -from __future__ import (absolute_import, division, print_function) -import os -try: # python3 - from urllib.request import urlopen - from urllib.error import HTTPError -except ImportError: - from urllib2 import urlopen - from urllib2 import HTTPError - -import math -from six.moves import range - -import numpy - -from . import HfirUtility as hutil - -# Import mantid -import mantid.simpleapi as api -from mantid.simpleapi import AnalysisDataService - -# from mantid.kernel import ConfigService - - -VanadiumPeakPositions = [0.5044, 0.5191, 0.5350, 0.5526, 0.5936, 0.6178, 0.6453, 0.6768, - 0.7134, 0.7566, 0.8089, 0.8737, 0.9571, 1.0701, 1.2356, 1.5133, 2.1401] - - -class PDRManager(object): - """ Powder diffraction reduction workspace manager - """ - - def __init__(self, exp, scan): - """ Initialization - """ - try: - self.exp = int(exp) - self.scan = int(scan) - except ValueError: - raise NotImplementedError("Set non-integer value as Exp and Scan to PDRManager.") - - self.unit = None - self.datamdws = None - self.monitormdws = None - self.reducedws = None - self.binsize = 1E10 - - self._rawSpiceTableWS = None - self._rawLogInfoWS = None - - # vanadium only - self._processedVanWS = None - self._processedVanWSTemp = None - self._processVanNote = "" - self._applySmoothVan = False - self._vanadiumPeakPosList = [] - - self._wavelength = None - - # register startup - api.UsageService.registerFeatureUsage("Interface", "HfirPowderReduction", False) - - return - - def applySmoothVanadium(self, smoothaccept): - """ Apply the smoothing effect of to vanadium data - """ - if isinstance(smoothaccept, bool) is False: - raise NotImplementedError('Input for applySmoothVanadium() is not boolean!') - - self._applySmoothVan = smoothaccept - - return - - def getAverageMonitorCounts(self): - """ Return the average monitor counts - """ - # Check - if self._rawSpiceTableWS is None: - raise NotImplementedError('Raw SPICE TableWorkspace is None for scan %d, exp %d' % ( - self.exp, self.scan - )) - - # Get the column index for monitor counts - colnames = self._rawSpiceTableWS.getColumnNames() - try: - imonitor = colnames.index("monitor") - except ValueError: - raise RuntimeError("monitor is not a column name in SPICE table workspace.") - - # Sum and average - numpts = self._rawSpiceTableWS.rowCount() - totalcounts = 0 - for irow in range(numpts): - moncounts = self._rawSpiceTableWS.cell(irow, imonitor) - totalcounts += moncounts - - return float(totalcounts) / float(numpts) - - def getProcessedVanadiumWS(self): - """ - """ - return self._processedVanWS - - def getProcessedVanadiumWSTemp(self): - """ - """ - return self._processedVanWSTemp - - def getRawSpiceTable(self): - """ - """ - return self._rawSpiceTableWS - - def getRawInfoMatrixWS(self): - """ - """ - return self._rawLogInfoWS - - def getVanadiumPeaks(self): - """ - """ - return self._vanadiumPeakPosList[:] - - def getWavelength(self): - """ - """ - return self._wavelength - - def isSmoothApplied(self): - """ - """ - return self._applySmoothVan - - def setup(self, datamdws, monitormdws, reducedws=None, unit=None, binsize=None): - """ Set up MDEventWorkspaces and reduction parameters - """ - self.datamdws = datamdws - self.monitormdws = monitormdws - if reducedws is not None: - self.reducedws = reducedws - if unit is not None: - self.unit = unit - try: - self.binsize = float(binsize) - except TypeError as e: - print(e) - - return - - def set_raw_workspaces(self, spice_table_ws, log_matrix_ws): - """ Set 2 raw SPICE workspaces - """ - # Validate - if spice_table_ws.id() != 'TableWorkspace' or log_matrix_ws.id() != 'Workspace2D': - raise NotImplementedError("Input workspaces for setRawWorkspaces() are not of correct types.") - - self._rawSpiceTableWS = spice_table_ws - self._rawLogInfoWS = log_matrix_ws - - return - - def setupMDWrokspaces(self, datamdws, monitormdws): - """ - """ - self.datamdws = datamdws - self.monitormdws = monitormdws - - return - - def setProcessedVanadiumData(self, wksp): - """ Set tempory processed vanadium data - Arguments: - - vanws :: workspace - - note :: string as note - """ - self._processedVanWS = wksp - - return - - def setProcessedVanadiumDataTemp(self, vanws, note): - """ Set tempory processed vanadium data - Arguments: - - vanws :: workspace - - note :: string as note - """ - self._processedVanWSTemp = vanws - self._processVanNote = note - - return - - def setVanadiumPeaks(self, vanpeakposlist): - """ Set up vanadium peaks in 2theta - """ - # Validate input - if isinstance(vanpeakposlist, list) is False: - raise NotImplementedError("Input must be a list. Now it it is %s." % (str(type(vanpeakposlist)))) - elif len(vanpeakposlist) == 0: - raise NotImplementedError("Input must be a non-empty list.") - - vanpeakposlist = sorted(vanpeakposlist) - if vanpeakposlist[0] < 5.: - raise NotImplementedError("Check whether the list %s is in unit of 2theta" % (str(vanpeakposlist))) - - # Set up - self._vanadiumPeakPosList = vanpeakposlist[:] - - return - - def setWavelength(self, wavelength): - """ Set wavelength for this run - """ - self._wavelength = float(wavelength) - if wavelength <= 0: - raise NotImplementedError("It is not physical to have negative neutron wavelength") - - return - - -# pylint: disable=too-many-public-methods - - -class HFIRPDRedControl(object): - """ Class for controlling HFIR powder reduction - """ - - def __init__(self): - """ Initialization - """ - self._myWorkspaceDict = {} # dictionary to manage all the workspaces reduced - # key = Exp/Scan - self._myMergedWSDict = {} # key = Exp/Scan list - - self._myWavelengthDict = {} - - self._lastWkspToMerge = [] - - return - - def applySmoothVanadium(self, expno, scanno, applysmooth): - """ Apply smoothed vanadium - """ - if ((expno, scanno) in self._myWorkspaceDict) is False: - raise NotImplementedError("Exp %d Scan %d does not have reduced \ - workspace." % (expno, scanno)) - else: - rmanager = self._myWorkspaceDict[(expno, scanno)] - rmanager.applySmoothVanadium(applysmooth) - - return - - def getIndividualDetCounts(self, exp, scan, detid, xlabel, normalized=True): - """ Get individual detector counts - :param exp: - :param scan: - :param detid: - :param xlabel: - :param normalized: - :return: - """ - # Check and get data - exp = int(exp) - scan = int(scan) - detid = int(detid) - - if ((exp, scan) in self._myWorkspaceDict) is False: - raise NotImplementedError("Exp %d Scan %d does not have reduced \ - workspace." % (exp, scan)) - else: - rmanager = self._myWorkspaceDict[(exp, scan)] - - datamdws = rmanager.datamdws - monitormdws = rmanager.monitormdws - - if datamdws is None or monitormdws is None: - raise NotImplementedError('Reduction manager has no MDEventWorkspaces setup.') - # END-IF-ELSE - - # Get raw counts - # FUTURE: use **args - if xlabel is None: - tempoutws = \ - api.GetSpiceDataRawCountsFromMD(InputWorkspace=datamdws, - MonitorWorkspace=monitormdws, - Mode='Detector', - DetectorID=detid, - NormalizeByMonitorCounts=normalized) - else: - print("Plot detector %d's counts vs. sample log %s." % (detid, xlabel)) - tempoutws = \ - api.GetSpiceDataRawCountsFromMD(InputWorkspace=datamdws, - MonitorWorkspace=monitormdws, - Mode='Detector', - DetectorID=detid, - XLabel=xlabel, - NormalizeByMonitorCounts=normalized) - - vecx = tempoutws.readX(0)[:] - vecy = tempoutws.readY(0)[:] - - return vecx, vecy - - def getRawDetectorCounts(self, exp, scan, ptnolist=None): - """ Return raw detector counts as a list of 3-tuples - """ - # Check and get data - exp = int(exp) - scan = int(scan) - - if ((exp, scan) in self._myWorkspaceDict) is False: - raise NotImplementedError("Exp %d Scan %d does not have reduced \ - workspace." % (exp, scan)) - else: - rmanager = self._myWorkspaceDict[(exp, scan)] - datamdws = rmanager.datamdws - monitormdws = rmanager.monitormdws - - if datamdws is None or monitormdws is None: - raise NotImplementedError('Reduction manager has no MDEventWorkspaces setup.') - # END-IF-ELSE - - # get the complete list of Pt. number - if ptnolist is None: - ptnolist = self._getRunNumberList(datamdws=rmanager.datamdws) - - rlist = [] - # Loop over all Pt. number - for ptno in ptnolist: - # get data - tempoutws = api.GetSpiceDataRawCountsFromMD(InputWorkspace=datamdws, - MonitorWorkspace=monitormdws, - Mode='Pt.', - Pt=ptno) - - vecx = tempoutws.readX(0)[:] - vecy = tempoutws.readY(0)[:] - - rlist.append((ptno, vecx, vecy)) - # ENDFOR - - return rlist - - def getSampleLogNames(self, expno, scanno): - """ Get the list of sample logs' names if they are - of float data type - """ - # check - if ((expno, scanno) in self._myWorkspaceDict) is False: - raise NotImplementedError("Exp %d Scan %d does not have reduced \ - workspace." % (expno, scanno)) - - # get data - rmanager = self._myWorkspaceDict[(expno, scanno)] - datamdws = rmanager.datamdws - - info0 = datamdws.getExperimentInfo(0) - run = info0.run() - plist = run.getProperties() - lognamelist = [] - for prop in plist: - if prop.__class__.__name__.lower().count('float') == 1: - lognamelist.append(prop.name) - - return lognamelist - - def getSampleLogValue(self, expno, scanno, samplelogname, xlabel): - """ Get vecx and vecy for sample log - """ - # Check and get data - exp = int(expno) - scan = int(scanno) - - if ((exp, scan) in self._myWorkspaceDict) is False: - raise NotImplementedError("Exp %d Scan %d does not have reduced \ - workspace." % (exp, scan)) - else: - rmanager = self._myWorkspaceDict[(exp, scan)] - datamdws = rmanager.datamdws - monitormdws = rmanager.monitormdws - - if datamdws is None or monitormdws is None: - raise NotImplementedError('Reduction manager has no MDEventWorkspaces setup.') - # END-IF-ELSE - - # get the complete list of Pt. number - # ptnolist = self._getRunNumberList(datamdws=rmanager.datamdws) - - # get data - print("[DB] Plot sample log: XLabel = %s" % (xlabel)) - tempoutws = api.GetSpiceDataRawCountsFromMD(InputWorkspace=datamdws, - MonitorWorkspace=monitormdws, - Mode='Sample Log', - SampleLogName=samplelogname, - XLabel=xlabel) - - vecx = tempoutws.readX(0)[:] - vecy = tempoutws.readY(0)[:] - - return (vecx, vecy) - - def getVectorToPlot(self, exp, scan): - """ Get vec x and vec y of the reduced workspace to plot - """ - # get on hold of reduced workspace - wsmanager = self.getWorkspace(exp, scan, raiseexception=True) - reducedws = wsmanager.reducedws - if reducedws is None: - raise NotImplementedError("Exp %d Scan %d does not have reduced workspace." % (exp, scan)) - - # convert to point data if necessary - if len(reducedws.readX(0)) != len(reducedws.readY(0)): - wsname = reducedws.name() + "_pd" - api.ConvertToPointData(InputWorkspace=reducedws, OutputWorkspace=wsname) - outws = AnalysisDataService.retrieve(wsname) - else: - outws = reducedws - - # get vectors - return outws.readX(0), outws.readY(0) - - def getVectorProcessVanToPlot(self, exp, scan, tempdata=False): - """ Get vec x and y for the processed vanadium spectrum - """ - # get on hold of processed vanadium data workspace - wsmanager = self.getWorkspace(exp, scan, raiseexception=True) - - if tempdata is True: - procVanWs = wsmanager.getProcessedVanadiumWSTemp() - else: - procVanWs = wsmanager.getProcessedVanadiumWS() - # procVanWs = wsmanager._processedVanWS - - if procVanWs is None: - raise NotImplementedError("Exp %d Scan %d does not have processed vanadium workspace." % (exp, scan)) - - # convert to point data if necessary - if len(procVanWs.readX(0)) != len(procVanWs.readY(0)): - wsname = procVanWs.name() + "_pd" - api.ConvertToPointData(InputWorkspace=procVanWs, OutputWorkspace=wsname) - outws = AnalysisDataService.retrieve(wsname) - else: - outws = procVanWs - - # get vectors - return outws.readX(0), outws.readY(0) - - def getMergedVector(self, mkey): - """ Get vector X and Y from merged scans - """ - if (mkey in self._myMergedWSDict) is True: - wksp = self._myMergedWSDict[mkey] - - # convert to point data if necessary - if len(wksp.readX(0)) != len(wksp.readY(0)): - wsname = wksp.name() + "_pd" - api.ConvertToPointData(InputWorkspace=wksp, OutputWorkspace=wsname) - wksp = AnalysisDataService.retrieve(wsname) - - vecx = wksp.readX(0) - vecy = wksp.readY(0) - else: - raise NotImplementedError("No merged workspace for key = %s." % (str(mkey))) - - return (vecx, vecy) - - def getVanadiumPeaksPos(self, exp, scan): - """ Convert vanadium peaks from d-spacing to 2theta - Arguments - - exp - - scan - - Return :: list of peak positions in 2-theta (Degrees) - """ - wsmanager = self.getWorkspace(exp, scan, raiseexception=True) - if wsmanager.datamdws is None: - self._logError("Unable to rebin the data for exp=%d, scan=%d because either data MD workspace and \ - monitor MD workspace is not present." % (exp, scan)) - return False - - wavelength = wsmanager.getWavelength() - - # Convert the vanadium peaks' position from dSpacing to 2theta - vanpeakpos2theta = [] - for peakpos in VanadiumPeakPositions: - lambda_over_2d = wavelength / 2. / peakpos - if abs(lambda_over_2d) <= 1.: - twotheta = math.asin(lambda_over_2d) * 2. * 180 / math.pi - vanpeakpos2theta.append(twotheta) - else: - print("Vanadium peak %f is out of d-Spacing range." % (peakpos)) - - vanpeakpos2theta = sorted(vanpeakpos2theta) - wsmanager.setVanadiumPeaks(vanpeakpos2theta) - - return vanpeakpos2theta - - def getWavelength(self, exp, scan): - """ Get wavelength - """ - exp = int(exp) - scan = int(scan) - return self._myWavelengthDict[(exp, scan)] - - def getWkspToMerge(self): - """ Get the individual workspaces that are used for merging in the last - merging-run activities - """ - wslist = [] - for wsmanager in self._lastWkspToMerge: - outws = wsmanager.reducedws - wslist.append(outws) - # ENDFOR (wsmanager) - - return wslist - - def getWorkspace(self, exp, scan, raiseexception): - """ - """ - # get on hold of data - if ((exp, scan) in self._myWorkspaceDict) is False: - if raiseexception is True: - raise NotImplementedError("Exp %d Scan %d has not been processed. " % (exp, scan)) - else: - return None - # ENDIF - - return self._myWorkspaceDict[(exp, scan)] - - def hasDataLoaded(self, exp, scan): - """ Check whether an experiment data set (defined by exp No. and scan No.) - has been loaded or not. - """ - if (exp, scan) in self._myWorkspaceDict: - return True - else: - return False - - def hasReducedWS(self, exp, scan): - """ Check whether an Exp/Scan has a reduced workspace - """ - if ((exp, scan) in self._myWorkspaceDict) is False: - print(list(self._myWorkspaceDict.keys())) - return False - - if self._myWorkspaceDict[(exp, scan)].reducedws is None: - return False - - return True - - def loadSpicePDData(self, expno, scanno, datafilename): - """ Load SPICE powder diffraction data to MDEventsWorkspaces - """ - # Create base workspace name - try: - basewsname = os.path.basename(datafilename).split(".")[0] - except AttributeError as e: - raise NotImplementedError("Unable to parse data file name due to %s." % (str(e))) - - # load SPICE - tablewsname = basewsname + "_RawTable" - infowsname = basewsname + "ExpInfo" - api.LoadSpiceAscii(Filename=datafilename, - OutputWorkspace=tablewsname, RunInfoWorkspace=infowsname) - - tablews = AnalysisDataService.retrieve(tablewsname) - infows = AnalysisDataService.retrieve(infowsname) - if tablews is None or infows is None: - raise NotImplementedError('Unable to retrieve either spice table workspace %s or log workspace %s' % ( - tablewsname, infowsname)) - - # Create a reduction manager and add workspaces to it - wsmanager = PDRManager(expno, scanno) - wsmanager.set_raw_workspaces(tablews, infows) - self._myWorkspaceDict[(int(expno), int(scanno))] = wsmanager - - return - - def mergeReduceSpiceData(self, expno, scannolist, unit, xmin, xmax, binsize): - """ Merge and reduce SPICE data files - Arguements: - - expscanfilelist: list of 3 tuples: expnumber, scannumber and file name - """ - # Collect data MD workspaces and monitor MD workspaces - datamdwslist = [] - monitormdwslist = [] - self._lastWkspToMerge = [] - - print("[Checkpoint 0] Scans = ", str(scannolist)) - for scanno in sorted(scannolist): - try: - wsmanager = self.getWorkspace(expno, scanno, True) - datamdwslist.append(wsmanager.datamdws) - monitormdwslist.append(wsmanager.monitormdws) - self._lastWkspToMerge.append(wsmanager) - except KeyError as ne: - print('[Error] Unable to retrieve MDWorkspaces for Exp %d Scan %d due to %s.' % ( - expno, scanno, str(ne))) - scannolist.remove(scanno) - # ENDFOR - - print("[Checkpoing 1] Scans = ", str(scannolist)) - - # Merge and binning - if len(datamdwslist) > 1: - mg_datamdws = datamdwslist[0] + datamdwslist[1] - mg_monitormdws = monitormdwslist[0] + monitormdwslist[1] - else: - mg_datamdws = datamdwslist[0] - mg_monitormdws = monitormdwslist[0] - for iw in range(2, len(datamdwslist)): - mg_datamdws += datamdwslist[iw] - mg_monitormdws += monitormdwslist[iw] - - # Set up binning parameters - if xmin is None or xmax is None: - binpar = "%.7f" % (binsize) - else: - binpar = "%.7f, %.7f, %.7f" % (xmin, binsize, xmax) - - # set up output workspace's name - scannolist = sorted(scannolist) - outwsname = "Merged_Exp%d_Scan%s_%s" % (expno, scannolist[0], scannolist[-1]) - - # Merge - wavelength = self.getWavelength(expno, scannolist[0]) - api.ConvertCWPDMDToSpectra(InputWorkspace=mg_datamdws, - InputMonitorWorkspace=mg_monitormdws, - OutputWorkspace=outwsname, - BinningParams=binpar, - UnitOutput=unit, - NeutronWaveLength=wavelength) - moutws = AnalysisDataService.retrieve(outwsname) - if moutws is None: - raise NotImplementedError("Merge failed.") - - key = (expno, str(scannolist)) - self._myMergedWSDict[key] = moutws - - return key - - def parseDetEffCorrFile(self, instrument, vancorrfname): - """ Parse detector efficiency correction file='HB2A - - Return :: 2-tuple (table workspace and or - """ - if instrument.upper() == 'HB2A': - vancorrdict, errmsg = hutil.parseDetEffCorrFile(vancorrfname) - if len(vancorrdict) > 0: - detefftablews = self._generateTableWS(vancorrdict) - else: - detefftablews = None - else: - detefftablews = None - errmsg = "Instrument %s is not supported for parsing vanadium (detector efficiency) correction." - - return (detefftablews, errmsg) - - def parseExcludedDetFile(self, instrument, excldetfname): - """ Parse excluded detectors file - - Return :: 2 -tuple (list/None, error message) - """ - if instrument.upper() == 'HB2A': - excldetlist, errmsg = hutil.parseDetExclusionFile(excldetfname) - else: - raise NotImplementedError( - 'Instrument %s is not supported for parsing excluded detectors file.' % (instrument)) - - return excldetlist, errmsg - - def parseSpiceData(self, expno, scanno, detefftablews=None): - """ Load SPICE data to MDWorkspaces from raw table workspace - """ - # Get reduction manager - try: - wsmanager = self._myWorkspaceDict[(int(expno), int(scanno))] - except KeyError: - raise NotImplementedError("Exp %d Scan %d has not been loaded yet." % (int(expno), int(scanno))) - - # Convert to MDWorkspace - tablews = wsmanager.getRawSpiceTable() - infows = wsmanager.getRawInfoMatrixWS() - - basewsname = tablews.name().split('_RawTable')[0] - datamdwsname = basewsname + "_DataMD" - monitorwsname = basewsname + "_MonitorMD" - api.ConvertSpiceDataToRealSpace(InputWorkspace=tablews, - RunInfoWorkspace=infows, - OutputWorkspace=datamdwsname, - OutputMonitorWorkspace=monitorwsname, - DetectorEfficiencyTableWorkspace=detefftablews) - - datamdws = AnalysisDataService.retrieve(datamdwsname) - monitormdws = AnalysisDataService.retrieve(monitorwsname) - - if datamdws is None or monitormdws is None: - raise NotImplementedError("Failed to convert SPICE data to MDEventWorkspaces \ - for experiment %d and scan %d." % (expno, scanno)) - - # Manager: - wsmanager.setupMDWrokspaces(datamdws, monitormdws) - self._myWorkspaceDict[(expno, scanno)] = wsmanager - - return True - - def reset_to_normalized(self, exp, scan_list, min_x, max_x, bin_size): - """ Reset the scaled up data to normalized data - :param exp: - :param scan_list: - :param min_x: - :param max_x: - :param bin_size: - :return: - """ - try: - exp = int(exp) - except ValueError as e: - return False, str(e) - - for scan in scan_list: - try: - scan = int(scan) - wsmanager = self._myWorkspaceDict[(exp, scan)] - except ValueError: - # type error, return with false - return False, 'Scan number %s is not integer.' % (str(scan)) - except KeyError: - # data has not been reduced yet. Reduce dat - self.reduceSpicePDData(exp, scan, unit='2theta', - xmin=min_x, xmax=max_x, binsize=bin_size) - wsmanager = self._myWorkspaceDict[(exp, scan)] - # END_TRY_EXCEPT - - # Reduce data if it is not reduced - if wsmanager.reducedws is None: - self.reduceSpicePDData(exp, scan, unit='2theta', xmin=min_x, xmax=max_x, binsize=bin_size) - - monitorcounts = wsmanager.getAverageMonitorCounts() - print('[DB] Exp %d Scan %d: average monitor counts = %.5f' % (exp, scan, monitorcounts)) - # FUTURE: implement method ws_manager.reset_to_normalized() instead - wsmanager.reducedws = wsmanager.reducedws / monitorcounts - # END_FOR(scan) - - return True, '' - - def scale_to_raw_monitor_counts(self, exp, scan_list, min_x, max_x, bin_size): - """ Scale up the reduced powder spectrum to its average monitor counts - :param exp: - :param scan_list: - :param min_x: - :param max_x: - :param bin_size: - :return: - """ - try: - exp = int(exp) - except ValueError as e: - return False, str(e) - - for scan in scan_list: - try: - scan = int(scan) - wsmanager = self._myWorkspaceDict[(exp, scan)] - except ValueError: - # type error, return with false - return False, 'Scan number %s is not integer.' % (str(scan)) - except KeyError: - # data has not been reduced yet. Reduce dat - self.reduceSpicePDData(exp, scan, unit='2theta', - xmin=min_x, xmax=max_x, binsize=bin_size) - wsmanager = self._myWorkspaceDict[(exp, scan)] - # END_TRY_EXCEPT - - # Reduce data if it is not reduced - if wsmanager.reducedws is None: - self.reduceSpicePDData(exp, scan, unit='2theta', xmin=min_x, xmax=max_x, binsize=bin_size) - - monitorcounts = wsmanager.getAverageMonitorCounts() - print('[DB] Exp %d Scan %d: average monitor counts = %.5f' % (exp, scan, monitorcounts)) - wsmanager.reducedws = wsmanager.reducedws * monitorcounts - # END_FOR(scan) - - return True, '' - - def reduceSpicePDData(self, exp, scan, unit, xmin, xmax, binsize, wavelength=None, - excludeddetlist=None, scalefactor=None): - """ Reduce SPICE powder diffraction data from MDEventWorkspaces - Return - Boolean as reduction is successful or not - """ - # Get reduction manager - try: - ws_manager = self._myWorkspaceDict[(int(exp), int(scan))] - except KeyError: - raise NotImplementedError("SPICE data for Exp %d Scan %d has not been loaded." % ( - int(exp), int(scan))) - - datamdws = ws_manager.datamdws - monitormdws = ws_manager.monitormdws - - # binning from MD to single spectrum ws - # set up binning parameters - if xmin is None or xmax is None: - binpar = "%.7f" % (binsize) - else: - binpar = "%.7f, %.7f, %.7f" % (xmin, binsize, xmax) - - # scale-factor - if scalefactor is None: - scalefactor = 1. - else: - scalefactor = float(scalefactor) - print("[DB] Scale factor is %f." % (scalefactor)) - - # Excluded detectors - if excludeddetlist is None: - excludeddetlist = [] - else: - print("[DB] Excluded detectors: %s" % (excludeddetlist), "Convert to numpy array", - numpy.array(excludeddetlist)) - - basewsname = datamdws.name().split("_DataMD")[0] - outwsname = basewsname + "_Reduced" - api.ConvertCWPDMDToSpectra(InputWorkspace=datamdws, - InputMonitorWorkspace=monitormdws, - OutputWorkspace=outwsname, - BinningParams=binpar, - UnitOutput=unit, - NeutronWaveLength=wavelength, - ExcludedDetectorIDs=numpy.array(excludeddetlist), - ScaleFactor=scalefactor) - - print("[DB] Reduction is finished. Data is in workspace %s. " % (outwsname)) - - # Set up class variable for min/max and - outws = AnalysisDataService.retrieve(outwsname) - if outws is None: - raise NotImplementedError("Failed to bin the MDEventWorkspaces to MatrixWorkspace.") - - # Manager: - if ((exp, scan) in self._myWorkspaceDict) is False: - raise NotImplementedError('Exp %d Scan %d has not been initialized. ' % (exp, scan)) - # wsmanager = PDRManager(exp, scan) - ws_manager = self._myWorkspaceDict[(exp, scan)] - ws_manager.setup(datamdws, monitormdws, outws, unit, binsize) - ws_manager.setWavelength(wavelength) - - # self._myWorkspaceDict[(exp, scan)] = wsmanager - - return True - - def retrieveCorrectionData(self, instrument, exp, scan, localdatadir): - """ Retrieve including dowloading and/or local locating - powder diffraction's correction files - - Arguments: - - instrument :: name of powder diffractometer in upper case - - exp :: integer as epxeriment number - - scan :: integer as scan number - - Return :: 2-tuple (True, list of returned file names) or (False, error reason) - """ - if instrument.upper() == 'HB2A': - # For HFIR HB2A only - - try: - wsmanager = self._myWorkspaceDict[(exp, scan)] - except KeyError as e: - raise e - - # Get parameter m1 and colltrans - m1 = self._getValueFromTable(wsmanager.getRawSpiceTable(), 'm1') - colltrans = self._getValueFromTable(wsmanager.getRawSpiceTable(), 'colltrans') - - # detector efficiency file - try: - detefffname, deteffurl, wavelength = hutil.makeHB2ADetEfficiencyFileName(exp, m1, colltrans) - except NotImplementedError as e: - raise e - if detefffname is not None: - localdetefffname = os.path.join(localdatadir, detefffname) - print("[DB] Detector efficiency file name: %s From %s" % (detefffname, deteffurl)) - if os.path.exists(localdetefffname) is False: - downloadFile(deteffurl, localdetefffname) - else: - print("[Info] Detector efficiency file %s exists in directory %s." % (detefffname, localdatadir)) - else: - localdetefffname = None - # ENDIF - - # excluded detectors file - excldetfname, exclurl = hutil.makeExcludedDetectorFileName(exp) - localexcldetfname = os.path.join(localdatadir, excldetfname) - print("[DB] Excluded det file name: %s From %s" % (excldetfname, exclurl)) - if os.path.exists(localexcldetfname) is False: - downloadstatus, errmsg = downloadFile(exclurl, localexcldetfname) - if downloadstatus is False: - localexcldetfname = None - print("[Error] %s" % (errmsg)) - else: - print("[Info] Detector exclusion file %s exists in directory %s." % (excldetfname, localdatadir)) - - # Set to ws manager - wsmanager.setWavelength(wavelength) - # wsmanager.setDetEfficencyFile() - # wsmanager.setExcludedDetFile() - - else: - # Other instruments - raise NotImplementedError("Instrument %s is not supported to retrieve correction file." % (instrument)) - - return (True, [wavelength, localdetefffname, localexcldetfname]) - - def saveMergedScan(self, sfilename, mergeindex): - """ Save the current merged scan - """ - if (mergeindex in self._myMergedWSDict) is True: - wksp = self._myMergedWSDict[mergeindex] - else: - raise NotImplementedError('Unable to locate the merged scan workspace.') - - api.SaveFocusedXYE(InputWorkspace=wksp, - StartAtBankNumber=1, - Filename=sfilename) - - return - - def savePDFile(self, exp, scan, filetype, sfilename): - """ Save a reduced workspace to gsas/fullprof/topaz data file - """ - # get workspace - wsmanager = self.getWorkspace(exp, scan, raiseexception=True) - if wsmanager.reducedws is None: - raise NotImplementedError("Unable to rebin the data for exp=%d, scan=%d because \ - either data MD workspace and monitor MD workspace is not present." % (exp, scan)) - else: - wksp = wsmanager.reducedws - - # save - filetype = filetype.lower() - if "gsas" in filetype: - if sfilename.endswith('.dat') is True: - sfilename.replace('.dat', '.gsa') - - api.SaveGSS(InputWorkspace=wksp, - Filename=sfilename, - SplitFiles=False, Append=False, - MultiplyByBinWidth=False, - Bank=1, - Format="SLOG", - ExtendedHeader=True) - # ENDIF - - if "fullprof" in filetype: - if sfilename.endswith('.gsa') is True: - sfilename.replace('.gsa', '.dat') - - api.SaveFocusedXYE(InputWorkspace=wksp, - StartAtBankNumber=1, - Filename=sfilename) - # ENDIF - - if "topas" in filetype: - sfilename = sfilename[:-4] + ".xye" - api.SaveFocusedXYE(InputWorkspace=wksp, - Filename=sfilename, - Format="TOPAS") - # ENDIF - - return - - def saveProcessedVanadium(self, expno, scanno, savefilename): - """ Save processed vanadium data - """ - # Get workspace - wsmanager = self.getWorkspace(expno, scanno, raiseexception=True) - - if wsmanager.isSmoothApplied() is True: - wksp = wsmanager.getProcessedVanadiumWSTemp() - else: - wksp = wsmanager.getProcessedVanadiumWS() - - # Save - api.SaveFocusedXYE(InputWorkspace=wksp, - StartAtBankNumber=1, - Filename=savefilename) - - return - - def setWavelength(self, exp, scan, wavelength): - """ Set wavelength for a specific scan - """ - exp = int(exp) - scan = int(scan) - if wavelength is None: - self._myWavelengthDict[(exp, scan)] = None - else: - self._myWavelengthDict[(exp, scan)] = float(wavelength) - - return - - def smoothVanadiumSpectrum(self, expno, scanno, smoothparams_str): - """ - """ - # Get reduced workspace - wsmanager = self.getWorkspace(expno, scanno, raiseexception=True) - vanRun = wsmanager.getProcessedVanadiumWS() - outws = vanRun.name() + "_smooth" - - outws = api.FFTSmooth(InputWorkspace=vanRun, - OutputWorkspace=outws, - Filter="Butterworth", - Params=smoothparams_str, - IgnoreXBins=True, - AllSpectra=True) - - if outws is not None: - wsmanager.setProcessedVanadiumDataTemp(outws, "FFT smooth") - - return True - - def stripVanadiumPeaks(self, exp, scan, binparams, vanpeakposlist=None): - """ Strip vanadium peaks - - Arguments: - - binparams :: string as the list of xmin, binsize, xmax or just binsize - - vanpeakposlist :: list of peak positions. If none, then using default - - Return :: - """ - # Get reduced workspace - wsmanager = self.getWorkspace(exp, scan, raiseexception=True) - wksp = wsmanager.reducedws - if wksp is None: - raise NotImplementedError("Unable to rebin the data for exp=%d, scan=%d because either data MD workspace and \ - monitor MD workspace is not present." % (exp, scan)) - - # Convert unit to Time-of-flight by rebinning - xaxis_unit = wksp.getAxis(0).getUnit().unitID() - if xaxis_unit != 'Degrees': - wksp = api.ConvertCWPDToSpectra(InputWorkspace=wksp, - OutputWorkspace=wksp.name(), - Params=binparams) - - # Vanadium peaks positions - if vanpeakposlist is None or len(vanpeakposlist) == 0: - vanpeakposlist = wsmanager.getVanadiumPeaks() - if vanpeakposlist is None: - raise NotImplementedError('No vanadium peaks has been set up.') - # ENDIF - - outwsname = wksp.name() + "_rmVan" - wksp = api.StripPeaks(InputWorkspace=wksp, - OutputWorkspace=outwsname, - PeakPositions=numpy.array(vanpeakposlist)) - - # Store - wsmanager.setProcessedVanadiumData(wksp) - - return True - - def _generateTableWS(self, vancorrdict): - """ Create table workspace - """ - tablews = api.CreateEmptyTableWorkspace(OutputWorkspace="tempcorrtable") - tablews.addColumn('int', 'DetID') - tablews.addColumn('double', 'Correction') - - for detid in sorted(vancorrdict.keys()): - tablews.addRow([detid, vancorrdict[detid]]) - - return tablews - - def _getRunNumberList(self, datamdws): - """ Get list of run number (i.e., Pt) from an MDEventWorkspace - - Return :: list of MDEventWrokspace - """ - ptnolist = [] - - numexpinfo = datamdws.getNumExperimentInfo() - for i in range(numexpinfo): - expinfo = datamdws.getExperimentInfo(i) - runid = expinfo.run().getProperty('run_number').value - if runid >= 0: - ptnolist.append(runid) - # ENDFOR - - return sorted(ptnolist) - - def _getValueFromTable(self, tablews, colname, rowindex=0): - """ Get value from a table workspace - """ - colnames = tablews.getColumnNames() - try: - colindex = colnames.index(colname) - rvalue = tablews.cell(rowindex, colindex) - except ValueError: - rvalue = None - - return rvalue - - -# ------------------------------------------------------------------------------- -# External Methods -# ------------------------------------------------------------------------------- - - -def downloadFile(url, localfilepath): - """ - Test: 'http://neutron.ornl.gov/user_data/hb2a/exp400/Datafiles/HB2A_exp0400_scan0001.dat' - - Arguments: - - localfilepath :: local data file name with full path. - """ - # open URL - try: - response = urlopen(url) - wbuf = response.read() - except HTTPError as e: - # Unable to download file - if str(e).count('HTTP Error 404') == 1: - return (False, str(e)) - else: - raise NotImplementedError("Unable to download file from %s\n\tCause: %s." % (url, str(e))) - # ENDIFELSE - - if wbuf.count('not found') > 0: - return (False, "File cannot be found at %s." % (url)) - - ofile = open(localfilepath, 'w') - ofile.write(wbuf) - ofile.close() - - return (True, "") diff --git a/scripts/HFIRPowderReduction/HfirPDReductionGUI.py b/scripts/HFIRPowderReduction/HfirPDReductionGUI.py deleted file mode 100644 index 23da43ffa00f1234f6f3a151d1a13b1339295957..0000000000000000000000000000000000000000 --- a/scripts/HFIRPowderReduction/HfirPDReductionGUI.py +++ /dev/null @@ -1,2419 +0,0 @@ -# pylint: disable=invalid-name, relative-import, too-many-lines,too-many-instance-attributes,too-many-arguments,C901 -################################################################################ -# Main class for HFIR powder reduction GUI -# Key word for future developing: FUTURE, NEXT, REFACTOR, RELEASE 2.0 -################################################################################ - -from __future__ import (absolute_import, division, print_function) -from six.moves import range -import numpy -import os - -try: - import urllib.request as urllib -except ImportError: - import urllib - -from .ui_MainWindow import Ui_MainWindow # import line for the UI python class -from PyQt4 import QtCore, QtGui - -try: - _fromUtf8 = QtCore.QString.fromUtf8 -except AttributeError: - def _fromUtf8(s): - return s - -import mantid -import mantidqtpython as mqt -from . import HfirPDReductionControl - -# ----- default configuration --------------- -DEFAULT_SERVER = 'http://neutron.ornl.gov/user_data' -DEFAULT_INSTRUMENT = 'hb2a' -DEFAULT_WAVELENGTH = 2.4100 - - -# ------------------------------------------- - - -class EmptyError(Exception): - """ Exception for finding empty input for integer or float - """ - - def __init__(self, value): - """ Init - """ - Exception.__init__(self) - self.value = value - - def __str__(self): - return repr(self.value) - - -class MultiScanTabState(object): - """ Description of the state of the multi-scan-tab is in - """ - NO_OPERATION = 0 - RELOAD_DATA = 1 - REDUCE_DATA = 2 - - def __init__(self): - """ Initialization - :return: - """ - self._expNo = -1 - self._scanList = [] - self._xMin = None - self._xMax = None - self._binSize = 0 - self._unit = '' - self._plotRaw = False - self._useDetEfficiencyCorrection = False - self._excludeDetectors = [] - - def compare_state(self, tab_state): - """ Compare this tab state and another tab state - :param tab_state: - :return: - """ - if isinstance(tab_state, MultiScanTabState) is False: - raise NotImplementedError('compare_state must have MultiScanTabStatus as input.') - - if self._expNo != tab_state.getExpNumber() or self._scanList != tab_state.getScanList: - return self.RELOAD_DATA - - for attname in self.__dict__.keys(): - if self.__getattribute__(attname) != tab_state.__getattribute__(attname): - return self.REDUCE_DATA - - return self.NO_OPERATION - - def getExpNumber(self): - """ Get experiment number - :return: - """ - return self._expNo - - def getScanList(self): - """ Get the list of scans - :return: - """ - return self._scanList[:] - - # pyline: disable=too-many-arguments - def setup(self, exp_no, scan_list, min_x, max_x, bin_size, unit, raw, correct_det_eff, exclude_dets): - """ - Set up the object - :param exp_no: - :param scan_list: - :param min_x: - :param max_x: - :param bin_size: - :param unit: - :param raw: - :param correct_det_eff: - :param exclude_dets: - :return: - """ - self._expNo = int(exp_no) - if isinstance(scan_list, list) is False: - raise NotImplementedError('Scan_List must be list!') - self._scanList = scan_list - self._xMin = min_x - self._xMax = max_x - self._binSize = float(bin_size) - self._unit = str(unit) - self._plotRaw = raw - self._useDetEfficiencyCorrection = correct_det_eff - self._excludeDetectors = exclude_dets - - return - - -# pylint: disable=too-many-public-methods,too-many-branches,too-many-locals,too-many-statements -class MainWindow(QtGui.QMainWindow): - """ Class of Main Window (top) - """ - - # Copy to ui.setupUI - # # Version 3.0 + Import for ui_MainWindow.py - # from MplFigureCanvas import Qt4MplCanvas - - # # Replace 'self.graphicsView = QtGui.QtGraphicsView' with the following - # self.graphicsView = Qt4MplCanvas(self.centralwidget) - # self.mainplot = self.graphicsView.getPlot() - - def __init__(self, parent=None): - """ Initialization and set up - """ - # Base class - QtGui.QMainWindow.__init__(self, parent) - - # UI Window (from Qt Designer) - self.ui = Ui_MainWindow() - self.ui.setupUi(self) - - # Define gui-event handling - - # menu - self.connect(self.ui.actionQuit, QtCore.SIGNAL('triggered()'), - self.doExist) - self.connect(self.ui.actionFind_Help, QtCore.SIGNAL('triggered()'), - self.doHelp) - - # main - self.connect(self.ui.comboBox_wavelength, QtCore.SIGNAL('currentIndexChanged(int)'), - self.doUpdateWavelength) - self.connect(self.ui.pushButton_browseExcludedDetFile, QtCore.SIGNAL('clicked()'), - self.doBrowseExcludedDetetorFile) - self.connect(self.ui.checkBox_useDetExcludeFile, QtCore.SIGNAL('stateChanged(int)'), - self.do_enable_excluded_dets) - - # tab 'Raw Detectors' - self.connect(self.ui.pushButton_plotRaw, QtCore.SIGNAL('clicked()'), - self.doPlotRawPtMain) - self.connect(self.ui.pushButton_ptUp, QtCore.SIGNAL('clicked()'), - self.do_plot_raw_pt_prev) - self.connect(self.ui.pushButton_ptDown, QtCore.SIGNAL('clicked()'), - self.doPlotRawPtNext) - self.connect(self.ui.pushButton_clearRawDets, QtCore.SIGNAL('clicked()'), - self.doClearRawDetCanvas) - - # tab 'Individual Detectors' - self.connect(self.ui.pushButton_plotIndvDet, QtCore.SIGNAL('clicked()'), - self.doPlotIndvDetMain) - self.connect(self.ui.pushButton_plotPrevDet, QtCore.SIGNAL('clicked()'), - self.doPlotIndvDetPrev) - self.connect(self.ui.pushButton_plotNextDet, QtCore.SIGNAL('clicked()'), - self.doPlotIndvDetNext) - self.connect(self.ui.pushButton_clearCanvasIndDet, QtCore.SIGNAL('clicked()'), - self.doClearIndDetCanvas) - self.connect(self.ui.pushButton_plotLog, QtCore.SIGNAL('clicked()'), - self.do_plot_sample_log) - - # tab 'Normalized' - self.connect(self.ui.pushButton_loadData, QtCore.SIGNAL('clicked()'), - self.doLoadData) - self.connect(self.ui.pushButton_prevScan, QtCore.SIGNAL('clicked()'), - self.doLoadReduceScanPrev) - self.connect(self.ui.pushButton_nextScan, QtCore.SIGNAL('clicked()'), - self.doLoadReduceScanNext) - self.connect(self.ui.pushButton_unit2theta, QtCore.SIGNAL('clicked()'), - self.doReduce2Theta) - self.connect(self.ui.pushButton_unitD, QtCore.SIGNAL('clicked()'), - self.doReduceDSpacing) - self.connect(self.ui.pushButton_unitQ, QtCore.SIGNAL('clicked()'), - self.doReduceQ) - self.connect(self.ui.pushButton_saveData, QtCore.SIGNAL('clicked()'), - self.doSaveData) - self.connect(self.ui.pushButton_clearTab2Canvas, QtCore.SIGNAL('clicked()'), - self.doClearCanvas) - - # tab 'Multiple Scans' - self.connect(self.ui.pushButton_loadMultData, QtCore.SIGNAL('clicked()'), - self.doLoadSetData) - self.connect(self.ui.pushButton_mscanBin, QtCore.SIGNAL('clicked()'), - self.doReduceSetData) - self.connect(self.ui.pushButton_mergeScans, QtCore.SIGNAL('clicked()'), - self.doMergeScans) - self.connect(self.ui.pushButton_viewMScan1D, QtCore.SIGNAL('clicked()'), - self.doMergeScanView1D) - self.connect(self.ui.pushButton_view2D, QtCore.SIGNAL('clicked()'), - self.doMergeScanView2D) - self.connect(self.ui.pushButton_viewMerge, QtCore.SIGNAL('clicked()'), - self.doMergeScanViewMerged) - self.connect(self.ui.pushButton_clearMultCanvas, QtCore.SIGNAL('clicked()'), - self.doClearMultiRunCanvas) - self.connect(self.ui.pushButton_saveAllIndScans, QtCore.SIGNAL('clicked()'), - self.doSaveMultipleScans) - self.connect(self.ui.pushButton_saveMerge, QtCore.SIGNAL('clicked()'), - self.doSaveMergedScan) - self.connect(self.ui.pushButton_plotRawMultiScans, QtCore.SIGNAL('clicked()'), - self.do_convert_plot_multi_scans) - - # tab 'Vanadium' - self.connect(self.ui.pushButton_stripVanPeaks, QtCore.SIGNAL('clicked()'), - self.doStripVandiumPeaks) - self.connect(self.ui.pushButton_saveVanRun, QtCore.SIGNAL('clicked()'), - self.doSaveVanRun) - self.connect(self.ui.pushButton_rebin2Theta, QtCore.SIGNAL('clicked()'), - self.doReduceVanadium2Theta) - self.connect(self.ui.pushButton_smoothVanData, QtCore.SIGNAL('clicked()'), - self.doSmoothVanadiumData) - self.connect(self.ui.pushButton_applySmooth, QtCore.SIGNAL('clicked()'), - self.doSmoothVanadiumApply) - self.connect(self.ui.pushButton_undoSmooth, QtCore.SIGNAL('clicked()'), - self.doSmoothVanadiumUndo) - - # tab 'Advanced Setup' - self.connect(self.ui.pushButton_browseCache, QtCore.SIGNAL('clicked()'), - self.doBrowseCache) - self.connect(self.ui.radioButton_useServer, QtCore.SIGNAL('clicked()'), - self.doChangeSrcLocation) - self.connect(self.ui.radioButton_useLocal, QtCore.SIGNAL('clicked()'), - self.doChangeSrcLocation) - self.connect(self.ui.pushButton_browseLocalSrc, QtCore.SIGNAL('clicked()'), - self.doBrowseLocalDataSrc) - self.connect(self.ui.pushButton_chkServer, QtCore.SIGNAL('clicked()'), - self.doCheckSrcServer) - - # Define signal-event handling - - # define event handlers for matplotlib canvas - self.ui.graphicsView_mergeRun.canvas.mpl_connect('button_press_event', - self.on_mouseDownEvent) - self.ui.graphicsView_mergeRun.canvas.mpl_connect('motion_notify_event', - self.on_mouseMotion) - - # Widget type definition - validator0 = QtGui.QIntValidator(self.ui.lineEdit_expNo) - validator0.setBottom(1) - self.ui.lineEdit_expNo.setValidator(validator0) - - validator1 = QtGui.QIntValidator(self.ui.lineEdit_expNo) - validator1.setBottom(1) - self.ui.lineEdit_scanNo.setValidator(validator1) - - validator2 = QtGui.QDoubleValidator(self.ui.lineEdit_wavelength) - validator2.setBottom(0.) - self.ui.lineEdit_wavelength.setValidator(validator2) - - validator3 = QtGui.QDoubleValidator(self.ui.lineEdit_xmin) - validator3.setBottom(0.) - self.ui.lineEdit_xmin.setValidator(validator3) - - validator4 = QtGui.QDoubleValidator(self.ui.lineEdit_xmax) - validator4.setBottom(0.) - self.ui.lineEdit_xmax.setValidator(validator4) - - validator5 = QtGui.QDoubleValidator(self.ui.lineEdit_binsize) - validator5.setBottom(0.) - self.ui.lineEdit_binsize.setValidator(validator5) - - validator6 = QtGui.QDoubleValidator(self.ui.lineEdit_ptNo) - validator6.setBottom(0) - self.ui.lineEdit_ptNo.setValidator(validator6) - - validator7 = QtGui.QDoubleValidator(self.ui.lineEdit_detID) - validator7.setBottom(0) - self.ui.lineEdit_detID.setValidator(validator7) - - validator8 = QtGui.QDoubleValidator(self.ui.lineEdit_min2Theta) - validator8.setBottom(0.) - self.ui.lineEdit_min2Theta.setValidator(validator8) - - validator9 = QtGui.QDoubleValidator(self.ui.lineEdit_max2Theta) - validator9.setBottom(0.) - self.ui.lineEdit_max2Theta.setValidator(validator9) - - validator10 = QtGui.QDoubleValidator(self.ui.lineEdit_binsize2Theta) - validator10.setBottom(0.) - self.ui.lineEdit_binsize2Theta.setValidator(validator10) - - validator11 = QtGui.QIntValidator(self.ui.lineEdit_scanStart) - validator11.setBottom(1) - self.ui.lineEdit_scanStart.setValidator(validator11) - - validator12 = QtGui.QIntValidator(self.ui.lineEdit_scanEnd) - validator12.setBottom(1) - self.ui.lineEdit_scanEnd.setValidator(validator12) - - validator13 = QtGui.QDoubleValidator(self.ui.lineEdit_normalizeMonitor) - validator13.setBottom(0.) - self.ui.lineEdit_normalizeMonitor.setValidator(validator13) - - validator14 = QtGui.QDoubleValidator(self.ui.lineEdit_mergeMinX) - validator14.setBottom(0.) - self.ui.lineEdit_mergeMinX.setValidator(validator14) - - validator15 = QtGui.QDoubleValidator(self.ui.lineEdit_mergeMaxX) - validator15.setBottom(0.) - self.ui.lineEdit_mergeMaxX.setValidator(validator15) - - validator16 = QtGui.QDoubleValidator(self.ui.lineEdit_mergeBinSize) - validator16.setBottom(0.) - self.ui.lineEdit_mergeBinSize.setValidator(validator16) - - # Get initial setup - # RELEASE 2.0 - This part will be implemented soon as default configuration is made - # Mantid configuration - self._instrument = str(self.ui.comboBox_instrument.currentText()) - - # UI widgets setup - self.ui.comboBox_outputFormat.addItems(['Fullprof']) # Supports Fullprof only now, 'GSAS', 'Fullprof+GSAS']) - - # RELEASE 2.0 : Need to disable some widgets... consider to refactor the code - self.ui.radioButton_useServer.setChecked(True) - self.ui.radioButton_useLocal.setChecked(False) - self.ui.checkBox_useDetExcludeFile.setChecked(True) - - self.ui.comboBox_wavelength.setCurrentIndex(0) - self.ui.lineEdit_wavelength.setText('2.41') - - self.ui.pushButton_unit2theta.setText(r'$2\theta$') - - # vanadium spectrum smooth parameters - self.ui.lineEdit_smoothParams.setText('20,2') - - # Set up data source - self._serverAddress = DEFAULT_SERVER - self._srcFromServer = True - self._localSrcDataDir = None - self._srcAtLocal = False - - self._currUnit = '2theta' - - # Workspaces - self._myControl = HfirPDReductionControl.HFIRPDRedControl() - - # Interactive graphics - self._viewMerge_X = None - self._viewMerge_Y = None - - # Control of plots: key = canvas, value = list of 2-integer-tuple (expno, scanno) - self._tabLineDict = {} - self._tabBinParamDict = {} - for key in [2]: - self._tabLineDict[key] = [] - for key in [2, 3, 4]: - self._tabBinParamDict[key] = [None, None, None] - - self._lastMergeLabel = "" - self._lastMergeIndex = -1 - - self._expNo = None - self._scanNo = None - self._detID = None - self._indvXLabel = None - - self._rawDetExpNo = None - self._rawDetScanNo = None - self._rawDetPlotMode = None - self._rawDetPtNo = None - - self._indvDetCanvasMode = 'samplelog' - - # Multiple scan tab - self._multiScanExp = None - self._multiScanList = [] - - # help - self.assistantProcess = QtCore.QProcess(self) - # pylint: disable=protected-access - self.collectionFile = os.path.join(mantid._bindir, '../docs/qthelp/MantidProject.qhc') - version = ".".join(mantid.__version__.split(".")[:2]) - self.qtUrl = 'qthelp://org.sphinx.mantidproject.' + version + '/doc/interfaces/HFIR Powder Reduction.html' - self.externalUrl = 'http://docs.mantidproject.org/nightly/interfaces/HFIR Powder Reduction.html' - - # Initial setup for tab - self.ui.tabWidget.setCurrentIndex(0) - cache_dir = str(self.ui.lineEdit_cache.text()).strip() - if len(cache_dir) == 0 or os.path.exists(cache_dir) is False: - invalid_cache = cache_dir - cache_dir = os.path.expanduser('~') - self.ui.lineEdit_cache.setText(cache_dir) - if len(invalid_cache) == 0: - warning_msg = 'Cache directory is not set. ' - else: - warning_msg = 'Cache directory {0} does not exist. '.format(invalid_cache) - warning_msg += 'Using {0} for caching dowloaded file instead.'.format(cache_dir) - print ('[WARNING] {0}'.format(warning_msg)) - - # Get on hold of raw data file - useserver = self.ui.radioButton_useServer.isChecked() - uselocal = self.ui.radioButton_useLocal.isChecked() - if useserver == uselocal: - self._logWarning("It is logically wrong to set up (1) neither server or local dir to " - "access data or (2) both server and local dir to retrieve data. " - "As default, it is set up to download data from server.") - useserver = True - uselocal = False - self.ui.radioButton_useServer.setChecked(True) - self.ui.radioButton_useLocal.setChecked(False) - - # register startup - mantid.UsageService.registerFeatureUsage("Interface", "HfirPowderReduction", False) - - return - - # -- Event Handling ---------------------------------------------------- - - def doBrowseCache(self): - """ Pop out a dialog to let user specify the directory to - cache downloaded data - """ - # home directory - homedir = str(self.ui.lineEdit_cache.text()).strip() - if len(homedir) > 0 and os.path.exists(homedir): - home = homedir - else: - home = os.getcwd() - - # pop out a dialog - dirs = str(QtGui.QFileDialog.getExistingDirectory(self, 'Get Directory', home)) - - # set to line edit - if dirs != home: - self.ui.lineEdit_cache.setText(dirs) - - return - - def doBrowseExcludedDetetorFile(self): - """ Browse excluded detector's file - Return :: None - """ - # Get file name - filefilter = "Text (*.txt);;Data (*.dat);;All files (*)" - curDir = os.getcwd() - excldetfnames = QtGui.QFileDialog.getOpenFileNames(self, 'Open File(s)', curDir, filefilter) - try: - excldetfname = excldetfnames[0] - self.ui.lineEdit_excludedDetFileName.setText(excldetfname) - except IndexError: - # return if there is no file selected - return - - # Parse det exclusion file - print("Detector exclusion file name is %s." % (excldetfname)) - excludedetlist, errmsg = self._myControl.parseExcludedDetFile('HB2A', excldetfname) - if len(errmsg) > 0: - self._logError(errmsg) - textbuf = "" - for detid in excludedetlist: - textbuf += "%d," % (detid) - if len(textbuf) > 0: - textbuf = textbuf[:-1] - self.ui.lineEdit_detExcluded.setText(textbuf) - - def doBrowseLocalDataSrc(self): - """ Browse local data storage - """ - msg = "Browse local data storage location. Implement ASAP" - QtGui.QMessageBox.information(self, "Click!", msg) - - def doChangeSrcLocation(self): - """ Source file location is changed - """ - useserver = self.ui.radioButton_useServer.isChecked() - uselocal = self.ui.radioButton_useLocal.isChecked() - - print("Use Server: ", useserver) - print("Use Local : ", uselocal) - - if (useserver and uselocal) or not (useserver or uselocal): - raise NotImplementedError("Impossible for radio buttons") - - self._srcAtLocal = uselocal - self._srcFromServer = useserver - - if uselocal is True: - self.ui.lineEdit_dataIP.setDisabled(True) - self.ui.pushButton_chkServer.setDisabled(True) - self.ui.lineEdit_localSrc.setDisabled(False) - self.ui.pushButton_browseLocalSrc.setDisabled(False) - - else: - self.ui.lineEdit_dataIP.setDisabled(False) - self.ui.pushButton_chkServer.setDisabled(False) - self.ui.lineEdit_localSrc.setDisabled(True) - self.ui.pushButton_browseLocalSrc.setDisabled(True) - - def doCheckSrcServer(self): - """" Check source data server's availability - """ - msg = "Check source data server! Implement ASAP" - QtGui.QMessageBox.information(self, "Click!", msg) - - def doClearCanvas(self): - """ Clear canvas - """ - itab = self.ui.tabWidget.currentIndex() - if itab == 2: - self.ui.graphicsView_reducedData.clearAllLines() - self._tabLineDict[itab] = [] - - def doClearIndDetCanvas(self): - """ Clear the canvas in tab 'Individual Detector' and current plotted lines - in managing dictionary - """ - # Clear all lines on canvas - self.ui.graphicsView_indvDet.clearAllLines() - # Remove their references in dictionary - if self.ui.graphicsView_indvDet in self._tabLineDict: - self._tabLineDict[self.ui.graphicsView_indvDet] = [] - # Reset colur schedule - self.ui.graphicsView_indvDet.resetLineColorStyle() - - def doClearMultiRunCanvas(self): - """ Clear the canvas in tab 'Multiple Run' - - This canvas is applied to both 1D and 2D image. - Clear-all-lines might be not enough to clear 2D image - """ - self.ui.graphicsView_mergeRun.clearCanvas() - - def doClearRawDetCanvas(self): - """ Clear the canvas in tab 'Raw Detector': - only need to clear lines - """ - self.ui.graphicsView_Raw.clearAllLines() - self._tabLineDict[self.ui.graphicsView_Raw] = [] - - def doClearVanadiumCanvas(self): - """ Clear the canvas in tab 'Vanadium' - """ - self.ui.graphicsView_vanPeaks.clearAllLines() - - def doExist(self): - """ Exist the application - """ - clearcache = self.ui.checkBox_delCache.isChecked() - - if clearcache: - urllib.delAllFile(self._cache) - - self.close() - - def doHelp(self): - """ Show help - Copied from DGSPlanner - """ - try: - import pymantidplot - pymantidplot.proxies.showCustomInterfaceHelp('HFIR Powder Reduction') - except ImportError: - self.assistantProcess.close() - self.assistantProcess.waitForFinished() - helpapp = QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.BinariesPath) + QtCore.QDir.separator() - helpapp += 'assistant' - args = ['-enableRemoteControl', '-collectionFile', self.collectionFile, '-showUrl', self.qtUrl] - if os.path.isfile(helpapp) and os.path.isfile(self.collectionFile): - self.assistantProcess.close() - self.assistantProcess.waitForFinished() - self.assistantProcess.start(helpapp, args) - else: - mqt.MantidQt.API.MantidDesktopServices.openUrl(QtCore.QUrl(self.externalUrl)) - def _load_spice_data_to_raw_table(self, exp_no, scan_no, data_file_name): - # flake8: noqa - try: - success = self._myControl.loadSpicePDData(exp_no, scan_no, data_file_name) - return success, "" if success else "Load data failed." - except NotImplementedError as ne: - return False, str(ne) - - def _get_corr_file_names_and_wavelength(self, exp_no, scan_no, data_file_name): - # Obtain the correction file names and wavelength from SPICE file - wavelength_error = False - err_msg = "" - local_dir = os.path.dirname(data_file_name) - try: - status, return_body = self._myControl.retrieveCorrectionData(instrument='HB2A', - exp=exp_no, scan=scan_no, - localdatadir=local_dir) - except NotImplementedError as e: - err_msg = str(e) - if err_msg.count('m1') > 0: - # error is about wavelength - status = False - wavelength_error = True - else: - # other error - raise e - - if status: - auto_wavelength = return_body[0] - van_corr_filename = return_body[1] - excl_det_filename = return_body[2] - - if van_corr_filename is not None: - self.ui.lineEdit_vcorrFileName.setText(van_corr_filename) - if excl_det_filename is not None: - self.ui.lineEdit_excludedDetFileName.setText(excl_det_filename) - else: - auto_wavelength = None - van_corr_filename = None - excl_det_filename = None - return auto_wavelength, van_corr_filename, excl_det_filename, wavelength_error, err_msg - - def _set_wavelength(self, auto_wavelength, wavelength_error, exp_no, scan_no, err_msg): - if auto_wavelength is None: - # unable to get wavelength from SPICE data - self.ui.comboBox_wavelength.setCurrentIndex(4) - if wavelength_error: - self.ui.lineEdit_wavelength.setText(err_msg) - else: - self.ui.lineEdit_wavelength.setText(self.ui.comboBox_wavelength.currentText()) - self._myControl.setWavelength(exp_no, scan_no, wavelength=None) - else: - # get wavelength from SPICE data. set value to GUI - self.ui.lineEdit_wavelength.setText(str(auto_wavelength)) - allowed_wavelengths = [2.41, 1.54, 1.12] - num_items = self.ui.comboBox_wavelength.count() - good = False - for ic in range(num_items - 1): - if abs(auto_wavelength - allowed_wavelengths[ic]) < 0.01: - good = True - self.ui.comboBox_wavelength.setCurrentIndex(ic) - - if not good: - self.ui.comboBox_wavelength.setCurrentIndex(num_items - 1) - - self._myControl.setWavelength(exp_no, scan_no, wavelength=auto_wavelength) - - def _get_and_parse_det_efficiency_file(self, van_corr_filename): - if self.ui.checkBox_useDetEffCorr.isChecked(): - # Apply detector efficiency correction - if van_corr_filename is None: - # browse vanadium correction file - file_filter = "Text (*.txt);;Data (*.dat);;All files (*)" - current_dir = os.getcwd() - van_corr_filenames = QtGui.QFileDialog.getOpenFileNames(self, 'Open File(s)', current_dir, file_filter) - if len(van_corr_filenames) > 0: - van_corr_filename = van_corr_filenames[0] - self.ui.lineEdit_vcorrFileName.setText(str(van_corr_filename)) - else: - self._logError("User does not specify any vanadium correction file.") - self.ui.checkBox_useDetEffCorr.setChecked(False) - - # Parse if it is not None - if van_corr_filename is not None: - detector_efficiency_ws, err_msg = self._myControl.parseDetEffCorrFile('HB2A', van_corr_filename) - if detector_efficiency_ws is None: - print("Parsing detectors efficiency file error: {0}.".format(err_msg)) - return None - else: - return detector_efficiency_ws - else: - return None - - else: - # Not chosen to apply detector efficiency correction:w - return None - - def _parse_spice_data_to_MDEventWS(self, detector_efficiency_table, exp_no, scan_no): - try: - print("Det Efficiency Table WS: ", str(detector_efficiency_table)) - exec_status = self._myControl.parseSpiceData(exp_no, scan_no, detector_efficiency_table) - return exec_status, "" if exec_status else "Parse data failed." - except NotImplementedError as e: - return False, str(e) - - def _parse_detector_exclusion_file(self, exclude_detector_filename): - if exclude_detector_filename is not None: - exclude_detector_list, err_msg = self._myControl.parseExcludedDetFile('HB2A', exclude_detector_filename) - - text_buf = "" - for det_id in exclude_detector_list: - text_buf += "{0},".format(det_id) - if len(text_buf) > 0: - text_buf = text_buf[:-1] - self.ui.lineEdit_detExcluded.setText(text_buf) - - def doLoadData(self, exp=None, scan=None): - """ Load and reduce data - It does not support for tab 'Advanced Setup' - For tab 'Raw Detector' and 'Individual Detector', this method will load data to MDEventWorkspaces - For tab 'Normalized' and 'Vanadium', this method will load data to MDEVentWorkspaces but NOT reduce to single spectrum - """ - # Kick away unsupported tabs - i_tab = self.ui.tabWidget.currentIndex() - tab_text = str(self.ui.tabWidget.tabText(i_tab)) - print("[DB] Current active tab is No. {0} as {1}.".format(i_tab, tab_text)) - - # Rule out unsupported tab - if i_tab == 5: - # 'advanced' - msg = "Tab {0} does not support 'Load Data'. Request is ambiguous.".format(tab_text) - QtGui.QMessageBox.information(self, "Click!", msg) - return - - # Get exp number and scan number - if isinstance(exp, int) and isinstance(scan, int): - # use input - exp_no = exp - scan_no = scan - else: - # read from GUI - try: - exp_no, scan_no = self._uiGetExpScanNumber() - self._logDebug("Attending to load Exp {0} Scan {1}.".format(exp_no, scan_no)) - except NotImplementedError as ne: - self._logError("Error to get Exp and Scan due to {0}.".format(str(ne))) - return - - # Form data file name and download data - status, data_filename = self._uiDownloadDataFile(exp=exp_no, scan=scan_no) - if not status: - self._logError("Unable to download or locate local data file for Exp {0} Scan {1}.".format(exp_no, scan_no)) - - # (Load data for tab 0, 1, 2 and 4) - if i_tab not in [0, 1, 2, 3, 4]: - # Unsupported Tabs: programming error! - err_msg = "{0}-th tab should not get this far.\n".format(i_tab) - err_msg += 'GUI has been changed, but the change has not been considered! iTab = {0}'.format(i_tab) - raise NotImplementedError(err_msg) - - # Load SPICE data to raw table (step 1) - load_success, msg = self._load_spice_data_to_raw_table(exp_no, scan_no, data_filename) - if not load_success: - self._logError(msg) - return - - # Obtain the correction file names and wavelength from SPICE file - (auto_wavelength, van_corr_filename, exclude_detector_filename, wavelength_error, err_msg) \ - = self._load_spice_data_to_raw_table(exp_no, scan_no, data_filename) - - # Set wavelength to GUI except 'multiple scans' - self._set_wavelength(auto_wavelength, wavelength_error, exp_no, scan_no, err_msg) - - # Optionally obtain and parse det effecient file - detector_efficiency_table_ws = self._get_and_parse_det_efficiency_file(van_corr_filename) - - # Parse SPICE data to MDEventWorkspaces - success, msg = self._parse_spice_data_to_MDEventWS(detector_efficiency_table_ws, exp_no, scan_no) - if not success: - self._logError(msg) - return - - # Optionally parse detector exclusion file and set to line text - self._parse_detector_exclusion_file(exclude_detector_filename) - - # Set up some widgets for raw detector data. Won't be applied to tab 3 - if i_tab != 3: - float_sample_log_name_list = self._myControl.getSampleLogNames(exp_no, scan_no) - self.ui.comboBox_indvDetXLabel.clear() - self.ui.comboBox_indvDetXLabel.addItem("2theta/Scattering Angle") - self.ui.comboBox_indvDetXLabel.addItems(float_sample_log_name_list) - self.ui.comboBox_indvDetYLabel.clear() - self.ui.comboBox_indvDetYLabel.addItems(float_sample_log_name_list) - - return True - - def doLoadSetData(self): - """ Load a set of data - This is the first step of doing multiple scans processing - """ - # Get inputs for exp number and scans - try: - rtup = self._uiGetExpScanTabMultiScans() - expno = rtup[0] - scanlist = rtup[1] - except NotImplementedError as nie: - self._logError("Unable to load data set in multiple scans due to %s." % (str(nie))) - - # Load and reduce data - loadstatus = True - for scan in sorted(scanlist): - tempstatus = self.doLoadData(expno, scan) - if not tempstatus: - self.ui.label_mergeMessage.setText('Error to load Exp %d Scan %d.' % (expno, scan)) - loadstatus = False - else: - message = 'Loaded Exp %d Scan %d.' % (expno, scan) - self.ui.label_mergeMessage.setText(message) - - # Load status - if loadstatus: - self.ui.label_mergeMessage.setText('All data files are loaded') - else: - self.ui.label_mergeMessage.setText('Not all data files are loaded') - - # Wave length - haswavelength = True - for scan in scanlist: - if self._myControl.getWavelength(expno, scan) is None: - self._logNotice("Exp %d Scan %d has no wavelength set up." % (expno, scan)) - haswavelength = False - break - - # Set unit box - if haswavelength: - self.ui.comboBox_mscanUnit.clear() - self.ui.comboBox_mscanUnit.addItems(['2theta', 'dSpacing', 'Momentum Transfer (Q)']) - else: - self.ui.comboBox_mscanUnit.clear() - self.ui.comboBox_mscanUnit.addItems(['2theta']) - - return - - def doLoadReduceScanPrev(self): - """ Load and reduce previous scan for tab 'Normalized' - """ - # Reduce scan number by 1 - try: - scanno = int(self.ui.lineEdit_scanNo.text()) - except ValueError: - self._logError("Either Exp No or Scan No is not set up right as integer.") - return - else: - scanno = scanno - 1 - if scanno < 1: - self._logWarning("Scan number is 1 already. Cannot have previous scan") - return - self.ui.lineEdit_scanNo.setText(str(scanno)) - - # Load data - self.ui.lineEdit_scanNo.setText(str(scanno)) - self.doLoadData() - - # Reduce data - self._uiReducePlotNoramlized(self._currUnit) - - def doLoadReduceScanNext(self): - """ Load and reduce next scan for tab 'Normalized' - """ - # Advance scan number by 1 - try: - scanno = int(self.ui.lineEdit_scanNo.text()) - except ValueError: - self._logError("Either Exp No or Scan No is not set up right as integer.") - return False - else: - scanno = scanno + 1 - if scanno < 1: - self._logWarning("Scan number is 1 already. Cannot have previous scan") - return False - - # Load data - self.ui.lineEdit_scanNo.setText(str(scanno)) - execstatus = self.doLoadData() - print("[DB] Load data : ", execstatus) - - # Reduce data - self._uiReducePlotNoramlized(self._currUnit) - - def doMergeScans(self): - """ Merge several scans for tab 'merge' - """ - # Get exp number and list of scans - try: - r = self._uiGetExpScanTabMultiScans() - expno = r[0] - scanlist = r[1] - except NotImplementedError as ne: - self._logError(str(ne)) - return False - - # Check whether the wavelengths are same to merge - try: - wl_list = [] - for scanno in scanlist: - print("Exp %d Scan %d. Wavelength = %s." % ( - expno, scanno, str(self._myControl.getWavelength(expno, scanno)))) - wl_list.append(float(self._myControl.getWavelength(expno, scanno))) - - wl_list = sorted(wl_list) - min_wl = wl_list[0] - max_wl = wl_list[-1] - if max_wl - min_wl > 1.0: - self._logWarning("All scans do not have same wavelengths!") - except TypeError: - self._logError('Not all scans have wavelength set up. Unable to merge scans.') - return - - # Check! - try: - unit = str(self.ui.comboBox_mscanUnit.currentText()) - xmin, binsize, xmax = self._uiGetBinningParams(itab=3) - # wavelength = min_wl - mindex = self._myControl.mergeReduceSpiceData(expno, scanlist, unit, xmin, xmax, binsize) - except Exception as e: - raise e - - label = "Exp %d, Scan %s." % (expno, str(scanlist)) - self._plotMergedReducedData(mindex, label) - self._lastMergeIndex = mindex - self._lastMergeLabel = label - - return - - def doMergeScanView1D(self): - """ Change the multiple runs to 1D - """ - # Highlight the button's color - self.ui.pushButton_view2D.setStyleSheet('QPushButton {background-color: yellow; color: red;}') - self.ui.pushButton_view2D.setEnabled(True) - self.ui.pushButton_viewMScan1D.setStyleSheet('QPushButton {background-color: white; color: gray;}') - self.ui.pushButton_viewMScan1D.setEnabled(False) - - # Process input experiment number and scan list - try: - r = self._uiGetExpScanTabMultiScans() - expno = r[0] - scanlist = r[1] - except NotImplementedError as e: - self._logError(str(e)) - return False - - # Clear image - canvas = self.ui.graphicsView_mergeRun - canvas.clearAllLines() - canvas.clearCanvas() - - # Plot data - unit = str(self.ui.comboBox_mscanUnit.currentText()) - xlabel = self._getXLabelFromUnit(unit) - - for scanno in scanlist: - label = "Exp %s Scan %s" % (str(expno), str(scanno)) - self._plotReducedData(expno, scanno, canvas, xlabel, label=label, clearcanvas=False) - - def doMergeScanView2D(self): - """ Change the merged run's view to 2D plot - """ - # Highlight button color and change the color of another one - self.ui.pushButton_view2D.setStyleSheet('QPushButton {background-color: white; color: gray;}') - self.ui.pushButton_view2D.setEnabled(False) - self.ui.pushButton_viewMScan1D.setStyleSheet('QPushButton {background-color: yellow; color: red;}') - self.ui.pushButton_viewMScan1D.setEnabled(True) - - # Get list of data to plot - r = self._uiGetExpScanTabMultiScans() - expno = r[0] - scanlist = r[1] - - # Convert the workspaces to 2D vector - vecylist = [] - yticklabels = [] - xmin = None - xmax = None - for scanno in scanlist: - # put y values to list for constructing 2D array - vecx, vecy = self._myControl.getVectorToPlot(expno, scanno) - - vecylist.append(vecy) - yticklabels.append('Exp %d Scan %d' % (expno, scanno)) - - # set up range of x - if xmin is None: - xmin = vecx[0] - xmax = vecx[-1] - - dim2array = numpy.array(vecylist) - - # Plot - holdprev = False - self.ui.graphicsView_mergeRun.clearAllLines() - self.ui.graphicsView_mergeRun.addPlot2D(dim2array, xmin=xmin, xmax=xmax, ymin=0, - ymax=len(vecylist), holdprev=holdprev, yticklabels=yticklabels) - - def doMergeScanViewMerged(self): - """ Change the merged run's view to 1D plot - """ - # Highlight the button's color - self.ui.pushButton_view2D.setStyleSheet('QPushButton {color: red;}') - self.ui.pushButton_view2D.setEnabled(True) - self.ui.pushButton_viewMScan1D.setStyleSheet('QPushButton {color: red;}') - self.ui.pushButton_viewMScan1D.setEnabled(True) - - # Clear image - self.ui.graphicsView_mergeRun.clearCanvas() - - # Plot - self._plotMergedReducedData(mkey=self._lastMergeIndex, label=self._lastMergeLabel) - - def doPlotIndvDetMain(self): - """ Plot individual detector - """ - # Get exp and scan numbers and check whether the data has been loaded - try: - expno = self._getInteger(self.ui.lineEdit_expNo) - scanno = self._getInteger(self.ui.lineEdit_scanNo) - except EmptyError as e: - self._logError(str(e)) - return - - # Get detector ID and x-label option - try: - status, detidlist = self._getIntArray(self.ui.lineEdit_detID.text()) - if status is False: - errmsg = detidlist - print("Unable to parse detector IDs due to %s." % (errmsg)) - return - else: - print("[DB] Detectors to plot: %s" % (detidlist)) - except EmptyError: - self._logError("Detector ID must be specified for plotting individual detector.") - return - - # Over plot previous or clear - overplot = self.ui.checkBox_overPlotIndvDet.isChecked() - if overplot is False: - self.doClearIndDetCanvas() - - xlabel = str(self.ui.comboBox_indvDetXLabel.currentText()).strip() - if xlabel != "" and xlabel != "Pt." and xlabel != "2theta/Scattering Angle": - # Plot with sample logs other than Pt. - self._logNotice("New Feature: X-label %s is supported for plotting individual detector's counts. " - " Set to detector angle." % xlabel) - xlabel = xlabel - else: - # Plot with Pt. or detector angles - if xlabel != "Pt.": - xlabel = "" - self._logNotice("X-label for individual detectror is '%s'." % (xlabel)) - - # plot - for detid in sorted(detidlist): - try: - self._plot_individual_detector_counts(expno, scanno, detid, xlabel, resetboundary=not overplot) - self._expNo = expno - self._scanNo = scanno - self._detID = detid - self._indvXLabel = xlabel - except NotImplementedError as e: - self._logError(str(e)) - - def doPlotIndvDetNext(self): - """ Plot next raw detector signals for tab 'Individual Detector' - """ - # Plot - try: - currdetid = self._detID + 1 - - # Over plot previous or clear - overplot = self.ui.checkBox_overPlotIndvDet.isChecked() - if overplot is False: - self.doClearIndDetCanvas() - - self._plot_individual_detector_counts(self._expNo, self._scanNo, currdetid, - self._indvXLabel) - except KeyError as e: - self._logError(str(e)) - else: - self._detID = currdetid - - # Update widget - self.ui.lineEdit_detID.setText(str(self._detID)) - - def doPlotIndvDetPrev(self): - """ Plot previous individual detector's signal for tab 'Individual Detector' - """ - # Plot - try: - currdetid = self._detID - 1 - - # Over plot previous or clear - overplot = self.ui.checkBox_overPlotIndvDet.isChecked() - if overplot is False: - self.doClearIndDetCanvas() - - self._plot_individual_detector_counts(self._expNo, self._scanNo, currdetid, - self._indvXLabel) - except KeyError as e: - self._logError(str(e)) - else: - self._detID = currdetid - - # Update widget - self.ui.lineEdit_detID.setText(str(self._detID)) - - def do_convert_plot_multi_scans(self): - """ Convert individual plots from normalized to raw or vice verse - """ - # Identify the mode - if str(self.ui.pushButton_plotRawMultiScans.text()) == 'Plot Raw': - new_mode = 'Plot Raw' - else: - new_mode = 'Plot Normalized' - - # Get information - try: - min_x = self._getFloat(self.ui.lineEdit_mergeMinX) - except EmptyError: - min_x = None - try: - max_x = self._getFloat(self.ui.lineEdit_mergeMaxX) - except EmptyError: - max_x = None - bin_size = self._getFloat(self.ui.lineEdit_mergeBinSize) - - # Process input experiment number and scan list - try: - r = self._uiGetExpScanTabMultiScans() - exp_no = r[0] - scan_list = r[1] - except NotImplementedError as e: - self._logError(str(e)) - return False - - # Re-process the data - if new_mode == 'Plot Raw': - if self._multiScanList is None or self._multiScanExp is None: - raise NotImplementedError('Experiment and scan list are not set up for plot raw.') - self._myControl.scale_to_raw_monitor_counts(self._multiScanExp, self._multiScanList, min_x, max_x, bin_size) - else: - self._myControl.reset_to_normalized(self._multiScanExp, self._multiScanList, min_x, max_x, bin_size) - - # Clear image - canvas = self.ui.graphicsView_mergeRun - canvas.clearAllLines() - canvas.clearCanvas() - canvas.resetLineColorStyle() - - # Plot data - unit = str(self.ui.comboBox_mscanUnit.currentText()) - xlabel = self._getXLabelFromUnit(unit) - - for scan_no in scan_list: - label = "Exp %s Scan %s" % (str(exp_no), str(scan_no)) - self._plotReducedData(exp_no, scan_no, canvas, xlabel, label=label, clearcanvas=False) - - # Change the button name - if new_mode == 'Plot Raw': - self.ui.pushButton_plotRawMultiScans.setText('Plot Normalized') - else: - self.ui.pushButton_plotRawMultiScans.setText('Plot Raw') - - def doPlotRawPtMain(self): - """ Plot current raw detector signal for a specific Pt. - """ - # Get experiment number and scan number for data file - try: - expno = self._getInteger(self.ui.lineEdit_expNo) - scanno = self._getInteger(self.ui.lineEdit_scanNo) - except EmptyError as e: - self._logError(str(e)) - return - - # plot options - doOverPlot = bool(self.ui.checkBox_overpltRawDet.isChecked()) - plotmode = str(self.ui.comboBox_rawDetMode.currentText()) - try: - ptNo = self._getInteger(self.ui.lineEdit_ptNo) - except EmptyError: - ptNo = None - - # plot - print("[DB] Plot Raw Detector: PlotMode = %s." % (plotmode)) - execstatus = self._plotRawDetSignal(expno, scanno, plotmode, ptNo, doOverPlot) - - # set global values if good - if execstatus is True: - self._rawDetPtNo = ptNo - self._rawDetExpNo = expno - self._rawDetScanNo = scanno - self._rawDetPlotMode = plotmode - else: - print("[Error] Execution fails with signal %s. " % (str(execstatus))) - - def doPlotRawPtNext(self): - """ Plot next raw detector signals - """ - # Check - if self._rawDetPtNo is not None: - ptno = self._rawDetPtNo + 1 - else: - self._logError("Unable to plot previous raw detector \ - because Pt. or Detector ID has not been set up yet.") - return - - # Get plot mode and plot - plotmode = str(self.ui.comboBox_rawDetMode.currentText()) - overplot = bool(self.ui.checkBox_overpltRawDet.isChecked()) - execstatus = self._plotRawDetSignal(self._rawDetExpNo, self._rawDetScanNo, plotmode, - ptno, overplot) - - # update if it is good to plot - if execstatus: - self._rawDetPtNo = ptno - self.ui.lineEdit_ptNo.setText(str(ptno)) - - def do_enable_excluded_dets(self): - """ Enable or disable the line editor for excluded detectors - :return: - """ - if self.ui.checkBox_useDetExcludeFile.isChecked(): - self.ui.lineEdit_detExcluded.setEnabled(True) - else: - self.ui.lineEdit_detExcluded.setDisabled(True) - - def do_plot_raw_pt_prev(self): - """ Plot previous raw detector - """ - # Validate input - if self._rawDetPtNo is not None: - ptno = self._rawDetPtNo - 1 - else: - self._logError("Unable to plot previous raw detector \ - because Pt. or Detector ID has not been set up yet.") - return - - # get plot mode and do plt - plotmode = str(self.ui.comboBox_rawDetMode.currentText()) - overplot = bool(self.ui.checkBox_overpltRawDet.isChecked()) - execstatus = self._plotRawDetSignal(self._rawDetExpNo, self._rawDetScanNo, plotmode, - ptno, overplot) - - # update if it is good to plot - if execstatus: - self._rawDetPtNo = ptno - self.ui.lineEdit_ptNo.setText(str(ptno)) - - def do_plot_sample_log(self): - """ Plot sample log vs. Pt. in tab 'Individual Detector' - """ - expNo = int(self.ui.lineEdit_expNo.text()) - scanno = int(self.ui.lineEdit_scanNo.text()) - logname = str(self.ui.comboBox_indvDetYLabel.currentText()) - self._plotSampleLog(expNo, scanno, logname) - - def doReduce2Theta(self): - """ Rebin the data and plot in 2theta for tab 'Normalized' - """ - unit = '2theta' - self._uiReducePlotNoramlized(unit) - - def doReduceDSpacing(self): - """ Rebin the data and plot in d-spacing for tab 'Normalized' - """ - # new unit and information - unit = "dSpacing" - self._uiReducePlotNoramlized(unit) - - def doReduceQ(self): - """ Rebin the data and plot in momentum transfer Q for tab 'Normalized' - """ - unit = 'Momentum Transfer (Q)' - self._uiReducePlotNoramlized(unit) - - def doReduceSetData(self): - """ Reduce multiple data - """ - # Get exp number and list of scans - try: - r = self._uiGetExpScanTabMultiScans() - expno = r[0] - scanlist = r[1] - except NotImplementedError as e: - self._logError(str(e)) - return False - else: - self._multiScanExp = expno - self._multiScanList = scanlist - - # Reduce and plot data - unit = str(self.ui.comboBox_mscanUnit.currentText()) - xlabel = self._getXLabelFromUnit(unit) - - canvas = self.ui.graphicsView_mergeRun - # canvas.clearAllLines() NO NEED - canvas.clearCanvas() - canvas.resetLineColorStyle() - - for scan in scanlist: - r = self._uiReduceData(3, unit, expno, scan) - good = r[0] - expno = r[1] - scanno = r[2] - - if good is True: - label = "Exp %s Scan %s" % (str(expno), str(scanno)) - self._plotReducedData(expno, scanno, canvas, xlabel, label=label, clearcanvas=False) - else: - self._logError('Failed to reduce Exp %s Scan %s' % (str(expno), str(scanno))) - - def doReduceVanadium2Theta(self): - """ Rebin MDEventWorkspaces in 2-theta. for pushButton_rebinD - in vanadium peak strip tab - - Suggested workflow - 1. Rebin data - 2. Calculate vanadium peaks in 2theta - 3. - """ - # Reduce data - unit = '2theta' - itab = 4 - r = self._uiReduceData(itab, unit) - good = r[0] - expno = r[1] - scanno = r[2] - - # Plot reduced data and vanadium peaks - if good is True: - canvas = self.ui.graphicsView_vanPeaks - xlabel = self._getXLabelFromUnit(unit) - label = "Exp %s Scan %s" % (str(expno), str(scanno)) - self._plotReducedData(expno, scanno, canvas, xlabel, label=label, clearcanvas=True) - - # plot vanadium peaks - vanpeakpos = self._myControl.getVanadiumPeaksPos(expno, scanno) - self.ui.lineEdit_stripVPeaks.setText(str(vanpeakpos)) - self._plotPeakIndicators(self.ui.graphicsView_vanPeaks, vanpeakpos) - - return good - - def doSaveData(self): - """ Save data - """ - # get exp number and scan number - try: - # exp and scan - expno, scanno = self._uiGetExpScanNumber() - # file type - filetype = str(self.ui.comboBox_outputFormat.currentText()) - # file name - savedatadir = str(self.ui.lineEdit_outputFileName.text()).strip() - if savedatadir is not None and os.path.exists(savedatadir) is True: - homedir = savedatadir - else: - homedir = os.getcwd() - # launch a dialog to get data - filefilter = "All files (*);;Fullprof (*.dat);;GSAS (*.gsa)" - sfilename = str(QtGui.QFileDialog.getSaveFileName(self, 'Save File', homedir, filefilter)) - except NotImplementedError as e: - self._logError(str(e)) - else: - self._myControl.savePDFile(expno, scanno, filetype, sfilename) - - def doSaveMergedScan(self): - """ Save merged scan - """ - homedir = os.getcwd() - filefilter = "Fullprof (*.dat)" - sfilename = str(QtGui.QFileDialog.getSaveFileName(self, 'Save File In Fullprof', homedir, filefilter)) - - self._myControl.saveMergedScan(sfilename, mergeindex=self._lastMergeIndex) - - def doSaveMultipleScans(self): - """ Save multiple scans - """ - # Get experiment number and scans - r = self._uiGetExpScanTabMultiScans() - expno = r[0] - scanslist = r[1] - - # Get base file name - homedir = os.getcwd() - savedir = str(QtGui.QFileDialog.getExistingDirectory(self, 'Get Directory To Save Fullprof', homedir)) - - for scanno in scanslist: - sfilename = os.path.join(savedir, "HB2A_Exp%d_Scan%d_FP.dat" % (expno, scanno)) - self._myControl.savePDFile(expno, scanno, 'fullprof', sfilename) - - def doSaveVanRun(self): - """ Save the vanadium run with peaks removed - """ - # Get experiment number and scan number - try: - expno, scanno = self._uiGetExpScanNumber() - except NotImplementedError as e: - self._logError("Unable to get exp number and scan number for smoothing vanadium data due to %s." % ( - str(e))) - return False - - homedir = os.getcwd() - filefilter = "Fullprof (*.dat)" - sfilename = str(QtGui.QFileDialog.getSaveFileName(self, 'Save File In Fullprof', homedir, filefilter)) - - self._myControl.saveProcessedVanadium(expno, scanno, sfilename) - - def doSmoothVanadiumData(self): - """ Smooth vanadium spectrum - """ - # Get experiment number and scan number - try: - expno, scanno = self._uiGetExpScanNumber() - except NotImplementedError as e: - self._logError("Unable to get exp number and scan number for smoothing vanadium data due to %s." % ( - str(e))) - return False - - smoothparams_str = str(self.ui.lineEdit_smoothParams.text()) - # Smooth data - status = self._myControl.smoothVanadiumSpectrum(expno, scanno, smoothparams_str) - if not status: - self._logError("Failed to smooth vanadium data") - - # Plot - unit = '2theta' - xlabel = self._getXLabelFromUnit(unit) - label = "Vanadium Exp %d Scan %d FFT-Smooth by %s" % (expno, scanno, smoothparams_str) - self._plotVanadiumRun(expno, scanno, xlabel, label, False, True) - - def doSmoothVanadiumApply(self): - """ Apply smoothing effect to vanadium data - """ - # Get experiment number and scan number - try: - expno, scanno = self._uiGetExpScanNumber() - except NotImplementedError as e: - self._logError("Unable to get exp number and scan number for smoothing vanadium data due to %s." % ( - str(e))) - return False - - self._myControl.applySmoothVanadium(expno, scanno, True) - - def doSmoothVanadiumUndo(self): - """ Undo smoothing vanadium - """ - try: - expno, scanno = self._uiGetExpScanNumber() - except NotImplementedError as e: - self._logError("Unable to get exp number and scan number for smoothing vanadium data due to %s." % ( - str(e))) - return False - - self._myControl.applySmoothVanadium(expno, scanno, False) - - def doStripVandiumPeaks(self): - """ Strip vanadium peaks - """ - # Get exp number an scan number - try: - expno, scanno = self._uiGetExpScanNumber() - except NotImplementedError as e: - self._logError("Error to get Exp and Scan due to %s." % (str(e))) - return False - - # Default unit - unit = '2theta' - - # Get and build binning parameter - xmin, binsize, xmax = self._uiGetBinningParams(itab=4) - if xmin is None: - binparams = '%f' % (binsize) - else: - binparams = '%f,%f,%f' % (xmin, binsize, xmax) - - # Strip vanadium peak - good = self._myControl.stripVanadiumPeaks(expno, scanno, binparams, vanpeakposlist=None) - - # Plot - if good: - xlabel = self._getXLabelFromUnit(unit) - label = "Exp %d Scan %d Bin = %.5f Vanadium Stripped" % (expno, scanno, binsize) - self._plotVanadiumRun(expno, scanno, xlabel, label, False) - - def doUpdateWavelength(self): - """ Update the wavelength to line edit - """ - index = self.ui.comboBox_wavelength.currentIndex() - - print("Update wavelength to ", index) - - if index == 0: - wavelength = 2.41 - elif index == 1: - wavelength = 1.54 - elif index == 2: - wavelength = 1.12 - else: - wavelength = None - - self.ui.lineEdit_wavelength.setText(str(wavelength)) - - def on_mouseDownEvent(self, event): - """ Respond to pick up a value with mouse down event - Definition of button_press_event is: - button_press_event(x, y, button, dblclick=False, guiEvent=None) - Thus event has x, y and button. - - event.button has 3 values: - 1: left - 2: middle - 3: right - """ - # FUTURE: Need to make this work - x = event.xdata - y = event.ydata - button = event.button - - if x is not None and y is not None: - # mouse is clicked within graph - if button == 1: - msg = "Mouse 1: You've clicked on a bar with coords:\n %f, %f\n and button %d" % (x, y, button) - print(msg) - elif button == 2: - msg = "Mouse 2: You've clicked on a bar with coords:\n %f, %f\n and button %d" % (x, y, button) - QtGui.QMessageBox.information(self, "Click!", msg) - - elif button == 3: - # right click of mouse will pop up a context-menu - # menu should be self.ui.menu? - menu = QtGui.QMenu(self) - - addAction = QtGui.QAction('Add', self) - addAction.triggered.connect(self.addSomething) - menu.addAction(addAction) - - rmAction = QtGui.QAction('Remove', self) - rmAction.triggered.connect(self.rmSomething) - menu.addAction(rmAction) - - # add other required actions - menu.popup(QtGui.QCursor.pos()) - - def on_mouseMotion(self, event): - """ Event handler for mouse being detected to move - """ - # prev_x = self._viewMerge_X - # prev_y = self._viewMerge_Y - - curx = event.xdata - cury = event.ydata - if curx is None or cury is None: - return - - self._viewMerge_X = event.xdata - self._viewMerge_Y = event.ydata - - def addSomething(self): - """ - """ - # FUTURE - Need to implement how to deal with this - print("Add scan back to merge") - - def rmSomething(self): - """ - """ - # FUTURE - Need to implement how to deal with this - print("Remove a scan from merged data.") - - # -------------------------------------------------------------------------- - # Private methods to plot data - # -------------------------------------------------------------------------- - def _plotIndividualDetCountsVsSampleLog(self, expno, scanno, detid, samplename, raw=True): - """ Plot one specific detector's counts vs. one specified sample log's value - along with all Pts. - For example: detector 11's counts vs. sample_b's value - :param expno: - :param scanno: - :param detid: - :param samplename: - :param raw: boolean whether the output is normalized by monitor counts - :return: - """ - # Validate input - try: - expno = int(expno) - scanno = int(scanno) - detid = int(detid) - samplename = str(samplename) - except ValueError: - raise NotImplementedError("ExpNo, ScanNo or DetID is not integer.") - - # Get the array for detector counts vs. sample log value by mapping Pt. - vecx, vecy = self._myControl.getIndividualDetCountsVsSample(expno, scanno, - detid, samplename, raw) - - # Clear canvas - self.ui.graphicsView_indvDet.clearCanvas() - - # Plot - marker, color = self.ui.graphicsView_indvDet.getNextLineMarkerColorCombo() - self.ui.graphicsView_indvDet.add_plot1d(vec_x=vecx, - vec_y=vecy, - marker=marker, - color=color, - x_label=samplename, - y_label='Counts', - label='DetID = %d' % (detid)) - - # FUTURE: In future, need to find out how to use self._graphIndDevMode - - def _plot_individual_detector_counts(self, expno, scanno, detid, xaxis, resetboundary=False): - """ Plot a specific detector's counts along all experiment points (pt) - :param expno: - :param scanno: - :param detid: - :param xaxis: - :param resetboundary: - :return: - """ - # Validate input - expno = int(expno) - scanno = int(scanno) - detid = int(detid) - - plot_error_bar = self.ui.checkBox_indDetErrorBar.isChecked() - plot_normal = self.ui.checkBox_indDetNormByMon.isChecked() - - # Reject if data is not loaded - if self._myControl.hasDataLoaded(expno, scanno) is False: - self._logError("Data file for Exp %d Scan %d has not been loaded." % (expno, scanno)) - return False - - # Canvas and line information - canvas = self.ui.graphicsView_indvDet - if canvas not in self._tabLineDict: - self._tabLineDict[canvas] = [] - - # get data - self._logNotice("Input x-axis is '%s' for plotting individual detector's counts." % (xaxis)) - if len(xaxis) == 0: - xaxis = None - vecx, vecy = self._myControl.getIndividualDetCounts(expno, scanno, detid, xaxis, plot_normal) - if not isinstance(vecx, numpy.ndarray): - raise NotImplementedError('vecx, vecy must be numpy arrays.') - if plot_error_bar: - y_err = numpy.sqrt(vecy) - else: - y_err = None - - # Plot to canvas - marker, color = canvas.getNextLineMarkerColorCombo() - if xaxis == "" or xaxis == "2theta/Scattering Angle": - xlabel = r'$2\theta$' - else: - xlabel = xaxis - # FUTURE - If it works with any way of plotting, then refactor Pt. with any other sample names - - label = "Detector ID: %d" % (detid) - - if self._tabLineDict[canvas].count((expno, scanno, detid)) == 0: - canvas.add_plot1d(vecx, vecy, marker=marker, color=color, x_label=xlabel, - y_label='Counts', label=label, y_err=y_err) - self._tabLineDict[canvas].append((expno, scanno, detid)) - - if resetboundary: - # Set xmin and xmax about the data for first time - xmin = min(vecx) - xmax = max(vecx) - ymin = min(vecy) - ymax = max(vecy) - else: - # auto setup for image boundary - xmin = min(min(vecx), canvas.getXLimit()[0]) - xmax = max(max(vecx), canvas.getXLimit()[1]) - ymin = min(min(vecy), canvas.getYLimit()[0]) - ymax = max(max(vecy), canvas.getYLimit()[1]) - - dx = xmax - xmin - dy = ymax - ymin - canvas.setXYLimit(xmin - dx * 0.0001, xmax + dx * 0.0001, ymin - dy * 0.0001, ymax + dy * 0.0001) - - # Set canvas mode - # FUTURE: Consider how to use self._graphIndDevMode in future - # self._graphIndDevMode = (xlabel, 'Counts') - - return True - - def _plotPeakIndicators(self, canvas, peakposlist): - """ Plot indicators for peaks - """ - print("[DB] Peak indicators are at ", peakposlist) - - rangey = canvas.getYLimit() - rangex = canvas.getXLimit() - - for pos in peakposlist: - if pos >= rangex[0] and pos <= rangex[1]: - vecx = numpy.array([pos, pos]) - vecy = numpy.array([rangey[0], rangey[1]]) - canvas.add_plot1d(vecx, vecy, color='black', line_style='--') - - def _plotRawDetSignal(self, expno, scanno, plotmode, ptno, dooverplot): - """ Plot the counts of all detectors of a certain Pt. in an experiment - """ - # Validate input - expno = int(expno) - scanno = int(scanno) - - # Set up canvas and dictionary - canvas = self.ui.graphicsView_Raw - if canvas not in self._tabLineDict: - self._tabLineDict[canvas] = [] - - # Check whether data exists - if not self._myControl.hasDataLoaded(expno, scanno): - self._logError("File has not been loaded for Exp %d Scan %d. Load data first!" % (expno, scanno)) - return - - # Get vecx and vecy - if plotmode == "All Pts.": - # Plot all Pts. - vecxylist = self._myControl.getRawDetectorCounts(expno, scanno) - - # Clear previous - self.ui.graphicsView_Raw.clearAllLines() - self.ui.graphicsView_Raw.setLineMarkerColorIndex(0) - self._tabLineDict[canvas] = [] - - elif plotmode == "Single Pts.": - # Plot plot - ptno = int(ptno) - - if not dooverplot: - self.ui.graphicsView_Raw.clearAllLines() - self.ui.graphicsView_Raw.setLineMarkerColorIndex(0) - self._tabLineDict[canvas] = [] - - # Plot one pts. - vecxylist = self._myControl.getRawDetectorCounts(expno, scanno, [ptno]) - - else: - # Raise exception - raise NotImplementedError("Plot mode %s is not supported." % (plotmode)) - - # Set up unit/x-label - unit = r"$2\theta$" - - # plot - xmin = None - xmax = None - ymin = None - ymax = None - for ptno, vecx, vecy in vecxylist: - # FUTURE: Label is left blank as there can be too many labels - label = 'Pt %d' % (ptno) - - # skip if this plot has existed - if self._tabLineDict[canvas].count((expno, scanno, ptno)) == 1: - continue - - marker, color = canvas.getNextLineMarkerColorCombo() - canvas.add_plot1d(vecx, vecy, marker=marker, color=color, x_label=unit, - y_label='intensity', label=label) - - # set up line tuple - self._tabLineDict[canvas].append((expno, scanno, ptno)) - - # auto setup for image boundary - xmin = min(min(vecx), canvas.getXLimit()[0]) - xmax = max(max(vecx), canvas.getXLimit()[1]) - ymin = min(min(vecy), canvas.getYLimit()[0]) - ymax = max(max(vecy), canvas.getYLimit()[1]) - - # Reset canvas x-y limit - if xmin is not None: - dx = xmax - xmin - dy = ymax - ymin - canvas.setXYLimit(xmin - dx * 0.0001, xmax + dx * 0.0001, ymin - dy * 0.0001, ymax + dy * 0.0001) - - return True - - def _plotMergedReducedData(self, mkey, label): - """ Plot the reduced data from merged ... - """ - # get the data - try: - vecx, vecy = self._myControl.getMergedVector(mkey) - except KeyError as e: - self._logError("Unable to retrieve merged reduced data due to %s." % (str(e))) - return - - canvas = self.ui.graphicsView_mergeRun - - # Clear canvas - canvas.clearAllLines() - canvas.clearCanvas() - - # Plot - marker, color = canvas.getNextLineMarkerColorCombo() - xlabel = self._getXLabelFromUnit(self.ui.comboBox_mscanUnit.currentText()) - - canvas.add_plot1d(vecx, vecy, marker=marker, color=color, - x_label=xlabel, y_label='intensity', label=label) - - xmax = max(vecx) - xmin = min(vecx) - dx = xmax - xmin - - ymax = max(vecy) - ymin = min(vecy) - dy = ymax - ymin - - canvas.setXYLimit(xmin - dx * 0.1, xmax + dx * 0.1, ymin - dy * 0.1, ymax + dy * 0.1) - - def _plotReducedData(self, exp, scan, canvas, xlabel, label=None, clearcanvas=True, - spectrum=0, plot_error=False): - """ Plot reduced data for exp and scan - """ - if spectrum != 0: - raise NotImplementedError("Unable to support spectrum = %d case." % (spectrum)) - - # whether the data is load - if not self._myControl.hasReducedWS(exp, scan): - self._logWarning("No data to plot!") - return - - # get to know whether it is required to clear the image - if clearcanvas: - canvas.clearAllLines() - canvas.setLineMarkerColorIndex(0) - - # plot - vec_x, vec_y = self._myControl.getVectorToPlot(exp, scan) - if not isinstance(vec_x, numpy.ndarray): - vec_x = numpy.array(vec_x) - vec_y = numpy.array(vec_y) - - # FUTURE - Should check y_err set up correctly in Mantid or not - if plot_error: - raise RuntimeError('Implement how to return y_err ASAP.') - else: - y_err = None - - # get the marker color for the line - marker, color = canvas.getNextLineMarkerColorCombo() - - # plot - if label is None: - label = "Exp %d Scan %d" % (exp, scan) - - canvas.add_plot1d(vec_x, vec_y, marker=marker, color=color, - x_label=xlabel, y_label='intensity', label=label, - y_err=y_err) - - if clearcanvas: - xmax = max(vec_x) - xmin = min(vec_x) - dx = xmax - xmin - - ymax = max(vec_y) - ymin = min(vec_y) - dy = ymax - ymin - - canvas.setXYLimit(xmin - dx * 0.1, xmax + dx * 0.1, ymin - dy * 0.1, ymax + dy * 0.1) - - def _plotSampleLog(self, expno, scanno, samplelogname): - """ Plot the value of a sample log among all Pt. - """ - # Validate input - expno = int(expno) - scanno = int(scanno) - samplelogname = str(samplelogname) - - # Reject if data is not loaded - if not self._myControl.hasDataLoaded(expno, scanno): - self._logError("Data file for Exp %d Scan %d has not been loaded." % (expno, scanno)) - return False - - # Canvas and line information - self._indvDetCanvasMode = 'samplelog' - - # pop out the xlabel list - # REFACTOR - Only need to set up once if previous plot has the same setup - - if self.ui.comboBox_indvDetXLabel.count() == 0: - floatsamplelognamelist = self._myControl.getSampleLogNames(expno, scanno) - self.ui.comboBox_indvDetXLabel.clear() - self.ui.comboBox_indvDetXLabel.addItems(floatsamplelognamelist) - raise RuntimeError("This X-label combo box should be set up during loading data before.") - - xlabel = str(self.ui.comboBox_indvDetXLabel.currentText()) - - # get data - vecx, vecy = self._myControl.getSampleLogValue(expno, scanno, samplelogname, xlabel) - - # Plot to canvas - canvas = self.ui.graphicsView_indvDet - # FUTURE - Clear canvas (think of a case that no need to clear canvas) - canvas.clearCanvas() - # canvas.clearAllLines() - - marker, color = canvas.getNextLineMarkerColorCombo() - if xlabel is None: - xlabel = r'Pt' - - label = samplelogname - - canvas.add_plot1d(vecx, vecy, marker=marker, color=color, x_label=xlabel, - y_label='Counts', label=label) - - # auto setup for image boundary - xmin = min(vecx) - xmax = max(vecx) - ymin = min(vecy) - ymax = max(vecy) - - dx = xmax - xmin - dy = ymax - ymin - canvas.setXYLimit(xmin - dx * 0.0001, xmax + dx * 0.0001, ymin - dy * 0.0001, ymax + dy * 0.0001) - - return True - - def _plotVanadiumRun(self, exp, scan, xlabel, label, clearcanvas=False, TempData=False): - """ Plot processed vanadium data - - Arguments: - - TempData :: flag whether the vanadium run is a temporary data set - """ - # Check whether the data is load - exp = int(exp) - scan = int(scan) - - if not self._myControl.hasReducedWS(exp, scan): - self._logWarning("No data to plot!") - return - - # Get data to plot - try: - vecx, vecy = self._myControl.getVectorProcessVanToPlot(exp, scan, TempData) - if not TempData: - vecx, vecyOrig = self._myControl.getVectorToPlot(exp, scan) - diffY = vecyOrig - vecy - except NotImplementedError as e: - errmsg = '[Error] Unable to retrieve processed vanadium spectrum for exp %d scan %d. ' \ - 'Reason: %s' % (exp, scan, str(e)) - QtGui.QMessageBox.information(self, "Return!", errmsg) - - return - - # Get to know whether it is required to clear the image - canvas = self.ui.graphicsView_vanPeaks - if TempData: - clearcanvas = False - if clearcanvas: - canvas.clearAllLines() - canvas.setLineMarkerColorIndex(0) - - # get the marker color for the line - if TempData: - marker = None - color = 'blue' - else: - marker, color = canvas.getNextLineMarkerColorCombo() - - # plot - canvas.add_plot1d(vecx, vecy, marker=marker, color=color, - x_label=xlabel, y_label='intensity', label=label) - - if not TempData: - canvas.add_plot1d(vecx, diffY, marker='+', color='green', - x_label=xlabel, y_label='intensity', label='Diff') - - # reset canvas limits - if clearcanvas: - xmax = max(vecx) - xmin = min(vecx) - dx = xmax - xmin - - ymax = max(vecy) - ymin = min(diffY) - dy = ymax - ymin - - canvas.setXYLimit(xmin - dx * 0.1, xmax + dx * 0.1, ymin - dy * 0.1, ymax + dy * 0.1) - - def _uiDownloadDataFile(self, exp, scan): - """ Download data file according to its exp and scan - Either download the data from a server or copy the data file from local - disk - """ - # Get on hold of raw data file - useserver = self.ui.radioButton_useServer.isChecked() - uselocal = self.ui.radioButton_useLocal.isChecked() - if useserver == uselocal: - self._logError("It is logically wrong to set up server/local dir for data.") - self.ui.radioButton_useServer.setChecked(True) - self.ui.radioButton_useLocal.setChecked(False) - - rvalue = False - if self._srcFromServer: - # Use server: build the URl to download data - if not self._serverAddress.endswith('/'): - self._serverAddress += '/' - fullurl = "%s%s/exp%d/Datafiles/%s_exp%04d_scan%04d.dat" % (self._serverAddress, - self._instrument.lower(), exp, - self._instrument.upper(), exp, scan) - print("URL: ", fullurl) - - cachedir = str(self.ui.lineEdit_cache.text()).strip() - if not os.path.exists(cachedir): - invalidcache = cachedir - cachedir = os.getcwd() - self.ui.lineEdit_cache.setText(cachedir) - self._logWarning("Cache directory %s is not valid. " - "Using current workspace directory %s as cache." % (invalidcache, cachedir)) - - filename = '%s_exp%04d_scan%04d.dat' % (self._instrument.upper(), exp, scan) - srcFileName = os.path.join(cachedir, filename) - status, errmsg = HfirPDReductionControl.downloadFile(fullurl, srcFileName) - if not status: - self._logError(errmsg) - srcFileName = None - else: - rvalue = True - - elif self._srcAtLocal: - # Data from local - srcFileName = os.path.join(self._localSrcDataDir, "%s/Exp%d_Scan%04d.dat" % (self._instrument, exp, scan)) - if os.path.exists(srcFileName): - rvalue = True - - else: - raise NotImplementedError("Logic error. Neither downloaded from server.\ - Nor from local drive") - - return (rvalue, srcFileName) - - def _uiGetBinningParams(self, itab): - """ Get binning parameters - - Return: - - xmin, binsize, xmax - """ - # Get value - if itab == 2: - xmin = str(self.ui.lineEdit_xmin.text()) - xmax = str(self.ui.lineEdit_xmax.text()) - binsize = str(self.ui.lineEdit_binsize.text()) - elif itab == 3: - xmin = str(self.ui.lineEdit_mergeMinX.text()) - xmax = str(self.ui.lineEdit_mergeMaxX.text()) - binsize = str(self.ui.lineEdit_mergeBinSize.text()) - elif itab == 4: - xmin = str(self.ui.lineEdit_min2Theta.text()) - xmax = str(self.ui.lineEdit_max2Theta.text()) - binsize = str(self.ui.lineEdit_binsize2Theta.text()) - else: - raise NotImplementedError("Binning parameters are not used for %d-th tab." % (itab)) - - # Parse values - try: - xmin = float(xmin) - xmax = float(xmax) - except ValueError: - xmin = None - xmax = None - else: - if xmin >= xmax: - raise NotImplementedError("set minimum X = %.5f is larger than \ - maximum X = %.5f" % (xmin, xmax)) - - try: - binsize = float(binsize) - except ValueError: - raise NotImplementedError("Error: bins size '%s' is not a float number." % (binsize)) - - # Fix for merging as xmin and xmax must be same for all scans - if itab == 3 and xmin is None: - xmin = 5. - xmax = 150. - - return (xmin, binsize, xmax) - - def _uiGetExcludedDetectors(self): - """ Get excluded detectors from input line edit - - Return :: list of detector IDs to exclude from reduction - """ - excludedetidlist = [] - - if self.ui.checkBox_useDetExcludeFile.isChecked(): - detids_str = str(self.ui.lineEdit_detExcluded.text()).strip() - status, excludedetidlist = self._getIntArray(detids_str) - if status is False: - self._logError("Extra scans are not a list of integers: %s." % ( - str(self.ui.lineEdit_extraScans.text()))) - excludedetidlist = [] - - return excludedetidlist - - def _uiGetExpScanNumber(self): - """ Get experiment number and scan number from widgets for merged - """ - expnostr = self.ui.lineEdit_expNo.text() - scannostr = self.ui.lineEdit_scanNo.text() - try: - expno = int(expnostr) - scanno = int(scannostr) - except ValueError: - raise NotImplementedError("Either Exp No '%s' or Scan No '%s \ - is not set up right as integer." % (expnostr, scannostr)) - - return (expno, scanno) - - def _uiGetExpScanTabMultiScans(self): - """ Get exp number and scans from tab 3 - """ - try: - expno = int(self.ui.lineEdit_expNo.text()) - startscan = int(self.ui.lineEdit_scanStart.text()) - endscan = int(self.ui.lineEdit_scanEnd.text()) - except ValueError as e: - raise RuntimeError("For merging scans, Exp No, Starting scan number and \ - end scan number must be given: %s" % (str(e))) - - # scans = [startscan, endscan] + [others] - [excluded] - status, extrascanlist = self._getIntArray(str(self.ui.lineEdit_extraScans.text())) - if not status: - raise RuntimeError(extrascanlist) - - status, excludedlist = self._getIntArray(str(self.ui.lineEdit_exclScans.text())) - self._logDebug("Excluded list: %s" % (str(excludedlist))) - if not status: - self._logError(excludedlist) - return - - scanslist = list(range(startscan, endscan + 1)) - scanslist.extend(extrascanlist) - scanslist = list(set(scanslist)) - for scan in excludedlist: - scanslist.remove(scan) - - return (expno, sorted(scanslist)) - - def _uiIsBinParamsChange(self, itab, binparams): - """ Check whether current bin parameters are same - as given value - """ - xmin, binsize, xmax = self._uiGetBinningParams(itab) - newbinparams = [xmin, binsize, xmax] - - # check binning - same = True - for i in range(3): - par_0 = binparams[i] - par_1 = newbinparams[i] - - try: - if abs(float(par_0) - float(par_1)) > 1.0E-6: - same = False - except TypeError: - if par_0 is not None or par_1 is not None: - same = False - - if not same: - break - - change = not same - if change: - print("[D...............B]", end=' ') - print("%s vs %s " % (str(xmin), str(self._tabBinParamDict[itab][0])), end=' ') - print("%s vs %s " % (str(xmax), str(self._tabBinParamDict[itab][2])), end=' ') - print("%s vs %s " % (str(binsize), str(self._tabBinParamDict[itab][1]))) - else: - print("[DB] Rebin = False") - - return change - - def _uiReduceData(self, itab, unit, expno=None, scanno=None): - """ Rebin and plot by reading GUI widgets' value - - Arguments: - - itab : index of the tab. Only 2m 3 and 4 are allowed - - unit : string for target unit - """ - # Experiment number and Scan number - if isinstance(expno, int) and isinstance(scanno, int): - # Call from tab-3 multiple scan - pass - else: - try: - expno, scanno = self._uiGetExpScanNumber() - except NotImplementedError as e: - self._logError(str(e)) - return - - # Get binning parameter - xmin, binsize, xmax = self._uiGetBinningParams(itab) - - # Get wavelength - try: - if itab == 3: - wavelength = float(self._myControl.getWavelength(expno, scanno)) - else: - wavelength = float(str(self.ui.lineEdit_wavelength.text())) - except TypeError: - if unit != '2theta': - raise NotImplementedError('Wavelength must be specified for unit %s.' % (unit)) - - # Get scale factor - try: - scalefactor = self._getFloat(self.ui.lineEdit_normalizeMonitor) - except EmptyError: - scalefactor = None - except ValueError as valueerror: - raise ValueError("Unable to get normalization factor due to %s." % (str(valueerror))) - - # Rebin - try: - # rebinned = self._myControl.rebin(expno, scanno, unit, wavelength, xmin, binsize, xmax) - excludeddetlist = self._uiGetExcludedDetectors() - self._myControl.reduceSpicePDData(expno, scanno, - unit, xmin, xmax, binsize, wavelength, excludeddetlist, scalefactor) - - # Record binning - self._tabBinParamDict[itab] = [xmin, binsize, xmax] - except NotImplementedError as e: - self._logError(str(e)) - return (False, expno, scanno) - - return (True, expno, scanno) - - def _uiReducePlotNoramlized(self, unit): - """ Support Reduce2Theta, ReduceDspacing and ReduceQ - """ - itab = 2 - canvas = self.ui.graphicsView_reducedData - expno, scanno = self._uiGetExpScanNumber() - - change = self._uiIsBinParamsChange(itab, self._tabBinParamDict[itab]) - # check whether line record - if unit == self._currUnit and self._tabLineDict[itab].count((expno, scanno)) > 0 and not change: - # there is no need to plot again as line exists - return - - # reduce - r = self._uiReduceData(2, unit) - good = r[0] - expno = r[1] - scanno = r[2] - - # failed to reduce - if not good: - self._logError("Failed to reduce Exp %d Scan %d" % (expno, scanno)) - return - - # clear canvas??? - if unit != self._currUnit: - clearcanvas = True - elif not self.ui.checkBox_clearPrevious.isChecked(): - # NOTE: naming of the widget is VERY confusing. Should be changed to keepPrevious - clearcanvas = True - else: - clearcanvas = False - - # reset record dictionary if unit is different from present - if clearcanvas: - self._tabLineDict[itab] = [] - - self._currUnit = unit - self._tabLineDict[itab].append((expno, scanno)) - - xlabel = self._getXLabelFromUnit(unit) - label = "Exp %s Scan %s" % (str(expno), str(scanno)) - self._plotReducedData(expno, scanno, canvas, xlabel, label=label, clearcanvas=clearcanvas) - - def _logDebug(self, dbinfo): - """ Log debug information - """ - print(dbinfo) - - def _logError(self, errinfo): - """ Log error information - """ - QtGui.QMessageBox.information(self, "Click!", errinfo) - - def _logNotice(self, loginfo): - """ Log error information - """ - msg = '[Notice] %s' % loginfo - print(msg) - # QtGui.QMessageBox.information(self, "Click!", msg) - - def _logWarning(self, warning_info): - """ Log error information - """ - msg = "[Warning]: %s" % (warning_info) - QtGui.QMessageBox.information(self, "OK!", msg) - - def _getFloat(self, lineedit): - """ Get integer from line edit - Exception: ValueError if empty or no input - """ - valuestr = str(lineedit.text()).strip() - if len(valuestr) == 0: - raise EmptyError("Input is empty. It cannot be converted to float.") - - try: - value = float(valuestr) - except ValueError as e: - raise e - - return value - - def _getInteger(self, lineedit): - """ Get integer from line edit - """ - valuestr = str(lineedit.text()).strip() - if len(valuestr) == 0: - raise EmptyError("Input is empty. It cannot be converted to integer.") - - try: - value = int(valuestr) - except ValueError as e: - raise e - - return value - - def _getIntArray(self, intliststring): - """ Validate whether the string can be divided into integer strings. - Allowed: a, b, c-d, e, f - - Return :: 2-tuple (status, list/error message) - """ - intliststring = str(intliststring) - if intliststring == "": - return (True, []) - - # Split by "," - termlevel0s = intliststring.split(",") - intlist = [] - - # For each term - errmsg = "" - returnstatus = True - - for level0term in termlevel0s: - level0term = level0term.strip() - - # split upon dash - - numdashes = level0term.count("-") - if numdashes == 0: - # one integer - valuestr = level0term - try: - intvalue = int(valuestr) - if str(intvalue) != valuestr: - returnstatus = False - errmsg = "Contains non-integer string %s." % (valuestr) - except ValueError: - returnstatus = False - errmsg = "String %s is not an integer." % (valuestr) - else: - intlist.append(intvalue) - - elif numdashes == 1: - # Integer range - twoterms = level0term.split("-") - templist = [] - for i in range(2): - valuestr = twoterms[i] - try: - intvalue = int(valuestr) - if str(intvalue) != valuestr: - returnstatus = False - errmsg = "Contains non-integer string %s." % (valuestr) - except ValueError: - returnstatus = False - errmsg = "String %s is not an integer." % (valuestr) - else: - templist.append(intvalue) - - # break loop - if not returnstatus: - break - intlist.extend(range(templist[0], templist[1] + 1)) - - else: - # Undefined siutation - returnstatus = False - errmsg = "Term %s contains more than 1 dash." % (level0term) - - # break loop if something is wrong - if not returnstatus: - break - - # Return with false - if not returnstatus: - return (False, errmsg) - - return (True, intlist) - - def _getXLabelFromUnit(self, unit): - """ Get X-label from unit - """ - if unit == '2theta': - xlabel = r'$2\theta$ (Degrees)' - elif unit == 'dSpacing': - xlabel = r"d $(\AA)$" - elif unit == 'Momentum Transfer (Q)': - xlabel = r"Q $(\AA^{-1})$" - else: - xlabel = 'Wacky Unknown' - - return xlabel diff --git a/scripts/HFIRPowderReduction/HfirUtility.py b/scripts/HFIRPowderReduction/HfirUtility.py deleted file mode 100644 index 816b19f76ca1cd90e67284151aaae28d15a78dc7..0000000000000000000000000000000000000000 --- a/scripts/HFIRPowderReduction/HfirUtility.py +++ /dev/null @@ -1,149 +0,0 @@ -#pylint: disable=invalid-name -################################################################################ -# -# Utility methods for HFIR powder reduction -# -################################################################################ - -from __future__ import (absolute_import, division, print_function) - - -def makeHB2ADetEfficiencyFileName(expno, m1, colltrans): - """ Fabricate the detector's efficiency file name for HB2A - Example: HB2A_exp0400__Ge_113_IN_vcorr.txt - - * Ge 113: lambda = 2.41 A, m1 = 9.45 - * Ge 115: lambda = 1.54 A, m1 = 0 - * Ge 117 lambda = 1.12 A, No used - - Arguments: - - expno :: experiment number - - m1 :: Ge setup for neutron wavelength (m1) - - colltrans :: for In/Out - - Return :: 3-tuple (filename, filename with URL, wavelength) - """ - # Determine wavelength setup - wavelengthsetup = None - m1 = float(m1) - if abs(m1 - 9.45) < 0.1: - # m1 = 9.45 - wavelength = 2.41 - wavelengthsetup = 'Ge_113' - elif abs(m1) < 0.1: - # m1 = 0. - wavelength = 1.54 - wavelengthsetup = 'Ge_115' - else: - # not defined - raise NotImplementedError("'m1' value %f is not defined for wavelength setup." % (m1)) - - # Determine In/Out, i.e., collimator trans - if colltrans is not None: - # colltrans is in sample log - colltrans = int(colltrans) - if abs(colltrans) == 80: - collimator = 'OUT' - elif colltrans == 0: - collimator = 'IN' - else: - raise NotImplementedError("'colltrans' equal to %d is not defined for IN/OUT." % (colltrans)) - - # Make the detector efficiency file name - expno = int(expno) - defefffilename = 'HB2A_exp%04d__%s_%s_vcorr.txt' % (expno, wavelengthsetup, collimator) - url = 'http://neutron.ornl.gov/user_data/hb2a/exp%d/Datafiles/%s' % (expno, defefffilename) - else: - # old style, no colltrans - defefffilename = None - url = None - # ENDIFELSE - - return (defefffilename, url, wavelength) - - -def makeExcludedDetectorFileName(expno): - """ Make the excluded detectors' file name - - Return :: 2-tuple (file name, URL) - """ - expno = int(expno) - excludeddetfilename = 'HB2A_exp%04d__exclude_detectors.txt' % (expno) - url = 'http://neutron.ornl.gov/user_data/hb2a/exp%d/Datafiles/%s' % (expno, excludeddetfilename) - - return (excludeddetfilename, url) - - -def makeDetGapFileName(expno): - """ Make the detectors' gap file name - - Return :: 2-tuple (file name, URL) - """ - expno = int(expno) - detgapfilename = 'HB2A_exp04d__gaps.txt' % (expno) - url = 'http://neutron.ornl.gov/user_data/hb2a/exp%d/Datafiles/%s' % (expno, detgapfilename) - - return (detgapfilename, url) - - -def parseDetEffCorrFile(vancorrfname): - """ Parse HB2A vanadium correction (detector efficiency correction) file - Return :: dictionary : key = det id, value = factor - """ - try: - cfile = open(vancorrfname, 'r') - lines = cfile.readlines() - cfile.close() - except IOError: - return (False, 'Unable to read vanadium correction file %s.'%(vancorrfname)) - - corrdict = {} - detid = 1 - for line in lines: - line = line.strip() - if len(line) == 0 or line[0] == '#': - continue - - terms = line.split() - factor = float(terms[0]) - corrdict[detid] = factor - - detid += 1 - # ENDFOR - - return (corrdict, '') - - -def parseDetExclusionFile(detexludefilename): - """ Parse excluded detectors file - Detector ID from standard HB2A detector exclusion file start from 0, - while in the other circumstance, it starts from 1. - Therefore Det ID output from here must be plus by 1. - Return :: 2-tuple - Success: Excluded detector IDs list, empty string - Fail: None, error message - """ - try: - defile = open(detexludefilename) - lines = defile.readlines() - defile.close() - except IOError: - return (None, 'Unable to read excluded detector file %s.'%(detexludefilename)) - - detexcludelist = [] - for line in lines: - line = line.strip() - if len(line) == 0 or line[0] == '#': - continue - - terms = line.split() - for term in terms: - try: - detid = int(term) + 1 - detexcludelist.append(detid) - except ValueError: - break - # ENDFOR - # ENDFOR - - return (detexcludelist, '') diff --git a/scripts/HFIRPowderReduction/MainWindow.ui b/scripts/HFIRPowderReduction/MainWindow.ui deleted file mode 100644 index 36cf466aa8c8ae9ebf7a5e502c238f5cf2fe20a9..0000000000000000000000000000000000000000 --- a/scripts/HFIRPowderReduction/MainWindow.ui +++ /dev/null @@ -1,2284 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>MainWindow</class> - <widget class="QMainWindow" name="MainWindow"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>1107</width> - <height>907</height> - </rect> - </property> - <property name="windowTitle"> - <string>MainWindow</string> - </property> - <widget class="QWidget" name="centralwidget"> - <layout class="QGridLayout" name="gridLayout_8"> - <item row="0" column="0"> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QLabel" name="label_expNo"> - <property name="text"> - <string>Exp No</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_expNo"/> - </item> - <item> - <widget class="QLabel" name="label_scanNo"> - <property name="text"> - <string>Scan No</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_scanNo"/> - </item> - <item> - <widget class="QPushButton" name="pushButton_loadData"> - <property name="toolTip"> - <string><html><head/><body><p>For tab 'Raw Detectors', 'Individual Detector', 'Normalized' and 'Vanadium', load SPICE data to MDEventWorkspaces. </p><p><br/></p><p>If the vanadium correction file and excluded detectors files are found, then these files will be parsed and set up. </p><p><br/></p><p>Wavelength will be set according to sample log. If failed, then it will be set to unknown. </p><p><br/></p><p>For tab 'Normalized' and 'Vanadium', there will be NO conversion to single spectrum powder diffraction data with this button. </p></body></html></string> - </property> - <property name="text"> - <string>Load Data</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_calibration"> - <property name="text"> - <string/> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_wavelength"> - <property name="text"> - <string>Wavelength</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="comboBox_wavelength"> - <item> - <property name="text"> - <string>2.41 Ã… (Ge 113 IN)</string> - </property> - </item> - <item> - <property name="text"> - <string>1.54 Ã… (115) </string> - </property> - </item> - <item> - <property name="text"> - <string>1.12 Ã… (117) </string> - </property> - </item> - <item> - <property name="text"> - <string>User Specified</string> - </property> - </item> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_wavelength"/> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="2"> - <widget class="QLineEdit" name="lineEdit_vcorrFileName"/> - </item> - <item row="0" column="0"> - <widget class="QCheckBox" name="checkBox_useDetEffCorr"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>250</width> - <height>0</height> - </size> - </property> - <property name="text"> - <string>Detectors Efficiency Correction</string> - </property> - </widget> - </item> - <item row="0" column="3"> - <widget class="QPushButton" name="pushButton_browseVCorrFile"> - <property name="text"> - <string>Browse</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLabel" name="label_detEffFileName"> - <property name="toolTip"> - <string><html><head/><body><p>Vanadium correction file</p></body></html></string> - </property> - <property name="text"> - <string>Detectors Efficiency File</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QLabel" name="label_excFileName"> - <property name="text"> - <string>Excluded Detectors File</string> - </property> - </widget> - </item> - <item row="0" column="4"> - <widget class="QPushButton" name="pushButton_viewVCorrection"> - <property name="text"> - <string>View Correction</string> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QCheckBox" name="checkBox_useDetExcludeFile"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>250</width> - <height>0</height> - </size> - </property> - <property name="toolTip"> - <string><html><head/><body><p>Apply the exclusion of specified detectors to final data reduction.</p></body></html></string> - </property> - <property name="text"> - <string>Apply Detectors Exclusion</string> - </property> - </widget> - </item> - <item row="0" column="5"> - <widget class="QComboBox" name="comboBox_effCorrect"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string><html><head/><body><p>File name for efficiency correction</p></body></html></string> - </property> - </widget> - </item> - <item row="1" column="2"> - <widget class="QLineEdit" name="lineEdit_excludedDetFileName"/> - </item> - <item row="1" column="3"> - <widget class="QPushButton" name="pushButton_browseExcludedDetFile"> - <property name="text"> - <string>Browse</string> - </property> - </widget> - </item> - <item row="1" column="4"> - <widget class="QLabel" name="label_detExcluded"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>155</width> - <height>0</height> - </size> - </property> - <property name="text"> - <string>Detectors to Exclude </string> - </property> - </widget> - </item> - <item row="1" column="5"> - <widget class="QLineEdit" name="lineEdit_detExcluded"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>20</width> - <height>0</height> - </size> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_25"/> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> - <widget class="QTabWidget" name="tabWidget"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string><html><head/><body><p><br/></p></body></html></string> - </property> - <property name="currentIndex"> - <number>3</number> - </property> - <widget class="QWidget" name="tab_3"> - <attribute name="title"> - <string>Raw Detectors</string> - </attribute> - <layout class="QGridLayout" name="gridLayout_4"> - <item row="0" column="0"> - <layout class="QVBoxLayout" name="verticalLayout_7"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_13"> - <item> - <widget class="QComboBox" name="comboBox_rawDetMode"> - <item> - <property name="text"> - <string>Single Pts.</string> - </property> - </item> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_ptNo"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_ptInfo"> - <property name="text"> - <string>Pt. Number From 1 To Maximum Pt.</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_10"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Preferred</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_14"> - <item> - <widget class="MplFigureCanvas" name="graphicsView_Raw"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - <item> - <layout class="QVBoxLayout" name="verticalLayout_9"> - <item> - <widget class="QPushButton" name="pushButton_plotRaw"> - <property name="text"> - <string>Plot Raw Detector</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="checkBox_overpltRawDet"> - <property name="text"> - <string>Over Plot Previous</string> - </property> - </widget> - </item> - <item> - <spacer name="verticalSpacer_5"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Preferred</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="pushButton_ptUp"> - <property name="text"> - <string>Previous Pt.</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pushButton_ptDown"> - <property name="text"> - <string>Next Pt.</string> - </property> - </widget> - </item> - <item> - <spacer name="verticalSpacer_4"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Preferred</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="pushButton_clearRawDets"> - <property name="text"> - <string>Clear</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_12"/> - </item> - </layout> - </item> - </layout> - </widget> - <widget class="QWidget" name="tab"> - <attribute name="title"> - <string>Normalized</string> - </attribute> - <layout class="QGridLayout" name="gridLayout_2"> - <item row="0" column="0"> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_3"> - <item> - <widget class="QLabel" name="label_normalizeMonitor"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>155</width> - <height>0</height> - </size> - </property> - <property name="text"> - <string>Normalization Monitor</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_normalizeMonitor"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>300</width> - <height>0</height> - </size> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Expanding</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_22"> - <item> - <widget class="QLabel" name="label_outputFormat"> - <property name="text"> - <string>Save As</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="comboBox_outputFormat"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_outputFileName"/> - </item> - <item> - <widget class="QPushButton" name="pushButton_saveData"> - <property name="text"> - <string>Save</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_14"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_5"> - <item> - <layout class="QGridLayout" name="gridLayout_reductionView"> - <item row="0" column="0"> - <widget class="MplFigureCanvas" name="graphicsView_reducedData"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QVBoxLayout" name="verticalLayout_3"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_6"> - <item> - <widget class="QLabel" name="label_18"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Binning To Unit</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QPushButton" name="pushButton_unit2theta"> - <property name="text"> - <string>2theta</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pushButton_unitD"> - <property name="text"> - <string>dSpacing</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pushButton_unitQ"> - <property name="text"> - <string>Q</string> - </property> - </widget> - </item> - <item> - <spacer name="verticalSpacer_6"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Preferred</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_27"> - <item> - <widget class="QLabel" name="label_19"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Binning Parameters</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_26"> - <item> - <widget class="QLabel" name="label_xmin"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Min X</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_xmin"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>10</width> - <height>0</height> - </size> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_28"> - <item> - <widget class="QLabel" name="label_xmax_2"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Max X</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_xmax"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>10</width> - <height>0</height> - </size> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_29"> - <item> - <widget class="QLabel" name="label_binsize"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Bin Size</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_binsize"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>10</width> - <height>0</height> - </size> - </property> - </widget> - </item> - </layout> - </item> - <item> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Preferred</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="pushButton_nextScan"> - <property name="text"> - <string>Next Scan</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pushButton_prevScan"> - <property name="text"> - <string>Prev Scan</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="checkBox_clearPrevious"> - <property name="text"> - <string>Keep Previous Plot</string> - </property> - </widget> - </item> - <item> - <spacer name="verticalSpacer_20"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Preferred</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="pushButton_clearTab2Canvas"> - <property name="toolTip"> - <string><html><head/><body><p>Clear canvas</p></body></html></string> - </property> - <property name="text"> - <string>Clear</string> - </property> - </widget> - </item> - <item> - <spacer name="verticalSpacer_3"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Expanding</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - </layout> - </item> - </layout> - </item> - </layout> - </widget> - <widget class="QWidget" name="tab_5"> - <attribute name="title"> - <string>Individual Detector</string> - </attribute> - <layout class="QGridLayout" name="gridLayout_7"> - <item row="0" column="0"> - <layout class="QVBoxLayout" name="verticalLayout_8"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_21"> - <item> - <widget class="QLabel" name="label_11"> - <property name="text"> - <string>Detector ID</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_detID"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>200</width> - <height>0</height> - </size> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_17"> - <property name="text"> - <string>Detector IDs From 1 to 44</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_18"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QCheckBox" name="checkBox_indDetNormByMon"> - <property name="toolTip"> - <string><html><head/><body><p>Whether the output counts are normalized by monitor counts</p></body></html></string> - </property> - <property name="text"> - <string>Normalized by Monitor</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="checkBox_indDetErrorBar"> - <property name="text"> - <string>Error Bar</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_4"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_17"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_23"> - <item> - <layout class="QVBoxLayout" name="verticalLayout_13"> - <item> - <widget class="MplFigureCanvas" name="graphicsView_indvDet"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QVBoxLayout" name="verticalLayout_12"> - <item> - <spacer name="verticalSpacer_23"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="pushButton_plotIndvDet"> - <property name="toolTip"> - <string><html><head/><body><p>Plot detector(s)'s counts against specified X-axis</p></body></html></string> - </property> - <property name="text"> - <string>Plot Detector Counts</string> - </property> - </widget> - </item> - <item> - <spacer name="verticalSpacer_24"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Preferred</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="label_21"> - <property name="text"> - <string>X-Axis</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="comboBox_indvDetXLabel"> - <property name="toolTip"> - <string><html><head/><body><p>Log names for detector's counts to plot with</p></body></html></string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="checkBox_overPlotIndvDet"> - <property name="text"> - <string>Over Plot Previous</string> - </property> - </widget> - </item> - <item> - <spacer name="verticalSpacer_17"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Minimum</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="pushButton_plotAllDet"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="text"> - <string>Plot All </string> - </property> - </widget> - </item> - <item> - <spacer name="verticalSpacer_14"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Minimum</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="pushButton_plotPrevDet"> - <property name="text"> - <string>Previous Detector</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pushButton_plotNextDet"> - <property name="text"> - <string>Next Detector</string> - </property> - </widget> - </item> - <item> - <spacer name="verticalSpacer_18"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="pushButton_clearCanvasIndDet"> - <property name="text"> - <string>Clear</string> - </property> - </widget> - </item> - <item> - <spacer name="verticalSpacer_15"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Expanding</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="label_6"> - <property name="text"> - <string>Sample Log</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="comboBox_indvDetYLabel"/> - </item> - <item> - <widget class="QPushButton" name="pushButton_plotLog"> - <property name="text"> - <string>Plot Sample Log</string> - </property> - </widget> - </item> - <item> - <spacer name="verticalSpacer_16"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - </layout> - </item> - </layout> - </item> - </layout> - </item> - </layout> - </widget> - <widget class="QWidget" name="tab_merge"> - <attribute name="title"> - <string>Multiple Scans</string> - </attribute> - <layout class="QGridLayout" name="gridLayout_6"> - <item row="0" column="0"> - <layout class="QVBoxLayout" name="verticalLayout_merge"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_19"> - <item> - <widget class="QLabel" name="label_8"> - <property name="toolTip"> - <string><html><head/><body><p>Starting scan number</p></body></html></string> - </property> - <property name="text"> - <string>From</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_scanStart"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_9"> - <property name="toolTip"> - <string><html><head/><body><p>Last scan number included </p></body></html></string> - </property> - <property name="text"> - <string>To</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_scanEnd"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_12"> - <property name="text"> - <string>Others</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_extraScans"/> - </item> - <item> - <widget class="QLabel" name="label_10"> - <property name="toolTip"> - <string><html><head/><body><p>Scan numbers that are excluded from merging beween 'from' and 'to'</p></body></html></string> - </property> - <property name="text"> - <string>Excluded Scans</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_exclScans"/> - </item> - <item> - <spacer name="horizontalSpacer_13"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="pushButton_loadMultData"> - <property name="minimumSize"> - <size> - <width>100</width> - <height>0</height> - </size> - </property> - <property name="text"> - <string>Load Data</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_18"> - <item> - <widget class="QLabel" name="label_15"> - <property name="text"> - <string>Miminum X</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_mergeMinX"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>0</width> - <height>0</height> - </size> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_14"> - <property name="text"> - <string>Maximum X</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_mergeMaxX"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_16"> - <property name="text"> - <string>Bin Size</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_mergeBinSize"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="contextMenuPolicy"> - <enum>Qt::NoContextMenu</enum> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="comboBox_mscanUnit"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>140</width> - <height>0</height> - </size> - </property> - <item> - <property name="text"> - <string>2Theta</string> - </property> - </item> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_3"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="pushButton_mscanBin"> - <property name="minimumSize"> - <size> - <width>100</width> - <height>0</height> - </size> - </property> - <property name="toolTip"> - <string><html><head/><body><p>Rebin the loaded data for</p><p>(1) All scans individually;</p><p>(2) Spectrum of the merged scans</p></body></html></string> - </property> - <property name="text"> - <string>Bin Data</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_16"> - <item> - <layout class="QVBoxLayout" name="verticalLayout_mergeView"> - <item> - <widget class="MplFigureCanvas" name="graphicsView_mergeRun"/> - </item> - </layout> - </item> - <item> - <layout class="QGridLayout" name="gridLayout_9"> - <item row="3" column="0"> - <widget class="QPushButton" name="pushButton_view2D"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>100</width> - <height>0</height> - </size> - </property> - <property name="text"> - <string>View 2D</string> - </property> - </widget> - </item> - <item row="9" column="0"> - <spacer name="verticalSpacer_19"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Expanding</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item row="11" column="0"> - <spacer name="verticalSpacer_10"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item row="5" column="0"> - <spacer name="verticalSpacer_12"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item row="2" column="0"> - <widget class="QPushButton" name="pushButton_viewMScan1D"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>100</width> - <height>0</height> - </size> - </property> - <property name="text"> - <string>View 1D</string> - </property> - </widget> - </item> - <item row="0" column="0"> - <widget class="QPushButton" name="pushButton_plotRawMultiScans"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>100</width> - <height>0</height> - </size> - </property> - <property name="toolTip"> - <string><html><head/><body><p>Plot unmerged reduced spectra from multiple scans.</p></body></html></string> - </property> - <property name="text"> - <string>Plot Raw</string> - </property> - </widget> - </item> - <item row="8" column="0"> - <widget class="QPushButton" name="pushButton_saveMerge"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>100</width> - <height>0</height> - </size> - </property> - <property name="font"> - <font> - <pointsize>10</pointsize> - </font> - </property> - <property name="text"> - <string>Save Merged</string> - </property> - </widget> - </item> - <item row="7" column="0"> - <widget class="QPushButton" name="pushButton_viewMerge"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>100</width> - <height>0</height> - </size> - </property> - <property name="font"> - <font> - <pointsize>10</pointsize> - <weight>50</weight> - <bold>false</bold> - </font> - </property> - <property name="text"> - <string>View Merged</string> - </property> - </widget> - </item> - <item row="10" column="0"> - <widget class="QPushButton" name="pushButton_clearMultCanvas"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>100</width> - <height>0</height> - </size> - </property> - <property name="text"> - <string>Clear</string> - </property> - </widget> - </item> - <item row="4" column="0"> - <widget class="QPushButton" name="pushButton_saveAllIndScans"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>100</width> - <height>0</height> - </size> - </property> - <property name="text"> - <string>Save All</string> - </property> - </widget> - </item> - <item row="6" column="0"> - <widget class="QPushButton" name="pushButton_mergeScans"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>100</width> - <height>0</height> - </size> - </property> - <property name="text"> - <string>Merge</string> - </property> - </widget> - </item> - <item row="1" column="0"> - <spacer name="verticalSpacer_11"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Preferred</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_20"> - <item> - <widget class="QLabel" name="label_13"> - <property name="text"> - <string>Vertical Label In 2D Plot</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="comboBox_2"/> - </item> - <item> - <widget class="QLabel" name="label_mergeMessage"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Message</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </item> - </layout> - </widget> - <widget class="QWidget" name="tab_4"> - <attribute name="title"> - <string>Vanadium</string> - </attribute> - <layout class="QGridLayout" name="gridLayout_5"> - <item row="0" column="0"> - <layout class="QVBoxLayout" name="verticalLayout_5"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_15"> - <item> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>Vanadium Peak List</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_stripVPeaks"> - <property name="enabled"> - <bool>false</bool> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_12"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Preferred</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="pushButton_resetVanPeakList"> - <property name="text"> - <string>Reset Vanadium Peaks List</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_11"> - <item> - <widget class="MplFigureCanvas" name="graphicsView_vanPeaks"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - <item> - <layout class="QVBoxLayout" name="verticalLayout_6"> - <item> - <spacer name="verticalSpacer_9"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Preferred</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="label_3"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Min 2Theta (Degrees)</string> - </property> - </widget> - </item> - <item> - <widget class="Line" name="line"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_min2Theta"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_4"> - <property name="text"> - <string>Max 2Theta (Degrees)</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_max2Theta"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_5"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Bin size (Degrees)</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_binsize2Theta"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pushButton_rebin2Theta"> - <property name="text"> - <string>Bin Vanadium</string> - </property> - </widget> - </item> - <item> - <spacer name="verticalSpacer_8"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Preferred</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="pushButton_stripVanPeaks"> - <property name="text"> - <string>Strip Vanadium Peaks</string> - </property> - </widget> - </item> - <item> - <spacer name="verticalSpacer_21"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Minimum</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item> - <layout class="QVBoxLayout" name="verticalLayout_14"> - <item> - <widget class="QPushButton" name="pushButton_smoothVanData"> - <property name="text"> - <string>Smooth Vanadium</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_20"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Smooth Parameters</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_smoothParams"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pushButton_applySmooth"> - <property name="text"> - <string>Apply Smooth</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pushButton_undoSmooth"> - <property name="text"> - <string>Undo Smooth</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <spacer name="verticalSpacer_22"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Preferred</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="pushButton_saveVanRun"> - <property name="toolTip"> - <string><html><head/><body><p>Save vanadium data for normalization. </p><p>If 'Apply Smooth' is pushed, then the smoothed data will be saved. </p></body></html></string> - </property> - <property name="text"> - <string>Save</string> - </property> - </widget> - </item> - <item> - <spacer name="verticalSpacer_7"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::MinimumExpanding</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - </layout> - </item> - </layout> - </item> - </layout> - </widget> - <widget class="QWidget" name="tab_2"> - <attribute name="title"> - <string>Advanced Setup</string> - </attribute> - <layout class="QGridLayout" name="gridLayout_3"> - <item row="0" column="0"> - <layout class="QVBoxLayout" name="verticalLayout_4"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_10"> - <item> - <widget class="QLabel" name="label_instrument"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>155</width> - <height>0</height> - </size> - </property> - <property name="text"> - <string>Instrument</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="comboBox_instrument"> - <item> - <property name="text"> - <string>HB2A</string> - </property> - </item> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_9"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Preferred</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <spacer name="verticalSpacer_2"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Preferred</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_7"> - <item> - <widget class="QLabel" name="label_cache"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>155</width> - <height>0</height> - </size> - </property> - <property name="toolTip"> - <string><html><head/><body><p>Cache data file download from server to local disk. </p><p>The default is current working directory. </p><p>The cached files will be deleted with normal quit. </p></body></html></string> - </property> - <property name="text"> - <string>Cache Raw Data File</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_cache"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>400</width> - <height>0</height> - </size> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pushButton_browseCache"> - <property name="text"> - <string>Browse</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="checkBox_delCache"> - <property name="toolTip"> - <string><html><head/><body><p>Cached files will be deleted upon quitting normally.</p></body></html></string> - </property> - <property name="text"> - <string>Delete Cache Before Quit</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_6"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_8"> - <item> - <widget class="QRadioButton" name="radioButton_useServer"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>20</width> - <height>0</height> - </size> - </property> - <property name="text"> - <string/> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>135</width> - <height>0</height> - </size> - </property> - <property name="text"> - <string>Server Address</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_dataIP"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>400</width> - <height>0</height> - </size> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pushButton_chkServer"> - <property name="text"> - <string>Check URL</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_7"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_9"> - <item> - <widget class="QRadioButton" name="radioButton_useLocal"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>20</width> - <height>0</height> - </size> - </property> - <property name="text"> - <string/> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_localSrc"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>135</width> - <height>0</height> - </size> - </property> - <property name="text"> - <string>Local Data Storage</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_localSrc"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>400</width> - <height>0</height> - </size> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pushButton_browseLocalSrc"> - <property name="text"> - <string>Browse</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_8"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_4"/> - </item> - </layout> - </item> - <item row="1" column="0"> - <spacer name="verticalSpacer_13"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - </layout> - </widget> - </widget> - </item> - </layout> - </item> - </layout> - </item> - </layout> - </widget> - <widget class="QMenuBar" name="menubar"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>1107</width> - <height>25</height> - </rect> - </property> - <widget class="QMenu" name="menuFile"> - <property name="title"> - <string>File</string> - </property> - <addaction name="actionNew"/> - <addaction name="actionOpen_2"/> - <addaction name="separator"/> - <addaction name="actionQuit"/> - </widget> - <widget class="QMenu" name="menuHelp"> - <property name="title"> - <string>Help</string> - </property> - <addaction name="actionFind_Help"/> - </widget> - <addaction name="menuFile"/> - <addaction name="menuHelp"/> - </widget> - <widget class="QStatusBar" name="statusbar"/> - <action name="actionQuit"> - <property name="text"> - <string>Quit</string> - </property> - <property name="shortcut"> - <string>Ctrl+Q</string> - </property> - </action> - <action name="actionLog"> - <property name="text"> - <string>Log</string> - </property> - <property name="shortcut"> - <string>Ctrl+L</string> - </property> - </action> - <action name="actionNew"> - <property name="text"> - <string>New</string> - </property> - <property name="shortcut"> - <string>Ctrl+N</string> - </property> - </action> - <action name="actionOpen"> - <property name="text"> - <string>Open</string> - </property> - </action> - <action name="actionOpen_2"> - <property name="text"> - <string>Open</string> - </property> - <property name="shortcut"> - <string>Ctrl+O</string> - </property> - </action> - <action name="actionLoad_Setup_File"> - <property name="text"> - <string>Load Setup File</string> - </property> - </action> - <action name="actionFind_Help"> - <property name="text"> - <string>Find Help</string> - </property> - </action> - </widget> - <customwidgets> - <customwidget> - <class>MplFigureCanvas</class> - <extends>QGraphicsView</extends> - <header>HFIRPowderReduction/MplFigureCanvas.h</header> - </customwidget> - </customwidgets> - <resources/> - <connections/> -</ui> diff --git a/scripts/HFIRPowderReduction/MplFigureCanvas.py b/scripts/HFIRPowderReduction/MplFigureCanvas.py deleted file mode 100644 index 61a6e5dcd656f8ecd7712474384c07b0c5db1981..0000000000000000000000000000000000000000 --- a/scripts/HFIRPowderReduction/MplFigureCanvas.py +++ /dev/null @@ -1,669 +0,0 @@ -#pylint: disable=invalid-name,too-many-public-methods,too-many-arguments,non-parent-init-called, too-many-branches -from __future__ import (absolute_import, division, print_function) -import os -import numpy as np - -from PyQt4 import QtGui - -from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas -from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar -from matplotlib.figure import Figure -import matplotlib.image - -MplLineStyles = ['-' , '--' , '-.' , ':' , 'None' , ' ' , ''] -MplLineMarkers = [ - ". (point )", - "* (star )", - "x (x )", - "o (circle )", - "s (square )", - "D (diamond )", - ", (pixel )", - "v (triangle_down )", - "^ (triangle_up )", - "< (triangle_left )", - "> (triangle_right)", - "1 (tri_down )", - "2 (tri_up )", - "3 (tri_left )", - "4 (tri_right )", - "8 (octagon )", - "p (pentagon )", - "h (hexagon1 )", - "H (hexagon2 )", - "+ (plus )", - "d (thin_diamond )", - "| (vline )", - "_ (hline )", - "None (nothing )"] - -MplBasicColors = [ - "black", - "red", - "blue", - "green", - "cyan", - "magenta", - "yellow"] #"white"] - - -class MplFigureCanvas(QtGui.QWidget): - """ A combined graphics view including matplotlib canvas and - a navigation tool bar - """ - - def __init__(self, parent): - """ Initialization - """ - # instantianize parent - QtGui.QWidget.__init__(self, parent) - - # set up canvas - self.canvas = Qt4MplCanvas(self) - self.toolbar = MyNavigationToolbar(self.canvas, self.canvas) - - # set up layout - self.vbox = QtGui.QVBoxLayout(self) - self.vbox.addWidget(self.canvas) - self.vbox.addWidget(self.toolbar) - - # auto line's maker+color list - self._myLineMarkerColorList = [] - self._myLineMarkerColorIndex = 0 - self.setAutoLineMarkerColorCombo() - - return - - def add_plot1d(self, x, y, color=None, label="", x_label=None, y_label=None, marker=None, - linestyle=None, linewidth=1, y_err=None): - """ Add a 1D plot to - :param x: - :param y: - :param color: - :param label: - :param x_label: - :param y_label: - :param marker: - :param linestyle: - :param linewidth: - :return: - """ - self.canvas.add_plot1d(x, y, color, label, x_label, y_label, marker, linestyle, linewidth, y_err) - - return - - def addPlot2D(self, array2d, xmin, xmax, ymin, ymax, holdprev=True, yticklabels=None): - """ Plot a 2D image - Arguments - - array2d :: numpy 2D array - """ - self.canvas.addPlot2D(array2d, xmin, xmax, ymin, ymax, holdprev, yticklabels) - - return - - def addImage(self, imagefilename): - """ Add an image by file - """ - # check - if os.path.exists(imagefilename) is False: - raise NotImplementedError("Image file %s does not exist." % (imagefilename)) - - self.canvas.addImage(imagefilename) - - return - - def clearAllLines(self): - """ - """ - self.canvas.clearAllLines() - - def clearCanvas(self): - """ Clear canvas - """ - return self.canvas.clearCanvas() - - def draw(self): - """ Draw to commit the change - """ - return self.canvas.draw() - - def getPlot(self): - """ - """ - return self.canvas.getPlot() - - def getLastPlotIndexKey(self): - """ Get ... - """ - return self.canvas.getLastPlotIndexKey() - - def getXLimit(self): - """ Get limit of Y-axis - """ - return self.canvas.getXLimit() - - def getYLimit(self): - """ Get limit of Y-axis - """ - return self.canvas.getYLimit() - - def removePlot(self, ikey): - """ - """ - return self.canvas.removePlot(ikey) - - def setXYLimits(self, xmin=None, xmax=None, ymin=None, ymax=None): - """ - """ - return self.canvas.setXYLimit(xmin, xmax, ymin, ymax) - - def updateLine(self, ikey, vecx, vecy, linestyle=None, linecolor=None, marker=None, markercolor=None): - """ - """ - return self.canvas.updateLine(ikey, vecx, vecy, linestyle, linecolor, marker, markercolor) - - def getLineStyleList(self): - """ - """ - return MplLineStyles - - def getLineMarkerList(self): - """ - """ - return MplLineMarkers - - def getLineBasicColorList(self): - """ - """ - return MplBasicColors - - def getDefaultColorMarkerComboList(self): - """ Get a list of line/marker color and marker style combination - as default to add more and more line to plot - """ - return self.canvas.getDefaultColorMarkerComboList() - - def getNextLineMarkerColorCombo(self): - """ As auto line's marker and color combo list is used, - get the NEXT marker/color combo - """ - # get from list - marker, color = self._myLineMarkerColorList[self._myLineMarkerColorIndex] - # process marker if it has information - if marker.count(' (') > 0: - marker = marker.split(' (')[0] - print("[DB] Print line %d: marker = %s, color = %s" % (self._myLineMarkerColorIndex, marker, color)) - - # update the index - self._myLineMarkerColorIndex += 1 - if self._myLineMarkerColorIndex == len(self._myLineMarkerColorList): - self._myLineMarkerColorIndex = 0 - - return marker, color - - def resetLineColorStyle(self): - """ Reset the auto index for line's color and style - """ - self._myLineMarkerColorIndex = 0 - return - - def setXYLimit(self, xmin, xmax, ymin, ymax): - """ Set X-Y limit automatically - """ - self.canvas.axes.set_xlim([xmin, xmax]) - self.canvas.axes.set_ylim([ymin, ymax]) - - self.canvas.draw() - - return - - def setAutoLineMarkerColorCombo(self): - """ - """ - self._myLineMarkerColorList = [] - for marker in MplLineMarkers: - for color in MplBasicColors: - self._myLineMarkerColorList.append( (marker, color) ) - - return - - def setLineMarkerColorIndex(self, newindex): - """ - """ - self._myLineMarkerColorIndex = newindex - - return - - -class Qt4MplCanvas(FigureCanvas): - """ A customized Qt widget for matplotlib figure. - It can be used to replace GraphicsView of QtGui - """ - - def __init__(self, parent): - """ Initialization - """ - # Instantiate matplotlib Figure - self.fig = Figure() - self.fig.patch.set_facecolor('white') - self.axes = self.fig.add_subplot(111) # return: matplotlib.axes.AxesSubplot - - # Initialize parent class and set parent - FigureCanvas.__init__(self, self.fig) - self.setParent(parent) - - # Set size policy to be able to expanding and resizable with frame - FigureCanvas.setSizePolicy(self, QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Expanding) - - FigureCanvas.updateGeometry(self) - - # Variables to manage all lines/subplot - self._lineDict = {} - self._lineIndex = 0 - - # legend and color bar - self.colorBar = None - # self._myLegend = None - - return - - def add_plot1d(self, vec_x, vec_y, color=None, label="", x_label=None, y_label=None, - marker=None, line_style=None, line_width=1, y_err=None): - """ Add a 1D plot (line) to canvas - :param vec_x: - :param vec_y: - :param color: - :param label: - :param x_label: - :param y_label: - :param marker: - :param line_style: - :param line_width: - :param y_err: - :return: - """ - # Check input - if isinstance(vec_x, np.ndarray) is False or isinstance(vec_y, np.ndarray) is False: - raise NotImplementedError('Input vec_x or vec_y for addPlot() must be numpy.array.') - plot_error = y_err is not None - if plot_error is True: - if isinstance(y_err, np.ndarray) is False: - raise NotImplementedError('Input y_err must be either None or numpy.array.') - - if len(vec_x) != len(vec_y): - raise NotImplementedError('Input vec_x and vec_y must have same size.') - if plot_error is True and len(y_err) != len(vec_x): - raise NotImplementedError('Input vec_x, vec_y and y_error must have same size.') - - # Hold previous data - self.axes.hold(True) - - # process inputs and defaults - # self.x = vec_x - # self.y = vec_y - - if color is None: - color = (0,1,0,1) - if marker is None: - marker = 'o' - if line_style is None: - line_style = '-' - - # color must be RGBA (4-tuple) - if plot_error is False: - r = self.axes.plot(vec_x, vec_y, color=color, marker=marker, linestyle=line_style, - label=label, linewidth=line_width) - # return: list of matplotlib.lines.Line2D object - else: - r = self.axes.errorbar(vec_x, vec_y, yerr=y_err, color=color, marker=marker, linestyle=line_style, - label=label, linewidth=line_width) - - self.axes.set_aspect('auto') - - # set x-axis and y-axis label - if x_label is not None: - self.axes.set_xlabel(x_label, fontsize=20) - if y_label is not None: - self.axes.set_ylabel(y_label, fontsize=20) - - # set/update legend - self._setupLegend() - - # Register - if plot_error is True and len(r) == 3: - # plot line with error bar. r[1] contains all lines - self._lineDict[self._lineIndex] = r - elif plot_error is False and len(r) == 1: - # regular line - self._lineDict[self._lineIndex] = r[0] - else: - print("Impoooooooooooooooosible! Number of returned tuple is %d"%(len(r))) - dbmsg = '' - for sub_r in r: - dbmsg += 'Type: %s, Value: %s\n' % (str(type(sub_r)), str(sub_r)) - print(dbmsg) - self._lineIndex += 1 - - # Flush/commit - self.draw() - - return - - def addPlot2D(self, array2d, xmin, xmax, ymin, ymax, holdprev, yticklabels=None): - """ Add a 2D plot - - Arguments: - - yticklabels :: list of string for y ticks - """ - # Release the current image - self.axes.hold(holdprev) - - # Do plot - # y ticks will be shown on line 1, 4, 23, 24 and 30 - # yticks = [1, 4, 23, 24, 30] - # self.axes.set_yticks(yticks) - - print("[DBNOW] Before imshow(), number of axes = %d" % (len(self.fig.axes))) - - # show image - imgplot = self.axes.imshow(array2d, extent=[xmin,xmax,ymin,ymax], interpolation='none') - print("[DBNOW] After imshow(), number of axes = %d" % (len(self.fig.axes))) - - # set y ticks as an option: - if yticklabels is not None: - # it will always label the first N ticks even image is zoomed in - print("--------> [FixMe]: Set up the Y-axis ticks is erroreous") - #self.axes.set_yticklabels(yticklabels) - - # explicitly set aspect ratio of the image - self.axes.set_aspect('auto') - - # Set color bar. plt.colorbar() does not work! - if self.colorBar is None: - # set color map type - imgplot.set_cmap('spectral') - self.colorBar = self.fig.colorbar(imgplot) - else: - self.colorBar.update_bruteforce(imgplot) - print("[DBNOW] After colorbar is added, number of axes = %d" % (len(self.fig.axes))) - - # Flush... - self._flush() - - return - - def addImage(self, imagefilename): - """ Add an image by file - """ - #import matplotlib.image as mpimg - - # set aspect to auto mode - self.axes.set_aspect('auto') - - img = matplotlib.image.imread(str(imagefilename)) - # lum_img = img[:,:,0] - # FUTURE : refactor for image size, interpolation and origin - imgplot = self.axes.imshow(img, extent=[0, 1000, 800, 0], interpolation='none', origin='lower') - - # Set color bar. plt.colorbar() does not work! - if self.colorBar is None: - # set color map type - imgplot.set_cmap('spectral') - self.colorBar = self.fig.colorbar(imgplot) - else: - self.colorBar.update_bruteforce(imgplot) - - self._flush() - - return - - def clearAllLines(self): - """ Remove all lines from the canvas - """ - for ikey in self._lineDict.keys(): - plot = self._lineDict[ikey] - if plot is None: - continue - if isinstance(plot, tuple) is False: - try: - self.axes.lines.remove(plot) - except ValueError as e: - print("[Error] Plot %s is not in axes.lines which has %d lines. Error mesage: %s" % ( - str(plot), len(self.axes.lines), str(e))) - self._lineDict[ikey] = None - else: - # error bar - plot[0].remove() - for line in plot[1]: - line.remove() - for line in plot[2]: - line.remove() - self._lineDict[ikey] = None - # ENDIF(plot) - # ENDFOR - - # Remove legend - # only appied in new version of matplotlib - # if self._myLegend is not None: - # self._myLegend.remove() - - self._setupLegend() - - self.draw() - - return - - def clearCanvas(self): - """ Clear data including lines and image from canvas - """ - # clear the image for next operation - self.axes.hold(False) - - # Clear all lines - self.clearAllLines() - - # clear image - self.axes.cla() - # Try to clear the color bar - if len(self.fig.axes) > 1: - self.fig.delaxes(self.fig.axes[1]) - self.colorBar = None - # This clears the space claimed by color bar but destroys sub_plot too. - self.fig.clear() - # Re-create subplot - self.axes = self.fig.add_subplot(111) - if len(self.fig.axes) > 0: - print("[DBNOW] Type of axes[0] = %s" % (str(type(self.fig.axes[0])))) - - # flush/commit - self._flush() - - return - - def getLastPlotIndexKey(self): - """ Get the index/key of the last added line - """ - return self._lineIndex-1 - - def getPlot(self): - """ reture figure's axes to expose the matplotlib figure to PyQt client - """ - return self.axes - - def getXLimit(self): - """ Get limit of Y-axis - """ - return self.axes.get_xlim() - - def getYLimit(self): - """ Get limit of Y-axis - """ - return self.axes.get_ylim() - - def setXYLimit(self, xmin, xmax, ymin, ymax): - """ - """ - # for X - xlims = self.axes.get_xlim() - xlims = list(xlims) - if xmin is not None: - xlims[0] = xmin - if xmax is not None: - xlims[1] = xmax - self.axes.set_xlim(xlims) - - # for Y - ylims = self.axes.get_ylim() - ylims = list(ylims) - if ymin is not None: - ylims[0] = ymin - if ymax is not None: - ylims[1] = ymax - self.axes.set_ylim(ylims) - - # try draw - self.draw() - - return - - def removePlot(self, ikey): - """ Remove the line with its index as key - """ - # self._lineDict[ikey].remove() - lines = self.axes.lines - print(str(type(lines)), lines) - print("ikey = ", ikey, self._lineDict[ikey]) - self.axes.lines.remove(self._lineDict[ikey]) - #self.axes.remove(self._lineDict[ikey]) - print(self._lineDict[ikey]) - self._lineDict[ikey] = None - - return - - def updateLine(self, ikey, vecx, vecy, linestyle=None, linecolor=None, marker=None, markercolor=None): - """ - """ - line = self._lineDict[ikey] - - if vecx is not None and vecy is not None: - line.set_xdata(vecx) - line.set_ydata(vecy) - - if linecolor is not None: - line.set_color(linecolor) - - if linestyle is not None: - line.set_linestyle(linestyle) - - if marker is not None: - line.set_marker(marker) - - if markercolor is not None: - line.set_markerfacecolor(markercolor) - - oldlabel = line.get_label() - line.set_label(oldlabel) - - self.axes.legend() - - # commit - self.draw() - - return - - def getLineStyleList(self): - """ - """ - return MplLineStyles - - def getLineMarkerList(self): - """ - """ - return MplLineMarkers - - def getLineBasicColorList(self): - """ - """ - return MplBasicColors - - def getDefaultColorMarkerComboList(self): - """ Get a list of line/marker color and marker style combination - as default to add more and more line to plot - """ - combolist = [] - nummarkers = len(MplLineMarkers) - numcolors = len(MplBasicColors) - - for i in range(nummarkers): - marker = MplLineMarkers[i] - for j in range(numcolors): - color = MplBasicColors[j] - combolist.append( (marker, color) ) - # ENDFOR (j) - # ENDFOR(i) - - return combolist - - def _flush(self): - """ A dirty hack to flush the image - """ - w, h = self.get_width_height() - self.resize(w+1,h) - self.resize(w,h) - - return - - def _setupLegend(self, location='best'): - """ Set up legend - self.axes.legend() - Handler is a Line2D object. Lable maps to the line object - """ - loclist = [ - "best", - "upper right", - "upper left", - "lower left", - "lower right", - "right", - "center left", - "center right", - "lower center", - "upper center", - "center"] - - # Check legend location valid or not - if location not in loclist: - location = 'best' - - handles, labels = self.axes.get_legend_handles_labels() - # self._myLegend = - self.axes.legend(handles, labels, loc=location) - # print handles - # print labels - #self.axes.legend(self._myLegendHandlers, self._myLegentLabels) - - return - - -class MyNavigationToolbar(NavigationToolbar): - """ A customized navigation tool bar attached to canvas - """ - - def __init__(self, parent, canvas): - """ Initialization - FUTURE: direction='h' - """ - self.canvas = canvas - QtGui.QWidget.__init__(self, parent) - - #if direction=='h' : - # self.layout = QtGui.QHBoxLayout(self) - #else : - # self.layout = QtGui.QVBoxLayout(self) - - #self.layout.setMargin(2) - #self.layout.setSpacing(0) - - NavigationToolbar.__init__( self, canvas, canvas ) - - return diff --git a/scripts/HFIRPowderReduction/README.md b/scripts/HFIRPowderReduction/README.md deleted file mode 100644 index 9799a0393d41e987afe4ce74c13f176ce6ee3865..0000000000000000000000000000000000000000 --- a/scripts/HFIRPowderReduction/README.md +++ /dev/null @@ -1,148 +0,0 @@ -Tasks ------ - - 6. Find out why the vanadium runs (379-10/11) look funny, i.e., oscilating curves; - 7. Talk with Clarina how to deal with vanadium spectrum with peaks striped; - 8. Tab *Normalized*: **Normalization Monitor** should have a default value as the average of monitor counts - 9. Check whether a scan has been loaded as **Load** is pushed; - 10. Enable *SaveGSS*() work with reactor-source powder diffractometers; - - -Finished Tasks --------------- - - 1. Make tab *Raw Detector* work; - 2. Make tab *Individual Detector* work; - 3. Implement tab *vanadium*; - 4. (75%) Each tab with *Previous* and *Next* buttons should have a data structure to record whether a certain plot is already on canvas - 5. Tab *Normalized*: **Normalization Monitor** is not parsed; - 6. Tab *Normalized*: apply reduction record to binning push buttons and avoid plotting one data twice on same plot with *Prev Scan* and *Next Scan*; - 7. Tab *Normalized*: **Save** does not work well with option *gsas and fullprof*; - 8. Tab *vanadium*: implement **Smooth Data**; - 9. Tab *vanadium*: implement **Save**; - 10. Tab *Multiple Scans*: implement **Save Merged** - 11. Tab *Multiple Scans*: implement **Save All** - - -Use cases for tabs ------------------- - - 1. **Raw Detectors**: Visualize the reading of detectors directly coming out of the raw data - * Plot N lines for N Pts.; - * Highlight (make it thicker) the Pt that is interested; - * New from Mantid: *ReadRawSpiceSignal(Pts)*; - 2. **Individual Detector**: Visual the readings of one detector across an experiment - * Plot the counts of any individual detector; - * Able to change the X-axis from 2theta to arbitrary sample environment log; - * New from Mantid: *ReadRawSpiceSignal(DetectorID, XLabel)*; - 3. **Normalized**: Reduce one scan each time - * Plot the reduced data - * Automatically locate detector efficiency file - * New from Mantid: *ConvertCWPDMDToSpectra(ExcludedDetectors=[])* - * New from Mantid: *ConvertSpiceDataToRealSpace(DetectorEfficiencyTable)* - 4. **Multiple Scans**: Reduce a set of scans - * Reduce a set of scans and plot in 2D/water-fall mode; - * Able to merge all the scans; - * New from Mantid: *ConvertCWPDMDToSpectra(ExcludedDetectors=[])* - 5. **Vanadium**: strip vanadium peaks - * Strip vanadium peak with unit 'Degrees' because of the binning (range and step size) must be respected; - * Peaks' position should be calculated and indicated auotmatically; - * *Mantid::StripPeaks()* will be called instread of *StripVadadiumPeaks()* because - the later one only works in d-spacing; - 6. **Advanced Setup** - * URL for raw data files; - - -Suggested workflow for *Normalization* -====================================== - -Here is a typical use case for reduce data via tab *Noramlization* - - 1. User specify *Exp No* and *Scan No*; - 2. HFIR-PDR-GUI loads SPICE data according to experiment number and scan number; - 3. HFIR-PDR-GUI checks whether vanadium correction file, i.e., detector efficiency file exists on server; - 4. HFIR-PDR-GUI checks whether excluded detectors file exists on server; - 5. HFIR-PDR-GUI checks log **m1** for wavelength and set to *Wavelength* ; - 6. User may specify detector efficient file; - 7. User specifies *Bin Size*; (Or auto bin size determination???) - 8. User pushes button *Load Data*; - 9. HFIR-PDF-GUI reduce data in unit of *2theta* by taking accounting of - * Detector efficiency; - * Excluded detectors; - 10. HFIR-PDR-GUI plots the reduced data; - 11. User may rebin by different binning parameters or unit; - 12. User may save the result; - - -Suggested workflow for *Multiple Scans* -======================================= - -It might be confusing to use the functionalities in tab *Multiple Scans*. -Here is the suggested workflow to reduce multiple scans and possibly merge them. - - 1. Set up *Exp No* and range of scan numbers; - 2. Push button *Load All* to load and reduce all runs specified in previous step to single-spectrum diffraction pattern; - 3. Waterfall plot all reduced scans in default; - 4. Optinally plot all data in 2D fill plot; - 5. User can delete some scans from the reduced scans via GUI or input text edit; - 6. Push button *Merge* to merge the scans; - 7. Push button *Save All* to save all individual scans to files; - 8. Push button *Save Merged* to save the merged scans to one file; - - -Features (Implemented) ----------------------- - - * Automatic wavelength mapping (in progress); - - -HB2A Data Reduction -------------------- - -Raw experimental data are to be corrected by (1) detector efficiency, (2) vanadium spectrum and etc. -Experiments are done with neutrons with various wavelengthes. -There information can be retrieved from HB2A's data repository accessible from internet. - -Experiment setup and sample log -=============================== - - 1. **Wavelength**: There are three settings for neutron wavelength, referenced by sample log *m1*. - * Ge 113: :math:`\lambda = 2.41 \AA`, m1 = 9.45 (The **error** can be 0.05, such that in Exp 231 scan0001, m1=9.5) - * Ge 115: :math:`\lambda = 1.54 \AA`, m1 = 0 - * Ge 117 :math:`\lambda = 1.12 \AA`, No used - - 2. **Collimator translation**: There are two status for collimator, which is specified by sample log *colltrans* - * *IN*: colltrans = 0 - * *OUT*: colltrans = +/-80 - - -Raw data correction files -========================= - - 1. **Detector efficiency**: - * File name: *HB2A_exp0IJK__GE_abc_XY_vcorr.txt* where - - IJK is the experiment number - - abc is the GE set up. It can be 113, 115 or 117 - - XY is either IN or OUT. - - Exmaple: *HB2A_exp0400__Ge_113_IN_vcorr.txt* - * Web address: *http://neutron.ornl.gov/user_data/hb2a/exp400/Datafiles/HB2A_exp0IJK__Ge_abc_IN_vcorr.txt* - - IJK is the experiment number - - abc is the GE set up. It can be 113, 115 or 117 - - XY is either IN or OUT. - - Exmaple: *http://neutron.ornl.gov/user_data/hb2a/exp400/Datafiles/HB2A_exp0400__Ge_113_IN_vcorr.txt* - - 2. **Excluded detectors**: Some detectors might be exluded from the experiment for some reason. It is recorded in some excluded detectors' file. - * File name: *HB2A_exp0IJK__exclude_detectors.txt* - - IJK is the epxeriment number - - Exmaple: *HB2A_exp0400__exclude_detectors.txt* - * Web address: *http://neutron.ornl.gov/user_data/hb2a/expIJK/Datafiles/HB2A_exp0IJK__exclude_detectors.txt* - - IJK is the experiment number - - Example: *http://neutron.ornl.gov/user_data/hb2a/exp400/Datafiles/HB2A_exp0400__exclude_detectors.txt* - - 3. Detector gaps: The 2-theta gap (in unit degrees) can be changed among cycles. - * Location example: *http://neutron.ornl.gov/user_data/hb2a/exp400/Datafiles/HB2A_exp0400__gaps.txt* - - - - - diff --git a/scripts/HFIRPowderReduction/__init__.py b/scripts/HFIRPowderReduction/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/scripts/HFIR_4Circle_Reduction/MainWindow.ui b/scripts/HFIR_4Circle_Reduction/MainWindow.ui index 84fd360d6e881358e6f739ddca171a85c000870b..62dad6cdb3483fa2f1ffe9e9b303182b91921007 100644 --- a/scripts/HFIR_4Circle_Reduction/MainWindow.ui +++ b/scripts/HFIR_4Circle_Reduction/MainWindow.ui @@ -579,7 +579,7 @@ <string><html><head/><body><p>Directory to save outcome of the data reduction</p></body></html></string> </property> <property name="text"> - <string>Working Direcotry</string> + <string>Working Directory</string> </property> </widget> </item> @@ -3470,7 +3470,7 @@ p, li { white-space: pre-wrap; } </sizepolicy> </property> <property name="toolTip"> - <string><html><head/><body><p>List of scans and possibly Pt numbers.</p><p><br/></p><p>Example 1:</p><p>123, 125-130, 301, 304</p><p>It will integrate all Pts. in each scan</p><p><br/></p><p>Example 2:</p><p>123 (1, 2, 3, 4-10), 125-130, </p><p>It will integrate all Pts. in all scans excpet 123, which will have a selected few to be integrated</p><p><br/></p><p>Example 3:</p><p>123, 125-130, 301, 304 | 1, 2, 3-9</p><p>It will integrate selected Pts. in the previous one</p></body></html></string> + <string><html><head/><body><p>List of scans and possibly Pt numbers.</p><p><br/></p><p>Example 1:</p><p>123, 125-130, 301, 304</p><p>It will integrate all Pts. in each scan</p><p><br/></p><p>Example 2:</p><p>123 (1, 2, 3, 4-10), 125-130, </p><p>It will integrate all Pts. in all scans except 123, which will have a selected few to be integrated</p><p><br/></p><p>Example 3:</p><p>123, 125-130, 301, 304 | 1, 2, 3-9</p><p>It will integrate selected Pts. in the previous one</p></body></html></string> </property> </widget> </item> diff --git a/scripts/HFIR_4Circle_Reduction/fputility.py b/scripts/HFIR_4Circle_Reduction/fputility.py index c0c4fd9698685c2d08aa519cf715ba264c6631cc..1508f1abf91d7ea5d5299a42c612db8c062e1155 100644 --- a/scripts/HFIR_4Circle_Reduction/fputility.py +++ b/scripts/HFIR_4Circle_Reduction/fputility.py @@ -74,7 +74,7 @@ def load_scd_fullprof_intensity_file(file_name): # line 2 format line, skip continue elif line.endswith('0 0'): - # line 3 as wave lengh line + # line 3 as wave length line wave_length = float(line.split()[0]) elif k_index < num_k_vector: # k-vector line: (num_k_vector) line right after k-indication line diff --git a/scripts/HFIR_4Circle_Reduction/guiutility.py b/scripts/HFIR_4Circle_Reduction/guiutility.py index 16efd7fd6d2e5e870d3b5e04542fb6ab876aca3d..fe363856a41545f8a9e3e7be860961aeaf1955fa 100644 --- a/scripts/HFIR_4Circle_Reduction/guiutility.py +++ b/scripts/HFIR_4Circle_Reduction/guiutility.py @@ -128,7 +128,7 @@ def map_to_color(data_array, base_color, change_color_flag): color_value = min(1.0 - 1.E-10, color_value) step_list_index += 1 else: - # use bae color + # use base color color_value = base_color[i_color] # ENDIF diff --git a/scripts/HFIR_4Circle_Reduction/hfctables.py b/scripts/HFIR_4Circle_Reduction/hfctables.py index dfee87978f983e5f52dc5ddadbb27a903a82d5f7..294cc7a3ac70bbb15fadd7325d42084f1a2ffb64 100644 --- a/scripts/HFIR_4Circle_Reduction/hfctables.py +++ b/scripts/HFIR_4Circle_Reduction/hfctables.py @@ -807,7 +807,7 @@ class UBMatrixPeakTable(tableBase.NTableWidget): def set_hkl(self, i_row, hkl, is_spice_hkl, error=None): """ - Set HKL to a row in the table. Show H/K/L with 4 decimal pionts + Set HKL to a row in the table. Show H/K/L with 4 decimal points :param i_row: :param hkl: HKL is a list of tuple :param is_spice_hkl: If true, then set input to cell for SPICE-imported HKL. Otherwise to calculated HKL. diff --git a/scripts/HFIR_4Circle_Reduction/mplgraphicsview.py b/scripts/HFIR_4Circle_Reduction/mplgraphicsview.py index 94085f529f4abd23bb00616f74598dee4168df56..485b34ac01a4c37853a364b0f9b4639061caef78 100644 --- a/scripts/HFIR_4Circle_Reduction/mplgraphicsview.py +++ b/scripts/HFIR_4Circle_Reduction/mplgraphicsview.py @@ -1352,7 +1352,7 @@ class Qt4MplCanvas(FigureCanvas): try: self.axes.lines.remove(plot) except ValueError as e: - print("[Error] Plot %s is not in axes.lines which has %d lines. Error mesage: %s" % ( + print("[Error] Plot %s is not in axes.lines which has %d lines. Error message: %s" % ( str(plot), len(self.axes.lines), str(e))) del self._lineDict[ikey] else: @@ -1421,7 +1421,7 @@ class Qt4MplCanvas(FigureCanvas): return self._lineIndex-1 def getPlot(self): - """ reture figure's axes to expose the matplotlib figure to PyQt client + """ return figure's axes to expose the matplotlib figure to PyQt client """ return self.axes @@ -1664,7 +1664,7 @@ class Qt4MplCanvas(FigureCanvas): def _setup_legend(self, location='best', font_size=10): """ Set up legend - self.axes.legend(): Handler is a Line2D object. Lable maps to the line object + self.axes.legend(): Handler is a Line2D object. Label maps to the line object Args: location: font_size: diff --git a/scripts/HFIR_4Circle_Reduction/peakprocesshelper.py b/scripts/HFIR_4Circle_Reduction/peakprocesshelper.py index 835b24787b74625aaf774234d618145af4762a64..a455ca06f6d02b27b06f702faa3e17b67a8f05ea 100644 --- a/scripts/HFIR_4Circle_Reduction/peakprocesshelper.py +++ b/scripts/HFIR_4Circle_Reduction/peakprocesshelper.py @@ -306,7 +306,7 @@ class PeakProcessRecord(object): """ # get PeaksWorkspace if AnalysisDataService.doesExist(self._myPeakWorkspaceName) is False: - raise RuntimeError('PeaksWorkspace %s does ot exit.' % self._myPeakWorkspaceName) + raise RuntimeError('PeaksWorkspace %s does not exist.' % self._myPeakWorkspaceName) peak_ws = AnalysisDataService.retrieve(self._myPeakWorkspaceName) diff --git a/scripts/HFIR_4Circle_Reduction/reduce4circleControl.py b/scripts/HFIR_4Circle_Reduction/reduce4circleControl.py index ae0507f22cc93810e9eb525fbf849ae594165a09..ddbd9d249b9be5ac3eb453797282438fa97bfd50 100644 --- a/scripts/HFIR_4Circle_Reduction/reduce4circleControl.py +++ b/scripts/HFIR_4Circle_Reduction/reduce4circleControl.py @@ -2198,7 +2198,7 @@ class CWSCDReductionControl(object): 'Center row number {0} of type {1} must either None or non-negative integer.' \ ''.format(center_row, type(center_row)) assert center_col is None or (isinstance(center_col, int) and center_col >= 0), \ - 'Center column number {0} of type {1} must be either Noe or non-negative integer.' \ + 'Center column number {0} of type {1} must be either None or non-negative integer.' \ ''.format(center_col, type(center_col)) if default: diff --git a/scripts/HFIR_4Circle_Reduction/reduce4circleGUI.py b/scripts/HFIR_4Circle_Reduction/reduce4circleGUI.py index 230e56b5261cd6808af6f3e4d2b0283816d89172..bce03b27aaafbe26010b2ec5d14d2ea5ee74b3f5 100644 --- a/scripts/HFIR_4Circle_Reduction/reduce4circleGUI.py +++ b/scripts/HFIR_4Circle_Reduction/reduce4circleGUI.py @@ -454,7 +454,7 @@ class MainWindow(QtGui.QMainWindow): # about pre-processed data self.ui.checkBox_searchPreprocessedFirst.setChecked(True) - # hide and disable some push buttons for future implemetation + # hide and disable some push buttons for future implementation self.ui.pushButton_viewScan3D.hide() self.ui.pushButton_plotSelectedData.hide() @@ -495,7 +495,7 @@ class MainWindow(QtGui.QMainWindow): try: calculated_hkl = self.ui.tableWidget_peaksCalUB.get_hkl(i_row, False) except RuntimeError as run_err: - errmsg = '[ERROR] Failed to get calculated HKL from UB calcualtion table due to {0}'.format(run_err) + errmsg = '[ERROR] Failed to get calculated HKL from UB calculation table due to {0}'.format(run_err) self.pop_one_button_dialog(errmsg) return None peak_info.set_hkl_np_array(numpy.array(calculated_hkl)) @@ -3681,7 +3681,7 @@ class MainWindow(QtGui.QMainWindow): def save_settings(self): """ - Save settings (parameter set) upon quiting + Save settings (parameter set) upon quitting :return: """ settings = QtCore.QSettings() diff --git a/scripts/HFIR_4Circle_Reduction/refineubfftsetup.py b/scripts/HFIR_4Circle_Reduction/refineubfftsetup.py index 0c5ef026dcc16d6b844bd7a144de06f00412842b..4c7a240d95db0e45bdfedb8810a93b8c485f620b 100644 --- a/scripts/HFIR_4Circle_Reduction/refineubfftsetup.py +++ b/scripts/HFIR_4Circle_Reduction/refineubfftsetup.py @@ -30,7 +30,7 @@ class RefineUBFFTSetupDialog(QtGui.QDialog): self.ui.lineEdit_maxD.setText('40.0') self.ui.lineEdit_tolerance.setText('0.15') - # connected to event hanlder + # connected to event handler self.connect(self.ui.buttonBox, QtCore.SIGNAL('accepted()'), self.do_ok) diff --git a/scripts/HFIR_4Circle_Reduction/viewspicedialog.py b/scripts/HFIR_4Circle_Reduction/viewspicedialog.py index 3df33e257100a11f655f062ac104aa7618ca9431..ce2994558005ec77619f078efb9561d38a89481d 100644 --- a/scripts/HFIR_4Circle_Reduction/viewspicedialog.py +++ b/scripts/HFIR_4Circle_Reduction/viewspicedialog.py @@ -5,7 +5,7 @@ from PyQt4 import QtGui class ViewSpiceDialog(QtGui.QDialog): - """Dialog ot view SPICE """ + """Dialog to view SPICE """ def __init__(self, parent): """Initialization diff --git a/scripts/HFIR_Powder_Diffraction_Reduction.py b/scripts/HFIR_Powder_Diffraction_Reduction.py deleted file mode 100644 index 9ede55d60029170392af9820935162eb82615c18..0000000000000000000000000000000000000000 --- a/scripts/HFIR_Powder_Diffraction_Reduction.py +++ /dev/null @@ -1,25 +0,0 @@ -#pylint: disable=invalid-name,no-name-in-module -""" - Script used to start the DGS reduction GUI from MantidPlot -""" -from __future__ import (absolute_import, division, print_function) -import sys - -from HFIRPowderReduction import HfirPDReductionGUI -from PyQt4 import QtGui - - -def qapp(): - if QtGui.QApplication.instance(): - _app = QtGui.QApplication.instance() - else: - _app = QtGui.QApplication(sys.argv) - return _app - - -app = qapp() - -reducer = HfirPDReductionGUI.MainWindow() #the main ui class in this file is called MainWindow -reducer.show() - -app.exec_() diff --git a/scripts/ISIS_SANS_v2_experimental.py b/scripts/ISIS_SANS_v2_experimental.py index 91f86da56e18e73d718d317f09c411ca6d2a9c90..27e97b5dce6bf94a1135f7b483babf4e19d77e60 100644 --- a/scripts/ISIS_SANS_v2_experimental.py +++ b/scripts/ISIS_SANS_v2_experimental.py @@ -3,27 +3,23 @@ Script used to start the Test Interface from MantidPlot """ from ui.sans_isis import sans_data_processor_gui -from sans.gui_logic.presenter.main_presenter import MainPresenter +from sans.gui_logic.presenter.run_tab_presenter import RunTabPresenter from sans.common.enums import SANSFacility # ----------------------------------------------- # Create presenter # ----------------------------------------------- -main_presenter = MainPresenter(SANSFacility.ISIS) - +run_tab_presenter = RunTabPresenter(SANSFacility.ISIS) # ------------------------------------------------- # Create view -# Note that the view owns the presenter, but only -# uses it for the setup. # ------------------------------------------------ -ui = sans_data_processor_gui.SANSDataProcessorGui(main_presenter) +ui = sans_data_processor_gui.SANSDataProcessorGui() # ----------------------------------------------- # Set view on the presenter. # The presenter delegates the view. # ----------------------------------------------- -main_presenter.set_view(ui) +run_tab_presenter.set_view(ui) # Show -if ui.setup_layout(): - ui.show() +ui.show() diff --git a/scripts/Inelastic/CrystalField/fitting.py b/scripts/Inelastic/CrystalField/fitting.py index 34c8e97ecd017c27b4f75c85d5bd506d19a38b79..0f56286573bb6e33ff08ed320d752dfd61a4411e 100644 --- a/scripts/Inelastic/CrystalField/fitting.py +++ b/scripts/Inelastic/CrystalField/fitting.py @@ -182,7 +182,7 @@ class CrystalField(object): if 'ResolutionModel' in kwargs and 'FWHM' in kwargs: msg = 'Both ''ResolutionModel'' and ''FWHM'' specified but can only accept one width option.' - msg += ' Prefering to use ResolutionModel, and ignoring FWHM.' + msg += ' Preferring to use ResolutionModel, and ignoring FWHM.' kwargs.pop('FWHM') warnings.warn(msg, SyntaxWarning) diff --git a/scripts/Inelastic/Direct/DirectEnergyConversion.py b/scripts/Inelastic/Direct/DirectEnergyConversion.py index afb0d4555aa1ab342a206e93bce2e8893564a5df..dde30a0ca619cd9abbdae75d549cb35e99191eae 100644 --- a/scripts/Inelastic/Direct/DirectEnergyConversion.py +++ b/scripts/Inelastic/Direct/DirectEnergyConversion.py @@ -1922,7 +1922,7 @@ def get_failed_spectra_list_from_masks(masked_wksp,prop_man): try: masked_wksp.name() #pylint: disable=broad-except - except Exeption: + except Exception: prop_man.log("***WARNING: cached mask workspace invalidated. Incorrect masking reported") return (failed_spectra,0) diff --git a/scripts/Inelastic/Direct/ISISDirecInelasticConfig.py b/scripts/Inelastic/Direct/ISISDirecInelasticConfig.py index 5f4424188dab1bb9e0059576e641168bcc59fc26..e9512fb0d869b96778cdc895c4979c19cd24d106 100644 --- a/scripts/Inelastic/Direct/ISISDirecInelasticConfig.py +++ b/scripts/Inelastic/Direct/ISISDirecInelasticConfig.py @@ -328,7 +328,7 @@ class UserProperties(object): error = True if error: raise RuntimeError("Experiment start date should be defined as" - " a sting in the form YYYYMMDD or YYMMDD but it is: {0}".format(start_date)) + " a string in the form YYYYMMDD or YYMMDD but it is: {0}".format(start_date)) return start_date def get_all_instruments(self): diff --git a/scripts/Inelastic/Direct/NonIDF_Properties.py b/scripts/Inelastic/Direct/NonIDF_Properties.py index 2029ade3f5b308b68a3124c1b107374b0c1cd797..f8c16aa30789c657cf5d12dc5688a2b37d3d1350 100644 --- a/scripts/Inelastic/Direct/NonIDF_Properties.py +++ b/scripts/Inelastic/Direct/NonIDF_Properties.py @@ -164,7 +164,7 @@ class NonIDF_Properties(object): def mapmask_ref_ws(self): """Property provides reference workspace for LoadMask and GroupWorkspace algorithms - on 26/07/2016 refernce workspace (a workspace which provides appropriate + on 26/07/2016 reference workspace (a workspace which provides appropriate spectra-detector mapping was implemented for LoadMask algorithm only. """ return self._mapmask_ref_ws diff --git a/scripts/Inelastic/Direct/PropertyManager.py b/scripts/Inelastic/Direct/PropertyManager.py index e97704ffb4a315ba20ec3f37bb43c8a7e7ce10e9..d3f423248f724dff2d3a1cc0d3f0ade317507932 100644 --- a/scripts/Inelastic/Direct/PropertyManager.py +++ b/scripts/Inelastic/Direct/PropertyManager.py @@ -627,7 +627,7 @@ class PropertyManager(NonIDF_Properties): missing=[] #pylint: disable=unused-variable ok,missing,found=self.find_files_to_sum() - #Presence of Cashe sum ws assumes that you sum files to workspace as they appear + #Presence of cashe_sum_ws assumes that you sum files to workspace as they appear # This mean, that we should not expect all files to be there at the beginning if not ok and not self.cashe_sum_ws: file_errors['missing_runs_toSum']=str(missing) diff --git a/scripts/Inelastic/Direct/ReductionHelpers.py b/scripts/Inelastic/Direct/ReductionHelpers.py index de58a85f0188d6860ba9753c288071ca9527b00e..9fc457ac27b8979113c8ca5c0f00d6638ddd394e 100644 --- a/scripts/Inelastic/Direct/ReductionHelpers.py +++ b/scripts/Inelastic/Direct/ReductionHelpers.py @@ -399,7 +399,7 @@ def parse_run_file_name(run_string): def process_prop_list(workspace,logName="CombinedSpectraIDList"): - """Method process log, which discribes list of spectra, attached to + """Method process log, which describes list of spectra, attached to the workspace """ if workspace.run().hasProperty(logName): diff --git a/scripts/Inelastic/Direct/ReductionWrapper.py b/scripts/Inelastic/Direct/ReductionWrapper.py index 4d233fedf1ff18e9f9d7a037b1664f515e603169..39252b58a39dcd502039acc18296c6bec3e52a79 100644 --- a/scripts/Inelastic/Direct/ReductionWrapper.py +++ b/scripts/Inelastic/Direct/ReductionWrapper.py @@ -662,7 +662,7 @@ def AdvancedProperties(adv_prop_definition): def iliad(reduce): """ This decorator wraps around main procedure and switch input from - web variables to properties or vise versa depending on web variables + web variables to properties or vice versa depending on web variables presence """ def iliad_wrapper(*args): diff --git a/scripts/Inelastic/Direct/RunDescriptor.py b/scripts/Inelastic/Direct/RunDescriptor.py index f7484accd2f31ca0606b8c90d6b0096a144d31c9..c9bb2622743077f0662948ce7a155f17e9722479 100644 --- a/scripts/Inelastic/Direct/RunDescriptor.py +++ b/scripts/Inelastic/Direct/RunDescriptor.py @@ -934,7 +934,7 @@ class RunDescriptor(PropDescriptor): mon_list = [monitors_ID] else: mon_list = self._holder.get_used_monitors_list() - # Check if all requested spectra are indeed availible + # Check if all requested spectra are indeed available for monID in mon_list: if monID in combined_spec_list: continue diff --git a/scripts/Inelastic/Direct/__init__.py b/scripts/Inelastic/Direct/__init__.py index 9b6fd7146a9c051527ddacfefb934556442ff08f..d6b9570b010671afb183e182325246b93ebb2d3e 100644 --- a/scripts/Inelastic/Direct/__init__.py +++ b/scripts/Inelastic/Direct/__init__.py @@ -1,4 +1,4 @@ -""" Classes and funcions exported from Direct Reduction Package: +""" Classes and functions exported from Direct Reduction Package: dgreduce -- outdated functions, provided for compartibility with old qtiGenie DirectEnergyConversion -- main reduction class diff --git a/scripts/Inelastic/Direct/dgreduce.py b/scripts/Inelastic/Direct/dgreduce.py index 5ba53a7d27335379242ac63089b5d3e3f950d253..288d75c1c4a7be7a2e11b1a40225b783b0601cc5 100644 --- a/scripts/Inelastic/Direct/dgreduce.py +++ b/scripts/Inelastic/Direct/dgreduce.py @@ -76,7 +76,7 @@ def arb_units(wb_run,sample_run,ei_guess,rebin,map_file='default',monovan_run=No ,diag_remove_zero=False,norm_method='current') - type help() for the list of all available keywords. All availible keywords are provided in InstName_Parameters.xml file + type help() for the list of all available keywords. All available keywords are provided in InstName_Parameters.xml file Some samples are: diff --git a/scripts/Inelastic/IndirectBayes.py b/scripts/Inelastic/IndirectBayes.py index 334e803b3a206d1bb3623519c9f84c7c2a04ffd5..80c94ab0d8383e1e27a50426f4cba8ed167fc48c 100644 --- a/scripts/Inelastic/IndirectBayes.py +++ b/scripts/Inelastic/IndirectBayes.py @@ -2,7 +2,7 @@ """ Bayes routines -Fortran programs use fixed length arrays whereas Python has variable lenght lists +Fortran programs use fixed length arrays whereas Python has variable length lists Input : the Python list is padded to Fortrans length using procedure PadArray Output : the Fortran numpy array is sliced to Python length using dataY = yout[:ny] """ @@ -40,7 +40,7 @@ def CalcErange(inWS,ns,erange,binWidth): rangeMask = (Xdata >= erange[0]) & (Xdata <= erange[1]) Xin = Xdata[rangeMask] - #get indicies of the bounds of our energy range + #get indices of the bounds of our energy range minIndex = np.where(Xdata==Xin[0])[0][0]+1 maxIndex = np.where(Xdata==Xin[-1])[0][0] @@ -84,7 +84,7 @@ def ResNormRun(vname,rname,erange,nbin,Plot='None',Save=False): nvan,ntc = CheckHistZero(vname) theta = GetThetaQ(vname)[0] efix = getEfixed(vname) - print("begining erange calc") + print("beginning erange calc") nout,bnorm,Xdat,Xv,Yv,Ev = CalcErange(vname,0,erange,nbin) print("end of erange calc") Ndat = nout[0] diff --git a/scripts/Inelastic/IndirectCommon.py b/scripts/Inelastic/IndirectCommon.py index 3c3f210144c77c2dc3c4353a8119db9611283c05..5474bf797330edea0af1e00e41434adfcddeb665 100644 --- a/scripts/Inelastic/IndirectCommon.py +++ b/scripts/Inelastic/IndirectCommon.py @@ -395,7 +395,7 @@ def getInstrumentParameter(ws, param_name): inst = s_api.mtd[ws].getInstrument() # Create a map of type parameters to functions. This is so we avoid writing lots of - # if statements becuase there's no way to dynamically get the type. + # if statements because there's no way to dynamically get the type. func_map = {'double': inst.getNumberParameter, 'string': inst.getStringParameter, 'int': inst.getIntParameter, 'bool': inst.getBoolParameter} @@ -490,7 +490,7 @@ def transposeFitParametersTable(params_table, output_table=None): def IndentifyDataBoundaries(sample_ws): """ - Indentifies and returns the first and last no zero data point in a workspace + Identifies and returns the first and last no zero data point in a workspace For multiple workspace spectra, the data points that are closest to the centre out of all the spectra in the workspace are returned diff --git a/scripts/Inelastic/IndirectReductionCommon.py b/scripts/Inelastic/IndirectReductionCommon.py index 27198d971728769e322179174cce152b0577f6ef..c3153954aa684b2bf6075e9b1df436a470d7e488 100644 --- a/scripts/Inelastic/IndirectReductionCommon.py +++ b/scripts/Inelastic/IndirectReductionCommon.py @@ -966,7 +966,7 @@ def rebin_reduction(workspace_name, rebin_string, multi_frame_rebin_string, num_ @param multi_frame_rebin_string Rebin string for multiple frame rebinning @param num_bins Max number of bins in input frames """ - from mantid.simpleapi import (Rebin, RebinToWorkspace, SortXAxis) + from mantid.simpleapi import (Rebin, SortXAxis) if rebin_string is not None: if multi_frame_rebin_string is not None and num_bins is not None: @@ -989,9 +989,18 @@ def rebin_reduction(workspace_name, rebin_string, multi_frame_rebin_string, num_ else: try: # If user does not want to rebin then just ensure uniform binning across spectra - RebinToWorkspace(WorkspaceToRebin=workspace_name, - WorkspaceToMatch=workspace_name, - OutputWorkspace=workspace_name) + # extract the binning parameters from the first spectrum. + # there is probably a better way to calculate the binning parameters, but this + # gets the right answer. + xaxis = mtd[workspace_name].readX(0) + params = [] + for i, x in enumerate(xaxis): + params.append(x) + if i < len(xaxis) -1: + params.append(xaxis[i+1] - x) # delta + Rebin(InputWorkspace=workspace_name, + OutputWorkspace=workspace_name, + Params=params) except RuntimeError: logger.warning('Rebinning failed, will try to continue anyway.') diff --git a/scripts/Inelastic/vesuvio/commands.py b/scripts/Inelastic/vesuvio/commands.py index 32de48bb47f2ffcd5c4680e99c54ac40166d4beb..a18122fd96b99e088c90dba3921fcf8ce2c872df 100644 --- a/scripts/Inelastic/vesuvio/commands.py +++ b/scripts/Inelastic/vesuvio/commands.py @@ -258,7 +258,7 @@ class VesuvioTOFFitRoutineIteration(object): class VesuvioMSHelper(object): """ - A helper class for storing and manipulating the multiple scattering paramaters of + A helper class for storing and manipulating the multiple scattering parameters of the Vesuvio TOF Fit Routine. Attributes: diff --git a/scripts/Interface/reduction_gui/reduction/sans/hfir_options_script.py b/scripts/Interface/reduction_gui/reduction/sans/hfir_options_script.py index 97ba2a4da97347cf9dd5ab7bb9e90077f403919f..b00af8fa58dab1d020a4463019238bd67dec0b4f 100644 --- a/scripts/Interface/reduction_gui/reduction/sans/hfir_options_script.py +++ b/scripts/Interface/reduction_gui/reduction/sans/hfir_options_script.py @@ -15,7 +15,7 @@ class ReductionOptions(BaseScriptElement): ny_pixels = 192 pixel_size = 5.1 - # Absoulte scale + # Absolute scale scaling_factor = 1.0 calculate_scale = False scaling_direct_file = '' diff --git a/scripts/Interface/reduction_gui/widgets/diffraction/diffraction_adv_setup.py b/scripts/Interface/reduction_gui/widgets/diffraction/diffraction_adv_setup.py index b0d709ef8f982d896731be733eec29248554ed44..9a32c96137b8876e41f65124ed13eb25cf6f443a 100644 --- a/scripts/Interface/reduction_gui/widgets/diffraction/diffraction_adv_setup.py +++ b/scripts/Interface/reduction_gui/widgets/diffraction/diffraction_adv_setup.py @@ -99,8 +99,8 @@ class AdvancedSetupWidget(BaseWidget): self.connect(self._content.help_button, QtCore.SIGNAL("clicked()"), self._show_help) - # Hanlder for events - # TODO - Need to add an event hanlder for the change of instrument and facility + # Handler for events + # TODO - Need to add an event handler for the change of instrument and facility # Validated widgets diff --git a/scripts/Interface/reduction_gui/widgets/diffraction/diffraction_run_setup.py b/scripts/Interface/reduction_gui/widgets/diffraction/diffraction_run_setup.py index 95d268b69923a64b839b58e11beb8686fbdec918..abca9cee7df545b8295c3611bce2ffd801657afe 100644 --- a/scripts/Interface/reduction_gui/widgets/diffraction/diffraction_run_setup.py +++ b/scripts/Interface/reduction_gui/widgets/diffraction/diffraction_run_setup.py @@ -314,7 +314,7 @@ class RunSetupWidget(BaseWidget): return s def _calfile_browse(self): - """ Event handing for browsing calibrtion file + """ Event handing for browsing calibration file """ fname = self.data_browse_dialog(data_type="*.h5;;*.cal;;*.hd5;;*.hdf;;*") if fname: @@ -323,7 +323,7 @@ class RunSetupWidget(BaseWidget): return def _charfile_browse(self): - """ Event handing for browsing calibrtion file + """ Event handing for browsing calibration file """ fname = self.data_browse_dialog("*.txt;;*", multi=True) if fname: @@ -439,7 +439,7 @@ class RunSetupWidget(BaseWidget): return True, '', intliststring def _overrideemptyrun_clicked(self): - """ Handling event if overriding emptry run + """ Handling event if overriding empty run """ if self._content.override_emptyrun_checkBox.isChecked() is True: self._content.emptyrun_edit.setEnabled(True) @@ -451,7 +451,7 @@ class RunSetupWidget(BaseWidget): return def _overridevanrun_clicked(self): - """ Handling event if overriding emptry run + """ Handling event if overriding empty run """ if self._content.override_vanrun_checkBox.isChecked() is True: self._content.vanrun_edit.setEnabled(True) @@ -463,7 +463,7 @@ class RunSetupWidget(BaseWidget): return def _overridevanbkgdrun_clicked(self): - """ Handling event if overriding emptry run + """ Handling event if overriding empty run """ if self._content.override_vanbkgdrun_checkBox.isChecked() is True: self._content.vanbkgdrun_edit.setEnabled(True) diff --git a/scripts/Interface/ui/diffraction/diffraction_adv_setup.ui b/scripts/Interface/ui/diffraction/diffraction_adv_setup.ui index 97deb39038c55b550031a9e35c6fa5acf00d1715..87e5d2a0a648456de5374ece1bd2384dcc080af5 100644 --- a/scripts/Interface/ui/diffraction/diffraction_adv_setup.ui +++ b/scripts/Interface/ui/diffraction/diffraction_adv_setup.ui @@ -435,7 +435,7 @@ <item row="4" column="1"> <widget class="QLineEdit" name="scaledata_edit"> <property name="toolTip"> - <string>Constant to multiply the data by before writting out</string> + <string>Constant to multiply the data by before writing out</string> </property> </widget> </item> @@ -461,7 +461,7 @@ </size> </property> <property name="text"> - <string>Minumum Cropped Wavelength</string> + <string>Minimum Cropped Wavelength</string> </property> </widget> </item> diff --git a/scripts/Interface/ui/diffraction/diffraction_run_setup.ui b/scripts/Interface/ui/diffraction/diffraction_run_setup.ui index 020bcbb9da0aa5e3ecfaba73dbcffe35b17d8d91..4ce255bd7bad71bc5fac44de9994f0f18149ccb1 100644 --- a/scripts/Interface/ui/diffraction/diffraction_run_setup.ui +++ b/scripts/Interface/ui/diffraction/diffraction_run_setup.ui @@ -726,7 +726,7 @@ </property> <property name="text"> <string>If characterization file is given, the correction run numbers are given by the file. -The corrections can be overriden and disabled though.</string> +The corrections can be overridden and disabled though.</string> </property> </widget> </item> @@ -737,7 +737,7 @@ The corrections can be overriden and disabled though.</string> <item row="0" column="3"> <widget class="QCheckBox" name="disablebkgdcorr_chkbox"> <property name="toolTip"> - <string><html><head/><body><p>Disable emptry/background correction.</p></body></html></string> + <string><html><head/><body><p>Disable empty/background correction.</p></body></html></string> </property> <property name="statusTip"> <string>Select to set the detector distance offset.</string> diff --git a/scripts/Interface/ui/reflectometer/refl_gui.py b/scripts/Interface/ui/reflectometer/refl_gui.py index 5f37b1a2cfc0492a4b4d6bb6a588737860977b9c..848268962cddf013a0f3aca3dae41767e1bd3ec1 100644 --- a/scripts/Interface/ui/reflectometer/refl_gui.py +++ b/scripts/Interface/ui/reflectometer/refl_gui.py @@ -276,7 +276,7 @@ We recommend you use ISIS Reflectometry instead, If this is not possible contact def _reset_table(self): """ - Reset the plot buttons and stitch checkboxes back to thier defualt state + Reset the plot buttons and stitch checkboxes back to their default state """ # switches from current to true, to false to make sure stateChanged fires self.checkTickAll.setCheckState(2) diff --git a/scripts/Interface/ui/reflectometer/refl_save.py b/scripts/Interface/ui/reflectometer/refl_save.py index 6bd68612da3e827b6d129951f5ce3a87556f8e13..8cf2ef782d37df5e77c216c5e5ffd682c862357f 100644 --- a/scripts/Interface/ui/reflectometer/refl_save.py +++ b/scripts/Interface/ui/reflectometer/refl_save.py @@ -314,7 +314,7 @@ class Ui_SaveWindow(object): except: print("Journal does not exist or is unreachable, please check your network connection.") -#--------- If "Save" button pressed, selcted workspaces are saved ------------- +#--------- If "Save" button pressed, selected workspaces are saved ------------- def buttonClickHandler1(self): prefix = str(self.lineEdit2.text()) if not (self.lineEdit.text() and os.path.exists(self.lineEdit.text())): diff --git a/scripts/Interface/ui/sans_isis/masking_table.ui b/scripts/Interface/ui/sans_isis/masking_table.ui index 29da7e2fb9998c60da19b8c66649e258fb599ba2..d79aeb097c674cdae9386ec2488ba2620e4fcab7 100644 --- a/scripts/Interface/ui/sans_isis/masking_table.ui +++ b/scripts/Interface/ui/sans_isis/masking_table.ui @@ -72,7 +72,7 @@ <item row="2" column="1"> <widget class="QPushButton" name="display_mask_push_button"> <property name="toolTip"> - <string><html><head/><body><p>Displays the masked scatter sample workspace in the InstrumentView. Note that the generation of the InstrumentView migth take several seconds.</p></body></html></string> + <string><html><head/><body><p>Displays the masked scatter sample workspace in the InstrumentView. Note that the generation of the InstrumentView might take several seconds.</p></body></html></string> </property> <property name="text"> <string>Display Mask</string> diff --git a/scripts/Interface/ui/sans_isis/sans_data_processor_gui.py b/scripts/Interface/ui/sans_isis/sans_data_processor_gui.py index dd0ac54f5067cfa14dfc230d5867962d57b63135..f537ad363a04e8536303eb3bc02dcce7897873ad 100644 --- a/scripts/Interface/ui/sans_isis/sans_data_processor_gui.py +++ b/scripts/Interface/ui/sans_isis/sans_data_processor_gui.py @@ -98,40 +98,56 @@ class SANSDataProcessorGui(QtGui.QMainWindow, ui_sans_data_processor_window.Ui_S pass @abstractmethod - def on_processing_finished(self): + def on_multi_period_selection(self, show_periods): pass @abstractmethod - def on_multi_period_selection(self): + def on_data_changed(self, row, column, new_value, old_value): pass @abstractmethod - def on_data_changed(self): + def on_manage_directories(self): pass @abstractmethod - def on_manage_directories(self): + def on_instrument_changed(self): pass @abstractmethod - def on_instrument_changed(self): + def on_row_inserted(self): + pass + + @abstractmethod + def on_rows_removed(self): + pass + + @abstractmethod + def on_copy_rows_requested(self): + pass + + @abstractmethod + def on_paste_rows_requested(self): + pass + + @abstractmethod + def on_insert_row(self): + pass + + @abstractmethod + def on_erase_rows(self): pass - def __init__(self, main_presenter): + @abstractmethod + def on_cut_rows(self): + pass + + def __init__(self): """ Initialise the interface """ super(QtGui.QMainWindow, self).__init__() self.setupUi(self) - # Main presenter - self._main_presenter = main_presenter - - # Algorithm configuration - self._gui_algorithm_name = self._main_presenter.get_gui_algorithm_name() - self._white_list_entries = self._main_presenter.get_white_list() - self._black_list = self._main_presenter.get_black_list() - # Listeners allow us to to notify all presenters self._settings_listeners = [] @@ -159,9 +175,31 @@ class SANSDataProcessorGui(QtGui.QMainWindow, ui_sans_data_processor_window.Ui_S self.instrument = SANSInstrument.from_string(instrument_name) + self.paste_button.setIcon(QtGui.QIcon(":/paste.png")) + self.copy_button.setIcon(QtGui.QIcon(":/copy.png")) + self.cut_button.setIcon(QtGui.QIcon(":/cut.png")) + self.erase_button.setIcon(QtGui.QIcon(":/erase.png")) + self.delete_row_button.setIcon(QtGui.QIcon(":/delete_row.png")) + self.insert_row_button.setIcon(QtGui.QIcon(":/insert_row.png")) + + self.paste_button.clicked.connect(self._paste_rows_requested) + self.copy_button.clicked.connect(self._copy_rows_requested) + self.erase_button.clicked.connect(self._erase_rows) + self.cut_button.clicked.connect(self._cut_rows) + + self.delete_row_button.clicked.connect(self._remove_rows_requested_from_button) + self.insert_row_button.clicked.connect(self._on_insert_button_pressed) + # Attach validators self._attach_validators() + self._setup_progress_bar() + + def _setup_progress_bar(self): + self.batch_progress_bar.setMinimum(0) + self.batch_progress_bar.setMaximum(1) + self.batch_progress_bar.setValue(0) + def add_listener(self, listener): if not isinstance(listener, SANSDataProcessorGui.RunTabListener): raise ValueError("The listener is not of type RunTabListener but rather {}".format(type(listener))) @@ -237,7 +275,7 @@ class SANSDataProcessorGui(QtGui.QMainWindow, ui_sans_data_processor_window.Ui_S self.instrument_combo_box.currentIndexChanged.connect(self._instrument_changed) - self.process_button.clicked.connect(self._on_python_process) + self.process_button.clicked.connect(self._processed_clicked) self.help_button.clicked.connect(self._on_help_button_clicked) @@ -289,13 +327,6 @@ class SANSDataProcessorGui(QtGui.QMainWindow, ui_sans_data_processor_window.Ui_S # Q Resolution self.q_resolution_moderator_file_push_button.clicked.connect(self._on_load_moderator_file) - self.plot_results_checkbox.stateChanged.connect(self._on_plot_results_toggled) - self.use_optimizations_checkbox.stateChanged.connect(self._on_use_optimisations_changed) - - self.output_mode_memory_radio_button.toggled.connect(self._on_output_mode_changed) - self.output_mode_file_radio_button.toggled.connect(self._on_output_mode_changed) - self.output_mode_both_radio_button.toggled.connect(self._on_output_mode_changed) - self.wavelength_stacked_widget.setCurrentIndex(0) return True @@ -306,58 +337,57 @@ class SANSDataProcessorGui(QtGui.QMainWindow, ui_sans_data_processor_window.Ui_S else: self.wavelength_stacked_widget.setCurrentIndex(0) - def _on_output_mode_changed(self, state): - self.data_processor_table.settingsChanged() - - def _on_use_optimisations_changed(self, state): - self.data_processor_table.settingsChanged() - - def _on_plot_results_toggled(self, state): - self.data_processor_table.settingsChanged() - def create_data_table(self, show_periods): # Delete an already existing table if self.data_processor_table: self.data_processor_table.setParent(None) - # Create the white list - self._white_list_entries = self._main_presenter.get_white_list(show_periods=show_periods) + self.data_processor_table = MantidQt.MantidWidgets.Batch.JobTreeView( + ["Sample Scatter", "ssp", "Sample Transmission", "stp", "Sample Direct", "sdp","Can Scatter", "csp", + "Can Transmission", "ctp", "Can Direct", "cdp", "Output Name", "User File", "Sample Thickness", "Options"] + , self.cell(""), self) - # Setup white list - white_list = MantidQt.MantidWidgets.DataProcessor.WhiteList() - for entry in self._white_list_entries: - # If there is a column name specified, then it is a white list entry. - if entry.column_name: - white_list.addElement(entry.column_name, entry.algorithm_property, entry.description, - entry.show_value, entry.prefix) + self.data_processor_table.setRootIsDecorated(False) - # Processing algorithm (mandatory) - unused_postprocessing_index = 0 - alg = MantidQt.MantidWidgets.DataProcessor.ProcessingAlgorithm(self._gui_algorithm_name, - 'unused_', unused_postprocessing_index, self._black_list) + row_entry = [''] * 16 + self.add_row(row_entry) + self._call_settings_listeners(lambda listener: listener.on_row_inserted(0, row_entry)) - self.data_processor_table = MantidQt.MantidWidgets.DataProcessor.QDataProcessorWidget(white_list, alg, self) - self.data_processor_table.setForcedReProcessing(True) + self.table_signals = \ + MantidQt.MantidWidgets.Batch.JobTreeViewSignalAdapter(self.data_processor_table, self) + # The signal adapter subscribes to events from the table + # and emits signals whenever it is notified. - # Add the presenter to the data processor - self.data_processor_table.accept(self._main_presenter) + if show_periods: + self.show_period_columns() + else: + self.hide_period_columns() # Set the list of available instruments in the widget and the default instrument instrument_name = config.getString("default.instrument") instrument_name_enum = get_instrument(instrument_name) - self.data_processor_table.setInstrumentList(SANSDataProcessorGui.INSTRUMENTS, instrument_name) if instrument_name_enum: self.set_instrument_settings(instrument_name_enum) self._instrument_changed() - # The widget will emit a 'runAsPythonScript' signal to run python code - self.data_processor_table.runAsPythonScript.connect(self._run_python_code) - self.data_processor_table.processButtonClicked.connect(self._processed_clicked) - self.data_processor_table.processingFinished.connect(self._processing_finished) self.data_processor_widget_layout.addWidget(self.data_processor_table) - self.data_processor_table.dataChanged.connect(self._data_changed) - self.data_processor_table.instrumentHasChanged.connect(self._handle_instrument_change) + self.table_signals.cellTextChanged.connect(self._data_changed) + self.table_signals.rowInserted.connect(self._row_inserted) + self.table_signals.removeRowsRequested.connect(self._remove_rows_requested) + self.table_signals.copyRowsRequested.connect(self._copy_rows_requested) + self.table_signals.pasteRowsRequested.connect(self._paste_rows_requested) + + def cell(self, text): + background_color = 'white' + border_thickness = 1 + border_color = "black" + border_opacity = 255 + is_editable = True + return MantidQt.MantidWidgets.Batch.Cell(text, background_color, border_thickness, border_color, border_opacity, is_editable) + + def row(self, path): + return MantidQt.MantidWidgets.Batch.RowLocation(path) def _setup_main_tab(self): self.user_file_button.clicked.connect(self._on_user_file_load) @@ -379,12 +409,44 @@ class SANSDataProcessorGui(QtGui.QMainWindow, ui_sans_data_processor_window.Ui_S """ self._call_settings_listeners(lambda listener: listener.on_processing_finished()) - def _data_changed(self): - self._call_settings_listeners(lambda listener: listener.on_data_changed()) + def _data_changed(self, row_location, column, old_value, new_value): + row = row_location.rowRelativeToParent() + self._call_settings_listeners(lambda listener: listener.on_data_changed(row, column, str(new_value), (old_value))) + + def _row_inserted(self, row_location): + if row_location.depth() > 1: + self.data_processor_table.removeRowAt(row_location) + else: + index = row_location.rowRelativeToParent() + row = self.get_row(row_location) + self._call_settings_listeners(lambda listener: listener.on_row_inserted(index, row)) + + def _remove_rows_requested(self, rows): + rows = [item.rowRelativeToParent() for item in rows] + self._call_settings_listeners(lambda listener: listener.on_rows_removed(rows)) + + def _remove_rows_requested_from_button(self): + rows = self.get_selected_rows() + self._call_settings_listeners(lambda listener: listener.on_rows_removed(rows)) + + def _copy_rows_requested(self): + self._call_settings_listeners(lambda listener: listener.on_copy_rows_requested()) + + def _erase_rows(self): + self._call_settings_listeners(lambda listener: listener.on_erase_rows()) + + def _cut_rows(self): + self._call_settings_listeners(lambda listener: listener.on_cut_rows()) + + def _paste_rows_requested(self): + self._call_settings_listeners(lambda listener: listener.on_paste_rows_requested()) def _instrument_changed(self): self._call_settings_listeners(lambda listener: listener.on_instrument_changed()) + def _on_insert_button_pressed(self): + self._call_settings_listeners(lambda listener: listener.on_insert_row()) + def _on_help_button_clicked(self): pymantidplot.proxies.showCustomInterfaceHelp('ISIS SANS v2') @@ -423,9 +485,6 @@ class SANSDataProcessorGui(QtGui.QMainWindow, ui_sans_data_processor_window.Ui_S instrument = get_instrument_from_gui_selection(instrument_string) self.instrument = instrument - def _on_python_process(self): - self.data_processor_table.processClicked() - def disable_buttons(self): self.process_button.setEnabled(False) self.instrument_combo_box.setEnabled(False) @@ -634,10 +693,7 @@ class SANSDataProcessorGui(QtGui.QMainWindow, ui_sans_data_processor_window.Ui_S self._call_settings_listeners(lambda listener: listener.on_mask_file_add()) def _on_multi_period_selection(self): - # Check if multi-period should be enabled - show_periods = self.multi_period_check_box.isChecked() - self.create_data_table(show_periods=show_periods) - self._call_settings_listeners(lambda listener: listener.on_multi_period_selection()) + self._call_settings_listeners(lambda listener: listener.on_multi_period_selection(self.is_multi_period_view())) def _on_manage_directories(self): self._call_settings_listeners(lambda listener: listener.on_manage_directories()) @@ -653,8 +709,6 @@ class SANSDataProcessorGui(QtGui.QMainWindow, ui_sans_data_processor_window.Ui_S reduction_mode_list = get_reduction_mode_strings_for_gui(instrument) self.set_reduction_modes(reduction_mode_list) - self.data_processor_table.on_comboProcessInstrument_currentIndexChanged(self.instrument_combo_box.currentIndex()) - def update_gui_combo_box(self, value, expected_type, combo_box): # There are two types of values that can be passed: # Lists: we set the combo box to the values in the list @@ -681,9 +735,6 @@ class SANSDataProcessorGui(QtGui.QMainWindow, ui_sans_data_processor_window.Ui_S else: gui_element.addItem(element) - def halt_process_flag(self): - self.data_processor_table.skipProcessing() - @staticmethod def _set_enum_as_element_in_combo_box(gui_element, element, expected_type): value_as_string = expected_type.to_string(element) @@ -755,6 +806,30 @@ class SANSDataProcessorGui(QtGui.QMainWindow, ui_sans_data_processor_window.Ui_S def zero_error_free(self, value): self.save_zero_error_free.setChecked(value) + @property + def progress_bar_minimum(self): + return self.batch_progress_bar.minimum() + + @progress_bar_minimum.setter + def progress_bar_minimum(self, value): + self.batch_progress_bar.setMinimum(value) + + @property + def progress_bar_maximum(self): + return self.batch_progress_bar.maximum() + + @progress_bar_maximum.setter + def progress_bar_maximum(self, value): + self.batch_progress_bar.setMaximum(value) + + @property + def progress_bar_value(self): + return self.batch_progress_bar.value() + + @progress_bar_value.setter + def progress_bar_value(self, progress): + self.batch_progress_bar.setValue(progress) + # ----------------------------------------------------------------- # Global options # ----------------------------------------------------------------- @@ -1797,108 +1872,83 @@ class SANSDataProcessorGui(QtGui.QMainWindow, ui_sans_data_processor_window.Ui_S # Table interaction # ------------------------------------------------------------------------------------------------------------------ def get_cell(self, row, column, convert_to=None): - value = self.data_processor_table.getCell(row, column) + row_location = self.row([row]) + value = self.data_processor_table.cellAt(row_location, column).contentText() return value if convert_to is None else convert_to(value) def set_cell(self, value, row, column): value_as_str = str(value) - self.data_processor_table.setCell(value_as_str, row, column) - - def get_number_of_rows(self): - return self.data_processor_table.getNumberOfRows() + cell = self.data_processor_table.cellAt(row, column) + cell.setContentText(value_as_str) + self.data_processor_table.setCellAt(row, column, cell) + + def change_row_color(self, color, row): + row_location = self.row([row]) + cell_data = self.data_processor_table.cellsAt(row_location) + for index, cell in enumerate(cell_data): + cell.setBackgroundColor(color) + self.data_processor_table.setCellAt(row_location, index, cell) + + def set_row_tooltip(self, tool_tip, row): + row_location = self.row([row]) + cell_data = self.data_processor_table.cellsAt(row_location) + for index, cell in enumerate(cell_data): + cell.setToolTip(tool_tip) + self.data_processor_table.setCellAt(row_location, index, cell) + + def get_selected_rows(self): + row_locations = self.data_processor_table.selectedRowLocations() + rows = [x.rowRelativeToParent() for x in row_locations] + return rows + + def get_row(self, row_location): + cell_data = self.data_processor_table.cellsAt(row_location) + return [str(x.contentText()) for x in cell_data] def clear_table(self): - self.data_processor_table.clearTable() + self.data_processor_table.removeAllRows() - def add_row(self, value): - """ - Inserts a row in to the table. + def clear_selection(self): + self.data_processor_table.clearSelection() - The value needs to have the form: "Input:test,Output:test,Options:OutputWorkspace=2", where the keys - are the names of the column - :param value: the value specifying a row - """ - self.data_processor_table.transfer([value]) + def update_table_selection(self, row_locations): + row_locations = [self.row([x]) for x in row_locations] + self.data_processor_table.setSelectedRowLocations(row_locations) - # ------------------------------------------------------------------------------------------------------------------ - # NON-ESSENTIAL (Should we get rid of it?) - # ------------------------------------------------------------------------------------------------------------------ - def add_actions_to_menus(self, workspace_list): - """ - Initialize table actions. Some table actions are not shown with the widget but they can be added to - external menus. - In this interface we have a 'File' menu and an 'Edit' menu - """ - self.menuEdit.clear() - self.menuFile.clear() - - # Actions that go in the 'Edit' menu - self._create_action(MantidQt.MantidWidgets.DataProcessor.ProcessCommand(self.data_processor_table), - self.menuEdit) - self._create_action(MantidQt.MantidWidgets.DataProcessor.PlotRowCommand(self.data_processor_table), - self.menuEdit) - self._create_action(MantidQt.MantidWidgets.DataProcessor.AppendRowCommand(self.data_processor_table), - self.menuEdit) - self._create_action(MantidQt.MantidWidgets.DataProcessor.CopySelectedCommand(self.data_processor_table), - self.menuEdit) - self._create_action(MantidQt.MantidWidgets.DataProcessor.CutSelectedCommand(self.data_processor_table), - self.menuEdit) - self._create_action(MantidQt.MantidWidgets.DataProcessor.PasteSelectedCommand(self.data_processor_table), - self.menuEdit) - self._create_action(MantidQt.MantidWidgets.DataProcessor.ClearSelectedCommand(self.data_processor_table), - self.menuEdit) - self._create_action(MantidQt.MantidWidgets.DataProcessor.DeleteRowCommand(self.data_processor_table), - self.menuEdit) - - # Actions that go in the 'File' menu - self._create_action(MantidQt.MantidWidgets.DataProcessor.OpenTableCommand(self.data_processor_table), - self.menuFile, workspace_list) - self._create_action(MantidQt.MantidWidgets.DataProcessor.NewTableCommand(self.data_processor_table), - self.menuFile) - self._create_action(MantidQt.MantidWidgets.DataProcessor.SaveTableCommand(self.data_processor_table), - self.menuFile) - self._create_action(MantidQt.MantidWidgets.DataProcessor.SaveTableAsCommand(self.data_processor_table), - self.menuFile) - self._create_action(MantidQt.MantidWidgets.DataProcessor.ImportTableCommand(self.data_processor_table), - self.menuFile) - self._create_action(MantidQt.MantidWidgets.DataProcessor.ExportTableCommand(self.data_processor_table), - self.menuFile) - self._create_action(MantidQt.MantidWidgets.DataProcessor.OptionsCommand(self.data_processor_table), - self.menuFile) - - def _create_action(self, command, menu, workspace_list=None): - """ - Create an action from a given DataProcessorCommand and add it to a given menu - A 'workspace_list' can be provided but it is only intended to be used with OpenTableCommand. - It refers to the list of table workspaces in the ADS that could be loaded into the widget. Note that only - table workspaces with an appropriate number of columns and column types can be loaded. - """ - if (workspace_list is not None and command.name() == "Open Table"): - submenu = QtGui.QMenu(command.name(), self) - submenu.setIcon(QtGui.QIcon(command.icon())) + def add_row(self, value): + value = [self.cell(x) for x in value] + self.data_processor_table.appendChildRowOf(self.row([]), value) - for ws in workspace_list: - ws_command = MantidQt.MantidWidgets.DataProcessor.WorkspaceCommand(self.data_processor_table, ws) - action = QtGui.QAction(QtGui.QIcon(ws_command.icon()), ws_command.name(), self) - action.triggered.connect(lambda: self._connect_action(ws_command)) - submenu.addAction(action) + def remove_rows(self, rows): + rows = [self.row([item]) for item in rows] + self.data_processor_table.removeRows(rows) - menu.addMenu(submenu) - else: - action = QtGui.QAction(QtGui.QIcon(command.icon()), command.name(), self) - action.setShortcut(command.shortcut()) - action.setStatusTip(command.tooltip()) - action.triggered.connect(lambda: self._connect_action(command)) - menu.addAction(action) + def insert_empty_row(self, row_index): + self.data_processor_table.insertChildRowOf(self.row([]), row_index) - def _connect_action(self, command): - """ - Executes an action - """ - command.execute() + def set_hinting_line_edit_for_column(self, column, hint_strategy): + self.data_processor_table.setHintsForColumn(column, hint_strategy) def _run_python_code(self, text): """ Re-emits 'runPytonScript' signal """ mantidplot.runPythonScript(text, True) + + def hide_period_columns(self): + self.multi_period_check_box.setChecked(False) + self.data_processor_table.hideColumn(1) + self.data_processor_table.hideColumn(3) + self.data_processor_table.hideColumn(5) + self.data_processor_table.hideColumn(7) + self.data_processor_table.hideColumn(9) + self.data_processor_table.hideColumn(11) + + def show_period_columns(self): + self.multi_period_check_box.setChecked(True) + self.data_processor_table.showColumn(1) + self.data_processor_table.showColumn(3) + self.data_processor_table.showColumn(5) + self.data_processor_table.showColumn(7) + self.data_processor_table.showColumn(9) + self.data_processor_table.showColumn(11) diff --git a/scripts/Interface/ui/sans_isis/sans_data_processor_window.ui b/scripts/Interface/ui/sans_isis/sans_data_processor_window.ui index de82db1a362f44e349339866f2059a8b39c7bed2..4aaffe722a805381f062d026f1c1967c9572739f 100644 --- a/scripts/Interface/ui/sans_isis/sans_data_processor_window.ui +++ b/scripts/Interface/ui/sans_isis/sans_data_processor_window.ui @@ -95,7 +95,7 @@ QGroupBox::title { <item> <widget class="QStackedWidget" name="main_stacked_widget"> <property name="currentIndex"> - <number>1</number> + <number>0</number> </property> <widget class="QWidget" name="run_page"> <layout class="QVBoxLayout" name="verticalLayout_3"> @@ -119,23 +119,53 @@ QGroupBox::title { </property> </widget> </item> - <item row="1" column="5"> - <widget class="QPushButton" name="user_file_button"> + <item row="0" column="4"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QComboBox" name="instrument_combo_box"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>834</width> + <height>16777215</height> + </size> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="1" column="4"> + <widget class="QLineEdit" name="user_file_line_edit"> <property name="toolTip"> <string><html><head/><body><p>Specify the user file (aka mask file) which is used to provide the bulk of the reduction settings. For a list of user file commands see <a href="https://www.mantidproject.org/SANS_User_File_Commands"><span style=" text-decoration: underline; color:#0000ff;">here</span></a>.</p></body></html></string> </property> - <property name="text"> - <string>Load User File</string> - </property> </widget> </item> - <item row="2" column="1"> - <widget class="QLabel" name="batch_label"> + <item row="2" column="5"> + <widget class="QPushButton" name="batch_button"> <property name="toolTip"> <string><html><head/><body><p>Specify a batch file to load. For the batch file format see <a href="https://www.mantidproject.org/SANS_batch_file_format"><span style=" text-decoration: underline; color:#0000ff;">here</span></a>.</p></body></html></string> </property> <property name="text"> - <string>Batch File:</string> + <string>Load Batch File</string> </property> </widget> </item> @@ -146,20 +176,13 @@ QGroupBox::title { </property> </widget> </item> - <item row="1" column="4"> - <widget class="QLineEdit" name="user_file_line_edit"> - <property name="toolTip"> - <string><html><head/><body><p>Specify the user file (aka mask file) which is used to provide the bulk of the reduction settings. For a list of user file commands see <a href="https://www.mantidproject.org/SANS_User_File_Commands"><span style=" text-decoration: underline; color:#0000ff;">here</span></a>.</p></body></html></string> - </property> - </widget> - </item> - <item row="2" column="5"> - <widget class="QPushButton" name="batch_button"> + <item row="2" column="1"> + <widget class="QLabel" name="batch_label"> <property name="toolTip"> <string><html><head/><body><p>Specify a batch file to load. For the batch file format see <a href="https://www.mantidproject.org/SANS_batch_file_format"><span style=" text-decoration: underline; color:#0000ff;">here</span></a>.</p></body></html></string> </property> <property name="text"> - <string>Load Batch File</string> + <string>Batch File:</string> </property> </widget> </item> @@ -170,6 +193,23 @@ QGroupBox::title { </property> </widget> </item> + <item row="3" column="5"> + <widget class="QPushButton" name="process_button"> + <property name="text"> + <string>Process</string> + </property> + </widget> + </item> + <item row="1" column="5"> + <widget class="QPushButton" name="user_file_button"> + <property name="toolTip"> + <string><html><head/><body><p>Specify the user file (aka mask file) which is used to provide the bulk of the reduction settings. For a list of user file commands see <a href="https://www.mantidproject.org/SANS_User_File_Commands"><span style=" text-decoration: underline; color:#0000ff;">here</span></a>.</p></body></html></string> + </property> + <property name="text"> + <string>Load User File</string> + </property> + </widget> + </item> <item row="0" column="5"> <widget class="QPushButton" name="manage_directories_button"> <property name="text"> @@ -177,51 +217,138 @@ QGroupBox::title { </property> </widget> </item> - <item row="0" column="4"> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> - <widget class="QComboBox" name="instrument_combo_box"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize"> - <size> - <width>834</width> - <height>16777215</height> - </size> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_11"> + <item> + <widget class="QToolButton" name="insert_row_button"> + <property name="toolTip"> + <string><html><head/><body><p>Insert row</p></body></html></string> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="iconSize"> + <size> + <width>24</width> + <height>24</height> + </size> + </property> + </widget> </item> - <item row="3" column="5"> - <widget class="QPushButton" name="process_button"> + <item> + <widget class="QToolButton" name="delete_row_button"> + <property name="toolTip"> + <string><html><head/><body><p>delete selected rows</p></body></html></string> + </property> <property name="text"> - <string>Process</string> + <string>...</string> + </property> + <property name="iconSize"> + <size> + <width>24</width> + <height>24</height> + </size> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line_6"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="copy_button"> + <property name="toolTip"> + <string><html><head/><body><p>copy selected rows</p></body></html></string> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="iconSize"> + <size> + <width>24</width> + <height>24</height> + </size> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="cut_button"> + <property name="toolTip"> + <string><html><head/><body><p>cut selected rows</p></body></html></string> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="iconSize"> + <size> + <width>24</width> + <height>24</height> + </size> </property> </widget> </item> + <item> + <widget class="QToolButton" name="paste_button"> + <property name="toolTip"> + <string><html><head/><body><p>paste rows</p></body></html></string> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="iconSize"> + <size> + <width>24</width> + <height>24</height> + </size> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="erase_button"> + <property name="toolTip"> + <string><html><head/><body><p>erase contents of selected rows</p></body></html></string> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="iconSize"> + <size> + <width>24</width> + <height>24</height> + </size> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> </layout> </item> <item> <layout class="QVBoxLayout" name="data_processor_widget_layout"/> </item> + <item> + <widget class="QProgressBar" name="batch_progress_bar"> + <property name="value"> + <number>24</number> + </property> + </widget> + </item> <item> <layout class="QGridLayout" name="gridLayout_7"> <item row="0" column="3"> @@ -455,7 +582,7 @@ QGroupBox::title { <item row="0" column="0"> <widget class="QLabel" name="reduction_mode_label"> <property name="toolTip"> - <string><html><head/><body><p>The reduction mode. This can be either of the banks of your instrument. In the case of two banks there is also the <span style=" font-style:italic;">Merged</span> and <span style=" font-style:italic;">All</span> mode. <span style=" font-style:italic;">Merged</span> mode stitches the reductions from two banks together. <span style=" font-style:italic;">All</span> mode reduces both banks.</p><p>Note that by default the entries are <span style=" font-style:italic;">LAB</span>, <span style=" font-style:italic;">HAB</span>, <span style=" font-style:italic;">Merged</span>, <span style=" font-style:italic;">All</span>. Once you have specifed data in the batch table, the entry names will be updated to reflect the naming of your instrument.</p></body></html></string> + <string><html><head/><body><p>The reduction mode. This can be either of the banks of your instrument. In the case of two banks there is also the <span style=" font-style:italic;">Merged</span> and <span style=" font-style:italic;">All</span> mode. <span style=" font-style:italic;">Merged</span> mode stitches the reductions from two banks together. <span style=" font-style:italic;">All</span> mode reduces both banks.</p><p>Note that by default the entries are <span style=" font-style:italic;">LAB</span>, <span style=" font-style:italic;">HAB</span>, <span style=" font-style:italic;">Merged</span>, <span style=" font-style:italic;">All</span>. Once you have specified data in the batch table, the entry names will be updated to reflect the naming of your instrument.</p></body></html></string> </property> <property name="text"> <string>Reduction Mode</string> @@ -465,7 +592,7 @@ QGroupBox::title { <item row="0" column="1"> <widget class="QComboBox" name="reduction_mode_combo_box"> <property name="toolTip"> - <string><html><head/><body><p>The reduction mode. This can be either of the banks of your instrument. In the case of two banks there is also the <span style=" font-style:italic;">Merged</span> and <span style=" font-style:italic;">All</span> mode. <span style=" font-style:italic;">Merged</span> mode stitches the reductions from two banks together. <span style=" font-style:italic;">All</span> mode reduces both banks.</p><p>Note that by default the entries are <span style=" font-style:italic;">LAB</span>, <span style=" font-style:italic;">HAB</span>, <span style=" font-style:italic;">Merged</span>, <span style=" font-style:italic;">All</span>. Once you have specifed data in the batch table, the entry names will be updated to reflect the naming of your instrument.</p></body></html></string> + <string><html><head/><body><p>The reduction mode. This can be either of the banks of your instrument. In the case of two banks there is also the <span style=" font-style:italic;">Merged</span> and <span style=" font-style:italic;">All</span> mode. <span style=" font-style:italic;">Merged</span> mode stitches the reductions from two banks together. <span style=" font-style:italic;">All</span> mode reduces both banks.</p><p>Note that by default the entries are <span style=" font-style:italic;">LAB</span>, <span style=" font-style:italic;">HAB</span>, <span style=" font-style:italic;">Merged</span>, <span style=" font-style:italic;">All</span>. Once you have specified data in the batch table, the entry names will be updated to reflect the naming of your instrument.</p></body></html></string> </property> </widget> </item> @@ -548,7 +675,7 @@ QGroupBox::title { <item row="2" column="0"> <widget class="QCheckBox" name="merged_scale_use_fit_check_box"> <property name="toolTip"> - <string><html><head/><body><p>If checked hten the scale will be fit during the merge operation.</p></body></html></string> + <string><html><head/><body><p>If checked then the scale will be fit during the merge operation.</p></body></html></string> </property> <property name="text"> <string>Use Fit</string> @@ -558,7 +685,7 @@ QGroupBox::title { <item row="2" column="1"> <widget class="QCheckBox" name="merged_shift_use_fit_check_box"> <property name="toolTip"> - <string><html><head/><body><p>If checked hten the shift will be fit during the merge operation.</p></body></html></string> + <string><html><head/><body><p>If checked then the shift will be fit during the merge operation.</p></body></html></string> </property> <property name="text"> <string>Use Fit</string> @@ -629,7 +756,7 @@ QGroupBox::title { <item> <widget class="QGroupBox" name="slice_event_group_box"> <property name="toolTip"> - <string><html><head/><body><p>In the case of data which was measured in event-mode, it is possible to perform time-of-flight slices of the data and reduce these separately.</p><p>Input can be:</p><p>-<span style=" font-style:italic;"> start:step:stop</span> specifies time slices from the <span style=" font-style:italic;">start</span> value to the <span style=" font-style:italic;">stop </span>value in steps of <span style=" font-style:italic;">step</span></p><p>- <span style=" font-style:italic;">start-stop </span>which specifies a time slice from the <span style=" font-style:italic;">start</span> value to the <span style=" font-style:italic;">stop</span> value</p><p>- <span style=" font-style:italic;">&gt;start</span> specifies a slice from the <span style=" font-style:italic;">start </span>value to the end of the data set</p><p>- <span style=" font-style:italic;">&lt;stop</span> specifes a slice from the start of the data set to the <span style=" font-style:italic;">stop </span>value</p><p>In addition it is possible to concatenate these specifications useing comma-separation. An example is:</p><p><span style=" font-style:italic;">5-10,12:2:16,20-30</span></p></body></html></string> + <string><html><head/><body><p>In the case of data which was measured in event-mode, it is possible to perform time-of-flight slices of the data and reduce these separately.</p><p>Input can be:</p><p>-<span style=" font-style:italic;"> start:step:stop</span> specifies time slices from the <span style=" font-style:italic;">start</span> value to the <span style=" font-style:italic;">stop </span>value in steps of <span style=" font-style:italic;">step</span></p><p>- <span style=" font-style:italic;">start-stop </span>which specifies a time slice from the <span style=" font-style:italic;">start</span> value to the <span style=" font-style:italic;">stop</span> value</p><p>- <span style=" font-style:italic;">&gt;start</span> specifies a slice from the <span style=" font-style:italic;">start </span>value to the end of the data set</p><p>- <span style=" font-style:italic;">&lt;stop</span> specifes a slice from the start of the data set to the <span style=" font-style:italic;">stop </span>value</p><p>In addition it is possible to concatenate these specifications using comma-separation. An example is:</p><p><span style=" font-style:italic;">5-10,12:2:16,20-30</span></p></body></html></string> </property> <property name="title"> <string>Event Slice</string> @@ -1629,7 +1756,7 @@ QGroupBox::title { <item row="1" column="0"> <widget class="QLabel" name="label_7"> <property name="toolTip"> - <string><html><head/><body><p>It is possible to perform wavelength slices of the data and reduce these separately.</p><p>Input can be:</p><p>-<span style=" font-style:italic;"> start:step:stop</span> specifies wavelength slices from the <span style=" font-style:italic;">start</span> value to the <span style=" font-style:italic;">stop </span>value in steps of <span style=" font-style:italic;">step</span></p><p>- <span style=" font-style:italic;">start-stop </span>which specifies a wavelength slice from the <span style=" font-style:italic;">start</span> value to the <span style=" font-style:italic;">stop</span> value</p><p>- <span style=" font-style:italic;">&gt;start</span> specifies a slice from the <span style=" font-style:italic;">start </span>value to the end of the data set</p><p>- <span style=" font-style:italic;">&lt;stop</span> specifes a slice from the start of the data set to the <span style=" font-style:italic;">stop </span>value</p><p>In addition it is possible to concatenate these specifications useing comma-separation. An example is:</p><p><span style=" font-style:italic;">5-10,12:2:16,20-30</span></p><p>A reduction will always be done between the maximum and minimum wavelengths of a given set.</p></body></html></string> + <string><html><head/><body><p>It is possible to perform wavelength slices of the data and reduce these separately.</p><p>Input can be:</p><p>-<span style=" font-style:italic;"> start:step:stop</span> specifies wavelength slices from the <span style=" font-style:italic;">start</span> value to the <span style=" font-style:italic;">stop </span>value in steps of <span style=" font-style:italic;">step</span></p><p>- <span style=" font-style:italic;">start-stop </span>which specifies a wavelength slice from the <span style=" font-style:italic;">start</span> value to the <span style=" font-style:italic;">stop</span> value</p><p>- <span style=" font-style:italic;">&gt;start</span> specifies a slice from the <span style=" font-style:italic;">start </span>value to the end of the data set</p><p>- <span style=" font-style:italic;">&lt;stop</span> specifes a slice from the start of the data set to the <span style=" font-style:italic;">stop </span>value</p><p>In addition it is possible to concatenate these specifications using comma-separation. An example is:</p><p><span style=" font-style:italic;">5-10,12:2:16,20-30</span></p><p>A reduction will always be done between the maximum and minimum wavelengths of a given set.</p></body></html></string> </property> <property name="text"> <string>Ranges [Ã…]</string> @@ -2080,28 +2207,6 @@ QGroupBox::title { </item> </layout> </widget> - <widget class="QMenuBar" name="menuBar"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>1211</width> - <height>22</height> - </rect> - </property> - <widget class="QMenu" name="menuEdit"> - <property name="title"> - <string>&Edit</string> - </property> - </widget> - <widget class="QMenu" name="menuFile"> - <property name="title"> - <string>Fi&le</string> - </property> - </widget> - <addaction name="menuFile"/> - <addaction name="menuEdit"/> - </widget> </widget> <customwidgets> <customwidget> diff --git a/scripts/LargeScaleStructures/data_stitching.py b/scripts/LargeScaleStructures/data_stitching.py index a87502228de1de4617e7ceb9080fd4a3c1699d96..4e9c4733a793b3d3ba98ac450521896d5f120255 100644 --- a/scripts/LargeScaleStructures/data_stitching.py +++ b/scripts/LargeScaleStructures/data_stitching.py @@ -271,7 +271,7 @@ class DataSet(object): def load(self, update_range=False, restricted_range=False): """ Load a data set from file - @param upate_range: if True, the Q range of the data set will be udpated + @param upate_range: if True, the Q range of the data set will be updated @param restricted_range: if True, zeros at the beginning and end will be stripped """ if os.path.isfile(self._file_path): diff --git a/scripts/LargeScaleStructures/geometry_writer.py b/scripts/LargeScaleStructures/geometry_writer.py index 0736201be5404093ac2232276f95515b601c1a27..8f986f55c84ab08dff3de5ecefaff6d733120faf 100644 --- a/scripts/LargeScaleStructures/geometry_writer.py +++ b/scripts/LargeScaleStructures/geometry_writer.py @@ -390,7 +390,7 @@ class MantidGeom(object): step2, ...]. If no step is required, use None. """ if len(idlist) % 3 != 0: - raise IndexError("Please specifiy list as [start1, end1, step1, " + raise IndexError("Please specify list as [start1, end1, step1, " + "start2, end2, step2, ...]. If no step is" + "required, use None.") num_ids = len(idlist) / 3 diff --git a/scripts/Muon/GUI/ElementalAnalysis/Plotting/plotting_view.py b/scripts/Muon/GUI/ElementalAnalysis/Plotting/plotting_view.py index 1e93d7872dd258e1fc8332e06cd9d587567bdfdb..8d5180cfc4c1187a357f728c78f7c2a04125fe38 100644 --- a/scripts/Muon/GUI/ElementalAnalysis/Plotting/plotting_view.py +++ b/scripts/Muon/GUI/ElementalAnalysis/Plotting/plotting_view.py @@ -248,7 +248,7 @@ class PlotView(QtWidgets.QWidget): self.workspace_plots[name] = lines def plot_workspace_errors(self, name, workspace): - """ Plots a workspace with errrors, and appends caps/bars to the subplot list. """ + """ Plots a workspace with errors, and appends caps/bars to the subplot list. """ subplot = self.get_subplot(name) line, cap_lines, bar_lines = plots.plotfunctions.errorbar( subplot, workspace, specNum=1) diff --git a/scripts/Muon/MaxentTools/multimaxalpha.py b/scripts/Muon/MaxentTools/multimaxalpha.py index 680204cfd815d3ffe2f2df3549d03d9992ff9158..a26f21346d50c09403fe93f63da3eef1ecce28b9 100644 --- a/scripts/Muon/MaxentTools/multimaxalpha.py +++ b/scripts/Muon/MaxentTools/multimaxalpha.py @@ -54,7 +54,7 @@ def MULTIMAX( else: (SENSE_phi, DETECT_a, DETECT_b, AMPS_amp) = MODAB(RUNDATA_hists, datum, sigma, MISSCHANNELS_mm, MAXPAGE_f, PULSESHAPE_convol, DETECT_e, SAVETIME_i2, mylog) - # outout per-iteration debug info + # output per-iteration debug info if(phaseconvWS): offset = 0 for k in range(POINTS_ngroups+len(deadDetectors)): diff --git a/scripts/PyChop/ISISDisk.py b/scripts/PyChop/ISISDisk.py index 56a0455228f7ff4d1cc74566076ddf2460b9fd2c..b5efb1777d77e3149f4f75f5258aba8455dd4b0d 100644 --- a/scripts/PyChop/ISISDisk.py +++ b/scripts/PyChop/ISISDisk.py @@ -59,7 +59,7 @@ class ISISDisk: self.samp_det = 3.5 # sample to detector distance in m self.chop_samp = 1.5 # final chopper to sample distance self.source_rep = 10 # rep rate of source - self.tmod = 3500 # maximimum emmision window from moderator in us + self.tmod = 3500 # maximum emission window from moderator in us self.frac_ei = 0.90 # fraction of Ei to plot energy loss lines self.Chop2Phase = 5 # Phase delay time in usec for chopper 2 (T0/frame overlap chopper) elif 'MERLIN' in instname: diff --git a/scripts/PyChop/ISISFermi.py b/scripts/PyChop/ISISFermi.py index 1b49160c4ab728310776b8866bf9070478d0d55e..7a33e0ba6dba8a954c62b7454da20242a9eca8bc 100644 --- a/scripts/PyChop/ISISFermi.py +++ b/scripts/PyChop/ISISFermi.py @@ -236,7 +236,7 @@ class ISISFermi: Inputs: ei - incident energy in meV [default: preset incident energy] - omega - chopper frequncy in Hz [default: preset frequency] + omega - chopper frequency in Hz [default: preset frequency] etrans - list of numpy array of energy transfers to calculate for (meV) [default: 0] Output: @@ -343,7 +343,7 @@ class ISISFermi: Inputs: etrans - list of numpy array of energy transfers to calculate for (meV) [default: linspace(0.05Ei, 0.95Ei, 19)] ei - incident energy in meV [default: preset energy] - omega - chopper frequncy in Hz [default: preset frequency] + omega - chopper frequency in Hz [default: preset frequency] Output: van - the incoherent (Vanadium) energy width at etrans in meV diff --git a/scripts/PyChop/Instruments.py b/scripts/PyChop/Instruments.py index 35bdb92cd8984f68bf225e1a0e44d7a0a4efe2f4..fd709f39f06ff68723dd8840022f7d4309243937 100644 --- a/scripts/PyChop/Instruments.py +++ b/scripts/PyChop/Instruments.py @@ -570,7 +570,7 @@ class Moderator(object): return np.sqrt(self.getAnalyticWidthSquared(Ei)) def getFlux(self, Ei): - """ Returns the white beam flux estimate from either measured data (prefered) or analytical model (backup) """ + """ Returns the white beam flux estimate from either measured data (preferred) or analytical model (backup) """ return self.getMeasuredFlux(Ei) if hasattr(self, 'flux_interp') else self.getAnalyticFlux(Ei) def getAnalyticFlux(self, Ei): @@ -755,7 +755,7 @@ class Instrument(object): Inputs: etrans - list of numpy array of energy transfers to calculate for (meV) [default: linspace(0.05Ei, 0.95Ei, 19)] ei - incident energy in meV [default: preset energy] - omega - chopper frequncy in Hz [default: preset frequency] + omega - chopper frequency in Hz [default: preset frequency] Output: van - the incoherent (Vanadium) energy FWHM at etrans in meV diff --git a/scripts/PyChop/MulpyRep.py b/scripts/PyChop/MulpyRep.py index d873517232c1df5902d390adf67f7ecae94d9d12..d89b6537a9ae90d7643cdfa052f050551aa699de 100644 --- a/scripts/PyChop/MulpyRep.py +++ b/scripts/PyChop/MulpyRep.py @@ -255,6 +255,6 @@ def calcChopTimes(efocus, freq, instrumentpars, chop2Phase=5): if lines: for line in lines: lines_all.append(line) - # ok, now we know the possible neutron velocities. we now ned their energies + # ok, now we know the possible neutron velocities. we now need their energies Ei = calcEnergy(lines_all, (dist[-1]+chop_samp)) return Ei, chop_times, [chop_times[0][0], chop_times[-1][0]], dist[-1]-dist[0], lines_all diff --git a/scripts/PyChop/let.yaml b/scripts/PyChop/let.yaml index 81826a98c696a12786e73d233a0a032412e52bac..24ce8ff4e2716c6d28046aae75c2b9058f55215f 100644 --- a/scripts/PyChop/let.yaml +++ b/scripts/PyChop/let.yaml @@ -1,6 +1,6 @@ name: LET # Input file for PyChop2 for the LET spectrometer at ISIS. -# At a minium, the "chopper_system" and "moderator" entries must be present +# At a minimum, the "chopper_system" and "moderator" entries must be present chopper_system: name: LET chopper system @@ -77,7 +77,7 @@ chopper_system: ei_limits: [0, 30] # Limits on ei for multirep calculations (reps outside range ignored) flux_ref_slot: 20 # Reference slot width (mm) for flux transmission calculation (disk choppers only) flux_ref_freq: 150 # Reference final chopper freq (Hz) for flux transmission calc (disk choppers only) - # Can define variants which overide one of the above parameters + # Can define variants which override one of the above parameters variants: # On LET the final chopper has 3 sets of slots with different widths High Flux: # This is the default mode (uses the widest 31mm slot). default: True # If this key is omitted, the variant without any option is used as default @@ -116,7 +116,7 @@ moderator: theta: 32.0 # Angle beamline makes with moderator face (degrees) source_rep: 10 # Frequency of source (Hz) emission_time: 3500 # Time width of source pulse in microseconds (only used to determine spurious reps in multi-rep mode) - measured_width: # Table of measured moderator time widths in microseconds. If present will overide imod and mod_pars + measured_width: # Table of measured moderator time widths in microseconds. If present will override imod and mod_pars isSigma: False # Indicates measurements are FWHM wavelength: [3.8063, 2.1961, 6.2121, 5.3820, 1.4371, 1.7010, 2.6920, 1.9013] width: [90.4, 40.8, 154.4, 131.2, 22.4, 25.6, 52.4, 32.4] diff --git a/scripts/PyChop/maps.yaml b/scripts/PyChop/maps.yaml index 8890d4084457089dc4fac8309e6d78db64d40eb5..90a5bebdede26f0d41d0c0c06fc439c546fbc306 100644 --- a/scripts/PyChop/maps.yaml +++ b/scripts/PyChop/maps.yaml @@ -13,9 +13,9 @@ chopper_system: distance: 8.831 # Distance from moderator to this chopper in metres slot_width: 68 # Slot width in mm guide_width: 50 # Width of guide after chopper in mm - nslot: 4 # Number of slots. If slot_ang_pos is specified can ommit this entry + nslot: 4 # Number of slots. If slot_ang_pos is specified can omit this entry # Next line has the angular position of the slots in degrees - # Must be monotonically increasing. Can omit if nslot is specifed, + # Must be monotonically increasing. Can omit if nslot is specified, # in which case it will be assumed that the slits are equally spaced. slot_ang_pos: [-180., -39.1, 0., 39.1] radius: 375 # Disk radius @@ -93,11 +93,11 @@ moderator: # of the flux distribution for ISIS TS1 moderators. If measured_flux is defined below, name can be anything imod: 2 # Moderator time profile type: 0==chi^2, 1==Ikeda-Carpenter, 2==modified chi^2 mod_pars: [38.6, 0.5226] # Parameters for time profile - mod_scale_fn: soft_hat # Function to modify the parameters depending on energy (ommit or leave blank for no modification) + mod_scale_fn: soft_hat # Function to modify the parameters depending on energy (omit or leave blank for no modification) mod_scale_par: [1.0, 0.0, 0.0, 150.0, 0.01, 70.0] theta: 32.0 # Angle beamline makes with moderator face (degrees) source_rep: 50 # Frequency of source (Hz) - measured_width: # Table of measured moderator time widths in microseconds. If present will overide imod and mod_pars + measured_width: # Table of measured moderator time widths in microseconds. If present will override imod and mod_pars isSigma: False # Indicates measurements are FWHM wavelength: [3.81593, 5.39537, 2.2052, 2.70006, 3.25499, 1.70813, 3.11649, 1.44378, 2.41516, 1.91018, 2.47745, 1.27303, 2.07872, 1.05928, 1.55951] width: [54, 62, 40, 44, 48, 35, 47, 30, 41, 37, 40, 25, 38, 20, 31] diff --git a/scripts/PyChop/mari.yaml b/scripts/PyChop/mari.yaml index ed1f092280975ed64578c9c5d07d8789783454ef..9cf77825f80fbad10b2de4ba703f05ffcced486a 100644 --- a/scripts/PyChop/mari.yaml +++ b/scripts/PyChop/mari.yaml @@ -13,9 +13,9 @@ chopper_system: distance: 7.85 # Distance from moderator to this chopper in metres slot_width: 65 # Slot width in mm guide_width: 60 # Width of guide after chopper in mm - nslot: 4 # Number of slots. If slot_ang_pos is specified can ommit this entry + nslot: 4 # Number of slots. If slot_ang_pos is specified can omit this entry # Next line has the angular position of the slots in degrees - # Must be monotonically increasing. Can omit if nslot is specifed, + # Must be monotonically increasing. Can omit if nslot is specified, # in which case it will be assumed that the slits are equally spaced. slot_ang_pos: [0, 36.48, 72.76, 145.52] radius: 367 # Disk radius @@ -121,7 +121,7 @@ moderator: mod_pars: [38.6, 0.5226] # Parameters for time profile theta: 13.0 # Angle beamline makes with moderator face (degrees) source_rep: 50 # Frequency of source (Hz) - measured_width: # Table of measured moderator time widths in microseconds. If present will overide imod and mod_pars + measured_width: # Table of measured moderator time widths in microseconds. If present will override imod and mod_pars isSigma: False # Indicates measurements are FWHM wavelength: [4.0240, 5.6898, 2.3250, 2.8480, 1.5224, 3.4331, 1.8009, 1.1167] width: [53.2, 62, 39.2, 44.8, 18.8, 48.8, 27.2, 12.4] diff --git a/scripts/PyChop/merlin.yaml b/scripts/PyChop/merlin.yaml index 4997b127cd4bf4f19473f23f6c93548e75b1d9cd..1d292a45311e4afa49d10daab160b176c628e3dd 100644 --- a/scripts/PyChop/merlin.yaml +++ b/scripts/PyChop/merlin.yaml @@ -13,9 +13,9 @@ chopper_system: distance: 9.3 # Distance from moderator to this chopper in metres slot_width: 950 # Slot width in mm guide_width: 64 # Width of guide after chopper in mm - nslot: 1 # Number of slots. If slot_ang_pos is specified can ommit this entry + nslot: 1 # Number of slots. If slot_ang_pos is specified can omit this entry # Next line has the angular position of the slots in degrees - # Must be monotonically increasing. Can omit if nslot is specifed, + # Must be monotonically increasing. Can omit if nslot is specified, # in which case it will be assumed that the slits are equally spaced. radius: 250 # Disk radius isDouble: False # Is this a double disk system? @@ -84,7 +84,7 @@ moderator: mod_pars: [80.0, 0.5226] # Parameters for time profile theta: 26.7 # Angle beamline makes with moderator face (degrees) source_rep: 50 # Frequency of source (Hz) - measured_width: # Table of measured moderator time widths in microseconds. If present will overide imod and mod_pars + measured_width: # Table of measured moderator time widths in microseconds. If present will override imod and mod_pars isSigma: False # Indicates measurements are FWHM wavelength: [3.81238, 5.38791, 2.20214, 2.69636, 3.25068, 1.70664, 1.9078, 1.4425, 3.11379, 2.41294, 2.47528, 1.27219, 2.07682, 1.05882, 1.55818] width: [49, 56, 34, 37, 42, 29, 30, 25, 40, 34, 35, 21, 31, 18, 26] diff --git a/scripts/QECoverage.py b/scripts/QECoverage.py index db18f5425f0460306d6b96d63e43f1f52118a845..94cb36fd9098daed1096ec65585482f1b4d56bdf 100644 --- a/scripts/QECoverage.py +++ b/scripts/QECoverage.py @@ -100,7 +100,7 @@ class QECoverageGUI(QtGui.QWidget): self.direct_emin_label = QtGui.QLabel("Emin", self.direct_emin) self.direct_emin_grid.addWidget(self.direct_emin_label) self.direct_emin_input = QtGui.QLineEdit("-10", self.direct_emin) - self.direct_emin_input.setToolTip("Mininum energy transfer to plot down to.") + self.direct_emin_input.setToolTip("Minimum energy transfer to plot down to.") self.direct_emin_grid.addWidget(self.direct_emin_input) self.direct_grid.addWidget(self.direct_emin) self.direct_plotbtn = QtGui.QPushButton("Plot Q-E", self.tab_direct) diff --git a/scripts/Reflectometry/isis_reflectometry/combineMulti.py b/scripts/Reflectometry/isis_reflectometry/combineMulti.py index d305edbc037fc1f9fbe6ef3224aad37935780539..5d8cf62531e148334567cdd49cc35f29440a6a0f 100644 --- a/scripts/Reflectometry/isis_reflectometry/combineMulti.py +++ b/scripts/Reflectometry/isis_reflectometry/combineMulti.py @@ -84,7 +84,7 @@ def stitch2(ws1, ws2, output_ws_name, begoverlap, endoverlap, Qmin, Qmax, binnin else: manual_scalefactor = False scalefactor = 1.0 - # Interally use the Stitch1D algorithm. + # Internally use the Stitch1D algorithm. outputs = Stitch1D(LHSWorkspace=ws1, RHSWorkspace=ws2, OutputWorkspace=output_ws_name, StartOverlap=begoverlap, EndOverlap=endoverlap, UseManualScaleFactor=manual_scalefactor, @@ -116,7 +116,7 @@ def combine2(wksp1, wksp2, outputwksp, begoverlap, endoverlap, Qmin, Qmax, binni else: manual_scalefactor = False scalefactor = 1.0 - # Interally use the Stitch1D algorithm. + # Internally use the Stitch1D algorithm. outputs = Stitch1D(LHSWorkspace=mtd[wksp1], RHSWorkspace=mtd[wksp2], OutputWorkspace=outputwksp, StartOverlap=begoverlap, EndOverlap=endoverlap, UseManualScaleFactor=manual_scalefactor, diff --git a/scripts/Reflectometry/isis_reflectometry/quick.py b/scripts/Reflectometry/isis_reflectometry/quick.py index 1d02a5df946330fce9cfe36cf9c0eafb099c669b..942269f5ee97edc73bbf6d7415cb08ffdab12bcd 100644 --- a/scripts/Reflectometry/isis_reflectometry/quick.py +++ b/scripts/Reflectometry/isis_reflectometry/quick.py @@ -1,6 +1,6 @@ # pylint: disable=invalid-name, too-many-branches, too-few-public-methods, too-many-arguments, too-many-locals ''' SVN Info: The variables below will only get subsituted at svn checkout if - the repository is configured for variable subsitution. + the repository is configured for variable substitution. $Id$ $HeadURL$ @@ -147,8 +147,8 @@ def quick_explicit(run, i0_monitor_index, lambda_min, lambda_max, background_min RunNumber = groupGet(_sample_ws.name(), 'samp', 'run_number') if not pointdet: - # Proccess Multi-Detector; assume MD goes to the end: - # if roi or db are given in the function then sum over the apropriate channels + # Process Multi-Detector; assume MD goes to the end: + # if roi or db are given in the function then sum over the appropriate channels print("This is a multidetector run.") _I0M = RebinToWorkspace(WorkspaceToRebin=_monitor_ws, WorkspaceToMatch=_detector_ws) diff --git a/scripts/SANS/DarkRunCorrection.py b/scripts/SANS/DarkRunCorrection.py index 6d32e9488d44a67802658d692ed04e1a7e52204a..de6234631c319f92968c463628e293f716010c16 100644 --- a/scripts/SANS/DarkRunCorrection.py +++ b/scripts/SANS/DarkRunCorrection.py @@ -177,7 +177,7 @@ class DarkRunNormalizationExtractor(object): @param prop: the property from which we extract the frames @returns the number of good frames ''' - # Since we are dealing with a cummulative sample log, we can extract + # Since we are dealing with a cumulative sample log, we can extract # the total number of good frames by looking at the last frame frames = prop.value return frames[-1] diff --git a/scripts/SANS/ISISCommandInterface.py b/scripts/SANS/ISISCommandInterface.py index 088de7b71f4b5aed6297fbd1e8493f737b1e49e1..bfebe9e5580a7bd30ac6e9167c0379c39ddbe337 100644 --- a/scripts/SANS/ISISCommandInterface.py +++ b/scripts/SANS/ISISCommandInterface.py @@ -499,7 +499,7 @@ def WavRangeReduction(wav_start=None, wav_end=None, full_trans_wav=None, name_su # This section provides a the REAR -- FRONT fitting and a stitched workspace. # If merge_flag is selected we use SANSStitch and get the fitting for free - # If fitRequired is selected, then we explicity call the SANSFitScale algorithm + # If fitRequired is selected, then we explicitly call the SANSFitScale algorithm if merge_flag: if ReductionSingleton().getNumSlices() > 1: slices = [] @@ -517,7 +517,7 @@ def WavRangeReduction(wav_start=None, wav_end=None, full_trans_wav=None, name_su retWSname = retWSname_merged elif fitRequired: - # Get fit paramters + # Get fit parameters scale_factor, shift_factor, fit_mode = su.extract_fit_parameters(rAnds) # Since only the fit is required we use only the SANSFitScale algorithm @@ -597,7 +597,7 @@ def _merge_workspaces(retWSname_front, retWSname_rear, rAnds): # The CAN was not specified consider_can = False - # Get fit paramters + # Get fit parameters scale_factor, shift_factor, fit_mode, fit_min, fit_max = su.extract_fit_parameters(rAnds) merge_range = ReductionSingleton().instrument.getDetector('FRONT').mergeRange @@ -643,7 +643,7 @@ def _merge_workspaces(retWSname_front, retWSname_rear, rAnds): # Get the merged workspace mergedQ = alg_stitch.getProperty("OutputWorkspace").value - # Add the ouput to the Analysis Data Service + # Add the output to the Analysis Data Service AnalysisDataService.addOrReplace(retWSname_merged, mergedQ) # save the properties Transmission and TransmissionCan inside the merged workspace @@ -1349,7 +1349,7 @@ def GetTransmissionMonitorSpectrum(): """ Gets the transmission monitor spectrum. In the case of 4 or 17788 (for LOQ) the result is 4. - @return: tranmission monitor spectrum + @return: transmission monitor spectrum """ transmission_monitor = ReductionSingleton().transmission_calculator.trans_mon if ReductionSingleton().instrument._NAME == "LOQ" and transmission_monitor == 17788: @@ -1382,7 +1382,7 @@ def GetTransmissionMonitorSpectrumShift(): """ Gets the addditional shift for the transmission monitor spectrum. This currently only exists for SANS2D - @return: tranmission monitor spectrum + @return: transmission monitor spectrum """ inst = ReductionSingleton().get_instrument() if inst.name() != "SANS2D" and inst.name() != "SANS2DTUBES": @@ -1409,7 +1409,7 @@ def SetTransmissionMonitorSpectrumShift(trans_mon_shift): def GetTransmissionRadiusInMM(): """ Gets the radius for usage with beam stop as transmission monitor in mm - @return: tranmission radius in mm + @return: transmission radius in mm """ radius = ReductionSingleton().transmission_calculator.radius if radius is not None: @@ -1453,7 +1453,7 @@ def SetTransmissionROI(trans_roi_files): def GetTransmissionMask(): """ - Gets the list of transmission maks file names + Gets the list of transmission mask file names @return: list of transmission mask file names or None """ trans_mask_files = ReductionSingleton().transmission_calculator.mask_files @@ -1486,7 +1486,7 @@ def AddRuns(runs, instrument='sans2d', saveAsEvent=False, binning="Monitors", is string list with the same format that is used for the Rebin algorithm. This property is ignored when saving as event data. @param isOverlay: sets if the the overlay mechanism should be used when the saveAsEvent flag is set - @param time_shifts: provides additional time shifts if the isOverlay flag is specified. The time shifts are specifed + @param time_shifts: provides additional time shifts if the isOverlay flag is specified. The time shifts are specified in a string list. Either time_shifts is not used or a list with times in secomds. Note that there has to be one entry fewer than the number of workspaces to add. @param defType: the file type @@ -1538,7 +1538,7 @@ def set_q_resolution_moderator(file_name): "which exists in the search directories. See details: %s" % str(details)) -# -- Use q resoltion +# -- Use q resolution def get_q_resultution_use(): ''' Gets if the q resolution option is being used @@ -1559,7 +1559,7 @@ def set_q_resolution_use(use): elif not use: ReductionSingleton().to_Q.set_use_q_resolution(False) else: - sanslog.warning('Warning: Could could not set useage of QResolution') + sanslog.warning('Warning: Could could not set usage of QResolution') # -- Collimation length @@ -1738,7 +1738,7 @@ def reset_q_resolution_settings(): def set_q_resolution_float(func, arg, msg): ''' Set a q resolution value - @param func: the speficied function to run + @param func: the specified function to run @param arg: the argument @param mgs: error message ''' @@ -1755,7 +1755,7 @@ def set_q_resolution_float(func, arg, msg): def get_q_resolution_float(func, msg): ''' Gets a q resolution value and checks if it has been set. - @param func: the speficied function to run + @param func: the specified function to run @param mgs: error message @return the correct value ''' diff --git a/scripts/SANS/SANSBatchMode.py b/scripts/SANS/SANSBatchMode.py index 046a27c33bece271e145782d6c7af6cb0d739707..f060f478afb4906b1d73e88604864b4064956fa3 100644 --- a/scripts/SANS/SANSBatchMode.py +++ b/scripts/SANS/SANSBatchMode.py @@ -201,7 +201,7 @@ def BatchReduce(filename, format, plotresults=False, saveAlgs={'SaveRKH':'txt'}, runinfo = [] for line in file_handle: # See how many pieces of information have been provided; - # brackets delineate the field seperator (nothing for space-delimited, ',' for comma-seperated) + # brackets delineate the field separator (nothing for space-delimited, ',' for comma-seperated) parts = line.rstrip().split(',') if addRunToStore(parts, runinfo) > 0: issueWarning('Incorrect structure detected in input file "' + filename + '" at line \n"' + line + '"\nEntry skipped\n') diff --git a/scripts/SANS/SANSUserFileParser.py b/scripts/SANS/SANSUserFileParser.py index 480c64d3d430e66a9c4cb963f72e5ff3854b2e62..4a810e0454345bb95f5eb914558f558108462ffa 100644 --- a/scripts/SANS/SANSUserFileParser.py +++ b/scripts/SANS/SANSUserFileParser.py @@ -53,7 +53,7 @@ class BackCommandParser(object): def _evaluate_mean(self, argument): ''' - Evalutes if the argument is either MEAN, TOF or something else. + Evaluates if the argument is either MEAN, TOF or something else. @param argument: string to investigate @raise RuntimeError: If the argument cannot be parsed correctly ''' @@ -68,7 +68,7 @@ class BackCommandParser(object): def _evaluate_uniform(self, argument): ''' - Evalutes if the argument is either TIME, UAMP or something else. + Evaluates if the argument is either TIME, UAMP or something else. @param argument: string to investigate @raise RuntimeError: If the argument cannot be parsed correctly ''' @@ -83,7 +83,7 @@ class BackCommandParser(object): def _evaluate_run(self, argument): ''' - Evalutes if the argument is RUN= + Evaluates if the argument is RUN= @param argument: string to investigate @raise RuntimeError: If the argument cannot be parsed correctly ''' @@ -98,7 +98,7 @@ class BackCommandParser(object): def _evaluate_mon(self, argument): ''' - Evaluates which detector to use. At this point the validty of this has already been checkd, so + Evaluates which detector to use. At this point the validty of this has already been checked, so we can just take it as is. @param argument: string to investigate @raise RuntimeError: If the argument cannot be parsed correctly diff --git a/scripts/SANS/SANSUtility.py b/scripts/SANS/SANSUtility.py index 2cc9f3d9fbc5d105272445bfa1c9459e71a0012b..3195b3a6481c21e418a5305c98fcbb822ee3700e 100644 --- a/scripts/SANS/SANSUtility.py +++ b/scripts/SANS/SANSUtility.py @@ -290,9 +290,10 @@ def fromEvent2Histogram(ws_event, ws_monitor, binning = ""): if binning != "": aux_hist = Rebin(ws_event, binning, False) - Rebin(ws_monitor, binning, False, OutputWorkspace=name) + Rebin(InputWorkspace=ws_monitor, Params=binning, PreserveEvents=False, OutputWorkspace=name) else: - aux_hist = RebinToWorkspace(ws_event, ws_monitor, False) + aux_hist = RebinToWorkspace(WorkspaceToRebin=ws_event, WorkspaceToMatch=ws_monitor, + PreserveEvents=False) ws_monitor.clone(OutputWorkspace=name) ConjoinWorkspaces(name, aux_hist, CheckOverlapping=True) @@ -967,7 +968,7 @@ class AddOperation(object): def __init__(self,isOverlay, time_shifts): """ The AddOperation requires to know if the workspaces are to - be plainly added or to be overlayed. Additional time shifts can be + be plainly added or to be overlaid. Additional time shifts can be specified @param isOverlay :: true if the operation is an overlay operation @param time_shifts :: a string with comma-separted time shift values @@ -1031,7 +1032,7 @@ class PlusWorkspaces(object): rhs_ws = self._get_workspace(RHS_workspace) # Apply shift to RHS sample logs where necessary. This is a hack because Plus cannot handle - # cummulative time series correctly at this point + # cumulative time series correctly at this point cummulative_correction = CummulativeTimeSeriesPropertyAdder() cummulative_correction. extract_sample_logs_from_workspace(lhs_ws, rhs_ws) Plus(LHSWorkspace = LHS_workspace, RHSWorkspace = RHS_workspace, OutputWorkspace = output_workspace) @@ -1048,7 +1049,7 @@ class PlusWorkspaces(object): class OverlayWorkspaces(object): """ Overlays (in time) a workspace on top of another workspace. The two - workspaces overlayed such that the first time entry of their proton_charge entry matches. + workspaces overlaid such that the first time entry of their proton_charge entry matches. This overlap can be shifted by the specified time_shift in seconds """ @@ -1069,11 +1070,11 @@ class OverlayWorkspaces(object): total_time_shift = time_difference + time_shift # Apply shift to RHS sample logs where necessary. This is a hack because Plus cannot handle - # cummulative time series correctly at this point + # cumulative time series correctly at this point cummulative_correction = CummulativeTimeSeriesPropertyAdder() cummulative_correction. extract_sample_logs_from_workspace(lhs_ws, rhs_ws) - # Create a temporary workspace with shifted time values from RHS, if the shift is necesary + # Create a temporary workspace with shifted time values from RHS, if the shift is necessary temp = rhs_ws temp_ws_name = 'shifted' if total_time_shift != 0.0: @@ -1184,7 +1185,7 @@ def transfer_special_sample_logs(from_ws, to_ws): class CummulativeTimeSeriesPropertyAdder(object): ''' Apply shift to RHS sample logs where necessary. This is a hack because Plus cannot handle - cummulative time series correctly at this point. + cumulative time series correctly at this point. ''' def __init__(self, total_time_shift_seconds = 0): @@ -1214,7 +1215,7 @@ class CummulativeTimeSeriesPropertyAdder(object): ''' run_lhs = lhs.getRun() run_rhs = rhs.getRun() - # Get the cummulative time s + # Get the cumulative time s for element in self._time_series: if (run_lhs.hasProperty(element) and run_rhs.hasProperty(element)): @@ -1267,7 +1268,7 @@ class CummulativeTimeSeriesPropertyAdder(object): def _update_single_valued_entries(self, workspace): ''' We need to update single-valued entries which are based on the - cummulative time series + cumulative time series @param workspace: the workspace which requires the changes ''' run = workspace.getRun() @@ -1348,7 +1349,7 @@ class CummulativeTimeSeriesPropertyAdder(object): def _get_raw_values(self, values): ''' - We extract the original data from the cummulative + We extract the original data from the cumulative series. ''' raw_values = [] @@ -1880,7 +1881,7 @@ def is_valid_user_file_extension(user_file): def createUnmanagedAlgorithm(name, **kwargs): ''' This creates an unmanged child algorithm with the - provided proeprties set. The returned algorithm has + provided properties set. The returned algorithm has not been executed yet. ''' alg = AlgorithmManager.createUnmanaged(name) @@ -1923,7 +1924,7 @@ def check_has_bench_rot(workspace, log_dict=None): run = workspace.run() if not run.hasProperty("Bench_Rot"): raise RuntimeError("LARMOR Instrument: Bench_Rot does not seem to be available on {0}. There might be " - "an issue with your data aquisition. Make sure that the sample_log entry " + "an issue with your data acquisition. Make sure that the sample_log entry " "Bench_Rot is available.".format(workspace.name())) @@ -1979,7 +1980,7 @@ def get_correct_combinDet_setting(instrument_name, detector_selection): """ We want to get the correct combinDet variable for batch reductions from a new detector selection. - @param instrument_name: the name of the intrument + @param instrument_name: the name of the instrument @param detector_selection: a detector selection comes directly from the reducer @return: a combinedet option """ diff --git a/scripts/SANS/SANSadd2.py b/scripts/SANS/SANSadd2.py index 5203b09781477b77cfe8011933ccc9cbcfdd9851..a82dcc64c15d5fc1b7d2d12a189c9b3102041868 100644 --- a/scripts/SANS/SANSadd2.py +++ b/scripts/SANS/SANSadd2.py @@ -207,7 +207,7 @@ def handle_saving_event_workspace_when_saving_as_histogram(binning, is_first_dat workspace_type = get_workspace_type(filename) if workspace_type is WorkspaceType.MultiperiodEvent: # If we are dealing with multi-period event workspaces then there is no way of getting any other - # sample log inforamtion hence we use make a copy of the monitor workspace and use that instead + # sample log information hence we use make a copy of the monitor workspace and use that instead # of the reloading the first file again CloneWorkspace(InputWorkspace=ADD_FILES_SUM_TEMPORARY_MONITORS, OutputWorkspace=ADD_FILES_SUM_TEMPORARY) else: diff --git a/scripts/SANS/centre_finder.py b/scripts/SANS/centre_finder.py index 770276ef046c2d3184332928a20c388404015b08..397d20be9b9a697e3c9c01150ab39c5b1ecebf00 100644 --- a/scripts/SANS/centre_finder.py +++ b/scripts/SANS/centre_finder.py @@ -93,7 +93,7 @@ class CentreFinder(object): self.coord1_scale_factor = setup.instrument.beam_centre_scale_factor1 self.coord2_scale_factor = setup.instrument.beam_centre_scale_factor2 - # We are looking only at the differnce between the old position and the trial. + # We are looking only at the difference between the old position and the trial. self.move(setup, trial[0]-self._last_pos[0], trial[1]-self._last_pos[1]) #phi masking will remove areas of the detector that we need @@ -364,7 +364,7 @@ class CentrePositioner(object): ''' return self.position_provider.provide_sign_policy() -# Thes classes make sure that only the relevant directions are updated +# These classes make sure that only the relevant directions are updated # They are not instrument dependent, they should only dependt on the user's choice. @@ -758,7 +758,7 @@ class PositionProviderAngleY(PositionProvider): ''' Get the sign policy for the angle, y translations. Displacing the beam by 5mm is equivalent to displacing the instrument by -5mm. The angle displacement in - LARMOR does the sign switch already. Hence we have a positve sign policy for + LARMOR does the sign switch already. Hence we have a positive sign policy for the angle direction ''' return self.sign_policy_angle, self.sign_policy_y diff --git a/scripts/SANS/isis_instrument.py b/scripts/SANS/isis_instrument.py index a83d4d4683402b63613c28dfd104f9d3cbfefe64..6163202b4994f01b5254574dff07633a65843067 100644 --- a/scripts/SANS/isis_instrument.py +++ b/scripts/SANS/isis_instrument.py @@ -408,7 +408,7 @@ class DetectorBank(object): """ Sets to relationship between the detectors and the spectra numbers. The relationship is given by an orientation string and this function throws if the string is not recognised - @param orien: the orienation string must be a string contained in the dictionary _ORIENTED + @param orien: the orientation string must be a string contained in the dictionary _ORIENTED """ self._ORIENTED[orien] self._orientation = orien @@ -564,7 +564,7 @@ class ISISInstrument(BaseInstrument): def suggest_incident_mntr(self, spectrum_number): """ - remove this function and the data memember it uses + remove this function and the data member it uses """ if not self._del_incidient_set: self.set_incident_mon(spectrum_number) @@ -788,7 +788,7 @@ class ISISInstrument(BaseInstrument): It configures the instrument for the specific run of the workspace for handle historical changes in the instrument. - It centralizes the detector bank to teh beamcentre (tuple of two values) + It centralizes the detector bank to the beamcentre (tuple of two values) """ ws_ref = mtd[str(ws_name)] try: @@ -895,8 +895,8 @@ class ISISInstrument(BaseInstrument): def get_m4_monitor_det_ID(self): """ - Gets the detecor ID assoicated with Monitor 4 - @returns: teh det ID of Monitor 4 + Gets the detecor ID associated with Monitor 4 + @returns: the det ID of Monitor 4 """ raise RuntimeError("Monitor 4 does not seem to be implemented.") @@ -943,7 +943,7 @@ class LOQ(ISISInstrument): It configures the instrument for the specific run of the workspace for handle historical changes in the instrument. - It centralizes the detector bank to teh beamcentre (tuple of two values) + It centralizes the detector bank to the beamcentre (tuple of two values) """ ws_ref = mtd[str(ws_name)] try: @@ -1139,7 +1139,7 @@ class SANS2D(ISISInstrument): def getDetValues(self, ws_name): """ - Retrive the values of Front_Det_Z, Front_Det_X, Front_Det_Rot, Rear_Det_Z and Rear_Det_X from + Retrieve the values of Front_Det_Z, Front_Det_X, Front_Det_Rot, Rear_Det_Z and Rear_Det_X from the workspace. If it does not find the value at the run info, it takes as default value the self.FRONT_DET_Z, self... which are extracted from the sample workspace at apply_detector_log. @@ -1520,7 +1520,7 @@ class LARMOR(ISISInstrument): def getDetValues(self, ws_name): """ - Retrive the values of Bench_Rot from the workspace. If it does not find the value at the run info, + Retrieve the values of Bench_Rot from the workspace. If it does not find the value at the run info, it takes as default value the self.BENCH_ROT, which are extracted from the sample workspace at apply_detector_log. This is done to allow the function move_components to use the correct values and not to use @@ -1729,13 +1729,13 @@ class LARMOR(ISISInstrument): @param x_beam: either a shift in mm or a angle in degree @param x_scale_factor: ''' - # in order to avoid rewriting old mask files from initial commisioning during 2014. + # in order to avoid rewriting old mask files from initial commissioning during 2014. ws_ref = mtd[workspace] # The angle value # Note that the x position gets converted from mm to m when read from the user file so we need to reverse this if X is now an angle if not LARMOR.is_run_new_style_run(ws_ref): - # Initial commisioning before run 2217 did not pay much attention to making sure the bench_rot value was meaningful + # Initial commissioning before run 2217 did not pay much attention to making sure the bench_rot value was meaningful xshift = -x_beam sanslog.notice("Setup move " + str(xshift * x_scale_factor) + " " + str(0.0) + " " + str(0.0)) MoveInstrumentComponent(workspace, ComponentName=component_name, X=xshift, Y=0.0, Z=0.0) @@ -1766,7 +1766,7 @@ class LARMOR(ISISInstrument): def cur_detector_position(self, ws_name): """Return the position of the center of the detector bank""" - # Unforunately getting the angle of the bench does not work so we have to get bench and detector + # Unfortunately getting the angle of the bench does not work so we have to get bench and detector # logger.warning("Entering cur_detector_position") ws = mtd[ws_name] @@ -1801,7 +1801,7 @@ class LARMOR(ISISInstrument): """ # logger.warning("Entering on_load_sample") ws_ref = mtd[str(ws_name)] - # in order to avoid problems with files from initial commisioning during 2014. + # in order to avoid problems with files from initial commissioning during 2014. # these didn't have the required log entries for the detector position if LARMOR.is_run_new_style_run(ws_ref): @@ -1815,7 +1815,7 @@ class LARMOR(ISISInstrument): run = ws_ref.run() if not run.hasProperty("Bench_Rot"): additional_message = ("The Bench_Rot entry seems to be missing. There might be " - "an issue with your data aquisition. Make sure that the sample_log entry " + "an issue with your data acquisition. Make sure that the sample_log entry " "Bench_Rot is available.") else: additional_message = "" @@ -1838,7 +1838,7 @@ class LARMOR(ISISInstrument): ''' Checks if the run assiated with the workspace is pre or post 2217 Original comment: - In order to avoid problems with files from initial commisioning during 2014. + In order to avoid problems with files from initial commissioning during 2014. these didn't have the required log entries for the detector position @param workspace_ref:: A handle to the workspace ''' diff --git a/scripts/SANS/isis_reducer.py b/scripts/SANS/isis_reducer.py index 5721f2a0d772672fd498b9b431deb3e9c45b2b8a..5463a10e01a3837e7a14dde9ff468e700303675a 100644 --- a/scripts/SANS/isis_reducer.py +++ b/scripts/SANS/isis_reducer.py @@ -382,7 +382,7 @@ class ISISReducer(Reducer): self.settings = get_settings_object() # Dark Run Subtraction handler. This is not a step but a utility class - # which gets used during cropping and Tranmission calculation + # which gets used during cropping and Transmission calculation self.dark_run_subtraction = isis_reduction_steps.DarkRunSubtraction() # Unwrap monitors @@ -729,7 +729,7 @@ class ISISReducer(Reducer): # set_beam_finder: override to accept the front detector def set_beam_finder(self, finder, det_bank='rear'): """ - Extends teh SANS_reducer in order to support 2 bank detectors + Extends the SANS_reducer in order to support 2 bank detectors Set the ReductionStep object that finds the beam center @param finder: BaseBeamFinder object @param det_bank: two valid options: 'rear', 'front' @@ -947,7 +947,7 @@ class ISISReducer(Reducer): def get_dark_run_setting(self, is_time, is_mon): ''' - Gets one of the four dark run setttings + Gets one of the four dark run settings @param is_time: is it time_based or not @param is_mon: monitors or not @returns the requested setting diff --git a/scripts/SANS/isis_reduction_steps.py b/scripts/SANS/isis_reduction_steps.py index bbf31b2df126baa7fe49971dee46880e3ed63899..c804083f8ccb103fb4665819681f1900b2d55ceb 100644 --- a/scripts/SANS/isis_reduction_steps.py +++ b/scripts/SANS/isis_reduction_steps.py @@ -331,7 +331,7 @@ class LoadRun(object): try: if self._is_trans and reducer.instrument.name() != 'LOQ': - # Unfortunatelly, LOQ in transmission acquire 3 monitors the 3 monitor usually + # Unfortunately, LOQ in transmission acquire 3 monitors the 3 monitor usually # is the first spectrum for detector. This causes the following method to fail # when it tries to load only monitors. Hence, we are forced to skip this method # for LOQ. ticket #8559 @@ -632,7 +632,7 @@ class Mask_ISIS(ReductionStep): def _infinite_plane(self, id, plane_pt, normal_pt, complement=False): """ - Generates xml code for an infinte plane + Generates xml code for an infinite plane @param id: a string to refer to the shape by @param plane_pt: a point in the plane @param normal_pt: the direction of a normal to the plane @@ -649,7 +649,7 @@ class Mask_ISIS(ReductionStep): def _infinite_cylinder(self, centre, radius, axis, id='shape'): """ Generates xml code for an infintely long cylinder - @param centre: a tupple for a point on the axis + @param centre: a tuple for a point on the axis @param radius: cylinder radius @param axis: cylinder orientation @param id: a string to refer to the shape by @@ -663,7 +663,7 @@ class Mask_ISIS(ReductionStep): def _finite_cylinder(self, centre, radius, height, axis, id='shape'): """ Generates xml code for an infintely long cylinder - @param centre: a tupple for a point on the axis + @param centre: a tuple for a point on the axis @param radius: cylinder radius @param height: cylinder height @param axis: cylinder orientation @@ -1179,7 +1179,7 @@ class DarkRunSubtraction(object): ''' # The named tuple contains the information for a dark run subtraction for a single run number ( of # a dark run file) - # The relevant inforamtion is the run number, if we use time or uamp, if we use mean or tof, if we + # The relevant information is the run number, if we use time or uamp, if we use mean or tof, if we # apply this to all detectors, if we apply this to monitors and if so to which monitors DarkRunSubtractionSettings = namedtuple("DarkRunSettings", "run_number time mean detector mon mon_numbers") @@ -3262,7 +3262,7 @@ class UserFile(ReductionStep): raise RuntimeError("%s was specified in the MASK file (%s) but the file cannot be found." % ( line.rsplit()[0], file_handle.name)) - # Check if one of the efficency files hasn't been set and assume the other is to be used + # Check if one of the efficiency files hasn't been set and assume the other is to be used reducer.instrument.copy_correction_files() # Run a consistency check @@ -3347,7 +3347,7 @@ class UserFile(ReductionStep): self._readFrontRescaleShiftSetup(det_specif, reducer) elif any(it == det_specif.strip() for it in ['FRONT', 'REAR', 'BOTH', 'MERGE', 'MERGED', 'MAIN', 'HAB']): # for /DET/FRONT, /DET/REAR, /DET/BOTH, /DET/MERGE and /DET/MERGED commands - # we also accomodate DET/MAIN and DET/HAB here which are specificially for LOQ + # we also accommodate DET/MAIN and DET/HAB here which are specifically for LOQ det_specif = det_specif.strip() if det_specif == 'MERGE': det_specif = 'MERGED' @@ -3546,7 +3546,7 @@ class UserFile(ReductionStep): def _read_mon_line(self, details, reducer): # noqa: C901 - # MON/LENTH, MON/SPECTRUM and MON/TRANS all accept the INTERPOLATE option + # MON/LENGTH, MON/SPECTRUM and MON/TRANS all accept the INTERPOLATE option interpolate = False interPlace = details.upper().find('/INTERPOLATE') if interPlace != -1: @@ -3564,7 +3564,7 @@ class UserFile(ReductionStep): spectrum = int(options[1]) # reducer.instrument.monitor_zs[spectrum] = options[0] - # the settings here are overriden by MON/SPECTRUM + # the settings here are overridden by MON/SPECTRUM if not self._incid_monitor_lckd: reducer.set_monitor_spectrum( spectrum, interpolate, override=False) @@ -3997,7 +3997,7 @@ class UserFile(ReductionStep): reducer.inst.reset_TOFs() def _read_calibfile_line(self, arguments, reducer): - # remove the equals from the beggining and any space around. + # remove the equals from the beginning and any space around. parts = re.split(r"\s?=\s?", arguments) if len(parts) != 2: return "Invalid input for TUBECALIBFILE" + str(arguments) + ". Expected TUBECALIBFILE = file_path" @@ -4023,7 +4023,7 @@ class UserFile(ReductionStep): def _read_unwrap_monitors_line(self, arguments, reducer): """ Checks if the montiors should be unwrapped. The arguments can be either ON or OFF. We don't care here about - any preceeding slash + any preceding slash Args: arguments: the arguments string reducer: a handle to the reducer (is not used) diff --git a/scripts/SANS/reduction_settings.py b/scripts/SANS/reduction_settings.py index 185794615c7527a9ca58da6fb1ba08db49b73aec..c61f97cf123c185c73a3b34bacb7bae8a8fb7740 100644 --- a/scripts/SANS/reduction_settings.py +++ b/scripts/SANS/reduction_settings.py @@ -73,7 +73,7 @@ REDUCTION_SETTINGS_OBJ_NAME = "ISISSANSReductionSettings" def get_settings_object(settings_prop_man_name=REDUCTION_SETTINGS_OBJ_NAME): """ Returns the PropertyManager object with the given name. This could be used - to store settings used by the reduction, or to seperately store some + to store settings used by the reduction, or to separately store some temporary or backup settings. If a PropertyManager object does not exist, then one is created. diff --git a/scripts/SANS/sans/algorithm_detail/batch_execution.py b/scripts/SANS/sans/algorithm_detail/batch_execution.py index e0953c3d81178c860d9b7b7980e51b0dca1c2d50..92b1fa39fb8700ea1a8af4398e39aa05e1c3e08b 100644 --- a/scripts/SANS/sans/algorithm_detail/batch_execution.py +++ b/scripts/SANS/sans/algorithm_detail/batch_execution.py @@ -433,7 +433,7 @@ def reduction_packages_require_splitting_for_event_slices(reduction_packages): The SANSSingleReduction algorithm can handle only a single time slice. For each time slice, we require an individual reduction. Hence we split the states up at this point. :param reduction_packages: a list of reduction packages. - :return: a list of reduction packages which has at leaset the same length as the input + :return: a list of reduction packages which has at least the same length as the input """ # Determine if the event slice sub-state object contains multiple event slice requests. This is given # by the number of elements in start_tof diff --git a/scripts/SANS/sans/algorithm_detail/mask_functions.py b/scripts/SANS/sans/algorithm_detail/mask_functions.py index 025c1280e4e9f83cffa4b09f086476dfd77982ef..ee45b9abc2ed6c257815e40cfa4164bc1a18dad7 100644 --- a/scripts/SANS/sans/algorithm_detail/mask_functions.py +++ b/scripts/SANS/sans/algorithm_detail/mask_functions.py @@ -136,7 +136,7 @@ class SpectraBlock(object): """ Create a list of spectra for a rectangular block of size x_dim by y_dim - :param y_lower: the x coordiante of the starting point of the lower left corner + :param y_lower: the x coordinate of the starting point of the lower left corner :param x_lower: the y coordinate of the starting point of the lower left corner :param y_dim: the y dimension :param x_dim: the x dimension diff --git a/scripts/SANS/sans/algorithm_detail/mask_workspace.py b/scripts/SANS/sans/algorithm_detail/mask_workspace.py index 951a5bee34c9de7104eeba0eb1a5c70223c2f158..db9d499c7d3c0beb9c4a70974e536d2e17b47c9f 100644 --- a/scripts/SANS/sans/algorithm_detail/mask_workspace.py +++ b/scripts/SANS/sans/algorithm_detail/mask_workspace.py @@ -305,7 +305,7 @@ def mask_beam_stop(mask_info, workspace, instrument, detector_names): :param mask_info: a SANSStateMask object. :param workspace: the workspace which is to be masked. - :param instrument: the instrument assoicated with the current workspace. + :param instrument: the instrument associated with the current workspace. :return: a masked workspace """ beam_stop_arm_width = mask_info.beam_stop_arm_width diff --git a/scripts/SANS/sans/algorithm_detail/single_execution.py b/scripts/SANS/sans/algorithm_detail/single_execution.py index f52f66cd30e52159e1a8fbb916f8d37f78be5f72..216616db165fd2223ef528780b0daec22e7046f7 100644 --- a/scripts/SANS/sans/algorithm_detail/single_execution.py +++ b/scripts/SANS/sans/algorithm_detail/single_execution.py @@ -13,7 +13,7 @@ import sys def run_core_reduction(reduction_alg, reduction_setting_bundle): """ - This function runs a core reduction. This is essentially half a reduction (either smaple or can). + This function runs a core reduction. This is essentially half a reduction (either sample or can). :param reduction_alg: a handle to the reduction algorithm. :param reduction_setting_bundle: a ReductionSettingBundle tuple diff --git a/scripts/SANS/sans/algorithm_detail/xml_shapes.py b/scripts/SANS/sans/algorithm_detail/xml_shapes.py index 14a900d3b931ddff411290a3152cada3eda476d7..d6e4fa88942d73265ed53992225946caa0e9d5fd 100644 --- a/scripts/SANS/sans/algorithm_detail/xml_shapes.py +++ b/scripts/SANS/sans/algorithm_detail/xml_shapes.py @@ -33,7 +33,7 @@ def infinite_plane(shape_id, plane_pt, normal_pt): def infinite_cylinder(centre, radius, axis, shape_id='shape'): """ Generates xml code for an infintely long cylinder - :param centre: a tupple for a point on the axis + :param centre: a tuple for a point on the axis :param radius: cylinder radius :param axis: cylinder orientation :param shape_id: a string to refer to the shape by diff --git a/scripts/SANS/sans/command_interface/ISISCommandInterface.py b/scripts/SANS/sans/command_interface/ISISCommandInterface.py index 8fe24e2ec42ab550e4dd4addeed66a53daed7157..5ceaf7848fa7b1f9a554fa113cd3cc5d55b57592 100644 --- a/scripts/SANS/sans/command_interface/ISISCommandInterface.py +++ b/scripts/SANS/sans/command_interface/ISISCommandInterface.py @@ -591,7 +591,7 @@ def LimitsWav(lmin, lmax, step, bin_type): @param lmin: the lower wavelength bound. @param lmax: the upper wavelength bound. @param step: the wavelength step. - @param bin_type: teh bin type, ie linear or logarithmic. Accepted strings are "LINEAR" and "LOGARITHMIC" + @param bin_type: the bin type, ie linear or logarithmic. Accepted strings are "LINEAR" and "LOGARITHMIC" """ lmin = float(lmin) lmax = float(lmax) @@ -826,7 +826,7 @@ def BatchReduce(filename, format, plotresults=False, saveAlgs=None, verbose=Fals if centreit: raise RuntimeError("The beam centre finder is currently not supported.") if plotresults: - raise RuntimeError("Plotting the results is currenlty not supported.") + raise RuntimeError("Plotting the results is currently not supported.") # Set up the save algorithms save_algs = [] @@ -897,7 +897,7 @@ def BatchReduce(filename, format, plotresults=False, saveAlgs=None, verbose=Fals # Name of the output. We need to modify the name according to the setup of the old reduction mechanism output_name = parsed_batch_entry[BatchReductionEntry.Output] - # In addition to the output name the user can specify with combineDet an additional suffix (in addtion to the + # In addition to the output name the user can specify with combineDet an additional suffix (in addition to the # suffix that the user can set already -- was there previously, so we have to provide that) use_reduction_mode_as_suffix = combineDet is not None @@ -1017,7 +1017,7 @@ def FindBeamCentre(rlow, rupp, MaxIter=10, xstart=None, ystart=None, tolerance=1 Finds the beam centre position. @param rlow: Inner radius of quadrant @param rupp: Outer radius of quadrant - @param MaxIter: Maximun number of iterations + @param MaxIter: Maximum number of iterations @param xstart: starting x centre position, if not set is taken from user file @param ystart: starting y centre position, if not set is taken from user file @param tolerance: Sets the step size at which the search will stop @@ -1028,7 +1028,7 @@ def FindBeamCentre(rlow, rupp, MaxIter=10, xstart=None, ystart=None, tolerance=1 if not xstart: xstart = state.move.detectors['LAB'].sample_centre_pos1 elif config['default.instrument'] == 'LARMOR': - # This is to mantain compatibility with how this function worked in the old Interface so that legacy scripts still + # This is to maintain compatibility with how this function worked in the old Interface so that legacy scripts still # function xstart = xstart * 1000 if not ystart: @@ -1088,7 +1088,7 @@ def AddRuns(runs, instrument='sans2d', saveAsEvent=False, binning="Monitors", is string list with the same format that is used for the Rebin algorithm. This property is ignored when saving as event data. @param isOverlay: sets if the the overlay mechanism should be used when the saveAsEvent flag is set - @param time_shifts: provides additional time shifts if the isOverlay flag is specified. The time shifts are specifed + @param time_shifts: provides additional time shifts if the isOverlay flag is specified. The time shifts are specified in a string list. Either time_shifts is not used or a list with times in secomds. Note that there has to be one entry fewer than the number of workspaces to add. @param defType: the file type diff --git a/scripts/SANS/sans/command_interface/command_interface_state_director.py b/scripts/SANS/sans/command_interface/command_interface_state_director.py index 44062441b4a7d08a0e132d2c4b05ce3f30c94bc9..47e4b77d2502bbf5fcafcfeb40a340cafd6c3d3f 100644 --- a/scripts/SANS/sans/command_interface/command_interface_state_director.py +++ b/scripts/SANS/sans/command_interface/command_interface_state_director.py @@ -190,7 +190,7 @@ class CommandInterfaceStateDirector(object): return # If there is more than one element, then we are only interested in the last element. The user could - # have overriden his wishes, e.g. + # have overridden his wishes, e.g. # ... # AssignSample('SANS2D1234') # ... @@ -434,7 +434,7 @@ class CommandInterfaceStateDirector(object): # Set the scale and the shift new_state_entries = {DetectorId.rescale: scale, DetectorId.shift: shift} - # Set the fit fot the scale + # Set the fit for the scale new_state_entries.update({DetectorId.rescale_fit: det_fit_range(start=q_min, stop=q_max, use_fit=fit_scale)}) # Set the fit for shift diff --git a/scripts/SANS/sans/common/constants.py b/scripts/SANS/sans/common/constants.py index c5584ac91d131d878fde8927ec9937afd282fa7b..353b6d1c733fee1ab6036f0be6732a3b5158266f 100644 --- a/scripts/SANS/sans/common/constants.py +++ b/scripts/SANS/sans/common/constants.py @@ -5,7 +5,7 @@ from __future__ import (absolute_import, division, print_function) # ---------------------------------------- -# Proeprty names for Algorithms +# Property names for Algorithms # --------------------------------------- MONITOR_SUFFIX = "_monitors" INPUT_WORKSPACE = "InputWorkspace" diff --git a/scripts/SANS/sans/common/enums.py b/scripts/SANS/sans/common/enums.py index 15b85038eba2601a173252a883e984508c2d7c51..285e39e5922a011ab39e7d396a48a08882a799cd 100644 --- a/scripts/SANS/sans/common/enums.py +++ b/scripts/SANS/sans/common/enums.py @@ -375,3 +375,12 @@ class IntegralEnum(object): Defines the entries of a batch reduction file. """ pass + + +@string_convertible +@serializable_enum("Unprocessed", "Processed", "Error") +class RowState(object): + """ + Defines the entries of a batch reduction file. + """ + pass diff --git a/scripts/SANS/sans/common/file_information.py b/scripts/SANS/sans/common/file_information.py index 98b7d8fef95176d17edfdb791dbe9fb3d0cf2756..3a99a179f2d050a41988ee6b4be451ae46ce032a 100644 --- a/scripts/SANS/sans/common/file_information.py +++ b/scripts/SANS/sans/common/file_information.py @@ -96,6 +96,8 @@ def find_sans_file(file_name): "the relevant paths are added and the correct instrument is selected." try: full_path = find_full_file_path(file_name) + if not full_path and not file_name.endswith('.nxs'): + full_path = find_full_file_path(file_name + '.nxs') if not full_path: # TODO: If we only provide a run number for example 98843 for LOQ measurments, but have LARMOR specified as the # Mantid instrument, then the FileFinder will search itself to death. This is a general Mantid issue. @@ -118,7 +120,7 @@ def get_extension_for_file_type(file_info): Get the extension for a specific file type. :param file_info: a SANSFileInformation object. - :return: the extension a stirng. This can be either nxs or raw. + :return: the extension a string. This can be either nxs or raw. """ if file_info.get_type() is FileType.ISISNexus or file_info.get_type() is FileType.ISISNexusAdded: extension = NXS_EXTENSION @@ -324,7 +326,7 @@ def get_number_of_periods_for_isis_nexus(file_name): def get_instrument_name_for_isis_nexus(file_name): """ - Instrument inforamtion is + Instrument information is file| |--mantid_workspace_1/raw_data_1| |--instrument| diff --git a/scripts/SANS/sans/common/general_functions.py b/scripts/SANS/sans/common/general_functions.py index c8d77e69a4b10f307c1076fdfb0aae66e9350535..59e1602ac20eb815f587c59d4bc58da271513e26 100644 --- a/scripts/SANS/sans/common/general_functions.py +++ b/scripts/SANS/sans/common/general_functions.py @@ -223,7 +223,7 @@ def add_to_sample_log(workspace, log_name, log_value, log_type): """ Adds a sample log to the workspace - :param workspace: the workspace to whcih the sample log is added + :param workspace: the workspace to which the sample log is added :param log_name: the name of the log :param log_value: the value of the log in string format :param log_type: the log value type which can be String, Number, Number Series diff --git a/scripts/SANS/sans/gui_logic/models/basic_hint_strategy.py b/scripts/SANS/sans/gui_logic/models/basic_hint_strategy.py new file mode 100644 index 0000000000000000000000000000000000000000..019a155e410dbea5fb3c464faf3470acfafa9c39 --- /dev/null +++ b/scripts/SANS/sans/gui_logic/models/basic_hint_strategy.py @@ -0,0 +1,17 @@ +from mantidqtpython import MantidQt + + +class BasicHintStrategy(MantidQt.MantidWidgets.HintStrategy): + def __init__(self, hint_dict): + super(BasicHintStrategy, self).__init__() + self.hint_dict = hint_dict + + def createHints(self): + hint_list = [] + for key, item in self.hint_dict.items(): + new_hint = MantidQt.MantidWidgets.Hint(key, item) + hint_list.append(new_hint) + return hint_list + + def __eq__(self, other): + return self.__dict__ == other.__dict__ diff --git a/scripts/SANS/sans/gui_logic/models/batch_process_runner.py b/scripts/SANS/sans/gui_logic/models/batch_process_runner.py new file mode 100644 index 0000000000000000000000000000000000000000..6ecd7b9d2ef503c336896773c3c5bd97ea521cf0 --- /dev/null +++ b/scripts/SANS/sans/gui_logic/models/batch_process_runner.py @@ -0,0 +1,42 @@ +from PyQt4.QtCore import pyqtSlot, QThreadPool, pyqtSignal, QObject +from sans.sans_batch import SANSBatchReduction +from ui.sans_isis.worker import Worker + + +class BatchProcessRunner(QObject): + row_processed_signal = pyqtSignal(int) + row_failed_signal = pyqtSignal(int, str) + + def __init__(self, notify_progress, notify_done, notify_error): + super(BatchProcessRunner, self).__init__() + self.row_processed_signal.connect(notify_progress) + self.row_failed_signal.connect(notify_error) + self.notify_done = notify_done + self.batch_processor = SANSBatchReduction() + self._worker = None + + @pyqtSlot() + def on_finished(self): + result = self._worker.result if self._worker else None + self._worker = None + self.notify_done(result) + + @pyqtSlot() + def on_error(self, error): + self._worker = None + + def process_states(self, states, use_optimizations, output_mode, plot_results, output_graph): + self._worker = Worker(self._process_states_on_thread, states, use_optimizations, output_mode, plot_results, + output_graph) + self._worker.signals.finished.connect(self.on_finished) + self._worker.signals.error.connect(self.on_error) + + QThreadPool.globalInstance().start(self._worker) + + def _process_states_on_thread(self, states, use_optimizations, output_mode, plot_results, output_graph): + for key, state in states.items(): + try: + self.batch_processor([state], use_optimizations, output_mode, plot_results, output_graph) + self.row_processed_signal.emit(key) + except Exception as e: + self.row_failed_signal.emit(key, str(e)) diff --git a/scripts/SANS/sans/gui_logic/models/create_state.py b/scripts/SANS/sans/gui_logic/models/create_state.py index 4f997b9c8336b682388708a62140ab74fd6077b5..ec4d3e59e7fb856bce43bb7a4aef2fa8d897b216 100644 --- a/scripts/SANS/sans/gui_logic/models/create_state.py +++ b/scripts/SANS/sans/gui_logic/models/create_state.py @@ -5,6 +5,7 @@ from sans.gui_logic.models.state_gui_model import StateGuiModel from sans.gui_logic.presenter.gui_state_director import (GuiStateDirector) from sans.user_file.user_file_reader import UserFileReader from mantid.kernel import Logger +from sans.state.state import State sans_logger = Logger("SANS") @@ -17,41 +18,41 @@ def create_states(state_model, table_model, instrument, facility, row_index=None :param row_index: the selected row, if None then all rows are generated """ number_of_rows = table_model.get_number_of_rows() - if row_index is not None: - # Check if the selected index is valid - if row_index >= number_of_rows: - return None - rows = [row_index] - else: - rows = range(number_of_rows) + rows = [x for x in row_index if x < number_of_rows] + states = {} + errors = {} gui_state_director = GuiStateDirector(table_model, state_model, facility) for row in rows: + state = _create_row_state(row, table_model, state_model, facility, instrument, file_lookup, gui_state_director) + if isinstance(state, State): + states.update({row: state}) + elif isinstance(state, str): + errors.update({row: state}) + return states, errors + + +def _create_row_state(row, table_model, state_model, facility, instrument, file_lookup, gui_state_director): + try: sans_logger.information("Generating state for row {}".format(row)) + state = None if not __is_empty_row(row, table_model): row_user_file = table_model.get_row_user_file(row) if row_user_file: row_state_model = create_gui_state_from_userfile(row_user_file, state_model) row_gui_state_director = GuiStateDirector(table_model, row_state_model, facility) - state = __create_row_state(row_gui_state_director, row, instrument, file_lookup=file_lookup) - states.update({row: state}) + state = row_gui_state_director.create_state(row, instrument=instrument, file_lookup=file_lookup) else: - state = __create_row_state(gui_state_director, row, instrument, file_lookup=file_lookup) - states.update({row: state}) - return states - - -def __create_row_state(director, row, instrument, file_lookup=True): - try: - return director.create_state(row, instrument=instrument, file_lookup=file_lookup) + state = gui_state_director.create_state(row, instrument=instrument, file_lookup=file_lookup) + return state except (ValueError, RuntimeError) as e: - raise RuntimeError("There was a bad entry for row {}. {}".format(row, str(e))) + return "{}".format(str(e)) def __is_empty_row(row, table): for key, value in table._table_entries[row].__dict__.items(): - if value and key not in ['index', 'options_column_model', 'sample_thickness']: + if value and key in ['sample_scatter']: return False return True diff --git a/scripts/SANS/sans/gui_logic/models/diagnostics_page_model.py b/scripts/SANS/sans/gui_logic/models/diagnostics_page_model.py index 127ce03caeec3d78674f7ae7384e0cfb3b17f2d2..986df77798c9dc2b31a1dcb54089ebe93646003d 100644 --- a/scripts/SANS/sans/gui_logic/models/diagnostics_page_model.py +++ b/scripts/SANS/sans/gui_logic/models/diagnostics_page_model.py @@ -157,7 +157,7 @@ def get_detector_size_from_sans_file(state, detector): def create_state(state_model_with_view_update, file, period, facility): - table_row = TableIndexModel(0, file, period, '', '', '', '', '', '', '', '', '', '') + table_row = TableIndexModel(file, period, '', '', '', '', '', '', '', '', '', '') table = TableModel() table.add_table_entry(0, table_row) diff --git a/scripts/SANS/sans/gui_logic/models/state_gui_model.py b/scripts/SANS/sans/gui_logic/models/state_gui_model.py index 8515418e0d973081f2267c45fa90b8781add58af..3d40e564e33439b05e0dc4a5f86ba8fd8fb3bf5a 100644 --- a/scripts/SANS/sans/gui_logic/models/state_gui_model.py +++ b/scripts/SANS/sans/gui_logic/models/state_gui_model.py @@ -1,4 +1,4 @@ -""" The state gui model contains all the reduction information which is not explictily available in the data table. +""" The state gui model contains all the reduction information which is not explicitly available in the data table. This is one of the two models which is used for the data reduction. It contains generally all the settings which are not available in the model associated with the data table. @@ -128,7 +128,7 @@ class StateGuiModel(object): if SetId.centre in self._user_file_items: settings = self._user_file_items[SetId.centre] else: - # If the entry does not already exist, then add it. The -1. is an illegal input which should get overriden + # If the entry does not already exist, then add it. The -1. is an illegal input which should get overridden # and if not we want it to fail. settings = [position_entry(pos1=0.0, pos2=0.0, detector_type=DetectorType.LAB)] @@ -374,7 +374,7 @@ class StateGuiModel(object): if LimitsId.wavelength in self._user_file_items: settings = self._user_file_items[LimitsId.wavelength] else: - # If the entry does not already exist, then add it. The -1. is an illegal input which should get overriden + # If the entry does not already exist, then add it. The -1. is an illegal input which should get overridden # and if not we want it to fail. settings = [simple_range(start=-1., stop=-1., step=-1., step_type=RangeStepType.Lin)] diff --git a/scripts/SANS/sans/gui_logic/models/table_model.py b/scripts/SANS/sans/gui_logic/models/table_model.py index aa904b9e934f65d71d2e9851680c4632508885e0..21ea07c0061b647fc64756c5b0ce84908d70b87c 100644 --- a/scripts/SANS/sans/gui_logic/models/table_model.py +++ b/scripts/SANS/sans/gui_logic/models/table_model.py @@ -9,15 +9,23 @@ from __future__ import (absolute_import, division, print_function) import os import re -from sans.gui_logic.sans_data_processor_gui_algorithm import create_option_column_properties +from sans.common.constants import ALL_PERIODS +from sans.gui_logic.models.basic_hint_strategy import BasicHintStrategy +from sans.common.enums import RowState class TableModel(object): + column_name_converter = ["sample_scatter", "sample_scatter_period", "sample_transmission", + "sample_transmission_period", "sample_direct", "sample_direct_period", + "can_scatter", "can_scatter_period", + "can_transmission", "can_transmission_period", "can_direct", "can_direct_period", + "output_name", "user_file", "sample_thickness", "options_column_model"] + def __init__(self): super(TableModel, self).__init__() self._user_file = "" self._batch_file = "" - self._table_entries = {} + self._table_entries = [] @staticmethod def _validate_file_name(file_name): @@ -32,11 +40,10 @@ class TableModel(object): @user_file.setter def user_file(self, value): - self._validate_file_name(value) self._user_file = value def get_row_user_file(self, row_index): - if row_index in self._table_entries: + if row_index < len(self._table_entries): return self._table_entries[row_index].user_file else: raise IndexError("The row {} does not exist.".format(row_index)) @@ -47,34 +54,81 @@ class TableModel(object): @batch_file.setter def batch_file(self, value): - self._validate_file_name(value) self._batch_file = value def get_table_entry(self, index): - if index not in self._table_entries: - raise ValueError("The {}th row entry does not exist".format(index)) return self._table_entries[index] def add_table_entry(self, row, table_index_model): - self._table_entries.update({row: table_index_model}) + self._table_entries.insert(row, table_index_model) + + def append_table_entry(self, table_index_model): + self._table_entries.append(table_index_model) + + def remove_table_entries(self, rows): + # For speed rows should be a Set here but don't think it matters for the list sizes involved. + self._table_entries[:] = [item for i,item in enumerate(self._table_entries) if i not in rows] + if not self._table_entries: + row_index_model = self.create_empty_row() + self.append_table_entry(row_index_model) + + def replace_table_entries(self, row_to_replace_index, rows_to_insert): + self.remove_table_entries(row_to_replace_index) + for row_entry in reversed(rows_to_insert): + self.add_table_entry(row_to_replace_index[0], row_entry) def clear_table_entries(self): - self._table_entries = {} + self._table_entries = [] + row_index_model = self.create_empty_row() + self.append_table_entry(row_index_model) def get_number_of_rows(self): return len(self._table_entries) + def update_table_entry(self, row, column, value): + self._table_entries[row].update_attribute(self.column_name_converter[column], value) + self._table_entries[row].update_attribute('row_state', RowState.Unprocessed) + self._table_entries[row].update_attribute('tool_tip', '') + + def is_empty_row(self, row): + return self._table_entries[row].is_empty() + + @staticmethod + def create_empty_row(): + row = [''] * 16 + return TableIndexModel(*row) + + def get_options_hint_strategy(self): + return OptionsColumnModel.get_hint_strategy() + + def set_row_to_processed(self, row, tool_tip): + self._table_entries[row].update_attribute('row_state', RowState.Processed) + self._table_entries[row].update_attribute('tool_tip', tool_tip) + + def reset_row_state(self, row): + self._table_entries[row].update_attribute('row_state', RowState.Unprocessed) + self._table_entries[row].update_attribute('tool_tip', '') + + def set_row_to_error(self, row, tool_tip): + self._table_entries[row].update_attribute('row_state', RowState.Error) + self._table_entries[row].update_attribute('tool_tip', tool_tip) + + def __eq__(self, other): + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + return self.__dict__ != other.__dict__ + class TableIndexModel(object): - def __init__(self, index, sample_scatter, sample_scatter_period, + def __init__(self, sample_scatter, sample_scatter_period, sample_transmission, sample_transmission_period, sample_direct, sample_direct_period, can_scatter, can_scatter_period, can_transmission, can_transmission_period, can_direct, can_direct_period, - output_name="", user_file="", options_column_string="", sample_thickness='0.0'): + output_name="", user_file="", sample_thickness='0.0', options_column_string=""): super(TableIndexModel, self).__init__() - self.index = index self.sample_scatter = sample_scatter self.sample_scatter_period = sample_scatter_period self.sample_transmission = sample_transmission @@ -93,8 +147,48 @@ class TableIndexModel(object): self.sample_thickness = sample_thickness self.output_name = output_name - # Options column entries - self.options_column_model = OptionsColumnModel(options_column_string) + self.options_column_model = options_column_string + + self.row_state = RowState.Unprocessed + self.tool_tip = '' + + # Options column entries + @property + def options_column_model(self): + return self._options_column_model + + @options_column_model.setter + def options_column_model(self, value): + self._options_column_model = OptionsColumnModel(value) + + def update_attribute(self, attribute_name, value): + setattr(self, attribute_name, value) + + def __eq__(self, other): + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + return self.__dict__ != other.__dict__ + + def to_list(self): + return [self.sample_scatter, self._string_period(self.sample_scatter_period), self.sample_transmission, + self._string_period(self.sample_transmission_period),self.sample_direct, + self._string_period(self.sample_direct_period), self.can_scatter, + self._string_period(self.can_scatter_period), self.can_transmission, + self._string_period(self.can_transmission_period), self.can_direct, + self._string_period(self.can_direct_period), self.output_name, self.user_file, self.sample_thickness, + self.options_column_model.get_options_string()] + + def isMultiPeriod(self): + return any ((self.sample_scatter_period, self.sample_transmission_period ,self.sample_direct_period, + self.can_scatter_period, self.can_transmission_period, self.can_direct_period)) + + def is_empty(self): + return not any((self.sample_scatter, self.sample_transmission, self.sample_direct, self.can_scatter, + self.can_transmission, self.can_direct)) + + def _string_period(self, _tag): + return "" if _tag == ALL_PERIODS else str(_tag) class OptionsColumnModel(object): @@ -106,13 +200,21 @@ class OptionsColumnModel(object): def get_options(self): return self._options + def get_options_string(self): + return self._options_column_string + @staticmethod def _get_permissible_properties(): - props = {} - option_column_properties = create_option_column_properties() - for element in option_column_properties: - props.update({element.algorithm_property: element.property_type}) - return props + return {"WavelengthMin":float, "WavelengthMax": float, "EventSlices": str} + + @staticmethod + def get_hint_strategy(): + return BasicHintStrategy({"WavelengthMin": 'The min value of the wavelength when converting from TOF.', + "WavelengthMax": 'The max value of the wavelength when converting from TOF.', + "EventSlices": 'The event slices to reduce.' + ' The format is the same as for the event slices' + ' box in settings, however if a comma separated list is given ' + 'it must be enclosed in quotes'}) @staticmethod def _parse_string(options_column_string): @@ -162,3 +264,9 @@ class OptionsColumnModel(object): conversion_functions = permissible_properties[key] options.update({key: conversion_functions(value)}) return options + + def __eq__(self, other): + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + return self.__dict__ != other.__dict__ diff --git a/scripts/SANS/sans/gui_logic/presenter/add_runs_presenter.py b/scripts/SANS/sans/gui_logic/presenter/add_runs_presenter.py index f835a3f1b50f16342ceff28a2f26efc8e8e2a648..89f0660b1522ea5be14832bff54d5f98a984bd04 100644 --- a/scripts/SANS/sans/gui_logic/presenter/add_runs_presenter.py +++ b/scripts/SANS/sans/gui_logic/presenter/add_runs_presenter.py @@ -18,7 +18,9 @@ class AddRunsPagePresenter(object): make_run_summation_presenter, view, parent_view): + self._view = view + self._parent_view = parent_view self._sum_runs = sum_runs self._use_generated_file_name = True self._run_selector_presenter = \ @@ -46,7 +48,9 @@ class AddRunsPagePresenter(object): # Therefore assumes that file names all have the same number of # leading zeroes since a shorter string is sorted after a longer one. names = [run.display_name() for run in run_selection] - return (max(names) + '-add' if names else '') + instrument = self._parent_view.instrument.to_string(self._parent_view.instrument) + + return (instrument + max(names) + '-add' if names else '') def _sum_base_file_name(self, run_selection): if self._use_generated_file_name: diff --git a/scripts/SANS/sans/gui_logic/presenter/main_presenter.py b/scripts/SANS/sans/gui_logic/presenter/main_presenter.py deleted file mode 100644 index 1a899dacb7aad1927c6d8cbe58b55b4a54666820..0000000000000000000000000000000000000000 --- a/scripts/SANS/sans/gui_logic/presenter/main_presenter.py +++ /dev/null @@ -1,98 +0,0 @@ -""" The main presenter. - -The MainPresenter provides the QDataProcessorWidget with additional processing options which have not been -set on the data table. The MainPresenter is required by the DataProcessorWidget framework. -""" - -from __future__ import (absolute_import, division, print_function) - -from mantidqtpython import MantidQt - -from sans.gui_logic.sans_data_processor_gui_algorithm import (get_gui_algorithm_name, get_white_list, - get_black_list) -from sans.gui_logic.presenter.run_tab_presenter import RunTabPresenter - - -class PresenterEnum(object): - class RunTabPresenter(object): - pass - - -class MainPresenter(MantidQt.MantidWidgets.DataProcessor.DataProcessorMainPresenter): - """ - Comments below are from Raquel: - - A DataProcessorMainPresenter. The base class provides default implementations - but we should re-implement the following methods: - - getPreprocessingOptions() -- to supply global pre-processing options to the table widget - - getProcessingOptions() -- to supply global processing options - - getPostprocessingOptionsAsString() -- to supply global post-processing options - - notifyADSChanged() -- to act when the ADS changed, typically we want to update - table actions with the list of table workspaces that can be loaded into the interface - - This is an intermediate layer needed in python. Ideally our gui class should - inherit from 'DataProcessorMainPresenter' directly and provide the required implementations, - but multiple inheritance does not seem to be fully supported, hence we need this extra class. - """ - - def __init__(self, facility): - super(MantidQt.MantidWidgets.DataProcessor.DataProcessorMainPresenter, self).__init__() - - self._view = None - - # Algorithm details - self._gui_algorithm_name = None - self._white_list = None - self._black_list = None - self._facility = facility - - # Set of sub presenters - self._presenters = {} - self._presenters.update({PresenterEnum.RunTabPresenter: RunTabPresenter(facility=self._facility)}) - - def set_view(self, view): - self._view = view - for _, presenter in self._presenters.items(): - presenter.set_view(self._view) - - def get_gui_algorithm_name(self): - if self._gui_algorithm_name is None: - self._gui_algorithm_name = get_gui_algorithm_name(self._facility) - return self._gui_algorithm_name - - def get_white_list(self, show_periods=False): - self._white_list = get_white_list(show_periods=show_periods) - return self._white_list - - def get_number_of_white_list_items(self): - return 0 if not self._white_list else len(self._white_list) - - def get_black_list(self): - if self._black_list is None: - self._black_list = get_black_list() - return self._black_list - - def confirmReductionPaused(self, group): - self._presenters[PresenterEnum.RunTabPresenter].on_processing_finished() - - # ------------------------------------------------------------------------------------------------------------------ - # Inherited methods - # ------------------------------------------------------------------------------------------------------------------ - def getProcessingOptions(self, group = 0): - """ - Gets the processing options from the run tab presenter - """ - return self._presenters[PresenterEnum.RunTabPresenter].get_processing_options() - - # ------------------------------------------------------------------------------------------------------------------ - # Unused - # ------------------------------------------------------------------------------------------------------------------ - def getPreprocessingOptions(self, group = 0): - empty = {} - return empty - - def getPostprocessingOptionsAsString(self, group = 0): - return "" - - def notifyADSChanged(self, workspace_list, group = 0): - self._view.add_actions_to_menus(workspace_list) diff --git a/scripts/SANS/sans/gui_logic/presenter/run_tab_presenter.py b/scripts/SANS/sans/gui_logic/presenter/run_tab_presenter.py index d9787c94c65a2df05dc78a5e4f6c32e6c838321a..d7fdea852d0d6080a0815660481d6316306e2a61 100644 --- a/scripts/SANS/sans/gui_logic/presenter/run_tab_presenter.py +++ b/scripts/SANS/sans/gui_logic/presenter/run_tab_presenter.py @@ -1,6 +1,6 @@ """ The run tab presenter. -This presenter is essentially the brain of the reduction gui. It controlls other presenters and is mainly responsible +This presenter is essentially the brain of the reduction gui. It controls other presenters and is mainly responsible for presenting and generating the reduction settings. """ @@ -10,20 +10,17 @@ import os import copy import time from mantid.kernel import Logger -from mantid.api import (AnalysisDataService, FileFinder, WorkspaceFactory) -from mantid.kernel import (Property) +from mantid.api import (FileFinder) from ui.sans_isis.sans_data_processor_gui import SANSDataProcessorGui from sans.gui_logic.models.state_gui_model import StateGuiModel +from sans.gui_logic.models.batch_process_runner import BatchProcessRunner from sans.gui_logic.models.table_model import TableModel, TableIndexModel from sans.gui_logic.presenter.settings_diagnostic_presenter import (SettingsDiagnosticPresenter) from sans.gui_logic.presenter.masking_table_presenter import (MaskingTablePresenter) from sans.gui_logic.presenter.beam_centre_presenter import BeamCentrePresenter -from sans.gui_logic.sans_data_processor_gui_algorithm import SANS_DUMMY_INPUT_ALGORITHM_PROPERTY_NAME -from sans.gui_logic.presenter.property_manager_service import PropertyManagerService -from sans.gui_logic.gui_common import (get_reduction_mode_strings_for_gui, generate_table_index, OPTIONS_SEPARATOR, - OPTIONS_EQUAL, get_instrument_strings_for_gui) -from sans.common.enums import (BatchReductionEntry, OutputMode, RangeStepType, SampleShape, FitType) +from sans.gui_logic.gui_common import (get_reduction_mode_strings_for_gui, get_instrument_strings_for_gui) +from sans.common.enums import (BatchReductionEntry, RangeStepType, SampleShape, FitType, RowState) from sans.user_file.user_file_reader import UserFileReader from sans.command_interface.batch_csv_file_parser import BatchCsvParser from sans.common.constants import ALL_PERIODS @@ -42,6 +39,8 @@ except (Exception, Warning): # this should happen when this is called from outside Mantidplot and only then, # the result is that attempting to plot will raise an exception +row_state_to_colour_mapping = {RowState.Unprocessed:'#FFFFFF', RowState.Processed:'#d0f4d0', RowState.Error:'#accbff'} + class RunTabPresenter(object): class ConcreteRunTabListener(SANSDataProcessorGui.RunTabListener): @@ -61,14 +60,11 @@ class RunTabPresenter(object): def on_processed_clicked(self): self._presenter.on_processed_clicked() - def on_processing_finished(self): - self._presenter.on_processing_finished() - - def on_multi_period_selection(self): - self._presenter.on_multi_period_selection() + def on_multi_period_selection(self, show_periods): + self._presenter.on_multiperiod_changed(show_periods) - def on_data_changed(self): - self._presenter.on_data_changed() + def on_data_changed(self, row, column, new_value, old_value): + self._presenter.on_data_changed(row, column, new_value, old_value) def on_manage_directories(self): self._presenter.on_manage_directories() @@ -76,6 +72,38 @@ class RunTabPresenter(object): def on_instrument_changed(self): self._presenter.on_instrument_changed() + def on_row_inserted(self, index, row): + self._presenter.on_row_inserted(index, row) + + def on_rows_removed(self, rows): + self._presenter.on_rows_removed(rows) + + def on_copy_rows_requested(self): + self._presenter.on_copy_rows_requested() + + def on_paste_rows_requested(self): + self._presenter.on_paste_rows_requested() + + def on_insert_row(self): + self._presenter.on_insert_row() + + def on_erase_rows(self): + self._presenter.on_erase_rows() + + def on_cut_rows(self): + self._presenter.on_cut_rows_requested() + + class ProcessListener(WorkHandler.WorkListener): + def __init__(self, presenter): + super(RunTabPresenter.ProcessListener, self).__init__() + self._presenter = presenter + + def on_processing_finished(self, result): + self._presenter.on_processing_finished(result) + + def on_processing_error(self, error): + self._presenter.on_processing_error(error) + def __init__(self, facility, view=None): super(RunTabPresenter, self).__init__() self._facility = facility @@ -83,25 +111,22 @@ class RunTabPresenter(object): self.sans_logger = Logger("SANS") # Name of grpah to output to self.output_graph = 'SANS-Latest' - # Presenter needs to have a handle on the view since it delegates it - self._view = None - self.set_view(view) - self._processing = False + self.progress = 0 # Models that are being used by the presenter self._state_model = None - self._table_model = None + self._table_model = TableModel() - # Due to the nature of the DataProcessorWidget we need to provide an algorithm with at least one input - # workspace and at least one output workspace. Our SANS state approach is not compatible with this. Hence - # we provide a dummy workspace which is not used. We keep it invisible on the ADS and delete it when the - # main_presenter is deleted. - # This is not a nice solution but in line with the SANS dummy algorithm approach that we have provided - # for the - self._create_dummy_input_workspace() + # Presenter needs to have a handle on the view since it delegates it + self._view = None + self.set_view(view) + self._processing = False + self.work_handler = WorkHandler() + self.batch_process_runner = BatchProcessRunner(self.notify_progress, self.on_processing_finished, self.on_processing_error) # File information for the first input self._file_information = None + self._clipboard = [] # Settings diagnostic tab presenter self._settings_diagnostic_tab_presenter = SettingsDiagnosticPresenter(self) @@ -115,9 +140,6 @@ class RunTabPresenter(object): # Workspace Diagnostic page presenter self._workspace_diagnostic_presenter = DiagnosticsPagePresenter(self, WorkHandler, run_integral, create_state, self._facility) - def __del__(self): - self._delete_dummy_input_workspace() - def _default_gui_setup(self): """ Provides a default setup of the GUI. This is important for the initial start up, when the view is being set. @@ -179,15 +201,15 @@ class RunTabPresenter(object): # Set appropriate view for the masking table presenter self._masking_table_presenter.set_view(self._view.masking_table) - # Set up the correct table row indices - self.on_multi_period_selection() - # Set the appropriate view for the beam centre presenter self._beam_centre_presenter.set_view(self._view.beam_centre) # Set the appropriate view for the diagnostic page self._workspace_diagnostic_presenter.set_view(self._view.diagnostic_page, self._view.instrument) + self._view.setup_layout() + self._view.set_hinting_line_edit_for_column(15, self._table_model.get_options_hint_strategy()) + def on_user_file_load(self): """ Loads the user file. Populates the models and the view. @@ -203,7 +225,7 @@ class RunTabPresenter(object): if not os.path.exists(user_file_path): raise RuntimeError("The user path {} does not exist. Make sure a valid user file path" " has been specified.".format(user_file_path)) - + self._table_model.user_file = user_file_path # Clear out the current view self._view.reset_all_fields_to_default() @@ -217,9 +239,8 @@ class RunTabPresenter(object): self._update_view_from_state_model() self._beam_centre_presenter.update_centre_positions(self._state_model) - # 6. Perform calls on child presenters - self._masking_table_presenter.on_update_rows() self._beam_centre_presenter.on_update_rows() + self._masking_table_presenter.on_update_rows() self._workspace_diagnostic_presenter.on_user_file_load(user_file_path) except Exception as e: @@ -241,29 +262,88 @@ class RunTabPresenter(object): raise RuntimeError("The batch file path {} does not exist. Make sure a valid batch file path" " has been specified.".format(batch_file_path)) + self._table_model.batch_file = batch_file_path + # 2. Read the batch file batch_file_parser = BatchCsvParser(batch_file_path) parsed_rows = batch_file_parser.parse_batch_file() - # 3. Clear the table - self._view.clear_table() - # 4. Populate the table - for row in parsed_rows: - self._populate_row_in_table(row) + # 3. Populate the table + self._table_model.clear_table_entries() + for index, row in enumerate(parsed_rows): + self._add_row_to_table_model(row, index) + self._table_model.remove_table_entries([len(parsed_rows)]) + + self.update_view_from_table_model() - # 5. Perform calls on child presenters - self._masking_table_presenter.on_update_rows() self._beam_centre_presenter.on_update_rows() + self._masking_table_presenter.on_update_rows() except RuntimeError as e: self.sans_logger.error("Loading of the batch file failed. {}".format(str(e))) self.display_warning_box('Warning', 'Loading of the batch file failed', str(e)) - def on_data_changed(self): - if not self._processing: - # 1. Perform calls on child presenters - self._masking_table_presenter.on_update_rows() - self._beam_centre_presenter.on_update_rows() + def _add_row_to_table_model(self,row, index): + """ + Adds a row to the table + """ + def get_string_entry(_tag, _row): + _element = "" + if _tag in _row: + _element = _row[_tag] + return _element + + def get_string_period(_tag): + return "" if _tag == ALL_PERIODS else str(_tag) + + # 1. Pull out the entries + sample_scatter = get_string_entry(BatchReductionEntry.SampleScatter, row) + sample_scatter_period = get_string_period(get_string_entry(BatchReductionEntry.SampleScatterPeriod, row)) + sample_transmission = get_string_entry(BatchReductionEntry.SampleTransmission, row) + sample_transmission_period = \ + get_string_period(get_string_entry(BatchReductionEntry.SampleTransmissionPeriod, row)) + sample_direct = get_string_entry(BatchReductionEntry.SampleDirect, row) + sample_direct_period = get_string_period(get_string_entry(BatchReductionEntry.SampleDirectPeriod, row)) + can_scatter = get_string_entry(BatchReductionEntry.CanScatter, row) + can_scatter_period = get_string_period(get_string_entry(BatchReductionEntry.CanScatterPeriod, row)) + can_transmission = get_string_entry(BatchReductionEntry.CanTransmission, row) + can_transmission_period = get_string_period(get_string_entry(BatchReductionEntry.CanScatterPeriod, row)) + can_direct = get_string_entry(BatchReductionEntry.CanDirect, row) + can_direct_period = get_string_period(get_string_entry(BatchReductionEntry.CanDirectPeriod, row)) + output_name = get_string_entry(BatchReductionEntry.Output, row) + file_information_factory = SANSFileInformationFactory() + file_information = file_information_factory.create_sans_file_information(sample_scatter) + sample_thickness = file_information._thickness + user_file = get_string_entry(BatchReductionEntry.UserFile, row) + + row_entry = [sample_scatter, sample_scatter_period, sample_transmission, sample_transmission_period, + sample_direct, sample_direct_period, can_scatter, can_scatter_period, can_transmission, can_transmission_period, + can_direct, can_direct_period, + output_name, user_file, sample_thickness, ''] + + table_index_model = TableIndexModel(*row_entry) + + self._table_model.add_table_entry(index, table_index_model) + + def update_view_from_table_model(self): + self._view.clear_table() + self._view.hide_period_columns() + for row_index, row in enumerate(self._table_model._table_entries): + row_entry = [str(x) for x in row.to_list()] + self._view.add_row(row_entry) + self._view.change_row_color(row_state_to_colour_mapping[row.row_state], row_index + 1) + self._view.set_row_tooltip(row.tool_tip, row_index + 1) + if row.isMultiPeriod(): + self._view.show_period_columns() + self._view.remove_rows([0]) + self._view.clear_selection() + + def on_data_changed(self, row, column, new_value, old_value): + self._table_model.update_table_entry(row, column, new_value) + self._view.change_row_color(row_state_to_colour_mapping[RowState.Unprocessed], row) + self._view.set_row_tooltip('', row) + self._beam_centre_presenter.on_update_rows() + self._masking_table_presenter.on_update_rows() def on_instrument_changed(self): self._setup_instrument_specific_settings() @@ -281,51 +361,134 @@ class RunTabPresenter(object): self._view.disable_buttons() self._processing = True self.sans_logger.information("Starting processing of batch table.") - # 0. Validate rows - self._create_dummy_input_workspace() - self._validate_rows() # 1. Set up the states and convert them into property managers - states = self.get_states() - if not states: - raise RuntimeError("There seems to have been an issue with setting the states. Make sure that a user file" - " has been loaded") - property_manager_service = PropertyManagerService() - property_manager_service.add_states_to_pmds(states) + selected_rows = self._view.get_selected_rows() + selected_rows = selected_rows if selected_rows else range(self._table_model.get_number_of_rows()) + for row in selected_rows: + self._table_model.reset_row_state(row) + self.update_view_from_table_model() + states, errors = self.get_states(row_index=selected_rows) - # 2. Add dummy input workspace to Options column - self._remove_dummy_workspaces_and_row_index() - self._set_dummy_workspace() + for row, error in errors.items(): + self.on_processing_error(row, error) - # 3. Add dummy row index to Options column - self._set_indices() + if not states: + self.on_processing_finished(None) + return # 4. Create the graph if continuous output is specified if mantidplot: if self._view.plot_results and not mantidplot.graph(self.output_graph): mantidplot.newGraph(self.output_graph) + # Check if optimizations should be used + use_optimizations = self._view.use_optimizations + + # Get the output mode + output_mode = self._view.output_mode + + # Check if results should be plotted + plot_results = self._view.plot_results + + # Get the name of the graph to output to + output_graph = self.output_graph + + self.progress = 0 + setattr(self._view, 'progress_bar_value', self.progress) + setattr(self._view, 'progress_bar_maximum', len(states)) + self.batch_process_runner.process_states(states,use_optimizations, output_mode, plot_results, output_graph) + except Exception as e: - self._view.halt_process_flag() self._view.enable_buttons() self.sans_logger.error("Process halted due to: {}".format(str(e))) self.display_warning_box('Warning', 'Process halted', str(e)) + def on_multiperiod_changed(self, show_periods): + if show_periods: + self._view.show_period_columns() + else: + self._view.hide_period_columns() + def display_warning_box(self, title, text, detailed_text): self._view.display_message_box(title, text, detailed_text) - def on_processing_finished(self): - self._remove_dummy_workspaces_and_row_index() + def notify_progress(self, row): + self.increment_progress() + message = '' + self._table_model.set_row_to_processed(row, message) + self.update_view_from_table_model() + + def on_processing_finished(self, result): self._view.enable_buttons() self._processing = False - def on_multi_period_selection(self): - multi_period = self._view.is_multi_period_view() - self.table_index = generate_table_index(multi_period) + def on_processing_error(self, row, error_msg): + self.increment_progress() + self._table_model.set_row_to_error(row, error_msg) + self.update_view_from_table_model() + + def increment_progress(self): + self.progress = self.progress + 1 + setattr(self._view, 'progress_bar_value', self.progress) + + def on_row_inserted(self, index, row): + row_table_index = TableIndexModel(*row) + self._table_model.add_table_entry(index, row_table_index) + + def on_insert_row(self): + selected_rows = self._view.get_selected_rows() + selected_row = selected_rows[0] + 1 if selected_rows else self._table_model.get_number_of_rows() + table_entry_row = self._table_model.create_empty_row() + self._table_model.add_table_entry(selected_row, table_entry_row) + self.update_view_from_table_model() + + def on_erase_rows(self): + selected_rows = self._view.get_selected_rows() + empty_row = TableModel.create_empty_row() + for row in selected_rows: + self._table_model.replace_table_entries([row], [empty_row]) + self.update_view_from_table_model() + + def on_rows_removed(self, rows): + self._table_model.remove_table_entries(rows) + self.update_view_from_table_model() + + def on_copy_rows_requested(self): + selected_rows = self._view.get_selected_rows() + self._clipboard = [] + for row in selected_rows: + data_from_table_model = self._table_model.get_table_entry(row).to_list() + self._clipboard.append(data_from_table_model) + + def on_cut_rows_requested(self): + self.on_copy_rows_requested() + rows = self._view.get_selected_rows() + self.on_rows_removed(rows) + + def on_paste_rows_requested(self): + if self._clipboard: + selected_rows = self._view.get_selected_rows() + selected_rows = selected_rows if selected_rows else [self._table_model.get_number_of_rows()] + replacement_table_index_models = [TableIndexModel(*x) for x in self._clipboard] + self._table_model.replace_table_entries(selected_rows, replacement_table_index_models) + self.update_view_from_table_model() def on_manage_directories(self): self._view.show_directory_manager() + def get_row_indices(self): + """ + Gets the indices of row which are not empty. + :return: a list of row indices. + """ + row_indices_which_are_not_empty = [] + number_of_rows = self._table_model.get_number_of_rows() + for row in range(number_of_rows): + if not self.is_empty_row(row): + row_indices_which_are_not_empty.append(row) + return row_indices_which_are_not_empty + def on_mask_file_add(self): """ We get the added mask file name and add it to the list of masks @@ -348,94 +511,26 @@ class RunTabPresenter(object): self._settings_diagnostic_tab_presenter.on_update_rows() self._beam_centre_presenter.on_update_rows() - def _add_to_hidden_options(self, row, property_name, property_value): - """ - Adds a new property to the Hidden Options column - - @param row: The row where the Options column is being altered - @param property_name: The property name on the GUI algorithm. - @param property_value: The value which is being set for the property. - """ - entry = property_name + OPTIONS_EQUAL + str(property_value) - options = self._get_hidden_options(row) - if options: - options += OPTIONS_SEPARATOR + entry - else: - options = entry - self._set_hidden_options(options, row) - - def _set_hidden_options(self, value, row): - self._view.set_cell(value, row, self.table_index['HIDDEN_OPTIONS_INDEX']) - - def _get_options(self, row): - return self._view.get_cell(row, self.table_index['OPTIONS_INDEX'], convert_to=str) - - def _get_hidden_options(self, row): - return self._view.get_cell(row, self.table_index['HIDDEN_OPTIONS_INDEX'], convert_to=str) - def is_empty_row(self, row): """ Checks if a row has no entries. These rows will be ignored. :param row: the row index :return: True if the row is empty. """ - indices = range(self.table_index['OPTIONS_INDEX'] + 1) - for index in indices: - cell_value = self._view.get_cell(row, index, convert_to=str) - if cell_value: - return False - return True - - def _remove_from_hidden_options(self, row, property_name): - """ - Remove the entries in the hidden options column - :param row: the row index - :param property_name: the property name which is to be removed - """ - options = self._get_hidden_options(row) - # Remove the property entry and the value - individual_options = options.split(",") - clean_options = [] - for individual_option in individual_options: - if property_name not in individual_option: - clean_options.append(individual_option) - clean_options = ",".join(clean_options) - self._set_hidden_options(clean_options, row) - - def _validate_rows(self): - """ - Validation of the rows. A minimal setup requires that ScatterSample is set. - """ - # If SampleScatter is empty, then don't run the reduction. - # We allow empty rows for now, since we cannot remove them from Python. - number_of_rows = self._view.get_number_of_rows() - for row in range(number_of_rows): - if not self.is_empty_row(row): - sample_scatter = self._view.get_cell(row, 0) - if not sample_scatter: - raise RuntimeError("Row {} has not SampleScatter specified. Please correct this.".format(row)) - - def get_processing_options(self): - """ - Creates a processing string for the data processor widget - - :return: A dict of key:value pairs of processing-algorithm properties and values for the data processor widget - """ - global_options = {} - - # Check if optimizations should be used - global_options['UseOptimizations'] = "1" if self._view.use_optimizations else "0" - - # Get the output mode - output_mode = self._view.output_mode - global_options['OutputMode'] = OutputMode.to_string(output_mode) - - # Check if results should be plotted - global_options['PlotResults'] = "1" if self._view.plot_results else "0" - - # Get the name of the graph to output to - global_options['OutputGraph'] = "{}".format(self.output_graph) - return global_options + return self._table_model.is_empty_row(row) + + # def _validate_rows(self): + # """ + # Validation of the rows. A minimal setup requires that ScatterSample is set. + # """ + # # If SampleScatter is empty, then don't run the reduction. + # # We allow empty rows for now, since we cannot remove them from Python. + # number_of_rows = self._table_model.get_number_of_rows() + # for row in range(number_of_rows): + # if not self.is_empty_row(row): + # sample_scatter = self._view.get_cell(row, 0) + # if not sample_scatter: + # raise RuntimeError("Row {} has not SampleScatter specified. Please correct this.".format(row)) # ------------------------------------------------------------------------------------------------------------------ # Controls @@ -469,30 +564,19 @@ class RunTabPresenter(object): # 1. Update the state model state_model_with_view_update = self._get_state_model_with_view_update() # 2. Update the table model - table_model = self._get_table_model() + table_model = self._table_model # 3. Go through each row and construct a state object if table_model and state_model_with_view_update: - states = create_states(state_model_with_view_update, table_model, self._view.instrument - , self._facility, row_index, file_lookup=file_lookup) + states, errors = create_states(state_model_with_view_update, table_model, self._view.instrument + , self._facility, row_index=row_index, file_lookup=file_lookup) else: states = None + errors = None stop_time_state_generation = time.time() time_taken = stop_time_state_generation - start_time_state_generation self.sans_logger.information("The generation of all states took {}s".format(time_taken)) - return states - - def get_row_indices(self): - """ - Gets the indices of row which are not empty. - :return: a list of row indices. - """ - row_indices_which_are_not_empty = [] - number_of_rows = self._view.get_number_of_rows() - for row in range(number_of_rows): - if not self.is_empty_row(row): - row_indices_which_are_not_empty.append(row) - return row_indices_which_are_not_empty + return states, errors def get_state_for_row(self, row_index, file_lookup=True): """ @@ -500,7 +584,7 @@ class RunTabPresenter(object): :param row_index: the row index :return: a state if the index is valid and there is a state else None """ - states = self.get_states(row_index=row_index, file_lookup=file_lookup) + states, errors = self.get_states(row_index=[row_index], file_lookup=file_lookup) if states is None: self.sans_logger.warning("There does not seem to be data for a row {}.".format(row_index)) return None @@ -861,135 +945,9 @@ class RunTabPresenter(object): if attribute is not None and attribute != '': setattr(state_model, attribute_name, attribute) - def _get_table_model(self): - # 1. Create a new table model - user_file = self._view.get_user_file_path() - batch_file = self._view.get_batch_file_path() - - table_model = TableModel() - table_model.user_file = user_file - self.batch_file = batch_file - - # 2. Iterate over each row, create a table row model and insert it - number_of_rows = self._view.get_number_of_rows() - is_multi_period_view = self._view.is_multi_period_view() - for row in range(number_of_rows): - sample_scatter = self.get_cell_value(row, 'SAMPLE_SCATTER_INDEX') - sample_transmission = self.get_cell_value(row, 'SAMPLE_TRANSMISSION_INDEX') - sample_direct = self.get_cell_value(row, 'SAMPLE_DIRECT_INDEX') - - can_scatter = self.get_cell_value(row, 'CAN_SCATTER_INDEX') - can_transmission = self.get_cell_value(row, 'CAN_TRANSMISSION_INDEX') - can_direct = self.get_cell_value(row, 'CAN_DIRECT_INDEX') - - sample_scatter_period = self.get_cell_value(row, 'SAMPLE_SCATTER_PERIOD_INDEX')if is_multi_period_view else "" - sample_transmission_period = self.get_cell_value(row, 'SAMPLE_TRANSMISSION_PERIOD_INDEX')if is_multi_period_view else "" - sample_direct_period = self.get_cell_value(row, 'SAMPLE_DIRECT_PERIOD_INDEX')if is_multi_period_view else "" - - can_scatter_period = self.get_cell_value(row, 'CAN_SCATTER_PERIOD_INDEX') if is_multi_period_view else "" - can_transmission_period = self.get_cell_value(row, 'CAN_TRANSMISSION_PERIOD_INDEX') if is_multi_period_view else "" - can_direct_period = self.get_cell_value(row, 'CAN_DIRECT_PERIOD_INDEX') if is_multi_period_view else "" - - output_name = self.get_cell_value(row, 'OUTPUT_NAME_INDEX') - sample_thickness = self.get_cell_value(row, 'SAMPLE_THICKNESS_INDEX') - user_file = self.get_cell_value(row, 'USER_FILE_INDEX') - - # Get the options string - # We don't have to add the hidden column here, since it only contains information for the SANS - # workflow to operate properly. It however does not contain information for the - options_string = self._get_options(row) - - table_index_model = TableIndexModel(index=row, - sample_scatter=sample_scatter, - sample_scatter_period=sample_scatter_period, - sample_transmission=sample_transmission, - sample_transmission_period=sample_transmission_period, - sample_direct=sample_direct, - sample_direct_period=sample_direct_period, - can_scatter=can_scatter, - can_scatter_period=can_scatter_period, - can_transmission=can_transmission, - can_transmission_period=can_transmission_period, - can_direct=can_direct, - can_direct_period=can_direct_period, - output_name=output_name, - user_file = user_file, - sample_thickness=sample_thickness, - options_column_string=options_string) - table_model.add_table_entry(row, table_index_model) - return table_model - def get_cell_value(self, row, column): return self._view.get_cell(row=row, column=self.table_index[column], convert_to=str) - def _populate_row_in_table(self, row): - """ - Adds a row to the table - """ - def get_string_entry(_tag, _row): - _element = "" - if _tag in _row: - _element = _row[_tag] - return _element - - def get_string_period(_tag): - return "" if _tag == ALL_PERIODS else str(_tag) - # 1. Pull out the entries - sample_scatter = get_string_entry(BatchReductionEntry.SampleScatter, row) - sample_scatter_period = get_string_entry(BatchReductionEntry.SampleScatterPeriod, row) - sample_transmission = get_string_entry(BatchReductionEntry.SampleTransmission, row) - sample_transmission_period = get_string_entry(BatchReductionEntry.SampleTransmissionPeriod, row) - sample_direct = get_string_entry(BatchReductionEntry.SampleDirect, row) - sample_direct_period = get_string_entry(BatchReductionEntry.SampleDirectPeriod, row) - can_scatter = get_string_entry(BatchReductionEntry.CanScatter, row) - can_scatter_period = get_string_entry(BatchReductionEntry.CanScatterPeriod, row) - can_transmission = get_string_entry(BatchReductionEntry.CanTransmission, row) - can_transmission_period = get_string_entry(BatchReductionEntry.CanScatterPeriod, row) - can_direct = get_string_entry(BatchReductionEntry.CanDirect, row) - can_direct_period = get_string_entry(BatchReductionEntry.CanDirectPeriod, row) - output_name = get_string_entry(BatchReductionEntry.Output, row) - file_information_factory = SANSFileInformationFactory() - file_information = file_information_factory.create_sans_file_information(sample_scatter) - sample_thickness = file_information._thickness - user_file = get_string_entry(BatchReductionEntry.UserFile, row) - - # If one of the periods is not null, then we should switch the view to multi-period view - if any ((sample_scatter_period, sample_transmission_period, sample_direct_period, can_scatter_period, - can_transmission_period, can_direct_period)): - if not self._view.is_multi_period_view(): - self._view.set_multi_period_view_mode(True) - - # 2. Create entry that can be understood by table - if self._view.is_multi_period_view(): - row_entry = "SampleScatter:{},ssp:{},SampleTrans:{},stp:{},SampleDirect:{},sdp:{}," \ - "CanScatter:{},csp:{},CanTrans:{},ctp:{}," \ - "CanDirect:{},cdp:{},OutputName:{},User File:{}," \ - "Sample Thickness:{:.2f}".format(sample_scatter, - get_string_period(sample_scatter_period), - sample_transmission, - get_string_period(sample_transmission_period), - sample_direct, - get_string_period(sample_direct_period), - can_scatter, - get_string_period(can_scatter_period), - can_transmission, - get_string_period(can_transmission_period), - can_direct, - get_string_period(can_direct_period), - output_name, user_file, sample_thickness) - else: - row_entry = "SampleScatter:{},SampleTrans:{},SampleDirect:{}," \ - "CanScatter:{},CanTrans:{}," \ - "CanDirect:{},OutputName:{},User File:{},Sample Thickness:{:.2f}".format(sample_scatter, - sample_transmission, - sample_direct, - can_scatter, - can_transmission, - can_direct, - output_name, user_file,sample_thickness) - - self._view.add_row(row_entry) - # ------------------------------------------------------------------------------------------------------------------ # Settings # ------------------------------------------------------------------------------------------------------------------ @@ -1000,34 +958,3 @@ class RunTabPresenter(object): self._view.set_instrument_settings(instrument) self._beam_centre_presenter.on_update_instrument(instrument) self._workspace_diagnostic_presenter.set_instrument_settings(instrument) - - # ------------------------------------------------------------------------------------------------------------------ - # Setting workaround for state in DataProcessorWidget - # ------------------------------------------------------------------------------------------------------------------ - def _remove_dummy_workspaces_and_row_index(self): - number_of_rows = self._view.get_number_of_rows() - for row in range(number_of_rows): - self._remove_from_hidden_options(row, "InputWorkspace") - self._remove_from_hidden_options(row, "RowIndex") - - def _set_indices(self): - number_of_rows = self._view.get_number_of_rows() - for row in range(number_of_rows): - to_set = Property.EMPTY_INT if self.is_empty_row(row) else row - self._add_to_hidden_options(row, "RowIndex", to_set) - - def _set_dummy_workspace(self): - number_of_rows = self._view.get_number_of_rows() - for row in range(number_of_rows): - self._add_to_hidden_options(row, "InputWorkspace", SANS_DUMMY_INPUT_ALGORITHM_PROPERTY_NAME) - - @staticmethod - def _create_dummy_input_workspace(): - if not AnalysisDataService.doesExist(SANS_DUMMY_INPUT_ALGORITHM_PROPERTY_NAME): - workspace = WorkspaceFactory.create("Workspace2D", 1, 1, 1) - AnalysisDataService.addOrReplace(SANS_DUMMY_INPUT_ALGORITHM_PROPERTY_NAME, workspace) - - @staticmethod - def _delete_dummy_input_workspace(): - if AnalysisDataService.doesExist(SANS_DUMMY_INPUT_ALGORITHM_PROPERTY_NAME): - AnalysisDataService.remove(SANS_DUMMY_INPUT_ALGORITHM_PROPERTY_NAME) diff --git a/scripts/SANS/sans/state/state.py b/scripts/SANS/sans/state/state.py index 3888fbb09e9718c80da380669b641a147be60576..261c847f7e14d1c6915c548dc4d4d8844e11d897 100644 --- a/scripts/SANS/sans/state/state.py +++ b/scripts/SANS/sans/state/state.py @@ -22,7 +22,7 @@ from sans.state.scale import StateScale from sans.state.convert_to_q import StateConvertToQ from sans.state.automatic_setters import (automatic_setters) -# Note that the compatibiliy state is not part of the new reduction chain, but allows us to accurately compare +# Note that the compatibility state is not part of the new reduction chain, but allows us to accurately compare # results obtained via the old and new reduction chain from sans.state.compatibility import (StateCompatibility, get_compatibility_builder) diff --git a/scripts/SANS/sans/state/state_base.py b/scripts/SANS/sans/state/state_base.py index 0153812d9f25ca08e6297e732eafe1bbb18b6366..167ca43e2e77d9b85092ac07feba8ea42f3b8dcd 100644 --- a/scripts/SANS/sans/state/state_base.py +++ b/scripts/SANS/sans/state/state_base.py @@ -508,8 +508,8 @@ def set_state_from_property_manager(instance, property_manager): """ Set the State object from the information stored on a property manager object. This is the deserialization step. - :param instance: the instance which is to be set with a values of the propery manager - :param property_manager: the property manager withe the stored setting + :param instance: the instance which is to be set with a values of the property manager + :param property_manager: the property manager with the stored setting """ def _set_element(inst, k_element, v_element): if k_element != STATE_NAME and k_element != STATE_MODULE: diff --git a/scripts/SANS/sans/test_helper/mock_objects.py b/scripts/SANS/sans/test_helper/mock_objects.py index c5a7d77091f08649f9f3940456921b5b53f047a6..6c0ae523c1b6cc57167cc2f586864641b6465e14 100644 --- a/scripts/SANS/sans/test_helper/mock_objects.py +++ b/scripts/SANS/sans/test_helper/mock_objects.py @@ -43,7 +43,7 @@ def get_cell_mock(row, column, convert_to=None, user_file_path = ""): _ = convert_to # noqa if row == 0: # For the first row we return the - # all of hte sample data + # all of the sample data if column == 0: return "SANS2D00022024" elif column == 2: diff --git a/scripts/SANS/sans/test_helper/user_file_test_helper.py b/scripts/SANS/sans/test_helper/user_file_test_helper.py index cbc4433c43b5ba2386572c83e3e8a763d5b61552..ab60cae454e398ee5508b895fce298fcc3e38268 100644 --- a/scripts/SANS/sans/test_helper/user_file_test_helper.py +++ b/scripts/SANS/sans/test_helper/user_file_test_helper.py @@ -89,6 +89,5 @@ def create_user_file(user_file_content): def make_sample_user_file(gravity ='ON'): return base_user_file.format(gravity) - sample_user_file = make_sample_user_file(gravity ='ON') sample_user_file_gravity_OFF = make_sample_user_file(gravity ='OFF') diff --git a/scripts/SANS/sans/user_file/user_file_parser.py b/scripts/SANS/sans/user_file/user_file_parser.py index 3d3ea0523185cb988ebc770ab72ac13f6ac31bed..35d11ca3ed4ee66ce1451654223f75c46dd27d23 100644 --- a/scripts/SANS/sans/user_file/user_file_parser.py +++ b/scripts/SANS/sans/user_file/user_file_parser.py @@ -143,7 +143,7 @@ class UserFileComponentParser(object): class BackParser(UserFileComponentParser): """ The BackParser handles the following structure - Command | Qualifer | Parameter + Command | Qualifier | Parameter BACK / MON/TIMES t1 t2 BACK / M m/TIMES t1 t2 BACK / M m t1 t2 @@ -784,7 +784,7 @@ class MaskParser(UserFileComponentParser): MASK Ssp1[>Ssp2] - MASK[/REAR/FRONT/HAB]/TIME t1 t2 or MASK[/REAR/FRONT/HAB]/T t1 t2 - if no detector is specfied, then mask + MASK[/REAR/FRONT/HAB]/TIME t1 t2 or MASK[/REAR/FRONT/HAB]/T t1 t2 - if no detector is specified, then mask is applied to both detectors. MASK/LINE width angle [x y] @@ -1125,7 +1125,7 @@ class SetParser(UserFileComponentParser): An undocumented feature is: SET CENTRE[/MAIN|/HAB] x y [d1 d2] - where d1 and d2 are pixel sizes. This is not used in the old parser, but user files have it nontheless. + where d1 and d2 are pixel sizes. This is not used in the old parser, but user files have it nonetheless. SET SCALES s a b c d """ @@ -1691,7 +1691,7 @@ class FitParser(UserFileComponentParser): fit_string = re.sub(self._lin_or_log_or_poly_to_remove, "", fit_string) # We should now have something like [poly_order] [w1 w2] - # There are four posibilties + # There are four possibilities # 1. There is no number # 2. There is one number -> it has to be the poly_order # 3. There are two numbers -> it has to be the w1 and w2 diff --git a/scripts/SCD_Reduction/ICCFitTools.py b/scripts/SCD_Reduction/ICCFitTools.py index 15c722b3a1a104af3972f47f5734db6cb8fecb75..4b960fd67e74bb76643341b4862375ce95d73774 100644 --- a/scripts/SCD_Reduction/ICCFitTools.py +++ b/scripts/SCD_Reduction/ICCFitTools.py @@ -456,7 +456,7 @@ def getHKLMask(UB, frac=0.5, dQPixel=0.005, dQ=None): def padeWrapper(x, a, b, c, d, f, g, h, i, j, k): """ - padeWrapper is a wrapper for the pade(c,x) function for compatability with curve_fit. + padeWrapper is a wrapper for the pade(c,x) function for compatibility with curve_fit. Inputs are x (numpy array) and the 8 coefficients for the approximant. Output are the values of the pade approximant at each value of x. """ @@ -575,7 +575,7 @@ def getTOFWS(box, flightPath, scatteringHalfAngle, tofPeak, peak, qMask, zBG=-1. workspaceNumber - None of not doing multiple fits. Otherwise it will append an integer in the mtd[] object so not to overwrite. Probably not needed in most cases. neigh_length_m - integer; how large of a convolution box to use. - pp_lambda - the most likely backgorund level; set to None if want to calculate + pp_lambda - the most likely background level; set to None if want to calculate calc_pp_lambda - boolean; True if you want to calculate pp_lambda using TOF profile fitting. If you do not want to, you can feed the value in as pp_lambda (calculated elsewhere). minppl_frac, maxppl_frac; range around predicted pp_lambda to check. @@ -696,7 +696,7 @@ def oneOverXSquared(x, A, bg): def getInitialGuess(tofWS, paramNames, energy, flightPath, padeCoefficients): """ - Returns intial parameters for fitting based on a few quickly derived TOF + Returns initial parameters for fitting based on a few quickly derived TOF profile parameters. tofWS is a worskapce containng the TOF profile, paramNames is the list of parameter names energy is the energy of the peak (units: eV) @@ -733,7 +733,7 @@ def getSample(run, DetCalFile, workDir, fileName, qLow=-25, qHigh=25, q_frame=' workDir - not used. TODO - remove this. fileName - str; the events file to load. Should probably be an absolute path. qLow, qHigh - the returned MDWorkspace will range from qLow to qHigh in all 3 directions. - q_frame - either 'sample' or 'lab'. Wether to return in the lab or sample coordinate system. + q_frame - either 'sample' or 'lab'. Whether to return in the lab or sample coordinate system. Returns: MDdata - a handle for the mtd['MDdata'] object, which contains the loaded run in reciprocal space. """ @@ -855,7 +855,7 @@ def doICCFit(tofWS, energy, flightPath, padeCoefficients, constraintScheme=None, fitResults - the output from Mantid's Fit() routine fICC - an IkedaCarpenterConvoluted function with parameters set to the fit values. """ - # Set up our inital guess + # Set up our initial guess fICC = ICC.IkedaCarpenterConvoluted() fICC.init() paramNames = [fICC.getParamName(x) for x in range(fICC.numParams())] diff --git a/scripts/SCD_Reduction/ReduceSCD.config b/scripts/SCD_Reduction/ReduceSCD.config index 324b3883589caf24d49f3ea2b12b0f784a38cdd6..f0326864456ee18a22f89b325fc82cd9275956aa 100644 --- a/scripts/SCD_Reduction/ReduceSCD.config +++ b/scripts/SCD_Reduction/ReduceSCD.config @@ -1,22 +1,22 @@ # Configuration file for ReduceSCD_OneRun.py and ReduceSCD_Parallel.py. # # Each line can either start with a comment, indicated by a '#' mark or start -# with a parameter name and value, optionally followed by a comment. ALL -# parameters used by the script must be specified. If a required parameter -# is not specified, the script will terminate with a message indicating which +# with a parameter name and value, optionally followed by a comment. ALL +# parameters used by the script must be specified. If a required parameter +# is not specified, the script will terminate with a message indicating which # parameter was missing. # # # _v1: December 3rd 2013. Mads Joergensen -# This version now includes the posibility to use the 1D cylindrical integration method -# and the posibility to load a UB matrix which will be used for integration of the individual +# This version now includes the possibility to use the 1D cylindrical integration method +# and the possibility to load a UB matrix which will be used for integration of the individual # runs and to index the combined file (Code from Xiapoing). # # # _v2: December 3rd 2013. Mads Joergensen -# Adds the posibility to optimize the loaded UB for each run for a better peak prediction +# Adds the possibility to optimize the loaded UB for each run for a better peak prediction # It is also possible to find the common UB by using lattice parameters of the first # run or the loaded matirix instead of the default FFT method # @@ -41,7 +41,7 @@ calibration_file_2 None # must be copied into one directory and that directory must be specified as # the data_directory # -data_directory None +data_directory None output_directory /SNS/TOPAZ/IPTS-9890/shared/SPAnH # Change to true for data with lots of peaks. Use False for ISAW ASCII output output_nexus False @@ -68,7 +68,7 @@ min_monitor_tof 1000 max_monitor_tof 12500 # -# Read the UB matrix from file. This option will be applied to each run and used for +# Read the UB matrix from file. This option will be applied to each run and used for # combined file. This option is especially helpful for 2nd frame TOPAZ data. read_UB False UB_filename /SNS/TOPAZ/IPTS-9890/shared/test/test.mat @@ -77,22 +77,22 @@ UB_filename /SNS/TOPAZ/IPTS-9890/shared/test/test.mat optimize_UB True # Use FundUBUsingLatticeParameters to find common UB (instead for FFT) -# This option will find the UB for the fist run and the cell parametes in the +# This option will find the UB for the fist run and the cell parameters in the # algorithm, unless a UB has been specified: in this case the values in the specified # file will be used. UseFirstLattice True # -# Specifiy a conventional cell type and centering. If these are None, only +# Specify a conventional cell type and centering. If these are None, only # one .mat and .integrate file will be written for this run, and they will -# be in terms of the Niggli reduced cell. If these specifiy a valid +# be in terms of the Niggli reduced cell. If these specify a valid # cell type and centering, an additional .mat and .integrate file will be # written for the specified cell_type and centering. NOTE: If run in # parallel, the driving script will only read the Niggli version of the # .integrate file, and will combine, re-index and convert to a conventional # cell, so these can usually be left as None. # -# Cell transformation is not applied to cylindrical profiles, +# Cell transformation is not applied to cylindrical profiles, # i.e. use None if cylindrical integration is used! # cell_type None @@ -102,29 +102,29 @@ allow_perm True # # Number of peaks to find, per run, both for getting the UB matrix, # AND to determine how many peaks are integrated, if peak positions are -# NOT predicted. NOTE: This number must be choosen carefully. If too +# NOT predicted. NOTE: This number must be chosen carefully. If too # many peaks are requested, find peaks will take a very long time and # the returned peaks will probably not even index, since most of them # will be "noise" peaks. If too few are requested, then there will be -# few peaks to be integrated, and the UB matrix may not be as accurate +# few peaks to be integrated, and the UB matrix may not be as accurate # as it should be for predicting peaks to integrate. # num_peaks_to_find 400 # -# min_d, max_d and tolerance control indexing peaks. max_d is also +# min_d, max_d and tolerance control indexing peaks. max_d is also # used to specify a threshold for the separation between peaks # returned by FindPeaksMD, so it should be specified somewhat larger -# than the largest cell edge in the Niggli reduced cell for the +# than the largest cell edge in the Niggli reduced cell for the # sample. # min_d 8 -max_d 20 +max_d 20 tolerance 0.12 # -# If predicted peak positions are to be integrated, -# the integrate_predicted_peaks flag should be set to True and the range +# If predicted peak positions are to be integrated, +# the integrate_predicted_peaks flag should be set to True and the range # of wavelengths and d-spacings must be specified # integrate_predicted_peaks True @@ -152,24 +152,24 @@ bkg_inner_radius 0.075 # for sphere or ellipse integration bkg_outer_radius 0.095 # for sphere or ellipse integration integrate_if_edge_peak True # for sphere integration only -# +# # Specify ellispe integration control parameters # -ellipse_region_radius 0.16 -ellipse_size_specified True +ellipse_region_radius 0.16 +ellipse_size_specified True # # Specify fit peaks integration control parameters. Check that these are -# correct, if use_fit_peaks_integration = True. Otherwise the values +# correct, if use_fit_peaks_integration = True. Otherwise the values # aren't used. # rebin_step -0.004 preserve_events True -use_ikeda_carpenter False +use_ikeda_carpenter False n_bad_edge_pixels 0 -# +# # Specify cylindrical integration control parameters # cylinder_radius 0.05 @@ -180,7 +180,7 @@ cylinder_length 0.30 # multiple runs in parallel. # ========================================================================== # -exp_name SPAnH +exp_name SPAnH reduce_one_run_script ReduceSCD_OneRun.py # @@ -194,18 +194,17 @@ run_nums 8512:8523 run_nums 8525:8551 # -# Specify the slurm partion, or None to use local processes. The parameter -# max_processes controls the maximum number of processes that will be run +# Specify the slurm partition, or None to use local processes. The parameter +# max_processes controls the maximum number of processes that will be run # simultaneously locally, or that will be simultaneously submitted to slurm. -# The value of max_processes should be choosen carefully with the size of the -# system in mind, to avoid overloading the system. Since the lower level +# The value of max_processes should be chosen carefully with the size of the +# system in mind, to avoid overloading the system. Since the lower level # calculations are all multi-threaded, this should be substantially lower than # the total number of cores available. # All runs will be processed eventually. If there are more runs than then # max_processes, as some processes finish, new ones will be started, until # all runs have been processed. # -#slurm_queue_name topazq -slurm_queue_name None -max_processes 13 - +#slurm_queue_name topazq +slurm_queue_name None +max_processes 13 diff --git a/scripts/SCD_Reduction/ReduceSCD_OneRun.py b/scripts/SCD_Reduction/ReduceSCD_OneRun.py index ca3a3f4d0ede8579d47954ad5bf8d1650997376f..f24b249606a69848393110806f353db0485b216b 100644 --- a/scripts/SCD_Reduction/ReduceSCD_OneRun.py +++ b/scripts/SCD_Reduction/ReduceSCD_OneRun.py @@ -21,12 +21,12 @@ # # _v1: December 3rd 2013. Mads Joergensen -# This version now includes the posibility to use the 1D cylindrical integration method -# and the posibility to load a UB matrix which will be used for integration of the individual +# This version now includes the possibility to use the 1D cylindrical integration method +# and the possibility to load a UB matrix which will be used for integration of the individual # runs and to index the combined file (Code from Xiapoing). # # _v2: December 3rd 2013. Mads Joergensen -# Adds the posibility to optimize the loaded UB for each run for a better peak prediction +# Adds the possibility to optimize the loaded UB for each run for a better peak prediction # It is also possible to find the common UB by using lattice parameters of the first # run or the loaded matirix instead of the default FFT method # @@ -342,7 +342,7 @@ else: SaveIsawPeaks(InputWorkspace=peaks_ws, AppendFile=False, Filename=run_niggli_integrate_file ) -# Print warning if user is trying to integrate using the cylindrical method and transorm the cell +# Print warning if user is trying to integrate using the cylindrical method and transform the cell if use_cylindrical_integration: if (cell_type is not None) or (centering is not None): print("WARNING: Cylindrical profiles are NOT transformed!!!") diff --git a/scripts/SCD_Reduction/ReduceSCD_Parallel.py b/scripts/SCD_Reduction/ReduceSCD_Parallel.py index 2b32abb6c91f2889a7bcf05a099e20a2a5491460..b0c5b99794c51bd5b6bea550215576fbf6fa1300 100644 --- a/scripts/SCD_Reduction/ReduceSCD_Parallel.py +++ b/scripts/SCD_Reduction/ReduceSCD_Parallel.py @@ -22,14 +22,14 @@ # # _v1: December 3rd 2013. Mads Joergensen -# This version now includes the posibility to use the 1D cylindrical integration method -# and the posibility to load a UB matrix which will be used for integration of the individual +# This version now includes the possibility to use the 1D cylindrical integration method +# and the possibility to load a UB matrix which will be used for integration of the individual # runs and to index the combined file (Code from Xiapoing). # # # _v2: December 3rd 2013. Mads Joergensen -# Adds the posibility to optimize the loaded UB for each run for a better peak prediction +# Adds the possibility to optimize the loaded UB for each run for a better peak prediction # It is also possible to find the common UB by using lattice parameters of the first # run or the loaded matirix instead of the default FFT method # @@ -225,7 +225,7 @@ if not use_cylindrical_integration: # # Load the combined file and re-index all of the peaks together. -# Save them back to the combined Niggli file (Or selcted UB file if in use...) +# Save them back to the combined Niggli file (Or selected UB file if in use...) # if output_nexus: peaks_ws = Load( Filename=niggli_integrate_file ) diff --git a/scripts/SCD_Reduction/TOPAZ.config b/scripts/SCD_Reduction/TOPAZ.config index 06bf251ccecdd5410e614b5f2581b11dda2fbbef..52a17763b148f4f58151648d6a6549022ea58379 100644 --- a/scripts/SCD_Reduction/TOPAZ.config +++ b/scripts/SCD_Reduction/TOPAZ.config @@ -15,7 +15,7 @@ calibration_file_2 None # must be copied into one directory and that directory must be specified as # the data_directory # -data_directory None +data_directory None output_directory None # @@ -33,8 +33,8 @@ min_monitor_tof 1000 max_monitor_tof 12500 # -# Read the UB matrix from file. This option will be applied to each run and -# used for combined file. This option is especially helpful for 2nd frame +# Read the UB matrix from file. This option will be applied to each run and +# used for combined file. This option is especially helpful for 2nd frame # TOPAZ data. read_UB False UB_filename None @@ -43,22 +43,22 @@ UB_filename None optimize_UB True # Use FundUBUsingLatticeParameters to find common UB (instead for FFT) -# This option will find the UB for the fist run and the cell parametes in the -# algorithm, unless a UB has been specified: in this case the values in the +# This option will find the UB for the fist run and the cell parameters in the +# algorithm, unless a UB has been specified: in this case the values in the # specified file will be used. UseFirstLattice True # -# Specifiy a conventional cell type and centering. If these are None, only +# Specify a conventional cell type and centering. If these are None, only # one .mat and .integrate file will be written for this run, and they will -# be in terms of the Niggli reduced cell. If these specifiy a valid +# be in terms of the Niggli reduced cell. If these specify a valid # cell type and centering, an additional .mat and .integrate file will be # written for the specified cell_type and centering. NOTE: If run in # parallel, the driving script will only read the Niggli version of the # .integrate file, and will combine, re-index and convert to a conventional # cell, so these can usually be left as None. # -# Cell trnasformation is not applied to cylindrical profiles, +# Cell trnasformation is not applied to cylindrical profiles, # i.e. use None if cylindrical integration is used! # cell_type None @@ -67,29 +67,29 @@ centering None # # Number of peaks to find, per run, both for getting the UB matrix, # AND to determine how many peaks are integrated, if peak positions are -# NOT predicted. NOTE: This number must be choosen carefully. If too +# NOT predicted. NOTE: This number must be chosen carefully. If too # many peaks are requested, find peaks will take a very long time and # the returned peaks will probably not even index, since most of them # will be "noise" peaks. If too few are requested, then there will be -# few peaks to be integrated, and the UB matrix may not be as accurate +# few peaks to be integrated, and the UB matrix may not be as accurate # as it should be for predicting peaks to integrate. # num_peaks_to_find 500 # -# min_d, max_d and tolerance control indexing peaks. max_d is also +# min_d, max_d and tolerance control indexing peaks. max_d is also # used to specify a threshold for the separation between peaks # returned by FindPeaksMD, so it should be specified somewhat larger -# than the largest cell edge in the Niggli reduced cell for the +# than the largest cell edge in the Niggli reduced cell for the # sample. # min_d 4 -max_d 8 +max_d 8 tolerance 0.12 # -# If predicted peak positions are to be integrated, -# the integrate_predicted_peaks flag should be set to True and the range +# If predicted peak positions are to be integrated, +# the integrate_predicted_peaks flag should be set to True and the range # of wavelengths and d-spacings must be specified # integrate_predicted_peaks False @@ -118,23 +118,23 @@ bkg_inner_radius 0.075 # for sphere or ellipse integration bkg_outer_radius 0.095 # for sphere or ellipse integration integrate_if_edge_peak True # for sphere integration only -# +# # Specify ellispe integration control parameters # -ellipse_region_radius 0.16 -ellipse_size_specified False +ellipse_region_radius 0.16 +ellipse_size_specified False # # Specify fit peaks integration control parameters. Check that these are -# correct, if use_fit_peaks_integration = True. Otherwise the values +# correct, if use_fit_peaks_integration = True. Otherwise the values # aren't used. # rebin_step -0.004 preserve_events True -use_ikeda_carpenter False +use_ikeda_carpenter False n_bad_edge_pixels 0 -# +# # Specify cylindrical integration control parameters # cylinder_radius 0.05 @@ -148,7 +148,7 @@ cylinder_profile_fit Gaussian # multiple runs in parallel. # ========================================================================== # -exp_name None +exp_name None reduce_one_run_script ReduceSCD_OneRun.py # @@ -161,17 +161,17 @@ reduce_one_run_script ReduceSCD_OneRun.py #run_nums 8525:8551 # -# Specify the slurm partion, or None to use local processes. The parameter -# max_processes controls the maximum number of processes that will be run +# Specify the slurm partition, or None to use local processes. The parameter +# max_processes controls the maximum number of processes that will be run # simultaneously locally, or that will be simultaneously submitted to slurm. -# The value of max_processes should be choosen carefully with the size of the -# system in mind, to avoid overloading the system. Since the lower level +# The value of max_processes should be chosen carefully with the size of the +# system in mind, to avoid overloading the system. Since the lower level # calculations are all multi-threaded, this should be substantially lower than # the total number of cores available. # All runs will be processed eventually. If there are more runs than then # max_processes, as some processes finish, new ones will be started, until # all runs have been processed. # -#slurm_queue_name topazq -#slurm_queue_name None -#max_processes 13 +#slurm_queue_name topazq +#slurm_queue_name None +#max_processes 13 diff --git a/scripts/reduction/instruments/sans/sans_reduction_steps.py b/scripts/reduction/instruments/sans/sans_reduction_steps.py index f3d77e985982fc6cda7b961ef943d66e17de04f4..ee63e251d1247a4a019ad331ba9a9a6316a664cf 100644 --- a/scripts/reduction/instruments/sans/sans_reduction_steps.py +++ b/scripts/reduction/instruments/sans/sans_reduction_steps.py @@ -95,7 +95,7 @@ class BaseTransmission(ReductionStep): def set_dark_current(self, dark_current=None): """ - Set the dark current data file to be subtracted from each tranmission data file + Set the dark current data file to be subtracted from each transmission data file @param dark_current: path to dark current data file """ self._dark_current_data = dark_current @@ -173,7 +173,7 @@ class Mask(ReductionStep): def __init__(self): """ - Initalize masking + Initialize masking """ super(Mask, self).__init__() self._nx_low = 0 @@ -217,7 +217,7 @@ class Mask(ReductionStep): def _infinite_plane(self, id, plane_pt, normal_pt, complement=False): """ - Generates xml code for an infinte plane + Generates xml code for an infinite plane @param id: a string to refer to the shape by @param plane_pt: a point in the plane @param normal_pt: the direction of a normal to the plane @@ -232,7 +232,7 @@ class Mask(ReductionStep): def _infinite_cylinder(self, centre, radius, axis, id='shape'): """ Generates xml code for an infintely long cylinder - @param centre: a tupple for a point on the axis + @param centre: a tuple for a point on the axis @param radius: cylinder radius @param axis: cylinder orientation @param id: a string to refer to the shape by @@ -246,7 +246,7 @@ class Mask(ReductionStep): def _finite_cylinder(self, centre, radius, height, axis, id='shape'): """ Generates xml code for an infintely long cylinder - @param centre: a tupple for a point on the axis + @param centre: a tuple for a point on the axis @param radius: cylinder radius @param height: cylinder height @param axis: cylinder orientation @@ -389,7 +389,7 @@ class CalculateNorm(object): distribution/non-distribution flag set correctly as they maybe converted ISIS only - ORNL doesnt't use that approach + ORNL doesn't use that approach """ TMP_WORKSPACE_NAME = '__CalculateNorm_loaded_temp' diff --git a/scripts/reduction_workflow/instruments/sans/hfir_command_interface.py b/scripts/reduction_workflow/instruments/sans/hfir_command_interface.py index f105ac1a89e55521c4301b7fb185eec66bd5055b..4f4061e7da97ddccda8d04b73c1bf0002ecc5ca9 100644 --- a/scripts/reduction_workflow/instruments/sans/hfir_command_interface.py +++ b/scripts/reduction_workflow/instruments/sans/hfir_command_interface.py @@ -514,7 +514,7 @@ def NoIQxQy(): def Mask(nx_low=0, nx_high=0, ny_low=0, ny_high=0, component_name=""): ''' - Maks edges of a component_name + Mask edges of a component_name By default is the main detector for both GPSANS and BioSans ''' ReductionSingleton().reduction_properties["MaskedEdges"] = [ diff --git a/scripts/test/DirectPropertyManater_OldInterfaceXest.py b/scripts/test/DirectPropertyManater_OldInterfaceXest.py index e5e05096db845b4b2fceb54267e5396de0f9e0db..ab99474b541bd37e642d044344c790c148b7985a 100644 --- a/scripts/test/DirectPropertyManater_OldInterfaceXest.py +++ b/scripts/test/DirectPropertyManater_OldInterfaceXest.py @@ -208,7 +208,7 @@ class DirectEnergyConversionTest(unittest.TestCase): def f_nxs(workspace, filename): tReducer.test_name += (workspace.name()+'_file_nxs_' + filename) - # redefine test save methors to produce test ouptut + # redefine test save methors to produce test output tReducer._DirectEnergyConversion__save_formats['.spe']=lambda workspace,filename: f_spe(workspace,filename) tReducer._DirectEnergyConversion__save_formats['.nxspe']=lambda workspace,filename : f_nxspe(workspace,filename) tReducer._DirectEnergyConversion__save_formats['.nxs']=lambda workspace,filename : f_nxs(workspace,filename) diff --git a/scripts/test/PyChopTest.py b/scripts/test/PyChopTest.py index 6b3bebc234f935f73a4f6586905af406d1c5f37c..279d6ee18b014222dfb89b21419b75bdaabd34b0 100644 --- a/scripts/test/PyChopTest.py +++ b/scripts/test/PyChopTest.py @@ -44,7 +44,7 @@ class PyChop2Tests(unittest.TestCase): flux = [] for inc, variant in enumerate(variants): chopobj = PyChop2('LET', variant) - # Checks that it instanciates the correct variant + # Checks that it instantiates the correct variant self.assertTrue(variant in chopobj.getChopper()) # Code should give an error if the chopper settings and Ei have # not been set. diff --git a/scripts/test/SANS/common/file_information_test.py b/scripts/test/SANS/common/file_information_test.py index 390c2c2cd95cffcd0904b0cbf1c2af3d7a62893e..fe692e2ff62e4bef7753c02f8a71a4d411b9f1aa 100644 --- a/scripts/test/SANS/common/file_information_test.py +++ b/scripts/test/SANS/common/file_information_test.py @@ -118,6 +118,19 @@ class SANSFileInformationTest(unittest.TestCase): self.assertTrue(file_information.get_thickness() == 1.0) self.assertTrue(file_information.get_shape() is SampleShape.FlatPlate) + def test_that_can_find_data_with_numbers_but_no_instrument(self): + # Arrange + # The file is a single period, histogram-based and added + + file_name = "74044-add" + factory = SANSFileInformationFactory() + + # Act + file_information = factory.create_sans_file_information(file_name) + + # Assert + self.assertTrue(file_information) + class SANSFileInformationGeneralFunctionsTest(unittest.TestCase): def test_that_finds_idf_and_ipf_paths(self): diff --git a/scripts/test/SANS/gui_logic/CMakeLists.txt b/scripts/test/SANS/gui_logic/CMakeLists.txt index f94b2a3b555d3131d2122b4f2a63196fca816aeb..729a9b8683afe9d9dc4c03d41d72c91bcc79f4ff 100644 --- a/scripts/test/SANS/gui_logic/CMakeLists.txt +++ b/scripts/test/SANS/gui_logic/CMakeLists.txt @@ -22,6 +22,7 @@ set ( TEST_PY_FILES diagnostics_page_presenter_test.py diagnostics_page_model_test.py create_state_test.py + batch_process_runner_test.py ) check_tests_valid ( ${CMAKE_CURRENT_SOURCE_DIR} ${TEST_PY_FILES} ) diff --git a/scripts/test/SANS/gui_logic/add_runs_presenter_test.py b/scripts/test/SANS/gui_logic/add_runs_presenter_test.py index 0df24a1d01f2fd6c67d8ad47686a30e61773253b..9ecd92d1bff7b981794b09ef1386a4d774ca5631 100644 --- a/scripts/test/SANS/gui_logic/add_runs_presenter_test.py +++ b/scripts/test/SANS/gui_logic/add_runs_presenter_test.py @@ -1,6 +1,7 @@ import unittest import sys from ui.sans_isis.add_runs_page import AddRunsPage +from ui.sans_isis.sans_data_processor_gui import SANSDataProcessorGui from sans.gui_logic.presenter.add_runs_presenter import AddRunsPagePresenter from sans.gui_logic.models.run_summation import RunSummation from sans.gui_logic.models.run_file import SummableRunFile @@ -10,6 +11,7 @@ from sans.gui_logic.presenter.summation_settings_presenter import SummationSetti from sans.gui_logic.presenter.run_selector_presenter import RunSelectorPresenter from fake_signal import FakeSignal from assert_called import assert_called +from sans.common.enums import SANSInstrument if sys.version_info.major == 2: import mock @@ -24,6 +26,11 @@ class AddRunsPagePresenterTestCase(unittest.TestCase): mock_view.outFileChanged = FakeSignal() return mock_view + def _make_mock_parent_view(self): + mock_parent_view = mock.create_autospec(SANSDataProcessorGui, spec_set=True) + mock_parent_view.instrument.to_string.return_value = 'LOQ' + return mock_parent_view + def setUpMockChildPresenters(self): self._summation_settings_presenter = \ self._make_mock_summation_settings_presenter() @@ -83,6 +90,7 @@ class InitializationTest(AddRunsPagePresenterTestCase): self.setUpMockChildPresentersWithDefaultSummationSettings() self.run_summation = self._make_mock_run_summation() self.view = self._make_mock_view() + self._parent_view = self._make_mock_parent_view() def _make_presenter_with_child_presenters(self, run_selection, @@ -143,6 +151,7 @@ class SummationSettingsViewEnablednessTest(SelectionMockingTestCase): def setUp(self): self.setUpMockChildPresenters() self._view = self._make_mock_view() + self._parent_view = self._make_mock_parent_view() self._event_run = self._make_fake_event_run() self._histogram_run = self._make_fake_histogram_run() self._make_presenter() @@ -167,7 +176,7 @@ class SummationSettingsViewEnablednessTest(SelectionMockingTestCase): self._capture_on_change_callback(self.run_selector_presenter), self._just_use_summation_settings_presenter(), self._view, - None) + self._parent_view) def test_disables_summation_settings_when_no_event_data(self): runs = self._make_mock_run_selection([self._histogram_run, @@ -192,6 +201,7 @@ class SummationConfigurationTest(SelectionMockingTestCase): def setUp(self): self.setUpMockChildPresentersWithDefaultSummationSettings() self.view = self._make_mock_view() + self.parent_view = self._make_mock_parent_view() def _make_presenter(self, run_summation, @@ -201,7 +211,7 @@ class SummationConfigurationTest(SelectionMockingTestCase): run_selection, summation_settings, self.view, - None) + self.parent_view) def _just_use_summation_settings_presenter(self): return self._just_use(self._summation_settings_presenter) @@ -220,7 +230,7 @@ class SummationConfigurationTest(SelectionMockingTestCase): self.view.sum.emit() run_summation.assert_called_with(fake_run_selection, self._summation_settings, - '3-add') + 'LOQ3-add') def test_shows_error_when_empty_default_directory(self): summation_settings_model = self._summation_settings_with_save_directory('') @@ -238,6 +248,7 @@ class BaseFileNameTest(SelectionMockingTestCase): def setUp(self): self.setUpMockChildPresentersWithDefaultSummationSettings() self.view = self._make_mock_view() + self.parent_view = self._make_mock_parent_view() def _make_presenter(self, run_summation): @@ -246,7 +257,7 @@ class BaseFileNameTest(SelectionMockingTestCase): self._capture_on_change_callback(self.run_selector_presenter), self._just_use_summation_settings_presenter(), self.view, - None) + self.parent_view) def _just_use_summation_settings_presenter(self): return self._just_use(self._summation_settings_presenter) @@ -269,7 +280,7 @@ class BaseFileNameTest(SelectionMockingTestCase): def test_generates_correct_base_name(self): generated_name = self._retrieve_generated_name_for(['1', '2', '3']) - self.assertEqual('3-add', generated_name) + self.assertEqual('LOQ3-add', generated_name) def test_regenerates_correct_base_name_after_highest_removed(self): run_summation = mock.Mock() @@ -277,7 +288,7 @@ class BaseFileNameTest(SelectionMockingTestCase): self._update_selection_model(self._make_mock_run_selection_from_paths(['4', '5', '6'])) self._update_selection_model(self._make_mock_run_selection_from_paths(['4', '5'])) self.view.sum.emit() - self.assertEqual('5-add', self._base_file_name_arg(run_summation)) + self.assertEqual('LOQ5-add', self._base_file_name_arg(run_summation)) def test_correct_base_name_after_set_by_user(self): user_out_file_name = 'Output' @@ -309,9 +320,9 @@ class BaseFileNameTest(SelectionMockingTestCase): run_summation = mock.Mock() presenter = self._make_presenter(run_summation) self._update_selection_model(self._make_mock_run_selection_from_paths(['4', '6', '5'])) - self.view.set_out_file_name.assert_called_with('6-add') + self.view.set_out_file_name.assert_called_with('LOQ6-add') self._update_selection_model(self._make_mock_run_selection_from_paths(['5', '4'])) - self.view.set_out_file_name.assert_called_with('5-add') + self.view.set_out_file_name.assert_called_with('LOQ5-add') class SumButtonTest(SelectionMockingTestCase): @@ -319,6 +330,7 @@ class SumButtonTest(SelectionMockingTestCase): self.setUpMockChildPresentersWithDefaultSummationSettings() self.run_summation = self._make_mock_run_summation() self.view = self._make_mock_view() + self.parent_view = self._make_mock_parent_view() self.presenter = self._make_presenter() def _make_presenter(self): @@ -327,7 +339,7 @@ class SumButtonTest(SelectionMockingTestCase): self._capture_on_change_callback(self.run_selector_presenter), self._just_use_summation_settings_presenter(), self.view, - None) + self.parent_view) def test_enables_sum_button_when_row_added(self): fake_run_selection = self._make_mock_run_selection_from_paths(['5']) diff --git a/scripts/test/SANS/gui_logic/batch_process_runner_test.py b/scripts/test/SANS/gui_logic/batch_process_runner_test.py new file mode 100644 index 0000000000000000000000000000000000000000..bc6b349b2ef66a6a3bdac4f68353113431b52e7d --- /dev/null +++ b/scripts/test/SANS/gui_logic/batch_process_runner_test.py @@ -0,0 +1,70 @@ +from __future__ import (absolute_import, division, print_function) +from sans.gui_logic.models.batch_process_runner import BatchProcessRunner +import unittest +import sys +from sans.common.enums import (OutputMode) +from PyQt4.QtCore import QThreadPool + +if sys.version_info.major > 2: + from unittest import mock +else: + import mock + + +class BatchProcessRunnerTest(unittest.TestCase): + def setUp(self): + self.notify_progress = mock.MagicMock() + self.notify_done = mock.MagicMock() + self.notify_error = mock.MagicMock() + + self.sans_batch_instance = mock.MagicMock() + batch_patcher = mock.patch('sans.gui_logic.models.batch_process_runner.SANSBatchReduction') + self.addCleanup(batch_patcher.stop) + self.batch_mock = batch_patcher.start() + self.batch_mock.return_value = self.sans_batch_instance + + self.batch_process_runner = BatchProcessRunner(self.notify_progress, self.notify_done, self.notify_error) + self.states = {0: 0, 1: 1, 2: 2} + + def test_that_notify_done_method_set_correctly(self): + self.batch_process_runner.notify_done() + + self.notify_done.assert_called_once_with() + + def test_that_process_states_calls_batch_reduce_for_each_row(self): + self.batch_process_runner.process_states(self.states, False, OutputMode.Both, False, '') + QThreadPool.globalInstance().waitForDone() + + self.assertEqual(self.sans_batch_instance.call_count, 3) + + def test_that_process_states_emits_row_processed_signal_after_each_row(self): + self.batch_process_runner.row_processed_signal = mock.MagicMock() + self.batch_process_runner.row_failed_signal = mock.MagicMock() + + self.batch_process_runner.process_states(self.states, False, OutputMode.Both, False, '') + QThreadPool.globalInstance().waitForDone() + + self.assertEqual(self.batch_process_runner.row_processed_signal.emit.call_count, 3) + self.batch_process_runner.row_processed_signal.emit.assert_any_call(0) + self.batch_process_runner.row_processed_signal.emit.assert_any_call(1) + self.batch_process_runner.row_processed_signal.emit.assert_any_call(2) + self.assertEqual(self.batch_process_runner.row_failed_signal.emit.call_count, 0) + + def test_that_process_states_emits_row_failed_signal_after_each_failed_row(self): + self.batch_process_runner.row_processed_signal = mock.MagicMock() + self.batch_process_runner.row_failed_signal = mock.MagicMock() + self.sans_batch_instance.side_effect = Exception('failure') + + self.batch_process_runner.process_states(self.states, False, OutputMode.Both, False, '') + QThreadPool.globalInstance().waitForDone() + + self.assertEqual(self.batch_process_runner.row_failed_signal.emit.call_count, 3) + self.batch_process_runner.row_failed_signal.emit.assert_any_call(0, 'failure') + self.batch_process_runner.row_failed_signal.emit.assert_any_call(1, 'failure') + self.batch_process_runner.row_failed_signal.emit.assert_any_call(2, 'failure') + self.assertEqual(self.batch_process_runner.row_processed_signal.emit.call_count, 0) + + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/scripts/test/SANS/gui_logic/create_state_test.py b/scripts/test/SANS/gui_logic/create_state_test.py index 89382de43c651c51c988f6f693e8c035a0997ff5..c193cc9080b31da7a2dc402e5af72e2c09f19673 100644 --- a/scripts/test/SANS/gui_logic/create_state_test.py +++ b/scripts/test/SANS/gui_logic/create_state_test.py @@ -8,6 +8,7 @@ from sans.gui_logic.models.create_state import (create_states, create_gui_state_ from sans.common.enums import (SANSInstrument, ISISReductionMode, SANSFacility, SaveType) from sans.gui_logic.models.state_gui_model import StateGuiModel from sans.gui_logic.models.table_model import TableModel, TableIndexModel +from sans.state.state import State if sys.version_info.major == 3: from unittest import mock @@ -15,49 +16,54 @@ else: import mock class GuiCommonTest(unittest.TestCase): - def setUp(self): self.table_model = TableModel() self.state_gui_model = StateGuiModel({}) - table_index_model_0 = TableIndexModel(0, 'LOQ74044', '', '', '', '', '', '', '', '', '', '', '') - table_index_model_1 = TableIndexModel(1, 'LOQ74044', '', '', '', '', '', '', '', '', '', '', '') + table_index_model_0 = TableIndexModel('LOQ74044', '', '', '', '', '', '', '', '', '', '', '') + table_index_model_1 = TableIndexModel('LOQ74044', '', '', '', '', '', '', '', '', '', '', '') self.table_model.add_table_entry(0, table_index_model_0) self.table_model.add_table_entry(1, table_index_model_1) + self.fake_state = mock.MagicMock(spec=State) + self.gui_state_director_instance = mock.MagicMock() + self.gui_state_director_instance.create_state.return_value = self.fake_state + self.patcher = mock.patch('sans.gui_logic.models.create_state.GuiStateDirector') + self.addCleanup(self.patcher.stop) + self.gui_state_director = self.patcher.start() + self.gui_state_director.return_value = self.gui_state_director_instance - @mock.patch('sans.gui_logic.models.create_state.__create_row_state') - def test_create_states_returns_correct_number_of_states(self, create_row_state_mock): - - states = create_states(self.state_gui_model, self.table_model, SANSInstrument.LOQ, SANSFacility.ISIS) + def test_create_states_returns_correct_number_of_states(self): + states, errors = create_states(self.state_gui_model, self.table_model, SANSInstrument.LOQ, SANSFacility.ISIS, + row_index=[0,1]) self.assertEqual(len(states), 2) - @mock.patch('sans.gui_logic.models.create_state.__create_row_state') - def test_create_states_returns_correct_number_of_states_for_specified_row_index(self, create_row_state_mock): + def test_create_states_returns_correct_number_of_states_for_specified_row_index(self): - states = create_states(self.state_gui_model, self.table_model, SANSInstrument.LOQ, SANSFacility.ISIS, row_index=1) + states, errors = create_states(self.state_gui_model, self.table_model, SANSInstrument.LOQ, SANSFacility.ISIS, + row_index=[1]) self.assertEqual(len(states), 1) - @mock.patch('sans.gui_logic.models.create_state.__create_row_state') - def test_skips_empty_rows(self, create_row_state_mock): - table_index_model = TableIndexModel(1, '', '', '', '', '', '', '', '', '', '', '', '') + def test_skips_empty_rows(self): + table_index_model = TableIndexModel('', '', '', '', '', '', '', '', '', '', '', '') self.table_model.add_table_entry(1, table_index_model) - states = create_states(self.state_gui_model, self.table_model, SANSInstrument.LOQ, SANSFacility.ISIS) + states, errors = create_states(self.state_gui_model, self.table_model, SANSInstrument.LOQ, SANSFacility.ISIS, + row_index=[0,1, 2]) - self.assertEqual(len(states), 1) + self.assertEqual(len(states), 2) - @mock.patch('sans.gui_logic.models.create_state.__create_row_state') @mock.patch('sans.gui_logic.models.create_state.create_gui_state_from_userfile') - def test_create_state_from_user_file_if_specified(self, create_gui_state_mock, create_row_state_mock): + def test_create_state_from_user_file_if_specified(self, create_gui_state_mock): create_gui_state_mock.returns = StateGuiModel({}) - table_index_model = TableIndexModel(0, 'LOQ74044', '', '', '', '', '', '', '', '', '', '', '', - user_file='MaskLOQData.txt') + table_index_model = TableIndexModel('LOQ74044', '', '', '', '', '', '', '', '', '', '', '', + user_file='MaskLOQData.txt') table_model = TableModel() table_model.add_table_entry(0, table_index_model) - states = create_states(self.state_gui_model, table_model, SANSInstrument.LOQ, SANSFacility.ISIS) + states, errors = create_states(self.state_gui_model, table_model, SANSInstrument.LOQ, SANSFacility.ISIS, + row_index=[0,1, 2]) self.assertEqual(len(states), 1) create_gui_state_mock.assert_called_once_with('MaskLOQData.txt', self.state_gui_model) diff --git a/scripts/test/SANS/gui_logic/gui_state_director_test.py b/scripts/test/SANS/gui_logic/gui_state_director_test.py index 6790394e4e5b2f39e92b0a1a632d0251e64a2080..8e406b37d815dd3f630199a9a710f40fd799955f 100644 --- a/scripts/test/SANS/gui_logic/gui_state_director_test.py +++ b/scripts/test/SANS/gui_logic/gui_state_director_test.py @@ -15,8 +15,9 @@ from sans.test_helper.user_file_test_helper import create_user_file, sample_user class GuiStateDirectorTest(unittest.TestCase): @staticmethod def _get_table_model(option_string="", sample_thickness=8.0): - table_index_model = TableIndexModel(0, "SANS2D00022024", "", "", "", "", "", "", "", "", - "", "", "", "", "", option_string, sample_thickness=sample_thickness) + table_index_model = TableIndexModel("SANS2D00022024", "", "", "", "", "", "", "", "", + "", "", "",options_column_string=option_string, + sample_thickness=sample_thickness) table_model = TableModel() table_model.add_table_entry(0, table_index_model) return table_model diff --git a/scripts/test/SANS/gui_logic/main_presenter_test.py b/scripts/test/SANS/gui_logic/main_presenter_test.py index 110d62cd9e88bb163a17c0df846a11a91c4c6f38..535b05dfe9e3abe611f0da06bf3b018d898f057d 100644 --- a/scripts/test/SANS/gui_logic/main_presenter_test.py +++ b/scripts/test/SANS/gui_logic/main_presenter_test.py @@ -2,81 +2,8 @@ from __future__ import (absolute_import, division, print_function) import unittest -import mantid - -from sans.test_helper.mock_objects import (create_mock_view2) -from sans.gui_logic.presenter.main_presenter import MainPresenter -from sans.common.enums import SANSFacility -from sans.test_helper.user_file_test_helper import (create_user_file, sample_user_file) -from sans.test_helper.common import (remove_file, save_to_csv) - - class MainPresenterTest(unittest.TestCase): - def test_that_gets_correct_gui_algorithm_name(self): - presenter = MainPresenter(SANSFacility.ISIS) - gui_algorithm_name = presenter.get_gui_algorithm_name() - self.assertTrue(gui_algorithm_name == "SANSGuiDataProcessorAlgorithm") - - def test_that_the_white_list_is_correct(self): - presenter = MainPresenter(SANSFacility.ISIS) - self.assertTrue(presenter.get_number_of_white_list_items() == 0) - white_list = presenter.get_white_list(show_periods=True) - self.assertEqual(presenter.get_number_of_white_list_items(), 20) - - self.assertTrue(white_list[0].algorithm_property == "SampleScatter") - self.assertTrue(white_list[1].algorithm_property == "SampleScatterPeriod") - self.assertTrue(white_list[2].algorithm_property == "SampleTransmission") - self.assertTrue(white_list[3].algorithm_property == "SampleTransmissionPeriod") - self.assertTrue(white_list[4].algorithm_property == "SampleDirect") - self.assertTrue(white_list[5].algorithm_property == "SampleDirectPeriod") - self.assertTrue(white_list[6].algorithm_property == "CanScatter") - self.assertTrue(white_list[7].algorithm_property == "CanScatterPeriod") - self.assertTrue(white_list[8].algorithm_property == "CanTransmission") - self.assertTrue(white_list[9].algorithm_property == "CanTransmissionPeriod") - self.assertTrue(white_list[10].algorithm_property == "CanDirect") - self.assertTrue(white_list[11].algorithm_property == "CanDirectPeriod") - self.assertTrue(white_list[12].algorithm_property == "UseOptimizations") - self.assertTrue(white_list[13].algorithm_property == "PlotResults") - self.assertTrue(white_list[14].algorithm_property == "OutputName") - self.assertTrue(white_list[15].algorithm_property == "UserFile") - self.assertEqual(white_list[16].algorithm_property, "SampleThickness") - self.assertTrue(white_list[17].algorithm_property == "RowIndex") - self.assertTrue(white_list[18].algorithm_property == "OutputMode") - self.assertTrue(white_list[19].algorithm_property == "OutputGraph") - - def test_that_black_list_is_correct(self): - presenter = MainPresenter(SANSFacility.ISIS) - expected = "InputWorkspace,OutputWorkspace,SampleScatter,SampleScatterPeriod,SampleTransmission," \ - "SampleTransmissionPeriod,SampleDirect,SampleDirectPeriod,CanScatter,CanScatterPeriod," \ - "CanTransmission,CanTransmissionPeriod,CanDirect,CanDirectPeriod," \ - "UseOptimizations,PlotResults,OutputName,UserFile,SampleThickness,RowIndex,OutputMode,OutputGraph," - self.assertEqual(expected, presenter.get_black_list()) - - def test_that_gets_pre_processing_options_are_valid_and_other_options_are_empty(self): - # Arrange - presenter = MainPresenter(SANSFacility.ISIS) - content = "# MANTID_BATCH_FILE add more text here\n" \ - "sample_sans,SANS2D00022024,sample_trans,SANS2D00022048," \ - "sample_direct_beam,SANS2D00022048,output_as,test_file\n" \ - "sample_sans,SANS2D00022024,output_as,test_file2\n" - batch_file_path = save_to_csv(content) - user_file_path = create_user_file(sample_user_file) - view = create_mock_view2(user_file_path, batch_file_path) - presenter.set_view(view) - - # Act - pre_processing_options = presenter.getProcessingOptions() - - # Assert - expected = {'UseOptimizations':'1','OutputMode':'PublishToADS','PlotResults':'1', \ - 'OutputGraph':'SANS-Latest'} - self.assertEqual(expected, pre_processing_options) - self.assertFalse(presenter.getPreprocessingOptions()) - self.assertFalse(presenter.getPostprocessingOptionsAsString()) - - # Clean up - remove_file(sample_user_file) - remove_file(user_file_path) + pass if __name__ == '__main__': diff --git a/scripts/test/SANS/gui_logic/run_tab_presenter_test.py b/scripts/test/SANS/gui_logic/run_tab_presenter_test.py index 7a21658b4e41bea875afb2849c25e3bab2abef73..605b1ea39388774626bf794fa0b5307c1cdefb57 100644 --- a/scripts/test/SANS/gui_logic/run_tab_presenter_test.py +++ b/scripts/test/SANS/gui_logic/run_tab_presenter_test.py @@ -9,11 +9,12 @@ from mantid.kernel import PropertyManagerDataService from sans.gui_logic.presenter.run_tab_presenter import RunTabPresenter from sans.common.enums import (SANSFacility, ReductionDimensionality, SaveType, ISISReductionMode, - RangeStepType, FitType) + RangeStepType, FitType, SANSInstrument, RowState) from sans.test_helper.user_file_test_helper import (create_user_file, sample_user_file, sample_user_file_gravity_OFF) from sans.test_helper.mock_objects import (create_mock_view) from sans.test_helper.common import (remove_file) from sans.common.enums import BatchReductionEntry +from sans.gui_logic.models.table_model import TableModel, TableIndexModel if sys.version_info.major == 3: @@ -30,13 +31,19 @@ BATCH_FILE_TEST_CONTENT_1 = [{BatchReductionEntry.SampleScatter: 1, BatchReducti BATCH_FILE_TEST_CONTENT_2 = [{BatchReductionEntry.SampleScatter: 'SANS2D00022024', BatchReductionEntry.SampleTransmission: 'SANS2D00022048', BatchReductionEntry.SampleDirect: 'SANS2D00022048', - BatchReductionEntry.Output: 'test_file', BatchReductionEntry.UserFile: 'user_test_file'}, + BatchReductionEntry.Output: 'test_file'}, {BatchReductionEntry.SampleScatter: 'SANS2D00022024', BatchReductionEntry.Output: 'test_file2'}] BATCH_FILE_TEST_CONTENT_3 = [{BatchReductionEntry.SampleScatter: 'SANS2D00022024', BatchReductionEntry.SampleScatterPeriod: '3', BatchReductionEntry.Output: 'test_file'}] +BATCH_FILE_TEST_CONTENT_4 = [{BatchReductionEntry.SampleScatter: 'SANS2D00022024', + BatchReductionEntry.SampleTransmission: 'SANS2D00022048', + BatchReductionEntry.SampleDirect: 'SANS2D00022048', + BatchReductionEntry.Output: 'test_file'}, + {BatchReductionEntry.SampleScatter: 'SANS2D00022024', BatchReductionEntry.Output: 'test_file2'}] + class MultiPeriodMock(object): def __init__(self, call_pattern): @@ -55,6 +62,7 @@ class RunTabPresenterTest(unittest.TestCase): def setUp(self): config.setFacility("ISIS") config.setString("default.instrument", "SANS2D") + patcher = mock.patch('sans.gui_logic.presenter.run_tab_presenter.BatchCsvParser') self.addCleanup(patcher.stop) self.BatchCsvParserMock = patcher.start() @@ -135,12 +143,6 @@ class RunTabPresenterTest(unittest.TestCase): self.assertEqual(view.beam_centre.hab_pos_1, 155.45) self.assertEqual(view.beam_centre.hab_pos_2, -169.6) - # Assert certain function calls - self.assertEqual(view.get_user_file_path.call_count, 3) - self.assertEqual(view.get_batch_file_path.call_count, 2) - self.assertEqual(view.get_cell.call_count, 66) - self.assertEqual(view.get_number_of_rows.call_count, 3) - # clean up remove_file(user_file_path) @@ -170,16 +172,15 @@ class RunTabPresenterTest(unittest.TestCase): # Assert self.assertEqual(view.add_row.call_count, 2) if use_multi_period: - expected_first_row = "SampleScatter:SANS2D00022024,ssp:,SampleTrans:SANS2D00022048,stp:,SampleDirect:SANS2D00022048,sdp:," \ - "CanScatter:,csp:,CanTrans:,ctp:,CanDirect:,cdp:,OutputName:test_file," \ - "User File:user_test_file,Sample Thickness:1.00" - expected_second_row = "SampleScatter:SANS2D00022024,ssp:,SampleTrans:,stp:,SampleDirect:,sdp:," \ - "CanScatter:,csp:,CanTrans:,ctp:,CanDirect:,cdp:,OutputName:test_file2,User File:,Sample Thickness:1.00" + expected_first_row = ['SANS2D00022024', '', 'SANS2D00022048', '', 'SANS2D00022048', '', '', '', '', '', '', + '', 'test_file', '', '1.0', ''] + expected_second_row = ['SANS2D00022024', '', '', '', '', '', '', '', '', '', '', '', 'test_file2', '', + '1.0', ''] else: - expected_first_row = "SampleScatter:SANS2D00022024,SampleTrans:SANS2D00022048,SampleDirect:SANS2D00022048," \ - "CanScatter:,CanTrans:,CanDirect:,OutputName:test_file,User File:user_test_file,Sample Thickness:1.00" - expected_second_row = "SampleScatter:SANS2D00022024,SampleTrans:,SampleDirect:," \ - "CanScatter:,CanTrans:,CanDirect:,OutputName:test_file2,User File:,Sample Thickness:1.00" + expected_first_row = ['SANS2D00022024', '', 'SANS2D00022048', '', 'SANS2D00022048', '', '', '', '', '', '', + '', 'test_file', '', '1.0', ''] + expected_second_row = ['SANS2D00022024', '', '', '', '', '', '', '', '', '', '', '', 'test_file2', '', '1.0' + , ''] calls = [mock.call(expected_first_row), mock.call(expected_second_row)] view.add_row.assert_has_calls(calls) @@ -210,10 +211,9 @@ class RunTabPresenterTest(unittest.TestCase): # Assert self.assertEqual(view.add_row.call_count, 1) - self.assertEqual(view.set_multi_period_view_mode.call_count, 1) + self.assertEqual(view.show_period_columns.call_count, 1) - expected_row = "SampleScatter:SANS2D00022024,ssp:3,SampleTrans:,stp:,SampleDirect:,sdp:," \ - "CanScatter:,csp:,CanTrans:,ctp:,CanDirect:,cdp:,OutputName:test_file,User File:,Sample Thickness:1.00" + expected_row = ['SANS2D00022024', '3', '', '', '', '', '', '', '', '', '', '', 'test_file', '', '1.0', ''] calls = [mock.call(expected_row)] view.add_row.assert_has_calls(calls) @@ -243,7 +243,7 @@ class RunTabPresenterTest(unittest.TestCase): presenter.on_batch_file_load() # Act - states = presenter.get_states() + states, errors = presenter.get_states(row_index=[0, 1]) # Assert self.assertTrue(len(states) == 2) @@ -283,6 +283,20 @@ class RunTabPresenterTest(unittest.TestCase): # Clean up self._remove_files(user_file_path=user_file_path, batch_file_path=batch_file_path) + def test_that_can_get_states_from_row_user_file(self): + # Arrange + row_user_file_path = create_user_file(sample_user_file_gravity_OFF) + batch_file_path, user_file_path, presenter, _ = self._get_files_and_mock_presenter(BATCH_FILE_TEST_CONTENT_4, + row_user_file_path = row_user_file_path) + presenter.on_user_file_load() + presenter.on_batch_file_load() + # Act + state = presenter.get_state_for_row(1) + state0 = presenter.get_state_for_row(0) + # Assert + self.assertTrue(state.convert_to_q.use_gravity is False) + self.assertTrue(state0.convert_to_q.use_gravity is True) + def test_that_can_get_state_for_index_if_index_exists(self): # Arrange batch_file_path, user_file_path, presenter, _ = self._get_files_and_mock_presenter(BATCH_FILE_TEST_CONTENT_2) @@ -304,23 +318,6 @@ class RunTabPresenterTest(unittest.TestCase): # Clean up self._remove_files(user_file_path=user_file_path, batch_file_path=batch_file_path) - def test_that_can_get_states_from_row_user_file(self): - # Arrange - row_user_file_path = create_user_file(sample_user_file_gravity_OFF) - batch_file_path, user_file_path, presenter, _ = self._get_files_and_mock_presenter(BATCH_FILE_TEST_CONTENT_2, - row_user_file_path = row_user_file_path) - - presenter.on_user_file_load() - presenter.on_batch_file_load() - - # Act - state = presenter.get_state_for_row(1) - state0 = presenter.get_state_for_row(0) - - # Assert - self.assertTrue(state.convert_to_q.use_gravity is False) - self.assertTrue(state0.convert_to_q.use_gravity is True) - def test_that_returns_none_when_index_does_not_exist(self): # Arrange batch_file_path, user_file_path, presenter, _ = self._get_files_and_mock_presenter(BATCH_FILE_TEST_CONTENT_2) @@ -339,133 +336,389 @@ class RunTabPresenterTest(unittest.TestCase): remove_file(batch_file_path) remove_file(user_file_path) - def test_that_populates_the_property_manager_data_service_when_processing_is_called(self): + def test_that_can_add_new_masks(self): # Arrange self._clear_property_manager_data_service() batch_file_path, user_file_path, presenter, _ = self._get_files_and_mock_presenter(BATCH_FILE_TEST_CONTENT_2) - # This is not the nicest of tests, but better to test this functionality than not presenter.on_user_file_load() presenter.on_batch_file_load() # Act - presenter.on_processed_clicked() + presenter.on_mask_file_add() # Assert - # We should have two states in the PropertyManagerDataService - self.assertEqual(len(PropertyManagerDataService.getObjectNames()), 2) + state = presenter.get_state_for_row(0) + mask_info = state.mask + mask_files = mask_info.mask_files + self.assertTrue(mask_files == [user_file_path]) # clean up self._remove_files(user_file_path=user_file_path, batch_file_path=batch_file_path) - self._clear_property_manager_data_service() - - def test_that_calls_halt_process_flag_if_user_file_has_not_been_loaded_and_process_is_run(self): - # Arrange - self._clear_property_manager_data_service() - batch_file_path, user_file_path, presenter, view = self._get_files_and_mock_presenter(BATCH_FILE_TEST_CONTENT_2) + def test_on_data_changed_calls_update_rows(self): + batch_file_path, user_file_path, presenter, _ = self._get_files_and_mock_presenter(BATCH_FILE_TEST_CONTENT_1) + presenter._masking_table_presenter = mock.MagicMock() + presenter._beam_centre_presenter = mock.MagicMock() + row_entry = [''] * 16 + presenter.on_row_inserted(0, row_entry) - presenter.on_processed_clicked() + presenter.on_data_changed(0, 0, '12335', '00000') - # Assert - # We should have printed an error message to the logs and called halt process flag - self.assertTrue(view.halt_process_flag.call_count == 1) - # clean up - self._remove_files(user_file_path=user_file_path, batch_file_path=batch_file_path) + presenter._masking_table_presenter.on_update_rows.assert_called_once_with() + presenter._beam_centre_presenter.on_update_rows.assert_called_once_with() - self._clear_property_manager_data_service() + def test_table_model_is_initialised_upon_presenter_creation(self): + presenter = RunTabPresenter(SANSFacility.ISIS) - def test_that_calls_halt_process_flag_if_state_are_invalid_and_process_is_run(self): - # Arrange - self._clear_property_manager_data_service() - batch_file_path, user_file_path, presenter, view = self._get_files_and_mock_presenter(BATCH_FILE_TEST_CONTENT_2) + self.assertEqual(presenter._table_model, TableModel()) - presenter.on_batch_file_load() - presenter.on_user_file_load() + def test_on_insert_row_updates_table_model(self): + presenter = RunTabPresenter(SANSFacility.ISIS) + presenter.set_view(mock.MagicMock()) + row = ['74044', '', '74044', '', '74044', '', '74044', '', '74044', '', '74044', '', 'test_reduction' + , 'user_file', '1.2', ''] + index = 0 - # Set invalid state - presenter._state_model.event_slices = 'Hello' + presenter.on_row_inserted(index, row) - presenter.on_processed_clicked() + self.assertEqual(presenter._table_model.get_number_of_rows(), 1) + model_row = presenter._table_model.get_table_entry(0) + self.assertEqual(model_row, TableIndexModel(*row)) - # Assert - # We should have printed an error to logs and called halt process flag - self.assertTrue(view.halt_process_flag.call_count == 1) + def test_that_all_columns_shown_when_multi_period_is_true(self): + presenter = RunTabPresenter(SANSFacility.ISIS) + presenter.set_view(mock.MagicMock()) - # clean up - self._remove_files(user_file_path=user_file_path, batch_file_path=batch_file_path) + presenter.on_multiperiod_changed(True) - self._clear_property_manager_data_service() + presenter._view.show_period_columns.assert_called_once_with() - def test_that_calls_halt_process_flag_if_states_are_not_retrievable_and_process_is_run(self): - # Arrange - self._clear_property_manager_data_service() - batch_file_path, user_file_path, presenter, view = self._get_files_and_mock_presenter(BATCH_FILE_TEST_CONTENT_2) + def test_that_period_columns_hidden_when_multi_period_is_false(self): + presenter = RunTabPresenter(SANSFacility.ISIS) + presenter.set_view(mock.MagicMock()) - presenter.on_batch_file_load() - presenter.on_user_file_load() + presenter.on_multiperiod_changed(False) - presenter.get_states = mock.MagicMock(return_value='') + presenter._view.hide_period_columns.assert_called_once_with() - presenter.on_processed_clicked() + def test_on_data_changed_updates_table_model(self): + presenter = RunTabPresenter(SANSFacility.ISIS) + presenter.set_view(mock.MagicMock()) + row = ['74044', '', '74044', '', '74044', '', '74044', '', '74044', '', '74044', '', 'test_reduction' + , 'user_file', '1.2', ''] + expected_row = ['74044', '', '74040', '', '74044', '', '74044', '', '74044', '', '74044', '', 'test_reduction' + , 'user_file', '1.2', ''] + presenter._table_model.add_table_entry(0, TableIndexModel(*row)) + row = 0 + column = 2 + value = '74040' + + presenter.on_data_changed(row, column, value, '') + + self.assertEqual(presenter._table_model.get_number_of_rows(), 1) + model_row = presenter._table_model.get_table_entry(0) + self.assertEqual(model_row, TableIndexModel(*expected_row)) + + def test_on_row_removed_removes_correct_row(self): + presenter = RunTabPresenter(SANSFacility.ISIS) + presenter.set_view(mock.MagicMock()) + row_0 = ['74040', '', '74040', '', '74040', '', '74040', '', '74040', '', '74040', '', 'test_reduction' + , 'user_file', '1.2', ''] + row_1 = ['74041', '', '74041', '', '74041', '', '74041', '', '74041', '', '74041', '', 'test_reduction' + , 'user_file', '1.2', ''] + row_2 = ['74042', '', '74042', '', '74042', '', '74042', '', '74042', '', '74042', '', 'test_reduction' + , 'user_file', '1.2', ''] + row_3 = ['74043', '', '74043', '', '74043', '', '74043', '', '74043', '', '74043', '', 'test_reduction' + , 'user_file', '1.2', ''] + presenter._table_model.add_table_entry(0, TableIndexModel(*row_0)) + presenter._table_model.add_table_entry(1, TableIndexModel(*row_1)) + presenter._table_model.add_table_entry(2, TableIndexModel(*row_2)) + presenter._table_model.add_table_entry(3, TableIndexModel(*row_3)) + rows = [0, 2] + + presenter.on_rows_removed(rows) + + self.assertEqual(presenter._table_model.get_number_of_rows(), 2) + model_row_0 = presenter._table_model.get_table_entry(0) + self.assertEqual(model_row_0, TableIndexModel(*row_1)) + model_row_1 = presenter._table_model.get_table_entry(1) + self.assertEqual(model_row_1, TableIndexModel(*row_3)) + + def test_on_rows_removed_updates_view(self): + presenter = RunTabPresenter(SANSFacility.ISIS) + presenter.set_view(mock.MagicMock()) + row_0 = ['74040', '', '74040', '', '74040', '', '74040', '', '74040', '', '74040', '', 'test_reduction' + , 'user_file', '1.2', ''] + row_1 = ['74041', '', '74041', '', '74041', '', '74041', '', '74041', '', '74041', '', 'test_reduction' + , 'user_file', '1.2', ''] + row_2 = ['74042', '', '74042', '', '74042', '', '74042', '', '74042', '', '74042', '', 'test_reduction' + , 'user_file', '1.2', ''] + row_3 = ['74043', '', '74043', '', '74043', '', '74043', '', '74043', '', '74043', '', 'test_reduction' + , 'user_file', '1.2', ''] + presenter._table_model.add_table_entry(0, TableIndexModel(*row_0)) + presenter._table_model.add_table_entry(1, TableIndexModel(*row_1)) + presenter._table_model.add_table_entry(2, TableIndexModel(*row_2)) + presenter._table_model.add_table_entry(3, TableIndexModel(*row_3)) + presenter.update_view_from_table_model = mock.MagicMock() + rows = [0, 2] + + presenter.on_rows_removed(rows) + + presenter.update_view_from_table_model.assert_called_once_with() + + def test_add_row_to_table_model_adds_row_to_table_model(self): + presenter = RunTabPresenter(SANSFacility.ISIS) + presenter.set_view(mock.MagicMock()) + parsed_data = BATCH_FILE_TEST_CONTENT_2 - # Assert - # We should have printed an error to logs and called halt process flag - self.assertTrue(view.halt_process_flag.call_count == 1) + for item, row in enumerate(parsed_data): + presenter._add_row_to_table_model(row, item) - # clean up - self._remove_files(user_file_path=user_file_path, batch_file_path=batch_file_path) + table_entry_0 = presenter._table_model.get_table_entry(0) + self.assertEqual(table_entry_0.output_name, 'test_file') + self.assertEqual(table_entry_0.sample_scatter, 'SANS2D00022024') + self.assertEqual(table_entry_0.sample_thickness, 1.0) - self._clear_property_manager_data_service() + table_entry_1 = presenter._table_model.get_table_entry(1) + self.assertEqual(table_entry_1.output_name, 'test_file2') - def test_that_can_add_new_masks(self): - # Arrange - self._clear_property_manager_data_service() + def test_update_view_from_table_model_updated_view_based_on_model(self): batch_file_path, user_file_path, presenter, _ = self._get_files_and_mock_presenter(BATCH_FILE_TEST_CONTENT_2) + presenter.set_view(mock.MagicMock()) + parsed_data = BATCH_FILE_TEST_CONTENT_2 + for item, row in enumerate(parsed_data): + presenter._add_row_to_table_model(row, item) + expected_call_0 = ['SANS2D00022024', '', 'SANS2D00022048', '', 'SANS2D00022048', '', '', '', '', '', '', '', + 'test_file', '', '1.0', ''] + expected_call_1 = ['SANS2D00022024', '', '', '', '', '', '', '', '', '', '', '', 'test_file2', '', '1.0', ''] - presenter.on_user_file_load() - presenter.on_batch_file_load() + presenter.update_view_from_table_model() - # Act - presenter.on_mask_file_add() + self.assertEqual(presenter._view.add_row.call_count, 2) - # Assert - state = presenter.get_state_for_row(0) - mask_info = state.mask - mask_files = mask_info.mask_files - self.assertTrue(mask_files == [user_file_path]) + presenter._view.add_row.called_with(expected_call_0) + presenter._view.add_row.called_with(expected_call_1) - # clean up - self._remove_files(user_file_path=user_file_path, batch_file_path=batch_file_path) + def test_setup_instrument_specific_settings(self): + presenter = RunTabPresenter(SANSFacility.ISIS) + presenter.set_view(mock.MagicMock()) + presenter._beam_centre_presenter = mock.MagicMock() + presenter._workspace_diagnostic_presenter = mock.MagicMock() + instrument = SANSInstrument.LOQ - def test_that_get_processing_options_returns_correct_value(self): - batch_file_path, user_file_path, presenter, _ = self._get_files_and_mock_presenter(BATCH_FILE_TEST_CONTENT_1) - expected_result = {'UseOptimizations':'1','OutputMode':'PublishToADS','PlotResults':'1','OutputGraph':'SANS-Latest'} + presenter._setup_instrument_specific_settings(SANSInstrument.LOQ) - result = presenter.get_processing_options() + presenter._view.set_instrument_settings.called_once_with(instrument) + presenter._beam_centre_presenter.on_update_instrument.called_once_with(instrument) + presenter._workspace_diagnostic_presenter.called_once_with(instrument) - self.assertEqual(expected_result, result) + def test_on_copy_rows_requested_adds_correct_rows_to_clipboard(self): + presenter = RunTabPresenter(SANSFacility.ISIS) + view = mock.MagicMock() + view.get_selected_rows = mock.MagicMock(return_value=[0]) + presenter.set_view(view) + test_row = ['SANS2D00022024', '', 'SANS2D00022048', '', 'SANS2D00022048', '', '', '', '', '', '', '', + 'test_file', '', '1.0', ''] - def test_on_data_changed_does_nothing_during_processing(self): - batch_file_path, user_file_path, presenter, _ = self._get_files_and_mock_presenter(BATCH_FILE_TEST_CONTENT_1) - presenter._masking_table_presenter = mock.MagicMock() - presenter._beam_centre_presenter = mock.MagicMock() - presenter._processing = True + presenter.on_row_inserted(0, test_row) - presenter.on_data_changed() + presenter.on_copy_rows_requested() - presenter._masking_table_presenter.on_update_rows.assert_not_called() - presenter._beam_centre_presenter.on_update_rows.assert_not_called() + self.assertEqual(presenter._clipboard, [test_row]) - def test_on_data_changed_calls_update_rows(self): - batch_file_path, user_file_path, presenter, _ = self._get_files_and_mock_presenter(BATCH_FILE_TEST_CONTENT_1) - presenter._masking_table_presenter = mock.MagicMock() - presenter._beam_centre_presenter = mock.MagicMock() + def test_on_paste_rows_requested_appends_new_row_if_no_row_selected(self): + presenter = RunTabPresenter(SANSFacility.ISIS) + view = mock.MagicMock() + view.get_selected_rows = mock.MagicMock(return_value=[]) + presenter.set_view(view) + test_row_0 = ['SANS2D00022024', '', 'SANS2D00022048', '', 'SANS2D00022048', '', '', '', '', '', '', '', + 'test_file', '', '1.0', ''] + test_row_1 = ['SANS2D00022024', '', '', '', '', '', '', '', '', '', '', '', 'test_file2', '', '1.0', ''] + presenter.on_row_inserted(0, test_row_0) + presenter.on_row_inserted(1, test_row_1) + presenter._clipboard = [test_row_0] - presenter.on_data_changed() + presenter.on_paste_rows_requested() - presenter._masking_table_presenter.on_update_rows.assert_called_once_with() - presenter._beam_centre_presenter.on_update_rows.assert_called_once_with() + self.assertEqual(presenter._table_model.get_number_of_rows(), 3) + self.assertEqual(presenter._table_model.get_table_entry(2).to_list(), test_row_0) + + def test_on_paste_rows_requested_replaces_row_if_one_row_is_selected(self): + presenter = RunTabPresenter(SANSFacility.ISIS) + view = mock.MagicMock() + view.get_selected_rows = mock.MagicMock(return_value=[1]) + presenter.set_view(view) + test_row_0 = ['SANS2D00022024', '', 'SANS2D00022048', '', 'SANS2D00022048', '', '', '', '', '', '', '', + 'test_file', '', '1.0', ''] + test_row_1 = ['SANS2D00022024', '', '', '', '', '', '', '', '', '', '', '', 'test_file2', '', '1.0', ''] + presenter.on_row_inserted(0, test_row_0) + presenter.on_row_inserted(1, test_row_1) + presenter.on_row_inserted(2, test_row_0) + presenter._clipboard = [test_row_0] + + presenter.on_paste_rows_requested() + + self.assertEqual(presenter._table_model.get_number_of_rows(), 3) + self.assertEqual(presenter._table_model.get_table_entry(1).to_list(), test_row_0) + + def test_on_paste_rows_requested_replaces_first_row_and_removes_rest_if_multiple_rows_selected(self): + presenter = RunTabPresenter(SANSFacility.ISIS) + view = mock.MagicMock() + view.get_selected_rows = mock.MagicMock(return_value=[0, 2]) + presenter.set_view(view) + test_row_0 = ['SANS2D00022024', '', 'SANS2D00022048', '', 'SANS2D00022048', '', '', '', '', '', '', '', + 'test_file', '', '1.0', ''] + test_row_1 = ['SANS2D00022024', '', '', '', '', '', '', '', '', '', '', '', 'test_file2', '', '1.0', ''] + test_row_2 = ['SANS2D00022024', '', '', '', '', '', '', '', '', '', '', '', 'test_file3', '', '1.0', ''] + presenter.on_row_inserted(0, test_row_0) + presenter.on_row_inserted(1, test_row_1) + presenter.on_row_inserted(2, test_row_2) + presenter._clipboard = [test_row_2] + + presenter.on_paste_rows_requested() + + self.assertEqual(presenter._table_model.get_number_of_rows(), 2) + self.assertEqual(presenter._table_model.get_table_entry(0).to_list(), test_row_2) + self.assertEqual(presenter._table_model.get_table_entry(1).to_list(), test_row_1) + + def test_on_paste_rows_updates_table_in_view(self): + presenter = RunTabPresenter(SANSFacility.ISIS) + view = mock.MagicMock() + view.get_selected_rows = mock.MagicMock(return_value=[]) + presenter.set_view(view) + test_row_0 = ['SANS2D00022024', '', 'SANS2D00022048', '', 'SANS2D00022048', '', '', '', '', '', '', '', + 'test_file', '', '1.0', ''] + test_row_1 = ['SANS2D00022024', '', '', '', '', '', '', '', '', '', '', '', 'test_file2', '', '1.0', ''] + presenter.on_row_inserted(0, test_row_0) + presenter.on_row_inserted(1, test_row_1) + presenter._clipboard = [test_row_0] + presenter.update_view_from_table_model = mock.MagicMock() + + presenter.on_paste_rows_requested() + + presenter.update_view_from_table_model.assert_called_once_with() + + def test_on_insert_row_adds_row_to_table_model_after_selected_row(self): + presenter = RunTabPresenter(SANSFacility.ISIS) + view = mock.MagicMock() + view.get_selected_rows = mock.MagicMock(return_value=[0]) + presenter.set_view(view) + test_row_0 = ['SANS2D00022024', '', 'SANS2D00022048', '', 'SANS2D00022048', '', '', '', '', '', '', '', + 'test_file', '', '1.0', ''] + test_row_1 = ['SANS2D00022024', '', '', '', '', '', '', '', '', '', '', '', 'test_file2', '', '1.0', ''] + presenter.on_row_inserted(0, test_row_0) + presenter.on_row_inserted(1, test_row_1) + + presenter.on_insert_row() + + self.assertEqual(presenter._table_model.get_number_of_rows(), 3) + self.assertEqual(presenter._table_model.get_table_entry(1).to_list(), [''] * 16) + self.assertEqual(presenter._table_model.get_table_entry(0).to_list(), test_row_0) + self.assertEqual(presenter._table_model.get_table_entry(2).to_list(), test_row_1) + + def test_on_insert_row_updates_view(self): + presenter = RunTabPresenter(SANSFacility.ISIS) + view = mock.MagicMock() + view.get_selected_rows = mock.MagicMock(return_value=[0]) + presenter.set_view(view) + test_row_0 = ['SANS2D00022024', '', 'SANS2D00022048', '', 'SANS2D00022048', '', '', '', '', '', '', '', + 'test_file', '', '1.0', ''] + test_row_1 = ['SANS2D00022024', '', '', '', '', '', '', '', '', '', '', '', 'test_file2', '', '1.0', ''] + presenter.on_row_inserted(0, test_row_0) + presenter.on_row_inserted(1, test_row_1) + presenter.update_view_from_table_model = mock.MagicMock() + + presenter.on_insert_row() + + presenter.update_view_from_table_model.assert_called_once_with() + + def test_on_erase_rows_clears_rows_from_table_model(self): + presenter = RunTabPresenter(SANSFacility.ISIS) + view = mock.MagicMock() + view.get_selected_rows = mock.MagicMock(return_value=[1, 2]) + presenter.set_view(view) + test_row_0 = ['SANS2D00022024', '', 'SANS2D00022048', '', 'SANS2D00022048', '', '', '', '', '', '', '', + 'test_file', '', '1.0', ''] + empty_row = TableModel.create_empty_row() + presenter.on_row_inserted(0, test_row_0) + presenter.on_row_inserted(1, test_row_0) + presenter.on_row_inserted(2, test_row_0) + + presenter.on_erase_rows() + + self.assertEqual(presenter._table_model.get_number_of_rows(), 3) + self.assertEqual(presenter._table_model.get_table_entry(0).to_list(), test_row_0) + self.assertEqual(presenter._table_model.get_table_entry(1), empty_row) + self.assertEqual(presenter._table_model.get_table_entry(2), empty_row) + + def test_on_erase_rows_updates_view(self): + presenter = RunTabPresenter(SANSFacility.ISIS) + view = mock.MagicMock() + view.get_selected_rows = mock.MagicMock(return_value=[1, 2]) + presenter.set_view(view) + test_row_0 = ['SANS2D00022024', '', 'SANS2D00022048', '', 'SANS2D00022048', '', '', '', '', '', '', '', + 'test_file', '', '1.0', ''] + presenter.on_row_inserted(0, test_row_0) + presenter.on_row_inserted(1, test_row_0) + presenter.on_row_inserted(2, test_row_0) + presenter.update_view_from_table_model = mock.MagicMock() + + presenter.on_erase_rows() + + presenter.update_view_from_table_model.assert_called_once_with() + + def test_on_cut_rows_requested_updates_clipboard(self): + presenter = RunTabPresenter(SANSFacility.ISIS) + view = mock.MagicMock() + view.get_selected_rows = mock.MagicMock(return_value=[0]) + presenter.set_view(view) + test_row = ['SANS2D00022024', '', 'SANS2D00022048', '', 'SANS2D00022048', '', '', '', '', '', '', '', + 'test_file', '', '1.0', ''] + + presenter.on_row_inserted(0, test_row) + + presenter.on_cut_rows_requested() + + self.assertEqual(presenter._clipboard, [test_row]) + + def test_on_cut_rows_requested_removes_selected_rows(self): + presenter = RunTabPresenter(SANSFacility.ISIS) + view = mock.MagicMock() + view.get_selected_rows = mock.MagicMock(return_value=[0]) + presenter.set_view(view) + test_row_0 = ['SANS2D00022024', '', 'SANS2D00022048', '', 'SANS2D00022048', '', '', '', '', '', '', '', + 'test_file', '', '1.0', ''] + test_row_1 = ['SANS2D00022024', '', '', '', '', '', '', '', '', '', '', '', 'test_file2', '', '1.0', ''] + presenter.on_row_inserted(0, test_row_0) + presenter.on_row_inserted(1, test_row_1) + + presenter.on_cut_rows_requested() + + self.assertEqual(presenter._table_model.get_number_of_rows(), 1) + self.assertEqual(presenter._table_model.get_table_entry(0).to_list(), test_row_1) + + def test_notify_progress_increments_progress(self): + presenter = RunTabPresenter(SANSFacility.ISIS) + view = mock.MagicMock() + presenter.set_view(view) + test_row_0 = ['SANS2D00022024', '', 'SANS2D00022048', '', 'SANS2D00022048', '', '', '', '', '', '', '', + 'test_file', '', '1.0', ''] + presenter.on_row_inserted(0, test_row_0) + presenter.notify_progress(0) + self.assertEqual(presenter.progress, 1) + self.assertEqual(presenter._view.progress_bar_value, 1) + + def test_that_notify_progress_updates_state_and_tooltip_of_row(self): + presenter = RunTabPresenter(SANSFacility.ISIS) + view = mock.MagicMock() + presenter.set_view(view) + test_row_0 = ['SANS2D00022024', '', 'SANS2D00022048', '', 'SANS2D00022048', '', '', '', '', '', '', '', + 'test_file', '', '1.0', ''] + presenter.on_row_inserted(0, test_row_0) + presenter.notify_progress(0) + self.assertEqual(presenter._table_model.get_table_entry(0).row_state, RowState.Processed) + self.assertEqual(presenter._table_model.get_table_entry(0).tool_tip, '') @staticmethod def _clear_property_manager_data_service(): @@ -474,10 +727,14 @@ class RunTabPresenterTest(unittest.TestCase): PropertyManagerDataService.remove(element) def _get_files_and_mock_presenter(self, content, is_multi_period=True, row_user_file_path = ""): + if row_user_file_path: + content[1].update({BatchReductionEntry.UserFile : row_user_file_path}) + batch_parser = mock.MagicMock() batch_parser.parse_batch_file = mock.MagicMock(return_value=content) self.BatchCsvParserMock.return_value = batch_parser batch_file_path = 'batch_file_path' + user_file_path = create_user_file(sample_user_file) view, _, _ = create_mock_view(user_file_path, batch_file_path, row_user_file_path) # We just use the sample_user_file since it exists. diff --git a/scripts/test/SANS/gui_logic/table_model_test.py b/scripts/test/SANS/gui_logic/table_model_test.py index 765f0dd4d6d8ec50c1bcbed7ea080aeb867c8c2c..34b8f7cd3a1b340118d018c07b840408fb5bb394 100644 --- a/scripts/test/SANS/gui_logic/table_model_test.py +++ b/scripts/test/SANS/gui_logic/table_model_test.py @@ -3,6 +3,7 @@ from __future__ import (absolute_import, division, print_function) import unittest from sans.gui_logic.models.table_model import (TableModel, TableIndexModel, OptionsColumnModel) +from sans.gui_logic.models.basic_hint_strategy import BasicHintStrategy class TableModelTest(unittest.TestCase): @@ -14,18 +15,18 @@ class TableModelTest(unittest.TestCase): def test_that_raises_if_table_index_does_not_exist(self): table_model = TableModel() - table_index_model = TableIndexModel(0, "", "", "", "", "", "", - "", "", "", "", "", "",) + row_entry = [''] * 16 + table_index_model = TableIndexModel(*row_entry) table_model.add_table_entry(0, table_index_model) - self.assertRaises(ValueError, table_model.get_table_entry, 1) + self.assertRaises(IndexError, table_model.get_table_entry, 1) def test_that_can_get_table_index_model_for_valid_index(self): table_model = TableModel() - table_index_model = TableIndexModel(0, "", "", "", "", "", "", - "", "", "", "", "", "") + row_entry = [''] * 16 + table_index_model = TableIndexModel(*row_entry) table_model.add_table_entry(0, table_index_model) returned_model = table_model.get_table_entry(0) - self.assertTrue(returned_model.index == 0) + self.assertTrue(returned_model.sample_scatter == '') def test_that_can_set_the_options_column_model(self): table_index_model = TableIndexModel(0, "", "", "", "", "", "", @@ -50,18 +51,18 @@ class TableModelTest(unittest.TestCase): def test_that_can_retrieve_user_file_from_table_index_model(self): table_model = TableModel() table_index_model = TableIndexModel(2, "", "", "", "", "", "", - "", "", "", "", "", "", "", "User_file_name") + "", "", "", "", "", "", "User_file_name") table_model.add_table_entry(2, table_index_model) - user_file = table_model.get_row_user_file(2) + user_file = table_model.get_row_user_file(0) self.assertEqual(user_file,"User_file_name") def test_that_can_retrieve_sample_thickness_from_table_index_model(self): sample_thickness = '8.0' table_model = TableModel() - table_index_model = TableIndexModel(2, "", "", "", "", "", "", + table_index_model = TableIndexModel("", "", "", "", "", "", "", "", "", "", "", "", sample_thickness=sample_thickness) table_model.add_table_entry(2, table_index_model) - row_entry = table_model.get_table_entry(2) + row_entry = table_model.get_table_entry(0) self.assertEqual(row_entry.sample_thickness, sample_thickness) def test_that_parse_string_returns_correctly(self): @@ -85,6 +86,52 @@ class TableModelTest(unittest.TestCase): self.assertEqual(number_of_rows, 2) + def test_when_table_is_cleared_is_left_with_one_empty_row(self): + table_model = TableModel() + table_index_model = TableIndexModel(0, "", "", "", "", "", "", + "", "", "", "", "", "") + table_model.add_table_entry(0, table_index_model) + table_index_model = TableIndexModel(1, "", "", "", "", "", "", + "", "", "", "", "", "") + table_model.add_table_entry(1, table_index_model) + empty_row = table_model.create_empty_row() + + table_model.clear_table_entries() + + self.assertEqual(table_model.get_number_of_rows(), 1) + self.assertEqual(table_model.get_table_entry(0), empty_row) + + def test_when_last_row_is_removed_table_is_left_with_one_empty_row(self): + table_model = TableModel() + table_index_model = TableIndexModel(0, "", "", "", "", "", "", + "", "", "", "", "", "") + table_model.add_table_entry(0, table_index_model) + table_index_model = TableIndexModel(1, "", "", "", "", "", "", + "", "", "", "", "", "") + table_model.add_table_entry(1, table_index_model) + empty_row = table_model.create_empty_row() + + table_model.remove_table_entries([0, 1]) + + self.assertEqual(table_model.get_number_of_rows(), 1) + self.assertEqual(table_model.get_table_entry(0), empty_row) + + def test_that_OptionsColumnModel_get_permissable_properties_returns_correct_properties(self): + permissable_properties = OptionsColumnModel._get_permissible_properties() + + self.assertEqual(permissable_properties, {"WavelengthMin":float, "WavelengthMax": float, "EventSlices": str}) + + def test_that_OptionsColumnModel_get_hint_strategy(self): + hint_strategy = OptionsColumnModel.get_hint_strategy() + expected_hint_strategy = BasicHintStrategy({"WavelengthMin": 'The min value of the wavelength when converting from TOF.', + "WavelengthMax": 'The max value of the wavelength when converting from TOF.', + "EventSlices": 'The event slices to reduce.' + ' The format is the same as for the event slices' + ' box in settings, however if a comma separated list is given ' + 'it must be enclosed in quotes'}) + + self.assertEqual(expected_hint_strategy, hint_strategy) + def _do_test_file_setting(self, func, prop): # Test that can set to empty string table_model = TableModel() @@ -95,9 +142,6 @@ class TableModelTest(unittest.TestCase): has_raised = True self.assertFalse(has_raised) - # Test raises for non-existent file path - self.assertRaises(ValueError, func, "/home/testSDFHSNDFG") - # Test that can be set to valid value setattr(table_model, prop, __file__) self.assertTrue(getattr(table_model, prop) == __file__) diff --git a/scripts/test/SANS/user_file/state_director_test.py b/scripts/test/SANS/user_file/state_director_test.py index 6449633c2316fc1c7614142421028ff56d91a766..061e6db6bf1b9f98721e8aedfd7499f5552e845e 100644 --- a/scripts/test/SANS/user_file/state_director_test.py +++ b/scripts/test/SANS/user_file/state_director_test.py @@ -197,7 +197,7 @@ class UserFileStateDirectorISISTest(unittest.TestCase): if os.path.exists(user_file_path): os.remove(user_file_path) - def test_stat_can_be_crated_from_valid_user_file_and_later_on_reset(self): + def test_stat_can_be_created_from_valid_user_file_and_later_on_reset(self): # Arrange file_information = SANSFileInformationMock(instrument=SANSInstrument.SANS2D, run_number=22024) data_builder = get_data_builder(SANSFacility.ISIS, file_information) diff --git a/scripts/test/SANSCommandInterfaceTest.py b/scripts/test/SANSCommandInterfaceTest.py index fdf744afee5bf6ce4aa59c9bd1aeb5c185b3f21b..397c274d1ce2c2097973c4143c7b55b024eeb1c4 100644 --- a/scripts/test/SANSCommandInterfaceTest.py +++ b/scripts/test/SANSCommandInterfaceTest.py @@ -389,7 +389,7 @@ class TestLARMORCommand(unittest.TestCase): selected_idf = "LARMOR_Definition_NONEXIST.xml" # Act + Assert self.assertFalse(command_iface.LARMOR(selected_idf), - "A non existant idf path should return false") + "A non existent idf path should return false") class TestMaskFile(unittest.TestCase): def test_throws_for_user_file_with_invalid_extension(self): diff --git a/scripts/test/SANSReducerTest.py b/scripts/test/SANSReducerTest.py index 9bb49dfc022b4f690453e795f0cd8710c45e59ea..0aa6c029c2a46fe86022f557399521c866cc68d7 100644 --- a/scripts/test/SANSReducerTest.py +++ b/scripts/test/SANSReducerTest.py @@ -9,7 +9,7 @@ import ISISCommandInterface as ici class TestReductionStateTransferer(unittest.TestCase): def test_that_state_is_transfered(self): """ - This test shows that some state can be transfered between the logic instances + This test shows that some state can be transferred between the logic instances of the ReducerSingelton. """ # 1. Create a ReudcerSingleton and apply the user file settings @@ -20,7 +20,7 @@ class TestReductionStateTransferer(unittest.TestCase): # 2. Change a setting (simulates a gui change) ici.ReductionSingleton().to_Q._use_gravity = False - # 3. Creat a transfer object such that this change is stored when the user file is applied again + # 3. Create a transfer object such that this change is stored when the user file is applied again transfer_state = ReductionStateTransferer() transfer_state.get_copy_of_reducer(ici.ReductionSingleton()) diff --git a/scripts/test/SANSUtilityTest.py b/scripts/test/SANSUtilityTest.py index 68b2d728ed358fe80fa14c9de09a930bf295277b..a10bd3aba508a347ae10278bfcfa133719411d88 100644 --- a/scripts/test/SANSUtilityTest.py +++ b/scripts/test/SANSUtilityTest.py @@ -141,7 +141,7 @@ class SANSUtilityTest(unittest.TestCase): # '>1':[[1, -1]], # just lower bound # '<5':[[-1, 5]], # just upper bound # '<5,8-9': [[-1, 5], [8,9]], - # '1:2:5': [[1,3], [3,5]] # sintax: start, step, stop + # '1:2:5': [[1,3], [3,5]] # syntax: start, step, stop # } # for (k, v) in inputs.items(): @@ -370,7 +370,7 @@ class AddOperationTest(unittest.TestCase): times1 = prop_in1.times times2 = prop_in2.times - # Total time differnce is TIME1 - (TIME2 + extraShift) + # Total time difference is TIME1 - (TIME2 + extraShift) shift = 0.0 if isOverlay: shift = time_duration.total_nanoseconds(DateAndTime(time1)- DateAndTime(time2))/1e9 - extra_time_shift