diff --git a/.gitignore b/.gitignore index 8f718aea18f8228889f4966d3e05d98422a63c57..5a12c9f6778a0f6d3d7e41243a29ccdc903a43d4 100644 --- a/.gitignore +++ b/.gitignore @@ -166,7 +166,7 @@ Desktop.ini .tags .tags_sorted_by_file -Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/LibHelper.h +Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/LibHelper.h # Make sure Third_Party doesn't get checked into the main repository diff --git a/Framework/API/CMakeLists.txt b/Framework/API/CMakeLists.txt index cbaec9de9b5cdf93e075d3f1aab6cf62ee14d592..f847f9e46ddb9db9caf008d904bce4d838d64efd 100644 --- a/Framework/API/CMakeLists.txt +++ b/Framework/API/CMakeLists.txt @@ -18,6 +18,7 @@ set ( SRC_FILES src/ChopperModel.cpp src/Column.cpp src/ColumnFactory.cpp + src/CommonBinsValidator.cpp src/CompositeCatalog.cpp src/CompositeDomainMD.cpp src/CompositeFunction.cpp @@ -45,6 +46,7 @@ set ( SRC_FILES src/FunctionValues.cpp src/GridDomain.cpp src/GridDomain1D.cpp + src/HistogramValidator.cpp src/HistoryItem.cpp src/HistoryView.cpp src/IDomainCreator.cpp @@ -74,7 +76,9 @@ set ( SRC_FILES src/ImplicitFunctionFactory.cpp src/ImplicitFunctionParameterParserFactory.cpp src/ImplicitFunctionParserFactory.cpp + src/IncreasingAxisValidator.cpp src/InstrumentDataService.cpp + src/InstrumentValidator.cpp src/JointDomain.cpp src/LatticeDomain.cpp src/LinearScale.cpp @@ -92,10 +96,11 @@ set ( SRC_FILES src/MultiPeriodGroupWorker.cpp src/MultipleExperimentInfos.cpp src/MultipleFileProperty.cpp + src/NotebookBuilder.cpp + src/NotebookWriter.cpp src/NullCoordTransform.cpp - src/NotebookBuilder.cpp - src/NotebookWriter.cpp src/NumericAxis.cpp + src/NumericAxisValidator.cpp src/ParamFunction.cpp src/ParameterReference.cpp src/ParameterTie.cpp @@ -104,17 +109,20 @@ set ( SRC_FILES src/Projection.cpp src/PropertyManagerDataService.cpp src/PropertyNexus.cpp + src/RawCountValidator.cpp src/RefAxis.cpp src/RemoteJobManagerFactory.cpp src/Run.cpp src/Sample.cpp src/SampleEnvironment.cpp src/SampleShapeValidator.cpp + src/SampleValidator.cpp src/ScopedWorkspace.cpp src/ScriptBuilder.cpp src/ScriptRepository.cpp src/ScriptRepositoryFactory.cpp src/SpectraAxis.cpp + src/SpectraAxisValidator.cpp src/SpectrumDetectorMapping.cpp src/TableRow.cpp src/TextAxis.cpp @@ -125,7 +133,7 @@ set ( SRC_FILES src/WorkspaceHistory.cpp src/WorkspaceOpOverloads.cpp src/WorkspaceProperty.cpp - src/WorkspaceValidators.cpp + src/WorkspaceUnitValidator.cpp ) set ( SRC_UNITY_IGNORE_FILES src/CompositeFunction.cpp @@ -158,6 +166,7 @@ set ( INC_FILES inc/MantidAPI/ChopperModel.h inc/MantidAPI/Column.h inc/MantidAPI/ColumnFactory.h + inc/MantidAPI/CommonBinsValidator.h inc/MantidAPI/CompositeCatalog.h inc/MantidAPI/CompositeDomain.h inc/MantidAPI/CompositeDomainMD.h @@ -189,6 +198,7 @@ set ( INC_FILES inc/MantidAPI/FunctionValues.h inc/MantidAPI/GridDomain.h inc/MantidAPI/GridDomain1D.h + inc/MantidAPI/HistogramValidator.h inc/MantidAPI/HistoryItem.h inc/MantidAPI/HistoryView.h inc/MantidAPI/IAlgorithm.h @@ -242,7 +252,9 @@ set ( INC_FILES inc/MantidAPI/ImplicitFunctionParameterParserFactory.h inc/MantidAPI/ImplicitFunctionParser.h inc/MantidAPI/ImplicitFunctionParserFactory.h + inc/MantidAPI/IncreasingAxisValidator.h inc/MantidAPI/InstrumentDataService.h + inc/MantidAPI/InstrumentValidator.h inc/MantidAPI/Jacobian.h inc/MantidAPI/JointDomain.h inc/MantidAPI/LatticeDomain.h @@ -253,8 +265,9 @@ set ( INC_FILES inc/MantidAPI/MDGeometry.h inc/MantidAPI/MatrixWSIndexCalculator.h inc/MantidAPI/MatrixWorkspace.h - inc/MantidAPI/MatrixWorkspace_fwd.h inc/MantidAPI/MatrixWorkspaceMDIterator.h + inc/MantidAPI/MatrixWorkspaceValidator.h + inc/MantidAPI/MatrixWorkspace_fwd.h inc/MantidAPI/MemoryManager.h inc/MantidAPI/ModeratorModel.h inc/MantidAPI/MultiDomainFunction.h @@ -262,10 +275,11 @@ set ( INC_FILES inc/MantidAPI/MultiPeriodGroupWorker.h inc/MantidAPI/MultipleExperimentInfos.h inc/MantidAPI/MultipleFileProperty.h - inc/MantidAPI/NotebookBuilder.h - inc/MantidAPI/NotebookWriter.h + inc/MantidAPI/NotebookBuilder.h + inc/MantidAPI/NotebookWriter.h inc/MantidAPI/NullCoordTransform.h inc/MantidAPI/NumericAxis.h + inc/MantidAPI/NumericAxisValidator.h inc/MantidAPI/ParamFunction.h inc/MantidAPI/ParameterReference.h inc/MantidAPI/ParameterTie.h @@ -274,12 +288,14 @@ set ( INC_FILES inc/MantidAPI/Projection.h inc/MantidAPI/PropertyManagerDataService.h inc/MantidAPI/PropertyNexus.h + inc/MantidAPI/RawCountValidator.h inc/MantidAPI/RefAxis.h inc/MantidAPI/RemoteJobManagerFactory.h inc/MantidAPI/Run.h inc/MantidAPI/Sample.h inc/MantidAPI/SampleEnvironment.h inc/MantidAPI/SampleShapeValidator.h + inc/MantidAPI/SampleValidator.h inc/MantidAPI/ScopedWorkspace.h inc/MantidAPI/ScriptBuilder.h inc/MantidAPI/ScriptRepository.h @@ -287,6 +303,7 @@ set ( INC_FILES inc/MantidAPI/SingleValueParameter.h inc/MantidAPI/SingleValueParameterParser.h inc/MantidAPI/SpectraAxis.h + inc/MantidAPI/SpectraAxisValidator.h inc/MantidAPI/SpectrumDetectorMapping.h inc/MantidAPI/TableRow.h inc/MantidAPI/TextAxis.h @@ -294,14 +311,14 @@ set ( INC_FILES inc/MantidAPI/VectorParameter.h inc/MantidAPI/VectorParameterParser.h inc/MantidAPI/Workspace.h - inc/MantidAPI/Workspace_fwd.h inc/MantidAPI/WorkspaceFactory.h inc/MantidAPI/WorkspaceGroup.h inc/MantidAPI/WorkspaceGroup_fwd.h inc/MantidAPI/WorkspaceHistory.h inc/MantidAPI/WorkspaceOpOverloads.h inc/MantidAPI/WorkspaceProperty.h - inc/MantidAPI/WorkspaceValidators.h + inc/MantidAPI/WorkspaceUnitValidator.h + inc/MantidAPI/Workspace_fwd.h ) set ( TEST_FILES @@ -317,6 +334,7 @@ set ( TEST_FILES AsynchronousTest.h BinEdgeAxisTest.h BoxControllerTest.h + CommonBinsValidatorTest.h CompositeFunctionTest.h CoordTransformTest.h CostFunctionFactoryTest.h @@ -337,6 +355,7 @@ set ( TEST_FILES FunctionPropertyTest.h FunctionTest.h FunctionValuesTest.h + HistogramValidatorTest.h HistoryItemTest.h HistoryViewTest.h IEventListTest.h @@ -352,6 +371,7 @@ set ( TEST_FILES ImplicitFunctionParserFactoryTest.h IncreasingAxisValidatorTest.h InstrumentDataServiceTest.h + InstrumentValidatorTest.h LatticeDomainTest.h LiveListenerFactoryTest.h LogManagerTest.h @@ -367,6 +387,7 @@ set ( TEST_FILES NotebookBuilderTest.h NotebookWriterTest.h NumericAxisTest.h + NumericAxisValidatorTest.h ParamFunctionAttributeHolderTest.h ParameterReferenceTest.h ParameterTieTest.h @@ -374,14 +395,17 @@ set ( TEST_FILES ProjectionTest.h PropertyManagerDataServiceTest.h PropertyNexusTest.h + RawCountValidatorTest.h RemoteJobManagerFactoryTest.h RunTest.h SampleEnvironmentTest.h SampleShapeValidatorTest.h SampleTest.h + SampleValidatorTest.h ScopedWorkspaceTest.h ScriptBuilderTest.h SpectraAxisTest.h + SpectraAxisValidatorTest.h SpectrumDetectorMappingTest.h TextAxisTest.h VectorParameterParserTest.h @@ -392,6 +416,7 @@ set ( TEST_FILES WorkspaceHistoryTest.h WorkspaceOpOverloadsTest.h WorkspacePropertyTest.h + WorkspaceUnitValidatorTest.h ) set ( GMOCK_TEST_FILES diff --git a/Framework/API/inc/MantidAPI/AlgorithmProxy.h b/Framework/API/inc/MantidAPI/AlgorithmProxy.h index ef45cafbbf59b8bce4303063b7ae87fb6a73fa05..cc2c06272044a8d3aee5889ffdb1da9975de73aa 100644 --- a/Framework/API/inc/MantidAPI/AlgorithmProxy.h +++ b/Framework/API/inc/MantidAPI/AlgorithmProxy.h @@ -116,6 +116,8 @@ public: void setPropertyValue(const std::string &name, const std::string &value); /// Do something after a property was set void afterPropertySet(const std::string &); + /// Make m_properties point to the same PropertyManager as po. + void copyPropertiesFrom(const PropertyManagerOwner &po); //@} void cancel(); diff --git a/Framework/API/inc/MantidAPI/CommonBinsValidator.h b/Framework/API/inc/MantidAPI/CommonBinsValidator.h new file mode 100644 index 0000000000000000000000000000000000000000..491e1fb63f0be05d84dc65edf01712a834195f4b --- /dev/null +++ b/Framework/API/inc/MantidAPI/CommonBinsValidator.h @@ -0,0 +1,52 @@ +#ifndef MANTID_API_COMMONBINSVALIDATOR_H_ +#define MANTID_API_COMMONBINSVALIDATOR_H_ + +#include "MantidAPI/MatrixWorkspaceValidator.h" + +namespace Mantid { +namespace API { + +/** + A validator which provides a <I>TENTATIVE</I> check that a workspace + contains common bins in each spectrum. + For efficiency reasons, it only checks that the first and last spectra have + common bins, so it is important to carry out a full check within the + algorithm itself. + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class MANTID_API_DLL CommonBinsValidator : public MatrixWorkspaceValidator { +public: + /// Gets the type of the validator + std::string getType() const { return "commonbins"; } + /// Clone the current state + Kernel::IValidator_sptr clone() const; + +private: + /// Check for validity + std::string checkValidity(const MatrixWorkspace_sptr &value) const; +}; + +} // namespace API +} // namespace Mantid + +#endif /* MANTID_API_COMMONBINSVALIDATOR_H_ */ \ No newline at end of file diff --git a/Framework/API/inc/MantidAPI/DeprecatedAlgorithm.h b/Framework/API/inc/MantidAPI/DeprecatedAlgorithm.h index 68c8250521e5bb0c2d476a682a009ac44c851898..f48837d236cb6925ef562a70ff597d62b28fc7db 100644 --- a/Framework/API/inc/MantidAPI/DeprecatedAlgorithm.h +++ b/Framework/API/inc/MantidAPI/DeprecatedAlgorithm.h @@ -52,7 +52,7 @@ private: /// Replacement version, -1 indicates latest int m_replacementVersion; /// The date that the algorithm was first deprecated. - std::string m_deprecatdDate; + std::string m_deprecatedDate; }; } // namespace API diff --git a/Framework/API/inc/MantidAPI/HistogramValidator.h b/Framework/API/inc/MantidAPI/HistogramValidator.h new file mode 100644 index 0000000000000000000000000000000000000000..a576d266ab28b1e245530d693cfeb04cb16b4f80 --- /dev/null +++ b/Framework/API/inc/MantidAPI/HistogramValidator.h @@ -0,0 +1,55 @@ +#ifndef MANTID_API_HISTOGRAMVALIDATOR_H_ +#define MANTID_API_HISTOGRAMVALIDATOR_H_ + +#include "MantidAPI/MatrixWorkspaceValidator.h" + +namespace Mantid { +namespace API { + +/** + A validator which checks that a workspace contains histogram data (the + default) or point data as required. + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class MANTID_API_DLL HistogramValidator : public MatrixWorkspaceValidator { +public: + explicit HistogramValidator(const bool &mustBeHistogram = true); + + /// Gets the type of the validator + std::string getType() const { return "histogram"; } + /// Clone the current state + Kernel::IValidator_sptr clone() const; + +private: + /// Check for validity + std::string checkValidity(const MatrixWorkspace_sptr &value) const; + + /// A flag indicating whether this validator requires that the workspace be a + /// histogram (true) or not + const bool m_mustBeHistogram; +}; + +} // namespace API +} // namespace Mantid + +#endif /* MANTID_API_HISTOGRAMVALIDATOR_H_ */ diff --git a/Framework/API/inc/MantidAPI/IncreasingAxisValidator.h b/Framework/API/inc/MantidAPI/IncreasingAxisValidator.h new file mode 100644 index 0000000000000000000000000000000000000000..95965219c77caeaf436903e4c4daba4a470940cd --- /dev/null +++ b/Framework/API/inc/MantidAPI/IncreasingAxisValidator.h @@ -0,0 +1,49 @@ +#ifndef MANTID_API_INCREASINGAXISVALIDATOR_H_ +#define MANTID_API_INCREASINGAXISVALIDATOR_H_ + +#include "MantidAPI/MatrixWorkspaceValidator.h" + +namespace Mantid { +namespace API { + +/** + A validator which checks that the X axis of a workspace is increasing from + left to right. + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class MANTID_API_DLL IncreasingAxisValidator : public MatrixWorkspaceValidator { +public: + /// Get the type of the validator + std::string getType() const { return "IncreasingAxis"; } + /// Clone the current state + Kernel::IValidator_sptr clone() const; + +private: + /// Check for validity + std::string checkValidity(const MatrixWorkspace_sptr &value) const; +}; + +} // namespace API +} // namespace Mantid + +#endif /* MANTID_API_INCREASINGAXISVALIDATOR_H_ */ diff --git a/Framework/API/inc/MantidAPI/InstrumentValidator.h b/Framework/API/inc/MantidAPI/InstrumentValidator.h new file mode 100644 index 0000000000000000000000000000000000000000..3362f8c80ce5ce06cd966bd0bdaab282e7b5d558 --- /dev/null +++ b/Framework/API/inc/MantidAPI/InstrumentValidator.h @@ -0,0 +1,57 @@ +#ifndef MANTID_API_INSTRUMENTVALIDATOR_H_ +#define MANTID_API_INSTRUMENTVALIDATOR_H_ + +#include "MantidAPI/DllConfig.h" +#include "MantidAPI/ExperimentInfo.h" +#include "MantidKernel/TypedValidator.h" + +namespace Mantid { +namespace API { + +class ExperimentInfo; + +/** + A validator which checks that a workspace has a valid instrument. + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class MANTID_API_DLL InstrumentValidator + : public Kernel::TypedValidator<boost::shared_ptr<ExperimentInfo>> { +public: + /// Enumeration describing requirements + enum Requirements { SourcePosition = 0x1, SamplePosition = 0x2 }; + + // The default is historical so I don't break a lot of user code + InstrumentValidator(const unsigned int flags = SamplePosition); + std::string getType() const; + Kernel::IValidator_sptr clone() const; + std::string + checkValidity(const boost::shared_ptr<ExperimentInfo> &value) const; + +private: + unsigned int m_requires; +}; + +} // namespace API +} // namespace Mantid + +#endif /* MANTID_API_INSTRUMENTVALIDATOR_H_ */ diff --git a/Framework/API/inc/MantidAPI/MatrixWorkspaceValidator.h b/Framework/API/inc/MantidAPI/MatrixWorkspaceValidator.h new file mode 100644 index 0000000000000000000000000000000000000000..6c3cbea5d0d74875d1513478d8404ba2a423d307 --- /dev/null +++ b/Framework/API/inc/MantidAPI/MatrixWorkspaceValidator.h @@ -0,0 +1,42 @@ +#ifndef MANTID_API_MATRIXWORKSPACEVALIDATOR_H_ +#define MANTID_API_MATRIXWORKSPACEVALIDATOR_H_ + +#include "MantidAPI/DllConfig.h" +#include "MantidAPI/MatrixWorkspace.h" +#include "MantidKernel/TypedValidator.h" + +namespace Mantid { +namespace API { + +/** + An interface for those validators that require the MatrixWorkspace interface + + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class MANTID_API_DLL MatrixWorkspaceValidator + : public Kernel::TypedValidator<MatrixWorkspace_sptr> {}; + +} // namespace API +} // namespace Mantid + +#endif /* MANTID_API_MATRIXWORKSPACEVALIDATOR_H_ */ \ No newline at end of file diff --git a/Framework/API/inc/MantidAPI/NumericAxisValidator.h b/Framework/API/inc/MantidAPI/NumericAxisValidator.h new file mode 100644 index 0000000000000000000000000000000000000000..e33deb71603395a8004fea88f9a049a9c2a8c14f --- /dev/null +++ b/Framework/API/inc/MantidAPI/NumericAxisValidator.h @@ -0,0 +1,53 @@ +#ifndef MANTID_API_NUMERICAXISVALIDATOR_H_ +#define MANTID_API_NUMERICAXISVALIDATOR_H_ + +#include "MantidAPI/MatrixWorkspaceValidator.h" + +namespace Mantid { +namespace API { + +/** + A validator which checks whether the input workspace has the Numeric data in + the axis. + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class MANTID_API_DLL NumericAxisValidator : public MatrixWorkspaceValidator { +public: + explicit NumericAxisValidator(const int &axisNumber = 1); + + /// Gets the type of the validator + std::string getType() const { return "numericaaxis"; } + /// Clone the current state + Kernel::IValidator_sptr clone() const; + +private: + /// Check for validity + std::string checkValidity(const MatrixWorkspace_sptr &value) const; + /// Axis number to check on, defaults to 1 + const int m_axisNumber; +}; + +} // namespace API +} // namespace Mantid + +#endif /* MANTID_API_NUMERICAXISVALIDATOR_H_ */ diff --git a/Framework/API/inc/MantidAPI/RawCountValidator.h b/Framework/API/inc/MantidAPI/RawCountValidator.h new file mode 100644 index 0000000000000000000000000000000000000000..fe3e2655ee66e7d611a2f2155281e3da5166451f --- /dev/null +++ b/Framework/API/inc/MantidAPI/RawCountValidator.h @@ -0,0 +1,53 @@ +#ifndef MANTID_API_RAWCOUNTVALIDATOR_H_ +#define MANTID_API_RAWCOUNTVALIDATOR_H_ + +#include "MantidAPI/MatrixWorkspaceValidator.h" + +namespace Mantid { +namespace API { + +/** A validator which checks that a workspace contains raw counts in its bins. + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class MANTID_API_DLL RawCountValidator : public MatrixWorkspaceValidator { +public: + explicit RawCountValidator(const bool &mustNotBeDistribution = true); + + /// Gets the type of the validator + std::string getType() const { return "rawcount"; } + /// Clone the current state + Kernel::IValidator_sptr clone() const; + +private: + /// Check for validity + std::string checkValidity(const MatrixWorkspace_sptr &value) const; + + /// A flag indicating whether this validator requires that the workspace must + /// be a distribution (false) or not (true, the default) + const bool m_mustNotBeDistribution; +}; + +} // namespace API +} // namespace Mantid + +#endif /* MANTID_API_RAWCOUNTVALIDATOR_H_ */ diff --git a/Framework/API/inc/MantidAPI/SampleValidator.h b/Framework/API/inc/MantidAPI/SampleValidator.h new file mode 100644 index 0000000000000000000000000000000000000000..38685e032578314d1dad514b881a7df534630b1f --- /dev/null +++ b/Framework/API/inc/MantidAPI/SampleValidator.h @@ -0,0 +1,50 @@ +#ifndef MANTID_API_SAMPLEVALIDATOR_H_ +#define MANTID_API_SAMPLEVALIDATOR_H_ + +#include "MantidAPI/MatrixWorkspaceValidator.h" + +namespace Mantid { +namespace API { + +/** + A validator which checks that sample has the required properties. + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class MANTID_API_DLL SampleValidator : public MatrixWorkspaceValidator { +public: + /// Enumeration describing requirements + enum Requirements { Shape = 0x1, Material = 0x2 }; + + SampleValidator(const unsigned int flags = (Shape | Material)); + std::string getType() const; + Kernel::IValidator_sptr clone() const; + std::string checkValidity(const MatrixWorkspace_sptr &value) const; + +private: + unsigned int m_requires; +}; + +} // namespace API +} // namespace Mantid + +#endif /* MANTID_API_SAMPLEVALIDATOR_H_ */ diff --git a/Framework/API/inc/MantidAPI/SpectraAxisValidator.h b/Framework/API/inc/MantidAPI/SpectraAxisValidator.h new file mode 100644 index 0000000000000000000000000000000000000000..bb96d2e5a3c0ce8784bdb79c94882c1db5472018 --- /dev/null +++ b/Framework/API/inc/MantidAPI/SpectraAxisValidator.h @@ -0,0 +1,53 @@ +#ifndef MANTID_API_SPECTRAAXISVALIDATOR_H_ +#define MANTID_API_SPECTRAAXISVALIDATOR_H_ + +#include "MantidAPI/MatrixWorkspaceValidator.h" + +namespace Mantid { +namespace API { + +/** + A validator which checks whether the input workspace has the Spectra number + in the axis. + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class MANTID_API_DLL SpectraAxisValidator : public MatrixWorkspaceValidator { +public: + explicit SpectraAxisValidator(const int &axisNumber = 1); + + /// Gets the type of the validator + std::string getType() const { return "spectraaxis"; } + /// Clone the current validator + Kernel::IValidator_sptr clone() const; + +private: + /// Check for validity + std::string checkValidity(const MatrixWorkspace_sptr &value) const; + /// Axis number to check on, defaults to 1 + const int m_axisNumber; +}; + +} // namespace API +} // namespace Mantid + +#endif /* MANTID_API_SPECTRAAXISVALIDATOR_H_ */ diff --git a/Framework/API/inc/MantidAPI/WorkspaceUnitValidator.h b/Framework/API/inc/MantidAPI/WorkspaceUnitValidator.h new file mode 100644 index 0000000000000000000000000000000000000000..f4ddf3a9133d3e3434e7c26c3c4510c4a95968e6 --- /dev/null +++ b/Framework/API/inc/MantidAPI/WorkspaceUnitValidator.h @@ -0,0 +1,53 @@ +#ifndef MANTID_API_WORKSPACEUNITVALIDATOR_H_ +#define MANTID_API_WORKSPACEUNITVALIDATOR_H_ + +#include "MantidAPI/MatrixWorkspaceValidator.h" + +namespace Mantid { +namespace API { + +/** + A validator which checks that the unit of the workspace referred to + by a WorkspaceProperty is the expected one. + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class MANTID_API_DLL WorkspaceUnitValidator : public MatrixWorkspaceValidator { +public: + explicit WorkspaceUnitValidator(const std::string &unitID = ""); + /// Gets the type of the validator + std::string getType() const { return "workspaceunit"; } + /// Clone the current state + Kernel::IValidator_sptr clone() const; + +private: + /// Check for validity. + std::string checkValidity(const MatrixWorkspace_sptr &value) const; + + /// The name of the required unit + const std::string m_unitID; +}; + +} // namespace API +} // namespace Mantid + +#endif /* MANTID_API_WORKSPACEUNITVALIDATOR_H_ */ \ No newline at end of file diff --git a/Framework/API/inc/MantidAPI/WorkspaceValidators.h b/Framework/API/inc/MantidAPI/WorkspaceValidators.h deleted file mode 100644 index f6bf5308cb4dac8dd5a9f6e6bc8c5363dcbcdccf..0000000000000000000000000000000000000000 --- a/Framework/API/inc/MantidAPI/WorkspaceValidators.h +++ /dev/null @@ -1,409 +0,0 @@ -#ifndef MANTID_API_WORKSPACEVALIDATORS_H_ -#define MANTID_API_WORKSPACEVALIDATORS_H_ - -//---------------------------------------------------------------------- -// Includes -//---------------------------------------------------------------------- -#include "MantidAPI/MatrixWorkspace.h" -#include "MantidKernel/TypedValidator.h" -#include "MantidKernel/CompositeValidator.h" -#include <numeric> -#include <vector> - -namespace Mantid { -namespace API { - -//=============================================================================================== -/** A validator for workspaces which can contain a number of individual - validators, - all of which must pass for the overall validator to do so. - - @author Russell Taylor, Tessella Support Services plc - @date 16/09/2008 - - Copyright © 2008-2010 ISIS Rutherford Appleton Laboratory, NScD Oak - Ridge National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - - File change history is stored at: <https://github.com/mantidproject/mantid>. - Code Documentation is available at: <http://doxygen.mantidproject.org> -*/ - -//============================================================================================== -/** - * An interface for those validators that require the MatrixWorkspace interface - */ -class MatrixWorkspaceValidator - : public Kernel::TypedValidator<MatrixWorkspace_sptr> {}; - -//=============================================================================================== -/** A validator which checks that the unit of the workspace referred to - * by a WorkspaceProperty is the expected one. - * - * @author Russell Taylor, Tessella Support Services plc - * @date 16/09/2008 - */ -class DLLExport WorkspaceUnitValidator : public MatrixWorkspaceValidator { -public: - /** Constructor - * @param unitID :: The name of the unit that the workspace must have. If - * left empty, - * the validator will simply check that the workspace is not - * unitless. - */ - explicit WorkspaceUnitValidator(const std::string &unitID = "") - : MatrixWorkspaceValidator(), m_unitID(unitID) {} - - /// Gets the type of the validator - std::string getType() const { return "workspaceunit"; } - /// Clone the current state - Kernel::IValidator_sptr clone() const { - return boost::make_shared<WorkspaceUnitValidator>(*this); - } - -private: - /** Checks that the units of the workspace data are declared match any - *required units - * - * @param value :: The workspace to test - * @return A user level description of the error or "" for no error - */ - std::string checkValidity(const MatrixWorkspace_sptr &value) const { - // This effectively checks for single-valued workspaces - if (value->axes() == 0) - return "A single valued workspace has no unit, which is required for " - "this algorithm"; - - Kernel::Unit_const_sptr unit = value->getAxis(0)->unit(); - // If m_unitID is empty it means that the workspace must have units, which - // can be anything - if (m_unitID.empty()) { - return (unit && (!boost::dynamic_pointer_cast<const Kernel::Units::Empty>( - unit)) - ? "" - : "The workspace must have units"); - } - // now check if the units of the workspace is correct - else { - if ((!unit) || (unit->unitID().compare(m_unitID))) { - return "The workspace must have units of " + - m_unitID; //+ "; its unit is: " + unit->caption(); - } else - return ""; - } - } - - /// The name of the required unit - const std::string m_unitID; -}; - -//=============================================================================================== -/** A validator which checks that a workspace contains histogram data (the - *default) - * or point data as required. - * - * @author Russell Taylor, Tessella Support Services plc - * @date 16/09/2008 - */ -class DLLExport HistogramValidator : public MatrixWorkspaceValidator { -public: - /** Constructor - * @param mustBeHistogram :: Flag indicating whether the check is that a - * workspace should - * contain histogram data (true, default) or shouldn't - * (false). - */ - explicit HistogramValidator(const bool &mustBeHistogram = true) - : MatrixWorkspaceValidator(), m_mustBeHistogram(mustBeHistogram) {} - - /// Gets the type of the validator - std::string getType() const { return "histogram"; } - /// Clone the current state - Kernel::IValidator_sptr clone() const { - return boost::make_shared<HistogramValidator>(*this); - } - -private: - /** Checks if the workspace contains a histogram when it shouldn't and - * vice-versa - * @param value :: The workspace to test - * @return A user level description if a problem exists or "" - */ - std::string checkValidity(const MatrixWorkspace_sptr &value) const { - if (m_mustBeHistogram) { - if (value->isHistogramData()) - return ""; - else - return "The workspace must contain histogram data"; - } else { - if (!value->isHistogramData()) - return ""; - else - return "The workspace must not contain histogram data"; - } - } - - /// A flag indicating whether this validator requires that the workspace be a - /// histogram (true) or not - const bool m_mustBeHistogram; -}; - -//=============================================================================================== -/** A validator which checks that a workspace contains raw counts in its bins - * - * @author Russell Taylor, Tessella Support Services plc - * @date 16/09/2008 - */ -class DLLExport RawCountValidator : public MatrixWorkspaceValidator { -public: - /** Constructor - * @param mustNotBeDistribution :: Flag indicating whether the check is that - * a workspace should - * not be a distribution (true, default) or - * should be (false). - */ - RawCountValidator(const bool &mustNotBeDistribution = true) - : m_mustNotBeDistribution(mustNotBeDistribution) {} - - /// Gets the type of the validator - std::string getType() const { return "rawcount"; } - /// Clone the current state - Kernel::IValidator_sptr clone() const { - return boost::make_shared<RawCountValidator>(*this); - } - -private: - /** Checks if the workspace must be a distribution but isn't and vice-versa - * @param value :: The workspace to test - * @return A user level description of any problem that exists or "" no - * problem - */ - std::string checkValidity(const MatrixWorkspace_sptr &value) const { - if (m_mustNotBeDistribution) { - if (!value->isDistribution()) - return ""; - else - return "A workspace containing numbers of counts is required here"; - } else { - if (value->isDistribution()) - return ""; - else - return "A workspace of numbers of counts is not allowed here"; - } - } - - /// A flag indicating whether this validator requires that the workspace must - /// be a distribution (false) or not (true, the default) - const bool m_mustNotBeDistribution; -}; - -//=============================================================================================== -/** A validator which provides a <I>TENTATIVE</I> check that a workspace - *contains - * common bins in each spectrum. - * For efficiency reasons, it only checks that the first and last spectra have - * common bins, so it is important to carry out a full check within the - *algorithm - * itself. - * - * @author Russell Taylor, Tessella Support Services plc - * @date 18/09/2008 - */ -class DLLExport CommonBinsValidator : public MatrixWorkspaceValidator { -public: - /// Gets the type of the validator - std::string getType() const { return "commonbins"; } - /// Clone the current state - Kernel::IValidator_sptr clone() const { - return boost::make_shared<CommonBinsValidator>(*this); - } - -private: - /** Checks that the bin boundaries of each histogram in the workspace are the - * same - * @param value :: The workspace to test - * @return A message for users saying that bins are different, otherwise "" - */ - std::string checkValidity(const MatrixWorkspace_sptr &value) const { - if (!value) - return "Enter an existing workspace"; - if (value->isCommonBins()) - return ""; - else - return "The workspace must have common bin boundaries for all histograms"; - } -}; -//=============================================================================================== -/** A validator which checks whether the input workspace has the Spectra number - * in the axis. - * @author Michael Whitty, STFC - * @date 15/09/2010 - */ -class DLLExport SpectraAxisValidator : public MatrixWorkspaceValidator { -public: - /** Class constructor with parameter. - * @param axisNumber :: set the axis number to validate - */ - SpectraAxisValidator(const int &axisNumber = 1) : m_axisNumber(axisNumber) {} - - /// Gets the type of the validator - std::string getType() const { return "spectraaxis"; } - /// Clone the current validator - Kernel::IValidator_sptr clone() const { - return boost::make_shared<SpectraAxisValidator>(*this); - } - -private: - /** Checks that the axis stated - * @param value :: The workspace to test - * @return A message for users with negative results, otherwise "" - */ - std::string checkValidity(const MatrixWorkspace_sptr &value) const { - Mantid::API::Axis *axis = value->getAxis(m_axisNumber); - if (axis->isSpectra()) - return ""; - else - return "A workspace with axis being Spectra Number is required here."; - } - const int m_axisNumber; ///< axis number to check on, defaults to 1 -}; -//=============================================================================================== -/** A validator which checks whether the input workspace has the Numeric data in - * the axis. - * @author Michael Whitty, STFC - * @date 15/09/2010 - */ -class DLLExport NumericAxisValidator : public MatrixWorkspaceValidator { -public: - /** Class constructor with parameter. - * @param axisNumber :: set the axis number to validate - */ - NumericAxisValidator(const int &axisNumber = 1) : m_axisNumber(axisNumber) {} - - /// Gets the type of the validator - std::string getType() const { return "numericaaxis"; } - /// Clone the current state - Kernel::IValidator_sptr clone() const { - return boost::make_shared<NumericAxisValidator>(*this); - } - -private: - /** Checks that the axis stated - * @param value :: The workspace to test - * @return A message for users with negative results, otherwise "" - */ - std::string checkValidity(const MatrixWorkspace_sptr &value) const { - Mantid::API::Axis *axis = value->getAxis(m_axisNumber); - if (axis->isNumeric()) - return ""; - else - return "A workspace with axis being a Numeric Axis is required here."; - } - const int m_axisNumber; ///< axis number to check on, defaults to 1 -}; - -//=============================================================================================== -/** A validator which checks that a workspace has a valid instrument - * or point data as required. - * - * @author Russell Taylor, Tessella - * @date 17/12/2010 - */ -class DLLExport InstrumentValidator - : public Kernel::TypedValidator<boost::shared_ptr<ExperimentInfo>> { -public: - /// Enumeration describing requirements - enum Requirements { SourcePosition = 0x1, SamplePosition = 0x2 }; - - // The default is historical so I don't break a lot of user code - InstrumentValidator(const unsigned int flags = SamplePosition); - std::string getType() const; - Kernel::IValidator_sptr clone() const; - std::string - checkValidity(const boost::shared_ptr<ExperimentInfo> &value) const; - -private: - unsigned int m_requires; -}; - -//============================================================================== -/** - @class SampleShapeValidator - - A validator which checks that sample has the required properties - */ -class DLLExport SampleValidator : public MatrixWorkspaceValidator { -public: - /// Enumeration describing requirements - enum Requirements { Shape = 0x1, Material = 0x2 }; - - SampleValidator(const unsigned int flags = (Shape | Material)); - std::string getType() const; - Kernel::IValidator_sptr clone() const; - std::string checkValidity(const MatrixWorkspace_sptr &value) const; - -private: - unsigned int m_requires; -}; - -//============================================================================== -/** - @class IncreasingAxisValidator - - A validator which checks that the X axis of a workspace is increasing from - left to right. - - @author Arturs Bekasovs [arturs.bekasovs@stfc.ac.uk] - @date 08/07/2013 - - TODO: Move out to the different file. - */ -class DLLExport IncreasingAxisValidator : public MatrixWorkspaceValidator { -public: - /// Get the type of the validator - std::string getType() const { return "IncreasingAxis"; } - /// Clone the current state - Kernel::IValidator_sptr clone() const { - return boost::make_shared<IncreasingAxisValidator>(*this); - } - -private: - /** - * Checks that X axis is in the right direction. - * - * @param value The workspace to check - * @return "" if is valid, otherwise a user level description of a problem - */ - std::string checkValidity(const MatrixWorkspace_sptr &value) const { - // 0 for X axis - Axis *xAxis = value->getAxis(0); - - // Left-most axis value should be less than the right-most, if ws has - // more than one X axis value - if (xAxis->length() > 1 && - xAxis->getValue(0) >= xAxis->getValue(xAxis->length() - 1)) - return "X axis of the workspace should be increasing from left to " - "right"; - else - return ""; - } -}; - -} // namespace API -} // namespace Mantid - -#endif /* MANTID_API_WORKSPACEVALIDATORS_H_ */ diff --git a/Framework/API/src/Algorithm.cpp b/Framework/API/src/Algorithm.cpp index e95b083c084a4db9beba993a20643fbb9c1f1d85..860a17a3d66cb681fd368d2f87a4f69347f5af71 100644 --- a/Framework/API/src/Algorithm.cpp +++ b/Framework/API/src/Algorithm.cpp @@ -1278,11 +1278,13 @@ bool Algorithm::processGroups() { // ---------- Create all the output workspaces ---------------------------- for (size_t owp = 0; owp < m_pureOutputWorkspaceProps.size(); owp++) { Property *prop = dynamic_cast<Property *>(m_pureOutputWorkspaceProps[owp]); - WorkspaceGroup_sptr outWSGrp = WorkspaceGroup_sptr(new WorkspaceGroup()); - outGroups.push_back(outWSGrp); - // Put the GROUP in the ADS - AnalysisDataService::Instance().addOrReplace(prop->value(), outWSGrp); - outWSGrp->observeADSNotifications(false); + if (prop) { + WorkspaceGroup_sptr outWSGrp = WorkspaceGroup_sptr(new WorkspaceGroup()); + outGroups.push_back(outWSGrp); + // Put the GROUP in the ADS + AnalysisDataService::Instance().addOrReplace(prop->value(), outWSGrp); + outWSGrp->observeADSNotifications(false); + } } // Go through each entry in the input group(s) diff --git a/Framework/API/src/AlgorithmProxy.cpp b/Framework/API/src/AlgorithmProxy.cpp index a400d76b3943ccaab4a31a82474c523b4be6f1b9..c1a77746b23d389a16f10c89c606aaa192430d24 100644 --- a/Framework/API/src/AlgorithmProxy.cpp +++ b/Framework/API/src/AlgorithmProxy.cpp @@ -218,6 +218,17 @@ void AlgorithmProxy::afterPropertySet(const std::string &name) { copyPropertiesFrom(*m_alg); } +/** + * Copy properties from another property manager + * Making sure that the concrete alg is kept in sync + * @param po :: The property manager to copy + */ +void AlgorithmProxy::copyPropertiesFrom(const PropertyManagerOwner &po) { + PropertyManagerOwner::copyPropertiesFrom(po); + createConcreteAlg(true); + m_alg->copyPropertiesFrom(*this); +} + //---------------------------------------------------------------------- // Private methods //---------------------------------------------------------------------- diff --git a/Framework/API/src/CommonBinsValidator.cpp b/Framework/API/src/CommonBinsValidator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..86871c6be5121ffff037b111437adb95d1c73725 --- /dev/null +++ b/Framework/API/src/CommonBinsValidator.cpp @@ -0,0 +1,28 @@ +#include "MantidAPI/CommonBinsValidator.h" +#include "MantidAPI/MatrixWorkspace.h" + +namespace Mantid { +namespace API { + +/// Clone the current state +Kernel::IValidator_sptr CommonBinsValidator::clone() const { + return boost::make_shared<CommonBinsValidator>(*this); +} + +/** Checks that the bin boundaries of each histogram in the workspace are the + * same + * @param value :: The workspace to test + * @return A message for users saying that bins are different, otherwise "" + */ +std::string +CommonBinsValidator::checkValidity(const MatrixWorkspace_sptr &value) const { + if (!value) + return "Enter an existing workspace"; + if (value->isCommonBins()) + return ""; + else + return "The workspace must have common bin boundaries for all histograms"; +} + +} // namespace API +} // namespace Mantid diff --git a/Framework/API/src/DeprecatedAlgorithm.cpp b/Framework/API/src/DeprecatedAlgorithm.cpp index 095b870de6dce2c5493b60e1b42277f86d52a730..804e2e0ca5c0caa89d57d3944d32415fcfd7f188 100644 --- a/Framework/API/src/DeprecatedAlgorithm.cpp +++ b/Framework/API/src/DeprecatedAlgorithm.cpp @@ -13,7 +13,7 @@ Kernel::Logger g_log("DeprecatedAlgorithm"); /// Does nothing other than make the compiler happy. DeprecatedAlgorithm::DeprecatedAlgorithm() - : m_replacementAlgorithm(), m_replacementVersion(-1), m_deprecatdDate() {} + : m_replacementAlgorithm(), m_replacementVersion(-1), m_deprecatedDate() {} /// Does nothing other than make the compiler happy. DeprecatedAlgorithm::~DeprecatedAlgorithm() {} @@ -37,7 +37,7 @@ void DeprecatedAlgorithm::useAlgorithm(const std::string &replacement, /// The date the algorithm was deprecated on void DeprecatedAlgorithm::deprecatedDate(const std::string &date) { - this->m_deprecatdDate = ""; + this->m_deprecatedDate = ""; if (date.empty()) { // TODO warn people that it wasn't set return; @@ -46,7 +46,7 @@ void DeprecatedAlgorithm::deprecatedDate(const std::string &date) { // TODO warn people that it wasn't set return; } - this->m_deprecatdDate = date; + this->m_deprecatedDate = date; } /// This merely prints the deprecation error for people to see. @@ -57,8 +57,8 @@ const std::string DeprecatedAlgorithm::deprecationMsg(const IAlgorithm *algo) { msg << "deprecated"; - if (!this->m_deprecatdDate.empty()) - msg << " (on " << this->m_deprecatdDate << ")"; + if (!this->m_deprecatedDate.empty()) + msg << " (on " << this->m_deprecatedDate << ")"; if (this->m_replacementAlgorithm.empty()) { msg << " and has no replacement."; diff --git a/Framework/API/src/ExperimentInfo.cpp b/Framework/API/src/ExperimentInfo.cpp index 26a61864f6b9927aad85b761c5e985a894de8ce7..3ddd52bfdf0bbefe09fb0864bbf10fd4f1ba0e93 100644 --- a/Framework/API/src/ExperimentInfo.cpp +++ b/Framework/API/src/ExperimentInfo.cpp @@ -1149,7 +1149,7 @@ void ExperimentInfo::readParameterMap(const std::string ¶meterStr) { // if( comp_name == prev_name ) continue; this blocks reading in different // parameters of the same component. RNT // prev_name = comp_name; - const Geometry::IComponent *comp = 0; + const Geometry::IComponent *comp = NULL; if (comp_name.find("detID:") != std::string::npos) { int detID = atoi(comp_name.substr(6).c_str()); comp = instr->getDetector(detID).get(); @@ -1164,8 +1164,7 @@ void ExperimentInfo::readParameterMap(const std::string ¶meterStr) { continue; } } - if (!comp) - continue; + // create parameter's value as a sum of all tokens with index 3 or larger // this allow a parameter's value to contain ";" std::string paramValue = tokens[3]; diff --git a/Framework/API/src/FunctionFactory.cpp b/Framework/API/src/FunctionFactory.cpp index 5d2a0a1aad401f3cebf7326d1219a3edf99798c1..29a5ec54767c1b593c9cf2e3c028f262707968d6 100644 --- a/Framework/API/src/FunctionFactory.cpp +++ b/Framework/API/src/FunctionFactory.cpp @@ -192,6 +192,9 @@ CompositeFunction_sptr FunctionFactoryImpl::createComposite( inputError(expr.str()); } + if (!cfun) + inputError(expr.str()); + for (; it != terms.end(); ++it) { const Expression &term = it->bracketsRemoved(); IFunction_sptr fun; diff --git a/Framework/API/src/HistogramValidator.cpp b/Framework/API/src/HistogramValidator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..603eedde2e6fe60bbc5c401a826780e58732de44 --- /dev/null +++ b/Framework/API/src/HistogramValidator.cpp @@ -0,0 +1,42 @@ +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/MatrixWorkspace.h" + +namespace Mantid { +namespace API { + +/** Constructor + * + * @param mustBeHistogram :: Flag indicating whether the check is that a + * workspace should contain histogram data (true, default) or shouldn't + * (false). + */ +HistogramValidator::HistogramValidator(const bool &mustBeHistogram) + : MatrixWorkspaceValidator(), m_mustBeHistogram(mustBeHistogram) {} + +/// Clone the current state +Kernel::IValidator_sptr HistogramValidator::clone() const { + return boost::make_shared<HistogramValidator>(*this); +} + +/** Checks if the workspace contains a histogram when it shouldn't and + * vice-versa + * @param value :: The workspace to test + * @return A user level description if a problem exists or "" + */ +std::string +HistogramValidator::checkValidity(const MatrixWorkspace_sptr &value) const { + if (m_mustBeHistogram) { + if (value->isHistogramData()) + return ""; + else + return "The workspace must contain histogram data"; + } else { + if (!value->isHistogramData()) + return ""; + else + return "The workspace must not contain histogram data"; + } +} + +} // namespace API +} // namespace Mantid diff --git a/Framework/API/src/IncreasingAxisValidator.cpp b/Framework/API/src/IncreasingAxisValidator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6d653af5335b0494dc6630dadf2bb2d73b9c0449 --- /dev/null +++ b/Framework/API/src/IncreasingAxisValidator.cpp @@ -0,0 +1,34 @@ +#include "MantidAPI/IncreasingAxisValidator.h" +#include "MantidAPI/MatrixWorkspace.h" + +namespace Mantid { +namespace API { + +/// Clone the current state +Kernel::IValidator_sptr IncreasingAxisValidator::clone() const { + return boost::make_shared<IncreasingAxisValidator>(*this); +} + +/** + * Checks that X axis is in the right direction. + * + * @param value The workspace to check + * @return "" if is valid, otherwise a user level description of a problem + */ +std::string IncreasingAxisValidator::checkValidity( + const MatrixWorkspace_sptr &value) const { + // 0 for X axis + Axis *xAxis = value->getAxis(0); + + // Left-most axis value should be less than the right-most, if ws has + // more than one X axis value + if (xAxis->length() > 1 && + xAxis->getValue(0) >= xAxis->getValue(xAxis->length() - 1)) + return "X axis of the workspace should be increasing from left to " + "right"; + else + return ""; +} + +} // namespace API +} // namespace Mantid diff --git a/Framework/API/src/InstrumentValidator.cpp b/Framework/API/src/InstrumentValidator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a8fc0b0e146b71e357a07bae0b4371a9d0610afd --- /dev/null +++ b/Framework/API/src/InstrumentValidator.cpp @@ -0,0 +1,56 @@ +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/ExperimentInfo.h" +#include "MantidKernel/Strings.h" + +namespace Mantid { +namespace API { +using Kernel::Strings::join; + +/** + * Construct a validator with requirements (default = SamplePosition) + * @param flags A combination of flags to specify requirements + */ +InstrumentValidator::InstrumentValidator(const unsigned int flags) + : m_requires(flags) {} + +/** + * @return A string type identifier for the object + */ +std::string InstrumentValidator::getType() const { return "Instrument"; } + +/** + * @return A copy of the current state of the object + */ +Kernel::IValidator_sptr InstrumentValidator::clone() const { + return boost::make_shared<InstrumentValidator>(*this); +} + +/** Checks that the workspace has an instrument defined + * @param value :: The workspace to test + * @return A user-level description if a problem exists or "" + */ +std::string InstrumentValidator::checkValidity( + const boost::shared_ptr<ExperimentInfo> &value) const { + const auto inst = value->getInstrument(); + if (!inst) + return "The workspace must have an instrument defined"; + + std::list<std::string> missing; + if ((m_requires & SourcePosition) && !inst->getSource()) { + missing.emplace_back("source"); + } + if ((m_requires & SamplePosition) && !inst->getSample()) { + missing.emplace_back("sample holder"); + } + + if (missing.empty()) + return ""; + else { + return "The instrument is missing the following " + "components: " + + join(missing.begin(), missing.end(), ","); + } +} + +} // namespace API +} // namespace Mantid diff --git a/Framework/API/src/NumericAxis.cpp b/Framework/API/src/NumericAxis.cpp index 819ad1a5445b13c0a0415db954d2b2650bfe0d60..d609325a2397082f50219cfd5610807e58ae826c 100644 --- a/Framework/API/src/NumericAxis.cpp +++ b/Framework/API/src/NumericAxis.cpp @@ -191,9 +191,9 @@ std::string NumericAxis::label(const std::size_t &index) const { auto it = numberLabel.end() - 1; for (; it != numberLabel.begin(); --it) { if (*it == '0') { - numberLabel.erase(it); + it = numberLabel.erase(it); } else if (*it == '.') { - numberLabel.erase(it); + it = numberLabel.erase(it); break; } else { break; diff --git a/Framework/API/src/NumericAxisValidator.cpp b/Framework/API/src/NumericAxisValidator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1273e248df1b5813a3a7a402a806313b558a2e1c --- /dev/null +++ b/Framework/API/src/NumericAxisValidator.cpp @@ -0,0 +1,32 @@ +#include "MantidAPI/NumericAxisValidator.h" +#include "MantidAPI/MatrixWorkspace.h" + +namespace Mantid { +namespace API { + +/** Class constructor with parameter. + * @param axisNumber :: set the axis number to validate + */ +NumericAxisValidator::NumericAxisValidator(const int &axisNumber) + : m_axisNumber(axisNumber) {} + +/// Clone the current state +Kernel::IValidator_sptr NumericAxisValidator::clone() const { + return boost::make_shared<NumericAxisValidator>(*this); +} + +/** Checks that the axis stated +* @param value :: The workspace to test +* @return A message for users with negative results, otherwise "" +*/ +std::string +NumericAxisValidator::checkValidity(const MatrixWorkspace_sptr &value) const { + Mantid::API::Axis *axis = value->getAxis(m_axisNumber); + if (axis->isNumeric()) + return ""; + else + return "A workspace with axis being a Numeric Axis is required here."; +} + +} // namespace API +} // namespace Mantid diff --git a/Framework/API/src/RawCountValidator.cpp b/Framework/API/src/RawCountValidator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1ab11c81051199aaecd51a7113b999cb187ac811 --- /dev/null +++ b/Framework/API/src/RawCountValidator.cpp @@ -0,0 +1,41 @@ +#include "MantidAPI/RawCountValidator.h" +#include "MantidAPI/MatrixWorkspace.h" + +namespace Mantid { +namespace API { + +/** Constructor + * @param mustNotBeDistribution :: Flag indicating whether the check is that + * a workspace should not be a distribution (true, default) or should be + * (false). + */ +RawCountValidator::RawCountValidator(const bool &mustNotBeDistribution) + : m_mustNotBeDistribution(mustNotBeDistribution) {} + +/// Clone the current state +Kernel::IValidator_sptr RawCountValidator::clone() const { + return boost::make_shared<RawCountValidator>(*this); +} + +/** Checks if the workspace must be a distribution but isn't and vice-versa + * @param value :: The workspace to test + * @return A user level description of any problem that exists or "" no + * problem + */ +std::string +RawCountValidator::checkValidity(const MatrixWorkspace_sptr &value) const { + if (m_mustNotBeDistribution) { + if (!value->isDistribution()) + return ""; + else + return "A workspace containing numbers of counts is required here"; + } else { + if (value->isDistribution()) + return ""; + else + return "A workspace of numbers of counts is not allowed here"; + } +} + +} // namespace API +} // namespace Mantid diff --git a/Framework/API/src/SampleValidator.cpp b/Framework/API/src/SampleValidator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6e85c719da2b27a8c1116a42af84ce2c3f25b81a --- /dev/null +++ b/Framework/API/src/SampleValidator.cpp @@ -0,0 +1,54 @@ +#include "MantidAPI/SampleValidator.h" +#include "MantidAPI/MatrixWorkspace.h" +#include "MantidKernel/Strings.h" + +namespace Mantid { +namespace API { +using Kernel::Strings::join; + +/** + * Construct a validator with a set of requirements + * @param flags A combination of SampleValidator::Requirements flags. Defaults + * to requiring both a shape and material + */ +SampleValidator::SampleValidator(const unsigned int flags) + : m_requires(flags) {} + +/** + * @return A string type identifier for the object + */ +std::string SampleValidator::getType() const { return "Sample"; } + +/** + * @return A copy of the current state of the object + */ +Kernel::IValidator_sptr SampleValidator::clone() const { + return boost::make_shared<SampleValidator>(*this); +} + +/** + * Check if the workspace satisfies the validation requirements + * @param value A pointer to a MatrixWorkspace object + * @return An empty string if the requirements are satisfied otherwise + * a string containing a message indicating the problem(s) + */ +std::string +SampleValidator::checkValidity(const MatrixWorkspace_sptr &value) const { + const auto &shape = value->sample().getShape(); + std::list<std::string> missing; + if ((m_requires & Shape) && !shape.hasValidShape()) + missing.emplace_back("shape"); + const auto &material = shape.material(); + if ((m_requires & Material) && material.name().empty()) + missing.emplace_back("material"); + + if (missing.empty()) + return ""; + else { + return "The sample is missing the following properties: " + + join(missing.begin(), missing.end(), ","); + } +} + +} // namespace API +} // namespace Mantid diff --git a/Framework/API/src/SpectraAxisValidator.cpp b/Framework/API/src/SpectraAxisValidator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..312c8dabd9a2e931fca08b50e51a1828f4bdf0b3 --- /dev/null +++ b/Framework/API/src/SpectraAxisValidator.cpp @@ -0,0 +1,32 @@ +#include "MantidAPI/SpectraAxisValidator.h" +#include "MantidAPI/MatrixWorkspace.h" + +namespace Mantid { +namespace API { + +/** Class constructor with parameter. + * @param axisNumber :: set the axis number to validate + */ +SpectraAxisValidator::SpectraAxisValidator(const int &axisNumber) + : m_axisNumber(axisNumber) {} + +/// Clone the current validator +Kernel::IValidator_sptr SpectraAxisValidator::clone() const { + return boost::make_shared<SpectraAxisValidator>(*this); +} + +/** Checks that the axis stated +* @param value :: The workspace to test +* @return A message for users with negative results, otherwise "" +*/ +std::string +SpectraAxisValidator::checkValidity(const MatrixWorkspace_sptr &value) const { + Mantid::API::Axis *axis = value->getAxis(m_axisNumber); + if (axis->isSpectra()) + return ""; + else + return "A workspace with axis being Spectra Number is required here."; +} + +} // namespace API +} // namespace Mantid diff --git a/Framework/API/src/WorkspaceFactory.cpp b/Framework/API/src/WorkspaceFactory.cpp index e2f890671126a479d732b36c980a5f9a530496d7..2eaca592865c4e520599f043bdb02b4c632c5acd 100644 --- a/Framework/API/src/WorkspaceFactory.cpp +++ b/Framework/API/src/WorkspaceFactory.cpp @@ -86,7 +86,7 @@ WorkspaceFactoryImpl::create(const MatrixWorkspace_const_sptr &parent, return ws; } -/** Initialise a workspace from its parent +/** Initialize a workspace from its parent * This sets values such as title, instrument, units, sample, spectramap. * This does NOT copy any data. * diff --git a/Framework/API/src/WorkspaceHistory.cpp b/Framework/API/src/WorkspaceHistory.cpp index c7bf7a9d6ce737665f837c8f59ac8f0d00afaad1..94bb24122e2785c1ab04d21948990c75739d15ef 100644 --- a/Framework/API/src/WorkspaceHistory.cpp +++ b/Framework/API/src/WorkspaceHistory.cpp @@ -370,7 +370,7 @@ WorkspaceHistory::parseAlgorithmHistory(const std::string &rawData) { // Get the duration getWordsInString(info[EXEC_DUR], dummy, dummy, temp, dummy); double dur = boost::lexical_cast<double>(temp); - if (dur < 0.0) { + if (dur < -1.0) { g_log.warning() << "Error parsing duration in algorithm history entry." << "\n"; dur = -1.0; diff --git a/Framework/API/src/WorkspaceOpOverloads.cpp b/Framework/API/src/WorkspaceOpOverloads.cpp index cfd3595724a9d60b327e5565606e1b504442491d..f29bca1ca5fe27a3bd029a203c5169e2eb8c3897 100644 --- a/Framework/API/src/WorkspaceOpOverloads.cpp +++ b/Framework/API/src/WorkspaceOpOverloads.cpp @@ -5,11 +5,11 @@ #include "MantidAPI/Algorithm.h" #include "MantidAPI/AlgorithmManager.h" #include "MantidKernel/Property.h" -#include "MantidKernel/Exception.h" +//#include "MantidKernel/Exception.h" #include "MantidAPI/MatrixWorkspace.h" #include "MantidAPI/IWorkspaceProperty.h" #include "MantidAPI/WorkspaceFactory.h" -#include "MantidAPI/SpectraAxis.h" +//#include "MantidAPI/SpectraAxis.h" #include "MantidAPI/IMDWorkspace.h" #include "MantidAPI/IMDHistoWorkspace.h" #include "MantidAPI/WorkspaceGroup_fwd.h" @@ -67,30 +67,20 @@ ResultType executeBinaryOperation(const std::string &algorithmName, alg->execute(); - if (alg->isExecuted()) { - // Get the output workspace property - if (child) { - return alg->getProperty("OutputWorkspace"); - } else { - API::Workspace_sptr result = - API::AnalysisDataService::Instance().retrieve( - alg->getPropertyValue("OutputWorkspace")); - return boost::dynamic_pointer_cast<typename ResultType::element_type>( - result); - } - } else { + if (!alg->isExecuted()) { std::string message = "Error while executing operation: " + algorithmName; throw std::runtime_error(message); } - throw Kernel::Exception::NotFoundError( - "Required output workspace property not found on Child Algorithm", - "OutputWorkspace"); - - // Horendous code inclusion to satisfy compilers that all code paths return a - // value - // in reality the above code should either throw or return successfully. - return ResultType(); + // Get the output workspace property + if (child) { + return alg->getProperty("OutputWorkspace"); + } else { + API::Workspace_sptr result = API::AnalysisDataService::Instance().retrieve( + alg->getPropertyValue("OutputWorkspace")); + return boost::dynamic_pointer_cast<typename ResultType::element_type>( + result); + } } template DLLExport MatrixWorkspace_sptr @@ -169,14 +159,12 @@ bool equals(const MatrixWorkspace_sptr lhs, const MatrixWorkspace_sptr rhs, // Rest: use default alg->execute(); - if (alg->isExecuted()) { - return (alg->getPropertyValue("Result") == "Success!"); - } else { + if (!alg->isExecuted()) { std::string message = "Error while executing operation: CheckWorkspacesMatch"; throw std::runtime_error(message); } - return false; + return (alg->getPropertyValue("Result") == "Success!"); } /** Creates a temporary single value workspace the error is set to zero @@ -512,17 +500,18 @@ bool WorkspaceHelpers::matchingBins(const MatrixWorkspace_const_sptr ws1, if (!step) step = 1; for (size_t i = step; i < numHist; i += step) { - const double firstWS = + const double firstWSLoop = std::accumulate(ws1->readX(i).begin(), ws1->readX(i).end(), 0.); - const double secondWS = + const double secondWSLoop = std::accumulate(ws2->readX(i).begin(), ws2->readX(i).end(), 0.); - if (std::abs(firstWS) < 1.0E-7 && std::abs(secondWS) < 1.0E-7) { + if (std::abs(firstWSLoop) < 1.0E-7 && std::abs(secondWSLoop) < 1.0E-7) { for (size_t j = 0; j < ws1->readX(i).size(); j++) { if (std::abs(ws1->readX(i)[j] - ws2->readX(i)[j]) > 1.0E-7) return false; } - } else if (std::abs(firstWS - secondWS) / - std::max<double>(std::abs(firstWS), std::abs(secondWS)) > + } else if (std::abs(firstWSLoop - secondWSLoop) / + std::max<double>(std::abs(firstWSLoop), + std::abs(secondWSLoop)) > 1.0E-7) return false; } diff --git a/Framework/API/src/WorkspaceUnitValidator.cpp b/Framework/API/src/WorkspaceUnitValidator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..23be6cc30aef9f4a7666df856d68da63d3246037 --- /dev/null +++ b/Framework/API/src/WorkspaceUnitValidator.cpp @@ -0,0 +1,57 @@ +#include "MantidAPI/WorkspaceUnitValidator.h" +#include "MantidAPI/MatrixWorkspace.h" +#include "MantidKernel/Unit.h" + +namespace Mantid { +namespace API { + +/** Constructor + * + * @param unitID :: The name of the unit that the workspace must have. If + * left empty, the validator will simply check that the workspace is not + * unitless. + */ +WorkspaceUnitValidator::WorkspaceUnitValidator(const std::string &unitID) + : MatrixWorkspaceValidator(), m_unitID(unitID) {} + +/** + * Clone the current state + */ +Kernel::IValidator_sptr WorkspaceUnitValidator::clone() const { + return boost::make_shared<WorkspaceUnitValidator>(*this); +} + +/** Checks that the units of the workspace data are declared match any + * required units + * + * @param value :: The workspace to test + * @return A user level description of the error or "" for no error + */ +std::string +WorkspaceUnitValidator::checkValidity(const MatrixWorkspace_sptr &value) const { + // This effectively checks for single-valued workspaces + if (value->axes() == 0) + return "A single valued workspace has no unit, which is required for " + "this algorithm"; + + Kernel::Unit_const_sptr unit = value->getAxis(0)->unit(); + // If m_unitID is empty it means that the workspace must have units, which + // can be anything + if (m_unitID.empty()) { + return ( + unit && (!boost::dynamic_pointer_cast<const Kernel::Units::Empty>(unit)) + ? "" + : "The workspace must have units"); + } + // now check if the units of the workspace is correct + else { + if ((!unit) || (unit->unitID().compare(m_unitID))) { + return "The workspace must have units of " + + m_unitID; //+ "; its unit is: " + unit->caption(); + } else + return ""; + } +} + +} // namespace API +} // namespace Mantid diff --git a/Framework/API/src/WorkspaceValidators.cpp b/Framework/API/src/WorkspaceValidators.cpp deleted file mode 100644 index d6d6efa3460f052e0e5ec983e197b4ce63f7618f..0000000000000000000000000000000000000000 --- a/Framework/API/src/WorkspaceValidators.cpp +++ /dev/null @@ -1,107 +0,0 @@ -//------------------------------------------------------------------------------ -// Includes -//------------------------------------------------------------------------------ -#include "MantidAPI/WorkspaceValidators.h" - -namespace Mantid { -using Kernel::Strings::join; - -namespace API { - -//------------------------------------------------------------------------------ -// InstrumentValidator -//------------------------------------------------------------------------------ -/** - * Construct a validator with requirements (default = SamplePosition) - * @param flags A combination of flags to specify requirements - */ -InstrumentValidator::InstrumentValidator(const unsigned int flags) - : m_requires(flags) {} - -/** - * @return A string type identifier for the object - */ -std::string InstrumentValidator::getType() const { return "Instrument"; } - -/** - * @return A copy of the current state of the object - */ -Kernel::IValidator_sptr InstrumentValidator::clone() const { - return boost::make_shared<InstrumentValidator>(*this); -} - -/** Checks that the workspace has an instrument defined - * @param value :: The workspace to test - * @return A user-level description if a problem exists or "" - */ -std::string InstrumentValidator::checkValidity( - const boost::shared_ptr<ExperimentInfo> &value) const { - const auto inst = value->getInstrument(); - if (!inst) - return "The workspace must have an instrument defined"; - - std::list<std::string> missing; - if ((m_requires & SourcePosition) && !inst->getSource()) { - missing.emplace_back("source"); - } - if ((m_requires & SamplePosition) && !inst->getSample()) { - missing.emplace_back("sample holder"); - } - - if (missing.empty()) - return ""; - else { - return "The instrument is missing the following " - "components: " + - join(missing.begin(), missing.end(), ","); - } -} - -//------------------------------------------------------------------------------ -// SampleValidator -//------------------------------------------------------------------------------ -/** - * Construct a validator with a set of requirements - * @param flags A combination of SampleValidator::Requirements flags. Defaults - * to requiring both a shape and material - */ -SampleValidator::SampleValidator(const unsigned int flags) - : m_requires(flags) {} - -/** - * @return A string type identifier for the object - */ -std::string SampleValidator::getType() const { return "Sample"; } - -/** - * @return A copy of the current state of the object - */ -Kernel::IValidator_sptr SampleValidator::clone() const { - return boost::make_shared<SampleValidator>(*this); -} - -/** - * Check if the workspace satisfies the validation requirements - * @param value A pointer to a MatrixWorkspace object - * @return An empty string if the requirements are satisfied otherwise - * a string containing a message indicating the problem(s) - */ -std::string -SampleValidator::checkValidity(const MatrixWorkspace_sptr &value) const { - const auto &shape = value->sample().getShape(); - std::list<std::string> missing; - if ((m_requires & Shape) && !shape.hasValidShape()) - missing.emplace_back("shape"); - const auto &material = shape.material(); - if ((m_requires & Material) && material.name().empty()) - missing.emplace_back("material"); - - if (missing.empty()) - return ""; - else { - return "The sample is missing the following properties: " + - join(missing.begin(), missing.end(), ","); - } -} -} -} diff --git a/Framework/API/test/AlgorithmProxyTest.h b/Framework/API/test/AlgorithmProxyTest.h index 8c50e2e0dcd53e09f3d9ce26df5d78dd7f952dd2..6e8cafd780007d1caedf0087baf6c4936736b8c6 100644 --- a/Framework/API/test/AlgorithmProxyTest.h +++ b/Framework/API/test/AlgorithmProxyTest.h @@ -212,6 +212,30 @@ public: } TS_ASSERT_EQUALS("InputWorkspace", alg->workspaceMethodInputProperty()); } + + void test_copyPropertiesFrom() { + IAlgorithm_sptr alg = + AlgorithmManager::Instance().create("ToyAlgorithmProxy"); + alg->initialize(); + alg->setPropertyValue("prop1", "string"); + alg->setPropertyValue("prop2", "1"); + IAlgorithm_sptr algCopy = + AlgorithmManager::Instance().create("ToyAlgorithmProxy"); + + auto algProxy = boost::dynamic_pointer_cast<AlgorithmProxy>(alg); + auto algCopyProxy = boost::dynamic_pointer_cast<AlgorithmProxy>(algCopy); + algCopyProxy->copyPropertiesFrom(*algProxy); + + int val = boost::lexical_cast<int>(algCopy->getPropertyValue("prop2")); + + TS_ASSERT_EQUALS(val, 1); + + // set another value and check the other value is unaffected + algCopy->setPropertyValue("prop1", "A difference"); + int val2 = boost::lexical_cast<int>(algCopy->getPropertyValue("prop2")); + + TS_ASSERT_EQUALS(val, val2); + } }; #endif /*ALGORITHMPROXYTEST_H_*/ diff --git a/Framework/API/test/CommonBinsValidatorTest.h b/Framework/API/test/CommonBinsValidatorTest.h new file mode 100644 index 0000000000000000000000000000000000000000..da9f44d52b3b905dc3291534d0f5bf2e15849302 --- /dev/null +++ b/Framework/API/test/CommonBinsValidatorTest.h @@ -0,0 +1,60 @@ +#ifndef MANTID_API_COMMONBINSVALIDATORTEST_H_ +#define MANTID_API_COMMONBINSVALIDATORTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidAPI/CommonBinsValidator.h" +#include "MantidTestHelpers/FakeObjects.h" + +using Mantid::API::CommonBinsValidator; + +class CommonBinsValidatorTest : 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 CommonBinsValidatorTest *createSuite() { + return new CommonBinsValidatorTest(); + } + static void destroySuite(CommonBinsValidatorTest *suite) { delete suite; } + + void test_empty() { + auto ws = boost::make_shared<WorkspaceTester>(); + CommonBinsValidator validator; + TS_ASSERT_EQUALS(validator.isValid(ws), ""); + } + + void test_zero_length_bins() { + auto ws = boost::make_shared<WorkspaceTester>(); + ws->init(2, 11, 10); + CommonBinsValidator validator; + TS_ASSERT_EQUALS(validator.isValid(ws), ""); + } + + void test_common_bins() { + auto ws = boost::make_shared<WorkspaceTester>(); + ws->init(3, 11, 10); + for (size_t k = 0; k < 3; ++k) + for (size_t i = 0; i < 11; ++i) { + auto di = double(i); + ws->dataX(k)[i] = di * (1.0 + 0.001 * di); + } + CommonBinsValidator validator; + TS_ASSERT_EQUALS(validator.isValid(ws), ""); + } + + void test_diff_bins() { + auto ws = boost::make_shared<WorkspaceTester>(); + ws->init(3, 11, 10); + for (size_t k = 0; k < 3; ++k) + for (size_t i = 0; i < 11; ++i) { + auto di = double(i + k); + ws->dataX(k)[i] = di * (1.0 + 0.001 * di); + } + CommonBinsValidator validator; + TS_ASSERT_EQUALS( + validator.isValid(ws), + "The workspace must have common bin boundaries for all histograms"); + } +}; + +#endif /* MANTID_API_COMMONBINSVALIDATORTEST_H_ */ diff --git a/Framework/API/test/HistogramValidatorTest.h b/Framework/API/test/HistogramValidatorTest.h new file mode 100644 index 0000000000000000000000000000000000000000..d916627aee046d72a71fbdae5e05ccc7cea69901 --- /dev/null +++ b/Framework/API/test/HistogramValidatorTest.h @@ -0,0 +1,36 @@ +#ifndef MANTID_API_HISTOGRAMVALIDATORTEST_H_ +#define MANTID_API_HISTOGRAMVALIDATORTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidAPI/HistogramValidator.h" +#include "MantidTestHelpers/FakeObjects.h" + +using Mantid::API::HistogramValidator; + +class HistogramValidatorTest : 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 HistogramValidatorTest *createSuite() { + return new HistogramValidatorTest(); + } + static void destroySuite(HistogramValidatorTest *suite) { delete suite; } + + void test_success() { + auto ws = boost::make_shared<WorkspaceTester>(); + ws->init(2, 11, 10); + HistogramValidator validator; + TS_ASSERT_EQUALS(validator.isValid(ws), ""); + } + + void test_fail() { + auto ws = boost::make_shared<WorkspaceTester>(); + ws->init(2, 10, 10); + HistogramValidator validator; + TS_ASSERT_EQUALS(validator.isValid(ws), + "The workspace must contain histogram data"); + } +}; + +#endif /* MANTID_API_HISTOGRAMVALIDATORTEST_H_ */ \ No newline at end of file diff --git a/Framework/API/test/IncreasingAxisValidatorTest.h b/Framework/API/test/IncreasingAxisValidatorTest.h index baca926a97e89efa645552d3684e716eabd55e5d..cb7ca28992fd94fcd3faeff6c5fb3d604b46ea8b 100644 --- a/Framework/API/test/IncreasingAxisValidatorTest.h +++ b/Framework/API/test/IncreasingAxisValidatorTest.h @@ -3,7 +3,7 @@ #include <cxxtest/TestSuite.h> -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/IncreasingAxisValidator.h" #include "MantidTestHelpers/FakeObjects.h" #include "MantidAPI/NumericAxis.h" diff --git a/Framework/API/test/InstrumentValidatorTest.h b/Framework/API/test/InstrumentValidatorTest.h new file mode 100644 index 0000000000000000000000000000000000000000..3edaddca83aa70324e9fa179fae8492a85d41f67 --- /dev/null +++ b/Framework/API/test/InstrumentValidatorTest.h @@ -0,0 +1,49 @@ +#ifndef MANTID_API_INSTRUMENTVALIDATORTEST_H_ +#define MANTID_API_INSTRUMENTVALIDATORTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidAPI/InstrumentValidator.h" +#include "MantidGeometry/Instrument/ObjComponent.h" +#include "MantidTestHelpers/FakeObjects.h" +#include "MantidTestHelpers/ComponentCreationHelper.h" + +using Mantid::API::InstrumentValidator; + +class InstrumentValidatorTest : 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 InstrumentValidatorTest *createSuite() { + return new InstrumentValidatorTest(); + } + static void destroySuite(InstrumentValidatorTest *suite) { delete suite; } + + void test_success() { + auto ws = boost::make_shared<WorkspaceTester>(); + auto instr = + boost::make_shared<Mantid::Geometry::Instrument>("TestInstrument"); + ws->setInstrument(instr); + // Define a sample as a simple sphere + auto sample = new Mantid::Geometry::ObjComponent( + "samplePos", + ComponentCreationHelper::createSphere(0.1, V3D(0, 0, 0), "1"), + instr.get()); + instr->setPos(0.0, 0.0, 0.0); + instr->add(sample); + instr->markAsSamplePos(sample); + + InstrumentValidator validator; + TS_ASSERT_EQUALS(validator.checkValidity(ws), ""); + } + + void test_fail() { + auto ws = boost::make_shared<WorkspaceTester>(); + InstrumentValidator validator; + TS_ASSERT_EQUALS( + validator.checkValidity(ws), + "The instrument is missing the following components: sample holder"); + } +}; + +#endif /* MANTID_API_INSTRUMENTVALIDATORTEST_H_ */ \ No newline at end of file diff --git a/Framework/API/test/NumericAxisValidatorTest.h b/Framework/API/test/NumericAxisValidatorTest.h new file mode 100644 index 0000000000000000000000000000000000000000..d33e9c5948abfbd590e5f38257edaad1d30a5c06 --- /dev/null +++ b/Framework/API/test/NumericAxisValidatorTest.h @@ -0,0 +1,39 @@ +#ifndef MANTID_API_NUMERICAXISVALIDATORTEST_H_ +#define MANTID_API_NUMERICAXISVALIDATORTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidAPI/NumericAxisValidator.h" +#include "MantidTestHelpers/FakeObjects.h" + +using Mantid::API::NumericAxisValidator; + +class NumericAxisValidatorTest : 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 NumericAxisValidatorTest *createSuite() { + return new NumericAxisValidatorTest(); + } + static void destroySuite(NumericAxisValidatorTest *suite) { delete suite; } + + void test_success() { + auto ws = boost::make_shared<WorkspaceTester>(); + ws->init(2, 11, 10); + auto newAxis = new NumericAxis(2); + ws->replaceAxis(1, newAxis); + NumericAxisValidator validator; + TS_ASSERT_EQUALS(validator.isValid(ws), ""); + } + + void test_fail() { + auto ws = boost::make_shared<WorkspaceTester>(); + ws->init(2, 11, 10); + NumericAxisValidator validator; + TS_ASSERT_EQUALS( + validator.isValid(ws), + "A workspace with axis being a Numeric Axis is required here."); + } +}; + +#endif /* MANTID_API_NUMERICAXISVALIDATORTEST_H_ */ \ No newline at end of file diff --git a/Framework/API/test/RawCountValidatorTest.h b/Framework/API/test/RawCountValidatorTest.h new file mode 100644 index 0000000000000000000000000000000000000000..5b8692dcb0d23081a011b69607ffee2fcea4a846 --- /dev/null +++ b/Framework/API/test/RawCountValidatorTest.h @@ -0,0 +1,36 @@ +#ifndef MANTID_API_RAWCOUNTVALIDATORTEST_H_ +#define MANTID_API_RAWCOUNTVALIDATORTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidAPI/RawCountValidator.h" +#include "MantidTestHelpers/FakeObjects.h" + +using Mantid::API::RawCountValidator; + +class RawCountValidatorTest : 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 RawCountValidatorTest *createSuite() { + return new RawCountValidatorTest(); + } + static void destroySuite(RawCountValidatorTest *suite) { delete suite; } + + void test_success() { + auto ws = boost::make_shared<WorkspaceTester>(); + RawCountValidator validator; + TS_ASSERT_EQUALS(validator.isValid(ws), ""); + } + + void test_fail() { + auto ws = boost::make_shared<WorkspaceTester>(); + ws->isDistribution(true); + RawCountValidator validator; + TS_ASSERT_EQUALS( + validator.isValid(ws), + "A workspace containing numbers of counts is required here"); + } +}; + +#endif /* MANTID_API_RAWCOUNTVALIDATORTEST_H_ */ \ No newline at end of file diff --git a/Framework/API/test/SampleValidatorTest.h b/Framework/API/test/SampleValidatorTest.h new file mode 100644 index 0000000000000000000000000000000000000000..abb1dcd897ff8c091f14bddb21d7a754af1bd47c --- /dev/null +++ b/Framework/API/test/SampleValidatorTest.h @@ -0,0 +1,43 @@ +#ifndef MANTID_API_SAMPLEVALIDATORTEST_H_ +#define MANTID_API_SAMPLEVALIDATORTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidAPI/SampleValidator.h" +#include "MantidTestHelpers/FakeObjects.h" +#include "MantidTestHelpers/ComponentCreationHelper.h" + +using Mantid::API::SampleValidator; + +class SampleValidatorTest : 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 SampleValidatorTest *createSuite() { + return new SampleValidatorTest(); + } + static void destroySuite(SampleValidatorTest *suite) { delete suite; } + + void test_fail() { + auto ws = boost::make_shared<WorkspaceTester>(); + ws->init(2, 11, 10); + SampleValidator validator; + TS_ASSERT_EQUALS( + validator.isValid(ws), + "The sample is missing the following properties: shape,material"); + } + + void test_success() { + auto ws = boost::make_shared<WorkspaceTester>(); + auto sphere = ComponentCreationHelper::createSphere(1.0, V3D(), "sphere"); + Mantid::Kernel::Material material( + "stuff", Mantid::PhysicalConstants::NeutronAtom(), 10); + sphere->setMaterial(material); + ws->mutableSample().setShape(*sphere); + + SampleValidator validator; + TS_ASSERT_EQUALS(validator.checkValidity(ws), ""); + } +}; + +#endif /* MANTID_API_SAMPLEVALIDATORTEST_H_ */ \ No newline at end of file diff --git a/Framework/API/test/SpectraAxisValidatorTest.h b/Framework/API/test/SpectraAxisValidatorTest.h new file mode 100644 index 0000000000000000000000000000000000000000..c1cdc4ca28170885f8e9f87a2d32171a73f6d080 --- /dev/null +++ b/Framework/API/test/SpectraAxisValidatorTest.h @@ -0,0 +1,39 @@ +#ifndef MANTID_API_SPECTRAAXISVALIDATORTEST_H_ +#define MANTID_API_SPECTRAAXISVALIDATORTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidAPI/SpectraAxisValidator.h" +#include "MantidTestHelpers/FakeObjects.h" + +using Mantid::API::SpectraAxisValidator; + +class SpectraAxisValidatorTest : 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 SpectraAxisValidatorTest *createSuite() { + return new SpectraAxisValidatorTest(); + } + static void destroySuite(SpectraAxisValidatorTest *suite) { delete suite; } + + void test_fail() { + auto ws = boost::make_shared<WorkspaceTester>(); + ws->init(2, 11, 10); + auto newAxis = new NumericAxis(2); + ws->replaceAxis(1, newAxis); + SpectraAxisValidator validator; + TS_ASSERT_EQUALS( + validator.isValid(ws), + "A workspace with axis being Spectra Number is required here."); + } + + void test_success() { + auto ws = boost::make_shared<WorkspaceTester>(); + ws->init(2, 11, 10); + SpectraAxisValidator validator; + TS_ASSERT_EQUALS(validator.isValid(ws), ""); + } +}; + +#endif /* MANTID_API_SPECTRAAXISVALIDATORTEST_H_ */ \ No newline at end of file diff --git a/Framework/API/test/WorkspaceUnitValidatorTest.h b/Framework/API/test/WorkspaceUnitValidatorTest.h new file mode 100644 index 0000000000000000000000000000000000000000..d2e86987bdd4a6ff7eddbaae445081d3b076fc2f --- /dev/null +++ b/Framework/API/test/WorkspaceUnitValidatorTest.h @@ -0,0 +1,36 @@ +#ifndef MANTID_API_WORKSPACEUNITVALIDATORTEST_H_ +#define MANTID_API_WORKSPACEUNITVALIDATORTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidAPI/WorkspaceUnitValidator.h" +#include "MantidTestHelpers/FakeObjects.h" + +using Mantid::API::WorkspaceUnitValidator; + +class WorkspaceUnitValidatorTest : 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 WorkspaceUnitValidatorTest *createSuite() { + return new WorkspaceUnitValidatorTest(); + } + static void destroySuite(WorkspaceUnitValidatorTest *suite) { delete suite; } + + void test_fail() { + auto ws = boost::make_shared<WorkspaceTester>(); + ws->init(2, 11, 10); + WorkspaceUnitValidator validator; + TS_ASSERT_EQUALS(validator.isValid(ws), "The workspace must have units"); + } + + void test_success() { + auto ws = boost::make_shared<WorkspaceTester>(); + ws->init(2, 11, 10); + ws->getAxis(0)->setUnit("TOF"); + WorkspaceUnitValidator validator; + TS_ASSERT_EQUALS(validator.isValid(ws), ""); + } +}; + +#endif /* MANTID_API_WORKSPACEUNITVALIDATORTEST_H_ */ \ No newline at end of file diff --git a/Framework/Algorithms/CMakeLists.txt b/Framework/Algorithms/CMakeLists.txt index 445f1c602b5a55ebdbf14fe468ff005ace9d28bc..9231a99e1f936d0aeae54af68af3dcbb6cf7b0f6 100644 --- a/Framework/Algorithms/CMakeLists.txt +++ b/Framework/Algorithms/CMakeLists.txt @@ -128,8 +128,10 @@ set ( SRC_FILES src/GenerateEventsFilter.cpp src/GeneratePeaks.cpp src/GeneratePythonScript.cpp + src/GetAllEi.cpp src/GetDetOffsetsMultiPeaks.cpp src/GetDetectorOffsets.cpp + src/GetAllEi.cpp src/GetEi.cpp src/GetEi2.cpp src/GetTimeSeriesLogInformation.cpp @@ -399,6 +401,7 @@ set ( INC_FILES inc/MantidAlgorithms/FixGSASInstrumentFile.h inc/MantidAlgorithms/FlatPlateAbsorption.h inc/MantidAlgorithms/GSLFunctions.h + inc/MantidAlgorithms/GetAllEi.h inc/MantidAlgorithms/GeneralisedSecondDifference.h inc/MantidAlgorithms/GenerateEventsFilter.h inc/MantidAlgorithms/GeneratePeaks.h @@ -684,6 +687,7 @@ set ( TEST_FILES GenerateIPythonNotebookTest.h GeneratePeaksTest.h GeneratePythonScriptTest.h + GetAllEiTest.h GetDetOffsetsMultiPeaksTest.h GetDetectorOffsetsTest.h GetEiTest.h diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateSampleWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateSampleWorkspace.h index 4a74b3b6a95bf4bd3076f123cf20baf15b8ff2ee..cef126ba1c1e1e557da6b0708b2930960bd8d1e4 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CreateSampleWorkspace.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateSampleWorkspace.h @@ -76,6 +76,7 @@ private: double noiseScale); void replaceAll(std::string &str, const std::string &from, const std::string &to); + void addChopperParameters(API::MatrixWorkspace_sptr &ws); /// A pointer to the random number generator Kernel::PseudoRandomNumberGenerator *m_randGen; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/GetAllEi.h b/Framework/Algorithms/inc/MantidAlgorithms/GetAllEi.h new file mode 100644 index 0000000000000000000000000000000000000000..155d8fc2d45d2c6bfa0310962dcfe8cef81e6614 --- /dev/null +++ b/Framework/Algorithms/inc/MantidAlgorithms/GetAllEi.h @@ -0,0 +1,126 @@ +#ifndef MANTID_ALGORITHMS_GETALLEI_H_ +#define MANTID_ALGORITHMS_GETALLEI_H_ + +#include "MantidKernel/System.h" +#include "MantidKernel/cow_ptr.h" +#include "MantidAPI/Algorithm.h" +#include "MantidAPI/MatrixWorkspace.h" +//#include "MantidAPI/IAlgorithm.h" + +namespace Mantid { + +namespace Algorithms { + +/** Estimate all incident energies, used by chopper instrument. + + Copyright © 2008-9 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid>. + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class DLLExport GetAllEi : public API::Algorithm { +public: + GetAllEi(); + virtual ~GetAllEi(){}; + + /// Algorithms name for identification. @see Algorithm::name + virtual const std::string name() const { return "GetAllEi"; }; + /// Algorithm's summary for use in the GUI and help. @see Algorithm::summary + virtual const std::string summary() const { + return "Analyze the chopper logs and the signal registered by the monitors " + "to identify energies used as incident energies in an inelastic " + "experiment."; + } + /// Algorithm's version for identification. @see Algorithm::version + virtual int version() const { return 1; }; + /// Algorithm's category for identification. @see Algorithm::category + virtual const std::string category() const { return "Inelastic"; }; + /// Cross-check properties with each other @see IAlgorithm::validateInputs + virtual std::map<std::string, std::string> validateInputs(); + +private: + // Implement abstract Algorithm methods + void init(); + void exec(); + Kernel::Property *getPLogForProperty(const API::MatrixWorkspace_sptr &inputWS, + const std::string &name); + void setFilterLog(const API::MatrixWorkspace_sptr &inputWS); + // former lambda function exposed as not evry compiler support this yet + bool peakGuess(const API::MatrixWorkspace_sptr &inputWS, size_t index, + double Ei, const std::vector<size_t> &monsRangeMin, + const std::vector<size_t> &monsRangeMax, double &peakPos, + double &peakHeight, double &peakTwoSigma); + +protected: // for testing, private otherwise. + // prepare working workspace with appropriate monitor spectra for fitting + API::MatrixWorkspace_sptr + // prepare matrix workspace to analyze monitor signal + buildWorkspaceToFit(const API::MatrixWorkspace_sptr &inputWS, + size_t &wsIndex0); + + /**Return average time series log value for the appropriately filtered log*/ + double getAvrgLogValue(const API::MatrixWorkspace_sptr &inputWS, + const std::string &propertyName, + std::vector<Kernel::SplittingInterval> &splitter); + /**process logs and retrieve chopper speed and chopper delay*/ + void findChopSpeedAndDelay(const API::MatrixWorkspace_sptr &inputWS, + double &chop_speed, double &chop_delay); + void findGuessOpeningTimes(const std::pair<double, double> &TOF_range, + double ChopDelay, double Period, + std::vector<double> &guess_opening_times); + /**Get energy of monitor peak if one is present*/ + bool findMonitorPeak(const API::MatrixWorkspace_sptr &inputWS, double Ei, + const std::vector<size_t> &monsRangeMin, + const std::vector<size_t> &monsRangeMax, double &energy, + double &height, double &width); + /**Find indexes of each expected peak intervals */ + void findBinRanges(const MantidVec &eBins, const MantidVec &signal, + const std::vector<double> &guess_energies, + double Eresolution, std::vector<size_t> &irangeMin, + std::vector<size_t> &irangeMax, + std::vector<bool> &guessValid); + + size_t calcDerivativeAndCountZeros(const std::vector<double> &bins, + const std::vector<double> &signal, + std::vector<double> &deriv, + std::vector<double> &zeros); + + /// if true, take derivate of the filter log to identify interval when + /// instrument is running. + bool m_FilterWithDerivative; + /// maximal relative peak width to consider acceptable. Defined by minimal + /// instrument resolution + /// and does not exceed 0.08 + double m_min_Eresolution; + // set as half max LET resolution at 20mev at 5e-4 + double m_max_Eresolution; + double m_peakEnergyRatio2reject; + // the value of constant phase shift on the chopper used to calculate + // tof at chopper from recorded delay. + double m_phase; + // internal pointer to access to chopper + boost::shared_ptr<const Geometry::IComponent> m_chopper; + // internal pointer to access log, used for filtering + Kernel::TimeSeriesProperty<double> *m_pFilterLog; +}; + +} // namespace Algorithms +} // namespace Mantid + +#endif /* MANTID_ALGORITHMS_GETALLEI_H_ */ diff --git a/Framework/Algorithms/src/AbsorptionCorrection.cpp b/Framework/Algorithms/src/AbsorptionCorrection.cpp index b80ec8b19e19433f7ec078c2fb612f4b9537d8c9..70903dcf3d193cf3f527a6a774439b6142389e40 100644 --- a/Framework/Algorithms/src/AbsorptionCorrection.cpp +++ b/Framework/Algorithms/src/AbsorptionCorrection.cpp @@ -2,13 +2,15 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/AbsorptionCorrection.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidGeometry/Objects/ShapeFactory.h" -#include "MantidKernel/UnitFactory.h" -#include "MantidKernel/Fast_Exponential.h" -#include "MantidKernel/VectorHelper.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" +#include "MantidKernel/Fast_Exponential.h" #include "MantidKernel/ListValidator.h" +#include "MantidKernel/UnitFactory.h" +#include "MantidKernel/VectorHelper.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/AlignDetectors.cpp b/Framework/Algorithms/src/AlignDetectors.cpp index de941aea91cf913e25be29eb8cb537a740f617e7..742f56343e698b4fae2c524d7927248922e68e0c 100644 --- a/Framework/Algorithms/src/AlignDetectors.cpp +++ b/Framework/Algorithms/src/AlignDetectors.cpp @@ -4,11 +4,13 @@ #include "MantidAlgorithms/AlignDetectors.h" #include "MantidAPI/FileProperty.h" #include "MantidAPI/ITableWorkspace.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/RawCountValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/OffsetsWorkspace.h" -#include "MantidKernel/V3D.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/PhysicalConstants.h" +#include "MantidKernel/V3D.h" #include "MantidKernel/UnitFactory.h" #include <fstream> #include <sstream> @@ -151,7 +153,9 @@ const std::string AlignDetectors::summary() const { } /// (Empty) Constructor -AlignDetectors::AlignDetectors() { this->tofToDmap = NULL; } +AlignDetectors::AlignDetectors() : m_numberOfSpectra(0) { + this->tofToDmap = NULL; +} /// Destructor AlignDetectors::~AlignDetectors() { delete this->tofToDmap; } diff --git a/Framework/Algorithms/src/AnnularRingAbsorption.cpp b/Framework/Algorithms/src/AnnularRingAbsorption.cpp index f38414c7f7ff268684cfba3b1fc1c937479def57..58b80dc9d919f8726012fee0940fa1bd44549655 100644 --- a/Framework/Algorithms/src/AnnularRingAbsorption.cpp +++ b/Framework/Algorithms/src/AnnularRingAbsorption.cpp @@ -1,7 +1,8 @@ #include "MantidAlgorithms/AnnularRingAbsorption.h" #include "MantidAPI/SampleEnvironment.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidGeometry/Instrument/ObjComponent.h" #include "MantidGeometry/Instrument/ReferenceFrame.h" @@ -9,10 +10,11 @@ #include "MantidGeometry/Objects/ShapeFactory.h" #include "MantidKernel/Atom.h" -#include "MantidKernel/NeutronAtom.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/Material.h" #include "MantidKernel/MandatoryValidator.h" +#include "MantidKernel/NeutronAtom.h" #include "MantidKernel/V3D.h" #include <boost/format.hpp> diff --git a/Framework/Algorithms/src/AppendSpectra.cpp b/Framework/Algorithms/src/AppendSpectra.cpp index 4efa279245915d7c63bcb81534a1c786ab5824bd..14cfa7656af6558b06c4743dff44fc79880ebd84 100644 --- a/Framework/Algorithms/src/AppendSpectra.cpp +++ b/Framework/Algorithms/src/AppendSpectra.cpp @@ -1,6 +1,5 @@ #include "MantidAlgorithms/AppendSpectra.h" -#include "MantidKernel/System.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/CommonBinsValidator.h" #include "MantidAPI/WorkspaceOpOverloads.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidKernel/BoundedValidator.h" diff --git a/Framework/Algorithms/src/ApplyDeadTimeCorr.cpp b/Framework/Algorithms/src/ApplyDeadTimeCorr.cpp index dc16356c68ae91486b5b8bd4ef90c9de1f890ca2..e50710997d9036191e5d48c42fd5114e05d33743 100644 --- a/Framework/Algorithms/src/ApplyDeadTimeCorr.cpp +++ b/Framework/Algorithms/src/ApplyDeadTimeCorr.cpp @@ -6,7 +6,6 @@ #include "MantidKernel/TimeSeriesProperty.h" #include "MantidKernel/PropertyWithValue.h" #include "boost/lexical_cast.hpp" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidAPI/ITableWorkspace.h" #include "MantidAPI/TableRow.h" diff --git a/Framework/Algorithms/src/ApplyDetailedBalance.cpp b/Framework/Algorithms/src/ApplyDetailedBalance.cpp index c5fdf2865461f3cc9e980fff8852b5752c050111..6fd2dc79cbd60860112bb005fc02713ebe7cf145 100644 --- a/Framework/Algorithms/src/ApplyDetailedBalance.cpp +++ b/Framework/Algorithms/src/ApplyDetailedBalance.cpp @@ -1,11 +1,12 @@ #include "MantidAlgorithms/ApplyDetailedBalance.h" -#include "MantidKernel/System.h" -#include "MantidKernel/TimeSeriesProperty.h" +#include "MantidAPI/WorkspaceUnitValidator.h" +#include "MantidKernel/CompositeValidator.h" +#include "MantidKernel/PhysicalConstants.h" #include "MantidKernel/PropertyWithValue.h" +#include "MantidKernel/TimeSeriesProperty.h" + #include "boost/lexical_cast.hpp" #include <cmath> -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/PhysicalConstants.h" using std::string; using namespace Mantid::Kernel; diff --git a/Framework/Algorithms/src/ApplyTransmissionCorrection.cpp b/Framework/Algorithms/src/ApplyTransmissionCorrection.cpp index c41ee0b23c4569dd0692bf4cd362b9bc9bac5a09..89a09d77008e3a0969d7715a0a225ee3e7694613 100644 --- a/Framework/Algorithms/src/ApplyTransmissionCorrection.cpp +++ b/Framework/Algorithms/src/ApplyTransmissionCorrection.cpp @@ -2,9 +2,11 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/ApplyTransmissionCorrection.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidAPI/WorkspaceOpOverloads.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/BinaryOperateMasks.cpp b/Framework/Algorithms/src/BinaryOperateMasks.cpp index 4ff720334961749c18cff5412052f3f9e359b3bd..6ebc7dc2068cd3644d46ae35ac4324aaf8069a64 100644 --- a/Framework/Algorithms/src/BinaryOperateMasks.cpp +++ b/Framework/Algorithms/src/BinaryOperateMasks.cpp @@ -1,7 +1,5 @@ #include "MantidAlgorithms/BinaryOperateMasks.h" -#include "MantidKernel/System.h" #include "MantidDataObjects/MaskWorkspace.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidKernel/ListValidator.h" using namespace Mantid::Kernel; diff --git a/Framework/Algorithms/src/CalculateEfficiency.cpp b/Framework/Algorithms/src/CalculateEfficiency.cpp index 24814cd4f45e6d47c872ea6acc54a0875a1e30c7..7dba05e6e247cdcc3fc1c9b450d2fa51d014664e 100644 --- a/Framework/Algorithms/src/CalculateEfficiency.cpp +++ b/Framework/Algorithms/src/CalculateEfficiency.cpp @@ -2,11 +2,10 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/CalculateEfficiency.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/EventList.h" -#include <vector> #include "MantidKernel/BoundedValidator.h" +#include <vector> namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/CalculateFlatBackground.cpp b/Framework/Algorithms/src/CalculateFlatBackground.cpp index 34b3f5a8ba418043878fcef208d96f97c787fa75..3f7be3751b51ef6911c03095757686b99ee99043 100644 --- a/Framework/Algorithms/src/CalculateFlatBackground.cpp +++ b/Framework/Algorithms/src/CalculateFlatBackground.cpp @@ -2,17 +2,18 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/CalculateFlatBackground.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidAPI/WorkspaceOpOverloads.h" #include "MantidAPI/FunctionFactory.h" +#include "MantidAPI/HistogramValidator.h" #include "MantidAPI/IFunction.h" +#include "MantidAPI/WorkspaceOpOverloads.h" +#include "MantidDataObjects/TableWorkspace.h" #include "MantidKernel/ArrayProperty.h" +#include "MantidKernel/ListValidator.h" +#include "MantidKernel/MandatoryValidator.h" #include "MantidKernel/VectorHelper.h" -#include "MantidDataObjects/TableWorkspace.h" #include <algorithm> #include <climits> -#include "MantidKernel/ListValidator.h" -#include "MantidKernel/MandatoryValidator.h" +#include <numeric> #include <boost/lexical_cast.hpp> namespace Mantid { diff --git a/Framework/Algorithms/src/CalculateResolution.cpp b/Framework/Algorithms/src/CalculateResolution.cpp index a0a8980966416a5a744c5026214cf3c2935a9db1..558bdf5db4fd5e9d01bbc1486dabce632990474f 100644 --- a/Framework/Algorithms/src/CalculateResolution.cpp +++ b/Framework/Algorithms/src/CalculateResolution.cpp @@ -1,6 +1,6 @@ #include "MantidAlgorithms/CalculateResolution.h" +#include "MantidAPI/InstrumentValidator.h" #include "MantidAPI/MatrixWorkspace.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidGeometry/IComponent.h" #include "MantidGeometry/Instrument.h" #include "MantidKernel/TimeSeriesProperty.h" diff --git a/Framework/Algorithms/src/CalculateTransmission.cpp b/Framework/Algorithms/src/CalculateTransmission.cpp index 072c2fa66a3840bfccd507170a85fefca3e48a65..752472e915a9f0646ec23e497332e469dbcdbdc2 100644 --- a/Framework/Algorithms/src/CalculateTransmission.cpp +++ b/Framework/Algorithms/src/CalculateTransmission.cpp @@ -3,14 +3,17 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/CalculateTransmission.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/CommonBinsValidator.h" +#include "MantidAPI/FunctionFactory.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/IFunction.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidAPI/WorkspaceOpOverloads.h" #include "MantidKernel/ArrayProperty.h" -#include "MantidKernel/VectorHelper.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/ListValidator.h" -#include "MantidAPI/FunctionFactory.h" -#include "MantidAPI/IFunction.h" +#include "MantidKernel/VectorHelper.h" #include <algorithm> #include <cassert> diff --git a/Framework/Algorithms/src/CalculateTransmissionBeamSpreader.cpp b/Framework/Algorithms/src/CalculateTransmissionBeamSpreader.cpp index 9696ed78ff77fca1a3a11095af172da6a476421b..c397d05a368bbb521b43f21a8e2e88b720b39135 100644 --- a/Framework/Algorithms/src/CalculateTransmissionBeamSpreader.cpp +++ b/Framework/Algorithms/src/CalculateTransmissionBeamSpreader.cpp @@ -2,10 +2,12 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/CalculateTransmissionBeamSpreader.h" -#include "MantidAlgorithms/SumSpectra.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/CommonBinsValidator.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidAPI/WorkspaceOpOverloads.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/ListValidator.h" namespace Mantid { diff --git a/Framework/Algorithms/src/ChopData.cpp b/Framework/Algorithms/src/ChopData.cpp index 3e7fc4fc7bba029f77cb06ddc3e9565e75beb973..28f221746db9966337f4b0c4a113da604ff9fff8 100644 --- a/Framework/Algorithms/src/ChopData.cpp +++ b/Framework/Algorithms/src/ChopData.cpp @@ -1,5 +1,8 @@ #include "MantidAlgorithms/ChopData.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/SpectraAxisValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/MultiThreaded.h" namespace Mantid { diff --git a/Framework/Algorithms/src/ClearInstrumentParameters.cpp b/Framework/Algorithms/src/ClearInstrumentParameters.cpp index 04c3f06953c48b941a9bc5f62214ff9483e010b1..3d906b174ae338f195bfdd2de8f6fd1f06ce8895 100644 --- a/Framework/Algorithms/src/ClearInstrumentParameters.cpp +++ b/Framework/Algorithms/src/ClearInstrumentParameters.cpp @@ -1,6 +1,6 @@ #include "MantidAlgorithms/ClearInstrumentParameters.h" #include "MantidAPI/FileProperty.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/InstrumentValidator.h" #include "MantidGeometry/IComponent.h" #include "MantidGeometry/Instrument.h" #include "MantidGeometry/Instrument/ParameterMap.h" diff --git a/Framework/Algorithms/src/ConjoinWorkspaces.cpp b/Framework/Algorithms/src/ConjoinWorkspaces.cpp index 9084f32bd316c8f5f1d72a90ee4b3bdbdaed0d42..6c9534667016d823b41472bd3e0286bf5c575e80 100644 --- a/Framework/Algorithms/src/ConjoinWorkspaces.cpp +++ b/Framework/Algorithms/src/ConjoinWorkspaces.cpp @@ -2,7 +2,7 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/ConjoinWorkspaces.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/CommonBinsValidator.h" #include "MantidAPI/SpectraAxis.h" namespace Mantid { diff --git a/Framework/Algorithms/src/ConvertAxesToRealSpace.cpp b/Framework/Algorithms/src/ConvertAxesToRealSpace.cpp index 5d3fea10458bb9ce29ab3ae9b86afd8a38b395ca..eb31dc324bc890430ec12db758ff1a343bc1d57b 100644 --- a/Framework/Algorithms/src/ConvertAxesToRealSpace.cpp +++ b/Framework/Algorithms/src/ConvertAxesToRealSpace.cpp @@ -1,5 +1,4 @@ #include "MantidAlgorithms/ConvertAxesToRealSpace.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidAPI/NumericAxis.h" #include "MantidDataObjects/Workspace2D.h" #include "MantidKernel/ListValidator.h" diff --git a/Framework/Algorithms/src/ConvertAxisByFormula.cpp b/Framework/Algorithms/src/ConvertAxisByFormula.cpp index ba63602625758b78e34e024b2f4f0fdc21ff4b87..7ca2d86629a6e93fdfd086a19cc17abc42858a5f 100644 --- a/Framework/Algorithms/src/ConvertAxisByFormula.cpp +++ b/Framework/Algorithms/src/ConvertAxisByFormula.cpp @@ -1,8 +1,9 @@ #include "MantidAlgorithms/ConvertAxisByFormula.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/ListValidator.h" -#include "MantidGeometry/muParser_Silent.h" +#include "MantidAPI/CommonBinsValidator.h" +#include "MantidAPI/IncreasingAxisValidator.h" #include "MantidAPI/RefAxis.h" +#include "MantidGeometry/muParser_Silent.h" +#include "MantidKernel/ListValidator.h" #include "MantidKernel/UnitFactory.h" #include <boost/shared_ptr.hpp> diff --git a/Framework/Algorithms/src/ConvertEmptyToTof.cpp b/Framework/Algorithms/src/ConvertEmptyToTof.cpp index 144171a08a4da4024893ff6003757e3e2ecbf8ee..85319960217c8f758a3a2344eb42e2716224cc89 100644 --- a/Framework/Algorithms/src/ConvertEmptyToTof.cpp +++ b/Framework/Algorithms/src/ConvertEmptyToTof.cpp @@ -3,13 +3,13 @@ //---------------------------------------------------------------------- #include "MantidAlgorithms/ConvertEmptyToTof.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/ArrayProperty.h" +#include "MantidAPI/ConstraintFactory.h" #include "MantidAPI/FunctionFactory.h" #include "MantidAPI/IPeakFunction.h" -#include "MantidAPI/ConstraintFactory.h" -#include "MantidKernel/UnitFactory.h" +#include "MantidAPI/WorkspaceUnitValidator.h" +#include "MantidKernel/ArrayProperty.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/UnitFactory.h" #include <cmath> #include <map> @@ -54,8 +54,7 @@ const std::string ConvertEmptyToTof::category() const { */ void ConvertEmptyToTof::init() { - auto wsValidator = boost::make_shared<CompositeValidator>(); - wsValidator->add<WorkspaceUnitValidator>("Empty"); + auto wsValidator = boost::make_shared<WorkspaceUnitValidator>("Empty"); declareProperty(new WorkspaceProperty<DataObjects::Workspace2D>( "InputWorkspace", "", Direction::Input, wsValidator), "Name of the input workspace"); diff --git a/Framework/Algorithms/src/ConvertFromDistribution.cpp b/Framework/Algorithms/src/ConvertFromDistribution.cpp index 9c881e02b9e957e8c8a3a9877e04535333ec0117..3f39c2030f0f8d8161c19af7879972959907eee7 100644 --- a/Framework/Algorithms/src/ConvertFromDistribution.cpp +++ b/Framework/Algorithms/src/ConvertFromDistribution.cpp @@ -2,8 +2,10 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/ConvertFromDistribution.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/RawCountValidator.h" #include "MantidAPI/WorkspaceOpOverloads.h" +#include "MantidKernel/CompositeValidator.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/ConvertSpectrumAxis.cpp b/Framework/Algorithms/src/ConvertSpectrumAxis.cpp index cfa92ffabf5d20b7c7c6db8102cb6973d002203e..d9cca8541838325f4875209f8c13755c20e3d4b2 100644 --- a/Framework/Algorithms/src/ConvertSpectrumAxis.cpp +++ b/Framework/Algorithms/src/ConvertSpectrumAxis.cpp @@ -2,15 +2,20 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/ConvertSpectrumAxis.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/InstrumentValidator.h" #include "MantidAPI/NumericAxis.h" -#include "MantidKernel/UnitFactory.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidAPI/Run.h" -#include <boost/function.hpp> -#include <boost/bind.hpp> -#include <cfloat> +#include "MantidAPI/SpectraAxisValidator.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/ListValidator.h" +#include "MantidKernel/UnitFactory.h" + +#include <boost/bind.hpp> +#include <boost/function.hpp> + +#include <cfloat> namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/ConvertSpectrumAxis2.cpp b/Framework/Algorithms/src/ConvertSpectrumAxis2.cpp index 58fe670a884249e4395a2a2843925c8b84fdc9e0..fd072bbea71a381fd2ea7299b3ea4a6ea185c3cf 100644 --- a/Framework/Algorithms/src/ConvertSpectrumAxis2.cpp +++ b/Framework/Algorithms/src/ConvertSpectrumAxis2.cpp @@ -2,16 +2,21 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/ConvertSpectrumAxis2.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/InstrumentValidator.h" #include "MantidAPI/NumericAxis.h" +#include "MantidAPI/Run.h" +#include "MantidAPI/SpectraAxisValidator.h" +#include "MantidKernel/CompositeValidator.h" +#include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/ListValidator.h" #include "MantidKernel/UnitConversion.h" #include "MantidKernel/UnitFactory.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidAPI/Run.h" -#include <boost/function.hpp> + #include <boost/bind.hpp> +#include <boost/function.hpp> + #include <cfloat> -#include "MantidKernel/BoundedValidator.h" -#include "MantidKernel/ListValidator.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/ConvertToDistribution.cpp b/Framework/Algorithms/src/ConvertToDistribution.cpp index c5a18d9594af5fe4e71e84111d583476bebeeb61..4c17fe561cb243fe925d45b3794eb1c21f3a4194 100644 --- a/Framework/Algorithms/src/ConvertToDistribution.cpp +++ b/Framework/Algorithms/src/ConvertToDistribution.cpp @@ -2,7 +2,9 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/ConvertToDistribution.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/RawCountValidator.h" +#include "MantidKernel/CompositeValidator.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/ConvertToHistogram.cpp b/Framework/Algorithms/src/ConvertToHistogram.cpp index 37acbb1439ea3462532815b25831d0052ef30db2..d72f63685baa09ea2566efed985846f9240e6430 100644 --- a/Framework/Algorithms/src/ConvertToHistogram.cpp +++ b/Framework/Algorithms/src/ConvertToHistogram.cpp @@ -2,7 +2,6 @@ // Includes //------------------------------------------------------------------------------ #include "MantidAlgorithms/ConvertToHistogram.h" -#include "MantidAPI/WorkspaceValidators.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/ConvertUnits.cpp b/Framework/Algorithms/src/ConvertUnits.cpp index 5a3012b50bf12fd6d09b9c2ec60fa77d618e4450..43d213c3a6c8972cf2592e40755b08aa57766444 100644 --- a/Framework/Algorithms/src/ConvertUnits.cpp +++ b/Framework/Algorithms/src/ConvertUnits.cpp @@ -2,19 +2,24 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/ConvertUnits.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidAPI/AlgorithmFactory.h" +#include "MantidAPI/CommonBinsValidator.h" +#include "MantidAPI/HistogramValidator.h" #include "MantidAPI/Run.h" -#include "MantidKernel/UnitFactory.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidDataObjects/Workspace2D.h" #include "MantidDataObjects/EventWorkspace.h" -#include <boost/function.hpp> +#include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" +#include "MantidKernel/ListValidator.h" +#include "MantidKernel/UnitFactory.h" + #include <boost/bind.hpp> +#include <boost/function.hpp> #include <boost/math/special_functions/fpclassify.hpp> + #include <cfloat> #include <limits> -#include "MantidKernel/BoundedValidator.h" -#include "MantidKernel/ListValidator.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/ConvertUnitsUsingDetectorTable.cpp b/Framework/Algorithms/src/ConvertUnitsUsingDetectorTable.cpp index 33c06ad4900fe13d0916b6ad17ddba9f0de2b792..a97fdd6433e02909ae3d290f4dbba4672ff00575 100644 --- a/Framework/Algorithms/src/ConvertUnitsUsingDetectorTable.cpp +++ b/Framework/Algorithms/src/ConvertUnitsUsingDetectorTable.cpp @@ -1,30 +1,24 @@ #include "MantidAlgorithms/ConvertUnitsUsingDetectorTable.h" +#include "MantidAPI/CommonBinsValidator.h" #include "MantidAPI/ITableWorkspace.h" -#include "MantidDataObjects/TableWorkspace.h" -#include "MantidAPI/AlgorithmFactory.h" +#include "MantidAPI/Run.h" #include "MantidAPI/TableRow.h" +#include "MantidDataObjects/EventWorkspace.h" +#include "MantidDataObjects/TableWorkspace.h" +#include "MantidDataObjects/Workspace2D.h" +#include "MantidKernel/BoundedValidator.h" #include "MantidKernel/ListValidator.h" #include "MantidKernel/UnitFactory.h" -#include "MantidAlgorithms/ConvertUnitsUsingDetectorTable.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidAPI/AlgorithmFactory.h" -#include "MantidAPI/Run.h" -#include "MantidKernel/UnitFactory.h" -#include "MantidDataObjects/Workspace2D.h" -#include "MantidDataObjects/TableWorkspace.h" -#include "MantidDataObjects/EventWorkspace.h" -#include <boost/function.hpp> #include <boost/bind.hpp> +#include <boost/function.hpp> #include <boost/math/special_functions/fpclassify.hpp> + +#include <algorithm> #include <cfloat> #include <limits> -#include <vector> -#include <algorithm> -#include "MantidKernel/BoundedValidator.h" -#include "MantidKernel/ListValidator.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/CopyInstrumentParameters.cpp b/Framework/Algorithms/src/CopyInstrumentParameters.cpp index 2eacc15ba853740c203f3637ffc7799c849f1eb8..61e350ee9654cdd2eb621216924f905a33944665 100644 --- a/Framework/Algorithms/src/CopyInstrumentParameters.cpp +++ b/Framework/Algorithms/src/CopyInstrumentParameters.cpp @@ -2,10 +2,10 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/CopyInstrumentParameters.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidAPI/MemoryManager.h" #include "MantidGeometry/Instrument/ParameterMap.h" +#include <iostream> + namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/CorelliCrossCorrelate.cpp b/Framework/Algorithms/src/CorelliCrossCorrelate.cpp index a6e0cb33adfc00ecba56d322c2c4855662b143b7..75bfd01219154690408f807d50bf75f27aa7cc33 100644 --- a/Framework/Algorithms/src/CorelliCrossCorrelate.cpp +++ b/Framework/Algorithms/src/CorelliCrossCorrelate.cpp @@ -1,10 +1,12 @@ #include "MantidAlgorithms/CorelliCrossCorrelate.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidDataObjects/EventWorkspace.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidGeometry/IComponent.h" +#include "MantidGeometry/muParser_Silent.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/MandatoryValidator.h" #include "MantidKernel/TimeSeriesProperty.h" -#include "MantidGeometry/muParser_Silent.h" namespace Mantid { namespace Algorithms { @@ -168,6 +170,11 @@ void CorelliCrossCorrelate::exec() { // Determine period from chopper frequency. auto motorSpeed = dynamic_cast<TimeSeriesProperty<double> *>( inputWS->run().getProperty("BL9:Chop:Skf4:MotorSpeed")); + if (!motorSpeed) { + throw Exception::NotFoundError( + "Could not find a log value for the motor speed", + "BL9:Chop:Skf4:MotorSpeed"); + } double period = 1e9 / static_cast<double>(motorSpeed->timeAverageValue()); g_log.information() << "Frequency = " << 1e9 / period << "Hz Period = " << period << "ns\n"; diff --git a/Framework/Algorithms/src/CorrectFlightPaths.cpp b/Framework/Algorithms/src/CorrectFlightPaths.cpp index 75608fd98addc548316097cac8d9e5b3730015e7..b6b8cbb2eaf3b3775dc4bf4d1d27eb29e4475e40 100644 --- a/Framework/Algorithms/src/CorrectFlightPaths.cpp +++ b/Framework/Algorithms/src/CorrectFlightPaths.cpp @@ -2,14 +2,14 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/CorrectFlightPaths.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidDataObjects/Workspace2D.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidDataObjects/EventWorkspace.h" -#include "MantidKernel/UnitFactory.h" -#include "MantidKernel/BoundedValidator.h" -#include "MantidKernel/ListValidator.h" +#include "MantidDataObjects/Workspace2D.h" #include "MantidGeometry/Instrument/ComponentHelper.h" #include "MantidGeometry/Instrument/ParameterMap.h" +#include "MantidKernel/CompositeValidator.h" +#include "MantidKernel/UnitFactory.h" #include <cmath> diff --git a/Framework/Algorithms/src/CorrectKiKf.cpp b/Framework/Algorithms/src/CorrectKiKf.cpp index bea4c9556cfbee0bfc0edf9e93a8e7841721c986..44c11cb2c03d2446d3276629a2feb88b2339926d 100644 --- a/Framework/Algorithms/src/CorrectKiKf.cpp +++ b/Framework/Algorithms/src/CorrectKiKf.cpp @@ -2,12 +2,12 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/CorrectKiKf.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidDataObjects/Workspace2D.h" #include "MantidDataObjects/EventWorkspace.h" -#include "MantidKernel/UnitFactory.h" #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/ListValidator.h" +#include "MantidKernel/UnitFactory.h" namespace Mantid { namespace Algorithms { @@ -29,8 +29,7 @@ CorrectKiKf::~CorrectKiKf() {} /// Initialisation method void CorrectKiKf::init() { - auto wsValidator = boost::make_shared<CompositeValidator>(); - wsValidator->add<WorkspaceUnitValidator>("DeltaE"); + auto wsValidator = boost::make_shared<WorkspaceUnitValidator>("DeltaE"); this->declareProperty( new WorkspaceProperty<API::MatrixWorkspace>( diff --git a/Framework/Algorithms/src/CreateCalFileByNames.cpp b/Framework/Algorithms/src/CreateCalFileByNames.cpp index 67e006535d12ca43b1fb4eafdb6e54221b0039fc..5fce447687eb61314466cdaa481a316473960879 100644 --- a/Framework/Algorithms/src/CreateCalFileByNames.cpp +++ b/Framework/Algorithms/src/CreateCalFileByNames.cpp @@ -4,12 +4,13 @@ #include "MantidAlgorithms/CreateCalFileByNames.h" #include "MantidAPI/FileProperty.h" #include "MantidAPI/InstrumentDataService.h" +#include "MantidAPI/InstrumentValidator.h" #include "MantidAPI/MatrixWorkspace.h" #include "MantidAPI/WorkspaceProperty.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/ConfigService.h" + #include <boost/algorithm/string/detail/classification.hpp> #include <boost/algorithm/string/split.hpp> + #include <fstream> #include <queue> diff --git a/Framework/Algorithms/src/CreateDummyCalFile.cpp b/Framework/Algorithms/src/CreateDummyCalFile.cpp index d7c9020aaf9ecfded65339768e765ff11d20f89b..a13e9ba5626e143f39053f6c44d5f3dea6f87ca6 100644 --- a/Framework/Algorithms/src/CreateDummyCalFile.cpp +++ b/Framework/Algorithms/src/CreateDummyCalFile.cpp @@ -111,7 +111,7 @@ void CreateDummyCalFile::exec() { std::string filename = getProperty("CalFilename"); // Plan to overwrite file, so do not check if it exists - bool overwrite = false; + const bool overwrite = false; int number = 0; Progress prog(this, 0.0, 0.8, assemblies.size()); diff --git a/Framework/Algorithms/src/CreateLogTimeCorrection.cpp b/Framework/Algorithms/src/CreateLogTimeCorrection.cpp index 61264770e98c0f19d4d10fa338cb55089cdc61cc..4652655b238a0dd0130e7c75e78c0219e19a592f 100644 --- a/Framework/Algorithms/src/CreateLogTimeCorrection.cpp +++ b/Framework/Algorithms/src/CreateLogTimeCorrection.cpp @@ -2,7 +2,7 @@ #include "MantidAPI/WorkspaceProperty.h" #include "MantidAPI/FileProperty.h" #include "MantidAPI/TableRow.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/InstrumentValidator.h" #include <fstream> diff --git a/Framework/Algorithms/src/CreatePSDBleedMask.cpp b/Framework/Algorithms/src/CreatePSDBleedMask.cpp index 1b5b6df6565838f359379c38f9ac336ebc4675d0..719cc8654ee67f937e723436c004863a442afc04 100644 --- a/Framework/Algorithms/src/CreatePSDBleedMask.cpp +++ b/Framework/Algorithms/src/CreatePSDBleedMask.cpp @@ -2,17 +2,16 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/CreatePSDBleedMask.h" -#include "MantidKernel/MultiThreaded.h" #include "MantidAPI/WorkspaceProperty.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/MultiThreaded.h" #include "MantidKernel/NullValidator.h" #include "MantidGeometry/Instrument/DetectorGroup.h" -#include <map> -#include <list> #include <cfloat> #include <iterator> +#include <list> +#include <map> namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/CreateSampleWorkspace.cpp b/Framework/Algorithms/src/CreateSampleWorkspace.cpp index 8d3585304e8c43cf9d972af12777e7adeb20ae92..4976102fe9062d9729b35fd29b8bb71cf05e25f1 100644 --- a/Framework/Algorithms/src/CreateSampleWorkspace.cpp +++ b/Framework/Algorithms/src/CreateSampleWorkspace.cpp @@ -203,7 +203,6 @@ void CreateSampleWorkspace::exec() { } m_randGen = new Kernel::MersenneTwister(seedValue); } - // Create an instrument with one or more rectangular banks. Instrument_sptr inst = createTestInstrumentRectangular( numBanks, bankPixelWidth, pixelSpacing, bankDistanceFromSample, @@ -221,6 +220,8 @@ void CreateSampleWorkspace::exec() { numBanks * bankPixelWidth * bankPixelWidth, num_bins, xMin, binWidth, bankPixelWidth * bankPixelWidth, inst, functionString, isRandom); } + // add chopper + this->addChopperParameters(ws); // Set the Unit of the X Axis try { @@ -249,6 +250,34 @@ void CreateSampleWorkspace::exec() { setProperty("OutputWorkspace", ws); ; } +/** Add chopper to the existing matrix workspace +@param ws -- shared pointer to existing matrix workspace which has instrument +and chopper + +@returns workspace modified to have Fermi chopper added to it. +*/ +void CreateSampleWorkspace::addChopperParameters( + API::MatrixWorkspace_sptr &ws) { + + auto testInst = ws->getInstrument(); + auto chopper = testInst->getComponentByName("chopper-position"); + + // add chopper parameters + auto ¶mMap = ws->instrumentParameters(); + const std::string description( + "The initial rotation phase of the disk used to calculate the time" + " for neutrons arriving at the chopper according to the formula time = " + "delay + initial_phase/Speed"); + paramMap.add<double>("double", chopper.get(), "initial_phase", -3000., + &description); + paramMap.add<std::string>("string", chopper.get(), "ChopperDelayLog", + "fermi_delay"); + paramMap.add<std::string>("string", chopper.get(), "ChopperSpeedLog", + "fermi_speed"); + paramMap.add<std::string>("string", chopper.get(), "FilterBaseLog", + "is_running"); + paramMap.add<bool>("bool", chopper.get(), "filter_with_derivative", false); +} /** Create histogram workspace */ @@ -479,6 +508,12 @@ Instrument_sptr CreateSampleWorkspace::createTestInstrumentRectangular( testInst->add(source); testInst->markAsSource(source); + // Add chopper + ObjComponent *chopper = new ObjComponent( + "chopper-position", Object_sptr(new Object), testInst.get()); + chopper->setPos(V3D(0.0, 0.0, -0.25 * sourceSampleDistance)); + testInst->add(chopper); + // Define a sample as a simple sphere Object_sptr sampleSphere = createSphere(0.001, V3D(0.0, 0.0, 0.0), "sample-shape"); diff --git a/Framework/Algorithms/src/CreateTransmissionWorkspace.cpp b/Framework/Algorithms/src/CreateTransmissionWorkspace.cpp index 2b7b6da122750c306b499535f4028362fcaf0a29..b18f7639e859f4df8176c559a0cb48f08e565c60 100644 --- a/Framework/Algorithms/src/CreateTransmissionWorkspace.cpp +++ b/Framework/Algorithms/src/CreateTransmissionWorkspace.cpp @@ -1,12 +1,8 @@ #include "MantidAlgorithms/CreateTransmissionWorkspace.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/MandatoryValidator.h" -#include "MantidKernel/ArrayProperty.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidKernel/EnabledWhenProperty.h" -#include "MantidKernel/RebinParamsValidator.h" -#include "MantidKernel/BoundedValidator.h" -#include <boost/make_shared.hpp> + #include <boost/assign/list_of.hpp> using namespace Mantid::Kernel; @@ -48,9 +44,7 @@ const std::string CreateTransmissionWorkspace::category() const { /** Initialize the algorithm's properties. */ void CreateTransmissionWorkspace::init() { - boost::shared_ptr<CompositeValidator> inputValidator = - boost::make_shared<CompositeValidator>(); - inputValidator->add(boost::make_shared<WorkspaceUnitValidator>("TOF")); + auto inputValidator = boost::make_shared<WorkspaceUnitValidator>("TOF"); declareProperty(new WorkspaceProperty<MatrixWorkspace>( "FirstTransmissionRun", "", Direction::Input, diff --git a/Framework/Algorithms/src/CreateTransmissionWorkspaceAuto.cpp b/Framework/Algorithms/src/CreateTransmissionWorkspaceAuto.cpp index f9c02b1c52857b591126eabbd164dd77ee760613..f1800493a048d9f836da08ac1465c0bf0b6b41ca 100644 --- a/Framework/Algorithms/src/CreateTransmissionWorkspaceAuto.cpp +++ b/Framework/Algorithms/src/CreateTransmissionWorkspaceAuto.cpp @@ -9,12 +9,11 @@ *WIKI*/ #include "MantidAlgorithms/CreateTransmissionWorkspaceAuto.h" -#include "MantidKernel/RebinParamsValidator.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/ListValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/BoundedValidator.h" -#include "MantidAPI/AlgorithmManager.h" +#include "MantidKernel/ListValidator.h" +#include "MantidKernel/RebinParamsValidator.h" using namespace Mantid::Kernel; using namespace Mantid::API; diff --git a/Framework/Algorithms/src/CropWorkspace.cpp b/Framework/Algorithms/src/CropWorkspace.cpp index 3107951ca432f29feac24ceccab5fc3f58e8f14e..8f11aeb64f9920361f8da933cf35ab1fed6c1fe5 100644 --- a/Framework/Algorithms/src/CropWorkspace.cpp +++ b/Framework/Algorithms/src/CropWorkspace.cpp @@ -2,12 +2,6 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/CropWorkspace.h" - -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidAPI/NumericAxis.h" -#include "MantidAPI/TextAxis.h" -#include "MantidKernel/VectorHelper.h" -#include "MantidAPI/MemoryManager.h" #include "MantidKernel/BoundedValidator.h" namespace Mantid { diff --git a/Framework/Algorithms/src/CrossCorrelate.cpp b/Framework/Algorithms/src/CrossCorrelate.cpp index 46e222a1a1c6b85958521c285ef290939dd3f5ee..d6d5138ac023799cec4189fdd9c504078c0804dd 100644 --- a/Framework/Algorithms/src/CrossCorrelate.cpp +++ b/Framework/Algorithms/src/CrossCorrelate.cpp @@ -1,14 +1,15 @@ //---------------------------------------------------------------------- // Includes //---------------------------------------------------------------------- - -#include <fstream> -#include <sstream> -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/VectorHelper.h" #include "MantidAlgorithms/CrossCorrelate.h" -#include <numeric> +#include "MantidAPI/RawCountValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" +#include "MantidKernel/VectorHelper.h" + +#include <numeric> +#include <sstream> namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/DetectorEfficiencyCor.cpp b/Framework/Algorithms/src/DetectorEfficiencyCor.cpp index 367403ea41f0f49a24819e644c2cb5ad862f08c9..1f54beb297d1d194a8649c56590e155aebb0b7de 100644 --- a/Framework/Algorithms/src/DetectorEfficiencyCor.cpp +++ b/Framework/Algorithms/src/DetectorEfficiencyCor.cpp @@ -1,11 +1,15 @@ #include "MantidAlgorithms/DetectorEfficiencyCor.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidKernel/Exception.h" #include "MantidKernel/PhysicalConstants.h" +#include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" + #include <algorithm> -#include <functional> #include <cmath> -#include "MantidKernel/BoundedValidator.h" +#include <functional> namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/DetectorEfficiencyCorUser.cpp b/Framework/Algorithms/src/DetectorEfficiencyCorUser.cpp index 8350ba3e3180264519d696f5adf90436c39096df..88085ac6165e01bc82d870d1f087876049b6f9a2 100644 --- a/Framework/Algorithms/src/DetectorEfficiencyCorUser.cpp +++ b/Framework/Algorithms/src/DetectorEfficiencyCorUser.cpp @@ -1,9 +1,10 @@ #include "MantidAlgorithms/DetectorEfficiencyCorUser.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/CompositeValidator.h" #include "MantidGeometry/muParser_Silent.h" -#include <ctime> namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/DetectorEfficiencyVariation.cpp b/Framework/Algorithms/src/DetectorEfficiencyVariation.cpp index 1028ee9ad56469fc4175e35cb8b5f27324185b56..011b562de726798e6589ff05826220931998a34b 100644 --- a/Framework/Algorithms/src/DetectorEfficiencyVariation.cpp +++ b/Framework/Algorithms/src/DetectorEfficiencyVariation.cpp @@ -2,10 +2,10 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/DetectorEfficiencyVariation.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidKernel/BoundedValidator.h" #include <boost/math/special_functions/fpclassify.hpp> -#include "MantidKernel/BoundedValidator.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/DiffractionEventCalibrateDetectors.cpp b/Framework/Algorithms/src/DiffractionEventCalibrateDetectors.cpp index 050b93edf61f6f0828e8575212e2fef0bb6385f9..d1d9cbaf304cecfe0db193f78e39aa8965d55ff0 100644 --- a/Framework/Algorithms/src/DiffractionEventCalibrateDetectors.cpp +++ b/Framework/Algorithms/src/DiffractionEventCalibrateDetectors.cpp @@ -4,27 +4,27 @@ #include "MantidAlgorithms/DiffractionEventCalibrateDetectors.h" #include "MantidAlgorithms/GSLFunctions.h" #include "MantidAPI/FileProperty.h" +#include "MantidAPI/IFunction.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/MatrixWorkspace.h" #include "MantidAPI/TableRow.h" #include "MantidAPI/TextAxis.h" -#include "MantidAPI/IFunction.h" #include "MantidDataObjects/EventList.h" #include "MantidDataObjects/EventWorkspace.h" +#include "MantidDataObjects/GroupingWorkspace.h" #include "MantidDataObjects/Workspace2D.h" #include "MantidGeometry/Instrument/RectangularDetector.h" #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/CPUTimer.h" #include "MantidKernel/Exception.h" #include "MantidKernel/UnitFactory.h" +#include "MantidKernel/BoundedValidator.h" + +#include <Poco/File.h> #include <cmath> #include <numeric> -#include <Poco/File.h> -#include <sstream> #include <fstream> -#include "MantidDataObjects/GroupingWorkspace.h" -#include "MantidAPI/AlgorithmFactory.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/BoundedValidator.h" -#include "MantidAPI/MatrixWorkspace.h" +#include <sstream> namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/DiffractionFocussing2.cpp b/Framework/Algorithms/src/DiffractionFocussing2.cpp index cf0cd5a42c1cb15a7e4aabe38408d5c39eef1977..eee96f03c7f86d667169fe809434f4554daded7a 100644 --- a/Framework/Algorithms/src/DiffractionFocussing2.cpp +++ b/Framework/Algorithms/src/DiffractionFocussing2.cpp @@ -2,21 +2,19 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/DiffractionFocussing2.h" +#include "MantidAPI/Axis.h" #include "MantidAPI/FileProperty.h" #include "MantidAPI/MemoryManager.h" +#include "MantidAPI/ISpectrum.h" +#include "MantidAPI/RawCountValidator.h" #include "MantidAPI/SpectraAxis.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/GroupingWorkspace.h" -#include "MantidDataObjects/Workspace2D.h" -#include "MantidKernel/CPUTimer.h" #include "MantidKernel/VectorHelper.h" -#include "MantidAPI/Axis.h" + #include <cfloat> -#include <fstream> #include <iterator> #include <numeric> -#include "MantidAPI/ISpectrum.h" using namespace Mantid::Kernel; using namespace Mantid::API; @@ -43,9 +41,7 @@ DiffractionFocussing2::~DiffractionFocussing2() {} */ void DiffractionFocussing2::init() { - auto wsValidator = boost::make_shared<CompositeValidator>(); - // wsValidator->add<wsValidator->add>("dSpacing"); - wsValidator->add<API::RawCountValidator>(); + auto wsValidator = boost::make_shared<API::RawCountValidator>(); declareProperty(new API::WorkspaceProperty<MatrixWorkspace>( "InputWorkspace", "", Direction::Input, wsValidator), "A 2D workspace with X values of d-spacing/Q-spacing"); diff --git a/Framework/Algorithms/src/EQSANSResolution.cpp b/Framework/Algorithms/src/EQSANSResolution.cpp index df4eb5d3308435b42f8caae7cffc4293127bdd2d..d2c958d7d5f5e5e2e4716ca97395d08e2c38f148 100644 --- a/Framework/Algorithms/src/EQSANSResolution.cpp +++ b/Framework/Algorithms/src/EQSANSResolution.cpp @@ -2,12 +2,6 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/EQSANSResolution.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidDataObjects/EventWorkspace.h" -#include "MantidDataObjects/EventList.h" -#include "MantidKernel/RebinParamsValidator.h" -#include "MantidKernel/ArrayProperty.h" -#include "MantidKernel/VectorHelper.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/EQSANSTofStructure.cpp b/Framework/Algorithms/src/EQSANSTofStructure.cpp index 0ec55d511661c82fe6c7b5a0635098f570dc569b..d129fb4032dbe0e1c115724342becccd8decd2bb 100644 --- a/Framework/Algorithms/src/EQSANSTofStructure.cpp +++ b/Framework/Algorithms/src/EQSANSTofStructure.cpp @@ -2,12 +2,12 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/EQSANSTofStructure.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/TimeSeriesProperty.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidDataObjects/Events.h" #include "MantidDataObjects/EventList.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidGeometry/Instrument.h" +#include "MantidKernel/TimeSeriesProperty.h" #include <vector> diff --git a/Framework/Algorithms/src/ElasticWindow.cpp b/Framework/Algorithms/src/ElasticWindow.cpp index f6cda7ece96c1971072bf27da87f5412b90f0194..3496acff080b5560b08bd434ff05118829adfebf 100644 --- a/Framework/Algorithms/src/ElasticWindow.cpp +++ b/Framework/Algorithms/src/ElasticWindow.cpp @@ -2,7 +2,7 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/ElasticWindow.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/MandatoryValidator.h" diff --git a/Framework/Algorithms/src/ExtractSpectra.cpp b/Framework/Algorithms/src/ExtractSpectra.cpp index c797b9b7bcc98937545883f26f19445063a055fe..b3530855cb3effad9bb21c1d1760dd0c4eefbbc5 100644 --- a/Framework/Algorithms/src/ExtractSpectra.cpp +++ b/Framework/Algorithms/src/ExtractSpectra.cpp @@ -3,7 +3,6 @@ #include "MantidAPI/MemoryManager.h" #include "MantidAPI/NumericAxis.h" #include "MantidAPI/TextAxis.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/VectorHelper.h" diff --git a/Framework/Algorithms/src/FFT.cpp b/Framework/Algorithms/src/FFT.cpp index f8e6db3c74314b67a7c712256543b0733b55e805..1d6f94e2bf38fe60405370cd002df6453f65d240 100644 --- a/Framework/Algorithms/src/FFT.cpp +++ b/Framework/Algorithms/src/FFT.cpp @@ -172,7 +172,7 @@ void FFT::exec() { // centerShift == true means that the zero on the x axis is assumed to be in // the data centre // at point with index i = ySize/2. If shift == false the zero is at i = 0 - bool centerShift = true; + const bool centerShift = true; API::TextAxis *tAxis = new API::TextAxis(nOut); int iRe = 0; diff --git a/Framework/Algorithms/src/FilterBadPulses.cpp b/Framework/Algorithms/src/FilterBadPulses.cpp index 262111e5bdf0a986eb661f43a985dbb2df12feb4..1a437b32dfc0395a9adaaf9803eb62f6573811ed 100644 --- a/Framework/Algorithms/src/FilterBadPulses.cpp +++ b/Framework/Algorithms/src/FilterBadPulses.cpp @@ -2,17 +2,14 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/FilterBadPulses.h" +#include "MantidAPI/FileProperty.h" #include "MantidDataObjects/EventWorkspace.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/UnitFactory.h" +#include "MantidKernel/BoundedValidator.h" #include "MantidKernel/PhysicalConstants.h" #include "MantidKernel/TimeSeriesProperty.h" -#include "MantidAPI/FileProperty.h" +#include "MantidKernel/UnitFactory.h" #include "MantidKernel/V3D.h" -#include <fstream> -#include "MantidKernel/BoundedValidator.h" - namespace Mantid { namespace Algorithms { // Register the algorithm into the algorithm factory diff --git a/Framework/Algorithms/src/FilterByTime.cpp b/Framework/Algorithms/src/FilterByTime.cpp index 6cdec5b56de6b60379e9459e476a1468508bf91b..474224de5fbae7b709002159704cac3034423921 100644 --- a/Framework/Algorithms/src/FilterByTime.cpp +++ b/Framework/Algorithms/src/FilterByTime.cpp @@ -3,14 +3,10 @@ //---------------------------------------------------------------------- #include "MantidAlgorithms/FilterByTime.h" #include "MantidDataObjects/EventWorkspace.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/UnitFactory.h" -#include "MantidKernel/PhysicalConstants.h" -#include "MantidKernel/DateAndTime.h" -#include "MantidAPI/FileProperty.h" - -#include <fstream> #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/DateAndTime.h" +#include "MantidKernel/PhysicalConstants.h" +#include "MantidKernel/UnitFactory.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/FindCenterOfMassPosition.cpp b/Framework/Algorithms/src/FindCenterOfMassPosition.cpp index 20964f31e5edb860cb8fe394702e34a10fd2bf40..aa74da68d4ec9f51afd070ed185bcbda651b092d 100644 --- a/Framework/Algorithms/src/FindCenterOfMassPosition.cpp +++ b/Framework/Algorithms/src/FindCenterOfMassPosition.cpp @@ -2,17 +2,15 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/FindCenterOfMassPosition.h" -#include "MantidKernel/ArrayProperty.h" -#include "MantidKernel/RebinParamsValidator.h" -#include "MantidKernel/UnitFactory.h" -#include "MantidKernel/PhysicalConstants.h" -#include "MantidKernel/VectorHelper.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" #include "MantidAPI/ITableWorkspace.h" #include "MantidAPI/TableRow.h" -#include <vector> +#include "MantidAPI/WorkspaceUnitValidator.h" +#include "MantidKernel/ArrayProperty.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/NullValidator.h" +#include "MantidKernel/PhysicalConstants.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/FindCenterOfMassPosition2.cpp b/Framework/Algorithms/src/FindCenterOfMassPosition2.cpp index 76bb448c085867c580f713ca6f2cac06bf06b5d0..09fc7ac018094ec8ed1c1efb25daec2819c8529b 100644 --- a/Framework/Algorithms/src/FindCenterOfMassPosition2.cpp +++ b/Framework/Algorithms/src/FindCenterOfMassPosition2.cpp @@ -2,18 +2,16 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/FindCenterOfMassPosition2.h" -#include "MantidKernel/ArrayProperty.h" -#include "MantidKernel/RebinParamsValidator.h" -#include "MantidKernel/UnitFactory.h" -#include "MantidKernel/PhysicalConstants.h" -#include "MantidKernel/VectorHelper.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" #include "MantidAPI/ITableWorkspace.h" #include "MantidAPI/TableRow.h" -#include <vector> +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/EventList.h" +#include "MantidKernel/ArrayProperty.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/PhysicalConstants.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/FindPeakBackground.cpp b/Framework/Algorithms/src/FindPeakBackground.cpp index f5de226028bff2fb6f34e25ccc26c37f68d85f66..047bb0748a29536e74291b11089fd189ca149331 100644 --- a/Framework/Algorithms/src/FindPeakBackground.cpp +++ b/Framework/Algorithms/src/FindPeakBackground.cpp @@ -157,7 +157,7 @@ void FindPeakBackground::exec() { Statistics stats = getStatistics(maskedY); Ymean = stats.mean; Yvariance = stats.standard_deviation * stats.standard_deviation; - Ysigma = std::sqrt((moment4(maskedY, n - l0, Ymean) - + Ysigma = std::sqrt((moment4(maskedY, static_cast<size_t>(xn), Ymean) - (xn - 3.0) / (xn - 1.0) * Yvariance) / xn); MantidVec::const_iterator it = diff --git a/Framework/Algorithms/src/FindPeaks.cpp b/Framework/Algorithms/src/FindPeaks.cpp index 5273c255ad5a789f30717cbfeeecadd6d5e8a8ba..67fd790e406c8bf64bd03f63717d3ab4d602638b 100644 --- a/Framework/Algorithms/src/FindPeaks.cpp +++ b/Framework/Algorithms/src/FindPeaks.cpp @@ -8,7 +8,6 @@ #include "MantidAPI/FunctionFactory.h" #include "MantidAPI/FuncMinimizerFactory.h" #include "MantidAPI/TableRow.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidDataObjects/Workspace2D.h" #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/StartsWithValidator.h" diff --git a/Framework/Algorithms/src/FitPeak.cpp b/Framework/Algorithms/src/FitPeak.cpp index 5a8f34e8eb8dc6a096bccab2c3789419c5e8bac7..831efbb6eeee6d3c66d2fc978891c605bb54ae40 100644 --- a/Framework/Algorithms/src/FitPeak.cpp +++ b/Framework/Algorithms/src/FitPeak.cpp @@ -502,10 +502,19 @@ void FitOneSinglePeak::highBkgdFit() { g_log.warning(outss.str()); size_t numpts = i_maxFitX - i_minFitX; - i_minPeakX += static_cast<size_t>(static_cast<double>(numpts) / 6.); - m_minPeakX = m_dataWS->readX(m_wsIndex)[i_minPeakX]; - i_maxPeakX -= static_cast<size_t>(static_cast<double>(numpts) / 6.); - m_maxPeakX = m_dataWS->readX(m_wsIndex)[i_maxPeakX]; + size_t shift = static_cast<size_t>(static_cast<double>(numpts) / 6.); + i_minPeakX += shift; + auto Xdata = m_dataWS->readX(m_wsIndex); + if (i_minPeakX >= Xdata.size()) + i_minPeakX = Xdata.size() - 1; + m_minPeakX = Xdata[i_minPeakX]; + + if (i_maxPeakX < shift) { + i_maxPeakX = 0; + } else { + i_maxPeakX -= shift; + } + m_maxPeakX = Xdata[i_maxPeakX]; } m_bkgdFunc = fitBackground(m_bkgdFunc); @@ -1288,7 +1297,8 @@ void FitPeak::processProperties() { // Peak range vector<double> peakrange = getProperty("PeakRange"); if (peakrange.size() != 2) { - throw runtime_error("Must enter 2 and only 2 items in fit window. "); + throw runtime_error( + "Must enter 2 and only 2 items for PeakRange in fit window. "); } m_minPeakX = peakrange[0]; m_maxPeakX = peakrange[1]; diff --git a/Framework/Algorithms/src/GetAllEi.cpp b/Framework/Algorithms/src/GetAllEi.cpp new file mode 100644 index 0000000000000000000000000000000000000000..60418d5071ea437e50237e3f826e2d099efadc9e --- /dev/null +++ b/Framework/Algorithms/src/GetAllEi.cpp @@ -0,0 +1,1255 @@ +//---------------------------------------------------------------------- +// Includes +//---------------------------------------------------------------------- +#include <boost/format.hpp> +#include <boost/algorithm/string.hpp> +#include <string> + +#include "MantidAlgorithms/GetAllEi.h" +#include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/FilteredTimeSeriesProperty.h" +#include "MantidKernel/EnabledWhenProperty.h" +#include "MantidKernel/UnitFactory.h" +#include "MantidKernel/Unit.h" +#include "MantidKernel/VectorHelper.h" +#include "MantidDataObjects/TableWorkspace.h" + +namespace Mantid { +namespace Algorithms { + +DECLARE_ALGORITHM(GetAllEi) + +/// Empty default constructor +GetAllEi::GetAllEi() + : Algorithm(), m_FilterWithDerivative(true), + // minimal resolution for all instruments + m_min_Eresolution(0.08), + // half maximal resolution for LET + m_max_Eresolution(0.5e-3), m_peakEnergyRatio2reject(0.1), m_phase(0), + m_chopper(), m_pFilterLog(NULL) {} + +/// Initialization method. +void GetAllEi::init() { + + declareProperty(new API::WorkspaceProperty<API::MatrixWorkspace>( + "Workspace", "", Kernel::Direction::Input), + "The input workspace containing the monitor's spectra " + "measured after the last chopper"); + auto nonNegative = boost::make_shared<Kernel::BoundedValidator<int>>(); + nonNegative->setLower(0); + + declareProperty( + "Monitor1SpecID", EMPTY_INT(), nonNegative, + "The workspace index (ID) of the spectra, containing first monitor's" + " signal to analyze."); + declareProperty( + "Monitor2SpecID", EMPTY_INT(), nonNegative, + "The workspace index (ID) of the spectra, containing second monitor's" + " signal to analyze."); + + declareProperty("ChopperSpeedLog", "Defined in IDF", + "Name of the instrument log, " + "containing chopper angular velocity. If 'Defined in IDF' " + "option is specified, " + "the log name is obtained from the IDF"); + declareProperty( + "ChopperDelayLog", "Defined in IDF", + "Name of the instrument log, " + "containing chopper delay time or chopper phase v.r.t. the pulse time. " + "If 'Defined in IDF' option is specified, " + "the log name is obtained from IDF"); + declareProperty( + "FilterBaseLog", "Defined in IDF", + "Name of the instrument log, " + "with positive values indicating that instrument is running\n " + "and 0 or negative that it is not.\n" + "The log is used to identify time interval to evaluate" + " chopper speed and chopper delay which matter.\n" + "If such log is not present, average log values are calculated " + "within experiment start&end time range."); + declareProperty( + "FilterWithDerivative", true, + "Use derivative of 'FilterBaseLog' " + "rather then log values itself to filter invalid time intervals.\n" + "Invalid values are then the " + "values where the derivative of the log turns zero.\n" + "E.g. the 'proton_chage' log grows for each frame " + "when instrument is counting and is constant otherwise."); + setPropertySettings( + "FilterWithDerivative", + new Kernel::EnabledWhenProperty("FilterBaseLog", + Kernel::ePropertyCriterion::IS_EQUAL_TO, + "Defined in IDF")); + + auto maxInRange = boost::make_shared<Kernel::BoundedValidator<double>>(); + maxInRange->setLower(1.e-6); + maxInRange->setUpper(0.1); + + declareProperty("MaxInstrResolution", 0.0005, maxInRange, + "The maximal energy resolution possible for an " + "instrument at working energies (full width at half " + "maximum). \nPeaks, sharper then " + "this width are rejected. Accepted limits are: 1e^(-6)-0.1"); + + auto minInRange = boost::make_shared<Kernel::BoundedValidator<double>>(); + minInRange->setLower(0.001); + minInRange->setUpper(0.5); + declareProperty( + "MinInstrResolution", 0.08, minInRange, + "The minimal energy resolution possible for an " + "instrument at working energies (full width at half maximum).\n" + "Peaks broader then this width are rejected. Accepted limits are: " + "0.001-0.5"); + + auto peakInRange = boost::make_shared<Kernel::BoundedValidator<double>>(); + peakInRange->setLower(0.0); + minInRange->setUpper(1.); + declareProperty( + "PeaksRatioToReject", 0.1, peakInRange, + "Ratio of a peak energy to the maximal energy among all peaks. " + "If the ratio is lower then the value specified here, " + "peak is treated as insignificant and rejected.\n" + "Accepted limits are:0.0 (All accepted) to 1 -- only one peak \n" + "(or peaks with max and equal intensity) are accepted."); + declareProperty( + "IgnoreSecondMonitor", false, + "Usually peaks are analyzed and accepted " + "only if identified on both monitors. If this property is set to true, " + "only first monitor peaks are analyzed.\n" + "This is debugging option as getEi has to use both monitors."); + + declareProperty( + new API::WorkspaceProperty<API::Workspace>("OutputWorkspace", "", + Kernel::Direction::Output), + "Name of the output matrix workspace, containing single spectra with" + " monitor peaks energies\n" + "together with total intensity within each peak."); +} + +// unnamed namespace for auxiliary file-based compilation units +namespace { + +/**Simple template function to remove invalid data from vector +*@param guessValid -- boolean vector of indicating if each particular guess is +*valid +*@param guess -- vector guess values at input and values with removing +* invalid parameters at output +*/ +template <class T> +void removeInvalidValues(const std::vector<bool> &guessValid, + std::vector<T> &guess) { + std::vector<T> new_guess; + new_guess.reserve(guess.size()); + + for (size_t i = 0; i < guessValid.size(); i++) { + if (guessValid[i]) { + new_guess.push_back(guess[i]); + } + } + new_guess.swap(guess); +} +/**Internal class to contain peak information */ +struct peakKeeper { + double position; + double height; + double sigma; + double energy; + + peakKeeper(double pos, double heigh, double sig) + : position(pos), height(heigh), sigma(sig) { + this->energy = std::sqrt(2 * M_PI) * height * sigma; + } + // to sort peaks + bool operator<(const peakKeeper &str) const { return (energy > str.energy); } +}; + +} // END unnamed namespace for auxiliary file-based compilation units + +/** Executes the algorithm -- found all existing monitor peaks. */ +void GetAllEi::exec() { + // Get pointers to the workspace, parameter map and table + API::MatrixWorkspace_sptr inputWS = getProperty("Workspace"); + m_min_Eresolution = getProperty("MinInstrResolution"); + m_max_Eresolution = getProperty("MaxInstrResolution"); + m_peakEnergyRatio2reject = getProperty("PeaksRatioToReject"); + + ////---> recalculate chopper delay to monitor position: + auto pInstrument = inputWS->getInstrument(); + // auto lastChopPositionComponent = + // pInstrument->getComponentByName("chopper-position"); + // auto chopPoint1 = pInstrument->getChopperPoint(0); ->TODO: BUG! this + // operation loses parameters map. + m_chopper = pInstrument->getComponentByName("chopper-position"); + if (!m_chopper) + throw std::runtime_error("Instrument " + pInstrument->getName() + + " does not have 'chopper-position' component"); + + auto phase = m_chopper->getNumberParameter("initial_phase"); + + if (phase.size() == 0) { + throw std::runtime_error("Can not find initial_phase parameter" + " attached to the chopper-position component"); + } + if (phase.size() > 1) { + throw std::runtime_error( + "Can not deal with multiple phases for initial_phase" + " parameter attached to the chopper-position component"); + } + m_phase = phase[0]; + + this->setFilterLog(inputWS); + + // auto chopPoint1 = pInstrument->getComponentByName("fermi-chopper"); + // auto par = chopPoint1->getDoubleParameter("Delay (us)"); + double chopSpeed, chopDelay; + findChopSpeedAndDelay(inputWS, chopSpeed, chopDelay); + g_log.debug() << boost::str( + boost::format("*Identified avrg ChopSpeed: %8.2f and Delay: %8.2f\n") % + chopSpeed % chopDelay); + + auto moderator = pInstrument->getSource(); + double chopDistance = m_chopper->getDistance( + *moderator); // location[0].distance(moderator->getPos()); + double velocity = chopDistance / chopDelay; + + // build workspace to find monitor's peaks + size_t det1WSIndex; + auto monitorWS = buildWorkspaceToFit(inputWS, det1WSIndex); + + // recalculate delay time from chopper position to monitor position + auto detector1 = inputWS->getDetector(det1WSIndex); + double mon1Distance = detector1->getDistance(*moderator); + double TOF0 = mon1Distance / velocity; + + //--->> below is reserved until full chopper's implementation is available; + // auto nChoppers = pInstrument->getNumberOfChopperPoints(); + // get last chopper. + /* + if( nChoppers==0)throw std::runtime_error("Instrument does not have any + choppers defined"); + + auto lastChopper = pInstrument->getChopperPoint(nChoppers-1); + ///<--------------------------------------------------- + */ + auto baseSpectrum = inputWS->getSpectrum(det1WSIndex); + std::pair<double, double> TOF_range = baseSpectrum->getXDataRange(); + + double Period = + (0.5 * 1.e+6) / chopSpeed; // 0.5 because some choppers open twice. + // Would be nice to have it 1 or 0.5 depending on chopper type, but + // it looks like not enough information on what chopper is available on ws; + std::vector<double> guess_opening; + this->findGuessOpeningTimes(TOF_range, TOF0, Period, guess_opening); + if (guess_opening.size() == 0) { + throw std::runtime_error( + "Can not find any chopper opening time within TOF range: " + + boost::lexical_cast<std::string>(TOF_range.first) + ':' + + boost::lexical_cast<std::string>(TOF_range.second)); + } else { + g_log.debug() << "*Found : " << guess_opening.size() + << " chopper prospective opening within time frame: " + << TOF_range.first << " to: " << TOF_range.second + << std::endl; + g_log.debug() << " Timings are:\n"; + for (size_t i = 0; i < guess_opening.size(); i++) { + g_log.debug() << boost::str(boost::format(" %8.2f; ") % guess_opening[i]); + } + g_log.debug() << std::endl; + } + std::pair<double, double> Mon1_Erange = + monitorWS->getSpectrum(0)->getXDataRange(); + std::pair<double, double> Mon2_Erange = + monitorWS->getSpectrum(1)->getXDataRange(); + double eMin = std::max(Mon1_Erange.first, Mon2_Erange.first); + double eMax = std::min(Mon1_Erange.second, Mon2_Erange.second); + g_log.debug() << boost::str( + boost::format( + "Monitors record data in energy range Emin=%8.2f; Emax=%8.2f\n") % + eMin % eMax); + + // convert to energy + std::vector<double> guess_ei; + guess_ei.reserve(guess_opening.size()); + double unused(0.0); + auto destUnit = Kernel::UnitFactory::Instance().create("Energy"); + destUnit->initialize(mon1Distance, 0., 0., + static_cast<int>(Kernel::DeltaEMode::Elastic), 0., + unused); + for (size_t i = 0; i < guess_opening.size(); i++) { + double eGuess = destUnit->singleFromTOF(guess_opening[i]); + if (eGuess > eMin && eGuess < eMax) { + guess_ei.push_back(eGuess); + } + } + g_log.debug() << "*From all chopper opening only: " + + boost::lexical_cast<std::string>(guess_ei.size()) + + " fell within both monitor's recording energy range\n"; + g_log.debug() << " Guess Energies are:\n"; + for (size_t i = 0; i < guess_ei.size(); i++) { + g_log.debug() << boost::str(boost::format(" %8.2f; ") % guess_ei[i]); + } + g_log.debug() << std::endl; + + std::sort(guess_ei.begin(), guess_ei.end()); + + std::vector<size_t> irange_min, irange_max; + std::vector<bool> guessValid; + // preprocess first monitors peaks; + g_log.debug() << "*Looking for real energy peaks on first monitor\n"; + findBinRanges(monitorWS->readX(0), monitorWS->readY(0), guess_ei, + this->m_min_Eresolution / (2 * std::sqrt(2 * std::log(2.))), + irange_min, irange_max, guessValid); + + // remove invalid guess values + removeInvalidValues<double>(guessValid, guess_ei); + + // preprocess second monitors peaks + std::vector<size_t> irange1_min, irange1_max; + if (!this->getProperty("IgnoreSecondMonitor")) { + g_log.debug() << "*Looking for real energy peaks on second monitor\n"; + findBinRanges(monitorWS->readX(1), monitorWS->readY(1), guess_ei, + this->m_min_Eresolution / (2 * std::sqrt(2 * std::log(2.))), + irange1_min, irange1_max, guessValid); + removeInvalidValues<double>(guessValid, guess_ei); + removeInvalidValues<size_t>(guessValid, irange_min); + removeInvalidValues<size_t>(guessValid, irange_max); + } else { + // this is wrong but will not be used anyway + // (except formally looping through vector) + irange1_min.assign(irange_min.begin(), irange_min.end()); + irange1_max.assign(irange_max.begin(), irange_max.end()); + } + g_log.debug() + << "*Identified: " + boost::lexical_cast<std::string>(guess_ei.size()) + + " peaks with sufficient signal around guess chopper opening\n"; + + std::vector<peakKeeper> peaks; + + double maxPeakEnergy(0); + std::vector<size_t> monsRangeMin(2), monsRangeMax(2); + for (size_t i = 0; i < guess_ei.size(); i++) { + monsRangeMin[0] = irange_min[i]; + monsRangeMax[0] = irange_max[i]; + monsRangeMin[1] = irange1_min[i]; + monsRangeMax[1] = irange1_max[i]; + + double energy, height, twoSigma; + bool found = findMonitorPeak(monitorWS, guess_ei[i], monsRangeMin, + monsRangeMax, energy, height, twoSigma); + if (found) { + peaks.push_back(peakKeeper(energy, height, 0.5 * twoSigma)); + if (peaks.back().energy > maxPeakEnergy) + maxPeakEnergy = peaks.back().energy; + } + } + monitorWS.reset(); + + size_t nPeaks = peaks.size(); + if (nPeaks == 0) { + throw std::runtime_error("Can not identify any energy peaks"); + } + // sort peaks and remove invalid one + guessValid.resize(nPeaks); + bool needsRemoval(false); + for (size_t i = 0; i < nPeaks; i++) { + peaks[i].energy /= maxPeakEnergy; + if (peaks[i].energy < m_peakEnergyRatio2reject) { + guessValid[i] = false; + g_log.debug() << "*Rejecting peak at Ei=" + + boost::lexical_cast<std::string>(peaks[i].position) + + " as its total energy lower then the threshold\n"; + needsRemoval = true; + } else { + guessValid[i] = true; + } + } + if (needsRemoval) + removeInvalidValues<peakKeeper>(guessValid, peaks); + nPeaks = peaks.size(); + // sort by energy decreasing -- see class definition + std::sort(peaks.begin(), peaks.end()); + + // finalize output + auto result_ws = API::WorkspaceFactory::Instance().create("Workspace2D", 1, + nPeaks, nPeaks); + + MantidVec peaks_positions; + MantidVec &Signal = result_ws->dataY(0); + MantidVec &Error = result_ws->dataE(0); + for (size_t i = 0; i < nPeaks; i++) { + peaks_positions.push_back(peaks[i].position); + Signal[i] = peaks[i].height; + Error[i] = peaks[i].sigma; + } + result_ws->setX(0, peaks_positions); + + setProperty("OutputWorkspace", result_ws); +} + +// unnamed namespace for auxiliary file-based functions, converted from lambda +// as not all Mantid compilers support lambda yet. + +/**The internal procedure to set filter log from properties, + defining it. +* @param inputWS -- shared pointer to the input workspace with + logs to analyze +*/ +void GetAllEi::setFilterLog(const API::MatrixWorkspace_sptr &inputWS) { + + std::string filerLogName; + std::string filterBase = getProperty("FilterBaseLog"); + if (boost::iequals(filterBase, "Defined in IDF")) { + filerLogName = m_chopper->getStringParameter("FilterBaseLog")[0]; + m_FilterWithDerivative = + m_chopper->getBoolParameter("filter_with_derivative")[0]; + } else { + filerLogName = filterBase; + m_FilterWithDerivative = getProperty("FilterWithDerivative"); + } + try { + m_pFilterLog = dynamic_cast<Kernel::TimeSeriesProperty<double> *>( + inputWS->run().getProperty(filerLogName)); + } catch (std::runtime_error &) { + g_log.warning() << " Can not retrieve (double) filtering log: " + + filerLogName + + " from current workspace\n" + " Using total experiment range to " + "find logs averages for chopper parameters\n"; + m_FilterWithDerivative = false; + } +} +/**Former lambda to identify guess values for a peak at given index +* and set up these parameters as input for fitting algorithm +* +*@param inputWS -- the workspace to process +*@param index -- the number of the workspace spectra to process +*@param Ei -- incident energy +*@param monsRangeMin -- vector of left boundaries for the subintervals to look +*for peak +*@param monsRangeMax -- vector of right boundaries for the subintervals to look +*for peak +* +*@param peakPos -- output energy of the peak +*@param peakHeight -- output height of the peak assuming Gaussian shape +*@param peakTwoSigma -- output width of the peak assuming Gaussian shape +*/ +bool GetAllEi::peakGuess(const API::MatrixWorkspace_sptr &inputWS, size_t index, + double Ei, const std::vector<size_t> &monsRangeMin, + const std::vector<size_t> &monsRangeMax, + double &peakPos, double &peakHeight, + double &peakTwoSigma) { + + // calculate sigma from half-width parameters + double maxSigma = Ei * m_min_Eresolution / (2 * std::sqrt(2 * std::log(2.))); + + double sMin(std::numeric_limits<double>::max()); + double sMax(-sMin); + double xOfMax(0), dXmax(0); + double Intensity(0); + + auto X = inputWS->readX(index); + auto S = inputWS->readY(index); + size_t ind_min = monsRangeMin[index]; + size_t ind_max = monsRangeMax[index]; + // interval too small -- not interested in a peak there + if (std::fabs(double(ind_max - ind_min)) < 5) + return false; + + // double xMin = X[ind_min]; + // double xMax = X[ind_max]; + // size_t ind_Ofmax(ind_min); + + for (size_t i = ind_min; i < ind_max; i++) { + double dX = X[i + 1] - X[i]; + double signal = S[i] / dX; + if (signal < sMin) + sMin = signal; + if (signal > sMax) { + sMax = signal; + dXmax = dX; + xOfMax = X[i]; + // ind_Ofmax=i; + } + Intensity += S[i]; + } + // monitor peak should not have just two counts in it. + if (sMax * dXmax <= 2) + return false; + // + // size_t SearchAreaSize = ind_max - ind_min; + + double SmoothRange = 2 * maxSigma; + + std::vector<double> SAvrg, binsAvrg; + Kernel::VectorHelper::smoothInRange(S, SAvrg, SmoothRange, &X, ind_min, + ind_max, &binsAvrg); + + double realPeakPos(xOfMax); // this position is less shifted + // due to the skew in averaging formula + bool foundRealPeakPos(false); + std::vector<double> der1Avrg, der2Avrg, peaks, hillsPos, SAvrg1, binsAvrg1; + size_t nPeaks = + this->calcDerivativeAndCountZeros(binsAvrg, SAvrg, der1Avrg, peaks); + size_t nHills = + this->calcDerivativeAndCountZeros(binsAvrg, der1Avrg, der2Avrg, hillsPos); + size_t nPrevHills = 2 * nHills; + if (nPeaks == 1) { + foundRealPeakPos = true; + realPeakPos = peaks[0]; + } + + size_t ic(0), stay_still_count(0); + bool iterations_fail(false); + while ((nPeaks > 1 || nHills > 2) && (!iterations_fail)) { + Kernel::VectorHelper::smoothInRange(SAvrg, SAvrg1, SmoothRange, &binsAvrg, + 0, ind_max - ind_min, &binsAvrg1); + nPrevHills = nHills; + + nPeaks = + this->calcDerivativeAndCountZeros(binsAvrg1, SAvrg1, der1Avrg, peaks); + nHills = this->calcDerivativeAndCountZeros(binsAvrg1, der1Avrg, der2Avrg, + hillsPos); + SAvrg.swap(SAvrg1); + binsAvrg.swap(binsAvrg1); + if (nPeaks == 1 && !foundRealPeakPos) { // fix first peak position found + foundRealPeakPos = true; // as averaging shift peaks on + realPeakPos = peaks[0]; // irregular grid. + } + ic++; + if (nPrevHills <= nHills) { + stay_still_count++; + } else { + stay_still_count = 0; + } + if (ic > 50 || stay_still_count > 3) + iterations_fail = true; + } + if (iterations_fail) { + g_log.information() << "*No peak search convergence after " + + boost::lexical_cast<std::string>(ic) + + " smoothing iterations at still_count: " + + boost::lexical_cast<std::string>( + stay_still_count) + + " Wrong energy or noisy peak at Ei=" + + boost::lexical_cast<std::string>(Ei) + << std::endl; + } + g_log.debug() << "*Performed: " + boost::lexical_cast<std::string>(ic) + + " averages for spectra " + + boost::lexical_cast<std::string>(index) + + " at energy: " + boost::lexical_cast<std::string>(Ei) + + "\n and found: " + + boost::lexical_cast<std::string>(nPeaks) + "peaks and " + + boost::lexical_cast<std::string>(nHills) + " hills\n"; + if (nPeaks != 1) { + g_log.debug() << "*Peak rejected as n-peaks !=1 after averaging\n"; + return false; + } + + peakPos = peaks[0]; + if (nHills > 2) { + size_t peakIndex = Kernel::VectorHelper::getBinIndex(hillsPos, peaks[0]); + peakTwoSigma = hillsPos[peakIndex + 1] - hillsPos[peakIndex]; + } else { + if (hillsPos.size() == 2) { + peakTwoSigma = hillsPos[1] - hillsPos[0]; + } else { + g_log.debug() << "*Peak rejected as averaging gives: " + + boost::lexical_cast<std::string>(nPeaks) + + " peaks and " + + boost::lexical_cast<std::string>(nHills) + + " heals\n"; + + return false; + } + } + // assuming that averaging conserves intensity and removing linear + // background: + peakHeight = Intensity / (0.5 * std::sqrt(2. * M_PI) * peakTwoSigma) - sMin; + peakPos = realPeakPos; + + return true; +} + +/**Get energy of monitor peak if one is present +*@param inputWS -- the workspace to process +*@param Ei -- incident energy +*@param monsRangeMin -- vector of indexes of left boundaries +* for the subintervals to look for peak +*@param monsRangeMax -- vector of indexes of right boundaries +* for the subintervals to look for peak +* +*@param position -- output energy of the peak center. +*@param height -- output height of the peak assuming Gaussian shape +*@param twoSigma -- output width of the peak assuming Gaussian shape +*/ +bool GetAllEi::findMonitorPeak(const API::MatrixWorkspace_sptr &inputWS, + double Ei, + const std::vector<size_t> &monsRangeMin, + const std::vector<size_t> &monsRangeMax, + double &position, double &height, + double &twoSigma) { + // calculate sigma from half-width parameters + double maxSigma = Ei * m_min_Eresolution / (2 * std::sqrt(2 * std::log(2.))); + double minSigma = Ei * m_max_Eresolution / (2 * std::sqrt(2 * std::log(2.))); + //-------------------------------------------------------------------- + double peak1Pos, peak1TwoSigma, peak1Height; + if (!peakGuess(inputWS, 0, Ei, monsRangeMin, monsRangeMax, peak1Pos, + peak1Height, peak1TwoSigma)) + return false; + if (0.25 * peak1TwoSigma > maxSigma || peak1TwoSigma < minSigma) { + g_log.debug() << "*Rejecting due to width: Peak at mon1 Ei=" + + boost::lexical_cast<std::string>(peak1Pos) + + " with Height:" + + boost::lexical_cast<std::string>(peak1Height) + + " and 2*Sigma: " + + boost::lexical_cast<std::string>(peak1TwoSigma) + << std::endl; + return false; + } + + if (!this->getProperty("IgnoreSecondMonitor")) { + double peak2Pos, peak2TwoSigma, peak2Height; + if (!peakGuess(inputWS, 1, Ei, monsRangeMin, monsRangeMax, peak2Pos, + peak2Height, peak2TwoSigma)) + return false; + // Let's not check anything except peak position for monitor2, as + // its intensity may be very low for some instruments. + // if(0.25*peak2TwoSigma>maxSigma||peak2TwoSigma<minSigma)return false; + + // peak in first and second monitors are too far from each other. May be the + // instrument + // is ill-calibrated but GetEi will probably not find this peak anyway. + if (std::fabs(peak1Pos - peak2Pos) > + 0.25 * (peak1TwoSigma + peak2TwoSigma)) { + g_log.debug() + << "*Rejecting due to displacement between Peak at mon1: Ei=" + + boost::lexical_cast<std::string>(peak1Pos) + " with Height:" + + boost::lexical_cast<std::string>(peak1Height) + + " and 2*Sigma: " + + boost::lexical_cast<std::string>(peak1TwoSigma) + + "\n and Peak at mon2: Ei= " + + boost::lexical_cast<std::string>(peak2Pos) + "and height: " + + boost::lexical_cast<std::string>(peak1Height) << std::endl; + + return false; + } + } + + position = peak1Pos; + twoSigma = peak1TwoSigma; + height = peak1Height; + + return true; +} +namespace { // for lambda extracted from calcDerivativeAndCountZeros + /**former lambda from calcDerivativeAndCountZeros + *estimating if sign have changed from its previous value + *@param val -- current function value + *@param prevSign -- the sign of the function at previous value + */ +bool signChanged(double val, int &prevSign) { + int curSign = (val >= 0 ? 1 : -1); + bool changed = curSign != prevSign; + prevSign = curSign; + return changed; +} +} + +/**Bare-bone function to calculate numerical derivative, and estimate number of +* zeros this derivative has. The function is assumed to be defined on the +* the left of a bin range so the derivative is calculated in the same point. +* No checks are performed for simplicity so data have to be correct +* form at input. +*@param bins -- vector of bin boundaries. +*@param signal -- vector of signal size of bins.size()-1 +*@param deriv -- output vector of numerical derivative +*@param zeros -- coordinates of found zeros + +*@return -- number of zeros, the derivative has in the interval provided. +*/ +size_t GetAllEi::calcDerivativeAndCountZeros(const std::vector<double> &bins, + const std::vector<double> &signal, + std::vector<double> &deriv, + std::vector<double> &zeros) { + size_t nPoints = signal.size(); + deriv.resize(nPoints); + zeros.resize(0); + + std::list<double> funVal; + double bin0 = bins[1] - bins[0]; + double f0 = signal[0] / bin0; + double bin1 = bins[2] - bins[1]; + double f1 = signal[1] / bin1; + + size_t nZeros(0); + + funVal.push_front(f1); + deriv[0] = 2 * (f1 - f0) / (bin0 + bin1); + int prevSign = (deriv[0] >= 0 ? 1 : -1); + + for (size_t i = 1; i < nPoints - 1; i++) { + bin1 = (bins[i + 2] - bins[i + 1]); + f1 = signal[i + 1] / bin1; + deriv[i] = (f1 - f0) / (bins[i + 2] - bins[i]); + f0 = funVal.back(); + funVal.pop_back(); + funVal.push_front(f1); + + if (signChanged(deriv[i], prevSign)) { + nZeros++; + zeros.push_back(0.5 * (bins[i - 1] + bins[i])); + } + } + deriv[nPoints - 1] = 2 * (f1 - f0) / (bin1 + bin0); + if (signChanged(deriv[nPoints - 1], prevSign)) { + zeros.push_back(bins[nPoints - 1]); + nZeros++; + } + + return nZeros; +} +namespace { // for lambda extracted from findBinRanges +// get bin range corresponding to the energy range +void getBinRange(const MantidVec &eBins, double eMin, double eMax, + size_t &index_min, size_t &index_max) { + + size_t nBins = eBins.size(); + if (eMin <= eBins[0]) { + index_min = 0; + } else { + index_min = Kernel::VectorHelper::getBinIndex(eBins, eMin); + } + + if (eMax >= eBins[nBins - 1]) { + index_max = nBins - 1; + } else { + index_max = Kernel::VectorHelper::getBinIndex(eBins, eMax) + 1; + if (index_max >= nBins) + index_max = nBins - 1; // last bin range anyway. Should not happen + } +} + +// refine bin range. May need better procedure for this. +bool refineEGuess(const MantidVec &eBins, const MantidVec &signal, + double &eGuess, size_t index_min, size_t index_max) { + + size_t ind_Emax = index_min; + double SMax(0); + for (size_t i = index_min; i < index_max; i++) { + double dX = eBins[i + 1] - eBins[i]; + double sig = signal[i] / dX; + if (sig > SMax) { + SMax = sig; + ind_Emax = i; + } + } + if (ind_Emax == index_min || ind_Emax == index_max) { + return false; + } + eGuess = 0.5 * (eBins[ind_Emax] + eBins[ind_Emax + 1]); + return true; +} + +struct peakKeeper2 { + double left_rng; + double right_rng; + peakKeeper2(){}; + peakKeeper2(double left, double right) : left_rng(left), right_rng(right) {} +}; +} + +/**Find indexes of each expected peak intervals from monotonous array of ranges. +*@param eBins -- bin ranges to look through +*@param signal -- vector of signal in the bins +*@param guess_energy -- vector of guess energies to look for +*@param eResolution -- instrument resolution in energy units +*@param irangeMin -- start indexes of energy intervals in the guess_energies +* vector. +*@param irangeMax -- final indexes of energy intervals in the guess_energies +* vector. +*@param guessValid -- output boolean vector, which specifies if guess energies +* in guess_energy vector are valid or not +*/ +void GetAllEi::findBinRanges(const MantidVec &eBins, const MantidVec &signal, + const std::vector<double> &guess_energy, + double eResolution, std::vector<size_t> &irangeMin, + std::vector<size_t> &irangeMax, + std::vector<bool> &guessValid) { + + // size_t nBins = eBins.size(); + guessValid.resize(guess_energy.size()); + + // Do the job + size_t ind_min, ind_max; + irangeMin.resize(0); + irangeMax.resize(0); + + // identify guess bin ranges + std::vector<peakKeeper2> guess_peak(guess_energy.size()); + for (size_t nGuess = 0; nGuess < guess_energy.size(); nGuess++) { + double eGuess = guess_energy[nGuess]; + getBinRange(eBins, eGuess * (1 - 4 * eResolution), + eGuess * (1 + 4 * eResolution), ind_min, ind_max); + guess_peak[nGuess] = peakKeeper2(eBins[ind_min], eBins[ind_max]); + } + // verify that the ranges not intercept and refine interceptions + for (size_t i = 1; i < guess_energy.size(); i++) { + if (guess_peak[i - 1].right_rng > guess_peak[i].left_rng) { + double mid_pnt = + 0.5 * (guess_peak[i - 1].right_rng + guess_peak[i].left_rng); + guess_peak[i - 1].right_rng = mid_pnt; + guess_peak[i].left_rng = mid_pnt; + } + } + // identify final bin ranges + for (size_t nGuess = 0; nGuess < guess_energy.size(); nGuess++) { + + double eGuess = guess_energy[nGuess]; + getBinRange(eBins, guess_peak[nGuess].left_rng, + guess_peak[nGuess].right_rng, ind_min, ind_max); + + if (refineEGuess(eBins, signal, eGuess, ind_min, ind_max)) { + getBinRange(eBins, std::max(guess_peak[nGuess].left_rng, + eGuess * (1 - 3 * eResolution)), + std::max(guess_peak[nGuess].right_rng, + eGuess * (1 + 3 * eResolution)), + ind_min, ind_max); + irangeMin.push_back(ind_min); + irangeMax.push_back(ind_max); + guessValid[nGuess] = true; + } else { + guessValid[nGuess] = false; + g_log.debug() << "*Incorrect guess energy: " + << boost::lexical_cast<std::string>(eGuess) + << " no energy peak found in 4*Sigma range\n"; + } + } + // if array decreasing rather then increasing, indexes behave differently. + // Will it still work? + if (irangeMax.size() > 0) { + if (irangeMax[0] < irangeMin[0]) { + irangeMax.swap(irangeMin); + } + } +} + +/**Build 2-spectra workspace in units of energy, used as source +*to identify actual monitors spectra +*@param inputWS shared pointer to initial workspace +*@param wsIndex0 -- returns workspace index for first detector. +*@return shared pointer to intermediate workspace, in units of energy +* used to fit monitor's spectra. +*/ +API::MatrixWorkspace_sptr +GetAllEi::buildWorkspaceToFit(const API::MatrixWorkspace_sptr &inputWS, + size_t &wsIndex0) { + + // at this stage all properties are validated so its safe to access them + // without + // additional checks. + specid_t specNum1 = getProperty("Monitor1SpecID"); + wsIndex0 = inputWS->getIndexFromSpectrumNumber(specNum1); + specid_t specNum2 = getProperty("Monitor2SpecID"); + size_t wsIndex1 = inputWS->getIndexFromSpectrumNumber(specNum2); + auto pSpectr1 = inputWS->getSpectrum(wsIndex0); + auto pSpectr2 = inputWS->getSpectrum(wsIndex1); + // assuming equally binned ws. + // auto bins = inputWS->dataX(wsIndex0); + auto bins = pSpectr1->dataX(); + size_t XLength = bins.size(); + size_t YLength = inputWS->dataY(wsIndex0).size(); + auto working_ws = + API::WorkspaceFactory::Instance().create(inputWS, 2, XLength, YLength); + // copy data --> very bad as implicitly assigns pointer + // to bins array and bins array have to exist out of this routine + // scope. + // This does not matter in this case as below we convert units + // which should decouple cow_pointer but very scary operation in + // general. + working_ws->setX(0, bins); + working_ws->setX(1, bins); + MantidVec &Signal1 = working_ws->dataY(0); + MantidVec &Error1 = working_ws->dataE(0); + MantidVec &Signal2 = working_ws->dataY(1); + MantidVec &Error2 = working_ws->dataE(1); + for (size_t i = 0; i < YLength; i++) { + Signal1[i] = inputWS->dataY(wsIndex0)[i]; + Error1[i] = inputWS->dataE(wsIndex0)[i]; + Signal2[i] = inputWS->dataY(wsIndex1)[i]; + Error2[i] = inputWS->dataE(wsIndex1)[i]; + } + // copy detector mapping + API::ISpectrum *spectrum = working_ws->getSpectrum(0); + spectrum->setSpectrumNo(specNum1); + spectrum->clearDetectorIDs(); + spectrum->addDetectorIDs(pSpectr1->getDetectorIDs()); + spectrum = working_ws->getSpectrum(1); + spectrum->setSpectrumNo(specNum2); + spectrum->clearDetectorIDs(); + spectrum->addDetectorIDs(pSpectr2->getDetectorIDs()); + + if (inputWS->getAxis(0)->unit()->caption() != "Energy") { + API::IAlgorithm_sptr conv = createChildAlgorithm("ConvertUnits"); + conv->initialize(); + conv->setProperty("InputWorkspace", working_ws); + conv->setProperty("OutputWorkspace", working_ws); + conv->setPropertyValue("Target", "Energy"); + conv->setPropertyValue("EMode", "Elastic"); + // conv->setProperty("AlignBins",true); --> throws due to bug in + // ConvertUnits + conv->execute(); + } + + return working_ws; +} +/**function calculates list of provisional chopper opening times. +*@param TOF_range -- std::pair containing min and max time, of signal +* measured on monitors +*@param ChopDelay -- the time of flight neutrons travel from source +* to the chopper opening. +*@param Period -- period of chopper openings + +*@param guess_opening_times -- output vector with time values +* at which neutrons may pass through the chopper. +*/ +void GetAllEi::findGuessOpeningTimes(const std::pair<double, double> &TOF_range, + double ChopDelay, double Period, + std::vector<double> &guess_opening_times) { + + if (ChopDelay >= TOF_range.second) { + std::string chop = boost::str(boost::format("%.2g") % ChopDelay); + std::string t_min = boost::str(boost::format("%.2g") % TOF_range.first); + std::string t_max = boost::str(boost::format("%.2g") % TOF_range.second); + throw std::runtime_error("Logical error: Chopper opening time: " + chop + + " is outside of time interval: " + t_min + ":" + + t_max + " of the signal, measured on monitors."); + } + + // number of times chopper with specified rotation period opens. + size_t n_openings = + static_cast<size_t>((TOF_range.second - ChopDelay) / Period) + 1; + // number of periods falling outside of the time period, measuring on monitor. + size_t n_start(0); + if (ChopDelay < TOF_range.first) { + n_start = static_cast<size_t>((TOF_range.first - ChopDelay) / Period) + 1; + n_openings -= n_start; + } + + guess_opening_times.resize(n_openings); + for (size_t i = n_start; i < n_openings + n_start; i++) { + guess_opening_times[i - n_start] = + ChopDelay + static_cast<double>(i) * Period; + } +} +/**Finds pointer to log value for the property with the name provided +* +*@param inputWS -- workspace with logs attached +*@param propertyName -- name of the property to find log for +* +*@return -- pointer to property which contain the log requested or nullptr if +* no log found or other errors identified. */ +Kernel::Property * +GetAllEi::getPLogForProperty(const API::MatrixWorkspace_sptr &inputWS, + const std::string &propertyName) { + + std::string LogName = this->getProperty(propertyName); + if (boost::iequals(LogName, "Defined in IDF")) { + auto AllNames = m_chopper->getStringParameter(propertyName); + if (AllNames.size() != 1) + return NULL; + LogName = AllNames[0]; + } + auto pIProperty = (inputWS->run().getProperty(LogName)); + + return pIProperty; +} + +/**Return average time series log value for the appropriately filtered log +* @param inputWS -- shared pointer to the input workspace containing +* the log to process +* @param propertyName -- log name +* @param splitter -- array of Kernel::splittingInterval data, used to +* filter input events or empty array to use +* experiment start/end times. +*/ +double +GetAllEi::getAvrgLogValue(const API::MatrixWorkspace_sptr &inputWS, + const std::string &propertyName, + std::vector<Kernel::SplittingInterval> &splitter) { + + auto pIProperty = getPLogForProperty(inputWS, propertyName); + + // this will always provide a defined pointer as this has been verified in + // validator. + auto pTimeSeries = + dynamic_cast<Kernel::TimeSeriesProperty<double> *>(pIProperty); + + if (splitter.size() == 0) { + auto TimeStart = inputWS->run().startTime(); + auto TimeEnd = inputWS->run().endTime(); + pTimeSeries->filterByTime(TimeStart, TimeEnd); + } else { + pTimeSeries->filterByTimes(splitter); + } + if (pTimeSeries->size() == 0) { + throw std::runtime_error( + "Can not find average value for log defined by property" + + propertyName + " As no valid log values are found."); + } + + return pTimeSeries->getStatistics().mean; +} +namespace { // former lambda function for findChopSpeedAndDelay + +/**Select time interval on the basis of previous time interval +* selection and check if current value gets in the selection +* +* @param t_beg -- initial time for current time interval +* @param t_end -- final time for current time interval +* @param inSelection -- the boolean indicating if previous interval +* was selected on input and current selected on +* output +* @param startTime -- total selection time start moment +* @param endTime -- total selection time final moments +* +*@return true if selection interval is completed +* (current interval is not selected) and false otherwise +*/ +bool SelectInterval(const Kernel::DateAndTime &t_beg, + const Kernel::DateAndTime &t_end, double value, + bool &inSelection, Kernel::DateAndTime &startTime, + Kernel::DateAndTime &endTime) { + + if (value > 0) { + if (!inSelection) { + startTime = t_beg; + } + inSelection = true; + } else { + if (inSelection) { + inSelection = false; + if (endTime > startTime) + return true; + } + } + endTime = t_end; + return false; +} +} +/**Analyze chopper logs and identify chopper speed and delay +@param inputWS -- sp to workspace with attached logs. +@param chop_speed -- output value for chopper speed in uSec +@param chop_delay -- output value for chopper delay in uSec +*/ +void GetAllEi::findChopSpeedAndDelay(const API::MatrixWorkspace_sptr &inputWS, + double &chop_speed, double &chop_delay) { + + // TODO: Make it dependent on inputWS time range + + std::vector<Kernel::SplittingInterval> splitter; + if (m_pFilterLog) { + std::unique_ptr<Kernel::TimeSeriesProperty<double>> pDerivative; + + // Define selecting function + bool inSelection(false); + // time interval to select (start-end) + Kernel::DateAndTime startTime, endTime; + // + // Analyze filtering log + auto dateAndTimes = m_pFilterLog->valueAsCorrectMap(); + auto it = dateAndTimes.begin(); + auto next = it; + next++; + std::map<Kernel::DateAndTime, double> derivMap; + auto itder = it; + if (m_FilterWithDerivative) { + pDerivative = m_pFilterLog->getDerivative(); + derivMap = pDerivative->valueAsCorrectMap(); + itder = derivMap.begin(); + } + + // initialize selection log + if (dateAndTimes.size() <= 1) { + SelectInterval(it->first, it->first, itder->second, inSelection, + startTime, endTime); + if (inSelection) { + startTime = inputWS->run().startTime(); + endTime = inputWS->run().endTime(); + Kernel::SplittingInterval interval(startTime, endTime, 0); + splitter.push_back(interval); + } else { + throw std::runtime_error("filtered all data points. Nothing to do"); + } + } else { + SelectInterval(it->first, next->first, itder->second, inSelection, + startTime, endTime); + } + + // if its filtered using log, both iterator walk through the same values + // if use derivative, derivative's values are used for filtering + // and derivative assumed in a center of an interval + for (; next != dateAndTimes.end(); ++next, ++itder) { + if (SelectInterval(it->first, next->first, itder->second, inSelection, + startTime, endTime)) { + Kernel::SplittingInterval interval(startTime, endTime, 0); + splitter.push_back(interval); + } + it = next; + } + // final interval + if (inSelection && (endTime > startTime)) { + Kernel::SplittingInterval interval(startTime, endTime, 0); + splitter.push_back(interval); + } + } // End of USE filter log. + + chop_speed = this->getAvrgLogValue(inputWS, "ChopperSpeedLog", splitter); + chop_speed = std::fabs(chop_speed); + if (chop_speed < 1.e-7) { + throw std::runtime_error("Chopper speed can not be zero "); + } + chop_delay = + std::fabs(this->getAvrgLogValue(inputWS, "ChopperDelayLog", splitter)); + + // process chopper delay in the units of degree (phase) + auto pProperty = getPLogForProperty(inputWS, "ChopperDelayLog"); + if (!pProperty) + throw std::runtime_error("ChopperDelayLog has been removed from workspace " + "during the algorithm execution"); + std::string units = pProperty->units(); + // its chopper phase provided + if (units == "deg" || + units.c_str()[0] == + -80) { //<- userd in ISIS ASCII representation of o(deg) + chop_delay *= 1.e+6 / (360. * chop_speed); // convert in uSec + } + chop_delay += m_phase / chop_speed; +} + +namespace { // namespace for lambda functions, used in validators + +/* former Lambda to validate if appropriate log is present in workspace +and if it's present, it is a time-series property +* @param prop_name -- the name of the log to check +* @param err_presence -- core error message to return if no log found +* @param err_type -- core error message to return if +* log is of incorrect type +* @param fail -- fail or warn if appropriate log is not available. +* +* @param result -- map to add the result of check for errors +* if no error found the map is not modified and remains +* empty. + + +* @return -- false if all checks are fine, or true if check is +* failed +*/ +bool check_time_series_property( + const GetAllEi *algo, const API::MatrixWorkspace_sptr &inputWS, + const boost::shared_ptr<const Geometry::IComponent> &chopper, + const std::string &prop_name, const std::string &err_presence, + const std::string &err_type, bool fail, + std::map<std::string, std::string> &result) { + + std::string LogName = algo->getProperty(prop_name); + if (boost::iequals(LogName, "Defined in IDF")) { + try { + auto theLogs = chopper->getStringParameter(prop_name); + if (theLogs.size() == 0) { + if (fail) + result[prop_name] = "Can not retrieve parameter " + prop_name + + " from the instrument definition file."; + return true; + } + LogName = theLogs[0]; + } catch (...) { + result[prop_name] = "Can not retrieve parameter " + prop_name + + " from the instrument definition file."; + return true; + } + } + try { + Kernel::Property *pProp = inputWS->run().getProperty(LogName); + auto pTSProp = dynamic_cast<Kernel::TimeSeriesProperty<double> *>(pProp); + if (!pTSProp) { + if (fail) + result[prop_name] = "Workspace contains " + err_type + LogName + + " But its type is not a timeSeries property"; + return true; + } + } catch (std::runtime_error &) { + if (fail) + result[prop_name] = "Workspace has to contain " + err_presence + LogName; + return true; + } + return false; +} +} + +/**Validates if input workspace contains all necessary logs and if all +* these logs are the logs of appropriate type +@return list of invalid logs or empty list if no errors is found. +*/ +std::map<std::string, std::string> GetAllEi::validateInputs() { + + // Do Validation + std::map<std::string, std::string> result; + + API::MatrixWorkspace_sptr inputWS = getProperty("Workspace"); + if (!inputWS) { + result["Workspace"] = "Input workspace can not be identified"; + return result; + } + if (!inputWS->isHistogramData()) { + result["Workspace"] = "Only histogram workspaces are currently supported. " + "Rebin input workspace first."; + } + + specid_t specNum1 = getProperty("Monitor1SpecID"); + try { + inputWS->getIndexFromSpectrumNumber(specNum1); + } catch (std::runtime_error &) { + result["Monitor1SpecID"] = + "Input workspace does not contain spectra with ID: " + + boost::lexical_cast<std::string>(specNum1); + } + specid_t specNum2 = getProperty("Monitor2SpecID"); + try { + inputWS->getIndexFromSpectrumNumber(specNum2); + } catch (std::runtime_error &) { + result["Monitor2SpecID"] = + "Input workspace does not contain spectra with ID: " + + boost::lexical_cast<std::string>(specNum2); + } + // check chopper and initiate it if present (for debugging) + m_chopper = inputWS->getInstrument()->getComponentByName("chopper-position"); + if (!m_chopper) { + result["Workspace_chopper"] = + " For this algorithm to work workspace has" + " to contain well defined 'chopper-position' component"; + return result; + } + + check_time_series_property(this, inputWS, m_chopper, "ChopperSpeedLog", + "chopper speed log with name: ", + "chopper speed log ", true, result); + check_time_series_property( + this, inputWS, m_chopper, "ChopperDelayLog", + "property related to chopper delay log with name: ", "chopper delay log ", + true, result); + bool failed = check_time_series_property( + this, inputWS, m_chopper, "FilterBaseLog", "filter base log named: ", + "filter base log: ", false, result); + if (failed) { + g_log.warning() + << " Can not find a log to identify good DAE operations.\n" + " Assuming that good operations start from experiment time=0"; + } else { + this->setFilterLog(inputWS); + } + return result; +} + +} // namespace Algorithms +} // namespace Mantid diff --git a/Framework/Algorithms/src/GetDetOffsetsMultiPeaks.cpp b/Framework/Algorithms/src/GetDetOffsetsMultiPeaks.cpp index 07e9673ba2151c55e0ce2beec63f3c18a07106b6..ed6fedd46ee75042c300526e89d281f43395ebad 100644 --- a/Framework/Algorithms/src/GetDetOffsetsMultiPeaks.cpp +++ b/Framework/Algorithms/src/GetDetOffsetsMultiPeaks.cpp @@ -1,24 +1,23 @@ #include "MantidAlgorithms/GetDetOffsetsMultiPeaks.h" #include "MantidAlgorithms/GSLFunctions.h" +#include "MantidAPI/CompositeFunction.h" #include "MantidAPI/FileProperty.h" #include "MantidAPI/FunctionFactory.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidAPI/WorkspaceFactory.h" #include "MantidAPI/ITableWorkspace.h" #include "MantidAPI/IPeakFunction.h" #include "MantidAPI/IBackgroundFunction.h" -#include "MantidAPI/CompositeFunction.h" #include "MantidAPI/TableRow.h" -#include "MantidKernel/ArrayProperty.h" -#include "MantidKernel/ListValidator.h" -#include "MantidKernel/VectorHelper.h" +#include "MantidAPI/WorkspaceFactory.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/MaskWorkspace.h" #include "MantidDataObjects/OffsetsWorkspace.h" +#include "MantidKernel/ArrayProperty.h" +#include "MantidKernel/ListValidator.h" #include "MantidKernel/Statistics.h" +#include "MantidKernel/VectorHelper.h" + #include <boost/math/special_functions/fpclassify.hpp> -#include <fstream> -#include <ostream> #include <sstream> namespace Mantid { diff --git a/Framework/Algorithms/src/GetDetectorOffsets.cpp b/Framework/Algorithms/src/GetDetectorOffsets.cpp index 86b595c4c5f14faae0dbdcaa28a8cc7e20b7390b..5af130be47dc42589c73a119d8910ff94ba8dbb3 100644 --- a/Framework/Algorithms/src/GetDetectorOffsets.cpp +++ b/Framework/Algorithms/src/GetDetectorOffsets.cpp @@ -1,19 +1,17 @@ #include "MantidAlgorithms/GetDetectorOffsets.h" +#include "MantidAPI/CompositeFunction.h" #include "MantidAPI/FileProperty.h" #include "MantidAPI/FunctionFactory.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidAPI/IPeakFunction.h" -#include "MantidAPI/IBackgroundFunction.h" -#include "MantidAPI/CompositeFunction.h" -#include "MantidDataObjects/OffsetsWorkspace.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidDataObjects/MaskWorkspace.h" -#include <boost/math/special_functions/fpclassify.hpp> -#include <fstream> -#include <ostream> -#include <sstream> +#include "MantidDataObjects/OffsetsWorkspace.h" #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/ListValidator.h" +#include <boost/math/special_functions/fpclassify.hpp> +#include <sstream> + namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/GetEi.cpp b/Framework/Algorithms/src/GetEi.cpp index 040830fa3dcec6de114074a44b87a887fa3701d7..2447bd9b0e91055c8360395399d0845c1545cb20 100644 --- a/Framework/Algorithms/src/GetEi.cpp +++ b/Framework/Algorithms/src/GetEi.cpp @@ -1,12 +1,14 @@ #include "MantidAlgorithms/GetEi.h" -#include "MantidKernel/ArrayProperty.h" -#include "MantidAPI/FileProperty.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" +#include "MantidKernel/Exception.h" +#include "MantidKernel/CompositeValidator.h" +#include "MantidKernel/BoundedValidator.h" #include "MantidKernel/PhysicalConstants.h" -#include "MantidAPI/WorkspaceValidators.h" + #include <boost/lexical_cast.hpp> -#include "MantidKernel/Exception.h" #include <cmath> -#include "MantidKernel/BoundedValidator.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/GetEi2.cpp b/Framework/Algorithms/src/GetEi2.cpp index 03cf0741b494e38c4c752a53d3a6b52d9fcdd723..e01d556106a5c727e34e267fb89018964f2b181d 100644 --- a/Framework/Algorithms/src/GetEi2.cpp +++ b/Framework/Algorithms/src/GetEi2.cpp @@ -1,18 +1,21 @@ #include "MantidAlgorithms/GetEi2.h" -#include "MantidKernel/PhysicalConstants.h" -#include "MantidKernel/VectorHelper.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidAPI/IEventWorkspace.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidGeometry/Instrument/DetectorGroup.h" #include "MantidGeometry/IObjComponent.h" +#include "MantidGeometry/muParser_Silent.h" +#include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" +#include "MantidKernel/PhysicalConstants.h" +#include "MantidKernel/VectorHelper.h" #include <boost/lexical_cast.hpp> #include <cmath> #include <algorithm> #include <sstream> -#include "MantidKernel/BoundedValidator.h" -#include "MantidGeometry/muParser_Silent.h" using namespace Mantid::Kernel; using namespace Mantid::API; diff --git a/Framework/Algorithms/src/He3TubeEfficiency.cpp b/Framework/Algorithms/src/He3TubeEfficiency.cpp index 0b82d45efee51204131cd80fb26212b20702965b..b8e5d300845d397c8b7a8e18436825100890634f 100644 --- a/Framework/Algorithms/src/He3TubeEfficiency.cpp +++ b/Framework/Algorithms/src/He3TubeEfficiency.cpp @@ -1,10 +1,13 @@ #include "MantidAlgorithms/He3TubeEfficiency.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/Workspace2D.h" #include "MantidKernel/ArrayBoundedValidator.h" #include "MantidKernel/ArrayProperty.h" -#include "MantidKernel/cow_ptr.h" +#include "MantidKernel/CompositeValidator.h" + #include <algorithm> #include <cmath> #include <stdexcept> diff --git a/Framework/Algorithms/src/IQTransform.cpp b/Framework/Algorithms/src/IQTransform.cpp index c2a5c506de78480e335546ce81b2db2cf9885327..d0484e12012ee7ed4563f64fbc68824149d58715 100644 --- a/Framework/Algorithms/src/IQTransform.cpp +++ b/Framework/Algorithms/src/IQTransform.cpp @@ -2,12 +2,15 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/IQTransform.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/IncreasingAxisValidator.h" +#include "MantidAPI/RawCountValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidKernel/ArrayProperty.h" -#include "MantidKernel/UnitFactory.h" -#include "MantidKernel/VectorHelper.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/ListValidator.h" +#include "MantidKernel/UnitFactory.h" +#include "MantidKernel/VectorHelper.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/IdentifyNoisyDetectors.cpp b/Framework/Algorithms/src/IdentifyNoisyDetectors.cpp index 0f4fd9d60e98339411cf48c23418c0cc3340e78a..8970268ec6e453b2326086689c3977de04cf60a3 100644 --- a/Framework/Algorithms/src/IdentifyNoisyDetectors.cpp +++ b/Framework/Algorithms/src/IdentifyNoisyDetectors.cpp @@ -1,5 +1,9 @@ #include "MantidAlgorithms/IdentifyNoisyDetectors.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/SpectraAxisValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" +#include "MantidKernel/CompositeValidator.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/IntegrateByComponent.cpp b/Framework/Algorithms/src/IntegrateByComponent.cpp index 3736939ef44d5308342132576d077262bd22c1a5..104713732b2aefb44f91e81125f1483a752da01d 100644 --- a/Framework/Algorithms/src/IntegrateByComponent.cpp +++ b/Framework/Algorithms/src/IntegrateByComponent.cpp @@ -1,5 +1,5 @@ #include "MantidAlgorithms/IntegrateByComponent.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" #include "MantidKernel/BoundedValidator.h" #include <gsl/gsl_statistics.h> #include <boost/math/special_functions/fpclassify.hpp> diff --git a/Framework/Algorithms/src/Integration.cpp b/Framework/Algorithms/src/Integration.cpp index 302661368b18d6047887914f40a7587d2a8ad4a5..eca1ce5afd3fd9a789892d7a4f843637a3071059 100644 --- a/Framework/Algorithms/src/Integration.cpp +++ b/Framework/Algorithms/src/Integration.cpp @@ -2,16 +2,15 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/Integration.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/VectorHelper.h" -#include "MantidDataObjects/EventWorkspace.h" -#include "MantidDataObjects/RebinnedOutput.h" -#include "MantidAPI/Progress.h" -#include <cmath> - #include "MantidAPI/NumericAxis.h" #include "MantidAPI/TextAxis.h" +#include "MantidDataObjects/EventWorkspace.h" +#include "MantidDataObjects/RebinnedOutput.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/VectorHelper.h" + +#include <cmath> +#include <numeric> namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/LorentzCorrection.cpp b/Framework/Algorithms/src/LorentzCorrection.cpp index 2d42cd4b7ccfccc6e28dfd1c2dbd4103ab9fb745..b83c575d271cfecb3d9583b4fa27a821a738e865 100644 --- a/Framework/Algorithms/src/LorentzCorrection.cpp +++ b/Framework/Algorithms/src/LorentzCorrection.cpp @@ -1,7 +1,7 @@ #include "MantidAlgorithms/LorentzCorrection.h" #include "MantidAPI/MatrixWorkspace.h" #include "MantidAPI/Progress.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidKernel/MultiThreaded.h" #include <boost/make_shared.hpp> #include <boost/shared_ptr.hpp> diff --git a/Framework/Algorithms/src/MaskBins.cpp b/Framework/Algorithms/src/MaskBins.cpp index 47358a6f69b014f5270851122da89df4e6f17b28..3c0992086a7da82b4a9afd29028d3d287af94f55 100644 --- a/Framework/Algorithms/src/MaskBins.cpp +++ b/Framework/Algorithms/src/MaskBins.cpp @@ -2,12 +2,13 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/MaskBins.h" -#include <limits> -#include <sstream> -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/BoundedValidator.h" +#include <limits> +#include <sstream> + namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/MaskBinsFromTable.cpp b/Framework/Algorithms/src/MaskBinsFromTable.cpp index afae3bc3632b3890d2c22ca7c134ef4d3a13283f..9f3c80a35ee0dc4ab3370c52807f3464a0db8855 100644 --- a/Framework/Algorithms/src/MaskBinsFromTable.cpp +++ b/Framework/Algorithms/src/MaskBinsFromTable.cpp @@ -1,7 +1,7 @@ #include "MantidAlgorithms/MaskBinsFromTable.h" #include "MantidKernel/System.h" #include "MantidAPI/WorkspaceProperty.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" #include "MantidAPI/MatrixWorkspace.h" #include "MantidAPI/TableRow.h" #include "MantidKernel/ArrayProperty.h" diff --git a/Framework/Algorithms/src/MaskDetectorsIf.cpp b/Framework/Algorithms/src/MaskDetectorsIf.cpp index 209f7a9873e4ecf268d92c43d65b3c901946a116..803f1008d76317cb96a3fd17fc3ba4c193cf401d 100644 --- a/Framework/Algorithms/src/MaskDetectorsIf.cpp +++ b/Framework/Algorithms/src/MaskDetectorsIf.cpp @@ -3,10 +3,10 @@ //---------------------------------------------------------------------- #include "MantidAlgorithms/MaskDetectorsIf.h" #include "MantidAPI/FileProperty.h" -#include "MantidAPI/WorkspaceValidators.h" -#include <fstream> #include "MantidKernel/ListValidator.h" +#include <fstream> + namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/Max.cpp b/Framework/Algorithms/src/Max.cpp index 7546fcac717306d23c913dc0d9047dae82bff790..fba42c21fb13c5a991c5e792564faccf16a3af66 100644 --- a/Framework/Algorithms/src/Max.cpp +++ b/Framework/Algorithms/src/Max.cpp @@ -2,9 +2,7 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/Max.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/VectorHelper.h" -#include "MantidAPI/Progress.h" +#include "MantidAPI/HistogramValidator.h" #include "MantidKernel/BoundedValidator.h" namespace Mantid { diff --git a/Framework/Algorithms/src/MaxMin.cpp b/Framework/Algorithms/src/MaxMin.cpp index d6273ea22f5311bde5b5919a938a4692341b43e5..c4011d80b83eb22b4587736aee53c8a05081b4f7 100644 --- a/Framework/Algorithms/src/MaxMin.cpp +++ b/Framework/Algorithms/src/MaxMin.cpp @@ -2,9 +2,7 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/MaxMin.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/VectorHelper.h" -#include "MantidAPI/Progress.h" +#include "MantidAPI/HistogramValidator.h" #include "MantidKernel/BoundedValidator.h" namespace Mantid { diff --git a/Framework/Algorithms/src/MedianDetectorTest.cpp b/Framework/Algorithms/src/MedianDetectorTest.cpp index 77aacd341507f67e1eb3e63aed54a1482291d817..c79c0eb1e07eb0923179fc162f93dc320b7223e2 100644 --- a/Framework/Algorithms/src/MedianDetectorTest.cpp +++ b/Framework/Algorithms/src/MedianDetectorTest.cpp @@ -1,6 +1,5 @@ #include "MantidAlgorithms/MedianDetectorTest.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/Exception.h" +#include "MantidAPI/HistogramValidator.h" #include "MantidKernel/BoundedValidator.h" #include <boost/math/special_functions/fpclassify.hpp> diff --git a/Framework/Algorithms/src/Min.cpp b/Framework/Algorithms/src/Min.cpp index 3a5308b3830f57c758d63fad0fcd83e4bcffdac7..9ef64db2439bff35c23ae087e21e5f88c3b2730e 100644 --- a/Framework/Algorithms/src/Min.cpp +++ b/Framework/Algorithms/src/Min.cpp @@ -2,9 +2,7 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/Min.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/VectorHelper.h" -#include "MantidAPI/Progress.h" +#include "MantidAPI/HistogramValidator.h" #include "MantidKernel/BoundedValidator.h" namespace Mantid { diff --git a/Framework/Algorithms/src/ModeratorTzero.cpp b/Framework/Algorithms/src/ModeratorTzero.cpp index 3363a67a67c6678cb115b142ad170536863f036f..91b979561b8520185f438b0a7f20898d60d681cc 100644 --- a/Framework/Algorithms/src/ModeratorTzero.cpp +++ b/Framework/Algorithms/src/ModeratorTzero.cpp @@ -2,14 +2,15 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/ModeratorTzero.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidDataObjects/Workspace2D.h" +#include "MantidAPI/WorkspaceUnitValidator.h" +#include "MantidDataObjects/EventList.h" #include "MantidDataObjects/EventWorkspace.h" +#include "MantidDataObjects/Workspace2D.h" +#include "MantidGeometry/muParser_Silent.h" #include "MantidKernel/ListValidator.h" #include "MantidKernel/UnitFactory.h" -#include "MantidGeometry/muParser_Silent.h" + #include <boost/lexical_cast.hpp> -#include "MantidDataObjects/EventList.h" namespace Mantid { namespace Algorithms { @@ -35,8 +36,7 @@ void ModeratorTzero::setFormula(const std::string &formula) { void ModeratorTzero::init() { - auto wsValidator = boost::make_shared<CompositeValidator>(); - wsValidator->add<WorkspaceUnitValidator>("TOF"); + auto wsValidator = boost::make_shared<WorkspaceUnitValidator>("TOF"); declareProperty(new WorkspaceProperty<MatrixWorkspace>( "InputWorkspace", "", Direction::Input, wsValidator), "The name of the input workspace, containing events and/or " diff --git a/Framework/Algorithms/src/ModeratorTzeroLinear.cpp b/Framework/Algorithms/src/ModeratorTzeroLinear.cpp index e05fb167d709390118651e08c1601cad936ae1ef..8e2820e42e81c4f6804659a9d5caf3b79d196830 100644 --- a/Framework/Algorithms/src/ModeratorTzeroLinear.cpp +++ b/Framework/Algorithms/src/ModeratorTzeroLinear.cpp @@ -2,9 +2,9 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/ModeratorTzeroLinear.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidDataObjects/Workspace2D.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidDataObjects/EventWorkspace.h" +#include "MantidDataObjects/Workspace2D.h" #include "MantidKernel/UnitFactory.h" #include <boost/lexical_cast.hpp> diff --git a/Framework/Algorithms/src/MonitorEfficiencyCorUser.cpp b/Framework/Algorithms/src/MonitorEfficiencyCorUser.cpp index 6b04c6163b6b0eb648f952a3611da0105d343efd..5278427de9e61d573a00f6cdee0ed2b5462857e7 100644 --- a/Framework/Algorithms/src/MonitorEfficiencyCorUser.cpp +++ b/Framework/Algorithms/src/MonitorEfficiencyCorUser.cpp @@ -1,10 +1,7 @@ #include "MantidAlgorithms/MonitorEfficiencyCorUser.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/BoundedValidator.h" -#include "MantidKernel/CompositeValidator.h" +#include "MantidAPI/InstrumentValidator.h" #include "MantidGeometry/muParser_Silent.h" #include "MantidKernel/MultiThreaded.h" -#include <ctime> namespace Mantid { namespace Algorithms { @@ -19,7 +16,8 @@ DECLARE_ALGORITHM(MonitorEfficiencyCorUser) //---------------------------------------------------------------------------------------------- /** Constructor */ -MonitorEfficiencyCorUser::MonitorEfficiencyCorUser() {} +MonitorEfficiencyCorUser::MonitorEfficiencyCorUser() + : m_inputWS(), m_outputWS(), m_Ei(.0), m_monitorCounts(0) {} //---------------------------------------------------------------------------------------------- /** Destructor diff --git a/Framework/Algorithms/src/MonteCarloAbsorption.cpp b/Framework/Algorithms/src/MonteCarloAbsorption.cpp index 0252a5bcd827c2cc9880b84ff1e4b3c1b0cbba3b..229285ea32c5d9657b1dc3698d050015afa5c314 100644 --- a/Framework/Algorithms/src/MonteCarloAbsorption.cpp +++ b/Framework/Algorithms/src/MonteCarloAbsorption.cpp @@ -2,13 +2,14 @@ // Includes //------------------------------------------------------------------------------ #include "MantidAlgorithms/MonteCarloAbsorption.h" -#include "MantidAPI/WorkspaceProperty.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/InstrumentValidator.h" #include "MantidAPI/SampleEnvironment.h" +#include "MantidAPI/WorkspaceProperty.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidGeometry/IDetector.h" #include "MantidGeometry/Objects/Track.h" #include "MantidKernel/BoundedValidator.h" -#include "MantidKernel/NeutronAtom.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/VectorHelper.h" #include <boost/random/uniform_int.hpp> diff --git a/Framework/Algorithms/src/MultipleScatteringCylinderAbsorption.cpp b/Framework/Algorithms/src/MultipleScatteringCylinderAbsorption.cpp index 5008df1b96ebf2bd8e1614d101794a1e297f951d..89ba570077bdf3a054c899ad7a2ecadde78e8430 100644 --- a/Framework/Algorithms/src/MultipleScatteringCylinderAbsorption.cpp +++ b/Framework/Algorithms/src/MultipleScatteringCylinderAbsorption.cpp @@ -2,9 +2,8 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/MultipleScatteringCylinderAbsorption.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/InstrumentValidator.h" #include "MantidDataObjects/EventWorkspace.h" -#include "MantidKernel/Exception.h" #include "MantidKernel/PhysicalConstants.h" #include <stdexcept> diff --git a/Framework/Algorithms/src/NormaliseByDetector.cpp b/Framework/Algorithms/src/NormaliseByDetector.cpp index 97e2ee6a72ee2c4ce3bddd1cb8b9f1af6f8a61b9..b06f40a2629a20cc0e6ff65cb37e1ac333000a01 100644 --- a/Framework/Algorithms/src/NormaliseByDetector.cpp +++ b/Framework/Algorithms/src/NormaliseByDetector.cpp @@ -1,18 +1,18 @@ #include "MantidAlgorithms/NormaliseByDetector.h" -#include "MantidKernel/System.h" -#include "MantidKernel/UnitFactory.h" -#include "MantidAPI/FunctionFactory.h" -#include "MantidAPI/MatrixWorkspace.h" -#include "MantidAPI/IFunction.h" #include "MantidAPI/FunctionDomain1D.h" +#include "MantidAPI/FunctionFactory.h" #include "MantidAPI/FunctionValues.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidAPI/Progress.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/IFunction.h" +#include "MantidAPI/MatrixWorkspace.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidGeometry/Instrument/ParameterMap.h" #include "MantidGeometry/Instrument/Component.h" #include "MantidGeometry/Instrument/DetectorGroup.h" #include "MantidGeometry/Instrument/FitParameter.h" #include "MantidGeometry/muParser_Silent.h" +#include "MantidKernel/CompositeValidator.h" +#include "MantidKernel/UnitFactory.h" using namespace Mantid::Kernel; using namespace Mantid::API; diff --git a/Framework/Algorithms/src/NormaliseToMonitor.cpp b/Framework/Algorithms/src/NormaliseToMonitor.cpp index d870469b1b28ec7a149c662388c9c2b5a19582f4..f8592f395175e7cacce6eaa1900828a11475a4dc 100644 --- a/Framework/Algorithms/src/NormaliseToMonitor.cpp +++ b/Framework/Algorithms/src/NormaliseToMonitor.cpp @@ -2,17 +2,19 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/NormaliseToMonitor.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/RawCountValidator.h" #include "MantidAPI/SpectraAxis.h" #include "MantidAPI/WorkspaceOpOverloads.h" -#include "MantidKernel/VectorHelper.h" +#include "MantidDataObjects/EventWorkspace.h" +#include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/EnabledWhenProperty.h" #include "MantidKernel/ListValidator.h" -#include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/VectorHelper.h" #include <cfloat> -#include "MantidDataObjects/EventWorkspace.h" -#include "MantidKernel/IPropertyManager.h" +#include <numeric> using namespace Mantid::DataObjects; using Mantid::Kernel::IPropertyManager; diff --git a/Framework/Algorithms/src/NormaliseToUnity.cpp b/Framework/Algorithms/src/NormaliseToUnity.cpp index 97edb9ce4fd2b1833a050d350419f22894c0e0f0..eb23f1cd5f3957c1429bee36a38a8ac50ee7bf49 100644 --- a/Framework/Algorithms/src/NormaliseToUnity.cpp +++ b/Framework/Algorithms/src/NormaliseToUnity.cpp @@ -2,9 +2,10 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/NormaliseToUnity.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidAPI/Progress.h" +#include "MantidAPI/CommonBinsValidator.h" +#include "MantidAPI/HistogramValidator.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/PDFFourierTransform.cpp b/Framework/Algorithms/src/PDFFourierTransform.cpp index 41219d20557743ef17e89f324f9d373a48fc65cf..c535813ba1e16eb49cdb089c19f3a28d6dbf4c1e 100644 --- a/Framework/Algorithms/src/PDFFourierTransform.cpp +++ b/Framework/Algorithms/src/PDFFourierTransform.cpp @@ -1,6 +1,5 @@ #include "MantidAlgorithms/PDFFourierTransform.h" -#include "MantidKernel/System.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/ListValidator.h" #include "MantidKernel/PhysicalConstants.h" diff --git a/Framework/Algorithms/src/PointByPointVCorrection.cpp b/Framework/Algorithms/src/PointByPointVCorrection.cpp index 6e001cfd900f4eaf4b31f68a7efac9aa6e57c44d..19bddb05cf7ace8ece1a461699194653f5970e58 100644 --- a/Framework/Algorithms/src/PointByPointVCorrection.cpp +++ b/Framework/Algorithms/src/PointByPointVCorrection.cpp @@ -3,9 +3,9 @@ //---------------------------------------------------------------------- #include "MantidAlgorithms/PointByPointVCorrection.h" #include "MantidKernel/VectorHelper.h" -#include "MantidAPI/WorkspaceValidators.h" #include <cfloat> #include <cmath> +#include <numeric> namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/Q1D2.cpp b/Framework/Algorithms/src/Q1D2.cpp index 78d913910c8e30a7bd7bd92c18ffff9d5a56914d..495d921058017d3549c8ac020d8ff4d9e06df281 100644 --- a/Framework/Algorithms/src/Q1D2.cpp +++ b/Framework/Algorithms/src/Q1D2.cpp @@ -2,16 +2,19 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/Q1D2.h" +#include "MantidAlgorithms/Qhelper.h" +#include "MantidAPI/CommonBinsValidator.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/ISpectrum.h" +#include "MantidAPI/WorkspaceUnitValidator.h" +#include "MantidDataObjects/Histogram1D.h" #include "MantidKernel/ArrayProperty.h" +#include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/RebinParamsValidator.h" #include "MantidKernel/UnitFactory.h" -#include "MantidKernel/PhysicalConstants.h" #include "MantidKernel/VectorHelper.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidDataObjects/Histogram1D.h" -#include "MantidAlgorithms/Qhelper.h" -#include "MantidKernel/BoundedValidator.h" -#include "MantidAPI/ISpectrum.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/Q1DWeighted.cpp b/Framework/Algorithms/src/Q1DWeighted.cpp index daa445af929575b29064d677926b51b6809aef40..806211eb597b8216f7990a6479d90949cbd6e5e7 100644 --- a/Framework/Algorithms/src/Q1DWeighted.cpp +++ b/Framework/Algorithms/src/Q1DWeighted.cpp @@ -2,15 +2,17 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/Q1DWeighted.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" +#include "MantidDataObjects/Histogram1D.h" #include "MantidKernel/ArrayProperty.h" +#include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" +#include "MantidKernel/PhysicalConstants.h" #include "MantidKernel/RebinParamsValidator.h" #include "MantidKernel/UnitFactory.h" -#include "MantidKernel/PhysicalConstants.h" #include "MantidKernel/VectorHelper.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidDataObjects/Histogram1D.h" -#include <vector> -#include "MantidKernel/BoundedValidator.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/Qhelper.cpp b/Framework/Algorithms/src/Qhelper.cpp index f8fb50ce236bacab30b4a38c0d5092c714b9b282..aad22cc3df354532788b013f50bced1db5f0205d 100644 --- a/Framework/Algorithms/src/Qhelper.cpp +++ b/Framework/Algorithms/src/Qhelper.cpp @@ -2,13 +2,6 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/Qhelper.h" -#include "MantidKernel/ArrayProperty.h" -#include "MantidKernel/RebinParamsValidator.h" -#include "MantidKernel/UnitFactory.h" -#include "MantidKernel/PhysicalConstants.h" -#include "MantidKernel/VectorHelper.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidDataObjects/Histogram1D.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/Qxy.cpp b/Framework/Algorithms/src/Qxy.cpp index d2609396a111e48832bc26e97db790e89d511937..b791d857ac10d6f6c45cc217d95f3feb626bfebd 100644 --- a/Framework/Algorithms/src/Qxy.cpp +++ b/Framework/Algorithms/src/Qxy.cpp @@ -4,10 +4,13 @@ #include "MantidAlgorithms/Qxy.h" #include "MantidAlgorithms/Qhelper.h" #include "MantidAPI/BinEdgeAxis.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" +#include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/UnitFactory.h" #include "MantidKernel/VectorHelper.h" -#include "MantidKernel/BoundedValidator.h" #include <boost/math/special_functions/fpclassify.hpp> namespace Mantid { diff --git a/Framework/Algorithms/src/ReadGroupsFromFile.cpp b/Framework/Algorithms/src/ReadGroupsFromFile.cpp index c355b8564e8dc78c40cccbfa5be5849ffc8299cd..fdfdf7844f95a19980f3b108f068962e7798a6d2 100644 --- a/Framework/Algorithms/src/ReadGroupsFromFile.cpp +++ b/Framework/Algorithms/src/ReadGroupsFromFile.cpp @@ -1,18 +1,14 @@ //---------------------------------------------------------------------- // Includes //---------------------------------------------------------------------- -#include <fstream> - #include "MantidAlgorithms/ReadGroupsFromFile.h" #include "MantidAPI/FileProperty.h" #include "MantidAPI/InstrumentDataService.h" +#include "MantidAPI/InstrumentValidator.h" #include "MantidAPI/MatrixWorkspace.h" #include "MantidAPI/WorkspaceProperty.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidDataObjects/Workspace2D.h" -#include "MantidKernel/ConfigService.h" #include "MantidKernel/ListValidator.h" -#include "MantidKernel/System.h" // Poco XML Headers for Grouping File #include <Poco/DOM/Document.h> @@ -20,6 +16,8 @@ #include <Poco/DOM/Element.h> #include <Poco/DOM/NodeList.h> +#include <fstream> + using namespace Mantid::API; using namespace Mantid::Kernel; using namespace Mantid::Geometry; diff --git a/Framework/Algorithms/src/Rebin.cpp b/Framework/Algorithms/src/Rebin.cpp index c1acf075fa22c0536aba77c1cd2d12d499b52fd0..678c303e3f1cd727b9fa5eca42004f28725cd96b 100644 --- a/Framework/Algorithms/src/Rebin.cpp +++ b/Framework/Algorithms/src/Rebin.cpp @@ -3,15 +3,11 @@ //---------------------------------------------------------------------- #include "MantidAlgorithms/Rebin.h" -#include "MantidKernel/ArrayProperty.h" -#include "MantidKernel/VectorHelper.h" -#include "MantidKernel/ListValidator.h" -#include "MantidKernel/RebinParamsValidator.h" -#include "MantidKernel/VisibleWhenProperty.h" - -#include "MantidAPI/WorkspaceValidators.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/EventList.h" +#include "MantidKernel/ArrayProperty.h" +#include "MantidKernel/RebinParamsValidator.h" +#include "MantidKernel/VectorHelper.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/ReflectometryReductionOne.cpp b/Framework/Algorithms/src/ReflectometryReductionOne.cpp index 430b9bf0c34bd19130093c35b65752f6773f0d17..4cd3d8f4e0c6db52a5be356d80c44a3e39320f29 100644 --- a/Framework/Algorithms/src/ReflectometryReductionOne.cpp +++ b/Framework/Algorithms/src/ReflectometryReductionOne.cpp @@ -1,12 +1,11 @@ #include "MantidAlgorithms/ReflectometryReductionOne.h" -#include "MantidGeometry/Instrument/ReferenceFrame.h" #include "MantidAPI/MatrixWorkspace.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidAPI/WorkspaceFactory.h" +#include "MantidAPI/WorkspaceUnitValidator.h" +#include "MantidGeometry/Instrument/ReferenceFrame.h" #include "MantidKernel/ListValidator.h" #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/EnabledWhenProperty.h" -#include "MantidKernel/RebinParamsValidator.h" #include <boost/make_shared.hpp> #include <boost/assign/list_of.hpp> diff --git a/Framework/Algorithms/src/ReflectometryReductionOneAuto.cpp b/Framework/Algorithms/src/ReflectometryReductionOneAuto.cpp index fcd4c481b612503e401b7d0f1d7ba2ec32581097..9f1ccdc743b5dff2c71919c6cbd687805997abf2 100644 --- a/Framework/Algorithms/src/ReflectometryReductionOneAuto.cpp +++ b/Framework/Algorithms/src/ReflectometryReductionOneAuto.cpp @@ -1,9 +1,9 @@ #include "MantidAlgorithms/ReflectometryReductionOneAuto.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/ListValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidKernel/ArrayProperty.h" -#include "MantidKernel/EnabledWhenProperty.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/EnabledWhenProperty.h" +#include "MantidKernel/ListValidator.h" #include "MantidKernel/RebinParamsValidator.h" #include <boost/optional.hpp> #include <boost/assign/list_of.hpp> @@ -110,9 +110,8 @@ void ReflectometryReductionOneAuto::init() { "I0 monitor workspace index"); declareProperty(new PropertyWithValue<std::string>("ProcessingInstructions", "", Direction::Input), - "Processing commands to select and add spectrum to make a " - "detector workspace. See [[PeformIndexOperations]] for " - "syntax."); + "Grouping pattern of workspace indices to yield only the" + " detectors of interest. See GroupDetectors for syntax."); declareProperty("WavelengthMin", Mantid::EMPTY_DBL(), "Wavelength Min in angstroms", Direction::Input); declareProperty("WavelengthMax", Mantid::EMPTY_DBL(), diff --git a/Framework/Algorithms/src/ReflectometryWorkflowBase.cpp b/Framework/Algorithms/src/ReflectometryWorkflowBase.cpp index 38522663a8796941adaa4650ccfff4bf01f2df63..94bb19678628d45155eabc132cbe78404505d4bd 100644 --- a/Framework/Algorithms/src/ReflectometryWorkflowBase.cpp +++ b/Framework/Algorithms/src/ReflectometryWorkflowBase.cpp @@ -1,9 +1,10 @@ -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/MandatoryValidator.h" +#include "MantidAlgorithms/ReflectometryWorkflowBase.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidKernel/ArrayProperty.h" -#include "MantidKernel/RebinParamsValidator.h" #include "MantidKernel/BoundedValidator.h" -#include "MantidAlgorithms/ReflectometryWorkflowBase.h" +#include "MantidKernel/CompositeValidator.h" +#include "MantidKernel/MandatoryValidator.h" +#include "MantidKernel/RebinParamsValidator.h" #include <boost/assign/list_of.hpp> diff --git a/Framework/Algorithms/src/Regroup.cpp b/Framework/Algorithms/src/Regroup.cpp index b3997f78f68c2899f31e85d3f23a45da697091dc..4abbbff1d039d7f1c053344fd272e4376f712315 100644 --- a/Framework/Algorithms/src/Regroup.cpp +++ b/Framework/Algorithms/src/Regroup.cpp @@ -2,11 +2,12 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/Regroup.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/CommonBinsValidator.h" +#include "MantidAPI/HistogramValidator.h" #include "MantidKernel/ArrayProperty.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/RebinParamsValidator.h" -#include <sstream> #include <numeric> #include <algorithm> #include <functional> diff --git a/Framework/Algorithms/src/RemoveBackground.cpp b/Framework/Algorithms/src/RemoveBackground.cpp index 76e10a78de8a04f7bae2ebe5ae3ec52c7f9aff19..c958ccedccdba37732122f297b3ac1c6255a2968 100644 --- a/Framework/Algorithms/src/RemoveBackground.cpp +++ b/Framework/Algorithms/src/RemoveBackground.cpp @@ -3,16 +3,18 @@ //---------------------------------------------------------------------- #include "MantidAlgorithms/RemoveBackground.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" +#include "MantidDataObjects/EventList.h" +#include "MantidDataObjects/EventWorkspace.h" #include "MantidKernel/ArrayProperty.h" -#include "MantidKernel/VectorHelper.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/ListValidator.h" #include "MantidKernel/RebinParamsValidator.h" +#include "MantidKernel/VectorHelper.h" #include "MantidKernel/VisibleWhenProperty.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidDataObjects/EventWorkspace.h" -#include "MantidDataObjects/EventList.h" - namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/RemoveBins.cpp b/Framework/Algorithms/src/RemoveBins.cpp index 48b633d5abc8382b5561401feb1ccb754ec5452b..9e8f74ede8b0fa0731859b299e06ab29430fe2df 100644 --- a/Framework/Algorithms/src/RemoveBins.cpp +++ b/Framework/Algorithms/src/RemoveBins.cpp @@ -2,11 +2,13 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/RemoveBins.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/UnitFactory.h" -#include "MantidKernel/MandatoryValidator.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/ListValidator.h" +#include "MantidKernel/MandatoryValidator.h" +#include "MantidKernel/UnitFactory.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/RemoveLowResTOF.cpp b/Framework/Algorithms/src/RemoveLowResTOF.cpp index 621db894fb1fd07f891f55f06bcdeedf848e6ff4..47c65f788a2dcedd00454e6deedd04158edf912f 100644 --- a/Framework/Algorithms/src/RemoveLowResTOF.cpp +++ b/Framework/Algorithms/src/RemoveLowResTOF.cpp @@ -1,8 +1,11 @@ -#include "MantidAlgorithms/AlignDetectors.h" #include "MantidAlgorithms/RemoveLowResTOF.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/RawCountValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidGeometry/Instrument.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/EnabledWhenProperty.h" #include "MantidKernel/UnitFactory.h" #include <limits> diff --git a/Framework/Algorithms/src/RemovePromptPulse.cpp b/Framework/Algorithms/src/RemovePromptPulse.cpp index ceaecb85d4746b238478623d474eab6efed925c3..ae43e1db8dbe835485aa5c68b3b806afb63fd5b4 100644 --- a/Framework/Algorithms/src/RemovePromptPulse.cpp +++ b/Framework/Algorithms/src/RemovePromptPulse.cpp @@ -1,9 +1,8 @@ #include "MantidAlgorithms/RemovePromptPulse.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidDataObjects/EventWorkspace.h" -#include "MantidKernel/System.h" -#include "MantidKernel/TimeSeriesProperty.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/TimeSeriesProperty.h" using std::string; namespace Mantid { @@ -72,7 +71,7 @@ void getTofRange(MatrixWorkspace_const_sptr wksp, double &tmin, double &tmax) { DataObjects::EventWorkspace_const_sptr eventWksp = boost::dynamic_pointer_cast<const DataObjects::EventWorkspace>(wksp); - bool isEvent = false; + const bool isEvent = false; if (isEvent) { eventWksp->getEventXMinMax(tmin, tmax); } else { diff --git a/Framework/Algorithms/src/ResampleX.cpp b/Framework/Algorithms/src/ResampleX.cpp index c8386e5d6f7f132218aa7d9168f3f42864788c4d..78f2267942ebe3790e4ab791a99014d348b07654 100644 --- a/Framework/Algorithms/src/ResampleX.cpp +++ b/Framework/Algorithms/src/ResampleX.cpp @@ -1,11 +1,11 @@ -#include <sstream> #include "MantidAlgorithms/ResampleX.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/VectorHelper.h" +#include <sstream> + namespace Mantid { namespace Algorithms { using namespace API; diff --git a/Framework/Algorithms/src/SANSDirectBeamScaling.cpp b/Framework/Algorithms/src/SANSDirectBeamScaling.cpp index f603aaed91cd7ed1293125ae4dbe3e8ff5713713..1ae0064a116eb8db2c871ee87dadfd1c1ad68cdd 100644 --- a/Framework/Algorithms/src/SANSDirectBeamScaling.cpp +++ b/Framework/Algorithms/src/SANSDirectBeamScaling.cpp @@ -2,15 +2,16 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/SANSDirectBeamScaling.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" +#include "MantidDataObjects/Histogram1D.h" #include "MantidKernel/ArrayProperty.h" +#include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/RebinParamsValidator.h" -#include "MantidKernel/UnitFactory.h" #include "MantidKernel/PhysicalConstants.h" +#include "MantidKernel/UnitFactory.h" #include "MantidKernel/VectorHelper.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidDataObjects/Histogram1D.h" -#include <vector> -#include "MantidKernel/BoundedValidator.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/SampleCorrections/MayersSampleCorrection.cpp b/Framework/Algorithms/src/SampleCorrections/MayersSampleCorrection.cpp index a849986bdc52fb2d29c473ef6a9088feed22e869..071b81d604bafcf800a4cd353e4bb2c00a84297c 100644 --- a/Framework/Algorithms/src/SampleCorrections/MayersSampleCorrection.cpp +++ b/Framework/Algorithms/src/SampleCorrections/MayersSampleCorrection.cpp @@ -3,9 +3,9 @@ //------------------------------------------------------------------------------ #include "MantidAlgorithms/SampleCorrections/MayersSampleCorrection.h" #include "MantidAlgorithms/SampleCorrections/MayersSampleCorrectionStrategy.h" -#include "MantidAPI/Progress.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/SampleValidator.h" #include "MantidAPI/WorkspaceFactory.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidGeometry/Instrument/ReferenceFrame.h" #include "MantidKernel/CompositeValidator.h" diff --git a/Framework/Algorithms/src/SetInstrumentParameter.cpp b/Framework/Algorithms/src/SetInstrumentParameter.cpp index e06d9b1f72eb441cf90572f88ff4e4551f7db4a2..63a006dedbee290d5530be631171b8a8d01aae8c 100644 --- a/Framework/Algorithms/src/SetInstrumentParameter.cpp +++ b/Framework/Algorithms/src/SetInstrumentParameter.cpp @@ -1,10 +1,10 @@ #include "MantidAlgorithms/SetInstrumentParameter.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidGeometry/Instrument.h" #include "MantidKernel/ArrayProperty.h" -#include "MantidKernel/MandatoryValidator.h" #include "MantidKernel/ListValidator.h" +#include "MantidKernel/MandatoryValidator.h" #include "MantidKernel/Strings.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidGeometry/Instrument.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/SmoothNeighbours.cpp b/Framework/Algorithms/src/SmoothNeighbours.cpp index ad39fb1d85c8c6b396edca2267188b3f0ff4f828..ef6a97273b595673dbf46a1c111856a2c73b887d 100644 --- a/Framework/Algorithms/src/SmoothNeighbours.cpp +++ b/Framework/Algorithms/src/SmoothNeighbours.cpp @@ -1,5 +1,5 @@ #include "MantidAlgorithms/SmoothNeighbours.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/InstrumentValidator.h" #include "MantidDataObjects/EventList.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/OffsetsWorkspace.h" @@ -8,11 +8,12 @@ #include "MantidGeometry/IComponent.h" #include "MantidGeometry/Instrument/RectangularDetector.h" #include "MantidGeometry/Instrument/DetectorGroup.h" +#include "MantidKernel/BoundedValidator.h" #include "MantidKernel/EnabledWhenProperty.h" +#include "MantidKernel/ListValidator.h" + #include <boost/algorithm/string.hpp> #include <boost/regex.hpp> -#include "MantidKernel/BoundedValidator.h" -#include "MantidKernel/ListValidator.h" using namespace Mantid::Kernel; using namespace Mantid::Geometry; diff --git a/Framework/Algorithms/src/SofQW.cpp b/Framework/Algorithms/src/SofQW.cpp index 8c6480f1954dfbe560ce3fab319cda5af791acbd..e56ce439f3a85ca4ced59d16ae7d9fd0ef11aa0d 100644 --- a/Framework/Algorithms/src/SofQW.cpp +++ b/Framework/Algorithms/src/SofQW.cpp @@ -4,17 +4,22 @@ #include <stdexcept> #include "MantidAlgorithms/SofQW.h" -#include "MantidDataObjects/Histogram1D.h" #include "MantidAPI/BinEdgeAxis.h" +#include "MantidAPI/CommonBinsValidator.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/InstrumentValidator.h" #include "MantidAPI/SpectrumDetectorMapping.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/ArrayProperty.h" -#include "MantidKernel/RebinParamsValidator.h" -#include "MantidKernel/VectorHelper.h" -#include "MantidKernel/UnitFactory.h" +#include "MantidAPI/SpectraAxisValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" +#include "MantidDataObjects/Histogram1D.h" #include "MantidGeometry/Instrument/DetectorGroup.h" +#include "MantidKernel/ArrayProperty.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/ListValidator.h" +#include "MantidKernel/RebinParamsValidator.h" +#include "MantidKernel/UnitFactory.h" +#include "MantidKernel/VectorHelper.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/SofQWCentre.cpp b/Framework/Algorithms/src/SofQWCentre.cpp index d6763d7a59eaa9639a97f3eb6420ee91c4f86812..34c28e07a785dd55c560fc2412dbdd80fbf5208b 100644 --- a/Framework/Algorithms/src/SofQWCentre.cpp +++ b/Framework/Algorithms/src/SofQWCentre.cpp @@ -1,20 +1,26 @@ //---------------------------------------------------------------------- // Includes //---------------------------------------------------------------------- -#include <stdexcept> - #include "MantidAlgorithms/SofQWCentre.h" #include "MantidDataObjects/Histogram1D.h" #include "MantidAPI/BinEdgeAxis.h" +#include "MantidAPI/CommonBinsValidator.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/SpectraAxisValidator.h" #include "MantidAPI/SpectrumDetectorMapping.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/ArrayProperty.h" -#include "MantidKernel/RebinParamsValidator.h" -#include "MantidKernel/VectorHelper.h" -#include "MantidKernel/UnitFactory.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidGeometry/Instrument/DetectorGroup.h" +#include "MantidKernel/ArrayProperty.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/ListValidator.h" +#include "MantidKernel/RebinParamsValidator.h" +#include "MantidKernel/UnitFactory.h" +#include "MantidKernel/VectorHelper.h" + +#include <numeric> +#include <stdexcept> namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/SolidAngle.cpp b/Framework/Algorithms/src/SolidAngle.cpp index 43b76ee1ee8f49476722d268e6d5b66e4a705ed5..b1d092b70bab0ec7f549ca54fa2b3af6d9c040a3 100644 --- a/Framework/Algorithms/src/SolidAngle.cpp +++ b/Framework/Algorithms/src/SolidAngle.cpp @@ -2,11 +2,11 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/SolidAngle.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidAPI/AlgorithmFactory.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidKernel/BoundedValidator.h" #include "MantidKernel/UnitFactory.h" + #include <cfloat> -#include "MantidKernel/BoundedValidator.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/SortEvents.cpp b/Framework/Algorithms/src/SortEvents.cpp index fef7295a185d1c2c80208dbb24a81fcdce4e4d00..77b619f5a277e119f59bec706dda1d063faf21e9 100644 --- a/Framework/Algorithms/src/SortEvents.cpp +++ b/Framework/Algorithms/src/SortEvents.cpp @@ -2,7 +2,6 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/SortEvents.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/ListValidator.h" diff --git a/Framework/Algorithms/src/SpecularReflectionPositionCorrect.cpp b/Framework/Algorithms/src/SpecularReflectionPositionCorrect.cpp index 3497a23d437b317b942c9f2da90897a1a40f95f5..bf1dc7ae29423ab0ccef331b3deca16b4f3367b5 100644 --- a/Framework/Algorithms/src/SpecularReflectionPositionCorrect.cpp +++ b/Framework/Algorithms/src/SpecularReflectionPositionCorrect.cpp @@ -1,12 +1,10 @@ #include "MantidAlgorithms/SpecularReflectionPositionCorrect.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidGeometry/Instrument/ComponentHelper.h" +#include "MantidGeometry/Instrument/DetectorGroup.h" +#include "MantidGeometry/Instrument/ReferenceFrame.h" #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/CompositeValidator.h" #include "MantidKernel/MandatoryValidator.h" -#include "MantidGeometry/Instrument/DetectorGroup.h" -#include "MantidGeometry/Instrument/ReferenceFrame.h" -#include "MantidGeometry/Instrument/ComponentHelper.h" -#include <boost/make_shared.hpp> using namespace Mantid::API; using namespace Mantid::Geometry; diff --git a/Framework/Algorithms/src/SphericalAbsorption.cpp b/Framework/Algorithms/src/SphericalAbsorption.cpp index 9449eb51b422f88ac99edf0969c46e844da18d9b..73fd77e14af619b155f3a136cd1755cd36b66307 100644 --- a/Framework/Algorithms/src/SphericalAbsorption.cpp +++ b/Framework/Algorithms/src/SphericalAbsorption.cpp @@ -2,14 +2,16 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/SphericalAbsorption.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidGeometry/Objects/ShapeFactory.h" -#include "MantidKernel/UnitFactory.h" -#include "MantidKernel/Fast_Exponential.h" -#include "MantidKernel/VectorHelper.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/Workspace2D.h" +#include "MantidGeometry/Objects/ShapeFactory.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" +#include "MantidKernel/Fast_Exponential.h" +#include "MantidKernel/UnitFactory.h" +#include "MantidKernel/VectorHelper.h" using namespace Mantid::PhysicalConstants; diff --git a/Framework/Algorithms/src/Stitch1D.cpp b/Framework/Algorithms/src/Stitch1D.cpp index 813bfdb825de1e19bbd158d85666eb04843e10a3..6ee41612d24897405c9e5928f9038edfd67fc6d5 100644 --- a/Framework/Algorithms/src/Stitch1D.cpp +++ b/Framework/Algorithms/src/Stitch1D.cpp @@ -1,19 +1,17 @@ #include "MantidAlgorithms/Stitch1D.h" #include "MantidAPI/WorkspaceProperty.h" #include "MantidAPI/MatrixWorkspace.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/PropertyWithValue.h" #include "MantidKernel/RebinParamsValidator.h" #include "MantidKernel/MultiThreaded.h" #include "MantidKernel/BoundedValidator.h" -#include <boost/make_shared.hpp> #include <boost/tuple/tuple.hpp> #include <boost/format.hpp> #include <boost/algorithm/string.hpp> #include <boost/math/special_functions.hpp> -#include <vector> #include <algorithm> using namespace Mantid::Kernel; diff --git a/Framework/Algorithms/src/Stitch1DMany.cpp b/Framework/Algorithms/src/Stitch1DMany.cpp index 8611b757ee9372acc8d756c7727534fc5312364a..da43501fa7b14433aa4c573525dd0a9656726c54 100644 --- a/Framework/Algorithms/src/Stitch1DMany.cpp +++ b/Framework/Algorithms/src/Stitch1DMany.cpp @@ -1,11 +1,9 @@ #include "MantidAlgorithms/Stitch1DMany.h" -#include "MantidAPI/AlgorithmManager.h" -#include "MantidAPI/WorkspaceProperty.h" #include "MantidAPI/MatrixWorkspace.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/WorkspaceProperty.h" #include "MantidKernel/ArrayProperty.h" -#include "MantidKernel/RebinParamsValidator.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/RebinParamsValidator.h" #include <boost/make_shared.hpp> diff --git a/Framework/Algorithms/src/StripVanadiumPeaks.cpp b/Framework/Algorithms/src/StripVanadiumPeaks.cpp index a50de4c62c0e6fb950dd1969e43b69944d38a9fb..491687e7948474a92a65822acc7f9722abe98c79 100644 --- a/Framework/Algorithms/src/StripVanadiumPeaks.cpp +++ b/Framework/Algorithms/src/StripVanadiumPeaks.cpp @@ -1,10 +1,9 @@ #include "MantidAlgorithms/StripVanadiumPeaks.h" -#include "MantidKernel/PhysicalConstants.h" -#include "MantidDataObjects/EventWorkspace.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidAPI/TableRow.h" -#include "MantidKernel/VectorHelper.h" +#include "MantidDataObjects/EventWorkspace.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/PhysicalConstants.h" +#include "MantidKernel/VectorHelper.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/SumNeighbours.cpp b/Framework/Algorithms/src/SumNeighbours.cpp index dcdb670b48c38eb86bf590ba2691095f4af6d23e..f029f7fa5714f5c359dccf703c146416eebdb92b 100644 --- a/Framework/Algorithms/src/SumNeighbours.cpp +++ b/Framework/Algorithms/src/SumNeighbours.cpp @@ -2,15 +2,16 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/SumNeighbours.h" +#include "MantidAPI/InstrumentValidator.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/EventList.h" #include "MantidGeometry/IComponent.h" #include "MantidGeometry/ICompAssembly.h" #include "MantidGeometry/Instrument/RectangularDetector.h" -#include "MantidAPI/WorkspaceValidators.h" -#include <boost/algorithm/string.hpp> #include "MantidKernel/BoundedValidator.h" +#include <boost/algorithm/string.hpp> + namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/SumSpectra.cpp b/Framework/Algorithms/src/SumSpectra.cpp index 7388ab59c7f2e88fa2bee3e86cdbc770f386f2ba..612141dab3fa7cc3a3bfe4e75dded4cb76441bbf 100644 --- a/Framework/Algorithms/src/SumSpectra.cpp +++ b/Framework/Algorithms/src/SumSpectra.cpp @@ -2,10 +2,10 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/SumSpectra.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/CommonBinsValidator.h" +#include "MantidDataObjects/RebinnedOutput.h" #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/BoundedValidator.h" -#include "MantidDataObjects/RebinnedOutput.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/TOFSANSResolution.cpp b/Framework/Algorithms/src/TOFSANSResolution.cpp index 342c6719e5e37dcd02738da33a7841cd53d8dfdd..18cb26fd59f926325adfc7c879ffc1c25baf1b25 100644 --- a/Framework/Algorithms/src/TOFSANSResolution.cpp +++ b/Framework/Algorithms/src/TOFSANSResolution.cpp @@ -2,16 +2,16 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/TOFSANSResolution.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidDataObjects/EventWorkspace.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidDataObjects/EventList.h" +#include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/Workspace2D.h" -#include "MantidKernel/RebinParamsValidator.h" #include "MantidKernel/ArrayProperty.h" +#include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/RebinParamsValidator.h" #include "MantidKernel/VectorHelper.h" #include "boost/math/special_functions/fpclassify.hpp" -#include "MantidKernel/BoundedValidator.h" namespace Mantid { namespace Algorithms { @@ -34,8 +34,7 @@ void TOFSANSResolution::init() { boost::make_shared<WorkspaceUnitValidator>("MomentumTransfer")), "Name the workspace to calculate the resolution for"); - auto wsValidator = boost::make_shared<CompositeValidator>(); - wsValidator->add<WorkspaceUnitValidator>("Wavelength"); + auto wsValidator = boost::make_shared<WorkspaceUnitValidator>("Wavelength"); declareProperty(new WorkspaceProperty<>("ReducedWorkspace", "", Direction::Input, wsValidator), "I(Q) workspace"); diff --git a/Framework/Algorithms/src/TOFSANSResolutionByPixel.cpp b/Framework/Algorithms/src/TOFSANSResolutionByPixel.cpp index d405f9179ba1c08486d26d4a218ecf6c61762f2c..51071266677504efc8e7763dd1bc05b4d44b00c2 100644 --- a/Framework/Algorithms/src/TOFSANSResolutionByPixel.cpp +++ b/Framework/Algorithms/src/TOFSANSResolutionByPixel.cpp @@ -2,12 +2,10 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/TOFSANSResolutionByPixel.h" +#include "MantidAlgorithms/GravitySANSHelper.h" #include "MantidAlgorithms/TOFSANSResolutionByPixelCalculator.h" #include "MantidAlgorithms/SANSCollimationLengthEstimator.h" -#include "MantidAlgorithms/GravitySANSHelper.h" -#include "MantidAlgorithms/CloneWorkspace.h" -#include "MantidAlgorithms/RebinToWorkspace.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidDataObjects/Workspace2D.h" #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/BoundedValidator.h" diff --git a/Framework/Algorithms/src/Transpose.cpp b/Framework/Algorithms/src/Transpose.cpp index af9019a8b8a3a8dde651495e86b89e786cfb8f26..194f41ee9e0f85dfb35137b00fd02de8eb264966 100644 --- a/Framework/Algorithms/src/Transpose.cpp +++ b/Framework/Algorithms/src/Transpose.cpp @@ -3,8 +3,8 @@ //---------------------------------------------------------------------- #include "MantidAlgorithms/Transpose.h" #include "MantidAPI/BinEdgeAxis.h" +#include "MantidAPI/CommonBinsValidator.h" #include "MantidAPI/NumericAxis.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidDataObjects/RebinnedOutput.h" namespace Mantid { diff --git a/Framework/Algorithms/src/UnwrapMonitor.cpp b/Framework/Algorithms/src/UnwrapMonitor.cpp index df3d8df8104a2f16cb93ebb85d2263a742d9716b..59f85033b655d16ef9701a79348e9725cbaa0bc2 100644 --- a/Framework/Algorithms/src/UnwrapMonitor.cpp +++ b/Framework/Algorithms/src/UnwrapMonitor.cpp @@ -2,10 +2,14 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/UnwrapMonitor.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/UnitFactory.h" -#include "MantidKernel/PhysicalConstants.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/RawCountValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" +#include "MantidKernel/PhysicalConstants.h" +#include "MantidKernel/UnitFactory.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/UnwrapSNS.cpp b/Framework/Algorithms/src/UnwrapSNS.cpp index eac769d4381f6a6f460f32a373cc4c33d1d808f2..0c9a7eb777777fa8d7519ea6f15dc8c119f43bb0 100644 --- a/Framework/Algorithms/src/UnwrapSNS.cpp +++ b/Framework/Algorithms/src/UnwrapSNS.cpp @@ -2,12 +2,17 @@ // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/UnwrapSNS.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/RawCountValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidDataObjects/EventList.h" -#include "MantidKernel/UnitFactory.h" +#include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/PhysicalConstants.h" +#include "MantidKernel/UnitFactory.h" + #include <limits> -#include "MantidKernel/BoundedValidator.h" namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/test/GetAllEiTest.h b/Framework/Algorithms/test/GetAllEiTest.h new file mode 100644 index 0000000000000000000000000000000000000000..9dfadd5311c1761101143bc1832f02b64436d75e --- /dev/null +++ b/Framework/Algorithms/test/GetAllEiTest.h @@ -0,0 +1,584 @@ +#ifndef GETALLEI_TEST_H_ +#define GETALLEI_TEST_H_ + +#include <memory> +#include <boost/math/special_functions/fpclassify.hpp> +#include <cxxtest/TestSuite.h> +#include "MantidAlgorithms/GetAllEi.h" +#include "MantidKernel/TimeSeriesProperty.h" +#include "MantidTestHelpers/WorkspaceCreationHelper.h" + +using namespace Mantid; +using namespace Mantid::Algorithms; +using namespace Mantid::API; + +class GetAllEiTester : public GetAllEi { +public: + void find_chop_speed_and_delay(const API::MatrixWorkspace_sptr &inputWS, + double &chop_speed, double &chop_delay) { + GetAllEi::findChopSpeedAndDelay(inputWS, chop_speed, chop_delay); + } + void findGuessOpeningTimes(const std::pair<double, double> &TOF_range, + double ChopDelay, double Period, + std::vector<double> &guess_opening_times) { + GetAllEi::findGuessOpeningTimes(TOF_range, ChopDelay, Period, + guess_opening_times); + } + bool filterLogProvided() const { return (m_pFilterLog != NULL); } + double getAvrgLogValue(const API::MatrixWorkspace_sptr &inputWS, + const std::string &propertyName) { + std::vector<Kernel::SplittingInterval> splitter; + return GetAllEi::getAvrgLogValue(inputWS, propertyName, splitter); + } + API::MatrixWorkspace_sptr + buildWorkspaceToFit(const API::MatrixWorkspace_sptr &inputWS, + size_t &wsIndex0) { + return GetAllEi::buildWorkspaceToFit(inputWS, wsIndex0); + } + void findBinRanges(const MantidVec &eBins, const MantidVec &signal, + const std::vector<double> &guess_energies, + double Eresolution, std::vector<size_t> &irangeMin, + std::vector<size_t> &irangeMax, + std::vector<bool> &guessValid) { + GetAllEi::findBinRanges(eBins, signal, guess_energies, Eresolution, + irangeMin, irangeMax, guessValid); + } + void setResolution(double newResolution) { + this->m_max_Eresolution = newResolution; + } + size_t calcDerivativeAndCountZeros(const std::vector<double> &bins, + const std::vector<double> &signal, + std::vector<double> &deriv, + std::vector<double> &zeros) { + return GetAllEi::calcDerivativeAndCountZeros(bins, signal, deriv, zeros); + } +}; + +class GetAllEiTest : 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 GetAllEiTest *createSuite() { return new GetAllEiTest(); } + static void destroySuite(GetAllEiTest *suite) { delete suite; } + + GetAllEiTest() {} + +public: + void testName() { TS_ASSERT_EQUALS(m_getAllEi.name(), "GetAllEi"); } + + void testVersion() { TS_ASSERT_EQUALS(m_getAllEi.version(), 1); } + + void testInit() { + TS_ASSERT_THROWS_NOTHING(m_getAllEi.initialize()); + TS_ASSERT(m_getAllEi.isInitialized()); + } + // + void test_validators_work() { + + MatrixWorkspace_sptr ws = this->createTestingWS(true); + + m_getAllEi.initialize(); + m_getAllEi.setProperty("Workspace", ws); + m_getAllEi.setProperty("OutputWorkspace", "monitor_peaks"); + TSM_ASSERT_THROWS( + "should throw runtime error on as spectra ID should be positive", + m_getAllEi.setProperty("Monitor1SpecID", -1), std::invalid_argument); + + m_getAllEi.setProperty("Monitor1SpecID", 1); + m_getAllEi.setProperty("Monitor2SpecID", 2); + m_getAllEi.setProperty("ChopperSpeedLog", "Chopper_Speed"); + m_getAllEi.setProperty("ChopperDelayLog", "Chopper_Delay"); + m_getAllEi.setProperty("FilterBaseLog", "proton_charge"); + m_getAllEi.setProperty("FilterWithDerivative", false); + + TSM_ASSERT_THROWS("should throw runtime error on validation as no " + "appropriate logs are defined", + m_getAllEi.execute(), std::runtime_error); + auto log_messages = m_getAllEi.validateInputs(); + TSM_ASSERT_EQUALS("Two logs should fail", log_messages.size(), 2); + // add invalid property type + ws->mutableRun().addLogData( + new Kernel::PropertyWithValue<double>("Chopper_Speed", 10.)); + auto log_messages2 = m_getAllEi.validateInputs(); + TSM_ASSERT_EQUALS("Two logs should fail", log_messages2.size(), 2); + + TSM_ASSERT_DIFFERS("should fail for different reason ", + log_messages["ChopperSpeedLog"], + log_messages2["ChopperSpeedLog"]); + // add correct property type: + ws->mutableRun().clearLogs(); + ws->mutableRun().addLogData( + new Kernel::TimeSeriesProperty<double>("Chopper_Speed")); + log_messages = m_getAllEi.validateInputs(); + TSM_ASSERT_EQUALS("One log should fail", log_messages.size(), 1); + TSM_ASSERT("Filter log is not provided ", !m_getAllEi.filterLogProvided()); + ws->mutableRun().addLogData( + new Kernel::TimeSeriesProperty<double>("Chopper_Delay")); + ws->mutableRun().addLogData( + new Kernel::TimeSeriesProperty<double>("proton_charge")); + log_messages = m_getAllEi.validateInputs(); + + TSM_ASSERT_EQUALS("All logs are defined", log_messages.size(), 0); + TSM_ASSERT("Filter log is provided ", m_getAllEi.filterLogProvided()); + + m_getAllEi.setProperty("Monitor1SpecID", 3); + log_messages = m_getAllEi.validateInputs(); + TSM_ASSERT_EQUALS("Workspace should not have spectra with ID=3", + log_messages.size(), 1); + } + // + void test_get_chopper_speed() { + + MatrixWorkspace_sptr ws = this->createTestingWS(true); + + m_getAllEi.initialize(); + m_getAllEi.setProperty("Workspace", ws); + m_getAllEi.setProperty("OutputWorkspace", "monitor_peaks"); + m_getAllEi.setProperty("Monitor1SpecID", 1); + m_getAllEi.setProperty("Monitor2SpecID", 2); + m_getAllEi.setProperty("ChopperSpeedLog", "Chopper_Speed"); + m_getAllEi.setProperty("ChopperDelayLog", "Chopper_Delay"); + m_getAllEi.setProperty("FilterBaseLog", "proton_charge"); + m_getAllEi.setProperty("FilterWithDerivative", false); + + std::unique_ptr<Kernel::TimeSeriesProperty<double>> chopSpeed( + new Kernel::TimeSeriesProperty<double>("Chopper_Speed")); + for (int i = 0; i < 10; i++) { + chopSpeed->addValue(Kernel::DateAndTime(10000 + 10 * i, 0), 1.); + } + for (int i = 0; i < 10; i++) { + chopSpeed->addValue(Kernel::DateAndTime(100 + 10 * i, 0), 10.); + } + for (int i = 0; i < 10; i++) { + chopSpeed->addValue(Kernel::DateAndTime(10 * i, 0), 100.); + } + ws->mutableRun().addLogData(chopSpeed.release()); + + // Test sort log by run time. + TSM_ASSERT_THROWS( + "Attempt to get log without start/stop time set should fail", + m_getAllEi.getAvrgLogValue(ws, "ChopperSpeedLog"), std::runtime_error); + + ws->mutableRun().setStartAndEndTime(Kernel::DateAndTime(90, 0), + Kernel::DateAndTime(10000, 0)); + double val = m_getAllEi.getAvrgLogValue(ws, "ChopperSpeedLog"); + TS_ASSERT_DELTA(val, (10 * 10 + 100.) / 11., 1.e-6); + + ws->mutableRun().setStartAndEndTime(Kernel::DateAndTime(100, 0), + Kernel::DateAndTime(10000, 0)); + val = m_getAllEi.getAvrgLogValue(ws, "ChopperSpeedLog"); + TS_ASSERT_DELTA(val, 10., 1.e-6); + + // Test sort log by log. + std::unique_ptr<Kernel::TimeSeriesProperty<double>> chopDelay( + new Kernel::TimeSeriesProperty<double>("Chopper_Delay")); + std::unique_ptr<Kernel::TimeSeriesProperty<double>> goodFram( + new Kernel::TimeSeriesProperty<double>("proton_charge")); + + for (int i = 0; i < 10; i++) { + auto time = Kernel::DateAndTime(200 + 10 * i, 0); + chopDelay->addValue(time, 10.); + if (i < 2) { + goodFram->addValue(time, 1); + } else { + goodFram->addValue(time, 0); + } + } + for (int i = 0; i < 10; i++) { + auto time = Kernel::DateAndTime(100 + 10 * i, 0); + chopDelay->addValue(time, 0.1); + goodFram->addValue(time, 1); + } + for (int i = 0; i < 10; i++) { + auto time = Kernel::DateAndTime(10 * i, 0); + chopDelay->addValue(time, 1.); + goodFram->addValue(time, 0); + } + ws->mutableRun().addLogData(chopDelay.release()); + ws->mutableRun().addLogData(goodFram.release()); + + // Run validate as this will set up property, which indicates filter log + // presence + auto errors = m_getAllEi.validateInputs(); + TSM_ASSERT_EQUALS("All logs are defined now", errors.size(), 0); + + double chop_speed, chop_delay; + m_getAllEi.find_chop_speed_and_delay(ws, chop_speed, chop_delay); + TSM_ASSERT_DELTA("Chopper delay should have special speed ", + (10 * 0.1 + 20) / 12., chop_delay, 1.e-6); + + goodFram.reset(new Kernel::TimeSeriesProperty<double>("proton_charge")); + for (int i = 0; i < 10; i++) { + auto time = Kernel::DateAndTime(100 + 10 * i, 0); + goodFram->addValue(time, 1); + } + + ws->mutableRun().addProperty(goodFram.release(), true); + errors = m_getAllEi.validateInputs(); + TSM_ASSERT_EQUALS("All logs are defined now", errors.size(), 0); + + m_getAllEi.find_chop_speed_and_delay(ws, chop_speed, chop_delay); + TSM_ASSERT_DELTA("Chopper delay should have special speed", 0.1, chop_delay, + 1.e-6); + } + void test_get_chopper_speed_filter_derivative() { + + MatrixWorkspace_sptr ws = this->createTestingWS(true); + + m_getAllEi.initialize(); + m_getAllEi.setProperty("Workspace", ws); + m_getAllEi.setProperty("OutputWorkspace", "monitor_peaks"); + m_getAllEi.setProperty("Monitor1SpecID", 1); + m_getAllEi.setProperty("Monitor2SpecID", 2); + m_getAllEi.setProperty("ChopperSpeedLog", "Chopper_Speed"); + m_getAllEi.setProperty("ChopperDelayLog", "Chopper_Delay"); + m_getAllEi.setProperty("FilterBaseLog", "proton_charge"); + m_getAllEi.setProperty("FilterWithDerivative", true); + + // Test select log by log derivative + std::unique_ptr<Kernel::TimeSeriesProperty<double>> chopDelay( + new Kernel::TimeSeriesProperty<double>("Chopper_Delay")); + std::unique_ptr<Kernel::TimeSeriesProperty<double>> chopSpeed( + new Kernel::TimeSeriesProperty<double>("Chopper_Speed")); + std::unique_ptr<Kernel::TimeSeriesProperty<double>> protCharge( + new Kernel::TimeSeriesProperty<double>("proton_charge")); + + double gf(0); + for (int i = 0; i < 50; i++) { + auto time = Kernel::DateAndTime(10 * i, 0); + if (i > 10 && i < 20) { + chopDelay->addValue(time, 100.); + chopSpeed->addValue(time, 0.); + protCharge->addValue(time, gf); + } else { + chopDelay->addValue(time, 10.); + chopSpeed->addValue(time, 50.); + protCharge->addValue(time, gf); + gf++; + } + } + ws->mutableRun().addLogData(chopSpeed.release()); + ws->mutableRun().addLogData(chopDelay.release()); + ws->mutableRun().addLogData(protCharge.release()); + + // Run validate as this will set up property, which indicates filter log + // presence + auto errors = m_getAllEi.validateInputs(); + TSM_ASSERT_EQUALS("All logs are defined now", errors.size(), 0); + + double chop_speed, chop_delay; + m_getAllEi.find_chop_speed_and_delay(ws, chop_speed, chop_delay); + TSM_ASSERT_DELTA("Chopper delay should have defined value ", 10., + chop_delay, 1.e-6); + TSM_ASSERT_DELTA("Chopper speed should have defined speed", 50., chop_speed, + 1.e-6); + } + + void test_guess_opening_times() { + + std::pair<double, double> TOF_range(5, 100); + double t0(6), Period(10); + std::vector<double> guess_tof; + m_getAllEi.findGuessOpeningTimes(TOF_range, t0, Period, guess_tof); + TSM_ASSERT_EQUALS("should have 10 periods within the specified interval", + guess_tof.size(), 10); + + guess_tof.resize(0); + t0 = TOF_range.first; + m_getAllEi.findGuessOpeningTimes(TOF_range, t0, Period, guess_tof); + TSM_ASSERT_EQUALS( + "Still should be 10 periods within the specified interval", + guess_tof.size(), 10); + + t0 = TOF_range.second; + TSM_ASSERT_THROWS( + "Should throw out of range", + m_getAllEi.findGuessOpeningTimes(TOF_range, t0, Period, guess_tof), + std::runtime_error); + + t0 = 1; + guess_tof.resize(0); + m_getAllEi.findGuessOpeningTimes(TOF_range, t0, Period, guess_tof); + TSM_ASSERT_EQUALS(" should be 9 periods within the specified interval", + guess_tof.size(), 9); + + guess_tof.resize(0); + t0 = 21; + TOF_range.first = 20; + m_getAllEi.findGuessOpeningTimes(TOF_range, t0, Period, guess_tof); + TSM_ASSERT_EQUALS(" should be 8 periods within the specified interval", + guess_tof.size(), 8); + } + // + void test_internalWS_to_fit() { + Mantid::DataObjects::Workspace2D_sptr tws = + WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(5, 100, + true); + auto det1 = tws->getDetector(0); + auto det2 = tws->getDetector(4); + auto spec1 = tws->getSpectrum(0); + auto spec2 = tws->getSpectrum(4); + auto detID1 = spec1->getDetectorIDs(); + auto detID2 = spec2->getDetectorIDs(); + + m_getAllEi.initialize(); + m_getAllEi.setProperty("Workspace", tws); + m_getAllEi.setProperty("OutputWorkspace", "monitor_peaks"); + m_getAllEi.setProperty("Monitor1SpecID", 1); + m_getAllEi.setProperty("Monitor2SpecID", 5); + + size_t wsIndex0; + auto wws = m_getAllEi.buildWorkspaceToFit(tws, wsIndex0); + + auto det1p = wws->getDetector(0); + auto det2p = wws->getDetector(1); + TSM_ASSERT_EQUALS("should be the same first detector position", + det1p->getRelativePos(), det1->getRelativePos()); + TSM_ASSERT_EQUALS("should be the same second detector position", + det2p->getRelativePos(), det2->getRelativePos()); + + TSM_ASSERT_EQUALS("Detector's ID for the first spectrum and new workspace " + "should coincide", + *(detID1.begin()), + (*wws->getSpectrum(0)->getDetectorIDs().begin())); + TSM_ASSERT_EQUALS("Detector's ID for the second spectrum and new workspace " + "should coincide", + *(detID2.begin()), + (*wws->getSpectrum(1)->getDetectorIDs().begin())); + auto pSpec1 = wws->getSpectrum(0); + auto pSpec2 = wws->getSpectrum(1); + auto Xsp1 = pSpec1->dataX(); + auto Xsp2 = pSpec2->dataX(); + size_t nSpectra = Xsp2.size(); + TS_ASSERT_EQUALS(nSpectra, 101); + TS_ASSERT(boost::math::isinf(Xsp1[nSpectra - 1])); + TS_ASSERT(boost::math::isinf(Xsp2[nSpectra - 1])); + + // for(size_t i=0;i<Xsp1.size();i++){ + // TS_ASSERT_DELTA(Xsp1[i],Xsp2[i],1.e-6); + //} + } + void test_calcDerivative() { + double sig[] = {1, 2, 3, 4, 5, 6}; + std::vector<double> signal(sig, sig + sizeof(sig) / sizeof(double)); + double bin[] = {2, 3, 4, 5, 6, 7, 8}; + std::vector<double> bins(bin, bin + sizeof(bin) / sizeof(double)); + std::vector<double> zeros; + + std::vector<double> deriv; + size_t nZer = + m_getAllEi.calcDerivativeAndCountZeros(bins, signal, deriv, zeros); + TS_ASSERT_EQUALS(nZer, 0); + TS_ASSERT_DELTA(deriv[0], deriv[1], 1.e-9); + TS_ASSERT_DELTA(deriv[0], deriv[5], 1.e-9); + TS_ASSERT_DELTA(deriv[0], deriv[2], 1.e-9); + TS_ASSERT_DELTA(deriv[0], 1., 1.e-9); + + double bin1[] = {0, 1, 3, 6, 10, 15, 21}; + std::vector<double> bins1(bin1, bin1 + sizeof(bin1) / sizeof(double)); + nZer = m_getAllEi.calcDerivativeAndCountZeros(bins1, signal, deriv, zeros); + TS_ASSERT_EQUALS(nZer, 0); + TS_ASSERT_DELTA(deriv[0], deriv[1], 1.e-9); + TS_ASSERT_DELTA(deriv[0], deriv[5], 1.e-9); + TS_ASSERT_DELTA(deriv[0], deriv[2], 1.e-9); + TS_ASSERT_DELTA(deriv[0], 0, 1.e-9); + + bins.resize(101); + signal.resize(100); + for (size_t i = 0; i < 101; i++) { + bins[i] = double(i) * 0.1; + } + for (size_t i = 0; i < 100; i++) { + signal[i] = std::sin(0.5 * (bins[i] + bins[i + 1])); + } + nZer = m_getAllEi.calcDerivativeAndCountZeros(bins, signal, deriv, zeros); + TS_ASSERT_EQUALS(nZer, 3); + for (size_t i = 0; i < 99; i++) { // intentionally left boundary point -- + // its accuracy is much lower + TSM_ASSERT_DELTA("At i=" + boost::lexical_cast<std::string>(i), deriv[i], + 10. * std::cos(0.5 * (bins[i] + bins[i + 1])), 1.e-1); + } + TS_ASSERT_DELTA(zeros[0], 1.55, 1.e-3); + TS_ASSERT_DELTA(zeros[1], 4.65, 1.e-3); + TS_ASSERT_DELTA(zeros[2], 7.85, 1.e-3); + } + void test_binRanges() { + std::vector<size_t> bin_min, bin_max, zeros; + // Index 0 1 2 3 4 5 6 7 8 9 10 11 12 13 + double debin[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15}; + std::vector<double> ebin(debin, debin + sizeof(debin) / sizeof(double)); + // Not yet supported in VC 2012 + // std::vector<double> ebin={1,2,3,4,5,6,7,8,9,10,11,12,13,15}; + // Ind 0 1 2 3 4 5 6 7 8 9 10 11 12 13 + double sig[] = {0, 0, 0, 3, 0, 0, 4, 0, 0, 0, 11, 0, 0}; + std::vector<double> signal(sig, sig + sizeof(sig) / sizeof(double)); + + double dguess[] = {1, 6, 10, 12}; + std::vector<double> guess(dguess, dguess + sizeof(dguess) / sizeof(double)); + std::vector<bool> guessValid; + + m_getAllEi.findBinRanges(ebin, signal, guess, 0.1, bin_min, bin_max, + guessValid); + + TS_ASSERT_EQUALS(bin_min.size(), 2) + TS_ASSERT_EQUALS(bin_max.size(), 2) + TS_ASSERT_EQUALS(guessValid.size(), 4) + TS_ASSERT_EQUALS(bin_min[0], 4) + TS_ASSERT_EQUALS(bin_max[0], 9) + TS_ASSERT_EQUALS(bin_min[1], 7) + TS_ASSERT_EQUALS(bin_max[1], 13) + + signal[10] = 0; + signal[11] = 11; + guess[1] = 3; + guess[2] = 6; + guess[3] = 11; + m_getAllEi.findBinRanges(ebin, signal, guess, 0.01, bin_min, bin_max, + guessValid); + TS_ASSERT_EQUALS(bin_min.size(), 3) + TS_ASSERT_EQUALS(bin_max.size(), 3) + TS_ASSERT_EQUALS(guessValid.size(), 4) + + TS_ASSERT_EQUALS(bin_min[0], 3); + TS_ASSERT_EQUALS(bin_max[0], 4); + TS_ASSERT(guessValid[1]); + + TS_ASSERT_EQUALS(bin_min[1], 6); + TS_ASSERT_EQUALS(bin_max[1], 7); + TS_ASSERT(guessValid[2]); + + TS_ASSERT_EQUALS(bin_min[2], 11); + TS_ASSERT_EQUALS(bin_max[2], 12); + TS_ASSERT(guessValid[3]); + + TS_ASSERT(!guessValid[0]); + } + + void test_getAllEi() { + auto ws = createTestingWS(); + + m_getAllEi.initialize(); + m_getAllEi.setProperty("Workspace", ws); + m_getAllEi.setProperty("OutputWorkspace", "monitor_peaks"); + m_getAllEi.setProperty("Monitor1SpecID", 1); + m_getAllEi.setProperty("Monitor2SpecID", 2); + m_getAllEi.setProperty("ChopperSpeedLog", "Chopper_Speed"); + m_getAllEi.setProperty("ChopperDelayLog", "Chopper_Delay"); + m_getAllEi.setProperty("FilterBaseLog", "is_running"); + m_getAllEi.setProperty("FilterWithDerivative", false); + m_getAllEi.setProperty("OutputWorkspace", "allEiWs"); + + TS_ASSERT_THROWS_NOTHING(m_getAllEi.execute()); + API::MatrixWorkspace_sptr out_ws; + TS_ASSERT_THROWS_NOTHING( + out_ws = API::AnalysisDataService::Instance() + .retrieveWS<API::MatrixWorkspace>("allEiWs")); + + TSM_ASSERT("Should be able to retrieve workspace", out_ws); + auto wso = dynamic_cast<DataObjects::Workspace2D *>(out_ws.get()); + TS_ASSERT(wso); + if (!wso) + return; + + auto &x = wso->dataX(0); + TSM_ASSERT_EQUALS("Second peak should be filtered by monitor ranges", + x.size(), 1); + TS_ASSERT_DELTA(x[0], 134.316, 1.e-3) + } + +private: + GetAllEiTester m_getAllEi; + + DataObjects::Workspace2D_sptr createTestingWS(bool noLogs = false) { + double delay(2000), chopSpeed(100), inital_chop_phase(-3000); + auto ws = WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument( + 2, 1000, true); + auto pInstrument = ws->getInstrument(); + auto chopper = pInstrument->getComponentByName("chopper-position"); + + // add chopper parameters + auto ¶mMap = ws->instrumentParameters(); + const std::string description( + "The initial rotation phase of the disk used to calculate the time" + " for neutrons arriving at the chopper according to the formula time = " + "delay + initial_phase/Speed"); + paramMap.add<double>("double", chopper.get(), "initial_phase", + inital_chop_phase, &description); + paramMap.add<std::string>("string", chopper.get(), "ChopperDelayLog", + "fermi_delay"); + paramMap.add<std::string>("string", chopper.get(), "ChopperSpeedLog", + "fermi_speed"); + paramMap.add<std::string>("string", chopper.get(), "FilterBaseLog", + "is_running"); + paramMap.add<bool>("bool", chopper.get(), "filter_with_derivative", false); + + // test instrument parameters (obtained from workspace): + auto moderator = pInstrument->getSource(); + auto detector1 = ws->getDetector(0); + auto detector2 = ws->getDetector(1); + double l_chop = chopper->getDistance(*moderator); + double l_mon1 = detector1->getDistance(*moderator); + double l_mon2 = detector2->getDistance(*moderator); + //,l_mon1(20-9),l_mon2(20-2); + double t_chop(delay + inital_chop_phase / chopSpeed); + double Period = + (0.5 * 1.e+6) / chopSpeed; // 0.5 because some choppers open twice. + auto &x = ws->dataX(0); + for (size_t i = 0; i < x.size(); i++) { + x[i] = 5 + double(i) * 10; + } + // signal at first monitor + double t1 = t_chop * l_mon1 / l_chop; + double t2 = (t_chop + Period) * l_mon1 / l_chop; + { + auto &y = ws->dataY(0); + for (size_t i = 0; i < y.size(); i++) { + double t = 0.5 * (x[i] + x[i + 1]); + double tm1 = t - t1; + double tm2 = t - t2; + y[i] = (10000 * std::exp(-tm1 * tm1 / 1000.) + + 20000 * std::exp(-tm2 * tm2 / 1000.)); + // std::cout<<"t="<<t<<" signal="<<y[i]<<" ind="<<i<<std::endl; + } + } + // signal at second monitor + t1 = t_chop * l_mon2 / l_chop; + t2 = (t_chop + Period) * l_mon2 / l_chop; + { + auto &y = ws->dataY(1); + for (size_t i = 0; i < y.size(); i++) { + double t = 0.5 * (x[i] + x[i + 1]); + double tm1 = t - t1; + double tm2 = t - t2; + y[i] = (100 * std::exp(-tm1 * tm1 / 1000.) + + 200 * std::exp(-tm2 * tm2 / 1000.)); + // std::cout<<"t="<<t<<" signal="<<y[i]<<" ind="<<i<<std::endl; + } + } + + if (noLogs) + return ws; + + std::unique_ptr<Kernel::TimeSeriesProperty<double>> chopDelayLog( + new Kernel::TimeSeriesProperty<double>("Chopper_Delay")); + std::unique_ptr<Kernel::TimeSeriesProperty<double>> chopSpeedLog( + new Kernel::TimeSeriesProperty<double>("Chopper_Speed")); + std::unique_ptr<Kernel::TimeSeriesProperty<double>> isRunning( + new Kernel::TimeSeriesProperty<double>("is_running")); + + for (int i = 0; i < 10; i++) { + auto time = Kernel::DateAndTime(10 * i, 0); + chopDelayLog->addValue(time, delay); + chopSpeedLog->addValue(time, chopSpeed); + isRunning->addValue(time, 1.); + } + + ws->mutableRun().addLogData(chopSpeedLog.release()); + ws->mutableRun().addLogData(chopDelayLog.release()); + ws->mutableRun().addLogData(isRunning.release()); + + return ws; + } +}; + +#endif diff --git a/Framework/Algorithms/test/RemoveExpDecayTest.h b/Framework/Algorithms/test/RemoveExpDecayTest.h index e4d20a3f95e44748f4f7128fdadcd112f6d298f5..136e48cf707bef934f0138026a1ad26eebee85b7 100644 --- a/Framework/Algorithms/test/RemoveExpDecayTest.h +++ b/Framework/Algorithms/test/RemoveExpDecayTest.h @@ -3,11 +3,11 @@ #include <cxxtest/TestSuite.h> #include "MantidAPI/FrameworkManager.h" -#include "MantidAlgorithms/RemoveExpDecay.h" +#include "MantidAPI/AlgorithmManager.h" #include "MantidTestHelpers/WorkspaceCreationHelper.h" -using namespace Mantid::Algorithms; using namespace Mantid::API; +using Mantid::MantidVec; const std::string outputName = "MuonRemoveExpDecay_Output"; @@ -21,52 +21,165 @@ public: RemoveExpDecayTest() { FrameworkManager::Instance(); } void testInit() { - MuonRemoveExpDecay alg; - alg.initialize(); - TS_ASSERT(alg.isInitialized()) + IAlgorithm_sptr alg = AlgorithmManager::Instance().create("RemoveExpDecay"); + alg->initialize(); + TS_ASSERT(alg->isInitialized()) } - void testExecute() { - auto ws = WorkspaceCreationHelper::Create2DWorkspace(1, 1); - - MuonRemoveExpDecay alg; - TS_ASSERT_THROWS_NOTHING(alg.initialize()); - TS_ASSERT(alg.isInitialized()); - alg.setChild(true); - alg.setProperty("InputWorkspace", ws); - alg.setPropertyValue("OutputWorkspace", outputName); - alg.setPropertyValue("Spectra", "0"); - TS_ASSERT_THROWS_NOTHING(alg.execute()); - TS_ASSERT(alg.isExecuted()) + void test_Execute() { + + auto ws = createWorkspace(1, 50); + + IAlgorithm_sptr alg = AlgorithmManager::Instance().create("RemoveExpDecay"); + alg->initialize(); + alg->setChild(true); + alg->setProperty("InputWorkspace", ws); + alg->setPropertyValue("OutputWorkspace", outputName); + TS_ASSERT_THROWS_NOTHING(alg->execute()); + TS_ASSERT(alg->isExecuted()); + + MatrixWorkspace_sptr outWS = alg->getProperty("OutputWorkspace"); } - void testExecuteWhereSepctraNotSet() { - auto ws = WorkspaceCreationHelper::Create2DWorkspace(1, 1); - - MuonRemoveExpDecay alg; - TS_ASSERT_THROWS_NOTHING(alg.initialize()); - TS_ASSERT(alg.isInitialized()); - alg.setChild(true); - alg.setProperty("InputWorkspace", ws); - alg.setPropertyValue("OutputWorkspace", outputName); - TS_ASSERT_THROWS_NOTHING(alg.execute()); - TS_ASSERT(alg.isExecuted()) + void test_EmptySpectrumList() { + + auto ws = createWorkspace(2, 50); + + IAlgorithm_sptr alg = AlgorithmManager::Instance().create("RemoveExpDecay"); + alg->initialize(); + alg->setChild(true); + alg->setProperty("InputWorkspace", ws); + alg->setPropertyValue("OutputWorkspace", outputName); + TS_ASSERT_THROWS_NOTHING(alg->execute()); + TS_ASSERT(alg->isExecuted()); + + MatrixWorkspace_sptr outWS = alg->getProperty("OutputWorkspace"); + + // First spectrum + // Test some X values + TS_ASSERT_DELTA(outWS->readX(0)[10], 0.2000, 0.0001); + TS_ASSERT_DELTA(outWS->readX(0)[19], 0.3800, 0.0001); + TS_ASSERT_DELTA(outWS->readX(0)[49], 0.9800, 0.0001); + // Test some Y values + TS_ASSERT_DELTA(outWS->readY(0)[10], -0.0992, 0.0001); + TS_ASSERT_DELTA(outWS->readY(0)[19], -0.0111, 0.0001); + TS_ASSERT_DELTA(outWS->readY(0)[49], -0.0622, 0.0001); + // Test some E values + TS_ASSERT_DELTA(outWS->readE(0)[10], 0.0054, 0.0001); + TS_ASSERT_DELTA(outWS->readE(0)[19], 0.0059, 0.0001); + TS_ASSERT_DELTA(outWS->readE(0)[49], 0.0077, 0.0001); + + // Second spectrum + // Test some X values + TS_ASSERT_DELTA(outWS->readX(1)[10], 0.2000, 0.0001); + TS_ASSERT_DELTA(outWS->readX(1)[19], 0.3800, 0.0001); + TS_ASSERT_DELTA(outWS->readX(1)[49], 0.9800, 0.0001); + // Test some Y values + TS_ASSERT_DELTA(outWS->readY(1)[10], 0.0274, 0.0001); + TS_ASSERT_DELTA(outWS->readY(1)[19], -0.1003, 0.0001); + TS_ASSERT_DELTA(outWS->readY(1)[49], 0.0802, 0.0001); + // Test some E values + TS_ASSERT_DELTA(outWS->readE(1)[10], 0.0054, 0.0001); + TS_ASSERT_DELTA(outWS->readE(1)[19], 0.0059, 0.0001); + TS_ASSERT_DELTA(outWS->readE(1)[49], 0.0078, 0.0001); + } + + void test_SpectrumList() { + + auto ws = createWorkspace(2, 50); + + // First, run the algorithm without specifying any spectrum + IAlgorithm_sptr alg1 = + AlgorithmManager::Instance().create("RemoveExpDecay"); + alg1->initialize(); + alg1->setChild(true); + alg1->setProperty("InputWorkspace", ws); + alg1->setPropertyValue("OutputWorkspace", outputName); + TS_ASSERT_THROWS_NOTHING(alg1->execute()); + TS_ASSERT(alg1->isExecuted()); + MatrixWorkspace_sptr out1 = alg1->getProperty("OutputWorkspace"); + + // Then run the algorithm on the second spectrum only + IAlgorithm_sptr alg2 = + AlgorithmManager::Instance().create("RemoveExpDecay"); + alg2->initialize(); + alg2->setChild(true); + alg2->setProperty("InputWorkspace", ws); + alg2->setPropertyValue("OutputWorkspace", outputName); + alg2->setPropertyValue("Spectra", "1"); + TS_ASSERT_THROWS_NOTHING(alg2->execute()); + TS_ASSERT(alg2->isExecuted()); + MatrixWorkspace_sptr out2 = alg2->getProperty("OutputWorkspace"); + + // Both output workspaces should have 2 spectra + TS_ASSERT_EQUALS(out1->getNumberHistograms(), ws->getNumberHistograms()); + TS_ASSERT_EQUALS(out2->getNumberHistograms(), ws->getNumberHistograms()); + + // Compare results, they should match for the selected spectrum + TS_ASSERT_EQUALS(out1->readX(1), out2->readX(1)); + TS_ASSERT_EQUALS(out1->readY(1), out2->readY(1)); + TS_ASSERT_EQUALS(out1->readE(1), out2->readE(1)); + + // Compare non-selected spectra, the should match the input ones + TS_ASSERT_EQUALS(ws->readX(0), out2->readX(0)); + TS_ASSERT_EQUALS(ws->readY(0), out2->readY(0)); + TS_ASSERT_EQUALS(ws->readE(0), out2->readE(0)); } void test_yUnitLabel() { - auto ws = WorkspaceCreationHelper::Create2DWorkspace(1, 1); - MuonRemoveExpDecay alg; - alg.initialize(); - alg.setChild(true); - alg.setProperty("InputWorkspace", ws); - alg.setProperty("OutputWorkspace", outputName); - alg.execute(); + auto ws = createWorkspace(4, 50); + + IAlgorithm_sptr alg = AlgorithmManager::Instance().create("RemoveExpDecay"); + alg->initialize(); + alg->setChild(true); + alg->setProperty("InputWorkspace", ws); + alg->setPropertyValue("OutputWorkspace", outputName); + TS_ASSERT_THROWS_NOTHING(alg->execute()); + TS_ASSERT(alg->isExecuted()) - MatrixWorkspace_sptr result = alg.getProperty("OutputWorkspace"); + MatrixWorkspace_sptr result = alg->getProperty("OutputWorkspace"); TS_ASSERT(result); TS_ASSERT_EQUALS(result->YUnitLabel(), "Asymmetry"); } + + MatrixWorkspace_sptr createWorkspace(size_t nspec, size_t maxt) { + + // Create a fake muon dataset + double a = 0.1; // Amplitude of the oscillations + double w = 25.; // Frequency of the oscillations + double tau = 2.2; // Muon life time + + MantidVec X; + MantidVec Y; + MantidVec E; + for (size_t s = 0; s < nspec; s++) { + for (size_t t = 0; t < maxt; t++) { + double x = static_cast<double>(t) / static_cast<double>(maxt); + double e = exp(-x / tau); + X.push_back(x); + Y.push_back(a * sin(w * x + + static_cast<double>(s) * M_PI / + static_cast<double>(nspec)) * + e + + e); + E.push_back(0.005); + } + } + + 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; + } }; #endif /*MUONREMOVEEXPDECAYTEST_H_*/ diff --git a/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h b/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h index f5f08d514683494a3c4327d930e392068240de3e..f051bc0a419caa4d5082e0b14bdc4c526ff882c6 100644 --- a/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h +++ b/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h @@ -8,7 +8,8 @@ namespace Mantid { namespace Crystal { -/** LoadIsawPeaks : Load an ISAW-style .peaks file +/** + * Load an ISAW-style .peaks or .integrate file * into a PeaksWorkspace * * @author Janik Zikovsky, SNS @@ -21,14 +22,16 @@ public: virtual ~LoadIsawPeaks(); /// Algorithm's name for identification - virtual const std::string name() const { return "LoadIsawPeaks"; }; + virtual const std::string name() const { return "LoadIsawPeaks"; } + /// Summary of algorithms purpose virtual const std::string summary() const { return "Load an ISAW-style .peaks file into a PeaksWorkspace."; } /// Algorithm's version for identification - virtual int version() const { return 1; }; + virtual int version() const { return 1; } + /// Algorithm's category for identification virtual const std::string category() const { return "Crystal;DataHandling\\Isaw"; @@ -36,26 +39,52 @@ public: /// Returns a confidence value that this algorithm can load a file virtual int confidence(Kernel::FileDescriptor &descriptor) const; - int findPixelID(Geometry::Instrument_const_sptr inst, std::string bankName, - int col, int row); private: /// Initialise the properties void init(); + /// Run the algorithm void exec(); + /// Reads calibration/detector section and returns first word of next line std::string ApplyCalibInfo(std::ifstream &in, std::string startChar, Geometry::Instrument_const_sptr instr_old, Geometry::Instrument_const_sptr instr, double &T0); + /// Reads first line of peaks file and returns first word of next line std::string readHeader(Mantid::DataObjects::PeaksWorkspace_sptr outWS, std::ifstream &in, double &T0); + /// Read a single peak from peaks file + DataObjects::Peak readPeak(DataObjects::PeaksWorkspace_sptr outWS, + std::string &lastStr, std::ifstream &in, + int &seqNum, std::string bankName); + + int findPixelID(Geometry::Instrument_const_sptr inst, std::string bankName, + int col, int row); + + /// Read the header of a peak block section, returns first word of next line + std::string readPeakBlockHeader(std::string lastStr, std::ifstream &in, + int &run, int &detName, double &chi, + double &phi, double &omega, double &monCount); + + /// Append peaks from given file to given workspace void appendFile(Mantid::DataObjects::PeaksWorkspace_sptr outWS, std::string filename); + + /// Compare number of peaks in given file to given workspace + /// Throws std::length_error on mismatch void checkNumberPeaks(Mantid::DataObjects::PeaksWorkspace_sptr outWS, std::string filename); + + /// Local cache of bank IComponents used in file + std::map<std::string, boost::shared_ptr<const Geometry::IComponent>> m_banks; + + /// Retrieve cached bank (or load and cache for next time) + boost::shared_ptr<const Geometry::IComponent> getCachedBankByName( + std::string bankname, + const boost::shared_ptr<const Geometry::Instrument> &inst); }; } // namespace Mantid diff --git a/Framework/Crystal/src/AnvredCorrection.cpp b/Framework/Crystal/src/AnvredCorrection.cpp index 31667b090362ea9d0168778db58460b94573120c..3f49fb8f31e249c413db7af989bb4df0f6715e8b 100644 --- a/Framework/Crystal/src/AnvredCorrection.cpp +++ b/Framework/Crystal/src/AnvredCorrection.cpp @@ -2,7 +2,7 @@ // Includes //---------------------------------------------------------------------- #include "MantidCrystal/AnvredCorrection.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/InstrumentValidator.h" #include "MantidGeometry/Objects/ShapeFactory.h" #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/UnitFactory.h" @@ -78,9 +78,7 @@ AnvredCorrection::AnvredCorrection() void AnvredCorrection::init() { // The input workspace must have an instrument and units of wavelength - boost::shared_ptr<CompositeValidator> wsValidator = - boost::make_shared<CompositeValidator>(); - wsValidator->add(boost::make_shared<InstrumentValidator>()); + auto wsValidator = boost::make_shared<InstrumentValidator>(); declareProperty(new WorkspaceProperty<>("InputWorkspace", "", Direction::Input, wsValidator), diff --git a/Framework/Crystal/src/FilterPeaks.cpp b/Framework/Crystal/src/FilterPeaks.cpp index 8e398c2b0de67a54cfba1205285caa2be5a0808c..f60acecea9586ca7449801c11b174ecdbefd7e16 100644 --- a/Framework/Crystal/src/FilterPeaks.cpp +++ b/Framework/Crystal/src/FilterPeaks.cpp @@ -98,6 +98,8 @@ void FilterPeaks::exec() { filterFunction = &intensity; else if (FilterVariable == "Signal/Noise") filterFunction = &SN; + else + throw std::invalid_argument("Unknown FilterVariable: " + FilterVariable); const double FilterValue = getProperty("FilterValue"); const std::string Operator = getProperty("Operator"); diff --git a/Framework/Crystal/src/FindSXPeaks.cpp b/Framework/Crystal/src/FindSXPeaks.cpp index 456d0c022b62f578840185a6f89974c1d9bac922..a2cdbc16f408aba18adec1153b38260ee6183580 100644 --- a/Framework/Crystal/src/FindSXPeaks.cpp +++ b/Framework/Crystal/src/FindSXPeaks.cpp @@ -2,7 +2,7 @@ // Includes //---------------------------------------------------------------------- #include "MantidCrystal/FindSXPeaks.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" #include "MantidKernel/VectorHelper.h" #include "MantidKernel/BoundedValidator.h" diff --git a/Framework/Crystal/src/IndexSXPeaks.cpp b/Framework/Crystal/src/IndexSXPeaks.cpp index 00cb0dd4f10e97bc6f856833adfc8afcea4be027..0409b1dd4e5ed9ccdb0e8bc04ef7ede55cb4a457 100644 --- a/Framework/Crystal/src/IndexSXPeaks.cpp +++ b/Framework/Crystal/src/IndexSXPeaks.cpp @@ -2,7 +2,6 @@ // Includes //---------------------------------------------------------------------- #include "MantidCrystal/IndexSXPeaks.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidKernel/VectorHelper.h" #include "MantidKernel/ArrayProperty.h" #include "MantidGeometry/Crystal/IPeak.h" diff --git a/Framework/Crystal/src/IntegratePeakTimeSlices.cpp b/Framework/Crystal/src/IntegratePeakTimeSlices.cpp index 70e398ef3d65ea8c30d3b112373b7e929153f56e..9828bea2f54bfa54db588459eca4c19b2d772842 100644 --- a/Framework/Crystal/src/IntegratePeakTimeSlices.cpp +++ b/Framework/Crystal/src/IntegratePeakTimeSlices.cpp @@ -587,6 +587,12 @@ void IntegratePeakTimeSlices::exec() { // Now set up the center for this peak int i = find("Mrow", names); + if (i < 0) { + throw std::runtime_error("Inconsistency found in algorithm " + "execution. The index for the parameter " + "Mrow is negative."); + } + lastRow = (int)(params[i] + .5); i = find("Mcol", names); lastCol = (int)(params[i] + .5); @@ -2220,7 +2226,16 @@ bool IntegratePeakTimeSlices::isGoodFit(std::vector<double> const ¶ms, std::vector<std::string> const &names, double chisqOverDOF) { int Ibk = find("Background", names); + if (Ibk < 0) + throw std::runtime_error( + "Irrecoverable inconsistency found. The index for the " + "parameter 'Background' is lower than zero."); + int IIntensity = find("Intensity", names); + if (IIntensity < 0) + throw std::runtime_error( + "Irrecoverable inconsistency found. The index for the " + "parameter 'Intensity' is lower than zero."); if (chisqOverDOF < 0) { @@ -2498,6 +2513,15 @@ int IntegratePeakTimeSlices::UpdateOutputWS( int Irow = find("Mrow", names); int Icol = find("Mcol", names); + if (Ibk < 0 || IIntensity < 0 || IVx < 0 || IVy < 0 || IVxy < 0 || Irow < 0 || + Icol < 0) { + throw std::runtime_error("Inconsistency found when updating output " + "workspace. None of the indices for the " + "parameters 'Background', 'Intensity', 'SScol', " + "'SSrow', 'SSrc', 'Mrow', 'Mcol' can be " + "negative."); + } + int newRowIndex = 0; if (dir > 0) diff --git a/Framework/Crystal/src/LoadHKL.cpp b/Framework/Crystal/src/LoadHKL.cpp index 0a2cdd3331a2f06b44acfe61f5341eee67f450c7..01bd724729514325c5ab87c8f4ca8491a9e6f251 100644 --- a/Framework/Crystal/src/LoadHKL.cpp +++ b/Framework/Crystal/src/LoadHKL.cpp @@ -1,5 +1,4 @@ #include "MantidAPI/FileProperty.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidCrystal/LoadHKL.h" #include "MantidCrystal/AnvredCorrection.h" #include "MantidGeometry/Instrument/Detector.h" diff --git a/Framework/Crystal/src/LoadIsawPeaks.cpp b/Framework/Crystal/src/LoadIsawPeaks.cpp index 4dc4b229cef31411c56aaf270075ecd24b75a52f..bec1b06a5a50a931294dcd83d625d172b7c28841 100644 --- a/Framework/Crystal/src/LoadIsawPeaks.cpp +++ b/Framework/Crystal/src/LoadIsawPeaks.cpp @@ -29,8 +29,9 @@ LoadIsawPeaks::LoadIsawPeaks() {} */ LoadIsawPeaks::~LoadIsawPeaks() {} +//---------------------------------------------------------------------------------------------- /** - * Return the confidence with with this algorithm can load the file + * Determine the confidence with which this algorithm can load a given file * @param descriptor A descriptor for the file * @returns An integer specifying the confidence level. 0 indicates it will not * be used @@ -78,12 +79,10 @@ int LoadIsawPeaks::confidence(Kernel::FileDescriptor &descriptor) const { confidence = 95; } catch (std::exception &) { } + return confidence; } -//---------------------------------------------------------------------------------------------- -//---------------------------------------------------------------------------------------------- - //---------------------------------------------------------------------------------------------- /** Initialize the algorithm's properties. */ @@ -99,6 +98,23 @@ void LoadIsawPeaks::init() { "Name of the output workspace."); } +//---------------------------------------------------------------------------------------------- +/** Execute the algorithm. + */ +void LoadIsawPeaks::exec() { + // Create the workspace + PeaksWorkspace_sptr ws(new PeaksWorkspace()); + + // This loads (appends) the peaks + this->appendFile(ws, getPropertyValue("Filename")); + + // Save it in the output + setProperty("OutputWorkspace", boost::dynamic_pointer_cast<Workspace>(ws)); + + this->checkNumberPeaks(ws, getPropertyValue("Filename")); +} + +//---------------------------------------------------------------------------------------------- std::string LoadIsawPeaks::ApplyCalibInfo(std::ifstream &in, std::string startChar, Geometry::Instrument_const_sptr instr_old, @@ -113,7 +129,6 @@ LoadIsawPeaks::ApplyCalibInfo(std::ifstream &in, std::string startChar, startChar = getWord(in, false); } if (!(in.good())) { - // g_log.error()<<"Peaks file has no time shift and L0 info"<<std::endl; throw std::invalid_argument("Peaks file has no time shift and L0 info"); } std::string L1s = getWord(in, false); @@ -190,7 +205,7 @@ LoadIsawPeaks::ApplyCalibInfo(std::ifstream &in, std::string startChar, } bankName += SbankNum; boost::shared_ptr<const Geometry::IComponent> bank = - instr_old->getComponentByName(bankName); + getCachedBankByName(bankName, instr_old); if (!bank) { g_log.error() << "There is no bank " << bankName << " in the instrument" @@ -291,15 +306,11 @@ std::string LoadIsawPeaks::readHeader(PeaksWorkspace_sptr outWS, Geometry::Instrument_const_sptr instr( new Geometry::Instrument(instr_old->baseInstrument(), map)); - // std::string s; std::string s = ApplyCalibInfo(in, "", instr_old, instr, T0); outWS->setInstrument(instr); // Now skip all lines on L1, detector banks, etc. until we get to a block of // peaks. They start with 0. - // readToEndOfLine( in , true ); - // readToEndOfLine( in , true ); - // s = getWord(in, false); while (s != "0" && in.good()) { readToEndOfLine(in, true); s = getWord(in, false); @@ -318,9 +329,10 @@ std::string LoadIsawPeaks::readHeader(PeaksWorkspace_sptr outWS, * @param bankName :: the bank number from the ISAW file. * @return the Peak the Peak object created */ -Mantid::DataObjects::Peak readPeak(PeaksWorkspace_sptr outWS, - std::string &lastStr, std::ifstream &in, - int &seqNum, std::string bankName) { +DataObjects::Peak LoadIsawPeaks::readPeak(PeaksWorkspace_sptr outWS, + std::string &lastStr, + std::ifstream &in, int &seqNum, + std::string bankName) { double h; double k; double l; @@ -387,9 +399,9 @@ Mantid::DataObjects::Peak readPeak(PeaksWorkspace_sptr outWS, Instrument_const_sptr inst = outWS->getInstrument(); if (!inst) throw std::runtime_error("No instrument in PeaksWorkspace!"); - LoadIsawPeaks u; - int pixelID = u.findPixelID(inst, bankName, static_cast<int>(col), - static_cast<int>(row)); + + int pixelID = + findPixelID(inst, bankName, static_cast<int>(col), static_cast<int>(row)); // Create the peak object Peak peak(outWS->getInstrument(), pixelID, wl); @@ -402,10 +414,12 @@ Mantid::DataObjects::Peak readPeak(PeaksWorkspace_sptr outWS, return peak; } +//---------------------------------------------------------------------------------------------- int LoadIsawPeaks::findPixelID(Instrument_const_sptr inst, std::string bankName, int col, int row) { boost::shared_ptr<const IComponent> parent = - inst->getComponentByName(bankName); + getCachedBankByName(bankName, inst); + if (parent->type().compare("RectangularDetector") == 0) { boost::shared_ptr<const RectangularDetector> RDet = boost::dynamic_pointer_cast<const RectangularDetector>(parent); @@ -441,9 +455,11 @@ int LoadIsawPeaks::findPixelID(Instrument_const_sptr inst, std::string bankName, //----------------------------------------------------------------------------------------------- /** Read the header of each peak block section */ -std::string readPeakBlockHeader(std::string lastStr, std::ifstream &in, - int &run, int &detName, double &chi, - double &phi, double &omega, double &monCount) { +std::string LoadIsawPeaks::readPeakBlockHeader(std::string lastStr, + std::ifstream &in, int &run, + int &detName, double &chi, + double &phi, double &omega, + double &monCount) { std::string s = lastStr; if (s.length() < 1 && in.good()) // blank line @@ -491,6 +507,11 @@ void LoadIsawPeaks::appendFile(PeaksWorkspace_sptr outWS, // Open the file std::ifstream in(filename.c_str()); + // Calculate filesize + in.seekg(0, in.end); + auto filelen = in.tellg(); + in.seekg(0, in.beg); + // Read the header, load the instrument double T0; std::string s = readHeader(outWS, in, T0); @@ -514,8 +535,8 @@ void LoadIsawPeaks::appendFile(PeaksWorkspace_sptr outWS, Mantid::Geometry::Goniometer uniGonio; uniGonio.makeUniversalGoniometer(); - // TODO: Can we find the number of peaks to get better progress reporting? - Progress prog(this, 0.0, 1.0, 100); + // Progress is reported based on how much of the file we've read + Progress prog(this, 0.0, 1.0, filelen); while (in.good()) { // Read the header if necessary @@ -565,9 +586,10 @@ void LoadIsawPeaks::appendFile(PeaksWorkspace_sptr outWS, << e.what() << std::endl; } - prog.report(); + prog.report(in.tellg()); } } + //----------------------------------------------------------------------------------------------- /** Count the peaks from a .peaks file and compare with the workspace * @param outWS :: the workspace in which to place the information @@ -592,19 +614,29 @@ void LoadIsawPeaks::checkNumberPeaks(PeaksWorkspace_sptr outWS, } //---------------------------------------------------------------------------------------------- -/** Execute the algorithm. +/** Retrieves pointer to given bank from local cache. + * + * When the bank isn't in the local cache, it is loaded and + * added to the cache for later use. Lifetime of the cache + * is bound to the lifetime of this instance of the algorithm + * (typically, the instance should be destroyed once exec() + * finishes). + * + * Note that while this is used only for banks here, it would + * work for caching any component without modification. + * + * @param bankname :: the name of the requested bank + * @param inst :: the instrument from which to load the bank if it is not yet + *cached + * @return A shared pointer to the request bank (empty shared pointer if not + *found) */ -void LoadIsawPeaks::exec() { - // Create the workspace - PeaksWorkspace_sptr ws(new PeaksWorkspace()); - - // This loads (appends) the peaks - this->appendFile(ws, getPropertyValue("Filename")); - - // Save it in the output - setProperty("OutputWorkspace", boost::dynamic_pointer_cast<Workspace>(ws)); - - this->checkNumberPeaks(ws, getPropertyValue("Filename")); +boost::shared_ptr<const IComponent> LoadIsawPeaks::getCachedBankByName( + std::string bankname, + const boost::shared_ptr<const Geometry::Instrument> &inst) { + if (m_banks.count(bankname) == 0) + m_banks[bankname] = inst->getComponentByName(bankname); + return m_banks[bankname]; } } // namespace Mantid diff --git a/Framework/Crystal/src/LoadIsawSpectrum.cpp b/Framework/Crystal/src/LoadIsawSpectrum.cpp index 1020210a59d8f48c1c261685b9a4e787d7427f38..2c5a6da66ba1706e9aa415a2cdbd27c3755d84ad 100644 --- a/Framework/Crystal/src/LoadIsawSpectrum.cpp +++ b/Framework/Crystal/src/LoadIsawSpectrum.cpp @@ -1,5 +1,4 @@ #include "MantidAPI/FileProperty.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidCrystal/LoadIsawSpectrum.h" #include "MantidDataObjects/Workspace2D.h" #include "MantidGeometry/Instrument/RectangularDetector.h" @@ -69,38 +68,24 @@ void LoadIsawSpectrum::exec() { std::vector<std::vector<double>> spectra; std::vector<std::vector<double>> time; int iSpec = 0; - if (iSpec == 1) { - while (!infile.eof()) // To get you all the lines. - { - // Set up sizes. (HEIGHT x WIDTH) - spectra.resize(a + 1); - getline(infile, STRING); // Saves the line in STRING. - infile >> spec[0] >> spec[1] >> spec[2] >> spec[3] >> spec[4] >> - spec[5] >> spec[6] >> spec[7] >> spec[8] >> spec[9] >> spec[10]; - for (int i = 0; i < 11; i++) - spectra[a].push_back(spec[i]); - a++; - } - } else { - for (int wi = 0; wi < 8; wi++) - getline(infile, STRING); // Saves the line in STRING. - while (!infile.eof()) // To get you all the lines. - { - time.resize(a + 1); - spectra.resize(a + 1); - getline(infile, STRING); // Saves the line in STRING. - if (infile.eof()) - break; - std::stringstream ss(STRING); - if (STRING.find("Bank") == std::string::npos) { - double time0, spectra0; - ss >> time0 >> spectra0; - time[a].push_back(time0); - spectra[a].push_back(spectra0); + for (int wi = 0; wi < 8; wi++) + getline(infile, STRING); // Saves the line in STRING. + while (!infile.eof()) // To get you all the lines. + { + time.resize(a + 1); + spectra.resize(a + 1); + getline(infile, STRING); // Saves the line in STRING. + if (infile.eof()) + break; + std::stringstream ss(STRING); + if (STRING.find("Bank") == std::string::npos) { + double time0, spectra0; + ss >> time0 >> spectra0; + time[a].push_back(time0); + spectra[a].push_back(spectra0); - } else { - a++; - } + } else { + a++; } } infile.close(); diff --git a/Framework/Crystal/src/MaskPeaksWorkspace.cpp b/Framework/Crystal/src/MaskPeaksWorkspace.cpp index 173c6877ede1aba29f3b21f045c73e8b67b54684..eccab7700967e20f1772efe0c842d64b30fb3866 100644 --- a/Framework/Crystal/src/MaskPeaksWorkspace.cpp +++ b/Framework/Crystal/src/MaskPeaksWorkspace.cpp @@ -3,13 +3,12 @@ //---------------------------------------------------------------------- #include "MantidCrystal/MaskPeaksWorkspace.h" #include "MantidDataObjects/PeaksWorkspace.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/InstrumentValidator.h" #include "MantidAPI/FileProperty.h" #include "MantidAPI/FunctionFactory.h" #include "MantidAPI/IPeakFunction.h" #include "MantidKernel/VectorHelper.h" #include "MantidKernel/ArrayProperty.h" -#include <fstream> namespace Mantid { namespace Crystal { diff --git a/Framework/Crystal/src/NormaliseVanadium.cpp b/Framework/Crystal/src/NormaliseVanadium.cpp index dd7b026f1c4a54171729bd101e1a436d104b9caa..cc42991e91367cbaa260fc5dcbe71aa58e7792cc 100644 --- a/Framework/Crystal/src/NormaliseVanadium.cpp +++ b/Framework/Crystal/src/NormaliseVanadium.cpp @@ -2,7 +2,7 @@ // Includes //---------------------------------------------------------------------- #include "MantidCrystal/NormaliseVanadium.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/InstrumentValidator.h" #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/UnitFactory.h" #include "MantidKernel/Fast_Exponential.h" @@ -26,8 +26,7 @@ NormaliseVanadium::NormaliseVanadium() : API::Algorithm() {} void NormaliseVanadium::init() { // The input workspace must have an instrument and units of wavelength - auto wsValidator = boost::make_shared<CompositeValidator>(); - wsValidator->add<InstrumentValidator>(); + auto wsValidator = boost::make_shared<InstrumentValidator>(); declareProperty(new WorkspaceProperty<>("InputWorkspace", "", Direction::Input, wsValidator), diff --git a/Framework/Crystal/src/OptimizeExtinctionParameters.cpp b/Framework/Crystal/src/OptimizeExtinctionParameters.cpp index 5cb88b11706a63b570e70bf636db0d70b0f9b9f5..f52313952078931c092fb49f01d12b1a1282f2d5 100644 --- a/Framework/Crystal/src/OptimizeExtinctionParameters.cpp +++ b/Framework/Crystal/src/OptimizeExtinctionParameters.cpp @@ -2,7 +2,6 @@ #include "MantidDataObjects/PeaksWorkspace.h" #include "MantidAPI/FileProperty.h" #include "MantidAPI/FunctionFactory.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidAPI/IPeakFunction.h" #include "MantidAPI/IBackgroundFunction.h" #include "MantidAPI/CompositeFunction.h" diff --git a/Framework/Crystal/src/OptimizeLatticeForCellType.cpp b/Framework/Crystal/src/OptimizeLatticeForCellType.cpp index b5b60609b2b08f3c6317cb9f80da1a5a6791e14f..26327af7378dc145c9d3314000aaa430c311d330 100644 --- a/Framework/Crystal/src/OptimizeLatticeForCellType.cpp +++ b/Framework/Crystal/src/OptimizeLatticeForCellType.cpp @@ -2,7 +2,6 @@ #include "MantidCrystal/GSLFunctions.h" #include "MantidAPI/FileProperty.h" #include "MantidAPI/FunctionFactory.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidAPI/IPeakFunction.h" #include "MantidKernel/VectorHelper.h" #include "MantidKernel/ListValidator.h" diff --git a/Framework/Crystal/src/PeakIntegration.cpp b/Framework/Crystal/src/PeakIntegration.cpp index 8c4a5f1f5bb8f897cee60688ec9d068bd584be3c..9da094c81196f2cf68705daf25cc447ba8d85a8d 100644 --- a/Framework/Crystal/src/PeakIntegration.cpp +++ b/Framework/Crystal/src/PeakIntegration.cpp @@ -2,7 +2,7 @@ // Includes //---------------------------------------------------------------------- #include "MantidAPI/MemoryManager.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/InstrumentValidator.h" #include "MantidAPI/FileProperty.h" #include "MantidAPI/FunctionFactory.h" #include "MantidAPI/IPeakFunction.h" @@ -14,7 +14,6 @@ #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/VisibleWhenProperty.h" #include <boost/math/special_functions/fpclassify.hpp> -#include <fstream> namespace Mantid { namespace Crystal { diff --git a/Framework/Crystal/src/PredictPeaks.cpp b/Framework/Crystal/src/PredictPeaks.cpp index d6b2032d12e760b89565e9047123393622ca34fd..c9a4014e0e6201c05c8ab193f9c80f7d1d48099e 100644 --- a/Framework/Crystal/src/PredictPeaks.cpp +++ b/Framework/Crystal/src/PredictPeaks.cpp @@ -1,7 +1,6 @@ #include "MantidCrystal/PredictPeaks.h" #include "MantidGeometry/Objects/InstrumentRayTracer.h" #include "MantidKernel/ListValidator.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidKernel/EnabledWhenProperty.h" #include "MantidAPI/IMDEventWorkspace.h" diff --git a/Framework/Crystal/src/SaveHKL.cpp b/Framework/Crystal/src/SaveHKL.cpp index 531893ebf5181eaacb538ee2eb25602000c59645..0892660f75417fbe9b98815157a12693a1a32eba 100644 --- a/Framework/Crystal/src/SaveHKL.cpp +++ b/Framework/Crystal/src/SaveHKL.cpp @@ -1,5 +1,4 @@ #include "MantidAPI/FileProperty.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidCrystal/SaveHKL.h" #include "MantidGeometry/Instrument/RectangularDetector.h" #include "MantidKernel/Utils.h" @@ -230,37 +229,23 @@ void SaveHKL::exec() { infile.open(spectraFile.c_str()); if (infile.is_open()) { size_t a = 0; - if (iSpec == 1) { - while (!infile.eof()) // To get you all the lines. - { - // Set up sizes. (HEIGHT x WIDTH) - spectra.resize(a + 1); - getline(infile, STRING); // Saves the line in STRING. - infile >> spec[0] >> spec[1] >> spec[2] >> spec[3] >> spec[4] >> - spec[5] >> spec[6] >> spec[7] >> spec[8] >> spec[9] >> spec[10]; - for (int i = 0; i < 11; i++) - spectra[a].push_back(spec[i]); + for (int wi = 0; wi < 8; wi++) + getline(infile, STRING); // Saves the line in STRING. + while (!infile.eof()) // To get you all the lines. + { + time.resize(a + 1); + spectra.resize(a + 1); + getline(infile, STRING); // Saves the line in STRING. + std::stringstream ss(STRING); + if (STRING.find("Bank") == std::string::npos) { + double time0, spectra0; + ss >> time0 >> spectra0; + time[a].push_back(time0); + spectra[a].push_back(spectra0); + + } else { a++; } - } else { - for (int wi = 0; wi < 8; wi++) - getline(infile, STRING); // Saves the line in STRING. - while (!infile.eof()) // To get you all the lines. - { - time.resize(a + 1); - spectra.resize(a + 1); - getline(infile, STRING); // Saves the line in STRING. - std::stringstream ss(STRING); - if (STRING.find("Bank") == std::string::npos) { - double time0, spectra0; - ss >> time0 >> spectra0; - time[a].push_back(time0); - spectra[a].push_back(spectra0); - - } else { - a++; - } - } } infile.close(); } diff --git a/Framework/Crystal/src/SaveIsawPeaks.cpp b/Framework/Crystal/src/SaveIsawPeaks.cpp index 9d8754c9ce9c8fb4e47f910fd854e7f69128d7a4..eb5403151890cc03f04798f5d73f622bbd9e0d42 100644 --- a/Framework/Crystal/src/SaveIsawPeaks.cpp +++ b/Framework/Crystal/src/SaveIsawPeaks.cpp @@ -1,5 +1,5 @@ #include "MantidAPI/FileProperty.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/InstrumentValidator.h" #include "MantidCrystal/SaveIsawPeaks.h" #include "MantidDataObjects/Peak.h" #include "MantidDataObjects/PeaksWorkspace.h" diff --git a/Framework/Crystal/src/SaveLauenorm.cpp b/Framework/Crystal/src/SaveLauenorm.cpp index 927a86d07c8a9797dfd8a0df0164c71fc6268431..339c05f661de42f35bec75af98fde98ee01a4000 100644 --- a/Framework/Crystal/src/SaveLauenorm.cpp +++ b/Framework/Crystal/src/SaveLauenorm.cpp @@ -1,5 +1,4 @@ #include "MantidAPI/FileProperty.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidCrystal/SaveLauenorm.h" #include "MantidGeometry/Instrument/RectangularDetector.h" #include "MantidKernel/Utils.h" diff --git a/Framework/Crystal/src/SetSpecialCoordinates.cpp b/Framework/Crystal/src/SetSpecialCoordinates.cpp index 492e5840cb752bdfaa8a8f22491f577611482007..05b5d9b518e062c79c30c9f312309ad1cd464587 100644 --- a/Framework/Crystal/src/SetSpecialCoordinates.cpp +++ b/Framework/Crystal/src/SetSpecialCoordinates.cpp @@ -1,5 +1,4 @@ #include "MantidCrystal/SetSpecialCoordinates.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidAPI/IPeaksWorkspace.h" #include "MantidAPI/IMDEventWorkspace.h" #include "MantidAPI/IMDHistoWorkspace.h" diff --git a/Framework/Crystal/src/SortHKL.cpp b/Framework/Crystal/src/SortHKL.cpp index 019bb2e8507fe323848e1eefcba552df6f5a3a51..7e1d9cadcc29f23a6ea860af189c12c1d92002d1 100644 --- a/Framework/Crystal/src/SortHKL.cpp +++ b/Framework/Crystal/src/SortHKL.cpp @@ -1,5 +1,4 @@ #include "MantidAPI/FileProperty.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidCrystal/SortHKL.h" #include "MantidDataObjects/Peak.h" #include "MantidDataObjects/PeaksWorkspace.h" diff --git a/Framework/Crystal/src/StatisticsOfPeaksWorkspace.cpp b/Framework/Crystal/src/StatisticsOfPeaksWorkspace.cpp index 4bf0b39255b41d08655309b985dd74dac3336407..07d090b008bde9a419d3272f6856c3080ea02631 100644 --- a/Framework/Crystal/src/StatisticsOfPeaksWorkspace.cpp +++ b/Framework/Crystal/src/StatisticsOfPeaksWorkspace.cpp @@ -1,5 +1,4 @@ #include "MantidAPI/FileProperty.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidCrystal/StatisticsOfPeaksWorkspace.h" #include "MantidKernel/Utils.h" #include "MantidKernel/BoundedValidator.h" diff --git a/Framework/Crystal/src/TOFExtinction.cpp b/Framework/Crystal/src/TOFExtinction.cpp index 609acdfb5cc0844652119b074ce47eda9c7c9e38..19fb13381c3df3d8ade2d6d7e8f7de99fe05b004 100644 --- a/Framework/Crystal/src/TOFExtinction.cpp +++ b/Framework/Crystal/src/TOFExtinction.cpp @@ -1,5 +1,4 @@ #include "MantidAPI/FileProperty.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidCrystal/TOFExtinction.h" #include "MantidDataObjects/Peak.h" #include "MantidDataObjects/PeaksWorkspace.h" diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/RefinePowderInstrumentParameters.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/RefinePowderInstrumentParameters.h index ae51ee6bc546147d19ee3d365b728512e0bf0641..9d3eeba57a4f02f257190c767a07f51f4f6f6df0 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/RefinePowderInstrumentParameters.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/RefinePowderInstrumentParameters.h @@ -152,43 +152,43 @@ private: //--------------- Class Variables ------------------- /// Output Workspace containing the dspacing ~ TOF peak positions - DataObjects::Workspace2D_sptr dataWS; + DataObjects::Workspace2D_sptr m_dataWS; /// Map for all peaks to fit individually - std::map<std::vector<int>, Functions::BackToBackExponential_sptr> mPeaks; + std::map<std::vector<int>, Functions::BackToBackExponential_sptr> m_Peaks; /// Map for all peaks' error (fitted vs. experimental): [HKL]: Chi^2 - std::map<std::vector<int>, double> mPeakErrors; + std::map<std::vector<int>, double> m_PeakErrors; /// Map for function (instrument parameter) - std::map<std::string, double> mFuncParameters; + std::map<std::string, double> m_FuncParameters; /// Map to store the original (input) parameters - std::map<std::string, double> mOrigParameters; + std::map<std::string, double> m_OrigParameters; /// Peak function parameter names - std::vector<std::string> mPeakFunctionParameterNames; + std::vector<std::string> m_PeakFunctionParameterNames; /// N sets of the peak parameter values for the best N chi2 for MC. It is /// paired with mPeakFunctionParameterNames - std::vector<std::pair<double, std::vector<double>>> mBestMCParameters; + std::vector<std::pair<double, std::vector<double>>> m_BestMCParameters; /// N sets of the peak parameter values for the best N chi2 for MC. It is /// paired with mPeakFunctionParameterNames - std::vector<std::pair<double, std::vector<double>>> mBestFitParameters; + std::vector<std::pair<double, std::vector<double>>> m_BestFitParameters; /// N sets of the homemade chi2 and gsl chi2 - std::vector<std::pair<double, double>> mBestFitChi2s; + std::vector<std::pair<double, double>> m_BestFitChi2s; /// Best Chi2 ever - double mBestGSLChi2; + double m_BestGSLChi2; /// Minimum allowed sigma of a peak - double mMinSigma; + double m_MinSigma; /// Minimum number of fitted peaks for refinement - size_t mMinNumFittedPeaks; + size_t m_MinNumFittedPeaks; /// Maximum number of data stored - size_t mMaxNumberStoredParameters; + size_t m_MaxNumberStoredParameters; /// Modelling function - Functions::ThermalNeutronDtoTOFFunction_sptr mFunction; + Functions::ThermalNeutronDtoTOFFunction_sptr m_Function; }; /** Formular for linear iterpolation: X = [(xf-x0)*Y - (xf*y0-x0*yf)]/(yf-y0) diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/GSLMatrix.h b/Framework/CurveFitting/inc/MantidCurveFitting/GSLMatrix.h index e9e35f7ac6e9d915984bba1aa8a17d91f7c10955..9add0ff7f666e5946222020673c31a24eb6c58d6 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/GSLMatrix.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/GSLMatrix.h @@ -241,6 +241,7 @@ inline GSLMatrixMult3 operator*(const GSLMatrixMult2 &mm, const Tr &m) { /// The << operator. Prints a matrix in rows. inline std::ostream &operator<<(std::ostream &ostr, const GSLMatrix &m) { + std::ios::fmtflags fflags(ostr.flags()); ostr << std::scientific << std::setprecision(6); for (size_t i = 0; i < m.size1(); ++i) { for (size_t j = 0; j < m.size2(); ++j) { @@ -248,6 +249,7 @@ inline std::ostream &operator<<(std::ostream &ostr, const GSLMatrix &m) { } ostr << std::endl; } + ostr.flags(fflags); return ostr; } diff --git a/Framework/CurveFitting/src/Algorithms/CalculateGammaBackground.cpp b/Framework/CurveFitting/src/Algorithms/CalculateGammaBackground.cpp index a6281e12576ea6a561de2189adf28c38e98ac59f..0daa71f91663bea98e7a610601556e78d77aa205 100644 --- a/Framework/CurveFitting/src/Algorithms/CalculateGammaBackground.cpp +++ b/Framework/CurveFitting/src/Algorithms/CalculateGammaBackground.cpp @@ -6,9 +6,11 @@ #include "MantidAPI/CompositeFunction.h" #include "MantidAPI/FunctionProperty.h" #include "MantidAPI/FunctionFactory.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidKernel/ArrayProperty.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/MandatoryValidator.h" #include "MantidKernel/PhysicalConstants.h" diff --git a/Framework/CurveFitting/src/Algorithms/CalculateMSVesuvio.cpp b/Framework/CurveFitting/src/Algorithms/CalculateMSVesuvio.cpp index c34d6b66b7caf69f416a7fb04af6a6f341c9a881..c0aab6f4f53fad24963adeb9762cd707836a1e7b 100644 --- a/Framework/CurveFitting/src/Algorithms/CalculateMSVesuvio.cpp +++ b/Framework/CurveFitting/src/Algorithms/CalculateMSVesuvio.cpp @@ -8,7 +8,7 @@ #include "MantidCurveFitting/Functions/VesuvioResolution.h" #include "MantidAPI/SampleShapeValidator.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidGeometry/Instrument/DetectorGroup.h" #include "MantidGeometry/Instrument/ParameterMap.h" diff --git a/Framework/CurveFitting/src/Algorithms/ConvertToYSpace.cpp b/Framework/CurveFitting/src/Algorithms/ConvertToYSpace.cpp index 1124ff0504e39bf341dc6e2d45f958ec507eeda8..1f2ba6bfb145c5dc580e11219a74c281bbb5966b 100644 --- a/Framework/CurveFitting/src/Algorithms/ConvertToYSpace.cpp +++ b/Framework/CurveFitting/src/Algorithms/ConvertToYSpace.cpp @@ -1,10 +1,11 @@ #include "MantidCurveFitting/Algorithms/ConvertToYSpace.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidGeometry/Instrument/DetectorGroup.h" #include "MantidKernel/BoundedValidator.h" - -#include <boost/make_shared.hpp> +#include "MantidKernel/CompositeValidator.h" namespace Mantid { namespace CurveFitting { diff --git a/Framework/CurveFitting/src/Algorithms/FitPowderDiffPeaks.cpp b/Framework/CurveFitting/src/Algorithms/FitPowderDiffPeaks.cpp index b69b92fdba2ae6bc11c07eaadbd5e5c46d75924d..87801460543315e7aaccd4501e43e74facf27e8f 100644 --- a/Framework/CurveFitting/src/Algorithms/FitPowderDiffPeaks.cpp +++ b/Framework/CurveFitting/src/Algorithms/FitPowderDiffPeaks.cpp @@ -2021,7 +2021,6 @@ bool FitPowderDiffPeaks::doFitMultiplePeaks( // 1. Fit peaks intensities first const size_t numpeaks = peakfuncs.size(); map<string, double> peaksfuncparams; - bool evergood = true; // a) Set up fit/fix vector<string> peakparnames = peakfuncs[0]->getParameterNames(); @@ -2045,7 +2044,7 @@ bool FitPowderDiffPeaks::doFitMultiplePeaks( double chi2; bool fitgood = doFitNPeaksSimple(dataws, wsindex, peaksfunc, peakfuncs, "Levenberg-MarquardtMD", 1000, chi2); - evergood = evergood || fitgood; + bool evergood = fitgood; // c) Process result if (!fitgood) { diff --git a/Framework/CurveFitting/src/Algorithms/LeBailFit.cpp b/Framework/CurveFitting/src/Algorithms/LeBailFit.cpp index 60e3d731b21978a1bb9b3ed92ab4deb36575ab06..21d6e9af3d6c32ae3b6a07aa2cd14487ad0aac60 100644 --- a/Framework/CurveFitting/src/Algorithms/LeBailFit.cpp +++ b/Framework/CurveFitting/src/Algorithms/LeBailFit.cpp @@ -341,7 +341,7 @@ void LeBailFit::exec() { case FIT: // LeBail Fit g_log.notice() << "Function: Do LeBail Fit ==> Monte Carlo.\n"; - + // fall through case MONTECARLO: // Monte carlo Le Bail refinement g_log.notice("Function: Do LeBail Fit By Monte Carlo Random Walk."); diff --git a/Framework/CurveFitting/src/Algorithms/NormaliseByPeakArea.cpp b/Framework/CurveFitting/src/Algorithms/NormaliseByPeakArea.cpp index 780f0feb4261bf251d0c137fae577124e818ec44..320b0e0a634c02a01930dc8823504a199c8202a3 100644 --- a/Framework/CurveFitting/src/Algorithms/NormaliseByPeakArea.cpp +++ b/Framework/CurveFitting/src/Algorithms/NormaliseByPeakArea.cpp @@ -1,10 +1,13 @@ #include "MantidCurveFitting/Algorithms/NormaliseByPeakArea.h" -#include "MantidAPI/IFunction.h" #include "MantidAPI/FunctionFactory.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/IFunction.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" #include <boost/make_shared.hpp> diff --git a/Framework/CurveFitting/src/Algorithms/RefinePowderInstrumentParameters.cpp b/Framework/CurveFitting/src/Algorithms/RefinePowderInstrumentParameters.cpp index 98a64f0b76769673b79f16fcf1fab4ce31aea6d1..80d4fdec61c340ed49b564399931f1824e76dc26 100644 --- a/Framework/CurveFitting/src/Algorithms/RefinePowderInstrumentParameters.cpp +++ b/Framework/CurveFitting/src/Algorithms/RefinePowderInstrumentParameters.cpp @@ -48,7 +48,9 @@ DECLARE_ALGORITHM(RefinePowderInstrumentParameters) //---------------------------------------------------------------------------------------------- /** Constructor */ -RefinePowderInstrumentParameters::RefinePowderInstrumentParameters() {} +RefinePowderInstrumentParameters::RefinePowderInstrumentParameters() + : m_BestGSLChi2(0.0), m_MinSigma(0.0), m_MinNumFittedPeaks(0), + m_MaxNumberStoredParameters(0) {} //---------------------------------------------------------------------------------------------- /** Destructor @@ -145,7 +147,7 @@ void RefinePowderInstrumentParameters::exec() { DataObjects::TableWorkspace_sptr parameterWS = this->getProperty("InstrumentParameterWorkspace"); - mMinSigma = getProperty("MinSigma"); + m_MinSigma = getProperty("MinSigma"); int tempint = getProperty("MinNumberFittedPeaks"); if (tempint <= 1) { @@ -153,13 +155,13 @@ void RefinePowderInstrumentParameters::exec() { << " is too small. " << endl; throw std::invalid_argument("Input MinNumberFittedPeaks is too small."); } - mMinNumFittedPeaks = static_cast<size_t>(tempint); + m_MinNumFittedPeaks = static_cast<size_t>(tempint); tempint = getProperty("NumberBestFitRecorded"); if (tempint <= 0) throw runtime_error( "Input NumberBestFitRecorded cannot be less and equal to 0. "); - mMaxNumberStoredParameters = static_cast<size_t>(tempint); + m_MaxNumberStoredParameters = static_cast<size_t>(tempint); string algoption = getProperty("RefinementAlgorithm"); if (algoption.compare("DirectFit") == 0) @@ -172,14 +174,14 @@ void RefinePowderInstrumentParameters::exec() { // 2. Parse input table workspace genPeaksFromTable(peakWS); - importParametersFromTable(parameterWS, mFuncParameters); - mOrigParameters = mFuncParameters; + importParametersFromTable(parameterWS, m_FuncParameters); + m_OrigParameters = m_FuncParameters; // 3. Generate a cener workspace as function of d-spacing. bool usemc = false; if (refinealgorithm == MonteCarlo) usemc = true; - genPeakCentersWorkspace(usemc, mMaxNumberStoredParameters); + genPeakCentersWorkspace(usemc, m_MaxNumberStoredParameters); // 4. Fit instrument geometry function stringstream errss; @@ -208,7 +210,7 @@ void RefinePowderInstrumentParameters::exec() { } // 5. Set output workspace - this->setProperty("OutputWorkspace", dataWS); + this->setProperty("OutputWorkspace", m_dataWS); // 6. Output new instrument parameters DataObjects::TableWorkspace_sptr fitparamws = @@ -228,16 +230,16 @@ void RefinePowderInstrumentParameters::fitInstrumentParameters() { // 1. Initialize the fitting function ThermalNeutronDtoTOFFunction rawfunc; - mFunction = boost::make_shared<ThermalNeutronDtoTOFFunction>(rawfunc); - mFunction->initialize(); + m_Function = boost::make_shared<ThermalNeutronDtoTOFFunction>(rawfunc); + m_Function->initialize(); - API::FunctionDomain1DVector domain(dataWS->readX(1)); + API::FunctionDomain1DVector domain(m_dataWS->readX(1)); API::FunctionValues values(domain); - const MantidVec &rawY = dataWS->readY(0); - const MantidVec &rawE = dataWS->readE(0); + const MantidVec &rawY = m_dataWS->readY(0); + const MantidVec &rawE = m_dataWS->readE(0); // 2. Set up parameters values - std::vector<std::string> funparamnames = mFunction->getParameterNames(); + std::vector<std::string> funparamnames = m_Function->getParameterNames(); std::vector<std::string> paramtofit = getProperty("ParametersToFit"); std::sort(paramtofit.begin(), paramtofit.end()); @@ -247,22 +249,22 @@ void RefinePowderInstrumentParameters::fitInstrumentParameters() { std::map<std::string, double>::iterator paramiter; for (size_t i = 0; i < funparamnames.size(); ++i) { string parname = funparamnames[i]; - paramiter = mFuncParameters.find(parname); - if (paramiter == mFuncParameters.end()) { + paramiter = m_FuncParameters.find(parname); + if (paramiter == m_FuncParameters.end()) { // Not found and thus skip continue; } double parvalue = paramiter->second; - mFunction->setParameter(parname, parvalue); + m_Function->setParameter(parname, parvalue); msgss << setw(10) << parname << " = " << parvalue << endl; } cout << msgss.str(); // 2b. Calculate the statistic of the starting values - double gslchi2 = calculateFunctionStatistic(mFunction, dataWS, 0); + double gslchi2 = calculateFunctionStatistic(m_Function, m_dataWS, 0); double homchi2 = - calculateD2TOFFunction(mFunction, domain, values, rawY, rawE); + calculateD2TOFFunction(m_Function, domain, values, rawY, rawE); cout << "Fit Starting Value: Chi^2 (GSL) = " << gslchi2 << ", Chi2^2 (Home) = " << homchi2 << endl; @@ -274,9 +276,9 @@ void RefinePowderInstrumentParameters::fitInstrumentParameters() { vsiter = std::find(paramtofit.begin(), paramtofit.end(), parname); if (vsiter == paramtofit.end()) - mFunction->fix(i); + m_Function->fix(i); else - mFunction->unfix(i); + m_Function->unfix(i); } // 4. Select minimizer. Use Simplex for more than 1 parameters to fit. @@ -288,13 +290,13 @@ void RefinePowderInstrumentParameters::fitInstrumentParameters() { g_log.information() << "Fit use minizer: " << minimizer << endl; // 5. Create and setup fit algorithm - g_log.information() << "Fit instrument geometry: " << mFunction->asString() + g_log.information() << "Fit instrument geometry: " << m_Function->asString() << std::endl; stringstream outss; - for (size_t i = 0; i < dataWS->readX(0).size(); ++i) - outss << dataWS->readX(0)[i] << "\t\t" << dataWS->readY(0)[i] << "\t\t" - << dataWS->readE(0)[i] << endl; + for (size_t i = 0; i < m_dataWS->readX(0).size(); ++i) + outss << m_dataWS->readX(0)[i] << "\t\t" << m_dataWS->readY(0)[i] << "\t\t" + << m_dataWS->readE(0)[i] << endl; cout << "Input Peak Position Workspace To Fit: " << endl << outss.str() << endl; @@ -302,8 +304,8 @@ void RefinePowderInstrumentParameters::fitInstrumentParameters() { fitalg->initialize(); fitalg->setProperty("Function", - boost::dynamic_pointer_cast<API::IFunction>(mFunction)); - fitalg->setProperty("InputWorkspace", dataWS); + boost::dynamic_pointer_cast<API::IFunction>(m_Function)); + fitalg->setProperty("InputWorkspace", m_dataWS); fitalg->setProperty("WorkspaceIndex", 0); fitalg->setProperty("Minimizer", minimizer); fitalg->setProperty("CostFunction", "Least squares"); @@ -326,31 +328,31 @@ void RefinePowderInstrumentParameters::fitInstrumentParameters() { API::IFunction_sptr fitfunc = fitalg->getProperty("Function"); // 4. Set the output data (model and diff) - mFunction->function(domain, values); + m_Function->function(domain, values); for (size_t i = 0; i < domain.size(); ++i) { - dataWS->dataY(1)[i] = values[i]; - dataWS->dataY(2)[i] = dataWS->readY(0)[i] - values[i]; + m_dataWS->dataY(1)[i] = values[i]; + m_dataWS->dataY(2)[i] = m_dataWS->readY(0)[i] - values[i]; } double selfchi2 = - calculateD2TOFFunction(mFunction, domain, values, rawY, rawE); + calculateD2TOFFunction(m_Function, domain, values, rawY, rawE); cout << "Homemade Chi^2 = " << selfchi2 << endl; // 5. Update fitted parameters for (size_t i = 0; i < funparamnames.size(); ++i) { std::string parname = funparamnames[i]; double parvalue = fitfunc->getParameter(parname); - mFuncParameters[parname] = parvalue; + m_FuncParameters[parname] = parvalue; } // 6. Pretty screen output stringstream dbss; dbss << "************ Fit Parameter Result *************" << std::endl; - for (paramiter = mFuncParameters.begin(); paramiter != mFuncParameters.end(); - ++paramiter) { + for (paramiter = m_FuncParameters.begin(); + paramiter != m_FuncParameters.end(); ++paramiter) { std::string parname = paramiter->first; - double inpparvalue = mOrigParameters[parname]; + double inpparvalue = m_OrigParameters[parname]; double parvalue = paramiter->second; dbss << setw(20) << parname << " = " << setw(15) << setprecision(6) << parvalue << "\t\tFrom " << setw(15) << setprecision(6) @@ -362,18 +364,18 @@ void RefinePowderInstrumentParameters::fitInstrumentParameters() { // 7. Play with Zscore: template<typename TYPE> // std::vector<double> getZscore(const std::vector<TYPE>& data, const bool // sorted=false); - vector<double> z0 = Kernel::getZscore(dataWS->readY(0)); - vector<double> z1 = Kernel::getZscore(dataWS->readY(1)); - vector<double> z2 = Kernel::getZscore(dataWS->readY(2)); + vector<double> z0 = Kernel::getZscore(m_dataWS->readY(0)); + vector<double> z1 = Kernel::getZscore(m_dataWS->readY(1)); + vector<double> z2 = Kernel::getZscore(m_dataWS->readY(2)); stringstream zss; zss << setw(20) << "d_h" << setw(20) << "Z DataY" << setw(20) << "Z ModelY" << setw(20) << "Z DiffY" << setw(20) << "DiffY" << endl; for (size_t i = 0; i < z0.size(); ++i) { - double d_h = dataWS->readX(0)[i]; + double d_h = m_dataWS->readX(0)[i]; double zdatay = z0[i]; double zmodely = z1[i]; double zdiffy = z2[i]; - double diffy = dataWS->readY(2)[i]; + double diffy = m_dataWS->readY(2)[i]; zss << setw(20) << d_h << setw(20) << zdatay << setw(20) << zmodely << setw(20) << zdiffy << setw(20) << diffy << endl; } @@ -392,7 +394,7 @@ bool RefinePowderInstrumentParameters::fitFunction(IFunction_sptr func, fitalg->setProperty("Function", boost::dynamic_pointer_cast<API::IFunction>(func)); - fitalg->setProperty("InputWorkspace", dataWS); + fitalg->setProperty("InputWorkspace", m_dataWS); fitalg->setProperty("WorkspaceIndex", 0); fitalg->setProperty("Minimizer", "Simplex"); fitalg->setProperty("CostFunction", "Least squares"); @@ -462,19 +464,20 @@ double RefinePowderInstrumentParameters::calculateFunctionStatistic( void RefinePowderInstrumentParameters::refineInstrumentParametersMC( TableWorkspace_sptr parameterWS, bool fit2) { // 1. Get function's parameter names - getD2TOFFuncParamNames(mPeakFunctionParameterNames); + getD2TOFFuncParamNames(m_PeakFunctionParameterNames); // 2. Parse parameter (table) workspace vector<double> stepsizes, lowerbounds, upperbounds; - importMonteCarloParametersFromTable(parameterWS, mPeakFunctionParameterNames, + importMonteCarloParametersFromTable(parameterWS, m_PeakFunctionParameterNames, stepsizes, lowerbounds, upperbounds); stringstream dbss; - for (size_t i = 0; i < mPeakFunctionParameterNames.size(); ++i) { - dbss << setw(20) << mPeakFunctionParameterNames[i] << ": Min = " << setw(15) - << setprecision(6) << lowerbounds[i] << ", Max = " << setw(15) - << setprecision(6) << upperbounds[i] << ", Step Size = " << setw(15) - << setprecision(6) << stepsizes[i] << endl; + for (size_t i = 0; i < m_PeakFunctionParameterNames.size(); ++i) { + dbss << setw(20) << m_PeakFunctionParameterNames[i] + << ": Min = " << setw(15) << setprecision(6) << lowerbounds[i] + << ", Max = " << setw(15) << setprecision(6) << upperbounds[i] + << ", Step Size = " << setw(15) << setprecision(6) << stepsizes[i] + << endl; } g_log.notice() << "Monte Carlo Parameters: " << endl << dbss.str(); @@ -494,33 +497,33 @@ void RefinePowderInstrumentParameters::refineInstrumentParametersMC( double stepsizescalefactor = 1.1; // 5. Monte Carlo simulation - doParameterSpaceRandomWalk(mPeakFunctionParameterNames, lowerbounds, + doParameterSpaceRandomWalk(m_PeakFunctionParameterNames, lowerbounds, upperbounds, stepsizes, maxsteps, stepsizescalefactor, fit2); // 6. Record the result - const MantidVec &X = dataWS->readX(0); - const MantidVec &Y = dataWS->readY(0); - const MantidVec &E = dataWS->readE(0); + const MantidVec &X = m_dataWS->readX(0); + const MantidVec &Y = m_dataWS->readY(0); + const MantidVec &E = m_dataWS->readE(0); FunctionDomain1DVector domain(X); FunctionValues values(domain); - for (size_t i = 0; i < mBestFitParameters.size(); ++i) { + for (size_t i = 0; i < m_BestFitParameters.size(); ++i) { // a. Set the function with the - for (size_t j = 0; j < mPeakFunctionParameterNames.size(); ++j) { - mFunction->setParameter(mPeakFunctionParameterNames[j], - mBestFitParameters[i].second[j]); + for (size_t j = 0; j < m_PeakFunctionParameterNames.size(); ++j) { + m_Function->setParameter(m_PeakFunctionParameterNames[j], + m_BestFitParameters[i].second[j]); } // b. Calculate - calculateD2TOFFunction(mFunction, domain, values, Y, E); + calculateD2TOFFunction(m_Function, domain, values, Y, E); vector<double> vec_n; - calculateThermalNeutronSpecial(mFunction, X, vec_n); + calculateThermalNeutronSpecial(m_Function, X, vec_n); // c. Put the data to output workspace - MantidVec &newY = dataWS->dataY(3 * i + 1); - MantidVec &newD = dataWS->dataY(3 * i + 2); - MantidVec &newN = dataWS->dataY(3 * i + 3); + MantidVec &newY = m_dataWS->dataY(3 * i + 1); + MantidVec &newD = m_dataWS->dataY(3 * i + 2); + MantidVec &newN = m_dataWS->dataY(3 * i + 3); for (size_t j = 0; j < newY.size(); ++j) { newY[j] = values[j]; newD[j] = Y[j] - values[j]; @@ -548,30 +551,30 @@ void RefinePowderInstrumentParameters::doParameterSpaceRandomWalk( << setw(20) << "Upper Boundary" << setw(20) << "Step Size" << endl; for (size_t i = 0; i < parnames.size(); ++i) inpinfo << setw(20) << parnames[i] << setw(20) << - mFuncParameters[parnames[i]] + m_FuncParameters[parnames[i]] << setw(20) << lowerbounds[i] << setw(20) << upperbounds[i] << setw(20) << stepsizes[i] << endl; cout << inpinfo.str(); ------------*/ - // 1. Set up starting values, esp. to mFunction + // 1. Set up starting values, esp. to m_Function size_t numparameters = parnames.size(); vector<double> paramvalues; for (size_t i = 0; i < numparameters; ++i) { string parname = parnames[i]; - double parvalue = mFuncParameters[parname]; + double parvalue = m_FuncParameters[parname]; paramvalues.push_back(parvalue); - mFunction->setParameter(parname, parvalue); + m_Function->setParameter(parname, parvalue); } // Calcualte the function's initial statistic - mBestGSLChi2 = calculateFunctionStatistic(mFunction, dataWS, 0); - cout << "Function with starting values has Chi2 = " << mBestGSLChi2 + m_BestGSLChi2 = calculateFunctionStatistic(m_Function, m_dataWS, 0); + cout << "Function with starting values has Chi2 = " << m_BestGSLChi2 << " (GSL L.M) " << endl; - const MantidVec &X = dataWS->readX(0); - const MantidVec &rawY = dataWS->readY(0); - const MantidVec &rawE = dataWS->readE(0); + const MantidVec &X = m_dataWS->readX(0); + const MantidVec &rawY = m_dataWS->readY(0); + const MantidVec &rawE = m_dataWS->readE(0); FunctionDomain1DVector domain(X); FunctionValues values(domain); @@ -623,7 +626,7 @@ void RefinePowderInstrumentParameters::doParameterSpaceRandomWalk( // 4. Do MC loops double curchi2 = - calculateD2TOFFunction(mFunction, domain, values, rawY, rawE); + calculateD2TOFFunction(m_Function, domain, values, rawY, rawE); g_log.notice() << "Monte Carlo Random Walk Starting Chi^2 = " << curchi2 << endl; @@ -656,7 +659,7 @@ void RefinePowderInstrumentParameters::doParameterSpaceRandomWalk( } try { - mFunction->setParameter(parnames[paramindex], newvalue); + m_Function->setParameter(parnames[paramindex], newvalue); } catch (runtime_error &) { stringstream errss; errss << "New Value = " << newvalue @@ -669,13 +672,13 @@ void RefinePowderInstrumentParameters::doParameterSpaceRandomWalk( // b. Calcualte the new double newchi2 = - calculateD2TOFFunction(mFunction, domain, values, rawY, rawE); + calculateD2TOFFunction(m_Function, domain, values, rawY, rawE); // Optionally fit if (fit2) { // i. Copy the parameters for (size_t i = 0; i < numparameters; ++i) { - double parvalue = mFunction->getParameter(i); + double parvalue = m_Function->getParameter(i); func4fit->setParameter(i, parvalue); } @@ -688,8 +691,8 @@ void RefinePowderInstrumentParameters::doParameterSpaceRandomWalk( double homchi2 = calculateD2TOFFunction(func4fit, domain, values, rawY, rawE); - if (gslchi2 < mBestGSLChi2) - mBestGSLChi2 = gslchi2; + if (gslchi2 < m_BestGSLChi2) + m_BestGSLChi2 = gslchi2; // iv. Archive vector<double> newparvalues; @@ -697,15 +700,15 @@ void RefinePowderInstrumentParameters::doParameterSpaceRandomWalk( double parvalue = func4fit->getParameter(i); newparvalues.push_back(parvalue); } - mBestFitParameters.push_back(make_pair(homchi2, newparvalues)); - mBestFitChi2s.push_back(make_pair(homchi2, gslchi2)); + m_BestFitParameters.push_back(make_pair(homchi2, newparvalues)); + m_BestFitChi2s.push_back(make_pair(homchi2, gslchi2)); // v. Sort and keep in size - sort(mBestFitParameters.begin(), mBestFitParameters.end()); - sort(mBestFitChi2s.begin(), mBestFitChi2s.end()); - if (mBestFitParameters.size() > mMaxNumberStoredParameters) { - mBestFitParameters.pop_back(); - mBestFitChi2s.pop_back(); + sort(m_BestFitParameters.begin(), m_BestFitParameters.end()); + sort(m_BestFitChi2s.begin(), m_BestFitChi2s.end()); + if (m_BestFitParameters.size() > m_MaxNumberStoredParameters) { + m_BestFitParameters.pop_back(); + m_BestFitChi2s.pop_back(); } // cout << "\tHomemade Chi^2 = " << homchi2 << endl; @@ -752,12 +755,12 @@ void RefinePowderInstrumentParameters::doParameterSpaceRandomWalk( // ii. Add the new values to vector vector<double> parametervalues = paramvalues; - mBestMCParameters.push_back(make_pair(newchi2, parametervalues)); + m_BestMCParameters.push_back(make_pair(newchi2, parametervalues)); // iii. Sort and delete the last if necessary - sort(mBestMCParameters.begin(), mBestMCParameters.end()); - if (mBestMCParameters.size() > mMaxNumberStoredParameters) - mBestMCParameters.pop_back(); + sort(m_BestMCParameters.begin(), m_BestMCParameters.end()); + if (m_BestMCParameters.size() > m_MaxNumberStoredParameters) + m_BestMCParameters.pop_back(); // iv. Update chi2 and ... curchi2 = newchi2; @@ -773,24 +776,24 @@ void RefinePowderInstrumentParameters::doParameterSpaceRandomWalk( // 3. Debug output stringstream mcresult; - mcresult << "Monte Carlo Result for " << mBestMCParameters.size() + mcresult << "Monte Carlo Result for " << m_BestMCParameters.size() << " Best Results" << endl; mcresult << "Number of acceptance = " << numacceptance << ", out of " << maxsteps << " MC steps." << "Accept ratio = " << static_cast<double>(numacceptance) / static_cast<double>(maxsteps) << endl; - mcresult << "Best " << mBestMCParameters.size() + mcresult << "Best " << m_BestMCParameters.size() << " Monte Carlo (no fit) results: " << endl; - for (size_t i = 0; i < mBestMCParameters.size(); ++i) { - mcresult << setw(3) << i << ": Chi^2 = " << mBestMCParameters[i].first + for (size_t i = 0; i < m_BestMCParameters.size(); ++i) { + mcresult << setw(3) << i << ": Chi^2 = " << m_BestMCParameters[i].first << endl; } - mcresult << "Best " << mBestMCParameters.size() - << " fitting results. Best Chi^2 = " << mBestGSLChi2 << endl; - for (size_t i = 0; i < mBestFitParameters.size(); ++i) { - mcresult << setw(3) << i << ": Chi^2 = " << mBestFitParameters[i].first - << ", GSL Chi^2 = " << mBestFitChi2s[i].second << endl; + mcresult << "Best " << m_BestMCParameters.size() + << " fitting results. Best Chi^2 = " << m_BestGSLChi2 << endl; + for (size_t i = 0; i < m_BestFitParameters.size(); ++i) { + mcresult << setw(3) << i << ": Chi^2 = " << m_BestFitParameters[i].first + << ", GSL Chi^2 = " << m_BestFitChi2s[i].second << endl; } g_log.notice() << mcresult.str(); @@ -809,7 +812,7 @@ void RefinePowderInstrumentParameters::getD2TOFFuncParamNames( d2toffunc.initialize(); std::vector<std::string> funparamnames = d2toffunc.getParameterNames(); - mFunction = boost::make_shared<ThermalNeutronDtoTOFFunction>(d2toffunc); + m_Function = boost::make_shared<ThermalNeutronDtoTOFFunction>(d2toffunc); // 3. Copy parnames = funparamnames; @@ -824,14 +827,14 @@ double RefinePowderInstrumentParameters::calculateD2TOFFunction( const MantidVec &rawY, const MantidVec &rawE) { // 1. Check validity if (!func) { - throw std::runtime_error("mFunction has not been initialized!"); + throw std::runtime_error("m_Function has not been initialized!"); } else { /* - vector<string> parnames = mFunction->getParameterNames(); + vector<string> parnames = m_Function->getParameterNames(); for (size_t i = 0; i < parnames.size(); ++i) { cout << "DBx1125 " << parnames[i] << " = " << - mFunction->getParameter(parnames[i]) << endl; + m_Function->getParameter(parnames[i]) << endl; } */ ; @@ -861,7 +864,7 @@ double RefinePowderInstrumentParameters::calculateD2TOFFunction( //------------------------------- Processing Inputs //---------------------------------------- /** Genearte peaks from input workspace - * Peaks are stored in a map. (HKL) is the key + * m_Peaks are stored in a map. (HKL) is the key */ void RefinePowderInstrumentParameters::genPeaksFromTable( DataObjects::TableWorkspace_sptr peakparamws) { @@ -873,7 +876,7 @@ void RefinePowderInstrumentParameters::genPeaksFromTable( "Invalid input table workspace for peak parameters"); } - mPeaks.clear(); + m_Peaks.clear(); // 2. Parse table workspace rows to generate peaks vector<string> colnames = peakparamws->getColumnNames(); @@ -940,12 +943,12 @@ void RefinePowderInstrumentParameters::genPeaksFromTable( hkl.push_back(k); hkl.push_back(l); - mPeaks.insert(std::make_pair(hkl, newpeakptr)); + m_Peaks.insert(std::make_pair(hkl, newpeakptr)); - mPeakErrors.insert(make_pair(hkl, chi2)); + m_PeakErrors.insert(make_pair(hkl, chi2)); - g_log.information() << "[GeneratePeaks] Peak " << ir << " HKL = [" << hkl[0] - << ", " << hkl[1] << ", " << hkl[2] + g_log.information() << "[Generatem_Peaks] Peak " << ir << " HKL = [" + << hkl[0] << ", " << hkl[1] << ", " << hkl[2] << "], Input Center = " << setw(10) << setprecision(6) << newpeak.centre() << endl; @@ -1118,17 +1121,17 @@ hkl, double lattice) /** Calcualte value n for thermal neutron peak profile */ void RefinePowderInstrumentParameters::calculateThermalNeutronSpecial( - IFunction_sptr mFunction, vector<double> vec_d, vector<double> &vec_n) { - if (mFunction->name().compare("ThermalNeutronDtoTOFFunction") != 0) { - g_log.warning() << "Function (" << mFunction->name() + IFunction_sptr m_Function, vector<double> vec_d, vector<double> &vec_n) { + if (m_Function->name().compare("ThermalNeutronDtoTOFFunction") != 0) { + g_log.warning() << "Function (" << m_Function->name() << " is not ThermalNeutronDtoTOFFunction. And it is not " "required to calculate n." << endl; for (size_t i = 0; i < vec_d.size(); ++i) vec_n.push_back(0); } - double width = mFunction->getParameter("Width"); - double tcross = mFunction->getParameter("Tcross"); + double width = m_Function->getParameter("Width"); + double tcross = m_Function->getParameter("Tcross"); for (size_t i = 0; i < vec_d.size(); ++i) { double dh = vec_d[i]; @@ -1149,7 +1152,7 @@ void RefinePowderInstrumentParameters::calculateThermalNeutronSpecial( void RefinePowderInstrumentParameters::genPeakCentersWorkspace( bool montecarlo, size_t numbestfit) { // 1. Collect values in a vector for sorting - double lattice = mFuncParameters["LatticeConstant"]; + double lattice = m_FuncParameters["LatticeConstant"]; if (lattice < 1.0E-5) { std::stringstream errmsg; errmsg << "Input Lattice constant = " << lattice @@ -1176,12 +1179,12 @@ void RefinePowderInstrumentParameters::genPeakCentersWorkspace( Geometry::UnitCell unitcell(lattice, lattice, lattice, 90.0, 90.0, 90.0); - for (peakiter = mPeaks.begin(); peakiter != mPeaks.end(); ++peakiter) { + for (peakiter = m_Peaks.begin(); peakiter != m_Peaks.end(); ++peakiter) { vector<int> hkl = peakiter->first; BackToBackExponential_sptr peak = peakiter->second; double sigma = peak->getParameter("S"); - if (sigma < mMinSigma) { + if (sigma < m_MinSigma) { g_log.information() << "Peak (" << hkl[0] << ", " << hkl[1] << ", " << hkl[2] << ") has unphysically small Sigma = " << sigma @@ -1222,18 +1225,18 @@ void RefinePowderInstrumentParameters::genPeakCentersWorkspace( nspec = 1 + 3; } - dataWS = boost::dynamic_pointer_cast<DataObjects::Workspace2D>( + m_dataWS = boost::dynamic_pointer_cast<DataObjects::Workspace2D>( API::WorkspaceFactory::Instance().create("Workspace2D", nspec, size, size)); - dataWS->getAxis(0)->setUnit("dSpacing"); + m_dataWS->getAxis(0)->setUnit("dSpacing"); // 4. Put data to output workspace for (size_t i = 0; i < peakcenters.size(); ++i) { for (size_t j = 0; j < nspec; ++j) { - dataWS->dataX(j)[i] = peakcenters[i].first; + m_dataWS->dataX(j)[i] = peakcenters[i].first; } - dataWS->dataY(0)[i] = peakcenters[i].second.first; - dataWS->dataE(0)[i] = peakcenters[i].second.second; + m_dataWS->dataY(0)[i] = peakcenters[i].second.first; + m_dataWS->dataE(0)[i] = peakcenters[i].second.second; } return; @@ -1250,18 +1253,18 @@ RefinePowderInstrumentParameters::genMCResultTable() { tablews->addColumn("double", "Chi2"); tablews->addColumn("double", "GSLChi2"); - for (size_t i = 0; i < mPeakFunctionParameterNames.size(); ++i) { - tablews->addColumn("double", mPeakFunctionParameterNames[i]); + for (size_t i = 0; i < m_PeakFunctionParameterNames.size(); ++i) { + tablews->addColumn("double", m_PeakFunctionParameterNames[i]); } // 2. Put values in - for (size_t ib = 0; ib < mBestFitParameters.size(); ++ib) { + for (size_t ib = 0; ib < m_BestFitParameters.size(); ++ib) { TableRow newrow = tablews->appendRow(); - double chi2 = mBestFitParameters[ib].first; - double gslchi2 = mBestFitChi2s[ib].second; + double chi2 = m_BestFitParameters[ib].first; + double gslchi2 = m_BestFitChi2s[ib].second; newrow << chi2 << gslchi2; - for (size_t ip = 0; ip < mPeakFunctionParameterNames.size(); ++ip) { - double tempdbl = mBestFitParameters[ib].second[ip]; + for (size_t ip = 0; ip < m_PeakFunctionParameterNames.size(); ++ip) { + double tempdbl = m_BestFitParameters[ib].second[ip]; newrow << tempdbl; } } // ENDFOR 1 Best Answer @@ -1290,7 +1293,7 @@ RefinePowderInstrumentParameters::genOutputInstrumentParameterTable() { std::map<std::string, double>::iterator pariter; - for (pariter = mFuncParameters.begin(); pariter != mFuncParameters.end(); + for (pariter = m_FuncParameters.begin(); pariter != m_FuncParameters.end(); ++pariter) { API::TableRow newrow = newtablews->appendRow(); std::string parname = pariter->first; diff --git a/Framework/CurveFitting/src/Algorithms/RefinePowderInstrumentParameters3.cpp b/Framework/CurveFitting/src/Algorithms/RefinePowderInstrumentParameters3.cpp index a5c35c1f331d71bca31643d8fc85b77d7bf7b2fd..f87a83a0013f454452b40c588a6b9787401d477a 100644 --- a/Framework/CurveFitting/src/Algorithms/RefinePowderInstrumentParameters3.cpp +++ b/Framework/CurveFitting/src/Algorithms/RefinePowderInstrumentParameters3.cpp @@ -870,8 +870,15 @@ double RefinePowderInstrumentParameters3::calculateFunctionError( // 2. Fit with zero iteration double chi2; string fitstatus; - doFitFunction(function, dataws, wsindex, "Levenberg-MarquardtMD", 0, chi2, - fitstatus); + const std::string minimizer = "Levenberg-MarquardtMD"; + bool fitOK = + doFitFunction(function, dataws, wsindex, minimizer, 0, chi2, fitstatus); + + if (!fitOK) { + g_log.warning() << "Fit by " << minimizer + << " with 0 iterations failed, with reason: " << fitstatus + << "\n"; + } // 3. Restore the fit/fix setup for (size_t i = 0; i < parnames.size(); ++i) { diff --git a/Framework/CurveFitting/src/Algorithms/SplineBackground.cpp b/Framework/CurveFitting/src/Algorithms/SplineBackground.cpp index 93b2e86016a7320e17d3ae657789ec49ad86da6f..a19fa51061060d39206dd760f8a1d8db453d9fb0 100644 --- a/Framework/CurveFitting/src/Algorithms/SplineBackground.cpp +++ b/Framework/CurveFitting/src/Algorithms/SplineBackground.cpp @@ -66,8 +66,7 @@ void SplineBackground::exec() { bool isMasked = inWS->hasMaskedBins(spec); std::vector<int> masked(Y.size()); if (isMasked) { - for (API::MatrixWorkspace::MaskList::const_iterator it = - inWS->maskedBins(spec).begin(); + for (auto it = inWS->maskedBins(spec).begin(); it != inWS->maskedBins(spec).end(); ++it) masked[it->first] = 1; n -= static_cast<int>(inWS->maskedBins(spec).size()); diff --git a/Framework/CurveFitting/src/GSLVector.cpp b/Framework/CurveFitting/src/GSLVector.cpp index 6c7c341cf7d4f0f9f158ba91e7ebffe771a3cce0..cdbc2a12db0e7f571b5a8703754af69f1805cfd1 100644 --- a/Framework/CurveFitting/src/GSLVector.cpp +++ b/Framework/CurveFitting/src/GSLVector.cpp @@ -157,10 +157,12 @@ double GSLVector::dot(const GSLVector &v) const { /// The << operator. std::ostream &operator<<(std::ostream &ostr, const GSLVector &v) { + std::ios::fmtflags fflags(ostr.flags()); ostr << std::scientific << std::setprecision(6); for (size_t j = 0; j < v.size(); ++j) { ostr << std::setw(13) << v[j] << ' '; } + ostr.flags(fflags); return ostr; } diff --git a/Framework/CurveFitting/src/IFittingAlgorithm.cpp b/Framework/CurveFitting/src/IFittingAlgorithm.cpp index de562d920cb7ca6961c07095663dd03ce53bc28c..4984b1edc74ed77ea305da877eece95d140f407f 100644 --- a/Framework/CurveFitting/src/IFittingAlgorithm.cpp +++ b/Framework/CurveFitting/src/IFittingAlgorithm.cpp @@ -216,9 +216,10 @@ void IFittingAlgorithm::addWorkspace(const std::string &workspacePropertyName, boost::shared_ptr<MultiDomainCreator> multiCreator = boost::dynamic_pointer_cast<MultiDomainCreator>(m_domainCreator); if (!multiCreator) { + auto &reference = *m_domainCreator.get(); throw std::runtime_error( std::string("MultiDomainCreator expected, found ") + - typeid(*m_domainCreator.get()).name()); + typeid(reference).name()); } if (!multiCreator->hasCreator(index)) { creator->declareDatasetProperties(suffix, addProperties); @@ -283,4 +284,4 @@ void IFittingAlgorithm::exec() { } } // namespace CurveFitting -} // namespace Mantid \ No newline at end of file +} // namespace Mantid diff --git a/Framework/CurveFitting/src/ParameterEstimator.cpp b/Framework/CurveFitting/src/ParameterEstimator.cpp index 93c46fd68fbb9ae0690fbf296458a5f3bb20b7c4..db682fa12c32e3fce6170d9e4ca8c7a28725dfcd 100644 --- a/Framework/CurveFitting/src/ParameterEstimator.cpp +++ b/Framework/CurveFitting/src/ParameterEstimator.cpp @@ -7,6 +7,8 @@ #include "MantidKernel/Logger.h" +#include <Poco/Mutex.h> + #include <cmath> namespace Mantid { @@ -18,20 +20,44 @@ using namespace Functions; /// The logger. Kernel::Logger g_log("ParameterEstimator"); +namespace { +/// Mutex to prevent simultaneous access to functionMap +Poco::Mutex FUNCTION_MAP_MUTEX; +} + enum Function { None, Gaussian, Lorentzian, BackToBackExponential }; typedef std::map<std::string, std::pair<size_t, Function>> FunctionMapType; //---------------------------------------------------------------------------------------------- + +/// Initializes a FunctionMapType object +/// @param functionMapType :: the function map to initialize +void initFunctionLookup(FunctionMapType &functionMapType) { + assert(functionMapType.empty()); + + functionMapType["Gaussian"] = std::make_pair(2, Gaussian); + functionMapType["Lorentzian"] = std::make_pair(2, Lorentzian); + functionMapType["BackToBackExponential"] = + std::make_pair(4, BackToBackExponential); +} + +/// Returns a reference to the static functionMapType +/// @returns :: a const reference to the functionMapType +const FunctionMapType &getFunctionMapType() { + + Poco::Mutex::ScopedLock lock(FUNCTION_MAP_MUTEX); + + static FunctionMapType functionMapType; + + if (functionMapType.empty()) + initFunctionLookup(functionMapType); + return functionMapType; +} + /// Return a function code for a function if it needs setting values or None /// otherwise. Function whichFunction(const API::IFunction &function) { - static FunctionMapType functionMap; - if (functionMap.empty()) { - functionMap["Gaussian"] = std::make_pair(2, Gaussian); - functionMap["Lorentzian"] = std::make_pair(2, Lorentzian); - functionMap["BackToBackExponential"] = - std::make_pair(4, BackToBackExponential); - } + const FunctionMapType &functionMap = getFunctionMapType(); auto index = functionMap.find(function.name()); if (index != functionMap.end()) { if (!function.isExplicitlySet(index->second.first)) diff --git a/Framework/CurveFitting/src/SimplexMinimizer.cpp b/Framework/CurveFitting/src/SimplexMinimizer.cpp index b0c5ba671041eaada2fdb2979a8abb0249bd05dc..694b344296ef6cb9944ff1f1932b6950cc8bd19e 100644 --- a/Framework/CurveFitting/src/SimplexMinimizer.cpp +++ b/Framework/CurveFitting/src/SimplexMinimizer.cpp @@ -55,6 +55,9 @@ void SimplexMinimizer::initialize(API::ICostFunction_sptr function, size_t) { size_t np = function->nParams(); // step size for simplex m_simplexStepSize = gsl_vector_alloc(np); + if (m_simplexStepSize == NULL) { + throw std::runtime_error("Simplex step size initialized to NULL pointer"); + } gsl_vector_set_all(m_simplexStepSize, m_size); // setup simplex container diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadAscii.h b/Framework/DataHandling/inc/MantidDataHandling/LoadAscii.h index 44e695b5bcd1d3a08be0c73641950774822fbbb9..cf495c009be312933a224018d34b0deb1079edab 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadAscii.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadAscii.h @@ -5,6 +5,7 @@ // Includes //---------------------------------------------------------------------- #include "MantidAPI/IFileLoader.h" +#include "MantidAPI/DeprecatedAlgorithm.h" namespace Mantid { namespace DataHandling { @@ -45,7 +46,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. File change history is stored at: <https://github.com/mantidproject/mantid>. Code Documentation is available at: <http://doxygen.mantidproject.org> */ -class DLLExport LoadAscii : public API::IFileLoader<Kernel::FileDescriptor> { +class DLLExport LoadAscii : public API::IFileLoader<Kernel::FileDescriptor>, + public API::DeprecatedAlgorithm { public: /// Default constructor LoadAscii(); diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadEventPreNexus.h b/Framework/DataHandling/inc/MantidDataHandling/LoadEventPreNexus.h index c3f14b233810c5a14e3082ea5bc88725df2ef0ed..328be8a18896d921be8e0a25bd1c6ff8f0185c86 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadEventPreNexus.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadEventPreNexus.h @@ -5,6 +5,7 @@ #include <string> #include <vector> #include "MantidAPI/IFileLoader.h" +#include "MantidAPI/DeprecatedAlgorithm.h" #include "MantidKernel/BinaryFile.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/Events.h" @@ -88,7 +89,8 @@ struct Pulse { #pragma pack(pop) class DLLExport LoadEventPreNexus - : public API::IFileLoader<Kernel::FileDescriptor> { + : public API::IFileLoader<Kernel::FileDescriptor>, + public API::DeprecatedAlgorithm { public: /// Constructor LoadEventPreNexus(); diff --git a/Framework/DataHandling/src/CheckMantidVersion.cpp b/Framework/DataHandling/src/CheckMantidVersion.cpp index 30a620c6079eaca94651b3e22d92d059b72a93cf..01776379510adfeda238fd768ab2a72cf9949863 100644 --- a/Framework/DataHandling/src/CheckMantidVersion.cpp +++ b/Framework/DataHandling/src/CheckMantidVersion.cpp @@ -107,11 +107,35 @@ void CheckMantidVersion::exec() { if (!json.empty()) { Json::Reader r; Json::Value root; - r.parse(json, root); + bool parseOK = r.parse(json, root); + if (!parseOK) { + // just warning. The parser is able to get relevant info even if there are + // formatting issues like missing quotes or brackets. + g_log.warning() << "Error found when parsing version information " + "retrieved from GitHub as a JSON string. " + "Error trying to parse this JSON string: " << json + << std::endl + << ". Parsing error details: " + << r.getFormattedErrorMessages() << std::endl; + } - std::string gitHubVersionTag = root["tag_name"].asString(); - mostRecentVersion = cleanVersionTag(gitHubVersionTag); + std::string gitHubVersionTag; + try { + gitHubVersionTag = root["tag_name"].asString(); + } catch (std::runtime_error &re) { + g_log.error() + << "Error while trying to get the field 'tag_name' from " + "the version information retrieved from GitHub. This " + "algorithm cannot continue and will stop now. Error details: " + << re.what() << std::endl; + + mostRecentVersion = "Could not get information from GitHub"; + setProperty("MostRecentVersion", mostRecentVersion); + setProperty("IsNewVersionAvailable", isNewVersionAvailable); + return; + } + mostRecentVersion = cleanVersionTag(gitHubVersionTag); isNewVersionAvailable = isVersionMoreRecent(currentVersion, mostRecentVersion); if (isNewVersionAvailable) { diff --git a/Framework/DataHandling/src/CompressEvents.cpp b/Framework/DataHandling/src/CompressEvents.cpp index 581ac3d877a23a594b99f2e011abda62550c0d55..3597a53930144170a37c23bccc2b7270269cb700 100644 --- a/Framework/DataHandling/src/CompressEvents.cpp +++ b/Framework/DataHandling/src/CompressEvents.cpp @@ -2,9 +2,8 @@ // Includes //---------------------------------------------------------------------- #include "MantidDataHandling/CompressEvents.h" -#include "MantidDataObjects/EventWorkspace.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidAPI/MemoryManager.h" +#include "MantidDataObjects/EventWorkspace.h" #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/BoundedValidator.h" #include <set> diff --git a/Framework/DataHandling/src/FindDetectorsPar.cpp b/Framework/DataHandling/src/FindDetectorsPar.cpp index ebf13530cb10af84b215944a36f5ec26b906d378..54a55db21733e1805eef52f48f2c924e01370b45 100644 --- a/Framework/DataHandling/src/FindDetectorsPar.cpp +++ b/Framework/DataHandling/src/FindDetectorsPar.cpp @@ -1,16 +1,19 @@ #include "MantidDataHandling/FindDetectorsPar.h" -#include "MantidGeometry/Objects/BoundingBox.h" -#include "MantidKernel/Logger.h" -#include "MantidKernel/ArrayProperty.h" -#include "MantidKernel/Exception.h" -#include "MantidKernel/MultiThreaded.h" -#include "MantidAPI/FileProperty.h" -#include "MantidGeometry/Instrument/DetectorGroup.h" -#include "MantidAPI/WorkspaceValidators.h" + #include "MantidAPI/AnalysisDataService.h" +#include "MantidAPI/CommonBinsValidator.h" +#include "MantidAPI/FileProperty.h" +#include "MantidAPI/InstrumentValidator.h" #include "MantidAPI/ITableWorkspace.h" #include "MantidAPI/TableRow.h" +#include "MantidGeometry/Instrument/DetectorGroup.h" +#include "MantidGeometry/Objects/BoundingBox.h" + +#include "MantidKernel/CompositeValidator.h" +#include "MantidKernel/Exception.h" +#include "MantidKernel/MultiThreaded.h" + #include <Poco/File.h> #include <limits> diff --git a/Framework/DataHandling/src/GroupDetectors.cpp b/Framework/DataHandling/src/GroupDetectors.cpp index a116a4e05c564dc93be1ad0734a52373617c27fc..5ff3c1c1b7d2b4ecf235f9a8a1c9d7ae0058d6a0 100644 --- a/Framework/DataHandling/src/GroupDetectors.cpp +++ b/Framework/DataHandling/src/GroupDetectors.cpp @@ -2,7 +2,7 @@ // Includes //---------------------------------------------------------------------- #include "MantidDataHandling/GroupDetectors.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/CommonBinsValidator.h" #include "MantidAPI/WorkspaceOpOverloads.h" #include "MantidKernel/ArrayProperty.h" #include <set> diff --git a/Framework/DataHandling/src/GroupDetectors2.cpp b/Framework/DataHandling/src/GroupDetectors2.cpp index 060f54bee77e172c5cfa3da87e6294c5f0aea2c2..7567cc8e6da22794430ce706cb97c7f5d4c1aeca 100644 --- a/Framework/DataHandling/src/GroupDetectors2.cpp +++ b/Framework/DataHandling/src/GroupDetectors2.cpp @@ -3,14 +3,14 @@ //---------------------------------------------------------------------- #include "MantidDataHandling/GroupDetectors2.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidAPI/SpectraAxis.h" +#include "MantidAPI/CommonBinsValidator.h" #include "MantidAPI/FileProperty.h" +#include "MantidAPI/SpectraAxis.h" #include "MantidDataHandling/LoadDetectorsGroupingFile.h" +#include "MantidGeometry/Instrument/DetectorGroup.h" #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/Exception.h" #include "MantidKernel/ListValidator.h" -#include "MantidGeometry/Instrument/DetectorGroup.h" #include <boost/regex.hpp> @@ -353,7 +353,7 @@ void GroupDetectors2::getGroups(API::MatrixWorkspace_const_sptr workspace, } // check we don't have an index that is too high for the workspace size_t maxIn = static_cast<size_t>(workspace->getNumberHistograms() - 1); - std::vector<size_t>::const_iterator it = m_GroupSpecInds[0].begin(); + auto it = m_GroupSpecInds[0].begin(); for (; it != m_GroupSpecInds[0].end(); ++it) { if (*it > maxIn) { g_log.error() << "Spectra index " << *it @@ -375,7 +375,7 @@ void GroupDetectors2::getGroups(API::MatrixWorkspace_const_sptr workspace, // up date unUsedSpec, this is used to find duplicates and when the user has // set KeepUngroupedSpectra - std::vector<size_t>::const_iterator index = m_GroupSpecInds[0].begin(); + auto index = m_GroupSpecInds[0].begin(); for (; index != m_GroupSpecInds[0].end(); ++index) { // the vector<int> m_GroupSpecInds[0] must not index contain // numbers that don't exist in the workspaace @@ -804,6 +804,10 @@ void GroupDetectors2::readFile(spec2index_map &specs2index, std::istream &File, numberOfSpectra = readInt(thisLine); } while (numberOfSpectra == EMPTY_LINE); + if (numberOfSpectra <= 0) { + throw std::invalid_argument("The number of spectra is zero or negative"); + } + // the value of this map is the list of spectra numbers that will be // combined into a group m_GroupSpecInds[spectrumNo].reserve(numberOfSpectra); diff --git a/Framework/DataHandling/src/LoadANSTOHelper.cpp b/Framework/DataHandling/src/LoadANSTOHelper.cpp index 2e539fb756adc0e48415746d9fcd9bbb5229d2e1..17d5c6f83bc20f1c59b77a4438e693e512e6d135 100644 --- a/Framework/DataHandling/src/LoadANSTOHelper.cpp +++ b/Framework/DataHandling/src/LoadANSTOHelper.cpp @@ -2,7 +2,6 @@ #include "MantidDataObjects/EventWorkspace.h" #include "MantidAPI/FileProperty.h" #include "MantidAPI/RegisterFileLoader.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidKernel/UnitFactory.h" #include "MantidGeometry/Instrument.h" #include "MantidGeometry/Instrument/RectangularDetector.h" diff --git a/Framework/DataHandling/src/LoadAscii.cpp b/Framework/DataHandling/src/LoadAscii.cpp index 747bd5422b98555db8ceb6e6bff37a5245f66abe..74dda663af566b72c71ca5209a90493ddff03af7 100644 --- a/Framework/DataHandling/src/LoadAscii.cpp +++ b/Framework/DataHandling/src/LoadAscii.cpp @@ -24,7 +24,9 @@ using namespace Kernel; using namespace API; /// Empty constructor -LoadAscii::LoadAscii() : m_columnSep(), m_separatorIndex() {} +LoadAscii::LoadAscii() : m_columnSep(), m_separatorIndex() { + this->useAlgorithm("LoadAscii", 2); +} /** * Return the confidence with with this algorithm can load the file diff --git a/Framework/DataHandling/src/LoadBBY.cpp b/Framework/DataHandling/src/LoadBBY.cpp index 5c670badbacd110171d22b117186b3d4f9f54c32..2db849718f279c461ff19ee9bb8f792f10345342 100644 --- a/Framework/DataHandling/src/LoadBBY.cpp +++ b/Framework/DataHandling/src/LoadBBY.cpp @@ -1,13 +1,12 @@ #include "MantidDataHandling/LoadBBY.h" -#include "MantidDataObjects/EventWorkspace.h" -#include "MantidKernel/PropertyWithValue.h" #include "MantidAPI/FileProperty.h" #include "MantidAPI/RegisterFileLoader.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/UnitFactory.h" +#include "MantidDataObjects/EventWorkspace.h" #include "MantidGeometry/Instrument.h" #include "MantidGeometry/Instrument/RectangularDetector.h" #include "MantidGeometry/Objects/ShapeFactory.h" +#include "MantidKernel/PropertyWithValue.h" +#include "MantidKernel/UnitFactory.h" #include "MantidNexus/NexusClasses.h" #include <Poco/TemporaryFile.h> @@ -405,6 +404,7 @@ void LoadBBY::exec() { createChildAlgorithm("LoadInstrument"); loadInstrumentAlg->setProperty("Workspace", eventWS); loadInstrumentAlg->setPropertyValue("InstrumentName", "BILBY"); + loadInstrumentAlg->setProperty("RewriteSpectraMap", false); loadInstrumentAlg->executeAsChildAlg(); setProperty("OutputWorkspace", eventWS); @@ -826,4 +826,4 @@ void BbyDetectorBankFactory::createAndAssign(size_t startIndex, } } // DataHandling -} // Mantid \ No newline at end of file +} // Mantid diff --git a/Framework/DataHandling/src/LoadDspacemap.cpp b/Framework/DataHandling/src/LoadDspacemap.cpp index bbbf5cc6c878a555eb1ddb45f9fafcac52a51baa..751343163fff9bd27f8f21ff75109295bc040e25 100644 --- a/Framework/DataHandling/src/LoadDspacemap.cpp +++ b/Framework/DataHandling/src/LoadDspacemap.cpp @@ -1,17 +1,15 @@ +#include "MantidDataHandling/LoadDspacemap.h" #include "MantidAPI/FileProperty.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidDataHandling/LoadCalFile.h" -#include "MantidDataHandling/LoadDspacemap.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/GroupingWorkspace.h" #include "MantidDataObjects/OffsetsWorkspace.h" -#include "MantidKernel/V3D.h" +#include "MantidGeometry/IDetector.h" #include "MantidKernel/BinaryFile.h" +#include "MantidKernel/ListValidator.h" #include "MantidKernel/PhysicalConstants.h" -#include "MantidKernel/System.h" #include "MantidKernel/UnitFactory.h" -#include "MantidGeometry/IDetector.h" -#include "MantidKernel/ListValidator.h" +#include "MantidKernel/V3D.h" using namespace Mantid::Kernel; using namespace Mantid::API; diff --git a/Framework/DataHandling/src/LoadEventPreNexus.cpp b/Framework/DataHandling/src/LoadEventPreNexus.cpp index 43f73c8f10abe5c91fba36406380bfab82c5570c..e6687146f3fab3f327e3d18c3213dddf8b786999 100644 --- a/Framework/DataHandling/src/LoadEventPreNexus.cpp +++ b/Framework/DataHandling/src/LoadEventPreNexus.cpp @@ -84,7 +84,9 @@ LoadEventPreNexus::LoadEventPreNexus() num_good_events(0), num_error_events(0), num_ignored_events(0), first_event(0), max_events(0), using_mapping_file(false), loadOnlySomeSpectra(false), spectraLoadMap(), longest_tof(0), - shortest_tof(0), parallelProcessing(false) {} + shortest_tof(0), parallelProcessing(false) { + this->useAlgorithm("LoadEventPreNexus", 2); +} LoadEventPreNexus::~LoadEventPreNexus() { delete this->eventfile; } diff --git a/Framework/DataHandling/src/LoadGSS.cpp b/Framework/DataHandling/src/LoadGSS.cpp index eb228a845fad9e75f85288cf57e9aac4b2626faf..86192ed9b42ab11bfa661fd3b81051edde09121d 100644 --- a/Framework/DataHandling/src/LoadGSS.cpp +++ b/Framework/DataHandling/src/LoadGSS.cpp @@ -5,7 +5,6 @@ #include "MantidAPI/ISpectrum.h" #include "MantidAPI/FileProperty.h" #include "MantidAPI/RegisterFileLoader.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidKernel/UnitFactory.h" #include "MantidGeometry/Instrument.h" #include "MantidGeometry/Instrument/Detector.h" diff --git a/Framework/DataHandling/src/LoadIsawDetCal.cpp b/Framework/DataHandling/src/LoadIsawDetCal.cpp index 5a7ddf61096bc0e18243b50d626eb116159d9055..2fc3168b716430b093a5fd2da80f0ef2f1aa17fa 100644 --- a/Framework/DataHandling/src/LoadIsawDetCal.cpp +++ b/Framework/DataHandling/src/LoadIsawDetCal.cpp @@ -2,26 +2,26 @@ // Includes //---------------------------------------------------------------------- #include "MantidDataHandling/LoadIsawDetCal.h" + #include "MantidAPI/FileProperty.h" -#include "MantidAPI/TableRow.h" +#include "MantidAPI/InstrumentValidator.h" + #include "MantidDataObjects/Workspace2D.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/EventList.h" #include "MantidDataObjects/PeaksWorkspace.h" -#include "MantidAPI/TextAxis.h" -#include "MantidKernel/UnitFactory.h" -#include "MantidKernel/ArrayProperty.h" -#include "MantidKernel/Exception.h" + #include "MantidGeometry/Instrument/RectangularDetector.h" #include "MantidGeometry/Instrument/ObjCompAssembly.h" #include "MantidGeometry/Instrument/ComponentHelper.h" + #include "MantidKernel/V3D.h" + #include <Poco/File.h> #include <sstream> #include <fstream> #include <numeric> #include <cmath> -#include "MantidAPI/WorkspaceValidators.h" namespace Mantid { namespace DataHandling { diff --git a/Framework/DataHandling/src/LoadQKK.cpp b/Framework/DataHandling/src/LoadQKK.cpp index 316cffc185ab4b6e02656661ef7d28664ddee6ac..61b45a8cb2b559b5ef5946cee55f665b52c347d9 100644 --- a/Framework/DataHandling/src/LoadQKK.cpp +++ b/Framework/DataHandling/src/LoadQKK.cpp @@ -2,14 +2,16 @@ // Includes //--------------------------------------------------- #include "MantidDataHandling/LoadQKK.h" + #include "MantidAPI/FileProperty.h" #include "MantidAPI/RegisterFileLoader.h" -#include "MantidAPI/WorkspaceValidators.h" -#include "MantidKernel/UnitFactory.h" + #include "MantidGeometry/Instrument.h" #include "MantidGeometry/Instrument/RectangularDetector.h" #include "MantidGeometry/Objects/ShapeFactory.h" +#include "MantidKernel/UnitFactory.h" + #include "MantidNexus/NexusClasses.h" #include <boost/math/special_functions/fpclassify.hpp> diff --git a/Framework/DataHandling/src/LoadRaw/isisraw.cpp b/Framework/DataHandling/src/LoadRaw/isisraw.cpp index 6037ec23a60ae12f7ffbcacb65f8b3695f64bbac..475c96358d3637d62e0030ac41939bca61816f33 100644 --- a/Framework/DataHandling/src/LoadRaw/isisraw.cpp +++ b/Framework/DataHandling/src/LoadRaw/isisraw.cpp @@ -460,7 +460,17 @@ int ISISRAW::ioRAW(FILE *file, bool from_file, bool read_data) { // ioRAW(file, &u_len, 1, from_file); if (from_file) { u_len = add.ad_data - add.ad_user - 2; + + if (u_len < 0 || (add.ad_data < add.ad_user + 2)) { + // this will/would be used for memory allocation + std::cerr << "Error in u_len value read from file, it would be " << u_len + << "; where it is calculated as " + "u_len = ad_data - ad_user - 2, where ad_data: " + << add.ad_data << ", ad_user: " << add.ad_user << std::endl; + return 0; + } } + ioRAW(file, &u_dat, u_len, from_file); ioRAW(file, &ver8, 1, from_file); fgetpos(file, &dhdr_pos); @@ -474,8 +484,12 @@ int ISISRAW::ioRAW(FILE *file, bool from_file, bool read_data) { if (from_file) { ndes = t_nper * (t_nsp1 + 1); ioRAW(file, &ddes, ndes, from_file); - for (i = 0; i < ndes; i++) - fseek(file, 4 * ddes[i].nwords, SEEK_CUR); + for (i = 0; i < ndes; i++) { + int zero = fseek(file, 4 * ddes[i].nwords, SEEK_CUR); + if (0 != zero) + std::cerr << "Failed to seek position in file for index: " << i + << "\n"; + } } } else if (dhdr.d_comp == 0) { ndata = t_nper * (t_nsp1 + 1) * (t_ntc1 + 1); @@ -527,15 +541,38 @@ int ISISRAW::ioRAW(FILE *file, bool from_file, bool read_data) { dhdr.d_exp_filesize = uncomp_filesize / 128; // in 512 byte blocks (vms default allocation unit) - fgetpos(file, &keep_pos); + int zero = fgetpos(file, &keep_pos); + if (!zero) { + std::cerr << "Error when getting file position: " << strerror(errno) + << std::endl; + return -1; + } + // update section addresses - fsetpos(file, &add_pos); + zero = fsetpos(file, &add_pos); + if (!zero) { + std::cerr << "Error when setting file position: " << strerror(errno) + << std::endl; + return -1; + } + ioRAW(file, &add, 1, from_file); // update data header and descriptors etc. - fsetpos(file, &dhdr_pos); + zero = fsetpos(file, &dhdr_pos); + if (!zero) { + std::cerr << "Error when setting file position to header: " + << strerror(errno) << std::endl; + return -1; + } + ioRAW(file, &dhdr, 1, from_file); ioRAW(file, &ddes, ndes, from_file); - fsetpos(file, &keep_pos); + zero = fsetpos(file, &keep_pos); + if (!zero) { + std::cerr << "Error when restoring file position: " << strerror(errno) + << std::endl; + return -1; + } } return 0; } @@ -669,16 +706,18 @@ int ISISRAW::ioRAW(FILE *file, LOG_LINE *s, int len, bool from_file) { /// stuff int ISISRAW::ioRAW(FILE *file, char *s, int len, bool from_file) { - size_t n; if ((len <= 0) || (s == 0)) { return 0; } + + size_t n; if (from_file) { n = fread(s, sizeof(char), len, file); return static_cast<int>(n - len); } else { n = fwrite(s, sizeof(char), len, file); } + return 0; } @@ -687,11 +726,15 @@ int ISISRAW::ioRAW(FILE *file, int *s, int len, bool from_file) { if ((len <= 0) || (s == 0)) { return 0; } + + size_t n; if (from_file) { - fread(s, sizeof(int), len, file); + n = fread(s, sizeof(int), len, file); + return static_cast<int>(n - len); } else { - fwrite(s, sizeof(int), len, file); + n = fwrite(s, sizeof(int), len, file); } + return 0; } @@ -700,10 +743,13 @@ int ISISRAW::ioRAW(FILE *file, uint32_t *s, int len, bool from_file) { if ((len <= 0) || (s == 0)) { return 0; } + + size_t n; if (from_file) { - fread(s, sizeof(uint32_t), len, file); + n = fread(s, sizeof(uint32_t), len, file); + return static_cast<int>(n - len); } else { - fwrite(s, sizeof(uint32_t), len, file); + n = fwrite(s, sizeof(uint32_t), len, file); } return 0; } @@ -714,12 +760,15 @@ int ISISRAW::ioRAW(FILE *file, float *s, int len, bool from_file) { if ((len <= 0) || (s == 0)) { return 0; } + + size_t n; if (from_file) { - fread(s, sizeof(float), len, file); + n = fread(s, sizeof(float), len, file); vaxf_to_local(s, &len, &errcode); + return static_cast<int>(n - len); } else { local_to_vaxf(s, &len, &errcode); - fwrite(s, sizeof(float), len, file); + n = fwrite(s, sizeof(float), len, file); vaxf_to_local(s, &len, &errcode); } return 0; @@ -900,36 +949,6 @@ int ISISRAW::readFromFile(const char *filename, bool read_data) { } } -/// stuff -int ISISRAW::writeToFile(const char *filename) { - unsigned char zero_pad[512]; - memset(zero_pad, 0, sizeof(zero_pad)); - remove(filename); -#ifdef MS_VISUAL_STUDIO - FILE *output_file = NULL; - if (fopen_s(&output_file, filename, "w+bc") != 0) { - return -1; - } -#else //_WIN32 - FILE *output_file = fopen(filename, "w+bc"); -#endif //_WIN32 - if (output_file != NULL) { - ioRAW(output_file, false, 0); - fflush(output_file); - // we need to pad to a multiple of 512 bytes for VMS compatibility - fseek(output_file, 0, SEEK_END); - long pos = ftell(output_file); - if (pos % 512 > 0) { - int npad = 512 - pos % 512; - fwrite(zero_pad, 1, npad, output_file); - } - fclose(output_file); - return 0; - } else { - return -1; - } -} - /// stuff int ISISRAW::printInfo(std::ostream &os) { int i; diff --git a/Framework/DataHandling/src/LoadRaw/isisraw.h b/Framework/DataHandling/src/LoadRaw/isisraw.h index c7c419aac95c38cfaaefb20c7d6f262499901955..84d82a06fe282a491b652c79e9f084d907683ecc 100644 --- a/Framework/DataHandling/src/LoadRaw/isisraw.h +++ b/Framework/DataHandling/src/LoadRaw/isisraw.h @@ -373,7 +373,6 @@ public: int ioRAW(FILE *file, DDES_STRUCT **s, int len, bool from_file); int ioRAW(FILE *file, LOG_LINE **s, int len, bool from_file); int readFromFile(const char *filename, bool read_data = true); - int writeToFile(const char *filename); int printInfo(std::ostream &os); int getTimeChannels(float *rtcb1, int n); }; diff --git a/Framework/DataHandling/src/LoadRaw/isisraw2.cpp b/Framework/DataHandling/src/LoadRaw/isisraw2.cpp index f4bbb1f41873c6d09032e9d21c667cd829995d36..331b26bb1f8bb3a6758834da87dc064b47ac0d5a 100644 --- a/Framework/DataHandling/src/LoadRaw/isisraw2.cpp +++ b/Framework/DataHandling/src/LoadRaw/isisraw2.cpp @@ -95,7 +95,17 @@ int ISISRAW2::ioRAW(FILE *file, bool from_file, bool read_data) { // ISISRAW::ioRAW(file, &u_len, 1, from_file); if (from_file) { u_len = add.ad_data - add.ad_user - 2; + + if (u_len < 0 || (add.ad_data < add.ad_user + 2)) { + // this will/would be used for memory allocation + g_log.error() << "Error in u_len value read from file, it would be " + << u_len << "; where it is calculated as " + "u_len = ad_data - ad_user - 2, where ad_data: " + << add.ad_data << ", ad_user: " << add.ad_user << "\n"; + throw std::runtime_error("Inconsistent value for the field u_len found"); + } } + ISISRAW::ioRAW(file, &u_dat, u_len, from_file); ISISRAW::ioRAW(file, &ver8, 1, from_file); fgetpos(file, &dhdr_pos); @@ -115,8 +125,13 @@ int ISISRAW2::ioRAW(FILE *file, bool from_file, bool read_data) { /// @param file :: The file pointer /// @param i :: The amount of data to skip void ISISRAW2::skipData(FILE *file, int i) { - if (i < ndes) - fseek(file, 4 * ddes[i].nwords, SEEK_CUR); + if (i < ndes) { + int zero = fseek(file, 4 * ddes[i].nwords, SEEK_CUR); + if (0 != zero) { + g_log.warning() << "Failed to skip data from file, with value: " << i + << "\n"; + } + } } /// Read data diff --git a/Framework/DataHandling/src/MaskDetectors.cpp b/Framework/DataHandling/src/MaskDetectors.cpp index 141acf5d0c8369fac89d6292a3cff3b889ac7ca3..cde8d9af47d06e555f8c80b64d2a9304121163dd 100644 --- a/Framework/DataHandling/src/MaskDetectors.cpp +++ b/Framework/DataHandling/src/MaskDetectors.cpp @@ -2,11 +2,11 @@ // Includes //---------------------------------------------------------------------- #include "MantidDataHandling/MaskDetectors.h" -#include "MantidAPI/FrameworkManager.h" + #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/MaskWorkspace.h" + #include "MantidKernel/ArrayProperty.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidKernel/BoundedValidator.h" #include <set> diff --git a/Framework/DataHandling/src/SaveCanSAS1D.cpp b/Framework/DataHandling/src/SaveCanSAS1D.cpp index 65ebb1ea446a059ba762d29d4220728f29836823..33224957650f863d5769dd05b9fe56101ccf9eb4 100644 --- a/Framework/DataHandling/src/SaveCanSAS1D.cpp +++ b/Framework/DataHandling/src/SaveCanSAS1D.cpp @@ -2,13 +2,17 @@ // Includes //---------------------------------------------------------------------- #include "MantidDataHandling/SaveCanSAS1D.h" + #include "MantidAPI/FileProperty.h" -#include "MantidKernel/Exception.h" +#include "MantidAPI/Run.h" +#include "MantidAPI/WorkspaceUnitValidator.h" + #include "MantidGeometry/IComponent.h" -#include "MantidAPI/WorkspaceValidators.h" + +#include "MantidKernel/Exception.h" #include "MantidKernel/MantidVersion.h" #include "MantidKernel/ListValidator.h" -#include "MantidAPI/Run.h" + #include <boost/shared_ptr.hpp> //----------------------------------------------------------------------------- diff --git a/Framework/DataHandling/src/SaveCanSAS1D2.cpp b/Framework/DataHandling/src/SaveCanSAS1D2.cpp index 49a9bb0a4f8ce1e8a9ebec32452525d66e7dd3b1..df414fa039447c4febfc5e44d9cc6a9f8a54cea0 100644 --- a/Framework/DataHandling/src/SaveCanSAS1D2.cpp +++ b/Framework/DataHandling/src/SaveCanSAS1D2.cpp @@ -2,14 +2,15 @@ // Includes //---------------------------------------------------------------------- #include "MantidDataHandling/SaveCanSAS1D2.h" + #include "MantidAPI/FileProperty.h" -#include "MantidKernel/Exception.h" +#include "MantidAPI/Run.h" +#include "MantidAPI/WorkspaceUnitValidator.h" + #include "MantidGeometry/IComponent.h" -#include "MantidAPI/WorkspaceValidators.h" + +#include "MantidKernel/Exception.h" #include "MantidKernel/MantidVersion.h" -#include "MantidKernel/ListValidator.h" -#include "MantidAPI/Run.h" -#include <boost/shared_ptr.hpp> //----------------------------------------------------------------------------- using namespace Mantid::Kernel; diff --git a/Framework/DataHandling/src/SaveDiffCal.cpp b/Framework/DataHandling/src/SaveDiffCal.cpp index 66259ba0ad274d6856f16180cc48240a99e183ca..96c2cbe07747c32a9b817a67505126fa137752eb 100644 --- a/Framework/DataHandling/src/SaveDiffCal.cpp +++ b/Framework/DataHandling/src/SaveDiffCal.cpp @@ -30,7 +30,8 @@ DECLARE_ALGORITHM(SaveDiffCal) //---------------------------------------------------------------------------------------------- /** Constructor */ -SaveDiffCal::SaveDiffCal() {} +SaveDiffCal::SaveDiffCal() + : m_numValues(0), m_calibrationWS(), m_detidToIndex() {} //---------------------------------------------------------------------------------------------- /** Destructor diff --git a/Framework/DataHandling/src/SaveGSS.cpp b/Framework/DataHandling/src/SaveGSS.cpp index 460f326f800f6ccb0538b63aa49f9b59740bf633..af536d1977a0afa2330f7b899b36a42d6e2c2031 100644 --- a/Framework/DataHandling/src/SaveGSS.cpp +++ b/Framework/DataHandling/src/SaveGSS.cpp @@ -2,11 +2,14 @@ // Includes //--------------------------------------------------- #include "MantidDataHandling/SaveGSS.h" -#include "MantidAPI/FileProperty.h" -#include "MantidAPI/WorkspaceValidators.h" + #include "MantidAPI/AlgorithmHistory.h" +#include "MantidAPI/FileProperty.h" +#include "MantidAPI/WorkspaceUnitValidator.h" + #include "MantidKernel/TimeSeriesProperty.h" #include "MantidKernel/ListValidator.h" + #include <boost/math/special_functions/fpclassify.hpp> #include <Poco/File.h> #include <Poco/Path.h> @@ -410,6 +413,7 @@ void writeLogValue(std::ostream &os, const Run &runinfo, void SaveGSS::writeHeaders(const std::string &format, std::stringstream &os, double primaryflightpath) const { const Run &runinfo = inputWS->run(); + std::ios::fmtflags fflags(os.flags()); // Run number if (format.compare(SLOG) == 0) { @@ -483,6 +487,8 @@ void SaveGSS::writeHeaders(const std::string &format, std::stringstream &os, os << "\n"; } + os.flags(fflags); + return; } @@ -491,10 +497,12 @@ void SaveGSS::writeHeaders(const std::string &format, std::stringstream &os, */ inline void writeBankLine(std::stringstream &out, const std::string &bintype, const int banknum, const size_t datasize) { + std::ios::fmtflags fflags(out.flags()); out << "BANK " << std::fixed << std::setprecision(0) << banknum // First bank should be 1 for GSAS; this can be changed << std::fixed << " " << datasize << std::fixed << " " << datasize << std::fixed << " " << bintype; + out.flags(fflags); } //---------------------------------------------------------------------------------------------- diff --git a/Framework/DataHandling/src/SaveNISTDAT.cpp b/Framework/DataHandling/src/SaveNISTDAT.cpp index 0b32dc7d6dcf8e41fed88f6c0715e9cdc582aa21..8df313f51064c5a4d544940865572342e636778e 100644 --- a/Framework/DataHandling/src/SaveNISTDAT.cpp +++ b/Framework/DataHandling/src/SaveNISTDAT.cpp @@ -3,7 +3,10 @@ //---------------------------------------------------------------------- #include "MantidDataHandling/SaveNISTDAT.h" #include "MantidAPI/FileProperty.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" +#include "MantidKernel/CompositeValidator.h" + #include <fstream> // used to get ofstream namespace Mantid { diff --git a/Framework/DataHandling/src/SaveNXSPE.cpp b/Framework/DataHandling/src/SaveNXSPE.cpp index e07c856189d1a7392aed34a9b1ac945f6799dbb3..3d9a6397fdb37ff36251547c39e9e6d997b68d89 100644 --- a/Framework/DataHandling/src/SaveNXSPE.cpp +++ b/Framework/DataHandling/src/SaveNXSPE.cpp @@ -1,10 +1,15 @@ #include "MantidDataHandling/SaveNXSPE.h" #include "MantidAPI/FileProperty.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/CommonBinsValidator.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidAPI/WorkspaceOpOverloads.h" -#include "MantidGeometry/Instrument/Detector.h" + #include "MantidDataHandling/FindDetectorsPar.h" +#include "MantidGeometry/Instrument/Detector.h" + +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/MantidVersion.h" #include <boost/scoped_array.hpp> diff --git a/Framework/DataHandling/src/SaveNXTomo.cpp b/Framework/DataHandling/src/SaveNXTomo.cpp index fb1ae0d02f6d4c633699088fee09857121afb6de..efd42c3346d85889cac94edd6aaaf1ec4b2ec4db 100644 --- a/Framework/DataHandling/src/SaveNXTomo.cpp +++ b/Framework/DataHandling/src/SaveNXTomo.cpp @@ -1,8 +1,14 @@ +#include "MantidDataHandling/SaveNXTomo.h" + #include "MantidAPI/FileProperty.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/CommonBinsValidator.h" +#include "MantidAPI/HistogramValidator.h" + #include "MantidDataHandling/FindDetectorsPar.h" -#include "MantidDataHandling/SaveNXTomo.h" + #include "MantidGeometry/IComponent.h" + +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/MantidVersion.h" #include <nexus/NeXusException.hpp> diff --git a/Framework/DataHandling/src/SaveNexus.cpp b/Framework/DataHandling/src/SaveNexus.cpp index a65dac9a97dd1f00b7a695c49fad098da15badd1..06c047463739c04cc2c116afbc7a47d1b33cbc6c 100644 --- a/Framework/DataHandling/src/SaveNexus.cpp +++ b/Framework/DataHandling/src/SaveNexus.cpp @@ -147,7 +147,7 @@ void SaveNexus::runSaveNexusProcessed() { // If we're tracking history, add the entry before we save it to file if (trackingHistory()) { m_history->fillAlgorithmHistory( - this, Mantid::Kernel::DateAndTime::getCurrentTime(), -1, + this, Mantid::Kernel::DateAndTime::getCurrentTime(), 0, Algorithm::g_execCount); if (!isChild()) { m_inputWorkspace->history().addHistory(m_history); diff --git a/Framework/DataHandling/src/SaveNexusProcessed.cpp b/Framework/DataHandling/src/SaveNexusProcessed.cpp index 20c6890c5bf3ab6ce715c2295aab85b86d11eaaf..261eb8079c01e9f164beb9f53ca1e13ab22833b9 100644 --- a/Framework/DataHandling/src/SaveNexusProcessed.cpp +++ b/Framework/DataHandling/src/SaveNexusProcessed.cpp @@ -291,7 +291,7 @@ void SaveNexusProcessed::doExec(Workspace_sptr inputWorkspace, // Switch to the Cpp API for the algorithm history if (trackingHistory()) { m_history->fillAlgorithmHistory( - this, Mantid::Kernel::DateAndTime::getCurrentTime(), -1, + this, Mantid::Kernel::DateAndTime::getCurrentTime(), 0, Algorithm::g_execCount); if (!isChild()) { inputWorkspace->history().addHistory(m_history); diff --git a/Framework/DataHandling/src/SavePAR.cpp b/Framework/DataHandling/src/SavePAR.cpp index bf4ea3d2395a941f182cc0b72ebe719a69d24fa9..858d42a4487f7217908c3672e669a8c1a9e93f60 100644 --- a/Framework/DataHandling/src/SavePAR.cpp +++ b/Framework/DataHandling/src/SavePAR.cpp @@ -1,10 +1,13 @@ #include "MantidDataHandling/SavePAR.h" -#include "MantidDataHandling/FindDetectorsPar.h" + #include "MantidAPI/FileProperty.h" +#include "MantidAPI/InstrumentValidator.h" + +#include "MantidDataHandling/FindDetectorsPar.h" + #include "MantidGeometry/Instrument/Detector.h" #include "MantidGeometry/Instrument/ObjComponent.h" #include "MantidGeometry/Objects/Object.h" -#include "MantidAPI/WorkspaceValidators.h" #include <cstdio> #include <fstream> diff --git a/Framework/DataHandling/src/SavePHX.cpp b/Framework/DataHandling/src/SavePHX.cpp index 579ba691415232329674dca274aee32009a4a907..12564c28e1524eca7c709d1275ada6f2d1eaf001 100644 --- a/Framework/DataHandling/src/SavePHX.cpp +++ b/Framework/DataHandling/src/SavePHX.cpp @@ -1,10 +1,13 @@ #include "MantidDataHandling/SavePHX.h" -#include "MantidDataHandling/FindDetectorsPar.h" + #include "MantidAPI/FileProperty.h" +#include "MantidAPI/InstrumentValidator.h" + +#include "MantidDataHandling/FindDetectorsPar.h" + #include "MantidGeometry/Instrument/Detector.h" #include "MantidGeometry/Instrument/ObjComponent.h" #include "MantidGeometry/Objects/Object.h" -#include "MantidAPI/WorkspaceValidators.h" #include <cstdio> #include <fstream> diff --git a/Framework/DataHandling/src/SaveParameterFile.cpp b/Framework/DataHandling/src/SaveParameterFile.cpp index 931538cbb9488116d9dcb0211b5061077e7df773..226e00665a2f41a939e8c3fea80d86ef7cfec0d6 100644 --- a/Framework/DataHandling/src/SaveParameterFile.cpp +++ b/Framework/DataHandling/src/SaveParameterFile.cpp @@ -1,6 +1,8 @@ -#include "MantidAPI/FileProperty.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidDataHandling/SaveParameterFile.h" + +#include "MantidAPI/FileProperty.h" +#include "MantidAPI/InstrumentValidator.h" + #include "MantidGeometry/IComponent.h" #include "MantidGeometry/Instrument.h" #include "MantidGeometry/Instrument/ParameterMap.h" diff --git a/Framework/DataHandling/src/SaveSPE.cpp b/Framework/DataHandling/src/SaveSPE.cpp index f455a0c15d2db3d19efc421176c8a8e5f3cf2052..58902124d4daab9a15db5e4d357fd4a0e30eafc2 100644 --- a/Framework/DataHandling/src/SaveSPE.cpp +++ b/Framework/DataHandling/src/SaveSPE.cpp @@ -2,13 +2,17 @@ // Includes //--------------------------------------------------- #include "MantidDataHandling/SaveSPE.h" +#include "MantidAPI/CommonBinsValidator.h" #include "MantidAPI/FileProperty.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" #include "MantidAPI/WorkspaceOpOverloads.h" +#include "MantidKernel/CompositeValidator.h" + #include "Poco/File.h" +#include <boost/math/special_functions/fpclassify.hpp> + #include <cstdio> #include <cmath> -#include <boost/math/special_functions/fpclassify.hpp> #include <stdexcept> namespace Mantid { diff --git a/Framework/DataHandling/src/SetScalingPSD.cpp b/Framework/DataHandling/src/SetScalingPSD.cpp index c977d3fad5df2c23771be8425438380a21b86f9a..3affb36b8cb1625621dd640030ab6ac6697faf87 100644 --- a/Framework/DataHandling/src/SetScalingPSD.cpp +++ b/Framework/DataHandling/src/SetScalingPSD.cpp @@ -4,14 +4,14 @@ // Includes //---------------------------------------------------------------------- #include "MantidDataHandling/SetScalingPSD.h" +#include "MantidAPI/FileProperty.h" +#include "MantidGeometry/Instrument/ComponentHelper.h" #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/BoundedValidator.h" -#include "MantidGeometry/Instrument/ComponentHelper.h" -#include "MantidAPI/FileProperty.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "LoadRaw/isisraw.h" + #include <cmath> #include <fstream> -#include "LoadRaw/isisraw.h" namespace Mantid { namespace DataHandling { diff --git a/Framework/DataHandling/test/CheckMantidVersionTest.h b/Framework/DataHandling/test/CheckMantidVersionTest.h index d6c1e17a95dc93acdedd0d93979488ee0e964ce3..d7cf6155fca679d6c730a2f7b7f5e55354adddb4 100644 --- a/Framework/DataHandling/test/CheckMantidVersionTest.h +++ b/Framework/DataHandling/test/CheckMantidVersionTest.h @@ -77,7 +77,8 @@ private: "\"https://api.github.com/users/peterfpeterson/received_events\",\n" " \"type\": \"User\",\n" " \"site_admin\": false\n" - " }"; + " }\n" + "}"; return outputString; } diff --git a/Framework/DataObjects/inc/MantidDataObjects/CalculateReflectometryQxQz.h b/Framework/DataObjects/inc/MantidDataObjects/CalculateReflectometryQxQz.h index 2656b0085f6924d57618e626b151cacf0d9d1508..7256f47e3bbb7c5b3a8a1936b742f8c057749b9f 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/CalculateReflectometryQxQz.h +++ b/Framework/DataObjects/inc/MantidDataObjects/CalculateReflectometryQxQz.h @@ -22,7 +22,8 @@ public: /** Constructor */ - CalculateReflectometryQxQz() : m_dirQx(0.0), m_dirQz(0.0) {} + CalculateReflectometryQxQz() + : m_cos_theta_i(0.0), m_sin_theta_i(0.0), m_dirQx(0.0), m_dirQz(0.0) {} /** Setter for the incident theta value require for the calculation. Internally diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDGridBox.tcc b/Framework/DataObjects/inc/MantidDataObjects/MDGridBox.tcc index d03eb54542a77ee0bdd2b9cd5f04adcf3020215a..4de121711232aa6c6a24fd477c7118097ca62778 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDGridBox.tcc +++ b/Framework/DataObjects/inc/MantidDataObjects/MDGridBox.tcc @@ -40,10 +40,10 @@ namespace DataObjects { */ TMDE(MDGridBox)::MDGridBox( BoxController *const bc, const uint32_t depth, - const std::vector< - Mantid::Geometry::MDDimensionExtents<coord_t>> &extentsVector) - : MDBoxBase<MDE, nd>(bc, depth, UNDEF_SIZET, extentsVector), - numBoxes(0), m_Children(), diagonalSquared(0.f), nPoints(0) { + const std::vector<Mantid::Geometry::MDDimensionExtents<coord_t>> & + extentsVector) + : MDBoxBase<MDE, nd>(bc, depth, UNDEF_SIZET, extentsVector), numBoxes(0), + m_Children(), diagonalSquared(0.f), nPoints(0) { initGridBox(); } @@ -55,8 +55,8 @@ TMDE(MDGridBox)::MDGridBox( */ TMDE(MDGridBox)::MDGridBox( boost::shared_ptr<API::BoxController> &bc, const uint32_t depth, - const std::vector< - Mantid::Geometry::MDDimensionExtents<coord_t>> &extentsVector) + const std::vector<Mantid::Geometry::MDDimensionExtents<coord_t>> & + extentsVector) : MDBoxBase<MDE, nd>(bc.get(), depth, UNDEF_SIZET, extentsVector), numBoxes(0), m_Children(), diagonalSquared(0.f), nPoints(0) { initGridBox(); @@ -68,17 +68,16 @@ template <typename MDE, size_t nd> size_t MDGridBox<MDE, nd>::initGridBox() { "MDGridBox::ctor(): No BoxController specified in box."); // How many is it split? - // If we are at the top level and we have a specific top level split, then set it. - boost::optional<std::vector<size_t>> splitTopInto = this->m_BoxController->getSplitTopInto(); - if (this->getDepth() == 0 && splitTopInto) - { + // If we are at the top level and we have a specific top level split, then set + // it. + boost::optional<std::vector<size_t>> splitTopInto = + this->m_BoxController->getSplitTopInto(); + if (this->getDepth() == 0 && splitTopInto) { for (size_t d = 0; d < nd; d++) split[d] = splitTopInto.get()[d]; - } - else - { - for (size_t d = 0; d < nd; d++) - split[d] = this->m_BoxController->getSplitInto(d); + } else { + for (size_t d = 0; d < nd; d++) + split[d] = this->m_BoxController->getSplitInto(d); } // Compute sizes etc. @@ -94,10 +93,9 @@ template <typename MDE, size_t nd> size_t MDGridBox<MDE, nd>::initGridBox() { * @param box :: MDBox containing the events to split */ TMDE(MDGridBox)::MDGridBox(MDBox<MDE, nd> *box) - : MDBoxBase<MDE, nd>(*box, box->getBoxController()), split(), - splitCumul(), m_SubBoxSize(), numBoxes(0), m_Children(), - diagonalSquared(0.f), nPoints(0) -{ + : MDBoxBase<MDE, nd>(*box, box->getBoxController()), split(), splitCumul(), + m_SubBoxSize(), numBoxes(0), m_Children(), diagonalSquared(0.f), + nPoints(0) { size_t totalSize = initGridBox(); double ChildVol(1); @@ -188,10 +186,10 @@ void MDGridBox<MDE, nd>::fillBoxShell(const size_t tot, */ TMDE(MDGridBox)::MDGridBox(const MDGridBox<MDE, nd> &other, Mantid::API::BoxController *const otherBC) - : MDBoxBase<MDE, nd>(other, otherBC), numBoxes(other.numBoxes), m_Children(), - diagonalSquared(other.diagonalSquared), nPoints(other.nPoints) { - for (size_t d = 0; d < nd; d++) - { + : MDBoxBase<MDE, nd>(other, otherBC), numBoxes(other.numBoxes), + m_Children(), diagonalSquared(other.diagonalSquared), + nPoints(other.nPoints) { + for (size_t d = 0; d < nd; d++) { split[d] = other.split[d]; splitCumul[d] = other.splitCumul[d]; m_SubBoxSize[d] = other.m_SubBoxSize[d]; @@ -415,7 +413,7 @@ TMDE(std::vector<MDE> *MDGridBox)::getEventsCopy() { */ TMDE(void MDGridBox)::getBoxes(std::vector<API::IMDNode *> &outBoxes, size_t maxDepth, bool leafOnly) { - //Add this box, unless we only want the leaves + // Add this box, unless we only want the leaves if (!leafOnly) outBoxes.push_back(this); @@ -1465,8 +1463,9 @@ TMDE(void MDGridBox)::integrateCylinder( coord_t out[nd]; radiusTransform.apply(boxCenter, out); if (out[0] < std::sqrt(diagonalSquared * 0.72 + radius * radius) && - std::fabs(out[1]) < - std::sqrt(diagonalSquared * 0.72 + 0.25 * length * length)) { + (nd >= 1 && + std::fabs(out[1]) < + std::sqrt(diagonalSquared * 0.72 + 0.25 * length * length))) { // If the center is closer than the size of the box, then it MIGHT be // touching. // (We multiply by 0.72 (about sqrt(2)) to look for half the diagonal). diff --git a/Framework/DataObjects/src/EventList.cpp b/Framework/DataObjects/src/EventList.cpp index efb6e74c71354d9c2d6207883c39d49a6e1e95f2..8dfbd6d9421904169c2016b3f5f11279c626469a 100644 --- a/Framework/DataObjects/src/EventList.cpp +++ b/Framework/DataObjects/src/EventList.cpp @@ -548,6 +548,7 @@ EventList &EventList::operator-=(const EventList &more_events) { minusHelper(this->weightedEvents, more_events.weightedEventsNoTime); break; } + break; case WEIGHTED_NOTIME: switch (more_events.getEventType()) { @@ -561,6 +562,7 @@ EventList &EventList::operator-=(const EventList &more_events) { minusHelper(this->weightedEventsNoTime, more_events.weightedEventsNoTime); break; } + break; } // No guaranteed order diff --git a/Framework/DataObjects/src/MDHistoWorkspaceIterator.cpp b/Framework/DataObjects/src/MDHistoWorkspaceIterator.cpp index 9965a7d050731a517612282a0975edcaa791e746..87ad5e25ccdc9c2f2b6a49f9bee92cd90d46debd 100644 --- a/Framework/DataObjects/src/MDHistoWorkspaceIterator.cpp +++ b/Framework/DataObjects/src/MDHistoWorkspaceIterator.cpp @@ -199,8 +199,17 @@ void MDHistoWorkspaceIterator::init( for (size_t d = 0; d < m_nd; d++) m_center[d] = m_origin[d] + 0.5f * m_binWidth[d]; // Skip on if the first point is NOT contained - if (!m_function->isPointContained(m_center)) - next(); + if (!m_function->isPointContained(m_center)) { + bool didNext = next(); + if (!didNext && this->valid()) { + throw std::runtime_error( + "Inconsistency found initializing " + "MDHistoWorkspace iterator: this iterator should be valid, but " + "when tried to skip the " + "first point (not contained) could not iterate to " + "next point."); + } + } } // --- Calculate index permutations for neighbour finding face touching --- @@ -293,9 +302,11 @@ bool MDHistoWorkspaceIterator::valid() const { return (m_pos < m_max); } /// @return true if you can continue iterating bool MDHistoWorkspaceIterator::next() { if (m_function) { + bool allIncremented = false; do { m_pos++; - Utils::NestedForLoop::Increment(m_nd, m_index, m_indexMax); + allIncremented = + Utils::NestedForLoop::Increment(m_nd, m_index, m_indexMax); // Calculate the center for (size_t d = 0; d < m_nd; d++) { m_center[d] = @@ -304,7 +315,8 @@ bool MDHistoWorkspaceIterator::next() { } // std::cout<<std::endl; // Keep incrementing until you are in the implicit function - } while (!m_function->isPointContained(m_center) && m_pos < m_max); + } while (!allIncremented && !m_function->isPointContained(m_center) && + m_pos < m_max); } else { ++m_pos; } diff --git a/Framework/DataObjects/src/PeakColumn.cpp b/Framework/DataObjects/src/PeakColumn.cpp index b3d7e129cc927636043721605c3517a80c4892a8..7554f7f04ab8fa95178afe9f906f3cfffa88caf6 100644 --- a/Framework/DataObjects/src/PeakColumn.cpp +++ b/Framework/DataObjects/src/PeakColumn.cpp @@ -80,7 +80,13 @@ PeakColumn::PeakColumn(std::vector<Peak> &peaks, const std::string &name) this->m_name = name; this->m_type = typeFromName(name); // Throws if the name is unknown this->m_hklPrec = 2; - ConfigService::Instance().getValue("PeakColumn.hklPrec", this->m_hklPrec); + const std::string key = "PeakColumn.hklPrec"; + int gotit = ConfigService::Instance().getValue(key, this->m_hklPrec); + if (!gotit) + g_log.information() + << "In PeakColumn constructor, did not find any value for '" << key + << "' from the Config Service. Using default: " << this->m_hklPrec + << "\n"; } //---------------------------------------------------------------------------------------------- @@ -134,6 +140,7 @@ const std::type_info &PeakColumn::get_pointer_type_info() const { void PeakColumn::print(size_t index, std::ostream &s) const { Peak &peak = m_peaks[index]; + std::ios::fmtflags fflags(s.flags()); if (m_name == "RunNumber") s << peak.getRunNumber(); else if (m_name == "DetID") @@ -152,6 +159,7 @@ void PeakColumn::print(size_t index, std::ostream &s) const { s << std::fixed << std::setprecision(m_hklPrec) << peak.getL(); } else s << peak.getValueByColName(m_name); + s.flags(fflags); } //------------------------------------------------------------------------------------- diff --git a/Framework/DataObjects/test/WorkspaceValidatorsTest.h b/Framework/DataObjects/test/WorkspaceValidatorsTest.h index 4182d305bc8ce58a3053f687223432fd1afd6e71..90af5914fb69ce2ad7443690c3308f5b32f04595 100644 --- a/Framework/DataObjects/test/WorkspaceValidatorsTest.h +++ b/Framework/DataObjects/test/WorkspaceValidatorsTest.h @@ -2,7 +2,12 @@ #define WORKSPACEVALIDATORSTEST_H_ #include <cxxtest/TestSuite.h> -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/CommonBinsValidator.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/RawCountValidator.h" +#include "MantidAPI/SampleValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidAPI/WorkspaceProperty.h" #include "MantidKernel/Material.h" #include "MantidKernel/NeutronAtom.h" diff --git a/Framework/Geometry/CMakeLists.txt b/Framework/Geometry/CMakeLists.txt index ed3948fe974248bc96432c9dd109bf0af5f5395c..9ec241cd5176b287923763d9a86807c85ab503da 100644 --- a/Framework/Geometry/CMakeLists.txt +++ b/Framework/Geometry/CMakeLists.txt @@ -1,6 +1,7 @@ set ( SRC_FILES ${SRC_FILES} ${OPENCASCADE_SRC} src/ComponentParser.cpp + src/Crystal/BasicHKLFilters.cpp src/Crystal/BraggScatterer.cpp src/Crystal/BraggScattererFactory.cpp src/Crystal/BraggScattererInCrystalStructure.cpp @@ -10,6 +11,8 @@ set ( SRC_FILES src/Crystal/CrystalStructure.cpp src/Crystal/CyclicGroup.cpp src/Crystal/Group.cpp + src/Crystal/HKLFilter.cpp + src/Crystal/HKLGenerator.cpp src/Crystal/IPeak.cpp src/Crystal/IndexingUtils.cpp src/Crystal/IsotropicAtomBraggScatterer.cpp @@ -25,9 +28,12 @@ set ( SRC_FILES src/Crystal/ProductOfCyclicGroups.cpp src/Crystal/ReducedCell.cpp src/Crystal/ReflectionCondition.cpp + src/Crystal/ReflectionGenerator.cpp src/Crystal/ScalarUtils.cpp src/Crystal/SpaceGroup.cpp src/Crystal/SpaceGroupFactory.cpp + src/Crystal/StructureFactorCalculator.cpp + src/Crystal/StructureFactorCalculatorSummation.cpp src/Crystal/SymmetryElement.cpp src/Crystal/SymmetryElementFactory.cpp src/Crystal/SymmetryOperation.cpp @@ -130,6 +136,7 @@ set ( SRC_UNITY_IGNORE_FILES src/Instrument/CompAssembly.cpp set ( INC_FILES inc/MantidGeometry/ComponentParser.h + inc/MantidGeometry/Crystal/BasicHKLFilters.h inc/MantidGeometry/Crystal/BraggScatterer.h inc/MantidGeometry/Crystal/BraggScattererFactory.h inc/MantidGeometry/Crystal/BraggScattererInCrystalStructure.h @@ -140,6 +147,8 @@ set ( INC_FILES inc/MantidGeometry/Crystal/CrystalStructure.h inc/MantidGeometry/Crystal/CyclicGroup.h inc/MantidGeometry/Crystal/Group.h + inc/MantidGeometry/Crystal/HKLFilter.h + inc/MantidGeometry/Crystal/HKLGenerator.h inc/MantidGeometry/Crystal/IPeak.h inc/MantidGeometry/Crystal/IndexingUtils.h inc/MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h @@ -157,9 +166,12 @@ set ( INC_FILES inc/MantidGeometry/Crystal/ProductOfCyclicGroups.h inc/MantidGeometry/Crystal/ReducedCell.h inc/MantidGeometry/Crystal/ReflectionCondition.h + inc/MantidGeometry/Crystal/ReflectionGenerator.h inc/MantidGeometry/Crystal/ScalarUtils.h inc/MantidGeometry/Crystal/SpaceGroup.h inc/MantidGeometry/Crystal/SpaceGroupFactory.h + inc/MantidGeometry/Crystal/StructureFactorCalculator.h + inc/MantidGeometry/Crystal/StructureFactorCalculatorSummation.h inc/MantidGeometry/Crystal/SymmetryElement.h inc/MantidGeometry/Crystal/SymmetryElementFactory.h inc/MantidGeometry/Crystal/SymmetryOperation.h @@ -256,6 +268,7 @@ set ( INC_FILES set ( TEST_FILES AcompTest.h AlgebraTest.h + BasicHKLFiltersTest.h BnIdTest.h BoundingBoxTest.h BraggScattererFactoryTest.h @@ -282,6 +295,8 @@ set ( TEST_FILES GeneralTest.h GoniometerTest.h GroupTest.h + HKLFilterTest.h + HKLGeneratorTest.h HKLTest.h IDFObjectTest.h IMDDimensionFactoryTest.h @@ -337,6 +352,7 @@ set ( TEST_FILES ReducedCellTest.h ReferenceFrameTest.h ReflectionConditionTest.h + ReflectionGeneratorTest.h RotCounterTest.h RulesBoolValueTest.h RulesCompGrpTest.h @@ -350,6 +366,8 @@ set ( TEST_FILES SpaceGroupFactoryTest.h SpaceGroupTest.h SphereTest.h + StructureFactorCalculatorSummationTest.h + StructureFactorCalculatorTest.h SurfaceFactoryTest.h SurfaceTest.h SymmetryElementFactoryTest.h diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/BasicHKLFilters.h b/Framework/Geometry/inc/MantidGeometry/Crystal/BasicHKLFilters.h new file mode 100644 index 0000000000000000000000000000000000000000..8081a3ebe33d623b95637c87a4995dfab5e02f74 --- /dev/null +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/BasicHKLFilters.h @@ -0,0 +1,162 @@ +#ifndef MANTID_GEOMETRY_BASICHKLFILTERS_H_ +#define MANTID_GEOMETRY_BASICHKLFILTERS_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidGeometry/Crystal/HKLFilter.h" +#include "MantidGeometry/Crystal/ReflectionCondition.h" +#include "MantidGeometry/Crystal/StructureFactorCalculator.h" +#include "MantidGeometry/Crystal/SpaceGroup.h" +#include "MantidGeometry/Crystal/UnitCell.h" + +#include <strstream> + +namespace Mantid { +namespace Geometry { + +/** BasicHKLFilters + + This file contains some implementations of HKLFilter that + provide filtering based on things like d-value, space group + or centering. + + A common use would be to generate a specific list of HKLs, + for example all reflections that are allowed according to a certain + range of d-values and the reflection conditions of a space group: + + HKLFilter_const_sptr filter = + boost::make_shared<HKLFilterDRange>(unitCell, 0.5) + & boost::make_shared<HKLFilterSpaceGroup>(spaceGroup); + + HKLGenerator gen(unitCell, 0.5); + std::vector<V3D> hkls; + + std::remove_copy_if(gen.begin(), gen.end(), std::back_inserter(hkls), + (~filter)->fn()); + + An existing list of HKLs could be checked for indices that match the + reflection conditions of a space group: + + HKLFilter_const_sptr sgFilter = + boost::make_shared<HKLFilterSpaceGroup>(spaceGroup); + + auto matchingHKLCount = std::count_if(hkls.begin(), hkls.end(), + sgFilter->fn()); + + auto violatingHKLCount = std::count_if(hkls.begin(), hkls.end(), + (~sgFilter)->fn()); + + Combining HKLGenerator and different HKLFilters provides a very flexible + system for creating and processing specific sets of Miller indices that + is easy to expand by adding other HKLFilters. + + @author Michael Wedel, ESS + @date 23/09/2015 + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ + +/** + * A class to filter HKLs by their d-values + * + * This class takes a UnitCell object and calculates the spacing of + * the lattice planes for each HKL. If the lattice spacing is within + * the spcified range of values, the reflection is allowed. + * + * If the first constructor with only dMin is used, dMax is taken to + * be the lattice parameter with the largest value. There can not be + * a greater interplanar spacing than that value. + */ +class MANTID_GEOMETRY_DLL HKLFilterDRange : public HKLFilter { +public: + HKLFilterDRange(const UnitCell &cell, double dMin); + HKLFilterDRange(const UnitCell &cell, double dMin, double dMax); + + std::string getDescription() const; + bool isAllowed(const Kernel::V3D &hkl) const; + +private: + void checkProperDRangeValues(); + + UnitCell m_cell; + double m_dmin, m_dmax; +}; + +/** + * A class to filter HKLs according to a space group + * + * HKLFilterSpaceGroup stores a SpaceGroup object and marks those + * reflections as allowed that are allowed according to the + * reflection conditions of the space group. + */ +class MANTID_GEOMETRY_DLL HKLFilterSpaceGroup : public HKLFilter { +public: + HKLFilterSpaceGroup(const SpaceGroup_const_sptr &spaceGroup); + + std::string getDescription() const; + bool isAllowed(const Kernel::V3D &hkl) const; + +protected: + SpaceGroup_const_sptr m_spaceGroup; +}; + +/** + * A class to filter HKLs according to structure factor magnitudes + * + * This filter takes a StructureFactorCalculator and calculates the + * structure factor for each HKL. If F^2 is larger than the specified + * minimum, the reflection is considered allowed. The default minimum + * is 1e-6. + */ +class MANTID_GEOMETRY_DLL HKLFilterStructureFactor : public HKLFilter { +public: + HKLFilterStructureFactor(const StructureFactorCalculator_sptr &calculator, + double fSquaredMin = 1.0e-6); + + std::string getDescription() const; + bool isAllowed(const Kernel::V3D &hkl) const; + +protected: + StructureFactorCalculator_sptr m_calculator; + double m_fSquaredMin; +}; + +/** + * A class to filter HKLs according to a lattice centering + * + * HKLFilterCentering is a filter that stores a ReflectionCondition object + * internally and filters the HKLs according to that. + */ +class MANTID_GEOMETRY_DLL HKLFilterCentering : public HKLFilter { +public: + HKLFilterCentering(const ReflectionCondition_sptr ¢ering); + + std::string getDescription() const; + bool isAllowed(const Kernel::V3D &hkl) const; + +protected: + ReflectionCondition_sptr m_centering; +}; + +} // namespace Geometry +} // namespace Mantid + +#endif /* MANTID_GEOMETRY_BASICHKLFILTERS_H_ */ diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererFactory.h b/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererFactory.h index 1b98b0eacd299f18d22ffa93b35166fa0f4b1721..2203f878b2c33329bf6d66cc46e3b51b21196a55 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererFactory.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererFactory.h @@ -4,7 +4,9 @@ #include "MantidGeometry/DllConfig.h" #include "MantidKernel/DynamicFactory.h" #include "MantidKernel/SingletonHolder.h" + #include "MantidGeometry/Crystal/BraggScatterer.h" +#include "MantidGeometry/Crystal/CompositeBraggScatterer.h" namespace Mantid { namespace Geometry { @@ -67,7 +69,7 @@ class MANTID_GEOMETRY_DLL BraggScattererFactoryImpl : public Kernel::DynamicFactory<BraggScatterer> { public: BraggScatterer_sptr createScatterer(const std::string &name, - const std::string &properties = ""); + const std::string &properties = "") const; /// Subscribes a scatterer class into the factory. template <class C> void subscribeScatterer() { diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererInCrystalStructure.h b/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererInCrystalStructure.h index 9cbb27cd64be109ea50e3f12d2fe40bd887ffeb1..abd137481536e20b60610d266e22fc81be6f754a 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererInCrystalStructure.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererInCrystalStructure.h @@ -14,12 +14,10 @@ namespace Geometry { This class provides an extension of BraggScatterer, suitable for scatterers that are part of a crystal structure. Information about - the unit cell and space group can be set. The space group information - is used to calculate equivalent positions in the structure. + the unit cell can be set. - Both space group and unit cell are exposed marked as exposed to - BraggScattererComposite, so all members of one composite will - have the same unit cell and space group. + The unit cell is marked as exposed to BraggScattererComposite, so all + members of one composite will have the same unit cell. @author Michael Wedel, Paul Scherrer Institut - SINQ @date 04/11/2014 @@ -51,9 +49,7 @@ public: virtual ~BraggScattererInCrystalStructure() {} Kernel::V3D getPosition() const; - std::vector<Kernel::V3D> getEquivalentPositions() const; UnitCell getCell() const; - SpaceGroup_const_sptr getSpaceGroup() const; protected: virtual void afterPropertySet(const std::string &propertyName); @@ -68,18 +64,13 @@ protected: virtual void setPosition(const Kernel::V3D &position); virtual void setCell(const UnitCell &cell); - virtual void setSpaceGroup(const SpaceGroup_const_sptr &spaceGroup); virtual void declareProperties(); Kernel::V3D getPositionFromString(const std::string &positionString) const; - void recalculateEquivalentPositions(); Kernel::V3D m_position; - std::vector<Kernel::V3D> m_equivalentPositions; - UnitCell m_cell; - SpaceGroup_const_sptr m_spaceGroup; }; typedef boost::shared_ptr<BraggScattererInCrystalStructure> @@ -99,6 +90,9 @@ protected: virtual std::string checkValidity(const std::string &unitCellString) const; }; +MANTID_GEOMETRY_DLL std::vector<std::string> +getTokenizedPositionString(const std::string &position); + } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/CompositeBraggScatterer.h b/Framework/Geometry/inc/MantidGeometry/Crystal/CompositeBraggScatterer.h index d1e23c735bba3d934b2d65cc15068487c12c318b..58ced2a99a06a94d745b7f0419097c77530ebfde 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/CompositeBraggScatterer.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/CompositeBraggScatterer.h @@ -73,7 +73,8 @@ public: std::string name() const { return "CompositeBraggScatterer"; } BraggScatterer_sptr clone() const; - void addScatterer(const BraggScatterer_sptr &scatterer); + virtual void addScatterer(const BraggScatterer_sptr &scatterer); + void setScatterers(const std::vector<BraggScatterer_sptr> &scatterers); size_t nScatterers() const; BraggScatterer_sptr getScatterer(size_t i) const; void removeScatterer(size_t i); @@ -88,6 +89,9 @@ protected: const std::string &propertyName, const std::string &propertyValue); + void addScattererImplementation(const BraggScatterer_sptr &scatterer); + void removeScattererImplementation(size_t i); + void redeclareProperties(); std::map<std::string, size_t> getPropertyCountMap() const; diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/CrystalStructure.h b/Framework/Geometry/inc/MantidGeometry/Crystal/CrystalStructure.h index 24d279a0d68867f21a7aadccab7a3894963df011..96eeb35286bef35cdc4e57d9230f0de170a5c15f 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/CrystalStructure.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/CrystalStructure.h @@ -8,12 +8,16 @@ #include "MantidGeometry/Crystal/SpaceGroup.h" #include "MantidGeometry/Crystal/ReflectionCondition.h" #include "MantidGeometry/Crystal/CompositeBraggScatterer.h" +#include "MantidGeometry/Crystal/HKLFilter.h" #include <boost/make_shared.hpp> namespace Mantid { namespace Geometry { +// Forward declaration +class StructureFactorCalculator; + /** @class CrystalStructure @@ -28,90 +32,30 @@ namespace Geometry { them in order to provide some useful calculations that are common when working with crystal structures. - A common task is to calculate lattice plane spacings for a - given list of HKL-values. For this calculation, only the unit - cell has to be known: - - CrystalStructure structure(someUnitCell); - - std::vector<double> dValues = structure.getDValues(hklList); - - Where did 'hklList' come from? For this, CrystalStructure offers - a method as well. Provided a unit cell, it's possible to get all - HKLs within a given d range: - - CrystalStructure structure(someUnitCell); - std::vector<V3D> hklList = structure.getHKLs(0.5, 10.0); - - If the lattice is centered, not all combinations of h, k and l are - allowed. The first method to provide a centering is to use - one of the ReflectionCondition-classes directly: - - ReflectionCondition_sptr fCentering = - boost::make_shared<ReflectionConditionAllFaceCentred>(); - - structure.setCentering(fCentering); - - Now, only reflections that fulfill the centering condition are - returned by getHKLs. For powder diffraction it's not very - useful to get all reflections, because symmetrically equivalent - reflections can not be distinguished. Which reflections are - equivalent is determined by the point group. Again, one possibility - is to directly assign a point group: - - PointGroup_sptr pointGroup = - PointGroupFactory::Instance().createPointGroup("m-3m"); - - structure.setPointGroup(pointGroup); - - std::vector<V3D> uniqueHKLs = structure.getUniqueHKLs(0.5, 10.0); - - The list uniqueHKLs contains only symmetrically independent - reflections. Both point group and centering may be provided - to the constructor of CrystalStructure as well: - - CrystalStructure structure(someUnitCell, pointGroup, centering); - - According to the list given above, this is not a complete description - of a crystal structure - indeed, the information only describes - the crystal lattice. As demonstrated by the examples, this is already - enough information for knowing which reflections are present in - a given d-range for many cases. - - An example where more information is required can be found in a very - common crystal structure, the structure of Silicon. Silicon crystallizes - in the space group Fd-3m (No. 227) and the asymmetric unit consists of - one Si-atom at the position (1/8, 1/8, 1/8) (for origin choice 2, with the - inversion at the origin). Looking up this space group in the International - Tables for Crystallography A reveals that placing a scatterer at this - position introduces a new reflection condition for general reflections hkl: - - h = 2n + 1 (reflections with odd h are allowed) - or h + k + l = 4n + Besides construction from actual objects, a CrystalStructure object can be + constructed from three strings that contain the corresponding information. - This means that for example the reflection family {2 2 2} is not allowed, - even though the F-centering would allow it. In other words, guessing - existing reflections of silicon only using lattice information does not lead - to the correct result. Besides that, there are also glide planes in that - space group, which come with additional reflection conditions as well. + The unit cell string must consist of 3 or 6 floating point numbers, which + are 3 lenghts in Angström and 3 angles in degree. If the angles are not + supplied, they are assumed to be 90 degrees. - One way to obtain the correct result for this case is to calculate - structure factors for each HKL and check whether |F|^2 is non-zero. Of - course, to perform this calculation, all three items mentioned in the list - at the beginning must be present. CrystalStructure offers an additional - constructor for this purpose: + The space group string must be a valid space group that is registered into + the factory. Lastly, specification of the atoms in the asymmetric unit is + required. The format is as follows: - CrystalStructure silicon(unitcell, spaceGroup, scatterers); + Element x y z Occupancy U_iso; + Element x y z Occupancy U_iso; + ... - After constructing the object like this, it's no longer possible to set - point group and centering, because this is determined by the space group. - Now, a different method for checking allowed reflections is available: + Element has to be a valid NeutronAtom, x, y and z are fractional coordinates + between 0 and 1 (other coordinates will be transformed to that range). It is + allowed (and encouraged) to use proper fractions in the coordinates, for + example: - std::vector<V3D> uniqueHKLs = silicon.getUniqueHKLs(0.5, 10.0, - CrystalStructure::UseStructureFactors); + Mg 1/3 2/3 1/4 1.0 0.05; - By supplying the extra argument, |F|^2 is calculated for each reflection - and if it's greater than 1e-9, it's considered to be allowed. + Occupancy must be given as values between 0 and 1 and U_iso is the isotropic + thermal displacement parameter, given in Angrström^2. @author Michael Wedel, Paul Scherrer Institut - SINQ @date 05/08/2014 @@ -138,20 +82,18 @@ namespace Geometry { */ class DLLExport CrystalStructure { public: - enum ReflectionConditionMethod { UseCentering, UseStructureFactor }; - - CrystalStructure( - const UnitCell &unitCell, - const PointGroup_sptr &pointGroup = - PointGroupFactory::Instance().createPointGroup("-1"), - const ReflectionCondition_sptr ¢ering = - ReflectionCondition_sptr(new ReflectionConditionPrimitive)); - CrystalStructure(const UnitCell &unitCell, const SpaceGroup_const_sptr &spaceGroup, const CompositeBraggScatterer_sptr &scatterers); - virtual ~CrystalStructure() {} + CrystalStructure(const std::string &unitCellString, + const std::string &spaceGroupString, + const std::string &scattererString); + + CrystalStructure(const CrystalStructure &other); + CrystalStructure &operator=(const CrystalStructure &other); + + ~CrystalStructure() {} UnitCell cell() const; void setCell(const UnitCell &cell); @@ -159,55 +101,24 @@ public: SpaceGroup_const_sptr spaceGroup() const; void setSpaceGroup(const SpaceGroup_const_sptr &spaceGroup); - void setPointGroup(const PointGroup_sptr &pointGroup); - PointGroup_sptr pointGroup() const; - PointGroup::CrystalSystem crystalSystem() const; - - void setCentering(const ReflectionCondition_sptr ¢ering); - ReflectionCondition_sptr centering() const; + ReflectionCondition_sptr centering() const { return m_centering; } CompositeBraggScatterer_sptr getScatterers() const; void setScatterers(const CompositeBraggScatterer_sptr &scatterers); void addScatterers(const CompositeBraggScatterer_sptr &scatterers); - std::vector<Kernel::V3D> - getHKLs(double dMin, double dMax, - ReflectionConditionMethod method = UseCentering) const; - std::vector<Kernel::V3D> - getUniqueHKLs(double dMin, double dMax, - ReflectionConditionMethod method = UseCentering) const; - - std::vector<double> getDValues(const std::vector<Kernel::V3D> &hkls) const; - std::vector<double> getFSquared(const std::vector<Kernel::V3D> &hkls) const; - protected: - void setPointGroupFromSpaceGroup(const SpaceGroup_const_sptr &spaceGroup); + void assignUnitCellToScatterers(const UnitCell &unitCell); + void setReflectionConditionFromSpaceGroup(const SpaceGroup_const_sptr &spaceGroup); - void assignSpaceGroupToScatterers(const SpaceGroup_const_sptr &spaceGroup); - void assignUnitCellToScatterers(const UnitCell &unitCell); - void initializeScatterers(); - bool - isStateSufficientForHKLGeneration(ReflectionConditionMethod method) const; - bool isStateSufficientForUniqueHKLGeneration( - ReflectionConditionMethod method) const; - - void throwIfRangeUnacceptable(double dMin, double dMax) const; - - bool isAllowed(const Kernel::V3D &hkl, - ReflectionConditionMethod method) const; - - double getDValue(const Kernel::V3D &hkl) const; - double getFSquared(const Kernel::V3D &hkl) const; - UnitCell m_cell; SpaceGroup_const_sptr m_spaceGroup; - CompositeBraggScatterer_sptr m_scatterers; - PointGroup_sptr m_pointGroup; ReflectionCondition_sptr m_centering; + CompositeBraggScatterer_sptr m_scatterers; }; typedef boost::shared_ptr<CrystalStructure> CrystalStructure_sptr; diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/HKLFilter.h b/Framework/Geometry/inc/MantidGeometry/Crystal/HKLFilter.h new file mode 100644 index 0000000000000000000000000000000000000000..ca812aebdefeb7fdaa31219407f718d6becdfa2b --- /dev/null +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/HKLFilter.h @@ -0,0 +1,175 @@ +#ifndef MANTID_GEOMETRY_HKLFILTER_H_ +#define MANTID_GEOMETRY_HKLFILTER_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidKernel/V3D.h" + +#include <boost/shared_ptr.hpp> +#include <functional> + +namespace Mantid { +namespace Geometry { + +/** HKLFilter + + There are many ways to filter lists of Miller indices HKL. In order + to be able to use HKLGenerator with arbitrary filters, HKLFilter provides + a general interface for such filters. + + The abstract base class HKLFilter defines a pure virtual method + HKLFilter::isAllowed(), which takes a V3D as argument and returns a boolean. + Implementing classes can then implement this method, wrapping very different + concepts of checking HKLs for certain characteristics. + + There are two general ways of using HKLFilters. When used "standalone", + the isAllowed()-function can be used directly: + + if(filter->isAllowed(hkl)) { + // do something + } + + For interoperability with STL-algorithms, HKLFilter provides a method that + returns a function-object with the filter: + + std::copy_if(generator.begin(), generator.end(), + hkls.begin(), filter->fn()); + + Often, it's not enough to filter a list by one criterion. To this end, + there are two implementations of HKLFilter that provide binary logic + operations + "and" (HKLFilterAnd) and "or" (HKLFilterOr). They can be constructed from two + HKLFilter_const_sptrs, or, more conveniently, by using the operators & and | + directly with those types. This makes it possible to combine filters in many + ways: + + HKLFilter_const_sptr filter = (filter1 | filter2) & filter3; + + Lastly, the unary logic operation "not" (HKLFilterNot) is implemented. This is + important for usability with the pre-C++11 algorithm std::remove_copy_if that + works logically reversed compared to std::copy_if: + + std::remove_copy_if(generator.begin(), generator.end(), hkls.begin(), + (~filter)->fn()); + + For actual implementations of HKLFilter, check out BasicHKLFilters, where some + important filters are defined. + + @author Michael Wedel, ESS + @date 06/09/2015 + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class MANTID_GEOMETRY_DLL HKLFilter { +public: + virtual ~HKLFilter() {} + + std::function<bool(const Kernel::V3D &)> fn() const; + + virtual std::string getDescription() const = 0; + virtual bool isAllowed(const Kernel::V3D &hkl) const = 0; +}; + +typedef boost::shared_ptr<const HKLFilter> HKLFilter_const_sptr; + +/// Base class for unary logic operations for HKLFilter. +class MANTID_GEOMETRY_DLL HKLFilterUnaryLogicOperation : public HKLFilter { +public: + HKLFilterUnaryLogicOperation(const HKLFilter_const_sptr &filter); + ~HKLFilterUnaryLogicOperation() {} + + /// Returns the operand of the function. + const HKLFilter_const_sptr &getOperand() const { return m_operand; } + +protected: + HKLFilter_const_sptr m_operand; +}; + +/// Logical "Not"-operation for HKLFilter. +class MANTID_GEOMETRY_DLL HKLFilterNot : public HKLFilterUnaryLogicOperation { +public: + /// Constructor, calls base class constructor, throws exception if filter is a + /// null pointer. + HKLFilterNot(const HKLFilter_const_sptr &filter) + : HKLFilterUnaryLogicOperation(filter) {} + ~HKLFilterNot() {} + + std::string getDescription() const; + bool isAllowed(const Kernel::V3D &hkl) const; +}; + +/// Base class for binary logic operations for HKLFilter. +class MANTID_GEOMETRY_DLL HKLFilterBinaryLogicOperation : public HKLFilter { +public: + HKLFilterBinaryLogicOperation(const HKLFilter_const_sptr &lhs, + const HKLFilter_const_sptr &rhs); + virtual ~HKLFilterBinaryLogicOperation() {} + + /// Returns the left-hand side operand of the operation. + const HKLFilter_const_sptr &getLHS() const { return m_lhs; } + + /// Returns the right-hand side operand of the operation. + const HKLFilter_const_sptr &getRHS() const { return m_rhs; } + +protected: + HKLFilter_const_sptr m_lhs; + HKLFilter_const_sptr m_rhs; +}; + +/// Logical "And"-operation for HKLFilter. +class MANTID_GEOMETRY_DLL HKLFilterAnd : public HKLFilterBinaryLogicOperation { +public: + /// Constructor, calls base class constructor, throws exception if either of + /// the operands is null. + HKLFilterAnd(const HKLFilter_const_sptr &lhs, const HKLFilter_const_sptr &rhs) + : HKLFilterBinaryLogicOperation(lhs, rhs) {} + ~HKLFilterAnd() {} + + std::string getDescription() const; + bool isAllowed(const Kernel::V3D &hkl) const; +}; + +/// Logical "Or"-operation for HKLFilter. +class MANTID_GEOMETRY_DLL HKLFilterOr : public HKLFilterBinaryLogicOperation { +public: + /// Constructor, calls base class constructor, throws exception if either of + /// the operands is null. + HKLFilterOr(const HKLFilter_const_sptr &lhs, const HKLFilter_const_sptr &rhs) + : HKLFilterBinaryLogicOperation(lhs, rhs) {} + ~HKLFilterOr() {} + + std::string getDescription() const; + bool isAllowed(const Kernel::V3D &hkl) const; +}; + +MANTID_GEOMETRY_DLL const HKLFilter_const_sptr +operator~(const HKLFilter_const_sptr &filter); + +MANTID_GEOMETRY_DLL const HKLFilter_const_sptr +operator&(const HKLFilter_const_sptr &lhs, const HKLFilter_const_sptr &rhs); + +MANTID_GEOMETRY_DLL const HKLFilter_const_sptr +operator|(const HKLFilter_const_sptr &lhs, const HKLFilter_const_sptr &rhs); + +} // namespace Geometry +} // namespace Mantid + +#endif /* MANTID_GEOMETRY_HKLFILTER_H_ */ diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/HKLGenerator.h b/Framework/Geometry/inc/MantidGeometry/Crystal/HKLGenerator.h new file mode 100644 index 0000000000000000000000000000000000000000..bbfde3fc99b3695b9b254245c192691d762ce50c --- /dev/null +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/HKLGenerator.h @@ -0,0 +1,186 @@ +#ifndef MANTID_GEOMETRY_HKLGENERATOR_H_ +#define MANTID_GEOMETRY_HKLGENERATOR_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidGeometry/Crystal/UnitCell.h" +#include "MantidKernel/V3D.h" + +#include <boost/iterator/iterator_facade.hpp> + +namespace Mantid { +namespace Geometry { + +/** HKLGenerator + + HKLGenerator is a pseudo-container that helps in generating actual + containers with V3D-objects representing Miller indices (HKL). + + It's a common task to generate lists of Miller indices. The simplest + way of doing that is to simply create a nested loop structure that + goes through all combinations of H, K, L within some limits and then + put them into a container (vector, list, set, ...): + + for(int h = -hmin; h <= hmax; ++h) { + for(int k = -kmin; k <= kmax; ++k) { + for(int l = -lmin; l <= lmax; ++l) { + hkls.push_back(V3D(h, k, l)); + } + } + } + + In most cases the list is not used like that, instead it's filtered + using some criteria, for example a certain range of d-spacings or + others, so the reflection needs to be checked first: + + ... + hkl = V3D(h, k, l) + if(isOk(hkl)) { + hkls.push_back(hkl); + } + ... + + Instead of explicitly stating the triple-loop, HKLGenerator provides + a shorter way for this process using a const_iterator. The first code + example then becomes this: + + HKLGenerator generator(V3D(hmin, kmin, lmin), V3D(hmax, kmax, lmax)); + for(auto hkl = generator.begin(); hkl != generator.end(); ++hkl) { + hkls.push_back(*hkl); + } + + Or even shorter, using std::copy: + + HKLGenerator generator(V3D(hmin, kmin, lmin), V3D(hmax, kmax, lmax)); + std::copy(generator.begin(), generator.end(), std::back_inserter(hkls)); + + It's also possible to use filters this way, but in a much easier fashion, + using std::copy_remove_if (pre C++11) or std::copy_if (C++11): + + // pre C++11 + std::copy_remove_if(generator.begin(), generator.end(), + std::back_inserter(hkls), isNotOk) + + // C++11 + std::copy_if(generator.begin(), generator.end(), std::back_inserter(hkls), + isOk) + + See the documentation for HKLFilter for more details on how to perform + actual filtering. + + Please be aware that the iterator increments infinitely if it passes the + specified maximimum HKL. In that case K and L remain constant while H is + incremented (until it overflows). + + @author Michael Wedel, ESS + @date 23/09/2015 + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class MANTID_GEOMETRY_DLL HKLGenerator { +public: + /** + * @brief The const_iterator class + * + * This class uses boost::iterator_facade to provide a const_iterator + * interface to HKLGenerator. This makes it very easy to use the standard + * library algorithms. It's a forward iterator, so it's not possible to use + * operator[] for random access of specific HKLs (this would have to be + * done on the generated container if that supports it). + * + * While the iterators can be instantiated directly, the intention is to + * use HKLGenerator::begin() and HKLGenerator::end(). + */ + class MANTID_GEOMETRY_DLL const_iterator + : public boost::iterator_facade<const_iterator, const Kernel::V3D &, + boost::forward_traversal_tag> { + public: + const_iterator(); + + explicit const_iterator(const Kernel::V3D ¤t); + + explicit const_iterator(const Kernel::V3D &hklMin, + const Kernel::V3D &hklMax); + + private: + // Required for boost::iterator_facade to work + friend class boost::iterator_core_access; + + void increment(); + + /// Returns true if other is at the same position + inline bool equal(const const_iterator &other) const { + return this->m_h == other.m_h && this->m_k == other.m_k && + this->m_l == other.m_l; + } + + /// Returns a const reference to the currently pointed at HKL. + inline const Kernel::V3D &dereference() const { return m_hkl; } + + /// Required for compilation in VS. Forward iterator can not be used + /// that way, so the implementation does nothing. + inline void advance(difference_type) {} + inline void decrement() {} + + int m_h, m_k, m_l; + Kernel::V3D m_hkl; + + int m_hMin, m_hMax; + int m_kMin, m_kMax; + int m_lMin, m_lMax; + }; + + HKLGenerator(const Kernel::V3D &hklMin, const Kernel::V3D &hklMax); + HKLGenerator(const Kernel::V3D &hklMinMax); + HKLGenerator(int hMinMax, int kMinMax, int lMinMax); + HKLGenerator(const UnitCell &unitCell, double dMin); + + virtual ~HKLGenerator() {} + + /// Returns the number of HKLs to be generated. + inline size_t size() const { return m_size; } + + /// Returns an iterator to the beginning of the sequence. + inline const const_iterator &begin() const { return m_begin; } + + /// Returns an iterator which "points at" one element past the end. + inline const const_iterator &end() const { return m_end; } + +private: + size_t getSize(const Kernel::V3D &min, const Kernel::V3D &max) const; + + const_iterator getBeginIterator() const; + const_iterator getEndIterator() const; + Kernel::V3D getEndHKL() const; + + Kernel::V3D m_hklMin; + Kernel::V3D m_hklMax; + + size_t m_size; + + const_iterator m_begin; + const_iterator m_end; +}; + +} // namespace Geometry +} // namespace Mantid + +#endif /* MANTID_GEOMETRY_HKLGENERATOR_H_ */ diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h b/Framework/Geometry/inc/MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h index 0a243f40c6a964250adddfd185533c9bee325f4f..24dd9e30aa59263162745d0d4a7bd426855025c1 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h @@ -60,26 +60,11 @@ typedef boost::shared_ptr<IsotropicAtomBraggScatterer> (hence the class name), which may be insufficient depending on the crystal structure, but as a first approximation it is often enough. - This class is designed to handle atoms in a unit cell. When a position is - set, the internally stored space group is used to generate all positions - that are symmetrically equivalent. In the structure factor calculation - method all contributions are summed. + This class is designed to handle atoms in the asymmetric unit of the cell, + creation of symmetrically equivalent atoms in the entire unit cell has to + be handled elsewhere. - Easiest is demonstration by example. Copper crystallizes in the space group - \f$Fm\bar{3}m\f$, Cu atoms occupy the position (0,0,0) and, because - of the F-centering, also 3 additional positions. - - BraggScatterer_sptr cu = - BraggScattererFactory::Instance().createScatterer( - "IsotropicAtomBraggScatterer", - "Element=Cu; SpaceGroup=F m -3 m") - - cu->setProperty("UnitCell", unitCellToStr(cellCu)); - StructureFactor F = cu->calculateStructureFactor(V3D(1, 1, 1)); - - The structure factor F contains contributions from all 4 copper atoms in the - cell. This is convenient especially for general positions. - The general position of \f$Fm\bar{3}m\f$ for example has 192 equivalents. + One example where this is done can be found in CrystalStructure. [1] http://ww1.iucr.org/comm/cnom/adp/finrep/finrep.html @@ -139,6 +124,23 @@ protected: typedef boost::shared_ptr<IsotropicAtomBraggScatterer> IsotropicAtomBraggScatterer_sptr; +class MANTID_GEOMETRY_DLL IsotropicAtomBraggScattererParser { +public: + IsotropicAtomBraggScattererParser(const std::string &scattererString); + + std::vector<BraggScatterer_sptr> operator()() const; + +private: + BraggScatterer_sptr getScatterer(const std::string &singleScatterer) const; + std::vector<std::string> + getCleanScattererTokens(const std::vector<std::string> &tokens) const; + + std::string m_scattererString; +}; + +MANTID_GEOMETRY_DLL std::string +getIsotropicAtomBraggScattererString(const BraggScatterer_sptr &scatterer); + } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/ReflectionGenerator.h b/Framework/Geometry/inc/MantidGeometry/Crystal/ReflectionGenerator.h new file mode 100644 index 0000000000000000000000000000000000000000..439fcfa162daeee23ff22469fd2f258932b7ad74 --- /dev/null +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/ReflectionGenerator.h @@ -0,0 +1,144 @@ +#ifndef MANTID_GEOMETRY_REFLECTIONGENERATOR_H_ +#define MANTID_GEOMETRY_REFLECTIONGENERATOR_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidGeometry/Crystal/CrystalStructure.h" +#include "MantidGeometry/Crystal/StructureFactorCalculator.h" +#include "MantidGeometry/Crystal/HKLFilter.h" + +namespace Mantid { +namespace Geometry { + +enum struct ReflectionConditionFilter { + None, + Centering, + SpaceGroup, + StructureFactor +}; + +/** ReflectionGenerator + + ReflectionGenerator is a class that provides the means to perform some + common tasks involving generation of reflections. While the combination + of HKLGenerator and HKLFilter is very flexible, very often a limited set + of operations has to be performed repeatedly, involving the crystal + structure. + + ReflectionGenerator is constructed from a CrystalStructure object, which + is then stored internally. Additionally, a default filter for reflection + conditions can be set, which is applied for HKL-generation in addition + to a DRangeFilter. For more flexibility, a method is provided that accepts + an HKLFilter as additional argument, this filter is then added to the + DRangeFilter. + + This way it's very simple to obtain for example a list of unique reflections + for a given crystal structure: + + CrystalStructure structure("5.43 5.43 5.43", + "F d -3 m", "Si 0 0 0 1.0 0.05"); + ReflectionGenerator generator(structure); + + // Get all unique HKLs between 0.5 and 5.0 Angstrom + std::vector<V3D> hkls = generator.getUniqueHKLs(0.5, 5.0); + + Additionally there are methods to obtain structure factors and d-values + for a given list of HKLs. + + The generated reflection lists can be filtered by several criteria to remove + reflections that are not allowed. In the default case, the reflection + conditions of the space group are used. Alternatively, the reflections can be + filtered according to the centering of the lattice or, with some more + computational effort, by their structure factors. + + The default filter method can be supplied to the constructor in the form of + the enum ReflectionConditionFilter. Furthermore, it's possible to provide + self-defined filters in overloaded versions of the HKL generation methods. + These can also be generated by using a small helper method that creates + the filters and populates them with values associated to the stored crystal + structure: + + + ReflectionGenerator generator( + CrystalStructure("5.43 5.43 5.43", + "F d -3 m", "Si 0 0 0 1.0 0.05")); + auto filter = generator.getReflectionConditionFilter( + ReflectionConditionFilter::StructureFactor); + + The filter can then be used in connection with HKLGenerator or the HKL- + generation methods of ReflectionGenerator. + + An example where structure factors are required can be found in a very + common crystal structure, the structure of Silicon. Silicon crystallizes + in the space group Fd-3m (No. 227) and the asymmetric unit consists of + one Si-atom at the position (1/8, 1/8, 1/8) (for origin choice 2, with the + inversion at the origin). Looking up this space group in the International + Tables for Crystallography A reveals that placing a scatterer at this + position introduces a new reflection condition for general reflections hkl: + + h = 2n + 1 (reflections with odd h are allowed) + or h + k + l = 4n + + This means that for example the reflection family {2 2 2} is not allowed, + even though the F-centering would allow it. Using the structure factor + calculation filter solves this problem. + + @author Michael Wedel, ESS + @date 30/09/2015 + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class MANTID_GEOMETRY_DLL ReflectionGenerator { +public: + ReflectionGenerator(const CrystalStructure &crystalStructure, + ReflectionConditionFilter defaultFilter = + ReflectionConditionFilter::SpaceGroup); + ~ReflectionGenerator() {} + + const CrystalStructure &getCrystalStructure() const; + + HKLFilter_const_sptr getDRangeFilter(double dMin, double dMax) const; + HKLFilter_const_sptr + getReflectionConditionFilter(ReflectionConditionFilter filter); + + std::vector<Kernel::V3D> getHKLs(double dMin, double dMax) const; + std::vector<Kernel::V3D> + getHKLs(double dMin, double dMax, + HKLFilter_const_sptr reflectionConditionFilter) const; + + std::vector<Kernel::V3D> getUniqueHKLs(double dMin, double dMax) const; + std::vector<Kernel::V3D> + getUniqueHKLs(double dMin, double dMax, + HKLFilter_const_sptr reflectionConditionFilter) const; + + std::vector<double> getDValues(const std::vector<Kernel::V3D> &hkls) const; + std::vector<double> getFsSquared(const std::vector<Kernel::V3D> &hkls) const; + +private: + CrystalStructure m_crystalStructure; + StructureFactorCalculator_sptr m_sfCalculator; + HKLFilter_const_sptr m_defaultHKLFilter; +}; + +} // namespace Geometry +} // namespace Mantid + +#endif /* MANTID_GEOMETRY_REFLECTIONGENERATOR_H_ */ diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculator.h b/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculator.h new file mode 100644 index 0000000000000000000000000000000000000000..04b51ff0b49f016817b43884dd822c9c59e09041 --- /dev/null +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculator.h @@ -0,0 +1,82 @@ +#ifndef MANTID_GEOMETRY_STRUCTUREFACTORCALCULATOR_H_ +#define MANTID_GEOMETRY_STRUCTUREFACTORCALCULATOR_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidGeometry/Crystal/CrystalStructure.h" + +namespace Mantid { +namespace Geometry { + +/** StructureFactorCalculator + + This is a base class for concrete structure factor calculators. It is used + to logically separate this calculation from CrystalStructure so that different + methods of calculation can be used. For actual implementations please consult + the available sub-classes. + + @author Michael Wedel, ESS + @date 05/09/2015 + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class MANTID_GEOMETRY_DLL StructureFactorCalculator { +public: + StructureFactorCalculator(); + virtual ~StructureFactorCalculator() {} + + void setCrystalStructure(const CrystalStructure &crystalStructure); + + /// In implementations this method should return the structure factor for the + /// specified HKL. + virtual StructureFactor getF(const Kernel::V3D &hkl) const = 0; + virtual double getFSquared(const Kernel::V3D &hkl) const; + + virtual std::vector<StructureFactor> + getFs(const std::vector<Kernel::V3D> &hkls) const; + virtual std::vector<double> + getFsSquared(const std::vector<Kernel::V3D> &hkls) const; + +protected: + virtual void + crystalStructureSetHook(const CrystalStructure &crystalStructure); +}; + +typedef boost::shared_ptr<StructureFactorCalculator> + StructureFactorCalculator_sptr; + +namespace StructureFactorCalculatorFactory { +/// Small templated factory function that creates the desired calculator +/// and initializes it by setting the crystal structure. +template <typename T> +StructureFactorCalculator_sptr +create(const CrystalStructure &crystalStructure) { + boost::shared_ptr<T> calculator = boost::make_shared<T>(); + calculator->setCrystalStructure(crystalStructure); + + return calculator; +} +} + +} // namespace Geometry +} // namespace Mantid + +#endif /* MANTID_GEOMETRY_STRUCTUREFACTORCALCULATOR_H_ */ diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculatorSummation.h b/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculatorSummation.h new file mode 100644 index 0000000000000000000000000000000000000000..5cfed836be0c671fee66916460800dcfc735911f --- /dev/null +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculatorSummation.h @@ -0,0 +1,64 @@ +#ifndef MANTID_GEOMETRY_STRUCTUREFACTORCALCULATORSUMMATION_H_ +#define MANTID_GEOMETRY_STRUCTUREFACTORCALCULATORSUMMATION_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidGeometry/Crystal/StructureFactorCalculator.h" + +namespace Mantid { +namespace Geometry { + +/** StructureFactorCalculatorSummation + + This implementation of StructureFactorCalculator uses the summation method + provided by BraggScatterer and its sub-classes. It obtains all scatterers in + the unit cell by combining the space group and the scatterers located in the + asymmetric unit (both taken from CrystalStructure) and stores them. + + @author Michael Wedel, ESS + @date 05/09/2015 + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class MANTID_GEOMETRY_DLL StructureFactorCalculatorSummation + : public StructureFactorCalculator { +public: + StructureFactorCalculatorSummation(); + virtual ~StructureFactorCalculatorSummation() {} + + StructureFactor getF(const Kernel::V3D &hkl) const; + +protected: + void crystalStructureSetHook(const CrystalStructure &crystalStructure); + + void updateUnitCellScatterers(const CrystalStructure &crystalStructure); + std::string getV3DasString(const Kernel::V3D &point) const; + + CompositeBraggScatterer_sptr m_unitCellScatterers; +}; + +typedef boost::shared_ptr<StructureFactorCalculatorSummation> + StructureFactorSummation_sptr; + +} // namespace Geometry +} // namespace Mantid + +#endif /* MANTID_GEOMETRY_STRUCTUREFACTORCALCULATORSUMMATION_H_ */ diff --git a/Framework/Geometry/src/Crystal/BasicHKLFilters.cpp b/Framework/Geometry/src/Crystal/BasicHKLFilters.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9dfec3038a8b7d458404e4ea5490392e80bc2182 --- /dev/null +++ b/Framework/Geometry/src/Crystal/BasicHKLFilters.cpp @@ -0,0 +1,120 @@ +#include "MantidGeometry/Crystal/BasicHKLFilters.h" + +namespace Mantid { +namespace Geometry { + +/// Constructor, dMax is set to the largest lattice parameter. +HKLFilterDRange::HKLFilterDRange(const UnitCell &cell, double dMin) + : m_cell(cell), m_dmin(dMin) { + m_dmax = std::max(m_cell.a(), std::max(m_cell.b(), m_cell.c())); + + checkProperDRangeValues(); +} + +/// Constructor with explicit dMax. +HKLFilterDRange::HKLFilterDRange(const UnitCell &cell, double dMin, double dMax) + : m_cell(cell), m_dmin(dMin), m_dmax(dMax) { + checkProperDRangeValues(); +} + +/// Returns a description containing the parameters of the filter. +std::string HKLFilterDRange::getDescription() const { + std::ostringstream strm; + strm << "(" << m_dmin << " <= d <= " << m_dmax << ")"; + + return strm.str(); +} + +/// Returns true if the d-value of the HKL is within the specified range. +bool HKLFilterDRange::isAllowed(const Kernel::V3D &hkl) const { + double d = m_cell.d(hkl); + + return d >= m_dmin && d <= m_dmax; +} + +/// Throws exception if m_dMin or m_dMax is <= 0 or if m_dMax < m_dMin. +void HKLFilterDRange::checkProperDRangeValues() { + if (m_dmin <= 0.0) { + throw std::range_error("dMin cannot be <= 0."); + } + + if (m_dmax <= 0.0) { + throw std::range_error("dMax cannot be <= 0."); + } + + if (m_dmax <= m_dmin) { + throw std::range_error("dMax cannot be smaller than dMin."); + } +} + +/// Constructor, throws exception if the supplied pointer is invalid. +HKLFilterSpaceGroup::HKLFilterSpaceGroup( + const SpaceGroup_const_sptr &spaceGroup) + : m_spaceGroup(spaceGroup) { + if (!m_spaceGroup) { + throw std::runtime_error( + "Cannot construct HKLFilterSpaceGroup from null space group."); + } +} + +/// Returns a description of the filter that contains the space group symbol. +std::string HKLFilterSpaceGroup::getDescription() const { + std::ostringstream strm; + strm << "(Space group: " << m_spaceGroup->hmSymbol() << ")"; + + return strm.str(); +} + +/// Returns true if the reflection is allowed by the space group reflection +/// conditions. +bool HKLFilterSpaceGroup::isAllowed(const Kernel::V3D &hkl) const { + return m_spaceGroup->isAllowedReflection(hkl); +} + +/// Constructor, throws exception if the calculator pointer is invalid. +HKLFilterStructureFactor::HKLFilterStructureFactor( + const StructureFactorCalculator_sptr &calculator, double fSquaredMin) + : m_calculator(calculator), m_fSquaredMin(fSquaredMin) { + if (!m_calculator) { + throw std::runtime_error( + "Cannot construct HKLFilterStructureFactor from null calculator."); + } +} + +/// Returns a description for the filter that contains the minimum F^2. +std::string HKLFilterStructureFactor::getDescription() const { + std::ostringstream strm; + strm << "(F^2 > " << m_fSquaredMin << ")"; + + return strm.str(); +} + +/// Returns true if F^2(hkl) is larger than the stored minimum. +bool HKLFilterStructureFactor::isAllowed(const Kernel::V3D &hkl) const { + return m_calculator->getFSquared(hkl) > m_fSquaredMin; +} + +/// Constructor, throws exception if pointer is null. +HKLFilterCentering::HKLFilterCentering( + const ReflectionCondition_sptr ¢ering) + : m_centering(centering) { + if (!m_centering) { + throw std::runtime_error( + "Cannot construct HKLFilterCentering from null centering."); + } +} + +/// Returns a description with the centering symbol. +std::string HKLFilterCentering::getDescription() const { + return "(Centering: " + m_centering->getSymbol() + ")"; +} + +/// Returns true if the HKL is allowed according to the lattice centering. +bool HKLFilterCentering::isAllowed(const Kernel::V3D &hkl) const { + return m_centering->isAllowed(static_cast<int>(hkl.X()), + static_cast<int>(hkl.Y()), + static_cast<int>(hkl.Z())); +} + +} // namespace Geometry +} // namespace Mantid diff --git a/Framework/Geometry/src/Crystal/BraggScattererFactory.cpp b/Framework/Geometry/src/Crystal/BraggScattererFactory.cpp index 14a4e4bd97f51c4935e6c1e9c48066474d52abf4..d873b535249ea0df0c2c5e3b505f3c8a76fd587b 100644 --- a/Framework/Geometry/src/Crystal/BraggScattererFactory.cpp +++ b/Framework/Geometry/src/Crystal/BraggScattererFactory.cpp @@ -19,9 +19,8 @@ namespace Geometry { * @param properties :: Semi-colon separated "name=value"-pairs. * @return Initialized scatterer object. */ -BraggScatterer_sptr -BraggScattererFactoryImpl::createScatterer(const std::string &name, - const std::string &properties) { +BraggScatterer_sptr BraggScattererFactoryImpl::createScatterer( + const std::string &name, const std::string &properties) const { BraggScatterer_sptr scatterer = create(name); scatterer->initialize(); diff --git a/Framework/Geometry/src/Crystal/BraggScattererInCrystalStructure.cpp b/Framework/Geometry/src/Crystal/BraggScattererInCrystalStructure.cpp index a9046162022c4c0faaad4ff4010b0013275ffae8..7ae70b86507cf844dd2b9db530615ea3a21a4158 100644 --- a/Framework/Geometry/src/Crystal/BraggScattererInCrystalStructure.cpp +++ b/Framework/Geometry/src/Crystal/BraggScattererInCrystalStructure.cpp @@ -25,16 +25,13 @@ using namespace Kernel; /// Default constructor. BraggScattererInCrystalStructure::BraggScattererInCrystalStructure() - : BraggScatterer(), m_position(), m_cell(UnitCell(1, 1, 1, 90, 90, 90)), - m_spaceGroup() {} + : BraggScatterer(), m_position(), m_cell(UnitCell(1, 1, 1, 90, 90, 90)) {} /// Sets the position of the scatterer to the supplied coordinates - vector is -/// wrapped to [0, 1) and equivalent positions are recalculated. +/// wrapped to [0, 1). void BraggScattererInCrystalStructure::setPosition( const Kernel::V3D &position) { m_position = getWrappedVector(position); - - recalculateEquivalentPositions(); } /// Returns the position of the scatterer. @@ -42,44 +39,17 @@ Kernel::V3D BraggScattererInCrystalStructure::getPosition() const { return m_position; } -/// Returns all equivalent positions of the scatterer according to the assigned -/// space group. -std::vector<Kernel::V3D> -BraggScattererInCrystalStructure::getEquivalentPositions() const { - return m_equivalentPositions; -} - /// Returns the cell which is currently set. UnitCell BraggScattererInCrystalStructure::getCell() const { return m_cell; } -/// Returns the assigned space group. -SpaceGroup_const_sptr BraggScattererInCrystalStructure::getSpaceGroup() const { - return m_spaceGroup; -} - /// Assigns a unit cell, which may be required for certain calculations. void BraggScattererInCrystalStructure::setCell(const UnitCell &cell) { m_cell = cell; } -/// Sets the space group, which is required for calculation of equivalent -/// positions. -void BraggScattererInCrystalStructure::setSpaceGroup( - const SpaceGroup_const_sptr &spaceGroup) { - m_spaceGroup = spaceGroup; - - recalculateEquivalentPositions(); -} - /// Declares basic properties, should not be overridden by subclasses, use /// declareScattererProperties instead. void BraggScattererInCrystalStructure::declareProperties() { - /* This is required for default behavior. It's not possible to call it - * from the constructure, because it's not guaranteed that the space group - * factory has been filled at the time the ScattererFactory is filled. - */ - setSpaceGroup(SpaceGroupFactory::Instance().createSpaceGroup("P 1")); - declareProperty( new Kernel::PropertyWithValue<std::string>("Position", "[0, 0, 0]"), "Position of the scatterer"); @@ -92,32 +62,13 @@ void BraggScattererInCrystalStructure::declareProperties() { "Unit cell."); exposePropertyToComposite("UnitCell"); - IValidator_sptr spaceGroupValidator = - boost::make_shared<ListValidator<std::string>>( - SpaceGroupFactory::Instance().subscribedSpaceGroupSymbols()); - declareProperty(new Kernel::PropertyWithValue<std::string>( - "SpaceGroup", "P 1", spaceGroupValidator), - "Space group."); - exposePropertyToComposite("SpaceGroup"); - declareScattererProperties(); } V3D BraggScattererInCrystalStructure::getPositionFromString( const std::string &positionString) const { - std::string positionStringClean = positionString; - positionStringClean.erase(std::remove_if(positionStringClean.begin(), - positionStringClean.end(), - boost::is_any_of("[]")), - positionStringClean.end()); - - std::vector<std::string> numberParts; - boost::split(numberParts, positionStringClean, boost::is_any_of(",")); - - if (numberParts.size() != 3) { - throw std::invalid_argument("Cannot parse '" + positionString + - "' as a position."); - } + std::vector<std::string> numberParts = + getTokenizedPositionString(positionString); mu::Parser parser; @@ -133,8 +84,7 @@ V3D BraggScattererInCrystalStructure::getPositionFromString( /** * Additional property processing * - * Takes care of handling new property values, for example for construction of a - * space group from string and so on. + * Takes care of handling new property values. * * Please note that derived classes should not re-implement this method, as * the processing for the base properties is absolutely necessary. Instead, all @@ -147,9 +97,6 @@ void BraggScattererInCrystalStructure::afterPropertySet( std::string position = getProperty("Position"); setPosition(getPositionFromString(position)); - } else if (propertyName == "SpaceGroup") { - setSpaceGroup(SpaceGroupFactory::Instance().createSpaceGroup( - getProperty("SpaceGroup"))); } else if (propertyName == "UnitCell") { setCell(strToUnitCell(getProperty("UnitCell"))); } @@ -157,18 +104,6 @@ void BraggScattererInCrystalStructure::afterPropertySet( afterScattererPropertySet(propertyName); } -/// Uses the stored space group to calculate all equivalent positions or if -/// present. -void BraggScattererInCrystalStructure::recalculateEquivalentPositions() { - m_equivalentPositions.clear(); - - if (m_spaceGroup) { - m_equivalentPositions = m_spaceGroup->getEquivalentPositions(m_position); - } else { - m_equivalentPositions.push_back(m_position); - } -} - /// Return a clone of the validator. IValidator_sptr UnitCellStringValidator::clone() const { return boost::make_shared<UnitCellStringValidator>(*this); @@ -187,5 +122,25 @@ std::string UnitCellStringValidator::checkValidity( return ""; } +/// Returns components of comma-separated position string, cleaned from [ and ]. +std::vector<std::string> +getTokenizedPositionString(const std::string &position) { + std::string positionStringClean = position; + positionStringClean.erase(std::remove_if(positionStringClean.begin(), + positionStringClean.end(), + boost::is_any_of("[]")), + positionStringClean.end()); + + std::vector<std::string> numberParts; + boost::split(numberParts, positionStringClean, boost::is_any_of(",")); + + if (numberParts.size() != 3) { + throw std::invalid_argument("Cannot parse '" + position + + "' as a position."); + } + + return numberParts; +} + } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/src/Crystal/CompositeBraggScatterer.cpp b/Framework/Geometry/src/Crystal/CompositeBraggScatterer.cpp index d004bde9faa304e63834e65c2db28dcee6819568..7a58df47252a25f6fffaca657c66a6f8cc00c81d 100644 --- a/Framework/Geometry/src/Crystal/CompositeBraggScatterer.cpp +++ b/Framework/Geometry/src/Crystal/CompositeBraggScatterer.cpp @@ -27,9 +27,7 @@ CompositeBraggScatterer_sptr CompositeBraggScatterer::create( const std::vector<BraggScatterer_sptr> &scatterers) { CompositeBraggScatterer_sptr collection = CompositeBraggScatterer::create(); - for (auto it = scatterers.begin(); it != scatterers.end(); ++it) { - collection->addScatterer(*it); - } + collection->setScatterers(scatterers); return collection; } @@ -41,9 +39,7 @@ BraggScatterer_sptr CompositeBraggScatterer::clone() const { boost::make_shared<CompositeBraggScatterer>(); clone->initialize(); - for (auto it = m_scatterers.begin(); it != m_scatterers.end(); ++it) { - clone->addScatterer(*it); - } + clone->setScatterers(m_scatterers); clone->setProperties(this->asString(false, ';')); @@ -54,13 +50,18 @@ BraggScatterer_sptr CompositeBraggScatterer::clone() const { /// cell to the clone and adds it to the composite. void CompositeBraggScatterer::addScatterer( const BraggScatterer_sptr &scatterer) { - if (!scatterer) { - throw std::invalid_argument("Cannot process null-scatterer."); - } + addScattererImplementation(scatterer); + redeclareProperties(); +} - BraggScatterer_sptr localScatterer = scatterer->clone(); +/// Clears all scatterers and assigns clones of the supplied ones. +void CompositeBraggScatterer::setScatterers( + const std::vector<BraggScatterer_sptr> &scatterers) { + removeAllScatterers(); - m_scatterers.push_back(localScatterer); + for (auto it = scatterers.begin(); it != scatterers.end(); ++it) { + addScattererImplementation(*it); + } redeclareProperties(); } @@ -82,20 +83,27 @@ BraggScatterer_sptr CompositeBraggScatterer::getScatterer(size_t i) const { /// Removes the i-th scatterer from the composite or throws an std::out_of_range /// exception. void CompositeBraggScatterer::removeScatterer(size_t i) { + removeScattererImplementation(i); + + redeclareProperties(); +} + +/// This method performs the actual removal of the i-th scatterer. +void CompositeBraggScatterer::removeScattererImplementation(size_t i) { if (i >= nScatterers()) { throw std::out_of_range("Index is out of range."); } m_scatterers.erase(m_scatterers.begin() + i); - - redeclareProperties(); } /// Removes all scatterers. void CompositeBraggScatterer::removeAllScatterers() { while (nScatterers() > 0) { - removeScatterer(0); + removeScattererImplementation(0); } + + redeclareProperties(); } /// Calculates the structure factor for the given HKL by summing all @@ -139,6 +147,17 @@ void CompositeBraggScatterer::propagatePropertyToScatterer( } } +/// This method performs the actual cloning and adding of a new scatterer. +void CompositeBraggScatterer::addScattererImplementation( + const BraggScatterer_sptr &scatterer) { + if (!scatterer) { + throw std::invalid_argument("Cannot process null-scatterer."); + } + + BraggScatterer_sptr localScatterer = scatterer->clone(); + m_scatterers.push_back(localScatterer); +} + /** * Synchronize properties with scatterer members * diff --git a/Framework/Geometry/src/Crystal/CrystalStructure.cpp b/Framework/Geometry/src/Crystal/CrystalStructure.cpp index 05963caaae393496b769669cf8c8c3bc5eeec581..d40ffe8bf0a99e95b075b1b3a8b04658be403e31 100644 --- a/Framework/Geometry/src/Crystal/CrystalStructure.cpp +++ b/Framework/Geometry/src/Crystal/CrystalStructure.cpp @@ -1,26 +1,23 @@ #include "MantidGeometry/Crystal/CrystalStructure.h" #include <boost/bind.hpp> #include <stdexcept> +#include <algorithm> +#include "MantidGeometry/Crystal/BasicHKLFilters.h" +#include "MantidGeometry/Crystal/HKLGenerator.h" #include "MantidGeometry/Crystal/SpaceGroupFactory.h" #include "MantidGeometry/Crystal/PointGroupFactory.h" +#include "MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h" +#include "MantidGeometry/Crystal/StructureFactorCalculatorSummation.h" + +#include <iostream> +#include <iomanip> namespace Mantid { namespace Geometry { using namespace Mantid::Kernel; -/// PointGroup/Centering based constructor -CrystalStructure::CrystalStructure(const UnitCell &unitCell, - const PointGroup_sptr &pointGroup, - const ReflectionCondition_sptr ¢ering) { - initializeScatterers(); - - setCell(unitCell); - setPointGroup(pointGroup); - setCentering(centering); -} - /// SpaceGroup/Scatterers constructor CrystalStructure::CrystalStructure( const UnitCell &unitCell, const SpaceGroup_const_sptr &spaceGroup, @@ -32,6 +29,38 @@ CrystalStructure::CrystalStructure( setSpaceGroup(spaceGroup); } +/// String-based constructor +CrystalStructure::CrystalStructure(const std::string &unitCellString, + const std::string &spaceGroupString, + const std::string &scattererString) { + initializeScatterers(); + + addScatterers(CompositeBraggScatterer::create( + IsotropicAtomBraggScattererParser(scattererString)())); + setCell(strToUnitCell(unitCellString)); + setSpaceGroup( + SpaceGroupFactory::Instance().createSpaceGroup(spaceGroupString)); +} + +/// Copy constructor +CrystalStructure::CrystalStructure(const CrystalStructure &other) { + initializeScatterers(); + setScatterers(other.getScatterers()); + setCell(other.cell()); + setSpaceGroup(other.spaceGroup()); +} + +/// Assignment operator +CrystalStructure &CrystalStructure::operator=(const CrystalStructure &other) { + if (&other != this) { + setScatterers(other.getScatterers()); + setCell(other.cell()); + setSpaceGroup(other.spaceGroup()); + } + + return *this; +} + /// Returns the unit cell of the structure UnitCell CrystalStructure::cell() const { return m_cell; } @@ -50,62 +79,12 @@ SpaceGroup_const_sptr CrystalStructure::spaceGroup() const { /** * Assigns a new space group to the crystal structure * - * Setting a new space group on a crystal structure causes several effects: - * - The space group is propagated to the scatterers - * - A new point group is assigned - * - A change in point group can also mean change in crystal system - * - A new reflection condition object is assigned - * After this operation, the crystal structure object may be in a state - * where it does not have a valid point group or centering. - * * @param spaceGroup :: New space group of the crystal structure */ void CrystalStructure::setSpaceGroup(const SpaceGroup_const_sptr &spaceGroup) { m_spaceGroup = spaceGroup; - setPointGroupFromSpaceGroup(m_spaceGroup); setReflectionConditionFromSpaceGroup(m_spaceGroup); - assignSpaceGroupToScatterers(m_spaceGroup); -} - -/// Assigns the point group or throws std::runtime_error if the space group has -/// been set before. -void CrystalStructure::setPointGroup(const PointGroup_sptr &pointGroup) { - if (m_spaceGroup) { - throw std::runtime_error( - "Cannot set point group if a space group has been set."); - } - - m_pointGroup = pointGroup; -} - -/// Returns the structure's point group -PointGroup_sptr CrystalStructure::pointGroup() const { return m_pointGroup; } - -/// Convenience method to get the PointGroup's crystal system -PointGroup::CrystalSystem CrystalStructure::crystalSystem() const { - if (!m_pointGroup) { - throw std::invalid_argument( - "Cannot determine crystal system from null-PointGroup."); - } - - return m_pointGroup->crystalSystem(); -} - -/// Sets the centering or throws std::runtime_error if a space group has been -/// assigned to the crystal structure -void CrystalStructure::setCentering(const ReflectionCondition_sptr ¢ering) { - if (m_spaceGroup) { - throw std::runtime_error( - "Cannot set centering if a space group has been set."); - } - - m_centering = centering; -} - -/// Returns the centering of the structure -ReflectionCondition_sptr CrystalStructure::centering() const { - return m_centering; } /// Return a clone of the internal CompositeBraggScatterer instance. @@ -134,125 +113,6 @@ void CrystalStructure::addScatterers( } assignUnitCellToScatterers(m_cell); - assignSpaceGroupToScatterers(m_spaceGroup); -} - -/// Returns a vector with all allowed HKLs in the given d-range -std::vector<Kernel::V3D> -CrystalStructure::getHKLs(double dMin, double dMax, - ReflectionConditionMethod method) const { - if (!isStateSufficientForHKLGeneration(method)) { - throw std::invalid_argument("Insufficient data for creation of a " - "reflection list, need at least centering and " - "unit cell."); - } - - throwIfRangeUnacceptable(dMin, dMax); - - std::vector<V3D> hkls; - - /* There's an estimation for the number of reflections from the unit cell - * volume - * and the minimum d-value. This should speed up insertion into the vector. - */ - size_t estimatedReflectionCount = static_cast<size_t>( - ceil(32.0 * M_PI * m_cell.volume()) / (3.0 * pow(2.0 * dMin, 3.0))); - hkls.reserve(estimatedReflectionCount); - - int hMax = static_cast<int>(m_cell.a() / dMin); - int kMax = static_cast<int>(m_cell.b() / dMin); - int lMax = static_cast<int>(m_cell.c() / dMin); - - for (int h = -hMax; h <= hMax; ++h) { - for (int k = -kMax; k <= kMax; ++k) { - for (int l = -lMax; l <= lMax; ++l) { - V3D hkl(h, k, l); - double d = getDValue(hkl); - - if (d <= dMax && d >= dMin && isAllowed(hkl, method)) { - hkls.push_back(hkl); - } - } - } - } - - return hkls; -} - -/// Returns a vector with all allowed symmetry independent HKLs (depends on -/// point group) in the given d-range -std::vector<Kernel::V3D> -CrystalStructure::getUniqueHKLs(double dMin, double dMax, - ReflectionConditionMethod method) const { - if (!isStateSufficientForUniqueHKLGeneration(method)) { - throw std::invalid_argument("Insufficient data for creation of a " - "reflection list, need at least centering, " - "unit cell and point group."); - } - - throwIfRangeUnacceptable(dMin, dMax); - - std::set<V3D> uniqueHKLs; - - int hMax = static_cast<int>(m_cell.a() / dMin); - int kMax = static_cast<int>(m_cell.b() / dMin); - int lMax = static_cast<int>(m_cell.c() / dMin); - - for (int h = -hMax; h <= hMax; ++h) { - for (int k = -kMax; k <= kMax; ++k) { - for (int l = -lMax; l <= lMax; ++l) { - V3D hkl(h, k, l); - double d = getDValue(hkl); - - if (d <= dMax && d >= dMin && isAllowed(hkl, method)) { - uniqueHKLs.insert(m_pointGroup->getReflectionFamily(hkl)); - } - } - } - } - - return std::vector<V3D>(uniqueHKLs.begin(), uniqueHKLs.end()); -} - -/// Maps a vector of hkls to d-values using the internal cell -std::vector<double> -CrystalStructure::getDValues(const std::vector<V3D> &hkls) const { - - std::vector<double> dValues(hkls.size()); - std::transform(hkls.begin(), hkls.end(), dValues.begin(), - boost::bind(&CrystalStructure::getDValue, this, _1)); - - return dValues; -} - -/// Returns |F(hkl)|^2 for all supplied hkls. -std::vector<double> -CrystalStructure::getFSquared(const std::vector<V3D> &hkls) const { - std::vector<double> fSquared; - fSquared.reserve(hkls.size()); - - for (auto hkl = hkls.begin(); hkl != hkls.end(); ++hkl) { - fSquared.push_back(getFSquared(*hkl)); - } - - return fSquared; -} - -/// Tries to set the point group from the space group symbol or removes the -/// current point group if creation fails. -void CrystalStructure::setPointGroupFromSpaceGroup( - const SpaceGroup_const_sptr &spaceGroup) { - m_pointGroup.reset(); - - if (spaceGroup) { - try { - m_pointGroup = - PointGroupFactory::Instance().createPointGroupFromSpaceGroup( - spaceGroup); - } catch (...) { - // do nothing - point group will be null - } - } } /// Tries to set the centering from the space group symbol or removes the @@ -279,19 +139,6 @@ void CrystalStructure::setReflectionConditionFromSpaceGroup( } } -/// Assigns the space group to all scatterers -void CrystalStructure::assignSpaceGroupToScatterers( - const SpaceGroup_const_sptr &spaceGroup) { - if (!m_scatterers) { - throw std::runtime_error( - "Scatterer collection is a null pointer. Aborting."); - } - - if (m_spaceGroup && m_scatterers->existsProperty("SpaceGroup")) { - m_scatterers->setProperty("SpaceGroup", spaceGroup->hmSymbol()); - } -} - /// Assigns the cell to all scatterers void CrystalStructure::assignUnitCellToScatterers(const UnitCell &unitCell) { if (!m_scatterers) { @@ -311,58 +158,5 @@ void CrystalStructure::initializeScatterers() { } } -/// Check that the internal state is sufficient for generating a list of HKLs -bool CrystalStructure::isStateSufficientForHKLGeneration( - CrystalStructure::ReflectionConditionMethod method) const { - switch (method) { - case UseStructureFactor: - return m_scatterers->nScatterers() > 0; - default: - return static_cast<bool>(m_centering); - } -} - -/// Check that the internal state is sufficient for generating a list of -/// symmetry independent HKLs -bool CrystalStructure::isStateSufficientForUniqueHKLGeneration( - CrystalStructure::ReflectionConditionMethod method) const { - return isStateSufficientForHKLGeneration(method) && m_pointGroup; -} - -/// Throws std::invalid_argument if dMin <= 0 or dMax >= dMin -void CrystalStructure::throwIfRangeUnacceptable(double dMin, - double dMax) const { - if (dMin <= 0.0) { - throw std::invalid_argument("dMin is <= 0.0, not a valid spacing."); - } - - if (dMax <= dMin) { - throw std::invalid_argument("dMax must be larger than dMin."); - } -} - -/// Checks whether a reflection is allowed, using the specified method -bool CrystalStructure::isAllowed( - const V3D &hkl, CrystalStructure::ReflectionConditionMethod method) const { - switch (method) { - case UseStructureFactor: - return getFSquared(hkl) > 1e-9; - default: - return m_centering->isAllowed(static_cast<int>(hkl.X()), - static_cast<int>(hkl.Y()), - static_cast<int>(hkl.Z())); - } -} - -/// Returns the lattice plane spacing for the given HKL. -double CrystalStructure::getDValue(const V3D &hkl) const { - return m_cell.d(hkl); -} - -/// Returns |F|^2 for the given HKL. -double CrystalStructure::getFSquared(const V3D &hkl) const { - return m_scatterers->calculateFSquared(hkl); -} - } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/src/Crystal/HKLFilter.cpp b/Framework/Geometry/src/Crystal/HKLFilter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ed218cb7fdb2f3fce2bdeaa204efc113e8479009 --- /dev/null +++ b/Framework/Geometry/src/Crystal/HKLFilter.cpp @@ -0,0 +1,117 @@ +#include "MantidGeometry/Crystal/HKLFilter.h" +#include <boost/make_shared.hpp> +#include <stdexcept> + +namespace Mantid { +namespace Geometry { + +/** + * Returns a function object that wraps HKLFilter::isAllowed + * + * This method uses std::bind to create a function object that + * represents the HKLFilter::isAllowed() method. This way it's + * possible to pass the function to STL-algorithms easily (see + * class documentation). + * + * @return Function object with filter function for V3D.s + */ +std::function<bool(const Kernel::V3D &)> HKLFilter::fn() const { + return std::bind(&HKLFilter::isAllowed, this, std::placeholders::_1); +} + +/// Stores the supplied filter, throws exception if filter is null. +HKLFilterUnaryLogicOperation::HKLFilterUnaryLogicOperation( + const HKLFilter_const_sptr &filter) + : m_operand(filter) { + if (!m_operand) { + throw std::runtime_error( + "Cannot create HKLFilterUnaryLogicOperation from null operand."); + } +} + +/// Returns a description of the HKLFilterNot. +std::string HKLFilterNot::getDescription() const { + return "!" + m_operand->getDescription(); +} + +/// Returns true if the wrapped filter returns false and false otherwise. +bool HKLFilterNot::isAllowed(const Kernel::V3D &hkl) const { + return !(m_operand->isAllowed(hkl)); +} + +/// Stores the left-hand and right-hand side operators, throws exception if +/// either is null. +HKLFilterBinaryLogicOperation::HKLFilterBinaryLogicOperation( + const HKLFilter_const_sptr &lhs, const HKLFilter_const_sptr &rhs) + : m_lhs(lhs), m_rhs(rhs) { + if (!m_lhs || !m_rhs) { + throw std::runtime_error("Cannot construct HKLFilterBinaryLogicOperation " + "with one or more null-operands."); + } +} + +/// Returns a description of the HKLFilterAnd. +std::string HKLFilterAnd::getDescription() const { + return "(" + m_lhs->getDescription() + " & " + m_rhs->getDescription() + ")"; +} + +/// Returns true if both wrapped filters return true. +bool HKLFilterAnd::isAllowed(const Kernel::V3D &hkl) const { + return m_lhs->isAllowed(hkl) && m_rhs->isAllowed(hkl); +} + +/// Returns a description of the HKLFilterOr. +std::string HKLFilterOr::getDescription() const { + return "(" + m_lhs->getDescription() + " | " + m_rhs->getDescription() + ")"; +} + +/// Returns true if either of the wrapped filters returns true. +bool HKLFilterOr::isAllowed(const Kernel::V3D &hkl) const { + return m_lhs->isAllowed(hkl) || m_rhs->isAllowed(hkl); +} + +/** + * Constructs an HKLFilterNot from the operand + * + * This function makes it easy to construct HKLFilterNot by using the + * operator ~, which inverts the wrapped filter. + * + * @param filter :: HKLFilter to invert. + * @return HKLFilterNot with the wrapped filter. + */ +const HKLFilter_const_sptr operator~(const HKLFilter_const_sptr &filter) { + return boost::make_shared<const HKLFilterNot>(filter); +} + +/** + * Constructs an HKLFilterAnd from the operands + * + * This function makes it easy to construct HKLFilterAnd by using the + * operator & directly on HKLFilter_const_sptr. + * + * @param lhs :: Left-hand side HKLFilter operand. + * @param rhs :: Right-hand side HKLFilter operand. + * @return HKLFilterAnd with two wrapped filters. + */ +const HKLFilter_const_sptr operator&(const HKLFilter_const_sptr &lhs, + const HKLFilter_const_sptr &rhs) { + return boost::make_shared<const HKLFilterAnd>(lhs, rhs); +} + +/** + * Constructs an HKLFilterOr from the operands + * + * This function makes it easy to construct HKLFilterOr by using the + * operator | directly on HKLFilter_const_sptr. + * + * @param lhs :: Left-hand side HKLFilter operand. + * @param rhs :: Right-hand side HKLFilter operand. + * @return HKLFilterOr with two wrapped filters. + */ +const HKLFilter_const_sptr operator|(const HKLFilter_const_sptr &lhs, + const HKLFilter_const_sptr &rhs) { + return boost::make_shared<HKLFilterOr>(lhs, rhs); +} + +} // namespace Geometry +} // namespace Mantid diff --git a/Framework/Geometry/src/Crystal/HKLGenerator.cpp b/Framework/Geometry/src/Crystal/HKLGenerator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..05a153674c612074fa06a4dd936f6285092284da --- /dev/null +++ b/Framework/Geometry/src/Crystal/HKLGenerator.cpp @@ -0,0 +1,101 @@ +#include "MantidGeometry/Crystal/HKLGenerator.h" + +namespace Mantid { +namespace Geometry { + +using namespace Kernel; + +/// Constructs a generator that creates all indices from hklMin to hklMax. +HKLGenerator::HKLGenerator(const Kernel::V3D &hklMin, const Kernel::V3D &hklMax) + : m_hklMin(hklMin), m_hklMax(hklMax), m_size(getSize(m_hklMin, m_hklMax)), + m_begin(getBeginIterator()), m_end(getEndIterator()) {} + +/// Constructs a generator that creates all indices from -hklMinMax to +/// hklMinMax. +HKLGenerator::HKLGenerator(const Kernel::V3D &hklMinMax) + : m_hklMin(hklMinMax * -1), m_hklMax(hklMinMax), + m_size(getSize(m_hklMin, m_hklMax)), m_begin(getBeginIterator()), + m_end(getEndIterator()) {} + +/// Constructs a generator that creates all indices from -h,-k,-l to h,k,l. +HKLGenerator::HKLGenerator(int hMinMax, int kMinMax, int lMinMax) { + m_hklMax = V3D(hMinMax, kMinMax, lMinMax); + m_hklMin = m_hklMax * -1; + m_size = getSize(m_hklMin, m_hklMax); + + m_begin = getBeginIterator(); + m_end = getEndIterator(); +} + +/// Constructs a generator that creates all indices for the given cell up to +/// dMin. +HKLGenerator::HKLGenerator(const UnitCell &unitCell, double dMin) { + m_hklMax = V3D(unitCell.a() / dMin, unitCell.b() / dMin, unitCell.c() / dMin); + m_hklMin = m_hklMax * -1; + m_size = getSize(m_hklMin, m_hklMax); + + m_begin = getBeginIterator(); + m_end = getEndIterator(); +} + +/// Returns the number of indices between min and max. +size_t HKLGenerator::getSize(const V3D &min, const V3D &max) const { + V3D diff = (max - min) + V3D(1, 1, 1); + return static_cast<size_t>(diff.X() * diff.Y() * diff.Z()); +} + +/// Constructs an iterator that points to the beginning of the sequence. +HKLGenerator::const_iterator HKLGenerator::getBeginIterator() const { + return HKLGenerator::const_iterator(m_hklMin, m_hklMax); +} + +/// Constructs an iterator that points to an HKL one past the maximum. +HKLGenerator::const_iterator HKLGenerator::getEndIterator() const { + return HKLGenerator::const_iterator(getEndHKL()); +} + +/// Returns the HKL "one past the maximum". +V3D HKLGenerator::getEndHKL() const { + return V3D(m_hklMax.X() + 1, m_hklMin.Y(), m_hklMin.Z()); +} + +/// Default constructor, requirement from boost::iterator_facade +HKLGenerator::const_iterator::const_iterator() + : m_h(0), m_k(0), m_l(0), m_hkl(V3D(0, 0, 0)), m_hMin(0), m_hMax(0), + m_kMin(0), m_kMax(0), m_lMin(0), m_lMax(0) {} + +/// Return an iterator with min = max = current. +HKLGenerator::const_iterator::const_iterator(const V3D ¤t) + : m_h(static_cast<int>(current.X())), m_k(static_cast<int>(current.Y())), + m_l(static_cast<int>(current.Z())), m_hkl(current), m_hMin(m_h), + m_hMax(m_h), m_kMin(m_k), m_kMax(m_k), m_lMin(m_l), m_lMax(m_l) {} + +/// Return an iterator that can move from min to max, with current = min +HKLGenerator::const_iterator::const_iterator(const V3D &hklMin, + const V3D &hklMax) + : m_h(static_cast<int>(hklMin.X())), m_k(static_cast<int>(hklMin.Y())), + m_l(static_cast<int>(hklMin.Z())), m_hkl(hklMin), m_hMin(m_h), + m_hMax(static_cast<int>(hklMax.X())), m_kMin(m_k), + m_kMax(static_cast<int>(hklMax.Y())), m_lMin(m_l), + m_lMax(static_cast<int>(hklMax.Z())) {} + +/// Increments HKL, l moves fastest, h moves slowest, wrapping around at the max +/// for each index. +void HKLGenerator::const_iterator::increment() { + ++m_l; + + if (m_l > m_lMax) { + m_l = m_lMin; + + ++m_k; + if (m_k > m_kMax) { + m_k = m_kMin; + ++m_h; + } + } + + m_hkl = V3D(m_h, m_k, m_l); +} + +} // namespace Geometry +} // namespace Mantid diff --git a/Framework/Geometry/src/Crystal/IsotropicAtomBraggScatterer.cpp b/Framework/Geometry/src/Crystal/IsotropicAtomBraggScatterer.cpp index 80e8f54eebf9e9ee47577303faec65ba32b13883..6797299f9b47dfe25d63f7db5c9fa6b834d8f244 100644 --- a/Framework/Geometry/src/Crystal/IsotropicAtomBraggScatterer.cpp +++ b/Framework/Geometry/src/Crystal/IsotropicAtomBraggScatterer.cpp @@ -7,6 +7,10 @@ #include "MantidGeometry/Crystal/BraggScattererFactory.h" +#include <boost/tokenizer.hpp> +#include <boost/algorithm/string.hpp> +#include <boost/assign.hpp> + namespace Mantid { namespace Geometry { @@ -56,9 +60,7 @@ double IsotropicAtomBraggScatterer::getU() const { return getProperty("U"); } /** * Calculates the structure factor * - * This method calculates the structure factor, taking into account - * contributions from all atoms on the stored position - * _and all symmetrically equivalent_. + * This method calculates the structure factor. * For details, please refer to the class documentation in the header file. * * @param hkl :: HKL for which the structure factor should be calculated @@ -69,16 +71,9 @@ IsotropicAtomBraggScatterer::calculateStructureFactor(const V3D &hkl) const { double amplitude = getOccupancy() * getDebyeWallerFactor(hkl) * getScatteringLength(); - StructureFactor sum(0.0, 0.0); - - std::vector<V3D> equivalentPositions = getEquivalentPositions(); - for (auto pos = equivalentPositions.begin(); pos != equivalentPositions.end(); - ++pos) { - double phase = 2.0 * M_PI * (*pos).scalar_prod(hkl); - sum += amplitude * StructureFactor(cos(phase), sin(phase)); - } + double phase = 2.0 * M_PI * m_position.scalar_prod(hkl); - return sum; + return amplitude * StructureFactor(cos(phase), sin(phase)); } /** @@ -136,5 +131,105 @@ double IsotropicAtomBraggScatterer::getScatteringLength() const { DECLARE_BRAGGSCATTERER(IsotropicAtomBraggScatterer) +/** + * Constructor for vector with IsotropicAtomBraggScatterers from a string + * + * The functor expects to be constructed from a string in the following format: + * + * Element x y z occupancy u_iso; Element x y z occupancy u_iso; ... + * + * It generates an IsotropicAtomBraggScatterer for each specified atom. + * + * @param scattererString :: String in the format specified above + */ +IsotropicAtomBraggScattererParser::IsotropicAtomBraggScattererParser( + const std::string &scattererString) + : m_scattererString(scattererString) {} + +/// Operator that returns vector of IsotropicAtomBraggScatterers. +std::vector<BraggScatterer_sptr> IsotropicAtomBraggScattererParser:: +operator()() const { + boost::char_separator<char> atomSep(";"); + boost::tokenizer<boost::char_separator<char>> tokens(m_scattererString, + atomSep); + std::vector<BraggScatterer_sptr> scatterers; + + for (auto it = tokens.begin(); it != tokens.end(); ++it) { + scatterers.push_back(getScatterer(boost::trim_copy(*it))); + } + + return scatterers; +} + +/// Returns IsotropicAtomBraggScatterer for string with format "Element x y z +/// occupancy u_iso". +BraggScatterer_sptr IsotropicAtomBraggScattererParser::getScatterer( + const std::string &singleScatterer) const { + std::vector<std::string> tokens; + boost::split(tokens, singleScatterer, boost::is_any_of(" ")); + + if (tokens.size() < 4 || tokens.size() > 6) { + throw std::invalid_argument("Could not parse scatterer string: " + + singleScatterer); + } + + std::vector<std::string> cleanScattererTokens = + getCleanScattererTokens(tokens); + std::vector<std::string> properties = + boost::assign::list_of("Element")("Position")("Occupancy")("U") + .convert_to_container<std::vector<std::string>>(); + + std::string initString; + for (size_t i = 0; i < cleanScattererTokens.size(); ++i) { + initString += properties[i] + "=" + cleanScattererTokens[i] + ";"; + } + + return BraggScattererFactory::Instance().createScatterer( + "IsotropicAtomBraggScatterer", initString); +} + +/// Converts tokens for getScatterer method so they can be processed by factory. +std::vector<std::string> +IsotropicAtomBraggScattererParser::getCleanScattererTokens( + const std::vector<std::string> &tokens) const { + std::vector<std::string> cleanTokens; + + // Element + cleanTokens.push_back(tokens[0]); + + // X, Y, Z + cleanTokens.push_back("[" + tokens[1] + "," + tokens[2] + "," + tokens[3] + + "]"); + + for (size_t i = 4; i < tokens.size(); ++i) { + cleanTokens.push_back(tokens[i]); + } + + return cleanTokens; +} + +std::string +getIsotropicAtomBraggScattererString(const BraggScatterer_sptr &scatterer) { + IsotropicAtomBraggScatterer_sptr isotropicAtom = + boost::dynamic_pointer_cast<IsotropicAtomBraggScatterer>(scatterer); + + if (!isotropicAtom) { + throw std::invalid_argument( + "Printing function can only process IsotropicAtomBraggScatterer."); + } + + std::string rawPositionString = isotropicAtom->getProperty("Position"); + std::vector<std::string> positionComponents = + getTokenizedPositionString(rawPositionString); + + std::stringstream outStream; + outStream << isotropicAtom->getElement() << " " << positionComponents[0] + << " " << positionComponents[1] << " " << positionComponents[2] + << " " << isotropicAtom->getOccupancy() << " " + << isotropicAtom->getU(); + + return outStream.str(); +} + } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/src/Crystal/ReflectionGenerator.cpp b/Framework/Geometry/src/Crystal/ReflectionGenerator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..59fd597ef216ad55f5d601c3a8f688c5e443738d --- /dev/null +++ b/Framework/Geometry/src/Crystal/ReflectionGenerator.cpp @@ -0,0 +1,146 @@ +#include "MantidGeometry/Crystal/ReflectionGenerator.h" +#include "MantidGeometry/Crystal/BasicHKLFilters.h" +#include "MantidGeometry/Crystal/StructureFactorCalculatorSummation.h" +#include "MantidGeometry/Crystal/HKLGenerator.h" + +namespace Mantid { +namespace Geometry { + +using namespace Kernel; + +/// Small helper functor to calculate d-Values from a unit cell. +class LatticeSpacingCalculator { +public: + LatticeSpacingCalculator(const UnitCell &cell) : m_cell(cell) {} + + double operator()(const V3D &hkl) { return m_cell.d(hkl); } + +private: + UnitCell m_cell; +}; + +/// Constructor +ReflectionGenerator::ReflectionGenerator( + const CrystalStructure &crystalStructure, + ReflectionConditionFilter defaultFilter) + : m_crystalStructure(crystalStructure), + m_sfCalculator(StructureFactorCalculatorFactory::create< + StructureFactorCalculatorSummation>(m_crystalStructure)), + m_defaultHKLFilter(getReflectionConditionFilter(defaultFilter)) {} + +/// Returns the internally stored crystal structure +const CrystalStructure &ReflectionGenerator::getCrystalStructure() const { + return m_crystalStructure; +} + +/// Returns a DRangeFilter from the supplied d-limits and the internally stored +/// cell. +HKLFilter_const_sptr ReflectionGenerator::getDRangeFilter(double dMin, + double dMax) const { + return boost::make_shared<const HKLFilterDRange>(m_crystalStructure.cell(), + dMin, dMax); +} + +/// Returns a reflection condition HKLFilter based on the supplied enum. +HKLFilter_const_sptr ReflectionGenerator::getReflectionConditionFilter( + ReflectionConditionFilter filter) { + switch (filter) { + case ReflectionConditionFilter::Centering: + return boost::make_shared<const HKLFilterCentering>( + m_crystalStructure.centering()); + break; + case ReflectionConditionFilter::SpaceGroup: + return boost::make_shared<const HKLFilterSpaceGroup>( + m_crystalStructure.spaceGroup()); + break; + case ReflectionConditionFilter::StructureFactor: + return boost::make_shared<const HKLFilterStructureFactor>(m_sfCalculator); + default: + return HKLFilter_const_sptr(); + } +} + +/// Returns a list of HKLs within the specified d-limits using the default +/// reflection condition filter. +std::vector<V3D> ReflectionGenerator::getHKLs(double dMin, double dMax) const { + return getHKLs(dMin, dMax, m_defaultHKLFilter); +} + +/// Returns a list of HKLs within the specified d-limits using the specified +/// filter. If the pointer is null, it's ignored. +std::vector<Kernel::V3D> ReflectionGenerator::getHKLs( + double dMin, double dMax, + HKLFilter_const_sptr reflectionConditionFilter) const { + HKLGenerator generator(m_crystalStructure.cell(), dMin); + + HKLFilter_const_sptr filter = getDRangeFilter(dMin, dMax); + if (reflectionConditionFilter) { + filter = filter & reflectionConditionFilter; + } + + std::vector<V3D> hkls; + hkls.reserve(generator.size()); + + std::remove_copy_if(generator.begin(), generator.end(), + std::back_inserter(hkls), (~filter)->fn()); + return hkls; +} + +/// Returns a list of symetrically independent HKLs within the specified +/// d-limits using the default reflection condition filter. +std::vector<V3D> ReflectionGenerator::getUniqueHKLs(double dMin, + double dMax) const { + return getUniqueHKLs(dMin, dMax, m_defaultHKLFilter); +} + +/// Returns a list of symetrically independent HKLs within the specified +/// d-limits using the specified reflection condition filter. +std::vector<V3D> ReflectionGenerator::getUniqueHKLs( + double dMin, double dMax, + HKLFilter_const_sptr reflectionConditionFilter) const { + HKLGenerator generator(m_crystalStructure.cell(), dMin); + + HKLFilter_const_sptr filter = getDRangeFilter(dMin, dMax); + if (reflectionConditionFilter) { + filter = filter & reflectionConditionFilter; + } + + std::vector<V3D> hkls; + hkls.reserve(generator.size()); + + PointGroup_sptr pg = m_crystalStructure.spaceGroup()->getPointGroup(); + + for (auto hkl = generator.begin(); hkl != generator.end(); ++hkl) { + if (filter->isAllowed(*hkl)) { + hkls.push_back(pg->getReflectionFamily(*hkl)); + } + } + + std::sort(hkls.begin(), hkls.end()); + hkls.erase(std::unique(hkls.begin(), hkls.end()), hkls.end()); + + return hkls; +} + +/// Returns a list of d-values that correspond to the supplied hkl list, using +/// the unit cell of the stored crystal structure. +std::vector<double> +ReflectionGenerator::getDValues(const std::vector<V3D> &hkls) const { + std::vector<double> dValues; + dValues.reserve(hkls.size()); + + std::transform(hkls.begin(), hkls.end(), std::back_inserter(dValues), + LatticeSpacingCalculator(m_crystalStructure.cell())); + + return dValues; +} + +/// Returns a list of squared structure factor amplitudes corresponding to the +/// supplied list of HKLs. +std::vector<double> +ReflectionGenerator::getFsSquared(const std::vector<V3D> &hkls) const { + return m_sfCalculator->getFsSquared(hkls); +} + +} // namespace Geometry +} // namespace Mantid diff --git a/Framework/Geometry/src/Crystal/ScalarUtils.cpp b/Framework/Geometry/src/Crystal/ScalarUtils.cpp index 096cbabf474a832b4b82a10cd92da237707671aa..e92b977edef531ba35d5a1092e8df1dc1ffe07e4 100644 --- a/Framework/Geometry/src/Crystal/ScalarUtils.cpp +++ b/Framework/Geometry/src/Crystal/ScalarUtils.cpp @@ -229,7 +229,7 @@ ConventionalCell ScalarUtils::GetCellForForm(const DblMatrix &UB, if (allowPermutations) { double angle_tolerance = 2.0; double length_factor = 1.05; - UB_list = GetRelatedUBs(UB, angle_tolerance, length_factor); + UB_list = GetRelatedUBs(UB, length_factor, angle_tolerance); } else { // Get exact form requested and not permutations UB_list.push_back(UB); diff --git a/Framework/Geometry/src/Crystal/StructureFactorCalculator.cpp b/Framework/Geometry/src/Crystal/StructureFactorCalculator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..df4cb44ed97825cee453bb450b2be33a9b5be755 --- /dev/null +++ b/Framework/Geometry/src/Crystal/StructureFactorCalculator.cpp @@ -0,0 +1,83 @@ +#include "MantidGeometry/Crystal/StructureFactorCalculator.h" + +#include <boost/bind.hpp> + +namespace Mantid { +namespace Geometry { + +StructureFactorCalculator::StructureFactorCalculator() {} + +/** + * Sets the crystal structure for which to calculate structure factors + * + * Additionally StructureFactorCalculator::crystalStructureSetHook() is called + * with the CrystalStructure. This function may be re-implemented + * by concrete structure factor calculators to perform other necessary actions + * that involve the crystal structure (for example extracting and storing + * members of it). + * + * @param crystalStructure :: Crystal structure for calculations. + */ +void StructureFactorCalculator::setCrystalStructure( + const CrystalStructure &crystalStructure) { + crystalStructureSetHook(crystalStructure); +} + +/// Returns F^2 for the given HKL, calling StructureFactorCalculator::getF(). +double StructureFactorCalculator::getFSquared(const Kernel::V3D &hkl) const { + StructureFactor sf = getF(hkl); + + return sf.real() * sf.real() + sf.imag() * sf.imag(); +} + +/** + * Returns structure factors for each HKL in the container + * + * The default implementation uses StructureFactorCalculator::getF() to get + * the structure factor for each HKL. This behavior can be overriden in + * sub-classes for example to implement this in a more efficient way. + * + * @param hkls :: Vector of HKLs. + * @return :: Vector of structure factors for the given HKLs. + */ +std::vector<StructureFactor> +StructureFactorCalculator::getFs(const std::vector<Kernel::V3D> &hkls) const { + std::vector<StructureFactor> structureFactors(hkls.size()); + + std::transform(hkls.begin(), hkls.end(), structureFactors.begin(), + boost::bind(&StructureFactorCalculator::getF, this, _1)); + + return structureFactors; +} + +/** + * Returns structure factors for each HKL in the container + * + * The default implementation uses StructureFactorCalculator::getFSquared() with + * each HKL. This behavior can be overriden in + * sub-classes for example to implement this in a more efficient way. + * + * @param hkls :: Vector of HKLs. + * @return :: Vector of squared structure factors for the given HKLs. + */ +std::vector<double> StructureFactorCalculator::getFsSquared( + const std::vector<Kernel::V3D> &hkls) const { + std::vector<double> fSquareds(hkls.size()); + + std::transform( + hkls.begin(), hkls.end(), fSquareds.begin(), + boost::bind(&StructureFactorCalculator::getFSquared, this, _1)); + + return fSquareds; +} + +/// This function is called from +/// StructureFactorCalculator::setCrystalStructure() and can be overriden to +/// perform additional actions. +void StructureFactorCalculator::crystalStructureSetHook( + const CrystalStructure &crystalStructure) { + UNUSED_ARG(crystalStructure) +} + +} // namespace Geometry +} // namespace Mantid diff --git a/Framework/Geometry/src/Crystal/StructureFactorCalculatorSummation.cpp b/Framework/Geometry/src/Crystal/StructureFactorCalculatorSummation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eabc22952cbd37217570255a766d4f023f170d83 --- /dev/null +++ b/Framework/Geometry/src/Crystal/StructureFactorCalculatorSummation.cpp @@ -0,0 +1,82 @@ +#include "MantidGeometry/Crystal/StructureFactorCalculatorSummation.h" +#include "MantidGeometry/Crystal/BraggScattererInCrystalStructure.h" + +#include <iomanip> + +namespace Mantid { +namespace Geometry { + +using namespace Kernel; + +StructureFactorCalculatorSummation::StructureFactorCalculatorSummation() + : StructureFactorCalculator(), + m_unitCellScatterers(CompositeBraggScatterer::create()) {} + +/// Returns the structure factor obtained from the stored scatterers. +StructureFactor +StructureFactorCalculatorSummation::getF(const Kernel::V3D &hkl) const { + return m_unitCellScatterers->calculateStructureFactor(hkl); +} + +/// Calls updateUnitCellScatterers() to rebuild the complete list of scatterers. +void StructureFactorCalculatorSummation::crystalStructureSetHook( + const CrystalStructure &crystalStructure) { + updateUnitCellScatterers(crystalStructure); +} + +/** + * Rebuilds the internal list of scatterers + * + * This method extracts two items from the supplied CrystalStructure object, the + * list of scatterers in the asymmetric unit and the space group. Then it + * generates all equivalent positions and creates a complete list of scatterers. + * + * @param crystalStructure :: CrystalStructure for structure factor calculation. + */ +void StructureFactorCalculatorSummation::updateUnitCellScatterers( + const CrystalStructure &crystalStructure) { + m_unitCellScatterers->removeAllScatterers(); + + CompositeBraggScatterer_sptr scatterersInAsymmetricUnit = + crystalStructure.getScatterers(); + SpaceGroup_const_sptr spaceGroup = crystalStructure.spaceGroup(); + + if (spaceGroup) { + std::vector<BraggScatterer_sptr> braggScatterers; + braggScatterers.reserve(scatterersInAsymmetricUnit->nScatterers() * + spaceGroup->order()); + + for (size_t i = 0; i < scatterersInAsymmetricUnit->nScatterers(); ++i) { + BraggScattererInCrystalStructure_sptr current = + boost::dynamic_pointer_cast<BraggScattererInCrystalStructure>( + scatterersInAsymmetricUnit->getScatterer(i)); + + if (current) { + std::vector<V3D> positions = + spaceGroup->getEquivalentPositions(current->getPosition()); + + for (auto pos = positions.begin(); pos != positions.end(); ++pos) { + BraggScatterer_sptr clone = current->clone(); + clone->setProperty("Position", getV3DasString(*pos)); + + braggScatterers.push_back(clone); + } + } + } + + m_unitCellScatterers->setScatterers(braggScatterers); + } +} + +/// Return V3D as string without losing precision. +std::string +StructureFactorCalculatorSummation::getV3DasString(const V3D &point) const { + std::ostringstream posStream; + posStream << std::setprecision(17); + posStream << point; + + return posStream.str(); +} + +} // namespace Geometry +} // namespace Mantid diff --git a/Framework/Geometry/src/Instrument.cpp b/Framework/Geometry/src/Instrument.cpp index 8841dfdceac65fa7349966abb79781c368247339..0990d31e19b2e3d79b816f62485c16a9f91b945f 100644 --- a/Framework/Geometry/src/Instrument.cpp +++ b/Framework/Geometry/src/Instrument.cpp @@ -1258,6 +1258,11 @@ Instrument::ContainsState Instrument::containsRectDetectors() const { if (detector && detector->isMonitor()) continue; + // skip choppers HACK! + if (comp->getName() == "chopper-position") { + continue; + } + if (dynamic_cast<const RectangularDetector *>(comp.get())) { if (!foundRect) foundRect = true; diff --git a/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp b/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp index cdc50169d55ad5ab98597068d3a5a4ced1b04ddb..f4c9afef815111745fea386715ae9a79b4d531ea 100644 --- a/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp +++ b/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp @@ -1554,7 +1554,15 @@ void InstrumentDefinitionParser::populateIdList(Poco::XML::Element *pE, increment = atoi((pIDElem->getAttribute("step")).c_str()); // check the start end and increment values are sensible - if (((endID - startID) / increment) < 0) { + if (0 == increment) { + std::stringstream ss; + ss << "The step element cannot be zero, found step: " << increment; + + throw Kernel::Exception::InstrumentDefinitionError(ss.str(), + filename); + } + int numSteps = (endID - startID) / increment; + if (numSteps < 0) { std::stringstream ss; ss << "The start, end, and step elements do not allow a single id " "in the idlist entry - "; @@ -1565,7 +1573,7 @@ void InstrumentDefinitionParser::populateIdList(Poco::XML::Element *pE, filename); } - idList.vec.reserve((endID - startID) / increment); + idList.vec.reserve(numSteps); for (int i = startID; i != endID + increment; i += increment) { idList.vec.push_back(i); } @@ -2301,7 +2309,9 @@ void InstrumentDefinitionParser::createNeutronicInstrument() { mapTypeNameToShape.find(shapeName); if (shapeIt != mapTypeNameToShape.end()) { // Change the shape on the current component to the one requested - dynamic_cast<ObjComponent *>(it->first)->setShape(shapeIt->second); + auto objCmpt = dynamic_cast<ObjComponent *>(it->first); + if (objCmpt) + objCmpt->setShape(shapeIt->second); } else { throw Exception::InstrumentDefinitionError( "Requested type " + shapeName + " not defined in IDF"); diff --git a/Framework/Geometry/src/Math/Acomp.cpp b/Framework/Geometry/src/Math/Acomp.cpp index 0788103182bd08ed8d4202180f43ed171f722ee3..75c5fb5fe2be6d8d76bc081899ffbf8b4e10774a 100644 --- a/Framework/Geometry/src/Math/Acomp.cpp +++ b/Framework/Geometry/src/Math/Acomp.cpp @@ -366,7 +366,8 @@ Assumes that the component is sorted and inserts appropiately. for (acp = AX.Comp.begin(); acp != AX.Comp.end(); ++acp) { std::vector<Acomp>::iterator cpt; cpt = std::lower_bound(Comp.begin(), Comp.end(), *acp); - if (cpt == Comp.end() || *cpt != *aup) // Only insert if new + if (cpt == Comp.end() || + (AX.Units.end() != aup && *cpt != *aup)) // Only insert if new Comp.insert(cpt, *acp); } return; @@ -981,6 +982,9 @@ It is set on exit (to the EPI) break; } + if (PIactive.end() == px) + continue; + EPI.push_back(PIform[*px]); // remove all minterm that the EPI covered for (ddx = DNFactive.begin(); ddx != DNFactive.end(); ++ddx) diff --git a/Framework/Geometry/src/Objects/Object.cpp b/Framework/Geometry/src/Objects/Object.cpp index e6ab975dda916bb686a74b0efc4530155844cac6..d7bccf922d68d8ae460d4ef200e57dec7ee257a5 100644 --- a/Framework/Geometry/src/Objects/Object.cpp +++ b/Framework/Geometry/src/Objects/Object.cpp @@ -221,11 +221,13 @@ int Object::complementaryObject(const int Cnum, std::string &Ln) { std::string::size_type posB; posB = Ln.find_first_of("()", posA); if (posB == std::string::npos) - throw std::runtime_error("Object::complemenet :: " + Ln); + throw std::runtime_error("Object::complement :: " + Ln); brackCnt = (Ln[posB] == '(') ? 1 : 0; while (posB != std::string::npos && brackCnt) { posB = Ln.find_first_of("()", posB); + if (posB == std::string::npos) + break; brackCnt += (Ln[posB] == '(') ? 1 : -1; posB++; } @@ -242,7 +244,7 @@ int Object::complementaryObject(const int Cnum, std::string &Ln) { return 1; } - throw std::runtime_error("Object::complemenet :: " + Part); + throw std::runtime_error("Object::complement :: " + Part); return 0; } diff --git a/Framework/Geometry/test/BasicHKLFiltersTest.h b/Framework/Geometry/test/BasicHKLFiltersTest.h new file mode 100644 index 0000000000000000000000000000000000000000..7295290c09a156062be0e9cd70d3c2308ef2bead --- /dev/null +++ b/Framework/Geometry/test/BasicHKLFiltersTest.h @@ -0,0 +1,146 @@ +#ifndef MANTID_GEOMETRY_BASICHKLFILTERSTEST_H_ +#define MANTID_GEOMETRY_BASICHKLFILTERSTEST_H_ + +#include <cxxtest/TestSuite.h> +#include <gtest/gtest.h> +#include <gmock/gmock.h> + +#include "MantidGeometry/Crystal/BasicHKLFilters.h" +#include "MantidGeometry/Crystal/SpaceGroupFactory.h" +#include "MantidGeometry/Crystal/StructureFactorCalculator.h" + +#include <strstream> + +using namespace Mantid::Geometry; +using namespace Mantid::Kernel; + +using ::testing::_; +using ::testing::Return; +using ::testing::Mock; + +class BasicHKLFiltersTest : 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 BasicHKLFiltersTest *createSuite() { + return new BasicHKLFiltersTest(); + } + static void destroySuite(BasicHKLFiltersTest *suite) { delete suite; } + + void testHKLFilterDRangeConstructors() { + UnitCell cell(10., 10., 10.); + + TS_ASSERT_THROWS_NOTHING(HKLFilterDRange dFilter(cell, 1.0)); + TS_ASSERT_THROWS(HKLFilterDRange dFilter(cell, -1.0), std::range_error); + TS_ASSERT_THROWS(HKLFilterDRange dFilter(cell, 0.0), std::range_error); + + TS_ASSERT_THROWS_NOTHING(HKLFilterDRange dFilter(cell, 1.0, 2.0)); + TS_ASSERT_THROWS(HKLFilterDRange dFilter(cell, 1.0, 0.5), std::range_error); + TS_ASSERT_THROWS(HKLFilterDRange dFilter(cell, 1.0, -0.5), + std::range_error); + } + + void testHKLFilterDRangeDescription() { + UnitCell cell(10., 10., 10.); + + std::ostringstream reference; + reference << "(" << 1.0 << " <= d <= " << 10.0 << ")"; + + HKLFilterDRange dFilter(cell, 1.0); + TS_ASSERT_EQUALS(dFilter.getDescription(), reference.str()); + } + + void testHKLFilterDRangeIsAllowed() { + UnitCell cell(10., 10., 10.); + HKLFilterDRange dFilter(cell, 1.0, 9.0); + + TS_ASSERT(dFilter.isAllowed(V3D(1, 2, 3))); + + TS_ASSERT(dFilter.isAllowed(V3D(2, 0, 0))); + TS_ASSERT(!dFilter.isAllowed(V3D(1, 0, 0))); + + TS_ASSERT(dFilter.isAllowed(V3D(10, 0, 0))); + TS_ASSERT(!dFilter.isAllowed(V3D(11, 0, 0))); + } + + void testHKLFilterSpaceGroupConstructor() { + SpaceGroup_const_sptr invalid; + TS_ASSERT_THROWS(HKLFilterSpaceGroup sgFilter(invalid), std::runtime_error); + + SpaceGroup_const_sptr sg = + SpaceGroupFactory::Instance().createSpaceGroup("F d -3 m"); + TS_ASSERT_THROWS_NOTHING(HKLFilterSpaceGroup sgFilter(sg)); + } + + void testHKLFilterSpaceGroupDescription() { + SpaceGroup_const_sptr sg = + SpaceGroupFactory::Instance().createSpaceGroup("F d -3 m"); + + HKLFilterSpaceGroup sgFilter(sg); + + TS_ASSERT_EQUALS(sgFilter.getDescription(), + "(Space group: " + sg->hmSymbol() + ")"); + } + + void testHKLFilterSpaceGroupIsAllowed() { + SpaceGroup_const_sptr sg = + SpaceGroupFactory::Instance().createSpaceGroup("F d -3 m"); + + HKLFilterSpaceGroup sgFilter(sg); + + TS_ASSERT(!sgFilter.isAllowed(V3D(1, 0, 0))); + TS_ASSERT(!sgFilter.isAllowed(V3D(1, 1, 0))); + TS_ASSERT(sgFilter.isAllowed(V3D(1, 1, 1))); + + TS_ASSERT(!sgFilter.isAllowed(V3D(2, 0, 0))); + TS_ASSERT(!sgFilter.isAllowed(V3D(3, 0, 0))); + TS_ASSERT(sgFilter.isAllowed(V3D(4, 0, 0))); + } + + void testHKLFilterStructureFactorConstructor() { + StructureFactorCalculator_sptr invalid; + TS_ASSERT_THROWS(HKLFilterStructureFactor sfFilter(invalid), + std::runtime_error); + + StructureFactorCalculator_sptr mock = + boost::make_shared<MockStructureFactorCalculator>(); + TS_ASSERT_THROWS_NOTHING(HKLFilterStructureFactor sfFilter(mock)); + TS_ASSERT_THROWS_NOTHING(HKLFilterStructureFactor sfFilter(mock, 12.0)); + } + + void testHKLFilterStructureFactorDescription() { + std::ostringstream reference; + reference << "(F^2 > " << 1.0 << ")"; + + StructureFactorCalculator_sptr mock = + boost::make_shared<MockStructureFactorCalculator>(); + HKLFilterStructureFactor sfFilter(mock, 1.0); + TS_ASSERT_EQUALS(sfFilter.getDescription(), reference.str()); + } + + void testHKLFilterStructureFactorIsAllowed() { + boost::shared_ptr<MockStructureFactorCalculator> mock = + boost::make_shared<MockStructureFactorCalculator>(); + + EXPECT_CALL(*mock, getFSquared(_)) + .WillOnce(Return(2.0)) + .WillOnce(Return(0.5)) + .WillOnce(Return(1.0)); + + HKLFilterStructureFactor sfFilter(mock, 1.0); + TS_ASSERT(sfFilter.isAllowed(V3D(1, 1, 1))); + TS_ASSERT(!sfFilter.isAllowed(V3D(1, 1, 1))); + TS_ASSERT(!sfFilter.isAllowed(V3D(1, 1, 1))); + + TS_ASSERT(Mock::VerifyAndClearExpectations(mock.get())) + } + +private: + class MockStructureFactorCalculator : public StructureFactorCalculator { + public: + MOCK_CONST_METHOD1(getF, StructureFactor(const V3D &)); + MOCK_CONST_METHOD1(getFSquared, double(const V3D &)); + }; +}; + +#endif /* MANTID_GEOMETRY_BASICHKLFILTERSTEST_H_ */ diff --git a/Framework/Geometry/test/BraggScattererInCrystalStructureTest.h b/Framework/Geometry/test/BraggScattererInCrystalStructureTest.h index 2f66f592ca71d10a57eb76f584560cad042cb040..fe58dd10a1d43c22e7212cb8dfee451150a3558d 100644 --- a/Framework/Geometry/test/BraggScattererInCrystalStructureTest.h +++ b/Framework/Geometry/test/BraggScattererInCrystalStructureTest.h @@ -33,7 +33,6 @@ public: TS_ASSERT(scatterer->existsProperty("Position")); TS_ASSERT(scatterer->existsProperty("UnitCell")); - TS_ASSERT(scatterer->existsProperty("SpaceGroup")); } void testAfterScattererPropertySet() { @@ -72,47 +71,6 @@ public: TS_ASSERT_EQUALS(scatterer->getCell().getG(), cell.getG()); } - void testGetSetSpaceGroup() { - BraggScattererInCrystalStructure_sptr scatterer = getInitializedScatterer(); - - SpaceGroup_const_sptr testGroup = - SpaceGroupFactory::Instance().createSpaceGroup("P m -3 m"); - - TS_ASSERT_THROWS_NOTHING(scatterer->setProperty("SpaceGroup", "P m -3 m")); - TS_ASSERT_EQUALS(scatterer->getSpaceGroup()->hmSymbol(), - testGroup->hmSymbol()); - } - - void testEquivalentPositions() { - BraggScattererInCrystalStructure_sptr scatterer = getInitializedScatterer(); - - V3D generalPosition(0.3, 0.32, 0.45); - - // No space group set - no equivalent positions - scatterer->setProperty("Position", "[0.3, 0.32, 0.45]"); - TS_ASSERT_EQUALS(scatterer->getEquivalentPositions().size(), 1); - TS_ASSERT_EQUALS(scatterer->getEquivalentPositions().front(), - generalPosition); - - // Assigning a space group must cause recalculation of equivalent positions - SpaceGroup_const_sptr testGroup = - SpaceGroupFactory::Instance().createSpaceGroup("P m -3 m"); - scatterer->setProperty("SpaceGroup", "P m -3 m"); - - TS_ASSERT_EQUALS(scatterer->getEquivalentPositions().size(), - testGroup->order()); - - // Re-setting the position also recalculates - V3D specialPosition(0.0, 0.0, 0.0); - - scatterer->setProperty("Position", "[0, 0, 0]"); - // Pm-3m does not contain translations, so (0,0,0) is not transformed by any - // symmetry operation of the group - TS_ASSERT_EQUALS(scatterer->getEquivalentPositions().size(), 1); - TS_ASSERT_EQUALS(scatterer->getEquivalentPositions().front(), - specialPosition); - } - void testUnitCellStringValidator() { IValidator_sptr validator = boost::make_shared<UnitCellStringValidator>(); diff --git a/Framework/Geometry/test/CompositeBraggScattererTest.h b/Framework/Geometry/test/CompositeBraggScattererTest.h index f5c45156900d5a7fac250eed7109010787ecc007..618c86120f6765301577d1116d4831617bb9bd95 100644 --- a/Framework/Geometry/test/CompositeBraggScattererTest.h +++ b/Framework/Geometry/test/CompositeBraggScattererTest.h @@ -9,6 +9,7 @@ #include "MantidGeometry/Crystal/SpaceGroupFactory.h" #include "MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h" +#include <iostream> #include <map> using namespace Mantid::Geometry; @@ -68,38 +69,16 @@ public: } void testAddGetScatterer() { - UnitCell cell(5.43, 5.43, 5.43); - SpaceGroup_const_sptr spaceGroup = - SpaceGroupFactory::Instance().createSpaceGroup("P 1 2/m 1"); - CompositeBraggScatterer_sptr scatterer = CompositeBraggScatterer::create(); TS_ASSERT_EQUALS(scatterer->propertyCount(), 0); IsotropicAtomBraggScatterer_sptr siOne = getInitializedScatterer("Si", "[0, 0, 0]"); - TS_ASSERT_DIFFERS(siOne->getSpaceGroup()->hmSymbol(), - spaceGroup->hmSymbol()); - size_t oldCount = scatterer->nScatterers(); scatterer->addScatterer(siOne); - TS_ASSERT_EQUALS(scatterer->propertyCount(), 2); + TS_ASSERT_EQUALS(scatterer->propertyCount(), 1); TS_ASSERT_EQUALS(scatterer->nScatterers(), oldCount + 1); - - // Properties are propagated. - scatterer->setProperty("UnitCell", unitCellToStr(cell)); - scatterer->setProperty("SpaceGroup", spaceGroup->hmSymbol()); - - // The scatterer is cloned, so the new space group is not in siOne - TS_ASSERT_EQUALS( - boost::dynamic_pointer_cast<BraggScattererInCrystalStructure>( - scatterer->getScatterer(0)) - ->getSpaceGroup() - ->hmSymbol(), - spaceGroup->hmSymbol()); - TS_ASSERT_DIFFERS(siOne->getSpaceGroup()->hmSymbol(), - spaceGroup->hmSymbol()); - TS_ASSERT_THROWS(scatterer->getScatterer(2), std::out_of_range); } @@ -147,12 +126,16 @@ public: UnitCell cell(5.43, 6.43, 7.43, 90.0, 103.0, 90.0); SpaceGroup_const_sptr spaceGroup = SpaceGroupFactory::Instance().createSpaceGroup("P 1 2/m 1"); + std::vector<V3D> positions = + spaceGroup->getEquivalentPositions(V3D(0.2, 0.3, 0.4)); CompositeBraggScatterer_sptr coll = CompositeBraggScatterer::create(); - coll->addScatterer( - getInitializedScatterer("Si", "[0.2, 0.3, 0.4]", 0.01267)); + for (auto pos = positions.begin(); pos != positions.end(); ++pos) { + std::ostringstream strm; + strm << (*pos); + coll->addScatterer(getInitializedScatterer("Si", strm.str(), 0.01267)); + } - coll->setProperty("SpaceGroup", spaceGroup->hmSymbol()); coll->setProperty("UnitCell", unitCellToStr(cell)); // Load reference data, obtained with SHELXL-2014. diff --git a/Framework/Geometry/test/CrystalStructureTest.h b/Framework/Geometry/test/CrystalStructureTest.h index 307106f56182291db5fe7eda0ec513887011d847..80fa1f63d0a5dfc9a391edbeb314c014b3fdda83 100644 --- a/Framework/Geometry/test/CrystalStructureTest.h +++ b/Framework/Geometry/test/CrystalStructureTest.h @@ -22,10 +22,7 @@ public: } static void destroySuite(CrystalStructureTest *suite) { delete suite; } - CrystalStructureTest() - : m_CsCl(4.126, 4.126, 4.126), - m_pg(PointGroupFactory::Instance().createPointGroup("m-3m")), - m_centering(new ReflectionConditionPrimitive) { + CrystalStructureTest() : m_CsCl(4.126, 4.126, 4.126) { m_spaceGroup = SpaceGroupFactory::Instance().createSpaceGroup("I m -3 m"); m_scatterers = CompositeBraggScatterer::create(); @@ -34,30 +31,10 @@ public: "IsotropicAtomBraggScatterer", "Element=Si;Position=[0,0,0]")); } - void testConstructionDefault() { - // Only cell is really required, for the others there's a default value - CrystalStructure structure(m_CsCl); - - TS_ASSERT_EQUALS(structure.cell().a(), m_CsCl.a()); - // TS_ASSERT(boost::dynamic_pointer_cast<PointGroupLaue1>(structure.pointGroup())); - TS_ASSERT(boost::dynamic_pointer_cast<ReflectionConditionPrimitive>( - structure.centering())); - TS_ASSERT_THROWS_NOTHING(structure.crystalSystem()); - TS_ASSERT_EQUALS(structure.crystalSystem(), PointGroup::Triclinic); - - CrystalStructure structurePg(m_CsCl, m_pg); - TS_ASSERT_EQUALS(structurePg.pointGroup(), m_pg); - TS_ASSERT(boost::dynamic_pointer_cast<ReflectionConditionPrimitive>( - structurePg.centering())); - TS_ASSERT_EQUALS(structurePg.crystalSystem(), m_pg->crystalSystem()); - - CrystalStructure structureAll(m_CsCl, m_pg, m_centering); - TS_ASSERT_EQUALS(structureAll.centering(), m_centering); - } - void testConstructionSpaceGroup() { TS_ASSERT_THROWS_NOTHING( CrystalStructure structure(m_CsCl, m_spaceGroup, m_scatterers)); + CrystalStructure structure(m_CsCl, m_spaceGroup, m_scatterers); TS_ASSERT_EQUALS(structure.cell().getG(), m_CsCl.getG()); TS_ASSERT_EQUALS(structure.spaceGroup(), m_spaceGroup); @@ -66,52 +43,20 @@ public: } void testSetSpaceGroup() { - CrystalStructure structure(m_CsCl, m_pg, m_centering); - - // Space group is null - TS_ASSERT(!structure.spaceGroup()); - TS_ASSERT_THROWS(std::string sg = - structure.getScatterers()->getProperty("SpaceGroup"), - Exception::NotFoundError); + CrystalStructure structure(m_CsCl, m_spaceGroup, m_scatterers); - TS_ASSERT_THROWS_NOTHING(structure.setSpaceGroup(m_spaceGroup)); + TS_ASSERT_EQUALS(structure.spaceGroup()->hmSymbol(), + m_spaceGroup->hmSymbol()); + TS_ASSERT_THROWS_NOTHING(structure.setSpaceGroup( + SpaceGroupFactory::Instance().createSpaceGroup("I a -3 d"))); // Not null anymore - TS_ASSERT(structure.spaceGroup()) - - // No Scatterers present, so space group is not set. - TS_ASSERT_THROWS(std::string sg = - structure.getScatterers()->getProperty("SpaceGroup"), - Exception::NotFoundError); - - // Adding a scatterer should set space group for all scatterers. - std::vector<BraggScatterer_sptr> scatterer( - 1, BraggScattererFactory::Instance().createScatterer( - "IsotropicAtomBraggScatterer", "Element=Si;Position=[0,0,0]")); - structure.addScatterers(CompositeBraggScatterer::create(scatterer)); - - std::string sg; - TS_ASSERT_THROWS_NOTHING( - sg = structure.getScatterers()->getPropertyValue("SpaceGroup")); - - // Symbol of test space group is I m -3 m - TS_ASSERT_EQUALS(sg, "I m -3 m") - - // pointers are different - TS_ASSERT_DIFFERS(structure.pointGroup(), m_pg); - // symbol is the same - TS_ASSERT_EQUALS(structure.pointGroup()->getSymbol(), "m-3m"); - - // pointers are different - TS_ASSERT_DIFFERS(structure.centering(), m_centering); - // symbols as well - TS_ASSERT_DIFFERS(structure.centering()->getSymbol(), - m_centering->getSymbol()); - TS_ASSERT_EQUALS(structure.centering()->getSymbol(), "I"); + TS_ASSERT(structure.spaceGroup()); + TS_ASSERT_EQUALS(structure.spaceGroup()->hmSymbol(), "I a -3 d") } void testCellGetSet() { - CrystalStructure structure(m_CsCl); + CrystalStructure structure(m_CsCl, m_spaceGroup, m_scatterers); TS_ASSERT_EQUALS(structure.cell().a(), m_CsCl.a()); UnitCell Si(5.43, 5.43, 5.43); @@ -120,313 +65,45 @@ public: TS_ASSERT_EQUALS(structure.cell().a(), Si.a()); } - void testPointGroupGetSet() { - CrystalStructure structure(m_CsCl, m_pg); - TS_ASSERT_EQUALS(structure.pointGroup(), m_pg); - TS_ASSERT_EQUALS(structure.crystalSystem(), m_pg->crystalSystem()); - - // PointGroup_sptr newPg = boost::make_shared<PointGroupLaue3>(); - // structure.setPointGroup(newPg); - - // TS_ASSERT_EQUALS(structure.pointGroup(), newPg); - // TS_ASSERT_EQUALS(structure.crystalSystem(), newPg->crystalSystem()); - - // setting a space group makes setting a point group impossible - structure.setSpaceGroup(m_spaceGroup); - // TS_ASSERT_DIFFERS(structure.crystalSystem(), newPg->crystalSystem()); - - // TS_ASSERT_THROWS(structure.setPointGroup(newPg), std::runtime_error); - } - - void testCenteringGetSet() { - CrystalStructure structure(m_CsCl, m_pg, m_centering); - TS_ASSERT_EQUALS(structure.centering(), m_centering); - - ReflectionCondition_sptr newCentering = - boost::make_shared<ReflectionConditionAFaceCentred>(); - structure.setCentering(newCentering); - - TS_ASSERT_EQUALS(structure.centering(), newCentering); - - // setting a space group makes setting a centering impossible - structure.setSpaceGroup(m_spaceGroup); - TS_ASSERT_DIFFERS(structure.centering()->getSymbol(), - newCentering->getSymbol()); - - TS_ASSERT_THROWS(structure.setCentering(newCentering), std::runtime_error); - } - - void testSufficientStateForHKLGeneration() { - TestableCrystalStructure structure; - - // Default is "UseCentering" - ReflectionCondition_sptr nullCentering; - structure.setCentering(nullCentering); - TS_ASSERT(!structure.isStateSufficientForHKLGeneration( - CrystalStructure::UseCentering)); - structure.setCentering(m_centering); - TS_ASSERT(structure.isStateSufficientForHKLGeneration( - CrystalStructure::UseCentering)); - - // Structure factor requires at least one scatterer - otherwise all hkl are - // "forbidden" - TS_ASSERT(!structure.isStateSufficientForHKLGeneration( - CrystalStructure::UseStructureFactor)); - structure.addScatterers(m_scatterers); - TS_ASSERT(structure.isStateSufficientForHKLGeneration( - CrystalStructure::UseStructureFactor)); - - // centering does not matter for this - structure.setCentering(nullCentering); - TS_ASSERT(structure.isStateSufficientForHKLGeneration( - CrystalStructure::UseStructureFactor)); - } - - void testSufficientStateForUniqueHKLGeneration() { - TestableCrystalStructure structure; - - // Default is "UseCentering" - ReflectionCondition_sptr nullCentering; - PointGroup_sptr nullPointGroup; - - structure.setCentering(nullCentering); - structure.setPointGroup(nullPointGroup); - - // Does not work with null point group - TS_ASSERT(!structure.isStateSufficientForUniqueHKLGeneration( - CrystalStructure::UseCentering)); - - // not even when centering is set - structure.setCentering(m_centering); - TS_ASSERT(!structure.isStateSufficientForUniqueHKLGeneration( - CrystalStructure::UseCentering)); - - // now it's okay - structure.setPointGroup(m_pg); - TS_ASSERT(structure.isStateSufficientForUniqueHKLGeneration( - CrystalStructure::UseCentering)); - - // Structure factor requires at least one scatterer - otherwise all hkl are - // "forbidden" - TS_ASSERT(!structure.isStateSufficientForUniqueHKLGeneration( - CrystalStructure::UseStructureFactor)); - structure.addScatterers(m_scatterers); - TS_ASSERT(structure.isStateSufficientForUniqueHKLGeneration( - CrystalStructure::UseStructureFactor)); - - // point group is required anyway - structure.setPointGroup(nullPointGroup); - TS_ASSERT(!structure.isStateSufficientForUniqueHKLGeneration( - CrystalStructure::UseStructureFactor)); - } - - void testThrowIfRangeUnacceptable() { - TestableCrystalStructure structure; + void testCrystalStructureFromStrings() { + CrystalStructure structure("5.431 5.431 5.431", "F d -3 m", + "Si 0 0 0 1.0 0.02"); - TS_ASSERT_THROWS(structure.throwIfRangeUnacceptable(0.0, 1.0), - std::invalid_argument); - TS_ASSERT_THROWS(structure.throwIfRangeUnacceptable(-10.0, 1.0), - std::invalid_argument); - TS_ASSERT_THROWS(structure.throwIfRangeUnacceptable(1.0, 0.0), - std::invalid_argument); - TS_ASSERT_THROWS(structure.throwIfRangeUnacceptable(1.0, -1.0), - std::invalid_argument); - TS_ASSERT_THROWS(structure.throwIfRangeUnacceptable(2.0, 1.0), - std::invalid_argument); + TS_ASSERT_EQUALS(structure.cell().a(), 5.431); + TS_ASSERT_EQUALS(structure.cell().b(), 5.431); + TS_ASSERT_EQUALS(structure.cell().c(), 5.431); - TS_ASSERT_THROWS_NOTHING(structure.throwIfRangeUnacceptable(1.0, 2.0)) + TS_ASSERT_EQUALS(structure.spaceGroup()->hmSymbol(), "F d -3 m"); + TS_ASSERT_EQUALS(structure.getScatterers()->nScatterers(), 1); } - void testGetUniqueHKLsHappyCase() { - double dMin = 0.55; - double dMax = 4.0; - - CrystalStructure structure(m_CsCl, m_pg, m_centering); - - TS_ASSERT_THROWS_NOTHING(structure.getUniqueHKLs(dMin, dMax)); - - std::vector<V3D> peaks = structure.getUniqueHKLs(dMin, dMax); - - TS_ASSERT_EQUALS(peaks.size(), 68); - TS_ASSERT_EQUALS(peaks[0], V3D(1, 1, 0)); - TS_ASSERT_EQUALS(peaks[11], V3D(3, 2, 0)); - TS_ASSERT_EQUALS(peaks[67], V3D(7, 2, 1)); + void testCopyConstructor() { + CrystalStructure one("1.2 2.3 3.4", "F d d d", "Fe 1/8 1/8 1/8 1.0 0.001"); - // make d-value list and check that peaks are within limits - std::vector<double> peaksD = structure.getDValues(peaks); - - std::sort(peaksD.begin(), peaksD.end()); - - TS_ASSERT_LESS_THAN_EQUALS(dMin, peaksD.front()); - TS_ASSERT_LESS_THAN_EQUALS(peaksD.back(), dMax); + CrystalStructure two(one); + TS_ASSERT_EQUALS(two.getScatterers()->nScatterers(), + one.getScatterers()->nScatterers()); + TS_ASSERT_EQUALS(two.spaceGroup()->hmSymbol(), + one.spaceGroup()->hmSymbol()); + TS_ASSERT_EQUALS(unitCellToStr(two.cell()), unitCellToStr(one.cell())); } - void testGetHKLsHappyCase() { - double dMin = 0.55; - double dMax = 4.0; - - // make a structure with P-1 - CrystalStructure structure( - m_CsCl, PointGroupFactory::Instance().createPointGroup("-1")); + void testAssignmentOperator() { + CrystalStructure one("1.2 2.3 3.4", "F d d d", "Fe 1/8 1/8 1/8 1.0 0.001"); - std::vector<V3D> unique = structure.getUniqueHKLs(dMin, dMax); - std::vector<V3D> peaks = structure.getHKLs(dMin, dMax); + CrystalStructure two = one; - // Because of symmetry -1, each reflection has multiplicity 2. - TS_ASSERT_EQUALS(peaks.size(), 2 * unique.size()); - } - - void testGetDValues() { - std::vector<V3D> hkls; - hkls.push_back(V3D(1, 0, 0)); - hkls.push_back(V3D(0, 1, 0)); - hkls.push_back(V3D(0, 0, 1)); - - UnitCell ortho(2.0, 3.0, 5.0); - CrystalStructure structure(ortho); - - std::vector<double> dValues = structure.getDValues(hkls); - - TS_ASSERT_EQUALS(dValues.size(), hkls.size()); - TS_ASSERT_EQUALS(dValues[0], 2.0); - TS_ASSERT_EQUALS(dValues[1], 3.0); - TS_ASSERT_EQUALS(dValues[2], 5.0); - } - - void testReflectionConditionMethods() { - /* This test compares the two methods that are available - * for testing if a reflection is allowed. - */ - - UnitCell cellSi(5.43, 5.43, 5.43); - PointGroup_sptr pgSi = - PointGroupFactory::Instance().createPointGroup("m-3m"); - ReflectionCondition_sptr centeringSi = - boost::make_shared<ReflectionConditionAllFaceCentred>(); - - // Crystal structure with cell, point group, centering - CrystalStructure siUseCentering(cellSi, pgSi, centeringSi); - std::vector<V3D> hklsCentering = - siUseCentering.getUniqueHKLs(0.6, 10.0, CrystalStructure::UseCentering); - - // Crystal structure with cell, space group, scatterers - must be a space - // group without glides/screws. - SpaceGroup_const_sptr sgSi = - SpaceGroupFactory::Instance().createSpaceGroup("F m -3 m"); - // With an atom at (x, x, x) there are no extra conditions. - CompositeBraggScatterer_sptr scatterers = CompositeBraggScatterer::create(); - scatterers->addScatterer(BraggScattererFactory::Instance().createScatterer( - "IsotropicAtomBraggScatterer", - "Element=Si;Position=[0.3,0.3,0.3];U=0.05")); - - CrystalStructure siUseStructureFactors(cellSi, sgSi, scatterers); - std::vector<V3D> hklsStructureFactors = siUseStructureFactors.getUniqueHKLs( - 0.6, 10.0, CrystalStructure::UseStructureFactor); - std::vector<V3D> hklsCenteringAlternative = - siUseStructureFactors.getUniqueHKLs(0.6, 10.0, - CrystalStructure::UseCentering); - - TS_ASSERT_EQUALS(hklsCentering.size(), hklsStructureFactors.size()); - TS_ASSERT_EQUALS(hklsCentering.size(), hklsCenteringAlternative.size()); - - for (size_t i = 0; i < hklsCentering.size(); ++i) { - TS_ASSERT_EQUALS(hklsCentering[i], hklsStructureFactors[i]); - TS_ASSERT_EQUALS(hklsCentering[i], hklsCenteringAlternative[i]); - } - - /* Add another scatterer and use setScatterers to replace old scatterers of - *siUseStructureFactors - * - * At this point the advantage of using the structure factor method is very - *clear. When an atom is - * added at a different position (for example [0.4, 0.4, 0.4]), some - *reflections become 0. - * - * When the atom is slightly shifted like in the case below, the same - *reflections as above are - * allowed. - */ - scatterers->addScatterer(BraggScattererFactory::Instance().createScatterer( - "IsotropicAtomBraggScatterer", - "Element=Si;Position=[0.42,0.42,0.42];U=0.05")); - siUseStructureFactors.setScatterers(scatterers); - - TS_ASSERT_EQUALS( - siUseStructureFactors.getScatterers()->getPropertyValue("SpaceGroup"), - "F m -3 m"); - - hklsStructureFactors = siUseStructureFactors.getUniqueHKLs( - 0.6, 10.0, CrystalStructure::UseStructureFactor); - - for (size_t i = 0; i < hklsCentering.size(); ++i) { - TS_ASSERT_EQUALS(hklsCentering[i], hklsStructureFactors[i]); - } - } - - void testHexagonal() { - UnitCell cellMg(3.2094, 3.2094, 5.2108, 90.0, 90.0, 120.0); - CompositeBraggScatterer_sptr scatterers = CompositeBraggScatterer::create(); - scatterers->addScatterer(BraggScattererFactory::Instance().createScatterer( - "IsotropicAtomBraggScatterer", - "Element=Mg;Position=[0.333333,0.666667,0.25];U=0.005")); - SpaceGroup_const_sptr sgMg = - SpaceGroupFactory::Instance().createSpaceGroup("P 63/m m c"); - - CrystalStructure mg(cellMg, sgMg, scatterers); - - std::vector<V3D> hkls = - mg.getUniqueHKLs(0.5, 10.0, CrystalStructure::UseStructureFactor); - for (size_t i = 0; i < hkls.size(); ++i) { - TS_ASSERT_LESS_THAN(0.5, cellMg.d(hkls[i])); - } - - std::vector<double> dValues = mg.getDValues(hkls); - for (size_t i = 0; i < hkls.size(); ++i) { - TS_ASSERT_LESS_THAN(0.5, dValues[i]); - } - } - - void testTrigonal() { - UnitCell cellAl2O3(4.759355, 4.759355, 12.99231, 90.0, 90.0, 120.0); - CompositeBraggScatterer_sptr scatterers = CompositeBraggScatterer::create(); - scatterers->addScatterer(BraggScattererFactory::Instance().createScatterer( - "IsotropicAtomBraggScatterer", - "Element=Al;Position=[0,0,0.35217];U=0.005")); - scatterers->addScatterer(BraggScattererFactory::Instance().createScatterer( - "IsotropicAtomBraggScatterer", - "Element=O;Position=[0.69365,0,0.25];U=0.005")); - SpaceGroup_const_sptr sgAl2O3 = - SpaceGroupFactory::Instance().createSpaceGroup("R -3 c"); - - std::cout << sgAl2O3->order() << std::endl; - - // O is on the 18e wyckoff position - std::vector<V3D> positions = sgAl2O3 * V3D(0.69365000, 0, 0.25000); - TS_ASSERT_EQUALS(positions.size(), 18); - - CrystalStructure mg(cellAl2O3, sgAl2O3, scatterers); - - std::vector<V3D> hkls = - mg.getUniqueHKLs(0.885, 10.0, CrystalStructure::UseStructureFactor); - - TS_ASSERT_EQUALS(hkls.size(), 44); + TS_ASSERT_EQUALS(two.getScatterers()->nScatterers(), + one.getScatterers()->nScatterers()); + TS_ASSERT_EQUALS(two.spaceGroup()->hmSymbol(), + one.spaceGroup()->hmSymbol()); + TS_ASSERT_EQUALS(unitCellToStr(two.cell()), unitCellToStr(one.cell())); } private: UnitCell m_CsCl; - PointGroup_sptr m_pg; - ReflectionCondition_sptr m_centering; - SpaceGroup_const_sptr m_spaceGroup; CompositeBraggScatterer_sptr m_scatterers; - - class TestableCrystalStructure : public CrystalStructure { - friend class CrystalStructureTest; - - public: - TestableCrystalStructure() : CrystalStructure(UnitCell()) {} - ~TestableCrystalStructure() {} - }; }; #endif /* MANTID_GEOMETRY_CRYSTALSTRUCTURETEST_H_ */ diff --git a/Framework/Geometry/test/HKLFilterTest.h b/Framework/Geometry/test/HKLFilterTest.h new file mode 100644 index 0000000000000000000000000000000000000000..c0ef32dde759a8601d65ffdfd9fae6adc7e001e8 --- /dev/null +++ b/Framework/Geometry/test/HKLFilterTest.h @@ -0,0 +1,209 @@ +#ifndef MANTID_GEOMETRY_HKLFILTERTEST_H_ +#define MANTID_GEOMETRY_HKLFILTERTEST_H_ + +#include <cxxtest/TestSuite.h> +#include <gtest/gtest.h> +#include <gmock/gmock.h> + +#include "MantidGeometry/Crystal/HKLFilter.h" +#include "MantidKernel/V3D.h" + +#include <boost/make_shared.hpp> + +using namespace Mantid::Geometry; +using namespace Mantid::Kernel; + +using ::testing::_; +using ::testing::Return; +using ::testing::Mock; + +class HKLFilterTest : 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 HKLFilterTest *createSuite() { return new HKLFilterTest(); } + static void destroySuite(HKLFilterTest *suite) { delete suite; } + + void testFn() { + MockHKLFilter filter; + EXPECT_CALL(filter, isAllowed(_)) + .Times(2) + .WillOnce(Return(true)) + .WillRepeatedly(Return(false)); + + std::function<bool(const V3D &)> f = filter.fn(); + + TS_ASSERT_EQUALS(f(V3D(1, 1, 1)), true); + TS_ASSERT_EQUALS(f(V3D(1, 1, 1)), false); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&filter)); + } + + void testUnaryLogicOperation() { + HKLFilter_const_sptr filter = boost::make_shared<MockHKLFilter>(); + + TS_ASSERT_THROWS_NOTHING(MockHKLFilterUnaryLogicOperation op(filter)); + + MockHKLFilterUnaryLogicOperation op(filter); + TS_ASSERT_EQUALS(op.getOperand(), filter); + + HKLFilter_const_sptr invalid; + TS_ASSERT_THROWS(MockHKLFilterUnaryLogicOperation op(invalid), + std::runtime_error); + } + + void testBinaryLogicOperation() { + HKLFilter_const_sptr lhs = boost::make_shared<MockHKLFilter>(); + HKLFilter_const_sptr rhs = boost::make_shared<MockHKLFilter>(); + + TS_ASSERT_THROWS_NOTHING(MockHKLFilterBinaryLogicOperation op(lhs, rhs)); + + MockHKLFilterBinaryLogicOperation op(lhs, rhs); + TS_ASSERT_EQUALS(op.getLHS(), lhs); + TS_ASSERT_EQUALS(op.getRHS(), rhs); + + HKLFilter_const_sptr invalid; + TS_ASSERT_THROWS(MockHKLFilterBinaryLogicOperation op(invalid, rhs), + std::runtime_error); + TS_ASSERT_THROWS(MockHKLFilterBinaryLogicOperation op(lhs, invalid), + std::runtime_error); + TS_ASSERT_THROWS(MockHKLFilterBinaryLogicOperation op(invalid, invalid), + std::runtime_error); + } + + void testHKLFilterNot() { + boost::shared_ptr<const MockHKLFilter> filter(new MockHKLFilter); + + EXPECT_CALL(*filter, isAllowed(_)) + .WillOnce(Return(true)) + .WillOnce(Return(false)); + + HKLFilterNot notFilter(filter); + + TS_ASSERT_EQUALS(notFilter.isAllowed(V3D(1, 1, 1)), false); + TS_ASSERT_EQUALS(notFilter.isAllowed(V3D(1, 1, 1)), true); + + TS_ASSERT(Mock::VerifyAndClearExpectations( + boost::const_pointer_cast<MockHKLFilter>(filter).get())); + } + + void testHKLFilterNotOperator() { + HKLFilter_const_sptr filter = boost::make_shared<MockHKLFilter>(); + + HKLFilter_const_sptr notFilter = ~filter; + + boost::shared_ptr<const HKLFilterNot> notFilterCasted = + boost::dynamic_pointer_cast<const HKLFilterNot>(notFilter); + TS_ASSERT(notFilterCasted); + + TS_ASSERT_EQUALS(notFilterCasted->getOperand(), filter); + } + + void testHKLFilterAnd() { + boost::shared_ptr<const MockHKLFilter> lhs(new MockHKLFilter); + EXPECT_CALL(*lhs, isAllowed(_)) + .WillOnce(Return(true)) + .WillOnce(Return(false)) + .WillOnce(Return(true)); + + boost::shared_ptr<const MockHKLFilter> rhs(new MockHKLFilter); + EXPECT_CALL(*rhs, isAllowed(_)) + .WillOnce(Return(true)) + .WillOnce(Return(false)); + + HKLFilterAnd andFilter(lhs, rhs); + + TS_ASSERT_EQUALS(andFilter.isAllowed(V3D(1, 1, 1)), true); + TS_ASSERT_EQUALS(andFilter.isAllowed(V3D(1, 1, 1)), false); + TS_ASSERT_EQUALS(andFilter.isAllowed(V3D(1, 1, 1)), false); + + TS_ASSERT(Mock::VerifyAndClearExpectations( + boost::const_pointer_cast<MockHKLFilter>(lhs).get())); + TS_ASSERT(Mock::VerifyAndClearExpectations( + boost::const_pointer_cast<MockHKLFilter>(rhs).get())); + } + + void testHKLFilterAndOperator() { + HKLFilter_const_sptr lhs = boost::make_shared<MockHKLFilter>(); + HKLFilter_const_sptr rhs = boost::make_shared<MockHKLFilter>(); + + HKLFilter_const_sptr andFilter = lhs & rhs; + + boost::shared_ptr<const HKLFilterAnd> andFilterCasted = + boost::dynamic_pointer_cast<const HKLFilterAnd>(andFilter); + + TS_ASSERT(andFilterCasted); + + TS_ASSERT_EQUALS(andFilterCasted->getLHS(), lhs); + TS_ASSERT_EQUALS(andFilterCasted->getRHS(), rhs); + } + + void testHKLFilterOr() { + boost::shared_ptr<const MockHKLFilter> lhs(new MockHKLFilter); + EXPECT_CALL(*lhs, isAllowed(_)) + .WillOnce(Return(true)) + .WillOnce(Return(false)) + .WillOnce(Return(true)) + .WillOnce(Return(false)); + + boost::shared_ptr<const MockHKLFilter> rhs(new MockHKLFilter); + EXPECT_CALL(*rhs, isAllowed(_)) + .WillOnce(Return(false)) + .WillOnce(Return(true)); + + HKLFilterOr orFilter(lhs, rhs); + + TS_ASSERT_EQUALS(orFilter.isAllowed(V3D(1, 1, 1)), true); + TS_ASSERT_EQUALS(orFilter.isAllowed(V3D(1, 1, 1)), false); + TS_ASSERT_EQUALS(orFilter.isAllowed(V3D(1, 1, 1)), true); + TS_ASSERT_EQUALS(orFilter.isAllowed(V3D(1, 1, 1)), true); + + TS_ASSERT(Mock::VerifyAndClearExpectations( + boost::const_pointer_cast<MockHKLFilter>(lhs).get())); + TS_ASSERT(Mock::VerifyAndClearExpectations( + boost::const_pointer_cast<MockHKLFilter>(rhs).get())); + } + + void testHKLFilterOrOperator() { + HKLFilter_const_sptr lhs = boost::make_shared<MockHKLFilter>(); + HKLFilter_const_sptr rhs = boost::make_shared<MockHKLFilter>(); + + HKLFilter_const_sptr orFilter = lhs | rhs; + + boost::shared_ptr<const HKLFilterOr> orFilterCasted = + boost::dynamic_pointer_cast<const HKLFilterOr>(orFilter); + + TS_ASSERT(orFilterCasted); + + TS_ASSERT_EQUALS(orFilterCasted->getLHS(), lhs); + TS_ASSERT_EQUALS(orFilterCasted->getRHS(), rhs); + } + +private: + class MockHKLFilter : public HKLFilter { + public: + MOCK_CONST_METHOD0(getDescription, std::string()); + MOCK_CONST_METHOD1(isAllowed, bool(const V3D &)); + }; + + class MockHKLFilterUnaryLogicOperation : public HKLFilterUnaryLogicOperation { + public: + MockHKLFilterUnaryLogicOperation(const HKLFilter_const_sptr &filter) + : HKLFilterUnaryLogicOperation(filter) {} + + MOCK_CONST_METHOD0(getDescription, std::string()); + MOCK_CONST_METHOD1(isAllowed, bool(const V3D &)); + }; + + class MockHKLFilterBinaryLogicOperation + : public HKLFilterBinaryLogicOperation { + public: + MockHKLFilterBinaryLogicOperation(const HKLFilter_const_sptr &lhs, + const HKLFilter_const_sptr &rhs) + : HKLFilterBinaryLogicOperation(lhs, rhs) {} + + MOCK_CONST_METHOD0(getDescription, std::string()); + MOCK_CONST_METHOD1(isAllowed, bool(const V3D &)); + }; +}; +#endif /* MANTID_GEOMETRY_HKLFILTERTEST_H_ */ diff --git a/Framework/Geometry/test/HKLGeneratorTest.h b/Framework/Geometry/test/HKLGeneratorTest.h new file mode 100644 index 0000000000000000000000000000000000000000..f6cffd236d46002b8dac782b7defd1f04d12bc89 --- /dev/null +++ b/Framework/Geometry/test/HKLGeneratorTest.h @@ -0,0 +1,98 @@ +#ifndef MANTID_GEOMETRY_HKLGENERATORTEST_H_ +#define MANTID_GEOMETRY_HKLGENERATORTEST_H_ + +#include <cxxtest/TestSuite.h> +#include "MantidGeometry/Crystal/HKLGenerator.h" + +using namespace Mantid::Geometry; +using namespace Mantid::Kernel; + +class HKLGeneratorTest : 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 HKLGeneratorTest *createSuite() { return new HKLGeneratorTest(); } + static void destroySuite(HKLGeneratorTest *suite) { delete suite; } + + void test_HKLGeneratorReturnsCorrectSizeSymmetricInt() { + HKLGenerator gen(2, 2, 2); + + TS_ASSERT_EQUALS(gen.size(), 125); + } + + void test_HKLGeneratorReturnsCorrectSizeSymmetricV3D() { + HKLGenerator gen(V3D(2, 2, 2)); + + TS_ASSERT_EQUALS(gen.size(), 125); + } + + void test_HKLGeneratorReturnsCorrectSizeAsymmetricV3D() { + HKLGenerator gen(V3D(-2, -1, -5), V3D(3, 4, -2)); + + TS_ASSERT_EQUALS(gen.size(), 144); + } + + void test_HKLGeneratorReturnsCorrectSizeOne() { + HKLGenerator gen(V3D(-2, -1, -5), V3D(-2, -1, -5)); + TS_ASSERT_EQUALS(gen.size(), 1); + } + + void test_beginIterator() { + HKLGenerator gen(V3D(-2, -2, -3), V3D(1, 1, 0)); + + HKLGenerator::const_iterator it = gen.begin(); + TS_ASSERT_EQUALS(*it, V3D(-2, -2, -3)); + } + + void test_endIterator() { + HKLGenerator gen(V3D(-2, -2, -3), V3D(1, 1, 0)); + + HKLGenerator::const_iterator it = gen.end(); + TS_ASSERT_EQUALS(*it, V3D(2, -2, -3)); + } + + void test_iterator_dereference() { + HKLGenerator::const_iterator it; + TS_ASSERT_EQUALS(*it, V3D(0, 0, 0)); + } + + void test_comparison() { + HKLGenerator::const_iterator it1(V3D(-2, -3, 1)); + HKLGenerator::const_iterator it2(V3D(-2, -3, 1)); + HKLGenerator::const_iterator it3(V3D(-2, -3, 0)); + + TS_ASSERT_EQUALS(it1, it2); + TS_ASSERT_DIFFERS(it1, it3); + } + + void test_iterator_increment() { + HKLGenerator::const_iterator defaultIterator; + TS_ASSERT_THROWS_NOTHING(++defaultIterator); + } + + void test_iterator_dereference_range() { + HKLGenerator::const_iterator it(V3D(-1, -1, -1), V3D(1, 1, 1)); + TS_ASSERT_EQUALS(*it, V3D(-1, -1, -1)); + ++it; + TS_ASSERT_EQUALS(*it, V3D(-1, -1, 0)); + } + + void test_hkl_range() { + HKLGenerator::const_iterator it(V3D(-1, -1, -1), V3D(1, 1, 1)); + HKLGenerator::const_iterator end(V3D(2, -1, -1)); + + std::vector<V3D> hkls; + std::copy(it, end, std::back_inserter(hkls)); + + TS_ASSERT_EQUALS(hkls.size(), 27); + TS_ASSERT_EQUALS(hkls[0], V3D(-1, -1, -1)); + TS_ASSERT_EQUALS(hkls[1], V3D(-1, -1, 0)); + TS_ASSERT_EQUALS(hkls[2], V3D(-1, -1, 1)); + TS_ASSERT_EQUALS(hkls[3], V3D(-1, 0, -1)); + TS_ASSERT_EQUALS(hkls[26], V3D(1, 1, 1)); + + TS_ASSERT_EQUALS(std::distance(it, end), 27); + } +}; + +#endif /* MANTID_GEOMETRY_HKLGENERATORTEST_H_ */ diff --git a/Framework/Geometry/test/IsotropicAtomBraggScattererTest.h b/Framework/Geometry/test/IsotropicAtomBraggScattererTest.h index 446c8b567157fc0972d92ccd3a8e92837069577e..0854c3a3d7d39509a1f8f77b10668c28b0920379 100644 --- a/Framework/Geometry/test/IsotropicAtomBraggScattererTest.h +++ b/Framework/Geometry/test/IsotropicAtomBraggScattererTest.h @@ -4,7 +4,6 @@ #include <cxxtest/TestSuite.h> #include "MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h" -#include "MantidGeometry/Crystal/SpaceGroupFactory.h" using namespace Mantid::Geometry; using namespace Mantid::Kernel; @@ -31,7 +30,6 @@ public: TS_ASSERT_THROWS_NOTHING(scatterer->initialize()); TS_ASSERT(scatterer->existsProperty("Position")); - TS_ASSERT(scatterer->existsProperty("SpaceGroup")); TS_ASSERT(scatterer->existsProperty("UnitCell")); TS_ASSERT(scatterer->existsProperty("U")); TS_ASSERT(scatterer->existsProperty("Element")); @@ -88,27 +86,22 @@ public: void testClone() { UnitCell cell(5.43, 5.43, 5.43); - SpaceGroup_const_sptr spaceGroup = - SpaceGroupFactory::Instance().createSpaceGroup("P m -3 m"); IsotropicAtomBraggScatterer_sptr scatterer = getInitializedScatterer("H", "[1, 0, 0]", 0.0); scatterer->setProperty("U", 3.04); scatterer->setProperty("Occupancy", 0.5); scatterer->setProperty("UnitCell", unitCellToStr(cell)); - scatterer->setProperty("SpaceGroup", spaceGroup->hmSymbol()); BraggScatterer_sptr baseclone = scatterer->clone(); BraggScattererInCrystalStructure_sptr clone = boost::dynamic_pointer_cast<BraggScattererInCrystalStructure>( baseclone); - TS_ASSERT(clone) + TS_ASSERT(clone); TS_ASSERT_EQUALS(clone->getPosition(), scatterer->getPosition()); TS_ASSERT_EQUALS(clone->getCell().getG(), scatterer->getCell().getG()); - TS_ASSERT_EQUALS(clone->getSpaceGroup()->hmSymbol(), - scatterer->getSpaceGroup()->hmSymbol()); IsotropicAtomBraggScatterer_sptr scattererClone = boost::dynamic_pointer_cast<IsotropicAtomBraggScatterer>(clone); @@ -154,50 +147,70 @@ public: TS_ASSERT_EQUALS(structureFactor.real(), bSi * 0.5 * 0.96708061593352515459); - // Set a space group with F-centering - SpaceGroup_const_sptr spaceGroup = - SpaceGroupFactory::Instance().createSpaceGroup("F m -3 m"); - scatterer->setProperty("SpaceGroup", spaceGroup->hmSymbol()); - - /* Now there are 4 equivalent positions, the contributions cancel out for - *(1, 0, 0) - * scalar products are: - * (1,0,0) * (0,0,0) = (1*0 + 1*0 + 1*0) = 0 cos(0) = 1, sin(0) - *= 0 - * (1,0,0) * (0,0.5,0.5) = (1*0 + 0*0.5 + 0*0.5) = 0 cos(0) = 1, sin(0) - *= 0 + /* Assume a space group with F centering. + * + * Now there are 4 equivalent positions, the contributions cancel out for + * (1, 0, 0) + * The scalar products are: + * (1,0,0) * (0,0,0) = (1*0 + 1*0 + 1*0) = 0 cos(0) = 1, + * sin(0) = 0 + * (1,0,0) * (0,0.5,0.5) = (1*0 + 0*0.5 + 0*0.5) = 0 cos(0) = 1, + * sin(0) = 0 * (1,0,0) * (0.5,0,0.5) = (1*0.5 + 0*0 + 0*0.5) = 0.5 cos(pi) = -1, - *sin(pi) = 0 + * sin(pi) = 0 * (1,0,0) * (0.5,0.5,0) = (1*0.5 + 0*0.5 + 0*0) = 0.5 cos(pi) = -1, - *sin(pi) = 0 + * sin(pi) = 0 * * That means 1 * real + 1 * real + (-1 * real) + (-1 * real) = 0 */ - structureFactor = scatterer->calculateStructureFactor(hkl); + StructureFactor totalStructureFactorForbidden; + + scatterer->setProperty("Position", "[0, 0, 0]"); + totalStructureFactorForbidden += scatterer->calculateStructureFactor(hkl); + + scatterer->setProperty("Position", "[0, 0.5, 0.5]"); + totalStructureFactorForbidden += scatterer->calculateStructureFactor(hkl); + + scatterer->setProperty("Position", "[0.5, 0, 0.5]"); + totalStructureFactorForbidden += scatterer->calculateStructureFactor(hkl); + + scatterer->setProperty("Position", "[0.5, 0.5, 0]"); + totalStructureFactorForbidden += scatterer->calculateStructureFactor(hkl); // It's not always exactly 0 (floating point math), but should not be less - // than 0 - TS_ASSERT_LESS_THAN(structureFactor.real(), 1e-9); - TS_ASSERT_LESS_THAN_EQUALS(0, structureFactor.real()); + TS_ASSERT_LESS_THAN(totalStructureFactorForbidden.real(), 1e-9); + TS_ASSERT_LESS_THAN_EQUALS(0, totalStructureFactorForbidden.real()); // For (1, 1, 1), the value is defined hkl = V3D(1, 1, 1); - structureFactor = scatterer->calculateStructureFactor(hkl); + + StructureFactor totalStructureFactorAllowed; + scatterer->setProperty("Position", "[0, 0, 0]"); + totalStructureFactorAllowed += scatterer->calculateStructureFactor(hkl); + + scatterer->setProperty("Position", "[0, 0.5, 0.5]"); + totalStructureFactorAllowed += scatterer->calculateStructureFactor(hkl); + + scatterer->setProperty("Position", "[0.5, 0, 0.5]"); + totalStructureFactorAllowed += scatterer->calculateStructureFactor(hkl); + + scatterer->setProperty("Position", "[0.5, 0.5, 0]"); + totalStructureFactorAllowed += scatterer->calculateStructureFactor(hkl); /* scalar products are: - * (1,1,1) * (0,0,0) = (1*0 + 1*0 + 1*0) = 0 cos(0) = 1, sin(0) = - *0 + * (1,1,1) * (0,0,0) = (1*0 + 1*0 + 1*0) = 0 cos(0) = 1 + * sin(0) = 0 * (1,1,1) * (0,0.5,0.5) = (1*0 + 1*0.5 + 1*0.5) = 1 cos(2pi) = 1, - *sin(2pi) = 0 + * sin(2pi) = 0 * (1,1,1) * (0.5,0,0.5) = (1*0.5 + 1*0 + 1*0.5) = 1 cos(2pi) = 1, - *sin(2pi) = 0 + * sin(2pi) = 0 * (1,1,1) * (0.5,0.5,0) = (1*0.5 + 1*0.5 + 1*0) = 1 cos(2pi) = 1, - *sin(2pi) = 0 + * sin(2pi) = 0 * * That means 4 * real * debye waller * occupation. d = 3.13... */ - TS_ASSERT_DELTA(structureFactor.real(), - 4.0 * bSi * 0.90445723107190849637 * 0.5, 5e-16) + TS_ASSERT_DELTA(totalStructureFactorAllowed.real(), + 4.0 * bSi * 0.90445723107190849637 * 0.5, 5e-16); } private: diff --git a/Framework/Geometry/test/ReflectionGeneratorTest.h b/Framework/Geometry/test/ReflectionGeneratorTest.h new file mode 100644 index 0000000000000000000000000000000000000000..9c3da2883aa0664fbd38315122247b895a5123cf --- /dev/null +++ b/Framework/Geometry/test/ReflectionGeneratorTest.h @@ -0,0 +1,126 @@ +#ifndef MANTID_GEOMETRY_REFLECTIONGENERATORTEST_H_ +#define MANTID_GEOMETRY_REFLECTIONGENERATORTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidGeometry/Crystal/ReflectionGenerator.h" +#include "MantidGeometry/Crystal/BasicHKLFilters.h" + +using namespace Mantid::Geometry; +using namespace Mantid::Kernel; + +class ReflectionGeneratorTest : 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 ReflectionGeneratorTest *createSuite() { + return new ReflectionGeneratorTest(); + } + static void destroySuite(ReflectionGeneratorTest *suite) { delete suite; } + + void test_getUniqueHKLs() { + double dMin = 0.55; + double dMax = 4.0; + + ReflectionGenerator generator( + CrystalStructure("4.126 4.126 4.126", "P m -3 m", "Si 0 0 0 1.0 0.01"), + ReflectionConditionFilter::Centering); + + TS_ASSERT_THROWS_NOTHING(generator.getUniqueHKLs(dMin, dMax)); + + std::vector<V3D> peaks = generator.getUniqueHKLs(dMin, dMax); + + TS_ASSERT_EQUALS(peaks.size(), 68); + TS_ASSERT_EQUALS(peaks[0], V3D(1, 1, 0)); + TS_ASSERT_EQUALS(peaks[11], V3D(3, 2, 0)); + TS_ASSERT_EQUALS(peaks[67], V3D(7, 2, 1)); + + // make d-value list and check that peaks are within limits + std::vector<double> peaksD = generator.getDValues(peaks); + + std::sort(peaksD.begin(), peaksD.end()); + + TS_ASSERT_LESS_THAN_EQUALS(dMin, peaksD.front()); + TS_ASSERT_LESS_THAN_EQUALS(peaksD.back(), dMax); + } + + void test_getHKLs() { + double dMin = 0.55; + double dMax = 4.0; + + // make a structure with P-1 + ReflectionGenerator generator( + CrystalStructure("4.126 4.126 4.126", "P -1", "Si 0 0 0 1.0 0.01"), + ReflectionConditionFilter::Centering); + + std::vector<V3D> unique = generator.getUniqueHKLs(dMin, dMax); + std::vector<V3D> peaks = generator.getHKLs(dMin, dMax); + + // Because of symmetry -1, each reflection has multiplicity 2. + TS_ASSERT_EQUALS(peaks.size(), 2 * unique.size()); + } + + void test_getDValues() { + std::vector<V3D> hkls; + hkls.push_back(V3D(1, 0, 0)); + hkls.push_back(V3D(0, 1, 0)); + hkls.push_back(V3D(0, 0, 1)); + + ReflectionGenerator generator( + CrystalStructure("2 3 5", "P -1", "Si 0 0 0 1.0 0.01")); + std::vector<double> dValues = generator.getDValues(hkls); + + TS_ASSERT_EQUALS(dValues.size(), hkls.size()); + TS_ASSERT_EQUALS(dValues[0], 2.0); + TS_ASSERT_EQUALS(dValues[1], 3.0); + TS_ASSERT_EQUALS(dValues[2], 5.0); + } + + void test_getUniqueHKLsStructureFactor() { + CrystalStructure si("5.43 5.43 5.43", "F m -3 m", + "Si 0.3 0.3 0.3 1.0 0.05"); + + ReflectionGenerator generator(si, + ReflectionConditionFilter::StructureFactor); + + std::vector<V3D> hklsCentering = generator.getUniqueHKLs( + 0.6, 10.0, boost::make_shared<HKLFilterCentering>(si.centering())); + + std::vector<V3D> hklsStructureFactors = generator.getUniqueHKLs(0.6, 10.0); + + TS_ASSERT_EQUALS(hklsCentering.size(), hklsStructureFactors.size()); + + for (size_t i = 0; i < hklsCentering.size(); ++i) { + TS_ASSERT_EQUALS(hklsCentering[i], hklsStructureFactors[i]); + } + } + + void test_getUniqueHKLsHexagonal() { + ReflectionGenerator generator( + CrystalStructure("3.2094 3.2094 5.2108 90.0 90.0 120.0", "P 63/m m c", + "Mg 1/3 2/3 1/4 1.0 0.005"), + ReflectionConditionFilter::StructureFactor); + + std::vector<V3D> hkls = generator.getUniqueHKLs(0.5, 10.0); + + TS_ASSERT_EQUALS(hkls.size(), 88); + + std::vector<double> dValues = generator.getDValues(hkls); + for (size_t i = 0; i < hkls.size(); ++i) { + TS_ASSERT_LESS_THAN(0.5, dValues[i]); + } + } + + void test_getUniqueHKLsTrigonal() { + ReflectionGenerator generator( + CrystalStructure("4.759355 4.759355 12.99231 90.0 90.0 120.0", "R -3 c", + "Al 0 0 0.35217 1.0 0.005; O 0.69365 0 1/4 1.0 0.005"), + ReflectionConditionFilter::StructureFactor); + + std::vector<V3D> hkls = generator.getUniqueHKLs(0.885, 10.0); + + TS_ASSERT_EQUALS(hkls.size(), 44); + } +}; + +#endif /* MANTID_GEOMETRY_REFLECTIONGENERATORTEST_H_ */ diff --git a/Framework/Geometry/test/StructureFactorCalculatorSummationTest.h b/Framework/Geometry/test/StructureFactorCalculatorSummationTest.h new file mode 100644 index 0000000000000000000000000000000000000000..a1ce3c9670a57b3edd0cd2dd6302d8c27c3a33bf --- /dev/null +++ b/Framework/Geometry/test/StructureFactorCalculatorSummationTest.h @@ -0,0 +1,75 @@ +#ifndef MANTID_GEOMETRY_STRUCTUREFACTORCALCULATORSUMMATIONTEST_H_ +#define MANTID_GEOMETRY_STRUCTUREFACTORCALCULATORSUMMATIONTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidGeometry/Crystal/StructureFactorCalculatorSummation.h" + +#include "MantidGeometry/Crystal/BraggScattererFactory.h" +#include "MantidGeometry/Crystal/SpaceGroupFactory.h" + +using namespace Mantid::Geometry; +using namespace Mantid::Kernel; + +class StructureFactorCalculatorSummationTest : 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 StructureFactorCalculatorSummationTest *createSuite() { + return new StructureFactorCalculatorSummationTest(); + } + static void destroySuite(StructureFactorCalculatorSummationTest *suite) { + delete suite; + } + + void testEquivalentPositionsAreUsed() { + // Approximate crystal structure of Silicon + CrystalStructure si = getCrystalStructure(); + + StructureFactorCalculatorSummation calculator; + calculator.setCrystalStructure(si); + + // {1 0 0} reflections are not allowed because of F centering + TS_ASSERT_LESS_THAN(calculator.getFSquared(V3D(1, 0, 0)), 1e-9); + + // {2 2 2} is forbidden because of Si on special position + TS_ASSERT_LESS_THAN(calculator.getFSquared(V3D(2, 2, 2)), 1e-9); + + // With space group P-1, those are allowed. + si.setSpaceGroup(SpaceGroupFactory::Instance().createSpaceGroup("P -1")); + + calculator.setCrystalStructure(si); + // {1 0 0} reflections are not allowed because of F centering + TS_ASSERT_LESS_THAN(1e-9, calculator.getFSquared(V3D(1, 0, 0))); + + // {2 2 2} is forbidden because of Si on special position + TS_ASSERT_LESS_THAN(1e-9, calculator.getFSquared(V3D(2, 2, 2))); + } + + void testCreateWithFactory() { + CrystalStructure si = getCrystalStructure(); + + StructureFactorCalculator_sptr calculator = + StructureFactorCalculatorFactory::create< + StructureFactorCalculatorSummation>(si); + + // same reflections as in testEquivalentPositionsAreUsed + TS_ASSERT_LESS_THAN(calculator->getFSquared(V3D(1, 0, 0)), 1e-9); + TS_ASSERT_LESS_THAN(calculator->getFSquared(V3D(2, 2, 2)), 1e-9); + } + +private: + CrystalStructure getCrystalStructure() { + CompositeBraggScatterer_sptr scatterers = CompositeBraggScatterer::create(); + scatterers->addScatterer(BraggScattererFactory::Instance().createScatterer( + "IsotropicAtomBraggScatterer", "Element=Si;Position=[0,0,0];U=0.05")); + + CrystalStructure si( + UnitCell(5.43, 5.43, 5.43), + SpaceGroupFactory::Instance().createSpaceGroup("F d -3 m"), scatterers); + + return si; + } +}; + +#endif /* MANTID_GEOMETRY_STRUCTUREFACTORCALCULATORSUMMATIONTEST_H_ */ diff --git a/Framework/Geometry/test/StructureFactorCalculatorTest.h b/Framework/Geometry/test/StructureFactorCalculatorTest.h new file mode 100644 index 0000000000000000000000000000000000000000..72421449f7132c3b281a0f7873be91431a052d59 --- /dev/null +++ b/Framework/Geometry/test/StructureFactorCalculatorTest.h @@ -0,0 +1,107 @@ +#ifndef MANTID_GEOMETRY_STRUCTUREFACTORCALCULATORTEST_H_ +#define MANTID_GEOMETRY_STRUCTUREFACTORCALCULATORTEST_H_ + +#include <cxxtest/TestSuite.h> +#include <gtest/gtest.h> +#include <gmock/gmock.h> + +#include "MantidGeometry/Crystal/StructureFactorCalculator.h" +#include "MantidGeometry/Crystal/SpaceGroupFactory.h" + +using namespace Mantid::Geometry; +using namespace Mantid::Kernel; +using ::testing::Mock; +using ::testing::_; +using ::testing::Return; + +class StructureFactorCalculatorTest : 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 StructureFactorCalculatorTest *createSuite() { + return new StructureFactorCalculatorTest(); + } + static void destroySuite(StructureFactorCalculatorTest *suite) { + delete suite; + } + + void testCrystalStructureSetHookIsCalled() { + CrystalStructure cs(UnitCell(1, 2, 3), + SpaceGroupFactory::Instance().createSpaceGroup("P -1"), + CompositeBraggScatterer::create()); + + MockStructureFactorCalculator calculator; + EXPECT_CALL(calculator, crystalStructureSetHook(_)).Times(1); + + calculator.setCrystalStructure(cs); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&calculator)); + } + + void testGetFSquared() { + MockStructureFactorCalculator calculator; + + EXPECT_CALL(calculator, getF(_)) + .WillRepeatedly(Return(StructureFactor(2.21, 3.1))); + + // Check that the square of 2.21 + i * 3.1 is returned + TS_ASSERT_DELTA(calculator.getFSquared(V3D()), 14.4941, 1e-15); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&calculator)); + } + + void testGetFs() { + MockStructureFactorCalculator calculator; + + int numHKLs = 10; + EXPECT_CALL(calculator, getF(_)) + .Times(numHKLs) + .WillRepeatedly(Return(StructureFactor(2.0, 2.0))); + + std::vector<V3D> hkls(numHKLs); + std::vector<StructureFactor> sfs = calculator.getFs(hkls); + + TS_ASSERT_EQUALS(sfs.size(), hkls.size()); + + for (auto sf = sfs.begin(); sf != sfs.end(); ++sf) { + TS_ASSERT_EQUALS(*sf, StructureFactor(2.0, 2.0)); + } + + TS_ASSERT(Mock::VerifyAndClearExpectations(&calculator)); + } + + void testGetFsSquared() { + MockStructureFactorCalculator calculator; + + int numHKLs = 10; + EXPECT_CALL(calculator, getF(_)) + .Times(numHKLs) + .WillRepeatedly(Return(StructureFactor(2.0, 2.0))); + + std::vector<V3D> hkls(numHKLs); + std::vector<double> sfsSquared = calculator.getFsSquared(hkls); + + TS_ASSERT_EQUALS(sfsSquared.size(), hkls.size()); + + for (auto sf = sfsSquared.begin(); sf != sfsSquared.end(); ++sf) { + TS_ASSERT_EQUALS(*sf, 8.0); + } + + TS_ASSERT(Mock::VerifyAndClearExpectations(&calculator)); + } + +private: + /* This MockStructureFactorCalculator helps to test whether the + * default implementations of the virtual methods work correctly. + * Furthermore it is used to confirm that crystalStructureSetHook + * is called appropriately. + */ + class MockStructureFactorCalculator : public StructureFactorCalculator { + public: + MOCK_CONST_METHOD1(getF, StructureFactor(const V3D &hkl)); + MOCK_METHOD1(crystalStructureSetHook, + void(const CrystalStructure &crystalStructure)); + }; +}; + +#endif /* MANTID_GEOMETRY_STRUCTUREFACTORCALCULATORTEST_H_ */ diff --git a/Framework/ICat/src/GSoap/stdsoap2.cpp b/Framework/ICat/src/GSoap/stdsoap2.cpp index ec26daa1e2e5e4ba9c1137565e6c2f1d5d763e28..252bc7ae6514f1f8380bd35f9c89fcc5e46abd54 100644 --- a/Framework/ICat/src/GSoap/stdsoap2.cpp +++ b/Framework/ICat/src/GSoap/stdsoap2.cpp @@ -2348,7 +2348,7 @@ int SOAP_FMAC2 soap_resolve(struct soap *soap) { } else if (*ip->id == '#') { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Missing data for id='%s'\n", ip->id)); - strcpy(soap->id, ip->id + 1); + strncpy(soap->id, ip->id + 1, sizeof(soap->id)); return soap->error = SOAP_MISSING_ID; } } @@ -2386,7 +2386,7 @@ int SOAP_FMAC2 soap_resolve(struct soap *soap) { "location=%p level=%u,%u id='%s'\n", ip->type, p, ip->level, fp->level, ip->id)); while (ip->level < k) { - void **q = (void **)soap_malloc(soap, sizeof(q)); + void **q = (void **)soap_malloc(soap, sizeof(*q)); if (!q) return soap->error; *q = p; @@ -3207,7 +3207,7 @@ const char *SOAP_FMAC2 soap_ssl_error(struct soap *soap, int ret) { int err = SSL_get_error(soap->ssl, ret); const char *msg = soap_code_str(h_ssl_error_codes, err); if (msg) - strcpy(soap->msgbuf, msg); + strncpy(soap->msgbuf, msg, sizeof(soap->msgbuf)); else return ERR_error_string(err, soap->msgbuf); if (ERR_peek_error()) { @@ -6049,7 +6049,7 @@ static int http_post(struct soap *soap, const char *endpoint, const char *host, sprintf(soap->tmpbuf, "[%s]", host); /* RFC 2732 */ else #endif - strcpy(soap->tmpbuf, host); + strncpy(soap->tmpbuf, host, sizeof(soap->tmpbuf)); } if ((err = soap->fposthdr(soap, "Host", soap->tmpbuf))) return err; @@ -8161,7 +8161,7 @@ void *SOAP_FMAC2 soap_id_lookup(struct soap *soap, const char *id, void **p, "Resolved href='%s' type=%d location=%p (%u bytes)\n", id, t, ip->ptr, (unsigned int)n)); if (ip->type != t) { - strcpy(soap->id, id); + strncpy(soap->id, id, sizeof(soap->id)); soap->error = SOAP_HREF; DBGLOG(TEST, SOAP_MESSAGE( @@ -8188,9 +8188,11 @@ void *SOAP_FMAC2 soap_id_lookup(struct soap *soap, const char *id, void **p, void *s, **r = &ip->link; q = (void **)ip->link; while (q) { - *r = (void *)soap_malloc(soap, sizeof(void *)); - if (!*r) + void **tmp = (void **)soap_malloc(soap, sizeof(void *)); + if (!tmp) return NULL; + *r = (void *)tmp; + s = *q; *q = *r; r = (void **)*r; @@ -8263,7 +8265,7 @@ void *SOAP_FMAC2 soap_id_forward(struct soap *soap, const char *href, void *p, "size=%lu level=%u got type=%d size=%lu\n", href, ip->type, (unsigned long)ip->size, k, st, (unsigned long)n)); - strcpy(soap->id, href); + strncpy(soap->id, href, sizeof(soap->id)); soap->error = SOAP_HREF; return NULL; } @@ -8355,12 +8357,12 @@ soap_id_enter(struct soap *soap, const char *id, void *p, int t, size_t n, "size=%lu level=%u got type=%d size=%lu\n", id, ip->type, (unsigned long)ip->size, k, t, (unsigned long)n)); - strcpy(soap->id, id); + strncpy(soap->id, id, sizeof(soap->id)); soap->error = SOAP_HREF; return NULL; } else if (ip->ptr) { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Multiply defined id='%s'\n", id)); - strcpy(soap->id, id); + strncpy(soap->id, id, sizeof(soap->id)); soap->error = SOAP_DUPLICATE_ID; return NULL; } else { @@ -10040,7 +10042,7 @@ int SOAP_FMAC2 soap_element_start_end_out(struct soap *soap, const char *tag) { if (soap->mode & SOAP_XML_CANONICAL) { struct soap_nlist *np; for (tp = soap->attributes; tp; tp = tp->next) { - if (tp->visible && tp->name) + if (tp->visible && tp->name[0]) soap_utilize_ns(soap, tp->name); } for (np = soap->nlist; np; np = np->next) { @@ -11048,7 +11050,7 @@ int SOAP_FMAC2 soap_peek_element(struct soap *soap) { soap->arraySize[sizeof(soap->arrayType) - 1] = '\0'; soap->arrayType[sizeof(soap->arrayType) - 1] = '\0'; } else if (!soap_match_tag(soap, tp->name, "SOAP-ENC:offset")) - strncpy(soap->arrayOffset, tp->value, sizeof(soap->arrayOffset)); + strncpy(soap->arrayOffset, tp->value, sizeof(soap->arrayOffset) - 1); else if (!soap_match_tag(soap, tp->name, "SOAP-ENC:position")) soap->position = soap_getposition(tp->value, soap->positions); else if (!soap_match_tag(soap, tp->name, "SOAP-ENC:root")) @@ -16060,18 +16062,24 @@ int SOAP_FMAC2 soap_puthttphdr(struct soap *soap, int status, size_t count) { } else strcat(soap->tmpbuf, s); if (soap->mime.start) { - strcat(soap->tmpbuf, "\"; start=\""); - strcat(soap->tmpbuf, soap->mime.start); + const char startStr[] = "\"; start=\""; + strcat(soap->tmpbuf, startStr); + strncat(soap->tmpbuf, soap->mime.start, + sizeof(soap->tmpbuf) - sizeof(startStr)); } strcat(soap->tmpbuf, "\""); if (r) { - strcat(soap->tmpbuf, "; start-info=\""); - strcat(soap->tmpbuf, r); - strcat(soap->tmpbuf, "\""); + const char startInfoStr[] = "; start-info=\""; + size_t lenStart = sizeof(soap->tmpbuf) - sizeof(startInfoStr); + strncat(soap->tmpbuf, startInfoStr, lenStart); + size_t lenR = lenStart - strnlen(r, lenStart); + strncat(soap->tmpbuf, r, lenR); + size_t lenEnd = lenR - 1; + strncat(soap->tmpbuf, "\"", lenEnd); } s = soap->tmpbuf; } else - s = strcpy(soap->tmpbuf, s); + s = strncpy(soap->tmpbuf, s, sizeof(soap->tmpbuf)); if (status == SOAP_OK && soap->version == 2 && soap->action && strlen(soap->action) + strlen(s) < sizeof(soap->tmpbuf) - 80) sprintf(soap->tmpbuf + strlen(s), "; action=\"%s\"", soap->action); diff --git a/Framework/Kernel/inc/MantidKernel/PropertyManagerOwner.h b/Framework/Kernel/inc/MantidKernel/PropertyManagerOwner.h index 7a095862e9ce2aad426bcb01da21b7910b545aa2..ada32918cb12d35a2b41a9359cce28e8c18ca112 100644 --- a/Framework/Kernel/inc/MantidKernel/PropertyManagerOwner.h +++ b/Framework/Kernel/inc/MantidKernel/PropertyManagerOwner.h @@ -65,7 +65,9 @@ public: void setPropertyOrdinal(const int &index, const std::string &value); /// Make m_properties point to the same PropertyManager as po. - void copyPropertiesFrom(const PropertyManagerOwner &po) { *this = po; } + virtual void copyPropertiesFrom(const PropertyManagerOwner &po) { + *this = po; + } bool existsProperty(const std::string &name) const; bool validateProperties() const; diff --git a/Framework/Kernel/inc/MantidKernel/TimeSeriesProperty.h b/Framework/Kernel/inc/MantidKernel/TimeSeriesProperty.h index 46177e23dcdaaccdd8236528af0aacc35c87d13a..cf1df3f3df0a80b93e127d1c0f38b4778ef017c9 100644 --- a/Framework/Kernel/inc/MantidKernel/TimeSeriesProperty.h +++ b/Framework/Kernel/inc/MantidKernel/TimeSeriesProperty.h @@ -116,6 +116,11 @@ public: virtual ~TimeSeriesProperty(); /// "Virtual" copy constructor TimeSeriesProperty<TYPE> *clone() const; + // + /// Return time series property, containing time derivative of current + /// property + std::unique_ptr<TimeSeriesProperty<double>> getDerivative() const; + /// "Virtual" copy constructor with a time shift in seconds virtual Property *cloneWithTimeShift(const double timeShift) const; /// Return the memory used by the property, in bytes @@ -273,6 +278,11 @@ public: /// Stringize the property std::string toString() const; + /**Reserve memory for efficient adding values to existing property + * makes sense only when you have reasonably precise estimate of the + * total size you'll need easily available in advance. */ + void reserve(size_t size) { m_values.reserve(size); }; + private: /// Sort the property into increasing times void sort() const; diff --git a/Framework/Kernel/inc/MantidKernel/VectorHelper.h b/Framework/Kernel/inc/MantidKernel/VectorHelper.h index b1643b23acca49c8d9be328558d7e745338d3f79..489b6d1864b0407af065d5b6301f97c7d0980607 100644 --- a/Framework/Kernel/inc/MantidKernel/VectorHelper.h +++ b/Framework/Kernel/inc/MantidKernel/VectorHelper.h @@ -59,7 +59,7 @@ rebinHistogram(const std::vector<double> &xold, const std::vector<double> &yold, std::vector<double> &ynew, std::vector<double> &enew, bool addition); -/// Convert an array of bin boundaries to bin centre values. +/// Convert an array of bin boundaries to bin center values. void MANTID_KERNEL_DLL convertToBinCentre(const std::vector<double> &bin_edges, std::vector<double> &bin_centres); @@ -81,6 +81,15 @@ MANTID_KERNEL_DLL int getBinIndex(const std::vector<double> &bins, MANTID_KERNEL_DLL void linearlyInterpolateY(const std::vector<double> &x, std::vector<double> &y, const double stepSize); +// Do running average of input vector within specified range, considering +// heterogeneous bin-boundaries +// if such boundaries are provided +MANTID_KERNEL_DLL void +smoothInRange(const std::vector<double> &input, std::vector<double> &output, + double avrgInterval, + std::vector<double> const *const binBoundaris = NULL, + size_t startIndex = 0, size_t endIndex = 0, + std::vector<double> *const outputBinBoundaries = NULL); //------------------------------------------------------------------------------------- /** Return the length of the vector (in the physical sense), @@ -102,7 +111,7 @@ template <typename T> T scalar_prod(const std::vector<T> &v1, const std::vector<T> &v2) { if (v1.size() != v2.size()) throw std::invalid_argument(" scalar product is defined only for the " - "vectors of the equivalient length"); + "vectors of the equivalent length"); T total = 0; for (size_t i = 0; i < v1.size(); i++) total += v1[i] * v2[i]; @@ -153,7 +162,7 @@ template <class T> struct SumGaussError : public std::binary_function<T, T, T> { }; /** - * Functor to deal with the increase in the error when adding (or substracting) + * Functor to deal with the increase in the error when adding (or subtracting) * a number of counts. * More generally add errors in quadrature using the square of one of the errors * (variance = error^2) diff --git a/Framework/Kernel/src/ANN/kd_dump.cpp b/Framework/Kernel/src/ANN/kd_dump.cpp index 203a443249f79c5ed1a24aa84dcac9c33ae2d1b0..eb99a37d414ff2aaefaad18ba3f2f46450b7553c 100644 --- a/Framework/Kernel/src/ANN/kd_dump.cpp +++ b/Framework/Kernel/src/ANN/kd_dump.cpp @@ -34,6 +34,8 @@ #include "kd_tree.h" // kd-tree declarations #include "bd_tree.h" // bd-tree declarations +#include <limits> + using namespace std; // make std:: available //---------------------------------------------------------------------- @@ -332,6 +334,15 @@ annReadDump(istream &in, // input stream for (j = 0; j < the_dim; j++) { // read bounding box low in >> the_bnd_box_hi[j]; } + + if (0 > the_n_pts || + static_cast<size_t>(std::numeric_limits<int>::max()) <= + static_cast<size_t>(the_n_pts / sizeof(ANNidx))) { + annError("Too big number of elements for the point index array. This " + "would cause an overflow when allocating memory", + ANNabort); + } + the_pidx = new ANNidx[the_n_pts]; // allocate point index array int next_idx = 0; // number of indices filled // read the tree and indices @@ -429,6 +440,16 @@ static ANNkd_ptr annReadTree(istream &in, // input stream int n_bnds; // number of bounding sides in >> n_bnds; // number of bounding sides // allocate bounds array + + if (0 > n_bnds || + static_cast<size_t>(std::numeric_limits<int>::max()) <= + static_cast<size_t>(n_bnds / sizeof(ANNorthHalfSpace))) { + annError("Too big number of bounding sides, would cause overflow when " + "allocating memory", + ANNabort); + exit(0); + } + ANNorthHSArray bds = new ANNorthHalfSpace[n_bnds]; for (int i = 0; i < n_bnds; i++) { int sd; // which side diff --git a/Framework/Kernel/src/DateValidator.cpp b/Framework/Kernel/src/DateValidator.cpp index 2ff99628903731dcf38e75d971c67852a1f8c550..5362fb247e217211a577736781841c1057ccacfe 100644 --- a/Framework/Kernel/src/DateValidator.cpp +++ b/Framework/Kernel/src/DateValidator.cpp @@ -28,6 +28,9 @@ struct tm getTimeValue(const std::string &sDate, std::string &error) { timeinfo.tm_wday = 0; timeinfo.tm_yday = 0; timeinfo.tm_isdst = -1; +#ifndef _WIN32 + timeinfo.tm_gmtoff = 0; +#endif std::basic_string<char>::size_type index, off = 0; int day, month, year; diff --git a/Framework/Kernel/src/Matrix.cpp b/Framework/Kernel/src/Matrix.cpp index f4e1adc13197297776e06c33da66c50614498298..014284f04c4da6b769c33f2d1157cb0390e3f336 100644 --- a/Framework/Kernel/src/Matrix.cpp +++ b/Framework/Kernel/src/Matrix.cpp @@ -158,17 +158,20 @@ Matrix<T>::Matrix(const Matrix<T> &A, const size_t nrow, const size_t ncol) throw Kernel::Exception::IndexError(ncol, A.ny, "Matrix::Constructor without col"); setMem(nx, ny); - size_t iR(0); - for (size_t i = 0; i <= nx; i++) { - if (i != nrow) { - size_t jR(0); - for (size_t j = 0; j <= ny; j++) { - if (j != ncol) { - V[iR][jR] = A.V[i][j]; - jR++; + if (V) { + size_t iR(0); + for (size_t i = 0; i <= nx; i++) { + if (i != nrow) { + size_t jR(0); + for (size_t j = 0; j <= ny; j++) { + if (j != ncol) { + + V[iR][jR] = A.V[i][j]; + jR++; + } } + iR++; } - iR++; } } } diff --git a/Framework/Kernel/src/Strings.cpp b/Framework/Kernel/src/Strings.cpp index c2bf98bd5ac359c668662ad04aab5db601603e03..44225dc1dbceae906bef58ab08bda5b599d093aa 100644 --- a/Framework/Kernel/src/Strings.cpp +++ b/Framework/Kernel/src/Strings.cpp @@ -865,34 +865,49 @@ int setValues(const std::string &Line, const std::vector<int> &Index, * @return a string with the word read in */ std::string getWord(std::istream &in, bool consumeEOL) { - std::string s; - char c = 0; - if (in.good()) - for (c = static_cast<char>(in.get()); c == ' ' && in.good(); - c = static_cast<char>(in.get())) { + std::string ret; + char nextch = 0; + + // Skip leading spaces + do { + nextch = static_cast<char>(in.get()); + } while (nextch == ' '); + + // Return an empty string on EOL; optionally consume it + if (nextch == '\n' || nextch == '\r') { + if (!consumeEOL) { + in.unget(); + } else if ((nextch == '\n' && in.peek() == '\r') || + (nextch == '\r' && in.peek() == '\n')) { + // Handle CRLF and LFCR on Unix by consuming both + in.ignore(); } - else - return std::string(); - - if (c == '\n') { - if (!consumeEOL) - in.putback(c); - return std::string(); + return ret; + } else { // Non-EOL and non-space character + in.unget(); // Put it back on stream } - s.push_back(c); - + // Get next word if stream is still valid if (in.good()) - for (c = static_cast<char>(in.get()); - in.good() && c != ' ' && c != '\n' && c != '\r'; - c = static_cast<char>(in.get())) - s.push_back(c); + in >> ret; + + // Optionally consume EOL character + if (consumeEOL) { + nextch = static_cast<char>(in.get()); - if (((c == '\n') || (c == '\r')) && !consumeEOL) - in.putback(c); + // Handle CRLF and LFCR on Unix by consuming both + if (nextch == '\n' || nextch == '\r') { + if ((nextch == '\n' && in.peek() == '\r') || + (nextch == '\r' && in.peek() == '\n')) { + in.ignore(); + } + } else { + in.unget(); + } + } - return s; + return ret; } //----------------------------------------------------------------------------------------------- diff --git a/Framework/Kernel/src/TimeSeriesProperty.cpp b/Framework/Kernel/src/TimeSeriesProperty.cpp index 3cc831022f25f516b30603ebccbaca119f83f68f..f1a10e4b434adeb6455e9f99648ed6ac8673f76f 100644 --- a/Framework/Kernel/src/TimeSeriesProperty.cpp +++ b/Framework/Kernel/src/TimeSeriesProperty.cpp @@ -57,6 +57,54 @@ TimeSeriesProperty<TYPE>::cloneWithTimeShift(const double timeShift) const { return timeSeriesProperty; } +/** Return time series property, containing time derivative of current property. +* The property itself and the returned time derivative become sorted by time and +* the derivative is calculated in seconds^-1. +* (e.g. dValue/dT where dT=t2-t1 is time difference in seconds +* for subsequent time readings and dValue=Val1-Val2 is difference in +* subsequent values) +* +*/ +template <typename TYPE> +std::unique_ptr<TimeSeriesProperty<double>> +TimeSeriesProperty<TYPE>::getDerivative() const { + + if (this->m_values.size() < 2) { + throw std::runtime_error("Derivative is not defined for a time-series " + "property with less then two values"); + } + + this->sort(); + auto it = this->m_values.begin(); + int64_t t0 = it->time().totalNanoseconds(); + TYPE v0 = it->value(); + + it++; + auto timeSeriesDeriv = std::unique_ptr<TimeSeriesProperty<double>>( + new TimeSeriesProperty<double>(this->name() + "_derivative")); + timeSeriesDeriv->reserve(this->m_values.size() - 1); + for (; it != m_values.end(); it++) { + TYPE v1 = it->value(); + int64_t t1 = it->time().totalNanoseconds(); + if (t1 != t0) { + double deriv = 1.e+9 * (double(v1 - v0) / double(t1 - t0)); + int64_t tm = static_cast<int64_t>((t1 + t0) / 2); + timeSeriesDeriv->addValue(Kernel::DateAndTime(tm), deriv); + } + t0 = t1; + v0 = v1; + } + return timeSeriesDeriv; +} +/** time series derivative specialization for string type */ +template <> +std::unique_ptr<TimeSeriesProperty<double>> +TimeSeriesProperty<std::string>::getDerivative() const { + throw std::runtime_error( + "Time series property derivative is not defined for strings"); + // return nullptr; +} + /** * Return the memory used by the property, in bytes * */ diff --git a/Framework/Kernel/src/VectorHelper.cpp b/Framework/Kernel/src/VectorHelper.cpp index 61aedadfc83fefb11da536e3229170dc378d050e..52144d225aa4f454563c018cefb3c214ad817445 100644 --- a/Framework/Kernel/src/VectorHelper.cpp +++ b/Framework/Kernel/src/VectorHelper.cpp @@ -533,6 +533,164 @@ void linearlyInterpolateY(const std::vector<double> &x, std::vector<double> &y, step++; } } +namespace { +/** internal function converted from Lambda to identify interval around +* specified point and run average around this point +* +*@param index -- index to average around +*@param startIndex -- index in the array of data (input to start average +* from) should be: index>=startIndex>=0 +*@param endIndex -- index in the array of data (input to end average at) +* should be: index<=endIndex<=input.size() +*@param halfWidth -- half width of the interval to integrate. +*@param input -- vector of input signal +*@param binBndrs -- pointer to vector of bin boundaries or NULL pointer. + */ +double runAverage(size_t index, size_t startIndex, size_t endIndex, + const double halfWidth, const std::vector<double> &input, + std::vector<double> const *const binBndrs) { + + size_t iStart, iEnd; + double weight0(0), weight1(0), start, end; + // + if (binBndrs) { + // identify initial and final bins to + // integrate over. Notice the difference + // between start and end bin and shift of + // the interpolating function into the center + // of each bin + auto &rBndrs = *binBndrs; + // bin0 = binBndrs->operator[](index + 1) - binBndrs->operator[](index); + + double binC = 0.5 * (rBndrs[index + 1] + rBndrs[index]); + start = binC - halfWidth; + end = binC + halfWidth; + if (start <= rBndrs[startIndex]) { + iStart = startIndex; + start = rBndrs[iStart]; + } else { + iStart = getBinIndex(*binBndrs, start); + weight0 = + (rBndrs[iStart + 1] - start) / (rBndrs[iStart + 1] - rBndrs[iStart]); + iStart++; + } + if (end >= rBndrs[endIndex]) { + iEnd = endIndex; // the signal defined up to i<iEnd + end = rBndrs[endIndex]; + } else { + iEnd = getBinIndex(*binBndrs, end); + weight1 = (end - rBndrs[iEnd]) / (rBndrs[iEnd + 1] - rBndrs[iEnd]); + } + if (iStart > iEnd) { // start and end get into the same bin + weight1 = 0; + weight0 = (end - start) / (rBndrs[iStart] - rBndrs[iStart - 1]); + } + } else { // integer indexes and functions defined in the bin centers + auto iHalfWidth = static_cast<size_t>(halfWidth); + iStart = index - iHalfWidth; + if (startIndex + iHalfWidth > index) + iStart = startIndex; + iEnd = index + iHalfWidth; + if (iEnd > endIndex) + iEnd = endIndex; + } + + double avrg = 0; + size_t ic = 0; + for (size_t j = iStart; j < iEnd; j++) { + avrg += input[j]; + ic++; + } + if (binBndrs) { // add values at edges + if (iStart != startIndex) + avrg += input[iStart - 1] * weight0; + if (iEnd != endIndex) + avrg += input[iEnd] * weight1; + + return avrg / (end - start); + } else { + return avrg / double(ic); + } +} +} +/** Basic running average of input vector within specified range, considering +* variable bin-boundaries if such boundaries are provided. +* The algorithm performs trapezium integration, so some peak shift +* related to the first derivative of the integrated function can be observed. +* +* @param input:: input vector to smooth +* @param output:: resulting vector (can not coincide with input) +* @param avrgInterval:: the interval to average function in. +* the function is averaged within +-0.5*avrgInterval +* @param binBndrs :: pointer to the vector, containing bin boundaries. +* If provided, its length has to be input.size()+1, +* if not, equal size bins of size 1 are assumed, +* so avrgInterval becomes the number of points +* to average over. Bin boundaries array have to +* increase and can not contain equal boundaries. +* @param startIndex:: if provided, its start index to run averaging from. +* if not, averaging starts from the index 0 +* @param endIndex :: final index to run average to, if provided. If +* not, or higher then number of elements in input array, +* averaging is performed to the end point of the input +* array +* @param outBins :: if present, pointer to a vector to return +* bin boundaries for output array. +*/ +void smoothInRange(const std::vector<double> &input, + std::vector<double> &output, const double avrgInterval, + std::vector<double> const *const binBndrs, size_t startIndex, + size_t endIndex, std::vector<double> *const outBins) { + + if (endIndex == 0) + endIndex = input.size(); + if (endIndex > input.size()) + endIndex = input.size(); + + if (endIndex <= startIndex) { + output.resize(0); + return; + } + + size_t max_size = input.size(); + if (binBndrs) { + if (binBndrs->size() != max_size + 1) { + throw std::invalid_argument( + "Array of bin boundaries, " + "if present, have to be one bigger then the input array"); + } + } + + size_t length = endIndex - startIndex; + output.resize(length); + + double halfWidth = avrgInterval / 2; + if (!binBndrs) { + if (std::floor(halfWidth) * 2 - avrgInterval > 1.e-6) { + halfWidth = std::floor(halfWidth) + 1; + } + } + + if (outBins) + outBins->resize(length + 1); + + // Run averaging + double binSize = 1; + for (size_t i = startIndex; i < endIndex; i++) { + if (binBndrs) { + binSize = binBndrs->operator[](i + 1) - binBndrs->operator[](i); + } + output[i - startIndex] = + runAverage(i, startIndex, endIndex, halfWidth, input, binBndrs) * + binSize; + if (outBins) { + outBins->operator[](i - startIndex) = binBndrs->operator[](i); + } + } + if (outBins) { + outBins->operator[](endIndex - startIndex) = binBndrs->operator[](endIndex); + } +} /// Declare all version of this template DLLExport std::vector<int32_t> diff --git a/Framework/Kernel/test/TimeSeriesPropertyTest.h b/Framework/Kernel/test/TimeSeriesPropertyTest.h index 284bfb9bc6f55d75e19630a1788b1839afbb4727..87a1480b405e3035e1babbded9d0a4469e34a2c5 100644 --- a/Framework/Kernel/test/TimeSeriesPropertyTest.h +++ b/Framework/Kernel/test/TimeSeriesPropertyTest.h @@ -122,7 +122,36 @@ public: TS_ASSERT_EQUALS(twoVals[1], threeVals[2]); TS_ASSERT_EQUALS(newVal, threeVals[1]); } + void test_GetDerivative() { + dProp->addValue("2007-11-30T16:17:10", 10); + dProp->addValue("2007-11-30T16:17:12", 12); + dProp->addValue("2007-11-30T16:17:01", 01); + dProp->addValue("2007-11-30T16:17:05", 05); + auto derProp = dProp->getDerivative(); + TS_ASSERT(dynamic_cast<TimeSeriesProperty<double> *>(derProp.get())) + + TS_ASSERT_EQUALS(derProp->size(), 3); + auto derValues = derProp->valuesAsVector(); + + TS_ASSERT_EQUALS(derValues[0], 1); + TS_ASSERT_EQUALS(derValues[1], 1); + TS_ASSERT_EQUALS(derValues[2], 1); + + TSM_ASSERT_THROWS("derivative undefined for string property", + sProp->getDerivative(), std::runtime_error); + + iProp->addValue("2007-11-30T16:17:10", 10); + TSM_ASSERT_THROWS( + "derivative undefined for property with less then 2 values", + iProp->getDerivative(), std::runtime_error); + iProp->addValue("2007-11-30T16:17:12", 12); + + derProp = iProp->getDerivative(); + TS_ASSERT_EQUALS(derProp->size(), 1); + derValues = derProp->valuesAsVector(); + TS_ASSERT_EQUALS(derValues[0], 1); + } void test_timesAsVector() { TimeSeriesProperty<double> *p = new TimeSeriesProperty<double>("doubleProp"); diff --git a/Framework/Kernel/test/VectorHelperTest.h b/Framework/Kernel/test/VectorHelperTest.h index 16f9f4b86a2f79e2fe41a07dc55323e44066e000..36ac636a8f3644be183ca269644490a15f7f741e 100644 --- a/Framework/Kernel/test/VectorHelperTest.h +++ b/Framework/Kernel/test/VectorHelperTest.h @@ -5,6 +5,7 @@ #include "MantidKernel/Timer.h" #include "MantidKernel/VectorHelper.h" #include <cxxtest/TestSuite.h> +#include <cstdlib> #include <boost/assign/list_of.hpp> using namespace Mantid::Kernel; @@ -266,6 +267,121 @@ public: index = VectorHelper::getBinIndex(m_test_bins, testValue)); TS_ASSERT_EQUALS(index, 2); } + void test_RunningAveraging() { + double id[] = {1, 2, 3, 4, 5, 6}; + std::vector<double> inputData(id, id + sizeof(id) / sizeof(double)); + double ib[] = {0, 1, 2, 3, 4, 5}; + std::vector<double> inputBoundaries(ib, ib + sizeof(ib) / sizeof(double)); + + std::vector<double> output; + TS_ASSERT_THROWS( + VectorHelper::smoothInRange(inputData, output, 6, &inputBoundaries), + std::invalid_argument); + inputBoundaries.push_back(6); + VectorHelper::smoothInRange(inputData, output, 6, &inputBoundaries); + + TS_ASSERT_DELTA(output[1] - output[0], 0.492, 1.e-3); + TS_ASSERT_DELTA(output[3] - output[2], 0.4545, 1.e-3); + TS_ASSERT_DELTA(output[5] - output[4], 0.492, 1.e-3); + inputBoundaries[1] = 1; + inputBoundaries[2] = 3; + inputBoundaries[3] = 6; + inputBoundaries[4] = 10; + inputBoundaries[5] = 15; + inputBoundaries[6] = 21; + VectorHelper::smoothInRange(inputData, output, 6, &inputBoundaries); + TS_ASSERT_DELTA(output[2], 3, 1.e-8); + TS_ASSERT_DELTA(output[0], 1, 1.e-8); + TS_ASSERT_DELTA(output[5], 6, 1.e-8); + + std::vector<double> out_bins; + VectorHelper::smoothInRange(inputData, output, 3, &inputBoundaries, 1, 5, + &out_bins); + TS_ASSERT_EQUALS(output.size(), 4); + TS_ASSERT_DELTA(output[1], 3, 1.e-8); + } + + void test_Smooth_keeps_peakPosition() { + + std::vector<double> output; + std::vector<double> inputBoundaries(21); + inputBoundaries[0] = 0; + double step(1); + for (size_t i = 1; i < 21; i++) { + inputBoundaries[i] = inputBoundaries[i - 1] + step; + step *= 1.1; + } + double norm = 100 / inputBoundaries[20]; + for (size_t i = 0; i < 21; i++) { + inputBoundaries[i] *= norm; + } + + std::vector<double> inputData(20); + for (size_t i = 0; i < 20; i++) { + double dev = 0.5 * (inputBoundaries[i] + inputBoundaries[i + 1]) - 50; + inputData[i] = + exp(-dev * dev / 100) * (inputBoundaries[i + 1] - inputBoundaries[i]); + } + int indOfMax = VectorHelper::getBinIndex(inputBoundaries, 50.); + double fMax = inputData[indOfMax] / + (inputBoundaries[indOfMax + 1] - inputBoundaries[indOfMax]); + double iLeft = inputData[indOfMax - 1] / + (inputBoundaries[indOfMax] - inputBoundaries[indOfMax - 1]); + double iRight = inputData[indOfMax + 1] / (inputBoundaries[indOfMax + 2] - + inputBoundaries[indOfMax + 1]); + + TS_ASSERT(iLeft < fMax); + TS_ASSERT(iRight < fMax); + VectorHelper::smoothInRange(inputData, output, 10, &inputBoundaries); + fMax = output[indOfMax] / + (inputBoundaries[indOfMax + 1] - inputBoundaries[indOfMax]); + iLeft = inputData[indOfMax - 1] / + (inputBoundaries[indOfMax] - inputBoundaries[indOfMax - 1]); + iRight = inputData[indOfMax + 1] / + (inputBoundaries[indOfMax + 2] - inputBoundaries[indOfMax + 1]); + + TS_ASSERT(iLeft < fMax); + TS_ASSERT(iRight < fMax); + + output.swap(inputData); + VectorHelper::smoothInRange(inputData, output, 10, &inputBoundaries); + + fMax = output[indOfMax] / + (inputBoundaries[indOfMax + 1] - inputBoundaries[indOfMax]); + iLeft = inputData[indOfMax - 1] / + (inputBoundaries[indOfMax] - inputBoundaries[indOfMax - 1]); + iRight = inputData[indOfMax + 1] / + (inputBoundaries[indOfMax + 2] - inputBoundaries[indOfMax + 1]); + + // TS_ASSERT(iLeft<fMax); + TS_ASSERT(iRight < fMax); + + output.swap(inputData); + VectorHelper::smoothInRange(inputData, output, 10, &inputBoundaries); + + fMax = output[indOfMax] / + (inputBoundaries[indOfMax + 1] - inputBoundaries[indOfMax]); + iLeft = inputData[indOfMax - 1] / + (inputBoundaries[indOfMax] - inputBoundaries[indOfMax - 1]); + iRight = inputData[indOfMax + 1] / + (inputBoundaries[indOfMax + 2] - inputBoundaries[indOfMax + 1]); + + // TS_ASSERT(iLeft<fMax); + TS_ASSERT(iRight < fMax); + + output.swap(inputData); + VectorHelper::smoothInRange(inputData, output, 10, &inputBoundaries); + + fMax = output[indOfMax] / + (inputBoundaries[indOfMax + 1] - inputBoundaries[indOfMax]); + iLeft = inputData[indOfMax - 1] / + (inputBoundaries[indOfMax] - inputBoundaries[indOfMax - 1]); + iRight = inputData[indOfMax + 1] / + (inputBoundaries[indOfMax + 2] - inputBoundaries[indOfMax + 1]); + + TS_ASSERT(inputData[indOfMax - 1] < output[indOfMax]); + TS_ASSERT(inputData[indOfMax + 1] < output[indOfMax]); + } private: /// Testing bins diff --git a/Framework/LiveData/src/ADARA/ADARAParser.cpp b/Framework/LiveData/src/ADARA/ADARAParser.cpp index 8fe1652ecb61c1985e1538b85869fc1c8d029b3f..1fe48e4b00b4755d3c0e3a73e5c25c8caf289e86 100644 --- a/Framework/LiveData/src/ADARA/ADARAParser.cpp +++ b/Framework/LiveData/src/ADARA/ADARAParser.cpp @@ -9,7 +9,7 @@ using namespace ADARA; Parser::Parser(unsigned int initial_buffer_size, unsigned int max_pkt_size) : m_size(initial_buffer_size), m_max_size(max_pkt_size), m_len(0), - m_restart_offset(0), m_oversize_len(0) { + m_restart_offset(0), m_oversize_len(0), m_oversize_offset(0) { m_buffer = new uint8_t[initial_buffer_size]; m_discarded_packets.clear(); } diff --git a/Framework/LiveData/src/ISISHistoDataListener.cpp b/Framework/LiveData/src/ISISHistoDataListener.cpp index d962ecea3eafff1aabb5550675c27bf898669eba..b211f601a4eb5dd334c87e053d597a875164d35d 100644 --- a/Framework/LiveData/src/ISISHistoDataListener.cpp +++ b/Framework/LiveData/src/ISISHistoDataListener.cpp @@ -181,6 +181,10 @@ boost::shared_ptr<Workspace> ISISHistoDataListener::extractData() { getFloatArray("RRPB", floatBuffer, 32); const double protonCharge = floatBuffer[8]; + if (m_timeRegime < 0) + throw std::runtime_error("The value of the time regime variable is " + "negative. This is an Internal inconsistency."); + // find out the number of histograms in the output workspace const size_t numberOfHistograms = m_specList.empty() ? m_numberOfSpectra[m_timeRegime] : m_specList.size(); diff --git a/Framework/LiveData/src/LoadDAE/isisds_command.cpp b/Framework/LiveData/src/LoadDAE/isisds_command.cpp index 790c2391b29ba8394be8f545f77d2e4e4fa1eeb6..b54ea2c9781699874f8f7b5c3b9b3cc1ba9209b8 100644 --- a/Framework/LiveData/src/LoadDAE/isisds_command.cpp +++ b/Framework/LiveData/src/LoadDAE/isisds_command.cpp @@ -145,8 +145,14 @@ SOCKET isisds_send_open(const char *host, ISISDSAccessMode access_type, if (s == INVALID_SOCKET) { return INVALID_SOCKET; } - setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *)&setkeepalive, - sizeof(setkeepalive)); + + int zero = setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *)&setkeepalive, + sizeof(setkeepalive)); + if (0 != zero) { + closesocket(s); + return INVALID_SOCKET; + } + if (connect(s, (struct sockaddr *)&address, sizeof(address)) == -1) { closesocket(s); return INVALID_SOCKET; diff --git a/Framework/MDAlgorithms/CMakeLists.txt b/Framework/MDAlgorithms/CMakeLists.txt index f3e9e4d04a2db2271f828af463f363f2364f2462..8725b21a5ce0ae0f8beeca48f7506a054beffeb4 100644 --- a/Framework/MDAlgorithms/CMakeLists.txt +++ b/Framework/MDAlgorithms/CMakeLists.txt @@ -12,6 +12,7 @@ set ( SRC_FILES src/CentroidPeaksMD.cpp src/CentroidPeaksMD2.cpp src/CloneMDWorkspace.cpp + src/CompactMD.cpp src/CompareMDWorkspaces.cpp src/ConvToMDBase.cpp src/ConvToMDEventsWS.cpp @@ -136,6 +137,7 @@ set ( INC_FILES inc/MantidMDAlgorithms/CentroidPeaksMD2.h inc/MantidMDAlgorithms/CloneMDWorkspace.h inc/MantidMDAlgorithms/CompareMDWorkspaces.h + inc/MantidMDAlgorithms/CompactMD.h inc/MantidMDAlgorithms/ConvToMDBase.h inc/MantidMDAlgorithms/ConvertCWPDMDToSpectra.h inc/MantidMDAlgorithms/ConvertCWSDExpToMomentum.h @@ -257,6 +259,7 @@ set ( TEST_FILES CentroidPeaksMDTest.h CloneMDWorkspaceTest.h CompareMDWorkspacesTest.h + CompactMDTest.h ConvertCWPDMDToSpectraTest.h ConvertCWSDExpToMomentumTest.h ConvertCWSDMDtoHKLTest.h diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CompactMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CompactMD.h new file mode 100644 index 0000000000000000000000000000000000000000..c206f73b5409e0178a836f0d32a3a30d67014c16 --- /dev/null +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CompactMD.h @@ -0,0 +1,65 @@ +#ifndef MANTID_MDALGORITHMS_COMPACTMD_H_ +#define MANTID_MDALGORITHMS_COMPACTMD_H_ + +/** An algorithm used to crop an MDHistoWorkspace based on the first + non-zero signals found in each dimension. + + @author Matt King + @date 02-10-2015 + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ + +#include "MantidAPI/IMDHistoWorkspace.h" +#include "MantidDataObjects/MDHistoWorkspace.h" +#include "MantidMDAlgorithms/CutMD.h" +#include "MantidAPI/Algorithm.h" +#include "boost/shared_ptr.hpp" +namespace Mantid { +namespace MDAlgorithms { +class DLLExport CompactMD : public API::Algorithm { +public: + CompactMD(){}; + ~CompactMD(){}; + + virtual void init(); + virtual void exec(); + /// Algorithm's name for identification + const std::string name() const { return "CompactMD"; } + /// Summary of algorithms purpose + const std::string summary() const { + return "Crops an MDHistoWorkspace based on the first non-zero signals " + "giving a more focussed area of interest."; + } + const std::string category() const { return "MDAlgorithms"; } + /// Algorithm's version for identification + int version() const { return 1; } + /// Finding the extents of the first non-zero signals. + void + findFirstNonZeroMinMaxExtents(Mantid::API::IMDHistoWorkspace_sptr inputWs, + std::vector<Mantid::coord_t> &minVec, + std::vector<Mantid::coord_t> &maxVec); +}; +} +} + +#endif // MANTID_MDALGORITHMS_COMPACTMD_H_ \ No newline at end of file diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Integrate3DEvents.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Integrate3DEvents.h index 2d2b6398fcbc13ef8930008df57da0b01eb015e7..d5a3c71fc66da3866275f0cd6a87bf0c4b5050e5 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Integrate3DEvents.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Integrate3DEvents.h @@ -127,10 +127,10 @@ private: double detectorQ(std::vector<Kernel::V3D> E1Vec, const Mantid::Kernel::V3D QLabFrame, std::vector<double> &r); // Private data members - PeakQMap peak_qs; // hashtable with peak Q-vectors - EventListMap event_lists; // hashtable with lists of events for each peak - Kernel::DblMatrix UBinv; // matrix mapping from Q to h,k,l - double radius; // size of sphere to use for events around a peak + PeakQMap m_peak_qs; // hashtable with peak Q-vectors + EventListMap m_event_lists; // hashtable with lists of events for each peak + Kernel::DblMatrix m_UBinv; // matrix mapping from Q to h,k,l + double m_radius; // size of sphere to use for events around a peak }; } // namespace MDAlgorithms diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/PreprocessDetectorsToMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/PreprocessDetectorsToMD.h index 7464a55bd76b1e3209a19e205b493542fbaa5642..f139433836d5c9fe001ec8fae65aff65db29325b 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/PreprocessDetectorsToMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/PreprocessDetectorsToMD.h @@ -6,7 +6,6 @@ //---------------------------------------------------------------------- #include "MantidAPI/Algorithm.h" #include "MantidDataObjects/TableWorkspace.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidMDAlgorithms/DllConfig.h" namespace Mantid { diff --git a/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp b/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp index b08e5a46ea2e45b5d4819401618fde18945c48b5..d9e2a957b1f7411b3848390a8cbe22415ea1609b 100644 --- a/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp +++ b/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp @@ -1,5 +1,5 @@ #include "MantidMDAlgorithms/CalculateCoverageDGS.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/InstrumentValidator.h" #include "MantidDataObjects/MDHistoWorkspace.h" #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/ArrayLengthValidator.h" diff --git a/Framework/MDAlgorithms/src/CompactMD.cpp b/Framework/MDAlgorithms/src/CompactMD.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7c815d5277ff64361e8487fe54f330c038b1f0bd --- /dev/null +++ b/Framework/MDAlgorithms/src/CompactMD.cpp @@ -0,0 +1,140 @@ +#include "MantidMDAlgorithms/CompactMD.h" +#include "MantidAPI/IMDIterator.h" +using namespace Mantid::API; +using namespace Mantid::Geometry; +using namespace Mantid::Kernel; + +namespace { +/** + * helper method to create a string from min and max extents (with non-zero + * signals) ready to be used as the PBins for IntegrateMDHistoWorkspace + * algorithm in + * exec + * @param minVector : Vector containing the minimum extents that we will crop + * to. + * @param maxVector : Vector containing the maximum extents that we will crop + * to. + * @param inputWs : Used in the calculation from centre to bin edges + * @return : a string vector of binning parameters for IntegrateMDHistoWorkspace + * to take as input. +*/ +std::vector<std::string> +createPBinStringVector(std::vector<Mantid::coord_t> minVector, + std::vector<Mantid::coord_t> maxVector, + IMDHistoWorkspace_sptr inputWs) { + size_t numDims = inputWs->getNumDims(); + std::vector<std::string> pBinStrVector; + for (size_t iter = 0; iter < numDims; iter++) { + if (minVector[iter] >= maxVector[iter]) { + std::cerr << "Minimum extent of non-zero signal must be LESS than the " + "maximum extent with non-zero signal" << std::endl; + } + // creating pbin string using Min and Max Centre positions + auto pBinStr = boost::lexical_cast<std::string>( + minVector[iter] - + (inputWs->getDimension(iter)->getBinWidth() * 0.5)) + + ",0," + + boost::lexical_cast<std::string>( + maxVector[iter] + + (inputWs->getDimension(iter)->getBinWidth() * 0.5)); + pBinStrVector.push_back(pBinStr); + } + return pBinStrVector; +} +} + +namespace Mantid { +namespace MDAlgorithms { + +DECLARE_ALGORITHM(CompactMD) + +/** +* Finding the centre points of Bins with non-zero signal values +* we then compare this centre to minimum and maximum centres we have +* to get the minimum and maximum extents of the workspace that has non-zero +* signal values in the Bins. +* @param inputWs : The workspace that will be iterated over to find the extents. +* @param minVec : Vector used to stored the minimum extent in each dimension +* @param maxVec : Vector used to stored the maximum extents in each dimension +*/ + +void CompactMD::findFirstNonZeroMinMaxExtents( + IMDHistoWorkspace_sptr inputWs, std::vector<Mantid::coord_t> &minVec, + std::vector<Mantid::coord_t> &maxVec) { + auto ws_iter = inputWs->createIterator(); + do { + if (ws_iter->getSignal() == 0) { + // if signal is 0 then go to next index + continue; + } else { + // we have found a non-zero signal we need to compare + // the position of the bin with our Min and Max values + auto current_index = ws_iter->getLinearIndex(); + auto current_center = inputWs->getCenter(current_index); + for (size_t index = 0; index < inputWs->getNumDims(); index++) { + if (current_center[index] > maxVec[index]) { + // set new maximum + maxVec[index] = current_center[index]; + } + if (current_center[index] < minVec[index]) { + // set new minimum + minVec[index] = current_center[index]; + } + } + } + } while (ws_iter->next()); +} + +/** +* Initiliase the algorithm's properties. +*/ +void CompactMD::init() { + // input workspace to compact + declareProperty(new WorkspaceProperty<IMDHistoWorkspace>("InputWorkspace", "", + Direction::Input), + "MDHistoWorkspace to compact"); + // output workspace that will have been compacted + declareProperty(new WorkspaceProperty<IMDHistoWorkspace>( + "OutputWorkspace", "", Direction::Output), + "Output compacted workspace"); +} +/** +* Execute the algorithm. +*/ +void CompactMD::exec() { + const IMDHistoWorkspace_sptr input_ws = this->getProperty("InputWorkspace"); + IMDWorkspace_sptr out_ws; + + const size_t nDimensions = input_ws->getNumDims(); + std::vector<Mantid::coord_t> minVector; + std::vector<Mantid::coord_t> maxVector; + + // fill the min/max vectors with values per dimension. + for (size_t index = 0; index < nDimensions; index++) { + minVector.push_back(input_ws->getDimension(index)->getMaximum()); + maxVector.push_back(input_ws->getDimension(index)->getMinimum()); + } + // start our search for the first non-zero signal index. + findFirstNonZeroMinMaxExtents(input_ws, minVector, maxVector); + auto pBinStrings = createPBinStringVector(minVector, maxVector, input_ws); + // creating IntegrateMDHistoWorkspace algorithm to crop our workspace. + auto cut_alg = this->createChildAlgorithm("IntegrateMDHistoWorkspace"); + cut_alg->setProperty("InputWorkspace", input_ws); + cut_alg->setProperty("OutputWorkspace", "temp"); + // setting property PxBin depending on the number of dimensions the + // input workspace has. + for (size_t iter = 0; iter < input_ws->getNumDims(); iter++) { + std::string propertyString = + "P" + boost::lexical_cast<std::string>(iter + 1) + "Bin"; + cut_alg->setProperty(propertyString, pBinStrings[iter]); + } + cut_alg->execute(); + + // retrieve the output workspace from IntegrateMDHistoWorkspace + IMDHistoWorkspace_sptr temp = cut_alg->getProperty("OutputWorkspace"); + out_ws = temp; + // set output workspace of CompactMD to output of IntegrateMDHistoWorkspace + this->setProperty("OutputWorkspace", out_ws); +} +} +} \ No newline at end of file diff --git a/Framework/MDAlgorithms/src/ConvertCWSDExpToMomentum.cpp b/Framework/MDAlgorithms/src/ConvertCWSDExpToMomentum.cpp index 091f8322f9c4d7c99a96fa07b0daa3bf8bbe0e49..746eb498bc4ad870cb81ff6452f4c2cce3ab69e5 100644 --- a/Framework/MDAlgorithms/src/ConvertCWSDExpToMomentum.cpp +++ b/Framework/MDAlgorithms/src/ConvertCWSDExpToMomentum.cpp @@ -25,7 +25,8 @@ DECLARE_ALGORITHM(ConvertCWSDExpToMomentum) /** Constructor */ ConvertCWSDExpToMomentum::ConvertCWSDExpToMomentum() - : m_iColFilename(2), m_iColStartDetID(3), m_setQRange(true) {} + : m_iColFilename(2), m_iColStartDetID(3), m_setQRange(true), + m_isBaseName(false) {} //---------------------------------------------------------------------------------------------- /** Destructor @@ -204,13 +205,15 @@ void ConvertCWSDExpToMomentum::addMDEvents(bool usevirtual) { // Check whether to add / or \ to m_dataDir std::string sep(""); if (m_dataDir.size() > 0) { - // Determine system - bool isWindows(false); +// Determine system #if _WIN64 - isWindows = true; -#elif _WIND32 - isWindows = true; + const bool isWindows = true; +#elif _WIN32 + const bool isWindows = true; +#else + const bool isWindows = false; #endif + if (isWindows && *m_dataDir.rbegin() != '\\') { sep = "\\"; } else if (!isWindows && *m_dataDir.rbegin() != '/') @@ -415,6 +418,13 @@ void ConvertCWSDExpToMomentum::convertSpiceMatrixToMomentumMDEvents( } expinfo->mutableRun().setGoniometer(dataws->run().getGoniometer(), false); expinfo->mutableRun().addProperty("run_number", runnumber); + // Add all the other propertys from original data workspace + const std::vector<Kernel::Property *> vec_property = + dataws->run().getProperties(); + for (size_t i = 0; i < vec_property.size(); ++i) { + expinfo->mutableRun().addProperty(vec_property[i]->clone()); + } + m_outputWS->addExperimentInfo(expinfo); return; diff --git a/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp b/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp index 3135b45ca53cba893ee347f0b150591e75017cb9..4f6bf32e23452dd2ec1d8b6ba2a0ed9ec04cddb4 100644 --- a/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp +++ b/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp @@ -1,6 +1,6 @@ #include "MantidAPI/IMDEventWorkspace.h" #include "MantidAPI/Progress.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/Workspace2D.h" #include "MantidGeometry/Crystal/OrientedLattice.h" diff --git a/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace2.cpp b/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace2.cpp index adf27e22bfebf50acca9eacb400cba07ea5bcdd8..4fc927b7a231e5905c4c3276c43eb69f2ddffed8 100644 --- a/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace2.cpp +++ b/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace2.cpp @@ -1,8 +1,6 @@ #include "MantidMDAlgorithms/ConvertToDiffractionMDWorkspace2.h" #include "MantidAPI/IMDEventWorkspace.h" -#include "MantidAPI/Progress.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/MDEventWorkspace.h" diff --git a/Framework/MDAlgorithms/src/ConvertToMD.cpp b/Framework/MDAlgorithms/src/ConvertToMD.cpp index 84a87c0a76fd3627fa1430df9aadcf29461b29a3..375e4467d683893bf65dd0f2a736b58f3bb5cf2c 100644 --- a/Framework/MDAlgorithms/src/ConvertToMD.cpp +++ b/Framework/MDAlgorithms/src/ConvertToMD.cpp @@ -3,8 +3,6 @@ #include <algorithm> #include "MantidAPI/IMDEventWorkspace.h" -#include "MantidAPI/Progress.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/ArrayLengthValidator.h" diff --git a/Framework/MDAlgorithms/src/ConvertToMDMinMaxGlobal.cpp b/Framework/MDAlgorithms/src/ConvertToMDMinMaxGlobal.cpp index 13dbd0d43c1e6a5dc66babc5ee38b05245c03ae1..c344b7c1b0bdd0b7bfb65af1b7cc759baea6c074 100644 --- a/Framework/MDAlgorithms/src/ConvertToMDMinMaxGlobal.cpp +++ b/Framework/MDAlgorithms/src/ConvertToMDMinMaxGlobal.cpp @@ -1,7 +1,10 @@ #include "MantidMDAlgorithms/ConvertToMDMinMaxGlobal.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidKernel/ArrayProperty.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/ListValidator.h" #include "MantidKernel/TimeSeriesProperty.h" #include "MantidKernel/VisibleWhenProperty.h" diff --git a/Framework/MDAlgorithms/src/ConvertToMDParent.cpp b/Framework/MDAlgorithms/src/ConvertToMDParent.cpp index d41e435fa5f888ed795ead18e6d8fdfbd2aeaa80..2c19786b0a51263b0022ff4bc0b347ebabbed181 100644 --- a/Framework/MDAlgorithms/src/ConvertToMDParent.cpp +++ b/Framework/MDAlgorithms/src/ConvertToMDParent.cpp @@ -1,9 +1,11 @@ #include "MantidMDAlgorithms/ConvertToMDParent.h" #include "MantidAPI/IMDEventWorkspace.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidKernel/ArrayProperty.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/ListValidator.h" #include "MantidKernel/VisibleWhenProperty.h" diff --git a/Framework/MDAlgorithms/src/ConvertToReflectometryQ.cpp b/Framework/MDAlgorithms/src/ConvertToReflectometryQ.cpp index cd2a8bff145221be83b4ab299bb36c53a428059d..399b1c3e426f90ed072a1c1ff80c4dc0d94a1ced 100644 --- a/Framework/MDAlgorithms/src/ConvertToReflectometryQ.cpp +++ b/Framework/MDAlgorithms/src/ConvertToReflectometryQ.cpp @@ -2,7 +2,8 @@ #include "MantidAPI/IEventWorkspace.h" #include "MantidAPI/ITableWorkspace.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidAPI/Progress.h" #include "MantidDataObjects/EventWorkspace.h" @@ -10,6 +11,7 @@ #include "MantidDataObjects/Workspace2D.h" #include "MantidKernel/ArrayProperty.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/EnabledWhenProperty.h" #include "MantidKernel/ListValidator.h" #include "MantidKernel/TimeSeriesProperty.h" diff --git a/Framework/MDAlgorithms/src/FindPeaksMD.cpp b/Framework/MDAlgorithms/src/FindPeaksMD.cpp index 1e94707a155f447cab458f8d4b2e3528fef25294..ba70dd4bedd2239fcf40c699cdac43d92045abe3 100644 --- a/Framework/MDAlgorithms/src/FindPeaksMD.cpp +++ b/Framework/MDAlgorithms/src/FindPeaksMD.cpp @@ -215,12 +215,15 @@ FindPeaksMD::createPeak(const Mantid::Kernel::V3D &Q, const double binCount) { boost::shared_ptr<DataObjects::Peak> p; if (dimType == QLAB) { // Build using the Q-lab-frame constructor - p = boost::shared_ptr<DataObjects::Peak>(new Peak(inst, Q)); + p = boost::make_shared<Peak>(inst, Q); // Save gonio matrix for later p->setGoniometerMatrix(m_goniometer); } else if (dimType == QSAMPLE) { // Build using the Q-sample-frame constructor - p = boost::shared_ptr<DataObjects::Peak>(new Peak(inst, Q, m_goniometer)); + p = boost::make_shared<Peak>(inst, Q, m_goniometer); + } else { + throw std::invalid_argument( + "Cannot Integrate peaks unless the dimension is QLAB or QSAMPLE"); } try { // Look for a detector diff --git a/Framework/MDAlgorithms/src/ImportMDEventWorkspace.cpp b/Framework/MDAlgorithms/src/ImportMDEventWorkspace.cpp index 9bb7c6d1a1723019e115ccda352ef3039a6dccee..8aab04ee8dbf02e05f695e30c90b2100fb472a3a 100644 --- a/Framework/MDAlgorithms/src/ImportMDEventWorkspace.cpp +++ b/Framework/MDAlgorithms/src/ImportMDEventWorkspace.cpp @@ -266,7 +266,13 @@ void ImportMDEventWorkspace::exec() { m_nDimensions + 4; // signal, error, run_no, detector_no m_IsFullDataObjects = (nActualColumns == columnsForFullEvents); - m_nDataObjects = posDiffMDEvent / nActualColumns; + if (0 == nActualColumns) { + m_nDataObjects = 0; + g_log.warning() << "The number of actual columns found in the file " + "(exlcuding comments) is zero" << std::endl; + } else { + m_nDataObjects = posDiffMDEvent / nActualColumns; + } // Get the min and max extents in each dimension. std::vector<double> extentMins(m_nDimensions); diff --git a/Framework/MDAlgorithms/src/Integrate3DEvents.cpp b/Framework/MDAlgorithms/src/Integrate3DEvents.cpp index f3db57b5fd7b3652e27e4bf5187cbf8311c872e5..372e9b1ad95a59e2852b7522d4b4e3602fc6a41b 100644 --- a/Framework/MDAlgorithms/src/Integrate3DEvents.cpp +++ b/Framework/MDAlgorithms/src/Integrate3DEvents.cpp @@ -35,14 +35,14 @@ using Mantid::Kernel::V3D; Integrate3DEvents::Integrate3DEvents( std::vector<std::pair<double, V3D>> const &peak_q_list, DblMatrix const &UBinv, double radius) { - this->UBinv = UBinv; - this->radius = radius; + m_UBinv = UBinv; + m_radius = radius; int64_t hkl_key; for (size_t it = 0; it != peak_q_list.size(); ++it) { hkl_key = getHklKey(peak_q_list[it].second); if (hkl_key != 0) // only save if hkl != (0,0,0) - peak_qs[hkl_key] = peak_q_list[it].second; + m_peak_qs[hkl_key] = peak_q_list[it].second; } } @@ -124,7 +124,12 @@ Integrate3DEvents::ellipseIntegrateEvents( return boost::make_shared<NoShape>(); } - std::vector<std::pair<double, V3D>> &some_events = event_lists[hkl_key]; + auto pos = m_event_lists.find(hkl_key); + if (m_event_lists.end() == pos) + return boost::make_shared<NoShape>(); + ; + + std::vector<std::pair<double, V3D>> &some_events = pos->second; if (some_events.size() < 3) // if there are not enough events to { // find covariance matrix, return @@ -132,14 +137,14 @@ Integrate3DEvents::ellipseIntegrateEvents( } DblMatrix cov_matrix(3, 3); - makeCovarianceMatrix(some_events, cov_matrix, radius); + makeCovarianceMatrix(some_events, cov_matrix, m_radius); std::vector<V3D> eigen_vectors; getEigenVectors(cov_matrix, eigen_vectors); std::vector<double> sigmas; for (int i = 0; i < 3; i++) { - sigmas.push_back(stdDev(some_events, eigen_vectors[i], radius)); + sigmas.push_back(stdDev(some_events, eigen_vectors[i], m_radius)); } bool invalid_peak = false; @@ -392,7 +397,7 @@ int64_t Integrate3DEvents::getHklKey2(V3D const &hkl) { * @param q_vector The q_vector to be mapped to h,k,l */ int64_t Integrate3DEvents::getHklKey(V3D const &q_vector) { - V3D hkl = UBinv * q_vector; + V3D hkl = m_UBinv * q_vector; int h = boost::math::iround<double>(hkl[0]); int k = boost::math::iround<double>(hkl[1]); int l = boost::math::iround<double>(hkl[2]); @@ -424,15 +429,15 @@ void Integrate3DEvents::addEvent(std::pair<double, V3D> event_Q, if (hkl_key == 0) // don't keep events associated with 0,0,0 return; - auto peak_it = peak_qs.find(hkl_key); - if (peak_it != peak_qs.end()) { + auto peak_it = m_peak_qs.find(hkl_key); + if (peak_it != m_peak_qs.end()) { if (!peak_it->second.nullVector()) { if (hkl_integ) - event_Q.second = event_Q.second - UBinv * peak_it->second; + event_Q.second = event_Q.second - m_UBinv * peak_it->second; else event_Q.second = event_Q.second - peak_it->second; - if (event_Q.second.norm() < radius) { - event_lists[hkl_key].push_back(event_Q); + if (event_Q.second.norm() < m_radius) { + m_event_lists[hkl_key].push_back(event_Q); } } } @@ -511,8 +516,8 @@ PeakShapeEllipsoid_const_sptr Integrate3DEvents::ellipseIntegrateEvents( // if necessary restrict the background ellipsoid // to lie within the specified sphere, and adjust // the other sizes, proportionally - if (r3 * max_sigma > radius) { - r3 = radius / max_sigma; + if (r3 * max_sigma > m_radius) { + r3 = m_radius / max_sigma; r1 = r3 * 0.79370053f; // This value for r1 and r2 makes the background r2 = r1; // shell volume equal to the peak region volume. } diff --git a/Framework/MDAlgorithms/src/IntegrateEllipsoids.cpp b/Framework/MDAlgorithms/src/IntegrateEllipsoids.cpp index ad7bec8a36395a171beca37f96c453a9fcbd9780..ca721437fce6cc96906887af9a14d2ff4436022c 100644 --- a/Framework/MDAlgorithms/src/IntegrateEllipsoids.cpp +++ b/Framework/MDAlgorithms/src/IntegrateEllipsoids.cpp @@ -1,7 +1,8 @@ #include "MantidMDAlgorithms/IntegrateEllipsoids.h" #include "MantidAPI/FileProperty.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/PeaksWorkspace.h" #include "MantidDataObjects/PeakShapeEllipsoid.h" diff --git a/Framework/MDAlgorithms/src/IntegrateMDHistoWorkspace.cpp b/Framework/MDAlgorithms/src/IntegrateMDHistoWorkspace.cpp index 711de48f4bf03d29ae298d0aaebf6c47f0f01693..ee80f5f9e527c13dde9b8612a768c4c3cde20b58 100644 --- a/Framework/MDAlgorithms/src/IntegrateMDHistoWorkspace.cpp +++ b/Framework/MDAlgorithms/src/IntegrateMDHistoWorkspace.cpp @@ -104,7 +104,7 @@ Mantid::coord_t getPrecisionCorrectedCoordinate(Mantid::coord_t position, // Check if the relative deviation is larger than 1e-6 const auto deviation = fabs((nearest - position) / binWidth); - const auto tolerance = 1e-6; + const auto tolerance = 1e-5; Mantid::coord_t coordinate(position); if (deviation < tolerance) { coordinate = nearest; @@ -195,6 +195,7 @@ MDHistoWorkspace_sptr createShapedOutput(IMDHistoWorkspace const *const inWS, binning.back()) /*max*/); // Set custom min, max and nbins. } else if (i < pbins.size() && similarBinning(pbins[i])) { auto binning = pbins[i]; + Mantid::coord_t pMin = static_cast<Mantid::coord_t>(binning.front()); Mantid::coord_t pMax = static_cast<Mantid::coord_t>(binning.back()); size_t numberOfBins; @@ -386,6 +387,10 @@ void IntegrateMDHistoWorkspace::exec() { // Create a thread-local input iterator. boost::scoped_ptr<MDHistoWorkspaceIterator> inIterator( dynamic_cast<MDHistoWorkspaceIterator *>(inWS->createIterator())); + if (!inIterator) { + throw std::runtime_error( + "Could not convert IMDIterator to a MDHistoWorkspaceIterator"); + } /* We jump to the iterator position which is closest in the model diff --git a/Framework/MDAlgorithms/src/MDNormDirectSC.cpp b/Framework/MDAlgorithms/src/MDNormDirectSC.cpp index bf6d76d02d1724504ed5d16bbf289e37863b4adf..20336f562b787a80af15e6326eef4524a1a21aca 100644 --- a/Framework/MDAlgorithms/src/MDNormDirectSC.cpp +++ b/Framework/MDAlgorithms/src/MDNormDirectSC.cpp @@ -1,9 +1,11 @@ #include "MantidMDAlgorithms/MDNormDirectSC.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/CommonBinsValidator.h" +#include "MantidAPI/InstrumentValidator.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/MDEventWorkspace.h" #include "MantidDataObjects/MDHistoWorkspace.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/TimeSeriesProperty.h" #include "MantidKernel/VectorHelper.h" diff --git a/Framework/MDAlgorithms/src/MDNormSCD.cpp b/Framework/MDAlgorithms/src/MDNormSCD.cpp index 31a69c5e9f109de3ab85d46f7945ac4052789a5b..b5141d1c6261d84c96796d48326a0fe63c580c57 100644 --- a/Framework/MDAlgorithms/src/MDNormSCD.cpp +++ b/Framework/MDAlgorithms/src/MDNormSCD.cpp @@ -1,9 +1,12 @@ #include "MantidMDAlgorithms/MDNormSCD.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/CommonBinsValidator.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/MDEventWorkspace.h" #include "MantidDataObjects/MDHistoWorkspace.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/TimeSeriesProperty.h" #include "MantidKernel/VectorHelper.h" diff --git a/Framework/MDAlgorithms/src/PreprocessDetectorsToMD.cpp b/Framework/MDAlgorithms/src/PreprocessDetectorsToMD.cpp index 837827c91fa24209572bb3781af4ef48a4d974d5..c3aa0a51f81f48e0ed42730b7d8ef8a14a1f45b3 100644 --- a/Framework/MDAlgorithms/src/PreprocessDetectorsToMD.cpp +++ b/Framework/MDAlgorithms/src/PreprocessDetectorsToMD.cpp @@ -1,7 +1,8 @@ #include "MantidMDAlgorithms/PreprocessDetectorsToMD.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/NumericAxis.h" #include "MantidKernel/CompositeValidator.h" #include "MantidKernel/PropertyWithValue.h" -#include "MantidAPI/NumericAxis.h" using namespace Mantid; using namespace Mantid::API; diff --git a/Framework/MDAlgorithms/src/ReplicateMD.cpp b/Framework/MDAlgorithms/src/ReplicateMD.cpp index f97a4822c388c378ffdd2bc9e9b495baa2345632..f60b7c005638cc174503903508972036d78f8528 100644 --- a/Framework/MDAlgorithms/src/ReplicateMD.cpp +++ b/Framework/MDAlgorithms/src/ReplicateMD.cpp @@ -152,7 +152,7 @@ const std::string ReplicateMD::category() const { return "MDAlgorithms"; } /// Algorithm's summary for use in the GUI and help. @see Algorithm::summary const std::string ReplicateMD::summary() const { - return "This is a algorithm to create a higher dimensional dataset by " + return "This is an algorithm to create a higher dimensional dataset by " "replicating along an additional axis"; } diff --git a/Framework/MDAlgorithms/src/SaveIsawQvector.cpp b/Framework/MDAlgorithms/src/SaveIsawQvector.cpp index 46f3d0f66fea322d216dd1e1d4afe0431acf4214..3f871f0992e8f7e6d672e93ebb565fcc826c4715 100644 --- a/Framework/MDAlgorithms/src/SaveIsawQvector.cpp +++ b/Framework/MDAlgorithms/src/SaveIsawQvector.cpp @@ -3,7 +3,8 @@ #include <fstream> #include "MantidAPI/FileProperty.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidKernel/CompositeValidator.h" #include "MantidMDAlgorithms/MDTransfFactory.h" diff --git a/Framework/MDAlgorithms/test/CompactMDTest.h b/Framework/MDAlgorithms/test/CompactMDTest.h new file mode 100644 index 0000000000000000000000000000000000000000..c902a63bd606528350418ca3664b634d0314e4bd --- /dev/null +++ b/Framework/MDAlgorithms/test/CompactMDTest.h @@ -0,0 +1,289 @@ +#ifndef MANTID_MDALGORITHMS_COMPACTMDTEST_H_ +#define MANTID_MDALGORITHMS_COMPACTMDTEST_H_ +#include <cxxtest/TestSuite.h> + +#include "MantidMDAlgorithms/CompactMD.h" +#include "MantidDataObjects/MDHistoWorkspace.h" +#include "MantidTestHelpers/MDEventsTestHelper.h" + +using Mantid::MDAlgorithms::CompactMD; +using namespace Mantid::API; + +//================== +// Functional Tests +//================== +class CompactMDTest : 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 CompactMDTest *createSuite() { return new CompactMDTest(); } + static void destroySuite(CompactMDTest *suite) { delete suite; } + + void test_Init() { + CompactMD alg; + TSM_ASSERT_THROWS_NOTHING("Instance of CompactMD threw: ", + alg.initialize()); + TSM_ASSERT("Instance of CompactMD was not initialised: ", + alg.isInitialized()); + } + void + test_all_non_zero_signals_are_kept_with_data_concentrated_in_the_centre() { + /* + *testing the effectiveness of CompactMD when the data looks like this: + *------------------ + * Input structure: + *------------------ + * ------------- + * | | |///| | | + * --------------------- + * -5-4-3 2-1 0 1 2 3 4 5 + *--------------------------- + * Expected output structure: + *---------------------------- + * should trim until the first non-zero value. + * ----- + * |///| + * ----- + * -1 0 1 + */ + + using namespace Mantid::DataObjects; + const size_t numDims = 1; + const double signal = 0.0; + const double errorSquared = 1.3; + size_t numBins[static_cast<int>(numDims)] = {5}; + Mantid::coord_t min[static_cast<int>(numDims)] = {-5}; + Mantid::coord_t max[static_cast<int>(numDims)] = {5}; + const std::string name("test"); + auto inWS = MDEventsTestHelper::makeFakeMDHistoWorkspaceGeneral( + numDims, signal, errorSquared, numBins, min, max, name); + inWS->setSignalAt(2, 1.0); // set middle bin signal to one + CompactMD alg; + alg.setChild(true); + alg.setRethrows(true); + alg.initialize(); + alg.setProperty("InputWorkspace", inWS); + alg.setProperty("OutputWorkspace", "out"); + alg.execute(); + // output workspace should be cropped so extents ~ [-1,1] + IMDHistoWorkspace_sptr outputWorkspace = alg.getProperty("OutputWorkspace"); + TSM_ASSERT_EQUALS("Should have a signal of 1.0: ", + outputWorkspace->getSignalAt(0), 1); + TSM_ASSERT_EQUALS("Minimum should be cropped to -1: ", + outputWorkspace->getDimension(0)->getMinimum(), -1.0); + TSM_ASSERT_EQUALS("Maximum should be cropped to 1: ", + outputWorkspace->getDimension(0)->getMaximum(), 1.0); + TSM_ASSERT_EQUALS("Number of Bins should be 1 : ", + outputWorkspace->getDimension(0)->getNBins(), 1.0); + TSM_ASSERT_EQUALS("Bin width should be consistent: ", + outputWorkspace->getDimension(0)->getBinWidth(), + inWS->getDimension(0)->getBinWidth()); + } + void test_all_non_zero_signals_are_kept_with_data_in_each_corner() { + /* + *testing the effectiveness of CompactMD when the data looks like this: + *----------------------------------- + * Input structure: 2D HistoWorkspace + *----------------------------------- + * ------------- -3 + * |/a/| |/b/| -2 + * ------------- -1 + * | | | | 0 + * ------------- 1 + * |/c/| |/d/| 2 + * ------------- 3 + * -3-2-1 0 1 2 3 + *---------------------------- + * Expected output structure: + *---------------------------- + * should not trim the workspace at all. + * ------------- -3 + * |/a/| |/b/| -2 + * ------------- -1 + * | | | | 0 + * ------------- 1 + * |/c/| |/d/| 2 + * ------------- 3 + * -3-2-1 0 1 2 3 + */ + using namespace Mantid::DataObjects; + const size_t numDims = 2; + const double signal = 0.0; + const double errorSquared = 1.2; + size_t numBins[static_cast<int>(numDims)] = {3, 3}; + Mantid::coord_t min[static_cast<int>(numDims)] = {-3, -3}; + Mantid::coord_t max[static_cast<int>(numDims)] = {3, 3}; + const std::string name("test"); + auto inWS = MDEventsTestHelper::makeFakeMDHistoWorkspaceGeneral( + numDims, signal, errorSquared, numBins, min, max, name); + inWS->setSignalAt(0, 1.0); // cell a + inWS->setSignalAt(2, 1.0); // cell b + inWS->setSignalAt(6, 1.0); // cell c + inWS->setSignalAt(8, 1.0); // cell d + + CompactMD alg; + alg.setChild(true); + alg.setRethrows(true); + alg.initialize(); + alg.setProperty("InputWorkspace", inWS); + alg.setProperty("OutputWorkspace", "out"); + alg.execute(); + IMDHistoWorkspace_sptr outputWorkspace = alg.getProperty("OutputWorkspace"); + TSM_ASSERT_EQUALS("Should have a signal of 1.0: ", + outputWorkspace->getSignalAt(0), 1); + TSM_ASSERT_EQUALS("Should have a signal of 1.0: ", + outputWorkspace->getSignalAt(2), 1); + TSM_ASSERT_EQUALS("Should have a signal of 1.0: ", + outputWorkspace->getSignalAt(6), 1); + TSM_ASSERT_EQUALS("Should have a signal of 1.0: ", + outputWorkspace->getSignalAt(8), 1); + TSM_ASSERT_EQUALS("Minimum for dim 0 should be consistent: ", + outputWorkspace->getDimension(0)->getMinimum(), + inWS->getDimension(0)->getMinimum()); + TSM_ASSERT_EQUALS("Maximum for dim 0 should be consistent: ", + outputWorkspace->getDimension(0)->getMaximum(), + inWS->getDimension(0)->getMaximum()); + TSM_ASSERT_EQUALS("Minimum for dim 1 should be consistent:", + outputWorkspace->getDimension(1)->getMinimum(), + inWS->getDimension(1)->getMinimum()); + TSM_ASSERT_EQUALS("Maximum for dim 1 should be consistent: ", + outputWorkspace->getDimension(1)->getMaximum(), + inWS->getDimension(1)->getMaximum()); + TSM_ASSERT_EQUALS("Number of Bins for dim 0 should be consistent : ", + outputWorkspace->getDimension(0)->getNBins(), + inWS->getDimension(0)->getNBins()); + TSM_ASSERT_EQUALS("Number of Bins for dim 1 should be consistent : ", + outputWorkspace->getDimension(1)->getNBins(), + inWS->getDimension(1)->getNBins()); + TSM_ASSERT_EQUALS("Bin width for dim 0 should be consistent: ", + outputWorkspace->getDimension(0)->getBinWidth(), + inWS->getDimension(0)->getBinWidth()); + TSM_ASSERT_EQUALS("Bin width for dim 1 should be consistent: ", + outputWorkspace->getDimension(1)->getBinWidth(), + inWS->getDimension(1)->getBinWidth()); + } + + void + test_all_non_zero_signals_are_kept_when_data_is_concentrated_in_one_half_of_the_workspace() { + /* + *testing the effectiveness of CompactMD when the data looks like this: + *------------------ + * Input structure: + *------------------ + * ------------- + * |///| | | + * ------------- + * -3-2-1 0 1 2 3 + *--------------------------- + * Expected output structure: + *---------------------------- + * should trim until the first non-zero value. + * ----- + * |///| + * ----- + * 1 2 3 + */ + + using namespace Mantid::DataObjects; + const size_t numDims = 1; + const double signal = 0.0; + const double errorSquared = 1.3; + size_t numBins[static_cast<int>(numDims)] = {3}; + Mantid::coord_t min[static_cast<int>(numDims)] = {-3}; + Mantid::coord_t max[static_cast<int>(numDims)] = {3}; + const std::string name("test"); + auto inWS = MDEventsTestHelper::makeFakeMDHistoWorkspaceGeneral( + numDims, signal, errorSquared, numBins, min, max, name); + inWS->setSignalAt(0, 1.0); // set right-most bin signal to one + CompactMD alg; + alg.setChild(true); + alg.setRethrows(true); + alg.initialize(); + alg.setProperty("InputWorkspace", inWS); + alg.setProperty("OutputWorkspace", "out"); + TS_ASSERT_THROWS_NOTHING(alg.execute()); + IMDHistoWorkspace_sptr outputWorkspace = alg.getProperty("OutputWorkspace"); + TS_ASSERT(outputWorkspace); + TSM_ASSERT_EQUALS("Should have a signal of 1.0: ", + outputWorkspace->getSignalAt(0), 1); + TSM_ASSERT_EQUALS("Minimum should be cut to 1: ", + outputWorkspace->getDimension(0)->getMinimum(), -3.0); + TSM_ASSERT_EQUALS("Maximum should still be 3: ", + outputWorkspace->getDimension(0)->getMaximum(), -1.0); + TSM_ASSERT_EQUALS("Number of Bins should be 1 : ", + outputWorkspace->getDimension(0)->getNBins(), 1); + TSM_ASSERT_EQUALS("Bin width should be consistent: ", + outputWorkspace->getDimension(0)->getBinWidth(), + inWS->getDimension(0)->getBinWidth()); + } + void test_compact_md_throws_when_loading_empty_workspace() { + using namespace Mantid::DataObjects; + const size_t numDims = 1; + const double signal = 0.0; + const double errorSquared = 1.3; + size_t numBins[static_cast<int>(numDims)] = {3}; + Mantid::coord_t min[static_cast<int>(numDims)] = {-3}; + Mantid::coord_t max[static_cast<int>(numDims)] = {3}; + const std::string name("test"); + auto inWS = MDEventsTestHelper::makeFakeMDHistoWorkspaceGeneral( + numDims, signal, errorSquared, numBins, min, max, name); + CompactMD alg; + alg.setChild(true); + alg.setRethrows(true); + alg.initialize(); + alg.setProperty("InputWorkspace", inWS); + alg.setProperty("OutputWorkspace", "out"); + TS_ASSERT_THROWS(alg.execute(), std::runtime_error &); + } +}; + +//=================== +// Performance Tests +//=================== +using namespace Mantid::DataObjects; +class CompactMDTestPerformance : public CxxTest::TestSuite { + +private: + MDHistoWorkspace_sptr m_ws; + +public: + // This pair of boilerplate methods prevent the suite being created statically + // This means the constructor isn't called when running other tests + static CompactMDTestPerformance *createSuite() { + return new CompactMDTestPerformance(); + } + static void destroySuite(CompactMDTestPerformance *suite) { delete suite; } + void setUp() { + // Create a 4D workspace. + const size_t numDims = 4; + const double signal = 0.0; + const double errorSquared = 1.2; + size_t numBins[static_cast<int>(numDims)] = {10, 20, 10, 20}; + Mantid::coord_t min[static_cast<int>(numDims)] = {-5, -10, -5, -10}; + Mantid::coord_t max[static_cast<int>(numDims)] = {5, 10, 5, 10}; + const std::string name("test"); + m_ws = MDEventsTestHelper::makeFakeMDHistoWorkspaceGeneral( + numDims, signal, errorSquared, numBins, min, max, name); + // setting signals like this for variety + auto iter = m_ws->createIterator(); + do { + auto index = iter->getLinearIndex(); + if (index % 2 == 0) { + m_ws->setSignalAt(index, 1.0); + } + } while (iter->next()); + } + void test_execute_4d() { + CompactMD alg; + alg.setChild(true); + alg.setRethrows(true); + alg.initialize(); + alg.setProperty("InputWorkspace", m_ws); + alg.setProperty("OutputWorkspace", "out"); + alg.execute(); + IMDHistoWorkspace_sptr outWS = alg.getProperty("OutputWorkspace"); + TS_ASSERT(outWS); + } +}; + +#endif // !MANTID_MDALGORITHMS_COMPACTMDTEST_H_ diff --git a/Framework/Properties/Mantid.properties.template b/Framework/Properties/Mantid.properties.template index 27e669d1d7ff7c2297397b120797a006c97aa4b6..9b160ba84bb9860cdd4b2237dc08e7576198f65b 100644 --- a/Framework/Properties/Mantid.properties.template +++ b/Framework/Properties/Mantid.properties.template @@ -16,7 +16,7 @@ default.facility = ISIS default.instrument = # Set of PyQt interfaces to add to the Interfaces menu, separated by a space. Interfaces are seperated from their respective categories by a "/". -mantidqt.python_interfaces = Direct/DGS_Reduction.py Direct/DGSPlanner.py SANS/ORNL_SANS.py Reflectometry/REFL_Reduction.py Reflectometry/REFL_SF_Calculator.py Reflectometry/REFM_Reduction.py Utility/TofConverter.py Reflectometry/ISIS_Reflectometry.py Diffraction/Powder_Diffraction_Reduction.py Utility/FilterEvents.py Diffraction/HFIR_Powder_Diffraction_Reduction.py +mantidqt.python_interfaces = Direct/DGS_Reduction.py Direct/DGSPlanner.py SANS/ORNL_SANS.py Reflectometry/REFL_Reduction.py Reflectometry/REFL_SF_Calculator.py Reflectometry/REFM_Reduction.py Utility/TofConverter.py Reflectometry/ISIS_Reflectometry.py Diffraction/Powder_Diffraction_Reduction.py Utility/FilterEvents.py Diffraction/HFIR_Powder_Diffraction_Reduction.py Diffraction/HFIR_4Circle_Reduction.py mantidqt.python_interfaces_directory = @MANTID_ROOT@/scripts diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/api/WorkspacePropertyExporter.h b/Framework/PythonInterface/inc/MantidPythonInterface/api/WorkspacePropertyExporter.h index f28cb82152330306db9044da42922b1e994284c0..aff1c6a9507ca2431c3838f5558181fc7933a5b9 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/api/WorkspacePropertyExporter.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/api/WorkspacePropertyExporter.h @@ -134,10 +134,10 @@ template <typename WorkspaceType> struct WorkspacePropertyExporter { API::PropertyMode::Type, API::LockMode::Type>( args("name", "defaultValue", "direction", "optional", "locking"))) // These variants require the validator object to be cloned - .def("__init__", - make_constructor( - &createPropertyWithValidator, default_call_policies(), - args("name", "defaultValue", "direction", "validator"))) + .def("__init__", make_constructor(&createPropertyWithValidator, + default_call_policies(), + (arg("name"), arg("defaultValue"), + arg("direction"), arg("validator")))) .def("__init__", make_constructor(&createPropertyWithOptionalFlag, default_call_policies(), @@ -148,7 +148,7 @@ template <typename WorkspaceType> struct WorkspacePropertyExporter { default_call_policies(), args("name", "defaultValue", "direction", "optional", "locking", "validator"))) - .def("isOptional", &TypedWorkspaceProperty::isOptional, + .def("isOptional", &TypedWorkspaceProperty::isOptional, arg("self"), "Returns true if the property has been marked as optional") .add_property("value", &value); diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/DataServiceExporter.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/DataServiceExporter.h index 5de200f77772535379d80f49cc8303345a0d4aba..90679c67007c4a433a9654ac8c4b214633f45354 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/DataServiceExporter.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/DataServiceExporter.h @@ -66,30 +66,37 @@ template <typename SvcType, typename SvcPtrType> struct DataServiceExporter { auto classType = PythonType(pythonClassName, no_init) .def("add", &DataServiceExporter::addItem, + (arg("self"), arg("name"), arg("item")), "Adds the given object to the service with the given name. If " "the name/object exists it will raise an error.") .def("addOrReplace", &DataServiceExporter::addOrReplaceItem, + (arg("self"), arg("name"), arg("item")), "Adds the given object to the service with the given name. " "The the name exists the object is replaced.") - .def("doesExist", &SvcType::doesExist, + .def("doesExist", &SvcType::doesExist, (arg("self"), arg("name")), "Returns True if the object is found in the service.") .def("retrieve", &DataServiceExporter::retrieveOrKeyError, + (arg("self"), arg("name")), "Retrieve the named object. Raises an exception if the name " "does not exist") - .def("remove", &SvcType::remove, "Remove a named object") - .def("clear", &SvcType::clear, + .def("remove", &SvcType::remove, (arg("self"), arg("name")), + "Remove a named object") + .def("clear", &SvcType::clear, arg("self"), "Removes all objects managed by the service.") - .def("size", &SvcType::size, + .def("size", &SvcType::size, arg("self"), "Returns the number of objects within the service") .def("getObjectNames", &DataServiceExporter::getObjectNamesAsList, + arg("self"), "Return the list of names currently known to the ADS") // Make it act like a dictionary - .def("__len__", &SvcType::size) - .def("__getitem__", &DataServiceExporter::retrieveOrKeyError) - .def("__setitem__", &DataServiceExporter::addOrReplaceItem) - .def("__contains__", &SvcType::doesExist) - .def("__delitem__", &SvcType::remove); + .def("__len__", &SvcType::size, arg("self")) + .def("__getitem__", &DataServiceExporter::retrieveOrKeyError, + (arg("self"), arg("name"))) + .def("__setitem__", &DataServiceExporter::addOrReplaceItem, + (arg("self"), arg("name"), arg("item"))) + .def("__contains__", &SvcType::doesExist, arg("self")) + .def("__delitem__", &SvcType::remove, (arg("self"), arg("name"))); return classType; } diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/TypedValidatorExporter.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/TypedValidatorExporter.h index e876486b65ce12d54ea8a1a57c5e651db2a7a722..aed38b70fe762cec3f5f3df0fa9c7fc1038125f5 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/TypedValidatorExporter.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/TypedValidatorExporter.h @@ -39,7 +39,7 @@ template <typename Type> struct TypedValidatorExporter { class_<TypedValidator<Type>, bases<IValidator>, boost::noncopyable>( pythonClassName, no_init) - .def("isValid", &IValidator::isValid<Type>, + .def("isValid", &IValidator::isValid<Type>, (arg("self"), arg("value")), "Returns an empty string if the value is considered valid, " "otherwise a string defining the error is returned."); } diff --git a/Framework/PythonInterface/mantid/api/src/Exports/Algorithm.cpp b/Framework/PythonInterface/mantid/api/src/Exports/Algorithm.cpp index 0aa43a5125cda02fbee15246c8a18a000b34103e..44b07a508d7484ec85fd0d0b15371ab40f1f85c4 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/Algorithm.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/Algorithm.cpp @@ -42,7 +42,11 @@ typedef void (*declarePropertyType3)(boost::python::object &self, typedef void (*declarePropertyType4)(boost::python::object &self, const std::string &, const boost::python::object &, const int); - +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wunused-local-typedef" +#endif // Overload types BOOST_PYTHON_FUNCTION_OVERLOADS(declarePropertyType1_Overload, PythonAlgorithm::declarePyAlgProperty, 2, 3) @@ -50,7 +54,9 @@ BOOST_PYTHON_FUNCTION_OVERLOADS(declarePropertyType2_Overload, PythonAlgorithm::declarePyAlgProperty, 3, 6) BOOST_PYTHON_FUNCTION_OVERLOADS(declarePropertyType3_Overload, PythonAlgorithm::declarePyAlgProperty, 4, 5) - +#ifdef __clang__ +#pragma clang diagnostic pop +#endif /** * Map a CancelException to a Python KeyboardInterupt * @param exc A cancel exception to translate. Unused here as the message is @@ -77,22 +83,19 @@ void export_leaf_classes() { .def("fromString", &Algorithm::fromString, "Initialize the algorithm from a string representation") .staticmethod("fromString") - .def("createChildAlgorithm", &Algorithm::createChildAlgorithm, - (arg("name"), arg("startProgress") = -1.0, arg("endProgress") = -1.0, - arg("enableLogging") = true, arg("version") = -1), + (arg("self"), arg("name"), arg("startProgress") = -1.0, + arg("endProgress") = -1.0, arg("enableLogging") = true, + arg("version") = -1), "Creates and intializes a named child algorithm. Output workspaces " "are given a dummy name.") - .def("declareProperty", (declarePropertyType1)&PythonAlgorithm::declarePyAlgProperty, declarePropertyType1_Overload( (arg("self"), arg("prop"), arg("doc") = ""))) - .def("enableHistoryRecordingForChild", - &Algorithm::enableHistoryRecordingForChild, (args("on")), + &Algorithm::enableHistoryRecordingForChild, (arg("self"), arg("on")), "Turns history recording on or off for an algorithm.") - .def("declareProperty", (declarePropertyType2)&PythonAlgorithm::declarePyAlgProperty, declarePropertyType2_Overload( @@ -102,7 +105,6 @@ void export_leaf_classes() { "Declares a named property where the type is taken from " "the type of the defaultValue and mapped to an appropriate C++ " "type")) - .def("declareProperty", (declarePropertyType3)&PythonAlgorithm::declarePyAlgProperty, declarePropertyType3_Overload( @@ -111,23 +113,22 @@ void export_leaf_classes() { "Declares a named property where the type is taken from the " "type " "of the defaultValue and mapped to an appropriate C++ type")) - .def("declareProperty", (declarePropertyType4)&PythonAlgorithm::declarePyAlgProperty, (arg("self"), arg("name"), arg("defaultValue"), arg("direction") = Direction::Input), "Declares a named property where the type is taken from the type " "of the defaultValue and mapped to an appropriate C++ type") - - .def("getLogger", &PythonAlgorithm::getLogger, + .def("getLogger", &PythonAlgorithm::getLogger, arg("self"), return_value_policy<reference_existing_object>(), "Returns a reference to this algorithm's logger") - .def("log", &PythonAlgorithm::getLogger, + .def("log", &PythonAlgorithm::getLogger, arg("self"), return_value_policy<reference_existing_object>(), "Returns a reference to this algorithm's logger") // Traditional name // deprecated methods .def("setWikiSummary", &PythonAlgorithm::setWikiSummary, + (arg("self"), arg("summary")), "(Deprecated.) Set summary for the help."); // Prior to version 3.2 there was a separate C++ PythonAlgorithm class that diff --git a/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmFactory.cpp b/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmFactory.cpp index 48b3811552796c151162c47efb7a013fbd5415aa..16596444d5052301e09371c9ef001fdf29eb5665 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmFactory.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmFactory.cpp @@ -99,8 +99,15 @@ void subscribe(AlgorithmFactoryImpl &self, const boost::python::object &obj) { // from the FileLoaderRegistry FileLoaderRegistry::Instance().unsubscribe(descr.first, descr.second); } - +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wunused-local-typedef" +#endif BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(existsOverloader, exists, 1, 2) +#ifdef __clang__ +#pragma clang diagnostic pop +#endif ///@endcond } @@ -118,12 +125,15 @@ void export_AlgorithmFactory() { "an option to specify the version")) .def("getRegisteredAlgorithms", &getRegisteredAlgorithms, + (arg("self"), arg("include_hidden")), "Returns a Python dictionary of currently registered algorithms") .def("highestVersion", &AlgorithmFactoryImpl::highestVersion, + (arg("self"), arg("algorithm_name")), "Returns the highest version of the named algorithm. Throws " "ValueError if no algorithm can be found") - .def("subscribe", &subscribe, "Register a Python class derived from " - "PythonAlgorithm into the factory") + .def("subscribe", &subscribe, (arg("self"), arg("object")), + "Register a Python class derived from " + "PythonAlgorithm into the factory") .def("Instance", &AlgorithmFactory::Instance, return_value_policy<reference_existing_object>(), diff --git a/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmHistory.cpp b/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmHistory.cpp index 8c886db7e8e024996dfda59da964188d8b61eb96..05a5f7045434a46b2bbd1ba14e0f7e9a2b35ec6a 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmHistory.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmHistory.cpp @@ -58,40 +58,42 @@ void export_AlgorithmHistory() { register_ptr_to_python<Mantid::API::AlgorithmHistory_sptr>(); class_<AlgorithmHistory>("AlgorithmHistory", no_init) - .def("name", &AlgorithmHistory::name, + .def("name", &AlgorithmHistory::name, arg("self"), return_value_policy<copy_const_reference>(), "Returns the name of the algorithm.") - .def("version", &AlgorithmHistory::version, + .def("version", &AlgorithmHistory::version, arg("self"), return_value_policy<copy_const_reference>(), "Returns the version of the algorithm.") .def("executionDuration", &AlgorithmHistory::executionDuration, - "Returns the execution duration of the algorithm.") + arg("self"), "Returns the execution duration of the algorithm.") - .def("executionDate", &AlgorithmHistory::executionDate, + .def("executionDate", &AlgorithmHistory::executionDate, arg("self"), "Returns the execution date of the algorithm.") - .def("execCount", &AlgorithmHistory::execCount, + .def("execCount", &AlgorithmHistory::execCount, arg("self"), return_value_policy<copy_const_reference>(), "Returns the execution number of the algorithm.") - .def("childHistorySize", &AlgorithmHistory::childHistorySize, + .def("childHistorySize", &AlgorithmHistory::childHistorySize, arg("self"), "Returns the number of the child algorithms.") .def("getChildAlgorithmHistory", - &AlgorithmHistory::getChildAlgorithmHistory, arg("index"), + &AlgorithmHistory::getChildAlgorithmHistory, + (arg("self"), arg("index")), "Returns the child algorithm at the given index in the history") - .def("getChildHistories", &getChildrenAsList, "Returns a list of child " - "algorithm histories for " - "this algorithm history.") + .def("getChildHistories", &getChildrenAsList, arg("self"), + "Returns a list of child " + "algorithm histories for " + "this algorithm history.") - .def("getProperties", &getPropertiesAsList, + .def("getProperties", &getPropertiesAsList, arg("self"), "Returns properties for this algorithm history.") .def("getChildAlgorithm", &AlgorithmHistory::getChildAlgorithm, - arg("index"), + (arg("self"), arg("index")), "Returns the algorithm at the given index in the history") // ----------------- Operators -------------------------------------- .def(self_ns::str(self)); diff --git a/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmManager.cpp b/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmManager.cpp index f827fd3728ba1ebccc8943358a1da9c8f7a28563..283b71e128e716988c2c52cc63c09f788932503f 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmManager.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmManager.cpp @@ -57,12 +57,20 @@ boost::python::list runningInstancesOf(AlgorithmManagerImpl &self, ///@cond //------------------------------------------------------------------------------------------------------ +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wunused-local-typedef" +#endif /// Define overload generators BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(create_overloads, AlgorithmManagerImpl::create, 1, 2) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(createUnmanaged_overloads, AlgorithmManagerImpl::createUnmanaged, 1, 2) +#ifdef __clang__ +#pragma clang diagnostic pop +#endif ///@endcond } @@ -78,22 +86,25 @@ void export_AlgorithmManager() { .def("createUnmanaged", &AlgorithmManagerImpl::createUnmanaged, createUnmanaged_overloads((arg("name"), arg("version")), "Creates an unmanaged algorithm.")) - .def("size", &AlgorithmManagerImpl::size, + .def("size", &AlgorithmManagerImpl::size, arg("self"), "Returns the number of managed algorithms") .def("setMaxAlgorithms", &AlgorithmManagerImpl::setMaxAlgorithms, + (arg("self"), arg("n")), "Set the maximum number of allowed managed algorithms") - .def("getAlgorithm", &getAlgorithm, + .def("getAlgorithm", &getAlgorithm, (arg("self"), arg("id_holder")), "Return the algorithm instance identified by the given id.") - .def("removeById", &removeById, + .def("removeById", &removeById, (arg("self"), arg("id_holder")), "Remove an algorithm from the managed list") .def("newestInstanceOf", &AlgorithmManagerImpl::newestInstanceOf, + (arg("self"), arg("algorithm_name")), "Returns the newest created instance of the named algorithm") .def("runningInstancesOf", &runningInstancesOf, + (arg("self"), arg("algorithm_name")), "Returns a list of managed algorithm instances that are " "currently executing") - .def("clear", &AlgorithmManagerImpl::clear, + .def("clear", &AlgorithmManagerImpl::clear, arg("self"), "Clears the current list of managed algorithms") - .def("cancelAll", &AlgorithmManagerImpl::cancelAll, + .def("cancelAll", &AlgorithmManagerImpl::cancelAll, arg("self"), "Requests that all currently running algorithms be cancelled"); // Instance method diff --git a/Framework/PythonInterface/mantid/api/src/Exports/Axis.cpp b/Framework/PythonInterface/mantid/api/src/Exports/Axis.cpp index 0df0e6417b49f3a387dacbd0df445430981119e2..664da1fb0da97aea7d9a3bfca91669d1b2683fa9 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/Axis.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/Axis.cpp @@ -25,9 +25,19 @@ namespace { namespace bpl = boost::python; //------------------------------- Overload macros --------------------------- +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wunused-local-typedef" +#endif + // Overloads for operator() function which has 1 optional argument BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Axis_getValue, Axis::getValue, 1, 2) +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + /** * Extract the axis values as a sequence. A numpy array is used if the * data is numerical or a simple python list is used if the data is a string @@ -73,33 +83,41 @@ void export_Axis() { // Class class_<Axis, boost::noncopyable>("MantidAxis", no_init) - .def("length", &Axis::length, "Returns the length of the axis") + .def("length", &Axis::length, arg("self"), + "Returns the length of the axis") .def("title", (const std::string &(Axis::*)() const) & Axis::title, - return_value_policy<copy_const_reference>(), "Get the axis title") - .def("isSpectra", &Axis::isSpectra, + arg("self"), return_value_policy<copy_const_reference>(), + "Get the axis title") + .def("isSpectra", &Axis::isSpectra, arg("self"), "Returns true if this is a SpectraAxis") - .def("isNumeric", &Axis::isNumeric, + .def("isNumeric", &Axis::isNumeric, arg("self"), "Returns true if this is a NumericAxis") - .def("isText", &Axis::isText, "Returns true if this is a TextAxis") - .def("label", &Axis::label, "Return the axis label") + .def("isText", &Axis::isText, arg("self"), + "Returns true if this is a TextAxis") + .def("label", &Axis::label, (arg("self"), arg("index")), + "Return the axis label") .def("getUnit", (const Unit_sptr &(Axis::*)() const) & Axis::unit, - return_value_policy<copy_const_reference>(), + arg("self"), return_value_policy<copy_const_reference>(), "Returns the unit object for the axis") .def("getValue", &Axis::getValue, - Axis_getValue(args("index", "vertical_index"), + Axis_getValue((arg("self"), arg("index"), arg("vertical_index")), "Returns the value at the given point on the Axis. " "The vertical axis index [default=0]")) - .def("extractValues", &extractAxisValues, + .def("extractValues", &extractAxisValues, arg("self"), "Return a numpy array of the axis values") - .def("setUnit", &Axis::setUnit, + .def("setUnit", &Axis::setUnit, (arg("self"), arg("unit_name")), return_value_policy<copy_const_reference>(), "Set the unit for this axis by name.") - .def("setValue", &Axis::setValue, "Set a value at the given index") - .def("getMin", &Axis::getMin, "Get min value specified on the axis") - .def("getMax", &Axis::getMax, "Get max value specified on the axis") + .def("setValue", &Axis::setValue, + (arg("self"), arg("index"), arg("value")), + "Set a value at the given index") + .def("getMin", &Axis::getMin, arg("self"), + "Get min value specified on the axis") + .def("getMax", &Axis::getMax, arg("self"), + "Get max value specified on the axis") //------------------------------------ Special methods //------------------------------------ - .def("__len__", &Axis::length); + .def("__len__", &Axis::length, arg("self")); } // -------------------------------------------------------------------------------------------- @@ -118,7 +136,8 @@ void export_NumericAxis() { /// Exported so that Boost.Python can give back a NumericAxis class when an /// Axis* is returned class_<NumericAxis, bases<Axis>, boost::noncopyable>("NumericAxis", no_init) - .def("create", &createNumericAxis, return_internal_reference<>(), + .def("create", &createNumericAxis, arg("length"), + return_internal_reference<>(), "Creates a new NumericAxis of a specified length") .staticmethod("create"); } @@ -141,7 +160,8 @@ void export_BinEdgeAxis() { /// Axis* is returned class_<BinEdgeAxis, bases<NumericAxis>, boost::noncopyable>("BinEdgeAxis", no_init) - .def("create", &createBinEdgeAxis, return_internal_reference<>(), + .def("create", &createBinEdgeAxis, arg("length"), + return_internal_reference<>(), "Creates a new BinEdgeAxis of a specified length") .staticmethod("create"); } @@ -159,9 +179,13 @@ Axis *createTextAxis(int length) { return new Mantid::API::TextAxis(length); } void export_TextAxis() { class_<TextAxis, bases<Axis>, boost::noncopyable>("TextAxis", no_init) - .def("setLabel", &TextAxis::setLabel, "Set the label at the given entry") - .def("label", &TextAxis::label, "Return the label at the given position") - .def("create", &createTextAxis, return_internal_reference<>(), + .def("setLabel", &TextAxis::setLabel, + (arg("self"), arg("index"), arg("label")), + "Set the label at the given entry") + .def("label", &TextAxis::label, (arg("self"), arg("index")), + "Return the label at the given position") + .def("create", &createTextAxis, arg("length"), + return_internal_reference<>(), "Creates a new TextAxis of a specified length") .staticmethod("create"); } diff --git a/Framework/PythonInterface/mantid/api/src/Exports/BoxController.cpp b/Framework/PythonInterface/mantid/api/src/Exports/BoxController.cpp index 7caf592a3ea586aad1dc6544bb2b80c7024c543b..af6debd38bd7864bcda9671f74e9e7979deeeed6 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/BoxController.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/BoxController.cpp @@ -11,24 +11,28 @@ void export_BoxController() { register_ptr_to_python<boost::shared_ptr<BoxController>>(); class_<BoxController, boost::noncopyable>("BoxController", no_init) - .def("getNDims", &BoxController::getNDims, "Get # of dimensions") - .def("getSplitThreshold", &BoxController::getSplitThreshold, + .def("getNDims", &BoxController::getNDims, arg("self"), + "Get # of dimensions") + .def("getSplitThreshold", &BoxController::getSplitThreshold, arg("self"), "Return the splitting threshold, in # of events") .def("getSplitInto", &BoxController::getSplitInto, + (arg("self"), arg("dim")), "Return into how many to split along a dimension") - .def("getMaxDepth", &BoxController::getMaxDepth, + .def("getMaxDepth", &BoxController::getMaxDepth, arg("self"), "Return the max recursion depth allowed for grid box splitting.") .def("getTotalNumMDBoxes", &BoxController::getTotalNumMDBoxes, + arg("self"), "Return the total number of MD Boxes, irrespective of depth") .def("getTotalNumMDGridBoxes", &BoxController::getTotalNumMDGridBoxes, + arg("self"), "Return the total number of MDGridBox'es, irrespective of depth") - .def("getAverageDepth", &BoxController::getAverageDepth, + .def("getAverageDepth", &BoxController::getAverageDepth, arg("self"), "Return the average recursion depth of gridding.") - .def("isFileBacked", &BoxController::isFileBacked, + .def("isFileBacked", &BoxController::isFileBacked, arg("self"), "Return True if the MDEventWorkspace is backed by a file ") - .def("getFilename", &BoxController::getFilename, + .def("getFilename", &BoxController::getFilename, arg("self"), "Return the full path to the file open as the file-based back or " "empty string if no file back-end is initiated") - .def("useWriteBuffer", &BoxController::useWriteBuffer, + .def("useWriteBuffer", &BoxController::useWriteBuffer, arg("self"), "Return true if the MRU should be used"); } diff --git a/Framework/PythonInterface/mantid/api/src/Exports/DataProcessorAlgorithm.cpp b/Framework/PythonInterface/mantid/api/src/Exports/DataProcessorAlgorithm.cpp index 1dacf9c7bc503e3455d541b358f1beb3dac72b61..00c8a38090785a1306a40883c221b28f3dffbcd5 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/DataProcessorAlgorithm.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/DataProcessorAlgorithm.cpp @@ -25,61 +25,72 @@ void export_DataProcessorAlgorithm() { "DataProcessorAlgorithm", "Base class workflow-type algorithms") .def("setLoadAlg", &DataProcessorAdapter::setLoadAlgProxy, + (arg("self"), arg("alg")), "Set the name of the algorithm called using the load() method " "[Default=Load]") .def("setLoadAlgFileProp", &DataProcessorAdapter::setLoadAlgFilePropProxy, + (arg("self"), arg("file_prop_name")), "Set the name of the file property for the load algorithm when " "using " "the load() method [Default=Filename]") .def("setAccumAlg", &DataProcessorAdapter::setAccumAlgProxy, + (arg("self"), arg("alg")), "Set the name of the algorithm called to accumulate a chunk of " "processed data [Default=Plus]") .def("determineChunk", &DataProcessorAdapter::determineChunkProxy, + (arg("self"), arg("file_name")), "Return a TableWorkspace containing the information on how to split " "the " "input file when processing in chunks") .def("loadChunk", &DataProcessorAdapter::loadChunkProxy, - "Load a chunk of data") + (arg("self"), arg("row_index")), "Load a chunk of data") .def("load", (loadOverload1)&DataProcessorAdapter::loadProxy, + (arg("self"), arg("input_data")), "Loads the given file or workspace data and returns the workspace. " "The output is not stored in the AnalysisDataService.") .def("load", (loadOverload2)&DataProcessorAdapter::loadProxy, + (arg("self"), arg("input_data"), arg("load_quite")), "Loads the given file or workspace data and returns the workspace. " "If loadQuiet=True then output is not stored in the " "AnalysisDataService.") .def("splitInput", &DataProcessorAdapter::splitInputProxy, - return_value_policy<VectorToNumpy>()) + (arg("self"), arg("input")), return_value_policy<VectorToNumpy>()) - .def("forwardProperties", &DataProcessorAdapter::forwardPropertiesProxy) + .def("forwardProperties", &DataProcessorAdapter::forwardPropertiesProxy, + arg("self")) .def("getProcessProperties", &DataProcessorAdapter::getProcessPropertiesProxy, + (arg("self"), arg("property_manager")), "Returns the named property manager from the service or creates " "a new one if it does not exist") .def("assemble", &DataProcessorAdapter::assembleProxy, + (arg("self"), arg("partial_wsname"), arg("output_wsname")), "If an MPI build, assemble the partial workspaces from all MPI " "processes. " "Otherwise, simply returns the input workspace") .def("saveNexus", &DataProcessorAdapter::saveNexusProxy, + (arg("self"), arg("output_wsname"), arg("output_filename")), "Save a workspace as a nexus file. If this is an MPI build then " "saving only " "happens for the main thread.") .def("isMainThread", &DataProcessorAdapter::isMainThreadProxy, + arg("self"), "Returns true if this algorithm is the main thread for an MPI " "build. For " "non-MPI build it always returns true") - .def("getNThreads", &DataProcessorAdapter::getNThreadsProxy, + .def("getNThreads", &DataProcessorAdapter::getNThreadsProxy, arg("self"), "Returns the number of running MPI processes in an MPI build or 1 " "for " "a non-MPI build"); diff --git a/Framework/PythonInterface/mantid/api/src/Exports/ExperimentInfo.cpp b/Framework/PythonInterface/mantid/api/src/Exports/ExperimentInfo.cpp index 758c1c8e2a933bc2f15a62470d37281966dac503..926a6d0b31e49e4e9970553c29118e819f30f7fd 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/ExperimentInfo.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/ExperimentInfo.cpp @@ -10,9 +10,17 @@ using Mantid::API::ExperimentInfo; using Mantid::PythonInterface::Policies::RemoveConstSharedPtr; using namespace boost::python; +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wunused-local-typedef" +#endif /// Overload generator for getInstrumentFilename BOOST_PYTHON_FUNCTION_OVERLOADS(getInstrumentFilename_Overload, ExperimentInfo::getInstrumentFilename, 1, 2) +#ifdef __clang__ +#pragma clang diagnostic pop +#endif void export_ExperimentInfo() { register_ptr_to_python<boost::shared_ptr<ExperimentInfo>>(); diff --git a/Framework/PythonInterface/mantid/api/src/Exports/FileFinder.cpp b/Framework/PythonInterface/mantid/api/src/Exports/FileFinder.cpp index f762919cdf1a63339a14da24330e4208426b954c..6d216cc065028263cc2edb49956b08f50b7456bc 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/FileFinder.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/FileFinder.cpp @@ -8,18 +8,26 @@ using Mantid::API::FileFinderImpl; using namespace boost::python; namespace { +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wunused-local-typedef" +#endif BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(getFullPathOverloader, getFullPath, 1, 2) +#ifdef __clang__ +#pragma clang diagnostic pop +#endif } void export_FileFinder() { class_<FileFinderImpl, boost::noncopyable>("FileFinderImpl", no_init) .def("getFullPath", &FileFinderImpl::getFullPath, getFullPathOverloader( - (arg("path"), arg("ignoreDirs") = false), + (arg("self"), arg("path"), arg("ignoreDirs") = false), "Return a full path to the given file if it can be found within " "datasearch.directories paths. Directories can be ignored with " "ignoreDirs=True. An empty string is returned otherwise.")) - .def("findRuns", &FileFinderImpl::findRuns, + .def("findRuns", &FileFinderImpl::findRuns, (arg("self"), arg("hintstr")), "Find a list of files file given a hint. " "The hint can be a comma separated list of run numbers and can also " "include ranges of runs, e.g. 123-135 or equivalently 123-35" diff --git a/Framework/PythonInterface/mantid/api/src/Exports/FileLoaderRegistry.cpp b/Framework/PythonInterface/mantid/api/src/Exports/FileLoaderRegistry.cpp index 5935cb7aae9932ac57f2f9c6f8ce18203e867f2d..baa9c3e8a188627728b20dfa745d7dd2cdfbaee7 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/FileLoaderRegistry.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/FileLoaderRegistry.cpp @@ -10,9 +10,10 @@ void export_FileLoaderRegistry() { class_<FileLoaderRegistryImpl, boost::noncopyable>("FileLoaderRegistryImpl", no_init) .def("canLoad", &FileLoaderRegistryImpl::canLoad, + (arg("self"), arg("algorithm_name"), arg("file_name")), "Perform a check that that the given algorithm can load the file") .def("Instance", &FileLoaderRegistry::Instance, return_value_policy<reference_existing_object>(), "Returns a reference to the FileLoaderRegistry singleton instance") .staticmethod("Instance"); -} \ No newline at end of file +} diff --git a/Framework/PythonInterface/mantid/api/src/Exports/FrameworkManager.cpp b/Framework/PythonInterface/mantid/api/src/Exports/FrameworkManager.cpp index 1e31d32096f1b312b05f7f5cfff115ab486ccf85..d6df442a862bd0060019dd70b7ef395c26ec8a73 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/FrameworkManager.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/FrameworkManager.cpp @@ -12,31 +12,34 @@ void export_FrameworkManager() { class_<FrameworkManagerImpl, boost::noncopyable>("FrameworkManagerImpl", no_init) .def("setNumOMPThreadsToConfigValue", - &FrameworkManagerImpl::setNumOMPThreadsToConfigValue, + &FrameworkManagerImpl::setNumOMPThreadsToConfigValue, arg("self"), "Sets the number of OpenMP threads to the value specified in the " "config file") .def("setNumOMPThreads", &FrameworkManagerImpl::setNumOMPThreads, + (arg("self"), arg("nthread")), "Set the number of OpenMP threads to the given value") .def("getNumOMPThreads", &FrameworkManagerImpl::getNumOMPThreads, + arg("self"), "Returns the number of OpenMP threads that will be used.") - .def("clear", &FrameworkManagerImpl::clear, + .def("clear", &FrameworkManagerImpl::clear, arg("self"), "Clear all memory held by Mantid") .def("clearAlgorithms", &FrameworkManagerImpl::clearAlgorithms, + arg("self"), "Clear memory held by algorithms (does not include workspaces)") - .def("clearData", &FrameworkManagerImpl::clearData, + .def("clearData", &FrameworkManagerImpl::clearData, arg("self"), "Clear memory held by the data service (essentially all workspaces, " "including hidden)") .def("clearInstruments", &FrameworkManagerImpl::clearInstruments, - "Clear memory held by the cached instruments") + arg("self"), "Clear memory held by the cached instruments") .def("clearPropertyManagers", - &FrameworkManagerImpl::clearPropertyManagers, + &FrameworkManagerImpl::clearPropertyManagers, arg("self"), "Clear memory held by the PropertyManagerDataService") .def("Instance", &FrameworkManager::Instance, diff --git a/Framework/PythonInterface/mantid/api/src/Exports/FunctionFactory.cpp b/Framework/PythonInterface/mantid/api/src/Exports/FunctionFactory.cpp index 2d94e8f7aea8f4484f240f8b13488aa68e7a6d44..7735fc15decf7418218e07c3b204f3235ef4774c 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/FunctionFactory.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/FunctionFactory.cpp @@ -89,15 +89,15 @@ void export_FunctionFactory() { class_<FunctionFactoryImpl, boost::noncopyable>("FunctionFactoryImpl", no_init) - .def("getFunctionNames", &getFunctionNames, + .def("getFunctionNames", &getFunctionNames, arg("self"), "Returns a list of the currently available functions") .def("createFunction", &FunctionFactoryImpl::createFunction, + (arg("self"), arg("type")), "Return a pointer to the requested function") - .def("subscribe", &subscribe, + .def("subscribe", &subscribe, (arg("self"), arg("object")), "Register a Python class derived from IFunction into the factory") .def("unsubscribe", &FunctionFactoryImpl::unsubscribe, - "Remove a type from the factory") - + (arg("self"), arg("class_name")), "Remove a type from the factory") .def("Instance", &FunctionFactory::Instance, return_value_policy<reference_existing_object>(), "Returns a reference to the FunctionFactory singleton") diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp index e2be117bf9a2e743ff79c79dfc3e2a0e5843cf51..009ca30fb110ff5ede255104d493cfe8e16fcbdf 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp @@ -302,89 +302,102 @@ void export_ialgorithm() { class_<IAlgorithm, bases<IPropertyManager>, boost::noncopyable>( "IAlgorithm", "Interface for all algorithms", no_init) - .def("name", &IAlgorithm::name, "Returns the name of the algorithm") - .def("alias", &IAlgorithm::alias, "Return the aliases for the algorithm") - .def("version", &IAlgorithm::version, + .def("name", &IAlgorithm::name, arg("self"), + "Returns the name of the algorithm") + .def("alias", &IAlgorithm::alias, arg("self"), + "Return the aliases for the algorithm") + .def("version", &IAlgorithm::version, arg("self"), "Returns the version number of the algorithm") - .def("cancel", &IAlgorithm::cancel, + .def("cancel", &IAlgorithm::cancel, arg("self"), "Request that the algorithm stop running") - .def("category", &IAlgorithm::category, + .def("category", &IAlgorithm::category, arg("self"), "Returns the category containing the algorithm") - .def("categories", &IAlgorithm::categories, + .def("categories", &IAlgorithm::categories, arg("self"), "Returns the list of categories this algorithm belongs to") - .def("summary", &IAlgorithm::summary, + .def("summary", &IAlgorithm::summary, arg("self"), "Returns a summary message describing the algorithm") - .def("workspaceMethodName", &IAlgorithm::workspaceMethodName, + .def("workspaceMethodName", &IAlgorithm::workspaceMethodName, arg("self"), "Returns a name that will be used when attached as a workspace " "method. Empty string indicates do not attach") - .def("workspaceMethodOn", &IAlgorithm::workspaceMethodOn, + .def("workspaceMethodOn", &IAlgorithm::workspaceMethodOn, arg("self"), return_value_policy<VectorToNumpy>(), // creates a list for strings "Returns a set of class names that will have the method attached. " "Empty list indicates all types") .def("workspaceMethodInputProperty", - &IAlgorithm::workspaceMethodInputProperty, + &IAlgorithm::workspaceMethodInputProperty, arg("self"), "Returns the name of the input workspace property used by the " "calling object") - .def("getAlgorithmID", &getAlgorithmID, + .def("getAlgorithmID", &getAlgorithmID, arg("self"), "Returns a unique identifier for this algorithm object") - .def("docString", &createDocString, + .def("docString", &createDocString, arg("self"), "Returns a doc string for the algorithm") .def("mandatoryProperties", &getInputPropertiesWithMandatoryFirst, + arg("self"), "Returns a list of input and in/out property names that is ordered " "such that the mandatory properties are first followed by the " "optional ones.") - .def("orderedProperties", &getAlgorithmPropertiesOrdered, + .def("orderedProperties", &getAlgorithmPropertiesOrdered, arg("self"), "Return a list of input, in/out and output properties " "such that the mandatory properties are first followed by the " "optional ones.") - .def("outputProperties", &getOutputProperties, + .def("outputProperties", &getOutputProperties, arg("self"), "Returns a list of the output properties on the algorithm") - .def("isInitialized", &IAlgorithm::isInitialized, + .def("isInitialized", &IAlgorithm::isInitialized, arg("self"), "Returns True if the algorithm is initialized, False otherwise") - .def("isExecuted", &IAlgorithm::isExecuted, + .def("isExecuted", &IAlgorithm::isExecuted, arg("self"), "Returns True if the algorithm has been executed successfully, " "False otherwise") - .def("isLogging", &IAlgorithm::isLogging, "Returns True if the " - "algorithm's logger is turned " - "on, False otherwise") - .def("isRunning", &IAlgorithm::isRunning, "Returns True if the algorithm " - "is considered to be running, " - "False otherwise") - .def("setChild", &IAlgorithm::setChild, + .def("isLogging", &IAlgorithm::isLogging, arg("self"), + "Returns True if the " + "algorithm's logger is turned " + "on, False otherwise") + .def("isRunning", &IAlgorithm::isRunning, arg("self"), + "Returns True if the algorithm " + "is considered to be running, " + "False otherwise") + .def("setChild", &IAlgorithm::setChild, (arg("self"), arg("is_child")), "If true this algorithm is run as a child algorithm. There will be " "no logging and nothing is stored in the Analysis Data Service") .def("enableHistoryRecordingForChild", &IAlgorithm::enableHistoryRecordingForChild, + (arg("self"), arg("on")), "If true then history will be recorded regardless of the child " "status") .def("setAlgStartupLogging", &IAlgorithm::setAlgStartupLogging, + (arg("self"), arg("enabled")), "If true then allow logging of start and end messages") .def("getAlgStartupLogging", &IAlgorithm::getAlgStartupLogging, - "Returns true if logging of start and end messages") + arg("self"), "Returns true if logging of start and end messages") .def("setAlwaysStoreInADS", &IAlgorithm::setAlwaysStoreInADS, + (arg("self"), arg("do_store")), "If true then even child algorithms will have their workspaces " "stored in the ADS.") - .def("isChild", &IAlgorithm::isChild, + .def("isChild", &IAlgorithm::isChild, arg("self"), "Returns True if the algorithm has been marked to run as a child. " "If True then Output workspaces " "are NOT stored in the Analysis Data Service but must be retrieved " "from the property.") - .def("setLogging", &IAlgorithm::setLogging, "Toggle logging on/off.") - .def("setRethrows", &IAlgorithm::setRethrows) - .def("initialize", &IAlgorithm::initialize, "Initializes the algorithm") - .def("validateInputs", &IAlgorithm::validateInputs, + .def("setLogging", &IAlgorithm::setLogging, (arg("self"), arg("value")), + "Toggle logging on/off.") + .def("setRethrows", &IAlgorithm::setRethrows, + (arg("self"), arg("rethrow")), "To query whether an algorithm " + "should rethrow exceptions when " + "executing.") + .def("initialize", &IAlgorithm::initialize, arg("self"), + "Initializes the algorithm") + .def("validateInputs", &IAlgorithm::validateInputs, arg("self"), "Cross-check all inputs and return any errors as a dictionary") - .def("execute", &executeProxy, + .def("execute", &executeProxy, arg("self"), "Runs the algorithm and returns whether it has been successful") // 'Private' static methods - .def("_algorithmInThread", &_algorithmInThread) + .def("_algorithmInThread", &_algorithmInThread, arg("thread_id")) .staticmethod("_algorithmInThread") // Special methods - .def("__str__", &IAlgorithm::toString) + .def("__str__", &IAlgorithm::toString, arg("self")) // deprecated methods - .def("getOptionalMessage", &getOptionalMessage, + .def("getOptionalMessage", &getOptionalMessage, arg("self"), "Returns the optional user message attached to the algorithm") - .def("getWikiSummary", &getWikiSummary, + .def("getWikiSummary", &getWikiSummary, arg("self"), "Returns the summary found on the wiki page"); } diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IFunction.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IFunction.cpp index 77761eb93936d24f8948d8cb9c6fdd1604d6f813..4805e9a712f33945ff66e444d5968e5cd0d0e139 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/IFunction.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/IFunction.cpp @@ -34,6 +34,11 @@ PyObject *getCategories(IFunction &self) { // -- Set property overloads -- // setProperty(index,value,explicit) typedef void (IFunction::*setParameterType1)(size_t, const double &value, bool); +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wunused-local-typedef" +#endif BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setParameterType1_Overloads, setParameter, 2, 3) // setProperty(index,value,explicit) @@ -41,7 +46,9 @@ typedef void (IFunction::*setParameterType2)(const std::string &, const double &value, bool); BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setParameterType2_Overloads, setParameter, 2, 3) - +#ifdef __clang__ +#pragma clang diagnostic pop +#endif ///@endcond } @@ -51,82 +58,96 @@ void export_IFunction() { class_<IFunction, IFunctionAdapter, boost::noncopyable>( "IFunction", "Base class for all functions", no_init) - .def("name", &IFunction::name, "Return the name of the function") + .def("name", &IFunction::name, arg("self"), + "Return the name of the function") - .def("category", &IFunctionAdapter::category, + .def("category", &IFunctionAdapter::category, arg("self"), "Return a semi-colon(;) separated string for the categories this " "class should belong to. For sub-categories use a \\ separator") - .def("initialize", &IFunction::initialize, + .def("initialize", &IFunction::initialize, arg("self"), "Declares any parameters and attributes on the function") - .def("getCategories", &getCategories, + .def("getCategories", &getCategories, arg("self"), "Returns a list of the categories for an algorithm") - .def("nAttributes", &IFunction::nAttributes, + .def("nAttributes", &IFunction::nAttributes, arg("self"), "Return the number of attributes (non-fitting arguments)") - .def("attributeNames", &IFunction::getAttributeNames, + .def("attributeNames", &IFunction::getAttributeNames, arg("self"), "The names of all the attributes") - .def("nParams", &IFunction::nParams, "Return the number of parameters") + .def("nParams", &IFunction::nParams, arg("self"), + "Return the number of parameters") - .def("parameterName", &IFunction::parameterName, + .def("parameterName", &IFunction::parameterName, (arg("self"), arg("i")), "Return the name of the ith parameter") .def("paramDescription", &IFunction::parameterDescription, - "Return a description of the ith parameter") + (arg("self"), arg("i")), "Return a description of the ith parameter") .def("isExplicitlySet", &IFunction::isExplicitlySet, + (arg("self"), arg("i")), "Return whether the ith parameter needs to be explicitely set") .def("getParameterValue", (double (IFunction::*)(size_t) const) & IFunction::getParameter, - "Get the value of the ith parameter") + (arg("self"), arg("i")), "Get the value of the ith parameter") .def("getParameterValue", (double (IFunction::*)(const std::string &) const) & IFunction::getParameter, - "Get the value of the named parameter") + (arg("self"), arg("name")), "Get the value of the named parameter") .def("setParameter", (setParameterType1)&IFunction::setParameter, - setParameterType1_Overloads("Sets the value of the ith parameter")) + setParameterType1_Overloads( + (arg("self"), arg("i"), arg("value"), arg("explicitlySet")), + "Sets the value of the ith parameter")) .def("setParameter", (setParameterType2)&IFunction::setParameter, - setParameterType2_Overloads("Sets the value of the named parameter")) + setParameterType2_Overloads( + (arg("self"), arg("name"), arg("value"), arg("explicitlySet")), + "Sets the value of the named parameter")) .def("declareAttribute", &IFunctionAdapter::declareAttribute, + (arg("self"), arg("name"), arg("default_value")), "Declare an attribute with an initial value") .def("getAttributeValue", (PyObject * (IFunctionAdapter::*)(const std::string &)) & IFunctionAdapter::getAttributeValue, + (arg("self"), arg("name")), "Return the value of the named attribute") .def("declareParameter", &IFunctionAdapter::declareFitParameter, + (arg("self"), arg("name"), arg("init_value"), arg("description")), "Declare a fitting parameter settings its default value & " "description") .def("declareParameter", &IFunctionAdapter::declareFitParameterNoDescr, + (arg("self"), arg("name"), arg("init_value")), "Declare a fitting parameter settings its default value") .def("declareParameter", &IFunctionAdapter::declareFitParameterZeroInit, + (arg("self"), arg("name")), "Declare a fitting parameter settings its default value to 0.0") //-- Deprecated functions that have the wrong names -- - .def("categories", &getCategories, + .def("categories", &getCategories, arg("self"), "Returns a list of the categories for an algorithm") - .def("numParams", &IFunction::nParams, "Return the number of parameters") - .def("getParamName", &IFunction::parameterName, + .def("numParams", &IFunction::nParams, arg("self"), + "Return the number of parameters") + .def("getParamName", &IFunction::parameterName, (arg("self"), arg("i")), "Return the name of the ith parameter") .def("getParamDescr", &IFunction::parameterDescription, - "Return a description of the ith parameter") + (arg("self"), arg("i")), "Return a description of the ith parameter") .def("getParamExplicit", &IFunction::isExplicitlySet, + (arg("self"), arg("i")), "Return whether the ith parameter needs to be explicitely set") .def("getParamValue", (double (IFunction::*)(std::size_t) const) & IFunction::getParameter, - "Get the value of the ith parameter") + (arg("self"), arg("i")), "Get the value of the ith parameter") //-- Python special methods -- - .def("__repr__", &IFunction::asString, + .def("__repr__", &IFunction::asString, arg("self"), "Return a string representation of the function"); } diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IFunction1D.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IFunction1D.cpp index b610b945ffb3ccb664e1fd82870631607349008c..a435fc7b192eadaad8060c02817d251d5bd2cf59 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/IFunction1D.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/IFunction1D.cpp @@ -18,6 +18,7 @@ void export_IFunction1D() { .def("function1D", (object (IFunction1DAdapter::*)(const object &) const) & IFunction1DAdapter::function1D, + (arg("self"), arg("xvals")), "Calculate the values of the function for the given x values and " "returns them"); } diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IMDEventWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IMDEventWorkspace.cpp index bd69cd0dab31b54c2ede7e5b609a0471b05bdde8..4bd404f62e4b60fe2af7038ce00b91a43326241e 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/IMDEventWorkspace.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/IMDEventWorkspace.cpp @@ -12,15 +12,15 @@ void export_IMDEventWorkspace() { // IMDEventWorkspace class class_<IMDEventWorkspace, bases<IMDWorkspace, MultipleExperimentInfos>, boost::noncopyable>("IMDEventWorkspace", no_init) - .def("getNPoints", &IMDEventWorkspace::getNPoints, + .def("getNPoints", &IMDEventWorkspace::getNPoints, arg("self"), "Returns the total number of points (events) in this workspace") - .def("getNumDims", &IMDEventWorkspace::getNumDims, + .def("getNumDims", &IMDEventWorkspace::getNumDims, arg("self"), "Returns the number of dimensions in this workspace") .def("getBoxController", (BoxController_sptr (IMDEventWorkspace::*)()) & IMDEventWorkspace::getBoxController, - "Returns the BoxController used in this workspace"); + arg("self"), "Returns the BoxController used in this workspace"); RegisterWorkspacePtrToPython<IMDEventWorkspace>(); } diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IMDHistoWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IMDHistoWorkspace.cpp index 3852f7080de7fc94c761795836bf827b22994e65..f64840efaf7bd9f7a3266ade3d528054fdb18aa4 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/IMDHistoWorkspace.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/IMDHistoWorkspace.cpp @@ -167,55 +167,65 @@ void export_IMDHistoWorkspace() { // IMDHistoWorkspace class class_<IMDHistoWorkspace, bases<IMDWorkspace, MultipleExperimentInfos>, boost::noncopyable>("IMDHistoWorkspace", no_init) - .def("getSignalArray", &getSignalArrayAsNumpyArray, + .def("getSignalArray", &getSignalArrayAsNumpyArray, arg("self"), "Returns a read-only numpy array containing the signal values") .def("getErrorSquaredArray", &getErrorSquaredArrayAsNumpyArray, + arg("self"), "Returns a read-only numpy array containing the square of the error " "values") - .def("getNumEventsArray", &getNumEventsArrayAsNumpyArray, + .def("getNumEventsArray", &getNumEventsArrayAsNumpyArray, arg("self"), "Returns a read-only numpy array containing the number of MD events " "in each bin") .def("signalAt", &IMDHistoWorkspace::signalAt, + (arg("self"), arg("index")), return_value_policy<copy_non_const_reference>(), "Return a reference to the signal at the linear index") .def("errorSquaredAt", &IMDHistoWorkspace::errorSquaredAt, + (arg("self"), arg("index")), return_value_policy<copy_non_const_reference>(), "Return the squared-errors at the linear index") .def("setSignalAt", &IMDHistoWorkspace::setSignalAt, + (arg("self"), arg("index"), arg("value")), "Sets the signal at the specified index.") .def("setErrorSquaredAt", &IMDHistoWorkspace::setErrorSquaredAt, + (arg("self"), arg("index"), arg("value")), "Sets the squared-error at the specified index.") .def("setSignalArray", &setSignalArray, + (arg("self"), arg("signalValues")), "Sets the signal from a numpy array. The sizes must match the " "current workspace sizes. A ValueError is thrown if not") - .def("setErrorSquaredArray", &setErrorSquaredArray, + .def("setErrorSquaredArray", &setErrorSquaredArray, arg("self"), "Sets the square of the errors from a numpy array. The sizes must " "match the current workspace sizes. A ValueError is thrown if not") .def("setTo", &IMDHistoWorkspace::setTo, + (arg("self"), arg("signal"), arg("error_squared"), + arg("num_events")), "Sets all signals/errors in the workspace to the given values") .def("getInverseVolume", &IMDHistoWorkspace::getInverseVolume, - return_value_policy<return_by_value>(), + arg("self"), return_value_policy<return_by_value>(), "Return the inverse of volume of EACH cell in the workspace.") .def("getLinearIndex", (size_t (IMDHistoWorkspace::*)(size_t, size_t) const) & IMDHistoWorkspace::getLinearIndex, + (arg("self"), arg("index1"), arg("index2")), return_value_policy<return_by_value>(), "Get the 1D linear index from the 2D array") .def("getLinearIndex", (size_t (IMDHistoWorkspace::*)(size_t, size_t, size_t) const) & IMDHistoWorkspace::getLinearIndex, + (arg("self"), arg("index1"), arg("index2"), arg("index3")), return_value_policy<return_by_value>(), "Get the 1D linear index from the 3D array") @@ -223,10 +233,13 @@ void export_IMDHistoWorkspace() { (size_t (IMDHistoWorkspace::*)(size_t, size_t, size_t, size_t) const) & IMDHistoWorkspace::getLinearIndex, + (arg("self"), arg("index1"), arg("index2"), arg("index3"), + arg("index4")), return_value_policy<return_by_value>(), "Get the 1D linear index from the 4D array") .def("getCenter", &IMDHistoWorkspace::getCenter, + (arg("self"), arg("linear_index")), return_value_policy<return_by_value>(), "Return the position of the center of a bin at a given position"); diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IMDWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IMDWorkspace.cpp index 3c8921df6623a7b4dee6c9abeb6324acb7341798..989089801c34318f3e7087c81f2a3221bd553a33 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/IMDWorkspace.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/IMDWorkspace.cpp @@ -25,17 +25,17 @@ void export_IMDWorkspace() { // EventWorkspace class class_<IMDWorkspace, bases<Workspace, MDGeometry>, boost::noncopyable>( "IMDWorkspace", no_init) - .def("getNPoints", &IMDWorkspace::getNPoints, args("self"), + .def("getNPoints", &IMDWorkspace::getNPoints, arg("self"), "Returns the total number of points within the workspace") - .def("getNEvents", &IMDWorkspace::getNEvents, args("self"), + .def("getNEvents", &IMDWorkspace::getNEvents, arg("self"), "Returns the total number of events, contributed to the workspace") .def("getSpecialCoordinateSystem", - &IMDWorkspace::getSpecialCoordinateSystem, args("self"), + &IMDWorkspace::getSpecialCoordinateSystem, arg("self"), "Returns the special coordinate system of the workspace") .def("displayNormalization", &IMDWorkspace::displayNormalization, args("self"), "Returns the visual normalization of the workspace.") .def("displayNormalizationHisto", - &IMDWorkspace::displayNormalizationHisto, args("self"), + &IMDWorkspace::displayNormalizationHisto, arg("self"), "For MDEventWorkspaces returns the visual normalization of dervied " "MDHistoWorkspaces." "For all others returns the same as displayNormalization."); diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IMaskWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IMaskWorkspace.cpp index 66affb607c0e136f9da7bbfb99b7d421020880b1..7090972a851786d4d7cf28c5e48773cfe1146485 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/IMaskWorkspace.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/IMaskWorkspace.cpp @@ -28,12 +28,13 @@ bool isMaskedFromList(const IMaskWorkspace &self, void export_IMaskWorkspace() { class_<IMaskWorkspace, boost::noncopyable>("IMaskWorkspace", no_init) - .def("getNumberMasked", &IMaskWorkspace::getNumberMasked, + .def("getNumberMasked", &IMaskWorkspace::getNumberMasked, arg("self"), "Returns the number of masked pixels in the workspace") .def("isMasked", (bool (IMaskWorkspace::*)(const Mantid::detid_t) const) & IMaskWorkspace::isMasked, + (arg("self"), arg("detector_id")), "Returns whether the given detector ID is masked") - .def("isMasked", isMaskedFromList, + .def("isMasked", isMaskedFromList, (arg("self"), arg("detector_id_list")), "Returns whether all of the given detector ID list are masked"); // register pointers diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp index 13ace3dced290717e05e3ff3888be2e1c5603115..f3e42c14c3f26423d58cb51961c44b632746c78a 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp @@ -36,95 +36,111 @@ void export_IPeak() { register_ptr_to_python<IPeak *>(); class_<IPeak, boost::noncopyable>("IPeak", no_init) - .def("getDetectorID", &IPeak::getDetectorID, + .def("getDetectorID", &IPeak::getDetectorID, arg("self"), "Get the ID of the detector at the center of the peak") - .def("setDetectorID", &IPeak::setDetectorID, + .def("setDetectorID", &IPeak::setDetectorID, (arg("self"), arg("det_id")), "Set the detector ID and look up and cache values related to it.") - .def("getRunNumber", &IPeak::getRunNumber, + .def("getRunNumber", &IPeak::getRunNumber, arg("self"), "Return the run number this peak was measured at") .def("setRunNumber", &IPeak::setRunNumber, + (arg("self"), arg("run_number")), "Set the run number that measured this peak") - .def("getMonitorCount", &IPeak::getMonitorCount, + .def("getMonitorCount", &IPeak::getMonitorCount, arg("self"), "Get the monitor count set for this peak") .def("setMonitorCount", &IPeak::setMonitorCount, + (arg("self"), arg("monitor_count")), "Set the monitor count for this peak") - .def("getH", &IPeak::getH, "Get the H index of the peak") - .def("getK", &IPeak::getK, "Get the K index of the peak") - .def("getL", &IPeak::getL, "Get the L index of the peak") - .def("getHKL", &IPeak::getHKL, "Get HKL as a V3D object") + .def("getH", &IPeak::getH, arg("self"), "Get the H index of the peak") + .def("getK", &IPeak::getK, arg("self"), "Get the K index of the peak") + .def("getL", &IPeak::getL, arg("self"), "Get the L index of the peak") + .def("getHKL", &IPeak::getHKL, arg("self"), "Get HKL as a V3D object") .def("setHKL", (void (IPeak::*)(double, double, double)) & IPeak::setHKL, + (arg("self"), arg("h"), arg("k"), arg("l")), "Set the HKL values of this peak") - .def("setH", &IPeak::setH, "Get the H index of the peak") - .def("setK", &IPeak::setK, "Get the K index of the peak") - .def("setL", &IPeak::setL, "Get the L index of the peak") - .def("getQLabFrame", &IPeak::getQLabFrame, + .def("setH", &IPeak::setH, (arg("self"), arg("h")), + "Get the H index of the peak") + .def("setK", &IPeak::setK, (arg("self"), arg("k")), + "Get the K index of the peak") + .def("setL", &IPeak::setL, (arg("self"), arg("l")), + "Get the L index of the peak") + .def("getQLabFrame", &IPeak::getQLabFrame, arg("self"), "Return the Q change (of the lattice, k_i - k_f) for this peak.\n" "The Q is in the Lab frame: the goniometer rotation was NOT taken " "out.\n" "Note: There is no 2*pi factor used, so \\|Q| = 1/wavelength.") - .def("findDetector", &IPeak::findDetector, + .def("findDetector", &IPeak::findDetector, arg("self"), "Using the instrument set in the peak, perform ray tracing to find " "the exact detector.") - .def("getQSampleFrame", &IPeak::getQSampleFrame, + .def("getQSampleFrame", &IPeak::getQSampleFrame, arg("self"), "Return the Q change (of the lattice, k_i - k_f) for this peak." "The Q is in the Sample frame: the goniometer rotation WAS taken " "out. ") - .def("setQLabFrame", setQLabFrame1, "Set the peak using the peak's " - "position in reciprocal space, in " - "the lab frame.") + .def("setQLabFrame", setQLabFrame1, (arg("self"), arg("qlab_frame")), + "Set the peak using the peak's " + "position in reciprocal space, in " + "the lab frame.") .def("setQLabFrame", setQLabFrame2, + (arg("self"), arg("qlab_frame"), arg("distance")), "Set the peak using the peak's position in reciprocal space, in the " "lab frame. Detector distance explicitly supplied.") // two argument // overload - .def("setQSampleFrame", setQSampleFrame1, "Set the peak using the peak's " + .def("setQSampleFrame", setQSampleFrame1, + (arg("self"), arg("qsample_frame")), "Set the peak using the peak's " "position in reciprocal space, " "in the sample frame.") .def("setQSampleFrame", setQSampleFrame2, + (arg("self"), arg("qsample_frame"), arg("distance")), "Set the peak using the peak's position in reciprocal space, in the " "sample frame. Detector distance explicitly supplied.") .def("setWavelength", &IPeak::setWavelength, + (arg("self"), arg("wave_length")), "Set the incident wavelength of the neutron. Calculates the energy " "from this assuming elastic scattering.") - .def("getWavelength", &IPeak::getWavelength, + .def("getWavelength", &IPeak::getWavelength, arg("self"), "Return the incident wavelength") - .def("getScattering", &IPeak::getScattering, + .def("getScattering", &IPeak::getScattering, arg("self"), "Calculate the scattering angle of the peak") - .def("getDSpacing", &IPeak::getDSpacing, + .def("getDSpacing", &IPeak::getDSpacing, arg("self"), "Calculate the d-spacing of the peak, in 1/Angstroms") - .def("getTOF", &IPeak::getTOF, "Calculate the time of flight (in " - "microseconds) of the neutrons for this " - "peak") - .def("getInitialEnergy", &IPeak::getInitialEnergy, + .def("getTOF", &IPeak::getTOF, arg("self"), + "Calculate the time of flight (in " + "microseconds) of the neutrons for this " + "peak") + .def("getInitialEnergy", &IPeak::getInitialEnergy, arg("self"), "Get the initial (incident) neutron energy") - .def("getFinalEnergy", &IPeak::getFinalEnergy, + .def("getFinalEnergy", &IPeak::getFinalEnergy, arg("self"), "Get the final neutron energy") .def("setInitialEnergy", &IPeak::setInitialEnergy, + (arg("self"), arg("initial_energy")), "Set the initial (incident) neutron energy") .def("setFinalEnergy", &IPeak::setFinalEnergy, - "Set the final neutron energy") - .def("getIntensity", &IPeak::getIntensity, + (arg("self"), arg("final_energy")), "Set the final neutron energy") + .def("getIntensity", &IPeak::getIntensity, arg("self"), "Return the integrated peak intensity") - .def("getSigmaIntensity", &IPeak::getSigmaIntensity, + .def("getSigmaIntensity", &IPeak::getSigmaIntensity, arg("self"), "Return the error on the integrated peak intensity") .def("setIntensity", &IPeak::setIntensity, - "Set the integrated peak intensity") + (arg("self"), arg("intensity")), "Set the integrated peak intensity") .def("setSigmaIntensity", &IPeak::setSigmaIntensity, + (arg("self"), arg("sigma_intensity")), "Set the error on the integrated peak intensity") - .def("getBinCount", &IPeak::getBinCount, + .def("getBinCount", &IPeak::getBinCount, arg("self"), "Return the # of counts in the bin at its peak") - .def("setBinCount", &IPeak::setBinCount, + .def("setBinCount", &IPeak::setBinCount, (arg("self"), arg("bin_count")), "Set the # of counts in the bin at its peak") - .def("getRow", &IPeak::getRow, "For RectangularDetectors only, returns " - "the row (y) of the pixel of the " - "detector.") - .def("getCol", &IPeak::getCol, "For RectangularDetectors only, returns " - "the column (x) of the pixel of the " - "detector.") - .def("getDetPos", &IPeak::getDetPos, + .def("getRow", &IPeak::getRow, arg("self"), + "For RectangularDetectors only, returns " + "the row (y) of the pixel of the " + "detector.") + .def("getCol", &IPeak::getCol, arg("self"), + "For RectangularDetectors only, returns " + "the column (x) of the pixel of the " + "detector.") + .def("getDetPos", &IPeak::getDetPos, arg("self"), "Return the detector position vector") - .def("getL1", &IPeak::getL1, + .def("getL1", &IPeak::getL1, arg("self"), "Return the L1 flight path length (source to sample), in meters. ") - .def("getL2", &IPeak::getL2, + .def("getL2", &IPeak::getL2, arg("self"), "Return the L2 flight path length (sample to detector), in meters.") - .def("getPeakShape", getPeakShape, "Get the peak shape"); + .def("getPeakShape", getPeakShape, arg("self"), "Get the peak shape"); } diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IPeakFunction.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IPeakFunction.cpp index f98e84fb8ec7b29d732c1f0626a252e2a9604872..3ac4f6332732a278c3b3ffaa9371cdb41d21edf9 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/IPeakFunction.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/IPeakFunction.cpp @@ -14,11 +14,13 @@ void export_IPeakFunction() { .def("functionLocal", (object (IPeakFunctionAdapter::*)(const object &) const) & IPeakFunction::functionLocal, + (arg("self"), arg("vec_x")), "Calculate the values of the function for the given x values. The " "output should be stored in the out array") - .def("intensity", &IPeakFunction::intensity, + .def("intensity", &IPeakFunction::intensity, arg("self"), "Returns the integral intensity of the peak function.") .def("setIntensity", &IPeakFunction::setIntensity, + (arg("self"), arg("new_intensity")), "Changes the integral intensity of the peak function by setting its " "height."); } diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IPeaksWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IPeaksWorkspace.cpp index cedd6732c37158cc1c9d6e074d721bd5203735f8..392d246c8fc1f0b33b63ddbeb98e747aabadd1de 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/IPeaksWorkspace.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/IPeaksWorkspace.cpp @@ -40,29 +40,33 @@ void export_IPeaksWorkspace() { // IPeaksWorkspace class class_<IPeaksWorkspace, bases<ITableWorkspace, ExperimentInfo>, boost::noncopyable>("IPeaksWorkspace", no_init) - .def("getNumberPeaks", &IPeaksWorkspace::getNumberPeaks, + .def("getNumberPeaks", &IPeaksWorkspace::getNumberPeaks, arg("self"), "Returns the number of peaks within the workspace") - .def("addPeak", &IPeaksWorkspace::addPeak, "Add a peak to the workspace") + .def("addPeak", &IPeaksWorkspace::addPeak, (arg("self"), arg("peak")), + "Add a peak to the workspace") .def("removePeak", &IPeaksWorkspace::removePeak, - "Remove a peak from the workspace") + (arg("self"), arg("peak_num")), "Remove a peak from the workspace") .def("getPeak", &IPeaksWorkspace::getPeakPtr, - return_internal_reference<>(), "Returns a peak at the given index") - .def("createPeak", createPeakQLab, + (arg("self"), arg("peak_num")), return_internal_reference<>(), + "Returns a peak at the given index") + .def("createPeak", createPeakQLab, (arg("self"), arg("data")), return_value_policy<manage_new_object>(), "Create a Peak and return it from its coordinates in the QLab frame") .def("createPeak", createPeakQLabWithDistance, + (arg("self"), arg("data"), arg("detector_distance")), return_value_policy<manage_new_object>(), "Create a Peak and return it from its coordinates in the QLab " "frame, detector-sample distance explicitly provided") - .def("createPeakHKL", createPeakHKL, + .def("createPeakHKL", createPeakHKL, (arg("self"), arg("data")), return_value_policy<manage_new_object>(), "Create a Peak and return it from its coordinates in the HKL frame") .def("hasIntegratedPeaks", &IPeaksWorkspace::hasIntegratedPeaks, - "Determine if the peaks have been integrated") - .def("getRun", &IPeaksWorkspace::mutableRun, + arg("self"), "Determine if the peaks have been integrated") + .def("getRun", &IPeaksWorkspace::mutableRun, arg("self"), return_internal_reference<>(), "Return the Run object for this workspace") .def("peakInfoNumber", &IPeaksWorkspace::peakInfoNumber, + (arg("self"), arg("qlab_frame"), arg("lab_coordinate")), "Peak info number at Q vector for this workspace"); //------------------------------------------------------------------------------------------------- diff --git a/Framework/PythonInterface/mantid/api/src/Exports/ISpectrum.cpp b/Framework/PythonInterface/mantid/api/src/Exports/ISpectrum.cpp index 1e27e7f78036b3a1a341ac103b9f1a0c747bec1f..3afbf36902caa3b24d84fadceb531e4cddd67ca3 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/ISpectrum.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/ISpectrum.cpp @@ -12,21 +12,24 @@ void export_ISpectrum() { class_<ISpectrum, boost::noncopyable>("ISpectrum", no_init) .def("hasDetectorID", &ISpectrum::hasDetectorID, + (arg("self"), arg("det_id")), "Returns True if the spectrum contain the given spectrum number") - .def("getSpectrumNo", &ISpectrum::getSpectrumNo, + .def("getSpectrumNo", &ISpectrum::getSpectrumNo, arg("self"), "Returns the spectrum number of this spectrum") .def("getDetectorIDs", (const std::set<detid_t> &(ISpectrum::*)() const) & ISpectrum::getDetectorIDs, - return_value_policy<copy_const_reference>(), + arg("self"), return_value_policy<copy_const_reference>(), "Returns a list of detector IDs for this spectrum") .def("addDetectorID", &ISpectrum::addDetectorID, - "Add a detector ID to this spectrum") + (arg("self"), arg("det_id")), "Add a detector ID to this spectrum") .def("setDetectorID", &ISpectrum::setDetectorID, - "Set the given ID has the only") - .def("clearDetectorIDs", &ISpectrum::clearDetectorIDs, + (arg("self"), arg("det_id")), "Set the given ID has the only") + .def("clearDetectorIDs", &ISpectrum::clearDetectorIDs, arg("self"), "Clear the set of detector IDs") .def("setSpectrumNo", &ISpectrum::setSpectrumNo, + (arg("self"), arg("num")), "Set the spectrum number for this spectrum") - .def("hasDx", &ISpectrum::hasDx, "Returns True if the spectrum uses the " - "DX (X Error) array, else False."); + .def("hasDx", &ISpectrum::hasDx, arg("self"), + "Returns True if the spectrum uses the " + "DX (X Error) array, else False."); } diff --git a/Framework/PythonInterface/mantid/api/src/Exports/ISplittersWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/Exports/ISplittersWorkspace.cpp index 55585283456e84176d06a1bc53b33b0f37a287a1..2ace16a65bb1aac998660d10ba45565d1a2e88c1 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/ISplittersWorkspace.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/ISplittersWorkspace.cpp @@ -11,7 +11,7 @@ void export_ISplittersWorkspace() { class_<ISplittersWorkspace, boost::noncopyable>("ISplittersWorkspace", no_init) .def("getNumberSplitters", &ISplittersWorkspace::getNumberSplitters, - "Returns the number of splitters within the workspace"); + arg("self"), "Returns the number of splitters within the workspace"); // register pointers RegisterWorkspacePtrToPython<ISplittersWorkspace>(); diff --git a/Framework/PythonInterface/mantid/api/src/Exports/ITableWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/Exports/ITableWorkspace.cpp index 8280d0fb2512acd690f46edcfa72fcfb2ede005a..853166f3094888aba80258dd77e561a5fbfe564b 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/ITableWorkspace.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/ITableWorkspace.cpp @@ -338,51 +338,55 @@ void export_ITableWorkspace() { class_<ITableWorkspace, bases<Workspace>, boost::noncopyable>( "ITableWorkspace", iTableWorkspace_docstring.c_str(), no_init) - .def("addColumn", &addColumn, (arg("type"), arg("name")), + .def("addColumn", &addColumn, (arg("self"), arg("type"), arg("name")), "Add a named column with the given type. Recognized types are: " "int,float,double,bool,str,V3D,long64") - .def("removeColumn", &ITableWorkspace::removeColumn, (arg("name")), - "Remove the named column") + .def("removeColumn", &ITableWorkspace::removeColumn, + (arg("self"), arg("name")), "Remove the named column") - .def("columnCount", &ITableWorkspace::columnCount, + .def("columnCount", &ITableWorkspace::columnCount, arg("self"), "Returns the number of columns in the workspace") - .def("rowCount", &ITableWorkspace::rowCount, + .def("rowCount", &ITableWorkspace::rowCount, arg("self"), "Returns the number of rows within the workspace") - .def("setRowCount", &ITableWorkspace::setRowCount, (arg("count")), + .def("setRowCount", &ITableWorkspace::setRowCount, + (arg("self"), arg("count")), "Resize the table to contain count rows") - .def("__len__", &ITableWorkspace::rowCount, + .def("__len__", &ITableWorkspace::rowCount, arg("self"), "Returns the number of rows within the workspace") - .def("getColumnNames", &ITableWorkspace::getColumnNames, + .def("getColumnNames", &ITableWorkspace::getColumnNames, arg("self"), boost::python::return_value_policy<VectorToNumpy>(), "Return a list of the column names") - .def("keys", &ITableWorkspace::getColumnNames, + .def("keys", &ITableWorkspace::getColumnNames, arg("self"), boost::python::return_value_policy<VectorToNumpy>(), "Return a list of the column names") - .def("column", &column, + .def("column", &column, (arg("self"), arg("column")), "Return all values of a specific column as a list") - .def("row", &row, "Return all values of a specific row as a dict") + .def("row", &row, (arg("self"), arg("row")), + "Return all values of a specific row as a dict") - .def("addRow", &addRowFromDict, + .def("addRow", &addRowFromDict, (arg("self"), arg("row_items_dict")), "Appends a row with the values from the dictionary") - .def("addRow", &addRowFromList, + .def("addRow", &addRowFromList, (arg("self"), arg("row_items_list")), "Appends a row with the values from the given list. " "It it assumed that the items are in the correct order for the " "defined columns") - .def("cell", &cell, "Return the given cell. If the first argument is a " - "number then it is interpreted as a row otherwise it " - "is interpreted as a column name") + .def("cell", &cell, (arg("self"), arg("value"), arg("row_or_column")), + "Return the given cell. If the first argument is a " + "number then it is interpreted as a row otherwise it " + "is interpreted as a column name") - .def("setCell", &setCell, + .def("setCell", &setCell, (arg("self"), arg("row_or_column"), + arg("column_or_row"), arg("value")), "Sets the value of a given cell. If the first argument is a " "number then it is interpreted as a row otherwise it is interpreted " "as a column name"); diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IWorkspaceProperty.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IWorkspaceProperty.cpp index 525d92c8448be014be0f277607eff7b2593beeb8..8e50a5b573226ff8e8a6707bca688bf8555f6c7b 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/IWorkspaceProperty.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/IWorkspaceProperty.cpp @@ -6,8 +6,8 @@ void export_IWorkspaceProperty() { using Mantid::API::IWorkspaceProperty; class_<IWorkspaceProperty, boost::noncopyable>("IWorkspaceProperty", no_init) - .def("isOptional", &IWorkspaceProperty::isOptional, + .def("isOptional", &IWorkspaceProperty::isOptional, arg("self"), "Is the input workspace property optional") - .def("isLocking", &IWorkspaceProperty::isLocking, + .def("isLocking", &IWorkspaceProperty::isLocking, arg("self"), "Will the workspace be locked when starting an algorithm"); } diff --git a/Framework/PythonInterface/mantid/api/src/Exports/InstrumentValidator.cpp b/Framework/PythonInterface/mantid/api/src/Exports/InstrumentValidator.cpp index b4985d71e60f31150577b8ed4fbd20f6b908bd90..651b725701c3c8d379f2f6e3276748a25c22b60c 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/InstrumentValidator.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/InstrumentValidator.cpp @@ -1,4 +1,4 @@ -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/InstrumentValidator.h" #include "MantidPythonInterface/kernel/TypedValidatorExporter.h" #include <boost/python/class.hpp> diff --git a/Framework/PythonInterface/mantid/api/src/Exports/Jacobian.cpp b/Framework/PythonInterface/mantid/api/src/Exports/Jacobian.cpp index 732cae6fca5c6feaec3b64c6d969d5ffbaa4067f..e9d0eb07cfbfb1e91c8151f51e009ff885a90daf 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/Jacobian.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/Jacobian.cpp @@ -9,11 +9,12 @@ void export_Jacobian() { register_ptr_to_python<Jacobian *>(); class_<Jacobian, boost::noncopyable>("Jacobian", no_init) - .def("set", &Jacobian::set, (arg("iy"), arg("ip"), arg("value")), + .def("set", &Jacobian::set, + (arg("self"), arg("iy"), arg("ip"), arg("value")), "Set an element of the Jacobian matrix where iy=index of data " "point, ip=index of parameter.") - .def("get", &Jacobian::get, (arg("iy"), arg("ip")), + .def("get", &Jacobian::get, (arg("self"), arg("iy"), arg("ip")), "Return the given element of the Jacobian matrix where iy=index of " "data point, ip=index of parameter."); } diff --git a/Framework/PythonInterface/mantid/api/src/Exports/MDGeometry.cpp b/Framework/PythonInterface/mantid/api/src/Exports/MDGeometry.cpp index 2c62473353409541efc3e8d1a815ac758c4ad425..c739bc51666f77b172acb054c3266249488ec7d7 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/MDGeometry.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/MDGeometry.cpp @@ -35,88 +35,94 @@ boost::python::list getNonIntegratedDimensionsAsPyList(const MDGeometry &self) { void export_MDGeometry() { class_<MDGeometry, boost::noncopyable>("MDGeometry", no_init) - .def("getNumDims", &MDGeometry::getNumDims, + .def("getNumDims", &MDGeometry::getNumDims, arg("self"), "Returns the number of dimensions present") - .def("getDimension", &MDGeometry::getDimension, (args("index")), + .def("getDimension", &MDGeometry::getDimension, + (arg("self"), arg("index")), return_value_policy<RemoveConstSharedPtr>(), "Returns the description of the dimension at the given index " "(starts from 0). Raises RuntimeError if index is out of range.") - .def("getDimensionWithId", &MDGeometry::getDimensionWithId, (args("id")), + .def("getDimensionWithId", &MDGeometry::getDimensionWithId, + (arg("self"), arg("id")), return_value_policy<RemoveConstSharedPtr>(), "Returns the description of the dimension with the given id string. " "Raises ValueError if the string is not a known id.") .def("getDimensionIndexByName", &MDGeometry::getDimensionIndexByName, - (args("name")), "Returns the index of the dimension with the given " - "name. Raises RuntimeError if the name does not " - "exist.") + (arg("self"), arg("name")), + "Returns the index of the dimension with the given " + "name. Raises RuntimeError if the name does not " + "exist.") .def("getDimensionIndexById", &MDGeometry::getDimensionIndexById, - (args("id")), "Returns the index of the dimension with the given " - "ID. Raises RuntimeError if the name does not exist.") + (arg("self"), arg("id")), + "Returns the index of the dimension with the given " + "ID. Raises RuntimeError if the name does not exist.") .def("getNonIntegratedDimensions", &getNonIntegratedDimensionsAsPyList, + arg("self"), "Returns the description objects of the non-integrated dimension as " "a python list of IMDDimension.") - .def("estimateResolution", &MDGeometry::estimateResolution, + .def("estimateResolution", &MDGeometry::estimateResolution, arg("self"), return_value_policy<VectorToNumpy>(), "Returns a numpy array containing the width of the smallest bin in " "each dimension") - .def("getXDimension", &MDGeometry::getXDimension, + .def("getXDimension", &MDGeometry::getXDimension, arg("self"), return_value_policy<RemoveConstSharedPtr>(), "Returns the dimension description mapped to X") - .def("getYDimension", &MDGeometry::getYDimension, + .def("getYDimension", &MDGeometry::getYDimension, arg("self"), return_value_policy<RemoveConstSharedPtr>(), "Returns the dimension description mapped to Y") - .def("getZDimension", &MDGeometry::getZDimension, + .def("getZDimension", &MDGeometry::getZDimension, arg("self"), return_value_policy<RemoveConstSharedPtr>(), "Returns the dimension description mapped to Z") - .def("getTDimension", &MDGeometry::getTDimension, + .def("getTDimension", &MDGeometry::getTDimension, arg("self"), return_value_policy<RemoveConstSharedPtr>(), "Returns the dimension description mapped to time") - .def("getGeometryXML", &MDGeometry::getGeometryXML, + .def("getGeometryXML", &MDGeometry::getGeometryXML, arg("self"), "Returns an XML representation, as a string, of the geometry of the " "workspace") .def("getBasisVector", (const Mantid::Kernel::VMD &(MDGeometry::*)(size_t) const) & MDGeometry::getBasisVector, - (args("index")), return_value_policy<copy_const_reference>(), + (arg("self"), arg("index")), + return_value_policy<copy_const_reference>(), "Returns a VMD object defining the basis vector for the specified " "dimension") .def("hasOriginalWorkspace", &MDGeometry::hasOriginalWorkspace, - (args("index")), + (arg("self"), arg("index")), "Returns True if there is a source workspace at the given index") .def("numOriginalWorkspaces", &MDGeometry::numOriginalWorkspaces, - "Returns the number of source workspaces attached") + arg("self"), "Returns the number of source workspaces attached") .def("getOriginalWorkspace", &MDGeometry::getOriginalWorkspace, - (args("index")), + (arg("self"), arg("index")), "Returns the source workspace attached at the given index") .def("getOrigin", (const Mantid::Kernel::VMD &(MDGeometry::*)() const) & MDGeometry::getOrigin, - return_value_policy<copy_const_reference>(), + arg("self"), return_value_policy<copy_const_reference>(), "Returns the vector of the origin (in the original workspace) that " "corresponds to 0,0,0... in this workspace") .def("getNumberTransformsFromOriginal", - &MDGeometry::getNumberTransformsFromOriginal, + &MDGeometry::getNumberTransformsFromOriginal, arg("self"), "Returns the number of transformations from original workspace " "coordinate systems") .def("getNumberTransformsToOriginal", - &MDGeometry::getNumberTransformsToOriginal, + &MDGeometry::getNumberTransformsToOriginal, arg("self"), "Returns the number of transformations to original workspace " "coordinate systems") diff --git a/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp index 0047015ad1c0e5fb397956107fe4ec08d21411c4..fbb754ab25819191b32321b6a3133e9441408f20 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp @@ -34,10 +34,17 @@ typedef return_value_policy<VectorRefToNumpy<WrapReadWrite>> return_readwrite_numpy; //------------------------------- Overload macros --------------------------- +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wunused-local-typedef" +#endif // Overloads for binIndexOf function which has 1 optional argument BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(MatrixWorkspace_binIndexOfOverloads, MatrixWorkspace::binIndexOf, 1, 2) - +#ifdef __clang__ +#pragma clang diagnostic pop +#endif /** * Set the values from an python array-style object into the given spectrum in * the workspace @@ -150,10 +157,10 @@ void export_MatrixWorkspace() { boost::noncopyable>("MatrixWorkspace", no_init) //--------------------------------------- Meta information //----------------------------------------------------------------------- - .def("blocksize", &MatrixWorkspace::blocksize, args("self"), + .def("blocksize", &MatrixWorkspace::blocksize, arg("self"), "Returns size of the Y data array") .def("getNumberHistograms", &MatrixWorkspace::getNumberHistograms, - args("self"), "Returns the number of spectra in the workspace") + arg("self"), "Returns the number of spectra in the workspace") .def("binIndexOf", &MatrixWorkspace::binIndexOf, MatrixWorkspace_binIndexOfOverloads( (arg("self"), arg("xvalue"), arg("workspaceIndex")), @@ -161,73 +168,79 @@ void export_MatrixWorkspace() { "workspace_index is optional [default=0]")) .def("detectorTwoTheta", (getDetectorSignature)&MatrixWorkspace::detectorTwoTheta, - args("self", "det"), + (arg("self"), arg("det")), "Returns the two theta value for a given detector") .def("detectorSignedTwoTheta", (getDetectorSignature)&MatrixWorkspace::detectorSignedTwoTheta, - args("self", "det"), + (arg("self"), arg("det")), "Returns the signed two theta value for given detector") .def("getSpectrum", (ISpectrum * (MatrixWorkspace::*)(const size_t)) & MatrixWorkspace::getSpectrum, - return_internal_reference<>(), args("self", "workspaceIndex"), + (arg("self"), arg("workspaceIndex")), return_internal_reference<>(), "Return the spectra at the given workspace index.") .def("getIndexFromSpectrumNumber", - &MatrixWorkspace::getIndexFromSpectrumNumber, args("self"), + &MatrixWorkspace::getIndexFromSpectrumNumber, + (arg("self"), arg("spec_no")), "Returns workspace index correspondent to the given spectrum " "number. Throws if no such spectrum is present in the workspace") .def("getDetector", &MatrixWorkspace::getDetector, return_value_policy<RemoveConstSharedPtr>(), - args("self", "workspaceIndex"), "Return the Detector or " - "DetectorGroup that is linked to " - "the given workspace index") - .def("getRun", &MatrixWorkspace::mutableRun, - return_internal_reference<>(), args("self"), + (arg("self"), arg("workspaceIndex")), + "Return the Detector or " + "DetectorGroup that is linked to " + "the given workspace index") + .def("getRun", &MatrixWorkspace::mutableRun, arg("self"), + return_internal_reference<>(), "Return the Run object for this workspace") - .def("axes", &MatrixWorkspace::axes, args("self"), + .def("axes", &MatrixWorkspace::axes, arg("self"), "Returns the number of axes attached to the workspace") - .def("getAxis", &MatrixWorkspace::getAxis, return_internal_reference<>(), - args("self", "axis_index")) - .def("isHistogramData", &MatrixWorkspace::isHistogramData, args("self"), + .def("getAxis", &MatrixWorkspace::getAxis, + (arg("self"), arg("axis_index")), return_internal_reference<>(), + "Get a pointer to a workspace axis") + .def("isHistogramData", &MatrixWorkspace::isHistogramData, arg("self"), "Returns True if this is considered to be binned data.") .def("isDistribution", (const bool &(MatrixWorkspace::*)() const) & MatrixWorkspace::isDistribution, - return_value_policy<copy_const_reference>(), args("self"), + arg("self"), return_value_policy<copy_const_reference>(), "Returns the status of the distribution flag") - .def("YUnit", &MatrixWorkspace::YUnit, args("self"), + .def("YUnit", &MatrixWorkspace::YUnit, arg("self"), "Returns the current Y unit for the data (Y axis) in the workspace") - .def("YUnitLabel", &MatrixWorkspace::YUnitLabel, args("self"), + .def("YUnitLabel", &MatrixWorkspace::YUnitLabel, arg("self"), "Returns the caption for the Y axis") // Deprecated - .def("getNumberBins", &getNumberBinsDeprecated, args("self"), + .def("getNumberBins", &getNumberBinsDeprecated, arg("self"), "Returns size of the Y data array (deprecated, use blocksize " "instead)") - .def("getSampleDetails", &getSampleDetailsDeprecated, - return_internal_reference<>(), args("self"), + .def("getSampleDetails", &getSampleDetailsDeprecated, arg("self"), + return_internal_reference<>(), "Return the Run object for this workspace (deprecated, use getRun " "instead)") //--------------------------------------- Setters //------------------------------------ .def("setYUnitLabel", &MatrixWorkspace::setYUnitLabel, - args("self", "newLabel"), + (arg("self"), arg("newLabel")), "Sets a new caption for the data (Y axis) in the workspace") - .def("setYUnit", &MatrixWorkspace::setYUnit, args("self", "newUnit"), + .def("setYUnit", &MatrixWorkspace::setYUnit, + (arg("self"), arg("newUnit")), "Sets a new unit for the data (Y axis) in the workspace") .def("setDistribution", (bool &(MatrixWorkspace::*)(const bool)) & MatrixWorkspace::isDistribution, - return_value_policy<return_by_value>(), args("self", "newVal"), + (arg("self"), arg("newVal")), return_value_policy<return_by_value>(), "Set distribution flag. If True the workspace has been divided by " "the bin-width.") .def("replaceAxis", &MatrixWorkspace::replaceAxis, - args("self", "axisIndex", "newAxis")) + (arg("self"), arg("axisIndex"), arg("newAxis")), + "Replaces one of the workspace's axes with the new one provided.") //--------------------------------------- Read spectrum data //------------------------- - .def("readX", &MatrixWorkspace::readX, return_readonly_numpy(), - args("self", "workspaceIndex"), "Creates a read-only numpy wrapper " - "around the original X data at the " - "given index") + .def("readX", &MatrixWorkspace::readX, + (arg("self"), arg("workspaceIndex")), return_readonly_numpy(), + "Creates a read-only numpy wrapper " + "around the original X data at the " + "given index") .def("readY", &MatrixWorkspace::readY, return_readonly_numpy(), args("self", "workspaceIndex"), "Creates a read-only numpy wrapper " "around the original Y data at the " diff --git a/Framework/PythonInterface/mantid/api/src/Exports/MultipleExperimentInfos.cpp b/Framework/PythonInterface/mantid/api/src/Exports/MultipleExperimentInfos.cpp index e1ee933671887581dcfb37ed06065f2045ba4643..1635dd5d4cc22a15a23e6c5c364668734bbd86f4 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/MultipleExperimentInfos.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/MultipleExperimentInfos.cpp @@ -12,8 +12,9 @@ void export_MultipleExperimentInfos() { .def("getExperimentInfo", (ExperimentInfo_sptr (MultipleExperimentInfos::*)(const uint16_t)) & MultipleExperimentInfos::getExperimentInfo, + (arg("self"), arg("run_index")), "Return the experiment info at the given index.") .def("getNumExperimentInfo", - &MultipleExperimentInfos::getNumExperimentInfo, + &MultipleExperimentInfos::getNumExperimentInfo, arg("self"), "Return the number of experiment info objects,"); } diff --git a/Framework/PythonInterface/mantid/api/src/Exports/Projection.cpp b/Framework/PythonInterface/mantid/api/src/Exports/Projection.cpp index 080bed5db9c13e75709f93e262432f96f35f05b7..0973bf8190b35b423e6065bea29cadcf4c3531e4 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/Projection.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/Projection.cpp @@ -114,21 +114,23 @@ void export_Projection() { "of u and v.") .def("__init__", make_constructor(&projCtor3), "Constructs a 3 dimensional projection") - .def("getOffset", &Projection::getOffset, + .def("getOffset", &Projection::getOffset, (arg("self"), arg("nd")), "Returns the offset for the given dimension", args("dimension")) - .def("getAxis", &Projection::getAxis, + .def("getAxis", &Projection::getAxis, (arg("self"), arg("nd")), "Returns the axis for the given dimension", args("dimension")) - .def("getType", &getUnit, "Returns the unit for the given dimension", - args("dimension")) + .def("getType", &getUnit, (arg("self"), arg("dimension")), + "Returns the unit for the given dimension") .def("setOffset", &Projection::setOffset, + (arg("self"), arg("nd"), arg("offset")), "Sets the offset for the given dimension", args("dimension", "offset")) .def("setAxis", &Projection::setAxis, - "Sets the axis for the given dimension", args("dimension", "axis")) - .def("setAxis", &projSetAxis, "Sets the axis for the given dimension", - args("dimension", "axis")) - .def("setType", &setUnit, "Sets the unit for the given dimension", - args("dimension", "unit")) + (arg("self"), arg("dimension"), arg("axis")), + "Sets the axis for the given dimension") + .def("setAxis", &projSetAxis, (arg("self"), arg("nd"), arg("data")), + "Sets the axis for the given dimension") + .def("setType", &setUnit, (arg("self"), arg("dimension"), arg("unit")), + "Sets the unit for the given dimension") .add_property( "u", make_function(&Projection::U, return_internal_reference<>(), boost::mpl::vector2<V3D &, Projection &>()), diff --git a/Framework/PythonInterface/mantid/api/src/Exports/Run.cpp b/Framework/PythonInterface/mantid/api/src/Exports/Run.cpp index 8f8548bbcc57f1bd0fc0ca70815263ec4b454a43..bc950c6e2ff6754c95539fd6a278f394a995040d 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/Run.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/Run.cpp @@ -116,67 +116,77 @@ void export_Run() { // Run class class_<Run, boost::noncopyable>("Run", no_init) - .def("getProtonCharge", &Run::getProtonCharge, + .def("getProtonCharge", &Run::getProtonCharge, arg("self"), "Return the total good proton charge for the run") - .def("integrateProtonCharge", &Run::integrateProtonCharge, + .def("integrateProtonCharge", &Run::integrateProtonCharge, arg("self"), "Return the total good proton charge for the run") - .def("hasProperty", &Run::hasProperty, + .def("hasProperty", &Run::hasProperty, (arg("self"), arg("name")), "Returns True if the given log value is contained within the run") - .def("getProperty", &Run::getProperty, + .def("getProperty", &Run::getProperty, (arg("self"), arg("name")), return_value_policy<return_by_value>(), "Returns the named property " "(log value). Use '.value' " "to return the value.") - .def("getProperties", &Run::getProperties, return_internal_reference<>(), + .def("getProperties", &Run::getProperties, arg("self"), + return_internal_reference<>(), "Return the list of run properties managed by this object.") .def("getLogData", (Property * (Run::*)(const std::string &) const) & Run::getLogData, - return_value_policy<return_by_value>(), + (arg("self"), arg("name")), return_value_policy<return_by_value>(), "Returns the named log. Use '.value' to return the value. The same " "as getProperty.") .def("getLogData", (const std::vector<Property *> &(Run::*)() const) & Run::getLogData, - return_internal_reference<>(), + arg("self"), return_internal_reference<>(), "Return the list of logs for this run. The same as getProperties.") .def("getGoniometer", (const Mantid::Geometry::Goniometer &(Run::*)() const) & Run::getGoniometer, - return_value_policy<reference_existing_object>(), + arg("self"), return_value_policy<reference_existing_object>(), "Get the oriented lattice for this sample") - .def("addProperty", &addProperty, "Adds a property with the given name " - "and value. If replace=True then an " - "existing property is overwritten") + .def("addProperty", &addProperty, + (arg("self"), arg("name"), arg("value"), arg("replace")), + "Adds a property with the given name " + "and value. If replace=True then an " + "existing property is overwritten") .def("addProperty", &addPropertyWithUnit, + (arg("self"), arg("name"), arg("value"), arg("units"), + arg("replace")), "Adds a property with the given name, value and unit. If " "replace=True then an existing property is overwritten") .def("setStartAndEndTime", &Run::setStartAndEndTime, + (arg("self"), arg("start"), arg("end")), "Set the start and end time of the run") - .def("startTime", &Run::startTime, + .def("startTime", &Run::startTime, arg("self"), "Return the total starting time of the run.") - .def("endTime", &Run::endTime, "Return the total ending time of the run.") + .def("endTime", &Run::endTime, arg("self"), + "Return the total ending time of the run.") //--------------------------- Dictionary // access---------------------------- - .def("get", &getWithDefault, "Returns the value pointed to by the key or " - "None if it does not exist") - .def("get", &get, + .def("get", &getWithDefault, (arg("self"), arg("key"), arg("default")), + "Returns the value pointed to by the key or " + "None if it does not exist") + .def("get", &get, (arg("self"), arg("key")), "Returns the value pointed to by the key or the default value given") - .def("keys", &keys, "Returns the names of the properties as list") - .def("__contains__", &Run::hasProperty) - .def("__getitem__", &Run::getProperty, + .def("keys", &keys, arg("self"), + "Returns the names of the properties as list") + .def("__contains__", &Run::hasProperty, (arg("self"), arg("name"))) + .def("__getitem__", &Run::getProperty, (arg("self"), arg("name")), return_value_policy<return_by_value>()) - .def("__setitem__", &addOrReplaceProperty) + .def("__setitem__", &addOrReplaceProperty, + (arg("self"), arg("name"), arg("value"))) ; } diff --git a/Framework/PythonInterface/mantid/api/src/Exports/Sample.cpp b/Framework/PythonInterface/mantid/api/src/Exports/Sample.cpp index cbf45afe13a4c246126189710d15d03a218f85e2..baa9826478dbad9a4c9ee7b2065d468a7cfedf01 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/Sample.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/Sample.cpp @@ -16,35 +16,41 @@ void export_Sample() { class_<Sample, boost::noncopyable>("Sample", no_init) .def("getName", &Sample::getName, - return_value_policy<copy_const_reference>(), + return_value_policy<copy_const_reference>(), arg("self"), "Returns the string name of the sample") .def("getOrientedLattice", (const OrientedLattice &(Sample::*)() const) & Sample::getOrientedLattice, - return_value_policy<reference_existing_object>(), + arg("self"), return_value_policy<reference_existing_object>(), "Get the oriented lattice for this sample") - .def("hasOrientedLattice", &Sample::hasOrientedLattice, + .def("hasOrientedLattice", &Sample::hasOrientedLattice, arg("self"), "Returns True if this sample has an oriented lattice, false " "otherwise") - .def("size", &Sample::size, + .def("size", &Sample::size, arg("self"), "Return the number of samples contained within this sample") // Required for ISIS SANS reduction until the full sample geometry is // defined on loading - .def("getGeometryFlag", &Sample::getGeometryFlag, + .def("getGeometryFlag", &Sample::getGeometryFlag, arg("self"), "Return the geometry flag.") - .def("getThickness", &Sample::getThickness, "Return the thickness in mm") - .def("getHeight", &Sample::getHeight, "Return the height in mm") - .def("getWidth", &Sample::getWidth, "Return the width in mm") + .def("getThickness", &Sample::getThickness, arg("self"), + "Return the thickness in mm") + .def("getHeight", &Sample::getHeight, arg("self"), + "Return the height in mm") + .def("getWidth", &Sample::getWidth, arg("self"), "Return the width in mm") .def("getMaterial", (const Material &(Sample::*)() const)(&Sample::getMaterial), - return_value_policy<reference_existing_object>(), + arg("self"), return_value_policy<reference_existing_object>(), "The material the sample is composed of") .def("setGeometryFlag", &Sample::setGeometryFlag, - "Set the geometry flag.") - .def("setThickness", &Sample::setThickness, "Set the thickness in mm.") - .def("setHeight", &Sample::setHeight, "Set the height in mm.") - .def("setWidth", &Sample::setWidth, "Set the width in mm.") + (arg("self"), arg("geom_id")), "Set the geometry flag.") + .def("setThickness", &Sample::setThickness, (arg("self"), arg("thick")), + "Set the thickness in mm.") + .def("setHeight", &Sample::setHeight, (arg("self"), arg("height")), + "Set the height in mm.") + .def("setWidth", &Sample::setWidth, (arg("self"), arg("width")), + "Set the width in mm.") // -------------------------Operators // ------------------------------------- - .def("__len__", &Sample::size) + .def("__len__", &Sample::size, arg("self"), + "Gets the number of samples in this collection") .def("__getitem__", &Sample::operator[], return_internal_reference<>()); } diff --git a/Framework/PythonInterface/mantid/api/src/Exports/ScriptRepository.cpp b/Framework/PythonInterface/mantid/api/src/Exports/ScriptRepository.cpp index 91979d2a4981d49db39845bc3dc316c1bd95b463..2422b6c7a81b3dace66d938011db87ac2ac29173 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/ScriptRepository.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/ScriptRepository.cpp @@ -196,11 +196,15 @@ Arguments:\n\ ///@todo better description class_<ScriptRepository, boost::noncopyable>("ScriptRepository", repo_desc, no_init) - .def("install", &ScriptRepository::install, install_desc) - .def("listFiles", &getListFiles, list_files_desc) - .def("fileInfo", &getInfo, file_info_desc) - .def("description", &getDescription, file_description_desc) - .def("fileStatus", &getStatus, file_status_desc) - .def("download", &ScriptRepository::download, download_desc) - .def("update", &ScriptRepository::check4Update, update_desc); + .def("install", &ScriptRepository::install, + (arg("self"), arg("local_path")), install_desc) + .def("listFiles", &getListFiles, arg("self"), list_files_desc) + .def("fileInfo", &getInfo, (arg("self"), arg("path")), file_info_desc) + .def("description", &getDescription, (arg("self"), arg("path")), + file_description_desc) + .def("fileStatus", &getStatus, (arg("self"), arg("path")), + file_status_desc) + .def("download", &ScriptRepository::download, + (arg("self"), arg("file_path")), download_desc) + .def("update", &ScriptRepository::check4Update, arg("self"), update_desc); } diff --git a/Framework/PythonInterface/mantid/api/src/Exports/ScriptRepositoryFactory.cpp b/Framework/PythonInterface/mantid/api/src/Exports/ScriptRepositoryFactory.cpp index 0f572e8bf639040dd0f7d8e74c9347f270ee083d..91eef3e80418280995943a92161a2537dded62a9 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/ScriptRepositoryFactory.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/ScriptRepositoryFactory.cpp @@ -19,6 +19,7 @@ void export_ScriptRepositoryFactory() { class_<ScriptRepositoryFactoryImpl, boost::noncopyable>( "ScriptRepositoryFactory", no_init) .def("create", &ScriptRepositoryFactoryImpl::create, + (arg("self"), arg("class_name")), "Return a pointer to the ScriptRepository object") .def("Instance", &ScriptRepositoryFactory::Instance, return_value_policy<reference_existing_object>(), diff --git a/Framework/PythonInterface/mantid/api/src/Exports/Workspace.cpp b/Framework/PythonInterface/mantid/api/src/Exports/Workspace.cpp index 04e52cc2d1278d5a60d6fb28ab6712f6b9f52424..a399b9ca775cb9cdad79cff7a4b904cef7f48692 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/Workspace.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/Workspace.cpp @@ -14,32 +14,43 @@ using namespace boost::python; namespace { ///@cond +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wunused-local-typedef" +#endif BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Workspace_isDirtyOverloads, Workspace::isDirty, 0, 1) +#ifdef __clang__ +#pragma clang diagnostic pop +#endif ///@endcond } void export_Workspace() { class_<Workspace, bases<DataItem>, boost::noncopyable>("Workspace", no_init) .def("getName", &Workspace::getName, - return_value_policy<copy_const_reference>(), args("self"), + return_value_policy<copy_const_reference>(), arg("self"), "Returns the name of the workspace. This could be an empty string") - .def("getTitle", &Workspace::getTitle, args("self"), + .def("getTitle", &Workspace::getTitle, arg("self"), "Returns the title of the workspace") - .def("setTitle", &Workspace::setTitle, args("self", "title")) - .def("getComment", &Workspace::getComment, + .def("setTitle", &Workspace::setTitle, (arg("self"), arg("title")), + "Set the title of the workspace") + .def("getComment", &Workspace::getComment, arg("self"), return_value_policy<copy_const_reference>(), "Returns the comment field on the workspace") - .def("setComment", &Workspace::setComment, args("self", "comment")) + .def("setComment", &Workspace::setComment, (arg("self"), arg("comment")), + "Set the comment field of the workspace") .def("isDirty", &Workspace::isDirty, - Workspace_isDirtyOverloads(arg("n"), "True if the workspace has run " - "more than n algorithms " - "(Default=1)")) - .def("getMemorySize", &Workspace::getMemorySize, args("self"), + Workspace_isDirtyOverloads((arg("self"), arg("n")), + "True if the workspace has run " + "more than n algorithms " + "(Default=1)")) + .def("getMemorySize", &Workspace::getMemorySize, arg("self"), "Returns the memory footprint of the workspace in KB") .def("getHistory", (const WorkspaceHistory &(Workspace::*)() const) & Workspace::getHistory, - return_value_policy<reference_existing_object>(), args("self"), + arg("self"), return_value_policy<reference_existing_object>(), "Return read-only access to the workspace history"); // register pointers diff --git a/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceFactory.cpp b/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceFactory.cpp index b77d3cc8a152a36926b9619fbb7cd84fd177162c..94373c2f9d16a87446c5864760cd9c88aa1aeea8 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceFactory.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceFactory.cpp @@ -40,10 +40,18 @@ Workspace_sptr createFromParentPtr(WorkspaceFactoryImpl &self, } /// Overload generator for create +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wunused-local-typedef" +#endif BOOST_PYTHON_FUNCTION_OVERLOADS(createFromParent_Overload, createFromParentPtr, 2, 5) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(createTable_Overload, createTable, 0, 1) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(createPeaks_Overload, createPeaks, 0, 1) +#ifdef __clang__ +#pragma clang diagnostic pop +#endif } void export_WorkspaceFactory() { @@ -62,22 +70,26 @@ void export_WorkspaceFactory() { class_<WorkspaceFactoryImpl, boost::noncopyable>("WorkspaceFactoryImpl", no_init) .def("create", &createFromParentPtr, - createFromParent_Overload( - createFromParentDoc, (arg("parent"), arg("NVectors") = -1, - arg("XLength") = -1, arg("YLength") = -1))) + createFromParent_Overload(createFromParentDoc, + (arg("self"), arg("parent"), + arg("NVectors") = -1, arg("XLength") = -1, + arg("YLength") = -1))) .def("create", (createFromScratchPtr)&WorkspaceFactoryImpl::create, createFromScratchDoc, return_value_policy<AsType<Workspace_sptr>>(), - (arg("className"), arg("NVectors"), arg("XLength"), arg("YLength"))) + (arg("self"), arg("className"), arg("NVectors"), arg("XLength"), + arg("YLength"))) .def("createTable", &WorkspaceFactoryImpl::createTable, - createTable_Overload("Creates an empty TableWorkspace", - (arg("className") = "TableWorkspace")) + createTable_Overload( + "Creates an empty TableWorkspace", + (arg("self"), arg("className") = "TableWorkspace")) [return_value_policy<AsType<Workspace_sptr>>()]) .def("createPeaks", &WorkspaceFactoryImpl::createPeaks, - createPeaks_Overload("Creates an empty PeaksWorkspace", - (arg("className") = "PeaksWorkspace")) + createPeaks_Overload( + "Creates an empty PeaksWorkspace", + (arg("self"), arg("className") = "PeaksWorkspace")) [return_value_policy<AsType<Workspace_sptr>>()]) .def("Instance", &WorkspaceFactory::Instance, diff --git a/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceGroup.cpp b/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceGroup.cpp index 702a7fe490a02376198838b30531fd34f70347cd..8c15d0331d17f326bcc93695ee46b4d083c8f017 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceGroup.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceGroup.cpp @@ -13,22 +13,26 @@ void export_WorkspaceGroup() { class_<WorkspaceGroup, bases<Workspace>, boost::noncopyable>("WorkspaceGroup", no_init) .def("getNumberOfEntries", &WorkspaceGroup::getNumberOfEntries, - "Returns the number of entries in the group") - .def("getNames", &WorkspaceGroup::getNames, + arg("self"), "Returns the number of entries in the group") + .def("getNames", &WorkspaceGroup::getNames, arg("self"), "Returns the names of the entries in the group") .def("contains", (bool (WorkspaceGroup::*)(const std::string &wsName) const) & WorkspaceGroup::contains, + (arg("self"), arg("workspace")), "Returns true if the given name is in the group") - .def("add", &WorkspaceGroup::add, "Add a name to the group") - .def("size", &WorkspaceGroup::size, + .def("add", &WorkspaceGroup::add, (arg("self"), arg("workspace_name")), + "Add a name to the group") + .def("size", &WorkspaceGroup::size, arg("self"), "Returns the number of workspaces contained in the group") - .def("remove", &WorkspaceGroup::remove, "Remove a name from the group") + .def("remove", &WorkspaceGroup::remove, + (arg("self"), arg("workspace_name")), "Remove a name from the group") .def("getItem", (Workspace_sptr (WorkspaceGroup::*)(const size_t) const) & WorkspaceGroup::getItem, + (arg("self"), arg("workspace_name")), return_value_policy<Policies::ToWeakPtr>(), "Returns the item at the given index") - .def("isMultiPeriod", &WorkspaceGroup::isMultiperiod, + .def("isMultiPeriod", &WorkspaceGroup::isMultiperiod, arg("self"), "Retuns true if the workspace group is multi-period") // ------------ Operators -------------------------------- .def("__len__", &WorkspaceGroup::getNumberOfEntries) diff --git a/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceHistory.cpp b/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceHistory.cpp index ad3133315cf8f163ccbd0f643d94ee004166d8d1..9a32321b85fe93b711c88e770ae089e673720b86 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceHistory.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceHistory.cpp @@ -38,27 +38,31 @@ void export_WorkspaceHistory() { class_<WorkspaceHistory, boost::noncopyable>("WorkspaceHistory", no_init) - .def("getAlgorithmHistories", &getHistoriesAsList, + .def("getAlgorithmHistories", &getHistoriesAsList, arg("self"), "Returns a list of algorithm histories for this workspace history.") .def("getAlgorithmHistory", &WorkspaceHistory::getAlgorithmHistory, - arg("index"), return_value_policy<Policies::RemoveConstSharedPtr>(), + (arg("self"), arg("index")), + return_value_policy<Policies::RemoveConstSharedPtr>(), "Returns the algorithm history at the given index in the history") - .def("size", &WorkspaceHistory::size, + .def("size", &WorkspaceHistory::size, arg("self"), "Returns the number of algorithms in the immediate history") - .def("empty", &WorkspaceHistory::empty, + .def("empty", &WorkspaceHistory::empty, arg("self"), "Returns whether the history has any entries") - .def("lastAlgorithm", &WorkspaceHistory::lastAlgorithm, + .def("lastAlgorithm", &WorkspaceHistory::lastAlgorithm, arg("self"), "Returns the last algorithm run on this workspace so that its " "properties can be accessed") .def("getAlgorithm", &WorkspaceHistory::getAlgorithm, + (arg("self"), arg("index")), "Returns the algorithm at the given index in the history") // ----------------- Operators -------------------------------------- - .def("__getitem__", &WorkspaceHistory::getAlgorithm) + .def("__getitem__", &WorkspaceHistory::getAlgorithm, + (arg("self"), arg("index")), + "Create an algorithm from a history record at a given index") .def(self_ns::str(self)); } diff --git a/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceValidators.cpp b/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceValidators.cpp index 7bb9257a0765c7c566065d0fc28ab6c5b8c2079d..898b1032bfd0a414f110e83b1296a5cd85837d87 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceValidators.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceValidators.cpp @@ -1,4 +1,9 @@ -#include "MantidAPI/WorkspaceValidators.h" // They are all defined in one file so export them in one +#include "MantidAPI/CommonBinsValidator.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/NumericAxisValidator.h" +#include "MantidAPI/RawCountValidator.h" +#include "MantidAPI/SpectraAxisValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidPythonInterface/kernel/TypedValidatorExporter.h" #include <boost/python/class.hpp> diff --git a/Framework/PythonInterface/mantid/geometry/CMakeLists.txt b/Framework/PythonInterface/mantid/geometry/CMakeLists.txt index b268c7b2f7b1854ec9b3dcd25e76286f88455ce5..371c0a374891f6ee1601ea94a91f0719f0d49ace 100644 --- a/Framework/PythonInterface/mantid/geometry/CMakeLists.txt +++ b/Framework/PythonInterface/mantid/geometry/CMakeLists.txt @@ -35,6 +35,8 @@ set ( EXPORT_FILES src/Exports/SymmetryElementFactory.cpp src/Exports/SymmetryOperation.cpp src/Exports/SymmetryOperationFactory.cpp + src/Exports/CrystalStructure.cpp + src/Exports/ReflectionGenerator.cpp ) ############################################################################################# diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/BoundingBox.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/BoundingBox.cpp index 47d718238f0c619778f94be92788e7ba868cf79c..52eb111ecf2762d427a04ebb3d880ff732e19084 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/BoundingBox.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/BoundingBox.cpp @@ -9,39 +9,40 @@ using namespace boost::python; void export_BoundingBox() { class_<BoundingBox>("BoundingBox", "Constructs a zero-sized box") .def(init<double, double, double, double, double, double>( - (arg("xmax"), arg("ymax"), arg("zmax"), arg("xmin"), arg("ymin"), - arg("zmin")), + (arg("self"), arg("xmax"), arg("ymax"), arg("zmax"), arg("xmin"), + arg("ymin"), arg("zmin")), "Constructs a box from the six given points")) - .def("minPoint", &BoundingBox::minPoint, + .def("minPoint", &BoundingBox::minPoint, arg("self"), return_value_policy<copy_const_reference>(), "Returns a V3D containing the values of the minimum of the box. See " "mantid.kernel.V3D") - .def("maxPoint", &BoundingBox::maxPoint, + .def("maxPoint", &BoundingBox::maxPoint, arg("self"), return_value_policy<copy_const_reference>(), "Returns a V3D containing the values of the minimum of the box. See " "mantid.kernel.V3D") - .def("centrePoint", &BoundingBox::centrePoint, + .def("centrePoint", &BoundingBox::centrePoint, arg("self"), "Returns a V3D containing the coordinates of the centre point. See " "mantid.kernel.V3D") - .def("width", &BoundingBox::width, "Returns a V3D containing the widths " - "for each dimension. See " - "mantid.kernel.V3D") + .def("width", &BoundingBox::width, arg("self"), + "Returns a V3D containing the widths " + "for each dimension. See " + "mantid.kernel.V3D") - .def("isNull", &BoundingBox::isNull, + .def("isNull", &BoundingBox::isNull, arg("self"), "Returns true if the box has no dimensions that have been set") - .def("isPointInside", &BoundingBox::isPointInside, + .def("isPointInside", &BoundingBox::isPointInside, arg("self"), "Returns true if the given point is inside the object. See " "mantid.kernel.V3D") .def("doesLineIntersect", (bool (BoundingBox::*)(const V3D &, const V3D &) const) & BoundingBox::doesLineIntersect, - (arg("startPoint"), arg("lineDir")), + (arg("self"), arg("startPoint"), arg("lineDir")), "Returns true if the line given by the starting point & direction " "vector passes through the box"); } diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/Component.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/Component.cpp index 5ad6c63e6d0715de3c948aa0857a4e78f618ca66..77b295f76a19e855e7abd89b2e65515276e89676 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/Component.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/Component.cpp @@ -7,6 +7,11 @@ using Mantid::Geometry::IComponent; using namespace boost::python; namespace { +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wunused-local-typedef" +#endif // Default parameter function overloads BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Component_getParameterNames, Component::getParameterNames, 0, 1) @@ -36,45 +41,62 @@ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Component_getParamShortDescription, BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Component_getParamDescription, Component::getParamDescription, 1, 2) } +#ifdef __clang__ +#pragma clang diagnostic pop +#endif void export_Component() { class_<Component, bases<IComponent>, boost::noncopyable>("Component", no_init) .def("getParameterNames", &Component::getParameterNames, - Component_getParameterNames()) - .def("hasParameter", &Component::hasParameter, Component_hasParameter()) + Component_getParameterNames((arg("self"), arg("recursive") = true))) + .def("hasParameter", &Component::hasParameter, + Component_hasParameter( + (arg("self"), arg("name"), arg("recursive") = true))) .def("getNumberParameter", &Component::getNumberParameter, - Component_getNumberParameter()) + Component_getNumberParameter( + (arg("self"), arg("pname"), arg("recursive") = true))) .def("getBoolParameter", &Component::getBoolParameter, - Component_getBoolParameter()) + Component_getBoolParameter( + (arg("self"), arg("pname"), arg("recursive") = true))) .def("getPositionParameter", &Component::getPositionParameter, - Component_getPositionParameter()) + Component_getPositionParameter( + (arg("self"), arg("pname"), arg("recursive") = true))) .def("getRotationParameter", &Component::getRotationParameter, - Component_getRotationParameter()) + Component_getRotationParameter( + (arg("self"), arg("pname"), arg("recursive") = true))) .def("getStringParameter", &Component::getStringParameter, - Component_getStringParameter()) + Component_getStringParameter( + (arg("self"), arg("pname"), arg("recursive") = true))) .def("getIntParameter", &Component::getIntParameter, - Component_getIntParameter()) + Component_getIntParameter( + (arg("self"), arg("pname"), arg("recursive") = true))) // - .def("getRotation", &Component::getRotation, Component_getRotation()) + .def("getRotation", &Component::getRotation, + Component_getRotation(arg("self"))) .def("getRelativePos", &Component::getRelativePos, - Component_getRelativePos()) + Component_getRelativePos(arg("self"))) // .def("getParamShortDescription", &Component::getParamShortDescription, - Component_getParamShortDescription()) + Component_getParamShortDescription( + (arg("self"), arg("pname"), arg("recursive") = true))) .def("getParamDescription", &Component::getParamDescription, - Component_getParamDescription()) - .def("getShortDescription", &Component::getShortDescription, + Component_getParamDescription( + (arg("self"), arg("pname"), arg("recursive") = true))) + + .def("getShortDescription", &Component::getShortDescription, arg("self"), "Return the short description of current parameterized component") - .def("getDescription", &Component::getDescription, + .def("getDescription", &Component::getDescription, arg("self"), "Return the description of current parameterized component") .def("setDescription", &Component::setDescription, + (arg("self"), arg("descr")), "Set component's description, works only if the component is " "parameterized component") // HACK -- python should return parameters regardless of type. this is // untill rows below do not work .def("getParameterType", &Component::getParameterType, - Component_getParameterType()) + Component_getParameterType( + (arg("self"), arg("pname"), arg("recursive") = true))) //// this does not work for some obvious or not obvious reasons //.def("getParameter", &Component::getNumberParameter, // Component_getNumberParameter()) diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/CrystalStructure.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/CrystalStructure.cpp new file mode 100644 index 0000000000000000000000000000000000000000..daf4587a81da370e1ffd0adc07d04f7b625a99c4 --- /dev/null +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/CrystalStructure.cpp @@ -0,0 +1,38 @@ +#include "MantidGeometry/Crystal/CrystalStructure.h" +#include "MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h" +#include <boost/python/class.hpp> +#include <boost/python/make_constructor.hpp> +#include <boost/python/register_ptr_to_python.hpp> + +using namespace Mantid::Geometry; +using namespace Mantid::Kernel; +using namespace boost::python; + +namespace { +SpaceGroup_sptr getSpaceGroup(CrystalStructure &self) { + return boost::const_pointer_cast<SpaceGroup>(self.spaceGroup()); +} + +std::vector<std::string> getScatterers(CrystalStructure &self) { + CompositeBraggScatterer_sptr scatterers = self.getScatterers(); + + std::vector<std::string> scattererStrings; + scattererStrings.reserve(scatterers->nScatterers()); + + for (size_t i = 0; i < scatterers->nScatterers(); ++i) { + scattererStrings.push_back( + getIsotropicAtomBraggScattererString(scatterers->getScatterer(i))); + } + + return scattererStrings; +} +} + +void export_CrystalStructure() { + class_<CrystalStructure>("CrystalStructure", no_init) + .def(init<const std::string &, const std::string &, const std::string &>( + (arg("unitCell"), arg("spaceGroup"), arg("scatterers")))) + .def("getUnitCell", &CrystalStructure::cell) + .def("getSpaceGroup", &getSpaceGroup) + .def("getScatterers", &getScatterers); +} diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/DetectorGroup.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/DetectorGroup.cpp index fe6107d725d865dd6248c4e34129de1970f47e1d..2a9be545cbb2fc04e75905bdc732db599aa5869b 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/DetectorGroup.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/DetectorGroup.cpp @@ -8,8 +8,8 @@ using namespace boost::python; void export_DetectorGroup() { class_<DetectorGroup, bases<IDetector>, boost::noncopyable>("DetectorGroup", no_init) - .def("getDetectorIDs", &DetectorGroup::getDetectorIDs, + .def("getDetectorIDs", &DetectorGroup::getDetectorIDs, arg("self"), "Returns the list of detector IDs within this group") - .def("getNameSeparator", &DetectorGroup::getNameSeparator, + .def("getNameSeparator", &DetectorGroup::getNameSeparator, arg("self"), "Returns separator for list of names of detectors"); } diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/Goniometer.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/Goniometer.cpp index 184ca40caf1c17fbcf4a54d0f95c9972e8dfed47..cf01cad70f650daf90365084fb77c668afc84ed2 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/Goniometer.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/Goniometer.cpp @@ -13,9 +13,17 @@ using namespace boost::python; namespace //<unnamed> { ///@cond +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wunused-local-typedef" +#endif // define overloaded functions BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(getEulerAngles_overloads, Goniometer::getEulerAngles, 0, 1) +#ifdef __clang__ +#pragma clang diagnostic pop +#endif ///@endcond /// Set the U vector via a numpy array @@ -37,6 +45,6 @@ void export_Goniometer() { getEulerAngles_overloads(args("self", "convention"), "Default convention is \'YZX\'. Universal " "goniometer is \'YZY\'")) - .def("getR", &Goniometer::getR, return_readonly_numpy()) - .def("setR", &setR); + .def("getR", &Goniometer::getR, arg("self"), return_readonly_numpy()) + .def("setR", &setR, (arg("self"), arg("rot"))); } diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/Group.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/Group.cpp index cc83d3c6c3de24031536b9e297a3b2049257e35e..28565ab5935ed0fbe38202afe72b96b047313d6d 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/Group.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/Group.cpp @@ -64,25 +64,35 @@ void export_Group() { .value("Associativity", Group::Associativity); class_<Group, boost::noncopyable>("Group", no_init) - .def("__init__", make_constructor(&constructGroupFromString), + .def("__init__", + make_constructor(&constructGroupFromString, default_call_policies(), + (arg("symmetryOperationString"))), "Construct a group from the provided initializer string.") - .def("__init__", make_constructor(&constructGroupFromVector), + .def("__init__", + make_constructor(&constructGroupFromVector, default_call_policies(), + (arg("symmetryOperationVector"))), "Construct a group from the provided symmetry operation list.") - .def("__init__", make_constructor(&constructGroupFromPythonList), + .def("__init__", make_constructor(&constructGroupFromPythonList, + default_call_policies(), + (arg("symmetryOperationList"))), "Construct a group from a python generated symmetry operation list.") - .def("getOrder", &Group::order, "Returns the order of the group.") - .def("getCoordinateSystem", &Group::getCoordinateSystem, + .def("getOrder", &Group::order, arg("self"), + "Returns the order of the group.") + .def("getCoordinateSystem", &Group::getCoordinateSystem, arg("self"), "Returns the type of coordinate system to distinguish groups with " "hexagonal system definition.") - .def("getSymmetryOperations", &Group::getSymmetryOperations, + .def("getSymmetryOperations", &Group::getSymmetryOperations, arg("self"), "Returns the symmetry operations contained in the group.") .def("getSymmetryOperationStrings", &getSymmetryOperationStrings, + arg("self"), "Returns the x,y,z-strings for the contained symmetry operations.") .def("containsOperation", &Group::containsOperation, + (arg("self"), arg("operation")), "Checks whether a SymmetryOperation is included in Group.") - .def("isGroup", &Group::isGroup, "Checks whether the contained symmetry " - "operations fulfill the group axioms.") - .def("fulfillsAxiom", &Group::fulfillsAxiom, + .def("isGroup", &Group::isGroup, arg("self"), + "Checks whether the contained symmetry " + "operations fulfill the group axioms.") + .def("fulfillsAxiom", &Group::fulfillsAxiom, (arg("self"), arg("axiom")), "Checks if the contained symmetry operations fulfill the specified " "group axiom."); } diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/ICompAssembly.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/ICompAssembly.cpp index bc8d4d2cec5779576dd9e2826a345c1cb12821b7..32e39ed16f535e568e236c64ae2cb23c558f3046 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/ICompAssembly.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/ICompAssembly.cpp @@ -11,8 +11,9 @@ void export_ICompAssembly() { class_<ICompAssembly, boost::python::bases<IComponent>, boost::noncopyable>( "ICompAssembly", no_init) - .def("nelements", &ICompAssembly::nelements, + .def("nelements", &ICompAssembly::nelements, arg("self"), "Returns the number of elements in the assembly") - .def("__getitem__", &ICompAssembly::operator[], + .def("__getitem__", + &ICompAssembly::operator[], (arg("self"), arg("index")), "Return the component at the given index"); } diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/IComponent.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/IComponent.cpp index ff0a91941229fe8a31096d5813371858ab8d374f..d6052b1728b8222a660fcca8861641bc14afa51f 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/IComponent.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/IComponent.cpp @@ -29,16 +29,18 @@ void export_IComponent() { register_ptr_to_python<boost::shared_ptr<IComponent>>(); class_<IComponent, boost::noncopyable>("IComponent", no_init) - .def("getPos", &IComponent::getPos, + .def("getPos", &IComponent::getPos, arg("self"), "Returns the absolute position of the component") - .def("getDistance", &getDistance, "Returns the distance, in metres, " - "between this and the given component") - .def("getName", &IComponent::getName, "Returns the name of the component") - .def("getFullName", &IComponent::getFullName, + .def("getDistance", &getDistance, (arg("self"), arg("other")), + "Returns the distance, in metres, " + "between this and the given component") + .def("getName", &IComponent::getName, arg("self"), + "Returns the name of the component") + .def("getFullName", &IComponent::getFullName, arg("self"), "Returns full path name of component") - .def("type", &IComponent::type, + .def("type", &IComponent::type, arg("self"), "Returns the type of the component represented as a string") - .def("getRelativeRot", &IComponent::getRelativeRot, + .def("getRelativeRot", &IComponent::getRelativeRot, arg("self"), return_value_policy<copy_const_reference>(), "Returns the relative rotation as a Quat"); } diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/IDetector.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/IDetector.cpp index 8bb8d0299891a3bd402d20f054313c877b2902c8..669fbd06ccd3263a61b79cddffa4ed6e0f5b5795 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/IDetector.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/IDetector.cpp @@ -11,18 +11,19 @@ void export_IDetector() { class_<IDetector, bases<IObjComponent>, boost::noncopyable>("IDetector", no_init) - .def("getID", &IDetector::getID, "Returns the detector ID") - .def("isMasked", &IDetector::isMasked, "Returns the value of the masked " - "flag. True means ignore this " - "detector") - .def("isMonitor", &IDetector::isMonitor, + .def("getID", &IDetector::getID, arg("self"), "Returns the detector ID") + .def("isMasked", &IDetector::isMasked, arg("self"), + "Returns the value of the masked flag. True means ignore this " + "detector") + .def("isMonitor", &IDetector::isMonitor, arg("self"), "Returns True if the detector is marked as a monitor in the IDF") - .def("solidAngle", &IDetector::solidAngle, "Return the solid angle in " - "steradians between this " - "detector and an observer") + .def("solidAngle", &IDetector::solidAngle, (arg("self"), arg("observer")), + "Return the solid angle in steradians between this " + "detector and an observer") .def("getTwoTheta", &IDetector::getTwoTheta, + (arg("self"), arg("observer"), arg("axis")), "Calculate the angle between this detector, another component and " "an axis") - .def("getPhi", &IDetector::getPhi, + .def("getPhi", &IDetector::getPhi, arg("self"), "Returns the azimuthal angle of this detector"); } diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/IMDDimension.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/IMDDimension.cpp index 7f32083e78fdf64734a7f246a1f820ed853d69ee..77f8f1778ea5f7e5b13d3488d92f118368ddae2b 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/IMDDimension.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/IMDDimension.cpp @@ -39,24 +39,24 @@ void export_IMDDimension() { register_ptr_to_python<boost::shared_ptr<IMDDimension>>(); class_<IMDDimension, boost::noncopyable>("IMDDimension", no_init) - .def("getName", &IMDDimension::getName, "Return the name of the " - "dimension as can be displayed " - "along the axis") - .def("getMaximum", &IMDDimension::getMaximum, + .def("getName", &IMDDimension::getName, arg("self"), + "Return the name of the dimension as can be displayed " + "along the axis") + .def("getMaximum", &IMDDimension::getMaximum, arg("self"), "Return the maximum extent of this dimension") - .def("getMinimum", &IMDDimension::getMinimum, + .def("getMinimum", &IMDDimension::getMinimum, arg("self"), "Return the maximum extent of this dimension") - .def("getNBins", &IMDDimension::getNBins, + .def("getNBins", &IMDDimension::getNBins, arg("self"), "Return the number of bins dimension have (an integrated has one). " "A axis directed along dimension would have getNBins+1 axis points.") - .def("getX", &IMDDimension::getX, + .def("getX", &IMDDimension::getX, (arg("self"), arg("ind")), "Return coordinate of the axis at the given index") - .def("getDimensionId", &IMDDimension::getDimensionId, + .def("getDimensionId", &IMDDimension::getDimensionId, arg("self"), "Return a short name which identify the dimension among other " "dimension." "A dimension can be usually find by its ID and various ") - .def("getUnits", &getUnitsAsStr, + .def("getUnits", &getUnitsAsStr, arg("self"), "Return the units associated with this dimension.") - .def("getMDFrame", &getMDFrame, + .def("getMDFrame", &getMDFrame, arg("self"), "Return the multidimensional frame for this dimension."); } diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/IObjComponent.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/IObjComponent.cpp index cf9a708a50efb951e0509784e099ca1c7d90a383..fe184670cb1d98c8599a96ee53409e82c426e0ae 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/IObjComponent.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/IObjComponent.cpp @@ -25,6 +25,7 @@ void export_IObjComponent() { class_<IObjComponent, boost::python::bases<IComponent>, boost::noncopyable>( "IObjComponent", no_init) - .def("shape", &getShape, "Get the object that represents the physical " - "shape of this component"); + .def("shape", &getShape, arg("self"), "Get the object that represents " + "the physical shape of this " + "component"); } diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/Instrument.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/Instrument.cpp index d7ba822270890191a23ac0612aea78464ad82b17..d082519344c6fb4c5b6e68d58ed979e01f4ad589 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/Instrument.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/Instrument.cpp @@ -15,41 +15,39 @@ void export_Instrument() { class_<Instrument, bases<CompAssembly>, boost::noncopyable>("Instrument", no_init) - .def("getSample", &Instrument::getSample, + .def("getSample", &Instrument::getSample, arg("self"), return_value_policy<RemoveConstSharedPtr>(), "Return the object that represents the sample") - .def("getSource", &Instrument::getSource, + .def("getSource", &Instrument::getSource, arg("self"), return_value_policy<RemoveConstSharedPtr>(), "Return the object that represents the source") .def("getComponentByName", (boost::shared_ptr<IComponent>(Instrument::*)(const std::string &)) & Instrument::getComponentByName, - "Returns the named component") + (arg("self"), arg("cname")), "Returns the named component") .def("getDetector", (boost::shared_ptr<IDetector>( Instrument::*)(const detid_t &) const) & Instrument::getDetector, + (arg("self"), arg("detector_id")), "Returns the detector with the given ID") .def("getReferenceFrame", (boost::shared_ptr<const ReferenceFrame>(Instrument::*)()) & Instrument::getReferenceFrame, - return_value_policy<RemoveConstSharedPtr>(), + arg("self"), return_value_policy<RemoveConstSharedPtr>(), "Returns the reference frame attached that defines the instrument " "axes") - .def("getValidFromDate", &Instrument::getValidFromDate, + .def("getValidFromDate", &Instrument::getValidFromDate, arg("self"), "Return the valid from date of the instrument") - .def("getValidToDate", &Instrument::getValidToDate, + .def("getValidToDate", &Instrument::getValidToDate, arg("self"), "Return the valid to date of the instrument") - .def("getBaseInstrument", &Instrument::baseInstrument, + .def("getBaseInstrument", &Instrument::baseInstrument, arg("self"), return_value_policy<RemoveConstSharedPtr>(), "Return reference to the base instrument"); - ; - - ; } diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/MDFrame.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/MDFrame.cpp index 3f6a3e2ed811775b0019107a4cce1f7a29f1114b..af5dad9763b679e40144822ef79e472624536e42 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/MDFrame.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/MDFrame.cpp @@ -13,6 +13,6 @@ void export_MDFrame() { register_ptr_to_python<boost::shared_ptr<MDFrame>>(); class_<MDFrame, boost::noncopyable>("MDFrame", no_init) - .def("getUnitLabel", &MDFrame::getUnitLabel) - .def("name", &MDFrame::name); + .def("getUnitLabel", &MDFrame::getUnitLabel, arg("self")) + .def("name", &MDFrame::name, arg("self")); } diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/Object.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/Object.cpp index 756ed9f2b7d8d8e1a0fed30067fb6c7ca722d43b..33acda45f4d304af7bba24863adb797455708765 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/Object.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/Object.cpp @@ -13,9 +13,9 @@ void export_Object() { class_<Object, boost::noncopyable>("Object", no_init) .def("getBoundingBox", (const BoundingBox &(Object::*)() const) & Object::getBoundingBox, - return_value_policy<copy_const_reference>(), + arg("self"), return_value_policy<copy_const_reference>(), "Return the axis-aligned bounding box for this shape") - .def("getShapeXML", &Object::getShapeXML, + .def("getShapeXML", &Object::getShapeXML, arg("self"), "Returns the XML that was used to create this shape."); } diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/OrientedLattice.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/OrientedLattice.cpp index b392a312a8eefe784c93c74f828db9efda0e334e..14a995b5b9a8a47c38e10f7a23d34f4bd591f057 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/OrientedLattice.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/OrientedLattice.cpp @@ -55,13 +55,17 @@ void export_OrientedLattice() { (arg("_a"), arg("_b"), arg("_c"), arg("_alpha"), arg("_beta"), arg("_gamma"), arg("Unit") = (int)(angDegrees)))) .def(init<UnitCell>(arg("uc"))) - .def("getuVector", (&OrientedLattice::getuVector)) - .def("getvVector", (&OrientedLattice::getvVector)) - .def("getU", &OrientedLattice::getU, return_readonly_numpy()) - .def("setU", &setU) - .def("getUB", &OrientedLattice::getUB, return_readonly_numpy()) - .def("setUB", &setUB) - .def("setUFromVectors", &setUFromVectors) - .def("qFromHKL", &qFromHKL, "Q vector from HKL vector") - .def("hklFromQ", &hklFromQ, "HKL value from Q vector"); + .def("getuVector", (&OrientedLattice::getuVector), arg("self")) + .def("getvVector", (&OrientedLattice::getvVector), arg("self")) + .def("getU", &OrientedLattice::getU, arg("self"), return_readonly_numpy()) + .def("setU", &setU, (arg("self"), arg("newU"))) + .def("getUB", &OrientedLattice::getUB, arg("self"), + return_readonly_numpy()) + .def("setUB", &setUB, (arg("self"), arg("newUB"))) + .def("setUFromVectors", &setUFromVectors, + (arg("self"), arg("u"), arg("v"))) + .def("qFromHKL", &qFromHKL, (arg("self"), arg("vec")), + "Q vector from HKL vector") + .def("hklFromQ", &hklFromQ, (arg("self"), arg("vec")), + "HKL value from Q vector"); } diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/PeakShape.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/PeakShape.cpp index 420e07c0ea2a4b5fca085a0adb15ba02098b4166..7c8fbf8f63638225abb96f5704d43dbde5b9c84b 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/PeakShape.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/PeakShape.cpp @@ -9,10 +9,12 @@ void export_PeakShape() { register_ptr_to_python<Mantid::Geometry::PeakShape_sptr>(); class_<PeakShape, boost::noncopyable>("PeakShape", no_init) - .def("toJSON", &PeakShape::toJSON, "Serialize object to JSON") - .def("shapeName", &PeakShape::shapeName, "Shape name for type of shape") - .def("algorithmVersion", &PeakShape::algorithmVersion, + .def("toJSON", &PeakShape::toJSON, arg("self"), + "Serialize object to JSON") + .def("shapeName", &PeakShape::shapeName, arg("self"), + "Shape name for type of shape") + .def("algorithmVersion", &PeakShape::algorithmVersion, arg("self"), "Number of source integration algorithm version") - .def("algorithmName", &PeakShape::algorithmName, + .def("algorithmName", &PeakShape::algorithmName, arg("self"), "Name of source integration algorithm"); } diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroup.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroup.cpp index 31d222c1a7f857eb4064efe43111e3034283bbdb..612397d3524a54e1a4bfbd7bcdccc5540e14b3d4 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroup.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroup.cpp @@ -55,14 +55,16 @@ void export_PointGroup() { .value("Cubic", PointGroup::Cubic); class_<PointGroup, boost::noncopyable, bases<Group>>("PointGroup", no_init) - .def("getName", &PointGroup::getName) - .def("getHMSymbol", &PointGroup::getSymbol) - .def("getCrystalSystem", &PointGroup::crystalSystem) + .def("getName", &PointGroup::getName, arg("self")) + .def("getHMSymbol", &PointGroup::getSymbol, arg("self")) + .def("getCrystalSystem", &PointGroup::crystalSystem, arg("self")) .def("isEquivalent", &isEquivalent, + (arg("self"), arg("hkl1"), arg("hkl2")), "Check whether the two HKLs are symmetrically equivalent.") - .def("getEquivalents", &getEquivalents, "Returns an array with all " - "symmetry equivalents of the " - "supplied HKL.") + .def("getEquivalents", &getEquivalents, (arg("self"), arg("hkl")), + "Returns an array with all symmetry equivalents of the supplied " + "HKL.") .def("getReflectionFamily", &getReflectionFamily, + (arg("self"), arg("hkl")), "Returns the same HKL for all symmetry equivalents."); } diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroupFactory.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroupFactory.cpp index 0ec8f5c51de65da80f1ffe5e224800ae214dc0e9..07ef88cf35da0139bc8344b68d2b0ca4761a4906 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroupFactory.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroupFactory.cpp @@ -25,19 +25,23 @@ void export_PointGroupFactory() { class_<PointGroupFactoryImpl, boost::noncopyable>("PointGroupFactoryImpl", no_init) .def("isSubscribed", &PointGroupFactoryImpl::isSubscribed, + (arg("self"), arg("hmSymbol")), "Returns true of the point group with the given symbol is " "subscribed.") .def("createPointGroup", &PointGroupFactoryImpl::createPointGroup, + (arg("self"), arg("hmSymbol")), "Creates a point group if registered.") .def("createPointGroupFromSpaceGroup", &getPointGroupFromSpaceGroup, + (arg("self"), arg("group")), "Creates the point group that corresponds to the given space group.") .def("createPointGroupFromSpaceGroupSymbol", - &getPointGroupFromSpaceGroupSymbol, + &getPointGroupFromSpaceGroupSymbol, (arg("self"), arg("group")), "Creates a point group directly from the space group symbol.") .def("getAllPointGroupSymbols", - &PointGroupFactoryImpl::getAllPointGroupSymbols, + &PointGroupFactoryImpl::getAllPointGroupSymbols, arg("self"), "Returns all registered point group symbols.") .def("getPointGroupSymbols", &PointGroupFactoryImpl::getPointGroupSymbols, + (arg("self"), arg("crystalsystem")), "Returns all point groups registered for the given crystal system.") .def("Instance", &PointGroupFactory::Instance, return_value_policy<reference_existing_object>(), diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/RectangularDetector.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/RectangularDetector.cpp index 01cf57f0361b3758262a8f13e8461379ec964353..8738dd36438adefb21edaf65818cf8196e0c93b4 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/RectangularDetector.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/RectangularDetector.cpp @@ -16,31 +16,33 @@ void export_RectangularDetector() { class_<RectangularDetector, bases<CompAssembly, IObjComponent>, boost::noncopyable>("RectangularDetector", no_init) - .def("xpixels", &RectangularDetector::xpixels, + .def("xpixels", &RectangularDetector::xpixels, arg("self"), "Returns the number of pixels in the X direction") - .def("ypixels", &RectangularDetector::ypixels, + .def("ypixels", &RectangularDetector::ypixels, arg("self"), "Returns the number of pixels in the Y direction") - .def("xstep", &RectangularDetector::xstep, + .def("xstep", &RectangularDetector::xstep, arg("self"), "Returns the step size in the X direction") - .def("ystep", &RectangularDetector::ystep, + .def("ystep", &RectangularDetector::ystep, arg("self"), "Returns the step size in the Y direction") - .def("xsize", &RectangularDetector::xsize, + .def("xsize", &RectangularDetector::xsize, arg("self"), "Returns the size in the X direction") - .def("ysize", &RectangularDetector::ysize, + .def("ysize", &RectangularDetector::ysize, arg("self"), "Returns the size in the Y direction") - .def("xstart", &RectangularDetector::xstart, + .def("xstart", &RectangularDetector::xstart, arg("self"), "Returns the start position in the X direction") - .def("ystart", &RectangularDetector::ystart, + .def("ystart", &RectangularDetector::ystart, arg("self"), "Returns the start position in the Y direction") - .def("idstart", &RectangularDetector::idstart, "Returns the idstart") + .def("idstart", &RectangularDetector::idstart, arg("self"), + "Returns the idstart") .def("idfillbyfirst_y", &RectangularDetector::idfillbyfirst_y, - "Returns the idfillbyfirst_y") - .def("idstepbyrow", &RectangularDetector::idstepbyrow, + arg("self"), "Returns the idfillbyfirst_y") + .def("idstepbyrow", &RectangularDetector::idstepbyrow, arg("self"), "Returns the idstepbyrow") - .def("idstep", &RectangularDetector::idstep, "Returns the idstep") - .def("minDetectorID", &RectangularDetector::minDetectorID, + .def("idstep", &RectangularDetector::idstep, arg("self"), + "Returns the idstep") + .def("minDetectorID", &RectangularDetector::minDetectorID, arg("self"), "Returns the minimum detector id") - .def("maxDetectorID", &RectangularDetector::maxDetectorID, + .def("maxDetectorID", &RectangularDetector::maxDetectorID, arg("self"), "Returns the maximum detector id"); } diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/ReferenceFrame.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/ReferenceFrame.cpp index be19d8047e4e04829fe7773e7f6ec54823f0f4ab..c8a79ddbbc76e80bf9bf83a2eb08ba863c6b6c7f 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/ReferenceFrame.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/ReferenceFrame.cpp @@ -21,13 +21,14 @@ void export_ReferenceFrame() { .export_values(); class_<ReferenceFrame, boost::noncopyable>("ReferenceFrame", no_init) - .def("pointingAlongBeam", &ReferenceFrame::pointingAlongBeam) - .def("pointingUp", &ReferenceFrame::pointingUp) - .def("vecPointingUp", &ReferenceFrame::vecPointingUp) - .def("vecPointingAlongBeam", &ReferenceFrame::vecPointingAlongBeam) - .def("pointingAlongBeamAxis", &ReferenceFrame::pointingAlongBeamAxis) - .def("pointingUpAxis", &ReferenceFrame::pointingUpAxis) - .def("pointingHorizontalAxis", &ReferenceFrame::pointingHorizontalAxis) - - ; + .def("pointingAlongBeam", &ReferenceFrame::pointingAlongBeam, arg("self")) + .def("pointingUp", &ReferenceFrame::pointingUp, arg("self")) + .def("vecPointingUp", &ReferenceFrame::vecPointingUp, arg("self")) + .def("vecPointingAlongBeam", &ReferenceFrame::vecPointingAlongBeam, + arg("self")) + .def("pointingAlongBeamAxis", &ReferenceFrame::pointingAlongBeamAxis, + arg("self")) + .def("pointingUpAxis", &ReferenceFrame::pointingUpAxis, arg("self")) + .def("pointingHorizontalAxis", &ReferenceFrame::pointingHorizontalAxis, + arg("self")); } diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/ReflectionGenerator.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/ReflectionGenerator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..83882c117af6c3965b0e7ed3aae8a75d9dab063b --- /dev/null +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/ReflectionGenerator.cpp @@ -0,0 +1,77 @@ +#include "MantidGeometry/Crystal/ReflectionGenerator.h" +#include "MantidPythonInterface/kernel/Converters/PySequenceToVector.h" +#include <boost/python/class.hpp> +#include <boost/python/enum.hpp> +#include <boost/python/list.hpp> + +using namespace Mantid::Geometry; +using namespace Mantid::Kernel; +using namespace Mantid::PythonInterface; +using namespace boost::python; + +namespace { +boost::python::list getListFromV3DVector(const std::vector<V3D> &hkls) { + boost::python::list hklList; + for (auto it = hkls.begin(); it != hkls.end(); ++it) { + hklList.append(*it); + } + return hklList; +} + +boost::python::list getHKLsDefaultFilter(ReflectionGenerator &self, double dMin, + double dMax) { + return getListFromV3DVector(self.getHKLs(dMin, dMax)); +} + +boost::python::list getHKLsUsingFilter(ReflectionGenerator &self, double dMin, + double dMax, + ReflectionConditionFilter filter) { + return getListFromV3DVector( + self.getHKLs(dMin, dMax, self.getReflectionConditionFilter(filter))); +} + +boost::python::list getUniqueHKLsDefaultFilter(ReflectionGenerator &self, + double dMin, double dMax) { + return getListFromV3DVector(self.getUniqueHKLs(dMin, dMax)); +} + +boost::python::list getUniqueHKLsUsingFilter(ReflectionGenerator &self, + double dMin, double dMax, + ReflectionConditionFilter filter) { + return getListFromV3DVector(self.getUniqueHKLs( + dMin, dMax, self.getReflectionConditionFilter(filter))); +} + +std::vector<double> getDValues(ReflectionGenerator &self, + const boost::python::object &hkls) { + Converters::PySequenceToVector<V3D> converter(hkls); + + return self.getDValues(converter()); +} + +std::vector<double> getFsSquared(ReflectionGenerator &self, + const boost::python::object &hkls) { + Converters::PySequenceToVector<V3D> converter(hkls); + + return self.getFsSquared(converter()); +} +} + +void export_ReflectionGenerator() { + enum_<ReflectionConditionFilter>("ReflectionConditionFilter") + .value("None", ReflectionConditionFilter::None) + .value("Centering", ReflectionConditionFilter::Centering) + .value("SpaceGroup", ReflectionConditionFilter::SpaceGroup) + .value("StructureFactor", ReflectionConditionFilter::StructureFactor) + .export_values(); + + class_<ReflectionGenerator>("ReflectionGenerator", no_init) + .def(init<const CrystalStructure &, optional<ReflectionConditionFilter>>( + (arg("crystalStructure"), arg("defaultFilter")))) + .def("getHKLs", &getHKLsDefaultFilter) + .def("getHKLsUsingFilter", &getHKLsUsingFilter) + .def("getUniqueHKLs", &getUniqueHKLsDefaultFilter) + .def("getUniqueHKLsUsingFilter", &getUniqueHKLsUsingFilter) + .def("getDValues", &getDValues) + .def("getFsSquared", &getFsSquared); +} diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroup.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroup.cpp index 9b83cabe216135b66e9d7a04c8aa141c5c0c5282..919d784341e24fcb868e2eff89e92e5523843112 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroup.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroup.cpp @@ -53,16 +53,19 @@ void export_SpaceGroup() { register_ptr_to_python<boost::shared_ptr<SpaceGroup>>(); class_<SpaceGroup, boost::noncopyable, bases<Group>>("SpaceGroup", no_init) - .def("getNumber", &SpaceGroup::number) - .def("getHMSymbol", &SpaceGroup::hmSymbol) + .def("getNumber", &SpaceGroup::number, arg("self")) + .def("getHMSymbol", &SpaceGroup::hmSymbol, arg("self")) .def("getEquivalentPositions", &getEquivalentPositions, + (arg("self"), arg("point")), "Returns an array with all symmetry equivalents of the supplied " "HKL.") .def("isAllowedReflection", &isAllowedReflection, + (arg("self"), arg("hkl")), "Returns True if the supplied reflection is allowed with respect to " "space group symmetry operations.") - .def("getPointGroup", &SpaceGroup::getPointGroup, + .def("getPointGroup", &SpaceGroup::getPointGroup, arg("self"), "Returns the point group of the space group.") .def("getSiteSymmetryGroup", &getSiteSymmetryGroup, + (arg("self"), arg("position")), "Returns the site symmetry group for supplied point coordinates."); } diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroupFactory.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroupFactory.cpp index 365d6e02a78ba2b35863b83effebb5d24cca5fe1..2b0a5b54e8302334ba9785e5c532f2d6dd51c2b8 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroupFactory.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroupFactory.cpp @@ -45,19 +45,24 @@ void export_SpaceGroupFactory() { class_<SpaceGroupFactoryImpl, boost::noncopyable>("SpaceGroupFactoryImpl", no_init) .def("isSubscribedSymbol", &isSubscribedSymbol, + (arg("self"), arg("symbol")), "Returns true if the space group the supplied symbol is subscribed.") .def("isSubscribedNumber", &isSubscribedNumber, + (arg("self"), arg("number")), "Returns true if a space group with the given number is subscribed.") - .def("createSpaceGroup", &createSpaceGroup, "Creates a space group.") - .def("getAllSpaceGroupSymbols", &allSpaceGroupSymbols, + .def("createSpaceGroup", &createSpaceGroup, (arg("self"), arg("symbol")), + "Creates a space group.") + .def("getAllSpaceGroupSymbols", &allSpaceGroupSymbols, arg("self"), "Returns all subscribed space group symbols.") .def("getAllSpaceGroupNumbers", - &SpaceGroupFactoryImpl::subscribedSpaceGroupNumbers, + &SpaceGroupFactoryImpl::subscribedSpaceGroupNumbers, arg("self"), "Returns all subscribed space group numbers.") .def("subscribedSpaceGroupSymbols", &spaceGroupSymbolsForNumber, + (arg("self"), arg("number")), "Returns all space group symbols that are registered under the " "given number.") - .def("getSpaceGroupsForPointGroup", &spaceGroupSymbolsForPointGroup) + .def("getSpaceGroupsForPointGroup", &spaceGroupSymbolsForPointGroup, + (arg("self"), arg("pointGroup"))) .def("Instance", &SpaceGroupFactory::Instance, return_value_policy<reference_existing_object>(), "Returns a reference to the SpaceGroupFactory singleton") diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryElement.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryElement.cpp index be79196c0fee3a15bbded1fa0030b42437bef456..f520a92edac03e3880ecc318023e2736efbe506f 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryElement.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryElement.cpp @@ -42,12 +42,12 @@ void export_SymmetryElement() { .value("None", SymmetryElementRotation::None); class_<SymmetryElement, boost::noncopyable>("SymmetryElement", no_init) - .def("getHMSymbol", &SymmetryElement::hmSymbol, + .def("getHMSymbol", &SymmetryElement::hmSymbol, arg("self"), "Returns the Hermann-Mauguin symbol for the element.") - .def("getAxis", &getAxis, "Returns the symmetry axis or [0,0,0] for " - "identiy, inversion and translations.") - .def("getRotationSense", &getRotationSense, - "Returns the rotation sense" - "of a rotation axis or None" + .def("getAxis", &getAxis, arg("self"), + "Returns the symmetry axis or [0,0,0] for " + "identiy, inversion and translations.") + .def("getRotationSense", &getRotationSense, arg("self"), + "Returns the rotation sense of a rotation axis or None" "if the element is not a rotation."); } diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryElementFactory.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryElementFactory.cpp index 59db23c9a35c62af611787e2ac2dc1b17e056fde..5804ab01d36d8075314e745c262736fbfa215372 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryElementFactory.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryElementFactory.cpp @@ -9,6 +9,7 @@ void export_SymmetryElementFactory() { class_<SymmetryElementFactoryImpl, boost::noncopyable>( "SymmetryElementFactoryImpl", no_init) .def("createSymElement", &SymmetryElementFactoryImpl::createSymElement, + (arg("self"), arg("operation")), "Creates the symmetry element that corresponds to the supplied " "symmetry operation.") .def("Instance", &SymmetryElementFactory::Instance, diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryOperation.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryOperation.cpp index 180a9153aa917276f8037cf9c0e0d1d8943dd0d7..d20617ea9576b16d6affdb008c4cb89aeb5beb1b 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryOperation.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryOperation.cpp @@ -34,19 +34,21 @@ void export_SymmetryOperation() { register_ptr_to_python<boost::shared_ptr<SymmetryOperation>>(); class_<SymmetryOperation>("SymmetryOperation") - .def("getOrder", &SymmetryOperation::order, + .def("getOrder", &SymmetryOperation::order, arg("self"), "Returns the order of the symmetry operation, which indicates how " "often the operation needs to be applied to a point to arrive at " "identity.") - .def("getIdentifier", &SymmetryOperation::identifier, + .def("getIdentifier", &SymmetryOperation::identifier, arg("self"), "The identifier of the operation in x,y,z-notation.") .def("transformCoordinates", &applyToCoordinates, + (arg("self"), arg("coordinates")), "Returns transformed coordinates. For transforming HKLs, use " "transformHKL.") - .def("transformHKL", &applyToVector, "Returns transformed HKLs. For " - "transformation of coordinates use " - "transformCoordinates.") - .def("apply", &applyToVector, "An alias for transformHKL."); + .def("transformHKL", &applyToVector, (arg("self"), arg("hkl")), + "Returns transformed HKLs. For transformation of coordinates use " + "transformCoordinates.") + .def("apply", &applyToVector, (arg("self"), arg("hkl")), + "An alias for transformHKL."); std_vector_exporter<Mantid::Geometry::SymmetryOperation>::wrap( "std_vector_symmetryoperation"); diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryOperationFactory.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryOperationFactory.cpp index dc78c2bcd5d569943f0c08956a9802974591fb1d..147ff1e85375cdc32b7c96902b8a1d4fb9ab5104 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryOperationFactory.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryOperationFactory.cpp @@ -25,14 +25,16 @@ void export_SymmetryOperationFactory() { class_<SymmetryOperationFactoryImpl, boost::noncopyable>( "SymmetryOperationFactoryImpl", no_init) .def("exists", &SymmetryOperationFactoryImpl::isSubscribed, + (arg("self"), arg("identifier")), "Returns true if the symmetry operation is supplied.") .def("createSymOp", &SymmetryOperationFactoryImpl::createSymOp, + (arg("self"), arg("identifier")), "Creates the symmetry operation from the supplied x,y,z-identifier.") - .def("createSymOps", &createSymOps, + .def("createSymOps", &createSymOps, (arg("self"), arg("identifier")), "Creates a vector of SymmetryOperation objects from a semi-colon " "separated list of x,y,z-identifiers.") .def("subscribedSymbols", - &SymmetryOperationFactoryImpl::subscribedSymbols, + &SymmetryOperationFactoryImpl::subscribedSymbols, arg("self"), "Return all subscribed symbols.") .def("Instance", &SymmetryOperationFactory::Instance, return_value_policy<reference_existing_object>(), diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/UnitCell.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/UnitCell.cpp index 9da36354a38d67012a65986d4586822ff4e7e1a9..326b247bb1c7a501a2711efd64b5728f94ec028a 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/UnitCell.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/UnitCell.cpp @@ -38,103 +38,129 @@ void export_UnitCell() { return_readonly_numpy; class_<UnitCell>("UnitCell", init<>()) - .def(init<UnitCell const &>(arg("other"))) - .def(init<double, double, double>((arg("_a"), arg("_b"), arg("_c")))) + .def(init<UnitCell const &>((arg("self"), arg("other")))) + .def(init<double, double, double>( + (arg("self"), arg("_a"), arg("_b"), arg("_c")))) .def(init<double, double, double, double, double, double, optional<int>>( - (arg("_a"), arg("_b"), arg("_c"), arg("_alpha"), arg("_beta"), - arg("_gamma"), arg("Unit") = (int)(angDegrees)))) - .def("a", (double (UnitCell::*)() const) & UnitCell::a) - .def("a1", (double (UnitCell::*)() const) & UnitCell::a1) - .def("a2", (double (UnitCell::*)() const) & UnitCell::a2) - .def("a3", (double (UnitCell::*)() const) & UnitCell::a3) - .def("alpha", (double (UnitCell::*)() const) & UnitCell::alpha) - .def("alpha1", (double (UnitCell::*)() const) & UnitCell::alpha1) - .def("alpha2", (double (UnitCell::*)() const) & UnitCell::alpha2) - .def("alpha3", (double (UnitCell::*)() const) & UnitCell::alpha3) - .def("alphastar", (double (UnitCell::*)() const) & UnitCell::alphastar) - .def("astar", (double (UnitCell::*)() const) & UnitCell::astar) - .def("b", (double (UnitCell::*)() const) & UnitCell::b) - .def("b1", (double (UnitCell::*)() const) & UnitCell::b1) - .def("b2", (double (UnitCell::*)() const) & UnitCell::b2) - .def("b3", (double (UnitCell::*)() const) & UnitCell::b3) - .def("beta", (double (UnitCell::*)() const) & UnitCell::beta) - .def("beta1", (double (UnitCell::*)() const) & UnitCell::beta1) - .def("beta2", (double (UnitCell::*)() const) & UnitCell::beta2) - .def("beta3", (double (UnitCell::*)() const) & UnitCell::beta3) - .def("betastar", (double (UnitCell::*)() const) & UnitCell::betastar) - .def("bstar", (double (UnitCell::*)() const) & UnitCell::bstar) - .def("c", (double (UnitCell::*)() const) & UnitCell::c) - .def("cstar", (double (UnitCell::*)() const) & UnitCell::cstar) + (arg("self"), arg("_a"), arg("_b"), arg("_c"), arg("_alpha"), + arg("_beta"), arg("_gamma"), arg("Unit") = (int)(angDegrees)))) + .def("a", (double (UnitCell::*)() const) & UnitCell::a, arg("self")) + .def("a1", (double (UnitCell::*)() const) & UnitCell::a1, arg("self")) + .def("a2", (double (UnitCell::*)() const) & UnitCell::a2, arg("self")) + .def("a3", (double (UnitCell::*)() const) & UnitCell::a3, arg("self")) + .def("alpha", (double (UnitCell::*)() const) & UnitCell::alpha, + arg("self")) + .def("alpha1", (double (UnitCell::*)() const) & UnitCell::alpha1, + arg("self")) + .def("alpha2", (double (UnitCell::*)() const) & UnitCell::alpha2, + arg("self")) + .def("alpha3", (double (UnitCell::*)() const) & UnitCell::alpha3, + arg("self")) + .def("alphastar", (double (UnitCell::*)() const) & UnitCell::alphastar, + arg("self")) + .def("astar", (double (UnitCell::*)() const) & UnitCell::astar, + arg("self")) + .def("b", (double (UnitCell::*)() const) & UnitCell::b, arg("self")) + .def("b1", (double (UnitCell::*)() const) & UnitCell::b1, arg("self")) + .def("b2", (double (UnitCell::*)() const) & UnitCell::b2, arg("self")) + .def("b3", (double (UnitCell::*)() const) & UnitCell::b3, arg("self")) + .def("beta", (double (UnitCell::*)() const) & UnitCell::beta, arg("self")) + .def("beta1", (double (UnitCell::*)() const) & UnitCell::beta1, + arg("self")) + .def("beta2", (double (UnitCell::*)() const) & UnitCell::beta2, + arg("self")) + .def("beta3", (double (UnitCell::*)() const) & UnitCell::beta3, + arg("self")) + .def("betastar", (double (UnitCell::*)() const) & UnitCell::betastar, + arg("self")) + .def("bstar", (double (UnitCell::*)() const) & UnitCell::bstar, + arg("self")) + .def("c", (double (UnitCell::*)() const) & UnitCell::c, arg("self")) + .def("cstar", (double (UnitCell::*)() const) & UnitCell::cstar, + arg("self")) .def("d", (double (UnitCell::*)(double, double, double) const) & UnitCell::d, - (arg("h"), arg("k"), arg("l"))) + (arg("self"), arg("h"), arg("k"), arg("l"))) .def("d", (double (UnitCell::*)(const V3D &) const) & UnitCell::d, - (arg("hkl"))) + (arg("self"), arg("hkl"))) .def("dstar", (double (UnitCell::*)(double, double, double) const) & UnitCell::dstar, - (arg("h"), arg("k"), arg("l"))) - .def("errora", (double (UnitCell::*)() const) & UnitCell::errora) - .def("errorb", (double (UnitCell::*)() const) & UnitCell::errorb) - .def("errorc", (double (UnitCell::*)() const) & UnitCell::errorc) + (arg("self"), arg("h"), arg("k"), arg("l"))) + .def("errora", (double (UnitCell::*)() const) & UnitCell::errora, + arg("self")) + .def("errorb", (double (UnitCell::*)() const) & UnitCell::errorb, + arg("self")) + .def("errorc", (double (UnitCell::*)() const) & UnitCell::errorc, + arg("self")) .def("erroralpha", (double (UnitCell::*)(int const) const) & UnitCell::erroralpha, - (arg("Unit") = (int)(angDegrees))) + (arg("self"), arg("Unit") = (int)(angDegrees))) .def("errorbeta", (double (UnitCell::*)(int const) const) & UnitCell::errorbeta, - (arg("Unit") = (int)(angDegrees))) + (arg("self"), arg("Unit") = (int)(angDegrees))) .def("errorgamma", (double (UnitCell::*)(int const) const) & UnitCell::errorgamma, - (arg("Unit") = (int)(angDegrees))) - .def("gamma", (double (UnitCell::*)() const) & UnitCell::gamma) - .def("gammastar", (double (UnitCell::*)() const) & UnitCell::gammastar) + (arg("self"), arg("Unit") = (int)(angDegrees))) + .def("gamma", (double (UnitCell::*)() const) & UnitCell::gamma, + arg("self")) + .def("gammastar", (double (UnitCell::*)() const) & UnitCell::gammastar, + arg("self")) .def("recAngle", (double (UnitCell::*)(double, double, double, double, double, double, int const) const) & UnitCell::recAngle, - (arg("h1"), arg("k1"), arg("l1"), arg("h2"), arg("k2"), arg("l2"), - arg("Unit") = (int)(angDegrees))) - .def("recVolume", (double (UnitCell::*)() const) & UnitCell::recVolume) + (arg("self"), arg("h1"), arg("k1"), arg("l1"), arg("h2"), arg("k2"), + arg("l2"), arg("Unit") = (int)(angDegrees))) + .def("recVolume", (double (UnitCell::*)() const) & UnitCell::recVolume, + arg("self")) .def("set", (void (UnitCell::*)(double, double, double, double, double, double, int const)) & UnitCell::set, - (arg("_a"), arg("_b"), arg("_c"), arg("_alpha"), arg("_beta"), - arg("_gamma"), arg("Unit") = (int)(angDegrees))) - .def("seta", (void (UnitCell::*)(double))(&UnitCell::seta), (arg("_a"))) + (arg("self"), arg("_a"), arg("_b"), arg("_c"), arg("_alpha"), + arg("_beta"), arg("_gamma"), arg("Unit") = (int)(angDegrees))) + .def("seta", (void (UnitCell::*)(double))(&UnitCell::seta), + (arg("self"), arg("_a"))) .def("setalpha", (void (UnitCell::*)(double, int const))(&UnitCell::setalpha), - (arg("_alpha"), arg("Unit") = (int)(angDegrees))) - .def("setb", (void (UnitCell::*)(double))(&UnitCell::setb), (arg("_b"))) + (arg("self"), arg("_alpha"), arg("Unit") = (int)(angDegrees))) + .def("setb", (void (UnitCell::*)(double))(&UnitCell::setb), + (arg("self"), arg("_b"))) .def("setbeta", (void (UnitCell::*)(double, int const))(&UnitCell::setbeta), - (arg("_beta"), arg("Unit") = (int)(angDegrees))) - .def("setc", (void (UnitCell::*)(double))(&UnitCell::setc), (arg("_c"))) + (arg("self"), arg("_beta"), arg("Unit") = (int)(angDegrees))) + .def("setc", (void (UnitCell::*)(double))(&UnitCell::setc), + (arg("self"), arg("_c"))) .def("setgamma", (void (UnitCell::*)(double, int const))(&UnitCell::setgamma), - (arg("_gamma"), arg("Unit") = (int)(angDegrees))) + (arg("self"), arg("_gamma"), arg("Unit") = (int)(angDegrees))) .def("setError", (void (UnitCell::*)(double, double, double, double, double, double, int const)) & UnitCell::setError, - (arg("_aerr"), arg("_berr"), arg("_cerr"), arg("_alphaerr"), - arg("_betaerr"), arg("_gammaerr"), arg("Unit") = (int)(angDegrees))) + (arg("self"), arg("_aerr"), arg("_berr"), arg("_cerr"), + arg("_alphaerr"), arg("_betaerr"), arg("_gammaerr"), + arg("Unit") = (int)(angDegrees))) .def("setErrora", (void (UnitCell::*)(double))(&UnitCell::setErrora), - (arg("_aerr"))) + (arg("self"), arg("_aerr"))) .def("setErroralpha", (void (UnitCell::*)(double, int const))(&UnitCell::setErroralpha), - (arg("_alphaerr"), arg("Unit") = (int)(angDegrees))) + (arg("self"), arg("_alphaerr"), arg("Unit") = (int)(angDegrees))) .def("setErrorb", (void (UnitCell::*)(double))(&UnitCell::setErrorb), - (arg("_berr"))) + (arg("self"), arg("_berr"))) .def("setErrorbeta", (void (UnitCell::*)(double, int const))(&UnitCell::setErrorbeta), - (arg("_betaerr"), arg("Unit") = (int)(angDegrees))) + (arg("self"), arg("_betaerr"), arg("Unit") = (int)(angDegrees))) .def("setErrorc", (void (UnitCell::*)(double))(&UnitCell::setErrorc), - (arg("_cerr"))) + (arg("self"), arg("_cerr"))) .def("setErrorgamma", (void (UnitCell::*)(double, int const))(&UnitCell::setErrorgamma), - (arg("_gammaerr"), arg("Unit") = (int)(angDegrees))) - .def("volume", (double (UnitCell::*)() const) & UnitCell::volume) - .def("getG", &UnitCell::getG, return_readonly_numpy()) - .def("getGstar", &UnitCell::getGstar, return_readonly_numpy()) - .def("getB", &UnitCell::getB, return_readonly_numpy()) - .def("recalculateFromGstar", &recalculateFromGstar); + (arg("self"), arg("_gammaerr"), arg("Unit") = (int)(angDegrees))) + .def("volume", (double (UnitCell::*)() const) & UnitCell::volume, + arg("self")) + .def("getG", &UnitCell::getG, arg("self"), return_readonly_numpy()) + .def("getGstar", &UnitCell::getGstar, arg("self"), + return_readonly_numpy()) + .def("getB", &UnitCell::getB, arg("self"), return_readonly_numpy()) + .def("recalculateFromGstar", &recalculateFromGstar, + (arg("self"), arg("NewGstar"))); scope().attr("deg2rad") = Mantid::Geometry::deg2rad; scope().attr("rad2deg") = Mantid::Geometry::rad2deg; diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigService.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigService.cpp index 61163771c9d2d3e88a73a25de32ab62e32c6cecb..22a6c099010b426e969319b0d978d85180b45722 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigService.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigService.cpp @@ -28,11 +28,20 @@ std::string getStringUsingCache(ConfigServiceImpl &self, return self.getString(key, true); } +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wunused-local-typedef" +#endif + /// Overload generator for getInstrument BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(getInstrument_Overload, getInstrument, 0, 1) /// Overload generator for getString BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(getString_Overload, getString, 1, 2) +#ifdef __clang__ +#pragma clang diagnostic pop +#endif } void export_ConfigService() { diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/Statistics.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/Statistics.cpp index 3cfaf72e9ec1d44d7e3816714d8a8d30c5f98de4..d2f9494ae0059a2f4839abd506fcf8da627f4c0c 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Exports/Statistics.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/Statistics.cpp @@ -93,10 +93,18 @@ Statistics getStatisticsNumpy(const numeric::array &data, throw UnknownDataType(); } } + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wunused-local-typedef" +#endif // Define an overload to handle the default argument BOOST_PYTHON_FUNCTION_OVERLOADS(getStatisticsOverloads, getStatisticsNumpy, 1, 2) - +#ifdef __clang__ +#pragma clang diagnostic pop +#endif //============================ Z score //============================================ @@ -145,9 +153,17 @@ std::vector<double> getModifiedZscoreNumpy(const numeric::array &data, } } +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wunused-local-typedef" +#endif // Define an overload to handle the default argument BOOST_PYTHON_FUNCTION_OVERLOADS(getModifiedZscoreOverloads, getModifiedZscoreNumpy, 1, 2) +#ifdef __clang__ +#pragma clang diagnostic pop +#endif //============================ getMoments //============================================ @@ -198,10 +214,17 @@ std::vector<double> getMomentsAboutOriginNumpy(const numeric::array &indep, return getMomentsNumpyImpl(&getMomentsAboutOrigin, indep, depend, maxMoment); } +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wunused-local-typedef" +#endif // Define an overload to handle the default argument BOOST_PYTHON_FUNCTION_OVERLOADS(getMomentsAboutOriginOverloads, getMomentsAboutOriginNumpy, 2, 3) - +#ifdef __clang__ +#pragma clang diagnostic pop +#endif /** * Proxy for @see Mantid::Kernel::getMomentsAboutMean so that it can accept * numpy arrays @@ -213,9 +236,18 @@ std::vector<double> getMomentsAboutMeanNumpy(const numeric::array &indep, return getMomentsNumpyImpl(&getMomentsAboutMean, indep, depend, maxMoment); } +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wunused-local-typedef" +#endif // Define an overload to handle the default argument BOOST_PYTHON_FUNCTION_OVERLOADS(getMomentsAboutMeanOverloads, getMomentsAboutMeanNumpy, 2, 3) +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + ///@endcond } diff --git a/Framework/PythonInterface/plugins/algorithms/ComputeCalibrationCoefVan.py b/Framework/PythonInterface/plugins/algorithms/ComputeCalibrationCoefVan.py new file mode 100644 index 0000000000000000000000000000000000000000..a6964b3768e7acd5a4056f52cbfb721c8c95ef06 --- /dev/null +++ b/Framework/PythonInterface/plugins/algorithms/ComputeCalibrationCoefVan.py @@ -0,0 +1,168 @@ +from mantid.api import PythonAlgorithm, AlgorithmFactory, MatrixWorkspaceProperty, Progress, InstrumentValidator +from mantid.kernel import Direction +import numpy as np +from scipy import integrate +import scipy as sp +import mlzutils + + +class ComputeCalibrationCoefVan(PythonAlgorithm): + """ Calculate coefficients to normalize by Vanadium and correct Debye Waller factor + """ + def __init__(self): + """ + Init + """ + PythonAlgorithm.__init__(self) + self.vanaws = None + self.defaultT = 293.0 # K, default temperature if not given + self.Mvan = 50.942 # [g/mol], Vanadium molar mass + self.DebyeT = 389.0 # K, Debye temperature for Vanadium + + def category(self): + """ Return category + """ + return "PythonAlgorithms;CorrectionFunctions\\EfficiencyCorrections" + + def name(self): + """ Return summary + """ + return "ComputeCalibrationCoefVan" + + def summary(self): + return "Calculate coefficients for detector efficiency correction using the Vanadium data." + + def PyInit(self): + """ Declare properties + """ + self.declareProperty(MatrixWorkspaceProperty("VanadiumWorkspace", "", direction=Direction.Input, + validator=InstrumentValidator()), + "Input Vanadium workspace") + self.declareProperty(MatrixWorkspaceProperty("OutputWorkspace", "", direction=Direction.Output), + "Name the workspace that will contain the calibration coefficients") + return + + def validateInputs(self): + issues = dict() + inws = self.getProperty("VanadiumWorkspace").value + run = inws.getRun() + + if not run.hasProperty('wavelength'): + issues['VanadiumWorkspace'] = "Input workspace must have wavelength sample log." + else: + try: + float(run.getProperty('wavelength').value) + except ValueError: + issues['VanadiumWorkspace'] = "Invalid value for wavelength sample log. Wavelength must be a number." + + return issues + + def get_temperature(self): + """ + tries to get temperature from the sample logs + in the case of fail, default value is returned + """ + run = self.vanaws.getRun() + if not run.hasProperty('temperature'): + self.log().warning("Temperature sample log is not present in " + self.vanaws.getName() + + " T=293K is assumed for Debye-Waller factor.") + return self.defaultT + try: + temperature = float(run.getProperty('temperature').value) + except ValueError, err: + self.log().warning("Error of getting temperature: " + err + + " T=293K is assumed for Debye-Waller factor.") + return self.defaultT + + return temperature + + def PyExec(self): + """ Main execution body + """ + self.vanaws = self.getProperty("VanadiumWorkspace").value # returns workspace instance + outws_name = self.getPropertyValue("OutputWorkspace") # returns workspace name (string) + nhist = self.vanaws.getNumberHistograms() + prog_reporter = Progress(self, start=0.0, end=1.0, nreports=nhist+1) + + # calculate array of Debye-Waller factors + dwf = self.calculate_dwf() + + # for each detector: fit gaussian to get peak_centre and fwhm + # sum data in the range [peak_centre - 3*fwhm, peak_centre + 3*fwhm] + dataX = self.vanaws.readX(0) + coefY = np.zeros(nhist) + coefE = np.zeros(nhist) + instrument = self.vanaws.getInstrument() + detID_offset = self.get_detID_offset() + for idx in range(nhist): + prog_reporter.report("Setting %dth spectrum" % idx) + dataY = self.vanaws.readY(idx) + det = instrument.getDetector(idx + detID_offset) + if np.max(dataY) == 0 or det.isMasked(): + coefY[idx] = 0. + coefE[idx] = 0. + else: + dataE = self.vanaws.readE(idx) + peak_centre, sigma = mlzutils.do_fit_gaussian(self.vanaws, idx, self.log()) + fwhm = sigma*2.*np.sqrt(2.*np.log(2.)) + idxmin = (np.fabs(dataX-peak_centre+3.*fwhm)).argmin() + idxmax = (np.fabs(dataX-peak_centre-3.*fwhm)).argmin() + coefY[idx] = dwf[idx]*sum(dataY[idxmin:idxmax+1]) + coefE[idx] = dwf[idx]*sum(dataE[idxmin:idxmax+1]) + + # create X array, X data are the same for all detectors, so + coefX = np.zeros(nhist) + coefX.fill(dataX[0]) + + create = self.createChildAlgorithm("CreateWorkspace") + create.setPropertyValue('OutputWorkspace', outws_name) + create.setProperty('ParentWorkspace', self.vanaws) + create.setProperty('DataX', coefX) + create.setProperty('DataY', coefY) + create.setProperty('DataE', coefE) + create.setProperty('NSpec', nhist) + create.setProperty('UnitX', 'TOF') + create.execute() + outws = create.getProperty('OutputWorkspace').value + + self.setProperty("OutputWorkspace", outws) + + def get_detID_offset(self): + """ + returns ID of the first detector + """ + return self.vanaws.getSpectrum(0).getDetectorIDs()[0] + + def calculate_dwf(self): + """ + Calculates Debye-Waller factor according to + Sears and Shelley Acta Cryst. A 47, 441 (1991) + """ + run = self.vanaws.getRun() + nhist = self.vanaws.getNumberHistograms() + thetasort = np.zeros(nhist) # theta in radians, not 2Theta + + instrument = self.vanaws.getInstrument() + detID_offset = self.get_detID_offset() + + for i in range(nhist): + det = instrument.getDetector(i + detID_offset) + thetasort[i] = 0.5*np.sign(np.cos(det.getPhi()))*self.vanaws.detectorTwoTheta(det) + # thetasort[i] = 0.5*self.vanaws.detectorSignedTwoTheta(det) # gives opposite sign for detectors 0-24 + + temperature = self.get_temperature() # T in K + wlength = float(run.getLogData('wavelength').value) # Wavelength, Angstrom + mass_vana = 0.001*self.Mvan/sp.constants.N_A # Vanadium mass, kg + temp_ratio = temperature/self.DebyeT + + if temp_ratio < 1.e-3: + integral = 0.5 + else: + integral = integrate.quad(lambda x: x/sp.tanh(0.5*x/temp_ratio), 0, 1)[0] + + msd = 3.*sp.constants.hbar**2/(2.*mass_vana*sp.constants.k * self.DebyeT)*integral*1.e20 + return np.exp(-msd*(4.*sp.pi*sp.sin(thetasort)/wlength)**2) + + +# Register algorithm with Mantid. +AlgorithmFactory.subscribe(ComputeCalibrationCoefVan) diff --git a/Framework/PythonInterface/plugins/algorithms/LoadVesuvio.py b/Framework/PythonInterface/plugins/algorithms/LoadVesuvio.py index e587a1bfdef0c883ffd6d29d8e7955c34d6b0dfe..477cf69705777a9ce74bfb877129a6023557327e 100644 --- a/Framework/PythonInterface/plugins/algorithms/LoadVesuvio.py +++ b/Framework/PythonInterface/plugins/algorithms/LoadVesuvio.py @@ -132,6 +132,20 @@ class LoadVesuvio(LoadEmptyVesuvio): else: self._exec_single_foil_state_mode() +#---------------------------------------------------------------------------------------- + + def validateInputs(self): + issues = {} + + # Validtae run number ranges + run_str = self.getProperty(RUN_PROP).value + if "-" in run_str: + lower, upper = run_str.split("-") + if upper < lower: + issues[RUN_PROP] = "Range must be in format lower-upper" + + return issues + #---------------------------------------------------------------------------------------- def _exec_difference_mode(self): @@ -346,24 +360,42 @@ class LoadVesuvio(LoadEmptyVesuvio): if index == 0: out_name, out_mon = SUMMED_WS, SUMMED_MON else: - out_name, out_mon = SUMMED_WS+'tmp', SUMMED_MON + 'tmp' + out_name, out_mon = SUMMED_WS + 'tmp', SUMMED_MON + 'tmp' + # Load data - ms.LoadRaw(Filename=run, SpectrumList=spectra, - OutputWorkspace=out_name, LoadMonitors='Exclude',EnableLogging=_LOGGING_) - ms.LoadRaw(Filename=run,SpectrumList=self._mon_spectra, - OutputWorkspace=out_mon,EnableLogging=_LOGGING_) - if index > 0: # sum - ms.Plus(LHSWorkspace=SUMMED_WS, RHSWorkspace=out_name, - OutputWorkspace=SUMMED_WS,EnableLogging=_LOGGING_) - ms.Plus(LHSWorkspace=SUMMED_MON, RHSWorkspace=out_mon, - OutputWorkspace=SUMMED_MON,EnableLogging=_LOGGING_) - ms.DeleteWorkspace(out_name,EnableLogging=_LOGGING_) - ms.DeleteWorkspace(out_mon,EnableLogging=_LOGGING_) - - ms.CropWorkspace(Inputworkspace= SUMMED_WS, OutputWorkspace= SUMMED_WS, - XMax=self._tof_max,EnableLogging=_LOGGING_) - ms.CropWorkspace(Inputworkspace= SUMMED_MON, OutputWorkspace= SUMMED_MON, - XMax=self._mon_tof_max, EnableLogging=_LOGGING_) + ms.LoadRaw(Filename=run, + SpectrumList=spectra, + OutputWorkspace=out_name, + LoadMonitors='Exclude', + EnableLogging=_LOGGING_) + ms.LoadRaw(Filename=run, + SpectrumList=self._mon_spectra, + OutputWorkspace=out_mon, + EnableLogging=_LOGGING_) + + # Sum + if index > 0: + ms.Plus(LHSWorkspace=SUMMED_WS, + RHSWorkspace=out_name, + OutputWorkspace=SUMMED_WS, + EnableLogging=_LOGGING_) + ms.Plus(LHSWorkspace=SUMMED_MON, + RHSWorkspace=out_mon, + OutputWorkspace=SUMMED_MON, + EnableLogging=_LOGGING_) + + ms.DeleteWorkspace(out_name, EnableLogging=_LOGGING_) + ms.DeleteWorkspace(out_mon, EnableLogging=_LOGGING_) + + ms.CropWorkspace(Inputworkspace= SUMMED_WS, + OutputWorkspace=SUMMED_WS, + XMax=self._tof_max, + EnableLogging=_LOGGING_) + ms.CropWorkspace(Inputworkspace= SUMMED_MON, + OutputWorkspace=SUMMED_MON, + XMax=self._mon_tof_max, + EnableLogging=_LOGGING_) + return mtd[SUMMED_WS], mtd[SUMMED_MON] #---------------------------------------------------------------------------------------- @@ -375,9 +407,9 @@ class LoadVesuvio(LoadEmptyVesuvio): run_str = self.getProperty(RUN_PROP).value # Load is not doing the right thing when summing. The numbers don't look correct if "-" in run_str: - lower,upper = run_str.split("-") + lower, upper = run_str.split("-") # Range goes lower to up-1 but we want to include the last number - runs = range(int(lower),int(upper)+1) + runs = range(int(lower), int(upper)+1) elif "," in run_str: runs = run_str.split(",") diff --git a/Framework/PythonInterface/plugins/algorithms/PDToPDFgetN.py b/Framework/PythonInterface/plugins/algorithms/PDToPDFgetN.py new file mode 100644 index 0000000000000000000000000000000000000000..db6819bf1d05cb23dc7ed144a29799ca64e6b257 --- /dev/null +++ b/Framework/PythonInterface/plugins/algorithms/PDToPDFgetN.py @@ -0,0 +1,143 @@ +#pylint: disable=no-init +from mantid.simpleapi import * +from mantid.api import * +from mantid.kernel import Direction, FloatArrayProperty +import mantid + +COMPRESS_TOL_TOF = .01 + + +class PDToPDFgetN(DataProcessorAlgorithm): + _focusPos = {} + _iparmFile = None + + def category(self): + return "Workflow\\Diffraction;PythonAlgorithms" + + def name(self): + return "PDToPDFgetN" + + def summary(self): + return "The algorithm used converting raw data to pdfgetn input files" + + def PyInit(self): + group = "Input" + self.declareProperty(FileProperty(name="Filename", + defaultValue="", action=FileAction.Load, + extensions=["_event.nxs", ".nxs.h5"]), + "Event file") + self.declareProperty("MaxChunkSize", 0.0, + "Specify maximum Gbytes of file to read in one chunk. Default is whole file.") + self.declareProperty("FilterBadPulses", 95., + doc="Filter out events measured while proton " + + "charge is more than 5% below average") + + self.declareProperty(MatrixWorkspaceProperty("InputWorkspace", "", + direction=Direction.Input, + optional=PropertyMode.Optional), + doc="Handle to reduced workspace") + self.setPropertyGroup("Filename", group) + self.setPropertyGroup("MaxChunkSize", group) + self.setPropertyGroup("FilterBadPulses", group) + self.setPropertyGroup("InputWorkspace", group) + + group = "Output" + self.declareProperty(MatrixWorkspaceProperty("OutputWorkspace", "", + direction=Direction.Output), + doc="Handle to reduced workspace") + self.declareProperty(FileProperty(name="PDFgetNFile", defaultValue="", action=FileAction.Save, + extensions=[".getn"]), "Output filename") + self.setPropertyGroup("OutputWorkspace", group) + self.setPropertyGroup("PDFgetNFile", group) + + self.declareProperty(FileProperty(name="CalibrationFile", + defaultValue="", action=FileAction.OptionalLoad, + extensions=[".h5", ".hd5", ".hdf", ".cal"])) + self.declareProperty(FileProperty(name="CharacterizationRunsFile", defaultValue="", + action=FileAction.OptionalLoad, + extensions=["txt"]), + "File with characterization runs denoted") + + self.declareProperty("RemovePromptPulseWidth", 0.0, + "Width of events (in microseconds) near the prompt pulse to remove. 0 disables") + self.declareProperty("CropWavelengthMin", 0., + "Crop the data at this minimum wavelength.") + self.declareProperty("CropWavelengthMax", 0., + "Crop the data at this maximum wavelength.") + + self.declareProperty(FloatArrayProperty("Binning", values=[0., 0., 0.], + direction=Direction.Input), "Positive is linear bins, negative is logorithmic") + self.declareProperty("ResampleX", 0, + "Number of bins in x-axis. Non-zero value overrides \"Params\" property. " + + "Negative value means logorithmic binning.") + + def _loadCharacterizations(self): + self._focusPos = {} + self._iparmFile = None + + charFilename = self.getProperty("CharacterizationRunsFile").value + + if charFilename is None or len(charFilename) <= 0: + return + + results = PDLoadCharacterizations(Filename=charFilename, + OutputWorkspace="characterizations") + self._iparmFile = results[1] + self._focusPos['PrimaryFlightPath'] = results[2] + self._focusPos['SpectrumIDs'] = results[3] + self._focusPos['L2'] = results[4] + self._focusPos['Polar'] = results[5] + self._focusPos['Azimuthal'] = results[6] + + def PyExec(self): + self._loadCharacterizations() + + wksp = self.getProperty("InputWorkspace").value + if wksp is None: + wksp = LoadEventAndCompress(Filename=self.getProperty("Filename").value, + OutputWorkspace=self.getPropertyValue("OutputWorkspace"), + MaxChunkSize=self.getProperty("MaxChunkSize").value, + FilterBadPulses=self.getProperty("FilterBadPulses").value, + CompressTOFTolerance=COMPRESS_TOL_TOF) + else: + self.log().information("Using input workspace. Ignoring properties 'Filename', " + + "'OutputWorkspace', 'MaxChunkSize', and 'FilterBadPulses'") + + charac = "" + if mtd.doesExist("characterizations"): + charac = "characterizations" + + # get the correct row of the table + PDDetermineCharacterizations(InputWorkspace=wksp, + Characterizations=charac, + ReductionProperties="__snspowderreduction") + + wksp = AlignAndFocusPowder(InputWorkspace=wksp, OutputWorkspace=wksp, + CalFileName=self.getProperty("CalibrationFile").value, + Params=self.getProperty("Binning").value, + ResampleX=self.getProperty("ResampleX").value, Dspacing=True, + PreserveEvents=False, + RemovePromptPulseWidth=self.getProperty("RemovePromptPulseWidth").value, + CompressTolerance=COMPRESS_TOL_TOF, + CropWavelengthMin=self.getProperty("CropWavelengthMin").value, + CropWavelengthMax=self.getProperty("CropWavelengthMax").value, + ReductionProperties="__snspowderreduction", + **(self._focusPos)) + wksp = NormaliseByCurrent(InputWorkspace=wksp, OutputWorkspace=wksp) + wksp.getRun()['gsas_monitor'] = 1 + if self._iparmFile is not None: + wksp.getRun()['iparm_file'] = self._iparmFile + + wksp = SetUncertainties(InputWorkspace=wksp, OutputWorkspace=wksp, + SetError="sqrt") + SaveGSS(InputWorkspace=wksp, + Filename=self.getProperty("PDFgetNFile").value, + SplitFiles=False, Append=False, + MultiplyByBinWidth=False, + Bank=mantid.pmds["__snspowderreduction"]["bank"].value, + Format="SLOG", ExtendedHeader=True) + + self.setProperty("OutputWorkspace", wksp) + +# Register algorithm with Mantid. +AlgorithmFactory.subscribe(PDToPDFgetN) diff --git a/Framework/PythonInterface/plugins/algorithms/SavePlot1DAsJson.py b/Framework/PythonInterface/plugins/algorithms/SavePlot1DAsJson.py index f52fad8cdc115c57000329048628b138798af648..7bc6cc433707c03185ec1ec1402151f124a6de45 100644 --- a/Framework/PythonInterface/plugins/algorithms/SavePlot1DAsJson.py +++ b/Framework/PythonInterface/plugins/algorithms/SavePlot1DAsJson.py @@ -1,4 +1,4 @@ -#pylint: disable=no-init,unused-variable +#pylint: disable=no-init,unused-variable,invalid-name,bare-except from mantid.api import * from mantid.kernel import * @@ -76,30 +76,47 @@ class SavePlot1DAsJson(PythonAlgorithm): return def _serialize(self, workspace, plotname): - wname = plotname or workspace.getName() + pname = plotname or workspace.getName() # init dictionary ishist = workspace.isHistogramData() plottype = "histogram" if ishist else "point" - serialized = {"type": plottype} - # helper - label = lambda axis: "%s (%s)" % ( - axis.getUnit().caption(), - axis.getUnit().symbol() or 1, + serialized = dict( + type = plottype, + data = dict(), ) # loop over spectra for i in range(workspace.getNumberHistograms()): - k = "%s%s" % (wname, i) - value = dict( - x=list(workspace.readX(i)), - y=list(workspace.readY(i)), - e=list(workspace.readE(i)), - xlabel=label(workspace.getAxis(0)), - ylabel=label(workspace.getAxis(1)), - title="long title of %s" % k, - ) - serialized[k] = value + spectrum_no = workspace.getSpectrum(i).getSpectrumNo() + # Why do we need label? + # label = "%s_spectrum_%d" % (pname, spectrum_no) + # labels.append(label) + # or title? + # title = "%s - spectrum %d" % (workspace.getTitle(), spectrum_no) + arr = [ + list(workspace.readX(i)), + list(workspace.readY(i)), + list(workspace.readE(i)), + ] + serialized['data'][spectrum_no] = arr continue - return serialized + # axes + # .. helper + label = lambda axis: axis.getUnit().caption() + def unit(axis): + s = axis.getUnit().symbol() + try: + return s.latex() + except: + return '%s' % s + axes = dict( + xlabel=label(workspace.getAxis(0)), + ylabel=label(workspace.getAxis(1)), + xunit = unit(workspace.getAxis(0)), + # yunit = unit(workspace.getAxis(1)), + yunit = workspace.YUnitLabel(), + ) + serialized['axes'] = axes + return {pname: serialized} # Register algorithm with Mantid diff --git a/Framework/PythonInterface/plugins/algorithms/TOFTOFCropWorkspace.py b/Framework/PythonInterface/plugins/algorithms/TOFTOFCropWorkspace.py new file mode 100644 index 0000000000000000000000000000000000000000..c7c6f387adb444ff9c0b0ded8ac87c33c0f3bd99 --- /dev/null +++ b/Framework/PythonInterface/plugins/algorithms/TOFTOFCropWorkspace.py @@ -0,0 +1,70 @@ +from mantid.api import PythonAlgorithm, AlgorithmFactory, WorkspaceProperty # , WorkspaceUnitValidator +from mantid.kernel import Direction +import mantid.simpleapi as api + + +class TOFTOFCropWorkspace(PythonAlgorithm): + """ Crop empty time channels + """ + def __init__(self): + PythonAlgorithm.__init__(self) + + def category(self): + """ Return category + """ + return "PythonAlgorithms\\MLZ\\TOFTOF;Utility" + + def name(self): + """ Return summary + """ + return "TOFTOFCropWorkspace" + + def summary(self): + return "Crop empty time channels." + + def PyInit(self): + """ Declare properties + """ + # better would be to use the validator, but it fails if WorkspaceGroup is given as an input + # self.declareProperty(WorkspaceProperty("InputWorkspace", "", direction=Direction.Input, + # validator=WorkspaceUnitValidator('TOF')), + # doc="Input workspace.") + self.declareProperty(WorkspaceProperty("InputWorkspace", "", direction=Direction.Input), + doc="Input workspace.") + self.declareProperty(WorkspaceProperty("OutputWorkspace", "", direction=Direction.Output), + doc="Name of the workspace that will contain the results") + return + + def validateInputs(self): + issues = dict() + input_workspace = self.getProperty("InputWorkspace").value + + xunit = input_workspace.getAxis(0).getUnit().unitID() + if xunit != 'TOF': + issues['InputWorkspace'] = "X axis units must be TOF. " + + # check for required properties + run = input_workspace.getRun() + if not run.hasProperty('channel_width'): + issues['InputWorkspace'] = "Input workpsace must have sample log channel_width." + if not run.hasProperty('full_channels'): + issues['InputWorkspace'] = "Input workpsace must have sample log full_channels." + + return issues + + def PyExec(self): + """ Main execution body + """ + inputws = self.getProperty("InputWorkspace").value + outputws = self.getProperty("OutputWorkspace").value + + run = inputws.getRun() + channel_width = float(run.getLogData('channel_width').value) + full_channels = float(run.getLogData('full_channels').value) + + outputws = api.CropWorkspace(inputws, XMin=0., XMax=full_channels*channel_width, OutputWorkspace=outputws) + self.setProperty("OutputWorkspace", outputws) + + +# Register algorithm with Mantid. +AlgorithmFactory.subscribe(TOFTOFCropWorkspace) diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DetectorFloodWeighting.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DetectorFloodWeighting.py index c929a3c23b3afe00c1ed0770e6b38ef0424e4a96..32bb98f27c6a938069e1ccb3c01af95a91ac9472 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DetectorFloodWeighting.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DetectorFloodWeighting.py @@ -1,5 +1,5 @@ from mantid.api import DataProcessorAlgorithm, AlgorithmFactory, MatrixWorkspaceProperty, WorkspaceUnitValidator, \ - Progress +PropertyMode, Progress from mantid.kernel import Direction, FloatArrayProperty, FloatArrayBoundedValidator @@ -22,7 +22,11 @@ class DetectorFloodWeighting(DataProcessorAlgorithm): self.declareProperty(MatrixWorkspaceProperty('InputWorkspace', '', direction=Direction.Input, validator=WorkspaceUnitValidator("Wavelength")), - doc='Flood weighting measurement') + doc='Flood weighting measurement') + self.declareProperty(MatrixWorkspaceProperty('TransmissionWorkspace', '', + direction=Direction.Input, optional=PropertyMode.Optional, + validator=WorkspaceUnitValidator("Wavelength")), + doc='Flood weighting measurement') validator = FloatArrayBoundedValidator() validator.setLower(0.) @@ -52,9 +56,6 @@ class DetectorFloodWeighting(DataProcessorAlgorithm): issues['Bands'] = 'Even number of Bands boundaries expected' return issues # Abort early. Do not continue - if len(bands) > 2: - issues['Bands'] = 'Presently this algorithm only supports one pair of bands' - all_limits=list() for i in range(0, len(bands), 2): lower = bands[i] @@ -69,6 +70,13 @@ class DetectorFloodWeighting(DataProcessorAlgorithm): all_limits.append(limits) if lower >= upper: issues['Bands'] = 'Bands should form lower, upper pairs' + input_ws = self.getProperty('InputWorkspace').value + trans_ws = self.getProperty('TransmissionWorkspace').value + if trans_ws: + if not trans_ws.getNumberHistograms() == input_ws.getNumberHistograms(): + issues['TransmissionWorkspace'] = 'Transmission should have same number of histograms as flood input workspace' + if not trans_ws.blocksize() == input_ws.blocksize(): + issues['TransmissionWorkspace'] = 'Transmission workspace should be rebinned the same as the flood input workspace' return issues @@ -79,53 +87,73 @@ class DetectorFloodWeighting(DataProcessorAlgorithm): divide.execute() return divide.getProperty("OutputWorkspace").value + def _add(self, lhs, rhs): + divide = self.createChildAlgorithm("Plus") + divide.setProperty("LHSWorkspace", lhs) + divide.setProperty("RHSWorkspace", rhs) + divide.execute() + return divide.getProperty("OutputWorkspace").value - def PyExec(self): - - progress = Progress(self, 0, 1, 4) # Four coarse steps - - in_ws = self.getProperty('InputWorkspace').value - bands = self.getProperty('Bands').value - - # Formulate bands - params = list() + def _integrate_bands(self, bands, in_ws): + # Formulate bands, integrate and sum + accumulated_output = None for i in range(0, len(bands), 2): lower = bands[i] upper = bands[i+1] step = upper - lower - params.append((lower, step, upper)) - progress.report() + rebin = self.createChildAlgorithm("Rebin") + rebin.setProperty("Params", [lower, step, upper]) + rebin.setProperty("InputWorkspace", in_ws) # Always integrating the same input workspace + rebin.execute() + integrated = rebin.getProperty("OutputWorkspace").value + if accumulated_output: + accumulated_output = self._add(accumulated_output, integrated) + else: + # First band + accumulated_output = integrated + return accumulated_output - accumulated_output = None - rebin = self.createChildAlgorithm("Rebin") - rebin.setProperty("Params", params[0]) - rebin.setProperty("InputWorkspace", in_ws) - rebin.execute() - accumulated_output = rebin.getProperty("OutputWorkspace").value - progress.report() - # Determine the max across all spectra - y_values = accumulated_output.extractY() - max_val = np.amax(y_values) + def PyExec(self): - # Create a workspace from the single max value - create = self.createChildAlgorithm("CreateSingleValuedWorkspace") - create.setProperty("DataValue", max_val) - create.execute() - max_ws = create.getProperty("OutputWorkspace").value + progress = Progress(self, 0, 1, 4) # Four coarse steps - # Divide each entry by max - normalized = self._divide(accumulated_output, max_ws) + in_ws = self.getProperty('InputWorkspace').value + trans_ws = self.getProperty('TransmissionWorkspace').value + bands = self.getProperty('Bands').value + + accumulated_output = self._integrate_bands(bands, in_ws) + if trans_ws: + accumulated_trans_output = self._integrate_bands(bands, trans_ws) progress.report() # Perform solid angle correction. Calculate solid angle then divide through. + normalized=accumulated_output if self.getProperty("SolidAngleCorrection").value: solidAngle = self.createChildAlgorithm("SolidAngle") - solidAngle.setProperty("InputWorkspace", normalized) + solidAngle.setProperty("InputWorkspace", accumulated_output) solidAngle.execute() solid_angle_weighting = solidAngle.getProperty("OutputWorkspace").value normalized = self._divide(normalized, solid_angle_weighting) progress.report() + # Divide through by the transmission workspace provided + if trans_ws: + normalized = self._divide(normalized, accumulated_trans_output) + # Determine the max across all spectra + y_values = normalized.extractY() + mean_val = np.mean(y_values) + # Create a workspace from the single max value + create = self.createChildAlgorithm("CreateSingleValuedWorkspace") + create.setProperty("DataValue", mean_val) + create.execute() + mean_ws = create.getProperty("OutputWorkspace").value + # Divide each entry by mean + normalized = self._divide(normalized, mean_ws) + progress.report() + # Fix-up ranges + for i in range(normalized.getNumberHistograms()): + normalized.dataX(i)[0] = bands[0] + normalized.dataX(i)[1] = bands[-1] self.setProperty('OutputWorkspace', normalized) diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/EVSDiffractionReduction.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/EVSDiffractionReduction.py new file mode 100644 index 0000000000000000000000000000000000000000..69a0a5485cf1d5ce2e9d537260f2e60f09e913d5 --- /dev/null +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/EVSDiffractionReduction.py @@ -0,0 +1,209 @@ +#pylint: disable=no-init +from mantid.simpleapi import * +from mantid.api import * +from mantid.kernel import * +from mantid import config + +import os + +class EVSDiffractionReduction(DataProcessorAlgorithm): + + _workspace_names = None + _chopped_data = None + _output_ws = None + _data_files = None + _instrument_name = None + _mode = None + _par_filename = None + _spectra_range = None + _grouping_method = None + _rebin_string = None + _ipf_filename = None + _sum_files = None + + + def category(self): + return 'Diffraction;PythonAlgorithms' + + + def summary(self): + return 'Performs diffraction reduction for VESUVIO' + + + def PyInit(self): + self.declareProperty(StringArrayProperty('InputFiles'), + doc='Comma separated list of input files.') + + self.declareProperty(FileProperty('InstrumentParFile', '', + action=FileAction.Load, + extensions=['.dat', '.par']), + doc='PAR file containing instrument definition.') + + self.declareProperty(name='SumFiles', defaultValue=False, + doc='Enabled to sum spectra from each input file.') + + self.declareProperty(IntArrayProperty('SpectraRange', [3, 198]), + doc='Range of spectra to use.') + + self.declareProperty(name='RebinParam', defaultValue='', + doc='Rebin parameters.') + + self.declareProperty(name='GroupingPolicy', defaultValue='All', + validator=StringListValidator(['All', 'Individual', 'IPF']), + doc='Selects the type of detector grouping to be used.') + + self.declareProperty(WorkspaceGroupProperty('OutputWorkspace', '', + direction=Direction.Output), + doc='Group name for the result workspaces.') + + + def validateInputs(self): + """ + Checks for issues with user input. + """ + issues = dict() + + # Validate input files + input_files = self.getProperty('InputFiles').value + if len(input_files) == 0: + issues['InputFiles'] = 'InputFiles must contain at least one filename' + + # Validate detector range + detector_range = self.getProperty('SpectraRange').value + if len(detector_range) != 2: + issues['SpectraRange'] = 'SpectraRange must be an array of 2 values only' + else: + if detector_range[0] > detector_range[1]: + issues['SpectraRange'] = 'SpectraRange must be in format [lower_index,upper_index]' + + return issues + + + def PyExec(self): + from IndirectReductionCommon import (load_files, + get_multi_frame_rebin, + identify_bad_detectors, + unwrap_monitor, + process_monitor_efficiency, + scale_monitor, + scale_detectors, + rebin_reduction, + group_spectra, + fold_chopped, + rename_reduction) + + self._setup() + + load_opts = dict() + load_opts['Mode'] = 'FoilOut' + load_opts['InstrumentParFile'] = self._par_filename + + self._workspace_names, self._chopped_data = load_files(self._data_files, + ipf_filename=self._ipf_filename, + spec_min=self._spectra_range[0], + spec_max=self._spectra_range[1], + sum_files=self._sum_files, + load_opts=load_opts) + + for c_ws_name in self._workspace_names: + is_multi_frame = isinstance(mtd[c_ws_name], WorkspaceGroup) + + # Get list of workspaces + if is_multi_frame: + workspaces = mtd[c_ws_name].getNames() + else: + workspaces = [c_ws_name] + + # Process rebinning for framed data + rebin_string_2, num_bins = get_multi_frame_rebin(c_ws_name, + self._rebin_string) + + masked_detectors = identify_bad_detectors(workspaces[0]) + + # Process workspaces + for ws_name in workspaces: + monitor_ws_name = ws_name + '_mon' + + # Process monitor + if not unwrap_monitor(ws_name): + ConvertUnits(InputWorkspace=monitor_ws_name, + OutputWorkspace=monitor_ws_name, + Target='Wavelength', + EMode='Elastic') + + process_monitor_efficiency(ws_name) + scale_monitor(ws_name) + + # Scale detector data by monitor intensities + scale_detectors(ws_name, 'Elastic') + + # Remove the no longer needed monitor workspace + DeleteWorkspace(monitor_ws_name) + + # Convert to dSpacing + ConvertUnits(InputWorkspace=ws_name, + OutputWorkspace=ws_name, + Target='dSpacing', + EMode='Elastic') + + # Handle rebinning + rebin_reduction(ws_name, + self._rebin_string, + rebin_string_2, + num_bins) + + # Group spectra + group_spectra(ws_name, + masked_detectors, + self._grouping_method) + + if is_multi_frame: + fold_chopped(c_ws_name) + + # Rename output workspaces + output_workspace_names = [rename_reduction(ws_name, self._sum_files) for ws_name in self._workspace_names] + + # Group result workspaces + GroupWorkspaces(InputWorkspaces=output_workspace_names, + OutputWorkspace=self._output_ws) + + self.setProperty('OutputWorkspace', self._output_ws) + + + def _setup(self): + """ + Gets algorithm properties. + """ + self._instrument_name = 'VESUVIO' + self._mode = 'diffspec' + + self._output_ws = self.getPropertyValue('OutputWorkspace') + self._data_files = self.getProperty('InputFiles').value + self._par_filename = self.getPropertyValue('InstrumentParFile') + self._spectra_range = self.getProperty('SpectraRange').value + self._rebin_string = self.getPropertyValue('RebinParam') + self._grouping_method = self.getPropertyValue('GroupingPolicy') + + if self._rebin_string == '': + self._rebin_string = None + + # Get the IPF filename + self._ipf_filename = self._instrument_name + '_diffraction_' + self._mode + '_Parameters.xml' + if not os.path.exists(self._ipf_filename): + self._ipf_filename = os.path.join(config['instrumentDefinition.directory'], self._ipf_filename) + logger.information('IPF filename is: %s' % (self._ipf_filename)) + + # Only enable sum files if we actually have more than one file + sum_files = self.getProperty('SumFiles').value + self._sum_files = False + + if sum_files: + num_raw_files = len(self._data_files) + if num_raw_files > 1: + self._sum_files = True + logger.information('Summing files enabled (have %d files)' % num_raw_files) + else: + logger.information('SumFiles options is ignored when only one file is provided') + + +AlgorithmFactory.subscribe(EVSDiffractionReduction) diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ResNorm2.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ResNorm2.py index 02de852f0963d86fd61d806772c7f34c9e6ceebf..461f44dfac4040837f72c838ae4e1d8c4fd1a4a2 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ResNorm2.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ResNorm2.py @@ -1,6 +1,7 @@ #pylint: disable=no-init from mantid.api import (PythonAlgorithm, AlgorithmFactory, MatrixWorkspaceProperty, - WorkspaceGroup, WorkspaceGroupProperty, Progress) + WorkspaceGroup, WorkspaceGroupProperty, ITableWorkspaceProperty, + Progress, PropertyMode) from mantid.kernel import Direction from mantid.simpleapi import * @@ -13,6 +14,7 @@ class ResNorm(PythonAlgorithm): _e_max = None _create_output = None _out_ws = None + _out_ws_table = None def category(self): @@ -53,6 +55,11 @@ class ResNorm(PythonAlgorithm): direction=Direction.Output), doc='Fitted parameter output') + self.declareProperty(ITableWorkspaceProperty('OutputWorkspaceTable', '', + optional=PropertyMode.Optional, + direction=Direction.Output), + doc='Table workspace of fit parameters') + def validateInputs(self): self._get_properties() @@ -85,6 +92,8 @@ class ResNorm(PythonAlgorithm): def PyExec(self): from IndirectCommon import getWSprefix + if self._create_output: + self._out_ws_table = self.getPropertyValue('OutputWorkspaceTable') # Process vanadium workspace van_ws = ConvertSpectrumAxis(InputWorkspace=self._van_ws, @@ -103,26 +112,29 @@ class ResNorm(PythonAlgorithm): input_str = '' for idx in range(num_hist): input_str += '%s,i%d;' % (padded_res_ws, idx) - prog_namer.report() + prog_namer.report('Generating PlotPeak input string') out_name = getWSprefix(self._res_ws) + 'ResNorm_Fit' function = 'name=TabulatedFunction,Workspace=%s,Scaling=1,Shift=0,XScaling=1,ties=(Shift=0)' % self._van_ws - fit_params = PlotPeakByLogValue(Input=input_str, - OutputWorkspace=out_name, - Function=function, - FitType='Individual', - PassWSIndexToFunction=True, - CreateOutput=self._create_output, - StartX=self._e_min, - EndX=self._e_max) + plot_peaks = self.createChildAlgorithm(name='PlotPeakByLogValue', startProgress=0.02, endProgress=0.94, enableLogging=True) + plot_peaks.setProperty('Input', input_str) + plot_peaks.setProperty('OutputWorkspace', out_name) + plot_peaks.setProperty('Function', function) + plot_peaks.setProperty('FitType', 'Individual') + plot_peaks.setProperty('PassWSIndexToFunction', True) + plot_peaks.setProperty('CreateOutput', self._create_output) + plot_peaks.setProperty('StartX', self._e_min) + plot_peaks.setProperty('EndX', self._e_max) + plot_peaks.execute() + fit_params = plot_peaks.getProperty('OutputWorkspace').value params = {'XScaling':'Stretch', 'Scaling':'Intensity'} result_workspaces = [] prog_process = Progress(self, start=0.94, end=1.0, nreports=3) for param_name, output_name in params.items(): result_workspaces.append(self._process_fit_params(fit_params, param_name, v_values, v_unit, output_name)) - prog_process.report() + prog_process.report('Processing Fit data') GroupWorkspaces(InputWorkspaces=result_workspaces, OutputWorkspace=self._out_ws) @@ -130,9 +142,10 @@ class ResNorm(PythonAlgorithm): DeleteWorkspace(van_ws) DeleteWorkspace(padded_res_ws) - prog_process.report() - if not self._create_output: - DeleteWorkspace(fit_params) + prog_process.report('Deleting workspaces') + + if self._create_output: + self.setProperty('OutputWorkspaceTable', fit_params) def _process_res_ws(self, num_hist): diff --git a/Framework/PythonInterface/plugins/algorithms/mlzutils.py b/Framework/PythonInterface/plugins/algorithms/mlzutils.py index 3b69302522b7ef2cd6d2eba41c946e3e548d5673..d0e47dbdc7891c084a714360e66ae6daf3b60f81 100644 --- a/Framework/PythonInterface/plugins/algorithms/mlzutils.py +++ b/Framework/PythonInterface/plugins/algorithms/mlzutils.py @@ -1,4 +1,6 @@ import mantid.simpleapi as api +from mantid.api import AlgorithmManager +import numpy as np def cleanup(wslist): @@ -154,3 +156,69 @@ def compare_mandatory(wslist, plist, logger, tolerance=0.01): "Workspaces: " + ", ".join(wslist) + "\n Values: " + str(properties) logger.error(message) raise RuntimeError(message) + + +def do_fit_gaussian(workspace, index, logger): + """ + Calculates guess values on peak centre, sigma and peak height. + Uses them as an input to run a fit algorithm + @ param workspace --- input workspace + @ param index --- the spectrum with which WorkspaceIndex to fit + @ returns peak_centre --- fitted peak centre + @ returns sigma --- fitted sigma + """ + nhist = workspace.getNumberHistograms() + if index > nhist: + message = "Index " + str(index) + " is out of range for the workspace " + workspace.getName() + logger.error(message) + raise RuntimeError(message) + + x_values = np.array(workspace.readX(index)) + y_values = np.array(workspace.readY(index)) + + # get peak centre position + imax = np.argmax(y_values) + height = y_values[imax] + + # check for zero or negative signal + if height <= 0: + logger.warning("Workspace %s, detector %d has maximum <= 0" % (workspace.getName(), index)) + return [0, 0] + + try_centre = x_values[imax] + + # guess sigma + indices = np.argwhere(y_values > 0.5*height) + nentries = len(indices) + if nentries < 3: + message = "Spectrum " + str(index) + " in workspace " + workspace.getName() +\ + " has too narrow peak. Cannot guess sigma. Check your data." + logger.error(message) + raise RuntimeError(message) + # fwhm = sigma * (2.*np.sqrt(2.*np.log(2.))) + fwhm = np.fabs(x_values[indices[nentries - 1, 0]] - x_values[indices[0, 0]]) + sigma = fwhm/(2.*np.sqrt(2.*np.log(2.))) + + # create and execute Fit algorithm + myfunc = 'name=Gaussian, Height='+str(height)+', PeakCentre='+str(try_centre)+', Sigma='+str(sigma) + startX = try_centre - 3.0*fwhm + endX = try_centre + 3.0*fwhm + prefix = "Fit" + workspace.getName() + str(index) + fit_alg = AlgorithmManager.createUnmanaged('Fit') + fit_alg.initialize() + fit_alg.setChild(True) + api.set_properties(fit_alg, Function=myfunc, InputWorkspace=workspace, CreateOutput=True, Output=prefix) + fit_alg.setProperty('StartX', startX) + fit_alg.setProperty('EndX', endX) + fit_alg.setProperty('WorkspaceIndex', index) + fit_successful = fit_alg.execute() + param_table = fit_alg.getProperty('OutputParameters').value + + if not fit_successful: + message = "For detector " + str(index) + " in workspace " + workspace.getName() +\ + "fit was not successful. Input guess parameters are " + str(myfunc) + logger.error(message) + raise RuntimeError(message) + + # return list: [peak_centre, sigma] + return param_table.column(1)[1:3] diff --git a/Framework/PythonInterface/test/python/mantid/geometry/CMakeLists.txt b/Framework/PythonInterface/test/python/mantid/geometry/CMakeLists.txt index 0a03316888ee6f52c89b0d38835bcd1b59b56f6a..069ccf32a1663bb22f1e4f7a3bb2fdf6d4376b32 100644 --- a/Framework/PythonInterface/test/python/mantid/geometry/CMakeLists.txt +++ b/Framework/PythonInterface/test/python/mantid/geometry/CMakeLists.txt @@ -17,6 +17,8 @@ set ( TEST_PY_FILES SymmetryElementTest.py SymmetryOperationTest.py GroupTest.py + CrystalStructureTest.py + ReflectionGeneratorTest.py ) check_tests_valid ( ${CMAKE_CURRENT_SOURCE_DIR} ${TEST_PY_FILES} ) diff --git a/Framework/PythonInterface/test/python/mantid/geometry/CrystalStructureTest.py b/Framework/PythonInterface/test/python/mantid/geometry/CrystalStructureTest.py new file mode 100644 index 0000000000000000000000000000000000000000..147d8e1e232adbea44574f5a908e45e4a68614ba --- /dev/null +++ b/Framework/PythonInterface/test/python/mantid/geometry/CrystalStructureTest.py @@ -0,0 +1,59 @@ +# pylint: disable=no-init,invalid-name,too-many-public-methods,broad-except +import unittest +from mantid.geometry import CrystalStructure + + +class CrystalStructureTest(unittest.TestCase): + def test_creation(self): + # Some valid constructions + self.assertTrue(self.createCrystalStructureOrRaise("5.43 5.43 5.43", "F d -3 m", "Al 1/3 0.454 1/12 1.0 0.01")) + self.assertTrue(self.createCrystalStructureOrRaise("5.43 5.43 5.43", "C m m m", "Al 1/3 0.454 1/12 1.0 0.01;\n" + "Si 2/3 0.121 1/8")) + self.assertTrue( + self.createCrystalStructureOrRaise("5.43 5.43 5.43 90 90 120", "R -3 c", "Al 1/3 0.454 1/12 1.0 0.01;\n" + "Si 2/3 0.121 1/8")) + + # Invalid unit cell specification + self.assertFalse( + self.createCrystalStructureOrRaise("5.43 5.43 5.43 90.0", "C m m m", "Al 1/3 0.454 1/12 1.0 0.01")) + + # Invalid space group + self.assertFalse( + self.createCrystalStructureOrRaise("5.43 5.43 5.43", "INVALID", "Al 1/3 0.454 1/12 1.0 0.01")) + + # Invalid atom specification + self.assertFalse( + self.createCrystalStructureOrRaise("5.43 5.43 5.43", "C m c e", "Al 1/3 0")) + + def createCrystalStructureOrRaise(self, unitCell, spaceGroup, atomStrings): + try: + CrystalStructure(unitCell, spaceGroup, atomStrings) + return True + except Exception: + return False + + def test_UnitCell(self): + structure = CrystalStructure("5.43 5.42 5.41", "F d -3 m", "Al 1/3 0.454 1/12 1.0 0.01") + cell = structure.getUnitCell() + + self.assertEqual(cell.a(), 5.43) + self.assertEqual(cell.b(), 5.42) + self.assertEqual(cell.c(), 5.41) + + def test_SpaceGroup(self): + structure = CrystalStructure("5.43 5.42 5.41", "F d -3 m", "Al 1/3 0.454 1/12 1.0 0.01") + spaceGroup = structure.getSpaceGroup() + + self.assertEqual(spaceGroup.getHMSymbol(), "F d -3 m") + + def test_scatterers(self): + initialString = "Al 1/3 0.454 1/12 1 0.01;Si 0.1 0.2 0.3 0.99 0.1" + + structure = CrystalStructure("5.43 5.42 5.41", "F d -3 m", initialString) + scatterers = structure.getScatterers() + + self.assertEqual(';'.join(scatterers), initialString) + + +if __name__ == '__main__': + unittest.main() diff --git a/Framework/PythonInterface/test/python/mantid/geometry/ReflectionGeneratorTest.py b/Framework/PythonInterface/test/python/mantid/geometry/ReflectionGeneratorTest.py new file mode 100644 index 0000000000000000000000000000000000000000..4c942f8a7ccd0140d98864097dc3f36f1cfc7ff8 --- /dev/null +++ b/Framework/PythonInterface/test/python/mantid/geometry/ReflectionGeneratorTest.py @@ -0,0 +1,69 @@ +# pylint: disable=no-init,invalid-name,too-many-public-methods +import unittest +from mantid.geometry import CrystalStructure, ReflectionGenerator, ReflectionConditionFilter +from mantid.kernel import V3D +import numpy as np + + +class CrystalStructureTest(unittest.TestCase): + crystalStructure = CrystalStructure("5.431 5.431 5.431", "F d -3 m", "Si 0 0 0 1.0 0.02") + + def test_create(self): + generator = ReflectionGenerator(self.crystalStructure) + generator = ReflectionGenerator(self.crystalStructure, ReflectionConditionFilter.Centering) + + def test_getHKLs(self): + generator = ReflectionGenerator(self.crystalStructure) + hkls = generator.getHKLs(1.0, 10.0) + + self.assertEqual(len(hkls), 138) + + # default is filtering by space group reflection condition + self.assertTrue(V3D(2, 2, 2) in hkls) + self.assertFalse(V3D(1, 0, 0) in hkls) + + def test_getHKLsUsingFilter(self): + generator = ReflectionGenerator(self.crystalStructure) + hkls = generator.getHKLsUsingFilter(1.0, 10.0, ReflectionConditionFilter.StructureFactor) + + self.assertEqual(len(hkls), 130) + + # The 222 is gone now + self.assertFalse(V3D(2, 2, 2) in hkls) + + def test_getUniqueHKLs(self): + generator = ReflectionGenerator(self.crystalStructure) + hkls = generator.getUniqueHKLs(1.0, 10.0) + + self.assertEqual(len(hkls), 9) + + self.assertTrue(V3D(2, 2, 2) in hkls) + self.assertFalse(V3D(1, 0, 0) in hkls) + + def test_getUniqueHKLsUsingFilter(self): + generator = ReflectionGenerator(self.crystalStructure) + hkls = generator.getUniqueHKLsUsingFilter(1.0, 10.0, ReflectionConditionFilter.StructureFactor) + + self.assertEqual(len(hkls), 8) + self.assertFalse(V3D(2, 2, 2) in hkls) + + def test_getDValues(self): + generator = ReflectionGenerator(self.crystalStructure) + hkls = [V3D(1, 0, 0), V3D(1, 1, 1)] + + dValues = generator.getDValues(hkls) + + self.assertEqual(len(hkls), len(dValues)) + self.assertAlmostEqual(dValues[0], 5.431, places=10) + self.assertAlmostEqual(dValues[1], 5.431 / np.sqrt(3.), places=10) + + def test_getFsSquared(self): + generator = ReflectionGenerator(self.crystalStructure) + hkls = generator.getUniqueHKLs(1.0, 10.0) + + fsSquared = generator.getFsSquared(hkls) + + self.assertEqual(len(fsSquared), len(hkls)) + +if __name__ == '__main__': + unittest.main() diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/CMakeLists.txt b/Framework/PythonInterface/test/python/plugins/algorithms/CMakeLists.txt index c12c040cddbff6f851d86f23bfa144fc0bbeb73f..952bb617bfa603aaaedee0c7393bf6f8a7ad9af5 100644 --- a/Framework/PythonInterface/test/python/plugins/algorithms/CMakeLists.txt +++ b/Framework/PythonInterface/test/python/plugins/algorithms/CMakeLists.txt @@ -8,6 +8,7 @@ set ( TEST_PY_FILES CalculateSampleTransmissionTest.py CheckForSampleLogsTest.py ConjoinSpectraTest.py + ComputeCalibrationCoefVanTest.py CorrectLogTimesTest.py CreateLeBailFitInputTest.py CreateMDTest.py @@ -26,6 +27,7 @@ set ( TEST_PY_FILES EnggFitPeaksTest.py EnggFocusTest.py EnggVanadiumCorrectionsTest.py + EVSDiffractionReductionTest.py FilterLogByTimeTest.py FindReflectometryLinesTest.py FlatPlatePaalmanPingsCorrectionTest.py @@ -75,6 +77,7 @@ set ( TEST_PY_FILES UpdatePeakParameterTableValueTest.py SANSSubtractTest.py TimeSliceTest.py + TOFTOFCropWorkspaceTest.py TOFTOFMergeRunsTest.py TOSCABankCorrectionTest.py TransformToIqtTest.py diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/ComputeCalibrationCoefVanTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/ComputeCalibrationCoefVanTest.py new file mode 100644 index 0000000000000000000000000000000000000000..aff74c2e324ac2e288cce0a16a55727b9000f691 --- /dev/null +++ b/Framework/PythonInterface/test/python/plugins/algorithms/ComputeCalibrationCoefVanTest.py @@ -0,0 +1,82 @@ +import unittest +from mantid.simpleapi import DeleteWorkspace, CreateSampleWorkspace, AddSampleLog, EditInstrumentGeometry,\ + CloneWorkspace, CheckWorkspacesMatch +from testhelpers import run_algorithm +from mantid.api import AnalysisDataService +from scipy.constants import N_A, hbar, k +import numpy as np + + +class ComputeCalibrationCoefVanTest(unittest.TestCase): + def setUp(self): + input_ws = CreateSampleWorkspace(Function="User Defined", + UserDefinedFunction="name=LinearBackground, A0=0.3;name=Gaussian, \ + PeakCentre=5, Height=10, Sigma=0.3", NumBanks=2, BankPixelWidth=1, + XMin=0, XMax=10, BinWidth=0.1, BankDistanceFromSample=4.0) + self._input_ws = input_ws + AddSampleLog(self._input_ws, LogName='wavelength', LogText='4.0', LogType='Number', LogUnit='Angstrom') + + def test_output(self): + outputWorkspaceName = "output_ws" + alg_test = run_algorithm("ComputeCalibrationCoefVan", VanadiumWorkspace=self._input_ws, + OutputWorkspace=outputWorkspaceName) + self.assertTrue(alg_test.isExecuted()) + wsoutput = AnalysisDataService.retrieve(outputWorkspaceName) + + # Output = Vanadium ws + self.assertEqual(wsoutput.getRun().getLogData('run_title').value, + self._input_ws.getRun().getLogData('run_title').value) + + # Size of output workspace + self.assertEqual(wsoutput.getNumberHistograms(), self._input_ws.getNumberHistograms()) + + DeleteWorkspace(wsoutput) + return + + def test_sum(self): + outputWorkspaceName = "output_ws" + alg_test = run_algorithm("ComputeCalibrationCoefVan", VanadiumWorkspace=self._input_ws, + OutputWorkspace=outputWorkspaceName) + self.assertTrue(alg_test.isExecuted()) + wsoutput = AnalysisDataService.retrieve(outputWorkspaceName) + + # check whether sum is calculated correctly, for theta=0, dwf=1 + y_sum = sum(self._input_ws.readY(0)[27:75]) + self.assertAlmostEqual(y_sum, wsoutput.readY(0)[0]) + + DeleteWorkspace(wsoutput) + + def test_dwf(self): + outputWorkspaceName = "output_ws" + + # change theta to make dwf != 1 + EditInstrumentGeometry(self._input_ws, L2="4,8", Polar="0,15", Azimuthal="0,0", DetectorIDs="1,2") + alg_test = run_algorithm("ComputeCalibrationCoefVan", VanadiumWorkspace=self._input_ws, + OutputWorkspace=outputWorkspaceName) + self.assertTrue(alg_test.isExecuted()) + wsoutput = AnalysisDataService.retrieve(outputWorkspaceName) + + # check dwf calculation + y_sum = sum(self._input_ws.readY(1)[27:75]) + mvan = 0.001*50.942/N_A + Bcoef = 4.736767162094296*1e+20*hbar*hbar/(2.0*mvan*k*389.0) + dwf = np.exp(-1.0*Bcoef*(4.0*np.pi*np.sin(0.5*np.radians(15.0))/4.0)**2) + self.assertAlmostEqual(y_sum*dwf, wsoutput.readY(1)[0]) + + DeleteWorkspace(wsoutput) + + def test_input_not_modified(self): + backup = CloneWorkspace(self._input_ws) + outputWorkspaceName = "output_ws" + alg_test = run_algorithm("ComputeCalibrationCoefVan", VanadiumWorkspace=self._input_ws, + OutputWorkspace=outputWorkspaceName) + self.assertTrue(alg_test.isExecuted()) + self.assertEqual("Success!", CheckWorkspacesMatch(backup, self._input_ws)) + DeleteWorkspace(backup) + + def tearDown(self): + if AnalysisDataService.doesExist(self._input_ws.getName()): + DeleteWorkspace(self._input_ws) + +if __name__ == "__main__": + unittest.main() diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/DetectorFloodWeightingTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/DetectorFloodWeightingTest.py index b2ca793e6254f263fb1d48b216104cfcf7f6b3fc..81540f1eda08b040642a558a43169aa48462b1b7 100644 --- a/Framework/PythonInterface/test/python/plugins/algorithms/DetectorFloodWeightingTest.py +++ b/Framework/PythonInterface/test/python/plugins/algorithms/DetectorFloodWeightingTest.py @@ -68,8 +68,53 @@ class DetectorFloodWeightingTest(unittest.TestCase): x_axis = out_ws.readX(0) self.assertEquals(x_axis[0], bands[0]) self.assertEquals(x_axis[-1], bands[-1]) - print out_ws.readY(0)[0] self.assertEquals(out_ws.readY(0)[0], 1.0) + + def test_execute_multiple_bands_no_solid_angle(self): + alg = AlgorithmManager.create("DetectorFloodWeighting") + alg.setChild(True) + alg.initialize() + alg.setProperty("SolidAngleCorrection", False) + signal_value = 2 + in_ws = self._create_ws(units="Wavelength", signal_value=signal_value, data_x=range(0,10,1)) + alg.setProperty("InputWorkspace", in_ws) + bands = [1,2,3,4] + alg.setProperty("Bands", bands) # One band + alg.setPropertyValue("OutputWorkspace", "dummy") + alg.execute() + + out_ws = alg.getProperty("OutputWorkspace").value + self.assertEqual(1, out_ws.blocksize()) + self.assertEqual("Wavelength", out_ws.getAxis(0).getUnit().unitID()) + self.assertEqual(in_ws.getNumberHistograms(), out_ws.getNumberHistograms(), msg="Number of histograms should be unchanged.") + x_axis = out_ws.readX(0) + self.assertEquals(x_axis[0], bands[0]) + self.assertEquals(x_axis[-1], bands[-1]) + self.assertEquals(out_ws.readY(0)[0], 1.0) + + def test_execute_multiple_bands_no_solid_angle_with_transmission(self): + alg = AlgorithmManager.create("DetectorFloodWeighting") + alg.setChild(True) + alg.initialize() + alg.setProperty("SolidAngleCorrection", False) + signal_value = 2 + in_ws = self._create_ws(units="Wavelength", signal_value=signal_value, data_x=range(0,10,1)) + alg.setProperty("InputWorkspace", in_ws) + alg.setProperty("TransmissionWorkspace", in_ws) + bands = [1,2,3,4] + alg.setProperty("Bands", bands) # One band + alg.setPropertyValue("OutputWorkspace", "dummy") + alg.execute() + + out_ws = alg.getProperty("OutputWorkspace").value + self.assertEqual(1, out_ws.blocksize()) + self.assertEqual("Wavelength", out_ws.getAxis(0).getUnit().unitID()) + self.assertEqual(in_ws.getNumberHistograms(), out_ws.getNumberHistograms(), msg="Number of histograms should be unchanged.") + x_axis = out_ws.readX(0) + self.assertEquals(x_axis[0], bands[0]) + self.assertEquals(x_axis[-1], bands[-1]) + self.assertEquals(out_ws.readY(0)[0], 1.0) + def test_execute_single_with_solid_angle(self): alg = AlgorithmManager.create("DetectorFloodWeighting") @@ -90,5 +135,6 @@ class DetectorFloodWeightingTest(unittest.TestCase): self.assertEqual(in_ws.getNumberHistograms(), out_ws.getNumberHistograms(), msg="Number of histograms should be unchanged.") + if __name__ == '__main__': unittest.main() diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/EVSDiffractionReductionTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/EVSDiffractionReductionTest.py new file mode 100644 index 0000000000000000000000000000000000000000..9ec89cdaf4051d9055296ecb9f3c04d0239c79d3 --- /dev/null +++ b/Framework/PythonInterface/test/python/plugins/algorithms/EVSDiffractionReductionTest.py @@ -0,0 +1,45 @@ +#pylint: disable=too-many-public-methods,invalid-name + +import unittest +from mantid.simpleapi import * +from mantid.api import * + + +class EVDDiffractionReductionTest(unittest.TestCase): + + def test_basic_reduction_completes(self): + """ + Sanity test to ensure the most basic reduction actually completes. + """ + + wks = EVSDiffractionReduction(InputFiles=['EVS15289.raw'], + InstrumentParFIle='IP0005.dat') + + self.assertTrue(isinstance(wks, WorkspaceGroup), 'Result workspace should be a workspace group.') + self.assertEqual(len(wks), 1) + self.assertEqual(wks.getNames()[0], 'EVS15289_diffspec_red') + + red_ws = wks[0] + self.assertEqual(red_ws.getAxis(0).getUnit().unitID(), 'dSpacing') + self.assertEqual(red_ws.getNumberHistograms(), 1) + + + def test_grouping_individual(self): + """ + Test setting individual grouping, one spectrum per detector. + """ + + wks = EVSDiffractionReduction(InputFiles=['EVS15289.raw'], + GroupingPolicy='Individual', + InstrumentParFIle='IP0005.dat') + + self.assertTrue(isinstance(wks, WorkspaceGroup), 'Result workspace should be a workspace group.') + self.assertEqual(len(wks), 1) + + red_ws = wks[0] + self.assertEqual(red_ws.getAxis(0).getUnit().unitID(), 'dSpacing') + self.assertEqual(red_ws.getNumberHistograms(), 196) + + +if __name__ == '__main__': + unittest.main() diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/SavePlot1DAsJsonTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/SavePlot1DAsJsonTest.py index 6e8c6100e3f2d764c4aa5a8b6c5bdb8961b02cbc..62f8c938fa13402e41580886bc0c61f632ad58d6 100644 --- a/Framework/PythonInterface/test/python/plugins/algorithms/SavePlot1DAsJsonTest.py +++ b/Framework/PythonInterface/test/python/plugins/algorithms/SavePlot1DAsJsonTest.py @@ -1,4 +1,4 @@ -#pylint: disable=invalid-name,too-many-public-methods +#pylint: disable=invalid-name,too-many-public-methods,too-many-arguments import unittest import numpy as np import mantid.simpleapi as api @@ -9,13 +9,13 @@ from mantid.api import AnalysisDataService import os, json -class SaveVulcanGSSTest(unittest.TestCase): +class SavePlot1DAsJsonTest(unittest.TestCase): def test_save_one_curve(self): """ Test to Save one curve """ - datawsname = "TestOneCurve" - E, I, err = self._createOneCurve(datawsname) + datawsname = "constant energy cut" + E, I, err = self._createOneQCurve(datawsname) # Execute out_path = "tempout_curve.json" @@ -26,11 +26,9 @@ class SaveVulcanGSSTest(unittest.TestCase): # executed? self.assertTrue(alg_test.isExecuted()) # Verify .... - d = json.load(open(out_path)) - d0 = d[datawsname+'0'] # plots are numbered - np.testing.assert_array_equal(d0['x'], E) - np.testing.assert_array_equal(d0['y'], I) - np.testing.assert_array_equal(d0['e'], err) + d = json.load(open(out_path))[datawsname] + self.assertEqual(d['type'], 'point') + self._checkData(d, E, I, err) # Delete the output file os.remove(out_path) return @@ -51,11 +49,8 @@ class SaveVulcanGSSTest(unittest.TestCase): # Executed? self.assertTrue(alg_test.isExecuted()) # Verify .... - d = json.load(open(out_path)) - d0 = d[datawsname+'0'] # plots are numbered - np.testing.assert_array_equal(d0['x'], E) - np.testing.assert_array_equal(d0['y'], I) - np.testing.assert_array_equal(d0['e'], err) + d = json.load(open(out_path))[datawsname] + self._checkData(d, E, I, err) # test overwrite alg_test = run_algorithm( "SavePlot1DAsJson", @@ -80,14 +75,9 @@ class SaveVulcanGSSTest(unittest.TestCase): # executed? self.assertTrue(alg_test.isExecuted()) # Verify .... - d = json.load(open(out_path)) - d0 = d[datawsname+'0'] # plots are numbered - np.testing.assert_array_equal(d0['x'], E) - np.testing.assert_array_equal(d0['y'], I) - np.testing.assert_array_equal(d0['e'], err) - d1 = d[datawsname+'1'] # - np.testing.assert_array_equal(d1['y'], I2) - np.testing.assert_array_equal(d1['e'], err2) + d = json.load(open(out_path))[datawsname] + self._checkData(d, E, I, err) + self._checkData(d, E, I2, err2, ID="2") # Delete the output file os.remove(out_path) return @@ -97,6 +87,7 @@ class SaveVulcanGSSTest(unittest.TestCase): """ Test to Save one curve with a name specified by client """ datawsname = "TestOneCurve" + plotname = "myplot" E, I, err = self._createOneCurve(datawsname) # Execute out_path = "tempout_curve_withname.json" @@ -104,36 +95,55 @@ class SaveVulcanGSSTest(unittest.TestCase): "SavePlot1DAsJson", InputWorkspace = datawsname, JsonFilename = out_path, - PlotName = "myplot") + PlotName = plotname) # executed? self.assertTrue(alg_test.isExecuted()) # Verify .... - d = json.load(open(out_path)) - plotname = "myplot" - d0 = d[plotname+'0'] # plots are numbered - np.testing.assert_array_equal(d0['x'], E) - np.testing.assert_array_equal(d0['y'], I) - np.testing.assert_array_equal(d0['e'], err) + d = json.load(open(out_path))[plotname] + self._checkData(d, E, I, err) # Delete the output file os.remove(out_path) return + def _checkData(self, s, E, I, err, ID="1"): + d0 = s["data"][ID] + np.testing.assert_array_equal(d0[0], E) + np.testing.assert_array_equal(d0[1], I) + np.testing.assert_array_equal(d0[2], err) + return + + def _createOneCurve(self, datawsname): """ Create data workspace """ - E = np.arange(-50, 50, 1.0) + E = np.arange(-50, 50, 10.0) I = 1000 * np.exp(-E**2/10**2) err = I ** .5 # create workspace dataws = api.CreateWorkspace( DataX = E, DataY = I, DataE = err, NSpec = 1, - UnitX = "Energy(meV)") + UnitX = "Energy") # Add to data service AnalysisDataService.addOrReplace(datawsname, dataws) return E, I, err + def _createOneQCurve(self, datawsname): + """ Create data workspace + """ + Q = np.arange(0, 13, 1.0) + I = 1000 * np.exp(-Q**2/10**2) + err = I ** .5 + # create workspace + dataws = api.CreateWorkspace( + DataX = Q, DataY = I, DataE = err, NSpec = 1, + UnitX = "Momentum") + # Add to data service + AnalysisDataService.addOrReplace(datawsname, dataws) + return Q, I, err + + def _createOneHistogram(self, datawsname): """ Create data workspace """ diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/TOFTOFCropWorkspaceTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/TOFTOFCropWorkspaceTest.py new file mode 100644 index 0000000000000000000000000000000000000000..14651813e297fe91d44d8e8006bfc41db7655bbb --- /dev/null +++ b/Framework/PythonInterface/test/python/plugins/algorithms/TOFTOFCropWorkspaceTest.py @@ -0,0 +1,59 @@ +import unittest +from mantid.simpleapi import Load, DeleteWorkspace, GroupWorkspaces, TOFTOFCropWorkspace +from testhelpers import run_algorithm +from mantid.api import AnalysisDataService + + +class TOFTOFCropWorkspaceTest(unittest.TestCase): + + _input_ws = None + _cropped_ws = None + + def setUp(self): + input_ws = Load(Filename="TOFTOFTestdata.nxs") + self._input_ws = input_ws + + def test_basicrun(self): + OutputWorkspaceName = "cropped_ws" + alg_test = run_algorithm("TOFTOFCropWorkspace", + InputWorkspace=self._input_ws, + OutputWorkspace=OutputWorkspaceName) + self.assertTrue(alg_test.isExecuted()) + self._cropped_ws = AnalysisDataService.retrieve(OutputWorkspaceName) + + run = self._cropped_ws.getRun() + # check existence of required entries in logs + self.assertTrue('full_channels' in run.keys()) + self.assertTrue('channel_width' in run.keys()) + # check their values + full_channels = float(run.getLogData('full_channels').value) + channel_width = float(run.getLogData('channel_width').value) + self.assertTrue(full_channels > 0.) + self.assertTrue(channel_width > 0.) + # check unit horizontal axis + self.assertEqual(self._cropped_ws.getAxis(0).getUnit().unitID(), 'TOF') + # check length of cropped ws + self.assertEqual(len(self._cropped_ws.readX(0)), int(full_channels)) + + def test_inputgroup(self): + group = GroupWorkspaces([self._input_ws]) + OutputWorkspaceName = "cropped_ws" + alg_test = run_algorithm("TOFTOFCropWorkspace", + InputWorkspace=group, + OutputWorkspace=OutputWorkspaceName) + self.assertTrue(alg_test.isExecuted()) + + def test_invalid_xunits(self): + self._input_ws.getAxis(0).setUnit('Wavelength') + OutputWorkspaceName = "cropped_ws" + self.assertRaises(RuntimeError, TOFTOFCropWorkspace, InputWorkspace=self._input_ws, + OutputWorkspace=OutputWorkspaceName) + + def cleanUp(self): + if AnalysisDataService.doesExist(self._input_ws): + DeleteWorkspace(self._input_ws) + if AnalysisDataService.doesExist(self._cropped_ws): + DeleteWorkspace(self._cropped_ws) + +if __name__ == "__main__": + unittest.main() diff --git a/Framework/PythonInterface/test/testhelpers/WorkspaceCreationHelperModule.cpp b/Framework/PythonInterface/test/testhelpers/WorkspaceCreationHelperModule.cpp index 810d3fe4179fdd9af9c2c3ebafebafcc9e919589..9e6e57799eb3bf45edf789edfa54b8de0d873698 100644 --- a/Framework/PythonInterface/test/testhelpers/WorkspaceCreationHelperModule.cpp +++ b/Framework/PythonInterface/test/testhelpers/WorkspaceCreationHelperModule.cpp @@ -21,6 +21,11 @@ using namespace Mantid::DataObjects::MDEventsTestHelper; using namespace Mantid::PythonInterface::Policies; using namespace WorkspaceCreationHelper; +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wunused-local-typedef" +#endif BOOST_PYTHON_FUNCTION_OVERLOADS(create2DWorkspaceWithFullInstrument_overloads, create2DWorkspaceWithFullInstrument, 2, 4) @@ -31,6 +36,10 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( create2DWorkspaceWithRectangularInstrument_overloads, create2DWorkspaceWithRectangularInstrument, 3, 3) +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + BOOST_PYTHON_MODULE(WorkspaceCreationHelper) { using namespace boost::python; diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiCreatePeaksFromCell.h b/Framework/SINQ/inc/MantidSINQ/PoldiCreatePeaksFromCell.h index b622976ee7e2e3c5f6f2c0689cfe79a0a21b7a39..0e1d54336ca6c9bf1a146f6a4390ea19ff1c6a71 100644 --- a/Framework/SINQ/inc/MantidSINQ/PoldiCreatePeaksFromCell.h +++ b/Framework/SINQ/inc/MantidSINQ/PoldiCreatePeaksFromCell.h @@ -57,13 +57,6 @@ protected: Geometry::SpaceGroup_const_sptr getSpaceGroup(const std::string &spaceGroupString) const; - Geometry::CompositeBraggScatterer_sptr - getScatterers(const std::string &scattererString) const; - Geometry::BraggScatterer_sptr - getScatterer(const std::string &singleScatterer) const; - std::vector<std::string> - getCleanScattererTokens(const std::vector<std::string> &tokens) const; - double getDMaxValue(const Geometry::UnitCell &unitCell) const; double getLargestDValue(const Geometry::UnitCell &unitCell) const; diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks2D.h b/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks2D.h index 973c128b27ba685ec33b4abfe7b79f178da2f9a5..1a7c1005d68692eb07359cc90d0ad0731cadf8ed 100644 --- a/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks2D.h +++ b/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks2D.h @@ -6,6 +6,7 @@ #include "MantidAPI/Algorithm.h" #include "MantidAPI/IFunction.h" #include "MantidAPI/IPeakFunction.h" +#include "MantidGeometry/Crystal/PointGroup.h" #include "MantidKernel/Matrix.h" @@ -104,6 +105,9 @@ protected: getFunctionPawley(std::string profileFunctionName, const PoldiPeakCollection_sptr &peakCollection); + std::string getCrystalSystemFromPointGroup( + const Geometry::PointGroup_sptr &pointGroup) const; + std::string getRefinedStartingCell(const std::string &initialCell, const std::string &crystalSystem, diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiMockInstrumentHelpers.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiMockInstrumentHelpers.h index 3174172ae4ec2fbf87198add5758e7af44874a4c..717702c21ffc041133aeb9c79238e12b23759e12 100644 --- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiMockInstrumentHelpers.h +++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiMockInstrumentHelpers.h @@ -532,9 +532,9 @@ public: CompositeBraggScatterer_sptr atoms = CompositeBraggScatterer::create(); atoms->addScatterer(atomSi); - CrystalStructure_sptr Si(new CrystalStructure( + CrystalStructure Si( UnitCell(5.43071, 5.43071, 5.43071), - SpaceGroupFactory::Instance().createSpaceGroup("P m -3 m"), atoms)); + SpaceGroupFactory::Instance().createSpaceGroup("P m -3 m"), atoms); return PoldiPeakCollection_sptr(new PoldiPeakCollection(Si, 1.1, 1.95)); } diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiPeakCollection.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiPeakCollection.h index 041f0be02f56b1197d358fa70149d2a25b0dc909..cbc0d31dd1ea8d87571fcae69723b75e145c169f 100644 --- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiPeakCollection.h +++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiPeakCollection.h @@ -50,7 +50,7 @@ public: PoldiPeakCollection(IntensityType intensityType = Maximum); PoldiPeakCollection(const DataObjects::TableWorkspace_sptr &workspace); - PoldiPeakCollection(const Geometry::CrystalStructure_sptr &crystalStructure, + PoldiPeakCollection(const Geometry::CrystalStructure &crystalStructure, double dMin, double dMax); virtual ~PoldiPeakCollection() {} diff --git a/Framework/SINQ/src/PoldiCreatePeaksFromCell.cpp b/Framework/SINQ/src/PoldiCreatePeaksFromCell.cpp index 0fd98199d55469039b65d1a46f3706f578313228..94b338277527b5254eac1e4259b9ecb2c2e197dd 100644 --- a/Framework/SINQ/src/PoldiCreatePeaksFromCell.cpp +++ b/Framework/SINQ/src/PoldiCreatePeaksFromCell.cpp @@ -6,11 +6,8 @@ #include "MantidSINQ/PoldiUtilities/PoldiPeakCollection.h" #include "MantidAPI/ITableWorkspace.h" #include "MantidGeometry/Crystal/SpaceGroupFactory.h" -#include "MantidGeometry/Crystal/BraggScattererFactory.h" - -#include <boost/tokenizer.hpp> -#include <boost/algorithm/string.hpp> -#include <boost/assign.hpp> +#include "MantidGeometry/Crystal/CompositeBraggScatterer.h" +#include "MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h" namespace Mantid { namespace Poldi { @@ -75,64 +72,6 @@ SpaceGroup_const_sptr PoldiCreatePeaksFromCell::getSpaceGroup( return SpaceGroupFactory::Instance().createSpaceGroup(spaceGroupString); } -CompositeBraggScatterer_sptr PoldiCreatePeaksFromCell::getScatterers( - const std::string &scattererString) const { - boost::char_separator<char> atomSep(";"); - boost::tokenizer<boost::char_separator<char>> tokens(scattererString, - atomSep); - - std::vector<BraggScatterer_sptr> scatterers; - - for (auto it = tokens.begin(); it != tokens.end(); ++it) { - scatterers.push_back(getScatterer(boost::trim_copy(*it))); - } - - return CompositeBraggScatterer::create(scatterers); -} - -BraggScatterer_sptr PoldiCreatePeaksFromCell::getScatterer( - const std::string &singleScatterer) const { - std::vector<std::string> tokens; - boost::split(tokens, singleScatterer, boost::is_any_of(" ")); - - if (tokens.size() < 4 || tokens.size() > 6) { - throw std::invalid_argument("Could not parse scatterer string: " + - singleScatterer); - } - - std::vector<std::string> cleanScattererTokens = - getCleanScattererTokens(tokens); - std::vector<std::string> properties = - boost::assign::list_of("Element")("Position")("Occupancy")("U") - .convert_to_container<std::vector<std::string>>(); - - std::string initString; - for (size_t i = 0; i < cleanScattererTokens.size(); ++i) { - initString += properties[i] + "=" + cleanScattererTokens[i] + ";"; - } - - return BraggScattererFactory::Instance().createScatterer( - "IsotropicAtomBraggScatterer", initString); -} - -std::vector<std::string> PoldiCreatePeaksFromCell::getCleanScattererTokens( - const std::vector<std::string> &tokens) const { - std::vector<std::string> cleanTokens; - - // Element - cleanTokens.push_back(tokens[0]); - - // X, Y, Z - cleanTokens.push_back("[" + tokens[1] + "," + tokens[2] + "," + tokens[3] + - "]"); - - for (size_t i = 4; i < tokens.size(); ++i) { - cleanTokens.push_back(tokens[i]); - } - - return cleanTokens; -} - /** Returns the largest lattice spacing based on the algorithm properties * * This method returns the largest allowed lattice spacing for calculations. If @@ -283,11 +222,11 @@ void PoldiCreatePeaksFromCell::exec() { g_log.information() << "Constrained unit cell is: " << unitCellToStr(unitCell) << std::endl; - CompositeBraggScatterer_sptr scatterers = getScatterers(getProperty("Atoms")); + CompositeBraggScatterer_sptr scatterers = CompositeBraggScatterer::create( + IsotropicAtomBraggScattererParser(getProperty("Atoms"))()); // Create a CrystalStructure-object for use with PoldiPeakCollection - CrystalStructure_sptr crystalStructure = - boost::make_shared<CrystalStructure>(unitCell, spaceGroup, scatterers); + CrystalStructure crystalStructure(unitCell, spaceGroup, scatterers); double dMin = getProperty("LatticeSpacingMin"); double dMax = getDMaxValue(unitCell); diff --git a/Framework/SINQ/src/PoldiFitPeaks2D.cpp b/Framework/SINQ/src/PoldiFitPeaks2D.cpp index 5ace6536c53526aaddd76b1e7faec2a84e5e7b44..dc9755d28fbc0efb9ba8f4463e93b03d0c66e3dc 100644 --- a/Framework/SINQ/src/PoldiFitPeaks2D.cpp +++ b/Framework/SINQ/src/PoldiFitPeaks2D.cpp @@ -546,8 +546,7 @@ Poldi2DFunction_sptr PoldiFitPeaks2D::getFunctionPawley( "peaks do not have point group."); } - std::string crystalSystem = - getCrystalSystemAsString(pointGroup->crystalSystem()); + std::string crystalSystem = getCrystalSystemFromPointGroup(pointGroup); pawleyFunction->setCrystalSystem(crystalSystem); UnitCell cell = peakCollection->unitCell(); @@ -575,6 +574,35 @@ Poldi2DFunction_sptr PoldiFitPeaks2D::getFunctionPawley( return mdFunction; } +/** + * Returns the crystal system for the specified point group + * + * This function simply uses Geometry::getCrystalSystemAsString(), except when + * the crystal system is trigonal but the point group uses hexagonal axes. In + * that case this function returns the string for PointGroup::Hexagonal. + * + * @param pointGroup :: The point group for which to find the crystal system + * @return The crystal system for the point group + */ +std::string PoldiFitPeaks2D::getCrystalSystemFromPointGroup( + const PointGroup_sptr &pointGroup) const { + if (!pointGroup) { + throw std::invalid_argument( + "Cannot return crystal system for null PointGroup."); + } + + PointGroup::CrystalSystem crystalSystem = pointGroup->crystalSystem(); + + if (crystalSystem == PointGroup::Trigonal) { + if (pointGroup->getCoordinateSystem() == + Group::CoordinateSystem::Hexagonal) { + return getCrystalSystemAsString(PointGroup::Hexagonal); + } + } + + return getCrystalSystemAsString(crystalSystem); +} + /** * Tries to refine the initial cell using the supplied peaks * diff --git a/Framework/SINQ/src/PoldiUtilities/PoldiAutoCorrelationCore.cpp b/Framework/SINQ/src/PoldiUtilities/PoldiAutoCorrelationCore.cpp index 4a3ec4167a2bcbb4b2ea8d71ff9529c35d134574..48b5317b0eacdd7fdf4cc32a6cb5af86b2223ca7 100644 --- a/Framework/SINQ/src/PoldiUtilities/PoldiAutoCorrelationCore.cpp +++ b/Framework/SINQ/src/PoldiUtilities/PoldiAutoCorrelationCore.cpp @@ -385,6 +385,18 @@ UncertainValue PoldiAutoCorrelationCore::getCMessAndCSigma( case 2: { int middleIndex = cleanIndex((locator.icmin + 1), m_timeBinCount); + if (middleIndex < 0) { + m_logger.warning() << "Inconsistency foun while calculating correlation " + "intensity and error for d-value: " + << boost::lexical_cast<std::string>(dValue) + << ", with detector index: " + << boost::lexical_cast<std::string>(index) + << ", got middle index: " + << boost::lexical_cast<std::string>(middleIndex) + << ", ignoring it." << std::endl; + break; + } + double counts = getCounts(locator.detectorElement, middleIndex); double normCounts = getNormCounts(locator.detectorElement, middleIndex); diff --git a/Framework/SINQ/src/PoldiUtilities/PoldiPeakCollection.cpp b/Framework/SINQ/src/PoldiUtilities/PoldiPeakCollection.cpp index bde86e64c42828a938b3422f1fd4383e408396f7..46ecefa2b6090f3c444b84eb3f9774b7a73c43d8 100644 --- a/Framework/SINQ/src/PoldiUtilities/PoldiPeakCollection.cpp +++ b/Framework/SINQ/src/PoldiUtilities/PoldiPeakCollection.cpp @@ -4,6 +4,8 @@ #include "MantidAPI/LogManager.h" #include "MantidGeometry/Crystal/PointGroupFactory.h" +#include "MantidGeometry/Crystal/ReflectionGenerator.h" + #include "boost/format.hpp" #include "boost/algorithm/string/join.hpp" @@ -33,27 +35,22 @@ PoldiPeakCollection::PoldiPeakCollection(const TableWorkspace_sptr &workspace) } PoldiPeakCollection::PoldiPeakCollection( - const Geometry::CrystalStructure_sptr &crystalStructure, double dMin, - double dMax) + const CrystalStructure &crystalStructure, double dMin, double dMax) : m_peaks(), m_intensityType(Integral), m_profileFunctionName(), m_pointGroup() { - if (!crystalStructure) { - throw std::invalid_argument( - "Cannot create PoldiPeakCollection from invalid CrystalStructure."); - } - m_pointGroup = PointGroupFactory::Instance().createPointGroupFromSpaceGroup( - crystalStructure->spaceGroup()); + crystalStructure.spaceGroup()); + + m_unitCell = crystalStructure.cell(); - m_unitCell = crystalStructure->cell(); + ReflectionGenerator generator(crystalStructure, + ReflectionConditionFilter::StructureFactor); - std::vector<V3D> uniqueHKL = crystalStructure->getUniqueHKLs( - dMin, dMax, Geometry::CrystalStructure::UseStructureFactor); - std::vector<double> dValues = crystalStructure->getDValues(uniqueHKL); - std::vector<double> structureFactors = - crystalStructure->getFSquared(uniqueHKL); + std::vector<V3D> hkls = generator.getUniqueHKLs(dMin, dMax); + std::vector<double> dValues = generator.getDValues(hkls); + std::vector<double> structureFactors = generator.getFsSquared(hkls); - setPeaks(uniqueHKL, dValues, structureFactors); + setPeaks(hkls, dValues, structureFactors); } PoldiPeakCollection_sptr PoldiPeakCollection::clone() { diff --git a/Framework/SINQ/src/PoldiUtilities/PoldiResidualCorrelationCore.cpp b/Framework/SINQ/src/PoldiUtilities/PoldiResidualCorrelationCore.cpp index 02f23178125755897c583659e66ec70e8ca6ed16..665b2f1eefa67af58661bb36d0e4c8d86b5c6904 100644 --- a/Framework/SINQ/src/PoldiUtilities/PoldiResidualCorrelationCore.cpp +++ b/Framework/SINQ/src/PoldiUtilities/PoldiResidualCorrelationCore.cpp @@ -99,6 +99,15 @@ void PoldiResidualCorrelationCore::distributeCorrelationCounts( case 2: { int middleIndex = cleanIndex((locator.icmin + 1), m_timeBinCount); + if (middleIndex < 0) { + m_logger.warning() + << "Inconsistency foun while calculating distribute " + "correlation counts for d-value with index " + << boost::lexical_cast<std::string>(k) << ", got middle index: " + << boost::lexical_cast<std::string>(middleIndex) + << ", ignoring it." << std::endl; + break; + } addToCountData(locator.detectorElement, middleIndex, deltaForD); } case 1: { diff --git a/Framework/SINQ/test/PoldiFitPeaks2DTest.h b/Framework/SINQ/test/PoldiFitPeaks2DTest.h index da95dd9141476a4b1fdef8b7604b044ff0b0f45a..a9f11eb2d9af4e130098bdbf47729f9625cfc4e6 100644 --- a/Framework/SINQ/test/PoldiFitPeaks2DTest.h +++ b/Framework/SINQ/test/PoldiFitPeaks2DTest.h @@ -433,6 +433,40 @@ public: TS_ASSERT_EQUALS(refinedCell, "5 5 5 90 90 90"); } + void testGetCrystalSystemFromPointGroup() { + TestablePoldiFitPeaks2D alg; + + auto pgCubic = PointGroupFactory::Instance().createPointGroup("m-3m"); + TS_ASSERT_EQUALS(alg.getCrystalSystemFromPointGroup(pgCubic), "Cubic"); + + auto pgTetra = PointGroupFactory::Instance().createPointGroup("4/mmm"); + TS_ASSERT_EQUALS(alg.getCrystalSystemFromPointGroup(pgTetra), "Tetragonal"); + + auto pgOrtho = PointGroupFactory::Instance().createPointGroup("mmm"); + TS_ASSERT_EQUALS(alg.getCrystalSystemFromPointGroup(pgOrtho), + "Orthorhombic"); + + auto pgMono = PointGroupFactory::Instance().createPointGroup("2/m"); + TS_ASSERT_EQUALS(alg.getCrystalSystemFromPointGroup(pgMono), "Monoclinic"); + + auto pgTric = PointGroupFactory::Instance().createPointGroup("-1"); + TS_ASSERT_EQUALS(alg.getCrystalSystemFromPointGroup(pgTric), "Triclinic"); + + auto pgHex = PointGroupFactory::Instance().createPointGroup("6/mmm"); + TS_ASSERT_EQUALS(alg.getCrystalSystemFromPointGroup(pgHex), "Hexagonal"); + + auto pgTrigRh = PointGroupFactory::Instance().createPointGroup("-3m r"); + TS_ASSERT_EQUALS(alg.getCrystalSystemFromPointGroup(pgTrigRh), "Trigonal"); + + auto pgTrigHex = PointGroupFactory::Instance().createPointGroup("-3m"); + TS_ASSERT_EQUALS(alg.getCrystalSystemFromPointGroup(pgTrigHex), + "Hexagonal"); + + PointGroup_sptr invalid; + TS_ASSERT_THROWS(alg.getCrystalSystemFromPointGroup(invalid), + std::invalid_argument); + } + private: PoldiInstrumentAdapter_sptr m_instrument; PoldiTimeTransformer_sptr m_timeTransformer; diff --git a/Framework/SINQ/test/PoldiPeakCollectionTest.h b/Framework/SINQ/test/PoldiPeakCollectionTest.h index 8f9ec43120a27baaf7fbd5f424f8aacc4fca7fb3..6d75c9df41d49c48e1a5ed0365bb5018ad959b9b 100644 --- a/Framework/SINQ/test/PoldiPeakCollectionTest.h +++ b/Framework/SINQ/test/PoldiPeakCollectionTest.h @@ -13,6 +13,7 @@ #include "MantidGeometry/Crystal/PointGroupFactory.h" #include "MantidGeometry/Crystal/SpaceGroupFactory.h" #include "MantidGeometry/Crystal/BraggScattererFactory.h" +#include "MantidGeometry/Crystal/ReflectionGenerator.h" #include <stdexcept> @@ -323,7 +324,7 @@ public: } void testStructureConstructor() { - CrystalStructure_sptr structure = getCsClStructure(); + CrystalStructure structure = getCsClStructure(); double dMin = 0.55; double dMax = 5.0; @@ -357,18 +358,19 @@ public: } void testSetPeaks() { - CrystalStructure_sptr structure = getCsClStructure(); + CrystalStructure structure = getCsClStructure(); + ReflectionGenerator generator(structure); double dMin = 0.55; double dMax = 5.0; - std::vector<V3D> hkls = structure->getUniqueHKLs(dMin, dMax); - std::vector<double> dValues = structure->getDValues(hkls); + std::vector<V3D> hkls = generator.getUniqueHKLs(dMin, dMax); + std::vector<double> dValues = generator.getDValues(hkls); std::vector<double> fSquared(dValues.size(), 0.0); TestablePoldiPeakCollection p; - p.setPointGroup(structure->pointGroup()); + p.setPointGroup(structure.spaceGroup()->getPointGroup()); TS_ASSERT_THROWS_NOTHING(p.setPeaks(hkls, dValues, fSquared)); dValues.pop_back(); @@ -377,7 +379,7 @@ public: } private: - CrystalStructure_sptr getCsClStructure() { + CrystalStructure getCsClStructure() { UnitCell CsCl(4.126, 4.126, 4.126); SpaceGroup_const_sptr Pm3m = SpaceGroupFactory::Instance().createSpaceGroup("P m -3 m"); @@ -392,7 +394,7 @@ private: atoms->addScatterer(cs); atoms->addScatterer(cl); - return boost::make_shared<CrystalStructure>(CsCl, Pm3m, atoms); + return CrystalStructure(CsCl, Pm3m, atoms); } TableWorkspace_sptr m_dummyData; diff --git a/Framework/TestHelpers/inc/MantidTestHelpers/FakeObjects.h b/Framework/TestHelpers/inc/MantidTestHelpers/FakeObjects.h index b9c906a2804d32c3049699391f332ba19d3fa9c3..59a51ac705f792a245fb5c3dc9d1ed4f7820f440 100644 --- a/Framework/TestHelpers/inc/MantidTestHelpers/FakeObjects.h +++ b/Framework/TestHelpers/inc/MantidTestHelpers/FakeObjects.h @@ -118,7 +118,7 @@ public: m_axes[1] = new Mantid::API::SpectraAxis(this); } size_t size() const { return vec.size() * blocksize(); } - size_t blocksize() const { return vec[0].dataY().size(); } + size_t blocksize() const { return vec.empty() ? 0 : vec[0].dataY().size(); } ISpectrum *getSpectrum(const size_t index) { return &vec[index]; } const ISpectrum *getSpectrum(const size_t index) const { return &vec[index]; diff --git a/Framework/TestHelpers/inc/MantidTestHelpers/WorkspaceCreationHelper.h b/Framework/TestHelpers/inc/MantidTestHelpers/WorkspaceCreationHelper.h index c5d103d323ea76a43b145d302051846e0c8fcbcf..c2bbf05191f2bacbb0af8f49ad7d46f61e8d42bd 100644 --- a/Framework/TestHelpers/inc/MantidTestHelpers/WorkspaceCreationHelper.h +++ b/Framework/TestHelpers/inc/MantidTestHelpers/WorkspaceCreationHelper.h @@ -46,7 +46,7 @@ public: return out; } }; -/** mock algorithn for doing logging/progress reporting*/ +/** mock algorithm for doing logging/progress reporting*/ class MockAlgorithm : public Mantid::API::Algorithm { public: MockAlgorithm(size_t nSteps = 100); @@ -178,8 +178,8 @@ void addNoise(Mantid::API::MatrixWorkspace_sptr ws, double noise, /** * Create a test workspace with a fully defined instrument * Each spectra will have a cylindrical detector defined 2*cylinder_radius away - * from the centre of the - * pervious. + * from the centre of the previous. + * * Data filled with: Y: 2.0, E: sqrt(2.0), X: nbins of width 1 starting at 0 */ Mantid::DataObjects::Workspace2D_sptr create2DWorkspaceWithFullInstrument( @@ -262,7 +262,7 @@ CreateRandomEventWorkspace(size_t numbins, size_t numpixels, Mantid::API::MatrixWorkspace_sptr CreateGroupedWorkspace2D(size_t numHist, int numBins, double binDelta); -// grouped workpsace with detectors arranges in rings in centre and into boxes +// grouped workspace with detectors arranges in rings in center and into boxes // outside Mantid::API::MatrixWorkspace_sptr CreateGroupedWorkspace2DWithRingsAndBoxes( size_t RootOfNumHist = 10, int numBins = 10, double binDelta = 1.0); diff --git a/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp b/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp index 88c67d797f42b4ec54f1238219a455cb436b9bf2..3d601ae49bc433f40bfb0c82aa8d02d8b936706c 100644 --- a/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp +++ b/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp @@ -23,6 +23,7 @@ #include "MantidGeometry/Instrument/Detector.h" #include "MantidGeometry/Instrument/ParameterMap.h" #include "MantidGeometry/Instrument/ReferenceFrame.h" +#include "MantidGeometry/Instrument/Component.h" #include "MantidGeometry/Objects/ShapeFactory.h" #include "MantidGeometry/Crystal/OrientedLattice.h" #include "MantidKernel/MersenneTwister.h" @@ -403,6 +404,10 @@ create2DWorkspaceWithFullInstrument(int nhist, int nbins, bool includeMonitors, testInst->setPos(0.0, 0.0, 0.0); testInst->add(sample); testInst->markAsSamplePos(sample); + // chopper position + Component *chop_pos = + new Component("chopper-position", Kernel::V3D(-10, 0, 0), testInst.get()); + testInst->add(chop_pos); return space; } diff --git a/Framework/WorkflowAlgorithms/src/DgsProcessDetectorVanadium.cpp b/Framework/WorkflowAlgorithms/src/DgsProcessDetectorVanadium.cpp index 1c4871d97d7b8db3862fe870e3319b4933f3ce3a..408d66a7a4c11e6f9f6d21de3cbacd75d833a6c2 100644 --- a/Framework/WorkflowAlgorithms/src/DgsProcessDetectorVanadium.cpp +++ b/Framework/WorkflowAlgorithms/src/DgsProcessDetectorVanadium.cpp @@ -1,6 +1,5 @@ #include "MantidWorkflowAlgorithms/DgsProcessDetectorVanadium.h" #include "MantidAPI/PropertyManagerDataService.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidKernel/ConfigService.h" #include "MantidKernel/FacilityInfo.h" #include "MantidWorkflowAlgorithms/WorkflowAlgorithmHelpers.h" diff --git a/Framework/WorkflowAlgorithms/src/EQSANSDarkCurrentSubtraction.cpp b/Framework/WorkflowAlgorithms/src/EQSANSDarkCurrentSubtraction.cpp index 399c082990d5ae1903aa0881595a2839e27aac15..5871e64724186557a97628ef0d2ed1f37ccd3fdb 100644 --- a/Framework/WorkflowAlgorithms/src/EQSANSDarkCurrentSubtraction.cpp +++ b/Framework/WorkflowAlgorithms/src/EQSANSDarkCurrentSubtraction.cpp @@ -3,7 +3,7 @@ //---------------------------------------------------------------------- #include "MantidWorkflowAlgorithms/EQSANSDarkCurrentSubtraction.h" #include "MantidDataObjects/EventWorkspace.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidKernel/TimeSeriesProperty.h" #include "MantidAPI/FileProperty.h" #include "Poco/Path.h" @@ -24,8 +24,7 @@ using namespace Geometry; using namespace DataObjects; void EQSANSDarkCurrentSubtraction::init() { - auto wsValidator = boost::make_shared<CompositeValidator>(); - wsValidator->add<WorkspaceUnitValidator>("Wavelength"); + auto wsValidator = boost::make_shared<WorkspaceUnitValidator>("Wavelength"); declareProperty(new WorkspaceProperty<>("InputWorkspace", "", Direction::Input, wsValidator)); diff --git a/Framework/WorkflowAlgorithms/src/EQSANSDarkCurrentSubtraction2.cpp b/Framework/WorkflowAlgorithms/src/EQSANSDarkCurrentSubtraction2.cpp index a87fa664cd67a50b5f24dde3a289d0b123619f0e..6497a24bf70fb8e393d2cf3f648b21a4ec9b47ef 100644 --- a/Framework/WorkflowAlgorithms/src/EQSANSDarkCurrentSubtraction2.cpp +++ b/Framework/WorkflowAlgorithms/src/EQSANSDarkCurrentSubtraction2.cpp @@ -3,7 +3,7 @@ //---------------------------------------------------------------------- #include "MantidWorkflowAlgorithms/EQSANSDarkCurrentSubtraction2.h" #include "MantidDataObjects/EventWorkspace.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidKernel/TimeSeriesProperty.h" #include "MantidAPI/FileProperty.h" #include "Poco/Path.h" @@ -24,8 +24,7 @@ using namespace Geometry; using namespace DataObjects; void EQSANSDarkCurrentSubtraction2::init() { - auto wsValidator = boost::make_shared<CompositeValidator>(); - wsValidator->add<WorkspaceUnitValidator>("Wavelength"); + auto wsValidator = boost::make_shared<WorkspaceUnitValidator>("Wavelength"); declareProperty(new WorkspaceProperty<>("InputWorkspace", "", Direction::Input, wsValidator)); diff --git a/Framework/WorkflowAlgorithms/src/EQSANSLoad.cpp b/Framework/WorkflowAlgorithms/src/EQSANSLoad.cpp index bf6eea1e2cc6be9404ce09046a013733cbaeaf5c..e93f43068f858c373d6eaa75efbd6a9deb7a1ba9 100644 --- a/Framework/WorkflowAlgorithms/src/EQSANSLoad.cpp +++ b/Framework/WorkflowAlgorithms/src/EQSANSLoad.cpp @@ -2,7 +2,7 @@ // Includes //---------------------------------------------------------------------- #include "MantidWorkflowAlgorithms/EQSANSLoad.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidAPI/AnalysisDataService.h" #include <MantidAPI/FileFinder.h> #include <MantidAPI/FileProperty.h> @@ -40,8 +40,7 @@ void EQSANSLoad::init() { "_event.nxs"), "The name of the input event Nexus file to load"); - auto wsValidator = boost::make_shared<CompositeValidator>(); - wsValidator->add<WorkspaceUnitValidator>("TOF"); + auto wsValidator = boost::make_shared<WorkspaceUnitValidator>("TOF"); declareProperty(new WorkspaceProperty<EventWorkspace>( "InputWorkspace", "", Direction::Input, PropertyMode::Optional, wsValidator), diff --git a/Framework/WorkflowAlgorithms/src/EQSANSMonitorTOF.cpp b/Framework/WorkflowAlgorithms/src/EQSANSMonitorTOF.cpp index 6b9de1045cc2608430b59656950347fc00f24447..5298328007ab8970b5696008b4288eebc426d944 100644 --- a/Framework/WorkflowAlgorithms/src/EQSANSMonitorTOF.cpp +++ b/Framework/WorkflowAlgorithms/src/EQSANSMonitorTOF.cpp @@ -2,7 +2,7 @@ // Includes //---------------------------------------------------------------------- #include "MantidWorkflowAlgorithms/EQSANSMonitorTOF.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidKernel/TimeSeriesProperty.h" #include "MantidGeometry/Instrument.h" #include "Poco/NumberFormatter.h" diff --git a/Framework/WorkflowAlgorithms/src/EQSANSQ2D.cpp b/Framework/WorkflowAlgorithms/src/EQSANSQ2D.cpp index fdedcf9074f68177be3891380e98ae05df6525d8..cf1207541d0d89ec0358253783a97be6969730ee 100644 --- a/Framework/WorkflowAlgorithms/src/EQSANSQ2D.cpp +++ b/Framework/WorkflowAlgorithms/src/EQSANSQ2D.cpp @@ -2,7 +2,7 @@ // Includes //---------------------------------------------------------------------- #include "MantidWorkflowAlgorithms/EQSANSQ2D.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "Poco/NumberFormatter.h" #include "MantidWorkflowAlgorithms/EQSANSInstrument.h" @@ -17,8 +17,7 @@ using namespace API; using namespace Geometry; void EQSANSQ2D::init() { - auto wsValidator = boost::make_shared<CompositeValidator>(); - wsValidator->add<WorkspaceUnitValidator>("Wavelength"); + auto wsValidator = boost::make_shared<WorkspaceUnitValidator>("Wavelength"); declareProperty(new WorkspaceProperty<>("InputWorkspace", "", Direction::Input, wsValidator), "Workspace to calculate I(qx,qy) from"); diff --git a/Framework/WorkflowAlgorithms/src/HFIRDarkCurrentSubtraction.cpp b/Framework/WorkflowAlgorithms/src/HFIRDarkCurrentSubtraction.cpp index cbcbc6da35a9aba7d385f2f1896cf4ecfec50a29..14e681d1d3c88a6d79afb6dc0abd10da664591ba 100644 --- a/Framework/WorkflowAlgorithms/src/HFIRDarkCurrentSubtraction.cpp +++ b/Framework/WorkflowAlgorithms/src/HFIRDarkCurrentSubtraction.cpp @@ -3,7 +3,7 @@ //---------------------------------------------------------------------- #include "MantidWorkflowAlgorithms/HFIRDarkCurrentSubtraction.h" #include "MantidAPI/MatrixWorkspace.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidAPI/FileProperty.h" #include "Poco/Path.h" #include "Poco/String.h" @@ -22,8 +22,7 @@ using namespace API; using namespace Geometry; void HFIRDarkCurrentSubtraction::init() { - auto wsValidator = boost::make_shared<CompositeValidator>(); - wsValidator->add<WorkspaceUnitValidator>("Wavelength"); + auto wsValidator = boost::make_shared<WorkspaceUnitValidator>("Wavelength"); declareProperty(new WorkspaceProperty<>("InputWorkspace", "", Direction::Input, wsValidator)); diff --git a/Framework/WorkflowAlgorithms/src/HFIRLoad.cpp b/Framework/WorkflowAlgorithms/src/HFIRLoad.cpp index 986917a278f4ed47309b0d49c1a70fb07ee7873e..e0bf04db46e939d9bd85ae7d691fd70dbbdecc94 100644 --- a/Framework/WorkflowAlgorithms/src/HFIRLoad.cpp +++ b/Framework/WorkflowAlgorithms/src/HFIRLoad.cpp @@ -3,7 +3,6 @@ //---------------------------------------------------------------------- #include "MantidWorkflowAlgorithms/HFIRLoad.h" #include "MantidWorkflowAlgorithms/HFIRInstrument.h" -#include "MantidAPI/WorkspaceValidators.h" #include <MantidAPI/FileProperty.h> #include "Poco/NumberFormatter.h" #include "MantidKernel/BoundedValidator.h" diff --git a/Framework/WorkflowAlgorithms/src/RefReduction.cpp b/Framework/WorkflowAlgorithms/src/RefReduction.cpp index 4ece40c1ee5a6b08b584bceb6cc4eb34b8aee91b..9cc5678a2d2df87113a607c4a9ac52bc0976f26b 100644 --- a/Framework/WorkflowAlgorithms/src/RefReduction.cpp +++ b/Framework/WorkflowAlgorithms/src/RefReduction.cpp @@ -2,7 +2,6 @@ // Includes //---------------------------------------------------------------------- #include "MantidWorkflowAlgorithms/RefReduction.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidAPI/MatrixWorkspace.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidKernel/UnitFactory.h" @@ -629,6 +628,8 @@ double RefReduction::calculateAngleREFM(MatrixWorkspace_sptr workspace) { Mantid::Kernel::Property *prop = workspace->run().getProperty("SampleDetDis"); Mantid::Kernel::TimeSeriesProperty<double> *dp = dynamic_cast<Mantid::Kernel::TimeSeriesProperty<double> *>(prop); + if (!dp) + throw std::runtime_error("SampleDetDis was not a TimeSeriesProperty"); const double det_distance = dp->getStatistics().mean / 1000.0; double direct_beam_pix = getProperty("DirectPixel"); diff --git a/Framework/WorkflowAlgorithms/src/RefRoi.cpp b/Framework/WorkflowAlgorithms/src/RefRoi.cpp index 749b6985016a59cbf9128175a128c9e37e2e2720..075e69641f0e62ad3b877b1b5e9376c7470270fd 100644 --- a/Framework/WorkflowAlgorithms/src/RefRoi.cpp +++ b/Framework/WorkflowAlgorithms/src/RefRoi.cpp @@ -2,7 +2,7 @@ // Includes //---------------------------------------------------------------------- #include "MantidWorkflowAlgorithms/RefRoi.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/CommonBinsValidator.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidKernel/UnitFactory.h" #include "Poco/String.h" diff --git a/Framework/WorkflowAlgorithms/src/SANSBeamFinder.cpp b/Framework/WorkflowAlgorithms/src/SANSBeamFinder.cpp index b6d6835037646809ff3be516f62d22e18b7bf203..71df22fd7c07a21f80d56c4705e0e33911690513 100644 --- a/Framework/WorkflowAlgorithms/src/SANSBeamFinder.cpp +++ b/Framework/WorkflowAlgorithms/src/SANSBeamFinder.cpp @@ -3,7 +3,6 @@ //---------------------------------------------------------------------- #include "MantidWorkflowAlgorithms/SANSBeamFinder.h" #include "MantidDataObjects/EventWorkspace.h" -#include "MantidAPI/WorkspaceValidators.h" #include "Poco/Path.h" #include "Poco/String.h" #include "Poco/NumberFormatter.h" diff --git a/Framework/WorkflowAlgorithms/src/SANSSensitivityCorrection.cpp b/Framework/WorkflowAlgorithms/src/SANSSensitivityCorrection.cpp index 807806137409e9139a123f46a2b2b0be75f3d0c5..0cd3944adc2b6d71b3f434d5d675019aee8dd2c9 100644 --- a/Framework/WorkflowAlgorithms/src/SANSSensitivityCorrection.cpp +++ b/Framework/WorkflowAlgorithms/src/SANSSensitivityCorrection.cpp @@ -3,7 +3,6 @@ //---------------------------------------------------------------------- #include "MantidWorkflowAlgorithms/SANSSensitivityCorrection.h" #include "MantidDataObjects/EventWorkspace.h" -#include "MantidAPI/WorkspaceValidators.h" #include "MantidAPI/AnalysisDataService.h" #include "MantidDataObjects/TableWorkspace.h" #include "MantidKernel/TimeSeriesProperty.h" diff --git a/Framework/WorkflowAlgorithms/src/SANSSolidAngleCorrection.cpp b/Framework/WorkflowAlgorithms/src/SANSSolidAngleCorrection.cpp index d100a795e047dc7c6213ca3f1bbd635c89a0577a..dbceb9892670dabce847ec333ae46dabdd3b2606 100644 --- a/Framework/WorkflowAlgorithms/src/SANSSolidAngleCorrection.cpp +++ b/Framework/WorkflowAlgorithms/src/SANSSolidAngleCorrection.cpp @@ -2,13 +2,15 @@ // Includes //---------------------------------------------------------------------- #include "MantidWorkflowAlgorithms/SANSSolidAngleCorrection.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidGeometry/IDetector.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/EventList.h" #include "MantidDataObjects/TableWorkspace.h" #include "MantidAPI/AlgorithmProperty.h" #include "MantidAPI/PropertyManagerDataService.h" +#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/PropertyManager.h" namespace Mantid { diff --git a/Framework/WorkflowAlgorithms/src/StepScan.cpp b/Framework/WorkflowAlgorithms/src/StepScan.cpp index 4541b25d6eae0ecaea86cc41b15ff4131c4a5bb3..c3a9522b10e3faf1b0a7e525668ee38d568cb1aa 100644 --- a/Framework/WorkflowAlgorithms/src/StepScan.cpp +++ b/Framework/WorkflowAlgorithms/src/StepScan.cpp @@ -1,6 +1,6 @@ #include "MantidWorkflowAlgorithms/StepScan.h" #include "MantidAPI/ITableWorkspace.h" -#include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidKernel/ListValidator.h" #include "MantidKernel/UnitFactory.h" diff --git a/MantidPlot/pymantidplot/__init__.py b/MantidPlot/pymantidplot/__init__.py index f77ce7c983d7da2f2fb6446947c212e40fcbedd5..3ea6a0189f54e0505309f7f71b712aba68fe14c9 100644 --- a/MantidPlot/pymantidplot/__init__.py +++ b/MantidPlot/pymantidplot/__init__.py @@ -300,7 +300,9 @@ def plotMD(source, plot_axis=-2, normalization=DEFAULT_MD_NORMALIZATION, error_b Args: source: Workspace(s) to plot plot_axis: Index of the plot axis (defaults to auto-select) - normalization: Type of normalization required (defaults to volume) + normalization: Type of normalization required (defaults to volume, options available: + MDNormalization.NoNormalization, MDNormalization.NumEventsNormalization, and + MDNormalization.VolumeNormalization). error_bars: Flag for error bar plotting. window: window used for plotting. If None a new one will be created clearWindow: if is True, the window specified will be cleared before adding new curve diff --git a/MantidPlot/src/ApplicationWindow.cpp b/MantidPlot/src/ApplicationWindow.cpp index d9455438c81ff03c2f0516cc79f00b0934b5c201..3fa69dd633f1932060d53fc279973fe2ed4731c0 100644 --- a/MantidPlot/src/ApplicationWindow.cpp +++ b/MantidPlot/src/ApplicationWindow.cpp @@ -10153,6 +10153,7 @@ void ApplicationWindow::showGraphContextMenu() { QMenu axes(this); QMenu colour(this); QMenu normalization(this); + QMenu normMD(this); QMenu exports(this); QMenu copy(this); QMenu prints(this); @@ -10218,6 +10219,27 @@ void ApplicationWindow::showGraphContextMenu() { noNorm->setChecked(!ag->isDistribution()); binNorm->setChecked(ag->isDistribution()); cm.insertItem(tr("&Normalization"), &normalization); + } else if (ag->normalizableMD()) { + QAction *noNormMD = new QAction(tr("N&one"), &normMD); + noNormMD->setCheckable(true); + connect(noNormMD, SIGNAL(activated()), ag, SLOT(noNormalizationMD())); + normMD.addAction(noNormMD); + + QAction *volNormMD = new QAction(tr("&Volume"), &normMD); + volNormMD->setCheckable(true); + connect(volNormMD, SIGNAL(activated()), ag, SLOT(volumeNormalizationMD())); + normMD.addAction(volNormMD); + + QAction *eventsNormMD = new QAction(tr("&Events"), &normMD); + eventsNormMD->setCheckable(true); + connect(eventsNormMD, SIGNAL(activated()), ag, SLOT(numEventsNormalizationMD())); + normMD.addAction(eventsNormMD); + + int normalization = ag->normalizationMD(); + noNormMD->setChecked(0 == normalization); + volNormMD->setChecked(1 == normalization); + eventsNormMD->setChecked(2 == normalization); + cm.insertItem("MD &Normalization", &normMD); } QMenu plotType(this); diff --git a/MantidPlot/src/ConfigDialog.cpp b/MantidPlot/src/ConfigDialog.cpp index 6344d67d31cb6107058a72196d4b9b7feec1ac5a..87e74e4ea83cab6eb72537345019aeadb92dc4f3 100644 --- a/MantidPlot/src/ConfigDialog.cpp +++ b/MantidPlot/src/ConfigDialog.cpp @@ -2341,8 +2341,11 @@ void ConfigDialog::apply() QList<MdiSubWindow*> windows = app->windowsList(); foreach(MdiSubWindow *w, windows){ if (w->isA("MultiLayer")){ - (dynamic_cast<MultiLayer*>(w))->setScaleLayersOnPrint(boxScaleLayersOnPrint->isChecked()); - (dynamic_cast<MultiLayer*>(w))->printCropmarks(boxPrintCropmarks->isChecked()); + MultiLayer* multiLayer = dynamic_cast<MultiLayer*>(w); + if (multiLayer) { + multiLayer->setScaleLayersOnPrint(boxScaleLayersOnPrint->isChecked()); + multiLayer->printCropmarks(boxPrintCropmarks->isChecked()); + } } } // general page: application tab diff --git a/MantidPlot/src/ContourLinesEditor.cpp b/MantidPlot/src/ContourLinesEditor.cpp index 19ff48b3bf2c9a39d2da9d592d99f953a1315e9b..144b2c7f245cd9c0bbb736cbee787ba77a733413 100644 --- a/MantidPlot/src/ContourLinesEditor.cpp +++ b/MantidPlot/src/ContourLinesEditor.cpp @@ -108,10 +108,14 @@ void ContourLinesEditor::updateContourLevels() int rows = table->rowCount(); QwtValueList levels; - for (int i = 0; i < rows; i++) - levels << dynamic_cast<DoubleSpinBox*>(table->cellWidget(i, 0))->value(); + for (int i = 0; i < rows; i++) { + DoubleSpinBox *spinBox = + dynamic_cast<DoubleSpinBox *>(table->cellWidget(i, 0)); + if (spinBox) + levels << spinBox->value(); + } - d_spectrogram->setContourLevels(levels); + d_spectrogram->setContourLevels(levels); } void ContourLinesEditor::updateContourPens() diff --git a/MantidPlot/src/CustomActionDialog.cpp b/MantidPlot/src/CustomActionDialog.cpp index 0ffe792247682d974fbf3c6af8338c200fa32c61..8b779deb8ec2a2fb4978b0b5a1439b5d8ba7b504 100644 --- a/MantidPlot/src/CustomActionDialog.cpp +++ b/MantidPlot/src/CustomActionDialog.cpp @@ -514,7 +514,10 @@ void CustomActionDialog::chooseFolder() QAction * CustomActionDialog::actionAt(int row) { ApplicationWindow *app = dynamic_cast<ApplicationWindow *>(parent()); - QList<QAction *>actions = app->customActionsList(); + if (!app) + throw std::runtime_error( + "The parent of this dialog was not the Application Window"); + QList<QAction *>actions = app->customActionsList(); if (actions.isEmpty() || row < 0 || row >= actions.count()) return 0; diff --git a/MantidPlot/src/Graph.cpp b/MantidPlot/src/Graph.cpp index db3b3e6fcd290c43819c2df94f5f38d021aee8a4..b90d59c0c2ba39d003eb0589957f4663b3ab805e 100644 --- a/MantidPlot/src/Graph.cpp +++ b/MantidPlot/src/Graph.cpp @@ -60,6 +60,7 @@ #include "MantidAPI/AnalysisDataService.h" #include "Mantid/MantidMatrixCurve.h" +#include "Mantid/MantidMDCurve.h" #include "MantidQtAPI/PlotAxis.h" #include "MantidQtAPI/QwtRasterDataMD.h" #include "MantidQtAPI/QwtWorkspaceSpectrumData.h" @@ -209,6 +210,9 @@ Graph::Graph(int x, int y, int width, int height, QWidget* parent, Qt::WFlags f) m_isDistribution = false; m_normalizable = false; + + m_normalizableMD = false; + m_normalizationMD = 0; } void Graph::notifyChanges() @@ -1436,7 +1440,8 @@ void Graph::setAxisScale(int axis, double start, double end, int type, double st QwtScaleWidget *rightAxis = d_plot->axisWidget(QwtPlot::yRight); if(rightAxis) { - if (type == ScaleTransformation::Log10 && (start <= 0 || start == DBL_MAX)) + //if (type == ScaleTransformation::Log10 && (start <= 0 || start == DBL_MAX)) + if (type == GraphOptions::Log10 && (start <= 0 || start == DBL_MAX)) { start = sp->getMinPositiveValue(); } @@ -3411,12 +3416,15 @@ QString Graph::yAxisTitleFromFirstCurve() using namespace Mantid::API; QString wsName = firstCurve->workspaceName(); auto ws = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(wsName.toStdString()); - return MantidQt::API::PlotAxis(m_isDistribution, *ws).title(); - } - else - { - return axisTitle(0); + if (ws) + return MantidQt::API::PlotAxis(m_isDistribution, *ws).title(); + } else if (auto *firstCurve = dynamic_cast<MantidMDCurve*>(curve(0))) { + MantidQwtIMDWorkspaceData* data = firstCurve->mantidData(); + if (data) + return data->getYAxisLabel(); } + + return axisTitle(0); } void Graph::contextMenuEvent(QContextMenuEvent *e) @@ -5519,9 +5527,9 @@ void Graph::noNormalization() if(!m_isDistribution) return; // Nothing to do m_isDistribution = false; - updateDataCurves(); - d_plot->updateAxes(); - setYAxisTitle(yAxisTitleFromFirstCurve()); + + updateCurvesAndAxes(); + notifyChanges(); } @@ -5533,11 +5541,65 @@ void Graph::binWidthNormalization() if(m_isDistribution) return; // Nothing to do m_isDistribution = true; + + updateCurvesAndAxes(); + + notifyChanges(); +} + +/** + * Set 'None' normalization for MD plots + */ +void Graph::noNormalizationMD() +{ + if (!normalizableMD()) + return; + + setNormalizationMD(0); + + updateCurvesAndAxes(); + + notifyChanges(); +} + +/** + * Set volume normalization for MD plots + */ +void Graph::volumeNormalizationMD() +{ + if (!normalizableMD()) + return; + + setNormalizationMD(1); + + updateCurvesAndAxes(); + + notifyChanges(); +} + +/** + * Set number of events normalization for MD plots + */ +void Graph::numEventsNormalizationMD() +{ + if (!normalizableMD()) + return; + + setNormalizationMD(2); + + updateCurvesAndAxes(); + + notifyChanges(); +} + +/** + * Convenience method to use when updating the normalization types + * (whether Matrix or MD data normalizatio). + */ +void Graph::updateCurvesAndAxes() { updateDataCurves(); d_plot->updateAxes(); setYAxisTitle(yAxisTitleFromFirstCurve()); - - notifyChanges(); } void Graph::setWaterfallXOffset(int offset) @@ -5653,6 +5715,15 @@ void Graph::updateDataCurves() mc->invalidateBoundingRect(); mc->loadData(); } + else if (MantidMDCurve *mdc = dynamic_cast<MantidMDCurve*>(pc)) + { + //mdc->setDrawAsDistribution(m_isDistribution); + // yes, using int in Graph and ApplicationWindow instead of the proper enum, just so that + // IMDWorkspace.h does not need to be included in more places in MantidPlot + mdc->mantidData()->setNormalization(static_cast<Mantid::API::MDNormalization>(m_normalizationMD)); + mdc->invalidateBoundingRect(); + } + } QApplication::restoreOverrideCursor(); } diff --git a/MantidPlot/src/Graph.h b/MantidPlot/src/Graph.h index 9512139404943318a36ffc5dc9fa343d9fc82d7d..34ae08f03ca7eacf89224cf0b37a0bffcc81b19d 100644 --- a/MantidPlot/src/Graph.h +++ b/MantidPlot/src/Graph.h @@ -209,6 +209,20 @@ public slots: bool isDistribution() const { return m_isDistribution; } void setDistribution(const bool on) { m_isDistribution = on; } + void noNormalizationMD(); + void numEventsNormalizationMD(); + void volumeNormalizationMD(); + + /// normalizable in the MD sense, don't confuse with (bin width) normalizable(), + /// True if this is a plot MD + bool normalizableMD() const { return m_normalizableMD; } + void setNormalizableMD(const bool on) { m_normalizableMD = on; } + + /// when using MD curves (true == normalizbleMD()), what type of normalization + int normalizationMD() const { return m_normalizationMD; } + void setNormalizationMD(const int normalization) { m_normalizationMD = normalization; } + + //! Accessor method for #d_plot. Plot* plotWidget(){return d_plot;}; @@ -813,6 +827,8 @@ private: QString yAxisTitleFromFirstCurve(); + void updateCurvesAndAxes(); + Plot *d_plot; QwtPlotZoomer *d_zoomer[2]; TitlePicker *titlePicker; @@ -877,6 +893,12 @@ private: bool m_isDistribution; // True, if the graph can be plotted as distribution bool m_normalizable; + + // True if the graph is an MD plot and can be normalized (none, volume, events) + bool m_normalizableMD; + /// type of normalization for MD curves + int m_normalizationMD; + // x and y units of MantidCurves boost::shared_ptr<Mantid::Kernel::Unit> m_xUnits; boost::shared_ptr<Mantid::Kernel::Unit> m_yUnits; diff --git a/MantidPlot/src/ImportASCIIDialog.cpp b/MantidPlot/src/ImportASCIIDialog.cpp index 44c2ff0105b2c0636fe4a8fcebce9f9dbdcb0dcd..075910ef35fb89d929af75626a20ae8a6845b781 100644 --- a/MantidPlot/src/ImportASCIIDialog.cpp +++ b/MantidPlot/src/ImportASCIIDialog.cpp @@ -450,62 +450,67 @@ void ImportASCIIDialog::preview() void ImportASCIIDialog::previewTable() { - if (!d_preview_table) - return; + if (!d_preview_table) + return; - if (!d_preview_table->isVisible()) - d_preview_table->show(); + if (!d_preview_table->isVisible()) + d_preview_table->show(); - if (d_current_path.trimmed().isEmpty()){ - d_preview_table->clear(); - d_preview_table->resetHeader(); - return; - } + if (d_current_path.trimmed().isEmpty()){ + d_preview_table->clear(); + d_preview_table->resetHeader(); + return; + } - int importMode = d_import_mode->currentIndex(); - if (importMode == NewTables) - importMode = Table::Overwrite; - else - importMode -= 2; - - d_preview_table->resetHeader(); - d_preview_table->importASCII(d_current_path, columnSeparator(), d_ignored_lines->value(), - d_rename_columns->isChecked(), d_strip_spaces->isChecked(), - d_simplify_spaces->isChecked(), d_import_comments->isChecked(), - d_comment_string->text(), (Table::ImportMode)importMode, - boxEndLine->currentIndex(), d_preview_lines_box->value()); - - if (d_import_dec_separators->isChecked()) - d_preview_table->updateDecimalSeparators(decimalSeparators()); - if (!d_preview_table->isVisible()) - d_preview_table->show(); + int importMode = d_import_mode->currentIndex(); + if (importMode == NewTables) { + importMode = (ImportASCIIDialog::ImportMode)Table::Overwrite; + } else { + importMode -= 2; + } + + d_preview_table->resetHeader(); + d_preview_table->importASCII(d_current_path, columnSeparator(), d_ignored_lines->value(), + d_rename_columns->isChecked(), d_strip_spaces->isChecked(), + d_simplify_spaces->isChecked(), d_import_comments->isChecked(), + d_comment_string->text(), (Table::ImportMode)importMode, + boxEndLine->currentIndex(), d_preview_lines_box->value()); + + if (d_import_dec_separators->isChecked()) + d_preview_table->updateDecimalSeparators(decimalSeparators()); + + if (!d_preview_table->isVisible()) + d_preview_table->show(); } -void ImportASCIIDialog::previewMatrix() -{ - if (!d_preview_matrix) - return; +void ImportASCIIDialog::previewMatrix() { + if (!d_preview_matrix) + return; - if (d_current_path.trimmed().isEmpty()){ - d_preview_matrix->clear(); - return; - } + if (d_current_path.trimmed().isEmpty()) { + d_preview_matrix->clear(); + return; + } - int importMode = d_import_mode->currentIndex(); - if (importMode == NewMatrices) - importMode = Matrix::Overwrite; - else - importMode -= 2; + int importMode = d_import_mode->currentIndex(); + if (importMode == NewMatrices) { + importMode = (ImportASCIIDialog::ImportMode)Matrix::Overwrite; + } else { + // Overwrite-2 => NewColumns (in both Matrix::importMode and + // ImportASCIIDialog::importMode) + importMode -= 2; + } - QLocale locale = d_preview_matrix->locale(); - if(d_import_dec_separators->isChecked()) - locale = decimalSeparators(); + QLocale locale = d_preview_matrix->locale(); + if (d_import_dec_separators->isChecked()) + locale = decimalSeparators(); - d_preview_matrix->importASCII(d_current_path, columnSeparator(), d_ignored_lines->value(), - d_strip_spaces->isChecked(), d_simplify_spaces->isChecked(), - d_comment_string->text(), importMode, locale, - boxEndLine->currentIndex(), d_preview_lines_box->value()); - d_preview_matrix->resizeColumnsToContents(); + d_preview_matrix->importASCII( + d_current_path, columnSeparator(), d_ignored_lines->value(), + d_strip_spaces->isChecked(), d_simplify_spaces->isChecked(), + d_comment_string->text(), importMode, locale, boxEndLine->currentIndex(), + d_preview_lines_box->value()); + d_preview_matrix->resizeColumnsToContents(); } void ImportASCIIDialog::changePreviewFile(const QString& path) @@ -542,8 +547,8 @@ void ImportASCIIDialog::setNewWindowsOnly(bool on) if (on){ d_import_mode->clear(); d_import_mode->addItem(tr("New Table")); - d_import_mode->addItem(tr("New Matrice")); - d_import_mode->addItem(tr("New Workspace")); + d_import_mode->addItem(tr("New Matrix")); + d_import_mode->addItem(tr("New Workspace")); } d_preview_button->setChecked(false); diff --git a/MantidPlot/src/Mantid/InstrumentWidget/InstrumentActor.cpp b/MantidPlot/src/Mantid/InstrumentWidget/InstrumentActor.cpp index 5e35f163b3589f562ab5ea69a329485be9cd5c8e..5c0e4b60da7f2cdbfbfe322332e9c4b39058df5e 100644 --- a/MantidPlot/src/Mantid/InstrumentWidget/InstrumentActor.cpp +++ b/MantidPlot/src/Mantid/InstrumentWidget/InstrumentActor.cpp @@ -1,35 +1,37 @@ #include "InstrumentActor.h" #include "CompAssemblyActor.h" -#include "ObjComponentActor.h" -#include "SampleActor.h" #include "ComponentActor.h" +#include "GLActorVisitor.h" #include "ObjCompAssemblyActor.h" +#include "ObjComponentActor.h" #include "RectangularDetectorActor.h" -#include "GLActorVisitor.h" +#include "SampleActor.h" -#include "MantidKernel/Exception.h" -#include "MantidKernel/V3D.h" -#include "MantidKernel/ConfigService.h" -#include "MantidGeometry/Objects/Object.h" -#include "MantidGeometry/ICompAssembly.h" -#include "MantidGeometry/IObjComponent.h" -#include "MantidAPI/MatrixWorkspace.h" -#include "MantidAPI/IMaskWorkspace.h" #include "MantidAPI/AnalysisDataService.h" +#include "MantidAPI/CommonBinsValidator.h" #include "MantidAPI/FrameworkManager.h" #include "MantidAPI/IAlgorithm.h" +#include "MantidAPI/IMaskWorkspace.h" +#include "MantidAPI/MatrixWorkspace.h" #include "MantidAPI/WorkspaceFactory.h" -#include "MantidAPI/WorkspaceValidators.h" -#include <boost/math/special_functions/fpclassify.hpp> +#include "MantidGeometry/Objects/Object.h" +#include "MantidGeometry/ICompAssembly.h" +#include "MantidGeometry/IDTypes.h" +#include "MantidGeometry/IObjComponent.h" + +#include "MantidKernel/ConfigService.h" +#include "MantidKernel/Exception.h" +#include "MantidKernel/ReadLock.h" +#include "MantidKernel/V3D.h" + #include <boost/algorithm/string.hpp> +#include <boost/math/special_functions/fpclassify.hpp> -#include <QSettings> #include <QMessageBox> +#include <QSettings> #include <numeric> -#include "MantidGeometry/IDTypes.h" -#include "MantidKernel/ReadLock.h" using namespace Mantid::Kernel::Exception; using namespace Mantid::Geometry; diff --git a/MantidPlot/src/Mantid/InstrumentWidget/OpenGLError.cpp b/MantidPlot/src/Mantid/InstrumentWidget/OpenGLError.cpp index 8da241a02ea906a903b8742b08ca3c812e99e00f..afa7126f7499db695f9a5f731a0b5a23eb26f4bc 100644 --- a/MantidPlot/src/Mantid/InstrumentWidget/OpenGLError.cpp +++ b/MantidPlot/src/Mantid/InstrumentWidget/OpenGLError.cpp @@ -33,3 +33,8 @@ std::ostream& OpenGLError::log() { return g_log.error(); } + +std::ostream& OpenGLError::logDebug() +{ + return g_log.debug(); +} diff --git a/MantidPlot/src/Mantid/InstrumentWidget/OpenGLError.h b/MantidPlot/src/Mantid/InstrumentWidget/OpenGLError.h index cdeb10d98f2ca333a20654e82d640597988998f8..c5e63188a828b6325d5725d70a9a11ba5006b648 100644 --- a/MantidPlot/src/Mantid/InstrumentWidget/OpenGLError.h +++ b/MantidPlot/src/Mantid/InstrumentWidget/OpenGLError.h @@ -16,6 +16,8 @@ public: static bool check(const std::string& funName); static bool hasError(const std::string& funName){return check(funName);} static std::ostream& log(); + static std::ostream& logDebug(); + private: std::string m_msg; }; diff --git a/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.cpp b/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.cpp index 1c6a0052da5fb529510990d2b153790c8ae3dee3..37a85ee1cfdd7f02149a70bff5c8a43c632989ad 100644 --- a/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.cpp +++ b/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.cpp @@ -220,7 +220,8 @@ void ProjectionSurface::draw(MantidGLWidget *widget,bool picking)const getController()->onPaint( painter ); painter.end(); // Discard any error generated here - glGetError(); + GLuint ecode = glGetError(); + OpenGLError::logDebug() << "Discarding OpenGL error: " << gluErrorString(ecode); } } diff --git a/MantidPlot/src/Mantid/InstrumentWidget/UnwrappedSurface.cpp b/MantidPlot/src/Mantid/InstrumentWidget/UnwrappedSurface.cpp index d83662b41b3b486ee0e4da6bce7f7fb13c2a5f1c..77766f8eff2801fa872fa1d9c612ba5122370e61 100644 --- a/MantidPlot/src/Mantid/InstrumentWidget/UnwrappedSurface.cpp +++ b/MantidPlot/src/Mantid/InstrumentWidget/UnwrappedSurface.cpp @@ -581,8 +581,8 @@ void UnwrappedSurface::drawSimpleToImage(QImage* image,bool picking)const if ( iw < 4 ) iw = 4; if ( ih < 4 ) ih = 4; - double w = (iw == 0)? dw : udet.width/2; - double h = (ih == 0)? dh : udet.height/2; + double w = udet.width/2; + double h = udet.height/2; if (!(m_viewRect.contains(udet.u-w, udet.v-h) || m_viewRect.contains(udet.u+w, udet.v+h))) continue; diff --git a/MantidPlot/src/Mantid/MantidUI.cpp b/MantidPlot/src/Mantid/MantidUI.cpp index d076bdf157480feeeb4f10b4ff922a8c1a7c90e4..f6ddf9efda70d0a46db18176e62f79426ebffe43 100644 --- a/MantidPlot/src/Mantid/MantidUI.cpp +++ b/MantidPlot/src/Mantid/MantidUI.cpp @@ -617,6 +617,9 @@ MultiLayer* MantidUI::plotMDList(const QStringList& wsNames, const int plotAxis, data->setPlotAxisChoice(plotAxis); data->setNormalization(normalization); + g->setNormalizableMD(true); + g->setNormalizationMD(normalization); + // Using information from the first graph if( i == 0 && isGraphNew ) g->setAutoScale(); diff --git a/MantidPlot/src/ScaleDetails.cpp b/MantidPlot/src/ScaleDetails.cpp index 71190376094ff0093f8972b303d2eba67214edcd..e6ef88b10316eb1eaf83abc126038653d8a710d5 100644 --- a/MantidPlot/src/ScaleDetails.cpp +++ b/MantidPlot/src/ScaleDetails.cpp @@ -272,6 +272,10 @@ void ScaleDetails::initWidgets() if (type == ScaleDraw::Date) { ScaleDraw *sclDraw = dynamic_cast<ScaleDraw *>(d_plot->axisScaleDraw(m_mappedaxis)); + if (!sclDraw) { + throw std::runtime_error("Could not convert the axis Scale Draw object " + "to a ScaleDraw object"); + } QDateTime origin = sclDraw->dateTimeOrigin(); m_dspnStart->hide(); diff --git a/MantidPlot/src/importOPJ.cpp b/MantidPlot/src/importOPJ.cpp index f5d393e96b4239a28a8c3f23f98e9eabfeca5a7d..458e67fe47debd7431cdd9268e58cb0edb4594b5 100644 --- a/MantidPlot/src/importOPJ.cpp +++ b/MantidPlot/src/importOPJ.cpp @@ -702,6 +702,8 @@ bool ImportOPJ::importGraphs(const OPJFile& opj) break; case 'F': s=opj.functionIndex(data.right(data.length()-2).toStdString().c_str()); + if (s<0) + break; int type; if(opj.functionType(s)==1)//Polar { diff --git a/MantidPlot/src/origin/OPJFile.cpp b/MantidPlot/src/origin/OPJFile.cpp index c0eaf257564f31fb9b64b0ffd2f0ac8fb75696b6..73c397f65f2b0677228b8845a3ee1219b7708505 100644 --- a/MantidPlot/src/origin/OPJFile.cpp +++ b/MantidPlot/src/origin/OPJFile.cpp @@ -52,6 +52,7 @@ #include <stdio.h> #include <stdlib.h> +#include <limits.h> #include <math.h> #include <cstring> #include <algorithm> //required for std::swap @@ -1327,6 +1328,12 @@ void OPJFile::readSpreadInfo(FILE *f, FILE *debug) fread(&sec_size,4,1,f); if(IsBigEndian()) SwapBytes(sec_size); + if (INT_MAX == sec_size) { + // this would end in an overflow and it's obviously wrong + fprintf(debug, "Error: while reading spread info, found section size: %d\n", sec_size); + fflush(debug); + } + //section_body_1 LAYER+=0x5; fseek(f,LAYER,SEEK_SET); @@ -1335,6 +1342,9 @@ void OPJFile::readSpreadInfo(FILE *f, FILE *debug) if(col_index!=-1) { char *stmp=new char[sec_size+1]; + if (!stmp) + break; + stmp[sec_size]='\0'; fread(stmp,sec_size,1,f); SPREADSHEET[spread].column[col_index].command=stmp; @@ -1552,6 +1562,12 @@ void OPJFile::readExcelInfo(FILE *f, FILE *debug) fread(&sec_size,4,1,f); if(IsBigEndian()) SwapBytes(sec_size); + if (INT_MAX == sec_size) { + // this would end in an overflow for new[] below and it's obviously wrong + fprintf(debug, "Error: while reading Excel info, found section size: %d\n", sec_size); + fflush(debug); + } + //section_body_1 LAYER+=0x5; fseek(f,LAYER,SEEK_SET); @@ -1802,6 +1818,12 @@ void OPJFile::readMatrixInfo(FILE *f, FILE *debug) fread(&sec_size,4,1,f); if(IsBigEndian()) SwapBytes(sec_size); + if (INT_MAX == sec_size) { + // this would end in an overflow for new[] below and it's obviously wrong + fprintf(debug, "Error: while reading matrix info, found section size: %d\n", sec_size); + fflush(debug); + } + //section_body_1 LAYER+=0x5; //check if it is a formula @@ -2933,11 +2955,17 @@ void OPJFile::readProjectTreeFolder(FILE *f, FILE *debug, tree<projectNode>::ite fread(&namesize,4,1,f); if(IsBigEndian()) SwapBytes(namesize); - POS+=5; + if (INT_MAX == namesize) { + // this would cause an overflow and it's anyway obviously wrong + fprintf(debug, "Error: while reading project tree folder, found project/folder name size: %d\n", namesize); + fflush(debug); + } // read folder name char* name=new char[namesize+1]; name[namesize]='\0'; + + POS+=5; fseek(f,POS,SEEK_SET); fread(name,namesize,1,f); tree<projectNode>::iterator current_folder=projectTree.append_child(parent, projectNode(name, 1, creation_date, modification_date)); diff --git a/MantidPlot/src/zlib123/minigzip.c b/MantidPlot/src/zlib123/minigzip.c index 6f12762c8ecedb7a71ddf33c3f7f848178ba3075..5263508908db17952ab8df54cbd0d1bfc0575657 100644 --- a/MantidPlot/src/zlib123/minigzip.c +++ b/MantidPlot/src/zlib123/minigzip.c @@ -209,8 +209,9 @@ void file_compress(file, mode) FILE *in; gzFile out; - strcpy(outfile, file); - strcat(outfile, GZ_SUFFIX); + strncpy(outfile, file, MAX_NAME_LEN-1); + outfile[MAX_NAME_LEN-1] = '\0'; + strncat(outfile, GZ_SUFFIX, MAX_NAME_LEN - strlen(outfile) - 1); in = fopen(file, "rb"); if (in == NULL) { diff --git a/MantidQt/CustomDialogs/inc/MantidQtCustomDialogs/GetNegMuMuonicXRDDialog.h b/MantidQt/CustomDialogs/inc/MantidQtCustomDialogs/GetNegMuMuonicXRDDialog.h index 85fa109a4511bb3ef96de179827dc54d33baab32..4d375e8cdc124c9d04bf0274f849ee4f597b7a13 100644 --- a/MantidQt/CustomDialogs/inc/MantidQtCustomDialogs/GetNegMuMuonicXRDDialog.h +++ b/MantidQt/CustomDialogs/inc/MantidQtCustomDialogs/GetNegMuMuonicXRDDialog.h @@ -36,19 +36,20 @@ namespace CustomDialogs { class GetNegMuMuonicXRDDialog : public API::AlgorithmDialog { Q_OBJECT - public: +public: /// Constructor GetNegMuMuonicXRDDialog(QWidget *parent = 0); - private: +private: /// Periodic Table widget used for selection of elements property - PeriodicTableWidget *periodicTable; + PeriodicTableWidget *m_periodicTable; /// QLineEdit used for input of y-position property - QLineEdit *yPosition; + QLineEdit *m_yPosition; /// QLineEdit used for input of GroupWorkspaceSpace - QLineEdit *groupWorkspaceNameInput; - //Check box for showing or hiding the Legend for PeriodicTableWidget - QCheckBox *showLegendCheck; + QLineEdit *m_groupWorkspaceNameInput; + // Check box for showing or hiding the Legend for PeriodicTableWidget + QCheckBox *m_showLegendCheck; + /// Validate that the input is not empty before running algorithm bool validateDialogInput(QString input); /** Enables a the buttons corresponding to the elements @@ -56,15 +57,15 @@ class GetNegMuMuonicXRDDialog : public API::AlgorithmDialog { */ void enableElementsForGetNegMuMuonicXRD(); - private slots: +private slots: /// When the "Run" button is clicked, the algorithm is executed with inputs void runClicked(); void showLegend(); - protected: +protected: // create the initial layout void initLayout(); - signals: +signals: /// signal emitted when validateDialogInput passes void validInput(); }; diff --git a/MantidQt/CustomDialogs/src/GetNegMuMuonicXRDDialog.cpp b/MantidQt/CustomDialogs/src/GetNegMuMuonicXRDDialog.cpp index 963da0325e8764e67562bd8801154cbca51c2648..463fae15e31cc0b36834b70bb1dfbef1ecd0c5a8 100644 --- a/MantidQt/CustomDialogs/src/GetNegMuMuonicXRDDialog.cpp +++ b/MantidQt/CustomDialogs/src/GetNegMuMuonicXRDDialog.cpp @@ -7,7 +7,6 @@ #include <QValidator> #include <QFormLayout> - namespace MantidQt { namespace CustomDialogs { DECLARE_DIALOG(GetNegMuMuonicXRDDialog) @@ -18,7 +17,8 @@ DECLARE_DIALOG(GetNegMuMuonicXRDDialog) */ GetNegMuMuonicXRDDialog::GetNegMuMuonicXRDDialog(QWidget *parent) - : API::AlgorithmDialog(parent) {} + : API::AlgorithmDialog(parent), m_periodicTable(NULL), m_yPosition(NULL), + m_groupWorkspaceNameInput(NULL), m_showLegendCheck(NULL) {} /// Initialise the layout void GetNegMuMuonicXRDDialog::initLayout() { @@ -26,18 +26,18 @@ void GetNegMuMuonicXRDDialog::initLayout() { this->setMaximumHeight(400); this->setMaximumWidth(675); // assign periodicTable member to a new periodicTable - periodicTable = new PeriodicTableWidget(); + m_periodicTable = new PeriodicTableWidget(); - // assign yPosition member to a new QLineEdit - yPosition = new QLineEdit(); - //assign GroupWorkspaceName member to a new QLineEdit - groupWorkspaceNameInput = new QLineEdit(); + // assign m_yPosition member to a new QLineEdit + m_yPosition = new QLineEdit(); + // assign GroupWorkspaceName member to a new QLineEdit + m_groupWorkspaceNameInput = new QLineEdit(); auto *groupWsInputLabel = new QLabel("OutputWorkspace"); - groupWorkspaceNameInput->setMaximumWidth(250); + m_groupWorkspaceNameInput->setMaximumWidth(250); // Disable all buttons on the periodicTable // as we only have a select few that need to be // enabled. - periodicTable->disableAllElementButtons(); + m_periodicTable->disableAllElementButtons(); /*Elements Enabled Correspond to those for which we * have data for in the dictionary found in @@ -51,44 +51,44 @@ void GetNegMuMuonicXRDDialog::initLayout() { // run button for executing the algorithm auto *runButton = new QPushButton("Run"); - // label for the QLineEdit for yPosition property - auto *yPositionLabel = new QLabel("Y Position"); + // label for the QLineEdit for m_yPosition property + auto *m_yPositionLabel = new QLabel("Y Position"); - /*validator allows only numeric input for yPosition + /*validator allows only numeric input for m_yPosition *this helps with validating the input. *Does not detect empty string as invalid input. */ - auto yPositionNumericValidator = new QDoubleValidator(); + auto m_yPositionNumericValidator = new QDoubleValidator(); // YPosition LineEdit Attributes - yPosition->setMaximumWidth(250); - yPosition->setPlaceholderText("-0.01"); - yPosition->setValidator(yPositionNumericValidator); + m_yPosition->setMaximumWidth(250); + m_yPosition->setPlaceholderText("-0.01"); + m_yPosition->setValidator(m_yPositionNumericValidator); // Run Button Attributes and signal/slot assignment runButton->setMaximumWidth(100); connect(runButton, SIGNAL(clicked()), this, SLOT(runClicked())); connect(this, SIGNAL(validInput()), this, SLOT(accept())); - //Show Legend button attributes and signal/slot asssignment - showLegendCheck = new QCheckBox("Show Legend"); - connect(showLegendCheck, SIGNAL(clicked()), this, SLOT(showLegend())); + // Show Legend button attributes and signal/slot asssignment + m_showLegendCheck = new QCheckBox("Show Legend"); + connect(m_showLegendCheck, SIGNAL(clicked()), this, SLOT(showLegend())); // Adding Widgets to Layout - main_layout->addWidget(periodicTable); - main_layout->addWidget(showLegendCheck); - main_layout->addWidget(yPositionLabel); - main_layout->addWidget(yPosition); + main_layout->addWidget(m_periodicTable); + main_layout->addWidget(m_showLegendCheck); + main_layout->addWidget(m_yPositionLabel); + main_layout->addWidget(m_yPosition); main_layout->addWidget(groupWsInputLabel); - main_layout->addWidget(groupWorkspaceNameInput); + main_layout->addWidget(m_groupWorkspaceNameInput); main_layout->addWidget(runButton); } /** * */ -void GetNegMuMuonicXRDDialog::showLegend(){ - bool checked = showLegendCheck->isChecked(); - periodicTable->showGroupLegend(checked); +void GetNegMuMuonicXRDDialog::showLegend() { + bool checked = m_showLegendCheck->isChecked(); + m_periodicTable->showGroupLegend(checked); } /** @@ -102,13 +102,13 @@ void GetNegMuMuonicXRDDialog::enableElementsForGetNegMuMuonicXRD() { * for the algorithm, and the button for that element can be enabled * the same as the elements are below. */ - periodicTable->enableButtonByName("Au"); - periodicTable->enableButtonByName("Ag"); - periodicTable->enableButtonByName("Cu"); - periodicTable->enableButtonByName("Zn"); - periodicTable->enableButtonByName("Pb"); - periodicTable->enableButtonByName("As"); - periodicTable->enableButtonByName("Sn"); + m_periodicTable->enableButtonByName("Au"); + m_periodicTable->enableButtonByName("Ag"); + m_periodicTable->enableButtonByName("Cu"); + m_periodicTable->enableButtonByName("Zn"); + m_periodicTable->enableButtonByName("Pb"); + m_periodicTable->enableButtonByName("As"); + m_periodicTable->enableButtonByName("Sn"); } /** @@ -128,7 +128,7 @@ bool GetNegMuMuonicXRDDialog::validateDialogInput(QString input) { */ void GetNegMuMuonicXRDDialog::runClicked() { // getting a list of strings of elements selected from periodicTableWidget - QString elementsSelectedStr = periodicTable->getAllCheckedElementsStr(); + QString elementsSelectedStr = m_periodicTable->getAllCheckedElementsStr(); // if no elements are selected from the PeriodicTableWidget, a pop-up appears // to the user. if (!validateDialogInput(elementsSelectedStr)) { @@ -141,15 +141,16 @@ void GetNegMuMuonicXRDDialog::runClicked() { // signal. if (validateDialogInput(elementsSelectedStr)) { storePropertyValue("Elements", elementsSelectedStr); - if (validateDialogInput(yPosition->text())) { - storePropertyValue("YAxisPosition", yPosition->text()); + if (validateDialogInput(m_yPosition->text())) { + storePropertyValue("YAxisPosition", m_yPosition->text()); } else { - // used as default value for yPosition property if the user does not input + // used as default value for m_yPosition property if the user does not + // input // one. - storePropertyValue("YAxisPosition", yPosition->placeholderText()); + storePropertyValue("YAxisPosition", m_yPosition->placeholderText()); } - if (validateDialogInput(groupWorkspaceNameInput->text())){ - storePropertyValue("OutputWorkspace", groupWorkspaceNameInput->text()); + if (validateDialogInput(m_groupWorkspaceNameInput->text())) { + storePropertyValue("OutputWorkspace", m_groupWorkspaceNameInput->text()); } emit validInput(); } diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionPresenter.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionPresenter.h index ab2cb4672c86bae2b479c406c6ba8a9076e5fe9b..5c4f2dba65bcd8cfe98cfdd5f0f267ba89a52a9b 100644 --- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionPresenter.h +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionPresenter.h @@ -11,6 +11,8 @@ #include <boost/scoped_ptr.hpp> +#include <Poco/Path.h> + #include <QObject> class QThread; @@ -176,6 +178,23 @@ private: Mantid::API::ITableWorkspace_sptr &vanIntegWS, Mantid::API::MatrixWorkspace_sptr &vanCurvesWS); + // plots workspace according to the user selection + void plotFocusedWorkspace(std::string outWSName, std::string bank); + + // algorithms to save the generated workspace + void saveGSS(std::string inputWorkspace, std::string bank, std::string runNo); + void saveFocusedXYE(std::string inputWorkspace, std::string bank, + std::string runNo); + void saveOpenGenie(std::string inputWorkspace, std::string specNums, + std::string bank, std::string runNo); + + // generates the required file name of the output files + std::string outFileNameFactory(std::string inputWorkspace, std::string runNo, + std::string bank, std::string format); + + // generates a directory if not found and handles the path + Poco::Path outFilesDir(std::string runNo); + /// string to use for ENGINX file names (as a prefix, etc.) const static std::string g_enginxStr; @@ -192,6 +211,9 @@ private: /// true if the last focusing completed successfully bool m_focusFinishedOK; + /// Counter for the cropped output files + static int g_croppedCounter; + /// Associated view for this presenter (MVP pattern) IEnggDiffractionView *const m_view; diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionQtTabCalib.ui b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionQtTabCalib.ui index cfd09d9f143835bce84f95d414ecd3e64cd86f96..6381604907d9e6602362cb87b8b9f8afccd1f7bc 100644 --- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionQtTabCalib.ui +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionQtTabCalib.ui @@ -168,32 +168,30 @@ <bool>false</bool> </property> <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0"> - <widget class="QLabel" name="label_new_vanadium_num"> - <property name="text"> - <string>Vanadium #:</string> - </property> - </widget> - </item> <item row="0" column="1" colspan="2"> - <widget class="QLineEdit" name="lineEdit_new_vanadium_num"> - <property name="text"> + <widget class="MantidQt::MantidWidgets::MWRunFiles" name="lineEdit_new_vanadium_num" native="true"> + <property name="text" stdset="0"> <string>236516</string> </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="label_new_ceria_num"> - <property name="text"> - <string>Calibration sample #:</string> + <property name="label" stdset="0"> + <string>Vanadium #:</string> + </property> + <property name="multipleFiles" stdset="0"> + <bool>true</bool> </property> </widget> </item> <item row="1" column="1" colspan="2"> - <widget class="QLineEdit" name="lineEdit_new_ceria_num"> - <property name="text"> + <widget class="MantidQt::MantidWidgets::MWRunFiles" name="lineEdit_new_ceria_num" native="true"> + <property name="text" stdset="0"> <string>241391</string> </property> + <property name="label" stdset="0"> + <string>Calibration sample #:</string> + </property> + <property name="multipleFiles" stdset="0"> + <bool>true</bool> + </property> </widget> </item> <item row="2" column="0" colspan="2"> @@ -216,6 +214,20 @@ </property> </widget> </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_new_ceria_num"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label_new_vanadium_num"> + <property name="text"> + <string/> + </property> + </widget> + </item> </layout> </widget> </item> @@ -236,6 +248,13 @@ </item> </layout> </widget> + <customwidgets> + <customwidget> + <class>MantidQt::MantidWidgets::MWRunFiles</class> + <extends>QWidget</extends> + <header>MantidQtMantidWidgets/MWRunFiles.h</header> + </customwidget> + </customwidgets> <resources/> <connections/> </ui> diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionQtTabFocus.ui b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionQtTabFocus.ui index da4954af8627faf0c93a9d1c3268b22d655fb790..b6f46a4ab6b44f102950099e87f1ce59e34e8819 100644 --- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionQtTabFocus.ui +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionQtTabFocus.ui @@ -7,30 +7,123 @@ <x>0</x> <y>0</y> <width>614</width> - <height>533</height> + <height>551</height> </rect> </property> <property name="windowTitle"> <string>Form</string> </property> - <layout class="QGridLayout" name="gridLayout_3"> - <item row="6" column="0"> - <widget class="QGroupBox" name="groupBox_focus_2"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="groupBox_focus"> <property name="title"> - <string>Output</string> + <string>Focus run</string> </property> - <layout class="QGridLayout" name="gridLayout_2"> + <layout class="QGridLayout" name="gridLayout"> + <item row="1" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout_5"> + <item> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <item> + <widget class="QLabel" name="label_banks_sel"> + <property name="text"> + <string>Banks:</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_5"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>298</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="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>18</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="QCheckBox" name="checkBox_focus_bank1"> + <property name="text"> + <string>1</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_focus_bank2"> + <property name="text"> + <string>2</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + <item row="2" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>238</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="pushButton_focus"> + <property name="text"> + <string>Focus</string> + </property> + </widget> + </item> + </layout> + </item> <item row="0" column="0"> - <layout class="QHBoxLayout" name="horizontalLayout_6"> + <layout class="QHBoxLayout" name="horizontalLayout"> <item> - <widget class="QCheckBox" name="checkBox_FocusedWS"> + <widget class="QLabel" name="label_run_num"> <property name="text"> - <string>Plot Focused Workspace</string> + <string/> </property> </widget> </item> <item> - <spacer name="horizontalSpacer_4"> + <spacer name="horizontalSpacer"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> @@ -42,12 +135,28 @@ </property> </spacer> </item> + <item> + <widget class="MantidQt::MantidWidgets::MWRunFiles" name="lineEdit_run_num" native="true"> + <property name="text" stdset="0"> + <string/> + </property> + <property name="readOnly" stdset="0"> + <bool>false</bool> + </property> + <property name="label" stdset="0"> + <string>Run #:</string> + </property> + <property name="multipleFiles" stdset="0"> + <bool>true</bool> + </property> + </widget> + </item> </layout> </item> </layout> </widget> </item> - <item row="2" column="0"> + <item> <widget class="QGroupBox" name="groupBox"> <property name="title"> <string>Focus Cropped</string> @@ -58,7 +167,7 @@ <item> <widget class="QLabel" name="label_cropped_run_num"> <property name="text"> - <string>Run #:</string> + <string/> </property> </widget> </item> @@ -76,13 +185,19 @@ </spacer> </item> <item> - <widget class="QLineEdit" name="lineEdit_cropped_run_num"> - <property name="text"> + <widget class="MantidQt::MantidWidgets::MWRunFiles" name="lineEdit_cropped_run_num" native="true"> + <property name="text" stdset="0"> <string/> </property> - <property name="readOnly"> + <property name="readOnly" stdset="0"> <bool>false</bool> </property> + <property name="label" stdset="0"> + <string>Run #:</string> + </property> + <property name="multipleFiles" stdset="0"> + <bool>true</bool> + </property> </widget> </item> </layout> @@ -148,147 +263,102 @@ </layout> </widget> </item> - <item row="4" column="0"> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>388</height> - </size> - </property> - </spacer> - </item> - <item row="0" column="0"> - <widget class="QGroupBox" name="groupBox_focus"> + <item> + <widget class="QGroupBox" name="groupBox_2"> <property name="title"> - <string>Focus run</string> + <string>Focus Texture</string> </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="2" column="0"> - <layout class="QHBoxLayout" name="horizontalLayout_3"> + <layout class="QGridLayout" name="gridLayout_4"> + <item row="0" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout_7"> <item> - <spacer name="horizontalSpacer_3"> + <widget class="QLabel" name="label_texture_run_num"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_6"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> - <width>238</width> + <width>98</width> <height>20</height> </size> </property> </spacer> </item> <item> - <widget class="QPushButton" name="pushButton_focus"> - <property name="text"> - <string>Focus</string> + <widget class="MantidQt::MantidWidgets::MWRunFiles" name="lineEdit_texture_run_num" native="true"> + <property name="text" stdset="0"> + <string/> + </property> + <property name="readOnly" stdset="0"> + <bool>false</bool> + </property> + <property name="label" stdset="0"> + <string>Run #:</string> + </property> + <property name="multipleFiles" stdset="0"> + <bool>true</bool> </property> </widget> </item> </layout> </item> <item row="1" column="0"> - <layout class="QHBoxLayout" name="horizontalLayout_5"> + <layout class="QHBoxLayout" name="horizontalLayout_8"> <item> - <layout class="QVBoxLayout" name="verticalLayout_3"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_4"> - <item> - <widget class="QLabel" name="label_banks_sel"> - <property name="text"> - <string>Banks:</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_5"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>298</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="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>18</height> - </size> - </property> - </spacer> - </item> - </layout> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Detector Grouping File:</string> + </property> + </widget> </item> <item> - <layout class="QVBoxLayout" name="verticalLayout_4"> - <item> - <widget class="QCheckBox" name="checkBox_focus_bank1"> - <property name="text"> - <string>1</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="checkBox_focus_bank2"> - <property name="text"> - <string>2</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> + <widget class="QLineEdit" name="lineEdit_texture_grouping_file"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> </item> - </layout> - </item> - <item row="0" column="0"> - <layout class="QHBoxLayout" name="horizontalLayout"> <item> - <widget class="QLabel" name="label_run_num"> + <widget class="QPushButton" name="pushButton_texture_browse_grouping_file"> <property name="text"> - <string>Run #:</string> + <string>Browse</string> </property> </widget> </item> + </layout> + </item> + <item row="2" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout_11"> <item> - <spacer name="horizontalSpacer"> + <spacer name="horizontalSpacer_9"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> - <width>98</width> + <width>40</width> <height>20</height> </size> </property> </spacer> </item> <item> - <widget class="QLineEdit" name="lineEdit_run_num"> + <widget class="QPushButton" name="pushButton_focus_texture"> <property name="text"> - <string/> - </property> - <property name="readOnly"> - <bool>false</bool> + <string>Focus</string> </property> </widget> </item> @@ -297,23 +367,42 @@ </layout> </widget> </item> - <item row="3" column="0"> - <widget class="QGroupBox" name="groupBox_2"> + <item> + <spacer name="verticalSpacer_3"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QGroupBox" name="groupBox_focus_3"> + <property name="minimumSize"> + <size> + <width>596</width> + <height>111</height> + </size> + </property> <property name="title"> - <string>Focus Texture</string> + <string>Output</string> </property> - <layout class="QGridLayout" name="gridLayout_4"> - <item row="0" column="0"> - <layout class="QHBoxLayout" name="horizontalLayout_7"> + <layout class="QVBoxLayout" name="verticalLayout_6"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_20"> <item> - <widget class="QLabel" name="label_texture_run_num"> + <widget class="QCheckBox" name="checkBox_FocusedWS"> <property name="text"> - <string>Run #:</string> + <string>Plot Focused Workspace</string> </property> </widget> </item> <item> - <spacer name="horizontalSpacer_6"> + <spacer name="horizontalSpacer_18"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> @@ -325,77 +414,106 @@ </property> </spacer> </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_21"> <item> - <widget class="QLineEdit" name="lineEdit_texture_run_num"> - <property name="text"> - <string/> + <spacer name="horizontalSpacer_19"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> </property> - <property name="readOnly"> - <bool>false</bool> + <property name="sizeHint" stdset="0"> + <size> + <width>98</width> + <height>20</height> + </size> </property> - </widget> + </spacer> </item> - </layout> - </item> - <item row="1" column="0"> - <layout class="QHBoxLayout" name="horizontalLayout_8"> <item> - <widget class="QLabel" name="label_2"> + <widget class="QLabel" name="label_4"> <property name="text"> - <string>Detector Grouping File:</string> + <string>Plot Data Representation:</string> </property> </widget> </item> <item> - <widget class="QLineEdit" name="lineEdit_texture_grouping_file"> + <widget class="QComboBox" name="comboBox_PlotData"> <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>1</horstretch> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="readOnly"> - <bool>true</bool> + <property name="minimumSize"> + <size> + <width>175</width> + <height>10</height> + </size> + </property> + <property name="sizeIncrement"> + <size> + <width>0</width> + <height>0</height> + </size> </property> + <property name="baseSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="layoutDirection"> + <enum>Qt::LeftToRight</enum> + </property> + <item> + <property name="text"> + <string>One Window - Replacing Plots</string> + </property> + </item> + <item> + <property name="text"> + <string>One Window - Waterfall</string> + </property> + </item> + <item> + <property name="text"> + <string>Multiple Windows</string> + </property> + </item> </widget> </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_22"> <item> - <widget class="QPushButton" name="pushButton_texture_browse_grouping_file"> + <widget class="QCheckBox" name="checkBox_SaveOutputFiles"> <property name="text"> - <string>Browse</string> + <string>Output Files</string> </property> </widget> </item> - </layout> - </item> - <item row="2" column="0"> - <layout class="QHBoxLayout" name="horizontalLayout_11"> <item> - <spacer name="horizontalSpacer_9"> + <spacer name="horizontalSpacer_20"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> - <width>40</width> + <width>98</width> <height>20</height> </size> </property> </spacer> </item> - <item> - <widget class="QPushButton" name="pushButton_focus_texture"> - <property name="text"> - <string>Focus</string> - </property> - </widget> - </item> </layout> </item> </layout> </widget> </item> - <item row="5" column="0"> + <item> <layout class="QHBoxLayout" name="horizontalLayout_13"> <item> <spacer name="horizontalSpacer_11"> @@ -421,6 +539,13 @@ </item> </layout> </widget> + <customwidgets> + <customwidget> + <class>MantidQt::MantidWidgets::MWRunFiles</class> + <extends>QWidget</extends> + <header>MantidQtMantidWidgets/MWRunFiles.h</header> + </customwidget> + </customwidgets> <resources/> <connections/> </ui> diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionViewQtGUI.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionViewQtGUI.h index baed981c8f15aa12f32c87aa18132004d4e24ec8..f813d2b37cb5782b6d39ef2ed7e7ac013d330350 100644 --- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionViewQtGUI.h +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionViewQtGUI.h @@ -121,6 +121,14 @@ public: virtual void plotFocusedSpectrum(const std::string &wsName); + virtual void plotWaterfallSpectrum(const std::string &wsName); + + virtual void plotReplacingWindow(const std::string &wsName); + + virtual bool saveOutputFiles() const; + + int currentPlotType() const { return m_currentType; } + private slots: /// for buttons, do calibrate, focus and similar void loadCalibrationClicked(); @@ -145,6 +153,12 @@ private slots: // slots of the general part of the interface void instrumentChanged(int idx); + // slots of the focus part of the interface + void plotRepChanged(int idx); + + // slots of plot spectrum check box status + void plotFocusStatus(); + // show the standard Mantid help window with this interface's help void openHelpWin(); @@ -183,6 +197,10 @@ private: /// instrument selected (ENGIN-X, etc.) std::string m_currentInst; + + // plot data representation type selected + int static m_currentType; + /// current calibration produced in the 'Calibration' tab std::string m_currentCalibFilename; /// calibration settings - from/to the 'settings' tab diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/IEnggDiffractionPresenter.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/IEnggDiffractionPresenter.h index a2c0240d4cefb1d2befa48388c9bb25ab47bfc01..01fcbcaa76dce48d4ff93578b350e60faef98845 100644 --- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/IEnggDiffractionPresenter.h +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/IEnggDiffractionPresenter.h @@ -38,16 +38,16 @@ public: /// These are user actions, triggered from the (passive) view, that need /// handling by the presenter enum Notification { - Start, ///< Start and setup interface - LoadExistingCalib, ///< Load a calibration already availble on disk - CalcCalib, ///< Calculate a (new) calibration - FocusRun, ///< Focus one or more run files - FocusCropped, ///< Focus one or more run files, cropped variant - FocusTexture, ///< Focus one or more run files, texture variant - ResetFocus, ///< Re-set / clear all focus inputs and options - LogMsg, ///< need to send a message to the Mantid log system - InstrumentChange, ///< Instrument selection updated - ShutDown ///< closing the interface + Start, ///< Start and setup interface + LoadExistingCalib, ///< Load a calibration already availble on disk + CalcCalib, ///< Calculate a (new) calibration + FocusRun, ///< Focus one or more run files + FocusCropped, ///< Focus one or more run files, cropped variant + FocusTexture, ///< Focus one or more run files, texture variant + ResetFocus, ///< Re-set / clear all focus inputs and options + LogMsg, ///< need to send a message to the Mantid log system + InstrumentChange, ///< Instrument selection updated + ShutDown ///< closing the interface }; /** diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/IEnggDiffractionView.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/IEnggDiffractionView.h index e701764dac3f0d11fa716a65cde8b98fd4ea1e00..91cd94e0835b6f9da52f9896e98843f7d6f469d2 100644 --- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/IEnggDiffractionView.h +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/IEnggDiffractionView.h @@ -115,6 +115,14 @@ public: */ virtual std::string currentInstrument() const = 0; + /** + * Selected plot data representation will be applied, which will + * ran through python script + * + * @return which format should to applied for plotting data + */ + virtual int currentPlotType() const = 0; + /** * The Vanadium run number used in the current calibration * @@ -262,6 +270,14 @@ public: */ virtual void saveSettings() const = 0; + /** + * Saves the ouput files which are generated, this can be done + * via Output Files checkbox on the focus tab + * + * @return bool + */ + virtual bool saveOutputFiles() const = 0; + /** * Produces a single spectrum graph for focused output. Runs * plotSpectrum function via python. @@ -269,6 +285,22 @@ public: * @param wsName name of the workspace to plot (must be in the ADS) */ virtual void plotFocusedSpectrum(const std::string &wsName) = 0; + + /** + * Produces a waterfall spectrum graph for focused output. Runs + * plotSpectrum function via python. + * + * @param wsName name of the workspace to plot (must be in the ADS) + */ + virtual void plotWaterfallSpectrum(const std::string &wsName) = 0; + + /** + * Produces a replaceable spectrum graph for focused output. Runs + * plotSpectrum function via python. + * + * @param wsName name of the workspace to plot (must be in the ADS) + */ + virtual void plotReplacingWindow(const std::string &wsName) = 0; }; } // namespace CustomInterfaces diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ConvFit.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ConvFit.h index ed25cc6eed04b5788c3f2a4eb7fad4e11b2c3eeb..6ec99813345874f90ebcfe5d3f91ee85d5af963e 100644 --- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ConvFit.h +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ConvFit.h @@ -77,6 +77,9 @@ private: QStringList m_fitStrings; QString m_previousFit; QString m_baseName; + int m_runMin; + int m_runMax; + }; } // namespace IDA } // namespace CustomInterfaces diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ISISEnergyTransfer.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ISISEnergyTransfer.h index d164fa8aa6aae3a65e4c873d541e6d5527df0039..49090162ee653bd896774ab56d46edfcee8606f6 100644 --- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ISISEnergyTransfer.h +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ISISEnergyTransfer.h @@ -6,68 +6,66 @@ #include "MantidKernel/System.h" #include "MantidQtCustomInterfaces/Background.h" -namespace MantidQt -{ -namespace CustomInterfaces -{ - /** ISISEnergyTransfer - Handles an energy transfer reduction for ISIS instruments. - - @author Dan Nixon - @date 23/07/2014 - - Copyright © 2013 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - - File change history is stored at: <https://github.com/mantidproject/mantid> - Code Documentation is available at: <http://doxygen.mantidproject.org> - */ - class DLLExport ISISEnergyTransfer : public IndirectDataReductionTab - { - Q_OBJECT - - public: - ISISEnergyTransfer(IndirectDataReduction * idrUI, QWidget * parent = 0); - virtual ~ISISEnergyTransfer(); - - virtual void setup(); - virtual void run(); - - public slots: - virtual bool validate(); - - private slots: - void algorithmComplete(bool error); - void setInstrumentDefault(); ///< Sets default parameters for current instrument - void mappingOptionSelected(const QString& groupType); ///< change ui to display appropriate options - void plotRaw(); ///< plot raw data from instrument - void pbRunEditing(); //< Called when a user starts to type / edit the runs to load. - void pbRunFinding(); //< Called when the FileFinder starts finding the files. - void pbRunFinished(); //< Called when the FileFinder has finished finding the files. - void plotRawComplete(bool error); //< Called when the Plot Raw algorithmm chain completes - - private: - Ui::ISISEnergyTransfer m_uiForm; - - QPair<QString, QString> createMapFile(const QString& groupType); ///< create the mapping file with which to group results - std::vector<std::string> getSaveFormats(); ///< get a vector of save formats - - }; +namespace MantidQt { +namespace CustomInterfaces { +/** ISISEnergyTransfer + Handles an energy transfer reduction for ISIS instruments. + + @author Dan Nixon + @date 23/07/2014 + + Copyright © 2013 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class DLLExport ISISEnergyTransfer : public IndirectDataReductionTab { + Q_OBJECT + +public: + ISISEnergyTransfer(IndirectDataReduction *idrUI, QWidget *parent = 0); + virtual ~ISISEnergyTransfer(); + + virtual void setup(); + virtual void run(); + +public slots: + virtual bool validate(); + +private slots: + void algorithmComplete(bool error); + void + setInstrumentDefault(); ///< Sets default parameters for current instrument + void mappingOptionSelected(const QString &groupType); ///< change ui to display appropriate options + void plotRaw(); ///< plot raw data from instrument + void pbRunEditing(); //< Called when a user starts to type / edit the runs to load. + void pbRunFinding(); //< Called when the FileFinder starts finding the files. + void pbRunFinished(); //< Called when the FileFinder has finished finding the files. + void plotRawComplete(bool error); //< Called when the Plot Raw algorithmm chain completes + +private: + Ui::ISISEnergyTransfer m_uiForm; + + QPair<QString, QString> createMapFile(const QString &groupType); ///< create the mapping file with which to group results + std::vector<std::string> getSaveFormats(); ///< get a vector of save formats +}; } // namespace CustomInterfaces } // namespace Mantid -#endif //MANTIDQTCUSTOMINTERFACES_ISISENERGYTRANSFER_H_ +#endif // MANTIDQTCUSTOMINTERFACES_ISISENERGYTRANSFER_H_ diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/QtReflMainView.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/QtReflMainView.h index 5423d7311d73d879001d488f2bdcd02e9b6ef5dc..9afef697eac851d26f37c65428ed899de1968700 100644 --- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/QtReflMainView.h +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/QtReflMainView.h @@ -62,6 +62,11 @@ namespace MantidQt virtual void giveUserWarning(std::string prompt, std::string title); virtual void giveUserCritical(std::string prompt, std::string title); virtual void showAlgorithmDialog(const std::string& algorithm); + virtual std::string requestNotebookPath(); + + //Settings + virtual void saveSettings(const std::map<std::string,QVariant>& options); + virtual void loadSettings(std::map<std::string,QVariant>& options); //Plotting virtual void plotWorkspaces(const std::set<std::string>& workspaces); diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflMainView.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflMainView.h index ba7cfe632c3682ec2472b1778fbfee8efb29998f..a60b2df5525e7d4ef0a35effba9220db034e6313 100644 --- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflMainView.h +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflMainView.h @@ -57,6 +57,11 @@ namespace MantidQt virtual void giveUserWarning(std::string prompt, std::string title) = 0; virtual void giveUserCritical(std::string prompt, std::string title) = 0; virtual void showAlgorithmDialog(const std::string& algorithm) = 0; + virtual std::string requestNotebookPath() = 0; + + //Settings + virtual void saveSettings(const std::map<std::string,QVariant>& options) = 0; + virtual void loadSettings(std::map<std::string,QVariant>& options) = 0; //Plotting virtual void plotWorkspaces(const std::set<std::string>& workspaces) = 0; diff --git a/MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffractionPresenter.cpp b/MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffractionPresenter.cpp index 0b0be67c9f4055f395f0eedcd8b963851a9b1b64..c2c32c4e2a7eb2f60de3a3a222bdf21b9fed3695 100644 --- a/MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffractionPresenter.cpp +++ b/MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffractionPresenter.cpp @@ -13,7 +13,6 @@ #include <boost/lexical_cast.hpp> #include <Poco/File.h> -#include <Poco/Path.h> #include <QThread> @@ -32,6 +31,7 @@ const std::string EnggDiffractionPresenter::g_enginxStr = "ENGINX"; const bool EnggDiffractionPresenter::g_askUserCalibFilename = false; const std::string EnggDiffractionPresenter::g_vanIntegrationWSName = "engggui_vanadium_integration_ws"; +int EnggDiffractionPresenter::g_croppedCounter = 0; EnggDiffractionPresenter::EnggDiffractionPresenter(IEnggDiffractionView *view) : m_workerThread(NULL), m_calibFinishedOK(false), m_focusFinishedOK(false), @@ -57,7 +57,8 @@ void EnggDiffractionPresenter::cleanup() { if (m_workerThread) { if (m_workerThread->isRunning()) { g_log.notice() << "A calibration process is currently running, shutting " - "it down immediately..." << std::endl; + "it down immediately..." + << std::endl; m_workerThread->wait(10); } delete m_workerThread; @@ -146,7 +147,8 @@ void EnggDiffractionPresenter::processCalcCalib() { return; } g_log.notice() << "EnggDiffraction GUI: starting new calibration. This may " - "take a few seconds... " << std::endl; + "take a few seconds... " + << std::endl; const std::string outFilename = outputCalibFilename(vanNo, ceriaNo); @@ -414,10 +416,9 @@ void EnggDiffractionPresenter::parseCalibrateFilename(const std::string &path, * @param vanNo vanadium run number * @param ceriaNo ceria run number */ -void -EnggDiffractionPresenter::startAsyncCalibWorker(const std::string &outFilename, - const std::string &vanNo, - const std::string &ceriaNo) { +void EnggDiffractionPresenter::startAsyncCalibWorker( + const std::string &outFilename, const std::string &vanNo, + const std::string &ceriaNo) { delete m_workerThread; m_workerThread = new QThread(this); EnggDiffWorker *worker = @@ -466,11 +467,13 @@ void EnggDiffractionPresenter::doNewCalibration(const std::string &outFilename, } catch (std::runtime_error &) { g_log.error() << "The calibration calculations failed. One of the " "algorithms did not execute correctly. See log messages " - "for details. " << std::endl; + "for details. " + << std::endl; } catch (std::invalid_argument &) { g_log.error() << "The calibration calculations failed. Some input properties " - "were not valid. See log messages for details. " << std::endl; + "were not valid. See log messages for details. " + << std::endl; } // restore normal data search paths conf.setDataSearchDirs(tmpDirs); @@ -710,8 +713,8 @@ void EnggDiffractionPresenter::inputChecksBeforeFocusTexture( inputChecksBeforeFocus(); } -void -EnggDiffractionPresenter::inputChecksBanks(const std::vector<bool> &banks) { +void EnggDiffractionPresenter::inputChecksBanks( + const std::vector<bool> &banks) { if (0 == banks.size()) { const std::string msg = "Error in specification of banks found when starting the " @@ -848,7 +851,8 @@ void EnggDiffractionPresenter::doFocusRun( const std::string &specNos, const std::string &dgFile) { g_log.notice() << "Generating new focusing workspace(s) and file(s) into " - "this directory: " << dir << std::endl; + "this directory: " + << dir << std::endl; // TODO: this is almost 100% common with doNewCalibrate() - refactor EnggDiffCalibSettings cs = m_view->currentCalibSettings(); @@ -887,7 +891,8 @@ void EnggDiffractionPresenter::doFocusRun( loadDetectorGroupingCSV(dgFile, bankIDs, specs); } catch (std::runtime_error &re) { g_log.error() << "Error loading detector grouping file: " + dgFile + - ". Detailed error: " + re.what() << std::endl; + ". Detailed error: " + re.what() + << std::endl; bankIDs.clear(); specs.clear(); } @@ -903,8 +908,8 @@ void EnggDiffractionPresenter::doFocusRun( fpath.append(effectiveFilenames[idx]).toString(); g_log.notice() << "Generating new focused file (bank " + boost::lexical_cast<std::string>(bankIDs[idx]) + - ") for run " + runNo + - " into: " << effectiveFilenames[idx] << std::endl; + ") for run " + runNo + " into: " + << effectiveFilenames[idx] << std::endl; try { doFocusing(cs, fullFilename, runNo, bankIDs[idx], specs[idx], dgFile); m_focusFinishedOK = true; @@ -916,7 +921,8 @@ void EnggDiffractionPresenter::doFocusRun( } catch (std::invalid_argument &ia) { g_log.error() << "The focusing failed. Some input properties were not valid. " - "See log messages for details. Error: " << ia.what() << std::endl; + "See log messages for details. Error: " + << ia.what() << std::endl; } } @@ -1015,8 +1021,8 @@ void EnggDiffractionPresenter::focusingFinished() { * * @param bank instrument bank number to focus * - * @param specNos string specifying a list of spectra (for cropped - * focusing), only considered if not empty + * @param specNos string specifying a list of spectra (for "cropped" + * focusing or "texture" focusing), only considered if not empty * * @param dgFile detector grouping file name. If not empty implies * texture focusing @@ -1056,16 +1062,29 @@ void EnggDiffractionPresenter::doFocusing(const EnggDiffCalibSettings &cs, } std::string outWSName; + std::string specNumsOpenGenie; if (!dgFile.empty()) { + // doing focus "texture" outWSName = "engggui_focusing_output_ws_texture_bank_" + boost::lexical_cast<std::string>(bank); + specNumsOpenGenie = specNos; } else if (specNos.empty()) { + // doing focus "normal" / by banks outWSName = "engggui_focusing_output_ws_bank_" + boost::lexical_cast<std::string>(bank); + + // specnum for opengenie according to bank number + if (boost::lexical_cast<std::string>(bank) == "1") { + specNumsOpenGenie = "1 - 1200"; + } else if (boost::lexical_cast<std::string>(bank) == "2") { + specNumsOpenGenie = "1201 - 1400"; + } + } else { + // doing focus "cropped" outWSName = "engggui_focusing_output_ws_cropped"; + specNumsOpenGenie = specNos; } - try { auto alg = Algorithm::fromString("EnggFocus"); alg->initialize(); @@ -1082,12 +1101,8 @@ void EnggDiffractionPresenter::doFocusing(const EnggDiffCalibSettings &cs, // TODO: use detector positions (from calibrate full) when available // alg->setProperty(DetectorPositions, TableWorkspace) alg->execute(); - - const bool plotFocusedWS = m_view->focusedOutWorkspace(); - if (plotFocusedWS == true) { - m_view->plotFocusedSpectrum(outWSName); - } - + // plot Focused workspace according to the data type selected + plotFocusedWorkspace(outWSName, boost::lexical_cast<std::string>(bank)); } catch (std::runtime_error &re) { g_log.error() << "Error in calibration. ", "Could not run the algorithm EnggCalibrate succesfully for bank " + @@ -1095,8 +1110,8 @@ void EnggDiffractionPresenter::doFocusing(const EnggDiffCalibSettings &cs, re.what() + " Please check also the log messages for details."; throw; } - g_log.notice() << "Produced focused workspace: " << outWSName << std::endl; + try { g_log.debug() << "Going to save focused output into nexus file: " << fullFilename << std::endl; @@ -1114,6 +1129,14 @@ void EnggDiffractionPresenter::doFocusing(const EnggDiffCalibSettings &cs, } g_log.notice() << "Saved focused workspace as file: " << fullFilename << std::endl; + + bool saveOutputFiles = m_view->saveOutputFiles(); + if (saveOutputFiles) { + saveFocusedXYE(outWSName, boost::lexical_cast<std::string>(bank), runNo); + saveGSS(outWSName, boost::lexical_cast<std::string>(bank), runNo); + saveOpenGenie(outWSName, specNumsOpenGenie, + boost::lexical_cast<std::string>(bank), runNo); + } } /** @@ -1160,7 +1183,8 @@ void EnggDiffractionPresenter::loadOrCalcVanadiumWorkspaces( "This is possibly because some of the settings are not " "consistent. Please check the log messages for " "details. Details: " + - std::string(ia.what()) << std::endl; + std::string(ia.what()) + << std::endl; throw; } catch (std::runtime_error &re) { g_log.error() << "Failed to calculate Vanadium corrections. " @@ -1169,7 +1193,8 @@ void EnggDiffractionPresenter::loadOrCalcVanadiumWorkspaces( "There was no obvious error in the input properties " "but the algorithm failed. Please check the log " "messages for details." + - std::string(re.what()) << std::endl; + std::string(re.what()) + << std::endl; throw; } } else { @@ -1325,5 +1350,226 @@ void EnggDiffractionPresenter::calcVanadiumWorkspaces( vanCurvesWS = ADS.retrieveWS<MatrixWorkspace>(curvesName); } +/** + * Checks the plot type selected and applies the appropriate + * python function to apply during first bank and second bank + * + * @param outWSName title of the focused workspace + * @param bank the number of bank + */ +void EnggDiffractionPresenter::plotFocusedWorkspace(std::string outWSName, + std::string bank) { + const bool plotFocusedWS = m_view->focusedOutWorkspace(); + int plotType = m_view->currentPlotType(); + if (plotFocusedWS) { + if (plotType == 0) { + if (bank == "1") + m_view->plotFocusedSpectrum(outWSName); + if (bank == "2") + m_view->plotReplacingWindow(outWSName); + } else if (1 == plotType) { + if (bank == "1") + m_view->plotFocusedSpectrum(outWSName); + if (bank == "2") + m_view->plotWaterfallSpectrum(outWSName); + } else if (2 == plotType) { + m_view->plotFocusedSpectrum(outWSName); + } + } +} + +/** + * Convert the generated output files and saves them in + * FocusedXYE format + * + * @param inputWorkspace title of the focused workspace + * @param bank the number of the bank as a string + * @param runNo the run number as a string + */ +void EnggDiffractionPresenter::saveFocusedXYE(const std::string inputWorkspace, + std::string bank, + std::string runNo) { + + // Generates the file name in the appropriate format + std::string fullFilename = + outFileNameFactory(inputWorkspace, runNo, bank, ".dat"); + + // Creates appropriate directory + Poco::Path saveDir = outFilesDir(runNo); + + // append the full file name in the end + saveDir.append(fullFilename); + + try { + g_log.debug() << "Going to save focused output into OpenGenie file: " + << fullFilename << std::endl; + auto alg = Algorithm::fromString("SaveFocusedXYE"); + alg->initialize(); + alg->setProperty("InputWorkspace", inputWorkspace); + std::string filename(saveDir.toString()); + alg->setPropertyValue("Filename", filename); + alg->setProperty("SplitFiles", false); + alg->setPropertyValue("StartAtBankNumber", bank); + alg->execute(); + } catch (std::runtime_error &re) { + g_log.error() << "Error in saving FocusedXYE format file. ", + "Could not run the algorithm SaveFocusXYE succesfully for " + "workspace " + + inputWorkspace + ". Error description: " + re.what() + + " Please check also the log messages for details."; + throw; + } + g_log.notice() << "Saved focused workspace as file: " << saveDir.toString() + << std::endl; +} + +/** + * Convert the generated output files and saves them in + * GSS format + * + * @param inputWorkspace title of the focused workspace + * @param bank the number of the bank as a string + * @param runNo the run number as a string + */ +void EnggDiffractionPresenter::saveGSS(const std::string inputWorkspace, + std::string bank, std::string runNo) { + + // Generates the file name in the appropriate format + std::string fullFilename = + outFileNameFactory(inputWorkspace, runNo, bank, ".gss"); + + // Creates appropriate directory + Poco::Path saveDir = outFilesDir(runNo); + + // append the full file name in the end + saveDir.append(fullFilename); + + try { + g_log.debug() << "Going to save focused output into OpenGenie file: " + << fullFilename << std::endl; + auto alg = Algorithm::fromString("SaveGSS"); + alg->initialize(); + alg->setProperty("InputWorkspace", inputWorkspace); + std::string filename(saveDir.toString()); + alg->setPropertyValue("Filename", filename); + alg->setProperty("SplitFiles", false); + alg->setPropertyValue("Bank", bank); + alg->execute(); + } catch (std::runtime_error &re) { + g_log.error() << "Error in saving GSS format file. ", + "Could not run the algorithm saveGSS succesfully for " + "workspace " + + inputWorkspace + ". Error description: " + re.what() + + " Please check also the log messages for details."; + throw; + } + g_log.notice() << "Saved focused workspace as file: " << saveDir.toString() + << std::endl; +} + +/** + * Convert the generated output files and saves them in + * OpenGenie format + * + * @param inputWorkspace title of the focused workspace + * @param specNums number of spectrum to display + * @param bank the number of the bank as a string + * @param runNo the run number as a string + */ +void EnggDiffractionPresenter::saveOpenGenie(const std::string inputWorkspace, + std::string specNums, + std::string bank, + std::string runNo) { + + // Generates the file name in the appropriate format + std::string fullFilename = + outFileNameFactory(inputWorkspace, runNo, bank, ".his"); + + // Creates appropriate directory + Poco::Path saveDir = outFilesDir(runNo); + + // append the full file name in the end + saveDir.append(fullFilename); + + try { + g_log.debug() << "Going to save focused output into OpenGenie file: " + << fullFilename << std::endl; + auto alg = Algorithm::fromString("SaveOpenGenieAscii"); + alg->initialize(); + alg->setProperty("InputWorkspace", inputWorkspace); + std::string filename(saveDir.toString()); + alg->setPropertyValue("Filename", filename); + alg->setPropertyValue("SpecNumberField", specNums); + alg->execute(); + } catch (std::runtime_error &re) { + g_log.error() << "Error in saving OpenGenie format file. ", + "Could not run the algorithm SaveOpenGenieAscii succesfully for " + "workspace " + + inputWorkspace + ". Error description: " + re.what() + + " Please check also the log messages for details."; + throw; + } + g_log.notice() << "Saved focused workspace as file: " << saveDir.toString() + << std::endl; +} + +/** + * Generates the required file name of the output files + * + * @param inputWorkspace title of the focused workspace + * @param runNo the run number as a string + * @param bank the number of the bank as a string + * @param format the format of the file to be saved as + */ +std::string EnggDiffractionPresenter::outFileNameFactory( + std::string inputWorkspace, std::string runNo, std::string bank, + std::string format) { + std::string fullFilename; + if (inputWorkspace.std::string::find("texture") != std::string::npos) { + fullFilename = "ENGINX_" + runNo + "_texture_" + bank + format; + } + if (inputWorkspace.std::string::find("cropped") != std::string::npos) { + fullFilename = "ENGINX_" + runNo + "_cropped_" + + boost::lexical_cast<std::string>(g_croppedCounter) + format; + g_croppedCounter++; + } else { + fullFilename = "ENGINX_" + runNo + "_bank_" + bank + format; + } + return fullFilename; +} + +/** + * Generates a directory if not found and handles the path + * + * @param runNo the run number as a string + */ +Poco::Path EnggDiffractionPresenter::outFilesDir(std::string runNo) { + Poco::Path saveDir; + try { + +// takes to the root of directory according to the platform +// and appends the following string provided +#ifdef __unix__ + saveDir = Poco::Path().home(); + saveDir.append("EnginX_Mantid"); + saveDir.append("User"); + saveDir.append(runNo); + saveDir.append("Focus"); +#else + // else or for windows run this + saveDir = (saveDir).expand("C:/EnginX_Mantid/User/" + runNo + "/Focus/"); +#endif + + if (!Poco::File(saveDir.toString()).exists()) { + Poco::File(saveDir.toString()).createDirectories(); + } + } catch (Poco::FileAccessDeniedException &e) { + g_log.error() << "error caused by file access/permission: " << e.what(); + } catch (std::runtime_error &re) { + g_log.error() << "Error while find/creating a path: " << re.what(); + } + return saveDir; +} + } // namespace CustomInterfaces } // namespace MantidQt diff --git a/MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffractionViewQtGUI.cpp b/MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffractionViewQtGUI.cpp index c594b5b2732fcbf545042214fcd30a80cc6dc117..ccd98974eb014d04e86557d598cd852ebdcbe4a4 100644 --- a/MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffractionViewQtGUI.cpp +++ b/MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffractionViewQtGUI.cpp @@ -25,6 +25,7 @@ namespace CustomInterfaces { DECLARE_SUBWINDOW(EnggDiffractionViewQtGUI) const double EnggDiffractionViewQtGUI::g_defaultRebinWidth = -0.0005; +int EnggDiffractionViewQtGUI::m_currentType = 0; const std::string EnggDiffractionViewQtGUI::g_iparmExtStr = "GSAS instrument parameters, IPARM file: PRM, PAR, IPAR, IPARAM " @@ -149,6 +150,7 @@ void EnggDiffractionViewQtGUI::doSetupTabSettings() { } void EnggDiffractionViewQtGUI::doSetupTabFocus() { + connect(m_uiTabFocus.pushButton_focus, SIGNAL(released()), this, SLOT(focusClicked())); @@ -163,6 +165,12 @@ void EnggDiffractionViewQtGUI::doSetupTabFocus() { connect(m_uiTabFocus.pushButton_reset, SIGNAL(released()), this, SLOT(focusResetClicked())); + + connect(m_uiTabFocus.comboBox_PlotData, SIGNAL(currentIndexChanged(int)), + this, SLOT(plotRepChanged(int))); + + connect(m_uiTabFocus.checkBox_FocusedWS, SIGNAL(clicked()), this, + SLOT(plotFocusStatus())); } void EnggDiffractionViewQtGUI::doSetupGeneralWidgets() { @@ -209,9 +217,11 @@ void EnggDiffractionViewQtGUI::readSettings() { qs.beginReadArray("user-params-focus-bank_i"); qs.setArrayIndex(0); - m_uiTabFocus.checkBox_focus_bank1->setChecked(qs.value("value", true).toBool()); + m_uiTabFocus.checkBox_focus_bank1->setChecked( + qs.value("value", true).toBool()); qs.setArrayIndex(1); - m_uiTabFocus.checkBox_focus_bank2->setChecked(qs.value("value", true).toBool()); + m_uiTabFocus.checkBox_focus_bank2->setChecked( + qs.value("value", true).toBool()); qs.endArray(); m_uiTabFocus.lineEdit_cropped_run_num->setText( @@ -230,6 +240,8 @@ void EnggDiffractionViewQtGUI::readSettings() { m_uiTabFocus.checkBox_FocusedWS->setChecked( qs.value("user-params-focus-plot-ws", true).toBool()); + m_uiTabFocus.comboBox_PlotData->setCurrentIndex(0); + QString lastPath = MantidQt::API::AlgorithmInputHistory::Instance().getPreviousDirectory(); // TODO: this should become << >> operators on @@ -272,12 +284,13 @@ void EnggDiffractionViewQtGUI::saveSettings() const { m_uiTabCalib.lineEdit_current_calib_filename->text()); qs.setValue("user-params-new-vanadium-num", - m_uiTabCalib.lineEdit_new_vanadium_num->text()); + m_uiTabCalib.lineEdit_new_vanadium_num->getText()); qs.setValue("user-params-new-ceria-num", - m_uiTabCalib.lineEdit_new_ceria_num->text()); + m_uiTabCalib.lineEdit_new_ceria_num->getText()); // user params - focusing - qs.setValue("user-params-focus-runno", m_uiTabFocus.lineEdit_run_num->text()); + qs.setValue("user-params-focus-runno", + m_uiTabFocus.lineEdit_run_num->getText()); qs.beginWriteArray("user-params-focus-bank_i"); qs.setArrayIndex(0); @@ -287,17 +300,16 @@ void EnggDiffractionViewQtGUI::saveSettings() const { qs.endArray(); qs.setValue("user-params-focus-cropped-runno", - m_uiTabFocus.lineEdit_cropped_run_num->text()); + m_uiTabFocus.lineEdit_cropped_run_num->getText()); qs.setValue("user-params-focus-cropped-spectrum-nos", m_uiTabFocus.lineEdit_cropped_spec_ids->text()); qs.setValue("user-params-focus-texture-runno", - m_uiTabFocus.lineEdit_texture_run_num->text()); + m_uiTabFocus.lineEdit_texture_run_num->getText()); qs.setValue("user-params-focus-texture-detector-grouping-file", m_uiTabFocus.lineEdit_texture_grouping_file->text()); - qs.setValue("user-params-focus-plot-ws", - m_uiTabFocus.checkBox_FocusedWS->checkState()); + qs.setValue("value", m_uiTabFocus.checkBox_FocusedWS->isChecked()); // TODO: this should become << >> operators on EnggDiffCalibSettings qs.setValue("input-dir-calib-files", @@ -374,11 +386,11 @@ std::string EnggDiffractionViewQtGUI::currentCeriaNo() const { } std::string EnggDiffractionViewQtGUI::newVanadiumNo() const { - return m_uiTabCalib.lineEdit_new_vanadium_num->text().toStdString(); + return m_uiTabCalib.lineEdit_new_vanadium_num->getText().toStdString(); } std::string EnggDiffractionViewQtGUI::newCeriaNo() const { - return m_uiTabCalib.lineEdit_new_ceria_num->text().toStdString(); + return m_uiTabCalib.lineEdit_new_ceria_num->getText().toStdString(); } std::string EnggDiffractionViewQtGUI::currentCalibFile() const { @@ -414,6 +426,7 @@ void EnggDiffractionViewQtGUI::enableCalibrateAndFocusActions(bool enable) { m_uiTabFocus.lineEdit_run_num->setEnabled(enable); m_uiTabFocus.pushButton_focus->setEnabled(enable); m_uiTabFocus.checkBox_FocusedWS->setEnabled(enable); + m_uiTabFocus.checkBox_SaveOutputFiles->setEnabled(enable); m_uiTabFocus.pushButton_focus->setEnabled(enable); m_uiTabFocus.pushButton_focus_cropped->setEnabled(enable); @@ -421,10 +434,33 @@ void EnggDiffractionViewQtGUI::enableCalibrateAndFocusActions(bool enable) { } void EnggDiffractionViewQtGUI::plotFocusedSpectrum(const std::string &wsName) { - std::string pyCode = "plotSpectrum('" + wsName + "', 0)"; + std::string pyCode = "win = plotSpectrum('" + wsName + "', 0)"; + + std::string status = + runPythonCode(QString::fromStdString(pyCode), false).toStdString(); + m_logMsgs.push_back("Plotted output focused data, with status string " + + status); + m_presenter->notify(IEnggDiffractionPresenter::LogMsg); +} + +void EnggDiffractionViewQtGUI::plotWaterfallSpectrum( + const std::string &wsName) { + // parameter of list ? + std::string pyCode = + "plotSpectrum('" + wsName + "', 0, waterfall = True, window = win)"; + std::string status = + runPythonCode(QString::fromStdString(pyCode), false).toStdString(); + m_logMsgs.push_back("Plotted output focused data, with status string " + + status); + m_presenter->notify(IEnggDiffractionPresenter::LogMsg); +} +void EnggDiffractionViewQtGUI::plotReplacingWindow(const std::string &wsName) { + std::string pyCode = + "plotSpectrum('" + wsName + "', 0, window = win, clearWindow = True)"; std::string status = runPythonCode(QString::fromStdString(pyCode), false).toStdString(); + m_logMsgs.push_back("Plotted output focused data, with status string " + status); m_presenter->notify(IEnggDiffractionPresenter::LogMsg); @@ -442,10 +478,9 @@ void EnggDiffractionViewQtGUI::resetFocus() { m_uiTabFocus.lineEdit_texture_grouping_file->setText(""); } -void -EnggDiffractionViewQtGUI::writeOutCalibFile(const std::string &outFilename, - const std::vector<double> &difc, - const std::vector<double> &tzero) { +void EnggDiffractionViewQtGUI::writeOutCalibFile( + const std::string &outFilename, const std::vector<double> &difc, + const std::vector<double> &tzero) { // TODO: this is horrible and should not last much here. // Avoid running Python code // Update this as soon as we have a more stable way of generating IPARM @@ -643,15 +678,15 @@ void EnggDiffractionViewQtGUI::browseTextureDetGroupingFile() { } std::string EnggDiffractionViewQtGUI::focusingRunNo() const { - return m_uiTabFocus.lineEdit_run_num->text().toStdString(); + return m_uiTabFocus.lineEdit_run_num->getText().toStdString(); } std::string EnggDiffractionViewQtGUI::focusingCroppedRunNo() const { - return m_uiTabFocus.lineEdit_cropped_run_num->text().toStdString(); + return m_uiTabFocus.lineEdit_cropped_run_num->getText().toStdString(); } std::string EnggDiffractionViewQtGUI::focusingTextureRunNo() const { - return m_uiTabFocus.lineEdit_texture_run_num->text().toStdString(); + return m_uiTabFocus.lineEdit_texture_run_num->getText().toStdString(); } std::string EnggDiffractionViewQtGUI::focusingDir() const { @@ -677,6 +712,25 @@ bool EnggDiffractionViewQtGUI::focusedOutWorkspace() const { return m_uiTabFocus.checkBox_FocusedWS->checkState(); } +bool EnggDiffractionViewQtGUI::saveOutputFiles() const { + return m_uiTabFocus.checkBox_SaveOutputFiles->checkState(); +} + +void EnggDiffractionViewQtGUI::plotFocusStatus() { + if (focusedOutWorkspace()) { + m_uiTabFocus.comboBox_PlotData->setEnabled(true); + } else { + m_uiTabFocus.comboBox_PlotData->setEnabled(false); + } +} + +void EnggDiffractionViewQtGUI::plotRepChanged(int /*idx*/) { + QComboBox *plotType = m_uiTabFocus.comboBox_PlotData; + if (!plotType) + return; + m_currentType = plotType->currentIndex(); +} + void EnggDiffractionViewQtGUI::instrumentChanged(int /*idx*/) { QComboBox *inst = m_ui.comboBox_instrument; if (!inst) diff --git a/MantidQt/CustomInterfaces/src/Indirect/ApplyPaalmanPings.cpp b/MantidQt/CustomInterfaces/src/Indirect/ApplyPaalmanPings.cpp index 42270faab779a63de3226cd5b3b3cc4ebd2c2de6..e4e9d4484706608f74596258ca4846cf1bc906b7 100644 --- a/MantidQt/CustomInterfaces/src/Indirect/ApplyPaalmanPings.cpp +++ b/MantidQt/CustomInterfaces/src/Indirect/ApplyPaalmanPings.cpp @@ -145,6 +145,7 @@ void ApplyPaalmanPings::run() { switch (result) { case QMessageBox::YesToAll: interpolateAll = true; + //fall through case QMessageBox::Yes: addInterpolationStep(factorWs, absCorProps["SampleWorkspace"]); break; @@ -175,9 +176,18 @@ void ApplyPaalmanPings::run() { correctionType = "cyl"; break; } - const QString outputWsName = + QString outputWsName = sampleWsName.left(nameCutIndex) + +"_" + correctionType + "_Corrected"; + if (useCan) { + auto containerWsName = m_uiForm.dsContainer->getCurrentDataName(); + int cutIndex = containerWsName.indexOf("_"); + if (cutIndex == -1) { + cutIndex = containerWsName.length(); + } + outputWsName += "_Subtract_" + containerWsName.left(cutIndex); + } + applyCorrAlg->setProperty("OutputWorkspace", outputWsName.toStdString()); // Add corrections algorithm to queue diff --git a/MantidQt/CustomInterfaces/src/Indirect/CalculatePaalmanPings.cpp b/MantidQt/CustomInterfaces/src/Indirect/CalculatePaalmanPings.cpp index 81277fad6d9919ec6d2057026a52be6716bff9c2..49584757883539d7ef1a4332893875067f9017e1 100644 --- a/MantidQt/CustomInterfaces/src/Indirect/CalculatePaalmanPings.cpp +++ b/MantidQt/CustomInterfaces/src/Indirect/CalculatePaalmanPings.cpp @@ -122,8 +122,17 @@ void CalculatePaalmanPings::run() { break; } - const QString outputWsName = + QString outputWsName = sampleWsName.left(nameCutIndex) + "_" + correctionType + "_abs"; + if (useCan) { + auto containerWsName = m_uiForm.dsContainer->getCurrentDataName(); + int cutIndex = containerWsName.indexOf("_"); + if (cutIndex == -1) { + cutIndex = containerWsName.length(); + } + outputWsName += "_Subtract_" + containerWsName.left(cutIndex); + } + absCorAlgo->setProperty("OutputWorkspace", outputWsName.toStdString()); // Add corrections algorithm to queue diff --git a/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp b/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp index c4e727187fc8084c0e25ba20eab0bc8384a87a9a..07fef6447c8a24678b514740f03f64a9664d855f 100644 --- a/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp +++ b/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp @@ -35,6 +35,8 @@ ConvFit::ConvFit(QWidget *parent) void ConvFit::setup() { // Create Property Managers m_stringManager = new QtStringPropertyManager(); + m_runMin = 0; + m_runMax = 0; // Initialise fitTypeStrings m_fitStrings = QStringList() << "" @@ -237,6 +239,8 @@ void ConvFit::run() { std::string function = std::string(func->asString()); std::string stX = m_properties["StartX"]->valueText().toStdString(); std::string enX = m_properties["EndX"]->valueText().toStdString(); + m_runMin = m_uiForm.spSpectraMin->value(); + m_runMax = m_uiForm.spSpectraMax->value(); std::string specMin = m_uiForm.spSpectraMin->text().toStdString(); std::string specMax = m_uiForm.spSpectraMax->text().toStdString(); int maxIterations = @@ -984,17 +988,24 @@ void ConvFit::updatePlot() { } // If there is a result plot then plot it - std::string groupName = m_baseName.toStdString() + "_Workspaces"; + std::string groupName = m_baseName.toStdString() + "_Workspaces"; if (AnalysisDataService::Instance().doesExist(groupName)) { WorkspaceGroup_sptr outputGroup = - AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>( - groupName); - if (specNo >= static_cast<int>(outputGroup->size())) + AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>(groupName); + if (specNo - m_runMin >= static_cast<int>(outputGroup->size())) return; - MatrixWorkspace_sptr ws = boost::dynamic_pointer_cast<MatrixWorkspace>( - outputGroup->getItem(specNo)); - if (ws) - m_uiForm.ppPlot->addSpectrum("Fit", ws, 1, Qt::red); + if ((specNo - m_runMin) >= 0) { + MatrixWorkspace_sptr ws = boost::dynamic_pointer_cast<MatrixWorkspace>( + outputGroup->getItem(specNo- m_runMin)); + if (ws) { + m_uiForm.ppPlot->addSpectrum("Fit", ws, 1, Qt::red); + m_uiForm.ppPlot->addSpectrum("Diff", ws, 2, Qt::blue); + if (m_uiForm.ckPlotGuess->isChecked()) { + m_uiForm.ppPlot->removeSpectrum("Guess"); + m_uiForm.ckPlotGuess->setChecked(false); + } + } + } } } diff --git a/MantidQt/CustomInterfaces/src/Indirect/ISISEnergyTransfer.cpp b/MantidQt/CustomInterfaces/src/Indirect/ISISEnergyTransfer.cpp index ae32ddc36c2e30d07b9ff6dd2d5de8769a48a24a..684a600758ee1da57dd55c4810ab16df27c780fe 100644 --- a/MantidQt/CustomInterfaces/src/Indirect/ISISEnergyTransfer.cpp +++ b/MantidQt/CustomInterfaces/src/Indirect/ISISEnergyTransfer.cpp @@ -69,19 +69,19 @@ bool ISISEnergyTransfer::validate() { UserInputValidator uiv; // Run files input - if (!m_uiForm.dsRunFiles->isValid()){ + if (!m_uiForm.dsRunFiles->isValid()) { uiv.addErrorMessage("Run file range is invalid."); } // Calibration file input if (m_uiForm.ckUseCalib->isChecked() && - !m_uiForm.dsCalibrationFile->isValid()){ + !m_uiForm.dsCalibrationFile->isValid()) { uiv.addErrorMessage("Calibration file/workspace is invalid."); } // Mapping file if ((m_uiForm.cbGroupingOptions->currentText() == "File") && - (!m_uiForm.dsMapFile->isValid())){ + (!m_uiForm.dsMapFile->isValid())) { uiv.addErrorMessage("Mapping file is invalid."); } @@ -115,17 +115,63 @@ bool ISISEnergyTransfer::validate() { // Spectra Number check const int specMin = m_uiForm.spSpectraMin->value(); const int specMax = m_uiForm.spSpectraMax->value(); - if(specMin > specMax){ - uiv.addErrorMessage("Spectra Min must be less than Spectra Max"); + if (specMin > specMax) { + uiv.addErrorMessage("Spectra Min must be less than Spectra Max"); } // Background Removal (TOF) - if(m_uiForm.ckBackgroundRemoval->isChecked()){ - const int start = m_uiForm.spBackgroundStart->value(); - const int end = m_uiForm.spBackgroundEnd->value(); - if(start > end){ - uiv.addErrorMessage("Background Start must be less than Background End"); - } + if (m_uiForm.ckBackgroundRemoval->isChecked()) { + const int start = m_uiForm.spBackgroundStart->value(); + const int end = m_uiForm.spBackgroundEnd->value(); + if (start > end) { + uiv.addErrorMessage("Background Start must be less than Background End"); + } + } + + if (m_uiForm.dsRunFiles->isValid()) { + int detectorMin = m_uiForm.spPlotTimeSpecMin->value(); + int detectorMax = m_uiForm.spPlotTimeSpecMax->value(); + + QString rawFile = m_uiForm.dsRunFiles->getFirstFilename(); + auto pos = rawFile.lastIndexOf("."); + auto extension = rawFile.right(rawFile.length() - pos); + QFileInfo rawFileInfo(rawFile); + std::string name = rawFileInfo.baseName().toStdString(); + + IAlgorithm_sptr loadAlg = AlgorithmManager::Instance().create("Load"); + loadAlg->initialize(); + loadAlg->setProperty("Filename", rawFile.toStdString()); + loadAlg->setProperty("OutputWorkspace", name); + if (extension.compare(".nxs") == 0) { + int64_t detectorMin = + static_cast<int64_t>(m_uiForm.spPlotTimeSpecMin->value()); + int64_t detectorMax = + static_cast<int64_t>(m_uiForm.spPlotTimeSpecMax->value()); + loadAlg->setProperty("SpectrumMin", detectorMin); + loadAlg->setProperty("SpectrumMax", detectorMax); + } else { + loadAlg->setProperty("SpectrumMin", detectorMin); + loadAlg->setProperty("SpectrumMax", detectorMax); + } + + loadAlg->execute(); + + if (m_uiForm.ckBackgroundRemoval->isChecked()) { + MatrixWorkspace_sptr tempWs = + AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(name); + const double minBack = tempWs->readX(0)[0]; + const double maxBack = tempWs->readX(0)[tempWs->blocksize()]; + + if (m_uiForm.spBackgroundStart->value() < minBack) { + uiv.addErrorMessage("The Start of Background Removal is less than the " + "minimum of the data range"); + } + + if (m_uiForm.spBackgroundEnd->value() > maxBack) { + uiv.addErrorMessage("The End of Background Removal is more than the " + "maximum of the data range"); + } + } } QString error = uiv.generateErrorMessage(); @@ -446,6 +492,15 @@ void ISISEnergyTransfer::plotRaw() { "Minimum spectra must be less than or equal to maximum spectra."); return; } + const int startBack = m_uiForm.spBackgroundStart->value(); + const int endBack = m_uiForm.spBackgroundEnd->value(); + + if (m_uiForm.ckBackgroundRemoval->isChecked() == true) { + if (startBack > endBack) { + emit showMessageBox("Background Start must be less than Background End"); + return; + } + } QString rawFile = m_uiForm.dsRunFiles->getFirstFilename(); auto pos = rawFile.lastIndexOf("."); @@ -453,7 +508,7 @@ void ISISEnergyTransfer::plotRaw() { QFileInfo rawFileInfo(rawFile); std::string name = rawFileInfo.baseName().toStdString(); - IAlgorithm_sptr loadAlg = AlgorithmManager::Instance().create("Load"); + IAlgorithm_sptr loadAlg = AlgorithmManager::Instance().create("Load"); loadAlg->initialize(); loadAlg->setProperty("Filename", rawFile.toStdString()); loadAlg->setProperty("OutputWorkspace", name); @@ -468,7 +523,27 @@ void ISISEnergyTransfer::plotRaw() { loadAlg->setProperty("SpectrumMin", detectorMin); loadAlg->setProperty("SpectrumMax", detectorMax); } - m_batchAlgoRunner->addAlgorithm(loadAlg); + + loadAlg->execute(); + + if (m_uiForm.ckBackgroundRemoval->isChecked()) { + MatrixWorkspace_sptr tempWs = + AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(name); + const double minBack = tempWs->readX(0)[0]; + const double maxBack = tempWs->readX(0)[tempWs->blocksize()]; + + if (startBack < minBack) { + emit showMessageBox("The Start of Background Removal is less than the " + "minimum of the data range"); + return; + } + + if (endBack > maxBack) { + emit showMessageBox("The End of Background Removal is more than the " + "maximum of the data range"); + return; + } + } // Rebin the workspace to its self to ensure constant binning BatchAlgorithmRunner::AlgorithmRuntimeProps inputToRebin; diff --git a/MantidQt/CustomInterfaces/src/Indirect/IqtFit.cpp b/MantidQt/CustomInterfaces/src/Indirect/IqtFit.cpp index 73551bd016c94b0fe116358e3a8051c4b20dd6a6..50a15e9f3e337ede61b2cec93184f7237eafe548 100644 --- a/MantidQt/CustomInterfaces/src/Indirect/IqtFit.cpp +++ b/MantidQt/CustomInterfaces/src/Indirect/IqtFit.cpp @@ -17,881 +17,902 @@ using namespace Mantid::API; -namespace -{ - Mantid::Kernel::Logger g_log("IqtFit"); +namespace { +Mantid::Kernel::Logger g_log("IqtFit"); } -namespace MantidQt -{ -namespace CustomInterfaces -{ -namespace IDA -{ - IqtFit::IqtFit(QWidget * parent) : - IndirectDataAnalysisTab(parent), - m_stringManager(NULL), m_ffTree(NULL), - m_ffRangeManager(NULL), - m_fixedProps(), - m_ffInputWS(), m_ffOutputWS(), - m_ffInputWSName(), - m_ties() - { - m_uiForm.setupUi(parent); - } - - void IqtFit::setup() - { - m_stringManager = new QtStringPropertyManager(m_parentWidget); - - m_ffTree = new QtTreePropertyBrowser(m_parentWidget); - m_uiForm.properties->addWidget(m_ffTree); - - auto fitRangeSelector = m_uiForm.ppPlot->addRangeSelector("FuryFitRange"); - connect(fitRangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(xMinSelected(double))); - connect(fitRangeSelector, SIGNAL(maxValueChanged(double)), this, SLOT(xMaxSelected(double))); +namespace MantidQt { +namespace CustomInterfaces { +namespace IDA { +IqtFit::IqtFit(QWidget *parent) + : IndirectDataAnalysisTab(parent), m_stringManager(NULL), m_ffTree(NULL), + m_ffRangeManager(NULL), m_fixedProps(), m_ffInputWS(), m_ffOutputWS(), + m_ffInputWSName(), m_ties() { + m_uiForm.setupUi(parent); +} - auto backgroundRangeSelector = m_uiForm.ppPlot->addRangeSelector("FuryFitBackground", - MantidWidgets::RangeSelector::YSINGLE); - backgroundRangeSelector->setRange(0.0,1.0); - backgroundRangeSelector->setColour(Qt::darkGreen); - connect(backgroundRangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(backgroundSelected(double))); +void IqtFit::setup() { + m_stringManager = new QtStringPropertyManager(m_parentWidget); + + m_ffTree = new QtTreePropertyBrowser(m_parentWidget); + m_uiForm.properties->addWidget(m_ffTree); + + auto fitRangeSelector = m_uiForm.ppPlot->addRangeSelector("FuryFitRange"); + connect(fitRangeSelector, SIGNAL(minValueChanged(double)), this, + SLOT(xMinSelected(double))); + connect(fitRangeSelector, SIGNAL(maxValueChanged(double)), this, + SLOT(xMaxSelected(double))); + + auto backgroundRangeSelector = m_uiForm.ppPlot->addRangeSelector( + "FuryFitBackground", MantidWidgets::RangeSelector::YSINGLE); + backgroundRangeSelector->setRange(0.0, 1.0); + backgroundRangeSelector->setColour(Qt::darkGreen); + connect(backgroundRangeSelector, SIGNAL(minValueChanged(double)), this, + SLOT(backgroundSelected(double))); + + // setupTreePropertyBrowser + m_ffRangeManager = new QtDoublePropertyManager(m_parentWidget); + + m_ffTree->setFactoryForManager(m_blnManager, m_blnEdFac); + m_ffTree->setFactoryForManager(m_dblManager, m_dblEdFac); + m_ffTree->setFactoryForManager(m_ffRangeManager, m_dblEdFac); + + m_properties["StartX"] = m_ffRangeManager->addProperty("StartX"); + m_ffRangeManager->setDecimals(m_properties["StartX"], NUM_DECIMALS); + m_properties["EndX"] = m_ffRangeManager->addProperty("EndX"); + m_dblManager->setDecimals(m_properties["EndX"], NUM_DECIMALS); + m_properties["MaxIterations"] = m_dblManager->addProperty("Max Iterations"); + m_dblManager->setDecimals(m_properties["MaxIterations"], 0); + m_dblManager->setValue(m_properties["MaxIterations"], 500); + + // FABADA + m_properties["FABADA"] = m_grpManager->addProperty("Bayesian"); + m_properties["UseFABADA"] = m_blnManager->addProperty("Use FABADA"); + m_properties["FABADA"]->addSubProperty(m_properties["UseFABADA"]); + m_properties["OutputFABADAChain"] = m_blnManager->addProperty("Output Chain"); + m_properties["FABADAChainLength"] = m_dblManager->addProperty("Chain Length"); + m_dblManager->setDecimals(m_properties["FABADAChainLength"], 0); + m_dblManager->setValue(m_properties["FABADAChainLength"], 10000); + m_properties["FABADAConvergenceCriteria"] = + m_dblManager->addProperty("Convergence Criteria"); + m_dblManager->setValue(m_properties["FABADAConvergenceCriteria"], 0.1); + m_properties["FABADAJumpAcceptanceRate"] = + m_dblManager->addProperty("Acceptance Rate"); + m_dblManager->setValue(m_properties["FABADAJumpAcceptanceRate"], 0.25); + m_ffTree->addProperty(m_properties["FABADA"]); + + connect(m_ffRangeManager, SIGNAL(valueChanged(QtProperty *, double)), this, + SLOT(propertyChanged(QtProperty *, double))); + connect(m_dblManager, SIGNAL(valueChanged(QtProperty *, double)), this, + SLOT(propertyChanged(QtProperty *, double))); + + m_properties["LinearBackground"] = + m_grpManager->addProperty("LinearBackground"); + m_properties["BackgroundA0"] = m_ffRangeManager->addProperty("A0"); + m_ffRangeManager->setDecimals(m_properties["BackgroundA0"], NUM_DECIMALS); + m_properties["LinearBackground"]->addSubProperty( + m_properties["BackgroundA0"]); + + m_properties["Exponential1"] = createExponential("Exponential1"); + m_properties["Exponential2"] = createExponential("Exponential2"); + + m_properties["StretchedExp"] = createStretchedExp("StretchedExp"); + + m_ffRangeManager->setMinimum(m_properties["BackgroundA0"], 0); + m_ffRangeManager->setMaximum(m_properties["BackgroundA0"], 1); + + m_dblManager->setMinimum(m_properties["Exponential1.Intensity"], 0); + m_dblManager->setMaximum(m_properties["Exponential1.Intensity"], 1); + + m_dblManager->setMinimum(m_properties["Exponential2.Intensity"], 0); + m_dblManager->setMaximum(m_properties["Exponential2.Intensity"], 1); + + m_dblManager->setMinimum(m_properties["StretchedExp.Intensity"], 0); + m_dblManager->setMaximum(m_properties["StretchedExp.Intensity"], 1); + + typeSelection(m_uiForm.cbFitType->currentIndex()); + + // Update guess curve on property change + connect(m_dblManager, SIGNAL(propertyChanged(QtProperty *)), this, + SLOT(plotGuess(QtProperty *))); + + // Signal/slot ui connections + connect(m_uiForm.dsSampleInput, SIGNAL(dataReady(const QString &)), this, + SLOT(newDataLoaded(const QString &))); + connect(m_uiForm.cbFitType, SIGNAL(currentIndexChanged(int)), this, + SLOT(typeSelection(int))); + connect(m_uiForm.pbSingle, SIGNAL(clicked()), this, SLOT(singleFit())); + + connect(m_uiForm.dsSampleInput, SIGNAL(filesFound()), this, + SLOT(updatePlot())); + + connect(m_uiForm.spPlotSpectrum, SIGNAL(valueChanged(int)), this, + SLOT(updatePlot())); + + connect(m_uiForm.spSpectraMin, SIGNAL(valueChanged(int)), this, + SLOT(specMinChanged(int))); + connect(m_uiForm.spSpectraMax, SIGNAL(valueChanged(int)), this, + SLOT(specMaxChanged(int))); + + // Set a custom handler for the QTreePropertyBrowser's ContextMenu event + m_ffTree->setContextMenuPolicy(Qt::CustomContextMenu); + connect(m_ffTree, SIGNAL(customContextMenuRequested(const QPoint &)), this, + SLOT(fitContextMenu(const QPoint &))); + + connect(m_blnManager, SIGNAL(valueChanged(QtProperty *, bool)), this, + SLOT(checkBoxUpdate(QtProperty *, bool))); +} - // setupTreePropertyBrowser - m_ffRangeManager = new QtDoublePropertyManager(m_parentWidget); +void IqtFit::run() { + if (m_ffInputWS == NULL) { + return; + } - m_ffTree->setFactoryForManager(m_blnManager, m_blnEdFac); - m_ffTree->setFactoryForManager(m_dblManager, m_dblEdFac); - m_ffTree->setFactoryForManager(m_ffRangeManager, m_dblEdFac); + const bool constrainBeta = m_uiForm.ckConstrainBeta->isChecked(); + const bool constrainIntens = m_uiForm.ckConstrainIntensities->isChecked(); + CompositeFunction_sptr func = createFunction(); + func->tie("f0.A1", "0"); - m_properties["StartX"] = m_ffRangeManager->addProperty("StartX"); - m_ffRangeManager->setDecimals(m_properties["StartX"], NUM_DECIMALS); - m_properties["EndX"] = m_ffRangeManager->addProperty("EndX"); - m_dblManager->setDecimals(m_properties["EndX"], NUM_DECIMALS); - m_properties["MaxIterations"] = m_dblManager->addProperty("Max Iterations"); - m_dblManager->setDecimals(m_properties["MaxIterations"], 0); - m_dblManager->setValue(m_properties["MaxIterations"], 500); + if (constrainIntens) { + constrainIntensities(func); + } - // FABADA - m_properties["FABADA"] = m_grpManager->addProperty("Bayesian"); - m_properties["UseFABADA"] = m_blnManager->addProperty("Use FABADA"); - m_properties["FABADA"]->addSubProperty(m_properties["UseFABADA"]); - m_properties["OutputFABADAChain"] = m_blnManager->addProperty("Output Chain"); - m_properties["FABADAChainLength"] = m_dblManager->addProperty("Chain Length"); - m_dblManager->setDecimals(m_properties["FABADAChainLength"], 0); - m_dblManager->setValue(m_properties["FABADAChainLength"], 10000); - m_properties["FABADAConvergenceCriteria"] = m_dblManager->addProperty("Convergence Criteria"); - m_dblManager->setValue(m_properties["FABADAConvergenceCriteria"], 0.1); - m_properties["FABADAJumpAcceptanceRate"] = m_dblManager->addProperty("Acceptance Rate"); - m_dblManager->setValue(m_properties["FABADAJumpAcceptanceRate"], 0.25); - m_ffTree->addProperty(m_properties["FABADA"]); + func->applyTies(); + + std::string function = std::string(func->asString()); + QString fitType = fitTypeString(); + QString specMin = m_uiForm.spSpectraMin->text(); + QString specMax = m_uiForm.spSpectraMax->text(); + + QString pyInput = + "from IndirectDataAnalysis import furyfitSeq, furyfitMult\n" + "input = '" + + m_ffInputWSName + "'\n" + "func = r'" + + QString::fromStdString(function) + "'\n" + "ftype = '" + + fitTypeString() + "'\n" + "startx = " + + m_properties["StartX"]->valueText() + "\n" + "endx = " + + m_properties["EndX"]->valueText() + "\n" + "plot = '" + + m_uiForm.cbPlotType->currentText() + "'\n" + "spec_min = " + + specMin + "\n" + "spec_max = " + + specMax + "\n" + "spec_max = None\n" + "minimizer = '" + + minimizerString("$outputname_$wsindex") + "'\n" + "max_iterations = " + + QString::number(m_dblManager->value(m_properties["MaxIterations"])) + + "\n"; + + if (constrainIntens) + pyInput += "constrain_intens = True \n"; + else + pyInput += "constrain_intens = False \n"; + + if (m_uiForm.ckSave->isChecked()) + pyInput += "save = True\n"; + else + pyInput += "save = False\n"; + + if (!constrainBeta) { + pyInput += "furyfitSeq(input, func, ftype, startx, endx, " + "spec_min=spec_min, spec_max=spec_max, " + "intensities_constrained=constrain_intens, Save=save, " + "Plot=plot, minimizer=minimizer, " + "max_iterations=max_iterations)\n"; + } else { + pyInput += "furyfitMult(input, func, ftype, startx, endx, " + "spec_min=spec_min, spec_max=spec_max, " + "intensities_constrained=constrain_intens, Save=save, " + "Plot=plot, minimizer=minimizer, " + "max_iterations=max_iterations)\n"; + } - connect(m_ffRangeManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(propertyChanged(QtProperty*, double))); - connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(propertyChanged(QtProperty*, double))); + QString pyOutput = runPythonCode(pyInput); - m_properties["LinearBackground"] = m_grpManager->addProperty("LinearBackground"); - m_properties["BackgroundA0"] = m_ffRangeManager->addProperty("A0"); - m_ffRangeManager->setDecimals(m_properties["BackgroundA0"], NUM_DECIMALS); - m_properties["LinearBackground"]->addSubProperty(m_properties["BackgroundA0"]); + // Set the result workspace for Python script export + QString inputWsName = QString::fromStdString(m_ffInputWS->getName()); + QString resultWsName = inputWsName.left(inputWsName.lastIndexOf("_")) + + "_fury_" + fitType + specMin + "_to_" + specMax + + "_Workspaces"; + m_pythonExportWsName = resultWsName.toStdString(); - m_properties["Exponential1"] = createExponential("Exponential1"); - m_properties["Exponential2"] = createExponential("Exponential2"); + updatePlot(); +} - m_properties["StretchedExp"] = createStretchedExp("StretchedExp"); +bool IqtFit::validate() { + UserInputValidator uiv; - m_ffRangeManager->setMinimum(m_properties["BackgroundA0"], 0); - m_ffRangeManager->setMaximum(m_properties["BackgroundA0"], 1); + uiv.checkDataSelectorIsValid("Sample", m_uiForm.dsSampleInput); - m_dblManager->setMinimum(m_properties["Exponential1.Intensity"], 0); - m_dblManager->setMaximum(m_properties["Exponential1.Intensity"], 1); + auto range = std::make_pair(m_ffRangeManager->value(m_properties["StartX"]), + m_ffRangeManager->value(m_properties["EndX"])); + uiv.checkValidRange("Ranges", range); - m_dblManager->setMinimum(m_properties["Exponential2.Intensity"], 0); - m_dblManager->setMaximum(m_properties["Exponential2.Intensity"], 1); + QString error = uiv.generateErrorMessage(); + showMessageBox(error); - m_dblManager->setMinimum(m_properties["StretchedExp.Intensity"], 0); - m_dblManager->setMaximum(m_properties["StretchedExp.Intensity"], 1); + return error.isEmpty(); +} - typeSelection(m_uiForm.cbFitType->currentIndex()); +void IqtFit::loadSettings(const QSettings &settings) { + m_uiForm.dsSampleInput->readSettings(settings.group()); +} - // Update guess curve on property change - connect(m_dblManager, SIGNAL(propertyChanged(QtProperty*)), this, SLOT(plotGuess(QtProperty*))); +/** + * Called when new data has been loaded by the data selector. + * + * Configures ranges for spin boxes before raw plot is done. + * + * @param wsName Name of new workspace loaded + */ +void IqtFit::newDataLoaded(const QString wsName) { + m_ffInputWSName = wsName; + m_ffInputWS = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>( + m_ffInputWSName.toStdString()); - // Signal/slot ui connections - connect(m_uiForm.dsSampleInput, SIGNAL(dataReady(const QString&)), this, SLOT(newDataLoaded(const QString&))); - connect(m_uiForm.cbFitType, SIGNAL(currentIndexChanged(int)), this, SLOT(typeSelection(int))); - connect(m_uiForm.pbSingle, SIGNAL(clicked()), this, SLOT(singleFit())); + int maxSpecIndex = static_cast<int>(m_ffInputWS->getNumberHistograms()) - 1; - connect(m_uiForm.dsSampleInput, SIGNAL(filesFound()), this, SLOT(updatePlot())); + m_uiForm.spPlotSpectrum->setMaximum(maxSpecIndex); + m_uiForm.spPlotSpectrum->setMinimum(0); + m_uiForm.spPlotSpectrum->setValue(0); - connect(m_uiForm.spPlotSpectrum, SIGNAL(valueChanged(int)), this, SLOT(updatePlot())); + m_uiForm.spSpectraMin->setMaximum(maxSpecIndex); + m_uiForm.spSpectraMin->setMinimum(0); - connect(m_uiForm.spSpectraMin, SIGNAL(valueChanged(int)), this, SLOT(specMinChanged(int))); - connect(m_uiForm.spSpectraMax, SIGNAL(valueChanged(int)), this, SLOT(specMaxChanged(int))); + m_uiForm.spSpectraMax->setMaximum(maxSpecIndex); + m_uiForm.spSpectraMax->setMinimum(0); + m_uiForm.spSpectraMax->setValue(maxSpecIndex); - // Set a custom handler for the QTreePropertyBrowser's ContextMenu event - m_ffTree->setContextMenuPolicy(Qt::CustomContextMenu); - connect(m_ffTree, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(fitContextMenu(const QPoint &))); + updatePlot(); +} - connect(m_blnManager, SIGNAL(valueChanged(QtProperty *, bool)), this, SLOT(checkBoxUpdate(QtProperty *, bool))); +CompositeFunction_sptr IqtFit::createFunction(bool tie) { + CompositeFunction_sptr result(new CompositeFunction); + QString fname; + const int fitType = m_uiForm.cbFitType->currentIndex(); + + IFunction_sptr func = + FunctionFactory::Instance().createFunction("LinearBackground"); + func->setParameter("A0", + m_ffRangeManager->value(m_properties["BackgroundA0"])); + result->addFunction(func); + result->tie("f0.A1", "0"); + if (tie) { + result->tie("f0.A0", + m_properties["BackgroundA0"]->valueText().toStdString()); } - void IqtFit::run() - { - if ( m_ffInputWS == NULL ) - { - return; - } - - const bool constrainBeta = m_uiForm.ckConstrainBeta->isChecked(); - const bool constrainIntens = m_uiForm.ckConstrainIntensities->isChecked(); - CompositeFunction_sptr func = createFunction(); - func->tie("f0.A1", "0"); + if (fitType == 2) { + fname = "StretchedExp"; + } else { + fname = "Exponential1"; + } - if ( constrainIntens ) - { - constrainIntensities(func); - } + result->addFunction(createUserFunction(fname, tie)); - func->applyTies(); - - std::string function = std::string(func->asString()); - QString fitType = fitTypeString(); - QString specMin = m_uiForm.spSpectraMin->text(); - QString specMax = m_uiForm.spSpectraMax->text(); - - QString pyInput = "from IndirectDataAnalysis import furyfitSeq, furyfitMult\n" - "input = '" + m_ffInputWSName + "'\n" - "func = r'" + QString::fromStdString(function) + "'\n" - "ftype = '" + fitTypeString() + "'\n" - "startx = " + m_properties["StartX"]->valueText() + "\n" - "endx = " + m_properties["EndX"]->valueText() + "\n" - "plot = '" + m_uiForm.cbPlotType->currentText() + "'\n" - "spec_min = " + specMin + "\n" - "spec_max = " + specMax + "\n" - "spec_max = None\n" - "minimizer = '" + minimizerString("$outputname_$wsindex") + "'\n" - "max_iterations = " + QString::number(m_dblManager->value(m_properties["MaxIterations"])) + "\n"; - - if (constrainIntens) pyInput += "constrain_intens = True \n"; - else pyInput += "constrain_intens = False \n"; - - if ( m_uiForm.ckSave->isChecked() ) pyInput += "save = True\n"; - else pyInput += "save = False\n"; - - if( !constrainBeta ) - { - pyInput += "furyfitSeq(input, func, ftype, startx, endx, spec_min=spec_min, spec_max=spec_max, intensities_constrained=constrain_intens, Save=save, Plot=plot, minimizer=minimizer, max_iterations=max_iterations)\n"; - } - else - { - pyInput += "furyfitMult(input, func, ftype, startx, endx, spec_min=spec_min, spec_max=spec_max, intensities_constrained=constrain_intens, Save=save, Plot=plot, minimizer=minimizer, max_iterations=max_iterations)\n"; + if (fitType == 1 || fitType == 3) { + if (fitType == 1) { + fname = "Exponential2"; + } else { + fname = "StretchedExp"; } + result->addFunction(createUserFunction(fname, tie)); + } - QString pyOutput = runPythonCode(pyInput); + // Return CompositeFunction object to caller. + result->applyTies(); + return result; +} - // Set the result workspace for Python script export - QString inputWsName = QString::fromStdString(m_ffInputWS->getName()); - QString resultWsName = inputWsName.left(inputWsName.lastIndexOf("_")) + "_fury_" + fitType + specMin + "_to_" + specMax + "_Workspaces"; - m_pythonExportWsName = resultWsName.toStdString(); +IFunction_sptr IqtFit::createUserFunction(const QString &name, bool tie) { + IFunction_sptr result = + FunctionFactory::Instance().createFunction("UserFunction"); + std::string formula; - updatePlot(); + if (name.startsWith("Exp")) { + formula = "Intensity*exp(-(x/Tau))"; + } else { + formula = "Intensity*exp(-(x/Tau)^Beta)"; } - bool IqtFit::validate() - { - UserInputValidator uiv; + IFunction::Attribute att(formula); + result->setAttribute("Formula", att); - uiv.checkDataSelectorIsValid("Sample", m_uiForm.dsSampleInput); + QList<QtProperty *> props = m_properties[name]->subProperties(); + for (int i = 0; i < props.size(); i++) { + std::string name = props[i]->propertyName().toStdString(); + result->setParameter(name, m_dblManager->value(props[i])); - auto range = std::make_pair(m_ffRangeManager->value(m_properties["StartX"]), m_ffRangeManager->value(m_properties["EndX"])); - uiv.checkValidRange("Ranges", range); - - QString error = uiv.generateErrorMessage(); - showMessageBox(error); - - return error.isEmpty(); + // add tie if parameter is fixed + if (tie || !props[i]->subProperties().isEmpty()) { + std::string value = props[i]->valueText().toStdString(); + result->tie(name, value); + } } - void IqtFit::loadSettings(const QSettings & settings) - { - m_uiForm.dsSampleInput->readSettings(settings.group()); - } + result->applyTies(); + return result; +} - /** - * Called when new data has been loaded by the data selector. - * - * Configures ranges for spin boxes before raw plot is done. - * - * @param wsName Name of new workspace loaded - */ - void IqtFit::newDataLoaded(const QString wsName) - { - m_ffInputWSName = wsName; - m_ffInputWS = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(m_ffInputWSName.toStdString()); +QtProperty *IqtFit::createExponential(const QString &name) { + QtProperty *expGroup = m_grpManager->addProperty(name); + m_properties[name + ".Intensity"] = m_dblManager->addProperty("Intensity"); + m_dblManager->setDecimals(m_properties[name + ".Intensity"], NUM_DECIMALS); + m_properties[name + ".Tau"] = m_dblManager->addProperty("Tau"); + m_dblManager->setDecimals(m_properties[name + ".Tau"], NUM_DECIMALS); + expGroup->addSubProperty(m_properties[name + ".Intensity"]); + expGroup->addSubProperty(m_properties[name + ".Tau"]); + return expGroup; +} - int maxSpecIndex = static_cast<int>(m_ffInputWS->getNumberHistograms()) - 1; +QtProperty *IqtFit::createStretchedExp(const QString &name) { + QtProperty *prop = m_grpManager->addProperty(name); + m_properties[name + ".Intensity"] = m_dblManager->addProperty("Intensity"); + m_properties[name + ".Tau"] = m_dblManager->addProperty("Tau"); + m_properties[name + ".Beta"] = m_dblManager->addProperty("Beta"); + m_dblManager->setRange(m_properties[name + ".Beta"], 0, 1); + m_dblManager->setDecimals(m_properties[name + ".Intensity"], NUM_DECIMALS); + m_dblManager->setDecimals(m_properties[name + ".Tau"], NUM_DECIMALS); + m_dblManager->setDecimals(m_properties[name + ".Beta"], NUM_DECIMALS); + prop->addSubProperty(m_properties[name + ".Intensity"]); + prop->addSubProperty(m_properties[name + ".Tau"]); + prop->addSubProperty(m_properties[name + ".Beta"]); + return prop; +} - m_uiForm.spPlotSpectrum->setMaximum(maxSpecIndex); - m_uiForm.spPlotSpectrum->setMinimum(0); - m_uiForm.spPlotSpectrum->setValue(0); +QString IqtFit::fitTypeString() const { + switch (m_uiForm.cbFitType->currentIndex()) { + case 0: + return "1E_s"; + case 1: + return "2E_s"; + case 2: + return "1S_s"; + case 3: + return "1E1S_s"; + default: + return "s"; + }; +} - m_uiForm.spSpectraMin->setMaximum(maxSpecIndex); - m_uiForm.spSpectraMin->setMinimum(0); +void IqtFit::typeSelection(int index) { + m_ffTree->clear(); - m_uiForm.spSpectraMax->setMaximum(maxSpecIndex); - m_uiForm.spSpectraMax->setMinimum(0); - m_uiForm.spSpectraMax->setValue(maxSpecIndex); + m_ffTree->addProperty(m_properties["StartX"]); + m_ffTree->addProperty(m_properties["EndX"]); + m_ffTree->addProperty(m_properties["MaxIterations"]); + m_ffTree->addProperty(m_properties["LinearBackground"]); + m_ffTree->addProperty(m_properties["FABADA"]); - updatePlot(); + // option should only be available with a single stretched exponential + m_uiForm.ckConstrainBeta->setEnabled((index == 2)); + if (!m_uiForm.ckConstrainBeta->isEnabled()) { + m_uiForm.ckConstrainBeta->setChecked(false); } - CompositeFunction_sptr IqtFit::createFunction(bool tie) - { - CompositeFunction_sptr result( new CompositeFunction ); - QString fname; - const int fitType = m_uiForm.cbFitType->currentIndex(); - - IFunction_sptr func = FunctionFactory::Instance().createFunction("LinearBackground"); - func->setParameter("A0", m_ffRangeManager->value(m_properties["BackgroundA0"])); - result->addFunction(func); - result->tie("f0.A1", "0"); - if ( tie ) { result->tie("f0.A0", m_properties["BackgroundA0"]->valueText().toStdString()); } - - if ( fitType == 2 ) { fname = "StretchedExp"; } - else { fname = "Exponential1"; } + switch (index) { + case 0: + m_ffTree->addProperty(m_properties["Exponential1"]); + + // remove option to plot beta + m_uiForm.cbPlotType->removeItem(4); + break; + case 1: + m_ffTree->addProperty(m_properties["Exponential1"]); + m_ffTree->addProperty(m_properties["Exponential2"]); + + // remove option to plot beta + m_uiForm.cbPlotType->removeItem(4); + break; + case 2: + m_ffTree->addProperty(m_properties["StretchedExp"]); + + // add option to plot beta + if (m_uiForm.cbPlotType->count() == 4) { + m_uiForm.cbPlotType->addItem("Beta"); + } - result->addFunction(createUserFunction(fname, tie)); + break; + case 3: + m_ffTree->addProperty(m_properties["Exponential1"]); + m_ffTree->addProperty(m_properties["StretchedExp"]); - if ( fitType == 1 || fitType == 3 ) - { - if ( fitType == 1 ) { fname = "Exponential2"; } - else { fname = "StretchedExp"; } - result->addFunction(createUserFunction(fname, tie)); + // add option to plot beta + if (m_uiForm.cbPlotType->count() == 4) { + m_uiForm.cbPlotType->addItem("Beta"); } - // Return CompositeFunction object to caller. - result->applyTies(); - return result; + break; } - IFunction_sptr IqtFit::createUserFunction(const QString & name, bool tie) - { - IFunction_sptr result = FunctionFactory::Instance().createFunction("UserFunction"); - std::string formula; - - if ( name.startsWith("Exp") ) { formula = "Intensity*exp(-(x/Tau))"; } - else { formula = "Intensity*exp(-(x/Tau)^Beta)"; } + plotGuess(NULL); +} - IFunction::Attribute att(formula); - result->setAttribute("Formula", att); +void IqtFit::updatePlot() { + if (!m_ffInputWS) { + g_log.error("No workspace loaded, cannot create preview plot."); + return; + } - QList<QtProperty*> props = m_properties[name]->subProperties(); - for ( int i = 0; i < props.size(); i++ ) - { - std::string name = props[i]->propertyName().toStdString(); - result->setParameter(name, m_dblManager->value(props[i])); + int specNo = m_uiForm.spPlotSpectrum->value(); + + m_uiForm.ppPlot->clear(); + m_uiForm.ppPlot->addSpectrum("Sample", m_ffInputWS, specNo); + + try { + const QPair<double, double> curveRange = + m_uiForm.ppPlot->getCurveRange("Sample"); + const std::pair<double, double> range(curveRange.first, curveRange.second); + m_uiForm.ppPlot->getRangeSelector("FuryFitRange") + ->setRange(range.first, range.second); + m_ffRangeManager->setRange(m_properties["StartX"], range.first, + range.second); + m_ffRangeManager->setRange(m_properties["EndX"], range.first, range.second); + + setDefaultParameters("Exponential1"); + setDefaultParameters("Exponential2"); + setDefaultParameters("StretchedExp"); + + m_uiForm.ppPlot->resizeX(); + m_uiForm.ppPlot->setAxisRange(qMakePair(0.0, 1.0), QwtPlot::yLeft); + } catch (std::invalid_argument &exc) { + showMessageBox(exc.what()); + } - //add tie if parameter is fixed - if ( tie || ! props[i]->subProperties().isEmpty() ) - { - std::string value = props[i]->valueText().toStdString(); - result->tie(name, value); + // If there is a result plot then plot it + if (AnalysisDataService::Instance().doesExist(m_pythonExportWsName)) { + WorkspaceGroup_sptr outputGroup = + AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>( + m_pythonExportWsName); + if (specNo >= static_cast<int>(outputGroup->size())) + return; + MatrixWorkspace_sptr ws = boost::dynamic_pointer_cast<MatrixWorkspace>( + outputGroup->getItem(specNo)); + if (ws) { + if (m_uiForm.ckPlotGuess->isChecked()) { + m_uiForm.ppPlot->removeSpectrum("Guess"); } + m_uiForm.ppPlot->addSpectrum("Fit", ws, 1, Qt::red); + m_uiForm.ppPlot->addSpectrum("Diff", ws, 2, Qt::blue); } - - result->applyTies(); - return result; - } - - QtProperty* IqtFit::createExponential(const QString & name) - { - QtProperty* expGroup = m_grpManager->addProperty(name); - m_properties[name+".Intensity"] = m_dblManager->addProperty("Intensity"); - m_dblManager->setDecimals(m_properties[name+".Intensity"], NUM_DECIMALS); - m_properties[name+".Tau"] = m_dblManager->addProperty("Tau"); - m_dblManager->setDecimals(m_properties[name+".Tau"], NUM_DECIMALS); - expGroup->addSubProperty(m_properties[name+".Intensity"]); - expGroup->addSubProperty(m_properties[name+".Tau"]); - return expGroup; } +} - QtProperty* IqtFit::createStretchedExp(const QString & name) - { - QtProperty* prop = m_grpManager->addProperty(name); - m_properties[name+".Intensity"] = m_dblManager->addProperty("Intensity"); - m_properties[name+".Tau"] = m_dblManager->addProperty("Tau"); - m_properties[name+".Beta"] = m_dblManager->addProperty("Beta"); - m_dblManager->setRange(m_properties[name+".Beta"], 0, 1); - m_dblManager->setDecimals(m_properties[name+".Intensity"], NUM_DECIMALS); - m_dblManager->setDecimals(m_properties[name+".Tau"], NUM_DECIMALS); - m_dblManager->setDecimals(m_properties[name+".Beta"], NUM_DECIMALS); - prop->addSubProperty(m_properties[name+".Intensity"]); - prop->addSubProperty(m_properties[name+".Tau"]); - prop->addSubProperty(m_properties[name+".Beta"]); - return prop; - } +void IqtFit::setDefaultParameters(const QString &name) { + double background = m_dblManager->value(m_properties["BackgroundA0"]); + // intensity is always 1-background + m_dblManager->setValue(m_properties[name + ".Intensity"], 1.0 - background); + auto x = m_ffInputWS->readX(0); + auto y = m_ffInputWS->readY(0); + double tau = 0; - QString IqtFit::fitTypeString() const - { - switch ( m_uiForm.cbFitType->currentIndex() ) - { - case 0: - return "1E_s"; - case 1: - return "2E_s"; - case 2: - return "1S_s"; - case 3: - return "1E1S_s"; - default: - return "s"; - }; + if (x.size() > 4) { + tau = -x[4] / log(y[4]); } - void IqtFit::typeSelection(int index) - { - m_ffTree->clear(); - - m_ffTree->addProperty(m_properties["StartX"]); - m_ffTree->addProperty(m_properties["EndX"]); - m_ffTree->addProperty(m_properties["MaxIterations"]); - m_ffTree->addProperty(m_properties["LinearBackground"]); - m_ffTree->addProperty(m_properties["FABADA"]); - - //option should only be available with a single stretched exponential - m_uiForm.ckConstrainBeta->setEnabled((index == 2)); - if (!m_uiForm.ckConstrainBeta->isEnabled()) - { - m_uiForm.ckConstrainBeta->setChecked(false); - } - - switch ( index ) - { - case 0: - m_ffTree->addProperty(m_properties["Exponential1"]); + m_dblManager->setValue(m_properties[name + ".Tau"], tau); + m_dblManager->setValue(m_properties[name + ".Beta"], 1.0); +} - //remove option to plot beta - m_uiForm.cbPlotType->removeItem(4); - break; - case 1: - m_ffTree->addProperty(m_properties["Exponential1"]); - m_ffTree->addProperty(m_properties["Exponential2"]); +/** + * Handles the user entering a new minimum spectrum index. + * + * Prevents the user entering an overlapping spectra range. + * + * @param value Minimum spectrum index + */ +void IqtFit::specMinChanged(int value) { + m_uiForm.spSpectraMax->setMinimum(value); +} - //remove option to plot beta - m_uiForm.cbPlotType->removeItem(4); - break; - case 2: - m_ffTree->addProperty(m_properties["StretchedExp"]); +/** + * Handles the user entering a new maximum spectrum index. + * + * Prevents the user entering an overlapping spectra range. + * + * @param value Maximum spectrum index + */ +void IqtFit::specMaxChanged(int value) { + m_uiForm.spSpectraMin->setMaximum(value); +} - //add option to plot beta - if(m_uiForm.cbPlotType->count() == 4) - { - m_uiForm.cbPlotType->addItem("Beta"); - } +void IqtFit::xMinSelected(double val) { + m_ffRangeManager->setValue(m_properties["StartX"], val); +} - break; - case 3: - m_ffTree->addProperty(m_properties["Exponential1"]); - m_ffTree->addProperty(m_properties["StretchedExp"]); - - //add option to plot beta - if(m_uiForm.cbPlotType->count() == 4) - { - m_uiForm.cbPlotType->addItem("Beta"); - } +void IqtFit::xMaxSelected(double val) { + m_ffRangeManager->setValue(m_properties["EndX"], val); +} - break; - } +void IqtFit::backgroundSelected(double val) { + m_ffRangeManager->setValue(m_properties["BackgroundA0"], val); + m_dblManager->setValue(m_properties["Exponential1.Intensity"], 1.0 - val); + m_dblManager->setValue(m_properties["Exponential2.Intensity"], 1.0 - val); + m_dblManager->setValue(m_properties["StretchedExp.Intensity"], 1.0 - val); +} - plotGuess(NULL); +void IqtFit::propertyChanged(QtProperty *prop, double val) { + auto fitRangeSelector = m_uiForm.ppPlot->getRangeSelector("FuryFitRange"); + auto backgroundRangeSelector = + m_uiForm.ppPlot->getRangeSelector("FuryFitBackground"); + + if (prop == m_properties["StartX"]) { + fitRangeSelector->setMinimum(val); + } else if (prop == m_properties["EndX"]) { + fitRangeSelector->setMaximum(val); + } else if (prop == m_properties["BackgroundA0"]) { + backgroundRangeSelector->setMinimum(val); + m_dblManager->setValue(m_properties["Exponential1.Intensity"], 1.0 - val); + m_dblManager->setValue(m_properties["Exponential2.Intensity"], 1.0 - val); + m_dblManager->setValue(m_properties["StretchedExp.Intensity"], 1.0 - val); + } else if (prop == m_properties["Exponential1.Intensity"] || + prop == m_properties["Exponential2.Intensity"] || + prop == m_properties["StretchedExp.Intensity"]) { + backgroundRangeSelector->setMinimum(1.0 - val); + m_dblManager->setValue(m_properties["Exponential1.Intensity"], val); + m_dblManager->setValue(m_properties["Exponential2.Intensity"], val); + m_dblManager->setValue(m_properties["StretchedExp.Intensity"], val); } +} - void IqtFit::updatePlot() - { - if(!m_ffInputWS) - { - g_log.error("No workspace loaded, cannot create preview plot."); - return; +void IqtFit::checkBoxUpdate(QtProperty *prop, bool checked) { + if (prop == m_properties["UseFABADA"]) { + if (checked) { + m_dblManager->setValue(m_properties["MaxIterations"], 20000); + + m_properties["FABADA"]->addSubProperty(m_properties["OutputFABADAChain"]); + m_properties["FABADA"]->addSubProperty(m_properties["FABADAChainLength"]); + m_properties["FABADA"]->addSubProperty( + m_properties["FABADAConvergenceCriteria"]); + m_properties["FABADA"]->addSubProperty( + m_properties["FABADAJumpAcceptanceRate"]); + } else { + m_dblManager->setValue(m_properties["MaxIterations"], 500); + + m_properties["FABADA"]->removeSubProperty( + m_properties["OutputFABADAChain"]); + m_properties["FABADA"]->removeSubProperty( + m_properties["FABADAChainLength"]); + m_properties["FABADA"]->removeSubProperty( + m_properties["FABADAConvergenceCriteria"]); + m_properties["FABADA"]->removeSubProperty( + m_properties["FABADAJumpAcceptanceRate"]); } + } +} - int specNo = m_uiForm.spPlotSpectrum->value(); - - m_uiForm.ppPlot->clear(); - m_uiForm.ppPlot->addSpectrum("Sample", m_ffInputWS, specNo); - - try - { - const QPair<double, double> curveRange = m_uiForm.ppPlot->getCurveRange("Sample"); - const std::pair<double, double> range(curveRange.first, curveRange.second); - m_uiForm.ppPlot->getRangeSelector("FuryFitRange")->setRange(range.first, range.second); - m_ffRangeManager->setRange(m_properties["StartX"], range.first, range.second); - m_ffRangeManager->setRange(m_properties["EndX"], range.first, range.second); - - setDefaultParameters("Exponential1"); - setDefaultParameters("Exponential2"); - setDefaultParameters("StretchedExp"); - - m_uiForm.ppPlot->resizeX(); - m_uiForm.ppPlot->setAxisRange(qMakePair(0.0, 1.0), QwtPlot::yLeft); - } - catch(std::invalid_argument & exc) - { - showMessageBox(exc.what()); +void IqtFit::constrainIntensities(CompositeFunction_sptr func) { + std::string paramName = "f1.Intensity"; + size_t index = func->parameterIndex(paramName); + + switch (m_uiForm.cbFitType->currentIndex()) { + case 0: // 1 Exp + case 2: // 1 Str + if (!func->isFixed(index)) { + func->tie(paramName, "1-f0.A0"); + } else { + std::string paramValue = + boost::lexical_cast<std::string>(func->getParameter(paramName)); + func->tie(paramName, paramValue); + func->tie("f0.A0", "1-" + paramName); } - - // If there is a result plot then plot it - if(AnalysisDataService::Instance().doesExist(m_pythonExportWsName)) - { - WorkspaceGroup_sptr outputGroup = AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>(m_pythonExportWsName); - if(specNo >= static_cast<int>(outputGroup->size())) - return; - MatrixWorkspace_sptr ws = boost::dynamic_pointer_cast<MatrixWorkspace>(outputGroup->getItem(specNo)); - if(ws) - m_uiForm.ppPlot->addSpectrum("Fit", ws, 1, Qt::red); + break; + case 1: // 2 Exp + case 3: // 1 Exp & 1 Str + if (!func->isFixed(index)) { + func->tie(paramName, "1-f2.Intensity-f0.A0"); + } else { + std::string paramValue = + boost::lexical_cast<std::string>(func->getParameter(paramName)); + func->tie(paramName, "1-f2.Intensity-f0.A0"); + func->tie(paramName, paramValue); } + break; } +} - void IqtFit::setDefaultParameters(const QString& name) - { - double background = m_dblManager->value(m_properties["BackgroundA0"]); - //intensity is always 1-background - m_dblManager->setValue(m_properties[name+".Intensity"], 1.0-background); - auto x = m_ffInputWS->readX(0); - auto y = m_ffInputWS->readY(0); - double tau = 0; - - if (x.size() > 4) - { - tau = -x[4] / log(y[4]); - } +/** + * Generates a string that defines the fitting minimizer based on the user + * options. + * + * @return Minimizer as a string + */ +QString IqtFit::minimizerString(QString outputName) const { + QString minimizer = "Levenberg-Marquardt"; - m_dblManager->setValue(m_properties[name+".Tau"], tau); - m_dblManager->setValue(m_properties[name+".Beta"], 1.0); - } + if (m_blnManager->value(m_properties["UseFABADA"])) { + minimizer = "FABADA"; - /** - * Handles the user entering a new minimum spectrum index. - * - * Prevents the user entering an overlapping spectra range. - * - * @param value Minimum spectrum index - */ - void IqtFit::specMinChanged(int value) - { - m_uiForm.spSpectraMax->setMinimum(value); - } + int chainLength = static_cast<int>( + m_dblManager->value(m_properties["FABADAChainLength"])); + minimizer += ",ChainLength=" + QString::number(chainLength); - /** - * Handles the user entering a new maximum spectrum index. - * - * Prevents the user entering an overlapping spectra range. - * - * @param value Maximum spectrum index - */ - void IqtFit::specMaxChanged(int value) - { - m_uiForm.spSpectraMin->setMaximum(value); - } + double convergenceCriteria = + m_dblManager->value(m_properties["FABADAConvergenceCriteria"]); + minimizer += ",ConvergenceCriteria=" + QString::number(convergenceCriteria); - void IqtFit::xMinSelected(double val) - { - m_ffRangeManager->setValue(m_properties["StartX"], val); - } + double jumpAcceptanceRate = + m_dblManager->value(m_properties["FABADAJumpAcceptanceRate"]); + minimizer += ",JumpAcceptanceRate=" + QString::number(jumpAcceptanceRate); - void IqtFit::xMaxSelected(double val) - { - m_ffRangeManager->setValue(m_properties["EndX"], val); - } + minimizer += ",PDF=" + outputName + "_PDF"; - void IqtFit::backgroundSelected(double val) - { - m_ffRangeManager->setValue(m_properties["BackgroundA0"], val); - m_dblManager->setValue(m_properties["Exponential1.Intensity"], 1.0-val); - m_dblManager->setValue(m_properties["Exponential2.Intensity"], 1.0-val); - m_dblManager->setValue(m_properties["StretchedExp.Intensity"], 1.0-val); + if (m_blnManager->value(m_properties["OutputFABADAChain"])) + minimizer += ",Chains=" + outputName + "_Chain"; } - void IqtFit::propertyChanged(QtProperty* prop, double val) - { - auto fitRangeSelector = m_uiForm.ppPlot->getRangeSelector("FuryFitRange"); - auto backgroundRangeSelector = m_uiForm.ppPlot->getRangeSelector("FuryFitBackground"); + return minimizer; +} - if ( prop == m_properties["StartX"] ) - { - fitRangeSelector->setMinimum(val); - } - else if ( prop == m_properties["EndX"] ) - { - fitRangeSelector->setMaximum(val); - } - else if ( prop == m_properties["BackgroundA0"]) - { - backgroundRangeSelector->setMinimum(val); - m_dblManager->setValue(m_properties["Exponential1.Intensity"], 1.0-val); - m_dblManager->setValue(m_properties["Exponential2.Intensity"], 1.0-val); - m_dblManager->setValue(m_properties["StretchedExp.Intensity"], 1.0-val); - } - else if( prop == m_properties["Exponential1.Intensity"] - || prop == m_properties["Exponential2.Intensity"] - || prop == m_properties["StretchedExp.Intensity"]) - { - backgroundRangeSelector->setMinimum(1.0-val); - m_dblManager->setValue(m_properties["Exponential1.Intensity"], val); - m_dblManager->setValue(m_properties["Exponential2.Intensity"], val); - m_dblManager->setValue(m_properties["StretchedExp.Intensity"], val); - } - } +void IqtFit::singleFit() { + if (!validate()) + return; - void IqtFit::checkBoxUpdate(QtProperty * prop, bool checked) - { - if(prop == m_properties["UseFABADA"]) - { - if(checked) - { - m_dblManager->setValue(m_properties["MaxIterations"], 20000); - - m_properties["FABADA"]->addSubProperty(m_properties["OutputFABADAChain"]); - m_properties["FABADA"]->addSubProperty(m_properties["FABADAChainLength"]); - m_properties["FABADA"]->addSubProperty(m_properties["FABADAConvergenceCriteria"]); - m_properties["FABADA"]->addSubProperty(m_properties["FABADAJumpAcceptanceRate"]); - } - else - { - m_dblManager->setValue(m_properties["MaxIterations"], 500); - - m_properties["FABADA"]->removeSubProperty(m_properties["OutputFABADAChain"]); - m_properties["FABADA"]->removeSubProperty(m_properties["FABADAChainLength"]); - m_properties["FABADA"]->removeSubProperty(m_properties["FABADAConvergenceCriteria"]); - m_properties["FABADA"]->removeSubProperty(m_properties["FABADAJumpAcceptanceRate"]); - } - } - } + // Don't plot a new guess curve until there is a fit + disconnect(m_dblManager, SIGNAL(propertyChanged(QtProperty *)), this, + SLOT(plotGuess(QtProperty *))); - void IqtFit::constrainIntensities(CompositeFunction_sptr func) - { - std::string paramName = "f1.Intensity"; - size_t index = func->parameterIndex(paramName); + // First create the function + auto function = createFunction(); - switch ( m_uiForm.cbFitType->currentIndex() ) - { + const int fitType = m_uiForm.cbFitType->currentIndex(); + if (m_uiForm.ckConstrainIntensities->isChecked()) { + switch (fitType) { case 0: // 1 Exp case 2: // 1 Str - if(!func->isFixed(index)) - { - func->tie(paramName, "1-f0.A0"); - } - else - { - std::string paramValue = boost::lexical_cast<std::string>(func->getParameter(paramName)); - func->tie(paramName, paramValue); - func->tie("f0.A0", "1-"+paramName); - } + m_ties = "f1.Intensity = 1-f0.A0"; break; case 1: // 2 Exp case 3: // 1 Exp & 1 Str - if(!func->isFixed(index)) - { - func->tie(paramName,"1-f2.Intensity-f0.A0"); - } - else - { - std::string paramValue = boost::lexical_cast<std::string>(func->getParameter(paramName)); - func->tie(paramName,"1-f2.Intensity-f0.A0"); - func->tie(paramName, paramValue); - } + m_ties = "f1.Intensity=1-f2.Intensity-f0.A0"; + break; + default: break; } } + QString ftype = fitTypeString(); - /** - * Generates a string that defines the fitting minimizer based on the user - * options. - * - * @return Minimizer as a string - */ - QString IqtFit::minimizerString(QString outputName) const - { - QString minimizer = "Levenberg-Marquardt"; - - if(m_blnManager->value(m_properties["UseFABADA"])) - { - minimizer = "FABADA"; - - int chainLength = static_cast<int>(m_dblManager->value(m_properties["FABADAChainLength"])); - minimizer += ",ChainLength=" + QString::number(chainLength); - - double convergenceCriteria = m_dblManager->value(m_properties["FABADAConvergenceCriteria"]); - minimizer += ",ConvergenceCriteria=" + QString::number(convergenceCriteria); - - double jumpAcceptanceRate = m_dblManager->value(m_properties["FABADAJumpAcceptanceRate"]); - minimizer += ",JumpAcceptanceRate=" + QString::number(jumpAcceptanceRate); - - minimizer += ",PDF=" + outputName + "_PDF"; - - if(m_blnManager->value(m_properties["OutputFABADAChain"])) - minimizer += ",Chains=" + outputName + "_Chain"; - } - - return minimizer; + updatePlot(); + if (m_ffInputWS == NULL) { + return; } - void IqtFit::singleFit() - { - if(!validate()) - return; - - // Don't plot a new guess curve until there is a fit - disconnect(m_dblManager, SIGNAL(propertyChanged(QtProperty*)), this, SLOT(plotGuess(QtProperty*))); - - // First create the function - auto function = createFunction(); - - const int fitType = m_uiForm.cbFitType->currentIndex(); - if ( m_uiForm.ckConstrainIntensities->isChecked() ) - { - switch ( fitType ) - { - case 0: // 1 Exp - case 2: // 1 Str - m_ties = "f1.Intensity = 1-f0.A0"; - break; - case 1: // 2 Exp - case 3: // 1 Exp & 1 Str - m_ties = "f1.Intensity=1-f2.Intensity-f0.A0"; - break; - default: - break; - } - } - QString ftype = fitTypeString(); - - updatePlot(); - if ( m_ffInputWS == NULL ) - { - return; - } - - QString pyInput = "from IndirectCommon import getWSprefix\nprint getWSprefix('%1')\n"; - pyInput = pyInput.arg(m_ffInputWSName); - m_singleFitOutputName = runPythonCode(pyInput).trimmed() + - QString("fury_") + - ftype + - m_uiForm.spPlotSpectrum->text(); - - // Create the Fit Algorithm - m_singleFitAlg = AlgorithmManager::Instance().create("Fit"); - m_singleFitAlg->initialize(); - m_singleFitAlg->setPropertyValue("Function", function->asString()); - m_singleFitAlg->setPropertyValue("InputWorkspace", m_ffInputWSName.toStdString()); - m_singleFitAlg->setProperty("WorkspaceIndex", m_uiForm.spPlotSpectrum->text().toInt()); - m_singleFitAlg->setProperty("StartX", m_ffRangeManager->value(m_properties["StartX"])); - m_singleFitAlg->setProperty("EndX", m_ffRangeManager->value(m_properties["EndX"])); - m_singleFitAlg->setProperty("MaxIterations", static_cast<int>(m_dblManager->value(m_properties["MaxIterations"]))); - m_singleFitAlg->setProperty("Minimizer", minimizerString(m_singleFitOutputName).toStdString()); - m_singleFitAlg->setProperty("Ties", m_ties.toStdString()); - m_singleFitAlg->setPropertyValue("Output", m_singleFitOutputName.toStdString()); - - connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), - this, SLOT(singleFitComplete(bool))); - - m_batchAlgoRunner->addAlgorithm(m_singleFitAlg); - m_batchAlgoRunner->executeBatchAsync(); - } + QString pyInput = + "from IndirectCommon import getWSprefix\nprint getWSprefix('%1')\n"; + pyInput = pyInput.arg(m_ffInputWSName); + m_singleFitOutputName = runPythonCode(pyInput).trimmed() + QString("fury_") + + ftype + m_uiForm.spPlotSpectrum->text(); + + // Create the Fit Algorithm + m_singleFitAlg = AlgorithmManager::Instance().create("Fit"); + m_singleFitAlg->initialize(); + m_singleFitAlg->setPropertyValue("Function", function->asString()); + m_singleFitAlg->setPropertyValue("InputWorkspace", + m_ffInputWSName.toStdString()); + m_singleFitAlg->setProperty("WorkspaceIndex", + m_uiForm.spPlotSpectrum->text().toInt()); + m_singleFitAlg->setProperty("StartX", + m_ffRangeManager->value(m_properties["StartX"])); + m_singleFitAlg->setProperty("EndX", + m_ffRangeManager->value(m_properties["EndX"])); + m_singleFitAlg->setProperty( + "MaxIterations", + static_cast<int>(m_dblManager->value(m_properties["MaxIterations"]))); + m_singleFitAlg->setProperty( + "Minimizer", minimizerString(m_singleFitOutputName).toStdString()); + m_singleFitAlg->setProperty("Ties", m_ties.toStdString()); + m_singleFitAlg->setPropertyValue("Output", + m_singleFitOutputName.toStdString()); + + connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, + SLOT(singleFitComplete(bool))); + + m_batchAlgoRunner->addAlgorithm(m_singleFitAlg); + m_batchAlgoRunner->executeBatchAsync(); +} - void IqtFit::singleFitComplete(bool error) - { - disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), - this, SLOT(singleFitComplete(bool))); +void IqtFit::singleFitComplete(bool error) { + disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, + SLOT(singleFitComplete(bool))); - if(error) - { - QString msg = "There was an error executing the fitting algorithm. Please see the " + if (error) { + QString msg = + "There was an error executing the fitting algorithm. Please see the " "Results Log pane for more details."; - showMessageBox(msg); - return; - } + showMessageBox(msg); + return; + } - IFunction_sptr outputFunc = m_singleFitAlg->getProperty("Function"); + IFunction_sptr outputFunc = m_singleFitAlg->getProperty("Function"); - // Get params. - QMap<QString,double> parameters; - std::vector<std::string> parNames = outputFunc->getParameterNames(); - std::vector<double> parVals; + // Get params. + QMap<QString, double> parameters; + std::vector<std::string> parNames = outputFunc->getParameterNames(); + std::vector<double> parVals; - for( size_t i = 0; i < parNames.size(); ++i ) - parVals.push_back(outputFunc->getParameter(parNames[i])); + for (size_t i = 0; i < parNames.size(); ++i) + parVals.push_back(outputFunc->getParameter(parNames[i])); - for ( size_t i = 0; i < parNames.size(); ++i ) - parameters[QString(parNames[i].c_str())] = parVals[i]; + for (size_t i = 0; i < parNames.size(); ++i) + parameters[QString(parNames[i].c_str())] = parVals[i]; - m_ffRangeManager->setValue(m_properties["BackgroundA0"], parameters["f0.A0"]); + m_ffRangeManager->setValue(m_properties["BackgroundA0"], parameters["f0.A0"]); - const int fitType = m_uiForm.cbFitType->currentIndex(); - if ( fitType != 2 ) - { - // Exp 1 - m_dblManager->setValue(m_properties["Exponential1.Intensity"], parameters["f1.Intensity"]); - m_dblManager->setValue(m_properties["Exponential1.Tau"], parameters["f1.Tau"]); + const int fitType = m_uiForm.cbFitType->currentIndex(); + if (fitType != 2) { + // Exp 1 + m_dblManager->setValue(m_properties["Exponential1.Intensity"], + parameters["f1.Intensity"]); + m_dblManager->setValue(m_properties["Exponential1.Tau"], + parameters["f1.Tau"]); - if ( fitType == 1 ) - { - // Exp 2 - m_dblManager->setValue(m_properties["Exponential2.Intensity"], parameters["f2.Intensity"]); - m_dblManager->setValue(m_properties["Exponential2.Tau"], parameters["f2.Tau"]); - } + if (fitType == 1) { + // Exp 2 + m_dblManager->setValue(m_properties["Exponential2.Intensity"], + parameters["f2.Intensity"]); + m_dblManager->setValue(m_properties["Exponential2.Tau"], + parameters["f2.Tau"]); } + } - if ( fitType > 1 ) - { - // Str - QString fval; - if ( fitType == 2 ) { fval = "f1."; } - else { fval = "f2."; } - - m_dblManager->setValue(m_properties["StretchedExp.Intensity"], parameters[fval+"Intensity"]); - m_dblManager->setValue(m_properties["StretchedExp.Tau"], parameters[fval+"Tau"]); - m_dblManager->setValue(m_properties["StretchedExp.Beta"], parameters[fval+"Beta"]); + if (fitType > 1) { + // Str + QString fval; + if (fitType == 2) { + fval = "f1."; + } else { + fval = "f2."; } - // Can start upddating the guess curve again - connect(m_dblManager, SIGNAL(propertyChanged(QtProperty*)), this, SLOT(plotGuess(QtProperty*))); - - // Plot the guess first so that it is under the fit - plotGuess(NULL); - // Now show the fitted curve of the mini plot - m_uiForm.ppPlot->addSpectrum("Fit", m_singleFitOutputName + "_Workspace", 1, Qt::red); - - m_pythonExportWsName = ""; + m_dblManager->setValue(m_properties["StretchedExp.Intensity"], + parameters[fval + "Intensity"]); + m_dblManager->setValue(m_properties["StretchedExp.Tau"], + parameters[fval + "Tau"]); + m_dblManager->setValue(m_properties["StretchedExp.Beta"], + parameters[fval + "Beta"]); } - void IqtFit::plotGuess(QtProperty*) - { - // Do nothing if there is no sample data curve - if(!m_uiForm.ppPlot->hasCurve("Sample")) - return; + // Can start upddating the guess curve again + connect(m_dblManager, SIGNAL(propertyChanged(QtProperty *)), this, + SLOT(plotGuess(QtProperty *))); - CompositeFunction_sptr function = createFunction(true); + // Plot the guess first so that it is under the fit + plotGuess(NULL); + // Now show the fitted curve of the mini plot + m_uiForm.ppPlot->addSpectrum("Fit", m_singleFitOutputName + "_Workspace", 1, + Qt::red); - // Create the double* array from the input workspace - const size_t binIndxLow = m_ffInputWS->binIndexOf(m_ffRangeManager->value(m_properties["StartX"])); - const size_t binIndxHigh = m_ffInputWS->binIndexOf(m_ffRangeManager->value(m_properties["EndX"])); - const size_t nData = binIndxHigh - binIndxLow; + m_pythonExportWsName = ""; +} - std::vector<double> inputXData(nData); +void IqtFit::plotGuess(QtProperty *) { + // Do nothing if there is no sample data curve + if (!m_uiForm.ppPlot->hasCurve("Sample")) + return; - const Mantid::MantidVec& XValues = m_ffInputWS->readX(0); + CompositeFunction_sptr function = createFunction(true); - const bool isHistogram = m_ffInputWS->isHistogramData(); + // Create the double* array from the input workspace + const size_t binIndxLow = + m_ffInputWS->binIndexOf(m_ffRangeManager->value(m_properties["StartX"])); + const size_t binIndxHigh = + m_ffInputWS->binIndexOf(m_ffRangeManager->value(m_properties["EndX"])); + const size_t nData = binIndxHigh - binIndxLow; - for ( size_t i = 0; i < nData ; i++ ) - { - if ( isHistogram ) - inputXData[i] = 0.5*(XValues[binIndxLow+i]+XValues[binIndxLow+i+1]); - else - inputXData[i] = XValues[binIndxLow+i]; - } + std::vector<double> inputXData(nData); - FunctionDomain1DVector domain(inputXData); - FunctionValues outputData(domain); - function->function(domain, outputData); + const Mantid::MantidVec &XValues = m_ffInputWS->readX(0); - QVector<double> dataX; - QVector<double> dataY; + const bool isHistogram = m_ffInputWS->isHistogramData(); - for ( size_t i = 0; i < nData; i++ ) - { - dataX.append(inputXData[i]); - dataY.append(outputData.getCalculated(i)); - } - IAlgorithm_sptr createWsAlg = AlgorithmManager::Instance().create("CreateWorkspace"); - createWsAlg->initialize(); - createWsAlg->setChild(true); - createWsAlg->setLogging(false); - createWsAlg->setProperty("OutputWorkspace", "__GuessAnon"); - createWsAlg->setProperty("NSpec", 1); - createWsAlg->setProperty("DataX", dataX.toStdVector()); - createWsAlg->setProperty("DataY", dataY.toStdVector()); - createWsAlg->execute(); - MatrixWorkspace_sptr guessWs = createWsAlg->getProperty("OutputWorkspace"); - - m_uiForm.ppPlot->addSpectrum("Guess", guessWs, 0, Qt::green); + for (size_t i = 0; i < nData; i++) { + if (isHistogram) + inputXData[i] = + 0.5 * (XValues[binIndxLow + i] + XValues[binIndxLow + i + 1]); + else + inputXData[i] = XValues[binIndxLow + i]; } - void IqtFit::fitContextMenu(const QPoint &) - { - QtBrowserItem* item(NULL); + FunctionDomain1DVector domain(inputXData); + FunctionValues outputData(domain); + function->function(domain, outputData); - item = m_ffTree->currentItem(); + QVector<double> dataX; + QVector<double> dataY; - if ( ! item ) - return; + for (size_t i = 0; i < nData; i++) { + dataX.append(inputXData[i]); + dataY.append(outputData.getCalculated(i)); + } + IAlgorithm_sptr createWsAlg = + AlgorithmManager::Instance().create("CreateWorkspace"); + createWsAlg->initialize(); + createWsAlg->setChild(true); + createWsAlg->setLogging(false); + createWsAlg->setProperty("OutputWorkspace", "__GuessAnon"); + createWsAlg->setProperty("NSpec", 1); + createWsAlg->setProperty("DataX", dataX.toStdVector()); + createWsAlg->setProperty("DataY", dataY.toStdVector()); + createWsAlg->execute(); + MatrixWorkspace_sptr guessWs = createWsAlg->getProperty("OutputWorkspace"); + + m_uiForm.ppPlot->addSpectrum("Guess", guessWs, 0, Qt::green); +} - // is it a fit property ? - QtProperty* prop = item->property(); +void IqtFit::fitContextMenu(const QPoint &) { + QtBrowserItem *item(NULL); - // is it already fixed? - bool fixed = prop->propertyManager() != m_dblManager; + item = m_ffTree->currentItem(); - if ( fixed && prop->propertyManager() != m_stringManager ) - return; + if (!item) + return; - // Create the menu - QMenu* menu = new QMenu("IqtFit", m_ffTree); - QAction* action; + // is it a fit property ? + QtProperty *prop = item->property(); - if ( ! fixed ) - { - action = new QAction("Fix", m_parentWidget); - connect(action, SIGNAL(triggered()), this, SLOT(fixItem())); - } - else - { - action = new QAction("Remove Fix", m_parentWidget); - connect(action, SIGNAL(triggered()), this, SLOT(unFixItem())); - } + // is it already fixed? + bool fixed = prop->propertyManager() != m_dblManager; - menu->addAction(action); + if (fixed && prop->propertyManager() != m_stringManager) + return; - // Show the menu - menu->popup(QCursor::pos()); + // Create the menu + QMenu *menu = new QMenu("IqtFit", m_ffTree); + QAction *action; + + if (!fixed) { + action = new QAction("Fix", m_parentWidget); + connect(action, SIGNAL(triggered()), this, SLOT(fixItem())); + } else { + action = new QAction("Remove Fix", m_parentWidget); + connect(action, SIGNAL(triggered()), this, SLOT(unFixItem())); } - void IqtFit::fixItem() - { - QtBrowserItem* item = m_ffTree->currentItem(); + menu->addAction(action); - // Determine what the property is. - QtProperty* prop = item->property(); + // Show the menu + menu->popup(QCursor::pos()); +} - QtProperty* fixedProp = m_stringManager->addProperty( prop->propertyName() ); - QtProperty* fprlbl = m_stringManager->addProperty("Fixed"); - fixedProp->addSubProperty(fprlbl); - m_stringManager->setValue(fixedProp, prop->valueText()); +void IqtFit::fixItem() { + QtBrowserItem *item = m_ffTree->currentItem(); - item->parent()->property()->addSubProperty(fixedProp); - m_fixedProps[fixedProp] = prop; - item->parent()->property()->removeSubProperty(prop); - } + // Determine what the property is. + QtProperty *prop = item->property(); - void IqtFit::unFixItem() - { - QtBrowserItem* item = m_ffTree->currentItem(); + QtProperty *fixedProp = m_stringManager->addProperty(prop->propertyName()); + QtProperty *fprlbl = m_stringManager->addProperty("Fixed"); + fixedProp->addSubProperty(fprlbl); + m_stringManager->setValue(fixedProp, prop->valueText()); - QtProperty* prop = item->property(); - if ( prop->subProperties().empty() ) - { - item = item->parent(); - prop = item->property(); - } + item->parent()->property()->addSubProperty(fixedProp); + m_fixedProps[fixedProp] = prop; + item->parent()->property()->removeSubProperty(prop); +} + +void IqtFit::unFixItem() { + QtBrowserItem *item = m_ffTree->currentItem(); - item->parent()->property()->addSubProperty(m_fixedProps[prop]); - item->parent()->property()->removeSubProperty(prop); - m_fixedProps.remove(prop); - QtProperty* proplbl = prop->subProperties()[0]; - delete proplbl; - delete prop; + QtProperty *prop = item->property(); + if (prop->subProperties().empty()) { + item = item->parent(); + prop = item->property(); } + item->parent()->property()->addSubProperty(m_fixedProps[prop]); + item->parent()->property()->removeSubProperty(prop); + m_fixedProps.remove(prop); + QtProperty *proplbl = prop->subProperties()[0]; + delete proplbl; + delete prop; +} + } // namespace IDA } // namespace CustomInterfaces } // namespace MantidQt diff --git a/MantidQt/CustomInterfaces/src/Indirect/ResNorm.cpp b/MantidQt/CustomInterfaces/src/Indirect/ResNorm.cpp index db18d7446223cff9a200a74af6b1c3b7d576843c..8df7976a765664a6cc7bd659a8c9cd7924592c82 100644 --- a/MantidQt/CustomInterfaces/src/Indirect/ResNorm.cpp +++ b/MantidQt/CustomInterfaces/src/Indirect/ResNorm.cpp @@ -112,6 +112,7 @@ void ResNorm::run() { resNorm->setProperty("EnergyMax", eMax); resNorm->setProperty("CreateOutput", true); resNorm->setProperty("OutputWorkspace", outputWsName.toStdString()); + resNorm->setProperty("OutputWorkspaceTable", (outputWsName + "_Fit").toStdString()); m_batchAlgoRunner->addAlgorithm(resNorm); // Handle saving diff --git a/MantidQt/CustomInterfaces/src/Muon/ALCInterface.cpp b/MantidQt/CustomInterfaces/src/Muon/ALCInterface.cpp index a52e8a9ea46656ce5503523ea3af0e8a01bf2846..f70fe204e98fc0c6d7dd30b80c2caff417715d33 100644 --- a/MantidQt/CustomInterfaces/src/Muon/ALCInterface.cpp +++ b/MantidQt/CustomInterfaces/src/Muon/ALCInterface.cpp @@ -31,6 +31,7 @@ namespace CustomInterfaces ALCInterface::ALCInterface(QWidget* parent) : UserSubWindow(parent), m_ui(), + m_baselineModellingView(NULL), m_peakFittingView(NULL), m_dataLoading(NULL), m_baselineModelling(NULL), m_peakFitting(NULL), m_baselineModellingModel(new ALCBaselineModellingModel()), m_peakFittingModel(new ALCPeakFittingModel()) diff --git a/MantidQt/CustomInterfaces/src/QtReflMainView.cpp b/MantidQt/CustomInterfaces/src/QtReflMainView.cpp index a2c94562df9b0f759051ea6d4a835b49f4ab67b0..7e2e98744f4fd4d7bac53712c2f43c88f9bd4a91 100644 --- a/MantidQt/CustomInterfaces/src/QtReflMainView.cpp +++ b/MantidQt/CustomInterfaces/src/QtReflMainView.cpp @@ -8,6 +8,12 @@ #include <qinputdialog.h> #include <qmessagebox.h> + +namespace +{ + const QString ReflSettingsGroup = "Mantid/CustomInterfaces/ISISReflectometry"; +} + namespace MantidQt { namespace CustomInterfaces @@ -434,6 +440,44 @@ namespace MantidQt runPythonCode(QString::fromStdString(pythonSrc.str())); } + /** + Show the user file dialog to choose save location of notebook + */ + std::string QtReflMainView::requestNotebookPath() + { + QString qfilename = QFileDialog::getSaveFileName(0, "Save notebook file", QDir::currentPath(), + "IPython Notebook files (*.ipynb);;All files (*.*)", + new QString("IPython Notebook files (*.ipynb)")); + return qfilename.toStdString(); + } + + /** + Save settings + @param options : map of user options to save + */ + void QtReflMainView::saveSettings(const std::map<std::string,QVariant>& options) + { + QSettings settings; + settings.beginGroup(ReflSettingsGroup); + for(auto it = options.begin(); it != options.end(); ++it) + settings.setValue(QString::fromStdString(it->first), it->second); + settings.endGroup(); + } + + /** + Load settings + @param options : map of user options to load into + */ + void QtReflMainView::loadSettings(std::map<std::string,QVariant>& options) + { + QSettings settings; + settings.beginGroup(ReflSettingsGroup); + QStringList keys = settings.childKeys(); + for(auto it = keys.begin(); it != keys.end(); ++it) + options[it->toStdString()] = settings.value(*it); + settings.endGroup(); + } + /** Plot a workspace */ diff --git a/MantidQt/CustomInterfaces/src/ReflMainViewPresenter.cpp b/MantidQt/CustomInterfaces/src/ReflMainViewPresenter.cpp index 8b813d6392f361ddceaef1748a5cf1a5cec4e2eb..9323fb9b10cc1e91839a520a0f17ac3b65a302f9 100644 --- a/MantidQt/CustomInterfaces/src/ReflMainViewPresenter.cpp +++ b/MantidQt/CustomInterfaces/src/ReflMainViewPresenter.cpp @@ -24,9 +24,6 @@ #include <fstream> #include <sstream> -#include <QSettings> -#include <QFileDialog> - using namespace Mantid::API; using namespace Mantid::Geometry; @@ -36,7 +33,6 @@ using namespace MantidQt::MantidWidgets; namespace { - const QString ReflSettingsGroup = "Mantid/CustomInterfaces/ISISReflectometry"; void validateModel(ITableWorkspace_sptr model) { @@ -295,16 +291,15 @@ namespace MantidQt */ void ReflMainViewPresenter::saveNotebook(std::map<int,std::set<int>> groups, std::set<int> rows) { - std::unique_ptr<ReflGenerateNotebook> notebook(new ReflGenerateNotebook( - m_wsName, m_model, m_view->getProcessInstrument(), COL_RUNS, COL_TRANSMISSION, COL_OPTIONS, COL_ANGLE, - COL_QMIN, COL_QMAX, COL_DQQ, COL_SCALE, COL_GROUP)); - QString qfilename = QFileDialog::getSaveFileName(0, "Save notebook file", QDir::currentPath(), - "IPython Notebook files (*.ipynb);;All files (*.*)", - new QString("IPython Notebook files (*.ipynb)")); - std::string filename = qfilename.toStdString(); + + std::string filename = m_view->requestNotebookPath(); if (filename == "") { return; } + + std::unique_ptr<ReflGenerateNotebook> notebook(new ReflGenerateNotebook( + m_wsName, m_model, m_view->getProcessInstrument(), COL_RUNS, COL_TRANSMISSION, COL_OPTIONS, COL_ANGLE, + COL_QMIN, COL_QMAX, COL_DQQ, COL_SCALE, COL_GROUP)); std::string generatedNotebook = notebook->generateNotebook(groups, rows); std::ofstream file(filename.c_str(), std::ofstream::trunc); @@ -1512,11 +1507,7 @@ namespace MantidQt m_options[it->first] = it->second; //Save any changes to disk - QSettings settings; - settings.beginGroup(ReflSettingsGroup); - for(auto it = m_options.begin(); it != m_options.end(); ++it) - settings.setValue(QString::fromStdString(it->first), it->second); - settings.endGroup(); + m_view->saveSettings(m_options); } /** Load options from disk if possible, or set to defaults */ @@ -1538,12 +1529,7 @@ namespace MantidQt m_options["RoundDQQPrecision"] = 3; //Load saved values from disk - QSettings settings; - settings.beginGroup(ReflSettingsGroup); - QStringList keys = settings.childKeys(); - for(auto it = keys.begin(); it != keys.end(); ++it) - m_options[it->toStdString()] = settings.value(*it); - settings.endGroup(); + m_view->loadSettings(m_options); } } } diff --git a/MantidQt/CustomInterfaces/src/Tomography/ImageStackPreParams.cpp b/MantidQt/CustomInterfaces/src/Tomography/ImageStackPreParams.cpp index 60d8a1e2bd0dbc8a26e01cb9dcae0898e0a27395..b343d7c20876fa95bda014ff49ed75407ab2daaf 100644 --- a/MantidQt/CustomInterfaces/src/Tomography/ImageStackPreParams.cpp +++ b/MantidQt/CustomInterfaces/src/Tomography/ImageStackPreParams.cpp @@ -5,9 +5,7 @@ using namespace MantidQt::CustomInterfaces; namespace MantidQt { namespace CustomInterfaces { -ImageStackPreParams::ImageStackPreParams() -{ +ImageStackPreParams::ImageStackPreParams() : medianFilter(false) {} -} } // namespace CustomInterfaces } // namespace MantidQt diff --git a/MantidQt/CustomInterfaces/src/Tomography/TomographyIfaceModel.cpp b/MantidQt/CustomInterfaces/src/Tomography/TomographyIfaceModel.cpp index 15c9f4550e6d57228cd464e6c3cb350e47c23449..5aaaaccde66a10647182a685e42fefe0ca5570aa 100644 --- a/MantidQt/CustomInterfaces/src/Tomography/TomographyIfaceModel.cpp +++ b/MantidQt/CustomInterfaces/src/Tomography/TomographyIfaceModel.cpp @@ -582,7 +582,6 @@ TomographyIfaceModel::loadFITSImage(const std::string &path) { "Failed to load image. Could not load this file as a " "FITS image: " + std::string(e.what())); - return WorkspaceGroup_sptr(); } if (!alg->isExecuted()) { throw std::runtime_error( diff --git a/MantidQt/CustomInterfaces/test/EnggDiffractionPresenterTest.h b/MantidQt/CustomInterfaces/test/EnggDiffractionPresenterTest.h index 043aba68ed970e70f14f1dd292e947a3ddcf03a6..6a83147a7069e733967abf8766e7cce520a39664 100644 --- a/MantidQt/CustomInterfaces/test/EnggDiffractionPresenterTest.h +++ b/MantidQt/CustomInterfaces/test/EnggDiffractionPresenterTest.h @@ -385,6 +385,8 @@ public: // check automatic plotting EXPECT_CALL(mockView, focusedOutWorkspace()).Times(1).WillOnce(Return(true)); EXPECT_CALL(mockView, plotFocusedSpectrum(testing::_)).Times(1); + // There are two/three other tests that have the disabled_ prefix so they + // normally run // Should not try to use options for other types of focusing EXPECT_CALL(mockView, focusingCroppedRunNo()).Times(0); diff --git a/MantidQt/CustomInterfaces/test/EnggDiffractionViewMock.h b/MantidQt/CustomInterfaces/test/EnggDiffractionViewMock.h index 36c5bdd0a65a6a4d027c6a2f19146fc64ec9bf73..3f099eb845d1bcddcc1e9ca3c33c41e3eece692e 100644 --- a/MantidQt/CustomInterfaces/test/EnggDiffractionViewMock.h +++ b/MantidQt/CustomInterfaces/test/EnggDiffractionViewMock.h @@ -50,6 +50,9 @@ public: // virtual std::string currentCalibFile() const; MOCK_CONST_METHOD0(currentCalibFile, std::string()); + // std::string currentPlotType + MOCK_CONST_METHOD0(currentPlotType, int()); + // virtual std::string newVanadiumNo() const; MOCK_CONST_METHOD0(newVanadiumNo, std::string()); @@ -104,8 +107,25 @@ public: // void saveSettings() const; MOCK_CONST_METHOD0(saveSettings, void()); + // std::string saveOutputFiles + MOCK_CONST_METHOD0(saveOutputFiles, bool()); + // virtual void plotFocusedSpectrum(); - MOCK_METHOD1(plotFocusedSpectrum, void(const std::string&)); + MOCK_METHOD1(plotFocusedSpectrum, void(const std::string &)); + + // void plotFocusStatus(); + MOCK_METHOD0(plotFocusStatus, void()); + + // void plotRepChanged(); + MOCK_METHOD1(plotRepChanged, void(int idx)); + + // virtual void plotWaterfallSpectrum + MOCK_METHOD1(plotWaterfallSpectrum, void(const std::string &wsName)); + + // virtual void plotReplacingWindow + MOCK_METHOD1(plotReplacingWindow, void(const std::string &wsName)); + + }; #endif // MANTID_CUSTOMINTERFACES_ENGGDIFFRACTIONVIEWMOCK_H diff --git a/MantidQt/CustomInterfaces/test/ReflMainViewMockObjects.h b/MantidQt/CustomInterfaces/test/ReflMainViewMockObjects.h index 2d7f91d24a4c10c40bf3b3b3eb28cd15585c7b90..e42a5a70d0bc573e435fb47faf22d0f7b0a6a2b6 100644 --- a/MantidQt/CustomInterfaces/test/ReflMainViewMockObjects.h +++ b/MantidQt/CustomInterfaces/test/ReflMainViewMockObjects.h @@ -33,6 +33,7 @@ public: MOCK_METHOD2(giveUserCritical, void(std::string, std::string)); MOCK_METHOD2(giveUserInfo, void(std::string, std::string)); MOCK_METHOD2(giveUserWarning, void(std::string, std::string)); + MOCK_METHOD0(requestNotebookPath, std::string()); MOCK_METHOD1(showAlgorithmDialog, void(const std::string&)); MOCK_METHOD1(plotWorkspaces, void(const std::set<std::string>&)); @@ -46,6 +47,7 @@ public: MOCK_CONST_METHOD0(getClipboard, std::string()); MOCK_CONST_METHOD0(getSearchString, std::string()); MOCK_CONST_METHOD0(getSearchInstrument, std::string()); + MOCK_METHOD0(getEnableNotebook, bool()); //Calls we don't care about virtual void showTable(QReflTableModel_sptr) {}; @@ -53,9 +55,10 @@ public: virtual void setOptionsHintStrategy(MantidQt::MantidWidgets::HintStrategy*) {}; virtual void setProgressRange(int,int) {}; virtual void setProgress(int) {}; - virtual bool getEnableNotebook() {return false;}; virtual void setTableList(const std::set<std::string>&) {}; virtual void setInstrumentList(const std::vector<std::string>&, const std::string&) {}; + virtual void saveSettings(const std::map<std::string,QVariant>&) {}; + virtual void loadSettings(std::map<std::string,QVariant>&) {}; virtual std::string getProcessInstrument() const {return "FAKE";} virtual boost::shared_ptr<IReflPresenter> getPresenter() const {return boost::shared_ptr<IReflPresenter>();} }; diff --git a/MantidQt/CustomInterfaces/test/ReflMainViewPresenterTest.h b/MantidQt/CustomInterfaces/test/ReflMainViewPresenterTest.h index 4c53fb56bf68c8693e9933f650f7aa5440c18545..36d043f921e47425dc4ed88c241c0207f61cee26 100644 --- a/MantidQt/CustomInterfaces/test/ReflMainViewPresenterTest.h +++ b/MantidQt/CustomInterfaces/test/ReflMainViewPresenterTest.h @@ -13,6 +13,7 @@ #include "MantidQtCustomInterfaces/ReflMainViewPresenter.h" #include "ReflMainViewMockObjects.h" +#include "../inc/MantidQtCustomInterfaces/IReflPresenter.h" using namespace MantidQt::CustomInterfaces; using namespace Mantid::API; @@ -136,6 +137,8 @@ public: TS_ASSERT(AnalysisDataService::Instance().doesExist("TestWorkspace")); AnalysisDataService::Instance().remove("TestWorkspace"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testSaveExisting() { @@ -152,6 +155,8 @@ public: presenter.notify(IReflPresenter::SaveFlag); AnalysisDataService::Instance().remove("TestWorkspace"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testSaveAs() { @@ -180,6 +185,8 @@ public: AnalysisDataService::Instance().remove("TestWorkspace"); AnalysisDataService::Instance().remove("Workspace"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testAppendRow() { @@ -220,6 +227,8 @@ public: // Tidy up AnalysisDataService::Instance().remove("TestWorkspace"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testAppendRowSpecify() { @@ -263,6 +272,8 @@ public: // Tidy up AnalysisDataService::Instance().remove("TestWorkspace"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testAppendRowSpecifyPlural() { @@ -305,6 +316,8 @@ public: // Tidy up AnalysisDataService::Instance().remove("TestWorkspace"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testPrependRow() { @@ -344,6 +357,8 @@ public: // Tidy up AnalysisDataService::Instance().remove("TestWorkspace"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testPrependRowSpecify() { @@ -386,6 +401,8 @@ public: // Tidy up AnalysisDataService::Instance().remove("TestWorkspace"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testPrependRowSpecifyPlural() { @@ -429,6 +446,8 @@ public: // Tidy up AnalysisDataService::Instance().remove("TestWorkspace"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testDeleteRowNone() { @@ -460,6 +479,8 @@ public: // Tidy up AnalysisDataService::Instance().remove("TestWorkspace"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testDeleteRowSingle() { @@ -495,6 +516,8 @@ public: // Tidy up AnalysisDataService::Instance().remove("TestWorkspace"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testDeleteRowPlural() { @@ -533,6 +556,8 @@ public: // Tidy up AnalysisDataService::Instance().remove("TestWorkspace"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testProcess() { @@ -559,6 +584,11 @@ public: EXPECT_CALL(mockView, getSelectedRows()) .Times(1) .WillRepeatedly(Return(rowlist)); + EXPECT_CALL(mockView, getEnableNotebook()) + .Times(1) + .WillRepeatedly(Return(false)); + EXPECT_CALL(mockView, requestNotebookPath()) + .Times(0); presenter.notify(IReflPresenter::ProcessFlag); // Check output workspaces were created as expected @@ -579,6 +609,52 @@ public: AnalysisDataService::Instance().remove("IvsLam_12346"); AnalysisDataService::Instance().remove("TOF_12346"); AnalysisDataService::Instance().remove("IvsQ_12345_12346"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); + } + + void testProcessWithNotebook() { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + createPrefilledWorkspace("TestWorkspace"); + EXPECT_CALL(mockView, getWorkspaceToOpen()) + .Times(1) + .WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + std::set<int> rowlist; + rowlist.insert(0); + rowlist.insert(1); + + createTOFWorkspace("TOF_12345", "12345"); + createTOFWorkspace("TOF_12346", "12346"); + + // We should not receive any errors + EXPECT_CALL(mockView, giveUserCritical(_, _)).Times(0); + + // The user hits the "process" button with the first two rows selected + EXPECT_CALL(mockView, getSelectedRows()) + .Times(1) + .WillRepeatedly(Return(rowlist)); + EXPECT_CALL(mockView, getEnableNotebook()) + .Times(1) + .WillRepeatedly(Return(true)); + EXPECT_CALL(mockView, requestNotebookPath()) + .Times(1); + presenter.notify(IReflPresenter::ProcessFlag); + + // Tidy up + AnalysisDataService::Instance().remove("TestWorkspace"); + AnalysisDataService::Instance().remove("IvsQ_12345"); + AnalysisDataService::Instance().remove("IvsLam_12345"); + AnalysisDataService::Instance().remove("TOF_12345"); + AnalysisDataService::Instance().remove("IvsQ_12346"); + AnalysisDataService::Instance().remove("IvsLam_12346"); + AnalysisDataService::Instance().remove("TOF_12346"); + AnalysisDataService::Instance().remove("IvsQ_12345_12346"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } /* @@ -641,6 +717,8 @@ public: AnalysisDataService::Instance().remove("IvsQ_12346"); AnalysisDataService::Instance().remove("IvsLam_12346"); AnalysisDataService::Instance().remove("IvsQ_dataA_12346"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testBadWorkspaceType() { @@ -671,6 +749,8 @@ public: presenter.notify(IReflPresenter::OpenTableFlag); AnalysisDataService::Instance().remove("TestWorkspace"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testBadWorkspaceLength() { @@ -705,6 +785,8 @@ public: presenter.notify(IReflPresenter::OpenTableFlag); AnalysisDataService::Instance().remove("TestWorkspace"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testPromptSaveAfterAppendRow() { @@ -732,6 +814,8 @@ public: // The user tries to create a new table again, and does not get bothered EXPECT_CALL(mockView, askUserYesNo(_, _)).Times(0); presenter.notify(IReflPresenter::NewTableFlag); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testPromptSaveAfterDeleteRow() { @@ -771,6 +855,8 @@ public: // The user tries to create a new table again, and does not get bothered EXPECT_CALL(mockView, askUserYesNo(_, _)).Times(0); presenter.notify(IReflPresenter::NewTableFlag); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testPromptSaveAndDiscard() { @@ -791,6 +877,8 @@ public: // These next two times they don't get prompted - they have a new table presenter.notify(IReflPresenter::NewTableFlag); presenter.notify(IReflPresenter::NewTableFlag); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testPromptSaveOnOpen() { @@ -823,6 +911,8 @@ public: .WillRepeatedly(Return("TestWorkspace")); EXPECT_CALL(mockView, askUserYesNo(_, _)).Times(0); presenter.notify(IReflPresenter::OpenTableFlag); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testExpandSelection() { @@ -984,6 +1074,8 @@ public: // Tidy up AnalysisDataService::Instance().remove("TestWorkspace"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testClearRows() { @@ -1043,6 +1135,8 @@ public: // Tidy up AnalysisDataService::Instance().remove("TestWorkspace"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testCopyRow() { @@ -1066,6 +1160,8 @@ public: .Times(1) .WillRepeatedly(Return(rowlist)); presenter.notify(IReflPresenter::CopySelectedFlag); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testCopyRows() { @@ -1095,6 +1191,8 @@ public: .Times(1) .WillRepeatedly(Return(rowlist)); presenter.notify(IReflPresenter::CopySelectedFlag); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testCutRow() { @@ -1129,6 +1227,8 @@ public: TS_ASSERT_EQUALS(ws->String(0, RunCol), "12345"); TS_ASSERT_EQUALS(ws->String(1, RunCol), "24681"); TS_ASSERT_EQUALS(ws->String(2, RunCol), "24682"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testCutRows() { @@ -1165,6 +1265,8 @@ public: TS_ASSERT_EQUALS(ws->rowCount(), 1); // Check the only unselected row is left behind TS_ASSERT_EQUALS(ws->String(0, RunCol), "24682"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testPasteRow() { @@ -1212,6 +1314,8 @@ public: TS_ASSERT_EQUALS(ws->Double(1, ScaleCol), 5.0); TS_ASSERT_EQUALS(ws->Int(1, GroupCol), 6); TS_ASSERT_EQUALS(ws->String(1, OptionsCol), "abc"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testPasteNewRow() { @@ -1257,6 +1361,8 @@ public: TS_ASSERT_EQUALS(ws->Double(4, ScaleCol), 5.0); TS_ASSERT_EQUALS(ws->Int(4, GroupCol), 6); TS_ASSERT_EQUALS(ws->String(4, OptionsCol), "abc"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testPasteRows() { @@ -1315,6 +1421,8 @@ public: TS_ASSERT_EQUALS(ws->Double(2, ScaleCol), 3.0); TS_ASSERT_EQUALS(ws->Int(2, GroupCol), 2); TS_ASSERT_EQUALS(ws->String(2, OptionsCol), "def"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testPasteNewRows() { @@ -1371,6 +1479,8 @@ public: TS_ASSERT_EQUALS(ws->Double(5, ScaleCol), 3.0); TS_ASSERT_EQUALS(ws->Int(5, GroupCol), 2); TS_ASSERT_EQUALS(ws->String(5, OptionsCol), "def"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testImportTable() { @@ -1378,6 +1488,8 @@ public: ReflMainViewPresenter presenter(&mockView); EXPECT_CALL(mockView, showAlgorithmDialog("LoadReflTBL")); presenter.notify(IReflPresenter::ImportTableFlag); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testExportTable() { @@ -1385,6 +1497,8 @@ public: ReflMainViewPresenter presenter(&mockView); EXPECT_CALL(mockView, showAlgorithmDialog("SaveReflTBL")); presenter.notify(IReflPresenter::ExportTableFlag); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testPlotRowWarn() { @@ -1416,6 +1530,8 @@ public: // Tidy up AnalysisDataService::Instance().remove("TestWorkspace"); AnalysisDataService::Instance().remove("TOF_12345"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } void testPlotGroupWarn() { @@ -1447,6 +1563,8 @@ public: AnalysisDataService::Instance().remove("TestWorkspace"); AnalysisDataService::Instance().remove("TOF_12345"); AnalysisDataService::Instance().remove("TOF_12346"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); } }; diff --git a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/FunctionBrowser.h b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/FunctionBrowser.h index 87c698152d416147984d697f1388586bcfcbb8c6..c9ed1e70dcc5161d9133979b1a95a8ff6dcd466e 100644 --- a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/FunctionBrowser.h +++ b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/FunctionBrowser.h @@ -296,6 +296,8 @@ protected slots: void parameterChanged(QtProperty*); void parameterButtonClicked(QtProperty*); void globalChanged(QtProperty*, const QString&, bool); + /// Set value of an attribute (as a property) to a function + void setAttributeToFunction(Mantid::API::IFunction& fun, QtProperty* prop); protected: /// Manager for function group properties diff --git a/MantidQt/MantidWidgets/src/FunctionBrowser.cpp b/MantidQt/MantidWidgets/src/FunctionBrowser.cpp index edd8806fe5a7c6193b98df76b252a8d114346712..4184cc459586d37d77b198d246ceac180de1eab4 100644 --- a/MantidQt/MantidWidgets/src/FunctionBrowser.cpp +++ b/MantidQt/MantidWidgets/src/FunctionBrowser.cpp @@ -1348,6 +1348,28 @@ void FunctionBrowser::addFunction() emit functionStructureChanged(); } +/** + * Set value of an attribute (as a property) to a function. + * @param fun :: Function to which attribute is set. + * @param prop :: A property with the name and value of the attribute. + */ +void FunctionBrowser::setAttributeToFunction(Mantid::API::IFunction& fun, QtProperty* prop) +{ + std::string attName = prop->propertyName().toStdString(); + SetAttributeFromProperty setter(this,prop); + Mantid::API::IFunction::Attribute attr = fun.getAttribute(attName); + attr.apply(setter); + try + { + fun.setAttribute(attName,attr); + } + catch(std::exception& expt) + { + QMessageBox::critical(this,"MantidPlot - Error", "Cannot set attribute " + QString::fromStdString(attName) + + " of function " + prop->propertyName() + ":\n\n" + QString::fromStdString(expt.what())); + } +} + /** * Return the function * @param prop :: Function property @@ -1380,6 +1402,10 @@ Mantid::API::IFunction_sptr FunctionBrowser::getFunction(QtProperty* prop, bool cf->addFunction(f); } } + else if (isAttribute(child)) + { + setAttributeToFunction(*fun, child); + } } } else @@ -1390,19 +1416,7 @@ Mantid::API::IFunction_sptr FunctionBrowser::getFunction(QtProperty* prop, bool { if (isAttribute(child)) { - std::string attName = child->propertyName().toStdString(); - SetAttributeFromProperty setter(this,child); - Mantid::API::IFunction::Attribute attr = fun->getAttribute(attName); - attr.apply(setter); - try - { - fun->setAttribute(attName,attr); - } - catch(std::exception& expt) - { - QMessageBox::critical(this,"MantidPlot - Error", "Cannot set attribute " + QString::fromStdString(attName) + - " of function " + prop->propertyName() + ":\n\n" + QString::fromStdString(expt.what())); - } + setAttributeToFunction(*fun, child); } else if (!attributesOnly && isParameter(child)) { diff --git a/MantidQt/Python/mantidqt.sip b/MantidQt/Python/mantidqt.sip index 47824677bf3e1bcd8e3a02a951fbbfa38afd5ad5..8278d788941a600a84f1dd6cc448d1fde138bc8f 100644 --- a/MantidQt/Python/mantidqt.sip +++ b/MantidQt/Python/mantidqt.sip @@ -1171,9 +1171,9 @@ void SliceViewer::setRebinNumBins(int xBins, int yBins) %End - void setRebinMode(bool mode, bool locked) throw (std::runtime_error); + void setRebinMode(bool mode) throw (std::runtime_error); %Docstring -void SliceViewer::setRebinMode(bool mode, bool locked) +void SliceViewer::setRebinMode(bool mode) ------------------------------------------------------ Sets the SliceViewer in dynamic rebin mode. In this mode, the current view area (see setXYLimits()) is used as the @@ -1183,8 +1183,6 @@ void SliceViewer::setRebinMode(bool mode, bool locked) Args: mode :: true for rebinning mode - locked :: if true, then the rebinned area is only refreshed manually - or when changing rebinning parameters. %End diff --git a/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.h b/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.h index f2eded1e2fa66061992d0583adf13527708f6afc..75014b4c584c09308350b1e6a85956cc64fa9d8a 100644 --- a/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.h +++ b/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.h @@ -117,7 +117,7 @@ public: /// Dynamic Rebinning-related Python bindings void setRebinThickness(int dim, double thickness); void setRebinNumBins(int xBins, int yBins); - void setRebinMode(bool mode, bool locked); + void setRebinMode(bool mode); void refreshRebin(); /// Methods relating to peaks overlays. @@ -188,7 +188,6 @@ public slots: void LineMode_toggled(bool); void SnapToGrid_toggled(bool); void RebinMode_toggled(bool); - void RebinLock_toggled(bool); void autoRebin_toggled(bool); // Dynamic rebinning @@ -333,7 +332,7 @@ private: /// Synced menu/buttons MantidQt::API::SyncedCheckboxes *m_syncLineMode, *m_syncSnapToGrid, - *m_syncRebinMode, *m_syncRebinLock, *m_syncAutoRebin; + *m_syncRebinMode, *m_syncAutoRebin; /// Cached double for infinity double m_inf; diff --git a/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.ui b/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.ui index 9414476bc32f0f92da829ed186475e2fdcb485cb..d3b64c0df10eab853bd8fcc3abe0e5fe74e5c353 100644 --- a/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.ui +++ b/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.ui @@ -489,47 +489,6 @@ </property> </widget> </item> - <item> - <widget class="QToolButton" name="btnRebinLock"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="minimumSize"> - <size> - <width>45</width> - <height>45</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>45</width> - <height>45</height> - </size> - </property> - <property name="toolTip"> - <string>Lock the rebinned workspace in place (use the refresh button to refresh)</string> - </property> - <property name="text"> - <string>...</string> - </property> - <property name="icon"> - <iconset> - <normaloff>:/SliceViewer/icons/stock-lock.png</normaloff>:/SliceViewer/icons/stock-lock.png</iconset> - </property> - <property name="iconSize"> - <size> - <width>32</width> - <height>32</height> - </size> - </property> - <property name="checkable"> - <bool>true</bool> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> <item> <spacer name="horizontalSpacer_5"> <property name="orientation"> diff --git a/MantidQt/SliceViewer/src/PeaksViewer.cpp b/MantidQt/SliceViewer/src/PeaksViewer.cpp index 8034a80c7909877c78b2e430082b98b8e5b4776a..ac8fb544ccfb0608c79fc78374bcc485ece737eb 100644 --- a/MantidQt/SliceViewer/src/PeaksViewer.cpp +++ b/MantidQt/SliceViewer/src/PeaksViewer.cpp @@ -122,9 +122,9 @@ PeaksViewer::~PeaksViewer() {} */ bool PeaksViewer::hasThingsToShow() const { return m_presenter->size() >= 1; } -void PeaksViewer:: clearPeaksModeRequest( +void PeaksViewer::clearPeaksModeRequest( const PeaksWorkspaceWidget *const originWidget, const bool on) { - EditMode mode; + EditMode mode = None; if (on) { QList<PeaksWorkspaceWidget *> children = qFindChildren<PeaksWorkspaceWidget *>(this); @@ -149,7 +149,7 @@ void PeaksViewer:: clearPeaksModeRequest( void PeaksViewer::addPeaksModeRequest(const PeaksWorkspaceWidget * const originWidget, const bool on) { - EditMode mode; + EditMode mode = None; if(on) { QList<PeaksWorkspaceWidget *> children = qFindChildren<PeaksWorkspaceWidget *>(this); diff --git a/MantidQt/SliceViewer/src/SliceViewer.cpp b/MantidQt/SliceViewer/src/SliceViewer.cpp index f251baaf4445e9f32142a3d54ea3d16ef6fe62a6..34bba3a13bc370f18250ec802dc46ad8a141908e 100644 --- a/MantidQt/SliceViewer/src/SliceViewer.cpp +++ b/MantidQt/SliceViewer/src/SliceViewer.cpp @@ -122,8 +122,6 @@ SliceViewer::SliceViewer(QWidget *parent) // hide unused buttons ui.btnZoom->hide(); // hidden for a long time - ui.btnRebinLock->hide(); // now replaced by auto rebin mode - // ui.btnClearLine->hide(); // turning off line mode now removes line // ----------- Toolbar button signals ---------------- QObject::connect(ui.btnResetZoom, SIGNAL(clicked()), this, SLOT(resetZoom())); @@ -379,13 +377,6 @@ void SliceViewer::initMenus() { SLOT(RebinMode_toggled(bool))); m_menuView->addAction(action); - action = new QAction(QPixmap(), "&Lock Rebinned WS", this); - m_syncRebinLock = new SyncedCheckboxes(action, ui.btnRebinLock, true); - connect(m_syncRebinLock, SIGNAL(toggled(bool)), this, - SLOT(RebinLock_toggled(bool))); - action->setVisible(false); // hide this action - m_menuView->addAction(action); - action = new QAction(QPixmap(), "Rebin Current View", this); action->setShortcut(Qt::Key_R + Qt::ControlModifier); action->setEnabled(false); @@ -691,7 +682,6 @@ void SliceViewer::setWorkspace(Mantid::API::IMDWorkspace_sptr ws) { // Can't use dynamic rebin mode with a MatrixWorkspace m_syncRebinMode->setEnabled(!matrix); - m_syncRebinLock->setEnabled(!matrix); // Go to no normalization by default for MatrixWorkspaces if (matrix) @@ -1008,13 +998,10 @@ void SliceViewer::setRebinNumBins(int xBins, int yBins) { * See setRebinThickness() to adjust the thickness in other dimensions. * * @param mode :: true for rebinning mode - * @param locked :: if true, then the rebinned area is only refreshed manually - * or when changing rebinning parameters. */ -void SliceViewer::setRebinMode(bool mode, bool locked) { +void SliceViewer::setRebinMode(bool mode) { // The events associated with these controls will trigger a re-draw m_syncRebinMode->toggle(mode); - m_syncRebinLock->toggle(locked); } //------------------------------------------------------------------------------ @@ -1098,7 +1085,6 @@ void SliceViewer::RebinMode_toggled(bool checked) { for (size_t d = 0; d < m_dimWidgets.size(); d++) m_dimWidgets[d]->showRebinControls(checked); ui.btnRebinRefresh->setEnabled(checked); - ui.btnRebinLock->setEnabled(checked); m_syncAutoRebin->setEnabled(checked); m_actionRefreshRebin->setEnabled(checked); m_rebinMode = checked; @@ -1118,17 +1104,6 @@ void SliceViewer::RebinMode_toggled(bool checked) { } } -//------------------------------------------------------------------------------ -/** Slot called when locking/unlocking the dynamically rebinned - * overlaid workspace - * @param checked :: DO lock the workspace in place - */ -void SliceViewer::RebinLock_toggled(bool checked) { - m_rebinLocked = checked; - // Rebin immediately - if (!m_rebinLocked && m_rebinMode) - this->rebinParamsChanged(); -} //------------------------------------------------------------------------------ /// Slot for zooming into diff --git a/MantidQt/SliceViewer/test/SliceViewerPythonInterfaceTest.py b/MantidQt/SliceViewer/test/SliceViewerPythonInterfaceTest.py index f7ac61b15e55516acb33bf420257de185ef081dc..cff5c28c1d8bc20a66cc35ae89fff4f6f0cb077d 100644 --- a/MantidQt/SliceViewer/test/SliceViewerPythonInterfaceTest.py +++ b/MantidQt/SliceViewer/test/SliceViewerPythonInterfaceTest.py @@ -449,7 +449,7 @@ class SliceViewerPythonInterfaceTest(unittest.TestCase): sv.setRebinThickness(2, 1.0) sv.setRebinNumBins(50, 200) sv.refreshRebin() - sv.setRebinMode(True, True) + sv.setRebinMode(True) time.sleep(1) self.assertTrue(mtd.doesExist('uniform_rebinned'), 'Dynamically rebinned workspace was created.') ws = mtd['uniform_rebinned'] diff --git a/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/GraphDisplay.h b/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/GraphDisplay.h index b3cd39f36e9a261ea1cfe2f29978d28b1efbb2c1..a7cdd630803f9bf82ed17fe8141e2dfad3eaac94 100644 --- a/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/GraphDisplay.h +++ b/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/GraphDisplay.h @@ -96,7 +96,7 @@ class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER GraphDisplay double m_minY; double m_maxY; - static QColor g_curveColors[]; + static std::vector<QColor> g_curveColors; }; diff --git a/MantidQt/SpectrumViewer/src/GraphDisplay.cpp b/MantidQt/SpectrumViewer/src/GraphDisplay.cpp index fb458c40088478e07a1b3a7bc941514268b022d4..3b3f3f25de46e91737a218ce8c00db2f5d172919 100644 --- a/MantidQt/SpectrumViewer/src/GraphDisplay.cpp +++ b/MantidQt/SpectrumViewer/src/GraphDisplay.cpp @@ -12,7 +12,7 @@ namespace MantidQt namespace SpectrumView { -QColor GraphDisplay::g_curveColors[] = {Qt::black, Qt::red, Qt::green, Qt::blue}; +std::vector<QColor> GraphDisplay::g_curveColors; /** * Construct a GraphDisplay to display selected graph on the specifed plot @@ -40,6 +40,11 @@ GraphDisplay::GraphDisplay( QwtPlot* graphPlot, { if(isVertical) graphPlot->setAxisMaxMajor( QwtPlot::xBottom, 3 ); + + g_curveColors.push_back(Qt::black); + g_curveColors.push_back(Qt::red); + g_curveColors.push_back(Qt::green); + g_curveColors.push_back(Qt::blue); } @@ -130,7 +135,7 @@ void GraphDisplay::setData(const QVector<double> & xData, auto curve = new QwtPlotCurve; curve->setData( xData, yData ); curve->attach( m_graphPlot ); - auto colorIndex = m_curves.size() % sizeof(g_curveColors); + auto colorIndex = m_curves.size() % g_curveColors.size(); curve->setPen(QPen(g_curveColors[colorIndex])); m_curves.append(curve); diff --git a/Testing/Data/DocTest/EVS15289.raw.md5 b/Testing/Data/DocTest/EVS15289.raw.md5 new file mode 100644 index 0000000000000000000000000000000000000000..dc2506b23352680b70b700899227c9fd2fc8a379 --- /dev/null +++ b/Testing/Data/DocTest/EVS15289.raw.md5 @@ -0,0 +1 @@ +ea1cb1b0d1daa9579fbeb4acf3716162 \ No newline at end of file diff --git a/Testing/Data/UnitTest/EVS15289.raw.md5 b/Testing/Data/UnitTest/EVS15289.raw.md5 new file mode 100644 index 0000000000000000000000000000000000000000..dc2506b23352680b70b700899227c9fd2fc8a379 --- /dev/null +++ b/Testing/Data/UnitTest/EVS15289.raw.md5 @@ -0,0 +1 @@ +ea1cb1b0d1daa9579fbeb4acf3716162 \ No newline at end of file diff --git a/Testing/SystemTests/tests/analysis/ISISDirectReductionComponents.py b/Testing/SystemTests/tests/analysis/ISISDirectReductionComponents.py index 214f517a7cc9a5b79b8f123ede6d7174597f4e39..437c4668bf1496371331dfb39d53947f1a15ef43 100644 --- a/Testing/SystemTests/tests/analysis/ISISDirectReductionComponents.py +++ b/Testing/SystemTests/tests/analysis/ISISDirectReductionComponents.py @@ -53,6 +53,7 @@ class ISIS_ReductionWebLike(stresstesting.MantidStressTest): if 'outWS' in mtd: return 'outWS' saveFileName = self.rd.reducer.save_file_name +#pylint: disable=unused-variable outWS = Load(Filename=saveFileName+'.nxs') outWS *= 0.997979227566217 fullRezPath =FileFinder.getFullPath(saveFileName+'.nxs') @@ -63,7 +64,11 @@ class ISIS_ReductionWebLike(stresstesting.MantidStressTest): def validate(self): """Returns the name of the workspace & file to compare""" + # tolerance defined outside of init +#pylint: disable=W0201 self.tolerance = 1e-6 + # tolerance_is_reller defined outside of init +#pylint: disable=W0201 self.tolerance_is_reller=True self.disableChecking.append('SpectraMap') self.disableChecking.append('Instrument') @@ -97,6 +102,8 @@ class ISIS_ReductionWrapperValidate(stresstesting.MantidStressTest): # this is correct workflow for the ref file #rd.reducer.prop_man.save_file_name = ref_file # temporary workflow, until we fix workspace adjustment + # disable pylint -- access to protected member +#pylint: disable=W0212 rd._tolerr =3.e-3 rd.reducer.prop_man.save_file_name = 'MARIReduction.nxs' rd.validate_run_number=11001 @@ -239,6 +246,13 @@ class ISISLoadFilesMER(stresstesting.MantidStressTest): det = mon_ws.getDetector(0) self.assertTrue(det.isMonitor()) + ei_ws = GetAllEi(mon_ws,69634,69638,IgnoreSecondMonitor=False) + self.assertTrue(isinstance(ei_ws,Workspace)) + + en_peaks = ei_ws.readX(0) + self.assertAlmostEquals(len(en_peaks),1) + self.assertAlmostEqual(en_peaks[0],108.94,2) + self.valid = True @@ -283,12 +297,16 @@ class ISISLoadFilesLET(stresstesting.MantidStressTest): # self.assertEqual(mon_ws.getNumberHistograms(),27) + ei_ws = GetAllEi(mon_ws,40966,40967,IgnoreSecondMonitor=True) + self.assertTrue(isinstance(ei_ws,Workspace)) self.valid = True + def validate(self): return self.valid if __name__=="__main__": - ISISLoadFilesMER.runTest() + tester = ISISLoadFilesLET() + tester.runTest() diff --git a/Testing/SystemTests/tests/analysis/LoadVesuvioTest.py b/Testing/SystemTests/tests/analysis/LoadVesuvioTest.py index d0fbaa674ef409534fa863367f3485c382d0a7c4..11fa3b62ea0893150faf633ee78992f4c4117bdd 100644 --- a/Testing/SystemTests/tests/analysis/LoadVesuvioTest.py +++ b/Testing/SystemTests/tests/analysis/LoadVesuvioTest.py @@ -238,6 +238,10 @@ class VesuvioTests(unittest.TestCase): #================== Failure cases ================================ + def test_run_range_bad_order_raises_error(self): + self.assertRaises(RuntimeError, ms.LoadVesuvio, Filename="14188-14187", + OutputWorkspace=self.ws_name) + def test_missing_spectra_property_raises_error(self): self.assertRaises(RuntimeError, ms.LoadVesuvio, Filename="14188", OutputWorkspace=self.ws_name) diff --git a/Testing/SystemTests/tests/analysis/SNSPowderRedux.py b/Testing/SystemTests/tests/analysis/SNSPowderRedux.py index 7db8091f619f1dcf2c0250cc97f6dbacadb17943..2f6331ed6f310ef032875a9aa46700b0c3b4093a 100644 --- a/Testing/SystemTests/tests/analysis/SNSPowderRedux.py +++ b/Testing/SystemTests/tests/analysis/SNSPowderRedux.py @@ -17,7 +17,8 @@ def getSaveDir(): return os.path.abspath(os.path.curdir) def do_cleanup(): - Files = ["PG3_9829.gsa", + Files = ["PG3_9829.getn", + "PG3_9829.gsa", "PG3_9829.py", "PG3_9830.gsa", "PG3_9830.py", @@ -249,3 +250,38 @@ class SeriesAndConjoinFilesTest(stresstesting.MantidStressTest): self.tolerance = 1.0e-2 return ('PG3_9829','PG3_9829_golden') #return ('PG3_9830','PG3_9830_golden') # can only validate one workspace + +class ToPDFgetNTest(stresstesting.MantidStressTest): + cal_file = "PG3_FERNS_d4832_2011_08_24.cal" + char_file = "PG3_characterization_2012_02_23-HR-ILL.txt" + data_file = "PG3_9829_event.nxs" + getn_file = "PG3_9829.getn" + + def cleanup(self): + do_cleanup() + return True + + def requiredMemoryMB(self): + """Requires 3Gb""" + return 3000 + + def requiredFiles(self): + files = [self.cal_file, self.char_file, self.data_file] + return files + + def runTest(self): + savedir = getSaveDir() + PDToPDFgetN(Filename=self.data_file, + FilterBadPulses=25, + OutputWorkspace=self.data_file, + PDFgetNFile=os.path.join(savedir, self.getn_file), + CalibrationFile=self.cal_file, + CharacterizationRunsFile=self.char_file, + RemovePromptPulseWidth=50, + Binning=-.0004) + + def validateMethod(self): + return None # it running is all that we need + + def validate(self): + pass diff --git a/Testing/SystemTests/tests/analysis/ValidateInstrumentDefinitionFiles.py b/Testing/SystemTests/tests/analysis/ValidateInstrumentDefinitionFiles.py index f4df6a0b791a56ac268dde824c99b4884f2bf9e0..299d6d5dc17f3a001ae3e1cb7aa485ce5db73da2 100644 --- a/Testing/SystemTests/tests/analysis/ValidateInstrumentDefinitionFiles.py +++ b/Testing/SystemTests/tests/analysis/ValidateInstrumentDefinitionFiles.py @@ -1,3 +1,4 @@ +#pylint: disable=invalid-name #pylint: disable=no-init from mantid import config import os @@ -10,6 +11,8 @@ EXPECTED_EXT = '.expected' class ValidateInstrumentDefinitionFiles(stresstesting.MantidStressTest): xsdFile='' + # Explicitly specify single file to test. If None, test all. + theFileToTest=None #"MARI_Definition.xml" def skipTests(self): try: @@ -66,7 +69,10 @@ class ValidateInstrumentDefinitionFiles(stresstesting.MantidStressTest): direc = config['instrumentDefinition.directory'] self.xsdFile = os.path.join(direc,'Schema/IDF/1.0/','IDFSchema.xsd') - files = self.__getDataFileList__() + if self.theFileToTest is None: + files = self.__getDataFileList__() + else: + files = [os.path.join(direc,self.theFileToTest)] # run the tests failed = [] @@ -94,5 +100,7 @@ class ValidateInstrumentDefinitionFiles(stresstesting.MantidStressTest): if __name__ == '__main__': valid = ValidateInstrumentDefinitionFiles() + # validate specific file + #valid.theFileToTest = "MARI_Definition.xml" valid.runTest() diff --git a/Vates/VatesAPI/src/vtkMDHistoQuadFactory.cpp b/Vates/VatesAPI/src/vtkMDHistoQuadFactory.cpp index 748722813c5ac3a15ecafcdd812c525e03cee2c2..5413e173b246519bac7a43cb2f923107b971d8ea 100644 --- a/Vates/VatesAPI/src/vtkMDHistoQuadFactory.cpp +++ b/Vates/VatesAPI/src/vtkMDHistoQuadFactory.cpp @@ -92,6 +92,12 @@ namespace Mantid coord_t incrementX = (maxX - minX) / static_cast<coord_t>(nBinsX); coord_t incrementY = (maxY - minY) / static_cast<coord_t>(nBinsY); + boost::scoped_ptr<MDHistoWorkspaceIterator> iterator(dynamic_cast<MDHistoWorkspaceIterator*>(createIteratorWithNormalization(m_normalizationOption, m_workspace.get()))); + if (!iterator) { + throw std::runtime_error( + "Could not convert IMDIterator to a MDHistoWorkspaceIterator"); + } + const int imageSize = (nBinsX ) * (nBinsY ); vtkPoints *points = vtkPoints::New(); points->Allocate(static_cast<int>(imageSize)); @@ -119,8 +125,7 @@ namespace Mantid double progressFactor = 0.5/double(nBinsX); double progressOffset = 0.5; - boost::scoped_ptr<MDHistoWorkspaceIterator> iterator(dynamic_cast<MDHistoWorkspaceIterator*>(createIteratorWithNormalization(m_normalizationOption, m_workspace.get()))); - + size_t index = 0; for (int i = 0; i < nBinsX; i++) { diff --git a/buildconfig/CMake/PylintSetup.cmake b/buildconfig/CMake/PylintSetup.cmake index cb29dd4f648ff8e008c3a66f99566ecf1395c589..fda959056926555585a1e69bf8dd59578befa888 100644 --- a/buildconfig/CMake/PylintSetup.cmake +++ b/buildconfig/CMake/PylintSetup.cmake @@ -33,6 +33,8 @@ if ( PYLINT_FOUND ) Framework/PythonInterface/plugins scripts Testing/SystemTests/tests/analysis + tools + docs/sphinxext/mantiddoc ) set ( PYLINT_EXCLUDES scripts/lib1to2 diff --git a/docs/source/algorithms/CompactMD-v1.rst b/docs/source/algorithms/CompactMD-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..388f9ca7a084c437305608994667507b9665158f --- /dev/null +++ b/docs/source/algorithms/CompactMD-v1.rst @@ -0,0 +1,62 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- +Used to crop an n-dimensional :ref:`MDHistoWorkspace <MDHistoWorkspace>` to the first non-zero signal values found in all dimensions. + +Cropping +-------- +The cropping is done by supplying `IntegrateMDHistoWorkspace <http://docs.mantidproject.org/nightly/algorithms/IntegrateMDHistoWorkspace-v1.html>`__ with the minimum and maximum extents associated with the first non-zero +signal values in the workspace. + + +Usage +----- + + +**Example - CompactMD on MDHistoWorkspace** + +.. testcode:: CompactMDOnMDHistoWorkspace + + import math + #create an MDEventWorkspace for Rebinning + mdws = CreateMDWorkspace(Dimensions=3, Extents='-10,10,-10,10,-10,10', Names='A,B,C', Units='U,U,U') + FakeMDEventData(InputWorkspace=mdws, PeakParams='100000,-5,-5,0,1') + FakeMDEventData(InputWorkspace=mdws, PeakParams='100000,0,0,0,1') + FakeMDEventData(InputWorkspace=mdws, PeakParams='100000,5,5,0,1') + #Rebin mdws to create an MDHistoWorkspace + binned_ws = BinMD(InputWorkspace=mdws, AxisAligned=False, BasisVector0='a,unit,1,1,0',BasisVector1='b,unit,-1,1,0',BasisVector2='c,unit,0,0,1',NormalizeBasisVectors=True,Translation=[-10,-10,0], OutputExtents=[0,math.sqrt(2*20*20),-2,2,-10,10], OutputBins=[100, 100, 1] ) + + #A visualisation of the rebinned_ws can be found in the 'Input' section below. + + #run CompactMD on the rebinned workspace + compact_output = CompactMD(binned_ws) + + #A visualisation of the compacted workspace can be found in the 'Output' section below. + +Input: + +.. figure:: /images/RebbinedWorkspaceNoCompactMDApplied.jpg + :alt: RebbinedWorkspaceNoCompactMDApplied.jpg + :width: 400px + :align: center + + +Output: + +.. figure:: /images/RebbinedWorkspaceWithCompactMDApplied.jpg + :alt: RebbinedWorkspaceWithCompactMDApplied.jpg + :width: 400px + :align: center + + + +.. categories:: + +.. sourcelink:: \ No newline at end of file diff --git a/docs/source/algorithms/ComputeCalibrationCoefVan-v1.rst b/docs/source/algorithms/ComputeCalibrationCoefVan-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..47661c2ffe102b08e1a498d0c60dc5ee66232113 --- /dev/null +++ b/docs/source/algorithms/ComputeCalibrationCoefVan-v1.rst @@ -0,0 +1,83 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Algorithm creates a workspace with detector sensitivity correction coefficients using the given Vanadium workspace. The correction coefficients are calculated as follows. + +1. Calculate the Debye-Waller factor according to Sears and Shelley *Acta Cryst. A* **47**, 441 (1991): + + :math:`D_i = \exp\left(-B_i\cdot\frac{4\pi\sin\theta_i}{\lambda^2}\right)` + + :math:`B_i = \frac{3\hbar^2\cdot 10^{20}}{2m_VkT_m}\cdot J(y)` + + where :math:`J(y) = 0.5` if :math:`y < 10^{-3}`, otherwise + + :math:`J(y) = \int_0^1 x\cdot\mathrm{coth}\left(\frac{x}{2y}\right)\,\mathrm{d}x` + + where :math:`y=T/T_m` is the ratio of the temperature during the experiment :math:`T` to the Debye temperature :math:`T_m = 389K`, :math:`m_V` is the Vanadium atomic mass (in kg) and :math:`\theta_i` is the polar angle of the i-th detector. + +.. warning:: + + If sample log *temperature* is not present in the given Vanadium workspace or temperature is set to an invalid value, T=293K will be taken for the Debye-Waller factor calculation. Algorithm will produce warning in this case. + +2. Perform Gaussian fit of the data to find out the position of the peak centre and FWHM. These values are used to calculate sum :math:`S_i` as + + :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. + +3. Finally, the correction coefficients :math:`K_i` are calculated as + + :math:`K_i = D_i\times S_i` + +Workspace containing these correction coefficients is created as an output and can be used as a RHS workspace in :ref:`algm-Divide` to apply correction to the LHS workspace. + +.. note:: + + If gaussian fit fails, algorithm terminates with an error message. The error message contains name of the workspace and detector number. + +Restrictions on the input workspace +################################### + +The valid input workspace: + +- must have an instrument set +- must have a *wavelength* sample log + + +Usage +----- + +**Example** + +.. testcode:: ExComputeCalibrationCoefVan + + # load Vanadium data + wsVana = LoadMLZ(Filename='TOFTOFTestdata.nxs') + # calculate correction coefficients + wsCoefs = ComputeCalibrationCoefVan(wsVana) + print 'Spectrum 4 of the output workspace is filled with: ', round(wsCoefs.readY(999)[0]) + + # wsCoefs can be used as rhs with Divide algorithm to apply correction to the data + wsCorr = wsVana/wsCoefs + print 'Spectrum 4 of the input workspace is filled with: ', round(wsVana.readY(999)[0], 1) + print 'Spectrum 4 of the corrected workspace is filled with: ', round(wsCorr.readY(999)[0], 5) + +Output: + +.. testoutput:: ExComputeCalibrationCoefVan + + Spectrum 4 of the output workspace is filled with: 6596.0 + Spectrum 4 of the input workspace is filled with: 1.0 + Spectrum 4 of the corrected workspace is filled with: 0.00015 + +.. categories:: + +.. sourcelink:: diff --git a/docs/source/algorithms/ConvertCWSDExpToMomentum-v1.rst b/docs/source/algorithms/ConvertCWSDExpToMomentum-v1.rst index 904b8dd2a5ccd21368da10509b6c936c4aa5fe42..1d88cdd45e69e58036d500ee26a3af2f5b079de6 100644 --- a/docs/source/algorithms/ConvertCWSDExpToMomentum-v1.rst +++ b/docs/source/algorithms/ConvertCWSDExpToMomentum-v1.rst @@ -19,18 +19,22 @@ 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 -momentum transfer (:math:`Q`). +momentum transfer (Q). Outline of algorithm #################### -1. Create output workspace. +1. Create output workspace + * Build a virtual instrument, requiring + - position of source - position of sample - detector ID, position, detector size of pixels + 2. Read in data via table workspace + * 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 @@ -75,8 +79,6 @@ Each MDEvent in output MDEventWorkspace contain * Detector ID * Run Number - - Combine Experiment Into One MDEventWorkspace -------------------------------------------- @@ -90,7 +92,7 @@ In order to integrate them into an organized data structure, i.e., *MDEventWorks a virtual instrument is built in the algorithm. Virtual instrument -================== +################## A virtual instrument is built in the algorithm. In this virtual instrument, the number of detectors and their position are determined @@ -98,13 +100,13 @@ by the number of individual detector's positions in the *experiment*. MDEventWorkspace -================ +################ There is only one *virtual* instrument and *N* ExperimentInfo. *N* is the total number of experiment points in the *experiment*. Inconsistency between using virtual instrument and copying instrument -===================================================================== +##################################################################### It is found that the results, i.e., the peak's position in sample-momentum space, by FindPeaksMD, are different betweent the MDEventWorkspaces @@ -145,7 +147,7 @@ with 2D angular detector. Usage ----- -**Example - convert an HB3A's experiment to MDWorkspace in sample momentum workspae and creating virtual instrument.:** +**Example - convert an HB3A's experiment to MDWorkspace in sample momentum workspae and creating virtual instrument** .. testcode:: ExConvertHB3AToMDVirtualInstrument diff --git a/docs/source/algorithms/DetectorFloodWeighting-v1.rst b/docs/source/algorithms/DetectorFloodWeighting-v1.rst index b248c4b9d900d79aff5dd5ec4825d7438e445d8b..68f78e13e9da56d2e6ce28321e11fa362144bfc2 100644 --- a/docs/source/algorithms/DetectorFloodWeighting-v1.rst +++ b/docs/source/algorithms/DetectorFloodWeighting-v1.rst @@ -10,8 +10,7 @@ Description ----------- This algorithm is used to calculate the detector flood weighting workspace use for pixel flood corrections. It was originally developed for the ANSTO Bilby instrument. -This algorithm crops the data over the specified wavelength region, then normalizes each spectrum to the workspace spectrum maxima. The algorithm will then -perform a solid angle correction on each spectra via :ref:`algm-SolidAngle`. +This algorithm crops the data over the specified wavelength region, and sums it. The algorithm will then perform a solid angle correction on each spectra via :ref:`algm-SolidAngle` if specified, and divides through by the provided transmission workspace if provided. The result is divided by the mean spectrum value in the previous result. Usage ----- @@ -30,8 +29,6 @@ Usage print 'Number Histograms',out_ws.getNumberHistograms() print 'Min X:', out_ws.readX(0)[0], 'Max X:', out_ws.readX(0)[1] - y_data = out_ws.extractY() - print 'Min Y:', np.amin(y_data), 'Max Y:', np.amax(y_data) Output: @@ -39,7 +36,6 @@ Output: Number Histograms 2 Min X: 0.0 Max X: 10.0 - Min Y: 0.5 Max Y: 1.0 **Example - With Solid Angle Correction ** diff --git a/docs/source/algorithms/EVSDiffractionReduction-v1.rst b/docs/source/algorithms/EVSDiffractionReduction-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..c6fd73dc8b257b04e86d4a71bb6d984f9da39d6e --- /dev/null +++ b/docs/source/algorithms/EVSDiffractionReduction-v1.rst @@ -0,0 +1,44 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +A version of :ref:`ISISIndirectDiffractionReduction +<algm-ISISIndirectDiffractionReduction>` specific to use with VESUVIO (EVS) +data, the reduction is performed in the same way however there is the additional +option to load a PAR file. + +Usage +----- + +**Example - Running EVSDiffractionReduction.** + +.. testcode:: ExEVSDiffractionReductionSimple + + EVSDiffractionReduction(InputFiles='EVS15289.raw', + OutputWorkspace='DiffractionReductions', + InstrumentParFile='IP0005.dat') + + ws = mtd['DiffractionReductions'].getItem(0) + + print 'Workspace name: %s' % ws.getName() + print 'Number of spectra: %d' % ws.getNumberHistograms() + print 'Number of bins: %s' % ws.blocksize() + +Output: + +.. testoutput:: ExEVSDiffractionReductionSimple + + Workspace name: EVS15289_diffspec_red + Number of spectra: 1 + Number of bins: 3875 + +.. categories:: + +.. sourcelink:: diff --git a/docs/source/algorithms/GetAllEi-v1.rst b/docs/source/algorithms/GetAllEi-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..c0e46da75eb0b368df50457ff64c7b2b4f1fb2e5 --- /dev/null +++ b/docs/source/algorithms/GetAllEi-v1.rst @@ -0,0 +1,95 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Algorithm finds the estimate for all incident energies allowed by chopper system of an inelastic instrument and returns a workspace, +with the estimates for positions, heights and width of incident energies provided by the choppers and registered on monitors. +These estimates can be used as guess value for :ref:`algm-GetEi` algorithm or as inputs for a peak fitting procedure. + +Algorithm performs number of steps to identify the values requested: + +#. It takes appropriate log names from instrument definition file (IDF), namely chopper-position component and calculates last chopper speed and delay as average + of the filtered log values. Guess chopper opening times are calculated from chopper speed and delay time. The "chopper-position" component with appropriate properties + has to be present in IDF for this algorithm to work. See ISIS MARI or MAPS instrument definition files for example of "chopper-position" component. + +#. Algorithm uses estimate for the minimal energy resolution of an instrument and searches for real peaks around guess values obtained + earlier within 4 sigma of this resolution interval. + +#. If peaks are found, the algorithm performs running averages over signal in the appropriate time interval until first derivative + of the signal has only one zero. The position of this zero is returned as the guess energy and the distance between closest to + the guess energy zeros of the second derivative are returned as the guess values for the peak width. The peak amplitude + is estimated from the total intensity of the signal within the search interval, assuming that the peak shape is Gaussian. + +#. Similar procedure is performed for second monitor. The peak is accepted only if the peak width lies between the minimal and maximal instrument resolution values + and the distance between peaks positions on two monitors (on energy scale) is smaller then two sigma. + +Algorithm returns matrix workspace containing single spectrum, with x-values representing peak positions, y-values: peak heights and the error: peak width. X-values are +sorted according to energy in peaks (peaks with maximal energy are returned first). + +Used Subalgorithms +------------------ +The algorithm uses :ref:`Unit Factory <Unit Factory>` and :ref:`algm-ConvertUnits` algorithm +to convert units from TOF to energy. + + +**Example: Find all incident energies for test workspace** + +.. testcode:: foundAllEi + + # BUILD SAMPLE WORKSPACE + # Build sample workspace with chopper and in energy units to + # have defined peaks in defined energy positions + wsEn=CreateSampleWorkspace(Function='Multiple Peaks', NumBanks=1, BankPixelWidth=2, NumEvents=10000, XUnit='Energy', XMin=10, XMax=200, BinWidth=0.1) + # convert units to TOF to simulate real workspace obtained from experiment + ws = ConvertUnits(InputWorkspace=wsEn, Target='TOF') + # find chopper log values would be present in real workspace + l_chop = 7.5 # chopper position build into test workspace + l_mon1 = 15. # monitor 1 position (detector 1), build into test workspace + t_mon1 = 3100. # the time of flight defined by incident energy of the peak generated by CreateSampelpWorkspace algorithm. + t_chop = (l_chop/l_mon1)*t_mon1 + # Add these log values to simulated workspace to represent real sample logs + AddTimeSeriesLog(ws, Name="fermi_delay", Time="2010-01-01T00:00:00", Value=t_chop ,DeleteExisting=True) + AddTimeSeriesLog(ws, Name="fermi_delay", Time="2010-01-01T00:30:00", Value=t_chop ) + AddTimeSeriesLog(ws, Name="fermi_speed", Time="2010-01-01T00:00:00", Value=900 ,DeleteExisting=True) + AddTimeSeriesLog(ws, Name="fermi_speed", Time="2010-01-01T00:30:00", Value=900) + #------------------------------------------------------------- + + # FIND GUESS PEAKS + allEiWs=GetAllEi(ws,Monitor1SpecID=1,Monitor2SpecID=2) + # Analyze results + allEi = allEiWs.readX(0); + peakHeight = allEiWs.readY(0); + peakWidth = allEiWs.readE(0); + + # Check if peaks positions are indeed correct: + #------------------------------------------------------------- + resEi=[] + for ei_guess in allEi: + nop,t_peak,monIndex,tZero=GetEi(InputWorkspace=ws, Monitor1Spec=1, Monitor2Spec=2, EnergyEstimate=ei_guess) + resEi.append((nop,t_peak)); + print "! Guess Ei ! peak TOF ! peak height ! peak width !" + for ind,val in enumerate(resEi): + print "! {0: >6.1f} ! {1: >6.2f} ! {2: >6.2f} ! {3: >6.2f} !".format(allEi[ind],val[1],peakHeight[ind],peakWidth[ind]) + # + # NOTE: incident energy of GetEi is calculated from distance between monitor 1 and 2, and this distance is not correct in + # the test workspace. The tested point is that getEi can find energies from guess values and TOF for peaks is correct. + +Output: + +.. testoutput:: foundAllEi + :options: +NORMALIZE_WHITESPACE + + ! Guess Ei ! peak TOF ! peak height ! peak width ! + ! 67.0 ! 4188.03 ! 34.68 ! 2.35 ! + ! 124.1 ! 3079.09 ! 14.01 ! 4.35 ! + +.. categories:: + +.. sourcelink:: diff --git a/docs/source/algorithms/LoadEventAndCompress-v1.rst b/docs/source/algorithms/LoadEventAndCompress-v1.rst index 904f90502164953738e1a6948991f082077e233c..62a3f3d65ff40e21572ce2ba45219dfb24bfb24a 100644 --- a/docs/source/algorithms/LoadEventAndCompress-v1.rst +++ b/docs/source/algorithms/LoadEventAndCompress-v1.rst @@ -41,6 +41,44 @@ download due to their size. They can however be downloaded using these links: PG3_9830_event = LoadEventAndCompress(Filename='PG3_9830_event.nxs', MaxChunkSize=1.) +**Example - Usage with MPI** + +Create a python driver script called test_mpi.py + +.. code-block:: python + + from mantid.simpleapi import * + import mantid + if AlgorithmFactory.exists('GatherWorkspaces'): + HAVE_MPI = True + from mpi4py import MPI + mpiRank = MPI.COMM_WORLD.Get_rank() + mpiSize = MPI.COMM_WORLD.Get_size() + else: + HAVE_MPI = False + mpiRank = 0 # simplify if clauses + mpiSize = 1 # simplify if clauses + + wksp = LoadEventAndCompress(Filename="PG3_2538_event.nxs") + print "Rank = ", mpiRank, "Number of Events = ", wksp.getNumberEvents() + if mpiRank == 0: + reduce = AlignAndFocusPowder(InputWorkspace=wksp, CalFileName='PG3_calibrate_d2538_2014_05_13.cal', Params='0.5,0.01,2') + SaveNexus(reduce,Filename=str(mpiSize)+"tasks.nxs") + +And run it using the following commands + +.. code-block:: + + $ module load mpi/openmpi-x86_64 + $ export LD_PRELOAD=/usr/lib64/openmpi/lib/libmpi.so + $ mpirun -np 8 mantidpython test_mpi.py + +to run without mpi is simply + +.. code-block:: + + $ mantidpython test_mpi.py + .. categories:: .. sourcelink:: diff --git a/docs/source/algorithms/LoadMuonNexus-v1.rst b/docs/source/algorithms/LoadMuonNexus-v1.rst index acd6e582bb31550062f1022df13e320769f1b1b6..5f8aaf88a3c54b19f06667b7430512ea550aefdc 100644 --- a/docs/source/algorithms/LoadMuonNexus-v1.rst +++ b/docs/source/algorithms/LoadMuonNexus-v1.rst @@ -79,77 +79,6 @@ The ChildAlgorithms used by LoadMuonNexus are: LoadInstrument fails. As the Nexus file has limited instrument data, this only populates a few fields. -Usage ------ - -.. include:: ../usagedata-note.txt - -**Example - Load ISIS muon MUSR dataset:** - -.. testcode:: LoadMuonNexusOnePeriod - - # Load MUSR dataset - ws = LoadMuonNexus(Filename="MUSR00015189.nxs",EntryNumber=1) - print "Workspace has ", ws[0].getNumberHistograms(), " spectra" - -Output: - -.. testoutput:: LoadMuonNexusOnePeriod - - Workspace has 64 spectra - -**Example - Load event nexus file with time filtering:** - -.. testcode:: ExLoadMuonNexusSomeSpectra - - # Load some spectra - ws = LoadMuonNexus(Filename="MUSR00015189.nxs",SpectrumMin=5,SpectrumMax=10,EntryNumber=1) - print "Workspace has ", ws[0].getNumberHistograms(), " spectra" - -Output: - -.. testoutput:: ExLoadMuonNexusSomeSpectra - - Workspace has 6 spectra - -**Example - Load dead times into table:** - -.. testcode:: ExLoadDeadTimeTable - - # Load some spectra - ws = LoadMuonNexus(Filename="emu00006473.nxs",SpectrumMin=5,SpectrumMax=10,DeadTimeTable="deadTimeTable") - tab = mtd['deadTimeTable'] - for i in range(0,tab.rowCount()): - print tab.cell(i,0), tab.cell(i,1) - -Output: - -.. testoutput:: ExLoadDeadTimeTable - - 5 0.00161112251226 - 6 0.00215016817674 - 7 0.0102171599865 - 8 0.00431686220691 - 9 0.00743605662137 - 10 0.00421147653833 - -**Example - Load detector grouping into table:** - -.. testcode:: ExLoadDetectorGrouping - - # Load some spectra - ws = LoadMuonNexus(Filename="emu00006473.nxs",SpectrumList="1,16,17,32",DetectorGroupingTable="detectorTable") - tab = mtd['detectorTable'] - for i in range(0,tab.rowCount()): - print tab.cell(i,0) - -Output: - -.. testoutput:: ExLoadDetectorGrouping - - [ 1 16] - [17 32] - .. categories:: .. sourcelink:: diff --git a/docs/source/algorithms/LoadMuonNexus-v2.rst b/docs/source/algorithms/LoadMuonNexus-v2.rst index 0ca954061e4aad8e1f7858f51b8fbd86d6ad6d88..2e0732e98a485b22bc128fe43e25cb757d49a566 100644 --- a/docs/source/algorithms/LoadMuonNexus-v2.rst +++ b/docs/source/algorithms/LoadMuonNexus-v2.rst @@ -80,6 +80,77 @@ detects that it has been asked to load a previous version muon nexus file it will call the previous version of the algorithm to perform the task. +Usage +----- + +.. include:: ../usagedata-note.txt + +**Example - Load ISIS muon MUSR dataset:** + +.. testcode:: LoadMuonNexusOnePeriod + + # Load MUSR dataset + ws = LoadMuonNexus(Filename="MUSR00015189.nxs",EntryNumber=1) + print "Workspace has ", ws[0].getNumberHistograms(), " spectra" + +Output: + +.. testoutput:: LoadMuonNexusOnePeriod + + Workspace has 64 spectra + +**Example - Load event nexus file with time filtering:** + +.. testcode:: ExLoadMuonNexusSomeSpectra + + # Load some spectra + ws = LoadMuonNexus(Filename="MUSR00015189.nxs",SpectrumMin=5,SpectrumMax=10,EntryNumber=1) + print "Workspace has ", ws[0].getNumberHistograms(), " spectra" + +Output: + +.. testoutput:: ExLoadMuonNexusSomeSpectra + + Workspace has 6 spectra + +**Example - Load dead times into table:** + +.. testcode:: ExLoadDeadTimeTable + + # Load some spectra + ws = LoadMuonNexus(Filename="emu00006473.nxs",SpectrumMin=5,SpectrumMax=10,DeadTimeTable="deadTimeTable") + tab = mtd['deadTimeTable'] + for i in range(0,tab.rowCount()): + print tab.cell(i,0), tab.cell(i,1) + +Output: + +.. testoutput:: ExLoadDeadTimeTable + + 5 0.00161112251226 + 6 0.00215016817674 + 7 0.0102171599865 + 8 0.00431686220691 + 9 0.00743605662137 + 10 0.00421147653833 + +**Example - Load detector grouping into table:** + +.. testcode:: ExLoadDetectorGrouping + + # Load some spectra + ws = LoadMuonNexus(Filename="emu00006473.nxs",SpectrumList="1,16,17,32",DetectorGroupingTable="detectorTable") + tab = mtd['detectorTable'] + for i in range(0,tab.rowCount()): + print tab.cell(i,0) + +Output: + +.. testoutput:: ExLoadDetectorGrouping + + [ 1 16] + [17 32] + .. categories:: .. sourcelink:: diff --git a/docs/source/algorithms/PDToPDFgetN-v1.rst b/docs/source/algorithms/PDToPDFgetN-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..f37aae644e29dee983a0c7e1ab829a772546b5a4 --- /dev/null +++ b/docs/source/algorithms/PDToPDFgetN-v1.rst @@ -0,0 +1,32 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +This is a workflow algorithm that creates files suitable as input +into `PDFgetN <http://pdfgetn.sourceforge.net/>`_. + +#. :ref:`algm-PDLoadCharacterizations` +#. :ref:`algm-LoadEventAndCompress` if ``InputWorkspace`` is not + provided +#. :ref:`algm-PDDetermineCharacterizations` to determine information + from the characterization file +#. :ref:`algm-AlignAndFocusPowder` +#. :ref:`algm-NormaliseByCurrent` +#. :ref:`algm-SetUncertainties` (``SetError="sqrt"``) +#. :ref:`algm-SaveGSS` + +Workflow +######## + +.. diagram:: PDToPDFgetN-v1_wkflw.dot + +.. categories:: + +.. sourcelink:: diff --git a/docs/source/algorithms/ReflectometryReductionOneAuto-v1.rst b/docs/source/algorithms/ReflectometryReductionOneAuto-v1.rst index 0cce65d4d5d91397826b2e8058ac0d1287e328ac..487796977b1aeaf78bd6e31e7ecdc875b6bd4277 100644 --- a/docs/source/algorithms/ReflectometryReductionOneAuto-v1.rst +++ b/docs/source/algorithms/ReflectometryReductionOneAuto-v1.rst @@ -13,13 +13,19 @@ Facade over :ref:`algm-ReflectometryReductionOne`. Pulls numeric parameters out of the instrument parameters where possible. You can override any of these automatically applied defaults by providing your own value for the input. +See :ref:`algm-ReflectometryReductionOne` for more information on the wrapped algorithm. + +ProcessingInstructions +###################### + If ProcessingInstructions is not set its value is inferred from other properties: * If AnalysisMode = PointDetectorAnalaysis and PointDetectorStart = PointDetectorStop then the spectrum specified by PointDetectorStart is used. * If AnalysisMode = PointDetectorAnalaysis and PointDetectorStart ≠PointDetectorStop then the sum of the spectra from PointDetectorStart to PointDetectorStop is used. * If AnalysisMode = MultiDetectorAnalaysis then all of the spectra from MultiDetectorStart onwards are used. -See :ref:`algm-ReflectometryReductionOne` for more information on the wrapped algorithm. +Note, the ProcessingInstructions are workspace indicies, 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`. Workflow for WorkspaceGroups ############################ diff --git a/docs/source/algorithms/RemoveExpDecay-v1.rst b/docs/source/algorithms/RemoveExpDecay-v1.rst index 7307a59b69f6df06cd07ce3e4b48d5faa0791848..099f5988544139bcfb50a2bec4e27a834ad1fb42 100644 --- a/docs/source/algorithms/RemoveExpDecay-v1.rst +++ b/docs/source/algorithms/RemoveExpDecay-v1.rst @@ -9,8 +9,9 @@ Description ----------- -This algorithm removes the exponential time decay from a specified muon -spectra. By default, all the spectra in a workspace will be corrected. +This algorithm removes the exponential time decay from the specified muon +spectra, leaving the rest unchanged. By default, all the spectra +in a workspace will be corrected. The formula for removing the exponential decay is given by: diff --git a/docs/source/algorithms/SavePlot1DAsJson-v1.rst b/docs/source/algorithms/SavePlot1DAsJson-v1.rst index 86cbeeefd4e066d2a6f835388fa7cd9269f02e8e..85bb7a8d062628aad864fac2e7a84bdde2c6c871 100644 --- a/docs/source/algorithms/SavePlot1DAsJson-v1.rst +++ b/docs/source/algorithms/SavePlot1DAsJson-v1.rst @@ -26,12 +26,12 @@ Usage import os, numpy as np # prepare input - E = np.arange(-50, 50, 1.0) + E = np.arange(-50, 50, 10.0) I = 1000 * np.exp(-E**2/10**2) err = I ** .5 dataws = CreateWorkspace( DataX = E, DataY = I, DataE = err, NSpec = 1, - UnitX = "Energy(meV)") + UnitX = "Energy") # output path out_json = "myplot.json" # run algorithm diff --git a/docs/source/algorithms/TOFTOFCropWorkspace-v1.rst b/docs/source/algorithms/TOFTOFCropWorkspace-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..2a390bc98a778ae33750d5aaaa43175e39501f3b --- /dev/null +++ b/docs/source/algorithms/TOFTOFCropWorkspace-v1.rst @@ -0,0 +1,59 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Applies algorithm :ref:`algm-Cropworkspace` to an input workspace or a group of workspaces to crop the empty time channels. Boundaries are calculated as follows: + + :math:`X_{min} = 0` + + :math:`X_{max} = N_{fc}\times\Delta t` + +where :math:`N_{fc}` is the number of full time channels defined in the *full_channels* sample log and :math:`\Delta t` is the channel width defined in the *channel_width* sample log. + + +Restrictions on the input workspace +################################### + +- The unit of the X-axis must be **Time-of-flight**. +- Workspace must contain *channel_width* and *full_channels* sample logs. + + +Usage +----- + +**Example** + +.. testcode:: ExTOFTOFCropWorkspace + + # Load data + ws=Load(Filename='TOFTOFTestdata.nxs') + + print "Input workspace" + print "Total number of time channels: ", len(ws.readX(0)) + print "Number of filled time channels: ", ws.getRun().getLogData('full_channels').value + + wscropped = TOFTOFCropWorkspace(ws) + + print "Output workspace" + print "Total number of time channels: ", len(wscropped.readX(0)) + +Output: + +.. testoutput:: ExTOFTOFCropWorkspace + + Input workspace + Total number of time channels: 1025 + Number of filled time channels: 1020.0 + Output workspace + Total number of time channels: 1020 + +.. categories:: + +.. sourcelink:: diff --git a/docs/source/concepts/CrystalStructureAndReflections.rst b/docs/source/concepts/CrystalStructureAndReflections.rst new file mode 100644 index 0000000000000000000000000000000000000000..443dd594566083f6cdd9d048bc7a2e6e3d1b698d --- /dev/null +++ b/docs/source/concepts/CrystalStructureAndReflections.rst @@ -0,0 +1,293 @@ +.. _Crystal structure and reflections: + +Crystal structure and reflections +================================= + +This document describes how crystal structure data can be processed and used in Mantid. For the understanding of the +concepts of :ref:`symmetry <Symmetry groups>` and :ref:`space groups <Point and space groups>` in Mantid it may be +useful to read those introductory articles before proceeding with this document. While there is a short introduction +into theoretical aspects this page is not a replacement for proper introductory text books on the subject where all +these principles are explained in great detail and on a much more general basis. + +Theoretical aspects +~~~~~~~~~~~~~~~~~~~ + +Crystal structures +------------------ + +A crystal is modelled as an infinitely repeating three-dimensional arrangement of scatterers, usually atoms. Due to +the periodic nature of crystals, the entire object can be described by specifying the repeated unit and how +it is repeated. These information are called "crystal structure" and comprise three components: + + 1. Lattice (describes the periodicity of the structure) + 2. Basis (distribution of scatterers in the unit cell) + 3. Space group (describes the symmetry of the arrangement of scatterers) + +The description of the basis depends on the model's level of detail. In the simplest case it could be a list of +point scatterers that are fully characterized by three coordinates (x, y and z in terms of the lattice vectors) and +a scattering length. In reality however, the scatterers are usually atoms that fluctuate about their average position +due to thermal agitation. A basic way to model this motion is to assume it to be an isotropic phenomenon, allowing the +description with one single parameter that quantifies the radius of a sphere in which the scatterer oscillates +harmonically. This so called Debye-Waller-factor will be introduced later on. + +Another important parameter for a basic description of the basis is the so called occupancy. It describes the fraction +of the total number of scatterer-positions that is actually occupied. A common example where this is required are +unordered binary metal mixtures where the same position in the crystal structure is partly filled with two different +atoms in a randomly distributed manner. + +To summarize, a very basic model of the basis comprises a list of scatterers that are in turn characterized by +six parameters: + + 1. Scattering length (known for each element) + 2. Fractional coordinate x + 3. Fractional coordinate y + 4. Fractional coordinate z + 5. Occupancy of the site + 6. Isotropic thermal displacement parameter + +Knowledge of the space group makes it possible to derive all scatterers in the entire unit cell. The symmetry operations +of the space group map each scatterer-position onto a set of equivalent positions that are consequently occupied by the +same type of scatterer as well. Since the unit cell is repeated infinitely in all three directions of space, it is +enough to describe one unit cell. Finally, the lattice is described by six parameters as well, the lengths of the three +lattice vectors (usually given in :math:`\mathrm{\AA{}}`) and the three angles (in degree) between these vectors. + +Reflections and structure factors +--------------------------------- + +In a diffraction experiment the periodic arrangement of atoms is probed using radiation, in this case in the form of +neutrons, of an appropriate wavelength (on the same scale of interatomic distances, typically between 0.5 and +5 :math:`\mathrm{\AA{}}`). The incident beam interacts with the scatterers and in certain orientations the beam is +"reflected" by a flock of lattice planes, a phenomenon which is described by Bragg's law: + +.. math:: + 2d\sin\theta = \lambda + +In this equation :math: `d` is the spacing between the lattice planes, :math:`\theta` is the angle of the incoming beam +and the lattice plane normal and lambda is the wavelength of the radiation. In an experiment theta and lambda are +usually limited, thus they are limiting the range of interplanar spacings that can be probed. In Bragg's law the lattice +plane families are only described by one parameter, the interplanar distance. But each lattice plane family also has an +orientation in space which can be described by the plane's normal vector. Usually the vector is given in terms of the +reciprocal lattice of the structure, where it is reduced to three integers H, K, L, the so called Miller indices. With +knowledge of the :ref:`unit cell <Lattice>` (and thus the :math:`\mathbf{B}`-matrix), the interplanar spacing can also +be computed like this: + +.. math:: + d = \frac{1}{\left|\mathbf{B}\cdot\mathbf{h}\right|} + +The parameters taken into account so far determine the geometric characteristics of Bragg-reflections, i.e. their +position on a detector and their time of flight. But besides these, each reflection also has an intensity. The +intensity is proportional to the squared structure factor, which depends on the kind and arrangement of scatterers in +the unit cell. The structure factor is a complex number and can be calculated for a certain HKL by summing the +contributions of all N atoms j in the unit cell: + +.. math:: + F_{\mathbf{h}} = \sum\limits_{j}^{N}b_j\exp\left(2\pi i \mathbf{h} \cdot \mathbf{x}_j\right) + +In the above equation :math:`b` is the scattering length, :math:`\mathbf{h}` is the Miller index triplet HKL and +:math:`\mathbf{x}` contains the fractional coordinates of the j-th atom. To take into account isotropic thermal +motion of atoms, the term is multiplied with the Debye-Waller factor: + +.. math:: + F_{\mathbf{h}} = \sum\limits_{j}^{N}b_j\exp\left(2\pi i \mathbf{h} \cdot \mathbf{x}_j\right) + \exp\left(-2\pi^2 U/d_{\mathbf{h}}^2\right) + +Here, :math:`U` is the isotropic atomic displacement parameter, usually given in :math:`\mathrm{\AA{}}^2` and +:math:`d` is the lattice spacing discussed above. There are other, more complex models to describe the movement of +atoms, taking into account anisotropic movement and also anharmonic effects. + +Implementation in Mantid +~~~~~~~~~~~~~~~~~~~~~~~~ + +The concepts described above are available through the Python interface of Mantid. Crystal structures are represented +by a class that stores the three necessary pieces of information. Objects of that class can be created by supplying +string representations of those three arguments. + +.. testcode:: ExCrystalStructureConstruction + + from mantid.geometry import CrystalStructure + + silicon = CrystalStructure("5.431 5.431 5.431", "F d -3 m", "Si 0 0 0 1.0 0.05") + + unitCell = silicon.getUnitCell() + print 'Crystal structure of silicon:' + print ' Unit cell:', unitCell.a(), unitCell.b(), unitCell.c(), unitCell.alpha(), unitCell.beta(), unitCell.gamma() + + spaceGroup = silicon.getSpaceGroup() + print ' Space group:', spaceGroup.getHMSymbol() + print ' Point group:', spaceGroup.getPointGroup().getHMSymbol() + + scatterers = silicon.getScatterers() + print ' Total number of scatterers:', len(scatterers) + + for i, scatterer in enumerate(scatterers): + print ' ' + str(i) + ':', scatterer + +The above script produces the following output: + +.. testoutput:: ExCrystalStructureConstruction + + Crystal structure of silicon: + Unit cell: 5.431 5.431 5.431 90.0 90.0 90.0 + Space group: F d -3 m + Point group: m-3m + Total number of scatterers: 1 + 0: Si 0 0 0 1 0.05 + +In general, the unit cell must be specified using either 3 or 6 space-separated floating point numbers, representing +the three axis lengths and the three angles between them. The list of scatterers is required to be a semi-colon +separated list of strings which contain the following information: Element symbol, x, y, z (fractional coordinates), +occupancy (between 0 and 1) and isotropic atomic displacement parameter. The fractional coordinates can also be given +as fractions (for example :math:`1/2` or :math:`1/3`) and for giving the coordinates in hexagonal or trigonal structures +this is highly recommended as there may be precision problems with decimal numbers. + +While the CrystalStructure class is storing information, there is another class that makes use of these information to +generate reflections and calculate structure factors. This class is called ReflectionGenerator and can be constructed +from a CrystalStructure-object: + +.. testcode:: ExReflectionGeneratorConstruction + + from mantid.geometry import CrystalStructure, ReflectionGenerator + from mantid.kernel import V3D + + silicon = CrystalStructure("5.431 5.431 5.431", "F d -3 m", "Si 0 0 0 1.0 0.05") + generator = ReflectionGenerator(silicon) + + # Create list of unique reflections between 0.7 and 3.0 Angstrom + hkls = generator.getUniqueHKLs(0.7, 3.0) + + print 'There are', len(hkls), 'unique reflections for Si in the specified resolution range.' + print 'The reflection [222] is' + (' not' if not V3D(2, 2, 2) in hkls else '') + ' contained in the list.' + +.. testoutput:: ExReflectionGeneratorConstruction + + There are 20 unique reflections for Si in the specified resolution range. + The reflection [222] is contained in the list. + +Checking the reflection conditions of space group :math:`Fd\bar{3}m` (origin choice 1) in the International Tables for +Crystallography shows that if an atom is on the 8a position, additional conditions apply (:math:`h=2n+1` or +:math:`h+k+l=4n` for general reflections). Using these additional conditions, the 222 reflection should in fact +not be in the list. This can be verified by calculating structure factors for the list of reflections and check if +there are very small values present. + +.. testcode:: ExReflectionGeneratorViolations + + from mantid.geometry import CrystalStructure, ReflectionGenerator + import numpy as np + + silicon = CrystalStructure("5.431 5.431 5.431", "F d -3 m", "Si 0 0 0 1.0 0.05") + generator = ReflectionGenerator(silicon) + + # Create list of unique reflections between 0.7 and 3.0 Angstrom + hkls = generator.getUniqueHKLs(0.7, 3.0) + + # Calculate structure factors for those HKLs + fSquared = generator.getFsSquared(hkls) + + # Find HKLs with very small structure factors: + zeroFSquared = [(hkl, sf) for hkl, sf in zip(hkls, fSquared) if sf < 1e-9] + + print 'HKL F^2' + for hkl, sf in zeroFSquared: + print hkl, ' ', np.round(sf, 2) + +The output of the above script should show three reflections with very small values for :math:`F^2`. Their indices +violate the special conditions mentioned in the previous paragraph, so the reflections are actually extinct: + +.. testoutput:: ExReflectionGeneratorViolations + + HKL F^2 + [2,2,2] 0.0 + [4,4,2] 0.0 + [6,2,2] 0.0 + +Those three reflections are included in the list of unique HKLs, because the standard method to determine whether a +reflection is allowed or not uses the space group symmetry which only reflects the general conditions listed in ITA. +It is however possible to exclude those reflections at the cost of more computations by making use of the structure +factor calculation. This can either be done by passing an additional enum-value of the type ReflectionConditionFilter +to the constructor of ReflectionGenerator or by passing it to the actual generator function: + +.. testcode:: ExReflectionGeneratorSF + + from mantid.geometry import CrystalStructure, ReflectionGenerator, ReflectionConditionFilter + from mantid.kernel import V3D + + silicon = CrystalStructure("5.431 5.431 5.431", "F d -3 m", "Si 0 0 0 1.0 0.05") + generator = ReflectionGenerator(silicon) + + # Create list of unique reflections between 0.7 and 3.0 Angstrom, use structure factors for filtering + hkls = generator.getUniqueHKLsUsingFilter(0.7, 3.0, ReflectionConditionFilter.StructureFactor) + + print 'There are', len(hkls), 'unique reflections for Si in the specified resolution range.' + print 'The reflection [222] is' + (' not' if not V3D(2, 2, 2) in hkls else '') + ' contained in the list.' + +With this option, the three reflections from the example above are missing and as an indicator, the [222] reflection +is actually checked: + +.. testoutput:: ExReflectionGeneratorSF + + There are 17 unique reflections for Si in the specified resolution range. + The reflection [222] is not contained in the list. + +Other options for filtering are Centering and None. If the latter one is used the reflections are only filtered +according to their :math:`d`-value to fit the specified range. + +Another capability of ReflectionGenerator is the calculation of :math:`d`-values for a list of HKLs, very similar +to the process for :math:`F^2`: + +.. testcode:: ExReflectionGeneratorCalculateD + + from mantid.geometry import CrystalStructure, ReflectionGenerator, ReflectionConditionFilter + import numpy as np + + silicon = CrystalStructure("5.431 5.431 5.431", "F d -3 m", "Si 0 0 0 1.0 0.05") + generator = ReflectionGenerator(silicon) + + # Create list of unique reflections between 0.7 and 3.0 Angstrom + hkls = generator.getUniqueHKLsUsingFilter(0.7, 3.0, ReflectionConditionFilter.StructureFactor) + + # Calculate d and F^2 + dValues = generator.getDValues(hkls) + fSquared = generator.getFsSquared(hkls) + + pg = silicon.getSpaceGroup().getPointGroup() + + # Make list of tuples and sort by d-values, descending, include point group for multiplicity. + reflections = sorted([(hkl, d, fsq, len(pg.getEquivalents(hkl))) for hkl, d, fsq in zip(hkls, dValues, fSquared)], + key=lambda x: x[1], reverse=True) + + print '{0:<8}{1:>8}{2:>8}{3:>4}'.format('HKL', 'd', 'F^2', 'M') + for reflection in reflections: + print '{0!s:<8}{1:>8.5f}{2:>8.2f}{3:>4}'.format(*reflection) + +This script will print a table with the reflections including their :math:`d`-value, :math:`F^2` and multiplicity due to point group +symmetry: + +.. testoutput:: ExReflectionGeneratorCalculateD + + HKL d F^2 M + [2,2,0] 1.92015 645.02 12 + [3,1,1] 1.63751 263.85 24 + [4,0,0] 1.35775 377.63 6 + [3,3,1] 1.24596 154.47 24 + [4,2,2] 1.10860 221.08 24 + [3,3,3] 1.04520 90.43 8 + [5,1,1] 1.04520 90.43 24 + [4,4,0] 0.96007 129.43 12 + [5,3,1] 0.91801 52.94 48 + [6,2,0] 0.85872 75.78 24 + [5,3,3] 0.82822 31.00 24 + [4,4,4] 0.78390 44.36 8 + [5,5,1] 0.76049 18.15 24 + [7,1,1] 0.76049 18.15 24 + [6,4,2] 0.72575 25.97 48 + [5,5,3] 0.70706 10.62 24 + [7,3,1] 0.70706 10.62 48 + +Further reading +~~~~~~~~~~~~~~~ + +This concept page explains what's available in the Python interface. Some underlying parts may be interesting for C++ +developers, as the concepts of generating and filtering HKLs are pretty much hidden behind the ReflectionGenerator class +in the Python interface. More detail is available in the generated C++ documentation. + +.. categories:: Concepts diff --git a/docs/source/concepts/DiffractionCalibrationWorkspace.rst b/docs/source/concepts/DiffractionCalibrationWorkspace.rst index 58ee3f066f1239d1014fabe0b5b590fe423205f9..105e6e31562877adb9521585cdb43bf2205a28ff 100644 --- a/docs/source/concepts/DiffractionCalibrationWorkspace.rst +++ b/docs/source/concepts/DiffractionCalibrationWorkspace.rst @@ -57,3 +57,5 @@ various parameters on an instrument view. * ``offset`` (double array) not used. Value of the legacy calibration file. The `group` information will still be extracted into separate `GroupingWorkspace` and `MaskWorkspace`. + +.. categories:: Concepts diff --git a/docs/source/concepts/MDNorm.rst b/docs/source/concepts/MDNorm.rst index 1a1fdf7a1e8cda9fd304ef831f7c0537bcf981d6..8f2d64ba4430c6a34de7cd74f4a404caf449b819 100644 --- a/docs/source/concepts/MDNorm.rst +++ b/docs/source/concepts/MDNorm.rst @@ -158,4 +158,6 @@ Current implementation As of release 3.3, the normalization can be calculated for single crystal diffraction (:ref:`MDNormSCD <algm-MDNormSCD>`) and single crystal direct geometry inelastic scattering -(:ref:`MDNormDirectSC <algm-MDNormDirectSC>`). +(:ref:`MDNormDirectSC <algm-MDNormDirectSC>`). + +.. categories:: Concepts diff --git a/docs/source/diagrams/PDToPDFgetN-v1_wkflw.dot b/docs/source/diagrams/PDToPDFgetN-v1_wkflw.dot new file mode 100644 index 0000000000000000000000000000000000000000..23d7d3128f5710701b37233d9e12463bd670748e --- /dev/null +++ b/docs/source/diagrams/PDToPDFgetN-v1_wkflw.dot @@ -0,0 +1,34 @@ +digraph AlignAndFocusPowder { + label="AlignAndFocusPowder Flowchart" + $global_style + + subgraph params { + $param_style + InputWorkspace + } + + subgraph algoritms { + $algorithm_style + loadChar [label="PDLoadCharacterizations v1"] + loadEvent [label="LoadEventAndCompress v1"] + determineChar [label="PDDetermineCharacterizations v1"] + alignAndFocus [label="AlignAndFocusPowder v1"] + norm [label="NormaliseByCurrent v1"] + setUncert [label="SetUncertainties v1"] + saveGSS [label="SaveGSS v1"] + } + + subgraph decisions { + $decision_style + } + + + loadChar -> determineChar + loadEvent -> InputWorkspace + InputWorkspace -> determineChar + InputWorkspace -> alignAndFocus + determineChar -> alignAndFocus + alignAndFocus -> norm + norm -> setUncert + setUncert -> saveGSS +} diff --git a/docs/source/images/RebbinedWorkspaceNoCompactMDApplied.JPG b/docs/source/images/RebbinedWorkspaceNoCompactMDApplied.JPG new file mode 100644 index 0000000000000000000000000000000000000000..977b23d832c1c10900d09d518dd9e1745776aa92 Binary files /dev/null and b/docs/source/images/RebbinedWorkspaceNoCompactMDApplied.JPG differ diff --git a/docs/source/images/RebbinedWorkspaceWithCompactMDApplied.JPG b/docs/source/images/RebbinedWorkspaceWithCompactMDApplied.JPG new file mode 100644 index 0000000000000000000000000000000000000000..36a4fbc0a412fce0fbb71bd17b3e0c75414ebce4 Binary files /dev/null and b/docs/source/images/RebbinedWorkspaceWithCompactMDApplied.JPG differ diff --git a/docs/source/interfaces/Engineering_Diffraction.rst b/docs/source/interfaces/Engineering_Diffraction.rst index fa92627075643a5f5df84bfa47f8633c0877e737..10c7cd263bfae9de07007325f2efb5606b076898 100644 --- a/docs/source/interfaces/Engineering_Diffraction.rst +++ b/docs/source/interfaces/Engineering_Diffraction.rst @@ -99,6 +99,24 @@ numbers. For example: 2, 100, 102, 107 3, 300, 310, 320-329, 350-370 +Output +^^^^^^ + +Under the output section, the user is provided with an option of +plotting data in three different formats. One Window - Replacing +Plots: will replace the previous graph and plot a new graph on top. +One Window - Waterfall: will plot all the generated focused +workspace graphs in one window which can be useful while comparing +various graphs. The Multiple Windows: will plot graph in +separate windows. + +The user also has an option of generated GSS, XYE and OpenGenie +formatted file by clicking the Output Files checkbox. This will +generated three different files for each focused output workspace +in Mantid. These files can be found with appropriate name at location: +C:\EnginX_Mantid\User\236516\Focus on Windows, the +EnginX_Mantid folder can be found on Desktop/Home on other platforms. + Settings -------- diff --git a/docs/source/interfaces/HFIR_4Circle_Reduction.rst b/docs/source/interfaces/HFIR_4Circle_Reduction.rst new file mode 100644 index 0000000000000000000000000000000000000000..01c42636b87472ebfb13e637f5a3ceb0597b8c99 --- /dev/null +++ b/docs/source/interfaces/HFIR_4Circle_Reduction.rst @@ -0,0 +1,116 @@ +HFIR Single Crystal Reduction Interface +======================================= + +.. contents:: Table of Contents + :local: + +Overview +-------- + +HFIR single crystalreduction interface is a GUI to download, view and reduce data from +HFIR's four-circle single crystal diffractometer in SPICE format. + + +Introduction of Tabs +-------------------- + + 1. **Setup and Data Access**: Configure the instrument name, data server URL and directories. + + - Configure the instrument name; + - Set up and test HB3A data server's URL; + - Configure the directory to save raw data; + - Configure the directory to save working result; + - Download data from server; + + 2. **View Raw Data**: View 2D image of counts on detector of one measurement. + + - Plot the counts of the 256 by 256 2D detector; + + 3. **Calculate UB**: Calculate UB matrix. + + - Find peak in one measurement; + - Option to load Miller index directly from SPICE file; + - Calculate UB matrix; + - Re-index the peaks; + + 4. **Merge Scan**: Merge all the measurements in a scan. + + - Merge all measuring points in a scan to an MDEventWorkspace in HKL-frame or Q-sample-frame; + - Allow various ways to set up UB matrix + + 5. **Refine UB**: Refine UB matrix + + - Disabled becaues it is in development still; + + 6. **Peak Integration**: Integrate peaks + + - Disabled because it is still in development. + +Use Cases +--------- + +Here are some use cases that can be used as examples. + + +Workflow to calculate UB matrix ++++++++++++++++++++++++++++++++ + +Here is a typical use case to calculate UB matrix + + 1. User specifies *Experiment* and pushes button *Set* + + 2. User enters tab *View Raw Data* + + 3. User inputs scan number and list all the measuring points + + 4. User views all the measurements + + 5. User finds out the measurement with the strongest reflection and push button use + + 6. GUI shifts to tab *Calculate UB* automatically + + 7. User pushes button *Find Peak* with checking *Load HKL from file* + + 8. GUI finds the peak center and load HKL + + 9. User pushes button *Add peak* to add the peak to table + + 10. User repeats step 2 to 9 to add other peaks + + 11. User select the peaks that are linearly independent and pushes *Calcualte UB* + + 12. GUI calculates UB matrix and show the result + + 13. User may push *Index peak* to use the calculated UB matrix to index peaks in the table to check UB matrix. + + +Workflow to merge measurements in scan +++++++++++++++++++++++++++++++++++++++ + +Here is a typical use case to merge all the measuring points (Pt.) in a scan. + + 1. User specifies *Experiment* and pushes button *Set* + + 2. User enters tab *Merge Scan* + + 3. User specifies the UB matrix either by *From tab Calculate UB* or by entering the values to text editor + + 4. User pushes button *Set*. + + 5. User specifies the frame in which the merged data will be in. If the target frame is Q-Sample-Sapce, then there is + no need to specify UB matrix; + + 6. User specifies the scan numbers and push button *Add*; + + 7. User specifies the base name for the output MDEventWorkspaces; + + 8. User pushes button *Process*; + + 9. User goes to MantidPlot to view the merged scan by SliceView or Vates. + + + +Limitation +---------- + +- HFIR single crystal reduction GUI supports for instrument HB3A only from release 3.5.0 and nightly. diff --git a/docs/sphinxext/mantiddoc/autodoc.py b/docs/sphinxext/mantiddoc/autodoc.py index 7817b508f97653e2d5eb9815fe7730779ad70056..bd4837657e339d297da7d8e938dd67ef301de427 100644 --- a/docs/sphinxext/mantiddoc/autodoc.py +++ b/docs/sphinxext/mantiddoc/autodoc.py @@ -21,4 +21,4 @@ def skip(app, what, name, obj, skip, options): def setup(app): # Define which methods are skipped when running autodoc # on a member - app.connect("autodoc-skip-member", skip) \ No newline at end of file + app.connect("autodoc-skip-member", skip) diff --git a/docs/sphinxext/mantiddoc/directives/__init__.py b/docs/sphinxext/mantiddoc/directives/__init__.py index aea156091ece2b95afd69e828c186a76bc2469b3..f6e7c496ec600f27ad1f1ae1b1f68f7995899d6d 100644 --- a/docs/sphinxext/mantiddoc/directives/__init__.py +++ b/docs/sphinxext/mantiddoc/directives/__init__.py @@ -7,7 +7,15 @@ 'mantiddoc.directives' to be added to the Sphinx extensions configuration. """ -import algorithm, alias, attributes, categories, diagram, interface, properties, sourcelink, summary +import mantiddoc.directives.algorithm +import mantiddoc.directives.alias +import mantiddoc.directives.attributes +import mantiddoc.directives.categories +import mantiddoc.directives.diagram +import mantiddoc.directives.interface +import mantiddoc.directives.properties +import mantiddoc.directives.sourcelink +import mantiddoc.directives.summary def setup(app): """ diff --git a/docs/sphinxext/mantiddoc/directives/algorithm.py b/docs/sphinxext/mantiddoc/directives/algorithm.py index 92afaa96abf20ab2192d2837ac53b722f614fcc4..9333d680eea9274d2bf3de4d7f6ed1b82a5d56f6 100644 --- a/docs/sphinxext/mantiddoc/directives/algorithm.py +++ b/docs/sphinxext/mantiddoc/directives/algorithm.py @@ -1,7 +1,4 @@ -from base import AlgorithmBaseDirective -from docutils import nodes -from sphinx.locale import _ -from sphinx.util.compat import make_admonition +from mantiddoc.directives.base import AlgorithmBaseDirective import os import re @@ -205,7 +202,7 @@ class AlgorithmDirective(AlgorithmBaseDirective): #------------------------------------------------------------------------------------------------------------ -def html_collect_pages(app): +def html_collect_pages(dummy_app): """ Write out unversioned algorithm pages that redirect to the highest version of the algorithm """ diff --git a/docs/sphinxext/mantiddoc/directives/alias.py b/docs/sphinxext/mantiddoc/directives/alias.py index 14000548f1ad1cd5fa59c4c3bf19537dab22a25c..b567306969544d6f79d66e5272eaef34ffc163b6 100644 --- a/docs/sphinxext/mantiddoc/directives/alias.py +++ b/docs/sphinxext/mantiddoc/directives/alias.py @@ -1,4 +1,4 @@ -from base import AlgorithmBaseDirective +from mantiddoc.directives.base import AlgorithmBaseDirective class AliasDirective(AlgorithmBaseDirective): diff --git a/docs/sphinxext/mantiddoc/directives/attributes.py b/docs/sphinxext/mantiddoc/directives/attributes.py index 2c224b2d79852b628654509419dc9e1e5c48efc3..3f45b202129a686f71c19b224fbe38a4c3a3da49 100644 --- a/docs/sphinxext/mantiddoc/directives/attributes.py +++ b/docs/sphinxext/mantiddoc/directives/attributes.py @@ -1,6 +1,4 @@ -from properties import PropertiesDirective -import string - +from mantiddoc.directives.properties import PropertiesDirective class AttributesDirective(PropertiesDirective): diff --git a/docs/sphinxext/mantiddoc/directives/categories.py b/docs/sphinxext/mantiddoc/directives/categories.py index 178c05b633724ba16044b6ad1e95e7e7edcb5b13..c651f0b4a13b3445e5967eed588a0daaba1e2bae 100644 --- a/docs/sphinxext/mantiddoc/directives/categories.py +++ b/docs/sphinxext/mantiddoc/directives/categories.py @@ -6,7 +6,7 @@ creates "index" pages that lists the contents of each category. The display of each "index" page is controlled by a jinja2 template. """ -from base import AlgorithmBaseDirective, algorithm_name_and_version +from mantiddoc.directives.base import AlgorithmBaseDirective, algorithm_name_and_version from sphinx.util.osutil import relative_uri import os @@ -299,8 +299,6 @@ def create_category_pages(app): Arguments: app: A Sphinx application object """ - import os.path - env = app.builder.env # jinja2 html template template = CATEGORY_PAGE_TEMPLATE diff --git a/docs/sphinxext/mantiddoc/directives/diagram.py b/docs/sphinxext/mantiddoc/directives/diagram.py index e9fd957acb915fbaef50a8af7fbd0dac8d43d6df..863d8256ad46a40680288bd5b884f44ea71d6808 100644 --- a/docs/sphinxext/mantiddoc/directives/diagram.py +++ b/docs/sphinxext/mantiddoc/directives/diagram.py @@ -1,4 +1,4 @@ -from base import BaseDirective +from mantiddoc.directives.base import BaseDirective from sphinx.locale import _ import os, string, subprocess @@ -63,7 +63,7 @@ class DiagramDirective(BaseDirective): dot_executable = os.environ["DOT_EXECUTABLE"] except: self.add_rst(".. figure:: /images/ImageNotFound.png\n\n" + - " graphviz not found - diagram could not be rendered.") + " graphviz not found - diagram could not be rendered.") return [] #Make sure we have an output directory diff --git a/docs/sphinxext/mantiddoc/directives/interface.py b/docs/sphinxext/mantiddoc/directives/interface.py index 531e6297162a747d64b7dea005e2099b69dd85d7..42dbbaef231993cf19b5f83fb1fcad2809f6e6c7 100644 --- a/docs/sphinxext/mantiddoc/directives/interface.py +++ b/docs/sphinxext/mantiddoc/directives/interface.py @@ -1,5 +1,4 @@ -from base import BaseDirective -from sphinx.locale import _ +from mantiddoc.directives.base import BaseDirective import os class InterfaceDirective(BaseDirective): diff --git a/docs/sphinxext/mantiddoc/directives/properties.py b/docs/sphinxext/mantiddoc/directives/properties.py index 3fdf7c0d4837eeb32668294db801a2cb4405c9c4..2e14a854077bea111e82ccfd43608175a5733b77 100644 --- a/docs/sphinxext/mantiddoc/directives/properties.py +++ b/docs/sphinxext/mantiddoc/directives/properties.py @@ -1,7 +1,7 @@ -from base import AlgorithmBaseDirective +#pylint: disable=invalid-name +from mantiddoc.directives.base import AlgorithmBaseDirective import string - class PropertiesDirective(AlgorithmBaseDirective): """ @@ -33,14 +33,14 @@ class PropertiesDirective(AlgorithmBaseDirective): header = ('Name', 'Default', 'Description') for i in xrange(ifunc.numParams()): - properties.append(( - ifunc.parameterName(i), - str(ifunc.getParameterValue(i)), - ifunc.paramDescription(i) - )) + properties.append((ifunc.parameterName(i), + str(ifunc.getParameterValue(i)), + ifunc.paramDescription(i) + )) self.add_rst(self.make_header("Properties (fitting parameters)")) else: # this is an Algorithm - alg = self.create_mantid_algorithm(self.algorithm_name(), self.algorithm_version()) + alg = self.create_mantid_algorithm(self.algorithm_name(), + self.algorithm_version()) alg_properties = alg.getProperties() if len(alg_properties) == 0: return False @@ -100,7 +100,7 @@ class PropertiesDirective(AlgorithmBaseDirective): # Added 10 to the length to ensure if table_content is 0 that # the table is still displayed. col_sizes = [max( (len(row[i] * 10) + 10) for row in table_content) - for i in range(len(header_content))] + for i in range(len(header_content))] # Use the column widths as a means to formatting columns. formatter = ' '.join('{%d:<%d}' % (index,col) for index, col in enumerate(col_sizes)) @@ -138,7 +138,7 @@ class PropertiesDirective(AlgorithmBaseDirective): if (direction_string[prop.direction] == "Output") and \ (not isinstance(prop, IWorkspaceProperty)): default_prop = "" - elif (prop.isValid == ""): + elif prop.isValid == "": default_prop = self._create_property_default_string(prop) else: default_prop = "*Mandatory*" @@ -161,14 +161,14 @@ class PropertiesDirective(AlgorithmBaseDirective): # Convert to int, then float, then any string try: val = int(default) - if (val >= 2147483647): + if val >= 2147483647: defaultstr = "*Optional*" else: defaultstr = str(val) except: try: val = float(default) - if (val >= 1e+307): + if val >= 1e+307: defaultstr = "*Optional*" else: defaultstr = str(val) @@ -214,7 +214,7 @@ class PropertiesDirective(AlgorithmBaseDirective): allowedValueString = str(prop.allowedValues) # 4 allows for [''] - if len(allowedValueString) > 4: + if len(allowedValueString) > 4: ##make sure the last sentence ended with a full stop (or equivalent) if (not desc.rstrip().endswith(".")) \ and (not desc.rstrip().endswith("!")) \ @@ -227,7 +227,7 @@ class PropertiesDirective(AlgorithmBaseDirective): if (not item.startswith(".")) and (not item[-4:].startswith(".")): isFileExts = False break - + prefixString = " Allowed values: " if isFileExts: prefixString = " Allowed extensions: " diff --git a/docs/sphinxext/mantiddoc/directives/sourcelink.py b/docs/sphinxext/mantiddoc/directives/sourcelink.py index 8ff7598f5290b338d98fd45c75198c6f80274f1d..1e436b1f71b441e1c1e965677e7e8391578d7249 100644 --- a/docs/sphinxext/mantiddoc/directives/sourcelink.py +++ b/docs/sphinxext/mantiddoc/directives/sourcelink.py @@ -87,7 +87,7 @@ class SourceLinkDirective(AlgorithmBaseDirective): raise SourceLinkError(error_string) try: - self.output_to_page(file_paths,file_name,sanity_checks); + self.output_to_page(file_paths,file_name,sanity_checks) except SourceLinkError as err: error_string += str(err) + "\n" @@ -112,12 +112,15 @@ class SourceLinkDirective(AlgorithmBaseDirective): suggested_path = "os_agnostic_path_to_file_from_source_root" if len(path_list) > 1: suggested_path = path_list[0].replace(self.source_root, "") - raise SourceLinkError("Found multiple possibilities for " + file_name + "." + extension + "\n" + - "Possible matches" + str(path_list) + "\n" + - "Specify one using the " + extension + " option\n" + - "e.g. \n" + - ".. sourcelink:\n" + - " :" + extension + ": " + suggested_path) + raise SourceLinkError("Found multiple possibilities for " + + file_name + "." + extension + "\n" + + "Possible matches" + str(path_list) + + "\n" + + "Specify one using the " + extension + + " option\n" + + "e.g. \n" + + ".. sourcelink:\n" + + " :" + extension + ": " + suggested_path) return self.file_lookup[file_name][extension] except KeyError: @@ -147,7 +150,7 @@ class SourceLinkDirective(AlgorithmBaseDirective): builddir = os.path.join(builddir, "..", "..") builddir = os.path.abspath(builddir) - for dirName, subdirList, fileList in os.walk(self.source_root): + for dirName, dummy_subdirList, fileList in os.walk(self.source_root): if dirName.startswith(builddir): continue # don't check or add to the cache for fname in fileList: @@ -183,29 +186,31 @@ class SourceLinkDirective(AlgorithmBaseDirective): suggested_path = "os_agnostic_path_to_file_from_Code/Mantid" if len(valid_ext_list) == 0: raise SourceLinkError("No file possibilities for " + file_name + " have been found\n" + - "Please specify a better one using the :filename: opiton or use the " + str(self.file_types.keys()) + " options\n" + - "e.g. \n" + - ".. sourcelink:\n" + - " :" + self.file_types.keys()[0] + ": " + suggested_path + "\n "+ - "or \n" + - ".. sourcelink:\n" + - " :filename: " + file_name) + "Please specify a better one using the :filename: opiton or use the " + + str(self.file_types.keys()) + " options\n" + + "e.g. \n" + + ".. sourcelink:\n" + + " :" + self.file_types.keys()[0] + ": " + suggested_path + "\n "+ + "or \n" + + ".. sourcelink:\n" + + " :filename: " + file_name) #if the have a cpp we should also have a h if ("cpp" in valid_ext_list) or ("h" in valid_ext_list): if ("cpp" not in valid_ext_list) or ("h" not in valid_ext_list): raise SourceLinkError("Only one of .h and .cpp found for " + file_name + "\n" + - "valid files found for " + str(valid_ext_list) + "\n" + - "Please specify the missing one using an " + str(self.file_types.keys()) + " option\n" + - "e.g. \n" + - ".. sourcelink:\n" + - " :" + self.file_types.keys()[0] + ": " + suggested_path) + "valid files found for " + str(valid_ext_list) + "\n" + + "Please specify the missing one using an " + + str(self.file_types.keys()) + " option\n" + + "e.g. \n" + + ".. sourcelink:\n" + + " :" + self.file_types.keys()[0] + ": " + suggested_path) return def output_path_to_page(self, filepath, extension): """ Outputs the source link for a file to the rst page """ - dirName,fName = os.path.split(filepath) + dummy_dirName,fName = os.path.split(filepath) self.add_rst(self.file_types[extension] + ": `" + fName + " <" + self.convert_path_to_github_url(filepath) + ">`_\n\n") return diff --git a/docs/sphinxext/mantiddoc/directives/summary.py b/docs/sphinxext/mantiddoc/directives/summary.py index cb0403e75fe1f092343fbfb26867452cd0b95583..71870dc64b418cfa06419eadf0eccb074e92664e 100644 --- a/docs/sphinxext/mantiddoc/directives/summary.py +++ b/docs/sphinxext/mantiddoc/directives/summary.py @@ -1,4 +1,4 @@ -from base import AlgorithmBaseDirective +from mantiddoc.directives.base import AlgorithmBaseDirective class SummaryDirective(AlgorithmBaseDirective): diff --git a/docs/sphinxext/mantiddoc/doctest.py b/docs/sphinxext/mantiddoc/doctest.py index 3bd4bea3581dcdcfd5a281f716c43a475eca4ae0..d6d176e0159c852380fc41e67e5d3993c89f0b7d 100644 --- a/docs/sphinxext/mantiddoc/doctest.py +++ b/docs/sphinxext/mantiddoc/doctest.py @@ -172,8 +172,10 @@ class TestSuiteReport(object): @property def nfailed(self): def sum_failure(fails, case): - if case.failed: return fails + 1 - else: return fails + if case.failed: + return fails + 1 + else: + return fails return reduce(sum_failure, self.testcases, 0) @property @@ -196,7 +198,7 @@ class TestCaseReport(object): @property def passed(self): - return (self.failure_descr == "") + return self.failure_descr == "" @property def failed(self): @@ -307,7 +309,7 @@ class DocTestOutputParser(object): % text[1]) results = results[2:] # trim off top two lines of header information maintests, cleanup = self.__split_on_cleanup(results) - overall_success = not (maintests[0] == FAILURE_MARKER) + overall_success = not maintests[0] == FAILURE_MARKER if overall_success: testcases = self.__parse_success(fullname, maintests) diff --git a/docs/sphinxext/mantiddoc/tools/screenshot.py b/docs/sphinxext/mantiddoc/tools/screenshot.py index e6e5eea328b0e1d2affaefb49dd89ebcffb17b99..ae3fcc38ef56cdf21781dd35b73886696dd37095 100644 --- a/docs/sphinxext/mantiddoc/tools/screenshot.py +++ b/docs/sphinxext/mantiddoc/tools/screenshot.py @@ -86,14 +86,14 @@ def custominterface_screenshot(name, directory, ext = ".png", widget_name = None dlg = threadsafe_call(iface_mgr.createSubWindow, name, None) if dlg is None: - raise RuntimeError("Interface '%s' could not be created" % name) + raise RuntimeError("Interface '%s' could not be created" % name) if widget_name: - widget = dlg.findChild(QWidget, widget_name) - if widget is None: - raise RuntimeError("Widget '%s' does not exist in interface '%s'" % (widget_name, name)) - picture = Screenshot(widget, name.replace(' ','_') + "_" + widget_name + "_widget" + ext, directory) + widget = dlg.findChild(QWidget, widget_name) + if widget is None: + raise RuntimeError("Widget '%s' does not exist in interface '%s'" % (widget_name, name)) + picture = Screenshot(widget, name.replace(' ','_') + "_" + widget_name + "_widget" + ext, directory) else: - picture = Screenshot(dlg, name.replace(' ','_') + "_interface" + ext, directory) + picture = Screenshot(dlg, name.replace(' ','_') + "_interface" + ext, directory) threadsafe_call(dlg.close) return picture diff --git a/instrument/Bilby_Definition.xml b/instrument/Bilby_Definition.xml index 81029ac258ae427777382b1c5f79f82a6478b94b..baa7b5eabc3295fd9b5a62f63f452d9a2aff8810 100644 --- a/instrument/Bilby_Definition.xml +++ b/instrument/Bilby_Definition.xml @@ -26,7 +26,7 @@ <component name="Source" type="source"> <location x="0.0" y="0.0" /> <parameter name="z"> - <logfile id="L1_chopper_value" eq="1*value"/> + <logfile id="L1_chopper_value" eq="-1*value"/> </parameter> </component> <type name="source" is="Source" /> @@ -503,4 +503,4 @@ </instrument> - \ No newline at end of file + diff --git a/instrument/LET_Definition.xml b/instrument/LET_Definition.xml index a79bb314a74bb19549a4f00e59d65464e242a800..7080cc17821f2160e36408f35283559141c0a7f8 100644 --- a/instrument/LET_Definition.xml +++ b/instrument/LET_Definition.xml @@ -6,7 +6,7 @@ xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 http://schema.mantidproject.org/IDF/1.0/IDFSchema.xsd" name="LET" valid-from ="1900-01-31 23:59:59" valid-to ="2014-02-10 23:59:59" - last-modified="2015-03-09 00:00:00"> + last-modified="2015-03-09 00:00:00"> <defaults> <length unit="meter"/> @@ -672,6 +672,32 @@ <value units="microseconds" val="0"/> </parameter> </component-link> +<!-- Chopper position --> + <component type="chopper-position"> + <location z="-1.5"/> + <!--description is="The component provides sample-choper distance, used + to estimate chopper delay time and Tobyfit resolution calculations."/--> + <parameter name="initial_phase"> + <value val="-0."/> + <description is="The initial rotation phase of the disk used to caluclate the time + for neutrons arriving at the chopper according to the formula time = delay + initial_phase/Speed"/> + </parameter> + <parameter name="ChopperDelayLog" type="string"> + <value val="Chopper5_Disk2_phase"/> + </parameter> + <parameter name="ChopperSpeedLog" type="string"> + <value val="Chopper5_Disk2_speed"/> + </parameter> + <parameter name="FilterBaseLog" type="string"> + <value val="good_uah_log"/> + </parameter> + <!-- if the log above should be used as it is or + one should calculate its derivative --> + <parameter name="filter_with_derivative" type="bool"> + <value val="True"/> + </parameter> + </component> + <type name="chopper-position" is="ChopperPos"></type> <!-- Set the same across the rest of the instrument --> <component-link name = "LET"> diff --git a/instrument/LET_Definition_dr2to12.xml b/instrument/LET_Definition_dr2to12.xml index b3aaebc9f94ba4bf49a735c4af897b356ee0477a..063d32140eec5dc1f503d07252fb7045d2f94b1c 100644 --- a/instrument/LET_Definition_dr2to12.xml +++ b/instrument/LET_Definition_dr2to12.xml @@ -25,6 +25,7 @@ components defined in this file to face a position by default --> <components-are-facing x="0.0" y="0.0" z="0.0" /> </defaults> + <!-- LIST OF PHYSICAL COMPONENTS (which the instrument consists of) --> <!-- detector components --> <properties> @@ -89,6 +90,7 @@ </cylinder> <algebra val="some-shape" /> </type> + <!-- Sample-position types --> <type name="nickel-holder" is="SamplePos"> @@ -666,6 +668,35 @@ <id start="12470001" end="12471024" /> <id start="12480001" end="12481024" /> </idlist> +<!-- Chopper position --> + <component type="chopper-position"> + <location z="-1.5"/> + <!--description is="The component provides sample-choper distance, used + to estimate chopper delay time and Tobyfit resolution calculations."/--> + <parameter name="initial_phase"> + <value val="-0."/> + <description is="The initial rotation phase of the disk used to caluclate the time + for neutrons arriving at the chopper according to the formula time = delay + initial_phase/Speed"/> + </parameter> + <parameter name="ChopperDelayLog" type="string"> + <value val="Chopper5_Disk2_phase"/> + </parameter> + <parameter name="ChopperSpeedLog" type="string"> + <value val="Chopper5_Disk2_speed"/> + </parameter> + <parameter name="FilterBaseLog" type="string"> + <value val="good_uah_log"/> + </parameter> + <!-- if the log above should be used as it is or + one should calculate its derivative --> + <parameter name="filter_with_derivative" type="bool"> + <value val="True"/> + </parameter> + + </component> + <type name="chopper-position" is="ChopperPos"></type> + + <!-- DETECTOR PARAMETERS --> <component-link name="monitors"> <parameter name="DelayTime"> diff --git a/instrument/MAPS_Definition.xml b/instrument/MAPS_Definition.xml index 5945f1ff1bdb314b8188dd48326e052f114087e9..ac7e3e16db7e15e5001ef00ef8a6f2cdbefc77c4 100644 --- a/instrument/MAPS_Definition.xml +++ b/instrument/MAPS_Definition.xml @@ -40,6 +40,36 @@ <location /> </component> <type name="sample-position" is="SamplePos"></type> + +<!-- Chopper position --> + <component type="chopper-position"> + <location z="-1.895"/> + <!--description is="The component provides sample-choper distance, used + to estimate chopper delay time and Tobyfit resolution calculations."/--> + <parameter name="initial_phase"> + <value val="130000."/> + <description is="The initial rotation phase of the disk used to caluclate the time + for neutrons arriving at the chopper according to the formula time = delay + initial_phase/Speed"/> + </parameter> + <parameter name="ChopperDelayLog" type="string"> + <value val="Chopper_delay"/> + </parameter> + <parameter name="ChopperSpeedLog" type="string"> + <value val="Chopper_Speed"/> + </parameter> + <parameter name="FilterBaseLog" type="string"> + <value val="good_uah_log"/> + </parameter> + <!-- if the log above should be used as it is or + one should calculate its derivative --> + <parameter name="filter_with_derivative" type="bool"> + <value val="True"/> + </parameter> + + </component> + <type name="chopper-position" is="ChopperPos"></type> + + <component type="monitors" idlist="monitors"> diff --git a/instrument/MARI_Definition.xml b/instrument/MARI_Definition.xml index 41a9900ffe0290b5c789aa22b3bd8cc6bd0e2d95..5ef895cb7b30160d062f8001a44364d251267eb1 100644 --- a/instrument/MARI_Definition.xml +++ b/instrument/MARI_Definition.xml @@ -42,6 +42,38 @@ <!-- CHOPPERS --> + <!-- Chopper position --> + <component type="chopper-position"> + <location z="-1.689"/> + <!--description is="The component provides sample-choper distance, used + to estimate chopper delay time and Tobyfit resolution calculations."/ --> + <!-- if chopper "a": t_offset = -3281.8/SPEED + 16.2; + if chopper "g": t_offset = -2822.5/SPEED + 9.7 + if chopper "s": t_offset = -3326.8/SPEED + 7.7 + --> + <parameter name="initial_phase"> + <value val="-3000."/> + <description is="The initial rotation phase of the disk used to caluclate the time + for neutrons arriving at the chopper according to the formula time = delay + initial_phase/Speed"/> + </parameter> + <parameter name="ChopperDelayLog" type="string"> + <value val="fermi_delay"/> + </parameter> + <parameter name="ChopperSpeedLog" type="string"> + <value val="fermi_speed"/> + </parameter> + <parameter name="FilterBaseLog" type="string"> + <value val="good_uah_log"/> + </parameter> + <!-- if the log above should be used as it is or + one should calculate its derivative --> + <parameter name="filter_with_derivative" type="bool"> + <value val="True"/> + </parameter> + + </component> + <type name="chopper-position" is="ChopperPos"></type> + <component type="fermi-chopper"> <location y="-0.1" z="-1.689" /> @@ -50,9 +82,11 @@ </parameter> <parameter name="Delay (us)"> <logfile id="fermi_delay" extract-single-value-as="last_value" /> - <description is="Delay is the time chopper waits for...? (test description)"/> + <description is="Delay is the time between the moment when beam hits moderator and the moment, + when neutron passes through chopper for the first time."/> </parameter> - </component> + + </component> <type name="fermi-chopper" is="chopper"> <cylinder id="body"> <centre-of-bottom-base x="0.0" y="0.0" z="0.0" /> diff --git a/instrument/MERLIN_Definition_after2013_4.xml b/instrument/MERLIN_Definition_after2013_4.xml index fd69107e5c7fdd2600996cd426f5dfb5fb84af57..4bb893e054a38bf4804f602fffac62d6dc918b69 100644 --- a/instrument/MERLIN_Definition_after2013_4.xml +++ b/instrument/MERLIN_Definition_after2013_4.xml @@ -62,8 +62,31 @@ <!-- Chopper position --> <component type="chopper-position"> <location z="-1.8"/> + <!--description is="The component provides sample-choper distance, used + to estimate chopper delay time and Tobyfit resolution calculations."/--> + <parameter name="initial_phase"> + <value val="-490000."/> + <description is="The initial rotation phase of the disk used to caluclate the time + for neutrons arriving at the chopper according to the formula time = delay + initial_phase/Speed"/> + </parameter> + <parameter name="ChopperDelayLog" type="string"> + <value val="Chopper_delay"/> + </parameter> + <parameter name="ChopperSpeedLog" type="string"> + <value val="Chopper_Speed"/> + </parameter> + <parameter name="FilterBaseLog" type="string"> + <value val="good_uah_log"/> + </parameter> + <!-- if the log above should be used as it is or + one should calculate its derivative --> + <parameter name="filter_with_derivative" type="bool"> + <value val="True"/> + </parameter> + </component> - <type name="chopper-position" is="ChopperPos"></type> + <type name="chopper-position" is="ChopperPos"></type> + <!-- DETECTORS --> diff --git a/instrument/Schema/IDF/1.0/IDFSchema.xsd b/instrument/Schema/IDF/1.0/IDFSchema.xsd index 4b2ea38bf59fbf02f4d836c6ae2b28c8e0c6e0f5..d2a3c79d955145c7a7aeef77f51e1ef3634fff75 100644 --- a/instrument/Schema/IDF/1.0/IDFSchema.xsd +++ b/instrument/Schema/IDF/1.0/IDFSchema.xsd @@ -289,9 +289,11 @@ <xs:simpleContent> <xs:extension base="xs:string"> <xs:anyAttribute/> + </xs:extension> </xs:simpleContent> </xs:complexType> + </xs:element> <xs:element name="properties"> <xs:complexType> diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index 7c00c508283118881ab92f0d7c8e6b079bc1f0f3..7cd45300f74869139a60cf613343c6613fe322d6 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -6,6 +6,7 @@ add_subdirectory(Interface/ui) add_subdirectory(lib1to2/gui) add_subdirectory(PyChop) add_subdirectory(TofConverter) +add_subdirectory(HFIR_4Circle_Reduction) # Chain all required interface custom targets into CompilePyUI add_custom_target(CompilePyUI DEPENDS @@ -15,6 +16,7 @@ add_custom_target(CompilePyUI DEPENDS CompileUITofConverter CompileUIUI CompileUILib1To2 + CompileUIHFIR_4Circle_Reduction ) set ( TEST_PY_FILES diff --git a/scripts/HFIR_4Circle_Reduction.py b/scripts/HFIR_4Circle_Reduction.py new file mode 100644 index 0000000000000000000000000000000000000000..89742c6bfa9f75bb50d994cf3148f7d9e1c84476 --- /dev/null +++ b/scripts/HFIR_4Circle_Reduction.py @@ -0,0 +1,17 @@ +#pylint: disable=invalid-name +from HFIR_4Circle_Reduction import reduce4circleGUI +from PyQt4 import QtGui +import sys + +def qapp(): + if QtGui.QApplication.instance(): + _app = QtGui.QApplication.instance() + else: + _app = QtGui.QApplication(sys.argv) + return _app + +app = qapp() + +reducer = reduce4circleGUI.MainWindow() #the main ui class in this file is called MainWindow +reducer.show() +app.exec_() diff --git a/scripts/HFIR_4Circle_Reduction/CMakeLists.txt b/scripts/HFIR_4Circle_Reduction/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..67fe46df205d951ff83380c933f71c88d5325604 --- /dev/null +++ b/scripts/HFIR_4Circle_Reduction/CMakeLists.txt @@ -0,0 +1,8 @@ +include(UiToPy) + +# List of UIs to Auto convert +set( UI_FILES + MainWindow.ui +) + +UiToPy( UI_FILES CompileUIHFIR_4Circle_Reduction) diff --git a/scripts/HFIR_4Circle_Reduction/MainWindow.ui b/scripts/HFIR_4Circle_Reduction/MainWindow.ui new file mode 100644 index 0000000000000000000000000000000000000000..4f7fa462e7008c7cf9e167e822ad5b0b47996aca --- /dev/null +++ b/scripts/HFIR_4Circle_Reduction/MainWindow.ui @@ -0,0 +1,2312 @@ +<?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>1292</width> + <height>783</height> + </rect> + </property> + <property name="windowTitle"> + <string>4-Circle Reduction</string> + </property> + <widget class="QWidget" name="centralwidget"> + <layout class="QHBoxLayout" name="horizontalLayout_11"> + <item> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_General"> + <item> + <widget class="QLabel" name="label_exp"> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>Experiment</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="lineEdit_exp"> + <property name="minimumSize"> + <size> + <width>40</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>60</width> + <height>16777215</height> + </size> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton_setExp"> + <property name="text"> + <string>Set</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_11"> + <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="QLabel" name="label_15"> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>Unit Cell</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_16"> + <property name="text"> + <string>a</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="lineEdit_a"> + <property name="maximumSize"> + <size> + <width>120</width> + <height>16777215</height> + </size> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_23"> + <property name="text"> + <string>b</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="lineEdit_b"> + <property name="maximumSize"> + <size> + <width>120</width> + <height>16777215</height> + </size> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_24"> + <property name="text"> + <string>c</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="lineEdit_c"> + <property name="maximumSize"> + <size> + <width>120</width> + <height>16777215</height> + </size> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_25"> + <property name="text"> + <string>alpha</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="lineEdit_alpha"> + <property name="maximumSize"> + <size> + <width>120</width> + <height>16777215</height> + </size> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_26"> + <property name="text"> + <string>beta</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="lineEdit_beta"> + <property name="maximumSize"> + <size> + <width>120</width> + <height>16777215</height> + </size> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_27"> + <property name="text"> + <string>gamma</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="lineEdit_gamma"> + <property name="maximumSize"> + <size> + <width>120</width> + <height>16777215</height> + </size> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_Tab"> + <item> + <widget class="QTabWidget" name="tabWidget"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="currentIndex"> + <number>0</number> + </property> + <widget class="QWidget" name="tab"> + <attribute name="title"> + <string>Setup && Data Access</string> + </attribute> + <layout class="QGridLayout" name="gridLayout_5"> + <item row="1" column="0"> + <widget class="QTextEdit" name="textEdit"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="html"> + <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">1. Configure the data reduction</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-style:italic;">(a) Do not modify ServerURL unless necessary;</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-style:italic;">(b) Click 'Apply' to check internet connection and directories;</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-style:italic;">(c) If 'Time out' is popped out, try to click 'Apply' again. Server may not be able to respond promptly.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt; font-style:italic;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">2. Start to reduce data</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-style:italic;">(a) Set</span><span style=" font-size:10pt;"> Experiment</span></p></body></html></string> + </property> + </widget> + </item> + <item row="6" column="0"> + <spacer name="verticalSpacer_2"> + <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="0" column="0"> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Configuration</string> + </property> + <layout class="QGridLayout" name="gridLayout_11"> + <item row="1" column="2"> + <widget class="QPushButton" name="pushButton_testURLs"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>200</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Test</string> + </property> + </widget> + </item> + <item row="2" column="2"> + <widget class="QPushButton" name="pushButton_browseLocalDataDir"> + <property name="text"> + <string>Browse</string> + </property> + </widget> + </item> + <item row="2" column="3"> + <spacer name="horizontalSpacer"> + <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 row="2" column="1"> + <widget class="QLineEdit" name="lineEdit_localSpiceDir"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string><html><head/><body><p>Directory for local data storage</p></body></html></string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label_instrument"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Instrument</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_dir"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>80</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string><html><head/><body><p>Directory for local data storage</p></body></html></string> + </property> + <property name="text"> + <string>Data Directory</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="comboBox_instrument"> + <item> + <property name="text"> + <string>HB3A</string> + </property> + </item> + </widget> + </item> + <item row="0" column="2"> + <widget class="QPushButton" name="pushButton_useDefaultDir"> + <property name="font"> + <font> + <pointsize>10</pointsize> + </font> + </property> + <property name="toolTip"> + <string><html><head/><body><p>Use default set up</p><p><br/></p></body></html></string> + </property> + <property name="text"> + <string>Load Default</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLineEdit" name="lineEdit_workDir"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string><html><head/><body><p>Directory to save outcome of the data reduction</p></body></html></string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="lineEdit_url"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_url"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>80</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string><html><head/><body><p>URL of the http server to download HB3A data</p></body></html></string> + </property> + <property name="text"> + <string>Server URL</string> + </property> + </widget> + </item> + <item row="3" column="2"> + <widget class="QPushButton" name="pushButton_browseWorkDir"> + <property name="text"> + <string>Browse</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_2"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>140</width> + <height>1</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>140</width> + <height>16777215</height> + </size> + </property> + <property name="toolTip"> + <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> + </property> + </widget> + </item> + <item row="4" column="2"> + <widget class="QPushButton" name="pushButton_applySetup"> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>Apply</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="4" column="0"> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Data Download</string> + </property> + <layout class="QGridLayout" name="gridLayout_12"> + <item row="0" column="2"> + <widget class="QPushButton" name="pushButton_browseLocalCache"> + <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="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Browse</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <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>80</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Scans List</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QComboBox" name="comboBox_mode"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string><html><head/><body><p>Mode &quot;download&quot;: download data to local disk;</p><p>Mode &quot;http server only&quot;: download data to cache, process and delete cached data upon returning</p></body></html></string> + </property> + <item> + <property name="text"> + <string>Download Complete Experiment</string> + </property> + </item> + <item> + <property name="text"> + <string>Download Selected Scans</string> + </property> + </item> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="lineEdit_localSrcDir"> + <property name="toolTip"> + <string><html><head/><body><p>Cache on local disk. The dowloaded data will be saved to here. </p></body></html></string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_datamode"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>80</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Download Mode</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label_4"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>140</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>140</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Destination</string> + </property> + </widget> + </item> + <item row="0" column="6"> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Minimum</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="2"> + <widget class="QPushButton" name="pushButton_downloadExpData"> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="toolTip"> + <string><html><head/><body><p><span style=" font-weight:400;">Download scans specified by 'Scans List'; </span></p><p><span style=" font-weight:400;">If 'Scans List' is empty, then the complete experiment data will be downloaded</span></p></body></html></string> + </property> + <property name="text"> + <string>Download</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLineEdit" name="lineEdit_downloadScans"/> + </item> + <item row="2" column="2"> + <widget class="QPushButton" name="pushButton_ListScans"> + <property name="text"> + <string>List Scans</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="3" column="0"> + <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> + </layout> + </widget> + <widget class="QWidget" name="tab_4"> + <attribute name="title"> + <string>View Raw Data</string> + </attribute> + <layout class="QGridLayout" name="gridLayout_9"> + <item row="0" column="0"> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="3"> + <layout class="QVBoxLayout" name="verticalLayout_5"> + <item> + <layout class="QGridLayout" name="gridLayout"/> + </item> + <item> + <widget class="QGroupBox" name="groupBox_3"> + <property name="title"> + <string>Scan</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLineEdit" name="lineEdit_run"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>10</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>10000</width> + <height>16777215</height> + </size> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton_setScanInfo"> + <property name="text"> + <string>Set</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton_showPtList"> + <property name="text"> + <string>List Pt.</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_4"> + <property name="title"> + <string> Pt</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QLineEdit" name="lineEdit_rawDataPtNo"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>60</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>1000</width> + <height>16777215</height> + </size> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton_plotRawPt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>80</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Plot</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton_usePt4UB"> + <property name="toolTip"> + <string><html><head/><body><p>Use this peak to calcualate UB matrix</p></body></html></string> + </property> + <property name="text"> + <string>Use</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_5"> + <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="QHBoxLayout" name="horizontalLayout_8"> + <item> + <widget class="QPushButton" name="pushButton_prevPtNumber"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>30</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>40</width> + <height>16777215</height> + </size> + </property> + <property name="toolTip"> + <string><html><head/><body><p>Previous Pt. No</p></body></html></string> + </property> + <property name="text"> + <string><---|</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_7"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Preferred</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="pushButton_nextPtNumber"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>30</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>40</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>|--></string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer_6"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="0" column="0"> + <widget class="MplGraphicsView" name="graphicsView"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab_2"> + <attribute name="title"> + <string>Calculate UB</string> + </attribute> + <layout class="QGridLayout" name="gridLayout_6"> + <item row="0" column="0"> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="QGroupBox" name="groupBox_7"> + <property name="title"> + <string>Add Peak</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <widget class="QLabel" name="label_scanNo"> + <property name="text"> + <string>Scan Number</string> + </property> + </widget> + </item> + <item row="0" column="8"> + <widget class="QLineEdit" name="lineEdit_H"> + <property name="maximumSize"> + <size> + <width>60</width> + <height>40</height> + </size> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QLabel" name="label_PtNo"> + <property name="text"> + <string>Pt Number</string> + </property> + </widget> + </item> + <item row="3" column="12"> + <widget class="QLineEdit" name="lineEdit_sampleQy"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="maximumSize"> + <size> + <width>120</width> + <height>16777215</height> + </size> + </property> + </widget> + </item> + <item row="0" column="11"> + <widget class="QLabel" name="label_11"> + <property name="text"> + <string>K</string> + </property> + </widget> + </item> + <item row="0" column="13"> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string>L</string> + </property> + </widget> + </item> + <item row="3" column="8"> + <widget class="QLineEdit" name="lineEdit_sampleQx"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="maximumSize"> + <size> + <width>120</width> + <height>16777215</height> + </size> + </property> + </widget> + </item> + <item row="3" column="6"> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string> Q-Sample </string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QLineEdit" name="lineEdit_ptNumber"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>60</width> + <height>16777215</height> + </size> + </property> + </widget> + </item> + <item row="3" column="11"> + <widget class="QLabel" name="label_9"> + <property name="text"> + <string>Y</string> + </property> + </widget> + </item> + <item row="3" column="14"> + <widget class="QLineEdit" name="lineEdit_sampleQz"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="maximumSize"> + <size> + <width>120</width> + <height>16777215</height> + </size> + </property> + </widget> + </item> + <item row="3" column="7"> + <widget class="QLabel" name="label_8"> + <property name="text"> + <string>X</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="lineEdit_scanNumber"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>60</width> + <height>16777215</height> + </size> + </property> + </widget> + </item> + <item row="0" column="12"> + <widget class="QLineEdit" name="lineEdit_K"> + <property name="maximumSize"> + <size> + <width>60</width> + <height>16777215</height> + </size> + </property> + </widget> + </item> + <item row="0" column="14"> + <widget class="QLineEdit" name="lineEdit_L"> + <property name="maximumSize"> + <size> + <width>60</width> + <height>16777215</height> + </size> + </property> + </widget> + </item> + <item row="0" column="7"> + <widget class="QLabel" name="label_12"> + <property name="text"> + <string>H</string> + </property> + </widget> + </item> + <item row="3" column="13"> + <widget class="QLabel" name="label_10"> + <property name="text"> + <string>Z</string> + </property> + </widget> + </item> + <item row="0" column="5"> + <spacer name="horizontalSpacer_4"> + <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 row="0" column="6"> + <widget class="QLabel" name="label_31"> + <property name="text"> + <string>Miller Index</string> + </property> + </widget> + </item> + <item row="0" column="4"> + <widget class="QPushButton" name="pushButton_findPeak"> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>Find Peak</string> + </property> + </widget> + </item> + <item row="3" column="4"> + <widget class="QCheckBox" name="checkBox_loadHKLfromFile"> + <property name="font"> + <font> + <pointsize>9</pointsize> + </font> + </property> + <property name="text"> + <string>Load HKL from file</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_7"> + <item> + <widget class="UBMatrixPeakTable" name="tableWidget_peaksCalUB"/> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_8"> + <item> + <widget class="QPushButton" name="pushButton_addPeakToCalUB"> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>Add Peak</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox_roundHKLInt"> + <property name="font"> + <font> + <pointsize>9</pointsize> + </font> + </property> + <property name="text"> + <string>RoundHKL to int</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_11"> + <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_deleteUBPeak"> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>200</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Delete</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton_clearUBPeakTable"> + <property name="text"> + <string>Clear</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_7"> + <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> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_13"> + <item> + <widget class="QLabel" name="label_32"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + <pointsize>14</pointsize> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>UB Matrix</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_6"> + <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="UBMatrixTable" name="tableWidget_ubMatrix"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>360</width> + <height>0</height> + </size> + </property> + <row> + <property name="text"> + <string/> + </property> + </row> + <row> + <property name="text"> + <string/> + </property> + </row> + <row> + <property name="text"> + <string/> + </property> + </row> + <column> + <property name="text"> + <string/> + </property> + </column> + <column> + <property name="text"> + <string/> + </property> + </column> + <column> + <property name="text"> + <string/> + </property> + </column> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_5"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_12"> + <item> + <widget class="QPushButton" name="pushButton_calUB"> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Calculate UB</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_8"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Ignored</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="pushButton_acceptUB"> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Accept</string> + </property> + </widget> + </item> + <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> + </layout> + </item> + <item> + <spacer name="horizontalSpacer_8"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Ignored</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_9"> + <item> + <widget class="QPushButton" name="pushButton_indexUBPeaks"> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Index Peak</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_12"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Ignored</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="pushButton_resetPeakHKLs"> + <property name="text"> + <string>Reset HKL</string> + </property> + </widget> + </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> + </layout> + </item> + </layout> + </item> + </layout> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab_advsetup"> + <attribute name="title"> + <string>Merge Scan</string> + </attribute> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QGroupBox" name="groupBox_5"> + <property name="title"> + <string>UB Matrix</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_13"> + <item> + <widget class="UBMatrixTable" name="tableWidget_ubSiceView"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>150</height> + </size> + </property> + <row> + <property name="text"> + <string/> + </property> + </row> + <row> + <property name="text"> + <string/> + </property> + </row> + <row> + <property name="text"> + <string/> + </property> + </row> + <column> + <property name="text"> + <string/> + </property> + </column> + <column> + <property name="text"> + <string/> + </property> + </column> + <column> + <property name="text"> + <string/> + </property> + </column> + <item row="0" column="0"> + <property name="text"> + <string>1</string> + </property> + </item> + <item row="1" column="1"> + <property name="text"> + <string>1</string> + </property> + </item> + <item row="2" column="2"> + <property name="text"> + <string>1</string> + </property> + </item> + </widget> + </item> + <item> + <spacer name="verticalSpacer_13"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Ignored</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QGridLayout" name="gridLayout_4"> + <item row="0" column="2"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>From tab 'Caclulate UB'</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QRadioButton" name="radioButton_ubFromTab1"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="0" column="1"> + <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> + <item row="2" column="0"> + <widget class="QRadioButton" name="radioButton_ubFromTab3"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="2" column="2"> + <widget class="QLabel" name="label_28"> + <property name="text"> + <string>From tab 'Refine UB'</string> + </property> + </widget> + </item> + <item row="3" column="2"> + <widget class="QPlainTextEdit" name="plainTextEdit_ubInput"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item row="3" column="0"> + <layout class="QVBoxLayout" name="verticalLayout_15"> + <item> + <widget class="QRadioButton" name="radioButton_ubFromList"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_15"> + <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> + <item> + <spacer name="verticalSpacer_14"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Ignored</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="pushButton_setUBSliceView"> + <property name="text"> + <string>Set</string> + </property> + </widget> + </item> + <item> + <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> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_6"> + <property name="title"> + <string>Process Data</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_14"> + <item> + <layout class="QGridLayout" name="gridLayout_10"> + <item row="1" column="0"> + <widget class="QLabel" name="label_29"> + <property name="toolTip"> + <string><html><head/><body><p>For MDEventsWorkspace with merged runs</p><p><br/></p><p>For example:</p></body></html></string> + </property> + <property name="text"> + <string>Base Workspace Name</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label_30"> + <property name="text"> + <string>Scans List</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="lineEdit_listScansSliceView"/> + </item> + <item row="0" column="2"> + <widget class="QPushButton" name="pushButton_addScanSliceView"> + <property name="text"> + <string>Add</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLineEdit" name="lineEdit_baseMergeMDName"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="comboBox_mergeScanFrame"> + <property name="minimumSize"> + <size> + <width>140</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string><html><head/><body><p>Type of frame that the final merged scan will be in.</p></body></html></string> + </property> + <item> + <property name="text"> + <string>HKL-Space</string> + </property> + </item> + <item> + <property name="text"> + <string>Q-Sample-Space</string> + </property> + </item> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_10"> + <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 row="1" column="2"> + <widget class="QPushButton" name="pushButton_process4SliceView"> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>Process</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="ProcessTableWidget" name="tableWidget_sliceViewProgress"> + <property name="toolTip"> + <string><html><head/><body><p>? columns: </p><p><br/></p><p>1. Scan number</p><p>2. Number of Pts.</p><p>3. Status: </p><p>(a) done</p><p>(b) error with error message</p><p>(c) on-going</p><p>(d) empty as not yet</p></body></html></string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab_3"> + <attribute name="title"> + <string>Refine UB</string> + </attribute> + <layout class="QGridLayout" name="gridLayout_8"> + <item row="0" column="0"> + <layout class="QVBoxLayout" name="verticalLayout_6"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_14"> + <item> + <widget class="QLabel" name="label_14"> + <property name="text"> + <string>Scan</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="lineEdit_scanRefineUB"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_13"> + <property name="text"> + <string>Pt.</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="lineEdit_ptRefineUB"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton_addToRefine"> + <property name="toolTip"> + <string><html><head/><body><p>Add a data point or data points (defined by scan number and pt number) to the list to refine UB matrix; </p><p><br/></p><p>Scan number can be a list of integers;</p><p><br/></p><p>Pt number can be empty such that all Pt. of that scan will be searched for peak and then used to refine UB matrix</p></body></html></string> + </property> + <property name="text"> + <string>Add</string> + </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> + <item> + <widget class="QPushButton" name="pushButton_addAllRefineUB"> + <property name="text"> + <string>Add All</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_15"> + <item> + <widget class="UBMatrixTable" name="tableWidget_refinedUB"> + <row> + <property name="text"> + <string/> + </property> + </row> + <row> + <property name="text"> + <string/> + </property> + </row> + <row> + <property name="text"> + <string/> + </property> + </row> + <column> + <property name="text"> + <string/> + </property> + </column> + <column> + <property name="text"> + <string/> + </property> + </column> + <column> + <property name="text"> + <string/> + </property> + </column> + </widget> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_7"/> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_10"> + <item> + <widget class="QPushButton" name="pushButton_acceptRefinedUB"> + <property name="text"> + <string>Accept</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton_resetRefinedUB"> + <property name="text"> + <string>Reset</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + <item> + <layout class="QGridLayout" name="gridLayout_7"> + <item row="0" column="0"> + <widget class="QLabel" name="label_17"> + <property name="text"> + <string>a</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QLabel" name="label_19"> + <property name="text"> + <string>c</string> + </property> + </widget> + </item> + <item row="0" column="4"> + <widget class="QLabel" name="label_21"> + <property name="text"> + <string>beta</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="label_18"> + <property name="text"> + <string>b</string> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QLabel" name="label_20"> + <property name="text"> + <string>alpha</string> + </property> + </widget> + </item> + <item row="0" column="5"> + <widget class="QLabel" name="label_22"> + <property name="text"> + <string>gamma</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="lineEdit_bUnitCell"/> + </item> + <item row="1" column="2"> + <widget class="QLineEdit" name="lineEdit_cUnitCell"/> + </item> + <item row="1" column="3"> + <widget class="QLineEdit" name="lineEdit_alphaUnitCell"/> + </item> + <item row="2" column="1"> + <widget class="QLineEdit" name="lineEdit_bError"/> + </item> + <item row="1" column="4"> + <widget class="QLineEdit" name="lineEdit_betaUnitCell"/> + </item> + <item row="1" column="0"> + <widget class="QLineEdit" name="lineEdit_aUnitCell"/> + </item> + <item row="2" column="2"> + <widget class="QLineEdit" name="lineEdit_cError"/> + </item> + <item row="2" column="0"> + <widget class="QLineEdit" name="lineEdit_aError"/> + </item> + <item row="2" column="3"> + <widget class="QLineEdit" name="lineEdit_alphaError"/> + </item> + <item row="2" column="4"> + <widget class="QLineEdit" name="lineEdit_betaError"/> + </item> + <item row="1" column="5"> + <widget class="QLineEdit" name="lineEdit_gammaUnitCell"/> + </item> + <item row="2" column="5"> + <widget class="QLineEdit" name="lineEdit_gammaError"/> + </item> + </layout> + </item> + </layout> + </item> + <item row="1" column="0"> + <spacer name="verticalSpacer_3"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab_indexPeak"> + <attribute name="title"> + <string>Peak Integration</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_11"> + <item> + <layout class="QGridLayout" name="gridLayout_13"> + <item row="1" column="6"> + <widget class="QCheckBox" name="checkBox_adaptQBkgd"> + <property name="text"> + <string>Adaptive Q Background</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="lineEdit_scanIntegratePeak"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QCheckBox" name="checkBox_cylinder"> + <property name="text"> + <string>Cylinder</string> + </property> + </widget> + </item> + <item row="1" column="3"> + <widget class="QLineEdit" name="lineEdit_bkgdInnerR"/> + </item> + <item row="1" column="5"> + <widget class="QLineEdit" name="lineEdit_bkgdOuterR"/> + </item> + <item row="2" column="4"> + <widget class="QLabel" name="label_36"> + <property name="text"> + <string>Percent Background</string> + </property> + </widget> + </item> + <item row="1" column="7"> + <widget class="QCheckBox" name="checkBox_integrateOnEdge"> + <property name="text"> + <string>Integrate on Edge</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>Scan Number</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_34"> + <property name="text"> + <string>Peak Radius</string> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QLineEdit" name="lineEdit_ptNumListIntPeak"/> + </item> + <item row="2" column="7"> + <widget class="QComboBox" name="comboBox_cylinderIntOption"/> + </item> + <item row="0" column="7"> + <widget class="QPushButton" name="pushButton_integratePeak"> + <property name="text"> + <string>Integrate Peaks</string> + </property> + </widget> + </item> + <item row="2" column="5"> + <widget class="QLineEdit" name="lineEdit_cylinderBkgdPercent"/> + </item> + <item row="1" column="4"> + <widget class="QLabel" name="label_35"> + <property name="text"> + <string>Background Outer Radius</string> + </property> + </widget> + </item> + <item row="0" column="5"> + <widget class="QComboBox" name="comboBox_3"> + <property name="toolTip"> + <string><html><head/><body><p>Choose the name of the tab, in which the UB matrix is used to convert signals to HKL frame.</p></body></html></string> + </property> + <item> + <property name="text"> + <string>Calculate UB</string> + </property> + </item> + <item> + <property name="text"> + <string>Merge Scan</string> + </property> + </item> + <item> + <property name="text"> + <string>Refine UB</string> + </property> + </item> + </widget> + </item> + <item row="2" column="6"> + <widget class="QComboBox" name="comboBox_cylinderProfile"> + <item> + <property name="text"> + <string>Gaussian</string> + </property> + </item> + </widget> + </item> + <item row="2" column="2"> + <widget class="QLabel" name="label_39"> + <property name="text"> + <string>Cylinder Length</string> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QLabel" name="label_37"> + <property name="text"> + <string>Background Inner Radius</string> + </property> + </widget> + </item> + <item row="2" column="3"> + <widget class="QLineEdit" name="lineEdit_cylinderLength"/> + </item> + <item row="0" column="2"> + <widget class="QLabel" name="label_33"> + <property name="text"> + <string>Pt Numbers</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="lineEdit_peakRadius"/> + </item> + </layout> + </item> + <item> + <widget class="IntegratePeaksTableWidget" name="tableWidget_peakIndex"/> + </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>1292</width> + <height>25</height> + </rect> + </property> + <widget class="QMenu" name="menuFile"> + <property name="title"> + <string>File</string> + </property> + <addaction name="separator"/> + <addaction name="actionExit"/> + <addaction name="separator"/> + </widget> + <widget class="QMenu" name="menuTools"> + <property name="title"> + <string>Tools</string> + </property> + <addaction name="actionSave_Session"/> + <addaction name="actionLoad_Session"/> + <addaction name="separator"/> + </widget> + <addaction name="menuFile"/> + <addaction name="menuTools"/> + </widget> + <widget class="QStatusBar" name="statusbar"/> + <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> + <property name="shortcut"> + <string>Ctrl+O</string> + </property> + </action> + <action name="actionSave"> + <property name="text"> + <string>Save</string> + </property> + </action> + <action name="actionLog"> + <property name="text"> + <string>Log</string> + </property> + <property name="shortcut"> + <string>Ctrl+L</string> + </property> + </action> + <action name="actionSave_Session"> + <property name="text"> + <string>Save Session</string> + </property> + <property name="shortcut"> + <string>Ctrl+Shift+S</string> + </property> + </action> + <action name="actionExit"> + <property name="text"> + <string>Exit</string> + </property> + <property name="shortcut"> + <string>Ctrl+Q</string> + </property> + </action> + <action name="actionLoad_Session"> + <property name="text"> + <string>Load Session</string> + </property> + <property name="shortcut"> + <string>Ctrl+Shift+L</string> + </property> + </action> + </widget> + <customwidgets> + <customwidget> + <class>MplGraphicsView</class> + <extends>QGraphicsView</extends> + <header>mplgraphicsview.h</header> + </customwidget> + <customwidget> + <class>UBMatrixPeakTable</class> + <extends>QTableWidget</extends> + <header>hfctables.h</header> + </customwidget> + <customwidget> + <class>UBMatrixTable</class> + <extends>QTableWidget</extends> + <header>hfctables.h</header> + </customwidget> + <customwidget> + <class>ProcessTableWidget</class> + <extends>QTableWidget</extends> + <header>hfctables.h</header> + </customwidget> + <customwidget> + <class>IntegratePeaksTableWidget</class> + <extends>QTableWidget</extends> + <header>hfctables.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/scripts/HFIR_4Circle_Reduction/NTableWidget.py b/scripts/HFIR_4Circle_Reduction/NTableWidget.py new file mode 100644 index 0000000000000000000000000000000000000000..198725f41ef1492b822dfddb572ecb7c75b0a3aa --- /dev/null +++ b/scripts/HFIR_4Circle_Reduction/NTableWidget.py @@ -0,0 +1,268 @@ +#pylint: disable=C0103,R0904 +# N(DAV)TableWidget +# + +from PyQt4 import QtGui, QtCore + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + _fromUtf8 = lambda s: s + + +class NTableWidget(QtGui.QTableWidget): + """ + NdavTableWidget inherits from QTableWidget by extending the features + for easy application. + """ + def __init__(self, parent): + """ + + :param parent: + :return: + """ + QtGui.QTableWidget.__init__(self, parent) + + self._myParent = parent + + self._myHeaderList = None + self._myColumnTypeList = None + + return + + def append_row(self, row_value_list, type_list=None): + """ + + :param row_value_list: + :return: + """ + # Check input + assert isinstance(row_value_list, list) + if type_list is not None: + assert isinstance(type_list, list) + assert len(row_value_list) == len(type_list) + else: + type_list = self._myColumnTypeList + if len(row_value_list) != self.columnCount(): + ret_msg = 'Input number of values (%d) is different from ' \ + 'column number (%d).' % (len(row_value_list), self.columnCount()) + return False, ret_msg + else: + ret_msg = '' + + # Insert new row + row_number = self.rowCount() + self.insertRow(row_number) + + # Set values + for i_col in xrange(min(len(row_value_list), self.columnCount())): + item = QtGui.QTableWidgetItem() + item.setText(_fromUtf8(str(row_value_list[i_col]))) + item.setFlags(item.flags() & ~QtCore.Qt.ItemIsEditable) + if type_list[i_col] == 'checkbox': + self.set_check_box(row_number, i_col, False) + else: + self.setItem(row_number, i_col, item) + # END-FOR(i_col) + + return True, ret_msg + + def delete_rows(self, row_number_list): + """ Delete rows + :param row_number_list: + :return: + """ + # Check and re-order row numbers + assert isinstance(row_number_list, list) + row_number_list.sort(reverse=True) + + for row_number in row_number_list: + self.removeRow(row_number) + + return + + def get_selected_rows(self): + """ + + :return: list of row numbers that are selected + """ + rows_list = list() + index_status = self._myColumnTypeList.index('checkbox') + for i_row in xrange(self.rowCount()): + is_checked = self.get_row_value(i_row)[index_status] + if is_checked: + rows_list.append(i_row) + + return rows_list + + def get_cell_value(self, row_index, col_index): + """ + + :param row_index: + :param col_index: + :return: + """ + c_type = self._myColumnTypeList[col_index] + + return_value = None + if c_type == 'checkbox': + # Check box + cell_i_j = self.cellWidget(row_index, col_index) + assert isinstance(cell_i_j, QtGui.QCheckBox) + return_value = cell_i_j.isChecked() + else: + # Regular cell + item_i_j = self.item(row_index, col_index) + assert isinstance(item_i_j, QtGui.QTableWidgetItem) + value = str(item_i_j.text()) + if c_type == 'int': + return_value = int(value) + elif c_type == 'float': + return_value = float(value) + + return return_value + + def get_row_value(self, row_index): + """ + :param row_index: + :return: list of objects + """ + if row_index < 0 or row_index >= self.rowCount(): + raise IndexError('Index of row (%d) is out of range.' % row_index) + + ret_list = list() + for i_col in xrange(len(self._myColumnTypeList)): + c_type = self._myColumnTypeList[i_col] + + if c_type == 'checkbox': + # Check box + cell_i_j = self.cellWidget(row_index, i_col) + assert isinstance(cell_i_j, QtGui.QCheckBox) + is_checked = cell_i_j.isChecked() + ret_list.append(is_checked) + else: + # Regular cell + item_i_j = self.item(row_index, i_col) + assert isinstance(item_i_j, QtGui.QTableWidgetItem) + value = str(item_i_j.text()).strip() + if len(value) > 0: + if c_type == 'int': + value = int(value) + elif c_type == 'float': + value = float(value) + else: + value = None + + ret_list.append(value) + # END-IF-ELSE + # END-FOR + + return ret_list + + def init_setup(self, column_tup_list): + """ Initial setup + :param column_tup_list: list of 2-tuple as string (column name) and string (data type) + :return: + """ + # Define column headings + num_cols = len(column_tup_list) + + # Class variables + self._myHeaderList = list() + self._myColumnTypeList = list() + + for c_tup in column_tup_list: + c_name = c_tup[0] + c_type = c_tup[1] + self._myHeaderList.append(c_name) + self._myColumnTypeList.append(c_type) + + self.setColumnCount(num_cols) + self.setHorizontalHeaderLabels(self._myHeaderList) + + return + + def init_size(self, num_rows, num_cols): + """ + + :return: + """ + self.setColumnCount(num_cols) + self.setRowCount(num_rows) + + return + + def set_check_box(self, row, col, state): + """ function to add a new select checkbox to a cell in a table row + won't add a new checkbox if one already exists + """ + # Check input + assert isinstance(state, bool) + + # Check if cellWidget exists + if self.cellWidget(row,col): + # existing: just set the value + self.cellWidget(row, col).setChecked(state) + else: + # case to add checkbox + checkbox = QtGui.QCheckBox() + checkbox.setText('') + checkbox.setChecked(state) + + # Adding a widget which will be inserted into the table cell + # then centering the checkbox within this widget which in turn, + # centers it within the table column :-) + self.setCellWidget(row, col, checkbox) + # END-IF-ELSE + + return + + def set_value_cell(self, row, col, value=''): + """ + Set value to a cell with integer, float or string + :param row: + :param col: + :param value: + :return: + """ + # Check + if row < 0 or row >= self.rowCount() or col < 0 or col >= self.columnCount(): + raise IndexError('Input row number or column number is out of range.') + + # Init cell + cell_item = QtGui.QTableWidgetItem() + cell_item.setText(_fromUtf8(str(value))) + cell_item.setFlags(cell_item.flags() & ~QtCore.Qt.ItemIsEditable) + + self.setItem(row, col, cell_item) + + return + + def update_cell_value(self, row, col, value): + """ + + :param row: + :param col: + :param value: + :return: + """ + cell_item = self.item(row, col) + cell_widget = self.cellWidget(row, col) + + if cell_item is not None and cell_widget is None: + # TableWidgetItem + assert isinstance(cell_item, QtGui.QTableWidgetItem) + if isinstance(value, float): + cell_item.setText(_fromUtf8('%.7f' % value)) + else: + cell_item.setText(_fromUtf8(str(value))) + elif cell_item is None and cell_widget is not None: + # TableCellWidget + if isinstance(cell_item, QtGui.QCheckBox) is True: + cell_item.setChecked(value) + else: + raise TypeError('Cell of type %s is not supported.' % str(type(cell_item))) + else: + raise TypeError('Table cell (%d, %d) is in an unsupported situation!' % (row, col)) + + return diff --git a/scripts/HFIR_4Circle_Reduction/__init__.py b/scripts/HFIR_4Circle_Reduction/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..04a95e8315757618d54dc05da33da722b0774d94 --- /dev/null +++ b/scripts/HFIR_4Circle_Reduction/__init__.py @@ -0,0 +1,2 @@ +#pylint: disable=invalid-name +#pylint: disable=invalid-name diff --git a/scripts/HFIR_4Circle_Reduction/fourcircle_utility.py b/scripts/HFIR_4Circle_Reduction/fourcircle_utility.py new file mode 100644 index 0000000000000000000000000000000000000000..35dc1fe387e6bd1597eed0a9eb6c52f8c08811f8 --- /dev/null +++ b/scripts/HFIR_4Circle_Reduction/fourcircle_utility.py @@ -0,0 +1,188 @@ +#pylint: disable=W0633,too-many-branches +__author__ = 'wzz' + +import os +import urllib2 +import socket + + +def check_url(url, read_lines=False): + """ Check whether a URL is valid + :param url: + :return: boolean, error message + """ + lines = None + try: + # Access URL + url_stream = urllib2.urlopen(url, timeout=2) + + # Read lines + if read_lines is True: + lines = url_stream.readlines() + except urllib2.URLError as url_error: + url_stream = url_error + except socket.timeout: + return False, 'Time out. Try again!' + + # Return result + if url_stream.code in (200, 401): + url_good = True + else: + url_good = False + + # Close connect + url_stream.close() + + # Return + if read_lines is True: + return url_good, lines + if url_good is False: + error_message = 'Unable to access %s. Check internet access. Code %d' % (url, url_stream.code) + else: + error_message = '' + + return url_good, error_message + + +def get_scans_list(server_url, exp_no, return_list=False): + """ Get list of scans under one experiment + :param server_url: + :param exp_no: + :return: message + """ + if server_url.endswith('/') is False: + server_url = '%s/' % server_url + data_dir_url = '%sexp%d/Datafiles' % (server_url, exp_no) + + does_exist, raw_lines = check_url(data_dir_url, read_lines=True) + if does_exist is False: + return "Experiment %d's URL %s cannot be found." % (exp_no, data_dir_url) + + # Scan through the index page + scan_list = [] + header = 'HB3A_exp%04d_scan' % exp_no + for line in raw_lines: + if line.count(header) > 0: + # try to find file HB3A_exp0123_scan6789.dat + term = line.split(header)[1].split('.dat')[0] + scan = int(term) + # check + if '%04d' % scan == term: + scan_list.append(scan) + # END_FOR + scan_list = sorted(scan_list) + if return_list is True: + return scan_list + + message = 'Experiment %d: Scan from %d to %d' % (exp_no, scan_list[0], scan_list[-1]) + + return message + + +def get_scans_list_local_disk(local_dir, exp_no): + """ Get scans from a specified directory on local disk + :param local_dir: + :param exp_no: + :return: + """ + scan_list = [] + + file_names = os.listdir(local_dir) + header = 'HB3A_exp%04d_scan' % exp_no + for name in file_names: + if name.count(header) > 0: + scan = int(name.split(header)[1].split('.dat')[0]) + scan_list.append(scan) + + scan_list = sorted(scan_list) + + if len(scan_list) == 0: + message = 'Experiment %d: No scan can be found.' % exp_no + else: + message = 'Experiment %d: Scan from %d to %d ' % (exp_no, scan_list[0], scan_list[-1]) + num_skip_scans = scan_list[-1] - scan_list[0] + 1 - len(scan_list) + if num_skip_scans > 0: + message += 'with %d ' % num_skip_scans + else: + message += 'without ' + message += 'missing scans.' + + return message + + +def parse_int_array(int_array_str): + """ Validate whether the string can be divided into integer strings. + Allowed: a, b, c-d, e, f + :param int_array_str: + :return: + """ + int_array_str = str(int_array_str) + if int_array_str == "": + return True, [] + + # Split by "," + term_level_0 = int_array_str.split(",") + integer_list = [] + + # For each term + err_msg = "" + ret_status = True + + for level0_term in term_level_0: + level0_term = level0_term.strip() + + # split upon dash - + num_dashes = level0_term.count("-") + if num_dashes == 0: + # one integer + value_str = level0_term + try: + int_value = int(value_str) + if str(int_value) != value_str: + ret_status = False + err_msg = "Contains non-integer string %s." % value_str + except ValueError: + ret_status = False + err_msg = "String %s is not an integer." % (value_str) + else: + integer_list.append(int_value) + + elif num_dashes == 1: + # Integer range + two_terms = level0_term.split("-") + temp_list = [] + for i in xrange(2): + value_str = two_terms[i] + try: + int_value = int(value_str) + if str(int_value) != value_str: + ret_status = False + err_msg = "Contains non-integer string %s." % (value_str) + except ValueError: + ret_status = False + err_msg = "String %s is not an integer." % (value_str) + else: + temp_list.append(int_value) + + # break loop + if ret_status is False: + break + # END_FOR(i) + integer_list.extend(range(temp_list[0], temp_list[1]+1)) + + else: + # Undefined situation + ret_status = False + err_msg = "Term %s contains more than 1 dash." % level0_term + # END-IF-ELSE + + # break loop if something is wrong + if ret_status is False: + break + # END-FOR(level0_term) + + # Return with false + if ret_status is False: + return False, err_msg + + return True, integer_list diff --git a/scripts/HFIR_4Circle_Reduction/guiutility.py b/scripts/HFIR_4Circle_Reduction/guiutility.py new file mode 100644 index 0000000000000000000000000000000000000000..79237a5729470b372017478b24a0564159d67fb1 --- /dev/null +++ b/scripts/HFIR_4Circle_Reduction/guiutility.py @@ -0,0 +1,164 @@ +# +# GUI Utility Methods +# +from PyQt4 import QtGui + + +def parse_float_array(array_str): + """ Parse a string to an array of float + :param array_str: + :return: boolean, list of floats/error message + """ + print array_str + assert isinstance(array_str, str) + array_str = array_str.replace(',', ' ') + array_str = array_str.replace('\n', ' ') + array_str = array_str.replace('\t ', ' ') + array_str = array_str.strip() + print '[DB] After processing: ', array_str + + float_str_list = array_str.split() + float_list = list() + for float_str in float_str_list: + try: + value = float(float_str) + except ValueError as value_error: + return False, 'Unable to parse %s due to %s.' % (float_str, str(value_error)) + else: + float_list.append(value) + # END-FOR + + return True, float_list + + +def parse_integer_list(array_str): + """ Parse a string to an array of integer separated by ',' + also, the format as 'a-b' is supported too + :param array_str: + :return: boolean, list of floats/error message + """ + assert isinstance(array_str, str) + array_str = array_str.replace(' ', '') + array_str = array_str.replace('\n', '') + array_str = array_str.replace('\t ', '') + + int_str_list = array_str.split(',') + integer_list = list() + for int_str in int_str_list: + + try: + int_value = int(int_str) + integer_list.append(int_value) + except ValueError: + num_dash = int_str.count('-') + if num_dash == 1: + terms = int_str.split('-') + try: + start_value = int(terms[0]) + end_value = int(terms[1]) + except ValueError: + raise RuntimeError('Unable to parse %s due to value error' % int_str) + elif num_dash == 2 and int_str.startswith('-'): + terms = int_str[1:].split('-') + try: + start_value = int(terms[0])*-1 + end_value = int(terms[1]) + except ValueError: + raise RuntimeError('Unable to parse %s due to value error' % int_str) + elif num_dash == 3: + terms = int_str.split('-') + try: + start_value = -1*int(terms[1]) + end_value = -1*int(terms[3]) + except ValueError: + raise RuntimeError('Unable to parse %s due to value error' % int_str) + except IndexError: + raise RuntimeError('Unable to parse %s due to value error' % int_str) + else: + raise RuntimeError('Unable to parse %s due to value error' % int_str) + + integer_list.extend(xrange(start_value, end_value+1)) + # END-FOR + + return integer_list + + +def parse_float_editors(line_edits): + """ + :param line_edits: + :return: (True, list of floats); (False, error message) + """ + # Set flag + return_single_value = False + + if isinstance(line_edits, QtGui.QLineEdit) is True: + line_edit_list = [line_edits] + return_single_value = True + elif isinstance(line_edits, list) is True: + line_edit_list = line_edits + else: + raise RuntimeError('Input is not LineEdit or list of LineEdit.') + + error_message = '' + float_list = [] + + for line_edit in line_edit_list: + assert isinstance(line_edit, QtGui.QLineEdit) + try: + str_value = str(line_edit.text()).strip() + float_value = float(str_value) + except ValueError as value_err: + error_message += 'Unable to parse to integer. %s\n' % (str(value_err)) + else: + float_list.append(float_value) + # END-TRY + # END-FOR + + if len(error_message) > 0: + return False, error_message + elif return_single_value is True: + return True, float_list[0] + + return True, float_list + + +def parse_integers_editors(line_edits): + """ + :param line_edits: + :return: (True, list of integers); (False, error message) + """ + # Set flag + return_single_value = False + + if isinstance(line_edits, QtGui.QLineEdit) is True: + line_edit_list = [line_edits] + return_single_value = True + elif isinstance(line_edits, list) is True: + line_edit_list = line_edits + else: + raise RuntimeError('Input is not LineEdit or list of LineEdit.') + + error_message = '' + integer_list = [] + + for line_edit in line_edit_list: + assert isinstance(line_edit, QtGui.QLineEdit) + try: + str_value = str(line_edit.text()).strip() + int_value = int(str_value) + except ValueError as value_err: + error_message += 'Unable to parse to integer. %s\n' % (str(value_err)) + else: + if str_value != '%d' % int_value: + error_message += 'Value %s is not a proper integer.\n' % str_value + else: + integer_list.append(int_value) + # END-TRY + # END-FOR + + if len(error_message) > 0: + return False, error_message + elif return_single_value is True: + return True, integer_list[0] + + return True, integer_list diff --git a/scripts/HFIR_4Circle_Reduction/hfctables.py b/scripts/HFIR_4Circle_Reduction/hfctables.py new file mode 100644 index 0000000000000000000000000000000000000000..dba8cb64a3aefb4adff82b540655251d9fe41311 --- /dev/null +++ b/scripts/HFIR_4Circle_Reduction/hfctables.py @@ -0,0 +1,385 @@ +#pylint: disable=W0403,C0103,R0901,R0904 +import numpy +import NTableWidget as tableBase + +# UB peak information table +Peak_Integration_Table_Setup = [('Scan', 'int'), + ('Pt', 'int'), + ('H', 'float'), + ('K', 'float'), + ('L', 'float'), + ('Q_x', 'float'), + ('Q_y', 'float'), + ('Q_z', 'float'), + ('Intensity', 'float')] + + +class IntegratePeaksTableWidget(tableBase.NTableWidget): + """ + Extended table widget for peak integration + """ + def __init__(self, parent): + """ + :param parent: + """ + tableBase.NTableWidget.__init__(self, parent) + + return + + def setup(self): + """ + Init setup + :return: + """ + self.init_setup(Peak_Integration_Table_Setup) + + return + + +class UBMatrixTable(tableBase.NTableWidget): + """ + Extended table for UB matrix + """ + def __init__(self, parent): + """ + + :param parent: + :return: + """ + tableBase.NTableWidget.__init__(self, parent) + + # Matrix + self._matrix = numpy.ndarray((3, 3), float) + for i in xrange(3): + for j in xrange(3): + self._matrix[i][j] = 0. + + return + + def _set_to_table(self): + """ + Set values in holder '_matrix' to TableWidget + :return: + """ + for i_row in xrange(3): + for j_col in xrange(3): + self.update_cell_value(i_row, j_col, self._matrix[i_row][j_col]) + + return + + def get_matrix(self): + """ + Get the copy of the matrix + :return: + """ + # print '[DB] MatrixTable: _Matrix = ', self._matrix + return self._matrix.copy() + + def set_from_list(self, element_array): + """ + Set table value including holder and QTable from a 1D numpy array + :param element_array: + :return: + """ + # Check + assert isinstance(element_array, list) + assert len(element_array) == 9 + + # Set value + i_array = 0 + for i in xrange(3): + for j in xrange(3): + self._matrix[i][j] = element_array[i_array] + i_array += 1 + + # Set to table + self._set_to_table() + + return + + def set_from_matrix(self, matrix): + """ + Set value to both holder and QTable from a numpy 3 x 3 matrix + :param matrix: + :return: + """ + # Check + assert isinstance(matrix, numpy.ndarray) + assert matrix.shape == (3, 3) + + for i in xrange(3): + for j in xrange(3): + self._matrix[i][j] = matrix[i][j] + + self._set_to_table() + + return + + def setup(self): + """ + Init setup + :return: + """ + # self.init_size(3, 3) + + for i in xrange(3): + for j in xrange(3): + self.set_value_cell(i, j) + + self._set_to_table() + + return + + +# UB peak information table +UB_Peak_Table_Setup = [('Scan', 'int'), + ('Pt', 'int'), + ('H', 'float'), + ('K', 'float'), + ('L', 'float'), + ('Q_x', 'float'), + ('Q_y', 'float'), + ('Q_z', 'float'), + ('Selected', 'checkbox'), + ('m1', 'float'), + ('Error', 'float')] + + +class UBMatrixPeakTable(tableBase.NTableWidget): + """ + Extended table for peaks used to calculate UB matrix + """ + def __init__(self, parent): + """ + + :param parent: + :return: + """ + tableBase.NTableWidget.__init__(self, parent) + + return + + def get_exp_info(self, row_index): + """ + Get experiment information from a row + :return: scan number, pt number + """ + assert isinstance(row_index, int) + + scan_number = self.get_cell_value(row_index, 0) + assert isinstance(scan_number, int) + pt_number = self.get_cell_value(row_index, 1) + assert isinstance(pt_number, int) + + return scan_number, pt_number + + def get_hkl(self, row_index): + """ + Get reflection's miller index + :param row_index: + :return: + """ + assert isinstance(row_index, int) + + m_h = self.get_cell_value(row_index, 2) + m_k = self.get_cell_value(row_index, 3) + m_l = self.get_cell_value(row_index, 4) + + assert isinstance(m_h, float) + assert isinstance(m_k, float) + assert isinstance(m_l, float) + + return m_h, m_k, m_l + + def get_scan_pt(self, row_number): + """ + Get Scan and Pt from a row + :param row_number: + :return: + """ + scan_number = self.get_cell_value(row_number, 0) + pt_number = self.get_cell_value(row_number, 1) + + return scan_number, pt_number + + def is_selected(self, row_index): + """ + + :return: + """ + if row_index < 0 or row_index >= self.rowCount(): + raise IndexError('Input row number %d is out of range [0, %d)' % (row_index, self.rowCount())) + + col_index = UB_Peak_Table_Setup.index(('Selected', 'checkbox')) + + return self.get_cell_value(row_index, col_index) + + def setup(self): + """ + Init setup + :return: + """ + self.init_setup(UB_Peak_Table_Setup) + + return + + def set_hkl(self, i_row, hkl, error=None): + """ + Set HKL to table + :param irow: + :param hkl: + """ + # Check + assert isinstance(i_row, int) + assert isinstance(hkl, list) + + i_col_h = UB_Peak_Table_Setup.index(('H', 'float')) + i_col_k = UB_Peak_Table_Setup.index(('K', 'float')) + i_col_l = UB_Peak_Table_Setup.index(('L', 'float')) + + self.update_cell_value(i_row, i_col_h, hkl[0]) + self.update_cell_value(i_row, i_col_k, hkl[1]) + self.update_cell_value(i_row, i_col_l, hkl[2]) + + if error is not None: + i_col_error = UB_Peak_Table_Setup.index(('Error', 'float')) + self.update_cell_value(i_row, i_col_error, error) + + return + + def update_hkl(self, i_row, h, k, l): + """ Update HKL value + """ + self.update_cell_value(i_row, 2, h) + self.update_cell_value(i_row, 3, k) + self.update_cell_value(i_row, 4, l) + + return + + +# Processing status table +Process_Table_Setup = [('Scan', 'int'), + ('Number Pt', 'int'), + ('Status', 'str'), + ('Merged Workspace', 'str'), + ('Group Name', 'str'), + ('Select', 'checkbox')] + + +class ProcessTableWidget(tableBase.NTableWidget): + """ + Extended table for peaks used to calculate UB matrix + """ + def __init__(self, parent): + """ + + :param parent: + :return: + """ + tableBase.NTableWidget.__init__(self, parent) + + return + + def append_scans(self, scans): + """ Append rows + :param scans: + :return: + """ + # Check + assert isinstance(scans, list) + + # Append rows + for scan in scans: + row_value_list = [scan, 0, 'In Queue', '', '', False] + status, err = self.append_row(row_value_list) + if status is False: + raise RuntimeError(err) + + return + + def setup(self): + """ + Init setup + :return: + """ + self.init_setup(Process_Table_Setup) + + return + + def set_scan_pt(self, scan_no, pt_list): + """ + :param scan_no: + :param pt_list: + :return: + """ + # Check + assert isinstance(scan_no, int) + + num_rows = self.rowCount() + set_done = False + for i_row in xrange(num_rows): + tmp_scan_no = self.get_cell_value(i_row, 0) + if scan_no == tmp_scan_no: + self.update_cell_value(i_row, 1, len(pt_list)) + set_done = True + break + # END-FOR + + if set_done is False: + return 'Unable to find scan %d in table.' % scan_no + + return '' + + def set_status(self, scan_no, status): + """ + Set the status for merging scan to QTable + :param status: + :return: + """ + # Check + assert isinstance(scan_no, int) + + num_rows = self.rowCount() + set_done = False + for i_row in xrange(num_rows): + tmp_scan_no = self.get_cell_value(i_row, 0) + if scan_no == tmp_scan_no: + self.update_cell_value(i_row, 2, status) + set_done = True + break + # END-FOR + + if set_done is False: + return 'Unable to find scan %d in table.' % scan_no + + return '' + + def set_ws_names(self, scan_num, merged_md_name, ws_group_name): + """ + Set the output workspace and workspace group's names to QTable + :param merged_md_name: + :param ws_group_name: + :return: + """ + # Check + assert isinstance(scan_num, int) + assert isinstance(merged_md_name, str) or merged_md_name is None + assert isinstance(ws_group_name, str) or ws_group_name is None + + num_rows = self.rowCount() + set_done = False + for i_row in xrange(num_rows): + tmp_scan_no = self.get_cell_value(i_row, 0) + if scan_num == tmp_scan_no: + if merged_md_name is not None: + self.update_cell_value(i_row, 3, merged_md_name) + if ws_group_name is not None: + self.update_cell_value(i_row, 4, ws_group_name) + set_done = True + break + # END-FOR + + if set_done is False: + return 'Unable to find scan %d in table.' % scan_num + + return diff --git a/scripts/HFIR_4Circle_Reduction/mplgraphicsview.py b/scripts/HFIR_4Circle_Reduction/mplgraphicsview.py new file mode 100644 index 0000000000000000000000000000000000000000..152ffc29c4775c6f98b8b67befe0554a36d66032 --- /dev/null +++ b/scripts/HFIR_4Circle_Reduction/mplgraphicsview.py @@ -0,0 +1,1255 @@ +#pylint: disable=invalid-name,too-many-public-methods,too-many-arguments,non-parent-init-called,R0902,too-many-branches,C0302 +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 NavigationToolbar2QTAgg as NavigationToolbar2 +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 )"] + +# Note: in colors, "white" is removed +MplBasicColors = [ + "black", + "red", + "blue", + "green", + "cyan", + "magenta", + "yellow"] + + +class IndicatorManager(object): + """ Manager for all indicator lines + """ + def __init__(self): + """ + + :return: + """ + # Auto color index + self._colorIndex = 0 + # Auto line ID + self._autoLineID = 1 + + self._lineManager = dict() + self._canvasLineKeyDict = dict() + self._indicatorTypeDict = dict() # value: 0 (horizontal), 1 (vertical), 2 (2-way) + + return + + def add_2way_indicator(self, x, x_min, x_max, y, y_min, y_max, color): + """ + + :param x: + :param x_min: + :param x_max: + :param y: + :param y_min: + :param y_max: + :param color: + :return: + """ + # Set up indicator ID + this_id = str(self._autoLineID) + self._autoLineID += 1 + + # Set up vectors + vec_x_horizontal = np.array([x_min, x_max]) + vec_y_horizontal = np.array([y, y]) + + vec_x_vertical = np.array([x, x]) + vec_y_vertical = np.array([y_min, y_max]) + + # + self._lineManager[this_id] = [vec_x_horizontal, vec_y_horizontal, vec_x_vertical, vec_y_vertical, color] + self._indicatorTypeDict[this_id] = 2 + + return this_id + + def add_horizontal_indicator(self, y, x_min, x_max, color): + """ + Add a horizontal indicator + :param y: + :param x_min: + :param x_max: + :param color: + :return: + """ + # Get ID + this_id = str(self._autoLineID) + self._autoLineID += 1 + + # + vec_x = np.array([x_min, x_max]) + vec_y = np.array([y, y]) + + # + self._lineManager[this_id] = [vec_x, vec_y, color] + self._indicatorTypeDict[this_id] = 0 + + return this_id + + def add_vertical_indicator(self, x, y_min, y_max, color): + """ + Add a vertical indicator to data structure + :return: indicator ID + """ + # Get ID + this_id = str(self._autoLineID) + self._autoLineID += 1 + + # + vec_x = np.array([x, x]) + vec_y = np.array([y_min, y_max]) + + # + self._lineManager[this_id] = [vec_x, vec_y, color] + self._indicatorTypeDict[this_id] = 1 + + return this_id + + def get_canvas_line_index(self, my_id): + """ + + :param my_id: + :return: + """ + assert isinstance(my_id, str) + + if my_id not in self._canvasLineKeyDict: + raise RuntimeError('Indicator ID %s cannot be found. Current keys are %s.' % ( + my_id, str(sorted(self._canvasLineKeyDict.keys())) + )) + return self._canvasLineKeyDict[my_id] + + def get_line_type(self, my_id): + """ + + :param my_id: + :return: + """ + return self._indicatorTypeDict[my_id] + + def get_2way_data(self, line_id): + """ + + :param line_id: + :return: + """ + assert self._indicatorTypeDict.has_key(line_id) + assert self._indicatorTypeDict[line_id] == 2 + + vec_set = [self._lineManager[line_id][0:2], self._lineManager[line_id][2:4]] + + return vec_set + + def get_data(self, line_id): + """ + Get line's vector x and vector y + :param line_id: + :return: + """ + return self._lineManager[line_id][0], self._lineManager[line_id][1] + + def get_line_style(self, line_id=None): + """ + + :param line_id: + :return: + """ + assert isinstance(line_id, None) + return '--' + + def get_live_indicator_ids(self): + """ + + :return: + """ + return sorted(self._lineManager.keys()) + + def get_marker(self): + """ + Get the marker a line + :param line_id: + :return: + """ + return 'o' + + def get_next_color(self): + """ + Get next color by auto color index + :return: string as color + """ + next_color = MplBasicColors[self._colorIndex] + + # Advance and possibly reset color scheme + self._colorIndex += 1 + if self._colorIndex == len(MplBasicColors): + self._colorIndex = 0 + + return next_color + + def set_canvas_line_index(self, my_id, canvas_line_index): + """ + + :param my_id: + :param canvas_line_index: + :return: + """ + self._canvasLineKeyDict[my_id] = canvas_line_index + + def shift(self, my_id, dx, dy): + """ + + :param my_id: + :param dx: + :param dy: + :return: + """ + print self._lineManager[my_id][0] + + if self._indicatorTypeDict[my_id] == 0: + # horizontal + self._lineManager[my_id][1] += dy + + elif self._indicatorTypeDict[my_id] == 1: + # vertical + self._lineManager[my_id][0] += dx + + elif self._indicatorTypeDict[my_id] == 2: + # 2-way + self._lineManager[my_id][2] += dx + self._lineManager[my_id][1] += dy + + else: + raise RuntimeError('Unsupported indicator of type %d' % self._indicatorTypeDict[my_id]) + + return + + def update_indicators_range(self, x_range, y_range): + """ + Update indicator's range + :param x_range: + :param y_range: + :return: + """ + for i_id in self._lineManager.keys(): + # NEXT - Need a new flag for direction of the indicating line, vertical or horizontal + if True: + self._lineManager[i_id][1][0] = y_range[0] + self._lineManager[i_id][1][-1] = y_range[1] + else: + self._lineManager[i_id][0][0] = x_range[0] + self._lineManager[i_id][0][-1] = x_range[1] + + return + + +class MplGraphicsView(QtGui.QWidget): + """ A combined graphics view including matplotlib canvas and + a navigation tool bar + + Note: Merged with HFIR_Powder_Reduction.MplFigureCAnvas + """ + def __init__(self, parent): + """ Initialization + """ + # Initialize parent + QtGui.QWidget.__init__(self, parent) + + # set up canvas + self._myCanvas = Qt4MplCanvas(self) + self._myToolBar = MyNavigationToolbar(self, self._myCanvas) + + # set up layout + self._vBox = QtGui.QVBoxLayout(self) + self._vBox.addWidget(self._myCanvas) + self._vBox.addWidget(self._myToolBar) + + # auto line's maker+color list + self._myLineMarkerColorList = [] + self._myLineMarkerColorIndex = 0 + self.setAutoLineMarkerColorCombo() + + # Declaration of class variables + self._indicatorKey = None + + # Indicator manager + self._myIndicatorsManager = IndicatorManager() + + return + + def add_line_set(self, vec_set, color, marker, line_style, line_width): + """ Add a set of line and manage together + :param vec_set: + :param color: + :param marker: + :param line_style: + :param line_width: + :return: + """ + key_list = list() + for vec_x, vec_y in vec_set: + temp_key = self._myCanvas.add_plot_1d(vec_x, vec_y, color=color, marker=marker, + line_style=line_style, line_width=line_width) + assert isinstance(temp_key, int) + assert temp_key >= 0 + key_list.append(temp_key) + + return key_list + + def add_plot_1d(self, vec_x, vec_y, y_err=None, color=None, label="", x_label=None, y_label=None, + marker=None, line_style=None, line_width=1): + """ Add a new plot + """ + line_key = self._myCanvas.add_plot_1d(vec_x, vec_y, y_err, color, label, x_label, y_label, marker, line_style, + line_width) + + return line_key + + def add_plot_1d_right(self, vec_x, vec_y, color=None, label='', marker=None, line_style=None, line_width=1): + """ + Add 1 line (1-d plot) to right axis + :param vec_x: + :param vec_y: + :param color: + :param label: + :param marker: + :param line_style: + :param line_width: + :return: + """ + line_key = self._myCanvas.add_1d_plot_right(vec_x, vec_y, label=label, + color=color, marker=marker, + linestyle=line_style, linewidth=line_width) + + return line_key + + def add_2way_indicator(self, x=None, y=None, color=None, master_line=None): + """ Add a 2-way indicator following an existing line? + :param x: + :param y: + :param color: + :return: + """ + if master_line is not None: + raise RuntimeError('Implement how to use master_line ASAP.') + + x_min, x_max = self._myCanvas.getXLimit() + if x is None: + x = (x_min + x_max) * 0.5 + else: + assert isinstance(x, float) + + y_min, y_max = self._myCanvas.getYLimit() + if y is None: + y = (y_min + y_max) * 0.5 + else: + assert isinstance(y, float) + + if color is None: + color = self._myIndicatorsManager.get_next_color() + else: + assert isinstance(color, str) + + my_id = self._myIndicatorsManager.add_2way_indicator(x, x_min, x_max, + y, y_min, y_max, + color) + vec_set = self._myIndicatorsManager.get_2way_data(my_id) + + canvas_line_index = self.add_line_set(vec_set, color=color, + marker=self._myIndicatorsManager.get_marker(), + line_style=self._myIndicatorsManager.get_line_style(), + line_width=1) + self._myIndicatorsManager.set_canvas_line_index(my_id, canvas_line_index) + + return my_id + + def add_horizontal_indicator(self, y=None, color=None): + """ Add an indicator line + """ + # Default + if y is None: + y_min, y_max = self._myCanvas.getYLimit() + y = (y_min + y_max) * 0.5 + else: + assert isinstance(y, float) + + x_min, x_max = self._myCanvas.getXLimit() + + # For color + if color is None: + color = self._myIndicatorsManager.get_next_color() + else: + assert isinstance(color, str) + + # Form + my_id = self._myIndicatorsManager.add_horizontal_indicator(y, x_min, x_max, color) + vec_x, vec_y = self._myIndicatorsManager.get_data(my_id) + + canvas_line_index = self._myCanvas.add_plot_1d(vec_x=vec_x, vec_y=vec_y, + color=color, marker=self._myIndicatorsManager.get_marker(), + line_style=self._myIndicatorsManager.get_line_style(), + line_width=1) + + self._myIndicatorsManager.set_canvas_line_index(my_id, canvas_line_index) + + return my_id + + def add_vertical_indicator(self, x=None, color=None): + """ + Add a vertical indicator line + :param x: None as the automatic mode using default from middle of canvas + :param color: None as the automatic mode using default + :return: indicator ID + """ + # For indicator line's position + if x is None: + x_min, x_max = self._myCanvas.getXLimit() + x = (x_min + x_max) * 0.5 + else: + assert isinstance(x, float) + + y_min, y_max = self._myCanvas.getYLimit() + + # For color + if color is None: + color = self._myIndicatorsManager.get_next_color() + else: + assert isinstance(color, str) + + # Form + my_id = self._myIndicatorsManager.add_vertical_indicator(x, y_min, y_max, color) + vec_x, vec_y = self._myIndicatorsManager.get_data(my_id) + + canvas_line_index = self._myCanvas.add_plot_1d(vec_x=vec_x, vec_y=vec_y, + color=color, marker=self._myIndicatorsManager.get_marker(), + line_style=self._myIndicatorsManager.get_line_style(), + line_width=1) + + self._myIndicatorsManager.set_canvas_line_index(my_id, canvas_line_index) + + return my_id + + def add_plot_2d(self, array2d, x_min, x_max, y_min, y_max, hold_prev_image=True, y_tick_label=None): + """ + Add a 2D image to canvas + :param array2d: numpy 2D array + :param x_min: + :param x_max: + :param y_min: + :param y_max: + :param hold_prev_image: + :param y_tick_label: + :return: + """ + self._myCanvas.addPlot2D(array2d, x_min, x_max, y_min, y_max, hold_prev_image, y_tick_label) + + 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._myCanvas.addImage(imagefilename) + + return + + def clear_all_lines(self): + """ + """ + self._myCanvas.clear_all_1d_plots() + + def clear_canvas(self): + """ Clear canvas + """ + return self._myCanvas.clear_canvas() + + def draw(self): + """ Draw to commit the change + """ + return self._myCanvas.draw() + + def evt_view_updated(self): + """ Event handling as canvas size updated + :return: + """ + # update the indicator + new_x_range = self.getXLimit() + new_y_range = self.getYLimit() + + self._myIndicatorsManager.update_indicators_range(new_x_range, new_y_range) + for indicator_key in self._myIndicatorsManager.get_live_indicator_ids(): + canvas_line_id = self._myIndicatorsManager.get_canvas_line_index(indicator_key) + data_x, data_y = self._myIndicatorsManager.get_data(indicator_key) + self.updateLine(canvas_line_id, data_x, data_y) + # END-FOR + + return + + def getPlot(self): + """ + """ + return self._myCanvas.getPlot() + + def getLastPlotIndexKey(self): + """ Get ... + """ + return self._myCanvas.getLastPlotIndexKey() + + def getXLimit(self): + """ Get limit of Y-axis + """ + return self._myCanvas.getXLimit() + + def getYLimit(self): + """ Get limit of Y-axis + """ + return self._myCanvas.getYLimit() + + def move_indicator(self, line_id, dx, dy): + """ + Move the indicator line in horizontal + :param line_id: + :param dx: + :return: + """ + # Shift value + self._myIndicatorsManager.shift(line_id, dx=dx, dy=dy) + + # apply to plot on canvas + if self._myIndicatorsManager.get_line_type(line_id) < 2: + # horizontal or vertical + canvas_line_index = self._myIndicatorsManager.get_canvas_line_index(line_id) + vec_x, vec_y = self._myIndicatorsManager.get_data(line_id) + self._myCanvas.updateLine(ikey=canvas_line_index, vecx=vec_x, vecy=vec_y) + else: + # 2-way + canvas_line_index_h, canvas_line_index_v = self._myIndicatorsManager.get_canvas_line_index(line_id) + h_vec_set, v_vec_set = self._myIndicatorsManager.get_2way_data(line_id) + + self._myCanvas.updateLine(ikey=canvas_line_index_h, vecx=h_vec_set[0], vecy=h_vec_set[1]) + self._myCanvas.updateLine(ikey=canvas_line_index_v, vecx=v_vec_set[0], vecy=v_vec_set[1]) + + return + + def remove_indicator(self, indicator_key): + """ Remove indicator line + :param indicator_key: + :return: + """ + # + plot_id = self._myIndicatorsManager.get_canvas_line_index(indicator_key) + self._myCanvas.remove_plot_1d(plot_id) + + return + + def removePlot(self, ikey): + """ + """ + return self._myCanvas.remove_plot_1d(ikey) + + def updateLine(self, ikey, vecx, vecy, linestyle=None, linecolor=None, marker=None, markercolor=None): + """ + """ + return self._myCanvas.updateLine(ikey, vecx, vecy, linestyle, linecolor, marker, markercolor) + + def update_indicator(self, i_key, color): + """ + Update indicator with new color + :param i_key: + :param vec_x: + :param vec_y: + :param color: + :return: + """ + if self._myIndicatorsManager.get_line_type(i_key) < 2: + # horizontal or vertical + canvas_line_index = self._myIndicatorsManager.get_canvas_line_index(i_key) + self._myCanvas.updateLine(ikey=canvas_line_index, vecx=None, vecy=None, linecolor=color) + else: + # 2-way + canvas_line_index_h, canvas_line_index_v = self._myIndicatorsManager.get_canvas_line_index(i_key) + # h_vec_set, v_vec_set = self._myIndicatorsManager.get_2way_data(i_key) + + self._myCanvas.updateLine(ikey=canvas_line_index_h, vecx=None, vecy=None, linecolor=color) + self._myCanvas.updateLine(ikey=canvas_line_index_v, vecx=None, vecy=None, linecolor=color) + + return + + def get_indicator_position(self, indicator_key): + """ Get position (x or y) of the indicator + :return: + """ + # NEXT - Consider a better and more consistent return + vec_x, vec_y = self._myIndicatorsManager.get_data(indicator_key) + if vec_x[0] == vec_x[1]: + return vec_x[0] + + return vec_y[0] + + 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._myCanvas.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 + + # NEXT-Urgent! - Find out difference between setXYLimit() and setXYLimits() + def setXYLimit(self, xmin, xmax, ymin, ymax): + """ Set X-Y limit automatically + """ + self._myCanvas.axes.set_xlim([xmin, xmax]) + self._myCanvas.axes.set_ylim([ymin, ymax]) + + self._myCanvas.draw() + + return + + def setXYLimits(self, xmin=None, xmax=None, ymin=None, ymax=None): + """ + """ + return self._myCanvas.setXYLimit(xmin, xmax, ymin, ymax) + + 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 + """ + # from mpl_toolkits.axes_grid1 import host_subplot + # import mpl_toolkits.axisartist as AA + # import matplotlib.pyplot as plt + + # Instantiating matplotlib Figure + self.fig = Figure() + self.fig.patch.set_facecolor('white') + + if True: + self.axes = self.fig.add_subplot(111) # return: matplotlib.axes.AxesSubplot + self.axes2 = None + else: + self.axes = self.fig.add_host_subplot(111) + + # 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 + + return + + def add_plot_1d(self, vec_x, vec_y, y_err=None, color=None, label="", x_label=None, y_label=None, + marker=None, line_style=None, line_width=1): + """ + + :param vec_x: numpy array X + :param vec_y: numpy array Y + :param y_err: + :param color: + :param label: + :param x_label: + :param y_label: + :param marker: + :param line_style: + :param line_width: + :return: new key + """ + # 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 + 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: + print "[DB] line_style = ", line_style, "line_width = ", line_width, "marker = ", marker, "color = ", color + 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 + line_key = self._lineIndex + if len(r) == 1: + self._lineDict[line_key] = r[0] + self._lineIndex += 1 + else: + print "Impoooooooooooooooosible! Return from plot is a %d-tuple. " % (len(r)) + + # Flush/commit + self.draw() + + return line_key + + def add_1d_plot_right(self, x, y, color=None, label="", x_label=None, ylabel=None, marker=None, linestyle=None, + linewidth=1): + """ Add a line (1-d plot) at right axis + """ + if self.axes2 is None: + self.axes2 = self.axes.twinx() + # print self.par1, type(self.par1) + + # Hold previous data + self.axes2.hold(True) + + # Default + if color is None: + color = (0, 1, 0, 1) + if marker is None: + marker = 'o' + if linestyle is None: + linestyle = '-' + + # Special default + if len(label) == 0: + label = 'right' + color = 'red' + + # color must be RGBA (4-tuple) + r = self.axes2.plot(x, y, color=color, marker=marker, linestyle=linestyle, + label=label, linewidth=linewidth) + # return: list of matplotlib.lines.Line2D object + + self.axes2.set_aspect('auto') + + # set x-axis and y-axis label + if x_label is not None: + self.axes2.set_xlabel(x_label, fontsize=20) + if ylabel is not None: + self.axes2.set_ylabel(ylabel, fontsize=20) + + # set/update legend + self._setupLegend() + + # Register + line_key = -1 + if len(r) == 1: + line_key = self._lineIndex + self._lineDict[line_key] = r[0] + self._lineIndex += 1 + else: + print "Impoooooooooooooooosible!" + + # Flush/commit + self.draw() + + return line_key + + + 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) + + # show image + imgplot = self.axes.imshow(array2d, extent=[xmin,xmax,ymin,ymax], interpolation='none') + # 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) + + # 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 clear_all_1d_plots(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 + + self._setupLegend() + + self.draw() + + return + + def clear_canvas(self): + """ Clear data including lines and image from canvas + """ + # clear the image for next operation + self.axes.hold(False) + + # Clear all lines + self.clear_all_1d_plots() + + # 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) + + # 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 remove_plot_1d(self, plot_key): + """ Remove the line with its index as key + :param plot_key: + :return: + """ + # self._lineDict[ikey].remove() + print 'Remove line... ', + + # Get all lines in list + lines = self.axes.lines + assert isinstance(lines, list) + + print 'Number of lines = %d, List: %s' % (len(lines), str(lines)) + print 'Line to remove: key = %s, Line Dict has key = %s' % (str(plot_key), str(self._lineDict.has_key(plot_key))) + + if plot_key in self._lineDict: + self.axes.lines.remove(self._lineDict[plot_key]) + self._lineDict[plot_key] = None + else: + raise RuntimeError('Line with ID %s is not recorded.' % plot_key) + + # Draw + self.draw() + + 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 xrange(nummarkers): + marker = MplLineMarkers[i] + for j in xrange(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.axes.legend(handles, labels, loc=location) + # print handles + # print labels + #self.axes.legend(self._myLegendHandlers, self._myLegentLabels) + + return + +# END-OF-CLASS (MplGraphicsView) + + +class MyNavigationToolbar(NavigationToolbar2): + """ A customized navigation tool bar attached to canvas + Note: + * home, left, right: will not disable zoom/pan mode + * zoom and pan: will turn on/off both's mode + + Other methods + * drag_pan(self, event): event handling method for dragging canvas in pan-mode + """ + NAVIGATION_MODE_NONE = 0 + NAVIGATION_MODE_PAN = 1 + NAVIGATION_MODE_ZOOM = 2 + + def __init__(self, parent, canvas): + """ Initialization + """ + NavigationToolbar2.__init__(self, canvas, canvas) + + self._myParent = parent + self._navigationMode = MyNavigationToolbar.NAVIGATION_MODE_NONE + + return + + def get_mode(self): + """ + :return: integer as none/pan/zoom mode + """ + return self._navigationMode + + # Overriding base's methods + def draw(self): + """ + Canvas is drawn called by pan(), zoom() + :return: + """ + NavigationToolbar2.draw(self) + + self._myParent.evt_view_updated() + + return + + def pan(self, *args): + """ + + :param args: + :return: + """ + NavigationToolbar2.pan(self, args) + + if self._navigationMode == MyNavigationToolbar.NAVIGATION_MODE_PAN: + # out of pan mode + self._navigationMode = MyNavigationToolbar.NAVIGATION_MODE_NONE + else: + # into pan mode + self._navigationMode = MyNavigationToolbar.NAVIGATION_MODE_PAN + + return + + def zoom(self, *args): + """ + Turn on/off zoom (zoom button) + :param args: + :return: + """ + NavigationToolbar2.zoom(self, args) + + if self._navigationMode == MyNavigationToolbar.NAVIGATION_MODE_ZOOM: + # out of zoom mode + self._navigationMode = MyNavigationToolbar.NAVIGATION_MODE_NONE + else: + # into zoom mode + self._navigationMode = MyNavigationToolbar.NAVIGATION_MODE_ZOOM + + return + + def _update_view(self): + """ + view update called by home(), back() and forward() + :return: + """ + NavigationToolbar2._update_view(self) + + self._myParent.evt_view_updated() + + return + diff --git a/scripts/HFIR_4Circle_Reduction/reduce4circleControl.py b/scripts/HFIR_4Circle_Reduction/reduce4circleControl.py new file mode 100644 index 0000000000000000000000000000000000000000..bb11355d3c1b09e8e5b011cd8b698d64614939aa --- /dev/null +++ b/scripts/HFIR_4Circle_Reduction/reduce4circleControl.py @@ -0,0 +1,1263 @@ +#pylint: disable=C0302,C0103,R0902,R0904,R0913,W0212,W0621,R0912 +################################################################################ +# +# Controlling class +# +# == Data download and storage == +# - Local data storage (local-mode) +# - Download from internet to cache (download-mode) +# +################################################################################ +import os +import urllib2 + +import numpy + +import mantid +import mantid.simpleapi as api +from mantid.api import AnalysisDataService + +DebugMode = True + +DET_X_SIZE = 256 +DET_Y_SIZE = 256 + + +class PeakInfo(object): + """ Class containing a peak's information for GUI + In order to manage some operations for a peak + It does not contain peak workspace but will hold + """ + def __init__(self, parent): + """ Init + """ + assert isinstance(parent, CWSCDReductionControl) + + # Define class variable + self._myParent = parent + self._userHKL = [0, 0, 0] + + self._myExpNumber = None + self._myScanNumber = None + self._myPtNumber = None + + self._myPeakWSKey = (None, None, None) + self._myPeakIndex = None + # IPeak instance + self._myPeak = None + + self._myLastPeakUB = None + + return + + def get_peak_workspace(self): + """ + Get peak workspace related + :return: + """ + assert isinstance(self._myPeakWSKey, tuple) + exp_number, scan_number, pt_number = self._myPeakWSKey + + return self._myParent.get_ub_peak_ws(exp_number, scan_number, pt_number)[1] + + def get_peak_ws_hkl(self): + """ Get HKL from PeakWorkspace + :return: + """ + hkl = self._myPeak.getHKL() + + return hkl.getX(), hkl.getY(), hkl.getZ() + + def get_user_hkl(self): + """ + Get HKL set to this object by client + :return: 3-tuple of float as (H, K, L) + """ + hkl = self._userHKL + + return hkl[0], hkl[1], hkl[2] + + def set_from_run_info(self, exp_number, scan_number, pt_number): + """ Set from run information with parent + :param exp_number: + :param scan_number: + :param pt_number: + :return: + """ + assert isinstance(exp_number, int) + assert isinstance(scan_number, int) + assert isinstance(pt_number, int) + + status, peak_ws = self._myParent.get_ub_peak_ws(exp_number, scan_number, pt_number) + if status is True: + self._myPeakWSKey = (exp_number, scan_number, pt_number) + self._myPeakIndex = 0 + self._myPeak = peak_ws.getPeak(0) + else: + error_message = peak_ws + return False, error_message + + self._myExpNumber = exp_number + self._myScanNumber = scan_number + self._myPtNumber = pt_number + + return True, '' + + def set_from_peak_ws(self, peak_ws, peak_index): + """ + Set from peak workspace + :param peak_ws: + :return: + """ + # Check + assert isinstance(peak_ws, mantid.dataobjects.PeaksWorkspace) + + # Get peak + try: + peak = peak_ws.getPeak(peak_index) + except RuntimeError as run_err: + raise RuntimeError(run_err) + + self._myPeak = peak + + return + + def set_peak_ws_hkl_from_user(self): + """ + + :return: + """ + # Check + if isinstance(self._myPeak, mantid.api.IPeak) is False: + raise RuntimeError('self._myPeakWS should be an instance of mantid.api.IPeak. ' + 'But it is of instance of %s now.' % str(type(self._myPeak))) + + # Get hkl + h, k, l = self._userHKL + print '[DB] PeakInfo Get User HKL = (%f, %f, %f) to IPeak ' % (h, k, l) + + self._myPeak.setHKL(h, k, l) + + return + + def set_user_hkl(self, h, k, l): + """ + Set HKL to this peak Info + :return: + """ + assert isinstance(h, float) + assert isinstance(k, float) + assert isinstance(l, float) + + self._userHKL[0] = h + self._userHKL[1] = k + self._userHKL[2] = l + + print '[DB] PeakInfo Set User HKL to (%f, %f, %f) ' % (self._userHKL[0], self._userHKL[1], self._userHKL[2]) + + return + + def getExpInfo(self): + """ + + :return: 3-tuple of integer as experiment number, scan number and Pt number + """ + return self._myExpNumber, self._myScanNumber, self._myPtNumber + + def getQSample(self): + """ + + :return: 3-tuple of floats as Qx, Qy, Qz + """ + q_sample = self._myPeak.getQSampleFrame() + return q_sample.getX(), q_sample.getY(), q_sample.getZ() + + +class CWSCDReductionControl(object): + """ Controlling class for reactor-based single crystal diffraction reduction + """ + def __init__(self, instrument_name=None): + """ init + """ + if isinstance(instrument_name, str): + self._instrumentName = instrument_name + elif instrument_name is None: + self._instrumentName = '' + else: + raise RuntimeError('Instrument name %s of type %s is not allowed.' % (str(instrument_name), + str(type(instrument_name)))) + + # Experiment number, data storage + # No Use/Confusing: self._expNumber = 0 + + self._dataDir = None + self._workDir = '/tmp' + + self._myServerURL = '' + + # Some set up + self._expNumber = None + + # Container for MDEventWorkspace for each Pt. + self._myPtMDDict = dict() + # Container for loaded workspaces + self._mySpiceTableDict = {} + # Container for loaded raw pt workspace + self._myRawDataWSDict = dict() + # Container for PeakWorkspaces for calculating UB matrix + self._myUBPeakWSDict = dict() + # Container for UB matrix + self._myUBMatrixDict = dict() + + # Peak Info + self._myPeakInfoDict = dict() + # Last UB matrix calculated + self._myLastPeakUB = None + # Flag for data storage + self._cacheDataOnly = False + + # A dictionary to manage all loaded and processed MDEventWorkspaces + # self._expDataDict = {} + + return + + def add_peak_info(self, exp_number, scan_number, pt_number): + """ Add a peak info for calculating UB matrix + :param exp_number: + :param scan_number: + :param pt_number: + :return: (boolean, PeakInfo/string) + """ + has_peak_ws, peak_ws = self.get_ub_peak_ws(exp_number, scan_number, pt_number) + if has_peak_ws is False: + err_msg = 'No peak workspace found for Exp %s Scan %s Pt %s' % ( + exp_number, scan_number, pt_number) + print '\n[DB] Fail to add peak info due to %s\n' % err_msg + return False, err_msg + + if peak_ws.rowCount() > 1: + err_msg = 'There are more than 1 peak in PeaksWorkspace.' + print '\n[DB] Fail to add peak info due to %s\n' % err_msg + return False, err_msg + + peak_info = PeakInfo(self) + peak_info.set_from_run_info(exp_number, scan_number, pt_number) + + # Add to data management + self._myPeakInfoDict[(exp_number, scan_number, pt_number)] = peak_info + + return True, peak_info + + def calculate_ub_matrix(self, peak_info_list, a, b, c, alpha, beta, gamma): + """ + Calculate UB matrix + + Set Miller index from raw data in Workspace2D. + :param peakws: + :param a: + :param b: + :param c: + :param alpha: + :param beta: + :param gamma: + :return: + """ + # Check + assert isinstance(peak_info_list, list) + for peak_info in peak_info_list: + if isinstance(peak_info, PeakInfo) is False: + raise NotImplementedError('Input PeakList is of type %s.' % str(type(peak_info_list[0]))) + assert isinstance(peak_info, PeakInfo) + + if len(peak_info_list) < 2: + return False, 'Too few peaks are input to calculate UB matrix. Must be >= 2.' + + # Construct a new peak workspace by combining all single peak + ub_peak_ws_name = 'Temp_UB_Peak' + ub_peak_ws = api.CloneWorkspace(InputWorkspace=peak_info_list[0].get_peak_workspace(), + OutputWorkspace=ub_peak_ws_name) + + for i_peak_info in xrange(1, len(peak_info_list)): + # Set HKL as optional + peak_ws = peak_info_list[i_peak_info].get_peak_workspace() + + # Combine peak workspace + ub_peak_ws = api.CombinePeaksWorkspaces(LHSWorkspace=ub_peak_ws, + RHSWorkspace=peak_ws, + CombineMatchingPeaks=False, + OutputWorkspace=ub_peak_ws_name) + # END-FOR(i_peak_info) + + # Calculate UB matrix + try: + api.CalculateUMatrix(PeaksWorkspace=ub_peak_ws_name, + a=a, b=b, c=c, alpha=alpha, beta=beta, gamma=gamma) + except ValueError as val_err: + return False, str(val_err) + + ub_matrix = ub_peak_ws.sample().getOrientedLattice().getUB() + + self._myLastPeakUB = ub_peak_ws + + return True, ub_matrix + + def does_raw_loaded(self, exp_no, scan_no, pt_no): + """ + Check whether the raw Workspace2D for a Pt. exists + :param exp_no: + :param scan_no: + :param pt_no: + :return: + """ + return (exp_no, scan_no, pt_no) in self._myRawDataWSDict + + def does_spice_loaded(self, exp_no, scan_no): + """ Check whether a SPICE file has been loaded + :param exp_no: + :param scan_no: + :return: + """ + return (exp_no, scan_no) in self._mySpiceTableDict + + def download_spice_file(self, exp_number, scan_number, over_write): + """ + Download a scan/pt data from internet + :param exp_number: experiment number + :param scan_number: + :return: + """ + # Check + if exp_number is None: + exp_number = self._expNumber + assert isinstance(exp_number, int) + assert isinstance(scan_number, int) + + # Generate the URL for SPICE data file + file_url = '%sexp%d/Datafiles/HB3A_exp%04d_scan%04d.dat' % (self._myServerURL, exp_number, + exp_number, scan_number) + file_name = '%s_exp%04d_scan%04d.dat' % (self._instrumentName, exp_number, scan_number) + file_name = os.path.join(self._dataDir, file_name) + if os.path.exists(file_name) is True and over_write is False: + return True, file_name + + # Download + try: + api.DownloadFile(Address=file_url, Filename=file_name) + except RuntimeError as run_err: + return False, str(run_err) + + # Check file exist? + if os.path.exists(file_name) is False: + return False, "Unable to locate downloaded file %s." % file_name + + return True, file_name + + def download_spice_xml_file(self, scan_no, pt_no, exp_no=None, overwrite=False): + """ Download a SPICE XML file for one measurement in a scan + :param scan_no: + :param pt_no: + :param exp_no: + :param overwrite: + :return: tuple (boolean, local file name/error message) + """ + # Experiment number + if exp_no is None: + exp_no = self._expNumber + + # Form the target file name and path + xml_file_name = '%s_exp%d_scan%04d_%04d.xml' % (self._instrumentName, exp_no, scan_no, pt_no) + local_xml_file_name = os.path.join(self._dataDir, xml_file_name) + if os.path.exists(local_xml_file_name) is True and overwrite is False: + return True, local_xml_file_name + + # Generate the URL for XML file + xml_file_url = '%sexp%d/Datafiles/%s' % (self._myServerURL, exp_no, xml_file_name) + + # Download + try: + api.DownloadFile(Address=xml_file_url, + Filename=local_xml_file_name) + except RuntimeError as run_err: + return False, 'Unable to download Detector XML file %s dur to %s.' % (xml_file_name, str(run_err)) + + # Check file exist? + if os.path.exists(local_xml_file_name) is False: + return False, "Unable to locate downloaded file %s."%(local_xml_file_name) + + return True, local_xml_file_name + + def download_data_set(self, scan_list, overwrite=False): + """ + Download data set including (1) spice file for a scan and (2) XML files for measurements + :param scan_list: + :return: + """ + # Check + if self._expNumber is None: + raise RuntimeError('Experiment number is not set up for controller.') + + error_message = '' + + for scan_no in scan_list: + # Download single spice file for a run + status, ret_obj = self.download_spice_file(exp_number=self._expNumber, + scan_number=scan_no, + over_write=overwrite) + + # Reject if SPICE file cannot download + if status is False: + error_message += '%s\n' % ret_obj + continue + + # Load SPICE file to Mantid + spice_file_name = ret_obj + status, ret_obj = self.load_spice_scan_file(self._expNumber, scan_no, spice_file_name) + if status is False: + error_message = ret_obj + return False, error_message + else: + spice_table = self._mySpiceTableDict[(self._expNumber, scan_no)] + assert spice_table + pt_no_list = self._get_pt_list_from_spice_table(spice_table) + + # Download all single-measurement file + for pt_no in pt_no_list: + status, ret_obj = self.download_spice_xml_file(scan_no, pt_no, overwrite=overwrite) + if status is False: + error_message += '%s\n' % ret_obj + # END-FOR + # END-FOR (scan_no) + + return True, error_message + + def existDataFile(self, scanno, ptno): + """ + Check whether data file for a scan or pt number exists + :param scanno: + :param ptno: + :return: + """ + # Check spice file + spice_file_name = '%s_exp%04d_scan%04d.dat'%(self._instrumentName, + self._expNumber, scanno) + spice_file_name = os.path.join(self._dataDir, spice_file_name) + if os.path.exists(spice_file_name) is False: + return False, 'Spice data file %s cannot be found.'% spice_file_name + + # Check xml file + xmlfilename = '%s_exp%d_scan%04d_%04d.xml'%(self._instrumentName, self._expNumber, + scanno, ptno) + xmlfilename = os.path.join(self._dataDir, xmlfilename) + if os.path.exists(xmlfilename) is False: + return (False, "Pt. XML file %s cannot be found."%(xmlfilename)) + + return True, "" + + def find_peak(self, exp_number, scan_number, pt_number): + """ Find 1 peak in sample Q space for UB matrix + :param scan_number: + :param pt_number: + :return:tuple as (boolean, object) such as (false, error message) and (true, PeakInfo object) + + This part will be redo as 11847_Load_HB3A_Experiment + """ + # Check + assert isinstance(exp_number, int) + assert isinstance(scan_number, int) + assert isinstance(pt_number, int) + + # Download or make sure data are there + status_sp, err_msg_sp = self.download_spice_file(exp_number, scan_number, over_write=False) + status_det, err_msg_det = self.download_spice_xml_file(scan_number, pt_number, exp_number, + overwrite=False) + if status_sp is False or status_det is False: + return False, 'Unable to access data (1) %s (2) %s' % (err_msg_sp, err_msg_det) + + # Collect reduction information: example + exp_info_ws_name = get_pt_info_ws_name(exp_number, scan_number) + virtual_instrument_info_table_name = get_virtual_instrument_table_name(exp_number, scan_number, pt_number) + api.CollectHB3AExperimentInfo( + ExperimentNumber=exp_number, + GenerateVirtualInstrument=False, + ScanList=[scan_number], + PtLists=[-1, pt_number], + DataDirectory=self._dataDir, + GetFileFromServer=False, + Detector2ThetaTolerance=0.01, + OutputWorkspace=exp_info_ws_name, + DetectorTableWorkspace=virtual_instrument_info_table_name) + + # Load XML file to MD + pt_md_ws_name = get_single_pt_md_name(exp_number, scan_number, pt_number) + api.ConvertCWSDExpToMomentum(InputWorkspace=exp_info_ws_name, + CreateVirtualInstrument=False, + OutputWorkspace=pt_md_ws_name, + Directory=self._dataDir) + + # Find peak in Q-space + pt_peak_ws_name = get_single_pt_peak_ws_name(exp_number, scan_number, pt_number) + api.FindPeaksMD(InputWorkspace=pt_md_ws_name, MaxPeaks=10, + DensityThresholdFactor=0.01, OutputWorkspace=pt_peak_ws_name) + peak_ws = AnalysisDataService.retrieve(pt_peak_ws_name) + pt_md_ws = AnalysisDataService.retrieve(pt_md_ws_name) + self._myPtMDDict[(exp_number, scan_number, pt_number)] = pt_md_ws + + num_peaks = peak_ws.getNumberPeaks() + if num_peaks != 1: + err_msg = 'Find %d peak from scan %d pt %d. ' \ + 'For UB matrix calculation, 1 and only 1 peak is allowed' % (num_peaks, scan_number, pt_number) + return False, err_msg + else: + self._add_ub_peak_ws(exp_number, scan_number, pt_number, peak_ws) + status, ret_obj = self.add_peak_info(exp_number, scan_number, pt_number) + if status is True: + pass + # peak_info = ret_obj + # peak_info.set_md_ws(pt_md_ws) + else: + err_msg = ret_obj + return False, err_msg + + return True, '' + + def get_experiment(self): + """ + Get experiment number + :return: + """ + return self._expNumber + + def get_pt_numbers(self, exp_no, scan_no, load_spice_scan=False): + """ Get Pt numbers (as a list) for a scan in an experiment + :param exp_no: + :param scan_no: + :param load_spice_scan: + :return: (Boolean, Object) as (status, pt number list/error message) + """ + # Check + if exp_no is None: + exp_no = self._expNumber + assert isinstance(exp_no, int) + assert isinstance(scan_no, int) + + # Get workspace + table_ws = self._get_spice_workspace(exp_no, scan_no) + if table_ws is None: + if load_spice_scan is False: + return False, 'Spice file for Exp %d Scan %d is not loaded.' % (exp_no, scan_no) + else: + status, error_message = self.load_spice_scan_file(exp_no, scan_no) + if status is True: + table_ws = self._get_spice_workspace(exp_no, scan_no) + if table_ws is None: + raise NotImplementedError('Logic error! Cannot happen!') + else: + return False, 'Unable to load Spice file for Exp %d Scan %d due to %s.' % ( + exp_no, scan_no, error_message) + + col_name_list = table_ws.getColumnNames() + i_pt = col_name_list.index('Pt.') + if i_pt < 0 or i_pt >= len(col_name_list): + return False, 'No column with name Pt. can be found in SPICE table.' + + pt_number_list = [] + num_rows = table_ws.rowCount() + for i in xrange(num_rows): + pt_number = table_ws.cell(i, i_pt) + pt_number_list.append(pt_number) + + return True, pt_number_list + + def get_raw_detector_counts(self, exp_no, scan_no, pt_no): + """ + Get counts on raw detector + :param scan_no: + :param pt_no: + :return: boolean, 2D numpy data + """ + # Get workspace (in memory or loading) + raw_ws = self.get_raw_data_workspace(exp_no, scan_no, pt_no) + if raw_ws is None: + return False, 'Raw data for Exp %d Scan %d Pt %d is not loaded.' % (exp_no, scan_no, pt_no) + + # Convert to numpy array + array2d = numpy.ndarray(shape=(DET_X_SIZE, DET_Y_SIZE), dtype='float') + for i in xrange(DET_X_SIZE): + for j in xrange(DET_Y_SIZE): + array2d[i][j] = raw_ws.readY(i * DET_X_SIZE + j)[0] + + return array2d + + def get_sample_log_value(self, exp_number, scan_number, pt_number, log_name): + """ + Get sample log's value + :param exp_number: + :param scan_number:167 + :param pt_number: + :param log_name: + :return: float + """ + assert isinstance(exp_number, int) + assert isinstance(scan_number, int) + assert isinstance(pt_number, int) + assert isinstance(log_name, str) + try: + md_ws = self._myPtMDDict[(exp_number, scan_number, pt_number)] + except KeyError as ke: + return 'Unable to find log value %s due to %s.' % (log_name, str(ke)) + + return md_ws.getExperimentInfo(0).run().getProperty(log_name).value + + def get_peak_info(self, exp_number, scan_number, pt_number): + """ + get peak information instance + :param exp_number: experiment number. if it is None, then use the current exp number + :param scan_number: + :param pt_number: + :return: + """ + # Check for type + if exp_number is None: + exp_number = self._expNumber + + assert isinstance(exp_number, int) + assert isinstance(scan_number, int) + assert isinstance(pt_number, int) + + # Check for existence + if (exp_number, scan_number, pt_number) not in self._myUBPeakWSDict: # self._myPeakInfoDict: + err_msg = 'Unable to find PeakInfo for Exp %d Scan %d Pt %d. ' \ + 'Existing keys are %s' % (exp_number, scan_number, pt_number, + str(self._myUBPeakWSDict.keys())) + return False, err_msg + + print '[DB] PeakInfoDictionary Keys = %s' % str(self._myPeakInfoDict.keys()) + + return True, self._myPeakInfoDict[(exp_number, scan_number, pt_number)] + + def get_ub_peak_ws(self, exp_number, scan_number, pt_number): + """ + Get peak workspace for the peak picked to calculate UB matrix + :param exp_number: + :param scan_number: + :param pt_number: + :return: + """ + assert isinstance(exp_number, int) + assert isinstance(scan_number, int) + assert isinstance(pt_number, int) + + if (exp_number, scan_number, pt_number) not in self._myUBPeakWSDict: + return False, 'Exp %d Scan %d Pt %d has no peak workspace.' % (exp_number, + scan_number, + pt_number) + + return True, self._myUBPeakWSDict[(exp_number, scan_number, pt_number)] + + def index_peak(self, ub_matrix, scan_number, pt_number): + """ Index peaks in a Pt. + :param ub_matrix: numpy.ndarray (3, 3) + :param scan_number: + :param pt_number: + :return: boolean, object (list of HKL or error message) + """ + # Check + assert isinstance(ub_matrix, numpy.ndarray) + assert ub_matrix.shape == (3, 3) + assert isinstance(scan_number, int) + assert isinstance(pt_number, int) + + # Find out the peak workspace + exp_num = self._expNumber + if (exp_num, scan_number, pt_number) in self._myUBPeakWSDict is False: + err_msg = 'No PeakWorkspace is found for exp %d scan %d pt %d' % ( + exp_num, scan_number, pt_number) + return False, err_msg + + peak_ws = self._myUBPeakWSDict[(exp_num, scan_number, pt_number)] + ub_1d = ub_matrix.reshape(9,) + print '[DB] UB matrix = ', ub_1d + + # Set UB + api.SetUB(Workspace=peak_ws, UB=ub_1d) + + # Note: IndexPeaks and CalcualtePeaksHKL do the same job + # while IndexPeaks has more control on the output + num_peak_index, error = api.IndexPeaks(PeaksWorkspace=peak_ws, + Tolerance=0.4, + RoundHKLs=False) + + if num_peak_index == 0: + return False, 'No peak can be indexed.' + elif num_peak_index > 1: + raise RuntimeError('Case for PeaksWorkspace containing more than 1 peak is not ' + 'considered. Contact developer for this issue.') + else: + hkl_v3d = peak_ws.getPeak(0).getHKL() + hkl = [hkl_v3d.X(), hkl_v3d.Y(), hkl_v3d.Z()] + + return True, (hkl, error) + + def load_spice_scan_file(self, exp_no, scan_no, spice_file_name=None): + """ + Load a SPICE scan file to table workspace and run information matrix workspace. + :param scan_no: + :param spice_file_name: + :return: status (boolean), error message (string) + """ + # Default for exp_no + if exp_no is None: + exp_no = self._expNumber + + # Check whether the workspace has been loaded + assert isinstance(exp_no, int) + assert isinstance(scan_no, int) + out_ws_name = get_spice_table_name(exp_no, scan_no) + if (exp_no, scan_no) in self._mySpiceTableDict: + return True, out_ws_name + + # Form standard name for a SPICE file if name is not given + if spice_file_name is None: + spice_file_name = os.path.join(self._dataDir, get_spice_file_name(exp_no, scan_no)) + + # Download SPICE file if necessary + if os.path.exists(spice_file_name) is False: + self.download_spice_file(exp_no, scan_no, over_write=True) + + try: + spice_table_ws, info_matrix_ws = api.LoadSpiceAscii(Filename=spice_file_name, + OutputWorkspace=out_ws_name, + RunInfoWorkspace='TempInfo') + api.DeleteWorkspace(Workspace=info_matrix_ws) + except RuntimeError as run_err: + return False, 'Unable to load SPICE data %s due to %s' % (spice_file_name, str(run_err)) + + # Store + self._add_spice_workspace(exp_no, scan_no, spice_table_ws) + + return True, out_ws_name + + def load_spice_xml_file(self, exp_no, scan_no, pt_no, xml_file_name=None): + """ + Load SPICE's XML file to + :param scan_no: + :param pt_no: + :return: + """ + # Form XMIL file as ~/../HB3A_exp355_scan%04d_%04d.xml'%(scan_no, pt) + if xml_file_name is None: + xml_file_name = os.path.join(self._dataDir, + 'HB3A_exp%d_scan%04d_%04d.xml' % (exp_no, scan_no, pt_no)) + + # Get spice table + spice_table_ws = self._get_spice_workspace(exp_no, scan_no) + assert isinstance(spice_table_ws, mantid.dataobjects.TableWorkspace) + spice_table_name = spice_table_ws.name() + + # Load SPICE Pt. file + # spice_table_name = 'Table_Exp%d_Scan%04d' % (exp_no, scan_no) + pt_ws_name = get_raw_data_workspace_name(exp_no, scan_no, pt_no) + try: + ret_obj = api.LoadSpiceXML2DDet(Filename=xml_file_name, + OutputWorkspace=pt_ws_name, + DetectorGeometry='256,256', + SpiceTableWorkspace=spice_table_name, + PtNumber=pt_no) + except RuntimeError as run_err: + return False, str(run_err) + + pt_ws = ret_obj + + # Add data storage + self._add_raw_workspace(exp_no, scan_no, pt_no, pt_ws) + + return True, pt_ws_name + + def group_workspaces(self, exp_number, group_name): + """ + + :return: + """ + # Find out the input workspace name + ws_names_str = '' + for key in self._myRawDataWSDict.keys(): + if key[0] == exp_number: + ws_names_str += '%s,' % self._myRawDataWSDict[key].name() + + for key in self._mySpiceTableDict.keys(): + if key[0] == exp_number: + ws_names_str += '%s,' % self._mySpiceTableDict[key].name() + + # Check + if len(ws_names_str) == 0: + return False, 'No workspace is found for experiment %d.' % exp_number + + # Remove last ',' + ws_names_str = ws_names_str[:-1] + + # Group + api.GroupWorkspaces(InputWorkspaces=ws_names_str, + OutputWorkspace=group_name) + + return + + def merge_pts_in_scan(self, exp_no, scan_no, target_ws_name, target_frame): + """ + Merge Pts in Scan + All the workspaces generated as internal results will be grouped + :param exp_no: + :param scan_no: + :param target_ws_name: + :param target_frame: + :return: (merged workspace name, workspace group name) + """ + # Check + if exp_no is None: + exp_no = self._expNumber + assert isinstance(exp_no, int) + assert isinstance(scan_no, int) + assert isinstance(target_frame, str) + assert isinstance(target_ws_name, str) + + ub_matrix_1d = None + + # Target frame + if target_frame.lower().startswith('hkl'): + target_frame = 'hkl' + ub_matrix_1d = self._myUBMatrixDict[self._expNumber].reshape(9,) + elif target_frame.lower().startswith('q-sample'): + target_frame = 'qsample' + + else: + raise RuntimeError('Target frame %s is not supported.' % target_frame) + + # Process data and save + status, pt_num_list = self.get_pt_numbers(exp_no, scan_no, True) + if status is False: + err_msg = pt_num_list + return False, err_msg + else: + print '[DB] Number of Pts for Scan %d is %d' % (scan_no, len(pt_num_list)) + print '[DB] Data directory: %s' % self._dataDir + max_pts = 0 + ws_names_str = '' + ws_names_to_group = '' + + for pt in pt_num_list: + try: + self.download_spice_xml_file(scan_no, pt, overwrite=False) + api.CollectHB3AExperimentInfo(ExperimentNumber=exp_no, ScanList='%d' % scan_no, PtLists='-1,%d' % pt, + DataDirectory=self._dataDir, + GenerateVirtualInstrument=False, + OutputWorkspace='ScanPtInfo_Exp%d_Scan%d' % (exp_no, scan_no), + DetectorTableWorkspace='MockDetTable') + + out_q_name = 'HB3A_Exp%d_Scan%d_Pt%d_MD' % (exp_no, scan_no, pt) + api.ConvertCWSDExpToMomentum(InputWorkspace='ScanPtInfo_Exp406_Scan%d' % scan_no, + CreateVirtualInstrument=False, + OutputWorkspace=out_q_name, + Directory=self._dataDir) + + ws_names_to_group += out_q_name + ',' + if target_frame == 'hkl': + out_hkl_name = 'HKL_Scan%d_Pt%d' % (scan_no, pt) + api.ConvertCWSDMDtoHKL(InputWorkspace=out_q_name, + UBMatrix=ub_matrix_1d, + OutputWorkspace=out_hkl_name) + ws_names_str += out_hkl_name + ',' + ws_names_to_group += out_hkl_name + ',' + else: + ws_names_str += out_q_name + ',' + + except RuntimeError as e: + print '[Error] Reducing scan %d pt %d due to %s' % (scan_no, pt, str(e)) + continue + + else: + max_pts = pt + # END-FOR + + # Merge + if target_frame == 'qsample': + out_ws_name = target_ws_name + '_QSample' + elif target_frame == 'hkl': + out_ws_name = target_ws_name + '_HKL' + else: + raise RuntimeError('Impossible to have target frame %s' % target_frame) + + ws_names_str = ws_names_str[:-1] + api.MergeMD(InputWorkspaces=ws_names_str, OutputWorkspace=out_ws_name, SplitInto=max_pts) + + # Group workspaces + group_name = 'Group_Exp406_Scan%d' % scan_no + api.GroupWorkspaces(InputWorkspaces=ws_names_to_group, OutputWorkspace=group_name) + spice_table_name = get_spice_table_name(exp_no, scan_no) + api.GroupWorkspaces(InputWorkspaces='%s,%s' % (group_name, spice_table_name), OutputWorkspace=group_name) + + ret_tup = out_ws_name, group_name + + return ret_tup + + def set_server_url(self, server_url): + """ + Set URL for server to download the data + :param server_url: + :return: + """ + # Server URL must end with '/' + self._myServerURL = str(server_url) + if self._myServerURL.endswith('/') is False: + self._myServerURL += '/' + + # Test URL valid or not + is_url_good = False + error_message = None + try: + result = urllib2.urlopen(self._myServerURL) + except urllib2.HTTPError, err: + error_message = str(err.code) + except urllib2.URLError, err: + error_message = str(err.args) + else: + is_url_good = True + result.close() + + if error_message is None: + error_message = '' + else: + error_message = 'Unable to open data server URL: %s due to %s.' % (server_url, error_message) + + return is_url_good, error_message + + def setWebAccessMode(self, mode): + """ + Set data access mode form server + :param mode: + :return: + """ + if isinstance(mode, str) is False: + raise RuntimeError('Input mode is not string') + + if mode == 'cache': + self._cacheDataOnly = True + elif mode == 'download': + self._cacheDataOnly = False + + return + + def set_local_data_dir(self, local_dir): + """ + Set local data storage + :param local_dir: + :return: + """ + # Get absolute path + if os.path.isabs(local_dir) is False: + # Input is relative path to current working directory + cwd = os.getcwd() + local_dir = os.path.join(cwd, local_dir) + + # Create cache directory if necessary + if os.path.exists(local_dir) is False: + try: + os.mkdir(local_dir) + except OSError as os_err: + return False, str(os_err) + + # Check whether the target is writable + if os.access(local_dir, os.W_OK) is False: + return False, 'Specified local data directory %s is not writable.' % local_dir + + # Successful + self._dataDir = local_dir + + return True, '' + + def set_ub_matrix(self, exp_number, ub_matrix): + """ + Set up UB matrix to _UBMatrix dictionary + :param exp_number: + :param ub_matrix: + :return: + """ + # Check + if exp_number is None: + exp_number = self._expNumber + + assert isinstance(exp_number, int) + assert isinstance(ub_matrix, numpy.ndarray) + assert ub_matrix.shape == (3, 3) + + # Set up + self._myUBMatrixDict[exp_number] = ub_matrix + + def set_working_directory(self, work_dir): + """ + Set up the directory for working result + :return: (boolean, string) + """ + if os.path.exists(work_dir) is False: + try: + os.mkdir(work_dir) + except OSError as os_err: + return False, 'Unable to create working directory %s due to %s.' % (work_dir, str(os_err)) + elif os.access(work_dir, os.W_OK) is False: + return False, 'User specified working directory %s is not writable.' % work_dir + + self._workDir = work_dir + + return True, '' + + def set_instrument_name(self, instrument_name): + """ + Set instrument name + :param instrument_name: + :return: + """ + # Check + if isinstance(instrument_name, str) is False: + return False, 'Input instrument name is not a string but of type %s.' % str(type(instrument_name)) + if len(instrument_name) == 0: + return False, 'Input instrument name is an empty string.' + + self._instrumentName = instrument_name + + return True, '' + + def set_exp_number(self, exp_number): + """ Add experiment number + :param exp_number: + :return: + """ + assert isinstance(exp_number, int) + self._expNumber = exp_number + + return True + + def set_hkl_to_peak(self, exp_number, scan_number, pt_number): + """ + Get HKL as _h, _k, _l from MDEventWorkspace. It is for HB3A only + :return: + """ + status, peak_info = self.get_peak_info(exp_number, scan_number, pt_number) + if status is False: + err_msg = peak_info + return False, err_msg + + md_ws = self._myPtMDDict[(exp_number, scan_number, pt_number)] + assert md_ws.getNumExperimentInfo() == 1 + exp_info = md_ws.getExperimentInfo(0) + + try: + m_h = float(exp_info.run().getProperty('_h').value) + m_k = float(exp_info.run().getProperty('_k').value) + m_l = float(exp_info.run().getProperty('_l').value) + except RuntimeError as error: + return False, 'Unable to retrieve HKL due to %s.' % (str(error)) + + peak_ws = peak_info.get_peak_workspace() + peak = peak_ws.getPeak(0) + peak.setHKL(m_h, m_k, m_l) + + return True, (m_h, m_k, m_l) + + def _add_raw_workspace(self, exp_no, scan_no, pt_no, raw_ws): + """ Add raw Pt.'s workspace + :param exp_no: + :param scan_no: + :param pt_no: + :param raw_ws: workspace or name of the workspace + :return: None + """ + # Check + assert isinstance(exp_no, int) + assert isinstance(scan_no, int) + assert isinstance(pt_no, int) + + if isinstance(raw_ws, str): + # Given by name + matrix_ws = AnalysisDataService.retrieve(raw_ws) + else: + matrix_ws = raw_ws + assert isinstance(matrix_ws, mantid.dataobjects.Workspace2D) + + self._myRawDataWSDict[(exp_no, scan_no, pt_no)] = matrix_ws + + return + + def _add_md_workspace(self, exp_no, scan_no, pt_no, md_ws): + """ + Add MD workspace to storage + :param exp_no: + :param scan_no: + :param pt_no: + :param md_ws: + :return: + """ + # Check input + print '[DB] Type of md_ws is %s.' % str(type(md_ws)) + assert isinstance(md_ws, mantid.dataobjects.MDEventWorkspace) + + assert isinstance(exp_no, int) + assert isinstance(scan_no, int) + assert isinstance(pt_no) + + self._myPtMDDict[(exp_no, scan_no, pt_no)] = md_ws + + return + + def _add_ub_peak_ws(self, exp_number, scan_number, pt_number, peak_ws): + """ + Add peak workspace for UB matrix + :param exp_number: + :param scan_number: + :param pt_number: + :param peak_ws: + :return: + """ + # Check + assert isinstance(peak_ws, mantid.dataobjects.PeaksWorkspace) + + assert isinstance(exp_number, int) + assert isinstance(scan_number, int) + assert isinstance(pt_number, int) + + # Add + self._myUBPeakWSDict[(exp_number, scan_number, pt_number)] = peak_ws + + return + + def _add_spice_workspace(self, exp_no, scan_no, spice_table_ws): + """ + """ + assert isinstance(exp_no, int) + assert isinstance(scan_no, int) + assert isinstance(spice_table_ws, mantid.dataobjects.TableWorkspace) + self._mySpiceTableDict[(exp_no, scan_no)] = spice_table_ws + + return + + def _get_spice_workspace(self, exp_no, scan_no): + """ Get SPICE's scan table workspace + :param exp_no: + :param scan_no: + :return: Table workspace or None + """ + try: + ws = self._mySpiceTableDict[(exp_no, scan_no)] + except KeyError: + print '[DB] Keys to SPICE TABLE: %s' % str(self._mySpiceTableDict.keys()) + return None + + return ws + + def get_raw_data_workspace(self, exp_no, scan_no, pt_no): + """ Get raw workspace + """ + try: + ws = self._myRawDataWSDict[(exp_no, scan_no, pt_no)] + assert isinstance(ws, mantid.dataobjects.Workspace2D) + except KeyError: + return None + + return ws + + def _get_pt_list_from_spice_table(self, spice_table_ws): + """ + Get list of Pt. from a SPICE table workspace + :param spice_table_ws: SPICE table workspace + :return: list of Pt. + """ + numrows = spice_table_ws.rowCount() + ptlist = [] + for irow in xrange(numrows): + ptno = int(spice_table_ws.cell(irow, 0)) + ptlist.append(ptno) + + return ptlist + + +def get_spice_file_name(exp_number, scan_number): + """ + Get standard HB3A SPICE file name from experiment number and scan number + :param exp_number: + :param scan_num: + :return: + """ + file_name = 'HB3A_exp%04d_scan%04d.dat' % (exp_number, scan_number) + + return file_name + + +def get_spice_table_name(exp_number, scan_number): + """ Form the name of the table workspace for SPICE + :param exp_number: + :param scan_number: + :return: + """ + table_name = 'HB3A_%03d_%04d_SpiceTable' % (exp_number, scan_number) + + return table_name + + +def get_raw_data_workspace_name(exp_number, scan_number, pt_number): + """ Form the name of the matrix workspace to which raw pt. XML file is loaded + :param exp_number: + :param scan_number: + :param pt_number: + :return: + """ + ws_name = 'HB3A_exp%d_scan%04d_%04d' % (exp_number, scan_number, pt_number) + + return ws_name + + +def get_pt_info_ws_name(exp_number, scan_number): + """ + Information table workspace'name from CollectHB3AInfo + :param exp_number: + :param scan_number: + :param pt_number: + :return: + """ + ws_name = 'ScanPtInfo_Exp%d_Scan%d' % (exp_number, scan_number) + + return ws_name + + +def get_single_pt_peak_ws_name(exp_number, scan_number, pt_number): + """ + Form the name of the peak workspace + :param exp_number: + :param scan_number: + :param pt_number: + :return: + """ + ws_name = 'Peak_Exp%d_Scan%d_Pt%d' % (exp_number, scan_number, pt_number) + + return ws_name + + +def get_single_pt_md_name(exp_number, scan_number, pt_number): + """ Form the name of the MDEvnetWorkspace for a single Pt. measurement + :param exp_number: + :param scan_number: + :param pt_number: + :return: + """ + ws_name = 'HB3A_Exp%d_Scan%d_Pt%d_MD' % (exp_number, scan_number, pt_number) + + return ws_name + + +def get_virtual_instrument_table_name(exp_number, scan_number, pt_number): + """ + Generate the name of the table workspace containing the virtual instrument information + :param exp_number: + :param scan_number: + :param pt_number: + :return: + """ + ws_name = 'VirtualInstrument_Exp%d_Scan%d_Pt%d_Table' % (exp_number, scan_number, pt_number) + + return ws_name diff --git a/scripts/HFIR_4Circle_Reduction/reduce4circleGUI.py b/scripts/HFIR_4Circle_Reduction/reduce4circleGUI.py new file mode 100644 index 0000000000000000000000000000000000000000..7009c1e8b8ec763ec515120f212242332cf5e2b9 --- /dev/null +++ b/scripts/HFIR_4Circle_Reduction/reduce4circleGUI.py @@ -0,0 +1,1092 @@ +#pylint: disable=invalid-name,relative-import,W0611,R0921,R0902,R0904,R0921,C0302 +################################################################################ +# +# MainWindow application for reducing HFIR 4-circle +# +################################################################################ +import os +import math +import csv +import time + +from PyQt4 import QtCore, QtGui + +import reduce4circleControl as r4c +import guiutility as gutil +import fourcircle_utility as fcutil + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + def _fromUtf8(s): + return s + +# import line for the UI python class +from ui_MainWindow import Ui_MainWindow + + +class MainWindow(QtGui.QMainWindow): + """ Class of Main Window (top) + """ + 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) + + # Mantid configuration + self._instrument = str(self.ui.comboBox_instrument.currentText()) + # config = ConfigService.Instance() + # self._instrument = config["default.instrument"] + + # Event handling definitions + # Top + self.connect(self.ui.pushButton_setExp, QtCore.SIGNAL('clicked()'), + self.do_set_experiment) + + # Tab 'Data Access' + self.connect(self.ui.pushButton_applySetup, QtCore.SIGNAL('clicked()'), + self.do_apply_setup) + self.connect(self.ui.pushButton_browseLocalDataDir, QtCore.SIGNAL('clicked()'), + self.do_browse_local_spice_data) + self.connect(self.ui.pushButton_testURLs, QtCore.SIGNAL('clicked()'), + self.do_test_url) + self.connect(self.ui.pushButton_ListScans, QtCore.SIGNAL('clicked()'), + self.do_list_scans) + self.connect(self.ui.pushButton_downloadExpData, QtCore.SIGNAL('clicked()'), + self.do_download_spice_data) + self.connect(self.ui.comboBox_mode, QtCore.SIGNAL('currentIndexChanged(int)'), + self.change_data_access_mode) + + # Tab 'View Raw Data' + self.connect(self.ui.pushButton_setScanInfo, QtCore.SIGNAL('clicked()'), + self.do_load_scan_info) + self.connect(self.ui.pushButton_plotRawPt, QtCore.SIGNAL('clicked()'), + self.do_plot_pt_raw) + self.connect(self.ui.pushButton_prevPtNumber, QtCore.SIGNAL('clicked()'), + self.do_plot_prev_pt_raw) + self.connect(self.ui.pushButton_nextPtNumber, QtCore.SIGNAL('clicked()'), + self.do_plot_next_pt_raw) + self.connect(self.ui.pushButton_showPtList, QtCore.SIGNAL('clicked()'), + self.show_scan_pt_list) + self.connect(self.ui.pushButton_usePt4UB, QtCore.SIGNAL('clicked()'), + self.do_add_peak_to_find) + + # Tab 'calculate ub matrix' + self.connect(self.ui.pushButton_findPeak, QtCore.SIGNAL('clicked()'), + self.do_find_peak) + self.connect(self.ui.pushButton_addPeakToCalUB, QtCore.SIGNAL('clicked()'), + self.do_add_ub_peak) + self.connect(self.ui.pushButton_calUB, QtCore.SIGNAL('clicked()'), + self.do_cal_ub_matrix) + self.connect(self.ui.pushButton_acceptUB, QtCore.SIGNAL('clicked()'), + self.doAcceptCalUB) + self.connect(self.ui.pushButton_indexUBPeaks, QtCore.SIGNAL('clicked()'), + self.do_index_ub_peaks) + self.connect(self.ui.pushButton_deleteUBPeak, QtCore.SIGNAL('clicked()'), + self.do_del_ub_peaks) + self.connect(self.ui.pushButton_clearUBPeakTable, QtCore.SIGNAL('clicked()'), + self.do_clear_ub_peaks) + self.connect(self.ui.pushButton_resetPeakHKLs, QtCore.SIGNAL('clicked()'), + self.do_reset_ub_peaks_hkl) + + # Tab 'Slice View' + self.connect(self.ui.pushButton_setUBSliceView, QtCore.SIGNAL('clicked()'), + self.do_set_ub_sv) + self.connect(self.ui.pushButton_process4SliceView, QtCore.SIGNAL('clicked()'), + self.do_merge_scans) + + # Tab 'Advanced' + self.connect(self.ui.pushButton_useDefaultDir, QtCore.SIGNAL('clicked()'), + self.do_setup_dir_default) + self.connect(self.ui.pushButton_browseLocalCache, QtCore.SIGNAL('clicked()'), + self.do_browse_local_cache_dir) + self.connect(self.ui.pushButton_browseWorkDir, QtCore.SIGNAL('clicked()'), + self.do_browse_working_dir) + self.connect(self.ui.comboBox_instrument, QtCore.SIGNAL('currentIndexChanged(int)'), + self.change_instrument_name) + + # Refine UB matrix + self.connect(self.ui.pushButton_addToRefine, QtCore.SIGNAL('clicked()'), + self.do_refine_ub) + self.connect(self.ui.pushButton_addAllRefineUB, QtCore.SIGNAL('clicked()'), + self.do_refine_ub) + self.connect(self.ui.pushButton_acceptRefinedUB, QtCore.SIGNAL('clicked()'), + self.do_refine_ub) + self.connect(self.ui.pushButton_resetRefinedUB, QtCore.SIGNAL('clicked()'), + self.do_refine_ub) + + # Tab 'Integrate Peaks' + self.connect(self.ui.pushButton_integratePeak, QtCore.SIGNAL('clicked()'), + self.do_integrate_peaks) + + # Menu + self.connect(self.ui.actionExit, QtCore.SIGNAL('triggered()'), + self.menu_quit) + + self.connect(self.ui.actionSave_Session, QtCore.SIGNAL('triggered()'), + self.save_current_session) + self.connect(self.ui.actionLoad_Session, QtCore.SIGNAL('triggered()'), + self.load_session) + + # Event handling for tab 'refine ub matrix' + self.connect(self.ui.pushButton_addToRefine, QtCore.SIGNAL('clicked()'), + self.doAddScanPtToRefineUB) + + # Validator ... (NEXT) + + # Declaration of class variable + # some configuration + self._homeSrcDir = os.getcwd() + self._homeDir = os.getcwd() + + # Control + self._myControl = r4c.CWSCDReductionControl(self._instrument) + self._allowDownload = True + self._dataAccessMode = 'Download' + + # Initial setup + self.ui.tabWidget.setCurrentIndex(0) + self.ui.tabWidget.setTabEnabled(4, False) + self.ui.tabWidget.setTabEnabled(5, False) + self._init_ub_table() + self.ui.radioButton_ubFromTab1.setChecked(True) + + # Tab 'Access' + self.ui.lineEdit_url.setText('http://neutron.ornl.gov/user_data/hb3a/') + self.ui.comboBox_mode.setCurrentIndex(0) + self.ui.lineEdit_localSpiceDir.setEnabled(True) + self.ui.pushButton_browseLocalDataDir.setEnabled(True) + + return + + def do_integrate_peaks(self): + """ + + :return: + """ + raise RuntimeError('ASAP') + + def do_refine_ub(self): + """ + + :return: + """ + raise RuntimeError('Next Release') + + def _init_ub_table(self): + """ DOC + :return: + """ + # UB-peak table + # NOTE: have to call this because pyqt set column and row to 0 after __init__ + # thus a 2-step initialization has to been adopted + self.ui.tableWidget_peaksCalUB.setup() + + self.ui.tableWidget_ubMatrix.setup() + self.ui.tableWidget_ubSiceView.setup() + self.ui.tableWidget_refinedUB.setup() + + self.ui.tableWidget_sliceViewProgress.setup() + + return + + def change_data_access_mode(self): + """ Change data access mode between downloading from server and local + Event handling methods + :return: + """ + new_mode = str(self.ui.comboBox_mode.currentText()) + self._dataAccessMode = new_mode + + if new_mode.startswith('Local') is True: + self.ui.lineEdit_localSpiceDir.setEnabled(True) + self.ui.pushButton_browseLocalDataDir.setEnabled(True) + self.ui.lineEdit_url.setEnabled(False) + self.ui.lineEdit_localSrcDir.setEnabled(False) + self.ui.pushButton_browseLocalCache.setEnabled(False) + self._allowDownload = False + else: + self.ui.lineEdit_localSpiceDir.setEnabled(False) + self.ui.pushButton_browseLocalDataDir.setEnabled(False) + self.ui.lineEdit_url.setEnabled(True) + self.ui.lineEdit_localSrcDir.setEnabled(True) + self.ui.pushButton_browseLocalCache.setEnabled(True) + self._allowDownload = True + + return + + def change_instrument_name(self): + """ Handing the event as the instrument name is changed + :return: + """ + new_instrument = str(self.ui.comboBox_instrument.currentText()) + self.pop_one_button_dialog('Change of instrument during data processing is dangerous.') + status, error_message = self._myControl.set_instrument_name(new_instrument) + if status is False: + self.pop_one_button_dialog(error_message) + + return + + def do_add_ub_peak(self): + """ Add current to ub peaks + :return: + """ + # Add peak + status, int_list = gutil.parse_integers_editors([self.ui.lineEdit_exp, + self.ui.lineEdit_scanNumber, + self.ui.lineEdit_ptNumber]) + if status is False: + self.pop_one_button_dialog(int_list) + exp_no, scan_no, pt_no = int_list + + # Get HKL from GUI + status, float_list = gutil.parse_float_editors([self.ui.lineEdit_H, + self.ui.lineEdit_K, + self.ui.lineEdit_L]) + if status is False: + err_msg = float_list + self.pop_one_button_dialog(err_msg) + return + h, k, l = float_list + + status, peak_info_obj = self._myControl.get_peak_info(exp_no, scan_no, pt_no) + if status is False: + error_message = peak_info_obj + self.pop_one_button_dialog(error_message) + return + assert isinstance(peak_info_obj, r4c.PeakInfo) + + if self.ui.checkBox_roundHKLInt.isChecked(): + h = math.copysign(1, h)*int(abs(h)+0.5) + k = math.copysign(1, k)*int(abs(k)+0.5) + l = math.copysign(1, l)*int(abs(l)+0.5) + peak_info_obj.set_user_hkl(h, k, l) + self.set_ub_peak_table(peak_info_obj) + + # Clear + self.ui.lineEdit_scanNumber.setText('') + self.ui.lineEdit_ptNumber.setText('') + + self.ui.lineEdit_sampleQx.setText('') + self.ui.lineEdit_sampleQy.setText('') + self.ui.lineEdit_sampleQz.setText('') + + self.ui.lineEdit_H.setText('') + self.ui.lineEdit_K.setText('') + self.ui.lineEdit_L.setText('') + + return + + def doAcceptCalUB(self): + """ Accept the calculated UB matrix + """ + raise RuntimeError('ASAP') + return + + def doAddScanPtToRefineUB(self): + """ Add scan/pt numbers to the list of data points for refining ub matrix + + And the added scan number and pt numbers will be reflected in the (left sidebar) + + """ + raise RuntimeError("ASAP") + + def do_add_peak_to_find(self): + """ + Add the scan/pt to the next + :return: + """ + scan_no = self.ui.lineEdit_run.text() + pt_no = self.ui.lineEdit_rawDataPtNo.text() + + self.ui.lineEdit_scanNumber.setText(scan_no) + self.ui.lineEdit_ptNumber.setText(pt_no) + + self.ui.tabWidget.setCurrentIndex(2) + + def do_browse_local_cache_dir(self): + """ Browse local cache directory + :return: + """ + local_cache_dir = str(QtGui.QFileDialog.getExistingDirectory(self, + 'Get Local Cache Directory', + self._homeSrcDir)) + + # Set local directory to control + status, error_message = self._myControl.set_local_data_dir(local_cache_dir) + if status is False: + self.pop_one_button_dialog(error_message) + return + + # Synchronize to local data/spice directory and local cache directory + if str(self.ui.lineEdit_localSpiceDir.text()) != '': + prev_dir = str(self.ui.lineEdit_localSrcDir.text()) + self.pop_one_button_dialog('Local data directory was set up as %s' % + prev_dir) + self.ui.lineEdit_localSrcDir.setText(local_cache_dir) + self.ui.lineEdit_localSpiceDir.setText(local_cache_dir) + + return + + def do_browse_local_spice_data(self): + """ Browse local source SPICE data directory + """ + src_spice_dir = str(QtGui.QFileDialog.getExistingDirectory(self, 'Get Directory', + self._homeSrcDir)) + # Set local data directory to controller + status, error_message = self._myControl.set_local_data_dir(src_spice_dir) + if status is False: + self.pop_one_button_dialog(error_message) + return + + self._homeSrcDir = src_spice_dir + self.ui.lineEdit_localSpiceDir.setText(src_spice_dir) + + return + + def do_browse_working_dir(self): + """ + Browse and set up working directory + :return: + """ + work_dir = str(QtGui.QFileDialog.getExistingDirectory(self, 'Get Working Directory', self._homeDir)) + status, error_message = self._myControl.set_working_directory(work_dir) + if status is False: + self.pop_one_button_dialog(error_message) + else: + self.ui.lineEdit_workDir.setText(work_dir) + + return + + def do_cal_ub_matrix(self): + """ Calculate UB matrix by 2 or 3 reflections + """ + # Get reflections + num_rows = self.ui.tableWidget_peaksCalUB.rowCount() + peak_info_list = list() + status, exp_number = gutil.parse_integers_editors(self.ui.lineEdit_exp) + for i_row in xrange(num_rows): + if self.ui.tableWidget_peaksCalUB.is_selected(i_row) is True: + scan_num, pt_num = self.ui.tableWidget_peaksCalUB.get_exp_info(i_row) + status, peak_info = self._myControl.get_peak_info(exp_number, scan_num, pt_num) + peak_info.set_peak_ws_hkl_from_user() + if status is False: + self.pop_one_button_dialog(peak_info) + return + assert isinstance(peak_info, r4c.PeakInfo) + peak_info_list.append(peak_info) + # END-FOR + + # Get lattice + status, ret_obj = self._get_lattice_parameters() + if status is True: + a, b, c, alpha, beta, gamma = ret_obj + else: + err_msg = ret_obj + self.pop_one_button_dialog(err_msg) + return + + # Calculate UB matrix + status, ub_matrix = self._myControl.calculate_ub_matrix(peak_info_list, a, b, c, + alpha, beta, gamma) + + # Deal with result + if status is True: + self._show_ub_matrix(ub_matrix) + else: + err_msg = ub_matrix + self.pop_one_button_dialog(err_msg) + + return + + def do_clear_ub_peaks(self): + """ + Clear all peaks in UB-Peak table + :return: + """ + self.ui.tableWidget_peaksCalUB.clear() + + return + + def do_del_ub_peaks(self): + """ + Delete a peak in UB-Peak table + :return: + """ + # Find out the lines to get deleted + row_num_list = self.ui.tableWidget_peaksCalUB.get_selected_rows() + print '[DB] Row %s are selected' % str(row_num_list) + + # Delete + self.ui.tableWidget_peaksCalUB.delete_rows(row_num_list) + + return + + def do_download_spice_data(self): + """ Download SPICE data + :return: + """ + # Check scans to download + scan_list_str = str(self.ui.lineEdit_downloadScans.text()) + if len(scan_list_str) > 0: + # user specifies scans to download + valid, scan_list = fcutil.parse_int_array(scan_list_str) + if valid is False: + error_message = scan_list + self.pop_one_button_dialog(error_message) + else: + # Get all scans + status, ret_obj = gutil.parse_integers_editors([self.ui.lineEdit_exp]) + if status is False: + self.pop_one_button_dialog(ret_obj) + return + exp_no = ret_obj + assert isinstance(exp_no, int) + server_url = str(self.ui.lineEdit_url.text()) + scan_list = fcutil.get_scans_list(server_url, exp_no, return_list=True) + self.pop_one_button_dialog('Going to download scans %s.' % str(scan_list)) + + # Check location + destination_dir = str(self.ui.lineEdit_localSrcDir.text()) + status, error_message = self._myControl.set_local_data_dir(destination_dir) + if status is False: + self.pop_one_button_dialog(error_message) + else: + self.pop_one_button_dialog('Spice files will be downloaded to %s.' % destination_dir) + + # Set up myControl for downloading data + exp_no = int(self.ui.lineEdit_exp.text()) + self._myControl.set_exp_number(exp_no) + + server_url = str(self.ui.lineEdit_url.text()) + status, error_message = self._myControl.set_server_url(server_url) + if status is False: + self.pop_one_button_dialog(error_message) + return + + # Download + self._myControl.download_data_set(scan_list) + + return + + def do_find_peak(self): + """ Find peak in a given scan/pt and record it + """ + # Get experiment, scan and pt + status, ret_obj = gutil.parse_integers_editors([self.ui.lineEdit_exp, + self.ui.lineEdit_scanNumber, + self.ui.lineEdit_ptNumber]) + if status is True: + exp_no, scan_no, pt_no = ret_obj + else: + self.pop_one_button_dialog(ret_obj) + return + + # Find peak + status, err_msg = self._myControl.find_peak(exp_no, scan_no, pt_no) + if status is False: + self.pop_one_button_dialog(ret_obj) + return + if self.ui.checkBox_loadHKLfromFile.isChecked() is True: + # This is the first time that in the workflow to get HKL from MD workspace + status, err_msg = self._myControl.set_hkl_to_peak(exp_no, scan_no, pt_no) + if status is False: + self.pop_one_button_dialog('Unable to locate peak info due to %s.' % err_msg) + + # Set up correct values to table tableWidget_peaksCalUB + self._myControl.add_peak_info(exp_no, scan_no, pt_no) + status, peak_info = self._myControl.get_peak_info(exp_no, scan_no, pt_no) + if status is False: + err_msg = peak_info + raise KeyError(err_msg) + assert isinstance(peak_info, r4c.PeakInfo) + + # Set the HKL value from PeakInfo directly + # BAD PROGRAMMING! THERE ARE TOO MANY WAYS TO ACCESS STORED HKL + h, k, l = peak_info.get_peak_ws_hkl() + self.ui.lineEdit_H.setText('%.2f' % h) + self.ui.lineEdit_K.setText('%.2f' % k) + self.ui.lineEdit_L.setText('%.2f' % l) + + q_sample = peak_info.getQSample() + self.ui.lineEdit_sampleQx.setText('%.5E' % q_sample[0]) + self.ui.lineEdit_sampleQy.setText('%.5E' % q_sample[1]) + self.ui.lineEdit_sampleQz.setText('%.5E' % q_sample[2]) + + # self.set_ub_peak_table(peak_info) + + return + + def do_index_ub_peaks(self): + """ Index the peaks in the UB matrix peak table + :return: + """ + # Get UB matrix + ub_matrix = self.ui.tableWidget_ubMatrix.get_matrix() + print '[DB] Get UB matrix ', ub_matrix + + # Do it for each peak + num_peaks = self.ui.tableWidget_peaksCalUB.rowCount() + err_msg = '' + for i_peak in xrange(num_peaks): + scan_no, pt_no = self.ui.tableWidget_peaksCalUB.get_exp_info(i_peak) + status, ret_obj = self._myControl.index_peak(ub_matrix, scan_number=scan_no, + pt_number=pt_no) + if status is True: + new_hkl = ret_obj[0] + error = ret_obj[1] + self.ui.tableWidget_peaksCalUB.set_hkl(i_peak, new_hkl, error) + else: + err_msg += ret_obj + '\n' + # END-FOR + + if len(err_msg) > 0: + self.pop_one_button_dialog(err_msg) + + return + + def do_list_scans(self): + """ List all scans available + :return: + """ + # Experiment number + exp_no = int(self.ui.lineEdit_exp.text()) + + access_mode = str(self.ui.comboBox_mode.currentText()) + if access_mode == 'Local': + spice_dir = str(self.ui.lineEdit_localSpiceDir.text()) + message = fcutil.get_scans_list_local_disk(spice_dir, exp_no) + else: + url = str(self.ui.lineEdit_url.text()) + message = fcutil.get_scans_list(url, exp_no) + + self.pop_one_button_dialog(message) + + return + + def do_load_scan_info(self): + """ Load SIICE's scan file + :return: + """ + # Get scan number + status, ret_obj = gutil.parse_integers_editors([self.ui.lineEdit_run]) + if status is True: + scan_no = ret_obj[0] + else: + err_msg = ret_obj + self.pop_one_button_dialog('Unable to get scan number in raw data tab due to %s.' % err_msg) + return + + status, err_msg = self._myControl.load_spice_scan_file(exp_no=None, scan_no=scan_no) + if status is False: + self.pop_one_button_dialog(err_msg) + + return + + def do_plot_pt_raw(self): + """ Plot the Pt. + """ + # Get measurement pt and the file number + status, ret_obj = gutil.parse_integers_editors([self.ui.lineEdit_exp, + self.ui.lineEdit_run, + self.ui.lineEdit_rawDataPtNo]) + if status is True: + exp_no = ret_obj[0] + scan_no = ret_obj[1] + pt_no = ret_obj[2] + else: + self.pop_one_button_dialog(ret_obj) + return + + # Call to plot 2D + self._plot_raw_xml_2d(exp_no, scan_no, pt_no) + + return + + def do_plot_prev_pt_raw(self): + """ Plot the Pt. + """ + # Get measurement pt and the file number + status, ret_obj = gutil.parse_integers_editors([self.ui.lineEdit_exp, + self.ui.lineEdit_run, + self.ui.lineEdit_rawDataPtNo]) + if status is True: + exp_no = ret_obj[0] + scan_no = ret_obj[1] + pt_no = ret_obj[2] + else: + self.pop_one_button_dialog(ret_obj) + return + + # Previous one + pt_no -= 1 + if pt_no <= 0: + self.pop_one_button_dialog('Pt. = 1 is the first one.') + return + else: + self.ui.lineEdit_rawDataPtNo.setText('%d' % pt_no) + + # Plot + self._plot_raw_xml_2d(exp_no, scan_no, pt_no) + + return + + def do_plot_next_pt_raw(self): + """ Plot the Pt. + """ + # Get measurement pt and the file number + status, ret_obj = gutil.parse_integers_editors([self.ui.lineEdit_exp, + self.ui.lineEdit_run, + self.ui.lineEdit_rawDataPtNo]) + if status is True: + exp_no = ret_obj[0] + scan_no = ret_obj[1] + pt_no = ret_obj[2] + else: + self.pop_one_button_dialog(ret_obj) + return + + # Previous one + pt_no += 1 + # get last Pt. number + status, last_pt_no = self._myControl.get_pt_numbers(exp_no, scan_no) + if status is False: + error_message = last_pt_no + self.pop_one_button_dialog('Unable to access Spice table for scan %d. Reason" %s.' % ( + scan_no, error_message)) + if pt_no > last_pt_no: + self.pop_one_button_dialog('Pt. = %d is the last one of scan %d.' % (pt_no, scan_no)) + return + else: + self.ui.lineEdit_rawDataPtNo.setText('%d' % pt_no) + + # Plot + self._plot_raw_xml_2d(exp_no, scan_no, pt_no) + + return + + def do_merge_scans(self): + """ Process data for slicing view + :return: + """ + # Get UB matrix + ub_matrix = self.ui.tableWidget_ubSiceView.get_matrix() + self._myControl.set_ub_matrix(exp_number=None, ub_matrix=ub_matrix) + + # Get list of scans + scan_list = gutil.parse_integer_list(str(self.ui.lineEdit_listScansSliceView.text())) + if len(scan_list) == 0: + self.pop_one_button_dialog('Scan list is empty.') + + # Set table + self.ui.tableWidget_sliceViewProgress.append_scans(scans=scan_list) + + # Warning + self.pop_one_button_dialog('Data processing is long. Be patient!') + + # Process + base_name = str(self.ui.lineEdit_baseMergeMDName.text()) + scan_list.sort() + frame = str(self.ui.comboBox_mergeScanFrame.currentText()) + for scan_no in scan_list: + # Download/check SPICE file + self._myControl.download_spice_file(None, scan_no, over_write=False) + + # Get some information + status, pt_list = self._myControl.get_pt_numbers(None, scan_no, load_spice_scan=True) + if status is False: + err_msg = pt_list + self.pop_one_button_dialog('Failed to get Pt. number: %s' % err_msg) + return + else: + # Set information to table + err_msg = self.ui.tableWidget_sliceViewProgress.set_scan_pt(scan_no, pt_list) + if len(err_msg) > 0: + self.pop_one_button_dialog(err_msg) + + out_ws_name = base_name + '%04d' % scan_no + self.ui.tableWidget_sliceViewProgress.set_scan_pt(scan_no, 'In Processing') + try: + ret_tup = self._myControl.merge_pts_in_scan(exp_no=None, scan_no=scan_no, + target_ws_name=out_ws_name, + target_frame=frame) + merge_status = 'Done' + merged_name = ret_tup[0] + group_name = ret_tup[1] + except RuntimeError as e: + merge_status = 'Failed. Reason: %s' % str(e) + merged_name = '' + group_name = '' + finally: + self.ui.tableWidget_sliceViewProgress.set_status(scan_no, merge_status) + self.ui.tableWidget_sliceViewProgress.set_ws_names(scan_no, merged_name, group_name) + + # Sleep for a while + time.sleep(0.1) + # END-FOR + + return + + def do_reset_ub_peaks_hkl(self): + """ + Reset user specified HKL value to peak table + :return: + """ + num_rows = self.ui.tableWidget_peaksCalUB.rowCount() + for i_row in xrange(num_rows): + print '[DB] Update row %d' % (i_row) + scan, pt = self.ui.tableWidget_peaksCalUB.get_scan_pt(i_row) + status, peak_info = self._myControl.get_peak_info(None, scan, pt) + if status is False: + error_message = peak_info + raise RuntimeError(error_message) + h, k, l = peak_info.get_user_hkl() + self.ui.tableWidget_peaksCalUB.update_hkl(i_row, h, k, l) + # END-FOR + + return + + def do_set_experiment(self): + """ Set experiment + :return: + """ + status, ret_obj = gutil.parse_integers_editors([self.ui.lineEdit_exp]) + if status is True: + exp_number = ret_obj[0] + curr_exp_number = self._myControl.get_experiment() + if curr_exp_number is not None and exp_number != curr_exp_number: + self.pop_one_button_dialog('Changing experiment to %d. Clean previous experiment %d\'s result' + ' in Mantid manually.' % (exp_number, curr_exp_number)) + self._myControl.set_exp_number(exp_number) + self.ui.lineEdit_exp.setStyleSheet('color: black') + else: + err_msg = ret_obj + self.pop_one_button_dialog('Unable to set experiment as %s' % err_msg) + self.ui.lineEdit_exp.setStyleSheet('color: red') + + self.ui.tabWidget.setCurrentIndex(0) + + return + + def do_set_ub_sv(self): + """ Set UB matrix in Slice view + :return: + """ + if self.ui.radioButton_ubFromTab1.isChecked(): + self.ui.tableWidget_ubSiceView.set_from_matrix(self.ui.tableWidget_ubMatrix.get_matrix()) + elif self.ui.radioButton_ubFromTab3.isChecked(): + self.ui.tableWidget_ubSiceView.set_from_matrix(self.ui.tableWidget_refinedUB.get_matrix()) + elif self.ui.radioButton_ubFromList.isChecked(): + status, ret_obj = gutil.parse_float_array(str(self.ui.plainTextEdit_ubInput.toPlainText())) + if status is False: + self.pop_one_button_dialog(ret_obj) + elif len(ret_obj) != 9: + self.pop_one_button_dialog('Requiring 9 floats for UB matrix. Only %d are given.' % len(ret_obj)) + else: + self.ui.tableWidget_ubSiceView.set_from_list(ret_obj) + else: + self.pop_one_button_dialog('None is selected to set UB matrix.') + + return + + def do_setup_dir_default(self): + """ + Set up default directory for storing data and working + :return: + """ + home_dir = os.path.expanduser('~') + + # Data cache directory + data_cache_dir = os.path.join(home_dir, 'Temp/HB3ATest') + self.ui.lineEdit_localSpiceDir.setText(data_cache_dir) + self.ui.lineEdit_localSrcDir.setText(data_cache_dir) + + work_dir = os.path.join(data_cache_dir, 'Workspace') + self.ui.lineEdit_workDir.setText(work_dir) + + return + + def do_apply_setup(self): + """ + Apply set up ... + :return: + """ + # Local data directory + local_data_dir = str(self.ui.lineEdit_localSpiceDir.text()) + if os.path.exists(local_data_dir) is False: + try: + os.mkdir(local_data_dir) + except OSError as os_error: + self.pop_one_button_dialog('Unable to create local data directory %s due to %s.' % ( + local_data_dir, str(os_error))) + self.ui.lineEdit_localSpiceDir.setStyleSheet("color: red;") + return + else: + self.ui.lineEdit_localSpiceDir.setStyleSheet("color: black;") + # END-IF + + # Working directory + working_dir = str(self.ui.lineEdit_workDir.text()) + if os.path.exists(working_dir) is False: + try: + os.mkdir(working_dir) + except OSError as os_error: + self.pop_one_button_dialog('Unable to create working directory %s due to %s.' % ( + working_dir, str(os_error))) + self.ui.lineEdit_workDir.setStyleSheet("color: red;") + return + else: + self.ui.lineEdit_workDir.setStyleSheet("color: black;") + # END-IF + + # Server URL + data_server = str(self.ui.lineEdit_url.text()) + url_is_good = self.do_test_url() + if url_is_good is False: + self.ui.lineEdit_url.setStyleSheet("color: red;") + return + else: + self.ui.lineEdit_url.setStyleSheet("color: black;") + + # Set to control + self._myControl.set_local_data_dir(local_data_dir) + self._myControl.set_working_directory(working_dir) + self._myControl.set_server_url(data_server) + + return + + def do_test_url(self): + """ Test whether the root URL provided specified is good + """ + url = str(self.ui.lineEdit_url.text()) + + url_is_good, err_msg = fcutil.check_url(url) + if url_is_good is True: + self.pop_one_button_dialog("URL %s is valid." % url) + else: + self.pop_one_button_dialog(err_msg) + + return url_is_good + + def pop_one_button_dialog(self, message): + """ Pop up a one-button dialog + :param message: + :return: + """ + assert isinstance(message, str) + QtGui.QMessageBox.information(self, '4-circle Data Reduction', message) + + return + + def save_current_session(self, filename=None): + """ Save current session/value setup to + :return: + """ + # Set up dictionary + save_dict = dict() + + # Setup + save_dict['lineEdit_localSpiceDir'] = str(self.ui.lineEdit_localSpiceDir.text()) + save_dict['lineEdit_url'] = str(self.ui.lineEdit_url.text()) + save_dict['lineEdit_workDir']= str(self.ui.lineEdit_workDir.text()) + + # Experiment + save_dict['lineEdit_exp'] = str(self.ui.lineEdit_exp.text()) + save_dict['lineEdit_scanNumber'] = self.ui.lineEdit_scanNumber.text() + save_dict['lineEdit_ptNumber'] = str(self.ui.lineEdit_ptNumber.text()) + + # Lattice + save_dict['lineEdit_a'] = str(self.ui.lineEdit_a.text()) + save_dict['lineEdit_b'] = str(self.ui.lineEdit_b.text()) + save_dict['lineEdit_c'] = str(self.ui.lineEdit_c.text()) + save_dict['lineEdit_alpha'] = str(self.ui.lineEdit_alpha.text()) + save_dict['lineEdit_beta'] = str(self.ui.lineEdit_beta.text()) + save_dict['lineEdit_gamma'] = str(self.ui.lineEdit_gamma.text()) + + # Merge scan + save_dict['plainTextEdit_ubInput'] = str(self.ui.plainTextEdit_ubInput.toPlainText()) + save_dict['lineEdit_listScansSliceView'] = str(self.ui.lineEdit_listScansSliceView.text()) + save_dict['lineEdit_baseMergeMDName'] = str(self.ui.lineEdit_baseMergeMDName.text()) + + # Save to csv file + if filename is None: + filename = 'session_backup.csv' + ofile = open(filename, 'w') + writer = csv.writer(ofile) + for key, value in save_dict.items(): + writer.writerow([key, value]) + ofile.close() + + return + + def load_session(self, filename=None): + """ + To load a session, i.e., read it back: + :param filename: + :return: + """ + if filename is None: + filename = 'session_backup.csv' + + in_file = open(filename, 'r') + reader = csv.reader(in_file) + my_dict = dict(x for x in reader) + + # ... + for key, value in my_dict.items(): + if key.startswith('lineEdit') is True: + self.ui.__getattribute__(key).setText(value) + elif key.startswith('plainText') is True: + self.ui.__getattribute__(key).setPlainText(value) + elif key.startswith('comboBox') is True: + self.ui.__getattribute__(key).setCurrentIndex(int(value)) + else: + self.pop_one_button_dialog('Error! Widget name %s is not supported' % key) + # END-FOR + + # ... + self._myControl.set_local_data_dir(str(self.ui.lineEdit_localSpiceDir.text())) + + return + + def menu_quit(self): + """ + + :return: + """ + self.close() + + def show_scan_pt_list(self): + """ Show the range of Pt. in a scan + :return: + """ + # Get parameters + status, inp_list = gutil.parse_integers_editors([self.ui.lineEdit_exp, self.ui.lineEdit_run]) + if status is False: + self.pop_one_button_dialog(inp_list) + return + else: + exp_no = inp_list[0] + scan_no = inp_list[1] + + status, ret_obj = self._myControl.get_pt_numbers(exp_no, scan_no) + + # Form message + if status is False: + # Failed to get Pt. list + error_message = ret_obj + self.pop_one_button_dialog(error_message) + else: + # Form message + pt_list = sorted(ret_obj) + num_pts = len(pt_list) + info = 'Exp %d Scan %d has %d Pt. ranging from %d to %d.\n' % (exp_no, scan_no, num_pts, + pt_list[0], pt_list[-1]) + num_miss_pt = pt_list[-1] - pt_list[0] + 1 - num_pts + if num_miss_pt > 0: + info += 'There are %d Pt. skipped.\n' % num_miss_pt + + self.pop_one_button_dialog(info) + + return + + def set_ub_peak_table(self, peakinfo): + """ + DOC + :param peak_info: + :return: + """ + assert isinstance(peakinfo, r4c.PeakInfo) + + # Get data + exp_number, scan_number, pt_number = peakinfo.getExpInfo() + h, k, l = peakinfo.get_user_hkl() + q_sample = peakinfo.getQSample() + m1 = self._myControl.get_sample_log_value(exp_number, scan_number, pt_number, '_m1') + + # Set to table + status, err_msg = self.ui.tableWidget_peaksCalUB.append_row( + [scan_number, pt_number, h, k, l, q_sample[0], q_sample[1], q_sample[2], False, m1, '']) + if status is False: + self.pop_one_button_dialog(err_msg) + + return + + def _get_lattice_parameters(self): + """ + Get lattice parameters from GUI + :return: (Boolean, Object). True, 6-tuple as a, b, c, alpha, beta, gamm + False: error message + """ + status, ret_list = gutil.parse_float_editors([self.ui.lineEdit_a, + self.ui.lineEdit_b, + self.ui.lineEdit_c, + self.ui.lineEdit_alpha, + self.ui.lineEdit_beta, + self.ui.lineEdit_gamma]) + if status is False: + err_msg = ret_list + err_msg = 'Unable to parse unit cell due to %s' % err_msg + return False, err_msg + + a, b, c, alpha, beta, gamma = ret_list + + return True, (a, b, c, alpha, beta, gamma) + + def _plot_raw_xml_2d(self, exp_no, scan_no, pt_no): + """ Plot raw workspace from XML file for a measurement/pt. + """ + # Check and load SPICE table file + does_exist = self._myControl.does_spice_loaded(exp_no, scan_no) + if does_exist is False: + # Download data + status, error_message = self._myControl.download_spice_file(exp_no, scan_no, over_write=False) + if status is True: + status, error_message = self._myControl.load_spice_scan_file(exp_no, scan_no) + if status is False and self._allowDownload is False: + self.pop_one_button_dialog(error_message) + return + else: + self.pop_one_button_dialog(error_message) + return + # END-IF(does_exist) + + # Load Data for Pt's xml file + does_exist = self._myControl.does_raw_loaded(exp_no, scan_no, pt_no) + + if does_exist is False: + # Check whether needs to download + status, error_message = self._myControl.download_spice_xml_file(scan_no, pt_no, exp_no=exp_no) + if status is False: + self.pop_one_button_dialog(error_message) + return + # Load SPICE xml file + status, error_message = self._myControl.load_spice_xml_file(exp_no, scan_no, pt_no) + if status is False: + self.pop_one_button_dialog(error_message) + return + + # Convert a list of vector to 2D numpy array for imshow() + # Get data and plot + raw_det_data = self._myControl.get_raw_detector_counts(exp_no, scan_no, pt_no) + self.ui.graphicsView.clear_canvas() + self.ui.graphicsView.add_plot_2d(raw_det_data, x_min=0, x_max=256, y_min=0, y_max=256, + hold_prev_image=False) + + return + + def _show_ub_matrix(self, ubmatrix): + """ Show UB matrix + :param ubmatrix: + :return: + """ + assert ubmatrix.shape == (3, 3) + + self.ui.tableWidget_ubMatrix.set_from_matrix(ubmatrix) + + return diff --git a/scripts/Inelastic/Direct/DirectEnergyConversion.py b/scripts/Inelastic/Direct/DirectEnergyConversion.py index 56043ad5aeed4096c76b402026bf270c95982230..74394d53c59d56718d782f4b99e3b56634f1a1f9 100644 --- a/scripts/Inelastic/Direct/DirectEnergyConversion.py +++ b/scripts/Inelastic/Direct/DirectEnergyConversion.py @@ -1,3 +1,4 @@ +#pylint: disable=too-many-lines #pylint: disable=invalid-name from mantid.simpleapi import * from mantid.kernel import funcreturns diff --git a/scripts/Inelastic/Direct/ISISDirecInelasticConfig.py b/scripts/Inelastic/Direct/ISISDirecInelasticConfig.py index 624f599ba04d0e2848de1d7eae90cd134bcf83b3..f3c816ecbac11ce60b67842eb3f6dfbf1c4caad9 100644 --- a/scripts/Inelastic/Direct/ISISDirecInelasticConfig.py +++ b/scripts/Inelastic/Direct/ISISDirecInelasticConfig.py @@ -484,12 +484,12 @@ class MantidConfigDirectInelastic(object): # def init_user(self,fedIDorUser,theUser=None): """Define settings, specific to a user - Supports two interfaces -- old and the new one + Supports two interfaces -- old and the new one where - OldInterface: requested two input parameters + OldInterface: requested two input parameters fedID -- users federal id theUser -- class defining all other user property - NewInterface: requested single parameter: + NewInterface: requested single parameter: theUser -- class defining all user's properties including fedID """ if not theUser: diff --git a/scripts/Inelastic/Direct/PropertiesDescriptors.py b/scripts/Inelastic/Direct/PropertiesDescriptors.py index f05779e6e22cb3be785e93284470526939658be8..aec0169cd240da45e7d63e5218902c7578eb579e 100644 --- a/scripts/Inelastic/Direct/PropertiesDescriptors.py +++ b/scripts/Inelastic/Direct/PropertiesDescriptors.py @@ -1,3 +1,4 @@ +#pylint: disable=too-many-lines #pylint: disable=invalid-name """ File contains collection of Descriptors used to define complex properties in NonIDF_Properties and PropertyManager classes diff --git a/scripts/Inelastic/Direct/RunDescriptor.py b/scripts/Inelastic/Direct/RunDescriptor.py index 9fda6508d6224a370358ac200b8968be3aeca2c5..b5e959ff885084e6a088e0647532fa21445b65ca 100644 --- a/scripts/Inelastic/Direct/RunDescriptor.py +++ b/scripts/Inelastic/Direct/RunDescriptor.py @@ -1,3 +1,4 @@ +#pylint: disable=too-many-lines #pylint: disable=invalid-name """ File contains Descriptors used describe run for direct inelastic reduction """ @@ -995,8 +996,8 @@ class RunDescriptor(PropDescriptor): Load(Filename=data_file, OutputWorkspace=ws_name,LoadMonitors = '1',MonitorsAsEvents='0') #HACK >>> , necessary until #11565 is fixed if nxs_file : - instr_name = RunDescriptor._holder.instr_name - if instr_name == 'LET' and self._run_number>14151 and self._run_number<14382: + instr_name = RunDescriptor._holder.instr_name + if instr_name == 'LET' and self._run_number>14151 and self._run_number<14382: FrameworkManager.clearInstruments() idf_file = api.ExperimentInfo.getInstrumentFilename(instr_name) idf_path,tile = os.path.split(idf_file) diff --git a/scripts/Interface/reduction_gui/reduction/diffraction/diffraction_reduction_script.py b/scripts/Interface/reduction_gui/reduction/diffraction/diffraction_reduction_script.py index 7140a4df5633e57ccaaca3b9719cc32474b3539f..abbd2f4eee91d7db012641d90db791d3ecdec1b6 100644 --- a/scripts/Interface/reduction_gui/reduction/diffraction/diffraction_reduction_script.py +++ b/scripts/Interface/reduction_gui/reduction/diffraction/diffraction_reduction_script.py @@ -84,7 +84,7 @@ class DiffractionReductionScripter(BaseReductionScripter): file_name, autosavexmlfname) wbuf += script wbuf += "\n========== End of Script ===========" - print (wbuf) + print wbuf return script diff --git a/scripts/Interface/reduction_gui/widgets/reflectometer/base_ref_reduction.py b/scripts/Interface/reduction_gui/widgets/reflectometer/base_ref_reduction.py index ea324c63828a6e03190b8b2c5fc99b90bdf2fd80..72cfb428315fa574ee295ed307c2e1e696f1eb99 100644 --- a/scripts/Interface/reduction_gui/widgets/reflectometer/base_ref_reduction.py +++ b/scripts/Interface/reduction_gui/widgets/reflectometer/base_ref_reduction.py @@ -1,3 +1,4 @@ +#pylint: disable=too-many-lines #pylint: disable=invalid-name,unused-import from PyQt4 import QtGui, QtCore import reduction_gui.widgets.util as util diff --git a/scripts/Interface/reduction_gui/widgets/reflectometer/refl_data_simple.py b/scripts/Interface/reduction_gui/widgets/reflectometer/refl_data_simple.py index bfb043368ad53ccaeb13b243a916cea1f8f5e615..8816e2f91ded5277314a7b6e267a8a72f8c424ac 100644 --- a/scripts/Interface/reduction_gui/widgets/reflectometer/refl_data_simple.py +++ b/scripts/Interface/reduction_gui/widgets/reflectometer/refl_data_simple.py @@ -1,3 +1,4 @@ +#pylint: disable=too-many-lines #pylint: disable=invalid-name from PyQt4 import QtGui, uic, QtCore import reduction_gui.widgets.util as util diff --git a/scripts/Interface/ui/reflectometer/refl_gui.py b/scripts/Interface/ui/reflectometer/refl_gui.py index 3bb3aed9b003789fd1786e1f1ecfa46f82878888..8f1a384733c2e605fd61b22f192b30ccc26b3b90 100644 --- a/scripts/Interface/ui/reflectometer/refl_gui.py +++ b/scripts/Interface/ui/reflectometer/refl_gui.py @@ -1,3 +1,4 @@ +#pylint: disable=too-many-lines #pylint: disable=invalid-name import ui_refl_window import refl_save diff --git a/scripts/Interface/ui/reflectometer/refl_save.py b/scripts/Interface/ui/reflectometer/refl_save.py index 6dabce7fe2a500d16899e687dde973628f1c98de..52f4c8dc61f64444d7263953e7a70dcf40d99a0a 100644 --- a/scripts/Interface/ui/reflectometer/refl_save.py +++ b/scripts/Interface/ui/reflectometer/refl_save.py @@ -1,8 +1,8 @@ -#pylint: disable=invalid-name +#pylint: disable-all from PyQt4 import QtCore, QtGui import os from mantid.simpleapi import * -from mantid.api import WorkspaceGroup +from mantid.api import WorkspaceGroup, AnalysisDataService import xml.etree.ElementTree as xml from isis_reflectometry.quick import * from isis_reflectometry.procedures import * @@ -32,10 +32,12 @@ class Ui_SaveWindow(object): def setupUi(self, SaveWindow): self.SavePath="" SaveWindow.setObjectName(_fromUtf8("SaveWindow")) - SaveWindow.resize(700, 450) + SaveWindow.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)) SaveWindow.setAcceptDrops(True) - + main_layout = QtGui.QHBoxLayout() + SaveWindow.setLayout(main_layout) self.centralWidget = QtGui.QWidget(SaveWindow) + main_layout.addWidget(self.centralWidget) self.centralWidget.setObjectName(_fromUtf8("centralWidget")) self.gridLayout_2 = QtGui.QGridLayout(self.centralWidget) self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2")) @@ -236,12 +238,18 @@ class Ui_SaveWindow(object): def retranslateUi(self, SaveWindow): SaveWindow.setWindowTitle(QtGui.QApplication.translate("SaveWindow", "SaveWindow", None, QtGui.QApplication.UnicodeUTF8)) - self.pushButton.setText(QtGui.QApplication.translate("SaveWindow", "SAVE", None, QtGui.QApplication.UnicodeUTF8)) + self.pushButton.setText(QtGui.QApplication.translate("SaveWindow", "Save", None, QtGui.QApplication.UnicodeUTF8)) self.pushButton_2.setText(QtGui.QApplication.translate("SaveWindow", "Refresh", None, QtGui.QApplication.UnicodeUTF8)) + def _get_saveable_workspace_names(self): + names = mtd.getObjectNames() + # Exclude WorkspaceGroups from our list. We cannot save them to ASCII. + names = [i for i in names if not isinstance(AnalysisDataService.retrieve(i), WorkspaceGroup)] + return names + def filterWksp(self): self.listWidget.clear() - names = mtd.getObjectNames() + names = self._get_saveable_workspace_names() if self.regExCheckBox.isChecked(): regex=re.compile(self.filterEdit.text()) filtered = list() @@ -268,7 +276,7 @@ class Ui_SaveWindow(object): def populateList(self): self.listWidget.clear() - names = mtd.getObjectNames() + names = self._get_saveable_workspace_names() if len(names): RB_Number=groupGet(names[0],'samp','rb_proposal') for ws in names: diff --git a/scripts/Reflectometry/isis_reflectometry/procedures.py b/scripts/Reflectometry/isis_reflectometry/procedures.py index 999dd0a65df4c3c69b2b8d82f085be1fa5d886ab..11d1a52448ec5749956eca3315db82a7a2537801 100644 --- a/scripts/Reflectometry/isis_reflectometry/procedures.py +++ b/scripts/Reflectometry/isis_reflectometry/procedures.py @@ -1,3 +1,4 @@ +#pylint: disable=too-many-lines #pylint: disable=invalid-name from math import * diff --git a/scripts/SANS/ISISCommandInterface.py b/scripts/SANS/ISISCommandInterface.py index 0ed8fd805b698e6a5c35ffdf68ae9425299ed478..3f06b3229bf67e2a871806a1a62459c5db70707b 100644 --- a/scripts/SANS/ISISCommandInterface.py +++ b/scripts/SANS/ISISCommandInterface.py @@ -1,3 +1,4 @@ +#pylint: disable=too-many-lines #pylint: disable=invalid-name """ Enables the SANS commands (listed at http://www.mantidproject.org/SANS) to @@ -574,7 +575,7 @@ def _fitRescaleAndShift(rAnds, frontData, rearData): # We need to make sure at this point that the workspaces are 1D. We # don't really know how to match the workspaces for the 2D case. - if (not su.is_1D_workspace(mtd[frontData]) or not su.is_1D_workspace(mtd[rearData])): + if not su.is_1D_workspace(mtd[frontData]) or not su.is_1D_workspace(mtd[rearData]): sanslog.warning("Request to perform a fit to find the shift and scale values for" "a non-1D workspace is not possible. Default values are provided.") scale = rAnds.scale diff --git a/scripts/SANS/SANSBatchMode.py b/scripts/SANS/SANSBatchMode.py index 3419a9c6cd16d07aede08f6ca2a48e6918fb1d9b..38f01016a7b8b7744b9bdd942883cb8c133268b4 100644 --- a/scripts/SANS/SANSBatchMode.py +++ b/scripts/SANS/SANSBatchMode.py @@ -178,7 +178,8 @@ def BatchReduce(filename, format, plotresults=False, saveAlgs={'SaveRKH':'txt'}, original_settings = settings, original_prop_man_settings = prop_man_settings) except (RunTimeError, ValueError) as e: - sanslog.warning("Error in Batchmode user files: Could not reset the specified user file %s. More info: %s" %(str(run['user_file']),str(e))) + sanslog.warning("Error in Batchmode user files: Could not reset the specified user file %s. More info: %s" %( + str(run['user_file']),str(e))) local_settings = copy.deepcopy(ReductionSingleton().reference()) local_prop_man_settings = ReductionSingleton().settings.clone("TEMP_SETTINGS") diff --git a/scripts/SANS/SANSUtility.py b/scripts/SANS/SANSUtility.py index b22d9e8c19ad5d785f2d99beb9479be8769d5258..c594e7548e3d319888d9136a2b8c14c6831b8221 100644 --- a/scripts/SANS/SANSUtility.py +++ b/scripts/SANS/SANSUtility.py @@ -1,3 +1,4 @@ +#pylint: disable=too-many-lines #pylint: disable=invalid-name ######################################################### # This module contains utility functions common to the diff --git a/scripts/SANS/isis_instrument.py b/scripts/SANS/isis_instrument.py index b4c0a9a507d3bbcb0a063ac2c540d05a12eeb1ce..821b956195403a29bfb2b308d0a83d29286235c9 100644 --- a/scripts/SANS/isis_instrument.py +++ b/scripts/SANS/isis_instrument.py @@ -1,3 +1,4 @@ +#pylint: disable=too-many-lines #pylint: disable=invalid-name import math import os diff --git a/scripts/SANS/isis_reduction_steps.py b/scripts/SANS/isis_reduction_steps.py index ebb89992488267b445b04ba4d1b5f16f99c55a98..f98175cf90062335d14d3cf0894e08d7e117e840 100644 --- a/scripts/SANS/isis_reduction_steps.py +++ b/scripts/SANS/isis_reduction_steps.py @@ -1,3 +1,4 @@ +#pylint: disable=too-many-lines #pylint: disable=invalid-name """ This file defines what happens in each step in the data reduction, it's diff --git a/scripts/reduction/instruments/reflectometer/wks_utility.py b/scripts/reduction/instruments/reflectometer/wks_utility.py index b9dec721553ac63bdbeb835d613fe0b306a45bb4..7544a27a51147a23863c1579e17d2db0afac45d3 100644 --- a/scripts/reduction/instruments/reflectometer/wks_utility.py +++ b/scripts/reduction/instruments/reflectometer/wks_utility.py @@ -1,3 +1,4 @@ +#pylint: disable=too-many-lines #pylint: disable=invalid-name from numpy import zeros, arctan2, arange, shape, sqrt, fliplr, asfarray, mean, sum, NAN from mantid.simpleapi import * diff --git a/tools/DOI/authors.py b/tools/DOI/authors.py index aefa191509e7cae27eb14df35dfc91e564189b23..2d35b45b4aec8710fb2a8a7cff85ed3b137977e2 100644 --- a/tools/DOI/authors.py +++ b/tools/DOI/authors.py @@ -1,3 +1,4 @@ +#pylint: disable=invalid-name from itertools import chain, ifilterfalse import string, os, re diff --git a/tools/DOI/doi.py b/tools/DOI/doi.py index 523d8c6399e989ea5f51f3fd05bb997df28031fd..56c4a8782a92cef962d8e76cd0750eac47717d4d 100644 --- a/tools/DOI/doi.py +++ b/tools/DOI/doi.py @@ -1,3 +1,4 @@ +#pylint: disable=invalid-name """A script for generating DataCite DOI's for Mantid releases, to be called by a Jenkins job during the release process. When given a major, minor and patch release number along with username and password credentials, it will build a @@ -60,7 +61,6 @@ import xml.etree.ElementTree as ET import subprocess import re -import os from datetime import date import authors @@ -69,7 +69,7 @@ import authors # two forms: # - 'OK' # - 'OK ([DOI])' -SUCCESS_RESPONSE = '^OK( \((.+)\))?$' +SUCCESS_RESPONSE = r'^OK( \((.+)\))?$' # Point all "deleted" DOIs to here: INVALID_URL = 'http://www.datacite.org/invalidDOI' @@ -210,8 +210,10 @@ def _http_request(body, method, url, options): ] # Set how loud cURL should be while running. - if options.debug: args.append('--verbose') - else: args.append('--silent') + if options.debug: + args.append('--verbose') + else: + args.append('--silent') args.append(url) @@ -529,4 +531,4 @@ if __name__ == "__main__": 'details. Note that this does NOT delete the DOI.' ) - run(parser.parse_args()) \ No newline at end of file + run(parser.parse_args()) diff --git a/tools/DefaultConfigFiles/configToCpp.py b/tools/DefaultConfigFiles/configToCpp.py index 6cd03a271650bc81ed2e03fcdc93110c0f563604..bb924e92af41df65efb48cf20fa26230099a49f7 100644 --- a/tools/DefaultConfigFiles/configToCpp.py +++ b/tools/DefaultConfigFiles/configToCpp.py @@ -7,8 +7,8 @@ import sys with open(sys.argv[2]) as f: for line in f: - line = line.rstrip('\n') - if line == "": - print sys.argv[1] + " << std::endl;" - else: - print sys.argv[1] + " << \"" + line + "\" << std::endl;" + line = line.rstrip('\n') + if line == "": + print sys.argv[1] + " << std::endl;" + else: + print sys.argv[1] + " << \"" + line + "\" << std::endl;" diff --git a/tools/PeriodicTable/generate_atom_code.py b/tools/PeriodicTable/generate_atom_code.py index 030cb3c39b70b79c292f827b48865e6eaa833d73..3e2be400a0091c7ae44503bf0c060233302194e2 100755 --- a/tools/PeriodicTable/generate_atom_code.py +++ b/tools/PeriodicTable/generate_atom_code.py @@ -1,3 +1,4 @@ +#pylint: disable=invalid-name #!/usr/bin/env python VERSION = "1.0" @@ -30,13 +31,13 @@ def writeMiddle(handle, abundance, atom): if density is None: density = "NAN" else: - desnity = str(density) + density = str(density) except TypeError: density = "NAN" handle.write("%f, %f, %s" % (abundance, mass, density)) def writeEnd(handle): - handle.write(");\n"); + handle.write(");\n") def writeIsotope(handle, element, atomicnumber): isotope = element._isotopes[atomicnumber] diff --git a/tools/Pylint/fixPylint.py b/tools/Pylint/fixPylint.py new file mode 100644 index 0000000000000000000000000000000000000000..5f3cf1d6990bde995780868418b7132eef3e4060 --- /dev/null +++ b/tools/Pylint/fixPylint.py @@ -0,0 +1,173 @@ +#pylint: disable=invalid-name,anomalous-backslash-in-string +import os +import re +import argparse + +def fixBadIndent(toModify,indent): + err_string=indent.replace(' Bad indentation. Found ','').replace('(bad-indentation)','').split('spaces, expected') + bad=int(err_string[0]) + good=int(err_string[1]) + return toModify.replace(' '*bad,' '*good) + +def fixParens(fname,errorlist,errlines): + tofixf=open(fname,'r') + file_content=tofixf.readlines() + tofixf.close() + newcontent=file_content + for i,error in zip(errlines,errorlist): + if error.find('(superfluous-parens)')!=-1: + kwd=error.split("'")[1] + pattern=re.compile(kwd+'(?P<spaces>\ *)\((?P<file_content>.*)\)') + match=pattern.search(file_content[i]) + d=match.groupdict() + newcontent[i]=file_content[i].replace(kwd+d['spaces']+'('+d['file_content']+')',kwd+' '+d['file_content']) + tofixf=open(fname,'w') + tofixf.write(''.join(newcontent)) + tofixf.close() + +def fixSeveralErrors(fname,errorlist,errlines): + tofixf=open(fname,'r') + file_content=tofixf.readlines() + tofixf.close() + newcontent=file_content + for i,error in zip(errlines,errorlist): + if error.find('Bad indentation')!=-1: + newcontent[i]=fixBadIndent(file_content[i],error) + if error.find('missing-final-newline')!=-1: + newcontent[-1]+='\n' + if error.find('mixed-indentation')!=-1: + newcontent[i]=file_content[i].replace('\t', ' ') + if error.find('trailing-whitespace')!=-1: + newcontent[i]=file_content[i].rstrip()+'\n' + if error.find('Unnecessary semicolon')!=-1: + newcontent[i]=file_content[i].replace(';','') + tofixf=open(fname,'w') + tofixf.write(''.join(newcontent)) + tofixf.close() + +def addIgnoreStatement(fname,errorlist): + tofixf=open(fname,'r') + file_content=tofixf.readlines() + tofixf.close() + ignore=[] + for error in errorlist: + if error.find('(invalid-name)')!=-1 and 'invalid-name' not in ignore: + ignore.append('invalid-name') + if error.find('(no-init)')!=-1 and 'no-init' not in ignore: + ignore.append('no-init') + if error.find('(too-many-lines)')!=-1 and 'too-many-lines' not in ignore: + ignore.append('too-many-lines') + if len(ignore)!=0: + tofixf=open(fname,'w') + tofixf.write("#pylint: disable="+','.join(ignore)+'\n') + tofixf.write(''.join(file_content)) + tofixf.close() + +def generate_choices(): + ch=['simple','parentheses','add_ignores'] + ch_help=['simple - fixes the following warning: bad-indentation, missing-final-newline, '+\ + 'mixed_indentation, trailing-whitespace, unnecesary-semicolon', + 'parentheses - fixes superfluous-parens warning', + 'add_ignores - adds ignore statemets at the beginning of each file to ignore invalid-name, no-init, too-many-lines'] + chhelp="The possible choices supported are:\n\t"+'\n\t'.join(ch_help) + return (ch,chhelp) + +if __name__=='__main__': + choices,choices_help=generate_choices() + parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter, + epilog=choices_help, + description='Fix some pylint warnings. It is STRONGLY RECOMMENDED to '+\ + 'rerun the pylintcheck between fixes') + parser.add_argument('-fix','--fix', default='simple', + choices=choices, + help='Select things to fix (default: simple). \nSee the choices options below.') + parser.add_argument('Filename', type=file, help='The output from "make pylint"') + parser.add_argument('-v','--version', action='version', version='%(prog)s 1.0') + + #read pylint.log + args = parser.parse_args() + oneline=args.Filename.read() + args.Filename.close() + #ignore everything up to the first error + oneline=oneline[oneline.find('****'):] + content=oneline.split('\n') + + fileindex=content.index('Checks of the following modules FAILED:') + files=[f.strip() for f in content[fileindex+1:-1]] + filenumber=0 + linenumber=0 + prevFile=True + + + while linenumber<fileindex: + filename=files[filenumber] + line=content[linenumber] + #find a file + if line.find('****')==0 and line.find('PyChop')==-1: + modname=line.split('************* Module ')[1] + if prevFile: + if os.path.isfile(filename): + correct_filename=filename + filenumber+=1 + prevFile=True + else: + prevFile=False + modname=modname.replace('.','/') + firstslash=modname.find('/') + if firstslash==-1: + correct_filename=filename+'/__init__.py' + else: + correct_filename=filename+modname[firstslash:]+'.py' + else: + lastmodulename=os.path.split(filename)[1] + modbase=modname.split('.')[0] + if lastmodulename==modbase: #still in the same module + modname=modname.replace('.','/') + firstslash=modname.find('/') + if firstslash==-1: + correct_filename=filename+'/__init__.py' + else: + correct_filename=filename+modname[firstslash:]+'.py' + else: #go to the next file or module + filenumber+=1 + filename=files[filenumber] + prevFile=True + if os.path.isfile(filename): + correct_filename=filename + filenumber+=1 + prevFile=True + else: + prevFile=False + modname=modname.replace('.','/') + firstslash=modname.find('/') + if firstslash==-1: + correct_filename=filename+'/__init__.py' + else: + correct_filename=filename+modname[firstslash:]+'.py' + #process it + j=1 + errors=[] + errorlines=[] + while linenumber+j<fileindex and content[linenumber+j].find('****')==-1: + err=content[linenumber+j] + if len(err)>0 and err[0] in ['C','W','E'] and err[1]==':': + lineNumber=int(err.split(':')[1].split(',')[0])-1 + errors.append(err.split(':')[2]) + errorlines.append(lineNumber) + j+=1 + if args.fix=='simple': + fixSeveralErrors(correct_filename,errors,errorlines) + elif args.fix=='add_ignores': + addIgnoreStatement(correct_filename,errors) + elif args.fix=='parentheses': + fixParens(correct_filename,errors,errorlines) + linenumber+=j-1 + else: + linenumber+=1 + + + + + + + diff --git a/tools/Pylint/pylint.cfg b/tools/Pylint/pylint.cfg index eec53d4f7b22bdfd67bc5e8f1c30b956fa6be060..cbf3bb4a69987805eca098774a89baba10598196 100644 --- a/tools/Pylint/pylint.cfg +++ b/tools/Pylint/pylint.cfg @@ -57,7 +57,7 @@ disable=W0142,I0011,F0401,W0614,E0602,C0111,C0326,W0401,R0201,R0801 output-format=colorized # Include message's id in output -include-ids=yes +#include-ids=yes # Put messages in a separate file for each module / package specified on the # command line instead of printing them on stdout. Reports (if any) will be diff --git a/tools/Pylint/run_pylint.py b/tools/Pylint/run_pylint.py index 4af4d89a1555aac11bb0ebba05fbc09d58ae5f6d..8368854c1fcafe1db6c7f464b3fe0a61a6f7922b 100644 --- a/tools/Pylint/run_pylint.py +++ b/tools/Pylint/run_pylint.py @@ -57,7 +57,7 @@ class Results(object): """ Return true if all files were clean """ - return (len(self.failures) == 0) + return len(self.failures) == 0 def add(self, modulename, status): """ @@ -172,8 +172,8 @@ def parse_arguments(argv): help="If provided, store the output in the given file.") parser.add_option("-x", "--exclude", dest="exclude", metavar="EXCLUDES", help="If provided, a space-separated list of " - "files/directories to exclude. Relative paths are " - "taken as relative to --basedir") + "files/directories to exclude. Relative paths are " + "taken as relative to --basedir") parser.set_defaults(format=DEFAULT_PYLINT_FORMAT, exe=DEFAULT_PYLINT_EXE, nofail=False, basedir=os.getcwd(), rcfile=DEFAULT_RCFILE, exclude="") @@ -242,6 +242,7 @@ def check_module_imports(): str: String indicating success/failure """ msg = "" + #pylint: disable=unused-variable try: import mantid except ImportError, exc: @@ -292,7 +293,7 @@ def run_checks(targets, serializer, options): targetpath = os.path.join(options.basedir, target) pkg_init = os.path.join(targetpath, "__init__.py") if os.path.isfile(targetpath) or os.path.isfile(pkg_init): - overall_stats.add(exec_pylint_on_importable(targetpath, serializer, options)) + overall_stats.add(targetpath, exec_pylint_on_importable(targetpath, serializer, options)) else: overall_stats.update(exec_pylint_on_all(targetpath, serializer, options, excludes)) ## @@ -352,7 +353,7 @@ def find_importable_targets(dirpath): pkg_init = os.path.join(abspath, "__init__.py") if (os.path.isfile(abspath) and item.endswith(".py")) or \ os.path.isfile(pkg_init): - importables.append(abspath) + importables.append(abspath) elif os.path.isdir(abspath): importables.extend(package_walk(abspath)) return importables @@ -386,7 +387,7 @@ def exec_pylint_on_importable(srcpath, serializer, options): with temp_dir_change(os.path.dirname(srcpath)): status = subp.call(cmd, stdout=serializer) - return (status == 0) + return status == 0 #------------------------------------------------------------------------------ diff --git a/tools/TestViewer/TestViewer.py b/tools/TestViewer/TestViewer.py index 428762ca8577534af6bc5449a80c9e08df2360d4..987819601d5c954e4bb51b9a0ce43707c03fdf91 100755 --- a/tools/TestViewer/TestViewer.py +++ b/tools/TestViewer/TestViewer.py @@ -4,4 +4,4 @@ """ Launch the GUI Test Viewer """ import main_window -main_window.start() \ No newline at end of file +main_window.start() diff --git a/tools/TestViewer/main_window.py b/tools/TestViewer/main_window.py index 06bbb4291e5da4fc4a11f68830377229835f6d0a..48975b55710a5871b9c86f8211cbe22a839e7ebc 100644 --- a/tools/TestViewer/main_window.py +++ b/tools/TestViewer/main_window.py @@ -1,12 +1,12 @@ +#pylint: disable=invalid-name #!/usr/bin/env python # -*- coding: utf-8 -*- import sys import time -import optparse import os -from PyQt4 import QtGui, uic, QtCore +from PyQt4 import QtGui, QtCore import PyQt4.QtCore from PyQt4.QtCore import * import PyQt4.QtGui @@ -14,10 +14,9 @@ from PyQt4.QtGui import * import ui_main_window import test_info -from test_info import TestSuite, TestSingle, TestProject, MultipleProjects +from test_info import TestSuite, TestSingle, TestProject -import test_tree -from test_tree import TestTreeModel, TreeItemSuite, TreeItemProject, TreeFilterProxyModel +from test_tree import TestTreeModel, TreeFilterProxyModel #================================================================================================== @@ -285,11 +284,11 @@ class TestViewerMainWindow(QtGui.QMainWindow, ui_main_window.Ui_MainWindow): # --- Text settings --- memory = s.value("memory_limit_MB", 8000).toInt()[0] - test_info.memory_limit_kb = memory*1024; + test_info.memory_limit_kb = memory*1024 self.textMemory.setPlainText("%d" % memory) timeout = s.value("process_timeout_sec", 30).toInt()[0] - test_info.process_timeout_sec = timeout; + test_info.process_timeout_sec = timeout self.textTimeout.setPlainText("%d" % timeout) self.select_by_string_lastValue = str(s.value("select_by_string_lastValue", "-Performance").toString()) @@ -313,10 +312,10 @@ class TestViewerMainWindow(QtGui.QMainWindow, ui_main_window.Ui_MainWindow): try: s = plainTextBox.toPlainText() value = int(s) - plainTextBox.setStyleSheet("QPlainTextEdit { background-color: white; }"); + plainTextBox.setStyleSheet("QPlainTextEdit { background-color: white; }") return value except: - plainTextBox.setStyleSheet("QPlainTextEdit { background-color: tomato; }"); + plainTextBox.setStyleSheet("QPlainTextEdit { background-color: tomato; }") return None @@ -326,14 +325,14 @@ class TestViewerMainWindow(QtGui.QMainWindow, ui_main_window.Ui_MainWindow): """ called when one of the text boxes changes """ s = self.settings - memory = self.get_int_from_text(self.textMemory); + memory = self.get_int_from_text(self.textMemory) if not memory is None: - test_info.memory_limit_kb = memory*1024; + test_info.memory_limit_kb = memory*1024 s.setValue("memory_limit_MB", memory) - timeout = self.get_int_from_text(self.textTimeout); + timeout = self.get_int_from_text(self.textTimeout) if not timeout is None: - test_info.process_timeout_sec = timeout; + test_info.process_timeout_sec = timeout s.setValue("process_timeout_sec", timeout) @@ -460,8 +459,8 @@ class TestViewerMainWindow(QtGui.QMainWindow, ui_main_window.Ui_MainWindow): if (time.time() - self.last_console_update) > 1.5: # Dont update more often than this: self.textConsole.setText( u'<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />\n' + self.stdout ) - sb = self.textConsole.verticalScrollBar(); - sb.setValue(sb.maximum()); + sb = self.textConsole.verticalScrollBar() + sb.setValue(sb.maximum()) self.last_console_update = time.time() @@ -540,7 +539,7 @@ class TestViewerMainWindow(QtGui.QMainWindow, ui_main_window.Ui_MainWindow): elif isinstance(res, TestSingle): self.labelTestType.setText("Single Test Results:") else: - raise "Incorrect object passed to show_results; should be TestProject, TestSuite, or TestSingle." + raise RuntimeError("Incorrect object passed to show_results; should be TestProject, TestSuite, or TestSingle.") self.labelTestName.setText( res.get_fullname() ) self.labelTestName.hide() self.textResults.setText( u'<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />\n' @@ -574,7 +573,8 @@ class TestViewerMainWindow(QtGui.QMainWindow, ui_main_window.Ui_MainWindow): parallel = self.checkInParallel.isChecked() # Do some setup of the worker and GUI num_steps = self.worker.set_parameters(self, selected_only=selected_only, make_tests=True, parallel=parallel) - if num_steps < 1: num_steps = 1 + if num_steps < 1: + num_steps = 1 self.progTest.setValue(0) self.progTest.setMaximum( num_steps ) self.set_running(True) @@ -631,15 +631,17 @@ class TestViewerMainWindow(QtGui.QMainWindow, ui_main_window.Ui_MainWindow): def start(): # Start the settings object. # TODO: Change the company name here and in MantidPlot - settings = QSettings("ISIS", "MantidTestViewer"); + settings = QSettings("ISIS", "MantidTestViewer") settings_bin_folder = str(settings.value("bin_folder", "../../Mantid/bin").toString()) settings_source_folder = str(settings.value("source_folder", "../../Mantid/Framework").toString()) bin_folder = "" - if len(sys.argv) > 1: bin_folder = sys.argv[1] + if len(sys.argv) > 1: + bin_folder = sys.argv[1] source_folder = "" - if len(sys.argv) > 2: source_folder = sys.argv[2] + if len(sys.argv) > 2: + source_folder = sys.argv[2] if bin_folder == "--help": print """TestViewer.py [BINFOLDER] [SOURCEFOLDER] @@ -690,4 +692,3 @@ def start(): if __name__ == '__main__': start() - diff --git a/tools/TestViewer/test_info.py b/tools/TestViewer/test_info.py index c43fb05c0cf7a6b8ba340dea515ec46d1c5643cf..e93f07021bebedf3cb17b4ab1e53fe6281c46a4f 100644 --- a/tools/TestViewer/test_info.py +++ b/tools/TestViewer/test_info.py @@ -1,3 +1,4 @@ +#pylint: disable=too-many-lines,invalid-name # -*- coding: utf-8 -*- """ Classes describing test projects, how they are run, @@ -77,7 +78,7 @@ class TestResult: def __eq__(self, other): """ Equality comparison """ if isinstance(other, TestResult): - return ((self.value == other.value) and (self.old == other.old)) + return (self.value == other.value) and (self.old == other.old) else: return self.value == other @@ -372,7 +373,7 @@ class TestSuite(object): self.contents_changed = True else: for i in xrange(len(self.tests)): - if (self.tests[i].name != other.tests[i].name): + if self.tests[i].name != other.tests[i].name: self.contents_changed = True self.tests[i].replace_contents( other.tests[i] ) # Copy local values @@ -402,7 +403,7 @@ class TestSuite(object): oldtime = self.source_file_mtime if os.path.exists(self.source_file): self.source_file_mtime = os.path.getmtime(self.source_file) - return (self.source_file_mtime != oldtime) + return self.source_file_mtime != oldtime def get_selected(self): return self.selected @@ -587,7 +588,7 @@ class TestSuite(object): return elif len(suites) > 1: for xmlSuite in suites: - if (suites[0].getAttribute("name") == self.name): + if suites[0].getAttribute("name") == self.name: break else: xmlSuite = suites[0] @@ -596,7 +597,7 @@ class TestSuite(object): xmlCases = xmlSuite.getElementsByTagName("testcase") for case in xmlCases: classname = case.getAttribute("classname") - if (classname == self.classname): + if classname == self.classname: # This is the single test name test_name = case.getAttribute("name") test = self.find_test(test_name) @@ -752,7 +753,7 @@ class TestProject(object): # This will run while calling the stdout callback. (status, output) = run_command_with_callback(full_command, callback_func) - if (status != 0): + if status != 0: msg = "-------- BUILD FAILED! ---------" if not callback_func is None: callback_func("%s" % msg) self.build_succeeded = False @@ -1055,7 +1056,7 @@ class MultipleProjects(object): word = val[1:] for pj in self.projects: for suite in pj.suites: - suite.selected = not (word in suite.name) + suite.selected = not word in suite.name if suite.selected: num += 1 else: word = val @@ -1486,14 +1487,14 @@ def test_results_compiling(): def test_age(): a = TestSingle("my_test_test", None) - assert (a.state == TestResult.NOT_RUN) + assert a.state == TestResult.NOT_RUN a.age() - assert (a.state == TestResult.NOT_RUN) - assert (a.state.old) + assert a.state == TestResult.NOT_RUN + assert a.state.old a = TestSingle("my_test_test", None) a.state = TestResult(TestResult.ALL_PASSED) a.age() - assert (a.state.old) + assert a.state.old test_results_compiling() test_age() diff --git a/tools/TestViewer/test_tree.py b/tools/TestViewer/test_tree.py index ac53c73d42d7350dcb87faf20c225b5e7e2bc71c..9c233db03d27a2f1b4e6569cd9ba148cf84dbf37 100644 --- a/tools/TestViewer/test_tree.py +++ b/tools/TestViewer/test_tree.py @@ -1,3 +1,4 @@ +#pylint: disable=invalid-name,no-init """ An AbstractTreeItem implementation for a QTreeView that uses the results from test runners. """ @@ -8,8 +9,7 @@ import PyQt4.QtGui from PyQt4.QtGui import * import test_info -from test_info import TestSuite, TestSingle, TestProject, MultipleProjects -import random +from test_info import TestSuite, TestProject import datetime HORIZONTAL_HEADERS = ("Test", "Status", "Time (sec)", "Last Run") @@ -81,16 +81,19 @@ def get_background_color(state): elif state == test_info.TestResult.ALL_PASSED: col = MyColors.lightGreen - if state.old: col = MyColors.darkishGreen + if state.old: + col = MyColors.darkishGreen elif state == test_info.TestResult.ALL_FAILED or (state == test_info.TestResult.SOME_FAILED) \ or state == test_info.TestResult.ABORTED: col = QColor(Qt.red) - if state.old: col = QColor( 200, 50, 50 ) + if state.old: + col = QColor( 200, 50, 50 ) elif state == test_info.TestResult.BUILD_ERROR: col = QColor(Qt.magenta) - if state.old: col = desaturate(col, 0.5) + if state.old: + col = desaturate(col, 0.5) # elif state == test_info.TestResult.SOME_FAILED: # col = MyColors.lightRed @@ -293,7 +296,7 @@ class TestTreeModel(QtCore.QAbstractItemModel): # What background color? if role == Qt.BackgroundRole: - return item.background_color(); + return item.background_color() #User role is used when directly querying the contents of the item if role == Qt.UserRole: @@ -488,7 +491,7 @@ class TestTreeModel(QtCore.QAbstractItemModel): for k in xrange(num_tests): test_indx = self.index(k, 0, suite_indx) # Sets it as checked. - self.setData(test_indx, QtCore.Qt.Checked, QtCore.Qt.CheckStateRole); + self.setData(test_indx, QtCore.Qt.Checked, QtCore.Qt.CheckStateRole) def mouseDoubleClickEvent(self): print "mouseDoubleClickEvent" @@ -534,7 +537,7 @@ class TreeFilterProxyModel(QSortFilterProxyModel): return False if self.selected_only: if isinstance(item, TestProject) or isinstance(item, TestSuite) : - return (item.get_selected() > 0) + return item.get_selected() > 0 else: # Don't filter out TestSingles based on selection (since they're all selected) return True diff --git a/tools/TestViewer/ui_main_window.py b/tools/TestViewer/ui_main_window.py index 415f4cf3f0b9fc2ffc51ce79f3bb345c6d99e958..d33d69c8a7d567dd0f6e2337f7b286e84a9f8ab6 100644 --- a/tools/TestViewer/ui_main_window.py +++ b/tools/TestViewer/ui_main_window.py @@ -1,3 +1,4 @@ +#pylint: disable=invalid-name # -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'main_window.ui' diff --git a/tools/VTKConverter/VTKConvert.py b/tools/VTKConverter/VTKConvert.py index 161b2fe69d72aad166bbf001c659f96c95df070d..3048c2c46f2f3071bb0b9f104c26f61ca1d7706f 100644 --- a/tools/VTKConverter/VTKConvert.py +++ b/tools/VTKConverter/VTKConvert.py @@ -1,3 +1,4 @@ +#pylint: disable=invalid-name #! /usr/bin/python # Convert an acor file into VTK format (specifically a vtp file) from xml.dom import minidom @@ -10,19 +11,19 @@ def convertToVTU(infile, outpath): planelist=[] npoints = 0 for line in datafile: - numbers = line.split(); - if( len(numbers) != 4 ): + numbers = line.split() + if len(numbers) != 4 : continue - if( npoints == 0 ): + if npoints == 0 : curz = numbers[2] - if( numbers[2] != curz ): + if numbers[2] != curz : datalist.append(planelist) curz = numbers[2] planelist=[] planelist.append(numbers) npoints += 1 -# Append last set + # Append last set datalist.append(planelist) datafile.close() @@ -43,7 +44,7 @@ def convertToVTU(infile, outpath): piece.setAttribute( "NumberOfPoints", str(npoints)) piece.setAttribute( "NumberOfCells", str(ncells)) -# First the PointData element + # First the PointData element point_data = doc.createElement("PointData") piece.appendChild(point_data) point_data.setAttribute("Scalars", "Intensity") @@ -59,7 +60,7 @@ def convertToVTU(infile, outpath): txt = doc.createTextNode(str(point[3])) data_array.appendChild(txt) -# Now the Points element + # Now the Points element points = doc.createElement("Points") piece.appendChild(points) @@ -111,12 +112,12 @@ def convertToVTU(infile, outpath): txt = doc.createTextNode("4") data_array.appendChild(txt) -# #print doc.toprettyxml(newl="\n") + #print doc.toprettyxml(newl="\n") shortname = infile.split('/') name = outpath + shortname[len(shortname)-1] + ".vtu" - file = open(name,'w') - doc.writexml(file, newl="\n") - file.close() + handle = open(name,'w') + doc.writexml(handle, newl="\n") + handle.close() del datalist del planelist @@ -160,6 +161,6 @@ def writeParallelVTU(files, prefix): # print doc.toprettyxml(newl="\n") filename = prefix + files[0].split('.')[0] + ".pvtu" # print filename - file = open(filename,'w') - doc.writexml(file, newl="\n") - file.close() + handle = open(filename,'w') + doc.writexml(handle, newl="\n") + handle.close() diff --git a/tools/VTKConverter/processISISData.py b/tools/VTKConverter/processISISData.py index 7d00849ca3f3d570c99e3dc54354b7cbac107ff3..7a988d0adbbaab4180538af8c941ed45a67dca34 100644 --- a/tools/VTKConverter/processISISData.py +++ b/tools/VTKConverter/processISISData.py @@ -1,24 +1,25 @@ +#pylint: disable=invalid-name #!/usr/bin/python import os import sys import VTKConvert -if( len(sys.argv) == 1 ): +if len(sys.argv) == 1 : print "Usage: processISISData file-name1 file-name2 ...\n processISISDATA dir-name" exit(1) names=[] is_dir = os.path.isdir(sys.argv[1]) -if( is_dir ): +if is_dir : names = os.listdir(sys.argv[1]) else: for i in range(1,len(sys.argv)): names.append(sys.argv[i]) prefix="" -if( is_dir ): +if is_dir : prefix = sys.argv[1].split('/')[0] + "-VTU/" - if( os.path.isdir(prefix) ): + if os.path.isdir(prefix) : print "Directory " + prefix + " already exists, please move\n" exit(1) else: @@ -27,7 +28,7 @@ else: prefix = "./" for file in names: - if( is_dir ): + if is_dir : filename = sys.argv[1] + file VTKConvert.convertToVTU(filename, prefix) diff --git a/tools/reports/facility-code-changes.py b/tools/reports/facility-code-changes.py index 9233650ef8185ed9ed41966af314de8365b1dde4..f8f1e906cde51814c8d5fd820b323dceb9f08b5a 100644 --- a/tools/reports/facility-code-changes.py +++ b/tools/reports/facility-code-changes.py @@ -1,3 +1,4 @@ +#pylint: disable=invalid-name from __future__ import (absolute_import, division, print_function, unicode_literals) __author__ = 'Stuart Campbell' @@ -176,14 +177,14 @@ if __name__ == '__main__': print("Getting stats for {0}-{1:02d}".format(str(year), month)) since = "--since='{0}-{1}-1'".format(str(year), str(month)) until = "--before='{0}-{1}-{2}'".format(str(year), str(month), str(days_in_month[month-1])) - + date_key = str(year)+'-{0:02d}'.format(month) facility_commits[date_key] = {} facility_changed[date_key] = {} facility_added[date_key] = {} facility_removed[date_key] = {} - + freading = open('facility-file-changes-{0}.stdout'.format(date_key),'r',buffering=0) # initialize facility counters @@ -197,7 +198,7 @@ if __name__ == '__main__': changed = 0 added = 0 removed = 0 - + # Is the line blank (or None) if line is None or len(line) is 0: # print("BLANK:'{0}'".format(str(line))) diff --git a/tools/reports/release-list.py b/tools/reports/release-list.py index f6a48764d64dbeade4b1df4a4ed9dfb7e7a93045..a74995bfa317d57197b2f7726be302e138e8ff08 100644 --- a/tools/reports/release-list.py +++ b/tools/reports/release-list.py @@ -1,3 +1,4 @@ +#pylint: disable=invalid-name from __future__ import (absolute_import, division, print_function, unicode_literals) import csv diff --git a/tools/scripts/AddAlgorithmWikiLinksToText.py b/tools/scripts/AddAlgorithmWikiLinksToText.py deleted file mode 100644 index e372fe01a3384d8b37ac4b5f1dbb15028a8f6810..0000000000000000000000000000000000000000 --- a/tools/scripts/AddAlgorithmWikiLinksToText.py +++ /dev/null @@ -1,17 +0,0 @@ -text = """ -===Algorithms=== -* PlotPeakByLogValue now optionally outputs calculated spectra like the Fit algorithm. -* StartLiveData now checks whether the instrument listener supports the provision of historic values. -* LiveData processing now handles the transition between runs much better at facilities that support this functionality (at present only the SNS). -* LoadEventNexus reads the Pause log and discards any events found during Paused time spans. -* GenerateEventsFilter has been improved to make it easier to use and allowing split sections to be added together into workplaces on a cyclic basis. -* LoadPreNexus is now more forgiving if it encounters bad event indexes in pulse ID file . - -""" - -import re - -algs = AlgorithmFactory.getRegisteredAlgorithms(True) -for alg in algs: - text = re.sub(r'\b' + alg+ r'\b',r'[http://docs.mantidproject.org/algorithms/' + alg + '.html ' + alg + '] ',text) -print text \ No newline at end of file diff --git a/tools/scripts/ConvertBadAlgmLinks.py b/tools/scripts/ConvertBadAlgmLinks.py index 4d7d71e86989bbaa469f1535c5510afdd5ce52ee..6759d9d23b3b5bdf2004bd2afeb048e9b6edd5c4 100644 --- a/tools/scripts/ConvertBadAlgmLinks.py +++ b/tools/scripts/ConvertBadAlgmLinks.py @@ -1,3 +1,4 @@ +#pylint: disable=invalid-name import re, glob, os def grep(patt,lines): @@ -30,13 +31,13 @@ for filename in files: #print os.path.basename(filename)[:-4] with open(filename) as file: - lines = file.readlines() - for alg in algs: - expr = regexs[alg] - results = grep(expr, lines) - if results: - print filename - print results + lines = file.readlines() + for alg in algs: + expr = regexs[alg] + results = grep(expr, lines) + if results: + print filename + print results diff --git a/tools/scripts/ConvertToRST/ConvertWikiPage.py b/tools/scripts/ConvertToRST/ConvertWikiPage.py deleted file mode 100644 index 696cb94f8c0c04968d309297b3ee10bea224d892..0000000000000000000000000000000000000000 --- a/tools/scripts/ConvertToRST/ConvertWikiPage.py +++ /dev/null @@ -1,284 +0,0 @@ -########################################################################################### -# Converts mediawiki pages to rst pages for sphinx. -# run with -h for command line arguments -# -# sample command C:\MantidInstall\bin\python.exe C:/Mantid/tools/scripts/ConvertToRST/ConvertWikiPage.py -# -o C:/Mantid/Code/Mantid/docs/source/training/MBC_Displaying_data_Formatting.rst -# -# pandoc must be installed an in the path -# -# extends pandoc by downloading and correcting image links, and adding links for algorithms, -# fit functions and common concepts (workspace types) -# -# Limitations: -# 1. in adding text to links or images in tables the table formatting will be disrupted -# 2. pandoc creates some images in an inline format, these cannot have the align tags added -# back on, this is marked with a comment, the solution is probably to move the image from -# the inline to normal format. -# 3. Image links cannot have spaces in the filename in rst. -# The spaces are removed in the downloaded file names, but not the links in the rst files. -# -########################################################################################## -import os -import re -import sys -import urllib2 -import urlparse -import argparse -import subprocess -import mantid - -def readWebPage(url): - # set your environment HTTP_PROXY to be your proxy - # for ral HTTP_PROXY=http://wwwcache.rl.ac.uk:8080 - aResp = urllib2.urlopen(url) - web_pg = aResp.read() - return web_pg - -def downloadImage(imgUrl, filePath): - downloadedImage = file(filePath, "wb") - - imageOnWeb = urllib2.urlopen(imgUrl) - while True: - buf = imageOnWeb.read(65536) - if len(buf) == 0: - break - downloadedImage.write(buf) - downloadedImage.close() - imageOnWeb.close() - - return filePath - -def convertURLToRaw(url): - return url + "?action=raw" - -def covertMediaWikiToRST(url): - cmd = 'pandoc -f mediawiki -t rst "' + url + '"' - print cmd - - return runProcess(cmd) - -def runProcess(cmd): - # instantiate a startupinfo obj: - startupinfo = subprocess.STARTUPINFO() - # set the use show window flag, might make conditional on being in Windows: - startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW - - p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, - startupinfo=startupinfo) - output, error = p.communicate() - output = output.replace("\r\n","\n") - print error - return output - -def processImageLinks(mediawikiText,rstText, imagePath, relImagePath): - retRstText = rstText - mwImagePattern = re.compile(r'\[\[(Image|File):(.+?)(\|.*?)?(\|.*?)?(\|.*?)?(\|.*?)?(\|.*?)?(\|.*?)?\]\]', - re.IGNORECASE) - rstImagePattern = re.compile(r'figure:: (([\w\-\_\\\/]+)\.(\w{2,5}))(.{0,50}\3){2}', - re.DOTALL) - rstSubstitutionImagePattern = re.compile(r'(figure|image):: (([\w\-\_\\\/]+)\.(\w{2,5}))') - - - imgLinkDict ={} - #for all of the mediawiki links - for m in re.finditer(mwImagePattern, mediawikiText): - print ("processing image link",m.group(0)) - rstLink = generateRstImageLink(m,relImagePath) - imgLinkDict[m.group(2)] = rstLink - print (rstLink) - - #for all of the rst figure links - replacements = [] - for m in re.finditer(rstImagePattern, retRstText): - rstLink = imgLinkDict[m.group(1)] - replacements.append((m.start(), m.end(), m.group(1), rstLink)) - - #perform replacements in reverse order - for (start,end,imagefile,rstLink) in reversed(replacements): - retRstText = retRstText[0:start] + rstLink + retRstText[end:] - - replacements = [] - for m in re.finditer(rstSubstitutionImagePattern, retRstText): - rstLink = imgLinkDict[m.group(2)] - rstLink = cleanInlineImagesDefinition(rstLink) - replacements.append((m.start(), m.end(), m.group(2), rstLink)) - - #perform replacements in reverse order - for (start,end,imagefile,rstLink) in reversed(replacements): - retRstText = retRstText[0:start] + rstLink + retRstText[end:] - - #get all of the image files - for imageName in imgLinkDict.keys(): - saveImageFromMW(imageName,imagePath) - - - return retRstText - -def saveImageFromMW(imageName,path): - url = "http://www.mantidproject.org/File:"+imageName.replace(" ","_") - print "Downloading image: ", url - imagePage = readWebPage(url) - mwImagePattern = re.compile(r'<div class="fullImageLink" id="file"><a href="([\/\w\.\-]+)">') - - imagePath = path + "/" + imageName.replace(" ","") - - match = re.search(mwImagePattern,imagePage) - if match is not None: - imageURL = match.group(1) - imageURL = "http://www.mantidproject.org" + imageURL - if not os.path.exists(imagePath): - print "saving ", imageName, "to", imagePath - downloadImage(imageURL,imagePath) - -def generateRstImageLink(match,relImagePath): - link = "image:: " + relImagePath+ "/" + match.group(2) + "\n" - for i in range(3,len(match.groups())): - if match.group(i) is None: - break - #strip off the first character as it is the | pipe - imageOption = addImageOption(match.group(i)[1:]) - if imageOption is not None: - link += "\t\t\t" + imageOption + "\n" - return link - -def addImageOption(mwImageOption): - imageOption = mwImageOption.strip() - if len(imageOption)>0: - if imageOption.endswith("px"): - return ":width: " + imageOption - elif imageOption in ["right","left","middle","centre"]: - return ":align: " + imageOption - else: - return ":alt: " + imageOption - -def cleanInlineImagesDefinition(rstLink): - match = re.search(r'^\s+:align:\s+\w+\s*$',rstLink,re.MULTILINE) - if match is not None: - #take the align out - rstLink = rstLink[0:match.start()] + rstLink[match.end()+1:] - #then add it at the end as a comment - rstLink += ".. FIXME (inline definition does not allow align)" + match.group(0) - return rstLink - -def ensureDirectoriesExist(path): - try: - os.makedirs(path) - except OSError: - pass - -def addLocalLinks(rstText,list,prefix): - retRstText = rstText - #build regex string for simple words - regex = r"[^`<]((\*{0,2})(\b" + r"\b|\b".join(list) + r"\b)\2)[^`_]" - pattern = re.compile(regex) - - replacements = [] - for m in re.finditer(pattern, retRstText): - rstLink = ":ref:`" + m.group(3) + " <" + prefix + m.group(3) + ">`" - print ("processing new link",m.group(1), rstLink) - replacements.append((m.start(1), m.end(1), m.group(1), rstLink)) - - #perform replacements in reverse order - for (start,end,item,rstLink) in reversed(replacements): - retRstText = retRstText[0:start] + rstLink + retRstText[end:] - - #build regex string for links - regexLink = r"`(.+?)<(\b" + r"\b|\b".join(list) + r"\b)>`__" - patternLink = re.compile(regexLink) - replacements = [] - for m in re.finditer(patternLink, retRstText): - rstLink = ":ref:`" + m.group(1) + " <" + prefix + m.group(2) + ">`" - print ("processing existing link",m.group(0), rstLink) - replacements.append((m.start(), m.end(), m.group(0), rstLink)) - - #perform replacements in reverse order - for (start,end,item,rstLink) in reversed(replacements): - retRstText = retRstText[0:start] + rstLink + retRstText[end:] - - return retRstText - -def fixUnderscoresInRefLinks(rstText): - retRstText = rstText - retRstText = re.sub(r"\b\\\_","_",retRstText) - - return retRstText - -################################################################################################################ - -parser = argparse.ArgumentParser(description='Converts mediawiki pages to rst pages for sphinx.') -parser.add_argument('inputURL', help='the url of a mediawiki page') -parser.add_argument('-o', '--o', - help='Provide a path to output to a file') -parser.add_argument('-i', '--i', - help='Provide a relative path from the file to the images directory') -parser.add_argument('-rp', '--rp', - help='Provide a reference link prefix') -parser.add_argument('-r', '--r', - help='Provide a reference link') - -args = parser.parse_args() -print args.inputURL -print args.o - -urlSegments = urlparse.urlparse(args.inputURL) -pageName = urlSegments.path[1:] -print "Parsing ", pageName - -#run pandoc and get the output in rst -mediawikiText = readWebPage(convertURLToRaw(args.inputURL)) - -#run pandoc and get the output in rst -rstText = covertMediaWikiToRST(convertURLToRaw(args.inputURL)) - -#print "*****************" -#print rstText -#print "*****************" - -relPath = "../images" -if args.i is not None: - relPath = os.path.dirname(args.i) -outDir = os.curdir -if args.o is not None: - outDir = os.path.dirname(args.o) - -imagePath = os.path.join(outDir,relPath) -imagePath = os.path.abspath(imagePath) -print imagePath, outDir - -ensureDirectoriesExist(imagePath) -ensureDirectoriesExist(outDir) - -#perform any processing beyond pandoc -rstText = fixUnderscoresInRefLinks(rstText) - -rstText = processImageLinks(mediawikiText,rstText, imagePath, relPath) - -wsList = ['EventWorkspace','MatrixWorkspace','PeaksWorkspace','MDWorkspace','Table Workspaces','WorkspaceGroup', - 'RectangularDetector','RAW File','Facilities File','FitConstraint','Framework Manager', - 'Instrument Data Service','InstrumentDefinitionFile','InstrumentParameterFile','Properties File', - 'MDHistoWorkspace','MDNorm','Nexus file','PeaksWorkspace','Point and space groups','RAW File' - 'Shared Pointer','Symmetry groups','Unit Factory','UserAlgorithms','Workflow Algorithm', - 'Workspace','Workspace2D','WorkspaceGroup'] -rstText = addLocalLinks(rstText,wsList,"") - -algList = mantid.AlgorithmFactory.getRegisteredAlgorithms(False).keys() -rstText = addLocalLinks(rstText,algList,"algm-") - -funcList = mantid.FunctionFactory.getFunctionNames() -rstText = addLocalLinks(rstText,funcList,"func-") - -#add reference name -refPrefix = "train-" -if args.rp is not None: - refPrefix = args.rp -refName = pageName -if args.r is not None: - refName = args.r -rstText = ".. _" + refPrefix + refName + ":\n\n" + rstText - -#save output -if args.o is not None: - sys.stdout = open(args.o, 'w') -print rstText - diff --git a/tools/scripts/CorrectConceptLinksinAlgPages.py b/tools/scripts/CorrectConceptLinksinAlgPages.py index 700472f0529451dd752ec48008bf364e34f51806..7dcd787a465a2a84151c64ec152e6b0f2ba720c7 100644 --- a/tools/scripts/CorrectConceptLinksinAlgPages.py +++ b/tools/scripts/CorrectConceptLinksinAlgPages.py @@ -1,51 +1,52 @@ +#pylint: disable=invalid-name import os, re import urllib2 concepts = ['Algorithm', -'Analysis_Data_Service', -'categories', -'Create_an_IDF', -'Data_Service', -'Dynamic_Factory', -'Error_Propagation', -'EventWorkspace', -'Facilities_File', -'FitConstraint', -'Framework_Manager', -'Geometry', -'Geometry_of_Position', -'Geometry_of_Shape', -'HowToDefineGeometricShape', -'index', -'Instrument', -'InstrumentDefinitionFile', -'InstrumentParameterFile', -'Instrument_Data_Service', -'Lattice', -'LET_Sample_IDF', -'MatrixWorkspace', -'MDHistoWorkspace', -'MDWorkspace', -'Nexus_file', -'Plugin', -'Project', -'Properties', -'Properties_File', -'RAW_File', -'Run', -'SANS2D_Sample_IDF', -'Shared_Pointer', -'Table_Workspaces', -'Unit_Factory', -'UserAlgorithms', -'Workflow_Algorithm', -'Workspace', -'Workspace2D', -'WorkspaceGroup'] + 'Analysis_Data_Service', + 'categories', + 'Create_an_IDF', + 'Data_Service', + 'Dynamic_Factory', + 'Error_Propagation', + 'EventWorkspace', + 'Facilities_File', + 'FitConstraint', + 'Framework_Manager', + 'Geometry', + 'Geometry_of_Position', + 'Geometry_of_Shape', + 'HowToDefineGeometricShape', + 'index', + 'Instrument', + 'InstrumentDefinitionFile', + 'InstrumentParameterFile', + 'Instrument_Data_Service', + 'Lattice', + 'LET_Sample_IDF', + 'MatrixWorkspace', + 'MDHistoWorkspace', + 'MDWorkspace', + 'Nexus_file', + 'Plugin', + 'Project', + 'Properties', + 'Properties_File', + 'RAW_File', + 'Run', + 'SANS2D_Sample_IDF', + 'Shared_Pointer', + 'Table_Workspaces', + 'Unit_Factory', + 'UserAlgorithms', + 'Workflow_Algorithm', + 'Workspace', + 'Workspace2D', + 'WorkspaceGroup'] def outputError(alg, algVersion, description, notes=""): - print "%s, %i, %s, %s" % (alg, algVersion, description, notes) + print "%s, %i, %s, %s" % (alg, algVersion, description, notes) rstdir = r"C:\Mantid\Code\Mantid\docs\source\algorithms" conceptsPattern = {} @@ -61,17 +62,17 @@ for alg in algs: fileFound = False filename = os.path.join(rstdir,alg + "-v" + str(algVersion) + ".rst") if os.path.exists(filename): - algText = "" - with open (filename, "r") as algRst: - fileFound = True - algText = algRst.read() - for concept in concepts: - regex = conceptsPattern[concept] - while (regex.search(algText) != None): - outputError(alg, algVersion, "found", concept) - algText = regex.sub(r":ref:`\1 <\2>`",algText) + algText = "" + with open (filename, "r") as algRst: + fileFound = True + algText = algRst.read() + for concept in concepts: + regex = conceptsPattern[concept] + while regex.search(algText) != None: + outputError(alg, algVersion, "found", concept) + algText = regex.sub(r":ref:`\1 <\2>`",algText) with open (filename, "w") as algRst: - algRst.write(algText) + algRst.write(algText) if fileFound==False: outputError(alg, algVersion, "File not found") diff --git a/tools/scripts/FindIncompleteAlgRSTPages.py b/tools/scripts/FindIncompleteAlgRSTPages.py index 27cd76c148f5d5c5450578f75e745419e65fe5b5..f4d05d10629102eab5eb160a5ed24eb1b0ff7749 100644 --- a/tools/scripts/FindIncompleteAlgRSTPages.py +++ b/tools/scripts/FindIncompleteAlgRSTPages.py @@ -1,26 +1,27 @@ +#pylint: disable=invalid-name import os, re import urllib2 def readWebPage(url): - proxy = urllib2.ProxyHandler({'http': 'wwwcache.rl.ac.uk:8080'}) - opener = urllib2.build_opener(proxy) - urllib2.install_opener(opener) - aResp =urllib2.urlopen(url) - web_pg = aResp.read(); - return web_pg + proxy = urllib2.ProxyHandler({'http': 'wwwcache.rl.ac.uk:8080'}) + opener = urllib2.build_opener(proxy) + urllib2.install_opener(opener) + aResp =urllib2.urlopen(url) + web_pg = aResp.read() + return web_pg def ticketExists(alg, ticketHash): - retVal = "" - algPattern = re.compile(alg, re.IGNORECASE) - for ticket in ticketHash: - ticketText = ticketHash[ticket] - if algPattern.search(ticketText): - retVal = str(ticket) - break - return retVal + retVal = "" + algPattern = re.compile(alg, re.IGNORECASE) + for ticket in ticketHash: + ticketText = ticketHash[ticket] + if algPattern.search(ticketText): + retVal = str(ticket) + break + return retVal def outputError(alg, algVersion, description, notes=""): - print "%s, %i, %s, %s" % (alg, algVersion, description, notes) + print "%s, %i, %s, %s" % (alg, algVersion, description, notes) rstdir = r"C:\Mantid\Code\Mantid\docs\source\algorithms" ticketList = [9582,9586,9607,9610,9704,9804,9726] @@ -39,13 +40,12 @@ for alg in algs: fileFound = False filename = os.path.join(rstdir,alg + "-v" + str(algVersion) + ".rst") if os.path.exists(filename): - with open (filename, "r") as algRst: - fileFound = True - algText = algRst.read() - if (usagePattern.search(algText) == None) and (excusesPattern.search(algText) == None): - #check if already in a ticket - usageTicket = ticketExists(alg,ticketHash) - outputError(alg, algVersion, "No usage section", usageTicket) + with open (filename, "r") as algRst: + fileFound = True + algText = algRst.read() + if (usagePattern.search(algText) == None) and (excusesPattern.search(algText) == None): + #check if already in a ticket + usageTicket = ticketExists(alg,ticketHash) + outputError(alg, algVersion, "No usage section", usageTicket) if fileFound==False: - outputError(alg, algVersion, "File not found") - + outputError(alg, algVersion, "File not found") diff --git a/tools/scripts/TestWikiPython.py b/tools/scripts/TestWikiPython.py index ff44eabe84669c17f9de58bd14b2ee19f5153da7..63d0e4b367106c17a36bebcbf2cdb8caec1f337b 100644 --- a/tools/scripts/TestWikiPython.py +++ b/tools/scripts/TestWikiPython.py @@ -1,3 +1,4 @@ +#pylint: disable=invalid-name ########################################################################################### # Extracts code blocks marked as python from mediawiki pages and checks they run # run with -h for command line arguments @@ -7,7 +8,6 @@ import os import re import sys import urllib2 -import urlparse import argparse import json @@ -31,6 +31,7 @@ def getTestablePages(url): def convertURLToRaw(url): return url.replace(" ","%20") + "?action=raw" + def writeTestRst(filepath,mediawikiText,pageName): ''' for a block of wiki text, writes out all tests found to an rst page @@ -133,7 +134,7 @@ parser.add_argument('-o', '--o', help='Provide a path to output to an output directory') args = parser.parse_args() -urlList = []; +urlList = [] baseUrl = "http://www.mantidproject.org/" if args.s is not None: baseUrl = args.s @@ -164,6 +165,3 @@ for url in urlList: #run pandoc and get the output in rst mediawikiText = readWebPage(convertURLToRaw(baseUrl + url)) writeTestRst(outputFile,mediawikiText,pageName) - - - diff --git a/tools/scripts/extractAlgorithmNames.py b/tools/scripts/extractAlgorithmNames.py index 05120ece167861601920362aa08ca0105a6bda7e..8945b898c9e698c5c3d261c1d0ba9d35ad42635e 100644 --- a/tools/scripts/extractAlgorithmNames.py +++ b/tools/scripts/extractAlgorithmNames.py @@ -1,17 +1,14 @@ +#pylint: disable=invalid-name # simply just print out all algorithm names in a directory which can be piped # to a file -import string, os, re - import glob -import mmap - os.chdir("PythonInterface/plugins/algorithms/WorkflowAlgorithms") -for file in glob.glob("*.py"): +for filename in glob.glob("*.py"): #print file - if 'PythonAlgorithm' in open(file).read(): - print file + if 'PythonAlgorithm' in open(filename).read(): + print filename #os.chdir("LiveData/src") @@ -19,4 +16,3 @@ for file in glob.glob("*.py"): # #print file # if 'DECLARE_ALGORITHM' in open(file).read(): # print file - diff --git a/tools/scripts/extractAuthorNamesFromGit.py b/tools/scripts/extractAuthorNamesFromGit.py index ee6bf1e2eceb5ff853dc9c5baa93a86814ee91d0..728ac36dadd8f2cc94f81df3cf512a7f4f4b93bb 100644 --- a/tools/scripts/extractAuthorNamesFromGit.py +++ b/tools/scripts/extractAuthorNamesFromGit.py @@ -1,3 +1,4 @@ +#pylint: disable=invalid-name # This python script is run after running extractAlgorithmNames.py, where # the output of that script is saved to a *.txt # @@ -18,7 +19,7 @@ allAlgs = [line.strip() for line in open(algorithmList)] os.chdir('PythonInterface/plugins/algorithms/WorkflowAlgorithms') for line in allAlgs: #print line - fullline = line + fullline = line args = [ 'git', 'log', '--pretty=short', @@ -30,11 +31,11 @@ for line in allAlgs: authors = subprocess.check_output(args).replace('"', '').split('\n') authors = set(authors) authors = authors - set(['']) - + for author in authors: #print author fullline = fullline + ", " + author - + print fullline #line = 'GroupWorkspaces.cpp' @@ -54,5 +55,5 @@ for line in allAlgs: #for author in authors: #print author # fullline = fullline + ", " + author - + #print fullline diff --git a/tools/skipped_systemtests.py b/tools/skipped_systemtests.py index c13d3e140d18102f3e4e847377f2ebcaacca1c8b..3ffdb9fb5837d1c055e93e8f019d11e31384d56e 100755 --- a/tools/skipped_systemtests.py +++ b/tools/skipped_systemtests.py @@ -1,3 +1,4 @@ +#pylint: disable=invalid-name #!/usr/bin/env python import ast @@ -33,7 +34,7 @@ def addTestResult(results, case, label): def printResultCell(mark, length): - if (mark): + if mark: left = int(length/2) right = length-left-1 print "%sx%s" % (' '*left, ' '*right),