diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index cb76fa46d12f841d1b5ee2f6f599720d197b6446..b9bbbac114cf4398acf75cbfec18f6bd9d203c4a 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,8 +1,8 @@ -The [developer documentation](http://www.mantidproject.org/Category:Development) has information on how to participate in the mantid project as a developer. This document is meant to outline the steps for contributing to mantid without becomming a developer. We aspire to have similar guidelines as [github](https://github.com/blog/1943-how-to-write-the-perfect-pull-request). +The [developer documentation](http://developer.mantidproject.org/) has information on how to participate in the mantid project as a developer. This document is meant to outline the steps for contributing to mantid without becomming a developer. We aspire to have similar guidelines as [github](https://github.com/blog/1943-how-to-write-the-perfect-pull-request). 1. [Fork](https://help.github.com/articles/fork-a-repo) the repository. *recommended:* Delete all branches other than `master`. This makes it easier to see what is in your fork later. 2. Clone the repository with the remotes `origin` pointing at your fork as `origin` and `mantidproject/mantid` as `upstream`. This is a [common setup](https://help.github.com/articles/configuring-a-remote-for-a-fork/). - 3. Make changes as you see fit. Please still follow the guidelines for [running the unit tests](http://www.mantidproject.org/Running_the_unit_tests) and the [build servers](http://www.mantidproject.org/The_automated_build_process). + 3. Make changes as you see fit. Please still follow the guidelines for [running the unit tests](http://developer.mantidproject.org/RunningTheUnitTests.html) and the [build servers](http://developer.mantidproject.org/AutomatedBuildProcess.html). 4. Submit a [pull request](https://help.github.com/articles/using-pull-requests) to this branch. This is a start to the conversation. 7. (Optional) email mantid-help@mantidproject.org requests to. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index f2a9331c7f867a4fc927dc4208dc5c038d649701..e229daad59c9b3566f585415c8178d10e1510a2f 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -19,7 +19,7 @@ Fixes #xxxx. <!-- and fix #xxxx or close #xxxx xor resolves #xxxx --> #### Reviewer #### -Please comment on the following ([full description](http://www.mantidproject.org/Individual_Ticket_Testing)): +Please comment on the following ([full description](http://developer.mantidproject.org/IndividualTicketTesting/)): ##### Code Review ##### diff --git a/.gitignore b/.gitignore index 07c6b866b6a40cebb9a12c58a6095cde08701e0e..0bf82370fc12d12d98df4433da272ee489769c11 100644 --- a/.gitignore +++ b/.gitignore @@ -177,7 +177,8 @@ Desktop.ini #Dynamically created files Framework/Kernel/inc/MantidKernel/GitHubApiHelper.h Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/LibHelper.h - +qt/applications/workbench/setup.py +qt/python/setup.py # Make sure Third_Party doesn't get checked into the main repository Third_Party/ diff --git a/CMakeLists.txt b/CMakeLists.txt index cbf238f3ac687378183395e565d967e9bc5d3bd6..ccade423d537682f25e723a062a5cbd298eec9c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,17 +17,19 @@ if (POLICY CMP0072) endif () # System package target is important for the windows builds as it allows us to package only the dlls and exes and exclude libs. Defaults to empty for other platforms. -set ( SYSTEM_PACKAGE_TARGET "") +set ( SYSTEM_PACKAGE_TARGET "" ) # Add the path to our custom 'find' modules set ( CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/buildconfig/CMake") -set ( ENABLE_MANTIDPLOT ON CACHE BOOL "Switch for compiling the Qt4-based gui & components") -# TODO: Switch this on by default when the builders all have Qt5 installed -set ( ENABLE_WORKBENCH OFF CACHE BOOL "Switch for compiling the Qt5-based gui & components") +set ( ENABLE_MANTIDPLOT ON CACHE BOOL "Enable Qt4-based gui & components" ) +set ( ENABLE_WORKBENCH OFF CACHE BOOL "Enable Qt5-based gui & components" ) +set ( PACKAGE_WORKBENCH OFF CACHE BOOL "If packaging is enabled then include the Qt-5 workbench in the package" ) +if ( PACKAGE_WORKBENCH AND NOT ENABLE_WORKBENCH ) + message ( FATAL_ERROR "Packaging workbench requested but workbench build is disabled!" ) +endif () -set ( CPACK_INSTALL_CMAKE_PROJECTS - "${CMAKE_BINARY_DIR}" "Mantid" "ALL" "/" ) +set ( CPACK_INSTALL_CMAKE_PROJECTS "${CMAKE_BINARY_DIR}" "Mantid" "ALL" "/" ) ########################################################################### # Quick exit if we only want data targets @@ -304,6 +306,9 @@ if ( ENABLE_CPACK ) # scipy set ( CPACK_RPM_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES},scipy" ) set ( CPACK_RPM_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES},mxml,hdf,hdf5,jsoncpp >= 0.7.0" ) + if (ENABLE_WORKBENCH) + set ( CPACK_RPM_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES},python-qt5" ) + endif() if( "${UNIX_CODENAME}" MATCHES "Santiago" ) # RHEL6 # On RHEL6 we have to use an updated qscintilla to fix an auto complete bug @@ -371,6 +376,13 @@ if ( ENABLE_CPACK ) list (REMOVE_ITEM DEPENDS_LIST "python-nxs (>= 4.3),") string ( REPLACE "python-" "python3-" DEPENDS_LIST ${DEPENDS_LIST} ) string ( REPLACE "python3-qt4" "python3-pyqt4" DEPENDS_LIST ${DEPENDS_LIST} ) + if (ENABLE_WORKBENCH) + set ( APPEND DEPENDS_LIST ",python3-qt5" ) + endif() + else() + if (ENABLE_WORKBENCH) + set ( APPEND DEPENDS_LIST ",pyqt5" ) + endif() endif () # parse list to string required for deb package string ( REPLACE ";" "" CPACK_DEBIAN_PACKAGE_DEPENDS ${DEPENDS_LIST} ) diff --git a/Framework/API/CMakeLists.txt b/Framework/API/CMakeLists.txt index 3fa7bdf8ff6ad8ad41ae13c977defe2ce4c8d3d3..78facd863b5900e0b3421ebd50e7b08a7b11d097 100644 --- a/Framework/API/CMakeLists.txt +++ b/Framework/API/CMakeLists.txt @@ -111,6 +111,7 @@ set ( SRC_FILES src/NullCoordTransform.cpp src/NumericAxis.cpp src/NumericAxisValidator.cpp + src/OrientedLatticeValidator.cpp src/ParallelAlgorithm.cpp src/ParamFunction.cpp src/ParameterReference.cpp @@ -310,6 +311,7 @@ set ( INC_FILES inc/MantidAPI/NullCoordTransform.h inc/MantidAPI/NumericAxis.h inc/MantidAPI/NumericAxisValidator.h + inc/MantidAPI/OrientedLatticeValidator.h inc/MantidAPI/ParallelAlgorithm.h inc/MantidAPI/ParamFunction.h inc/MantidAPI/ParameterReference.h @@ -435,6 +437,7 @@ set ( TEST_FILES NotebookWriterTest.h NumericAxisTest.h NumericAxisValidatorTest.h + OrientedLatticeValidatorTest.h ParamFunctionAttributeHolderTest.h ParameterReferenceTest.h ParameterTieTest.h diff --git a/Framework/API/inc/MantidAPI/OrientedLatticeValidator.h b/Framework/API/inc/MantidAPI/OrientedLatticeValidator.h new file mode 100644 index 0000000000000000000000000000000000000000..edceaeb05f25b2c0d5a10cc5c54c976266b4bf43 --- /dev/null +++ b/Framework/API/inc/MantidAPI/OrientedLatticeValidator.h @@ -0,0 +1,52 @@ +#ifndef MANTID_API_ORIENTEDLATTICEVALIDATOR_H +#define MANTID_API_ORIENTEDLATTICEVALIDATOR_H + +#include "MantidAPI/DllConfig.h" +#include "MantidAPI/ExperimentInfo.h" +#include "MantidKernel/TypedValidator.h" + +/** + A validator which checks that a workspace has an oriented lattice attached to + it. + + 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> +*/ +namespace Mantid { +namespace API { +class MANTID_API_DLL OrientedLatticeValidator + : public Kernel::TypedValidator<ExperimentInfo_sptr> { +public: + /// Gets the type of the validator + std::string getType() const { return "orientedlattice"; } + /// Clone the current state + Kernel::IValidator_sptr clone() const override; + +private: + /// Check for validity. + std::string + checkValidity(const ExperimentInfo_sptr &workspace) const override; +}; + +} // namespace API +} // namespace Mantid + +#endif // MANTID_API_ORIENTEDLATTICEVALIDATOR_H diff --git a/Framework/API/src/OrientedLatticeValidator.cpp b/Framework/API/src/OrientedLatticeValidator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2aedef2bb82b5b591af75d7508c55c779e8e852c --- /dev/null +++ b/Framework/API/src/OrientedLatticeValidator.cpp @@ -0,0 +1,34 @@ +#include "MantidAPI/OrientedLatticeValidator.h" +#include "MantidAPI/ExperimentInfo.h" +#include "MantidAPI/Sample.h" +#include "MantidKernel/IValidator.h" +#include <boost/make_shared.hpp> + +using Mantid::Kernel::IValidator_sptr; + +namespace Mantid { +namespace API { + +/** + * Clone the current state + */ +Kernel::IValidator_sptr OrientedLatticeValidator::clone() const { + return boost::make_shared<OrientedLatticeValidator>(*this); +} + +/** Checks that workspace has an oriented lattice. + * + * @param info :: The experiment info to check for an oriented lattice. + * @return A user level description of the error or "" for no error + */ +std::string +OrientedLatticeValidator::checkValidity(const ExperimentInfo_sptr &info) const { + if (!info->sample().hasOrientedLattice()) { + return "Workspace must have a sample with an orientation matrix defined."; + } else { + return ""; + } +} + +} // namespace API +} // namespace Mantid diff --git a/Framework/API/test/OrientedLatticeValidatorTest.h b/Framework/API/test/OrientedLatticeValidatorTest.h new file mode 100644 index 0000000000000000000000000000000000000000..15056f1f8b37447ece1a6d9533cece0635007f95 --- /dev/null +++ b/Framework/API/test/OrientedLatticeValidatorTest.h @@ -0,0 +1,47 @@ +#ifndef MANTID_ORIENTEDLATTICEVALIDATOR_TEST_H +#define MANTID_ORIENTEDLATTICEVALIDATOR_TEST_H + +#include <boost/make_shared.hpp> +#include <cxxtest/TestSuite.h> + +#include "MantidAPI/ExperimentInfo.h" +#include "MantidAPI/OrientedLatticeValidator.h" +#include "MantidAPI/Sample.h" +#include "MantidGeometry/Crystal/OrientedLattice.h" +#include "MantidTestHelpers/FakeObjects.h" + +class OrientedLatticeValidatorTest : 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 OrientedLatticeValidatorTest *createSuite() { + return new OrientedLatticeValidatorTest(); + } + static void destroySuite(OrientedLatticeValidatorTest *suite) { + delete suite; + } + + void test_getType() { + OrientedLatticeValidator validator; + TS_ASSERT_EQUALS(validator.getType(), "orientedlattice") + } + + void test_isValid_is_valid_when_latticeDefined() { + OrientedLattice lattice; + auto info = boost::make_shared<ExperimentInfo>(); + info->mutableSample().setOrientedLattice(&lattice); + + OrientedLatticeValidator validator; + TS_ASSERT_EQUALS(validator.isValid(info), ""); + }; + + void test_isValid_is_invalid_when_latticeUndefined() { + auto info = boost::make_shared<ExperimentInfo>(); + OrientedLatticeValidator validator; + TS_ASSERT_EQUALS( + validator.isValid(info), + "Workspace must have a sample with an orientation matrix defined."); + }; +}; + +#endif // MANTID_ORIENTEDLATTICEVALIDATOR_TEST_H diff --git a/Framework/DataHandling/src/SaveGSS.cpp b/Framework/DataHandling/src/SaveGSS.cpp index e0553f416d692b38d431ceb1e0761c50fc62ec84..ed411a29fc9d03ef67682d7ae4c75e0577bf29ef 100644 --- a/Framework/DataHandling/src/SaveGSS.cpp +++ b/Framework/DataHandling/src/SaveGSS.cpp @@ -9,6 +9,7 @@ #include "MantidKernel/ArrayLengthValidator.h" #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/CompositeValidator.h" +#include "MantidKernel/Exception.h" #include "MantidKernel/ListValidator.h" #include "MantidKernel/PhysicalConstants.h" #include "MantidKernel/TimeSeriesProperty.h" @@ -668,13 +669,11 @@ void SaveGSS::openFileStream(const std::string &outFilePath, // Have to wrap this in a unique pointer as GCC 4.x (RHEL 7) does // not support the move operator on iostreams outStream.open(outFilePath, mode); - if (outStream.fail()) { // Get the error message from library and log before throwing const std::string error = strerror(errno); - g_log.error("Failed to open file. Error was: " + error); - throw std::runtime_error("Could not open the file at the following path: " + - outFilePath); + throw Kernel::Exception::FileError( + "Failed to open file. Error was: " + error, outFilePath); } // Stream is good at this point @@ -751,21 +750,6 @@ std::map<std::string, std::string> SaveGSS::validateInputs() { return result; } -namespace { // anonymous -// throw an exception if file cannot be written -void checkWritable(const std::string &filename) { - const auto fileobj = Poco::File(filename); - if (fileobj.exists()) { - if (!fileobj.canWrite()) - throw std::runtime_error("Cannot write to " + filename); - } else { - const auto pathobj = Poco::Path(filename).makeAbsolute().parent(); - if (!Poco::File(pathobj.toString()).canWrite()) - throw std::runtime_error("Cannot write to " + pathobj.toString()); - } -} -} // namespace - /** * Writes all the spectra to the file(s) from the buffer to the * list of output file paths. @@ -782,13 +766,10 @@ void SaveGSS::writeBufferToFile(size_t numOutFiles, size_t numSpectra) { const auto numOutFilesInt64 = static_cast<int64_t>(numOutFiles); - // verify that all paths can be written to - for (const auto &filename : m_outFileNames) { - checkWritable(filename); - } - PARALLEL_FOR_NO_WSP_CHECK() for (int64_t fileIndex = 0; fileIndex < numOutFilesInt64; fileIndex++) { + PARALLEL_START_INTERUPT_REGION + // Open each file when there are multiple std::ofstream fileStream; openFileStream(m_outFileNames[fileIndex], fileStream); @@ -807,7 +788,9 @@ void SaveGSS::writeBufferToFile(size_t numOutFiles, size_t numSpectra) { "Failed to close the file at " + m_outFileNames[fileIndex] + " - this file may be empty, corrupted or incorrect."); } + PARALLEL_END_INTERUPT_REGION } + PARALLEL_CHECK_INTERUPT_REGION } void SaveGSS::writeRALFHeader(std::stringstream &out, int bank, @@ -850,7 +833,6 @@ void SaveGSS::writeRALF_ALTdata(std::stringstream &out, const int bank, std::vector<std::unique_ptr<std::stringstream>> outLines; outLines.resize(numberOfOutLines); - PARALLEL_FOR_NO_WSP_CHECK() for (int64_t i = 0; i < numberOfOutLines; i++) { outLines[i] = makeStringStream(); auto &outLine = *outLines[i]; diff --git a/Framework/DataHandling/src/SaveNexusProcessed.cpp b/Framework/DataHandling/src/SaveNexusProcessed.cpp index 04f5e45932330d4044da107983af2017ed8c523f..fdd8cd6ec3f3815b026b77e00347175c0ec3d937 100644 --- a/Framework/DataHandling/src/SaveNexusProcessed.cpp +++ b/Framework/DataHandling/src/SaveNexusProcessed.cpp @@ -220,7 +220,7 @@ void SaveNexusProcessed::doExec( nexusFile->openNexusWrite(m_filename, entryNumber); // Equivalent C++ API handle - auto cppFile = new ::NeXus::File(nexusFile->fileID); + ::NeXus::File cppFile(nexusFile->fileID); prog_init.reportIncrement(1, "Opening file"); if (nexusFile->writeNexusProcessedHeader(m_title, wsName) != 0) @@ -231,7 +231,7 @@ void SaveNexusProcessed::doExec( // write instrument data, if present and writer enabled if (matrixWorkspace) { // Save the instrument names, ParameterMap, sample, run - matrixWorkspace->saveExperimentInfoNexus(cppFile); + matrixWorkspace->saveExperimentInfoNexus(&cppFile); prog_init.reportIncrement(1, "Writing sample and instrument"); // check if all X() are in fact the same array @@ -256,23 +256,21 @@ void SaveNexusProcessed::doExec( spec, "workspace", true); } - cppFile->openGroup("instrument", "NXinstrument"); - saveSpectraMapNexus(*matrixWorkspace, cppFile, spec, ::NeXus::LZW); - cppFile->closeGroup(); + cppFile.openGroup("instrument", "NXinstrument"); + saveSpectraMapNexus(*matrixWorkspace, &cppFile, spec, ::NeXus::LZW); + cppFile.closeGroup(); } // finish matrix workspace specifics if (peaksWorkspace) { // Save the instrument names, ParameterMap, sample, run - peaksWorkspace->saveExperimentInfoNexus(cppFile); + peaksWorkspace->saveExperimentInfoNexus(&cppFile); prog_init.reportIncrement(1, "Writing sample and instrument"); } // peaks workspace specifics if (peaksWorkspace) { - // g_log.information("Peaks Workspace saving to Nexus would be done"); - // int pNum = peaksWorkspace->getNumberPeaks(); - peaksWorkspace->saveNexus(cppFile); + peaksWorkspace->saveNexus(&cppFile); } // finish peaks workspace specifics else if (tableWorkspace) // Table workspace specifics @@ -294,7 +292,7 @@ void SaveNexusProcessed::doExec( } } - inputWorkspace->history().saveNexus(cppFile); + inputWorkspace->history().saveNexus(&cppFile); nexusFile->closeGroup(); } diff --git a/Framework/DataObjects/test/WorkspaceValidatorsTest.h b/Framework/DataObjects/test/WorkspaceValidatorsTest.h index f54126de447492575f5f8dee6b214831e3f23ca1..4fea1646dd445dd74c067f07d727fd60e71d6050 100644 --- a/Framework/DataObjects/test/WorkspaceValidatorsTest.h +++ b/Framework/DataObjects/test/WorkspaceValidatorsTest.h @@ -5,12 +5,14 @@ #include "MantidAPI/CommonBinsValidator.h" #include "MantidAPI/HistogramValidator.h" #include "MantidAPI/InstrumentValidator.h" +#include "MantidAPI/OrientedLatticeValidator.h" #include "MantidAPI/RawCountValidator.h" #include "MantidAPI/Sample.h" #include "MantidAPI/SampleValidator.h" #include "MantidAPI/WorkspaceProperty.h" #include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidDataObjects/Workspace2D.h" +#include "MantidGeometry/Crystal/OrientedLattice.h" #include "MantidKernel/Material.h" #include "MantidKernel/NeutronAtom.h" #include "MantidKernel/UnitFactory.h" @@ -218,6 +220,22 @@ public: } } + void testOrientedLatticeValidator() { + using Mantid::API::OrientedLatticeValidator; + using Mantid::DataObjects::Workspace2D; + using Mantid::Geometry::OrientedLattice; + OrientedLatticeValidator validator; + auto ws = boost::make_shared<Workspace2D>(); + TS_ASSERT_EQUALS( + validator.isValid(ws), + "Workspace must have a sample with an orientation matrix defined."); + + OrientedLattice lattice; + ws->mutableSample().setOrientedLattice(&lattice); + + TS_ASSERT_EQUALS(validator.isValid(ws), ""); + } + void testSampleValidator() { using Mantid::Geometry::CSGObject; using Mantid::Kernel::Material; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadDNSSCD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadDNSSCD.h index 1cebdd54ab3f3fec92ee392f50fb9335b086f1a0..57bd0766e398b71eff36f20691ebccd5ad5403a6 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadDNSSCD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadDNSSCD.h @@ -59,6 +59,10 @@ public: return "MDAlgorithms\\DataHandling"; } + const std::vector<std::string> seeAlso() const override { + return {"LoadDNSLegacy", "LoadWANDSCD", "ConvertWANDSCDtoQ"}; + } + /// Returns a confidence value that this algorithm can load a file int confidence(Kernel::FileDescriptor &descriptor) const override; @@ -68,6 +72,9 @@ private: /// Run the algorithm void exec() override; + /// The column separator + std::string m_columnSep; + /// number of workspace dimensions size_t m_nDims; @@ -78,11 +85,13 @@ private: /// structure for experimental data struct ExpData { - double deterota; - double huber; + double deterota; // detector rotation angle + double huber; // sample rotation angle double wavelength; - double norm; - std::vector<double> signal; + double norm; // normalizarion + size_t nchannels; // TOF channels number + double chwidth; // channel width, microseconds + std::vector<std::vector<double>> signal; std::vector<int> detID; }; @@ -91,6 +100,7 @@ private: /// Output IMDEventWorkspace Mantid::API::IMDEventWorkspace_sptr m_OutWS; + int splitIntoColumns(std::list<std::string> &columns, std::string &str); void read_data(const std::string fname, std::map<std::string, std::string> &str_metadata, std::map<std::string, double> &num_metadata); diff --git a/Framework/MDAlgorithms/src/LoadDNSSCD.cpp b/Framework/MDAlgorithms/src/LoadDNSSCD.cpp index 3be4cd8641601bfa35bdc95a01ca94f497bada3d..3592d4f9b650734bbc5b661c52bd2cda239033b3 100644 --- a/Framework/MDAlgorithms/src/LoadDNSSCD.cpp +++ b/Framework/MDAlgorithms/src/LoadDNSSCD.cpp @@ -6,18 +6,24 @@ #include "MantidAPI/RegisterFileLoader.h" #include "MantidAPI/Run.h" #include "MantidAPI/WorkspaceFactory.h" +#include "MantidDataObjects/MDBoxBase.h" #include "MantidDataObjects/MDEventFactory.h" +#include "MantidDataObjects/MDEventInserter.h" #include "MantidGeometry/Crystal/IndexingUtils.h" #include "MantidGeometry/Crystal/OrientedLattice.h" +#include "MantidGeometry/Instrument.h" #include "MantidGeometry/MDGeometry/HKL.h" #include "MantidKernel/ArrayLengthValidator.h" #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/ConfigService.h" #include "MantidKernel/ListValidator.h" +#include "MantidKernel/PhysicalConstants.h" #include "MantidKernel/TimeSeriesProperty.h" #include "MantidKernel/UnitLabelTypes.h" #include "MantidKernel/VectorHelper.h" +#include "MantidMDAlgorithms/MDWSDescription.h" +#include "MantidMDAlgorithms/MDWSTransform.h" #include <Poco/DateTime.h> #include <Poco/DateTimeFormat.h> #include <Poco/DateTimeFormatter.h> @@ -33,11 +39,6 @@ #include <iterator> #include <map> -#include "MantidDataObjects/MDBoxBase.h" -#include "MantidDataObjects/MDEventInserter.h" -#include "MantidMDAlgorithms/MDWSDescription.h" -#include "MantidMDAlgorithms/MDWSTransform.h" - //======================== // helper functions namespace { @@ -94,7 +95,7 @@ DECLARE_FILELOADER_ALGORITHM(LoadDNSSCD) //---------------------------------------------------------------------------------------------- /** Constructor */ -LoadDNSSCD::LoadDNSSCD() : m_nDims(3) {} +LoadDNSSCD::LoadDNSSCD() : m_columnSep("\t, ;"), m_nDims(4) {} /** * Return the confidence with with this algorithm can load the file @@ -202,6 +203,19 @@ void LoadDNSSCD::init() { Kernel::make_unique<WorkspaceProperty<API::ITableWorkspace>>( "SaveHuberTo", "", Direction::Output, PropertyMode::Optional), "A workspace name to save a list of raw sample rotation angles."); + + auto mustBeIntPositive = boost::make_shared<BoundedValidator<int>>(); + mustBeIntPositive->setLower(0); + declareProperty(make_unique<PropertyWithValue<int>>( + "ElasticChannel", 0, mustBeIntPositive, Direction::Input), + "Elastic channel number. Only for TOF data."); + + auto mustBeNegative = boost::make_shared<BoundedValidator<double>>(); + mustBeNegative->setUpper(0.0); + declareProperty( + make_unique<PropertyWithValue<double>>("DeltaEmin", -10.0, mustBeNegative, + Direction::Input), + "Minimal energy transfer to consider. Should be <=0. Only for TOF data."); } //---------------------------------------------------------------------------------------------- @@ -301,6 +315,15 @@ void LoadDNSSCD::exec() { throw std::runtime_error( "No valid DNS files have been provided. Nothing to load."); + // merge data with different time channel number is not allowed + auto ch_n = m_data.front().nchannels; + bool same_channel_number = + std::all_of(m_data.begin(), m_data.end(), + [ch_n](ExpData &d) { return (d.nchannels == ch_n); }); + if (!same_channel_number) + throw std::runtime_error( + "Error: cannot merge data with different TOF channel numbers."); + m_OutWS = MDEventFactory::CreateMDWorkspace(m_nDims, "MDEvent"); m_OutWS->addExperimentInfo(expinfo); @@ -333,6 +356,13 @@ void LoadDNSSCD::exec() { setProperty("OutputWorkspace", m_OutWS); } +int LoadDNSSCD::splitIntoColumns(std::list<std::string> &columns, + std::string &str) { + boost::split(columns, str, boost::is_any_of(m_columnSep), + boost::token_compress_on); + return static_cast<int>(columns.size()); +} + //---------------------------------------------------------------------------------------------- template <class T> @@ -373,15 +403,17 @@ void LoadDNSSCD::updateProperties(API::Run &run, void LoadDNSSCD::fillOutputWorkspace(double wavelength) { // dimensions - std::vector<std::string> vec_ID(3); + std::vector<std::string> vec_ID(4); vec_ID[0] = "H"; vec_ID[1] = "K"; vec_ID[2] = "L"; + vec_ID[3] = "DeltaE"; - std::vector<std::string> dimensionNames(3); + std::vector<std::string> dimensionNames(4); dimensionNames[0] = "H"; dimensionNames[1] = "K"; dimensionNames[2] = "L"; + dimensionNames[3] = "DeltaE"; Mantid::Kernel::SpecialCoordinateSystem coordinateSystem = Mantid::Kernel::HKL; @@ -396,10 +428,36 @@ void LoadDNSSCD::fillOutputWorkspace(double wavelength) { std::vector<double> u = getProperty("HKL1"); std::vector<double> v = getProperty("HKL2"); + // load empty DNS instrument to access L1 and L2 + IAlgorithm_sptr loadAlg = + AlgorithmManager::Instance().create("LoadEmptyInstrument"); + loadAlg->setChild(true); + loadAlg->setLogging(false); + loadAlg->initialize(); + loadAlg->setProperty("InstrumentName", "DNS"); + loadAlg->setProperty("OutputWorkspace", "__DNS_Inst"); + loadAlg->execute(); + MatrixWorkspace_sptr instWS = loadAlg->getProperty("OutputWorkspace"); + const auto &instrument = instWS->getInstrument(); + const auto &samplePosition = instrument->getSample()->getPos(); + const auto &sourcePosition = instrument->getSource()->getPos(); + const auto beamVector = samplePosition - sourcePosition; + const auto l1 = beamVector.norm(); + // calculate tof1 + auto velocity = PhysicalConstants::h / + (PhysicalConstants::NeutronMass * wavelength * 1e-10); // m/s + auto tof1 = 1e+06 * l1 / velocity; // microseconds + g_log.debug() << "TOF1 = " << tof1 << std::endl; + // calculate incident energy + auto Ei = 0.5 * PhysicalConstants::NeutronMass * velocity * velocity / + PhysicalConstants::meV; + g_log.debug() << "Ei = " << Ei << std::endl; + + double dEmin = getProperty("DeltaEmin"); // estimate extents double qmax = 4.0 * M_PI / wavelength; - std::vector<double> extentMins = {-qmax * a, -qmax * b, -qmax * c}; - std::vector<double> extentMaxs = {qmax * a, qmax * b, qmax * c}; + std::vector<double> extentMins = {-qmax * a, -qmax * b, -qmax * c, dEmin}; + std::vector<double> extentMaxs = {qmax * a, qmax * b, qmax * c, Ei}; // Get MDFrame of HKL type with RLU auto unitFactory = makeMDUnitFactoryChain(); @@ -446,52 +504,103 @@ void LoadDNSSCD::fillOutputWorkspace(double wavelength) { ub_inv.Invert(); // Creates a new instance of the MDEventInserter to output workspace - MDEventWorkspace<MDEvent<3>, 3>::sptr mdws_mdevt_3 = - boost::dynamic_pointer_cast<MDEventWorkspace<MDEvent<3>, 3>>(m_OutWS); - MDEventInserter<MDEventWorkspace<MDEvent<3>, 3>::sptr> inserter(mdws_mdevt_3); + MDEventWorkspace<MDEvent<4>, 4>::sptr mdws_mdevt_4 = + boost::dynamic_pointer_cast<MDEventWorkspace<MDEvent<4>, 4>>(m_OutWS); + MDEventInserter<MDEventWorkspace<MDEvent<4>, 4>::sptr> inserter(mdws_mdevt_4); // create a normalization workspace IMDEventWorkspace_sptr normWS = m_OutWS->clone(); // Creates a new instance of the MDEventInserter to norm workspace - MDEventWorkspace<MDEvent<3>, 3>::sptr normws_mdevt_3 = - boost::dynamic_pointer_cast<MDEventWorkspace<MDEvent<3>, 3>>(normWS); - MDEventInserter<MDEventWorkspace<MDEvent<3>, 3>::sptr> norm_inserter( - normws_mdevt_3); + MDEventWorkspace<MDEvent<4>, 4>::sptr normws_mdevt_4 = + boost::dynamic_pointer_cast<MDEventWorkspace<MDEvent<4>, 4>>(normWS); + MDEventInserter<MDEventWorkspace<MDEvent<4>, 4>::sptr> norm_inserter( + normws_mdevt_4); // scattering angle limits std::vector<double> tth_limits = getProperty("TwoThetaLimits"); double theta_min = tth_limits[0] * deg2rad / 2.0; double theta_max = tth_limits[1] * deg2rad / 2.0; + // get elastic channel from the user input + int echannel_user = getProperty("ElasticChannel"); + // Go though each element of m_data to convert to MDEvent for (ExpData ds : m_data) { uint16_t runindex = 0; signal_t norm_signal(ds.norm); signal_t norm_error = std::sqrt(m_normfactor * norm_signal); - double k = 2.0 / ds.wavelength; + double ki = 2.0 * M_PI / ds.wavelength; for (size_t i = 0; i < ds.detID.size(); i++) { - signal_t signal(ds.signal[i]); - signal_t error = std::sqrt(signal); + const auto &detector = instWS->getDetector(i); + const auto &detectorPosition = detector->getPos(); + const auto detectorVector = detectorPosition - samplePosition; + const auto l2 = detectorVector.norm(); + auto tof2_elastic = 1e+06 * l2 / velocity; + // geometric elastic channel + int echannel_geom = + static_cast<int>(std::ceil(tof2_elastic / ds.chwidth)); + // rotate the signal array to get elastic peak at right position + int ch_diff = echannel_geom - echannel_user; + if ((echannel_user > 0) && (ch_diff < 0)) { + std::rotate(ds.signal[i].begin(), ds.signal[i].begin() - ch_diff, + ds.signal[i].end()); + } else if ((echannel_user > 0) && (ch_diff > 0)) { + std::rotate(ds.signal[i].rbegin(), ds.signal[i].rbegin() + ch_diff, + ds.signal[i].rend()); + } detid_t detid(ds.detID[i]); double theta = 0.5 * (ds.detID[i] * 5.0 - ds.deterota) * deg2rad; + int64_t nchannels = static_cast<int64_t>(ds.signal[i].size()); if ((theta > theta_min) && (theta < theta_max)) { - double omega = (ds.huber - ds.deterota) * deg2rad - theta; - V3D uphi(-cos(omega), 0, -sin(omega)); - V3D hphi = uphi * k * sin(theta); - V3D hkl = ub_inv * hphi; - std::vector<Mantid::coord_t> millerindex(3); - millerindex[0] = static_cast<float>(hkl.X()); - millerindex[1] = static_cast<float>(hkl.Y()); - millerindex[2] = static_cast<float>(hkl.Z()); - inserter.insertMDEvent( - static_cast<float>(signal), static_cast<float>(error * error), - static_cast<uint16_t>(runindex), detid, millerindex.data()); - - norm_inserter.insertMDEvent(static_cast<float>(norm_signal), - static_cast<float>(norm_error * norm_error), - static_cast<uint16_t>(runindex), detid, - millerindex.data()); + PARALLEL_FOR_IF(Kernel::threadSafe(*m_OutWS, *normWS)) + for (auto channel = 0; channel < nchannels; channel++) { + PARALLEL_START_INTERUPT_REGION + double signal = ds.signal[i][channel]; + signal_t error = std::sqrt(signal); + double tof2 = static_cast<double>(channel) * ds.chwidth + + 0.5 * ds.chwidth; // bin centers + double dE = 0.0; + if (nchannels > 1) { + double v2 = 1e+06 * l2 / tof2; + dE = Ei - 0.5 * PhysicalConstants::NeutronMass * v2 * v2 / + PhysicalConstants::meV; + } + if (dE > dEmin) { + double kf = + std::sqrt(ki * ki - 2.0e-20 * PhysicalConstants::NeutronMass * + dE * PhysicalConstants::meV / + (PhysicalConstants::h_bar * + PhysicalConstants::h_bar)); + double tlab = + std::atan2(ki - kf * cos(2.0 * theta), kf * sin(2.0 * theta)); + double omega = (ds.huber - ds.deterota) * deg2rad - tlab; + V3D uphi(-cos(omega), 0, -sin(omega)); + double qabs = 0.5 * + std::sqrt(ki * ki + kf * kf - + 2.0 * ki * kf * cos(2.0 * theta)) / + M_PI; + V3D hphi = uphi * qabs; // qabs = ki * sin(theta), for elastic case; + V3D hkl = ub_inv * hphi; + std::vector<Mantid::coord_t> millerindex(4); + millerindex[0] = static_cast<float>(hkl.X()); + millerindex[1] = static_cast<float>(hkl.Y()); + millerindex[2] = static_cast<float>(hkl.Z()); + millerindex[3] = static_cast<float>(dE); + PARALLEL_CRITICAL(addValues) { + inserter.insertMDEvent( + static_cast<float>(signal), static_cast<float>(error * error), + static_cast<uint16_t>(runindex), detid, millerindex.data()); + + norm_inserter.insertMDEvent( + static_cast<float>(norm_signal), + static_cast<float>(norm_error * norm_error), + static_cast<uint16_t>(runindex), detid, millerindex.data()); + } + } + PARALLEL_END_INTERUPT_REGION + } + PARALLEL_CHECK_INTERUPT_REGION } } } @@ -572,28 +681,36 @@ void LoadDNSSCD::read_data(const std::string fname, } } - // the algorithm does not work with TOF data for the moment std::map<std::string, double>::const_iterator m = num_metadata.lower_bound("TOF"); g_log.debug() << "TOF Channels number: " << m->second << std::endl; - if (m->second != 1) - throw std::runtime_error( - "Algorithm does not support TOF data. TOF Channels number must be 1."); + std::map<std::string, double>::const_iterator w = + num_metadata.lower_bound("Time"); + g_log.debug() << "Channel width: " << w->second << std::endl; ExpData ds; ds.deterota = num_metadata["DeteRota"]; ds.huber = num_metadata["Huber"]; ds.wavelength = 10.0 * num_metadata["Lambda[nm]"]; ds.norm = num_metadata[m_normtype]; + ds.chwidth = w->second; + ds.nchannels = static_cast<size_t>(std::ceil(m->second)); // read data array getline(file, line); - int d; - double x; - while (file) { - file >> d >> x; - ds.detID.push_back(d); - ds.signal.push_back(x); + + std::list<std::string> columns; + while (getline(file, line)) { + boost::trim(line); + const int cols = splitIntoColumns(columns, line); + if (cols > 0) { + ds.detID.push_back(std::stoi(columns.front())); + columns.pop_front(); + std::vector<double> signal; + std::transform(columns.begin(), columns.end(), std::back_inserter(signal), + [](const std::string &s) { return std::stod(s); }); + ds.signal.push_back(signal); + } } // DNS PA detector bank has only 24 detectors ds.detID.resize(24); diff --git a/Framework/MDAlgorithms/test/LoadDNSSCDTest.h b/Framework/MDAlgorithms/test/LoadDNSSCDTest.h index 9bfe650d060e9cd82189c69086b9a1c7facd46f3..56b2df7bbd0208467fac1fcfe99ce189cff7dac6 100644 --- a/Framework/MDAlgorithms/test/LoadDNSSCDTest.h +++ b/Framework/MDAlgorithms/test/LoadDNSSCDTest.h @@ -1,6 +1,7 @@ #ifndef MANTID_MDALGORITHMS_LOADDNSSCDEWTEST_H_ #define MANTID_MDALGORITHMS_LOADDNSSCDEWTEST_H_ +#include "LoadDNSSCDTestReference.h" #include "MantidAPI/AnalysisDataService.h" #include "MantidAPI/BoxController.h" #include "MantidAPI/ExperimentInfo.h" @@ -25,6 +26,37 @@ using namespace Mantid::API; using namespace Mantid::DataObjects; using namespace Mantid::MDAlgorithms; +bool cmp_Events(const std::vector<coord_t> &ev1, + const std::vector<coord_t> &ev2) { + // event1 < event2 if it has smaller det_id and dE + assert(ev1.size() == 8); + assert(ev2.size() == 8); + float eps = 1.0e-07f; + if (std::abs(ev1[3] - ev2[3]) > eps) { + return ev1[3] < ev2[3]; + } else { + return ev1[7] < ev2[7]; + } +} + +void sort_Events(std::vector<coord_t> &events) { + // 1. split the events vector into 8-sized chunks + std::vector<std::vector<coord_t>> sub_events; + auto itr = events.cbegin(); + while (itr < events.cend()) { + sub_events.emplace_back(std::vector<coord_t>(itr, itr + 8)); + itr += 8; + } + // 2. sort the vector of chunks + std::sort(sub_events.begin(), sub_events.end(), cmp_Events); + + // 3. put the sorted array back + events.clear(); + for (auto ev : sub_events) { + events.insert(end(events), begin(ev), end(ev)); + } +} + class LoadDNSSCDTest : public CxxTest::TestSuite { public: // This pair of boilerplate methods prevent the suite being created statically @@ -137,6 +169,7 @@ public: TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("NormalizationWorkspace", normWSName)); TS_ASSERT_THROWS_NOTHING(alg.setProperty("Normalization", "monitor")); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("DeltaEmin", "-2.991993")); TS_ASSERT_THROWS_NOTHING(alg.execute();); TS_ASSERT(alg.isExecuted()); @@ -147,9 +180,9 @@ public: outWSName)); TS_ASSERT(iws); - TS_ASSERT_EQUALS(iws->getNumDims(), 3); + TS_ASSERT_EQUALS(iws->getNumDims(), 4); TS_ASSERT_EQUALS(iws->getNPoints(), 24); - TS_ASSERT_EQUALS(iws->id(), "MDEventWorkspace<MDEvent,3>"); + TS_ASSERT_EQUALS(iws->id(), "MDEventWorkspace<MDEvent,4>"); // test box controller BoxController_sptr bc = iws->getBoxController(); @@ -157,15 +190,19 @@ public: TS_ASSERT_EQUALS(bc->getNumMDBoxes().size(), 6); // test dimensions - std::vector<std::string> v = {"H", "K", "L"}; - for (auto i = 0; i < 3; i++) { + std::vector<std::string> v = {"H", "K", "L", "DeltaE"}; + for (auto i = 0; i < 4; i++) { auto dim = iws->getDimension(i); TS_ASSERT(dim); TS_ASSERT_EQUALS(dim->getName(), v[i]); TS_ASSERT_EQUALS(dim->getNBins(), 5); double d(1.0e-05); TS_ASSERT_DELTA(dim->getMinimum(), -2.991993, d); - TS_ASSERT_DELTA(dim->getMaximum(), 2.991993, d); + if (i < 3) { + TS_ASSERT_DELTA(dim->getMaximum(), 2.991993, d); + } else { + TS_ASSERT_DELTA(dim->getMaximum(), 4.637426, d); + } } AnalysisDataService::Instance().remove(outWSName); } @@ -213,182 +250,14 @@ public: std::vector<coord_t> events; size_t ncols; box->getEventsData(events, ncols); - // 7 columns: I, err^2, run_num, det_id, h, k, l - TS_ASSERT_EQUALS(ncols, 7); - // 7*24 = 168 - TS_ASSERT_EQUALS(events.size(), 168); + // 8 columns: I, err^2, run_num, det_id, h, k, l, dE + TS_ASSERT_EQUALS(ncols, 8); + // 8*24 = 192 + TS_ASSERT_EQUALS(events.size(), 192); // reference vector - const std::vector<coord_t> ref = {4366, - 4366, - 0, - 0, - -0.09776273f, - -0.09776273f, - 0.10005156f, - 31461, - 31461, - 0, - 1, - -0.15959044f, - -0.15959044f, - 0.14884006f, - 33314, - 33314, - 0, - 2, - -0.224231616093f, - -0.224231616093f, - 0.189927174618f, - 32369, - 32369, - 0, - 3, - -0.291194311172f, - -0.291194311172f, - 0.223000198347f, - 31851, - 31851, - 0, - 4, - -0.359968893923f, - -0.359968893923f, - 0.247807429194f, - 30221, - 30221, - 0, - 5, - -0.430031948245f, - -0.430031948245f, - 0.264160069153f, - 26267, - 26267, - 0, - 6, - -0.500850251989f, - -0.500850251989f, - 0.271933664761f, - 26788, - 26788, - 0, - 7, - -0.571884835101f, - -0.571884835101f, - 0.27106905426f, - 29729, - 29729, - 0, - 8, - -0.642595081514f, - -0.642595081514f, - 0.26157281786f, - 30188, - 30188, - 0, - 9, - -0.712442843555f, - -0.712442843555f, - 0.243517227652f, - 28116, - 28116, - 0, - 10, - -0.78089653758f, - -0.78089653758f, - 0.217039697581f, - 30277, - 30277, - 0, - 11, - -0.847435189645f, - -0.847435189645f, - 0.182341737639f, - 20231, - 20231, - 0, - 12, - -0.911552400429f, - -0.911552400429f, - 0.13968742025f, - 24538, - 24538, - 0, - 13, - -0.972760199244f, - -0.972760199244f, - 0.089401370527f, - 16416, - 16416, - 0, - 14, - -1.03059275778f, - -1.03059275778f, - 0.0318662956709f, - 20225, - 20225, - 0, - 15, - -1.08460993535f, - -1.08460993535f, - -0.0324799276578f, - 19957, - 19957, - 0, - 16, - -1.13440062862f, - -1.13440062862f, - -0.103147585846f, - 19570, - 19570, - 0, - 17, - -1.17958590034f, - -1.17958590034f, - -0.179598855345f, - 20743, - 20743, - 0, - 18, - -1.21982186332f, - -1.21982186332f, - -0.261251895832f, - 22758, - 22758, - 0, - 19, - -1.25480229757f, - -1.25480229757f, - -0.347485278364f, - 23001, - 23001, - 0, - 20, - -1.28426098088f, - -1.28426098088f, - -0.437642714831f, - 21836, - 21836, - 0, - 21, - -1.30797371487f, - -1.30797371487f, - -0.531038052704f, - 23877, - 23877, - 0, - 22, - -1.32576003133f, - -1.32576003133f, - -0.626960497068f, - 13340, - 13340, - 0, - 23, - -1.33748456564f, - -1.33748456564f, - -0.724680020201f}; double d(1.0e-06); - for (auto i = 0; i < 168; i++) { - TS_ASSERT_DELTA(events[i], ref[i], d); + for (auto i = 0; i < 192; i++) { + TS_ASSERT_DELTA(events[i], test_DataWS_ref[i], d); } AnalysisDataService::Instance().remove(outWSName); @@ -407,6 +276,7 @@ public: TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("NormalizationWorkspace", normWSName)); TS_ASSERT_THROWS_NOTHING(alg.setProperty("Normalization", "monitor")); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("DeltaEmin", "-2.991993")); TS_ASSERT_THROWS_NOTHING(alg.execute();); TS_ASSERT(alg.isExecuted()); @@ -417,9 +287,9 @@ public: normWSName)); TS_ASSERT(nws); - TS_ASSERT_EQUALS(nws->getNumDims(), 3); + TS_ASSERT_EQUALS(nws->getNumDims(), 4); TS_ASSERT_EQUALS(nws->getNPoints(), 24); - TS_ASSERT_EQUALS(nws->id(), "MDEventWorkspace<MDEvent,3>"); + TS_ASSERT_EQUALS(nws->id(), "MDEventWorkspace<MDEvent,4>"); // test box controller BoxController_sptr bc = nws->getBoxController(); @@ -427,15 +297,19 @@ public: TS_ASSERT_EQUALS(bc->getNumMDBoxes().size(), 6); // test dimensions - std::vector<std::string> v = {"H", "K", "L"}; - for (auto i = 0; i < 3; i++) { + std::vector<std::string> v = {"H", "K", "L", "DeltaE"}; + for (auto i = 0; i < 4; i++) { auto dim = nws->getDimension(i); TS_ASSERT(dim); TS_ASSERT_EQUALS(dim->getName(), v[i]); TS_ASSERT_EQUALS(dim->getNBins(), 5); double d(1.0e-05); TS_ASSERT_DELTA(dim->getMinimum(), -2.991993, d); - TS_ASSERT_DELTA(dim->getMaximum(), 2.991993, d); + if (i < 3) { + TS_ASSERT_DELTA(dim->getMaximum(), 2.991993, d); + } else { + TS_ASSERT_DELTA(dim->getMaximum(), 4.637426, d); + } } AnalysisDataService::Instance().remove(normWSName); } @@ -483,182 +357,13 @@ public: std::vector<coord_t> events; size_t ncols; box->getEventsData(events, ncols); - // 7 columns: I, err^2, run_num, det_id, h, k, l - TS_ASSERT_EQUALS(ncols, 7); - // 7*24 = 168 - TS_ASSERT_EQUALS(events.size(), 168); - // reference vector - const std::vector<coord_t> ref = {8332872, - 8332872, - 0, - 0, - -0.09776273f, - -0.09776273f, - 0.10005156f, - 8332872, - 8332872, - 0, - 1, - -0.15959044f, - -0.15959044f, - 0.14884006f, - 8332872, - 8332872, - 0, - 2, - -0.224231616093f, - -0.224231616093f, - 0.189927174618f, - 8332872, - 8332872, - 0, - 3, - -0.291194311172f, - -0.291194311172f, - 0.223000198347f, - 8332872, - 8332872, - 0, - 4, - -0.359968893923f, - -0.359968893923f, - 0.247807429194f, - 8332872, - 8332872, - 0, - 5, - -0.430031948245f, - -0.430031948245f, - 0.264160069153f, - 8332872, - 8332872, - 0, - 6, - -0.500850251989f, - -0.500850251989f, - 0.271933664761f, - 8332872, - 8332872, - 0, - 7, - -0.571884835101f, - -0.571884835101f, - 0.27106905426f, - 8332872, - 8332872, - 0, - 8, - -0.642595081514f, - -0.642595081514f, - 0.26157281786f, - 8332872, - 8332872, - 0, - 9, - -0.712442843555f, - -0.712442843555f, - 0.243517227652f, - 8332872, - 8332872, - 0, - 10, - -0.78089653758f, - -0.78089653758f, - 0.217039697581f, - 8332872, - 8332872, - 0, - 11, - -0.847435189645f, - -0.847435189645f, - 0.182341737639f, - 8332872, - 8332872, - 0, - 12, - -0.911552400429f, - -0.911552400429f, - 0.13968742025f, - 8332872, - 8332872, - 0, - 13, - -0.972760199244f, - -0.972760199244f, - 0.089401370527f, - 8332872, - 8332872, - 0, - 14, - -1.03059275778f, - -1.03059275778f, - 0.0318662956709f, - 8332872, - 8332872, - 0, - 15, - -1.08460993535f, - -1.08460993535f, - -0.0324799276578f, - 8332872, - 8332872, - 0, - 16, - -1.13440062862f, - -1.13440062862f, - -0.103147585846f, - 8332872, - 8332872, - 0, - 17, - -1.17958590034f, - -1.17958590034f, - -0.179598855345f, - 8332872, - 8332872, - 0, - 18, - -1.21982186332f, - -1.21982186332f, - -0.261251895832f, - 8332872, - 8332872, - 0, - 19, - -1.25480229757f, - -1.25480229757f, - -0.347485278364f, - 8332872, - 8332872, - 0, - 20, - -1.28426098088f, - -1.28426098088f, - -0.437642714831f, - 8332872, - 8332872, - 0, - 21, - -1.30797371487f, - -1.30797371487f, - -0.531038052704f, - 8332872, - 8332872, - 0, - 22, - -1.32576003133f, - -1.32576003133f, - -0.626960497068f, - 8332872, - 8332872, - 0, - 23, - -1.33748456564f, - -1.33748456564f, - -0.724680020201f}; + // 8 columns: I, err^2, run_num, det_id, h, k, l, dE + TS_ASSERT_EQUALS(ncols, 8); + // 8*24 = 192 + TS_ASSERT_EQUALS(events.size(), 192); double d(1.0e-06); - for (auto i = 0; i < 168; i++) { - TS_ASSERT_DELTA(events[i], ref[i], d); + for (auto i = 0; i < 192; i++) { + TS_ASSERT_DELTA(events[i], test_NormMonitor_ref[i], d); } AnalysisDataService::Instance().remove(normWSName); @@ -707,39 +412,13 @@ public: std::vector<coord_t> events; size_t ncols; box->getEventsData(events, ncols); - // 7 columns: I, err^2, run_num, det_id, h, k, l - TS_ASSERT_EQUALS(ncols, 7); - // 7*24 = 168 - TS_ASSERT_EQUALS(events.size(), 168); - // reference vector - const std::vector<coord_t> ref = { - 600, 0, 0, 0, -0.09776273f, -0.09776273f, 0.10005156f, - 600, 0, 0, 1, -0.15959044f, -0.15959044f, 0.14884006f, - 600, 0, 0, 2, -0.224231616093f, -0.224231616093f, 0.189927174618f, - 600, 0, 0, 3, -0.291194311172f, -0.291194311172f, 0.223000198347f, - 600, 0, 0, 4, -0.359968893923f, -0.359968893923f, 0.247807429194f, - 600, 0, 0, 5, -0.430031948245f, -0.430031948245f, 0.264160069153f, - 600, 0, 0, 6, -0.500850251989f, -0.500850251989f, 0.271933664761f, - 600, 0, 0, 7, -0.571884835101f, -0.571884835101f, 0.27106905426f, - 600, 0, 0, 8, -0.642595081514f, -0.642595081514f, 0.26157281786f, - 600, 0, 0, 9, -0.712442843555f, -0.712442843555f, 0.243517227652f, - 600, 0, 0, 10, -0.78089653758f, -0.78089653758f, 0.217039697581f, - 600, 0, 0, 11, -0.847435189645f, -0.847435189645f, 0.182341737639f, - 600, 0, 0, 12, -0.911552400429f, -0.911552400429f, 0.13968742025f, - 600, 0, 0, 13, -0.972760199244f, -0.972760199244f, 0.089401370527f, - 600, 0, 0, 14, -1.03059275778f, -1.03059275778f, 0.0318662956709f, - 600, 0, 0, 15, -1.08460993535f, -1.08460993535f, -0.0324799276578f, - 600, 0, 0, 16, -1.13440062862f, -1.13440062862f, -0.103147585846f, - 600, 0, 0, 17, -1.17958590034f, -1.17958590034f, -0.179598855345f, - 600, 0, 0, 18, -1.21982186332f, -1.21982186332f, -0.261251895832f, - 600, 0, 0, 19, -1.25480229757f, -1.25480229757f, -0.347485278364f, - 600, 0, 0, 20, -1.28426098088f, -1.28426098088f, -0.437642714831f, - 600, 0, 0, 21, -1.30797371487f, -1.30797371487f, -0.531038052704f, - 600, 0, 0, 22, -1.32576003133f, -1.32576003133f, -0.626960497068f, - 600, 0, 0, 23, -1.33748456564f, -1.33748456564f, -0.724680020201f}; + // 8 columns: I, err^2, run_num, det_id, h, k, l, dE + TS_ASSERT_EQUALS(ncols, 8); + // 8*24 = 192 + TS_ASSERT_EQUALS(events.size(), 192); double d(1.0e-06); - for (auto i = 0; i < 168; i++) { - TS_ASSERT_DELTA(events[i], ref[i], d); + for (auto i = 0; i < 192; i++) { + TS_ASSERT_DELTA(events[i], test_NormTime_ref[i], d); } AnalysisDataService::Instance().remove(normWSName); @@ -821,7 +500,7 @@ public: outWSName)); TS_ASSERT(iws); - TS_ASSERT_EQUALS(iws->getNumDims(), 3); + TS_ASSERT_EQUALS(iws->getNumDims(), 4); // data should be replicated for each huber value TS_ASSERT_EQUALS(iws->getNPoints(), 24 * n); @@ -890,63 +569,13 @@ public: std::vector<coord_t> events; size_t ncols; box->getEventsData(events, ncols); - // 7 columns: I, err^2, run_num, det_id, h, k, l - TS_ASSERT_EQUALS(ncols, 7); - // 7*7 = 49 - TS_ASSERT_EQUALS(events.size(), 49); - // reference vector - const std::vector<coord_t> ref = {32369, - 32369, - 0, - 3, - -0.291194311172f, - -0.291194311172f, - 0.223000198347f, - 31851, - 31851, - 0, - 4, - -0.359968893923f, - -0.359968893923f, - 0.247807429194f, - 30221, - 30221, - 0, - 5, - -0.430031948245f, - -0.430031948245f, - 0.264160069153f, - 26267, - 26267, - 0, - 6, - -0.500850251989f, - -0.500850251989f, - 0.271933664761f, - 26788, - 26788, - 0, - 7, - -0.571884835101f, - -0.571884835101f, - 0.27106905426f, - 29729, - 29729, - 0, - 8, - -0.642595081514f, - -0.642595081514f, - 0.26157281786f, - 30188, - 30188, - 0, - 9, - -0.712442843555f, - -0.712442843555f, - 0.243517227652f}; + // 8 columns: I, err^2, run_num, det_id, h, k, l, dE + TS_ASSERT_EQUALS(ncols, 8); + // 8*7 = 56 + TS_ASSERT_EQUALS(events.size(), 56); double d(1.0e-06); - for (auto i = 0; i < 49; i++) { - TS_ASSERT_DELTA(events[i], ref[i], d); + for (auto i = 0; i < 56; i++) { + TS_ASSERT_DELTA(events[i], test_2ThetaLimits_ref[i], d); } AnalysisDataService::Instance().remove(outWSName); @@ -963,26 +592,163 @@ public: AnalysisDataService::Instance().remove(normWSName); } - void test_Load2() { - // algorithm should load one file and skip the TOF file + void test_TOFWSStructure() { + std::string outWSName("LoadDNSSCDTest_OutputWS"); + std::string normWSName("LoadDNSSCDTest_OutputWS_norm"); + + LoadDNSSCD alg; + TS_ASSERT_THROWS_NOTHING(alg.initialize()); + TS_ASSERT(alg.isInitialized()); + TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Filenames", "dnstof.d_dat")); + TS_ASSERT_THROWS_NOTHING( + alg.setPropertyValue("OutputWorkspace", outWSName)); + TS_ASSERT_THROWS_NOTHING( + alg.setPropertyValue("NormalizationWorkspace", normWSName)); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("Normalization", "monitor")); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("DeltaEmin", "-2.991993")); + TS_ASSERT_THROWS_NOTHING(alg.execute();); + TS_ASSERT(alg.isExecuted()); + + // Retrieve the workspace from data service. + IMDEventWorkspace_sptr iws; + TS_ASSERT_THROWS_NOTHING( + iws = AnalysisDataService::Instance().retrieveWS<IMDEventWorkspace>( + outWSName)); + TS_ASSERT(iws); + + TS_ASSERT_EQUALS(iws->getNumDims(), 4); + TS_ASSERT_EQUALS(iws->getNPoints(), 1968); + TS_ASSERT_EQUALS(iws->id(), "MDEventWorkspace<MDEvent,4>"); + // test some metadata + TS_ASSERT_EQUALS(iws->getNumExperimentInfo(), 1); + ExperimentInfo_sptr expinfo = iws->getExperimentInfo(0); + auto &run = expinfo->run(); + TimeSeriesProperty<double> *p = dynamic_cast<TimeSeriesProperty<double> *>( + run.getProperty("TOF channels")); + TS_ASSERT_DELTA(p->firstValue(), 100, 1.0e-05); + p = dynamic_cast<TimeSeriesProperty<double> *>( + run.getProperty("Time per channel")); + TS_ASSERT_DELTA(p->firstValue(), 40.1, 1.0e-05); + // test box controller + BoxController_sptr bc = iws->getBoxController(); + TS_ASSERT(bc); + TS_ASSERT_EQUALS(bc->getNumMDBoxes().size(), 6); + + // test dimensions + std::vector<std::string> v = {"H", "K", "L", "DeltaE"}; + for (auto i = 0; i < 4; i++) { + auto dim = iws->getDimension(i); + TS_ASSERT(dim); + TS_ASSERT_EQUALS(dim->getName(), v[i]); + TS_ASSERT_EQUALS(dim->getNBins(), 5); + double d(1.0e-05); + TS_ASSERT_DELTA(dim->getMinimum(), -2.991993, d); + if (i < 3) { + TS_ASSERT_DELTA(dim->getMaximum(), 2.991993, d); + } else { + TS_ASSERT_DELTA(dim->getMaximum(), 4.637426, d); + } + } + AnalysisDataService::Instance().remove(outWSName); + } + + void test_TOFWSData() { + // test whether the calculation for inelastic data are correct std::string outWSName("LoadDNSSCDTest_OutputWS"); std::string normWSName("LoadDNSSCDTest_OutputWS_norm"); - std::string filenames = "dn134011vana.d_dat,dnstof.d_dat"; LoadDNSSCD alg; - alg.setRethrows(true); TS_ASSERT_THROWS_NOTHING(alg.initialize()); TS_ASSERT(alg.isInitialized()); - TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Filenames", filenames)); + TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Filenames", "dnstof.d_dat")); TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", outWSName)); TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("NormalizationWorkspace", normWSName)); TS_ASSERT_THROWS_NOTHING(alg.setProperty("Normalization", "monitor")); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("a", 3.55)); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("b", 3.55)); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("c", 24.778)); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("alpha", 90.0)); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("beta", 90.0)); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("gamma", 120.0)); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("OmegaOffset", 0.0)); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("HKL1", "1,1,0")); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("HKL2", "0,0,1")); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("TwoThetaLimits", "20.0,55.0")); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("DeltaEmin", "-3.0")); + TS_ASSERT_THROWS_NOTHING(alg.execute();); + TS_ASSERT(alg.isExecuted()); + + // Retrieve the workspace from data service. + IMDEventWorkspace_sptr iws; + TS_ASSERT_THROWS_NOTHING( + iws = AnalysisDataService::Instance().retrieveWS<IMDEventWorkspace>( + outWSName)); + TS_ASSERT(iws); + + std::vector<API::IMDNode *> boxes(0, NULL); + iws->getBoxes(boxes, 10000, false); + TSM_ASSERT_EQUALS("Number of boxes", boxes.size(), 1); + API::IMDNode *box = boxes[0]; + // there are 7 points (the rest is outside of 2theta limits) + TS_ASSERT_EQUALS(box->getNPoints(), 574); + std::vector<coord_t> events; + size_t ncols; + box->getEventsData(events, ncols); + // 8 columns: I, err^2, run_num, det_id, h, k, l, dE + TS_ASSERT_EQUALS(ncols, 8); + // 8*574 = 4592 + TS_ASSERT_EQUALS(events.size(), 4592); + double d(1.0e-06); + sort_Events(events); + for (auto i = 0; i < 82 * 8; i++) { + TS_ASSERT_DELTA(events[i], test_TOFWSData_ref[i], d); + } + + AnalysisDataService::Instance().remove(outWSName); + + // test the normalization workspace as well + IMDEventWorkspace_sptr nws; + TS_ASSERT_THROWS_NOTHING( + nws = AnalysisDataService::Instance().retrieveWS<IMDEventWorkspace>( + normWSName)); + TS_ASSERT(nws); + // there are 7 histograms (the rest is outside of 2theta limits) + TS_ASSERT_EQUALS(nws->getNPoints(), 574); - // algorithm should throw only if no valid files is provided - TS_ASSERT_THROWS_NOTHING(alg.execute()); + AnalysisDataService::Instance().remove(normWSName); + } + + void test_TOFWSDataRotateEPP() { + // test whether the calculation for inelastic data are correct + + std::string outWSName("LoadDNSSCDTest_OutputWS"); + std::string normWSName("LoadDNSSCDTest_OutputWS_norm"); + + LoadDNSSCD alg; + TS_ASSERT_THROWS_NOTHING(alg.initialize()); + TS_ASSERT(alg.isInitialized()); + TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Filenames", "dnstof.d_dat")); + TS_ASSERT_THROWS_NOTHING( + alg.setPropertyValue("OutputWorkspace", outWSName)); + TS_ASSERT_THROWS_NOTHING( + alg.setPropertyValue("NormalizationWorkspace", normWSName)); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("Normalization", "monitor")); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("a", 3.55)); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("b", 3.55)); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("c", 24.778)); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("alpha", 90.0)); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("beta", 90.0)); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("gamma", 120.0)); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("OmegaOffset", -43.0)); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("HKL1", "1,1,0")); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("HKL2", "0,0,1")); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("TwoThetaLimits", "25.0,60.0")); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("DeltaEmin", "-3.0")); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("ElasticChannel", "64")); + TS_ASSERT_THROWS_NOTHING(alg.execute();); TS_ASSERT(alg.isExecuted()); // Retrieve the workspace from data service. @@ -992,23 +758,52 @@ public: outWSName)); TS_ASSERT(iws); - TS_ASSERT_EQUALS(iws->getNumDims(), 3); - TS_ASSERT_EQUALS(iws->getNPoints(), 24); + std::vector<API::IMDNode *> boxes(0, NULL); + iws->getBoxes(boxes, 10000, false); + TSM_ASSERT_EQUALS("Number of boxes", boxes.size(), 1); + API::IMDNode *box = boxes[0]; + // there are 7 points (the rest is outside of 2theta limits) + TS_ASSERT_EQUALS(box->getNPoints(), 574); + std::vector<coord_t> events; + size_t ncols; + box->getEventsData(events, ncols); + // 8 columns: I, err^2, run_num, det_id, h, k, l, dE + TS_ASSERT_EQUALS(ncols, 8); + // 8*574 = 4592 + TS_ASSERT_EQUALS(events.size(), 4592); + double d(1.0e-06); + sort_Events(events); + for (auto i = 0; i < 82 * 8; i++) { + TS_ASSERT_DELTA(events[i], test_TOFWSDataRotateEPP_ref[i], d); + } + AnalysisDataService::Instance().remove(outWSName); + + // test the normalization workspace as well + IMDEventWorkspace_sptr nws; + TS_ASSERT_THROWS_NOTHING( + nws = AnalysisDataService::Instance().retrieveWS<IMDEventWorkspace>( + normWSName)); + TS_ASSERT(nws); + // there are 7 points (the rest is outside of 2theta limits) + TS_ASSERT_EQUALS(nws->getNPoints(), 574); + + AnalysisDataService::Instance().remove(normWSName); } //-------------------- Test failure -------------------------------------- void test_failTOF() { - // algorithm does not load TOF files + // algorithm does not load files with different number of time channels std::string outWSName("LoadDNSSCDTest_OutputWS"); std::string normWSName("LoadDNSSCDTest_OutputWS_norm"); + std::string filenames = "dn134011vana.d_dat,dnstof.d_dat"; LoadDNSSCD alg; alg.setRethrows(true); TS_ASSERT_THROWS_NOTHING(alg.initialize()); TS_ASSERT(alg.isInitialized()); - TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Filenames", "dnstof.d_dat")); + TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Filenames", filenames)); TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", outWSName)); TS_ASSERT_THROWS_NOTHING( diff --git a/Framework/MDAlgorithms/test/LoadDNSSCDTestReference.h b/Framework/MDAlgorithms/test/LoadDNSSCDTestReference.h new file mode 100644 index 0000000000000000000000000000000000000000..9f13d18e02cfc003cb0fecd5846c47eaeb8ef95f --- /dev/null +++ b/Framework/MDAlgorithms/test/LoadDNSSCDTestReference.h @@ -0,0 +1,268 @@ +#ifndef LOADDNSSCDTESTREFERENCE_H +#define LOADDNSSCDTESTREFERENCE_H + +#include "MantidGeometry/MDGeometry/MDTypes.h" +// clang-format makes the reference data unreadable, therefore +// clang-format off +const std::vector<Mantid::coord_t> test_DataWS_ref = { + 4366, 4366, 0, 0, -0.09776273f, -0.09776273f, 0.10005156f, 0.0f, + 31461, 31461, 0, 1, -0.15959044f, -0.15959044f, 0.14884006f, 0.0f, + 33314, 33314, 0, 2, -0.224231616093f, -0.224231616093f, 0.189927174618f, 0.0f, + 32369, 32369, 0, 3, -0.291194311172f, -0.291194311172f, 0.223000198347f, 0.0f, + 31851, 31851, 0, 4, -0.359968893923f, -0.359968893923f, 0.247807429194f, 0.0f, + 30221, 30221, 0, 5, -0.430031948245f, -0.430031948245f, 0.264160069153f, 0.0f, + 26267, 26267, 0, 6, -0.500850251989f, -0.500850251989f, 0.271933664761f, 0.0f, + 26788, 26788, 0, 7, -0.571884835101f, -0.571884835101f, 0.27106905426f, 0.0f, + 29729, 29729, 0, 8, -0.642595081514f, -0.642595081514f, 0.26157281786f, 0.0f, + 30188, 30188, 0, 9, -0.712442843555f, -0.712442843555f, 0.243517227652f, 0.0f, + 28116, 28116, 0, 10, -0.78089653758f, -0.78089653758f, 0.217039697581f, 0.0f, + 30277, 30277, 0, 11, -0.847435189645f, -0.847435189645f, 0.182341737639f, 0.0f, + 20231, 20231, 0, 12, -0.911552400429f, -0.911552400429f, 0.13968742025f, 0.0f, + 24538, 24538, 0, 13, -0.972760199244f, -0.972760199244f, 0.089401370527f, 0.0f, + 16416, 16416, 0, 14, -1.03059275778f, -1.03059275778f, 0.0318662956709f, 0.0f, + 20225, 20225, 0, 15, -1.08460993535f, -1.08460993535f, -0.0324799276578f, 0.0f, + 19957, 19957, 0, 16, -1.13440062862f, -1.13440062862f, -0.103147585846f, 0.0f, + 19570, 19570, 0, 17, -1.17958590034f, -1.17958590034f, -0.179598855345f, 0.0f, + 20743, 20743, 0, 18, -1.21982186332f, -1.21982186332f, -0.261251895832f, 0.0f, + 22758, 22758, 0, 19, -1.25480229757f, -1.25480229757f, -0.347485278364f, 0.0f, + 23001, 23001, 0, 20, -1.28426098088f, -1.28426098088f, -0.437642714831f, 0.0f, + 21836, 21836, 0, 21, -1.30797371487f, -1.30797371487f, -0.531038052704f, 0.0f, + 23877, 23877, 0, 22, -1.32576003133f, -1.32576003133f, -0.626960497068f, 0.0f, + 13340, 13340, 0, 23, -1.33748456564f, -1.33748456564f, -0.724680020201f, 0.0f}; + + +const std::vector<Mantid::coord_t> test_NormMonitor_ref = { + 8332872, 8332872, 0, 0, -0.09776273f, -0.09776273f, 0.10005156f, 0.0f, + 8332872, 8332872, 0, 1, -0.15959044f, -0.15959044f, 0.14884006f, 0.0f, + 8332872, 8332872, 0, 2, -0.224231616093f, -0.224231616093f, 0.189927174618f, 0.0f, + 8332872, 8332872, 0, 3, -0.291194311172f, -0.291194311172f, 0.223000198347f, 0.0f, + 8332872, 8332872, 0, 4, -0.359968893923f, -0.359968893923f, 0.247807429194f, 0.0f, + 8332872, 8332872, 0, 5, -0.430031948245f, -0.430031948245f, 0.264160069153f, 0.0f, + 8332872, 8332872, 0, 6, -0.500850251989f, -0.500850251989f, 0.271933664761f, 0.0f, + 8332872, 8332872, 0, 7, -0.571884835101f, -0.571884835101f, 0.27106905426f, 0.0f, + 8332872, 8332872, 0, 8, -0.642595081514f, -0.642595081514f, 0.26157281786f, 0.0f, + 8332872, 8332872, 0, 9, -0.712442843555f, -0.712442843555f, 0.243517227652f, 0.0f, + 8332872, 8332872, 0, 10, -0.78089653758f, -0.78089653758f, 0.217039697581f, 0.0f, + 8332872, 8332872, 0, 11, -0.847435189645f, -0.847435189645f, 0.182341737639f, 0.0f, + 8332872, 8332872, 0, 12, -0.911552400429f, -0.911552400429f, 0.13968742025f, 0.0f, + 8332872, 8332872, 0, 13, -0.972760199244f, -0.972760199244f, 0.089401370527f, 0.0f, + 8332872, 8332872, 0, 14, -1.03059275778f, -1.03059275778f, 0.0318662956709f, 0.0f, + 8332872, 8332872, 0, 15, -1.08460993535f, -1.08460993535f, -0.0324799276578f, 0.0f, + 8332872, 8332872, 0, 16, -1.13440062862f, -1.13440062862f, -0.103147585846f, 0.0f, + 8332872, 8332872, 0, 17, -1.17958590034f, -1.17958590034f, -0.179598855345f, 0.0f, + 8332872, 8332872, 0, 18, -1.21982186332f, -1.21982186332f, -0.261251895832f, 0.0f, + 8332872, 8332872, 0, 19, -1.25480229757f, -1.25480229757f, -0.347485278364f, 0.0f, + 8332872, 8332872, 0, 20, -1.28426098088f, -1.28426098088f, -0.437642714831f, 0.0f, + 8332872, 8332872, 0, 21, -1.30797371487f, -1.30797371487f, -0.531038052704f, 0.0f, + 8332872, 8332872, 0, 22, -1.32576003133f, -1.32576003133f, -0.626960497068f, 0.0f, + 8332872, 8332872, 0, 23, -1.33748456564f, -1.33748456564f, -0.724680020201f, 0.0f}; + + +const std::vector<Mantid::coord_t> test_NormTime_ref = { + 600, 0, 0, 0, -0.09776273f, -0.09776273f, 0.10005156f, 0.0f, + 600, 0, 0, 1, -0.15959044f, -0.15959044f, 0.14884006f, 0.0f, + 600, 0, 0, 2, -0.224231616093f, -0.224231616093f, 0.189927174618f, 0.0f, + 600, 0, 0, 3, -0.291194311172f, -0.291194311172f, 0.223000198347f, 0.0f, + 600, 0, 0, 4, -0.359968893923f, -0.359968893923f, 0.247807429194f, 0.0f, + 600, 0, 0, 5, -0.430031948245f, -0.430031948245f, 0.264160069153f, 0.0f, + 600, 0, 0, 6, -0.500850251989f, -0.500850251989f, 0.271933664761f, 0.0f, + 600, 0, 0, 7, -0.571884835101f, -0.571884835101f, 0.27106905426f, 0.0f, + 600, 0, 0, 8, -0.642595081514f, -0.642595081514f, 0.26157281786f, 0.0f, + 600, 0, 0, 9, -0.712442843555f, -0.712442843555f, 0.243517227652f, 0.0f, + 600, 0, 0, 10, -0.78089653758f, -0.78089653758f, 0.217039697581f, 0.0f, + 600, 0, 0, 11, -0.847435189645f, -0.847435189645f, 0.182341737639f, 0.0f, + 600, 0, 0, 12, -0.911552400429f, -0.911552400429f, 0.13968742025f, 0.0f, + 600, 0, 0, 13, -0.972760199244f, -0.972760199244f, 0.089401370527f, 0.0f, + 600, 0, 0, 14, -1.03059275778f, -1.03059275778f, 0.0318662956709f, 0.0f, + 600, 0, 0, 15, -1.08460993535f, -1.08460993535f, -0.0324799276578f, 0.0f, + 600, 0, 0, 16, -1.13440062862f, -1.13440062862f, -0.103147585846f, 0.0f, + 600, 0, 0, 17, -1.17958590034f, -1.17958590034f, -0.179598855345f, 0.0f, + 600, 0, 0, 18, -1.21982186332f, -1.21982186332f, -0.261251895832f, 0.0f, + 600, 0, 0, 19, -1.25480229757f, -1.25480229757f, -0.347485278364f, 0.0f, + 600, 0, 0, 20, -1.28426098088f, -1.28426098088f, -0.437642714831f, 0.0f, + 600, 0, 0, 21, -1.30797371487f, -1.30797371487f, -0.531038052704f, 0.0f, + 600, 0, 0, 22, -1.32576003133f, -1.32576003133f, -0.626960497068f, 0.0f, + 600, 0, 0, 23, -1.33748456564f, -1.33748456564f, -0.724680020201f, 0.0f}; + + +const std::vector<Mantid::coord_t> test_2ThetaLimits_ref = { + 32369, 32369, 0, 3, -0.291194311172f, -0.291194311172f, 0.223000198347f, 0.0f, + 31851, 31851, 0, 4, -0.359968893923f, -0.359968893923f, 0.247807429194f, 0.0f, + 30221, 30221, 0, 5, -0.430031948245f, -0.430031948245f, 0.264160069153f, 0.0f, + 26267, 26267, 0, 6, -0.500850251989f, -0.500850251989f, 0.271933664761f, 0.0f, + 26788, 26788, 0, 7, -0.571884835101f, -0.571884835101f, 0.27106905426f, 0.0f, + 29729, 29729, 0, 8, -0.642595081514f, -0.642595081514f, 0.26157281786f, 0.0f, + 30188, 30188, 0, 9, -0.712442843555f, -0.712442843555f, 0.243517227652f, 0.0f}; + +// reference vector, EPP is wrong, since no elastic channel is given +const std::vector<Mantid::coord_t> test_TOFWSData_ref = { + 0, 0, 0, 3, -0.0943541043211f, -0.0943541043211f, 2.51817307323f, -2.22473993186f, //0 + 0, 0, 0, 3, -0.105491719946f, -0.105491719946f, 2.18460421817f, -1.53897441518f, //1 + 0, 0, 0, 3, -0.115542738924f, -0.115542738924f, 1.88357866605f, -0.951095651067f, //2 + 0, 0, 0, 3, -0.124658779393f, -0.124658779393f, 1.61055549086f, -0.443322919741f, //3 + 0, 0, 0, 3, -0.132964505153f, -0.132964505153f, 1.36180104236f, -0.00173676689289f, //4 + 0, 0, 0, 3, -0.140563360636f, -0.140563360636f, 1.13421718522f, 0.384685191257f, //5 + 0, 0, 0, 3, -0.147541901385f, -0.147541901385f, 0.925211602133f, 0.724762824962f, //6 + 0, 0, 0, 3, -0.153973105606f, -0.153973105606f, 0.732598613797f, 1.02562126597f, //7 + 0, 0, 0, 3, -0.159918935922f, -0.159918935922f, 0.55452245477f, 1.29306717609f, //8 + 0, 0, 0, 3, -0.165432342216f, -0.165432342216f, 0.389397289126f, 1.53187104043f, //9 + 0, 0, 0, 3, -0.170558842805f, -0.170558842805f, 0.235859854405f, 1.7459813825f, //10 + 0, 0, 0, 3, -0.175337784032f, -0.175337784032f, 0.0927317372921f, 1.93868903792f, //11 + 0, 0, 0, 3, -0.179803352064f, -0.179803352064f, -0.0410109295185f, 2.11275436309f, //12 + 0, 0, 0, 3, -0.183985391967f, -0.183985391967f, -0.166261998436f, 2.27050663742f, //13 + 0, 0, 0, 3, -0.187910075568f, -0.187910075568f, -0.283805309267f, 2.41392239469f, //14 + 0, 0, 0, 3, -0.1916004497f, -0.1916004497f, -0.394331109003f, 2.54468763779f, //15 + 0, 0, 0, 3, -0.1950768891f, -0.1950768891f, -0.498449616001f, 2.664247618f, //16 + 0, 0, 0, 3, -0.198357472759f, -0.198357472759f, -0.596702291619f, 2.77384694056f, //17 + 0, 0, 0, 3, -0.20145829841f, -0.20145829841f, -0.689571258983f, 2.87456208674f, //18 + 0, 0, 0, 3, -0.204393746692f, -0.204393746692f, -0.777487214755f, 2.96732794808f, //19 + 0, 0, 0, 3, -0.207176704155f, -0.207176704155f, -0.86083610789f, 3.05295960034f, //20 + 0, 0, 0, 3, -0.209818752378f, -0.209818752378f, -0.939964803903f, 3.13217026882f, //21 + 0, 0, 0, 3, -0.212330329085f, -0.212330329085f, -1.01518590999f, 3.20558622767f, //22 + 0, 0, 0, 3, -0.214720865951f, -0.214720865951f, -1.08678190253f, 3.27375921711f, //23 + 0, 0, 0, 3, -0.216998906964f, -0.216998906964f, -1.15500867189f, 3.33717683991f, //24 + 0, 0, 0, 3, -0.219172210459f, -0.219172210459f, -1.2200985783f, 3.39627130464f, //25 + 0, 0, 0, 3, -0.221247837392f, -0.221247837392f, -1.28226309565f, 3.45142680925f, //26 + 0, 0, 0, 3, -0.223232227977f, -0.223232227977f, -1.34169510674f, 3.5029858015f, //27 + 0, 0, 0, 3, -0.225131268429f, -0.225131268429f, -1.39857090231f, 3.55125430721f, //28 + 0, 0, 0, 3, -0.226950349283f, -0.226950349283f, -1.45305192753f, 3.59650648186f, //29 + 0, 0, 0, 3, -0.228694416494f, -0.228694416494f, -1.50528631254f, 3.63898851198f, //30 + 0, 0, 0, 3, -0.230368016343f, -0.230368016343f, -1.55541021734f, 3.67892197067f, //31 + 0, 0, 0, 3, -0.231975335009f, -0.231975335009f, -1.60354901701f, 3.71650671254f, //32 + 0, 0, 0, 3, -0.233520233533f, -0.233520233533f, -1.64981834872f, 3.75192337916f, //33 + 0, 0, 0, 3, -0.23500627878f, -0.23500627878f, -1.69432503923f, 3.78533557363f, //34 + 0, 0, 0, 3, -0.236436770934f, -0.236436770934f, -1.73716792823f, 3.81689175332f, //35 + 0, 0, 0, 3, -0.237814767963f, -0.237814767963f, -1.77843860111f, 3.84672688183f, //36 + 0, 0, 0, 3, -0.239143107441f, -0.239143107441f, -1.81822204254f, 3.87496387446f, //37 + 0, 0, 0, 3, -0.240424426052f, -0.240424426052f, -1.85659722056f, 3.90171486617f, //38 + 0, 0, 0, 3, -0.24166117706f, -0.24166117706f, -1.89363760977f, 3.92708232664f, //39 + 0, 0, 0, 3, -0.242855645982f, -0.242855645982f, -1.92941166089f, 3.95116004298f, //40 + 1, 1, 0, 3, -0.244009964688f, -0.244009964688f, -1.9639832229f, 3.97403398783f, //41 + 1, 1, 0, 3, -0.245126124099f, -0.245126124099f, -1.99741192336f, 3.99578308789f, //42 + 0, 0, 0, 3, -0.246205985642f, -0.246205985642f, -2.0297535116f, 4.01647990566f, + 2, 2, 0, 3, -0.247251291615f, -0.247251291615f, -2.06106016902f, 4.03619124547f, + 0, 0, 0, 3, -0.248263674566f, -0.248263674566f, -2.09138078999f, 4.05497869322f, + 2, 2, 0, 3, -0.249244665798f, -0.249244665798f, -2.12076123667f, 4.07289909803f, + 6, 6, 0, 3, -0.250195703099f, -0.250195703099f, -2.14924457046f, 4.09000500276f, //EPP + 3, 3, 0, 3, -0.251118137774f, -0.251118137774f, -2.17687126264f, 4.10634502964f, + 0, 0, 0, 3, -0.252013241051f, -0.252013241051f, -2.20367938617f, 4.12196422612f, + 0, 0, 0, 3, -0.252882209926f, -0.252882209926f, -2.22970479075f, 4.1369043757f, + 0, 0, 0, 3, -0.253726172503f, -0.253726172503f, -2.25498126284f, 4.15120427767f, + 0, 0, 0, 3, -0.254546192879f, -0.254546192879f, -2.27954067188f, 4.16489999925f, + 0, 0, 0, 3, -0.255343275622f, -0.255343275622f, -2.30341310445f, 4.17802510323f, + 0, 0, 0, 3, -0.256118369875f, -0.256118369875f, -2.32662698715f, 4.19061085383f, + 0, 0, 0, 3, -0.256872373129f, -0.256872373129f, -2.34920919958f, 4.20268640299f, + 0, 0, 0, 3, -0.257606134684f, -0.257606134684f, -2.37118517811f, 4.2142789594f, + 0, 0, 0, 3, -0.258320458847f, -0.258320458847f, -2.39257901152f, 4.22541394183f, + 0, 0, 0, 3, -0.259016107869f, -0.259016107869f, -2.41341352902f, 4.23611511866f, + 0, 0, 0, 3, -0.259693804658f, -0.259693804658f, -2.43371038155f, 4.24640473475f, + 0, 0, 0, 3, -0.260354235286f, -0.260354235286f, -2.45349011683f, 4.25630362721f, + 0, 0, 0, 3, -0.260998051308f, -0.260998051308f, -2.4727722487f, 4.2658313309f, + 0, 0, 0, 3, -0.2616258719f, -0.2616258719f, -2.49157532139f, 4.27500617494f, + 0, 0, 0, 3, -0.262238285852f, -0.262238285852f, -2.50991696898f, 4.2838453709f, + 0, 0, 0, 3, -0.262835853406f, -0.262835853406f, -2.52781397058f, 4.2923650936f, + 0, 0, 0, 3, -0.263419107964f, -0.263419107964f, -2.54528230147f, 4.30058055512f, + 0, 0, 0, 3, -0.26398855768f, -0.26398855768f, -2.56233718075f, 4.3085060728f, + 0, 0, 0, 3, -0.264544686935f, -0.264544686935f, -2.57899311548f, 4.31615513161f, + 0, 0, 0, 3, -0.265087957711f, -0.265087957711f, -2.5952639419f, 4.32354044159f, + 0, 0, 0, 3, -0.265618810868f, -0.265618810868f, -2.61116286371f, 4.33067399066f, + 0, 0, 0, 3, -0.266137667344f, -0.266137667344f, -2.62670248786f, 4.33756709332f, + 0, 0, 0, 3, -0.266644929262f, -0.266644929262f, -2.64189485783f, 4.34423043551f, + 0, 0, 0, 3, -0.267140980972f, -0.267140980972f, -2.65675148482f, 4.35067411606f, + 0, 0, 0, 3, -0.267626190022f, -0.267626190022f, -2.67128337679f, 4.35690768501f, + 0, 0, 0, 3, -0.268100908065f, -0.268100908065f, -2.6855010657f, 4.36294017896f, + 0, 0, 0, 3, -0.268565471711f, -0.268565471711f, -2.69941463291f, 4.3687801539f, + 0, 0, 0, 3, -0.269020203322f, -0.269020203322f, -2.7130337331f, 4.37443571549f, + 0, 0, 0, 3, -0.269465411759f, -0.269465411759f, -2.72636761653f, 4.37991454727f, + 0, 0, 0, 3, -0.269901393077f, -0.269901393077f, -2.73942515004f, 4.38522393675f, + 0, 0, 0, 3, -0.27032843119f, -0.27032843119f, -2.75221483671f, 4.39037079963f, + 0, 0, 0, 3, -0.270746798477f, -0.270746798477f, -2.76474483431f, 4.39536170235f, + 0, 0, 0, 3, -0.271156756372f, -0.271156756372f, -2.77702297266f, 4.40020288306f}; + +// reference vector, EPP should be near dE=0 +const std::vector<Mantid::coord_t> test_TOFWSDataRotateEPP_ref = { + 0, 0, 0, 4, 0.0354153287653f, 0.0354153287653f, 3.30960431031f, -2.22473993186f, + 0, 0, 0, 4, 0.0119271789404f, 0.0119271789404f, 3.14246833446f, -1.53897441518f, + 1, 1, 0, 4, -0.00926944407241f, -0.00926944407241f, 2.99163830747f, -0.951095651067f, + 1, 1, 0, 4, -0.0284942882003f, -0.0284942882003f, 2.85483898067f, -0.443322919741f, + 1, 1, 0, 4, -0.0460102572946f, -0.0460102572946f, 2.73019959403f, -0.00173676689289f, + 3, 3, 0, 4, -0.0620355056149f, -0.0620355056149f, 2.61616781476f, 0.384685191257f, + 1, 1, 0, 4, -0.0767525703988f, -0.0767525703988f, 2.51144475217f, 0.724762824962f, + 1, 1, 0, 4, -0.0903153555918f, -0.0903153555918f, 2.41493526311f, 1.02562126597f, + 0, 0, 0, 4, -0.102854534355f, -0.102854534355f, 2.32570950908f, 1.29306717609f, + 0, 0, 0, 4, -0.114481772845f, -0.114481772845f, 2.24297290079f, 1.53187104043f, + 0, 0, 0, 4, -0.125293064774f, -0.125293064774f, 2.16604237028f, 1.7459813825f, + 0, 0, 0, 4, -0.135371387759f, -0.135371387759f, 2.09432746896f, 1.93868903792f, + 0, 0, 0, 4, -0.144788837105f, -0.144788837105f, 2.02731518411f, 2.11275436309f, + 0, 0, 0, 4, -0.153608353159f, -0.153608353159f, 1.96455764752f, 2.27050663742f, + 0, 0, 0, 4, -0.161885129764f, -0.161885129764f, 1.90566211317f, 2.41392239469f, + 0, 0, 0, 4, -0.169667770453f, -0.169667770453f, 1.85028273012f, 2.54468763779f, + 0, 0, 0, 4, -0.176999243565f, -0.176999243565f, 1.7981137461f, 2.664247618f, + 0, 0, 0, 4, -0.183917675938f, -0.183917675938f, 1.74888385976f, 2.77384694056f, + 0, 0, 0, 4, -0.190457016127f, -0.190457016127f, 1.70235150145f, 2.87456208674f, + 0, 0, 0, 4, -0.196647591505f, -0.196647591505f, 1.65830086891f, 2.96732794808f, + 0, 0, 0, 4, -0.202516578553f, -0.202516578553f, 1.61653858092f, 3.05295960034f, + 0, 0, 0, 4, -0.208088401699f, -0.208088401699f, 1.57689083915f, 3.13217026882f, + 0, 0, 0, 4, -0.213385073084f, -0.213385073084f, 1.53920101056f, 3.20558622767f, + 0, 0, 0, 4, -0.218426483198f, -0.218426483198f, 1.50332755925f, 3.27375921711f, + 0, 0, 0, 4, -0.223230650484f, -0.223230650484f, 1.46914227036f, 3.33717683991f, + 0, 0, 0, 4, -0.227813936514f, -0.227813936514f, 1.43652871888f, 3.39627130464f, + 0, 0, 0, 4, -0.232191232162f, -0.232191232162f, 1.405380945f, 3.45142680925f, + 0, 0, 0, 4, -0.236376119209f, -0.236376119209f, 1.37560230404f, 3.5029858015f, + 0, 0, 0, 4, -0.240381011115f, -0.240381011115f, 1.34710446484f, 3.55125430721f, + 0, 0, 0, 4, -0.244217275993f, -0.244217275993f, 1.31980653466f, 3.59650648186f, + 0, 0, 0, 4, -0.247895344381f, -0.247895344381f, 1.29363429232f, 3.63898851198f, + 0, 0, 0, 4, -0.251424803946f, -0.251424803946f, 1.26851951432f, 3.67892197067f, + 0, 0, 0, 4, -0.254814482933f, -0.254814482933f, 1.24439938099f, 3.71650671254f, + 0, 0, 0, 4, -0.258072523902f, -0.258072523902f, 1.22121595187f, 3.75192337916f, + 0, 0, 0, 4, -0.261206449024f, -0.261206449024f, 1.198915701f, 3.78533557363f, + 0, 0, 0, 4, -0.264223218067f, -0.264223218067f, 1.17744910437f, 3.81689175332f, + 0, 0, 0, 4, -0.267129279989f, -0.267129279989f, 1.15677027275f, 3.84672688183f, + 0, 0, 0, 4, -0.269930618959f, -0.269930618959f, 1.13683662426f, 3.87496387446f, + 0, 0, 0, 4, -0.272632795488f, -0.272632795488f, 1.11760859164f, 3.90171486617f, + 0, 0, 0, 4, -0.275240983267f, -0.275240983267f, 1.09904936015f, 3.92708232664f, + 0, 0, 0, 4, -0.277760002234f, -0.277760002234f, 1.08112463231f, 3.95116004298f, + 0, 0, 0, 4, -0.280194348295f, -0.280194348295f, 1.06380241632f, 3.97403398783f, + 0, 0, 0, 4, -0.282548220105f, -0.282548220105f, 1.04705283558f, 3.99578308789f, + 0, 0, 0, 4, -0.284825543238f, -0.284825543238f, 1.03084795664f, 4.01647990566f, + 0, 0, 0, 4, -0.287029992032f, -0.287029992032f, 1.01516163384f, 4.03619124547f, + 0, 0, 0, 4, -0.289165009367f, -0.289165009367f, 0.999969368441f, 4.05497869322f, + 0, 0, 0, 4, -0.291233824614f, -0.291233824614f, 0.985248181042f, 4.07289909803f, + 0, 0, 0, 4, -0.293239469931f, -0.293239469931f, 0.970976495549f, 4.09000500276f, + 0, 0, 0, 4, -0.295184795087f, -0.295184795087f, 0.957134033679f, 4.10634502964f, + 0, 0, 0, 4, -0.297072480979f, -0.297072480979f, 0.943701718828f, 4.12196422612f, + 0, 0, 0, 4, -0.298905051955f, -0.298905051955f, 0.930661588352f, 4.1369043757f, + 0, 0, 0, 4, -0.300684887075f, -0.300684887075f, 0.91799671343f, 4.15120427767f, + 0, 0, 0, 4, -0.302414230419f, -0.302414230419f, 0.905691125739f, 4.16489999925f, + 0, 0, 0, 4, -0.304095200523f, -0.304095200523f, 0.893729750291f, 4.17802510323f, + 0, 0, 0, 4, -0.305729799037f, -0.305729799037f, 0.882098343821f, 4.19061085383f, + 0, 0, 0, 4, -0.307319918681f, -0.307319918681f, 0.870783438208f, 4.20268640299f, + 0, 0, 0, 4, -0.308867350548f, -0.308867350548f, 0.859772288449f, 4.2142789594f, + 0, 0, 0, 4, -0.310373790843f, -0.310373790843f, 0.849052824778f, 4.22541394183f, + 0, 0, 0, 4, -0.311840847078f, -0.311840847078f, 0.838613608522f, 4.23611511866f, + 0, 0, 0, 4, -0.313270043798f, -0.313270043798f, 0.828443791396f, 4.24640473475f, + 0, 0, 0, 4, -0.314662827862f, -0.314662827862f, 0.81853307789f, 4.25630362721f, + 0, 0, 0, 4, -0.316020573333f, -0.316020573333f, 0.808871690511f, 4.2658313309f, + 0, 0, 0, 4, -0.317344585997f, -0.317344585997f, 0.799450337601f, 4.27500617494f, + 0, 0, 0, 4, -0.318636107553f, -0.318636107553f, 0.790260183535f, 4.2838453709f, + 0, 0, 0, 4, -0.319896319496f, -0.319896319496f, 0.781292821082f, 4.2923650936f, + 0, 0, 0, 4, -0.321126346721f, -0.321126346721f, 0.772540245755f, 4.30058055512f, + 0, 0, 0, 4, -0.322327260876f, -0.322327260876f, 0.763994831973f, 4.3085060728f, + 0, 0, 0, 4, -0.323500083472f, -0.323500083472f, 0.755649310912f, 4.31615513161f, + 0, 0, 0, 4, -0.324645788783f, -0.324645788783f, 0.747496749875f, 4.32354044159f, + 0, 0, 0, 4, -0.325765306543f, -0.325765306543f, 0.739530533091f, 4.33067399066f, + 0, 0, 0, 4, -0.326859524467f, -0.326859524467f, 0.731744343804f, 4.33756709332f, + 0, 0, 0, 4, -0.327929290594f, -0.327929290594f, 0.724132147574f, 4.34423043551f, + 0, 0, 0, 4, -0.328975415481f, -0.328975415481f, 0.716688176675f, 4.35067411606f, + 0, 0, 0, 4, -0.329998674249f, -0.329998674249f, 0.709406915523f, 4.35690768501f, + 0, 0, 0, 4, -0.330999808504f, -0.330999808504f, 0.702283087044f, 4.36294017896f, + 0, 0, 0, 4, -0.331979528123f, -0.331979528123f, 0.695311639923f, 4.3687801539f, + 0, 0, 0, 4, -0.332938512934f, -0.332938512934f, 0.688487736656f, 4.37443571549f, + 0, 0, 0, 4, -0.333877414294f, -0.333877414294f, 0.681806742359f, 4.37991454727f, + 0, 0, 0, 4, -0.334796856559f, -0.334796856559f, 0.675264214264f, 4.38522393675f, + 0, 0, 0, 4, -0.335697438469f, -0.335697438469f, 0.668855891874f, 4.39037079963f, + 0, 0, 0, 4, -0.336579734452f, -0.336579734452f, 0.662577687705f, 4.39536170235f, + 0, 0, 0, 4, -0.337444295843f, -0.337444295843f, 0.656425678595f, 4.40020288306f}; + +// clang-format on +#endif // LOADDNSSCDTESTREFERENCE_H diff --git a/Framework/Muon/src/CalculateMuonAsymmetry.cpp b/Framework/Muon/src/CalculateMuonAsymmetry.cpp index 6b85662dbad5878846cd9f3fcc5298eee627d3da..15f6af64f6797c63a769c9944860f57069a87646 100644 --- a/Framework/Muon/src/CalculateMuonAsymmetry.cpp +++ b/Framework/Muon/src/CalculateMuonAsymmetry.cpp @@ -80,6 +80,7 @@ void CalculateMuonAsymmetry::init() { "MaxIterations", 500, mustBePositive->clone(), "Stop after this number of iterations if a good fit is not found"); declareProperty("OutputStatus", "", Kernel::Direction::Output); + declareProperty("ChiSquared", 0.0, Kernel::Direction::Output); declareProperty(make_unique<API::FunctionProperty>("OutputFunction", Kernel::Direction::Output), "The fitting function after fit."); @@ -251,7 +252,8 @@ std::vector<double> CalculateMuonAsymmetry::getNormConstants( fit->execute(); auto status = fit->getPropertyValue("OutputStatus"); setProperty("OutputStatus", status); - + double chi2 = std::stod(fit->getPropertyValue("OutputChi2overDoF")); + setProperty("ChiSquared", chi2); API::IFunction_sptr tmp = fit->getProperty("Function"); setProperty("OutputFunction", tmp); try { diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/ContainerDtype.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/ContainerDtype.h index ba5428819b01be68143c591c6cb625844f89cbd9..a356083e3d1e290aad15b542d17bcc4b50121993 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/ContainerDtype.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/ContainerDtype.h @@ -8,7 +8,7 @@ ContainerDtype Header File A helper free function to allow identification of data type being used by - providing a numpy friendly string. + providing a numpy friendly string (using the numpy array interface). @author Lamar Moore STFC, Bhuvan Bezawada STFC @date 21/06/2018 @@ -43,29 +43,13 @@ namespace Converters { template <template <class> class Container, typename HeldType> std::string dtype(const Container<HeldType> &) { if (std::is_same<HeldType, bool>::value) { - return "bool_"; - } else if (std::is_same<HeldType, short>::value) { - return "int16"; - } else if (std::is_same<HeldType, std::int8_t>::value) { - return "int8"; - } else if (std::is_same<HeldType, std::int16_t>::value) { - return "int16"; - } else if (std::is_same<HeldType, std::int32_t>::value) { - return "int32"; - } else if (std::is_same<HeldType, std::int64_t>::value) { - return "int64"; - } else if (std::is_same<HeldType, long>::value) { - return "int_"; - } else if (std::is_same<HeldType, long long>::value) { - return "int64"; - } else if (std::is_same<HeldType, float>::value) { - return "float32"; - } else if (std::is_same<HeldType, double>::value) { - return "float64"; - } else if (std::is_same<HeldType, std::string>::value) { - return "string_"; + return "b"; + } else if (std::is_integral<HeldType>::value) { + return "i"; + } else if (std::is_floating_point<HeldType>::value) { + return "f"; } else { - return "object_"; + return "O"; } } diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/PropertyWithValueExporter.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/PropertyWithValueExporter.h index 6254785d87f458ef42cfe257b964a9627b3896c2..2270d5c0425acaf2d5e954bfe6fa0397f26c4aa4 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/PropertyWithValueExporter.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/PropertyWithValueExporter.h @@ -37,6 +37,15 @@ // Call the dtype helper function template <typename HeldType> std::string dtype(Mantid::Kernel::PropertyWithValue<HeldType> &self) { + // Check for the special case of a string + if (std::is_same<HeldType, std::string>::value) { + std::stringstream ss; + std::string val = self.value(); + ss << "S" << val.size(); + std::string ret_val = ss.str(); + return ret_val; + } + return Mantid::PythonInterface::Converters::dtype(self); } diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/PropertyWithValueFactory.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/PropertyWithValueFactory.h index 9b4f222e2ca53a3f888f68abb26f377aaefd5f60..b591c6c6c0b67b51a67f4aae0197d0a4797b6d3a 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/PropertyWithValueFactory.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/PropertyWithValueFactory.h @@ -1,5 +1,5 @@ -#ifndef MANTID_PYTHONINTERFACE_PROEPRTYWITHVALUEFACTORY_H_ -#define MANTID_PYTHONINTERFACE_PROEPRTYWITHVALUEFACTORY_H_ +#ifndef MANTID_PYTHONINTERFACE_PROPERTYWITHVALUEFACTORY_H_ +#define MANTID_PYTHONINTERFACE_PROPERTYWITHVALUEFACTORY_H_ /** Copyright © 2011 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source @@ -26,8 +26,8 @@ // Includes //----------------------------------------------------------------------------- #include "MantidPythonInterface/kernel/Registry/PropertyValueHandler.h" +#include <boost/python/list.hpp> #include <memory> -#include <string> namespace Mantid { //--------------------------------------------------------------------------- @@ -53,6 +53,10 @@ public: create(const std::string &name, const boost::python::object &defaultValue, const unsigned int direction); + static std::unique_ptr<Kernel::Property> + createTimeSeries(const std::string &name, + const boost::python::list &defaultValue); + private: /// Return a handler that maps the python type to a C++ type static const PropertyValueHandler &lookup(PyObject *const object); @@ -63,4 +67,4 @@ private: } // namespace PythonInterface } // namespace Mantid -#endif // MANTID_PYTHONINTERFACE_PROEPRTYWITHVALUEFACTORY_H_ +#endif // MANTID_PYTHONINTERFACE_PROPERTYWITHVALUEFACTORY_H_ diff --git a/Framework/PythonInterface/mantid/api/CMakeLists.txt b/Framework/PythonInterface/mantid/api/CMakeLists.txt index ceff8f34f5952a884bdab6b4a3647aab6589758b..61c8df4b654716aa66e216fef51f6f7a46c84030 100644 --- a/Framework/PythonInterface/mantid/api/CMakeLists.txt +++ b/Framework/PythonInterface/mantid/api/CMakeLists.txt @@ -14,7 +14,6 @@ set ( EXPORT_FILES src/Exports/AlgorithmHistory.cpp src/Exports/CatalogManager.cpp src/Exports/CatalogSession.cpp - src/Exports/DetectorInfo.cpp src/Exports/DeprecatedAlgorithmChecker.cpp src/Exports/Algorithm.cpp src/Exports/DataProcessorAlgorithm.cpp @@ -55,6 +54,7 @@ set ( EXPORT_FILES src/Exports/WorkspaceValidators.cpp src/Exports/ADSValidator.cpp src/Exports/InstrumentValidator.cpp + src/Exports/OrientedLatticeValidator.cpp src/Exports/Axis.cpp src/Exports/IPeak.cpp src/Exports/BoxController.cpp diff --git a/Framework/PythonInterface/mantid/api/src/Exports/DetectorInfo.cpp b/Framework/PythonInterface/mantid/api/src/Exports/DetectorInfo.cpp deleted file mode 100644 index cb2aa1c730016998cff493bd39b38bc1c9cf5d7f..0000000000000000000000000000000000000000 --- a/Framework/PythonInterface/mantid/api/src/Exports/DetectorInfo.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "MantidGeometry/Instrument/DetectorInfo.h" -#include <boost/python/class.hpp> - -using Mantid::Geometry::DetectorInfo; -using namespace boost::python; - -void export_DetectorInfo() { - // WARNING DetectorInfo is work in progress and not ready for exposing more of - // its functionality to Python, and should not yet be used in user scripts. DO - // NOT ADD EXPORTS TO OTHER METHODS without contacting the team working on - // Instrument-2.0. - bool (DetectorInfo::*isMonitor)(const size_t) const = - &DetectorInfo::isMonitor; - bool (DetectorInfo::*isMasked)(const size_t) const = &DetectorInfo::isMasked; - class_<DetectorInfo, boost::noncopyable>("DetectorInfo", no_init) - .def("__len__", &DetectorInfo::size, (arg("self")), - "Returns the size of the DetectorInfo, i.e., the number of " - "detectors in the instrument.") - .def("size", &DetectorInfo::size, (arg("self")), - "Returns the size of the DetectorInfo, i.e., the number of " - "detectors in the instrument.") - .def("isMonitor", isMonitor, (arg("self"), arg("index")), - "Returns True if the detector is a monitor.") - .def("isMasked", isMasked, (arg("self"), arg("index")), - "Returns True if the detector is masked."); -} diff --git a/Framework/PythonInterface/mantid/api/src/Exports/ExperimentInfo.cpp b/Framework/PythonInterface/mantid/api/src/Exports/ExperimentInfo.cpp index 237397700903b022f28c1b59d178ee455291164c..459a987c54318dffd3c2f2436c93ded403f5b046 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/ExperimentInfo.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/ExperimentInfo.cpp @@ -75,7 +75,8 @@ void export_ExperimentInfo() { .def("detectorInfo", &ExperimentInfo::detectorInfo, return_value_policy<reference_existing_object>(), args("self"), - "Return a const reference to the :class:`~mantid.api.DetectorInfo` " + "Return a const reference to the " + ":class:`~mantid.geometry.DetectorInfo` " "object.") .def("spectrumInfo", &ExperimentInfo::spectrumInfo, return_value_policy<reference_existing_object>(), args("self"), diff --git a/Framework/PythonInterface/mantid/api/src/Exports/OrientedLatticeValidator.cpp b/Framework/PythonInterface/mantid/api/src/Exports/OrientedLatticeValidator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fd6a74a50a1c96b043a6daa73aba8cc9671cb7c3 --- /dev/null +++ b/Framework/PythonInterface/mantid/api/src/Exports/OrientedLatticeValidator.cpp @@ -0,0 +1,19 @@ +#include "MantidAPI/OrientedLatticeValidator.h" +#include "MantidPythonInterface/kernel/TypedValidatorExporter.h" +#include <boost/python/class.hpp> + +using namespace Mantid::API; +using Mantid::PythonInterface::TypedValidatorExporter; +using namespace boost::python; + +// This is typed on the ExperimentInfo class +void export_OrientedLatticeValidator() { + TypedValidatorExporter<ExperimentInfo_sptr>::define( + "OrientedLatticeValidator"); + + class_<OrientedLatticeValidator, + bases<Mantid::Kernel::TypedValidator<ExperimentInfo_sptr>>, + boost::noncopyable>( + "OrientedLatticeValidator", + init<>("Checks that the workspace has an orientation matrix defined")); +} diff --git a/Framework/PythonInterface/mantid/dataobjects/src/Exports/EventList.cpp b/Framework/PythonInterface/mantid/dataobjects/src/Exports/EventList.cpp index 538a8620ec61f2304ecaf2e98d1b8f46a98d26dd..9b810b94f2d69191f6c87c609bdbaa5d8a4c8041 100644 --- a/Framework/PythonInterface/mantid/dataobjects/src/Exports/EventList.cpp +++ b/Framework/PythonInterface/mantid/dataobjects/src/Exports/EventList.cpp @@ -2,6 +2,7 @@ #include "MantidPythonInterface/kernel/GetPointer.h" #include <boost/python/class.hpp> #include <boost/python/register_ptr_to_python.hpp> +#include <boost/python/return_arg.hpp> using namespace boost::python; using namespace Mantid::DataObjects; @@ -22,5 +23,13 @@ void export_EventList() { "EventList") .def("addEventQuickly", &addEventToEventList, args("self", "tof", "pulsetime"), - "Create TofEvent and add to EventList."); + "Create TofEvent and add to EventList.") + .def("__iadd__", + (EventList & (EventList::*)(const EventList &)) & + EventList::operator+=, + return_self<>(), (arg("self"), arg("other"))) + .def("__isub__", + (EventList & (EventList::*)(const EventList &)) & + EventList::operator-=, + return_self<>(), (arg("self"), arg("other"))); } diff --git a/Framework/PythonInterface/mantid/geometry/CMakeLists.txt b/Framework/PythonInterface/mantid/geometry/CMakeLists.txt index 7034d098719d25ec1f94e1ce2e685de3c94b29db..4392273d5aea71c4a4f18d200f41f4d21dc46a75 100644 --- a/Framework/PythonInterface/mantid/geometry/CMakeLists.txt +++ b/Framework/PythonInterface/mantid/geometry/CMakeLists.txt @@ -38,6 +38,7 @@ set ( EXPORT_FILES src/Exports/SymmetryOperationFactory.cpp src/Exports/CrystalStructure.cpp src/Exports/ReflectionGenerator.cpp + src/Exports/DetectorInfo.cpp ) ############################################################################################# diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/DetectorInfo.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/DetectorInfo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0952b0c8ae7c834a715660f135e7e070eae26049 --- /dev/null +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/DetectorInfo.cpp @@ -0,0 +1,72 @@ +#include "MantidGeometry/Instrument/DetectorInfo.h" +#include "MantidKernel/Quat.h" +#include "MantidKernel/V3D.h" +#include <boost/python/class.hpp> +#include <boost/python/copy_const_reference.hpp> +#include <boost/python/return_value_policy.hpp> + +using Mantid::Geometry::DetectorInfo; +using Mantid::Kernel::Quat; +using Mantid::Kernel::V3D; +using namespace boost::python; + +void export_DetectorInfo() { + + // Function pointers to distinguish between overloaded versions + bool (DetectorInfo::*isMonitor)(const size_t) const = + &DetectorInfo::isMonitor; + + bool (DetectorInfo::*isMasked)(const size_t) const = &DetectorInfo::isMasked; + + double (DetectorInfo::*twoTheta)(const size_t) const = + &DetectorInfo::twoTheta; + + Mantid::Kernel::V3D (DetectorInfo::*position)(const size_t) const = + &DetectorInfo::position; + + Mantid::Kernel::Quat (DetectorInfo::*rotation)(const size_t) const = + &DetectorInfo::rotation; + + void (DetectorInfo::*setMasked)(const size_t, bool) = + &DetectorInfo::setMasked; + + // Export to Python + class_<DetectorInfo, boost::noncopyable>("DetectorInfo", no_init) + .def("__len__", &DetectorInfo::size, (arg("self")), + "Returns the size of the DetectorInfo, i.e., the number of " + "detectors in the instrument.") + + .def("size", &DetectorInfo::size, (arg("self")), + "Returns the size of the DetectorInfo, i.e., the number of " + "detectors in the instrument.") + + .def("isMonitor", isMonitor, (arg("self"), arg("index")), + "Returns True if the detector is a monitor.") + + .def("isMasked", isMasked, (arg("self"), arg("index")), + "Returns True if the detector is masked.") + + .def("setMasked", setMasked, (arg("self"), arg("index"), arg("masked")), + "Set the mask flag of the detector where the detector is identified " + "by 'index'.") + + .def("clearMaskFlags", &DetectorInfo::clearMaskFlags, (arg("self")), + "Sets all mask flags to false (unmasked).") + + .def("isEquivalent", &DetectorInfo::isEquivalent, + (arg("self"), arg("other")), + "Returns True if the content of this " + "detector is equivalent to the content " + "of the other detector.") + + .def("twoTheta", twoTheta, (arg("self"), arg("index")), + "Returns 2 theta (scattering angle w.r.t beam direction).") + + .def("position", position, (arg("self"), arg("index")), + "Returns the absolute position of the detector where the detector " + "is identified by 'index'.") + + .def("rotation", rotation, (arg("self"), arg("index")), + "Returns the absolute rotation of the detector where the detector " + "is identified by 'index'."); +} diff --git a/Framework/PythonInterface/mantid/kernel/CMakeLists.txt b/Framework/PythonInterface/mantid/kernel/CMakeLists.txt index b8ce08e9069086e3ec66795771b1c7875e46226e..ca639abb8e96d43ade974d3463057629f8b535ec 100644 --- a/Framework/PythonInterface/mantid/kernel/CMakeLists.txt +++ b/Framework/PythonInterface/mantid/kernel/CMakeLists.txt @@ -60,6 +60,7 @@ set ( EXPORT_FILES src/Exports/UsageService.cpp src/Exports/Atom.cpp src/Exports/StringContainsValidator.cpp + src/Exports/PropertyFactory.cpp ) set ( MODULE_DEFINITION ${CMAKE_CURRENT_BINARY_DIR}/kernel.cpp ) diff --git a/Framework/PythonInterface/mantid/kernel/funcinspect.py b/Framework/PythonInterface/mantid/kernel/funcinspect.py index 1da6e1e69032960d9efbe82e1d7f32b0642e09b0..8f6354b1287e2f690d7605ca567e13c636525bd7 100644 --- a/Framework/PythonInterface/mantid/kernel/funcinspect.py +++ b/Framework/PythonInterface/mantid/kernel/funcinspect.py @@ -148,7 +148,7 @@ __operator_names = set(['CALL_FUNCTION', 'CALL_FUNCTION_VAR', 'CALL_FUNCTION_KW' 'INPLACE_MODULO', 'INPLACE_ADD', 'INPLACE_SUBTRACT', 'INPLACE_LSHIFT','INPLACE_RSHIFT','INPLACE_AND', 'INPLACE_XOR', 'INPLACE_OR', 'COMPARE_OP', - 'CALL_FUNCTION_EX']) + 'CALL_FUNCTION_EX', 'LOAD_METHOD', 'CALL_METHOD']) #-------------------------------------------------------------------------------------- def process_frame(frame): diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/ArrayProperty.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/ArrayProperty.cpp index c765253ae931cb167a601d4dbf2a6530cee44265..3dab4e7248a82d8072dc5f2f447cd629ad4d4d34 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Exports/ArrayProperty.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/ArrayProperty.cpp @@ -33,6 +33,35 @@ template <typename type> std::string dtype(ArrayProperty<type> &self) { return Converters::dtype(self); } +// Check for the special case of a string +template <> std::string dtype(ArrayProperty<std::string> &self) { + // Get a vector of all the strings + std::vector<std::string> values = self(); + + // Vector of ints to store the sizes of each of the strings + std::vector<size_t> stringSizes; + + // Block allocate memory + stringSizes.reserve(self.size()); + + // Loop for the number of strings + // For each string store the number of characters + for (auto val : values) { + auto size = val.size(); + stringSizes.emplace_back(size); + } + + // Find the maximum number of characters + size_t max = + *std::max_element(std::begin(stringSizes), std::end(stringSizes)); + + // Create the string to return + std::stringstream ss; + ss << "S" << max; + std::string retVal = ss.str(); + return retVal; +} + #define EXPORT_ARRAY_PROP(type, prefix) \ class_<ArrayProperty<type>, bases<PropertyWithValue<std::vector<type>>>, \ boost::noncopyable>(#prefix "ArrayProperty", no_init) \ diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyFactory.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyFactory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8e3f145c4238923e32eb696e72c465d91878f7cf --- /dev/null +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyFactory.cpp @@ -0,0 +1,38 @@ +#include "MantidPythonInterface/kernel/Registry/PropertyWithValueFactory.h" +#include "MantidPythonInterface/kernel/Registry/SequenceTypeHandler.h" +#include "MantidPythonInterface/kernel/Registry/TypedPropertyValueHandler.h" + +#include <boost/python/class.hpp> +#include <boost/python/manage_new_object.hpp> +#include <boost/python/register_ptr_to_python.hpp> +#include <boost/python/return_value_policy.hpp> + +using Mantid::Kernel::Property; +using Mantid::PythonInterface::Registry::PropertyWithValueFactory; +using namespace boost::python; + +// Empty class definition +class PropertyFactory {}; + +// Helper namespace +namespace propertyFactoryHelper { + +// Helper function to remove unique pointer and return a raw pointer +Property *removeUniquePointer(const std::string &name, + const boost::python::list &defaultValue) { + + // Get the unique pointer from the factory and convert it into a raw pointer + auto ptr = PropertyWithValueFactory::createTimeSeries(name, defaultValue); + + return ptr.release(); +} +} // namespace propertyFactoryHelper + +// Export the PropertyFactory +void export_PropertyFactory() { + class_<PropertyFactory, boost::noncopyable>("PropertyFactory", no_init) + .def("createTimeSeries", &propertyFactoryHelper::removeUniquePointer, + arg("log_name"), arg("log_values"), + return_value_policy<manage_new_object>()) + .staticmethod("createTimeSeries"); +} diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/TimeSeriesProperty.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/TimeSeriesProperty.cpp index 1d279c71e452db4315d262945a3a96854af0d97e..747aa190f702724de5c4485c90762c2dbf92f1ab 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Exports/TimeSeriesProperty.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/TimeSeriesProperty.cpp @@ -42,6 +42,33 @@ template <typename TYPE> std::string dtype(TimeSeriesProperty<TYPE> &self) { return Mantid::PythonInterface::Converters::dtype(self); } +// Check for the special case of a string +template <> std::string dtype(TimeSeriesProperty<std::string> &self) { + // Vector of ints to store the sizes of each of the strings + std::vector<size_t> stringSizes; + + // Block allocate memory + stringSizes.reserve(self.size()); + + // Loop for the number of strings in self + for (int i = 0; i < self.size(); i++) { + // For each string store the number of characters + std::string val = self.nthValue(i); + size_t size = val.size(); + stringSizes.emplace_back(size); + } + + // Find the maximum number of characters + size_t max = + *std::max_element(std::begin(stringSizes), std::end(stringSizes)); + + // Create the string to return + std::stringstream ss; + ss << "S" << max; + std::string retVal = ss.str(); + return retVal; +} + // Macro to reduce copy-and-paste #define EXPORT_TIMESERIES_PROP(TYPE, Prefix) \ register_ptr_to_python<TimeSeriesProperty<TYPE> *>(); \ diff --git a/Framework/PythonInterface/mantid/kernel/src/Registry/PropertyWithValueFactory.cpp b/Framework/PythonInterface/mantid/kernel/src/Registry/PropertyWithValueFactory.cpp index 6a36d5fb6d89133990ec0a228e18a44c4cef0c1b..eefac49393bcb5bcc3d8dd2540593ef904baba09 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Registry/PropertyWithValueFactory.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Registry/PropertyWithValueFactory.cpp @@ -3,15 +3,27 @@ //----------------------------------------------------------------------------- #include "MantidPythonInterface/kernel/Registry/PropertyWithValueFactory.h" #include "MantidKernel/PropertyWithValue.h" +#include "MantidKernel/TimeSeriesProperty.h" #include "MantidKernel/WarningSuppressions.h" #include "MantidPythonInterface/kernel/Registry/MappingTypeHandler.h" #include "MantidPythonInterface/kernel/Registry/SequenceTypeHandler.h" #include "MantidPythonInterface/kernel/Registry/TypedPropertyValueHandler.h" #include <boost/make_shared.hpp> +#include <boost/python.hpp> +#include <boost/python/class.hpp> +#include <boost/python/extract.hpp> +#include <boost/python/list.hpp> +#include <boost/python/object.hpp> #include <cassert> +using Mantid::Kernel::TimeSeriesProperty; +using Mantid::PythonInterface::Registry::PropertyWithValueFactory; +using namespace boost::python; +using namespace Mantid::Kernel; +using namespace Mantid::PythonInterface; + namespace Mantid { namespace PythonInterface { namespace Registry { @@ -139,6 +151,42 @@ PropertyWithValueFactory::create(const std::string &name, return create(name, defaultValue, validator, direction); } +/** + * Creates a TimeSeriesProperty<Type> instance from the given information. + * The python type is mapped to a C type + * @param name :: The name of the property + * @param defaultValue :: A default value for this property. + * @returns A pointer to a new Property object + */ +std::unique_ptr<Mantid::Kernel::Property> +PropertyWithValueFactory::createTimeSeries(const std::string &name, + const list &defaultValue) { + + // Use a PyObject pointer to determine the type stored in the list + auto obj = object(defaultValue[0]).ptr(); + auto val = defaultValue[0]; + + /** + * Decide which kind of TimeSeriesProperty to return + * Need to use a different method to check for boolean values + * since extract<> seems to get confused sometimes. + */ + if (PyBool_Check(obj)) { + return Mantid::Kernel::make_unique<TimeSeriesProperty<bool>>(name); + } else if (extract<int>(val).check()) { + return Mantid::Kernel::make_unique<TimeSeriesProperty<int>>(name); + } else if (extract<double>(val).check()) { + return Mantid::Kernel::make_unique<TimeSeriesProperty<double>>(name); + } else if (extract<std::string>(val).check()) { + return Mantid::Kernel::make_unique<TimeSeriesProperty<std::string>>(name); + } + + // If we reach here an error has occurred as there are no type to create + // a TimeSeriesProperty from + throw std::runtime_error( + "Cannot create a TimeSeriesProperty with that data type!"); +} + //------------------------------------------------------------------------- // Private methods //------------------------------------------------------------------------- diff --git a/Framework/PythonInterface/plugins/algorithms/ExportSampleLogsToHDF5.py b/Framework/PythonInterface/plugins/algorithms/ExportSampleLogsToHDF5.py index 4c5cbe388fedbb14f45b08449d7b28fa0508ef32..ef85ddedc9e768949b794ea9ada787b5d5666290 100644 --- a/Framework/PythonInterface/plugins/algorithms/ExportSampleLogsToHDF5.py +++ b/Framework/PythonInterface/plugins/algorithms/ExportSampleLogsToHDF5.py @@ -49,7 +49,7 @@ class ExportSampleLogsToHDF5(PythonAlgorithm): if prop.name not in blacklist and not self._ignore_property(prop)] for log_property in log_properties: - property_dtype = self._dtype_from_property_type(log_property) + property_dtype = log_property.dtype() log_value = self._get_value_from_property(log_property) if log_value is None: continue @@ -58,18 +58,6 @@ class ExportSampleLogsToHDF5(PythonAlgorithm): data=[log_value]) log_dataset.attrs["Units"] = log_property.units - def _dtype_from_property_type(self, prop): - if isinstance(prop, (FloatPropertyWithValue, FloatTimeSeriesProperty, FloatArrayProperty)): - return "f" - if isinstance(prop, (IntPropertyWithValue, Int32TimeSeriesProperty, Int64TimeSeriesProperty)): - return "i" - if isinstance(prop, (BoolPropertyWithValue, BoolTimeSeriesProperty)): - return "b" - if isinstance(prop, StringPropertyWithValue): - return "S{}".format(len(prop.value)) - raise RuntimeError("Unrecognised property type: \"{}\". Please contact the development team with this message". - format(prop.type)) - def _get_value_from_property(self, prop): if isinstance(prop, FloatArrayProperty): if len(prop.value) > 0: diff --git a/Framework/PythonInterface/plugins/algorithms/LRScalingFactors.py b/Framework/PythonInterface/plugins/algorithms/LRScalingFactors.py index 85432d320798cf24b808636fe26af8c4171ccd66..236e92d55103eaeade54e4c54180d3c5918da1be 100644 --- a/Framework/PythonInterface/plugins/algorithms/LRScalingFactors.py +++ b/Framework/PythonInterface/plugins/algorithms/LRScalingFactors.py @@ -63,7 +63,9 @@ class LRScalingFactors(PythonAlgorithm): "Pixel range defining the data peak") self.declareProperty(IntArrayProperty("SignalBackgroundPixelRange", [147, 163]), "Pixel range defining the background") - self.declareProperty(IntArrayProperty("LowResolutionPixelRange", [94, 160]), + self.declareProperty(IntArrayProperty("LowResolutionPixelRange", + [Property.EMPTY_INT, Property.EMPTY_INT], + direction=Direction.Input), "Pixel range defining the region to use in the low-resolution direction") self.declareProperty("IncidentMedium", "Medium", doc="Name of the incident medium") self.declareProperty("FrontSlitName", "S1", doc="Name of the front slit") @@ -454,6 +456,12 @@ class LRScalingFactors(PythonAlgorithm): @param background_range: range of pixels defining the background @param low_res_range: range of pixels in the x-direction """ + # Check low-res axis + if low_res_range[0] == Property.EMPTY_INT: + low_res_range[0] = 0 + if low_res_range[1] == Property.EMPTY_INT: + low_res_range[1] = int(workspace.getInstrument().getNumberParameter("number-of-x-pixels")[0])-1 + # Rebin TOF axis tof_range = self.getProperty("TOFRange").value tof_step = self.getProperty("TOFSteps").value diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/LoadWAND.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/LoadWAND.py index f4f9aa7578416a6d32915769490f87d8f863ea35..101c8126ab11f88e8380e370218ffe633221f4e5 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/LoadWAND.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/LoadWAND.py @@ -1,9 +1,11 @@ from __future__ import absolute_import, division, print_function from mantid.api import DataProcessorAlgorithm, AlgorithmFactory, MultipleFileProperty, FileAction, WorkspaceProperty -from mantid.kernel import Direction, UnitConversion, Elastic, Property, IntArrayProperty -from mantid.simpleapi import (LoadEventNexus, Integration, mtd, SetGoniometer, DeleteWorkspace, AddSampleLog, - MaskBTP, RenameWorkspace, GroupWorkspaces) +from mantid.kernel import Direction, UnitConversion, Elastic, Property, IntArrayProperty, StringListValidator +from mantid.simpleapi import (mtd, SetGoniometer, AddSampleLog, MaskBTP, RenameWorkspace, GroupWorkspaces, + CreateWorkspace, LoadNexusLogs, LoadInstrument) from six.moves import range +import numpy as np +import h5py class LoadWAND(DataProcessorAlgorithm): @@ -22,6 +24,7 @@ class LoadWAND(DataProcessorAlgorithm): self.declareProperty(IntArrayProperty("RunNumbers", []), 'Run numbers to load') self.declareProperty("Wavelength", 1.488, doc="Wavelength to set the workspace") self.declareProperty("ApplyMask", True, "If True standard masking will be applied to the workspace") + self.declareProperty("Grouping", 'None', StringListValidator(['None', '2x2', '4x4']), "Group pixels") self.declareProperty(WorkspaceProperty(name="OutputWorkspace", defaultValue="", direction=Direction.Output)) def validateInputs(self): @@ -44,11 +47,59 @@ class LoadWAND(DataProcessorAlgorithm): outWS = self.getPropertyValue("OutputWorkspace") group_names = [] + grouping = self.getProperty("Grouping").value + if grouping == 'None': + grouping = 1 + else: + grouping = 2 if grouping == '2x2' else 4 + for i, run in enumerate(runs): - LoadEventNexus(Filename=run, OutputWorkspace='__tmp_load', LoadMonitors=True, EnableLogging=False, - startProgress=i/len(runs), endProgress=(i+0.8)/len(runs)) - Integration(InputWorkspace='__tmp_load', OutputWorkspace='__tmp_load', EnableLogging=False, - startProgress=(i+0.8)/len(runs), endProgress=(i+1)/len(runs)) + data = np.zeros((512*480*8),dtype=np.int64) + with h5py.File(run, 'r') as f: + monitor_count = f['/entry/monitor1/total_counts'].value[0] + run_number = f['/entry/run_number'].value[0] + for b in range(8): + data += np.bincount(f['/entry/bank'+str(b+1)+'_events/event_id'].value,minlength=512*480*8) + data = data.reshape((480*8, 512)) + if grouping == 2: + data = data[::2,::2] + data[1::2,::2] + data[::2,1::2] + data[1::2,1::2] + elif grouping == 4: + data = (data[::4,::4] + data[1::4,::4] + data[2::4,::4] + data[3::4,::4] + + data[::4,1::4] + data[1::4,1::4] + data[2::4,1::4] + data[3::4,1::4] + + data[::4,2::4] + data[1::4,2::4] + data[2::4,2::4] + data[3::4,2::4] + + data[::4,3::4] + data[1::4,3::4] + data[2::4,3::4] + data[3::4,3::4]) + + CreateWorkspace(DataX=[wavelength-0.001, wavelength+0.001], + DataY=data, + DataE=np.sqrt(data), + UnitX='Wavelength', + YUnitLabel='Counts', + NSpec=1966080//grouping**2, + OutputWorkspace='__tmp_load', EnableLogging=False) + LoadNexusLogs('__tmp_load', Filename=run, EnableLogging=False) + AddSampleLog('__tmp_load', LogName="monitor_count", LogType='Number', NumberType='Double', + LogText=str(monitor_count), EnableLogging=False) + AddSampleLog('__tmp_load', LogName="gd_prtn_chrg", LogType='Number', NumberType='Double', + LogText=str(monitor_count), EnableLogging=False) + AddSampleLog('__tmp_load', LogName="Wavelength", LogType='Number', NumberType='Double', + LogText=str(wavelength), EnableLogging=False) + AddSampleLog('__tmp_load', LogName="Ei", LogType='Number', NumberType='Double', + LogText=str(UnitConversion.run('Wavelength', 'Energy', wavelength, 0, 0, 0, Elastic, 0)), EnableLogging=False) + AddSampleLog('__tmp_load', LogName="run_number", LogText=run_number, EnableLogging=False) + + if grouping > 1: # Fix detector IDs per spectrum before loading instrument + __tmp_load = mtd['__tmp_load'] + for n in range(__tmp_load.getNumberHistograms()): + s=__tmp_load.getSpectrum(n) + for i in range(grouping): + for j in range(grouping): + s.addDetectorID(int(n*grouping%512 + n//(512/grouping)*512*grouping + j + i*512)) + + LoadInstrument('__tmp_load', InstrumentName='WAND', RewriteSpectraMap=False, EnableLogging=False) + else: + LoadInstrument('__tmp_load', InstrumentName='WAND', RewriteSpectraMap=True, EnableLogging=False) + + SetGoniometer('__tmp_load', Axis0="HB2C:Mot:s1,0,1,0,1", EnableLogging=False) if self.getProperty("ApplyMask").value: MaskBTP('__tmp_load', Pixel='1,2,511,512', EnableLogging=False) @@ -58,20 +109,6 @@ class LoadWAND(DataProcessorAlgorithm): else: MaskBTP('__tmp_load', Bank='8', Tube='475-480', EnableLogging=False) - mtd['__tmp_load'].getAxis(0).setUnit("Wavelength") - w = [wavelength-0.001, wavelength+0.001] - for idx in range(mtd['__tmp_load'].getNumberHistograms()): - mtd['__tmp_load'].setX(idx, w) - - SetGoniometer('__tmp_load', Axis0="HB2C:Mot:s1,0,1,0,1", EnableLogging=False) - AddSampleLog('__tmp_load', LogName="gd_prtn_chrg", LogType='Number', NumberType='Double', - LogText=str(mtd['__tmp_load'+'_monitors'].getNumberEvents()), EnableLogging=False) - DeleteWorkspace('__tmp_load'+'_monitors', EnableLogging=False) - - AddSampleLog('__tmp_load', LogName="Wavelength", LogType='Number', NumberType='Double', - LogText=str(wavelength), EnableLogging=False) - AddSampleLog('__tmp_load', LogName="Ei", LogType='Number', NumberType='Double', - LogText=str(UnitConversion.run('Wavelength', 'Energy', wavelength, 0, 0, 0, Elastic, 0)), EnableLogging=False) if len(runs) == 1: RenameWorkspace('__tmp_load', outWS, EnableLogging=False) else: diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/WANDPowderReduction.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/WANDPowderReduction.py index 2cc9e8cbf5c7ad07415e90c0395cd056b45391df..d0a59e59c21cdeae92f0b9b19b32d70dd6be0b98 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/WANDPowderReduction.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/WANDPowderReduction.py @@ -1,11 +1,13 @@ from __future__ import absolute_import, division, print_function from mantid.api import (DataProcessorAlgorithm, AlgorithmFactory, MatrixWorkspaceProperty, PropertyMode) +from mantid.dataobjects import MaskWorkspaceProperty from mantid.simpleapi import (ConvertSpectrumAxis, Transpose, ResampleX, CopyInstrumentParameters, Divide, DeleteWorkspace, Scale, MaskAngle, ExtractMask, Minus, - RemoveMaskedSpectra, mtd) + ExtractUnmaskedSpectra, mtd, + BinaryOperateMasks) from mantid.kernel import StringListValidator, Direction, Property, FloatBoundedValidator @@ -48,6 +50,11 @@ class WANDPowderReduction(DataProcessorAlgorithm): validator=FloatBoundedValidator(0.0), doc="The background will be scaled by this number before being subtracted.") + self.declareProperty(MaskWorkspaceProperty("MaskWorkspace", '', + optional=PropertyMode.Optional, + direction=Direction.Input), + doc='The mask from this workspace will be applied before reduction') + self.copyProperties('ConvertSpectrumAxis', ['Target', 'EFixed']) self.copyProperties('ResampleX', ['XMin', 'XMax', 'NumberBins', 'LogBinning']) @@ -65,6 +72,7 @@ class WANDPowderReduction(DataProcessorAlgorithm): data = self.getProperty("InputWorkspace").value cal = self.getProperty("CalibrationWorkspace").value bkg = self.getProperty("BackgroundWorkspace").value + mask = self.getProperty("MaskWorkspace").value target = self.getProperty("Target").value eFixed = self.getProperty("EFixed").value xMin = self.getProperty("XMin").value @@ -88,13 +96,17 @@ class WANDPowderReduction(DataProcessorAlgorithm): if maskAngle != Property.EMPTY_DBL: MaskAngle(Workspace='__mask_tmp', MinAngle=maskAngle, Angle='Phi', EnableLogging=False) - RemoveMaskedSpectra(InputWorkspace=data, MaskedWorkspace='__mask_tmp', OutputWorkspace='__data_tmp', EnableLogging=False) + if mask is not None: + BinaryOperateMasks(InputWorkspace1='__mask_tmp', InputWorkspace2=mask, + OperationType='OR', OutputWorkspace='__mask_tmp', EnableLogging=False) + + ExtractUnmaskedSpectra(InputWorkspace=data, MaskWorkspace='__mask_tmp', OutputWorkspace='__data_tmp', EnableLogging=False) ConvertSpectrumAxis(InputWorkspace='__data_tmp', Target=target, EFixed=eFixed, OutputWorkspace=outWS, EnableLogging=False) Transpose(InputWorkspace=outWS, OutputWorkspace=outWS, EnableLogging=False) ResampleX(InputWorkspace=outWS, OutputWorkspace=outWS, XMin=xMin, XMax=xMax, NumberBins=numberBins, EnableLogging=False) if cal is not None: - RemoveMaskedSpectra(InputWorkspace=cal, MaskedWorkspace='__mask_tmp', OutputWorkspace='__cal_tmp', EnableLogging=False) + ExtractUnmaskedSpectra(InputWorkspace=cal, MaskWorkspace='__mask_tmp', OutputWorkspace='__cal_tmp', EnableLogging=False) CopyInstrumentParameters(data, '__cal_tmp', EnableLogging=False) ConvertSpectrumAxis(InputWorkspace='__cal_tmp', Target=target, EFixed=eFixed, OutputWorkspace='__cal_tmp', EnableLogging=False) Transpose(InputWorkspace='__cal_tmp', OutputWorkspace='__cal_tmp', EnableLogging=False) @@ -109,7 +121,7 @@ class WANDPowderReduction(DataProcessorAlgorithm): Scale(InputWorkspace=outWS, OutputWorkspace=outWS, Factor=cal_scale/data_scale, EnableLogging=False) if bkg is not None: - RemoveMaskedSpectra(InputWorkspace=bkg, MaskedWorkspace='__mask_tmp', OutputWorkspace='__bkg_tmp', EnableLogging=False) + ExtractUnmaskedSpectra(InputWorkspace=bkg, MaskWorkspace='__mask_tmp', OutputWorkspace='__bkg_tmp', EnableLogging=False) CopyInstrumentParameters(data, '__bkg_tmp', EnableLogging=False) ConvertSpectrumAxis(InputWorkspace='__bkg_tmp', Target=target, EFixed=eFixed, OutputWorkspace='__bkg_tmp', EnableLogging=False) Transpose(InputWorkspace='__bkg_tmp', OutputWorkspace='__bkg_tmp', EnableLogging=False) diff --git a/Framework/PythonInterface/test/python/mantid/api/CMakeLists.txt b/Framework/PythonInterface/test/python/mantid/api/CMakeLists.txt index afd9d68ce1f6220c96711de0e574fdb6eadbd293..6a6816959dea5cd0d8bf275861851bb10d97ea22 100644 --- a/Framework/PythonInterface/test/python/mantid/api/CMakeLists.txt +++ b/Framework/PythonInterface/test/python/mantid/api/CMakeLists.txt @@ -14,7 +14,6 @@ set ( TEST_PY_FILES CompositeFunctionTest.py DataProcessorAlgorithmTest.py DeprecatedAlgorithmCheckerTest.py - DetectorInfoTest.py ExperimentInfoTest.py FilePropertyTest.py FileFinderTest.py diff --git a/Framework/PythonInterface/test/python/mantid/api/DetectorInfoTest.py b/Framework/PythonInterface/test/python/mantid/api/DetectorInfoTest.py deleted file mode 100644 index efac03965c6f05761ee13ee2361994f4eec67f16..0000000000000000000000000000000000000000 --- a/Framework/PythonInterface/test/python/mantid/api/DetectorInfoTest.py +++ /dev/null @@ -1,29 +0,0 @@ -from __future__ import (absolute_import, division, print_function) - -import unittest -from testhelpers import WorkspaceCreationHelper - -class DetectorInfoTest(unittest.TestCase): - - _ws = None - - def setUp(self): - if self.__class__._ws is None: - self.__class__._ws = WorkspaceCreationHelper.create2DWorkspaceWithFullInstrument(2, 1, False) # no monitors - self.__class__._ws.getSpectrum(0).clearDetectorIDs() - - def test_len(self): - info = self._ws.detectorInfo() - self.assertEquals(len(info), 2) - - def test_size(self): - info = self._ws.detectorInfo() - self.assertEquals(info.size(), 2) - - def test_isMasked(self): - info = self._ws.detectorInfo() - self.assertEquals(info.isMasked(0), False) - self.assertEquals(info.isMasked(1), False) - -if __name__ == '__main__': - unittest.main() diff --git a/Framework/PythonInterface/test/python/mantid/api/WorkspaceValidatorsTest.py b/Framework/PythonInterface/test/python/mantid/api/WorkspaceValidatorsTest.py index 128b3f48ddfcc8310219d4063d38703a0e47eded..a2de10979bb1fda1200bdb7abfac059b819e7368 100644 --- a/Framework/PythonInterface/test/python/mantid/api/WorkspaceValidatorsTest.py +++ b/Framework/PythonInterface/test/python/mantid/api/WorkspaceValidatorsTest.py @@ -9,7 +9,8 @@ from mantid.kernel import IValidator from mantid.api import (WorkspaceUnitValidator, HistogramValidator, RawCountValidator, CommonBinsValidator, SpectraAxisValidator, NumericAxisValidator, - InstrumentValidator, MDFrameValidator) + InstrumentValidator, MDFrameValidator, + OrientedLatticeValidator) class WorkspaceValidatorsTest(unittest.TestCase): @@ -68,9 +69,19 @@ class WorkspaceValidatorsTest(unittest.TestCase): testhelpers.assertRaisesNothing(self, InstrumentValidator) def test_MDFrameValidator_construction(self): + """ + Test that the MDFrameValidator can be constructed + with a single string + """ testhelpers.assertRaisesNothing(self, MDFrameValidator, "HKL") self.assertRaises(Exception, MDFrameValidator) + def test_OrientedLatticeValidator_construction(self): + """ + Test that the OrientedLatticeValidator can be constructed + with no args + """ + testhelpers.assertRaisesNothing(self, OrientedLatticeValidator) if __name__ == '__main__': unittest.main() diff --git a/Framework/PythonInterface/test/python/mantid/dataobjects/EventListTest.py b/Framework/PythonInterface/test/python/mantid/dataobjects/EventListTest.py index edcffb793905e1e7db9d1c91429e410086d79c78..00429a7bf89d8520bc7e7364cc193447c6e14695 100644 --- a/Framework/PythonInterface/test/python/mantid/dataobjects/EventListTest.py +++ b/Framework/PythonInterface/test/python/mantid/dataobjects/EventListTest.py @@ -9,6 +9,12 @@ from mantid.dataobjects import EventList class EventListTest(unittest.TestCase): + def createRandomEventList(self, length): + el = EventList() + for i in range(length): + el.addEventQuickly(float(i), DateAndTime(i)) + return el + def test_event_list_constructor(self): el = EventList() self.assertEquals(el.getNumberEvents(), 0) @@ -23,5 +29,31 @@ class EventListTest(unittest.TestCase): self.assertEquals(el.getPulseTimes()[0], DateAndTime(42)) + def test_event_list_iadd(self): + left = self.createRandomEventList(10) + rght = self.createRandomEventList(20) + + left += rght + + self.assertEquals(left.getEventType(), EventType.TOF) + self.assertEquals(rght.getEventType(), EventType.TOF) + + self.assertEquals(left.getNumberEvents(), 30) + self.assertEquals(rght.getNumberEvents(), 20) + + def test_event_list_isub(self): + left = self.createRandomEventList(10) + rght = self.createRandomEventList(20) + + left -= rght + + self.assertEquals(left.getEventType(), EventType.WEIGHTED) + self.assertEquals(rght.getEventType(), EventType.TOF) + + self.assertEquals(left.getNumberEvents(), 30) + self.assertEquals(rght.getNumberEvents(), 20) + + self.assertEquals(left.integrate(-1.,31., True), -10.) + if __name__ == '__main__': unittest.main() diff --git a/Framework/PythonInterface/test/python/mantid/geometry/CMakeLists.txt b/Framework/PythonInterface/test/python/mantid/geometry/CMakeLists.txt index 4939ae92b77ddc8754c1b373d029f45847660e43..22cb63524b998c5c881652b68600205ee27cf4ae 100644 --- a/Framework/PythonInterface/test/python/mantid/geometry/CMakeLists.txt +++ b/Framework/PythonInterface/test/python/mantid/geometry/CMakeLists.txt @@ -20,6 +20,7 @@ set ( TEST_PY_FILES GroupTest.py CrystalStructureTest.py ReflectionGeneratorTest.py + DetectorInfoTest.py ) check_tests_valid ( ${CMAKE_CURRENT_SOURCE_DIR} ${TEST_PY_FILES} ) diff --git a/Framework/PythonInterface/test/python/mantid/geometry/DetectorInfoTest.py b/Framework/PythonInterface/test/python/mantid/geometry/DetectorInfoTest.py new file mode 100644 index 0000000000000000000000000000000000000000..cf4af4bf44aef00817695caf0327220950e6021b --- /dev/null +++ b/Framework/PythonInterface/test/python/mantid/geometry/DetectorInfoTest.py @@ -0,0 +1,202 @@ +from __future__ import (absolute_import, division, print_function) + +import unittest +from testhelpers import WorkspaceCreationHelper +from mantid.kernel import V3D +from mantid.kernel import Quat +from mantid.simpleapi import * + + +class DetectorInfoTest(unittest.TestCase): + + _ws = None + + def setUp(self): + """ Setup Workspace to use""" + if self.__class__._ws is None: + self.__class__._ws = WorkspaceCreationHelper.create2DWorkspaceWithFullInstrument(2, 1, False) # no monitors + self.__class__._ws.getSpectrum(0).clearDetectorIDs() + + """ + ---------------------------------------------------------------------------- + Normal Tests + ---------------------------------------------------------------------------- + + The following test cases test normal usage of the exposed methods. + """ + + def test_len(self): + """ Test return value for number of detectors """ + info = self._ws.detectorInfo() + self.assertEquals(len(info), 2) + + def test_size(self): + """ Test return value for number of detectors """ + info = self._ws.detectorInfo() + self.assertEquals(info.size(), 2) + + def test_isMonitor(self): + """ Check if detector is a monitor """ + info = self._ws.detectorInfo() + self.assertEquals(info.isMonitor(0), False) + self.assertEquals(info.isMonitor(1), False) + + def test_isMasked(self): + """ Check masking of detector """ + info = self._ws.detectorInfo() + self.assertEquals(info.isMasked(0), False) + self.assertEquals(info.isMasked(1), False) + + def test_setMasked(self): + """ Test that the detector's masking can be set to True. """ + info = self._ws.detectorInfo() + info.setMasked(0, True) + self.assertTrue(info.isMasked(0)) + + def test_clearMaskFlags(self): + """ Test that the detector's masking can be cleared. """ + info = self._ws.detectorInfo() + info.setMasked(0, True) + self.assertTrue(info.isMasked(0)) + info.clearMaskFlags() + self.assertFalse(info.isMasked(0)) + + def test_isEquivalent(self): + """ Check equality of detectors """ + info = self._ws.detectorInfo() + self.assertTrue(info.isEquivalent(info)) + self.assertTrue(info == info) + + def test_twoTheta(self): + """ See if the returned value is a double (float in Python). """ + info = self._ws.detectorInfo() + self.assertEquals(type(info.twoTheta(0)), float) + + def test_createWorkspaceAndDetectorInfo(self): + """ Try to create a workspace and see if DetectorInfo object + is accessable """ + dataX = [1,2,3,4,5] + dataY = [1,2,3,4,5] + workspace = CreateWorkspace(DataX=dataX, DataY=dataY) + info = workspace.detectorInfo() + self.assertEquals(info.size(), 0) + + """ + The following test cases test for returned objects to do with position + and rotation. + """ + + def test_position(self): + """ Test that the detector's position is returned. """ + info = self._ws.detectorInfo() + self.assertEquals(type(info.position(0)), V3D) + self.assertEquals(type(info.position(1)), V3D) + + def test_rotation(self): + """ Test that the detector's rotation is returned. """ + info = self._ws.detectorInfo() + self.assertEquals(type(info.rotation(0)), Quat) + self.assertEquals(type(info.rotation(1)), Quat) + + + """ + ---------------------------------------------------------------------------- + Extreme Tests + ---------------------------------------------------------------------------- + + The following test cases test around boundary cases for the exposed methods. + """ + def test_isMonitor_extreme(self): + info = self._ws.detectorInfo() + with self.assertRaises(OverflowError): + info.isMonitor(-1) + + def test_isMasked_extreme(self): + info = self._ws.detectorInfo() + with self.assertRaises(OverflowError): + info.isMasked(-1) + + def test_twoTheta_extreme(self): + info = self._ws.detectorInfo() + with self.assertRaises(OverflowError): + info.twoTheta(-1) + self.assertEquals(type(info.twoTheta(0)), float) + self.assertEquals(type(info.twoTheta(1)), float) + + def test_position_extreme(self): + info = self._ws.detectorInfo() + with self.assertRaises(OverflowError): + info.position(-1) + + + """ + ---------------------------------------------------------------------------- + Exceptional Tests + ---------------------------------------------------------------------------- + + Each of the tests below tries to pass invalid parameters to the exposed + methods and expect an error to be thrown. + """ + def test_size_exceptional(self): + info = self._ws.detectorInfo() + with self.assertRaises(TypeError): + info.size(0) + + def test_isMonitor_exceptional(self): + info = self._ws.detectorInfo() + with self.assertRaises(TypeError): + info.isMonitor("Error") + with self.assertRaises(TypeError): + info.isMonitor(10.0) + + def test_isMasked_exceptional(self): + info = self._ws.detectorInfo() + with self.assertRaises(TypeError): + info.isMasked("Error") + with self.assertRaises(TypeError): + info.isMasked(10.0) + + def test_setMasked_exceptional(self): + info = self._ws.detectorInfo() + with self.assertRaises(TypeError): + info.setMasked(0, "False") + with self.assertRaises(TypeError): + info.setMasked("False", True) + + def test_clearMaskFlags_exceptional(self): + info = self._ws.detectorInfo() + with self.assertRaises(TypeError): + info.clearMaskFlags("All") + with self.assertRaises(TypeError): + info.clearMaskFlags(1.10) + + def test_isEquivalent_exceptional(self): + info = self._ws.detectorInfo() + with self.assertRaises(TypeError): + info.isEquivalent("Hello") + with self.assertRaises(TypeError): + info.isEquivalent(11.1) + + def test_twoTheta_exceptional(self): + info = self._ws.detectorInfo() + with self.assertRaises(TypeError): + info.twoTheta("Zero") + with self.assertRaises(TypeError): + info.twoTheta(1.0) + + def test_position_exceptional(self): + info = self._ws.detectorInfo() + with self.assertRaises(TypeError): + info.position("Zero") + with self.assertRaises(TypeError): + info.position(0.0) + + def test_rotation_exceptional(self): + info = self._ws.detectorInfo() + with self.assertRaises(TypeError): + info.rotation("Zero") + with self.assertRaises(TypeError): + info.rotation(0.0) + +if __name__ == '__main__': + unittest.main() diff --git a/Framework/PythonInterface/test/python/mantid/kernel/ArrayPropertyTest.py b/Framework/PythonInterface/test/python/mantid/kernel/ArrayPropertyTest.py index db5f08d0f2783b2a600c8b6c576f9a78edc110f4..2564e68a9791e6d2204dc09112f0cdb0ca08b244 100644 --- a/Framework/PythonInterface/test/python/mantid/kernel/ArrayPropertyTest.py +++ b/Framework/PythonInterface/test/python/mantid/kernel/ArrayPropertyTest.py @@ -154,17 +154,9 @@ class ArrayPropertyTest(unittest.TestCase): str_arr = StringArrayProperty("letters", str_input_values, validator, direc) # Test - self.assertEquals(float_arr.dtype(), "float64") - self.assertEquals(str_arr.dtype(), "string_") - - # Implementation of IntArrayProperty is based on long - # (which is itself implementation defined, so a special case is needed here) - if sys.platform == 'win32' or sys.platform == 'darwin': - # Windows and macOS should return "int_" - self.assertEquals(int_arr.dtype(), "int_") - else: - # Linux based systems should return "int64" - self.assertEquals(int_arr.dtype(), "int64") + self.assertEquals(float_arr.dtype(), "f") + self.assertEquals(int_arr.dtype(), "i") + self.assertEquals(str_arr.dtype(), "S1") def test_construct_numpy_array_with_given_dtype_float(self): # Set up @@ -174,11 +166,11 @@ class ArrayPropertyTest(unittest.TestCase): # Create float array float_input_values = [1.1, 2.5, 5.6, 4.6, 9.0, 6.0] float_arr = FloatArrayProperty("floats", float_input_values, validator, direc) - + # Use the returned dtype() to check it works with numpy arrays x = np.arange(1, 10, dtype=float_arr.dtype()) self.assertIsInstance(x, np.ndarray) - self.assertEquals(x.dtype, float_arr.dtype()) + self.assertEquals(x.dtype, float_arr.dtype()) def test_construct_numpy_array_with_given_dtype_int(self): # Set up @@ -188,7 +180,7 @@ class ArrayPropertyTest(unittest.TestCase): # Create int array int_input_values = [1, 2, 5, 4, 9, 6] int_arr = IntArrayProperty("integers", int_input_values, validator, direc) - + # Use the returned dtype() to check it works with numpy arrays x = np.arange(1, 10, dtype=int_arr.dtype()) self.assertIsInstance(x, np.ndarray) @@ -202,12 +194,12 @@ class ArrayPropertyTest(unittest.TestCase): # Create string array str_input_values = ["hello", "testing", "word", "another word", "word"] str_arr = StringArrayProperty("letters", str_input_values, validator, direc) - + # Use the returned dtype() to check it works with numpy arrays x = np.array(str_input_values, dtype=str_arr.dtype()) self.assertIsInstance(x, np.ndarray) # Expect longest string to be returned - self.assertEquals(x.dtype, "S12") + self.assertEquals(x.dtype, "S12") def test_PythonAlgorithm_setProperty_With_Ranges_String(self): """ diff --git a/Framework/PythonInterface/test/python/mantid/kernel/PropertyWithValueTest.py b/Framework/PythonInterface/test/python/mantid/kernel/PropertyWithValueTest.py index 56908e8161f3b6e592b3ba4dd07e1a8e2c46d88a..ecab49de0d4f581e60f363e66e929eda7929c424 100644 --- a/Framework/PythonInterface/test/python/mantid/kernel/PropertyWithValueTest.py +++ b/Framework/PythonInterface/test/python/mantid/kernel/PropertyWithValueTest.py @@ -128,7 +128,7 @@ class PropertyWithValueTest(unittest.TestCase): self.assertEquals(result.endswith("98,99"), True) # Check the dtype return value - self.assertEquals(det_list_prop.dtype(), "int32") + self.assertEquals(det_list_prop.dtype(), "i") def _do_vector_double_numpy_test(self, int_type=False): create_ws = AlgorithmManager.createUnmanaged('CreateWorkspace') diff --git a/Framework/PythonInterface/test/python/mantid/kernel/TimeSeriesPropertyTest.py b/Framework/PythonInterface/test/python/mantid/kernel/TimeSeriesPropertyTest.py index 265cec042163963dc593dbb1030c5bb7965754f2..7313b62885e78df25ef71a000e1326b8e8d3eaf5 100644 --- a/Framework/PythonInterface/test/python/mantid/kernel/TimeSeriesPropertyTest.py +++ b/Framework/PythonInterface/test/python/mantid/kernel/TimeSeriesPropertyTest.py @@ -61,7 +61,7 @@ class TimeSeriesPropertyTest(unittest.TestCase): self.assertEquals(log_series.size(), self._ntemp) self.assertAlmostEqual(log_series.nthValue(0), -0.00161) # Check the dtype return value - self.assertEquals(log_series.dtype(), "float64") + self.assertEquals(log_series.dtype(), "f") def test_time_series_int_can_be_extracted(self): log_series = self._test_ws.getRun()["raw_frames"] @@ -69,7 +69,7 @@ class TimeSeriesPropertyTest(unittest.TestCase): self.assertEquals(log_series.size(), self._nframes) self.assertEquals(log_series.nthValue(1), 1436) # Check the dtype return value - self.assertEquals(log_series.dtype(), "int64") + self.assertEquals(log_series.dtype(), "i") def test_time_series_string_can_be_extracted(self): log_series = self._test_ws.getRun()["icp_event"] @@ -77,14 +77,14 @@ class TimeSeriesPropertyTest(unittest.TestCase): self.assertEquals(log_series.size(), 4) self.assertEquals(log_series.nthValue(0).strip(), 'CHANGE_PERIOD 1') # Check the dtype return value - self.assertEquals(log_series.dtype(), "string_") + self.assertEquals(log_series.dtype(), "S61") def test_time_series_bool_can_be_extracted(self): log_series = self._test_ws.getRun()["period 1"] self._check_has_time_series_attributes(log_series) self.assertEquals(log_series.size(), 1) # Check the dtype return value - self.assertEquals(log_series.dtype(), "bool_") + self.assertEquals(log_series.dtype(), "b") def _check_has_time_series_attributes(self, log, values_type=np.ndarray): self.assertTrue(hasattr(log, "value")) diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/ExportSampleLogsToHDF5Test.py b/Framework/PythonInterface/test/python/plugins/algorithms/ExportSampleLogsToHDF5Test.py index e5fdde253267ccad8e974d70f435682c4930e31c..2f81160e3fe5e3e8acf397e7edb011a999abd8da 100644 --- a/Framework/PythonInterface/test/python/plugins/algorithms/ExportSampleLogsToHDF5Test.py +++ b/Framework/PythonInterface/test/python/plugins/algorithms/ExportSampleLogsToHDF5Test.py @@ -26,7 +26,7 @@ class ExportSampleLogsToHDF5Test(unittest.TestCase): if mantid.mtd.doesExist(self.TEST_WS_NAME): mantid.mtd.remove(self.TEST_WS_NAME) - + def test_saveFileWithSingleValueProperties(self): input_ws = self._create_sample_workspace() self._add_log_to_workspace(input_ws, "Test1", 1.0) @@ -80,6 +80,34 @@ class ExportSampleLogsToHDF5Test(unittest.TestCase): logs_group = output_file["Sample Logs"] self.assertEquals(logs_group["TestLog"].attrs["Units"], "uAmps") + def test_create_timeSeries(self): + """ Tests that the correct TimeSeriesProperty is returned when given a + name and a list of values of a given type.""" + + # Test for Int32TimeSeriesProperty + int_log_name = "Int32Series" + int_log_values = [1,2,3,4,5,6,7] + int_prop = PropertyFactory.createTimeSeries(int_log_name, int_log_values) + self.assertEquals(type(int_prop), Int32TimeSeriesProperty) + + # Test for BoolTimeSeriesProperty + bool_log_name = "BoolSeries" + bool_log_values = [True, False, False, True, False] + bool_prop = PropertyFactory.createTimeSeries(bool_log_name, bool_log_values) + self.assertEquals(type(bool_prop), BoolTimeSeriesProperty) + + # Test for StringSeriesProperty + str_log_name = "StringSeries" + str_log_values = ["Testing", "string", "time", "series", "property"] + str_prop = PropertyFactory.createTimeSeries(str_log_name, str_log_values) + self.assertEquals(type(str_prop), StringTimeSeriesProperty) + + # Test for FloatTimeSeriesProperty + float_log_name = "FloatSeries" + float_log_values = [1.0 ,2.1, 3.2, 4.3, 5.6, 6.7, 7.8] + float_prop = PropertyFactory.createTimeSeries(float_log_name, float_log_values) + self.assertTrue(type(float_prop), FloatTimeSeriesProperty) + def _add_log_to_workspace(self, ws, log_name, log_value): if isinstance(log_value, list): ws.mutableRun()[log_name] = self._create_time_series_log(log_name, log_value) @@ -98,21 +126,11 @@ class ExportSampleLogsToHDF5Test(unittest.TestCase): return ws def _create_time_series_log(self, log_name, log_value): - if isinstance(log_value[0], int): - prop = Int32TimeSeriesProperty(log_name) - elif isinstance(log_value[0], float): - prop = FloatTimeSeriesProperty(log_name) - elif isinstance(log_value[0], str): - prop = StringTimeSeriesProperty(log_name) - elif isinstance(log_value[0], bool): - prop = BoolTimeSeriesProperty(log_name) - else: - raise RuntimeError("Unsupported property type {}".format(type(log_value[0]))) - + prop = PropertyFactory.createTimeSeries(log_name, log_value) for i, value in enumerate(log_value): prop.addValue(i, value) return prop if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/LoadWANDTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/LoadWANDTest.py index b0d5a4746ffc20ad922f0d5afeddafe1eaab9603..21ffa1ac0bfda45dc032c35be1b8347b3b430193 100644 --- a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/LoadWANDTest.py +++ b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/LoadWANDTest.py @@ -6,11 +6,11 @@ import unittest class LoadWANDTest(unittest.TestCase): def test(self): - ws = LoadWAND('HB2C_7000.nxs.h5') + ws = LoadWAND('HB2C_7000.nxs.h5', Grouping='2x2') self.assertTrue(ws) self.assertEquals(ws.blocksize(), 1) - self.assertEquals(ws.getNumberHistograms(), 1966080) - self.assertEquals(ws.readY(1031100), 5) + self.assertEquals(ws.getNumberHistograms(), 1966080//4) + self.assertEquals(ws.readY(257775), 4) self.assertEquals(ws.run().getProtonCharge(), 907880) self.assertAlmostEqual(ws.run().getGoniometer().getEulerAngles()[0], -142.6) self.assertEquals(ws.run().getLogData('Wavelength').value, 1.488) diff --git a/MantidPlot/CMakeLists.txt b/MantidPlot/CMakeLists.txt index 7d114bcccc73e7fd702e531532b1f6067f470953..66d1fff962807c4399153f6f3453780ac873e6c4 100644 --- a/MantidPlot/CMakeLists.txt +++ b/MantidPlot/CMakeLists.txt @@ -455,7 +455,7 @@ add_custom_command ( OUTPUT ${SIP_SRC_AUTO} -I ${PYQT4_SIP_DIR} ${MANTIDQTPYTHON_SIP_INCLUDES} ${PYQT4_SIP_FLAGS} -c ${CMAKE_CURRENT_BINARY_DIR} -j1 -w -o ${SIP_SPEC} - DEPENDS ${SIP_INCLUDE_DIRECTORY}/sip.h src/qti.sip ${QTI_SIP_HDRS} ../qt/python/mantidqtpython/mantidqtpython_def.sip + DEPENDS ${SIP_INCLUDE_DIR}/sip.h src/qti.sip ${QTI_SIP_HDRS} ../qt/python/mantidqtpython/mantidqtpython_def.sip COMMENT "Generating python bindings using sip" ) diff --git a/MantidPlot/pymantidplot/__init__.py b/MantidPlot/pymantidplot/__init__.py index bf537f68c501e696c644af7f503ed09e47a29112..fe00aacdcaa078cf3939c1d557bc48cf05b973db 100644 --- a/MantidPlot/pymantidplot/__init__.py +++ b/MantidPlot/pymantidplot/__init__.py @@ -57,17 +57,17 @@ def _get_analysis_data_service(): # -------------------------- Wrapped MantidPlot functions ----------------- -def runPythonScript(code, async=False, quiet=False, redirect=True): +def runPythonScript(code, asynchronous=False, quiet=False, redirect=True): """ Redirects the runPythonScript method to the app object @param code :: A string of code to execute - @param async :: If the true the code is executed in a separate thread + @param asynchronous :: If the true the code is executed in a separate thread @param quiet :: If true no messages reporting status are issued @param redirect :: If true then output is redirected to MantidPlot """ - if async and QtCore.QThread.currentThread() != QtGui.qApp.thread(): - async = False - threadsafe_call(_qti.app.runPythonScript, code, async, quiet, redirect) + if asynchronous and QtCore.QThread.currentThread() != QtGui.qApp.thread(): + asynchronous = False + threadsafe_call(_qti.app.runPythonScript, code, asynchronous, quiet, redirect) # Overload for consistency with qtiplot table(..) & matrix(..) commands diff --git a/MantidPlot/src/ApplicationWindow.h b/MantidPlot/src/ApplicationWindow.h index 1e0122798c3b7846121c284c68e50acb3d48b8fc..61c1c66d5db19de26b8e15fb6385d817311660b8 100644 --- a/MantidPlot/src/ApplicationWindow.h +++ b/MantidPlot/src/ApplicationWindow.h @@ -257,7 +257,7 @@ public slots: int lineNumber); /// Runs an arbitrary lump of python code, return true/false on /// success/failure. - bool runPythonScript(const QString &code, bool async = false, + bool runPythonScript(const QString &code, bool asynchronous = false, bool quiet = false, bool redirect = true); QList<MdiSubWindow *> windowsList() const; diff --git a/MantidPlot/src/qti.sip b/MantidPlot/src/qti.sip index 2972608196c575f291d27c6678b8a8d48bb0460e..679cf688fb15308704c0ee85321019cf3b5de161 100644 --- a/MantidPlot/src/qti.sip +++ b/MantidPlot/src/qti.sip @@ -1103,7 +1103,7 @@ sipType=sipFindType(sipCpp->metaObject()->className()); public: void setExitCode(int code); - bool runPythonScript(const QString & code, const bool async = false, + bool runPythonScript(const QString & code, const bool asynchronous = false, bool quiet=false, bool redirect=true); enum MatrixToTableConversion{Direct, XYZ, YXZ}; diff --git a/Testing/SystemTests/lib/systemtests/stresstesting.py b/Testing/SystemTests/lib/systemtests/stresstesting.py index 6d7d12bc24ae83b6186b532a928f1549414e4f09..92efbd7a86f640de138235b3ded0b161f129a8e0 100644 --- a/Testing/SystemTests/lib/systemtests/stresstesting.py +++ b/Testing/SystemTests/lib/systemtests/stresstesting.py @@ -933,7 +933,6 @@ class MantidFrameworkConfig: # Up the log level so that failures can give useful information config['logging.loggers.root.level'] = self.__loglevel - config['logging.channels.consoleFilterChannel.level'] = self.__loglevel # Set the correct search path config['datasearch.directories'] = self.__dataDirs diff --git a/Testing/SystemTests/tests/analysis/LRScalingFactorsTest.py b/Testing/SystemTests/tests/analysis/LRScalingFactorsTest.py index a501b481cd1f10049b2157d3f425c19ef8a581f7..edf904e295bf7ed368f110605aad31504bda081c 100644 --- a/Testing/SystemTests/tests/analysis/LRScalingFactorsTest.py +++ b/Testing/SystemTests/tests/analysis/LRScalingFactorsTest.py @@ -25,6 +25,7 @@ class LRPrimaryFractionTest(stresstesting.MantidStressTest): TOFRange=[10008, 35000], TOFSteps=200, SignalPeakPixelRange=[150, 160], SignalBackgroundPixelRange=[147, 163], + LowResolutionPixelRange=[94, 160], ScalingFactorFile=self.cfg_file) def validate(self): diff --git a/buildconfig/CMake/LinuxPackageScripts.cmake b/buildconfig/CMake/LinuxPackageScripts.cmake index 4e70e144b791cfe3b02a08f77f0acd7b8ec31253..8fb1be25b6be2633e98510ccc7f2dab2ece4510a 100644 --- a/buildconfig/CMake/LinuxPackageScripts.cmake +++ b/buildconfig/CMake/LinuxPackageScripts.cmake @@ -3,6 +3,9 @@ # # It provides: # - launch_mantidplot.sh +# - launch_mantidworkbench.sh +# - mantid.sh <- for stable releases +# - mantid.csh <- for stable releases # ########################################################################### @@ -17,7 +20,7 @@ set ( PLUGINS_DIR plugins ) # Separate directory of plugins to be discovered by the ParaView framework # These cannot be mixed with our other plugins. Further sub-directories # based on the Qt version will also be created by the installation targets -set ( PVPLUGINS_SUBDIR paraview ) +set ( PVPLUGINS_DIR "plugins/paraview/qt4/" ) if ( CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT ) set ( CMAKE_INSTALL_PREFIX /opt/mantid${CPACK_PACKAGE_SUFFIX} CACHE PATH "Install path" FORCE ) @@ -34,7 +37,7 @@ set ( CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION /opt /usr/share/applications file ( WRITE ${CMAKE_CURRENT_BINARY_DIR}/mantid.sh "#!/bin/sh\n" "MANTIDPATH=${CMAKE_INSTALL_PREFIX}/${BIN_DIR}\n" - "PV_PLUGIN_PATH=${CMAKE_INSTALL_PREFIX}/${PVPLUGINS_DIR}/${PVPLUGINS_DIR}\n" + "PV_PLUGIN_PATH=${CMAKE_INSTALL_PREFIX}/${PVPLUGINS_DIR}\n" "PATH=$PATH:$MANTIDPATH\n" "export MANTIDPATH PV_PLUGIN_PATH PATH\n" @@ -44,7 +47,7 @@ file ( WRITE ${CMAKE_CURRENT_BINARY_DIR}/mantid.sh file ( WRITE ${CMAKE_CURRENT_BINARY_DIR}/mantid.csh "#!/bin/csh\n" "setenv MANTIDPATH \"${CMAKE_INSTALL_PREFIX}/${BIN_DIR}\"\n" - "setenv PV_PLUGIN_PATH \"${CMAKE_INSTALL_PREFIX}/${PVPLUGINS_DIR}/${PVPLUGINS_DIR}\"\n" + "setenv PV_PLUGIN_PATH \"${CMAKE_INSTALL_PREFIX}/${PVPLUGINS_DIR}\"\n" "setenv PATH \"\${PATH}:\${MANTIDPATH}\"\n" ) @@ -132,6 +135,17 @@ endif() ############################################################################ # Launcher scripts ############################################################################ +# common definition of work for virtualgl - lots of escaping things from cmake +set ( VIRTUAL_GL_WRAPPER +"# whether or not to use vglrun +if [ -n \"\${NXSESSIONID}\" ]; then + command -v vglrun >/dev/null 2>&1 || { echo >&2 \"MantidPlot requires VirtualGL but it's not installed. Aborting.\"; exit 1; } + VGLRUN=\"vglrun\" +elif [ -n \"\${TLSESSIONDATA}\" ]; then + command -v vglrun >/dev/null 2>&1 || { echo >&2 \"MantidPlot requires VirtualGL but it's not installed. Aborting.\"; exit 1; } + VGLRUN=\"vglrun\" +fi" ) + # The scripts need tcmalloc to be resolved to the runtime library as the plain # .so symlink is only present when a -dev/-devel package is present if ( TCMALLOC_FOUND ) @@ -140,6 +154,46 @@ if ( TCMALLOC_FOUND ) string( REGEX REPLACE "([0-9]+)\.[0-9]+\.[0-9]+$" "\\1" TCMALLOC_RUNTIME_LIB ${TCMALLOC_RUNTIME_LIB} ) endif () +# definitions to preload tcmalloc +set ( TCMALLOC_DEFINITIONS +"# Define parameters for tcmalloc +LOCAL_PRELOAD=${TCMALLOC_RUNTIME_LIB} +if [ -n \"\${LD_PRELOAD}\" ]; then + LOCAL_PRELOAD=\${LOCAL_PRELOAD}:\${LD_PRELOAD} +fi +if [ -z \"\${TCMALLOC_RELEASE_RATE}\" ]; then + TCM_RELEASE=10000 +else + TCM_RELEASE=\${TCMALLOC_RELEASE_RATE} +fi + +# Define when to report large memory allocation +if [ -z \"\${TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD}\" ]; then + # total available memory + TCM_REPORT=\$(grep MemTotal /proc/meminfo --color=never | awk '{print \$2}') + # half of available memory + TCM_REPORT=`expr 512 \\* \$TCM_REPORT` + # minimum is 1GB + if [ \${TCM_REPORT} -le 1073741824 ]; then + TCM_REPORT=1073741824 + fi +else + TCM_REPORT=\${TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD} +fi" ) + +# chunk of code for fixing MANTIDPATH +set ( MTD_PATH_DEFINITION "MANTIDPATH=\${INSTALLDIR}/bin" ) + +# chunk of code for launching gdb +set ( GDB_DEFINITIONS +"# run with gdb THIS OPTION MUST BE SUPPLIED FIRST +if [ -n \"\$1\" ] && [ \"\$1\" = \"--debug\" ]; then + shift + GDB=\"gdb --args\" +fi" ) + +set ( ERROR_CMD "ErrorReporter/error_dialog_app.py --exitcode=\$? --directory=\$INSTALLDIR/bin" ) + # Local dev version if ( MAKE_VATES ) set ( PARAVIEW_PYTHON_PATHS ":${ParaView_DIR}/lib:${ParaView_DIR}/lib/site-packages" ) @@ -147,15 +201,26 @@ else () set ( PARAVIEW_PYTHON_PATHS "" ) endif () +set ( LOCAL_PYPATH "\${INSTALLDIR}/bin" ) +set ( SCRIPTSDIR ${CMAKE_HOME_DIRECTORY}/scripts) + +# used by mantidplot and mantidworkbench if (ENABLE_MANTIDPLOT) set ( MANTIDPLOT_EXEC MantidPlot ) - set ( SCRIPTSDIR ${CMAKE_HOME_DIRECTORY}/scripts) configure_file ( ${CMAKE_MODULE_PATH}/Packaging/launch_mantidplot.sh.in ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/launch_mantidplot.sh @ONLY ) # Needs to be executable execute_process ( COMMAND "chmod" "+x" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/launch_mantidplot.sh" OUTPUT_QUIET ERROR_QUIET ) endif () +if (ENABLE_WORKBENCH) + set ( MANTIDWORKBENCH_EXEC workbench ) # what the actual thing is called + configure_file ( ${CMAKE_MODULE_PATH}/Packaging/launch_mantidworkbench.sh.in + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/launch_mantidworkbench.sh @ONLY ) + # Needs to be executable + execute_process ( COMMAND "chmod" "+x" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/launch_mantidworkbench.sh" + OUTPUT_QUIET ERROR_QUIET ) +endif() configure_file ( ${CMAKE_MODULE_PATH}/Packaging/mantidpython.in ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mantidpython @ONLY ) # Needs to be executable @@ -168,31 +233,33 @@ execute_process ( COMMAND "chmod" "+x" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AddPyt OUTPUT_QUIET ERROR_QUIET ) # Package version -set ( EXTRA_LDPATH "\${INSTALLDIR}/../lib/paraview-${ParaView_VERSION_MAJOR}.${ParaView_VERSION_MINOR}" ) if ( MAKE_VATES ) - set ( PV_PYTHON_PATH "\${INSTALLDIR}/../lib/paraview-${ParaView_VERSION_MAJOR}.${ParaView_VERSION_MINOR}" ) + set ( EXTRA_LDPATH "\${INSTALLDIR}/lib/paraview-${ParaView_VERSION_MAJOR}.${ParaView_VERSION_MINOR}" ) + set ( PV_PYTHON_PATH "\${INSTALLDIR}/lib/paraview-${ParaView_VERSION_MAJOR}.${ParaView_VERSION_MINOR}" ) set ( PARAVIEW_PYTHON_PATHS ":${PV_PYTHON_PATH}:${PV_PYTHON_PATH}/site-packages:${PV_PYTHON_PATH}/site-packages/vtk" ) else () set ( PARAVIEW_PYTHON_PATHS "" ) endif () +# used by mantidplot and mantidworkbench +set ( LOCAL_PYPATH "\${INSTALLDIR}/lib:\${INSTALLDIR}/plugins" ) +set ( SCRIPTSDIR "\${INSTALLDIR}/scripts") + if (ENABLE_MANTIDPLOT) set ( MANTIDPLOT_EXEC MantidPlot_exe ) - set ( SCRIPTSDIR "\${INSTALLDIR}/../scripts") configure_file ( ${CMAKE_MODULE_PATH}/Packaging/launch_mantidplot.sh.in ${CMAKE_CURRENT_BINARY_DIR}/launch_mantidplot.sh.install @ONLY ) - install ( FILES ${CMAKE_CURRENT_BINARY_DIR}/launch_mantidplot.sh.install - DESTINATION ${BIN_DIR} RENAME launch_mantidplot.sh - PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ - GROUP_EXECUTE GROUP_READ - WORLD_EXECUTE WORLD_READ - ) + install ( PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/launch_mantidplot.sh.install + DESTINATION ${BIN_DIR} RENAME launch_mantidplot.sh ) endif () +if (PACKAGE_WORKBENCH) # will eventually switch to ENABLE_WORKBENCH + set ( MANTIDWORKBENCH_EXEC workbench ) # what the actual thing is called + configure_file ( ${CMAKE_MODULE_PATH}/Packaging/launch_mantidworkbench.sh.in + ${CMAKE_CURRENT_BINARY_DIR}/launch_mantidworkbench.sh.install @ONLY ) + install ( PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/launch_mantidworkbench.sh.install + DESTINATION ${BIN_DIR} RENAME mantidworkbench ) +endif() configure_file ( ${CMAKE_MODULE_PATH}/Packaging/mantidpython.in ${CMAKE_CURRENT_BINARY_DIR}/mantidpython.install @ONLY ) -install ( FILES ${CMAKE_CURRENT_BINARY_DIR}/mantidpython.install - DESTINATION ${BIN_DIR} RENAME mantidpython - PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ - GROUP_EXECUTE GROUP_READ - WORLD_EXECUTE WORLD_READ -) +install ( PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/mantidpython.install + DESTINATION ${BIN_DIR} RENAME mantidpython ) diff --git a/buildconfig/CMake/Packaging/launch_mantidplot.sh.in b/buildconfig/CMake/Packaging/launch_mantidplot.sh.in index a8822b897ea6f5f97d204ae12853012924a03cb7..dc4c9d534d9ecfa1500ea81080660b4553a1328a 100644 --- a/buildconfig/CMake/Packaging/launch_mantidplot.sh.in +++ b/buildconfig/CMake/Packaging/launch_mantidplot.sh.in @@ -6,49 +6,18 @@ # Find out where we are THISFILE=$(readlink -f "$0") -INSTALLDIR=$(echo $THISFILE | sed -r -e 's|^(.*)/(.*)$|\1|g') #.* is greedy and eats up until the final slash +INSTALLDIR=$(dirname $THISFILE) # directory of executable +INSTALLDIR=$(dirname $INSTALLDIR) # root install directory -# Define extra libraries and load paths -LOCAL_PRELOAD=@TCMALLOC_RUNTIME_LIB@ -if [ -n "${LD_PRELOAD}" ]; then - LOCAL_PRELOAD=${LOCAL_PRELOAD}:${LD_PRELOAD} -fi -if [ -z "${TCMALLOC_RELEASE_RATE}" ]; then - TCM_RELEASE=10000 -else - TCM_RELEASE=${TCMALLOC_RELEASE_RATE} -fi +@MTD_PATH_DEFINITION@ -if [ -n "${NXSESSIONID}" ]; then - command -v vglrun >/dev/null 2>&1 || { echo >&2 "MantidPlot requires VirtualGL but it's not installed. Aborting."; exit 1; } - VGLRUN="vglrun" -elif [ -n "${TLSESSIONDATA}" ]; then - command -v vglrun >/dev/null 2>&1 || { echo >&2 "MantidPlot requires VirtualGL but it's not installed. Aborting."; exit 1; } - VGLRUN="vglrun" -fi +@TCMALLOC_DEFINITIONS@ -# Define when to report large memory allocation -if [ -z "${TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD}" ]; then - # total available memory - TCM_REPORT=$(grep MemTotal /proc/meminfo --color=never | awk '{print $2}') - # half of available memory - TCM_REPORT=`expr 512 \* $TCM_REPORT` - # minimum is 1GB - if [ ${TCM_REPORT} -le 1073741824 ]; then - TCM_REPORT=1073741824 - fi -else - TCM_REPORT=${TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD} -fi - -# run with gdb THIS OPTION MUST BE SUPPLIED FIRST -if [ -n "$1" ] && [ "$1" = "--debug" ]; then - shift - GDB="gdb --args" -fi +@VIRTUAL_GL_WRAPPER@ +@GDB_DEFINITIONS@ # Launch LD_PRELOAD=${LOCAL_PRELOAD} TCMALLOC_RELEASE_RATE=${TCM_RELEASE} \ - TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD=${TCM_REPORT} QT_API=pyqt \ - @WRAPPER_PREFIX@$VGLRUN $GDB $INSTALLDIR/@MANTIDPLOT_EXEC@ $*@WRAPPER_POSTFIX@ || @PYTHON_EXECUTABLE@ @SCRIPTSDIR@/ErrorReporter/error_dialog_app.py --exitcode=$? --directory=$INSTALLDIR + TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD=${TCM_REPORT} \ + @WRAPPER_PREFIX@$VGLRUN $GDB $INSTALLDIR/bin/@MANTIDPLOT_EXEC@ $*@WRAPPER_POSTFIX@ || @PYTHON_EXECUTABLE@ @SCRIPTSDIR@/@ERROR_CMD@ diff --git a/buildconfig/CMake/Packaging/launch_mantidworkbench.sh.in b/buildconfig/CMake/Packaging/launch_mantidworkbench.sh.in new file mode 100644 index 0000000000000000000000000000000000000000..25a5d1354b675f266e61a519bb321768cf9d066f --- /dev/null +++ b/buildconfig/CMake/Packaging/launch_mantidworkbench.sh.in @@ -0,0 +1,29 @@ +#!/bin/sh +# +# Launch Mantidplot using any necessary LD_PRELOAD or software collection behaviour +# +# Script is configured by CMake + +# Find out where we are +THISFILE=$(readlink -f "$0") +INSTALLDIR=$(dirname $THISFILE) # directory of executable +INSTALLDIR=$(dirname $INSTALLDIR) # root install directory + +@MTD_PATH_DEFINITION@ + +@TCMALLOC_DEFINITIONS@ + +@VIRTUAL_GL_WRAPPER@ + +# Define where python libraries are +LOCAL_PYTHONPATH=@LOCAL_PYPATH@@PARAVIEW_PYTHON_PATHS@ +if [ -n "${PYTHONPATH}" ]; then + LOCAL_PYTHONPATH=${LOCAL_PYTHONPATH}:${PYTHONPATH} +fi + +@GDB_DEFINITIONS@ + +LD_PRELOAD=${LOCAL_PRELOAD} TCMALLOC_RELEASE_RATE=${TCM_RELEASE} \ + TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD=${TCM_REPORT} \ + PYTHONPATH=${LOCAL_PYTHONPATH} \ + @WRAPPER_PREFIX@$VGLRUN $GDB @PYTHON_EXECUTABLE@ $INSTALLDIR/bin/@MANTIDWORKBENCH_EXEC@ $*@WRAPPER_POSTFIX@ || @PYTHON_EXECUTABLE@ @SCRIPTSDIR@/@ERROR_CMD@ diff --git a/buildconfig/CMake/Packaging/mantidpython.in b/buildconfig/CMake/Packaging/mantidpython.in index 668620b986878f3a36a9dd9e47801860871eb9e4..1b9df21e90ce8a6ec06ea990e83108b3688746df 100755 --- a/buildconfig/CMake/Packaging/mantidpython.in +++ b/buildconfig/CMake/Packaging/mantidpython.in @@ -5,74 +5,44 @@ # Script is configured by CMake # Find out where we are -SCRIPTFILE=$(readlink -f "$0") -INSTALLDIR=${SCRIPTFILE%/*} +THISFILE=$(readlink -f "$0") +INSTALLDIR=$(dirname $THISFILE) # directory of executable +INSTALLDIR=$(dirname $INSTALLDIR) # root install directory -# Define extra libraries and load paths -LOCAL_PRELOAD=@TCMALLOC_RUNTIME_LIB@ -if [ -n "${LD_PRELOAD}" ]; then - LOCAL_PRELOAD=${LOCAL_PRELOAD}:${LD_PRELOAD} -fi -if [ -z "${TCMALLOC_RELEASE_RATE}" ]; then - TCM_RELEASE=10000 -else - TCM_RELEASE=${TCMALLOC_RELEASE_RATE} -fi -LOCAL_LDPATH=@EXTRA_LDPATH@:${LD_LIBRARY_PATH} +@MTD_PATH_DEFINITION@ -# Define when to report large memory allocation -if [ -z "${TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD}" ]; then - # total available memory - TCM_REPORT=$(grep MemTotal /proc/meminfo --color=never | awk '{print $2}') - # half of available memory - TCM_REPORT=`expr 512 \* $TCM_REPORT` - # minimum is 1GB - if [ ${TCM_REPORT} -le 1073741824 ]; then - TCM_REPORT=1073741824 - fi -else - TCM_REPORT=${TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD} +@TCMALLOC_DEFINITIONS@ + +LOCAL_LDPATH=@EXTRA_LDPATH@ +if [ -n "${LD_LIBRARY_PATH}" ]; then + LOCAL_LDPATH=${LOCAL_LDPATH}:${LD_LIBRARY_PATH} fi # Define paraview information -PV_PLUGIN_PATH="${INSTALLDIR}/pvplugins/pvplugins" +PV_PLUGIN_PATH="${INSTALLDIR}/plugins/paraview/qt4" -# Define extra libraries for python -LOCAL_PYTHONPATH=${INSTALLDIR}@PARAVIEW_PYTHON_PATHS@ +# Define where python libraries are +LOCAL_PYTHONPATH=${INSTALLDIR}/bin:@LOCAL_PYPATH@@PARAVIEW_PYTHON_PATHS@ if [ -n "${PYTHONPATH}" ]; then LOCAL_PYTHONPATH=${LOCAL_PYTHONPATH}:${PYTHONPATH} fi -# Define QT_API to pyqt if not provided -if [ -z "${QT_API}" ]; then - QT_API=pyqt -fi - -# Define MANTIDPATH -MANTIDPATH="${INSTALLDIR}" - if [ -n "$1" ] && [ "$1" = "--classic" ]; then shift - set -- @WRAPPER_PREFIX@@PYTHON_EXECUTABLE@ $*@WRAPPER_POSTFIX@ - elif [ -n "$1" ] && [ -n "$2" ] && [ "$1" = "-n" ]; then ranks=$2 shift 2 set -- mpirun -n $ranks @WRAPPER_PREFIX@@PYTHON_EXECUTABLE@ $*@WRAPPER_POSTFIX@ - else IPYTHON_STARTUP="import IPython;IPython.start_ipython()" - set -- @WRAPPER_PREFIX@@PYTHON_EXECUTABLE@ -c "${IPYTHON_STARTUP}" $*@WRAPPER_POSTFIX@ - fi - LD_PRELOAD=${LOCAL_PRELOAD} TCMALLOC_RELEASE_RATE=${TCM_RELEASE} \ - TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD=${TCM_REPORT} \ - LD_LIBRARY_PATH=${LOCAL_LDPATH} QT_API=${QT_API} \ - PV_PLUGIN_PATH=${PV_PLUGIN_PATH} \ - MANTIDPATH=${MANTIDPATH} \ - PYTHONPATH=${LOCAL_PYTHONPATH} \ - exec "$@" + TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD=${TCM_REPORT} \ + PYTHONPATH=${LOCAL_PYTHONPATH} \ + LD_LIBRARY_PATH=${LOCAL_LDPATH} \ + PV_PLUGIN_PATH=${PV_PLUGIN_PATH} \ + exec "$@" +# diff --git a/buildconfig/CMake/Packaging/rpm/scripts/rpm_post_install.sh.in b/buildconfig/CMake/Packaging/rpm/scripts/rpm_post_install.sh.in index 98e6a3106cb167bc5edf26dd5acc56138cc8e5ed..671583b86c43ad6f2908d78ddb3ed39090f7f79c 100644 --- a/buildconfig/CMake/Packaging/rpm/scripts/rpm_post_install.sh.in +++ b/buildconfig/CMake/Packaging/rpm/scripts/rpm_post_install.sh.in @@ -12,6 +12,7 @@ if [ -f $RPM_INSTALL_PREFIX0/@BIN_DIR@/MantidPlot ]; then if [ ! -s $RPM_INSTALL_PREFIX0/@BIN_DIR@/MantidPlot ]; then ln -s $RPM_INSTALL_PREFIX0/@BIN_DIR@/launch_mantidplot.sh $RPM_INSTALL_PREFIX0/@BIN_DIR@/MantidPlot fi + # create link to old name so upgrading from old packages doesn't delete the executable if [ ! -s $RPM_INSTALL_PREFIX0/@BIN_DIR@/mantidplot ]; then ln -s $RPM_INSTALL_PREFIX0/@BIN_DIR@/launch_mantidplot.sh $RPM_INSTALL_PREFIX0/@BIN_DIR@/mantidplot fi @@ -24,11 +25,20 @@ if [ ${ENVVARS_ON_INSTALL} -eq 1 ]; then ln -s $RPM_INSTALL_PREFIX0/@ETC_DIR@/mantid.csh /etc/profile.d/mantid.csh ln -s $RPM_INSTALL_PREFIX0/@ETC_DIR@/mantid.pth @PYTHON_SITE@/mantid.pth else - # Create symbolic links in world's path - if [ ! -L /usr/bin/mantidplot@CPACK_PACKAGE_SUFFIX@ ]; then - ln -s $RPM_INSTALL_PREFIX0/@BIN_DIR@/launch_mantidplot.sh /usr/bin/mantidplot@CPACK_PACKAGE_SUFFIX@ + # symbolic links in world's path of mantidplot + if [ -e $RPM_INSTALL_PREFIX0/@BIN_DIR@/mantidplot ]; then + if [ ! -L /usr/bin/mantidplot@CPACK_PACKAGE_SUFFIX@ ]; then + ln -s $RPM_INSTALL_PREFIX0/@BIN_DIR@/mantidplot /usr/bin/mantidplot@CPACK_PACKAGE_SUFFIX@ + fi fi + # symbolic link for mantidpython if [ ! -L /usr/bin/mantidpython@CPACK_PACKAGE_SUFFIX@ ]; then ln -s $RPM_INSTALL_PREFIX0/@BIN_DIR@/mantidpython /usr/bin/mantidpython@CPACK_PACKAGE_SUFFIX@ fi + # link the workbench if it exists + if [ -e $RPM_INSTALL_PREFIX0/@BIN_DIR@/mantidworkbench ]; then + if [ ! -L /usr/bin/mantidworkbench@CPACK_PACKAGE_SUFFIX@ ]; then + ln -s $RPM_INSTALL_PREFIX0/@BIN_DIR@/mantidworkbench /usr/bin/mantidworkbench@CPACK_PACKAGE_SUFFIX@ + fi + fi fi diff --git a/buildconfig/CMake/Packaging/rpm/scripts/rpm_post_uninstall.sh.in b/buildconfig/CMake/Packaging/rpm/scripts/rpm_post_uninstall.sh.in index 3b54e3bb45e7be20ac992f5c472446c0f6eda349..2ab08a710e0427a09c742c4dfa561f306f676fbb 100644 --- a/buildconfig/CMake/Packaging/rpm/scripts/rpm_post_uninstall.sh.in +++ b/buildconfig/CMake/Packaging/rpm/scripts/rpm_post_uninstall.sh.in @@ -10,8 +10,10 @@ ENVVARS_ON_INSTALL=@ENVVARS_ON_INSTALL_INT@ # Remove exe and links only if it looks like we were removed # and not upgraded. If launch_mantidplot.sh exists then package # has been upgraded and MantidPlot_exe replaced so don't touch anything -if [ ! -e $RPM_INSTALL_PREFIX0/@BIN_DIR@/launch_mantidplot.sh ]; then - rm $RPM_INSTALL_PREFIX0/@BIN_DIR@/MantidPlot_exe +if [ ! -e $RPM_INSTALL_PREFIX0/@BIN_DIR@/launch_mantidplot.sh ]; then + if [ -e $RPM_INSTALL_PREFIX0/@BIN_DIR@/MantidPlot_exe ]; then + rm $RPM_INSTALL_PREFIX0/@BIN_DIR@/MantidPlot_exe + fi if [ ${ENVVARS_ON_INSTALL} -eq 1 ]; then if [ -h /etc/profile.d/mantid.sh ]; then @@ -40,6 +42,10 @@ if [ ! -e $RPM_INSTALL_PREFIX0/@BIN_DIR@/launch_mantidplot.sh ]; then if [ -L $RPM_INSTALL_PREFIX0/@BIN_DIR@/mantidplot ]; then rm $RPM_INSTALL_PREFIX0/@BIN_DIR@/mantidplot fi + + if [ -L /usr/bin/mantidworkbench@CPACK_PACKAGE_SUFFIX@ ]; then + rm /usr/bin/mantidworkbench@CPACK_PACKAGE_SUFFIX@ + fi fi # If the install prefix contains mantid then prune empty directories. diff --git a/buildconfig/CMake/PythonPackageTargetFunctions.cmake b/buildconfig/CMake/PythonPackageTargetFunctions.cmake new file mode 100644 index 0000000000000000000000000000000000000000..afcc9daed46436c60aec95292fcc6fc9ac41d0d0 --- /dev/null +++ b/buildconfig/CMake/PythonPackageTargetFunctions.cmake @@ -0,0 +1,79 @@ +# Defines functions to help deal with python packages + +# Function to create links to python packages in the source tree +# If the EXECUTABLE option is provided then it additional build rules are +# defined to ensure startup scripts are regenerated appropriately +function ( add_python_package pkg_name ) + # Create a setup.py file if necessary + set ( _setup_py ${CMAKE_CURRENT_SOURCE_DIR}/setup.py ) + set ( _setup_py_build_root ${CMAKE_CURRENT_BINARY_DIR} ) + if ( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in" ) + set ( SETUPTOOLS_BUILD_COMMANDS_DEF +"def patch_setuptools_command(cmd_cls_name): + import importlib + cmd_module = importlib.import_module('setuptools.command.' + cmd_cls_name) + setuptools_command_cls = getattr(cmd_module, cmd_cls_name) + + class CustomCommand(setuptools_command_cls): + user_options = setuptools_command_cls.user_options[:] + boolean_options = setuptools_command_cls.boolean_options[:] + def finalize_options(self): + build_cmd = self.get_finalized_command('build') + self.build_lib = '${_setup_py_build_root}/build' + setuptools_command_cls.finalize_options(self) + + return CustomCommand + +CustomBuildPy = patch_setuptools_command('build_py') +CustomInstall = patch_setuptools_command('install') +CustomInstallLib = patch_setuptools_command('install_lib') +" ) + set ( SETUPTOOLS_BUILD_COMMANDS_USE "cmdclass={'build_py': CustomBuildPy, 'install': CustomInstall, 'install-lib': CustomInstallLib }" ) + configure_file ( ${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in ${_setup_py} @ONLY ) + endif () + + set ( _egg_link_dir ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR} ) + set ( _egg_link ${_egg_link_dir}/${pkg_name}.egg-link ) + + if ( ARGC GREATER 1 AND "${ARGN}" STREQUAL "EXECUTABLE" ) + if ( WIN32 ) + set ( _startup_script ${_egg_link_dir}/${pkg_name}-script.pyw ) + set ( _startup_exe ${_egg_link_dir}/${pkg_name}.exe ) + else () + set ( _startup_script ) + set ( _startup_exe ${_egg_link_dir}/${pkg_name} ) + endif () + endif () + + # create the developer setup which just creates a pth file rather than copying things over + set ( _outputs ${_egg_link} ${_startup_script} ${_startup_exe} ) + add_custom_command ( OUTPUT ${_outputs} + COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${_egg_link_dir} + ${PYTHON_EXECUTABLE} ${_setup_py} develop + --install-dir ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR} + --script-dir ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS ${_setup_py} + ) + add_custom_target ( ${pkg_name} ALL + DEPENDS ${_outputs} + ) + + if ( ${PACKAGE_WORKBENCH} ) + # setuptools by default wants to build into a directory called 'build' relative the to the working directory. We have overridden + # commands in setup.py.in to force the build directory to take place out of source. The install directory is specified here and then + # --install-scripts=bin --install-lib=lib removes any of the plaform/distribution specific install directories so we can have a flat + # structure + install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} ${_setup_py} install -O1 --single-version-externally-managed --root=${_setup_py_build_root}/install --install-scripts=bin --install-lib=lib WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})") + # register the "installed" components with cmake so it will carry them over + install(DIRECTORY ${_setup_py_build_root}/install/lib + DESTINATION . + PATTERN "test" EXCLUDE ) + + # install the generated executable - only tested with "workbench" + if ( ARGC GREATER 1 AND "${ARGN}" STREQUAL "EXECUTABLE" ) + install(PROGRAMS ${_setup_py_build_root}/install/bin/${pkg_name} + DESTINATION bin) + endif() + endif() +endfunction () diff --git a/buildconfig/CMake/QtTargetFunctions.cmake b/buildconfig/CMake/QtTargetFunctions.cmake index 7314faba29176e1386d232ea2e288345709851e6..01772f4b161f53eb6ef84cacfea6075cc3e8dbdb 100644 --- a/buildconfig/CMake/QtTargetFunctions.cmake +++ b/buildconfig/CMake/QtTargetFunctions.cmake @@ -214,13 +214,11 @@ function (mtd_add_qt_target) _append_qt_suffix (AS_DIR VERSION ${PARSED_QT_VERSION} OUTPUT_VARIABLE _install_dir ${PARSED_INSTALL_DIR_BASE}) else() - set ( _install_dir ${LIB_DIR} ) + set ( _install_dir "" ) + message ( FATAL_ERROR "Target: ${_target} is configured to build but has no install destination" ) endif() - # Hack: Only install Qt4 to packages for now... - if (${PARSED_QT_VERSION} EQUAL 4) - install ( TARGETS ${_target} ${SYSTEM_PACKAGE_TARGET} DESTINATION ${_install_dir} ) - endif() - endif() + mtd_install_qt_library ( ${PARSED_QT_VERSION} ${_target} "${SYSTEM_PACKAGE_TARGET}" ${_install_dir} ) + endif () # Group into folder for VS set_target_properties ( ${_target} PROPERTIES FOLDER "Qt${PARSED_QT_VERSION}" ) @@ -234,6 +232,17 @@ function (mtd_add_qt_target) endfunction() +# Create an install rule for a Qt target +# - qt_version The version of Qt targeted +# - target The name of the target +# - install_target_type The type of target that should be installed. See https://cmake.org/cmake/help/latest/command/install.html?highlight=install +# - install_dir A relative directory to install_prefix +function (mtd_install_qt_library qt_version target install_target_type install_dir ) + if ( qt_version EQUAL 4 OR (qt_version EQUAL 5 AND ${PACKAGE_WORKBENCH}) ) + install ( TARGETS ${target} ${install_target_type} DESTINATION ${install_dir} ) + endif () +endfunction () + function (mtd_add_qt_tests) _qt_versions(_qt_vers ${ARGN}) # Create targets diff --git a/buildconfig/CMake/SipQtTargetFunctions.cmake b/buildconfig/CMake/SipQtTargetFunctions.cmake index 120ad0175939f086b12674900e8a3874cb885081..85c049f710054a0027fdd9698a5649090d320509 100644 --- a/buildconfig/CMake/SipQtTargetFunctions.cmake +++ b/buildconfig/CMake/SipQtTargetFunctions.cmake @@ -3,7 +3,7 @@ # of .sip definitions include ( QtTargetFunctions ) -# + # brief: Add a module target to generate Python bindings # for a set of sip sources. The sources list should be a list of filenames # without a path. The .sip module is generated in the CMAKE_CURRENT_BINARY_DIR @@ -17,6 +17,9 @@ include ( QtTargetFunctions ) # keyword: LINK_LIBS A list of additional target_link_libraries # keyword: PYQT_VERSION A single value indicating the version of PyQt # to compile against +# keyword: INSTALL_DIR The target location for installing this library +# keyword: OSX_INSTALL_RPATH Install path for osx version > 10.8 +# keyword: LINUX_INSTALL_RPATH Install path for CMAKE_SYSTEM_NAME == Linux function ( mtd_add_sip_module ) find_file ( _sipmodule_template_path NAME sipqtmodule_template.sip.in PATHS ${CMAKE_MODULE_PATH} ) @@ -27,7 +30,7 @@ function ( mtd_add_sip_module ) set ( options ) set ( oneValueArgs MODULE_NAME TARGET_NAME MODULE_OUTPUT_DIR PYQT_VERSION FOLDER ) - set ( multiValueArgs SIP_SRCS HEADER_DEPS INCLUDE_DIRS LINK_LIBS OSX_INSTALL_RPATH LINUX_INSTALL_RPATH ) + set ( multiValueArgs SIP_SRCS HEADER_DEPS INCLUDE_DIRS LINK_LIBS INSTALL_DIR OSX_INSTALL_RPATH LINUX_INSTALL_RPATH ) cmake_parse_arguments ( PARSED "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) @@ -106,6 +109,10 @@ function ( mtd_add_sip_module ) endif () endif () + if ( PARSED_INSTALL_DIR AND PACKAGE_WORKBENCH) + mtd_install_qt_library ( ${PARSED_PYQT_VERSION} ${PARSED_TARGET_NAME} "" ${PARSED_INSTALL_DIR} ) + endif () + if ( WIN32 ) set_target_properties( ${PARSED_TARGET_NAME} PROPERTIES PREFIX "" SUFFIX ".pyd" ) if ( PYTHON_DEBUG_LIBRARY ) diff --git a/buildconfig/Jenkins/buildscript b/buildconfig/Jenkins/buildscript index 7f5edb19d98c68f0420e5bca482a824c1ca135b8..2a79c6fdf5e2e03887ce614b98fb278edadeb3c6 100755 --- a/buildconfig/Jenkins/buildscript +++ b/buildconfig/Jenkins/buildscript @@ -229,8 +229,9 @@ if [[ ${DO_BUILD_PKG} == true ]]; then PACKAGINGVARS="-DPACKAGE_DOCS=ON" # Set some variables relating to the linux packages if [[ "${ON_MACOS}" == true ]]; then - PACKAGINGVARS="${PACKAGINGVARS} -DCPACK_PACKAGE_SUFFIX=" + PACKAGINGVARS="${PACKAGINGVARS} -DPACKAGE_WORKBENCH=OFF -DCPACK_PACKAGE_SUFFIX=" else + PACKAGINGVARS="${PACKAGINGVARS} -DPACKAGE_WORKBENCH=ON" # Use different suffix for linux builds if parameter is not defined if [[ -n "${PACKAGE_SUFFIX}" ]]; then echo "Using PACKAGE_SUFFIX=${PACKAGE_SUFFIX} from job parameter" @@ -293,7 +294,7 @@ rm -f -- *.dmg *.rpm *.deb *.tar.gz *.tar.xz ############################################################################### # CMake configuration ############################################################################### -$SCL_ENABLE "${CMAKE_EXE} ${CMAKE_GENERATOR} -DCMAKE_BUILD_TYPE=${BUILD_CONFIG} -DENABLE_CPACK=ON -DMAKE_VATES=ON -DParaView_DIR=${PARAVIEW_DIR} -DMANTID_DATA_STORE=${MANTID_DATA_STORE} -DDOCS_HTML=ON -DENABLE_CONDA=ON -DENABLE_WORKBENCH=ON -DENABLE_FILE_LOGGING=OFF ${DIST_FLAGS} ${PACKAGINGVARS} ${CLANGTIDYVAR} .." +$SCL_ENABLE "${CMAKE_EXE} ${CMAKE_GENERATOR} -DCMAKE_BUILD_TYPE=${BUILD_CONFIG} -DENABLE_CPACK=ON -DMAKE_VATES=ON -DParaView_DIR=${PARAVIEW_DIR} -DMANTID_DATA_STORE=${MANTID_DATA_STORE} -DDOCS_HTML=ON -DENABLE_CONDA=ON -DENABLE_WORKBENCH=ON ${DIST_FLAGS} ${PACKAGINGVARS} ${CLANGTIDYVAR} .." ############################################################################### # Coverity build should exit early diff --git a/buildconfig/Jenkins/buildscript.bat b/buildconfig/Jenkins/buildscript.bat index 7244fd4fd2b4f31da34e7a21d058263ef7b2cbdb..8a7d9211c778f75ecf4b43c5778b5dbe115332a6 100755 --- a/buildconfig/Jenkins/buildscript.bat +++ b/buildconfig/Jenkins/buildscript.bat @@ -150,7 +150,7 @@ if not "%JOB_NAME%"=="%JOB_NAME:debug=%" ( ) else ( set VATES_OPT_VAL=ON ) -call cmake.exe -G "%CM_GENERATOR%" -DCMAKE_SYSTEM_VERSION=%SDK_VERSION% -DCONSOLE=OFF -DENABLE_CPACK=ON -DMAKE_VATES=%VATES_OPT_VAL% -DParaView_DIR=%PARAVIEW_DIR% -DMANTID_DATA_STORE=!MANTID_DATA_STORE! -DENABLE_WORKBENCH=ON -DUSE_PRECOMPILED_HEADERS=ON -DENABLE_FILE_LOGGING=OFF %PACKAGE_OPTS% .. +call cmake.exe -G "%CM_GENERATOR%" -DCMAKE_SYSTEM_VERSION=%SDK_VERSION% -DCONSOLE=OFF -DENABLE_CPACK=ON -DMAKE_VATES=%VATES_OPT_VAL% -DParaView_DIR=%PARAVIEW_DIR% -DMANTID_DATA_STORE=!MANTID_DATA_STORE! -DENABLE_WORKBENCH=ON -DPACKAGE_WORKBENCH=OFF -DUSE_PRECOMPILED_HEADERS=ON %PACKAGE_OPTS% .. if ERRORLEVEL 1 exit /B %ERRORLEVEL% ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: diff --git a/dev-docs/source/GettingStartedWithPyCharm.rst b/dev-docs/source/GettingStartedWithPyCharm.rst index 58aa3852d64eb2c6a248ed9807da7d30b75e407a..8d138d26e53fd04c859ee59410267e4cc67930f2 100644 --- a/dev-docs/source/GettingStartedWithPyCharm.rst +++ b/dev-docs/source/GettingStartedWithPyCharm.rst @@ -103,3 +103,18 @@ On Linux the instructions are identical to Windows except that : - In step 1, the file is ``pycharm.sh`` rather than ``pycharm.bat`` - In step 2, use the native python interpreter (``/usr/bin/python2.7/python.exe``) rather than from ``<Mantid Source Directory>/external/src/ThirdParty/lib/python2.7/python.exe`` - In step 4, add ``<Mantid Build Directory>/bin;`` to the ``PATH`` environment variable in the new configuration (rather than ``<Mantid Build Directory>/bin/Debug;``), and remove the other three file paths. + +Useful Plugins +############## + +You can install non-default plugins by pressing ``Ctrl+Alt+S`` to open the **Settings/Preferences** dialog and then going to **Plugins**. +From here you can manage plugins, or add new ones by clicking **Browse repositories**. + +The following non-default plugins are things our team has found useful for Mantid development: + +- **Markdown support** - Side by side rendering of markdown documents such as``.md`` , ``.rst`` (requires `Graphviz <https://graphviz.gitlab.io/download/>`_ to show graphs in preview) +- **dotplugin** - Syntax highlighting for ``DOT`` +- **BashSupport** - Syntax highlighting for ``BASH`` scripts +- **CMD Support** - Syntax highlighting for ``.BAT`` ~scripts + +Please add to this list if you find a useful plugin of your own diff --git a/dev-docs/source/IndividualTicketTesting.rst b/dev-docs/source/IndividualTicketTesting.rst new file mode 100644 index 0000000000000000000000000000000000000000..de0d31601d3e47794da51efd1edd3033d7f78377 --- /dev/null +++ b/dev-docs/source/IndividualTicketTesting.rst @@ -0,0 +1,50 @@ +.. _IndividualTicketTesting: + +========================= +Individual Ticket Testing +========================= + +An important step in our :ref:`development workflow <GitWorkflow>` is the testing of individual issues/tickets after the development on them is complete, and before the code is merges into the master branch. Developers pick one from `the list <https://github.com/mantidproject/mantid/pulls>`_ of completed issues and perform a number of verification steps on it. The mechanics of testing a pull request (e.g. the git commands to use) are described :ref:`here <GitWorkflow>`. This page is concerned with the aspects that should be considered in deciding whether a pull request should be recommended to merge or sent back to the developer for further work. *There should be very little reluctance to reopen a ticket even for minor issues.* + +Code Review +=========== + +The code changes should be manually reviewed (the github compare view is ideal for this). A couple of pieces on the value of code review can be found at `scientopia <http://scientopia.org/blogs/goodmath/2011/07/06/things-everyone-should-do-code-review>`_ and `codinghorror <http://www.codinghorror.com/blog/2006/01/code-reviews-just-do-it.html>`_. + +* The primary aim is to find bugs that the developer and tests so far have not spotted. +* But also consider whether the code is 'clean', well-structured and easy to read/maintain. +* Part of this is that: + + * There should be are no compiler (or doxygen) warnings coming from any modified classes + * The code conforms to our :ref:`coding standards <MantidStandards>`. + +* Unit tests (or system tests if more appropriate) should be checked that they: + + * Exist and give adequate coverage (see :ref:`unit testing practices <UnitTestGoodPractice>`). + * If the ticket is fixing a bug there should be a test that makes sure we don't have to fix the same bug again! + * Do not load real data (data loading algorithms get a free pass on this one). + * Leave the system in the same state that they found it (i.e. clean up). + * Have a performance test, if appropriate. + +* Check that any user documentation is adequate and that there are release notes. In the case of new algorithms, there should be an accompanying ``*.rst`` file that has been added, containing an explanation of what exactly the algorithm does along with Python usage examples. + +Functional Testing +================== + +The first thing to note is that this should **not** just be a quick check of whatever the ticket says it does. Testing should be as much, if not more, about making sure the code *does not do what it's not supposed to do* as that it *does do what it's supposed to*. + +* All of the builds pass +* The developer should have included instructions in the ticket of how to test things work. +* But, as noted above, don’t just do that – also try to break it: click random buttons on GUIs, give unexpected/invalid inputs, etc. +* Note down what you did in the ticket, and the platform you did it on. + +If all the requirements have been met and documented approve the PR using `GitHub's review mechanism <https://help.github.com/articles/about-pull-request-reviews/>`_. + +Gatekeeper +========== + +The ``@mantidproject/gatekeepers`` group is who is meant to merge pull requests into master. This is done by social contract. A gatekeeper can ``merge`` code if: + +* Green tick on the last build indicating all automated testing has succeeded +* Adequate tests, both success and failure cases have been performed +* There is comment on the code being reviewed diff --git a/dev-docs/source/Standards/MantidStandards.rst b/dev-docs/source/Standards/MantidStandards.rst index adfa95c3beecd23abf4a54afb0fd2f2394b5ca90..b8533c1da97b1a97e2b9fc00d027b425c4b537c4 100644 --- a/dev-docs/source/Standards/MantidStandards.rst +++ b/dev-docs/source/Standards/MantidStandards.rst @@ -1,3 +1,5 @@ +.. _MantidStandards: + ================ Mantid Standards ================ @@ -106,7 +108,7 @@ Parameter names must: - Start with a capital letter - Have a capital letter for each new word (e.g. 'InputWorkspace') - Use alphanumeric characters only (i.e. cannot contain any of these ``/,._-'\"`` or whitespace) -- Can contain numbers but only allowed after the first character. +- Can contain numbers but only allowed after the first character. Notable exceptions to these rules are lattice constants (i.e. a, b, c, alpha, beta, gamma). diff --git a/dev-docs/source/index.rst b/dev-docs/source/index.rst index f03b7c4e3dad06d0709ea427a9f8b7e30435186d..a951ad20986b624cdf8c29953a99626affefc34e 100644 --- a/dev-docs/source/index.rst +++ b/dev-docs/source/index.rst @@ -125,7 +125,7 @@ Tools :doc:`GettingStartedWithPyCharm` Describes how to set up the PyCharm interpreter, and debug python code (Windows/Linux only). - + :doc:`Eclipse` Guide to setting up Eclipse on Ubuntu @@ -139,6 +139,7 @@ Testing RunningTheUnitTests DebuggingUnitTests UnitTestGoodPractice + IndividualTicketTesting WritingPerformanceTests SystemTests DataFilesForTesting @@ -153,6 +154,9 @@ Testing :doc:`UnitTestGoodPractice` Guidance on writing good unit tests. +:doc:`IndividualTicketTesting` + What to expect and inspect when reviewing an individual contribution to mantid. + :doc:`WritingPerformanceTests` A walk through of how to write a performance test. @@ -206,4 +210,3 @@ Component Overviews RemoteJobSubmissionAPI WritingAnAlgorithm WritingCustomConvertToMDTransformation - diff --git a/docs/source/algorithms/LoadDNSSCD-v1.rst b/docs/source/algorithms/LoadDNSSCD-v1.rst index d3b24caaf87f879236a4aa96b3150f23a7673dff..28f2f8d005c83ead775b47e92b15c551ea79c1fc 100644 --- a/docs/source/algorithms/LoadDNSSCD-v1.rst +++ b/docs/source/algorithms/LoadDNSSCD-v1.rst @@ -25,7 +25,7 @@ As a result, two workspaces are created: - `NormalizationWorkspace` contains the choosen normalization data (either monitor counts or experiment duration time). -Both workspaces have :math:`(H,K,L)` dimensions. The metadata are loaded into time series sample logs. +Both workspaces have :math:`(H,K,L,dE)` dimensions. The metadata are loaded into time series sample logs. .. note:: @@ -36,11 +36,11 @@ Restrictions - This algorithm only supports the *DNS* instrument in its configuration with one detector bank (polarisation analysis). -- This algorithm does not support DNS TOF mode data. It is meant only for single crystal diffraction experiments with 1 TOF channel. +- This algorithm does not allow to merge datasets with different number of TOF channels. Data replication -________________ +---------------- For standard data (vanadium, NiCr, background) the sample rotation angle is assumed to be not important. These data are typically measured only for one sample rotation angle. The algorithm can replicate these data for the same sample rotation angles as a single crystal sample has been measured. For this purpose optional input fields *SaveHuberTo* and *LoadHuberFrom* can be used. @@ -91,7 +91,7 @@ Usage dimension.getUnits())) # print information about the table workspace - print ("TableWorkspace '{0}' has {1} row in the column '{2}'.".format(huber_ws.getName(), + print ("TableWorkspace '{0}' has {1} row in the column '{2}'.".format(huber_ws.name(), huber_ws.rowCount(), huber_ws.getColumnNames()[0])) print("It contains sample rotation angle {} degrees".format(huber_ws.cell(0, 0))) @@ -100,11 +100,12 @@ Usage .. testoutput:: LoadDNSSCDEx1 - Output Workspace Type is: MDEventWorkspace<MDEvent,3> - It has 24 events and 3 dimensions: + Output Workspace Type is: MDEventWorkspace<MDEvent,4> + It has 24 events and 4 dimensions: Dimension 0 has name: H, id: H, Range: -15.22 to 15.22 r.l.u Dimension 1 has name: K, id: K, Range: -15.22 to 15.22 r.l.u Dimension 2 has name: L, id: L, Range: -41.95 to 41.95 r.l.u + Dimension 3 has name: DeltaE, id: DeltaE, Range: -10.00 to 4.64 r.l.u TableWorkspace 'huber_ws' has 1 row in the column 'Huber(degrees)'. It contains sample rotation angle 79.0 degrees @@ -147,10 +148,10 @@ Usage .. testoutput:: LoadDNSSCDEx2 - Output Workspace Type is: MDEventWorkspace<MDEvent,3> - It has 10 events and 3 dimensions. - Normalization Workspace Type is: MDEventWorkspace<MDEvent,3> - It has 10 events and 3 dimensions. + Output Workspace Type is: MDEventWorkspace<MDEvent,4> + It has 10 events and 4 dimensions. + Normalization Workspace Type is: MDEventWorkspace<MDEvent,4> + It has 10 events and 4 dimensions. **Example 3 - Load sample rotation angles from the table** @@ -186,17 +187,18 @@ Usage print("It has {0} events and {1} dimensions.".format(ws.getNEvents(), ws.getNumDims())) # setting for the BinMD algorithm - bvec0 = '[100],unit,1,0,0' - bvec1 = '[001],unit,0,0,1' - bvec2 = '[010],unit,0,1,0' - extents = '-2,1.5,-0.2,6.1,-10,10' - bins = '10,10,1' + bvec0 = '[100],unit,1,0,0,0' + bvec1 = '[001],unit,0,0,1,0' + bvec2 = '[010],unit,0,1,0,0' + bvec3 = 'dE,meV,0,0,0,1' + extents = '-2,1.5,-0.2,6.1,-10,10,-10,4.6' + bins = '10,10,1,1' # bin the data - data_raw = BinMD(ws, AxisAligned='0', BasisVector0=bvec0, BasisVector1=bvec1, - BasisVector2=bvec2, OutputExtents=extents, OutputBins=bins, NormalizeBasisVectors='0') + data_raw = BinMD(ws, AxisAligned='0', BasisVector0=bvec0, BasisVector1=bvec1, BasisVector2=bvec2, + BasisVector3=bvec3, OutputExtents=extents, OutputBins=bins, NormalizeBasisVectors='0') # bin normalization - data_norm = BinMD(ws_norm, AxisAligned='0', BasisVector0=bvec0, BasisVector1=bvec1, - BasisVector2=bvec2, OutputExtents=extents, OutputBins=bins, NormalizeBasisVectors='0') + data_norm = BinMD(ws_norm, AxisAligned='0', BasisVector0=bvec0, BasisVector1=bvec1, BasisVector2=bvec2, + BasisVector3=bvec3, OutputExtents=extents, OutputBins=bins, NormalizeBasisVectors='0') # normalize data data = data_raw/data_norm @@ -204,16 +206,17 @@ Usage print("Reduced Workspace Type is: {}".format(data.id())) print("It has {} dimensions.".format(data.getNumDims())) s = data.getSignalArray() - print("Signal at some points: {0:.4f}, {1:.4f}, {2:.4f}".format(s[7,1][0], s[7,2][0], s[7,3][0])) + print("Signal at some points: {0:.4f}, {1:.4f}, {2:.4f}".format( + float(s[7,1][0]), float(s[7,2][0]), float(s[7,3][0]))) **Output:** .. testoutput:: LoadDNSSCDEx3 - Output Workspace Type is: MDEventWorkspace<MDEvent,3> - It has 240 events and 3 dimensions. + Output Workspace Type is: MDEventWorkspace<MDEvent,4> + It has 240 events and 4 dimensions. Reduced Workspace Type is: MDHistoWorkspace - It has 3 dimensions. + It has 4 dimensions. Signal at some points: 0.0035, 0.0033, 0.0035 .. categories:: diff --git a/docs/source/algorithms/LoadWAND-v1.rst b/docs/source/algorithms/LoadWAND-v1.rst index e42fefb113a075212f4ba28a5b21932c003d25d9..c2229dcb094fd5b93a7606463463a411a8f44571 100644 --- a/docs/source/algorithms/LoadWAND-v1.rst +++ b/docs/source/algorithms/LoadWAND-v1.rst @@ -32,6 +32,11 @@ numbers, see Usage example bellow. If multiple files are loaded they will be named 'OutputWorkspace'+'_runnumber' and be grouped in 'OutputWorkspace'. +There is a grouping option to group pixels by either 2x2 or 4x4 which +will help in reducing memory usage and speed up the later reduction +steps. In most cases you will not see a difference in reduced data +with 4x4 pixel grouping. + Usage ----- diff --git a/docs/source/api/python/mantid/api/DetectorInfo.rst b/docs/source/api/python/mantid/api/DetectorInfo.rst deleted file mode 100644 index c089436d90c88b882fa41ddb854c4ecaadbf3fa3..0000000000000000000000000000000000000000 --- a/docs/source/api/python/mantid/api/DetectorInfo.rst +++ /dev/null @@ -1,15 +0,0 @@ -============== - DetectorInfo -============== - -This a python binding to the C++ class Mantid::API::DetectorInfo. - -*bases:* :py:obj:`mantid.api.DetectorInfo` - -.. module:`mantid.api` - -.. autoclass:: mantid.api.DetectorInfo - :members: - :undoc-members: - :inherited-members: - diff --git a/docs/source/api/python/mantid/api/SpectrumInfo.rst b/docs/source/api/python/mantid/api/SpectrumInfo.rst index 6b8e3c5cf1912f99e8c643bc989139a111e794fe..f66653f6cdbb965d14e84553324c15250a54b0d3 100644 --- a/docs/source/api/python/mantid/api/SpectrumInfo.rst +++ b/docs/source/api/python/mantid/api/SpectrumInfo.rst @@ -2,7 +2,7 @@ SpectrumInfo ============== -This a python binding to the C++ class Mantid::API::SpectrumInfo. +This is a python binding to the C++ class Mantid::API::SpectrumInfo. *bases:* :py:obj:`mantid.api.SpectrumInfo` diff --git a/docs/source/api/python/mantid/geometry/DetectorInfo.rst b/docs/source/api/python/mantid/geometry/DetectorInfo.rst new file mode 100644 index 0000000000000000000000000000000000000000..d8d0cae824046b23f4496f14af139955cd59b506 --- /dev/null +++ b/docs/source/api/python/mantid/geometry/DetectorInfo.rst @@ -0,0 +1,113 @@ +============== + DetectorInfo +============== + +This is a python binding to the C++ class Mantid::Geometry::DetectorInfo. + +Most of the information concerning ``DetectorInfo`` can be found in the `Instrument Access Layers <https://github.com/mantidproject/mantid/blob/9e3d799d40fda4a5ca08887e8c47f41c3316da91/docs/source/concepts/InstrumentAccessLayers.rst>`_ document. + +-------- +Purpose +-------- +The purpose of the ``DetectorInfo`` object is to allow the user to access information about the detector(s) being used in an experiment. The ``DetectorInfo`` object can be used to access geometric information such as the number of detectors in the beamline, the absolute position of a detector as well as the absolute rotation of a detector. + +Many users may need this extra information so that they can have a better understanding of the beamline they are using. This information is easy and fast to access. Some information like mask flags can be modified directly. + +The ``DetectorInfo`` object is one of three objects that the user can gain access to from a workspace. +The other two are: + + * SpectrumInfo + * ComponentInfo + +--------- +Indexing +--------- +The ``DetectorInfo`` object is accessed by an index going from 0 to N-1, where N is the number of detectors. +It is important to note that the detector index is NOT the detector ID. A detector index is a way of addressing and enumerating detectors in the beamline. +A detector index can be found from a detector ID using ``indexOf``. + +------- +Usage +------- + +**Example 1 - Creating a DetectorInfo Object:** +This example shows how to obtain a ``DetectorInfo`` object from a workspace object. +The return value is a ``DetectorInfo`` object. + +.. testcode:: CreateDetectorInfoObject + + # Create a workspace to use + ws = CreateSampleWorkspace() + + # Get the DetectorInfo object + info = ws.detectorInfo() + print(type(info)) + +Output: + +.. testoutput:: CreateDetectorInfoObject + + <class 'mantid.geometry._geometry.DetectorInfo'> + + +**Example 2 - Calling Some Methods on the DetectorInfo Object:** +This example shows how to call a few different methods on the DetectorInfo object. + +The ``setMasked`` method takes in an integer ``index`` parameter which corresponds to a detector as well as a boolean ``masked`` parameter. +The user then has the option to set the masking of the detector identified by ``index`` to ``True`` or ``False``. + +The ``twoTheta()`` method takes in an integer ``index`` parameter which represents a detector index. +The return value is a float which represents the scattering angle with respect to the beam direction. + +The ``position()`` method takes an ``index`` parameter which represents a detector index. +The method returns the absolute position of that detector. +The returned object is of type ``V3D`` which is a point in 3D space. + +The ``size()`` method does not take in any parameters and returns the number of detectors in the instrument. +One can also use the built in ``__len__`` function to obtain the same result. + +.. testcode:: CallMethods + + # Create a workspace to use + ws = CreateSampleWorkspace() + + # Get the DetectorInfo object + info = ws.detectorInfo() + + # Call setMasked + info.setMasked(0, True) + print(info.isMasked(0)) + info.setMasked(0, False) + print(info.isMasked(0)) + + # Call twoTheta + print(info.twoTheta(0)) + + # Call the position method + print(info.position(0)) + + # Call size and __len__ + print(info.size()) + print(len(info)) + +Output: + +.. testoutput:: CallMethods + + True + False + 0.0 + [0,0,5] + 200 + 200 + + +*bases:* :py:obj:`mantid.geometry.DetectorInfo` + +.. module:`mantid.geometry` + +.. autoclass:: mantid.geometry.DetectorInfo + :members: + :undoc-members: + :inherited-members: + diff --git a/docs/source/release/v3.14.0/diffraction.rst b/docs/source/release/v3.14.0/diffraction.rst index 3e1bebd3e81151c493a06216ef8cad1b26babc30..63cd639b84e49daafc6aae2986973162d3db127d 100644 --- a/docs/source/release/v3.14.0/diffraction.rst +++ b/docs/source/release/v3.14.0/diffraction.rst @@ -13,6 +13,8 @@ Improvements ############ - :ref:`SNAPReduce <algm-SNAPReduce>` now has progress bar and all output workspaces have history +- :ref:`LoadWAND <algm-LoadWAND>` has grouping option added and loads faster +- Mask workspace option added to :ref:`WANDPowderReduction <algm-WANDPowderReduction>` :ref:`Release 3.14.0 <v3.14.0>` diff --git a/docs/source/release/v3.14.0/direct_inelastic.rst b/docs/source/release/v3.14.0/direct_inelastic.rst index 17c7168d3801571e16d51d9d97e6d1aa702a564f..bd9955f081f110392f1c3585718f87aa85c49086 100644 --- a/docs/source/release/v3.14.0/direct_inelastic.rst +++ b/docs/source/release/v3.14.0/direct_inelastic.rst @@ -28,3 +28,8 @@ Improvements :ref:`Release 3.14.0 <v3.14.0>` + +Improvements +############ + +- :ref:`LoadDNSSCD <algm-LoadDNSSCD>` has been improved to be able to load TOF data. diff --git a/docs/source/release/v3.14.0/framework.rst b/docs/source/release/v3.14.0/framework.rst index 0f3567c74535eaf288d510a9aae48450ee4a00ec..68ff8bc001e92b240993eaa2de48a6452c9f8036 100644 --- a/docs/source/release/v3.14.0/framework.rst +++ b/docs/source/release/v3.14.0/framework.rst @@ -55,6 +55,8 @@ Python New ### + - New python validator type: `:class:`~mantid.geometry.OrientedLattice`. Checks whether a workspace has an oriented lattice object attached. + Improvements ############ diff --git a/docs/source/release/v3.14.0/muon.rst b/docs/source/release/v3.14.0/muon.rst index e0350f5c48c7760d3986cbe4afc183fc58ba4701..d7482b1100c2514bae59dd070dbbdc463a54052f 100644 --- a/docs/source/release/v3.14.0/muon.rst +++ b/docs/source/release/v3.14.0/muon.rst @@ -11,10 +11,12 @@ Interface Improvements ############ - Elemental Analysis added to Muon Interfaces: Includes a selectable Periodic Table. +- TF Asymmetry mode now displays the chi squared value at the top of the browser. Bugfixes ######## - Results table now includes all logs that are common to all of the loaded files. +- When turning TF Asymmetry mode off it no longer resets the global options. Algorithms ---------- diff --git a/docs/source/release/v3.14.0/reflectometry.rst b/docs/source/release/v3.14.0/reflectometry.rst index 2452fc016e8c72c90d04c3ca47e9e0b478c05408..eb95dda9c5a7fbb39089a7f6a8050a2da203d3cd 100644 --- a/docs/source/release/v3.14.0/reflectometry.rst +++ b/docs/source/release/v3.14.0/reflectometry.rst @@ -9,4 +9,8 @@ Reflectometry Changes putting new features at the top of the section, followed by improvements, followed by bug fixes. +Liquids Reflectometer +--------------------- +- Default x-direction pixel range for the scaling factor calculation is now set to the full width of the detector as opposed to a restricted guess. + :ref:`Release 3.14.0 <v3.14.0>` diff --git a/instrument/V20_4-tubes_150deg_Definition_v01.xml b/instrument/V20_4-tubes_150deg_Definition_v01.xml index f124bc641ea87c3f4a44f41ad39e96f2a8d04e50..1b270aeaf13d461c0d48798c7af92dbd8341ed7f 100644 --- a/instrument/V20_4-tubes_150deg_Definition_v01.xml +++ b/instrument/V20_4-tubes_150deg_Definition_v01.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- For help on the notation used to specify an Instrument Definition File see http://www.mantidproject.org/IDF --> +<!-- IDF configurations can be gound here https://github.com/mantidproject/documents/blob/master/IDF-Configurations/V20_idf_configurations_v05.pptx --> <instrument xmlns="http://www.mantidproject.org/IDF/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 Schema/IDFSchema.xsd" name="IMAT" valid-from ="1900-01-31 23:59:59" valid-to ="2099-12-31 23:59:59" @@ -19,7 +20,7 @@ last-modified="2018-02-09 09:00:00"> </defaults> <component type="source-chopper"> - <location x="0.0" y="0.0" z="-50.6"/> + <location x="0.0" y="0.0" z="-28.9"/> </component> <type name="source-chopper"/> diff --git a/instrument/V20_4-tubes_90deg_Definition_v01.xml b/instrument/V20_4-tubes_90deg_Definition_v01.xml index f798c1ca10ba3ef246ea8d465661d3a5c2b51c94..e60b04144da4c94225646941f05b950306304906 100644 --- a/instrument/V20_4-tubes_90deg_Definition_v01.xml +++ b/instrument/V20_4-tubes_90deg_Definition_v01.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- For help on the notation used to specify an Instrument Definition File see http://www.mantidproject.org/IDF --> +<!-- IDF configurations can be gound here https://github.com/mantidproject/documents/blob/master/IDF-Configurations/V20_idf_configurations_v05.pptx --> <instrument xmlns="http://www.mantidproject.org/IDF/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 Schema/IDFSchema.xsd" name="IMAT" valid-from ="1900-01-31 23:59:59" valid-to ="2099-12-31 23:59:59" @@ -19,7 +20,7 @@ last-modified="2018-02-09 09:00:00"> </defaults> <component type="source-chopper"> - <location x="0.0" y="0.0" z="-50.6"/> + <location x="0.0" y="0.0" z="-28.9"/> </component> <type name="source-chopper"/> @@ -42,7 +43,7 @@ last-modified="2018-02-09 09:00:00"> <location x="-0.070" /> <location x="-0.035" /> <location x="0.000" /> - <location x="-0.035" /> + <location x="0.035" /> </component> </type> diff --git a/instrument/V20_Transm_BeamMonitor_Definition_v01.xml b/instrument/V20_Transm_BeamMonitor_Definition_v01.xml new file mode 100644 index 0000000000000000000000000000000000000000..9a3777c977f49c2821ab272939074eff43772bf4 --- /dev/null +++ b/instrument/V20_Transm_BeamMonitor_Definition_v01.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- For help on the notation used to specify an Instrument Definition File +see http://www.mantidproject.org/IDF --> +<!-- IDF configurations can be gound here https://github.com/mantidproject/documents/blob/master/IDF-Configurations/V20_idf_configurations_v05.pptx --> +<instrument xmlns="http://www.mantidproject.org/IDF/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 Schema/IDFSchema.xsd" +name="IMAT" valid-from ="1900-01-31 23:59:59" +valid-to ="2099-12-31 23:59:59" +last-modified="2018-02-09 09:00:00"> + <defaults> + <length unit="meter"/> + <angle unit="degree"/> + <reference-frame> + <!-- The z-axis is set parallel to and in the direction of the beam. the + y-axis points up and the coordinate system is right handed. --> + <along-beam axis="z"/> + <pointing-up axis="y"/> + <handedness val="right"/> + </reference-frame> + <default-view axis-view="z"/> + </defaults> + + <component type="source-chopper"> + <location x="0.0" y="0.0" z="-25.3"/> + </component> + <type name="source-chopper"/> + + <component type="wfm-chopper"> + <location x="0.0" y="0.0" z="-18.45"/> + </component> + <type name="wfm-chopper" is="Source" /> + + <component type="some-sample-holder"> + <location x="0.0" y="0.0" z="0"/> + </component> + <type name="some-sample-holder" is="SamplePos" /> + + <component name="transmission-beam-monitor" type="monitor" idlist="monitor-id-list"> + <location x="0.0" y="0.0" z="0.030" /> + </component> + + <type name="monitor" is="monitor"> + <cuboid id="shape"> + <left-front-bottom-point x="0.02" y="-0.0525" z="0.0" /> + <left-front-top-point x="0.02" y="-0.0525" z="0.040" /> + <left-back-bottom-point x="-0.02" y="-0.0525" z="0.0" /> + <right-front-bottom-point x="0.02" y="0.0525" z="0.0" /> + </cuboid> + </type> + + <idlist idname="monitor-id-list"> + <id val="3" /> + </idlist> + +</instrument> diff --git a/qt/CMakeLists.txt b/qt/CMakeLists.txt index 28e79e57ca2f3bf5ee139bc00793373bd40f8634..5df1efb28936b4320e15951c35aceb7fd8e4bc42 100644 --- a/qt/CMakeLists.txt +++ b/qt/CMakeLists.txt @@ -3,37 +3,6 @@ find_package ( QScintillaQt4 REQUIRED ) # Utilities for defining targets include ( QtTargetFunctions ) -# Function to create links to python packages in the source tree -# If the EXECUTABLE option is provided then it additional build rules are -# defined to ensure startup scripts are regenerated appropriately -function ( add_python_package pkg_name ) - # Create a setup.py file - set ( _setup_py ${CMAKE_CURRENT_SOURCE_DIR}/setup.py ) - set ( _egg_link_dir ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR} ) - set ( _egg_link ${_egg_link_dir}/${pkg_name}.egg-link ) - if ( ARGV0 EQUAL "EXECUTABLE" ) - if ( WIN32 ) - set ( _startup_script ${_egg_link_dir}/${pkg_name}-script.pyw ) - set ( _startup_exe ${_egg_link_dir}/${pkg_name}.exe ) - else () - set ( _startup_script ) - set ( _startup_exe ${_egg_link_dir}/${pkg_name} ) - endif () - endif () - set ( _outputs ${_egg_link} ${_startup_script} ${_startup_exe} ) - add_custom_command ( OUTPUT ${_outputs} - COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${_egg_link_dir} - ${PYTHON_EXECUTABLE} ${_setup_py} develop - --install-dir ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR} - --script-dir ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - DEPENDS ${_setup_py} - ) - add_custom_target ( ${pkg_name} ALL - DEPENDS ${_outputs} - ) -endfunction () - # Resource compiler for PyQt5 if ( ENABLE_WORKBENCH AND NOT PYRCC5_CMD ) # Newer versions of PyQt5 have a pyrcc_main python module, whereas older diff --git a/qt/applications/workbench/setup.py b/qt/applications/workbench/setup.py.in similarity index 76% rename from qt/applications/workbench/setup.py rename to qt/applications/workbench/setup.py.in index 6e3db4ad665309e688d04d56de958f5b79b2dfc1..dedef6c41ab3a5163ac374765dd40d1cdac50b42 100644 --- a/qt/applications/workbench/setup.py +++ b/qt/applications/workbench/setup.py.in @@ -16,15 +16,20 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -from setuptools import setup +from setuptools import find_packages, setup + +@SETUPTOOLS_BUILD_COMMANDS_DEF@ # The most basic setup possible to be able to use setup.py develop setup( - name="workbench", + name='MantidWorkbench', # probaly the wrong name if someone wants to include it + version='@VERSION_MAJOR@.@VERSION_MINOR@.@VERSION_PATCH@', install_requires=['mantidqt'], + packages=find_packages(exclude=['*.test']), entry_points={ 'gui_scripts': [ 'workbench = workbench.app.mainwindow:main' ] }, + @SETUPTOOLS_BUILD_COMMANDS_USE@ ) diff --git a/qt/applications/workbench/workbench/app/mainwindow.py b/qt/applications/workbench/workbench/app/mainwindow.py index 19c6f7e14d6acdf693fa91d9c4eb084aa6d4ac3e..5bc70668d16fd7e4ced0d99dc70517f87c754cd2 100644 --- a/qt/applications/workbench/workbench/app/mainwindow.py +++ b/qt/applications/workbench/workbench/app/mainwindow.py @@ -21,7 +21,9 @@ from __future__ import (absolute_import, division, print_function, unicode_literals) import atexit +import imp import importlib +import os import sys # ----------------------------------------------------------------------------- @@ -42,7 +44,7 @@ requirements.check_qt() # ----------------------------------------------------------------------------- # Qt # ----------------------------------------------------------------------------- -from qtpy.QtCore import (QEventLoop, Qt, QTimer, QCoreApplication) # noqa +from qtpy.QtCore import (QEventLoop, Qt, QCoreApplication) # noqa from qtpy.QtGui import (QColor, QPixmap) # noqa from qtpy.QtWidgets import (QApplication, QDesktopWidget, QFileDialog, QMainWindow, QSplashScreen) # noqa @@ -90,11 +92,8 @@ QApplication.processEvents(QEventLoop.AllEvents) # ----------------------------------------------------------------------------- # Utilities/Widgets # ----------------------------------------------------------------------------- -from mantidqt.py3compat import qbytearray_to_str # noqa from mantidqt.utils.qt import add_actions, create_action # noqa from mantidqt.widgets.manageuserdirectories import ManageUserDirectories # noqa -from workbench.config.main import CONF # noqa -from workbench.external.mantid import prepare_mantid_env # noqa # ----------------------------------------------------------------------------- # MainWindow @@ -413,12 +412,19 @@ def start_workbench(app): def main(): """Main entry point for the application""" - # Prepare for mantid import - prepare_mantid_env() + # Mantid needs to be able to find its .properties file. It looks + # in the application directory by default but this is + # the directory of python[.exe] and not guaranteed to be where + # the properties files is located. MANTIDPATH overrides this. + # If we allow a user to override MANTIDPATH then we could end up + # loading the wrong properties file and plugins built against + # a different version of Mantid and this would likely result in + # segfault. + _, pkgpath, _ = imp.find_module('mantid') + os.environ['MANTIDPATH'] = os.path.dirname(pkgpath) # todo: parse command arguments - # general initialization app = initialize() # the default sys check interval leads to long lags # when request scripts to be aborted diff --git a/qt/applications/workbench/workbench/external/__init__.py b/qt/applications/workbench/workbench/external/__init__.py deleted file mode 100644 index 38b6452e68f2d819b646bccff5c213e92581ea5a..0000000000000000000000000000000000000000 --- a/qt/applications/workbench/workbench/external/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# This file is part of the mantid workbench. -# -# Copyright (C) 2017 mantidproject -# -# This program 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. -# -# This program 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/>. diff --git a/qt/applications/workbench/workbench/external/mantid.py b/qt/applications/workbench/workbench/external/mantid.py deleted file mode 100644 index 39dd34eedca38d121b8d0f8b150cf1bf53e147ee..0000000000000000000000000000000000000000 --- a/qt/applications/workbench/workbench/external/mantid.py +++ /dev/null @@ -1,33 +0,0 @@ -# This file is part of the mantid workbench. -# -# Copyright (C) 2017 mantidproject -# -# This program 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. -# -# This program 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/>. -"""Defines utility functionality for interacting with the mantid framework -""" -from __future__ import unicode_literals - -from imp import find_module -import os - - -def prepare_mantid_env(): - # Mantid needs to be able to find its .properties file. It looks - # in the application directory but by default but this is python.exe. - # MANTIDPATH can be used to override this. If it is not set - # we currently assume the Mantid.properties is in the same location as the - # mantid module itself - if 'MANTIDPATH' not in os.environ: - _, pkgpath, _ = find_module('mantid') - os.environ['MANTIDPATH'] = os.path.dirname(pkgpath) diff --git a/qt/applications/workbench/workbench/plugins/test/test_jupyterconsole.py b/qt/applications/workbench/workbench/plugins/test/test_jupyterconsole.py index f1ae661e90d3e4e8d804651b025fdc944edb1f9e..ed88ea6334583c8f3310dd4e8ab1715144406709 100644 --- a/qt/applications/workbench/workbench/plugins/test/test_jupyterconsole.py +++ b/qt/applications/workbench/workbench/plugins/test/test_jupyterconsole.py @@ -20,7 +20,7 @@ from __future__ import (absolute_import) import unittest # third-party library imports -from mantidqt.utils.qt.testing import requires_qapp +from mantidqt.utils.qt.test import requires_qapp from qtpy.QtWidgets import QMainWindow # local package imports diff --git a/qt/applications/workbench/workbench/widgets/plotselector/test/test_plotselector_view.py b/qt/applications/workbench/workbench/widgets/plotselector/test/test_plotselector_view.py index fba1be352f09d0e0f51f8fdf0c53dd3f5330b992..dcb7fa8b9bc75df912e9eb9056c43934c0486a74 100644 --- a/qt/applications/workbench/workbench/widgets/plotselector/test/test_plotselector_view.py +++ b/qt/applications/workbench/workbench/widgets/plotselector/test/test_plotselector_view.py @@ -21,7 +21,7 @@ from qtpy.QtTest import QTest import qtawesome as qta -from mantidqt.utils.qt.testing import requires_qapp +from mantidqt.utils.qt.test import requires_qapp from workbench.widgets.plotselector.presenter import PlotSelectorPresenter from workbench.widgets.plotselector.view import EXPORT_TYPES, PlotSelectorView, Column diff --git a/qt/paraview_ext/VatesAlgorithms/CMakeLists.txt b/qt/paraview_ext/VatesAlgorithms/CMakeLists.txt index 5fc54adb2eeddf14972e2714d1fd9130b6818eda..8d4a794b3cb33c5f4745f254454c4de8237d6e4e 100644 --- a/qt/paraview_ext/VatesAlgorithms/CMakeLists.txt +++ b/qt/paraview_ext/VatesAlgorithms/CMakeLists.txt @@ -50,7 +50,7 @@ ${POCO_LIBRARIES} if (OSX_VERSION VERSION_GREATER 10.8) set_target_properties(VatesAlgorithms PROPERTIES INSTALL_RPATH "@loader_path/../Contents/MacOS;@loader_path/../Libraries") elseif ( ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" ) - set_target_properties(VatesAlgorithms PROPERTIES INSTALL_RPATH "\$ORIGIN/../${LIB_DIR}") + set_target_properties(VatesAlgorithms PROPERTIES INSTALL_RPATH "\$ORIGIN/../${LIB_DIR};\$ORIGIN/../${LIB_DIR}/paraview-${ParaView_VERSION_MAJOR}.${ParaView_VERSION_MINOR}") endif () # Create test file projects diff --git a/qt/python/CMakeLists.txt b/qt/python/CMakeLists.txt index 508b70e03026ca2f7cf23c5f7150a0e5a3366cea..e92c9fd5375c586af71ca8c5ad6c13d0973518db 100644 --- a/qt/python/CMakeLists.txt +++ b/qt/python/CMakeLists.txt @@ -1,6 +1,7 @@ # This file manages building/installation of the mantidqt and mantidqtpython # Python wrappers. # +include ( PythonPackageTargetFunctions ) # Legacy wrappers for MantidPlot add_subdirectory ( mantidqtpython ) @@ -20,7 +21,6 @@ if ( ENABLE_WORKBENCH ) ${CMAKE_CURRENT_SOURCE_DIR}/mantidqt/utils/qt/plugins.py ) - # Create egg link to binary output directory for mantidqt add_python_package ( mantidqt ) # Configure resources data in place for ease of development. The output diff --git a/qt/python/mantidqt/CMakeLists.txt b/qt/python/mantidqt/CMakeLists.txt index 1ec7b21fc9d2478fea791db55318cfe486266792..6ca91e85bdc9c66d88074b58a1754ab417e5c70b 100644 --- a/qt/python/mantidqt/CMakeLists.txt +++ b/qt/python/mantidqt/CMakeLists.txt @@ -2,7 +2,6 @@ include ( SipQtTargetFunctions ) set ( COMMON_INC_DIR ../../../widgets/common/inc ) set ( HEADER_DEPENDS - ${COMMON_INC_DIR}/MantidQtWidgets/Common/AlgorithmDialog.h ${COMMON_INC_DIR}/MantidQtWidgets/Common/AlgorithmDialog.h ${COMMON_INC_DIR}/MantidQtWidgets/Common/Message.h ${COMMON_INC_DIR}/MantidQtWidgets/Common/MessageDisplay.h @@ -18,7 +17,8 @@ list ( APPEND common_link_libs ${PYTHON_LIBRARIES} ) -# Wrapper module linked against Qt4 +# Wrapper module linked against Qt4 - not currently installed until required for backward compatability +# with MantidPlot mtd_add_sip_module ( MODULE_NAME _commonqt4 TARGET_NAME mantidqt_commonqt4 @@ -59,5 +59,9 @@ mtd_add_sip_module ( ${PYTHON_LIBRARIES} ${Boost_LIBRARIES} API + INSTALL_DIR + ${LIB_DIR}/mantidqt + LINUX_INSTALL_RPATH + "\$ORIGIN/.." FOLDER Qt5 ) diff --git a/qt/python/mantidqt/dialogs/test/test_algorithm_dialog.py b/qt/python/mantidqt/dialogs/test/test_algorithm_dialog.py index d5ac28bfd304a7da8221cd7fd6f590e8570d5319..3d4595a4e13d49b8e43db64031d48543e1c498ff 100644 --- a/qt/python/mantidqt/dialogs/test/test_algorithm_dialog.py +++ b/qt/python/mantidqt/dialogs/test/test_algorithm_dialog.py @@ -20,7 +20,7 @@ from qtpy.QtWidgets import QWidget, QLineEdit from mantid.api import AlgorithmManager, AlgorithmFactory, PythonAlgorithm from mantid.kernel import Direction, FloatArrayProperty -from mantidqt.utils.qt.testing import requires_qapp +from mantidqt.utils.qt.test import requires_qapp from mantidqt.dialogs.algorithmdialog import AlgorithmDialog from mantidqt.dialogs.genericdialog import GenericDialog from mantidqt.interfacemanager import InterfaceManager diff --git a/qt/python/mantidqt/dialogs/test/test_spectraselectiondialog.py b/qt/python/mantidqt/dialogs/test/test_spectraselectiondialog.py index 135614b46a41c1f39fb20cbac9d6062c3098a72d..fe899f3841ba35e7edbc38524b1b3a592c91734d 100644 --- a/qt/python/mantidqt/dialogs/test/test_spectraselectiondialog.py +++ b/qt/python/mantidqt/dialogs/test/test_spectraselectiondialog.py @@ -24,7 +24,7 @@ from mantid.simpleapi import CreateSampleWorkspace, CropWorkspace from qtpy.QtWidgets import QDialogButtonBox # local imports -from mantidqt.utils.qt.testing import requires_qapp +from mantidqt.utils.qt.test import requires_qapp from mantidqt.dialogs.spectraselectordialog import parse_selection_str, SpectraSelectionDialog diff --git a/qt/python/mantidqt/utils/qt/testing/__init__.py b/qt/python/mantidqt/utils/qt/test/__init__.py similarity index 100% rename from qt/python/mantidqt/utils/qt/testing/__init__.py rename to qt/python/mantidqt/utils/qt/test/__init__.py diff --git a/qt/python/mantidqt/utils/qt/testing/modal_tester.py b/qt/python/mantidqt/utils/qt/test/modal_tester.py similarity index 100% rename from qt/python/mantidqt/utils/qt/testing/modal_tester.py rename to qt/python/mantidqt/utils/qt/test/modal_tester.py diff --git a/qt/python/mantidqt/utils/qt/testing/run_test_app.py b/qt/python/mantidqt/utils/qt/test/run_test_app.py similarity index 100% rename from qt/python/mantidqt/utils/qt/testing/run_test_app.py rename to qt/python/mantidqt/utils/qt/test/run_test_app.py diff --git a/qt/python/mantidqt/utils/test/test_modal_tester.py b/qt/python/mantidqt/utils/test/test_modal_tester.py index 66ec5ff868b2092b947658ad327bd18462163dd3..9d68103564fd269b16e9edc55b824ea5ebd4fafc 100644 --- a/qt/python/mantidqt/utils/test/test_modal_tester.py +++ b/qt/python/mantidqt/utils/test/test_modal_tester.py @@ -22,7 +22,7 @@ import unittest from qtpy.QtWidgets import QInputDialog -from mantidqt.utils.qt.testing import requires_qapp, ModalTester +from mantidqt.utils.qt.test import requires_qapp, ModalTester @requires_qapp diff --git a/qt/python/mantidqt/utils/test/test_qt_utils.py b/qt/python/mantidqt/utils/test/test_qt_utils.py index 6e9497eaf7ed1d56aa70560cfefb4ec20a89c5e8..d1d88a021bd98dafb4538b498fb45c6b94b1f1d0 100644 --- a/qt/python/mantidqt/utils/test/test_qt_utils.py +++ b/qt/python/mantidqt/utils/test/test_qt_utils.py @@ -27,7 +27,7 @@ try: except ImportError: NEW_STYLE_SIGNAL = True -from mantidqt.utils.qt.testing import requires_qapp +from mantidqt.utils.qt.test import requires_qapp from mantidqt.utils.qt import add_actions, create_action diff --git a/qt/python/mantidqt/utils/test/test_writetosignal.py b/qt/python/mantidqt/utils/test/test_writetosignal.py index e65614158ae8ac1bb7058806cf4b7b19ca39d198..5742e465dd9acba02a5aee5d224c9a786dbcb3e9 100644 --- a/qt/python/mantidqt/utils/test/test_writetosignal.py +++ b/qt/python/mantidqt/utils/test/test_writetosignal.py @@ -23,7 +23,7 @@ import unittest from qtpy.QtCore import QCoreApplication, QObject # local imports -from mantidqt.utils.qt.testing import requires_qapp +from mantidqt.utils.qt.test import requires_qapp from mantidqt.utils.writetosignal import WriteToSignal diff --git a/qt/python/mantidqt/widgets/algorithmselector/test/test_algorithmselector.py b/qt/python/mantidqt/widgets/algorithmselector/test/test_algorithmselector.py index ae0da9bbb0a345b6e979513582c72ddab9d321f8..c346fd1266bd52a75c11d2f2206a298cd5ad8089 100644 --- a/qt/python/mantidqt/widgets/algorithmselector/test/test_algorithmselector.py +++ b/qt/python/mantidqt/widgets/algorithmselector/test/test_algorithmselector.py @@ -23,7 +23,7 @@ import unittest from qtpy.QtCore import Qt from qtpy.QtTest import QTest -from mantidqt.utils.qt.testing import requires_qapp, select_item_in_combo_box, select_item_in_tree +from mantidqt.utils.qt.test import requires_qapp, select_item_in_combo_box, select_item_in_tree from mantidqt.widgets.algorithmselector.model import AlgorithmSelectorModel from mantidqt.widgets.algorithmselector.widget import AlgorithmSelectorWidget diff --git a/qt/python/mantidqt/widgets/codeeditor/test/test_codeeditor.py b/qt/python/mantidqt/widgets/codeeditor/test/test_codeeditor.py index 933547f4e0c0de6cef74fd06ff31cc0c647a8e18..63887f2d8a8d39c8a1d810ae058b4fbfe5eee833 100644 --- a/qt/python/mantidqt/widgets/codeeditor/test/test_codeeditor.py +++ b/qt/python/mantidqt/widgets/codeeditor/test/test_codeeditor.py @@ -21,7 +21,7 @@ import unittest # local imports from mantidqt.widgets.codeeditor.editor import CodeEditor -from mantidqt.utils.qt.testing import requires_qapp +from mantidqt.utils.qt.test import requires_qapp TEST_LANG = "Python" diff --git a/qt/python/mantidqt/widgets/codeeditor/test/test_execution.py b/qt/python/mantidqt/widgets/codeeditor/test/test_execution.py index b0d6a5b7865644ca2882d7d21827ba53437ce2ab..e10529105be6e44c524b5b603224007499ea462c 100644 --- a/qt/python/mantidqt/widgets/codeeditor/test/test_execution.py +++ b/qt/python/mantidqt/widgets/codeeditor/test/test_execution.py @@ -23,7 +23,7 @@ import unittest from qtpy.QtCore import QCoreApplication, QObject # local imports -from mantidqt.utils.qt.testing import requires_qapp +from mantidqt.utils.qt.test import requires_qapp from mantidqt.widgets.codeeditor.execution import PythonCodeExecution diff --git a/qt/python/mantidqt/widgets/codeeditor/test/test_interpreter.py b/qt/python/mantidqt/widgets/codeeditor/test/test_interpreter.py index 18cfbb0d85db0bec0e740485ff0572b9750ba0c6..43956c43a5659fb2963b15b8010c2715a1329565 100644 --- a/qt/python/mantidqt/widgets/codeeditor/test/test_interpreter.py +++ b/qt/python/mantidqt/widgets/codeeditor/test/test_interpreter.py @@ -24,7 +24,7 @@ import six # local imports from mantidqt.widgets.codeeditor.interpreter import PythonFileInterpreter -from mantidqt.utils.qt.testing import requires_qapp +from mantidqt.utils.qt.test import requires_qapp if six.PY2: import mock diff --git a/qt/python/mantidqt/widgets/codeeditor/test/test_multifileinterpreter.py b/qt/python/mantidqt/widgets/codeeditor/test/test_multifileinterpreter.py index 2122b51f23169e5cdd40d11ce8fe7bc9426ba3e6..c152e31c23da4dab3d83092c5f1e8451f2b97c50 100644 --- a/qt/python/mantidqt/widgets/codeeditor/test/test_multifileinterpreter.py +++ b/qt/python/mantidqt/widgets/codeeditor/test/test_multifileinterpreter.py @@ -22,7 +22,7 @@ import unittest # third-party library imports # local imports -from mantidqt.utils.qt.testing import requires_qapp +from mantidqt.utils.qt.test import requires_qapp from mantidqt.widgets.codeeditor.multifileinterpreter import MultiPythonFileInterpreter diff --git a/qt/python/mantidqt/widgets/test/test_jupyterconsole.py b/qt/python/mantidqt/widgets/test/test_jupyterconsole.py index b102633b5c92652eb504ccb9f5c5a09dce04a367..c13e8e3c877e1843b54e57fae112bb60eb4b09cf 100644 --- a/qt/python/mantidqt/widgets/test/test_jupyterconsole.py +++ b/qt/python/mantidqt/widgets/test/test_jupyterconsole.py @@ -26,7 +26,7 @@ from qtpy import QT_VERSION # local package imports from mantidqt.widgets.jupyterconsole import InProcessJupyterConsole -from mantidqt.utils.qt.testing import requires_qapp +from mantidqt.utils.qt.test import requires_qapp PRE_IPY5_PY3_QT5 = (sys.version_info.major == 3 and IPython.version_info[0] < 5 and int(QT_VERSION[0]) == 5) diff --git a/qt/python/mantidqt/widgets/test/test_messagedisplay.py b/qt/python/mantidqt/widgets/test/test_messagedisplay.py index 01a2fc1287d9ef0367e118ce9a69ebe7ca346757..665d73c88c00d3c3026ec0cfc86196af4b5e82f6 100644 --- a/qt/python/mantidqt/widgets/test/test_messagedisplay.py +++ b/qt/python/mantidqt/widgets/test/test_messagedisplay.py @@ -20,7 +20,7 @@ from __future__ import (absolute_import, division, print_function, import unittest from mantidqt.widgets.messagedisplay import MessageDisplay -from mantidqt.utils.qt.testing import requires_qapp +from mantidqt.utils.qt.test import requires_qapp @requires_qapp diff --git a/qt/python/mantidqt/widgets/workspacewidget/test/test_workspacetreewidget.py b/qt/python/mantidqt/widgets/workspacewidget/test/test_workspacetreewidget.py index c58f0c263fc8320d25b9cd3ba5303a9e8f2b3158..bcd52c80976fb17b152005878e17cc4fbbf190c1 100644 --- a/qt/python/mantidqt/widgets/workspacewidget/test/test_workspacetreewidget.py +++ b/qt/python/mantidqt/widgets/workspacewidget/test/test_workspacetreewidget.py @@ -19,7 +19,7 @@ from __future__ import absolute_import, print_function import unittest from mantidqt.widgets.workspacewidget.workspacetreewidget import WorkspaceTreeWidget -from mantidqt.utils.qt.testing import requires_qapp +from mantidqt.utils.qt.test import requires_qapp @requires_qapp diff --git a/qt/python/mantidqt/widgets/workspacewidget/workspacetreewidget.py b/qt/python/mantidqt/widgets/workspacewidget/workspacetreewidget.py index f8fee5faa670f553f8595f478f3c8bcfede1c4c5..fbb7909906199c03ac31c44a3635f487a6f71d2f 100644 --- a/qt/python/mantidqt/widgets/workspacewidget/workspacetreewidget.py +++ b/qt/python/mantidqt/widgets/workspacewidget/workspacetreewidget.py @@ -24,5 +24,5 @@ from __future__ import (absolute_import, unicode_literals) from mantidqt.utils.qt import import_qt -WorkspaceTreeWidget = import_qt('.._common', 'mantidqt.widgets.workspacewidget', +WorkspaceTreeWidget = import_qt('..._common', 'mantidqt.widgets.workspacewidget', 'WorkspaceTreeWidgetSimple') diff --git a/qt/python/setup.py b/qt/python/setup.py.in similarity index 70% rename from qt/python/setup.py rename to qt/python/setup.py.in index bdfe7f9bd16f6f1e16d2ca037f09879741805526..12ed9d606069c5e990b1b74048429d6fd1ddb27d 100644 --- a/qt/python/setup.py +++ b/qt/python/setup.py.in @@ -16,9 +16,15 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -from setuptools import setup +from setuptools import find_packages, setup + +@SETUPTOOLS_BUILD_COMMANDS_DEF@ # The most basic setup possible to be able to use setup.py develop setup( - name="mantidqt", + name='mantidqt', # must match what is required by workbench setup.py + version='@VERSION_MAJOR@.@VERSION_MINOR@.@VERSION_PATCH@', + packages=find_packages(exclude=['*.test']), + package_data={'mantidqt': ['dialogs/*.ui']}, + @SETUPTOOLS_BUILD_COMMANDS_USE@ ) diff --git a/qt/widgets/common/CMakeLists.txt b/qt/widgets/common/CMakeLists.txt index 58323bb8d146747ce0b1eea469939e39b426d508..2783cc5b2400bd7457126257969078b2630873fe 100644 --- a/qt/widgets/common/CMakeLists.txt +++ b/qt/widgets/common/CMakeLists.txt @@ -531,6 +531,8 @@ mtd_add_qt_library (TARGET_NAME MantidQtWidgetsCommon Qt5::PrintSupport ${_webwidgets_tgt} Qt5::Qscintilla + INSTALL_DIR + ${LIB_DIR} OSX_INSTALL_RPATH @loader_path/../MacOS @loader_path/../Libraries diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index 0f583c6c95b0ba88d3cea7047475cd80335176e9..243dc4aadce2c2c5c95eb00867e97a8cc128cd1f 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -872,7 +872,6 @@ void MuonFitPropertyBrowser::showEvent(QShowEvent *e) { * @param ws :: The workspace */ bool MuonFitPropertyBrowser::isWorkspaceValid(Workspace_sptr ws) const { - auto fsad = ws->getName(); QString workspaceName(QString::fromStdString(ws->getName())); if ((workspaceName.contains("_Raw")) || @@ -944,6 +943,11 @@ void MuonFitPropertyBrowser::finishHandleTF(const IAlgorithm *alg) { std::vector<std::string> wsList = alg->getProperty("UnNormalizedWorkspaceList"); emit fittingDone(QString::fromStdString(wsList[0])); + double quality = alg->getProperty("ChiSquared"); + // std::string costFunction = + + emit changeWindowTitle(QString("Fit Function (") + "Chi-sq " + " = " + + QString::number(quality) + ", " + status + ")"); if (nWorkspaces == 1) { emit algorithmFinished(QString::fromStdString(wsList[0] + "_workspace")); } @@ -1170,7 +1174,7 @@ void MuonFitPropertyBrowser::ConvertFitFunctionForMuonTFAsymmetry( boost::dynamic_pointer_cast<IFunction>(m_compositeFunction); QStringList globals; - if (enabled && m_isMultiFittingMode) { + if (m_isMultiFittingMode) { // manually set the function values old = m_functionBrowser->getGlobalFunction(); globals = m_functionBrowser->getGlobalParameters(); diff --git a/qt/widgets/factory/CMakeLists.txt b/qt/widgets/factory/CMakeLists.txt index 1f6dd12c4dd5f92a61183efd198fe9f8f009c656..be29eaa80bbf78bafb8fd38dcf5315a5bfe24b1b 100644 --- a/qt/widgets/factory/CMakeLists.txt +++ b/qt/widgets/factory/CMakeLists.txt @@ -6,11 +6,11 @@ set ( INC_FILES inc/MantidQtWidgets/Factory/WidgetFactory.h ) -set ( MOC_FILES +set ( MOC_FILES inc/MantidQtWidgets/Factory/WidgetFactory.h ) -set ( UI_FILES +set ( UI_FILES ) set ( TEST_FILES @@ -37,7 +37,8 @@ mtd_add_qt_library (TARGET_NAME MantidQtWidgetsFactory MantidQtWidgetsCommon MantidQtWidgetsLegacyQwt MantidQtWidgetsSliceViewer + INSTALL_DIR + ${LIB_DIR} LINUX_INSTALL_RPATH "\$ORIGIN/../${LIB_DIR}" ) - diff --git a/qt/widgets/instrumentview/CMakeLists.txt b/qt/widgets/instrumentview/CMakeLists.txt index a0573d09f7853c4e3fac66650aecb7591d17e045..e63d30c9986470a3c20b27e65682038b098c6534 100644 --- a/qt/widgets/instrumentview/CMakeLists.txt +++ b/qt/widgets/instrumentview/CMakeLists.txt @@ -135,10 +135,11 @@ mtd_add_qt_library (TARGET_NAME MantidQtWidgetsInstrumentView MTD_QT_LINK_LIBS MantidQtWidgetsCommon MantidQtWidgetsLegacyQwt + INSTALL_DIR + ${LIB_DIR} + OSX_INSTALL_RPATH + @loader_path/../MacOS + @loader_path/../Libraries + LINUX_INSTALL_RPATH + "\$ORIGIN/../${LIB_DIR}" ) - -if (OSX_VERSION VERSION_GREATER 10.8) - set_target_properties(MantidQtWidgetsInstrumentViewQt4 PROPERTIES INSTALL_RPATH "@loader_path/../MacOS;@loader_path/../Libraries") -elseif ( ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" ) - set_target_properties(MantidQtWidgetsInstrumentViewQt4 PROPERTIES INSTALL_RPATH "\$ORIGIN/../${LIB_DIR}") -endif () diff --git a/qt/widgets/legacyqwt/CMakeLists.txt b/qt/widgets/legacyqwt/CMakeLists.txt index 004a0271725b9273dc9f2c10eb9ff12b3d7d49fa..d2014997a426d7489ccd0b6ba24417b41fb93768 100644 --- a/qt/widgets/legacyqwt/CMakeLists.txt +++ b/qt/widgets/legacyqwt/CMakeLists.txt @@ -77,6 +77,8 @@ mtd_add_qt_library (TARGET_NAME MantidQtWidgetsLegacyQwt Qwt5 MTD_QT_LINK_LIBS MantidQtWidgetsCommon + INSTALL_DIR + ${LIB_DIR} OSX_INSTALL_RPATH @loader_path/../MacOS LINUX_INSTALL_RPATH diff --git a/qt/widgets/refdetectorview/CMakeLists.txt b/qt/widgets/refdetectorview/CMakeLists.txt index e0f806beb037465e0332b81c78721d8cc9d769e8..2d651511e4ff97ebe1b796c514aad3f57e99f6dc 100644 --- a/qt/widgets/refdetectorview/CMakeLists.txt +++ b/qt/widgets/refdetectorview/CMakeLists.txt @@ -50,14 +50,14 @@ mtd_add_qt_library (TARGET_NAME MantidQtWidgetsRefDetectorView Qwt5 MTD_QT_LINK_LIBS MantidQtWidgetsSpectrumViewer + INSTALL_DIR + ${LIB_DIR} + OSX_INSTALL_RPATH + @loader_path/../MacOS + LINUX_INSTALL_RPATH + "\$ORIGIN/../${LIB_DIR}" ) -if (OSX_VERSION VERSION_GREATER 10.8) - set_target_properties( MantidQtWidgetsRefDetectorViewQt4 PROPERTIES INSTALL_RPATH "@loader_path/../MacOS") -elseif ( ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" ) - set_target_properties( MantidQtWidgetsRefDetectorViewQt4 PROPERTIES INSTALL_RPATH "\$ORIGIN/../${LIB_DIR}") -endif () - ########################################################################### # DEMO/GUI TESTING APPLICATIONS ########################################################################### diff --git a/qt/widgets/sliceviewer/CMakeLists.txt b/qt/widgets/sliceviewer/CMakeLists.txt index 3473c45eddebfbe39d90627bd6f1b78a7ed6fd7f..97fe4355fa4b8b60918c1bd932e04dbacc89063e 100644 --- a/qt/widgets/sliceviewer/CMakeLists.txt +++ b/qt/widgets/sliceviewer/CMakeLists.txt @@ -138,6 +138,8 @@ mtd_add_qt_library (TARGET_NAME MantidQtWidgetsSliceViewer MTD_QT_LINK_LIBS MantidQtWidgetsCommon MantidQtWidgetsLegacyQwt + INSTALL_DIR + ${LIB_DIR} OSX_INSTALL_RPATH loader_path/../MacOS LINUX_INSTALL_RPATH diff --git a/qt/widgets/spectrumviewer/CMakeLists.txt b/qt/widgets/spectrumviewer/CMakeLists.txt index 233088f1c7a150dfbf97d02d72335167420906f2..29f1e5638fa6335f628f8b73c36376285d81bd93 100644 --- a/qt/widgets/spectrumviewer/CMakeLists.txt +++ b/qt/widgets/spectrumviewer/CMakeLists.txt @@ -74,6 +74,8 @@ mtd_add_qt_library (TARGET_NAME MantidQtWidgetsSpectrumViewer MTD_QT_LINK_LIBS MantidQtWidgetsCommon MantidQtWidgetsLegacyQwt + INSTALL_DIR + ${LIB_DIR} ) if (OSX_VERSION VERSION_GREATER 10.8) diff --git a/scripts/Diffraction/isis_powder/gem_routines/gem_algs.py b/scripts/Diffraction/isis_powder/gem_routines/gem_algs.py index ae6db76614fd6b86141e3848441d29d4273c90e8..4c18c8f528206ba1dca0877b8230e56bab29ef6c 100644 --- a/scripts/Diffraction/isis_powder/gem_routines/gem_algs.py +++ b/scripts/Diffraction/isis_powder/gem_routines/gem_algs.py @@ -3,8 +3,7 @@ from __future__ import (absolute_import, division, print_function) import mantid.simpleapi as mantid from isis_powder.routines import absorb_corrections, common -from isis_powder.routines.run_details import create_run_details_object, \ - RunDetailsWrappedCommonFuncs, CustomFuncForRunDetails +from isis_powder.routines.run_details import create_run_details_object, get_cal_mapping_dict from isis_powder.gem_routines import gem_advanced_config @@ -20,32 +19,31 @@ def calculate_van_absorb_corrections(ws_to_correct, multiple_scattering, is_vana return ws_to_correct -def gem_get_chopper_config(forwarded_value, inst_settings): - # Forwarded value should be a cal mapping - cal_mapping = forwarded_value - return common.cal_map_dictionary_key_helper(cal_mapping, inst_settings.mode) - - def get_run_details(run_number_string, inst_settings, is_vanadium_run): - cal_mapping_callable = CustomFuncForRunDetails().add_to_func_chain( - user_function=RunDetailsWrappedCommonFuncs.get_cal_mapping_dict, run_number_string=run_number_string, - inst_settings=inst_settings - ).add_to_func_chain(user_function=gem_get_chopper_config, inst_settings=inst_settings) - # Get empty and vanadium - err_message = "this must be under the relevant Rietveld or PDF mode." - empty_run_callable = cal_mapping_callable.add_to_func_chain( - user_function=RunDetailsWrappedCommonFuncs.cal_dictionary_key_helper, key="empty_run_numbers", - append_to_error_message=err_message) + mode_run_numbers = _get_current_mode_dictionary(run_number_string, inst_settings) + + empty_runs = _get_run_numbers_for_key(current_mode_run_numbers=mode_run_numbers, key="empty_run_numbers") + vanadium_runs = _get_run_numbers_for_key(current_mode_run_numbers=mode_run_numbers, key="vanadium_run_numbers") - vanadium_run_callable = cal_mapping_callable.add_to_func_chain( - user_function=RunDetailsWrappedCommonFuncs.cal_dictionary_key_helper, key="vanadium_run_numbers", - append_to_error_message=err_message) + grouping_file_name = inst_settings.grouping_file_name return create_run_details_object(run_number_string=run_number_string, inst_settings=inst_settings, - is_vanadium_run=is_vanadium_run, empty_run_call=empty_run_callable, - vanadium_run_call=vanadium_run_callable) + is_vanadium_run=is_vanadium_run, empty_run_number=empty_runs, + grouping_file_name=grouping_file_name, vanadium_string=vanadium_runs) + + +def _get_run_numbers_for_key(current_mode_run_numbers, key): + err_message = "this must be under the relevant Rietveld or PDF mode." + return common.cal_map_dictionary_key_helper(current_mode_run_numbers, key=key, + append_to_error_message=err_message) + + +def _get_current_mode_dictionary(run_number_string, inst_settings): + mapping_dict = get_cal_mapping_dict(run_number_string, inst_settings.cal_mapping_path) + # Get the current mode "Rietveld" or "PDF" run numbers + return common.cal_map_dictionary_key_helper(mapping_dict, inst_settings.mode) def save_maud(d_spacing_group, output_path): diff --git a/scripts/Diffraction/isis_powder/hrpd_routines/Examples/Calibration/16_5/hrpd_new_072_01_corr.cal b/scripts/Diffraction/isis_powder/hrpd_routines/Examples/Calibration/16_5/hrpd_new_072_01_corr.cal new file mode 100644 index 0000000000000000000000000000000000000000..6fa7738b58539b2a7f8fc98ef6504e0341d2ec45 --- /dev/null +++ b/scripts/Diffraction/isis_powder/hrpd_routines/Examples/Calibration/16_5/hrpd_new_072_01_corr.cal @@ -0,0 +1,2780 @@ +# Ariel detector file, written Sat Nov 24 16:52:56 2007 +# Format: number UDET offset select group + 0 1100 0.0000000 0 1 + 1 1101 0.0000000 0 1 + 2 1102 0.0000000 0 1 + 3 1103 0.0000000 0 1 + 4 1104 0.0000000 0 1 + 5 1105 0.0000000 0 1 + 6 1106 0.0000000 0 1 + 7 1107 0.0000000 0 1 + 8 1108 0.0000000 0 1 + 9 1109 0.0000000 0 1 + 10 1110 0.0000000 0 1 + 11 1111 0.0000000 0 1 + 12 1112 0.0000000 0 1 + 13 1113 0.0000000 0 1 + 14 1114 0.0000000 0 1 + 15 1115 0.0000000 0 1 + 16 1116 0.0000000 0 1 + 17 1117 0.0000000 0 1 + 18 1118 0.0000000 0 1 + 19 1119 0.0000000 0 1 + 20 1120 0.0000000 0 1 + 21 1121 0.0000000 0 1 + 22 1122 0.0000000 0 1 + 23 1123 0.0000000 0 1 + 24 1124 0.0000000 0 1 + 25 1125 0.0000000 0 1 + 26 1126 0.0000000 0 1 + 27 1127 0.0000000 0 1 + 28 1128 0.0000000 0 1 + 29 1129 0.0000000 0 1 + 30 1130 0.0000000 0 1 + 31 1131 0.0000000 0 1 + 32 1132 0.0000000 0 1 + 33 1133 0.0000000 0 1 + 34 1134 0.0000000 0 1 + 35 1135 0.0000000 0 1 + 36 1136 0.0000000 0 1 + 37 1137 0.0000000 0 1 + 38 1138 0.0000000 0 1 + 39 1139 0.0000000 0 1 + 40 1140 0.0000000 0 1 + 41 1141 0.0000000 0 1 + 42 1142 0.0000000 0 1 + 43 1143 0.0000000 0 1 + 44 1144 0.0000000 0 1 + 45 1145 0.0000000 0 1 + 46 1146 0.0000000 0 1 + 47 1147 0.0000000 0 1 + 48 1148 0.0000000 0 1 + 49 1149 0.0000000 0 1 + 50 1150 0.0000000 0 1 + 51 1151 0.0000000 0 1 + 52 1152 0.0000000 0 1 + 53 1153 0.0000000 0 1 + 54 1154 0.0000000 0 1 + 55 1155 0.0000000 0 1 + 56 1156 0.0000000 0 1 + 57 1157 0.0000000 0 1 + 58 1158 0.0000000 0 1 + 59 1159 0.0000000 0 1 + 60 1160 0.0000000 0 1 + 61 1161 0.0000000 0 1 + 62 1162 0.0000000 0 1 + 63 1163 0.0000000 0 1 + 64 1164 0.0000000 0 1 + 65 1165 0.0000000 0 1 + 66 1166 0.0000000 0 1 + 67 1167 0.0000000 0 1 + 68 1168 0.0000000 0 1 + 69 1169 0.0000000 0 1 + 70 1170 0.0000000 0 1 + 71 1171 0.0000000 0 1 + 72 1172 0.0000000 0 1 + 73 1173 0.0000000 0 1 + 74 1174 0.0000000 0 1 + 75 1175 0.0000000 0 1 + 76 1176 0.0000000 0 1 + 77 1177 0.0000000 0 1 + 78 1178 0.0000000 0 1 + 79 1179 0.0000000 0 1 + 80 1180 0.0000000 0 1 + 81 1181 0.0000000 0 1 + 82 1182 0.0000000 0 1 + 83 1183 0.0000000 0 1 + 84 1184 0.0000000 0 1 + 85 1185 0.0000000 0 1 + 86 1186 0.0000000 0 1 + 87 1187 0.0000000 0 1 + 88 1188 0.0000000 0 1 + 89 1189 0.0000000 0 1 + 90 1190 0.0000000 0 1 + 91 1191 0.0000000 0 1 + 92 1192 0.0000000 0 1 + 93 1193 0.0000000 0 1 + 94 1194 0.0000000 0 1 + 95 1195 0.0000000 0 1 + 96 1196 0.0000000 0 1 + 97 1197 0.0000000 0 1 + 98 1198 0.0000000 0 1 + 99 1199 0.0000000 0 1 + 100 1200 0.0000000 0 1 + 101 1201 0.0000000 0 1 + 102 1202 0.0000000 0 1 + 103 1203 0.0000000 0 1 + 104 1204 0.0000000 0 1 + 105 1205 0.0000000 0 1 + 106 1206 0.0000000 0 1 + 107 1207 0.0000000 0 1 + 108 1208 0.0000000 0 1 + 109 1209 0.0000000 0 1 + 110 1210 0.0000000 0 1 + 111 1211 0.0000000 0 1 + 112 1212 0.0000000 0 1 + 113 1213 0.0000000 0 1 + 114 1214 0.0000000 0 1 + 115 1215 0.0000000 0 1 + 116 1216 0.0000000 0 1 + 117 1217 0.0000000 0 1 + 118 1218 0.0000000 0 1 + 119 1219 0.0000000 0 1 + 120 1220 0.0000000 0 1 + 121 1221 0.0000000 0 1 + 122 1222 0.0000000 0 1 + 123 1223 0.0000000 0 1 + 124 1224 0.0000000 0 1 + 125 1225 0.0000000 0 1 + 126 1226 0.0000000 0 1 + 127 1227 0.0000000 0 1 + 128 2100 0.0000000 0 1 + 129 2101 0.0000000 0 1 + 130 2102 0.0000161 1 1 + 131 2103 -0.0000139 1 1 + 132 2104 0.0001156 1 1 + 133 2105 0.0001294 1 1 + 134 2106 0.0002665 1 1 + 135 2107 0.0001922 1 1 + 136 2108 0.0001922 1 1 + 137 2109 0.0003095 1 1 + 138 2110 0.0003095 1 1 + 139 2111 0.0003039 1 1 + 140 2112 0.0003039 1 1 + 141 2113 0.0004182 1 1 + 142 2114 0.0004182 1 1 + 143 2115 0.0004080 1 1 + 144 2116 0.0004080 1 1 + 145 2117 0.0005247 1 1 + 146 2118 0.0005247 1 1 + 147 2119 0.0005014 1 1 + 148 2120 0.0005014 1 1 + 149 2121 0.0006162 1 1 + 150 2122 0.0006162 1 1 + 151 2123 0.0005947 1 1 + 152 2124 0.0005947 1 1 + 153 2125 0.0007070 1 1 + 154 2126 0.0007070 1 1 + 155 2127 0.0006847 1 1 + 156 2128 0.0006847 1 1 + 157 2129 0.0007974 1 1 + 158 2130 0.0007974 1 1 + 159 2131 0.0007927 1 1 + 160 2132 0.0007927 1 1 + 161 2133 0.0009075 1 1 + 162 2134 0.0009075 1 1 + 163 2135 0.0008940 1 1 + 164 2136 0.0008940 1 1 + 165 2137 0.0010187 1 1 + 166 2138 0.0010187 1 1 + 167 2139 0.0010151 1 1 + 168 2140 0.0010151 1 1 + 169 2141 0.0011360 1 1 + 170 2142 0.0011360 1 1 + 171 2143 0.0011349 1 1 + 172 2144 0.0011349 1 1 + 173 2145 0.0012556 1 1 + 174 2146 0.0012556 1 1 + 175 2147 0.0012609 1 1 + 176 2148 0.0012609 1 1 + 177 2149 0.0013878 1 1 + 178 2150 0.0013878 1 1 + 179 2151 0.0013908 1 1 + 180 2152 0.0013908 1 1 + 181 2153 0.0015181 1 1 + 182 2154 0.0015181 1 1 + 183 2155 0.0015310 1 1 + 184 2156 0.0015310 1 1 + 185 2157 0.0016659 1 1 + 186 2158 0.0016659 1 1 + 187 2159 0.0016707 1 1 + 188 2160 0.0016707 1 1 + 189 2161 0.0018101 1 1 + 190 2162 0.0018101 1 1 + 191 2163 0.0018154 1 1 + 192 2164 0.0018154 1 1 + 193 2165 0.0019505 1 1 + 194 2166 0.0019505 1 1 + 195 2167 0.0019682 1 1 + 196 2168 0.0019682 1 1 + 197 2169 0.0021005 1 1 + 198 2170 0.0021005 1 1 + 199 2171 0.0021203 1 1 + 200 2172 0.0021203 1 1 + 201 2173 0.0022603 1 1 + 202 2174 0.0022603 1 1 + 203 2175 0.0022824 1 1 + 204 2176 0.0022824 1 1 + 205 2177 0.0024297 1 1 + 206 2178 0.0024297 1 1 + 207 2179 0.0024609 1 1 + 208 2180 0.0024609 1 1 + 209 2181 0.0026038 1 1 + 210 2182 0.0026038 1 1 + 211 2183 0.0026364 1 1 + 212 2184 0.0026364 1 1 + 213 2185 0.0027874 1 1 + 214 2186 0.0027874 1 1 + 215 2187 0.0028215 1 1 + 216 2188 0.0028215 1 1 + 217 2189 0.0029767 1 1 + 218 2190 0.0029767 1 1 + 219 2191 0.0030203 1 1 + 220 2192 0.0030203 1 1 + 221 2193 0.0031762 1 1 + 222 2194 0.0031762 1 1 + 223 2195 0.0032049 1 1 + 224 2196 0.0032049 1 1 + 225 2197 0.0033555 1 1 + 226 2198 0.0033555 1 1 + 227 2199 0.0034055 1 1 + 228 2200 0.0034055 1 1 + 229 2201 0.0035574 1 1 + 230 2202 0.0035574 1 1 + 231 2203 0.0036128 1 1 + 232 2204 0.0036128 1 1 + 233 2205 0.0037786 1 1 + 234 2206 0.0037786 1 1 + 235 2207 0.0038282 1 1 + 236 2208 0.0038282 1 1 + 237 2209 0.0039876 1 1 + 238 2210 0.0039876 1 1 + 239 2211 0.0040535 1 1 + 240 2212 0.0040535 1 1 + 241 2213 0.0042063 1 1 + 242 2214 0.0042063 1 1 + 243 2215 0.0041808 1 1 + 244 2216 0.0041808 1 1 + 245 2217 0.0000000 0 1 + 246 2218 0.0000000 0 1 + 247 2219 0.0000000 0 1 + 248 2220 0.0000000 0 1 + 249 2221 0.0000000 0 1 + 250 2222 0.0000000 0 1 + 251 2223 0.0000000 0 1 + 252 2224 0.0000000 0 1 + 253 2225 0.0000000 0 1 + 254 2226 0.0000000 0 1 + 255 2227 0.0000000 0 1 + 256 3100 0.0000000 0 1 + 257 3101 0.0000000 0 1 + 258 3102 0.0000161 1 1 + 259 3103 -0.0000139 1 1 + 260 3104 0.0001156 1 1 + 261 3105 0.0001294 1 1 + 262 3106 0.0002665 1 1 + 263 3107 0.0001922 1 1 + 264 3108 0.0001922 1 1 + 265 3109 0.0003095 1 1 + 266 3110 0.0003095 1 1 + 267 3111 0.0003039 1 1 + 268 3112 0.0003039 1 1 + 269 3113 0.0004182 1 1 + 270 3114 0.0004182 1 1 + 271 3115 0.0004080 1 1 + 272 3116 0.0004080 1 1 + 273 3117 0.0005247 1 1 + 274 3118 0.0005247 1 1 + 275 3119 0.0005014 1 1 + 276 3120 0.0005014 1 1 + 277 3121 0.0006162 1 1 + 278 3122 0.0006162 1 1 + 279 3123 0.0005947 1 1 + 280 3124 0.0005947 1 1 + 281 3125 0.0007070 1 1 + 282 3126 0.0007070 1 1 + 283 3127 0.0006847 1 1 + 284 3128 0.0006847 1 1 + 285 3129 0.0007974 1 1 + 286 3130 0.0007974 1 1 + 287 3131 0.0007927 1 1 + 288 3132 0.0007927 1 1 + 289 3133 0.0009075 1 1 + 290 3134 0.0009075 1 1 + 291 3135 0.0008940 1 1 + 292 3136 0.0008940 1 1 + 293 3137 0.0010187 1 1 + 294 3138 0.0010187 1 1 + 295 3139 0.0010151 1 1 + 296 3140 0.0010151 1 1 + 297 3141 0.0011360 1 1 + 298 3142 0.0011360 1 1 + 299 3143 0.0011349 1 1 + 300 3144 0.0011349 1 1 + 301 3145 0.0012556 1 1 + 302 3146 0.0012556 1 1 + 303 3147 0.0012609 1 1 + 304 3148 0.0012609 1 1 + 305 3149 0.0013878 1 1 + 306 3150 0.0013878 1 1 + 307 3151 0.0013908 1 1 + 308 3152 0.0013908 1 1 + 309 3153 0.0015181 1 1 + 310 3154 0.0015181 1 1 + 311 3155 0.0015310 1 1 + 312 3156 0.0015310 1 1 + 313 3157 0.0016659 1 1 + 314 3158 0.0016659 1 1 + 315 3159 0.0016707 1 1 + 316 3160 0.0016707 1 1 + 317 3161 0.0018101 1 1 + 318 3162 0.0018101 1 1 + 319 3163 0.0018154 1 1 + 320 3164 0.0018154 1 1 + 321 3165 0.0019505 1 1 + 322 3166 0.0019505 1 1 + 323 3167 0.0019682 1 1 + 324 3168 0.0019682 1 1 + 325 3169 0.0021005 1 1 + 326 3170 0.0021005 1 1 + 327 3171 0.0021203 1 1 + 328 3172 0.0021203 1 1 + 329 3173 0.0022603 1 1 + 330 3174 0.0022603 1 1 + 331 3175 0.0022824 1 1 + 332 3176 0.0022824 1 1 + 333 3177 0.0024297 1 1 + 334 3178 0.0024297 1 1 + 335 3179 0.0024609 1 1 + 336 3180 0.0024609 1 1 + 337 3181 0.0026038 1 1 + 338 3182 0.0026038 1 1 + 339 3183 0.0026364 1 1 + 340 3184 0.0026364 1 1 + 341 3185 0.0027874 1 1 + 342 3186 0.0027874 1 1 + 343 3187 0.0028215 1 1 + 344 3188 0.0028215 1 1 + 345 3189 0.0029767 1 1 + 346 3190 0.0029767 1 1 + 347 3191 0.0030203 1 1 + 348 3192 0.0030203 1 1 + 349 3193 0.0031762 1 1 + 350 3194 0.0031762 1 1 + 351 3195 0.0032049 1 1 + 352 3196 0.0032049 1 1 + 353 3197 0.0033555 1 1 + 354 3198 0.0033555 1 1 + 355 3199 0.0034055 1 1 + 356 3200 0.0034055 1 1 + 357 3201 0.0035574 1 1 + 358 3202 0.0035574 1 1 + 359 3203 0.0036128 1 1 + 360 3204 0.0036128 1 1 + 361 3205 0.0037786 1 1 + 362 3206 0.0037786 1 1 + 363 3207 0.0038282 1 1 + 364 3208 0.0038282 1 1 + 365 3209 0.0039876 1 1 + 366 3210 0.0039876 1 1 + 367 3211 0.0040535 1 1 + 368 3212 0.0040535 1 1 + 369 3213 0.0042063 1 1 + 370 3214 0.0042063 1 1 + 371 3215 0.0041808 1 1 + 372 3216 0.0041808 1 1 + 373 3217 0.0000000 0 1 + 374 3218 0.0000000 0 1 + 375 3219 0.0000000 0 1 + 376 3220 0.0000000 0 1 + 377 3221 0.0000000 0 1 + 378 3222 0.0000000 0 1 + 379 3223 0.0000000 0 1 + 380 3224 0.0000000 0 1 + 381 3225 0.0000000 0 1 + 382 3226 0.0000000 0 1 + 383 3227 0.0000000 0 1 + 384 4100 0.0000000 0 1 + 385 4101 0.0000000 0 1 + 386 4102 0.0000161 1 1 + 387 4103 -0.0000139 1 1 + 388 4104 0.0001156 1 1 + 389 4105 0.0001294 1 1 + 390 4106 0.0002665 1 1 + 391 4107 0.0001922 1 1 + 392 4108 0.0001922 1 1 + 393 4109 0.0003095 1 1 + 394 4110 0.0003095 1 1 + 395 4111 0.0003039 1 1 + 396 4112 0.0003039 1 1 + 397 4113 0.0004182 1 1 + 398 4114 0.0004182 1 1 + 399 4115 0.0004080 1 1 + 400 4116 0.0004080 1 1 + 401 4117 0.0005247 1 1 + 402 4118 0.0005247 1 1 + 403 4119 0.0005014 1 1 + 404 4120 0.0005014 1 1 + 405 4121 0.0006162 1 1 + 406 4122 0.0006162 1 1 + 407 4123 0.0005947 1 1 + 408 4124 0.0005947 1 1 + 409 4125 0.0007070 1 1 + 410 4126 0.0007070 1 1 + 411 4127 0.0006847 1 1 + 412 4128 0.0006847 1 1 + 413 4129 0.0007974 1 1 + 414 4130 0.0007974 1 1 + 415 4131 0.0007927 1 1 + 416 4132 0.0007927 1 1 + 417 4133 0.0009075 1 1 + 418 4134 0.0009075 1 1 + 419 4135 0.0008940 1 1 + 420 4136 0.0008940 1 1 + 421 4137 0.0010187 1 1 + 422 4138 0.0010187 1 1 + 423 4139 0.0010151 1 1 + 424 4140 0.0010151 1 1 + 425 4141 0.0011360 1 1 + 426 4142 0.0011360 1 1 + 427 4143 0.0011349 1 1 + 428 4144 0.0011349 1 1 + 429 4145 0.0012556 1 1 + 430 4146 0.0012556 1 1 + 431 4147 0.0012609 1 1 + 432 4148 0.0012609 1 1 + 433 4149 0.0013878 1 1 + 434 4150 0.0013878 1 1 + 435 4151 0.0013908 1 1 + 436 4152 0.0013908 1 1 + 437 4153 0.0015181 1 1 + 438 4154 0.0015181 1 1 + 439 4155 0.0015310 1 1 + 440 4156 0.0015310 1 1 + 441 4157 0.0016659 1 1 + 442 4158 0.0016659 1 1 + 443 4159 0.0016707 1 1 + 444 4160 0.0016707 1 1 + 445 4161 0.0018101 1 1 + 446 4162 0.0018101 1 1 + 447 4163 0.0018154 1 1 + 448 4164 0.0018154 1 1 + 449 4165 0.0019505 1 1 + 450 4166 0.0019505 1 1 + 451 4167 0.0019682 1 1 + 452 4168 0.0019682 1 1 + 453 4169 0.0021005 1 1 + 454 4170 0.0021005 1 1 + 455 4171 0.0021203 1 1 + 456 4172 0.0021203 1 1 + 457 4173 0.0022603 1 1 + 458 4174 0.0022603 1 1 + 459 4175 0.0022824 1 1 + 460 4176 0.0022824 1 1 + 461 4177 0.0024297 1 1 + 462 4178 0.0024297 1 1 + 463 4179 0.0024609 1 1 + 464 4180 0.0024609 1 1 + 465 4181 0.0026038 1 1 + 466 4182 0.0026038 1 1 + 467 4183 0.0026364 1 1 + 468 4184 0.0026364 1 1 + 469 4185 0.0027874 1 1 + 470 4186 0.0027874 1 1 + 471 4187 0.0028215 1 1 + 472 4188 0.0028215 1 1 + 473 4189 0.0029767 1 1 + 474 4190 0.0029767 1 1 + 475 4191 0.0030203 1 1 + 476 4192 0.0030203 1 1 + 477 4193 0.0031762 1 1 + 478 4194 0.0031762 1 1 + 479 4195 0.0032049 1 1 + 480 4196 0.0032049 1 1 + 481 4197 0.0033555 1 1 + 482 4198 0.0033555 1 1 + 483 4199 0.0034055 1 1 + 484 4200 0.0034055 1 1 + 485 4201 0.0035574 1 1 + 486 4202 0.0035574 1 1 + 487 4203 0.0036128 1 1 + 488 4204 0.0036128 1 1 + 489 4205 0.0037786 1 1 + 490 4206 0.0037786 1 1 + 491 4207 0.0038282 1 1 + 492 4208 0.0038282 1 1 + 493 4209 0.0039876 1 1 + 494 4210 0.0039876 1 1 + 495 4211 0.0040535 1 1 + 496 4212 0.0040535 1 1 + 497 4213 0.0042063 1 1 + 498 4214 0.0042063 1 1 + 499 4215 0.0041808 1 1 + 500 4216 0.0041808 1 1 + 501 4217 0.0000000 0 1 + 502 4218 0.0000000 0 1 + 503 4219 0.0000000 0 1 + 504 4220 0.0000000 0 1 + 505 4221 0.0000000 0 1 + 506 4222 0.0000000 0 1 + 507 4223 0.0000000 0 1 + 508 4224 0.0000000 0 1 + 509 4225 0.0000000 0 1 + 510 4226 0.0000000 0 1 + 511 4227 0.0000000 0 1 + 512 5100 0.0000000 0 1 + 513 5101 0.0000000 0 1 + 514 5102 0.0000000 0 1 + 515 5103 0.0000000 0 1 + 516 5104 0.0000000 0 1 + 517 5105 0.0000000 0 1 + 518 5106 0.0000000 0 1 + 519 5107 0.0000000 0 1 + 520 5108 0.0000000 0 1 + 521 5109 0.0000000 0 1 + 522 5110 0.0000000 0 1 + 523 5111 0.0000000 0 1 + 524 5112 0.0000000 0 1 + 525 5113 0.0000000 0 1 + 526 5114 0.0000000 0 1 + 527 5115 0.0000000 0 1 + 528 5116 0.0000000 0 1 + 529 5117 0.0000000 0 1 + 530 5118 0.0000000 0 1 + 531 5119 0.0000000 0 1 + 532 5120 0.0000000 0 1 + 533 5121 0.0000000 0 1 + 534 5122 0.0000000 0 1 + 535 5123 0.0000000 0 1 + 536 5124 0.0000000 0 1 + 537 5125 0.0000000 0 1 + 538 5126 0.0000000 0 1 + 539 5127 0.0000000 0 1 + 540 5128 0.0000000 0 1 + 541 5129 0.0000000 0 1 + 542 5130 0.0000000 0 1 + 543 5131 0.0000000 0 1 + 544 5132 0.0000000 0 1 + 545 5133 0.0000000 0 1 + 546 5134 0.0000000 0 1 + 547 5135 0.0000000 0 1 + 548 5136 0.0000000 0 1 + 549 5137 0.0000000 0 1 + 550 5138 0.0000000 0 1 + 551 5139 0.0000000 0 1 + 552 5140 0.0000000 0 1 + 553 5141 0.0000000 0 1 + 554 5142 0.0000000 0 1 + 555 5143 0.0000000 0 1 + 556 5144 0.0000000 0 1 + 557 5145 0.0000000 0 1 + 558 5146 0.0000000 0 1 + 559 5147 0.0000000 0 1 + 560 5148 0.0000000 0 1 + 561 5149 0.0000000 0 1 + 562 5150 0.0000000 0 1 + 563 5151 0.0000000 0 1 + 564 5152 0.0000000 0 1 + 565 5153 0.0000000 0 1 + 566 5154 0.0000000 0 1 + 567 5155 0.0000000 0 1 + 568 5156 0.0000000 0 1 + 569 5157 0.0000000 0 1 + 570 5158 0.0000000 0 1 + 571 5159 0.0000000 0 1 + 572 5160 0.0000000 0 1 + 573 5161 0.0000000 0 1 + 574 5162 0.0000000 0 1 + 575 5163 0.0000000 0 1 + 576 5164 0.0000000 0 1 + 577 5165 0.0000000 0 1 + 578 5166 0.0000000 0 1 + 579 5167 0.0000000 0 1 + 580 5168 0.0000000 0 1 + 581 5169 0.0000000 0 1 + 582 5170 0.0000000 0 1 + 583 5171 0.0000000 0 1 + 584 5172 0.0000000 0 1 + 585 5173 0.0000000 0 1 + 586 5174 0.0000000 0 1 + 587 5175 0.0000000 0 1 + 588 5176 0.0000000 0 1 + 589 5177 0.0000000 0 1 + 590 5178 0.0000000 0 1 + 591 5179 0.0000000 0 1 + 592 5180 0.0000000 0 1 + 593 5181 0.0000000 0 1 + 594 5182 0.0000000 0 1 + 595 5183 0.0000000 0 1 + 596 5184 0.0000000 0 1 + 597 5185 0.0000000 0 1 + 598 5186 0.0000000 0 1 + 599 5187 0.0000000 0 1 + 600 5188 0.0000000 0 1 + 601 5189 0.0000000 0 1 + 602 5190 0.0000000 0 1 + 603 5191 0.0000000 0 1 + 604 5192 0.0000000 0 1 + 605 5193 0.0000000 0 1 + 606 5194 0.0000000 0 1 + 607 5195 0.0000000 0 1 + 608 5196 0.0000000 0 1 + 609 5197 0.0000000 0 1 + 610 5198 0.0000000 0 1 + 611 5199 0.0000000 0 1 + 612 5200 0.0000000 0 1 + 613 5201 0.0000000 0 1 + 614 5202 0.0000000 0 1 + 615 5203 0.0000000 0 1 + 616 5204 0.0000000 0 1 + 617 5205 0.0000000 0 1 + 618 5206 0.0000000 0 1 + 619 5207 0.0000000 0 1 + 620 5208 0.0000000 0 1 + 621 5209 0.0000000 0 1 + 622 5210 0.0000000 0 1 + 623 5211 0.0000000 0 1 + 624 5212 0.0000000 0 1 + 625 5213 0.0000000 0 1 + 626 5214 0.0000000 0 1 + 627 5215 0.0000000 0 1 + 628 5216 0.0000000 0 1 + 629 5217 0.0000000 0 1 + 630 5218 0.0000000 0 1 + 631 5219 0.0000000 0 1 + 632 5220 0.0000000 0 1 + 633 5221 0.0000000 0 1 + 634 5222 0.0000000 0 1 + 635 5223 0.0000000 0 1 + 636 5224 0.0000000 0 1 + 637 5225 0.0000000 0 1 + 638 5226 0.0000000 0 1 + 639 5227 0.0000000 0 1 + 640 6100 0.0000000 0 1 + 641 6101 0.0000000 0 1 + 642 6102 0.0000161 1 1 + 643 6103 -0.0000139 1 1 + 644 6104 0.0001156 1 1 + 645 6105 0.0001294 1 1 + 646 6106 0.0002665 1 1 + 647 6107 0.0001922 1 1 + 648 6108 0.0001922 1 1 + 649 6109 0.0003095 1 1 + 650 6110 0.0003095 1 1 + 651 6111 0.0003039 1 1 + 652 6112 0.0003039 1 1 + 653 6113 0.0004182 1 1 + 654 6114 0.0004182 1 1 + 655 6115 0.0004080 1 1 + 656 6116 0.0004080 1 1 + 657 6117 0.0005247 1 1 + 658 6118 0.0005247 1 1 + 659 6119 0.0005014 1 1 + 660 6120 0.0005014 1 1 + 661 6121 0.0006162 1 1 + 662 6122 0.0006162 1 1 + 663 6123 0.0005947 1 1 + 664 6124 0.0005947 1 1 + 665 6125 0.0007070 1 1 + 666 6126 0.0007070 1 1 + 667 6127 0.0006847 1 1 + 668 6128 0.0006847 1 1 + 669 6129 0.0007974 1 1 + 670 6130 0.0007974 1 1 + 671 6131 0.0007927 1 1 + 672 6132 0.0007927 1 1 + 673 6133 0.0009075 1 1 + 674 6134 0.0009075 1 1 + 675 6135 0.0008940 1 1 + 676 6136 0.0008940 1 1 + 677 6137 0.0010187 1 1 + 678 6138 0.0010187 1 1 + 679 6139 0.0010151 1 1 + 680 6140 0.0010151 1 1 + 681 6141 0.0011360 1 1 + 682 6142 0.0011360 1 1 + 683 6143 0.0011349 1 1 + 684 6144 0.0011349 1 1 + 685 6145 0.0012556 1 1 + 686 6146 0.0012556 1 1 + 687 6147 0.0012609 1 1 + 688 6148 0.0012609 1 1 + 689 6149 0.0013878 1 1 + 690 6150 0.0013878 1 1 + 691 6151 0.0013908 1 1 + 692 6152 0.0013908 1 1 + 693 6153 0.0015181 1 1 + 694 6154 0.0015181 1 1 + 695 6155 0.0015310 1 1 + 696 6156 0.0015310 1 1 + 697 6157 0.0016659 1 1 + 698 6158 0.0016659 1 1 + 699 6159 0.0016707 1 1 + 700 6160 0.0016707 1 1 + 701 6161 0.0018101 1 1 + 702 6162 0.0018101 1 1 + 703 6163 0.0018154 1 1 + 704 6164 0.0018154 1 1 + 705 6165 0.0019505 1 1 + 706 6166 0.0019505 1 1 + 707 6167 0.0019682 1 1 + 708 6168 0.0019682 1 1 + 709 6169 0.0021005 1 1 + 710 6170 0.0021005 1 1 + 711 6171 0.0021203 1 1 + 712 6172 0.0021203 1 1 + 713 6173 0.0022603 1 1 + 714 6174 0.0022603 1 1 + 715 6175 0.0022824 1 1 + 716 6176 0.0022824 1 1 + 717 6177 0.0024297 1 1 + 718 6178 0.0024297 1 1 + 719 6179 0.0024609 1 1 + 720 6180 0.0024609 1 1 + 721 6181 0.0026038 1 1 + 722 6182 0.0026038 1 1 + 723 6183 0.0026364 1 1 + 724 6184 0.0026364 1 1 + 725 6185 0.0027874 1 1 + 726 6186 0.0027874 1 1 + 727 6187 0.0028215 1 1 + 728 6188 0.0028215 1 1 + 729 6189 0.0029767 1 1 + 730 6190 0.0029767 1 1 + 731 6191 0.0030203 1 1 + 732 6192 0.0030203 1 1 + 733 6193 0.0031762 1 1 + 734 6194 0.0031762 1 1 + 735 6195 0.0032049 1 1 + 736 6196 0.0032049 1 1 + 737 6197 0.0033555 1 1 + 738 6198 0.0033555 1 1 + 739 6199 0.0034055 1 1 + 740 6200 0.0034055 1 1 + 741 6201 0.0035574 1 1 + 742 6202 0.0035574 1 1 + 743 6203 0.0036128 1 1 + 744 6204 0.0036128 1 1 + 745 6205 0.0037786 1 1 + 746 6206 0.0037786 1 1 + 747 6207 0.0038282 1 1 + 748 6208 0.0038282 1 1 + 749 6209 0.0039876 1 1 + 750 6210 0.0039876 1 1 + 751 6211 0.0040535 1 1 + 752 6212 0.0040535 1 1 + 753 6213 0.0042063 1 1 + 754 6214 0.0042063 1 1 + 755 6215 0.0041808 1 1 + 756 6216 0.0041808 1 1 + 757 6217 0.0000000 0 1 + 758 6218 0.0000000 0 1 + 759 6219 0.0000000 0 1 + 760 6220 0.0000000 0 1 + 761 6221 0.0000000 0 1 + 762 6222 0.0000000 0 1 + 763 6223 0.0000000 0 1 + 764 6224 0.0000000 0 1 + 765 6225 0.0000000 0 1 + 766 6226 0.0000000 0 1 + 767 6227 0.0000000 0 1 + 768 7100 0.0000000 0 1 + 769 7101 0.0000000 0 1 + 770 7102 0.0000161 1 1 + 771 7103 -0.0000139 1 1 + 772 7104 0.0001156 1 1 + 773 7105 0.0001294 1 1 + 774 7106 0.0002665 1 1 + 775 7107 0.0001922 1 1 + 776 7108 0.0001922 1 1 + 777 7109 0.0003095 1 1 + 778 7110 0.0003095 1 1 + 779 7111 0.0003039 1 1 + 780 7112 0.0003039 1 1 + 781 7113 0.0004182 1 1 + 782 7114 0.0004182 1 1 + 783 7115 0.0004080 1 1 + 784 7116 0.0004080 1 1 + 785 7117 0.0005247 1 1 + 786 7118 0.0005247 1 1 + 787 7119 0.0005014 1 1 + 788 7120 0.0005014 1 1 + 789 7121 0.0006162 1 1 + 790 7122 0.0006162 1 1 + 791 7123 0.0005947 1 1 + 792 7124 0.0005947 1 1 + 793 7125 0.0007070 1 1 + 794 7126 0.0007070 1 1 + 795 7127 0.0006847 1 1 + 796 7128 0.0006847 1 1 + 797 7129 0.0007974 1 1 + 798 7130 0.0007974 1 1 + 799 7131 0.0007927 1 1 + 800 7132 0.0007927 1 1 + 801 7133 0.0009075 1 1 + 802 7134 0.0009075 1 1 + 803 7135 0.0008940 1 1 + 804 7136 0.0008940 1 1 + 805 7137 0.0010187 1 1 + 806 7138 0.0010187 1 1 + 807 7139 0.0010151 1 1 + 808 7140 0.0010151 1 1 + 809 7141 0.0011360 1 1 + 810 7142 0.0011360 1 1 + 811 7143 0.0011349 1 1 + 812 7144 0.0011349 1 1 + 813 7145 0.0012556 1 1 + 814 7146 0.0012556 1 1 + 815 7147 0.0012609 1 1 + 816 7148 0.0012609 1 1 + 817 7149 0.0013878 1 1 + 818 7150 0.0013878 1 1 + 819 7151 0.0013908 1 1 + 820 7152 0.0013908 1 1 + 821 7153 0.0015181 1 1 + 822 7154 0.0015181 1 1 + 823 7155 0.0015310 1 1 + 824 7156 0.0015310 1 1 + 825 7157 0.0016659 1 1 + 826 7158 0.0016659 1 1 + 827 7159 0.0016707 1 1 + 828 7160 0.0016707 1 1 + 829 7161 0.0018101 1 1 + 830 7162 0.0018101 1 1 + 831 7163 0.0018154 1 1 + 832 7164 0.0018154 1 1 + 833 7165 0.0019505 1 1 + 834 7166 0.0019505 1 1 + 835 7167 0.0019682 1 1 + 836 7168 0.0019682 1 1 + 837 7169 0.0021005 1 1 + 838 7170 0.0021005 1 1 + 839 7171 0.0021203 1 1 + 840 7172 0.0021203 1 1 + 841 7173 0.0022603 1 1 + 842 7174 0.0022603 1 1 + 843 7175 0.0022824 1 1 + 844 7176 0.0022824 1 1 + 845 7177 0.0024297 1 1 + 846 7178 0.0024297 1 1 + 847 7179 0.0024609 1 1 + 848 7180 0.0024609 1 1 + 849 7181 0.0026038 1 1 + 850 7182 0.0026038 1 1 + 851 7183 0.0026364 1 1 + 852 7184 0.0026364 1 1 + 853 7185 0.0027874 1 1 + 854 7186 0.0027874 1 1 + 855 7187 0.0028215 1 1 + 856 7188 0.0028215 1 1 + 857 7189 0.0029767 1 1 + 858 7190 0.0029767 1 1 + 859 7191 0.0030203 1 1 + 860 7192 0.0030203 1 1 + 861 7193 0.0031762 1 1 + 862 7194 0.0031762 1 1 + 863 7195 0.0032049 1 1 + 864 7196 0.0032049 1 1 + 865 7197 0.0033555 1 1 + 866 7198 0.0033555 1 1 + 867 7199 0.0034055 1 1 + 868 7200 0.0034055 1 1 + 869 7201 0.0035574 1 1 + 870 7202 0.0035574 1 1 + 871 7203 0.0036128 1 1 + 872 7204 0.0036128 1 1 + 873 7205 0.0037786 1 1 + 874 7206 0.0037786 1 1 + 875 7207 0.0038282 1 1 + 876 7208 0.0038282 1 1 + 877 7209 0.0039876 1 1 + 878 7210 0.0039876 1 1 + 879 7211 0.0040535 1 1 + 880 7212 0.0040535 1 1 + 881 7213 0.0042063 1 1 + 882 7214 0.0042063 1 1 + 883 7215 0.0041808 1 1 + 884 7216 0.0041808 1 1 + 885 7217 0.0000000 0 1 + 886 7218 0.0000000 0 1 + 887 7219 0.0000000 0 1 + 888 7220 0.0000000 0 1 + 889 7221 0.0000000 0 1 + 890 7222 0.0000000 0 1 + 891 7223 0.0000000 0 1 + 892 7224 0.0000000 0 1 + 893 7225 0.0000000 0 1 + 894 7226 0.0000000 0 1 + 895 7227 0.0000000 0 1 + 896 8100 0.0000000 0 1 + 897 8101 0.0000000 0 1 + 898 8102 0.0000161 1 1 + 899 8103 -0.0000139 1 1 + 900 8104 0.0001156 1 1 + 901 8105 0.0001294 1 1 + 902 8106 0.0002665 1 1 + 903 8107 0.0001922 1 1 + 904 8108 0.0001922 1 1 + 905 8109 0.0003095 1 1 + 906 8110 0.0003095 1 1 + 907 8111 0.0003039 1 1 + 908 8112 0.0003039 1 1 + 909 8113 0.0004182 1 1 + 910 8114 0.0004182 1 1 + 911 8115 0.0004080 1 1 + 912 8116 0.0004080 1 1 + 913 8117 0.0005247 1 1 + 914 8118 0.0005247 1 1 + 915 8119 0.0005014 1 1 + 916 8120 0.0005014 1 1 + 917 8121 0.0006162 1 1 + 918 8122 0.0006162 1 1 + 919 8123 0.0005947 1 1 + 920 8124 0.0005947 1 1 + 921 8125 0.0007070 1 1 + 922 8126 0.0007070 1 1 + 923 8127 0.0006847 1 1 + 924 8128 0.0006847 1 1 + 925 8129 0.0007974 1 1 + 926 8130 0.0007974 1 1 + 927 8131 0.0007927 1 1 + 928 8132 0.0007927 1 1 + 929 8133 0.0009075 1 1 + 930 8134 0.0009075 1 1 + 931 8135 0.0008940 1 1 + 932 8136 0.0008940 1 1 + 933 8137 0.0010187 1 1 + 934 8138 0.0010187 1 1 + 935 8139 0.0010151 1 1 + 936 8140 0.0010151 1 1 + 937 8141 0.0011360 1 1 + 938 8142 0.0011360 1 1 + 939 8143 0.0011349 1 1 + 940 8144 0.0011349 1 1 + 941 8145 0.0012556 1 1 + 942 8146 0.0012556 1 1 + 943 8147 0.0012609 1 1 + 944 8148 0.0012609 1 1 + 945 8149 0.0013878 1 1 + 946 8150 0.0013878 1 1 + 947 8151 0.0013908 1 1 + 948 8152 0.0013908 1 1 + 949 8153 0.0015181 1 1 + 950 8154 0.0015181 1 1 + 951 8155 0.0015310 1 1 + 952 8156 0.0015310 1 1 + 953 8157 0.0016659 1 1 + 954 8158 0.0016659 1 1 + 955 8159 0.0016707 1 1 + 956 8160 0.0016707 1 1 + 957 8161 0.0018101 1 1 + 958 8162 0.0018101 1 1 + 959 8163 0.0018154 1 1 + 960 8164 0.0018154 1 1 + 961 8165 0.0019505 1 1 + 962 8166 0.0019505 1 1 + 963 8167 0.0019682 1 1 + 964 8168 0.0019682 1 1 + 965 8169 0.0021005 1 1 + 966 8170 0.0021005 1 1 + 967 8171 0.0021203 1 1 + 968 8172 0.0021203 1 1 + 969 8173 0.0022603 1 1 + 970 8174 0.0022603 1 1 + 971 8175 0.0022824 1 1 + 972 8176 0.0022824 1 1 + 973 8177 0.0024297 1 1 + 974 8178 0.0024297 1 1 + 975 8179 0.0024609 1 1 + 976 8180 0.0024609 1 1 + 977 8181 0.0026038 1 1 + 978 8182 0.0026038 1 1 + 979 8183 0.0026364 1 1 + 980 8184 0.0026364 1 1 + 981 8185 0.0027874 1 1 + 982 8186 0.0027874 1 1 + 983 8187 0.0028215 1 1 + 984 8188 0.0028215 1 1 + 985 8189 0.0029767 1 1 + 986 8190 0.0029767 1 1 + 987 8191 0.0030203 1 1 + 988 8192 0.0030203 1 1 + 989 8193 0.0031762 1 1 + 990 8194 0.0031762 1 1 + 991 8195 0.0032049 1 1 + 992 8196 0.0032049 1 1 + 993 8197 0.0033555 1 1 + 994 8198 0.0033555 1 1 + 995 8199 0.0034055 1 1 + 996 8200 0.0034055 1 1 + 997 8201 0.0035574 1 1 + 998 8202 0.0035574 1 1 + 999 8203 0.0036128 1 1 + 1000 8204 0.0036128 1 1 + 1001 8205 0.0037786 1 1 + 1002 8206 0.0037786 1 1 + 1003 8207 0.0038282 1 1 + 1004 8208 0.0038282 1 1 + 1005 8209 0.0039876 1 1 + 1006 8210 0.0039876 1 1 + 1007 8211 0.0040535 1 1 + 1008 8212 0.0040535 1 1 + 1009 8213 0.0042063 1 1 + 1010 8214 0.0042063 1 1 + 1011 8215 0.0041808 1 1 + 1012 8216 0.0041808 1 1 + 1013 8217 0.0000000 0 1 + 1014 8218 0.0000000 0 1 + 1015 8219 0.0000000 0 1 + 1016 8220 0.0000000 0 1 + 1017 8221 0.0000000 0 1 + 1018 8222 0.0000000 0 1 + 1019 8223 0.0000000 0 1 + 1020 8224 0.0000000 0 1 + 1021 8225 0.0000000 0 1 + 1022 8226 0.0000000 0 1 + 1023 8227 0.0000000 0 1 + 1024 1001 0.0000000 1 0 + 1025 1002 0.0000000 1 0 + 1026 901000 0.0000000 0 2 + 1027 901001 0.0000000 0 2 + 1028 901002 0.0000000 0 2 + 1029 901003 0.0000000 0 2 + 1030 901004 0.0000000 0 2 + 1031 901005 0.0000000 0 2 + 1032 901006 0.0000000 0 2 + 1033 901007 0.0022486 1 2 + 1034 901008 0.0022273 1 2 + 1035 901009 0.0022462 1 2 + 1036 901010 0.0021854 1 2 + 1037 901011 0.0022457 1 2 + 1038 901012 0.0021593 1 2 + 1039 901013 0.0022211 1 2 + 1040 901014 0.0021513 1 2 + 1041 901015 0.0021885 1 2 + 1042 901016 0.0020993 1 2 + 1043 901017 0.0021661 1 2 + 1044 901018 0.0020462 1 2 + 1045 901019 0.0000000 0 2 + 1046 901020 0.0020236 1 2 + 1047 901021 0.0019770 1 2 + 1048 901022 0.0019817 1 2 + 1049 901023 0.0020584 1 2 + 1050 901024 0.0019922 1 2 + 1051 901025 0.0020410 1 2 + 1052 901026 0.0019241 1 2 + 1053 901027 0.0019624 1 2 + 1054 901028 0.0018643 1 2 + 1055 901029 0.0018939 1 2 + 1056 901030 0.0018352 1 2 + 1057 901031 0.0019177 1 2 + 1058 901032 0.0000000 0 2 + 1059 901033 0.0018605 1 2 + 1060 901034 0.0018476 1 2 + 1061 901035 0.0018287 1 2 + 1062 901036 0.0017540 1 2 + 1063 901037 0.0018020 1 2 + 1064 901038 0.0016889 1 2 + 1065 901039 0.0017606 1 2 + 1066 901040 0.0016948 1 2 + 1067 901041 0.0017184 1 2 + 1068 901042 0.0016261 1 2 + 1069 901043 0.0016629 1 2 + 1070 901044 0.0000000 0 2 + 1071 901045 0.0016676 1 2 + 1072 901046 0.0013772 1 2 + 1073 901047 0.0016006 1 2 + 1074 901048 0.0015382 1 2 + 1075 901049 0.0016176 1 2 + 1076 901050 0.0015127 1 2 + 1077 901051 0.0015834 1 2 + 1078 901052 0.0014696 1 2 + 1079 901053 0.0015254 1 2 + 1080 901054 0.0014474 1 2 + 1081 901055 0.0000000 0 2 + 1082 901056 0.0014321 1 2 + 1083 901057 0.0014370 1 2 + 1084 901058 0.0013876 1 2 + 1085 901059 0.0014307 1 2 + 1086 901060 0.0013450 1 2 + 1087 901061 0.0013833 1 2 + 1088 901062 0.0012971 1 2 + 1089 901063 0.0013459 1 2 + 1090 901064 0.0012596 1 2 + 1091 901065 0.0013146 1 2 + 1092 901066 0.0000000 0 2 + 1093 901067 0.0000000 0 2 + 1094 901068 0.0000000 0 2 + 1095 901069 0.0000000 0 2 + 1096 901070 0.0000000 0 2 + 1097 901071 0.0000000 0 2 + 1098 901072 0.0000000 0 2 + 1099 901073 0.0000000 0 2 + 1100 901074 0.0000000 0 2 + 1101 901075 0.0000000 0 2 + 1102 901076 0.0007140 1 2 + 1103 901077 0.0011524 1 2 + 1104 901078 0.0010672 1 2 + 1105 901079 0.0011550 1 2 + 1106 901080 0.0010681 1 2 + 1107 901081 0.0011141 1 2 + 1108 901082 0.0010259 1 2 + 1109 901083 0.0010745 1 2 + 1110 901084 0.0010038 1 2 + 1111 901085 0.0010211 1 2 + 1112 901086 0.0009552 1 2 + 1113 901087 0.0009692 1 2 + 1114 901088 0.0009291 1 2 + 1115 901089 0.0009166 1 2 + 1116 901090 0.0009318 1 2 + 1117 901091 0.0009520 1 2 + 1118 901092 0.0008833 1 2 + 1119 901093 0.0009466 1 2 + 1120 901094 0.0008382 1 2 + 1121 901095 0.0008896 1 2 + 1122 901096 0.0008141 1 2 + 1123 901097 0.0009025 1 2 + 1124 901098 0.0007935 1 2 + 1125 901099 0.0008507 1 2 + 1126 901100 0.0007731 1 2 + 1127 901101 0.0008290 1 2 + 1128 901102 0.0007683 1 2 + 1129 901103 0.0008275 1 2 + 1130 901104 0.0007196 1 2 + 1131 901105 0.0007890 1 2 + 1132 901106 0.0006939 1 2 + 1133 901107 0.0007512 1 2 + 1134 901108 0.0006808 1 2 + 1135 901109 0.0007359 1 2 + 1136 901110 0.0006437 1 2 + 1137 901111 0.0006973 1 2 + 1138 901112 0.0006210 1 2 + 1139 901113 0.0006858 1 2 + 1140 901114 0.0005868 1 2 + 1141 901115 0.0006558 1 2 + 1142 901116 0.0005743 1 2 + 1143 901117 0.0006885 1 2 + 1144 901118 0.0009516 1 2 + 1145 901119 0.0016927 1 2 + 1146 902000 0.0000000 0 2 + 1147 902001 0.0000000 0 2 + 1148 902002 0.0000000 0 2 + 1149 902003 0.0000000 0 2 + 1150 902004 0.0000000 0 2 + 1151 902005 0.0000000 0 2 + 1152 902006 0.0000000 0 2 + 1153 902007 0.0022486 1 2 + 1154 902008 0.0022273 1 2 + 1155 902009 0.0022462 1 2 + 1156 902010 0.0021854 1 2 + 1157 902011 0.0022457 1 2 + 1158 902012 0.0021593 1 2 + 1159 902013 0.0022211 1 2 + 1160 902014 0.0021513 1 2 + 1161 902015 0.0021885 1 2 + 1162 902016 0.0020993 1 2 + 1163 902017 0.0021661 1 2 + 1164 902018 0.0020462 1 2 + 1165 902019 0.0000000 0 2 + 1166 902020 0.0020236 1 2 + 1167 902021 0.0019770 1 2 + 1168 902022 0.0019817 1 2 + 1169 902023 0.0020584 1 2 + 1170 902024 0.0019922 1 2 + 1171 902025 0.0020410 1 2 + 1172 902026 0.0019241 1 2 + 1173 902027 0.0019624 1 2 + 1174 902028 0.0018643 1 2 + 1175 902029 0.0018939 1 2 + 1176 902030 0.0018352 1 2 + 1177 902031 0.0019177 1 2 + 1178 902032 0.0000000 0 2 + 1179 902033 0.0018605 1 2 + 1180 902034 0.0018476 1 2 + 1181 902035 0.0018287 1 2 + 1182 902036 0.0017540 1 2 + 1183 902037 0.0018020 1 2 + 1184 902038 0.0016889 1 2 + 1185 902039 0.0017606 1 2 + 1186 902040 0.0016948 1 2 + 1187 902041 0.0017184 1 2 + 1188 902042 0.0016261 1 2 + 1189 902043 0.0016629 1 2 + 1190 902044 0.0000000 0 2 + 1191 902045 0.0016676 1 2 + 1192 902046 0.0013772 1 2 + 1193 902047 0.0016006 1 2 + 1194 902048 0.0015382 1 2 + 1195 902049 0.0016176 1 2 + 1196 902050 0.0015127 1 2 + 1197 902051 0.0015834 1 2 + 1198 902052 0.0014696 1 2 + 1199 902053 0.0015254 1 2 + 1200 902054 0.0014474 1 2 + 1201 902055 0.0000000 0 2 + 1202 902056 0.0014321 1 2 + 1203 902057 0.0014370 1 2 + 1204 902058 0.0013876 1 2 + 1205 902059 0.0014307 1 2 + 1206 902060 0.0013450 1 2 + 1207 902061 0.0013833 1 2 + 1208 902062 0.0012971 1 2 + 1209 902063 0.0013459 1 2 + 1210 902064 0.0012596 1 2 + 1211 902065 0.0013146 1 2 + 1212 902066 0.0000000 0 2 + 1213 902067 0.0000000 0 2 + 1214 902068 0.0000000 0 2 + 1215 902069 0.0000000 0 2 + 1216 902070 0.0000000 0 2 + 1217 902071 0.0000000 0 2 + 1218 902072 0.0000000 0 2 + 1219 902073 0.0000000 0 2 + 1220 902074 0.0000000 0 2 + 1221 902075 0.0000000 0 2 + 1222 902076 0.0007140 1 2 + 1223 902077 0.0011524 1 2 + 1224 902078 0.0010672 1 2 + 1225 902079 0.0011550 1 2 + 1226 902080 0.0010681 1 2 + 1227 902081 0.0011141 1 2 + 1228 902082 0.0010259 1 2 + 1229 902083 0.0010745 1 2 + 1230 902084 0.0010038 1 2 + 1231 902085 0.0010211 1 2 + 1232 902086 0.0009552 1 2 + 1233 902087 0.0009692 1 2 + 1234 902088 0.0009291 1 2 + 1235 902089 0.0009166 1 2 + 1236 902090 0.0009318 1 2 + 1237 902091 0.0009520 1 2 + 1238 902092 0.0008833 1 2 + 1239 902093 0.0009466 1 2 + 1240 902094 0.0008382 1 2 + 1241 902095 0.0008896 1 2 + 1242 902096 0.0008141 1 2 + 1243 902097 0.0009025 1 2 + 1244 902098 0.0007935 1 2 + 1245 902099 0.0008507 1 2 + 1246 902100 0.0007731 1 2 + 1247 902101 0.0008290 1 2 + 1248 902102 0.0007683 1 2 + 1249 902103 0.0008275 1 2 + 1250 902104 0.0007196 1 2 + 1251 902105 0.0007890 1 2 + 1252 902106 0.0006939 1 2 + 1253 902107 0.0007512 1 2 + 1254 902108 0.0006808 1 2 + 1255 902109 0.0007359 1 2 + 1256 902110 0.0006437 1 2 + 1257 902111 0.0006973 1 2 + 1258 902112 0.0006210 1 2 + 1259 902113 0.0006858 1 2 + 1260 902114 0.0005868 1 2 + 1261 902115 0.0006558 1 2 + 1262 902116 0.0005743 1 2 + 1263 902117 0.0006885 1 2 + 1264 902118 0.0009516 1 2 + 1265 902119 0.0016927 1 2 + 1266 903000 0.0000000 0 2 + 1267 903001 0.0000000 0 2 + 1268 903002 0.0000000 0 2 + 1269 903003 0.0000000 0 2 + 1270 903004 0.0000000 0 2 + 1271 903005 0.0000000 0 2 + 1272 903006 0.0000000 0 2 + 1273 903007 0.0022486 1 2 + 1274 903008 0.0022273 1 2 + 1275 903009 0.0022462 1 2 + 1276 903010 0.0021854 1 2 + 1277 903011 0.0022457 1 2 + 1278 903012 0.0021593 1 2 + 1279 903013 0.0022211 1 2 + 1280 903014 0.0021513 1 2 + 1281 903015 0.0021885 1 2 + 1282 903016 0.0020993 1 2 + 1283 903017 0.0021661 1 2 + 1284 903018 0.0020462 1 2 + 1285 903019 0.0000000 0 2 + 1286 903020 0.0020236 1 2 + 1287 903021 0.0019770 1 2 + 1288 903022 0.0019817 1 2 + 1289 903023 0.0020584 1 2 + 1290 903024 0.0019922 1 2 + 1291 903025 0.0020410 1 2 + 1292 903026 0.0019241 1 2 + 1293 903027 0.0019624 1 2 + 1294 903028 0.0018643 1 2 + 1295 903029 0.0018939 1 2 + 1296 903030 0.0018352 1 2 + 1297 903031 0.0019177 1 2 + 1298 903032 0.0000000 0 2 + 1299 903033 0.0018605 1 2 + 1300 903034 0.0018476 1 2 + 1301 903035 0.0018287 1 2 + 1302 903036 0.0017540 1 2 + 1303 903037 0.0018020 1 2 + 1304 903038 0.0016889 1 2 + 1305 903039 0.0017606 1 2 + 1306 903040 0.0016948 1 2 + 1307 903041 0.0017184 1 2 + 1308 903042 0.0016261 1 2 + 1309 903043 0.0016629 1 2 + 1310 903044 0.0000000 0 2 + 1311 903045 0.0016676 1 2 + 1312 903046 0.0013772 1 2 + 1313 903047 0.0016006 1 2 + 1314 903048 0.0015382 1 2 + 1315 903049 0.0016176 1 2 + 1316 903050 0.0015127 1 2 + 1317 903051 0.0015834 1 2 + 1318 903052 0.0014696 1 2 + 1319 903053 0.0015254 1 2 + 1320 903054 0.0014474 1 2 + 1321 903055 0.0000000 0 2 + 1322 903056 0.0014321 1 2 + 1323 903057 0.0014370 1 2 + 1324 903058 0.0013876 1 2 + 1325 903059 0.0014307 1 2 + 1326 903060 0.0013450 1 2 + 1327 903061 0.0013833 1 2 + 1328 903062 0.0012971 1 2 + 1329 903063 0.0013459 1 2 + 1330 903064 0.0012596 1 2 + 1331 903065 0.0013146 1 2 + 1332 903066 0.0000000 0 2 + 1333 903067 0.0000000 0 2 + 1334 903068 0.0000000 0 2 + 1335 903069 0.0000000 0 2 + 1336 903070 0.0000000 0 2 + 1337 903071 0.0000000 0 2 + 1338 903072 0.0000000 0 2 + 1339 903073 0.0000000 0 2 + 1340 903074 0.0000000 0 2 + 1341 903075 0.0000000 0 2 + 1342 903076 0.0007140 1 2 + 1343 903077 0.0011524 1 2 + 1344 903078 0.0010672 1 2 + 1345 903079 0.0011550 1 2 + 1346 903080 0.0010681 1 2 + 1347 903081 0.0011141 1 2 + 1348 903082 0.0010259 1 2 + 1349 903083 0.0010745 1 2 + 1350 903084 0.0010038 1 2 + 1351 903085 0.0010211 1 2 + 1352 903086 0.0009552 1 2 + 1353 903087 0.0009692 1 2 + 1354 903088 0.0009291 1 2 + 1355 903089 0.0009166 1 2 + 1356 903090 0.0009318 1 2 + 1357 903091 0.0009520 1 2 + 1358 903092 0.0008833 1 2 + 1359 903093 0.0009466 1 2 + 1360 903094 0.0008382 1 2 + 1361 903095 0.0008896 1 2 + 1362 903096 0.0008141 1 2 + 1363 903097 0.0009025 1 2 + 1364 903098 0.0007935 1 2 + 1365 903099 0.0008507 1 2 + 1366 903100 0.0007731 1 2 + 1367 903101 0.0008290 1 2 + 1368 903102 0.0007683 1 2 + 1369 903103 0.0008275 1 2 + 1370 903104 0.0007196 1 2 + 1371 903105 0.0007890 1 2 + 1372 903106 0.0006939 1 2 + 1373 903107 0.0007512 1 2 + 1374 903108 0.0006808 1 2 + 1375 903109 0.0007359 1 2 + 1376 903110 0.0006437 1 2 + 1377 903111 0.0006973 1 2 + 1378 903112 0.0006210 1 2 + 1379 903113 0.0006858 1 2 + 1380 903114 0.0005868 1 2 + 1381 903115 0.0006558 1 2 + 1382 903116 0.0005743 1 2 + 1383 903117 0.0006885 1 2 + 1384 903118 0.0009516 1 2 + 1385 903119 0.0016927 1 2 + 1386 904000 0.0000000 0 2 + 1387 904001 0.0000000 0 2 + 1388 904002 0.0000000 0 2 + 1389 904003 0.0000000 0 2 + 1390 904004 0.0000000 0 2 + 1391 904005 0.0000000 0 2 + 1392 904006 0.0000000 0 2 + 1393 904007 0.0022486 1 2 + 1394 904008 0.0022273 1 2 + 1395 904009 0.0022462 1 2 + 1396 904010 0.0021854 1 2 + 1397 904011 0.0022457 1 2 + 1398 904012 0.0021593 1 2 + 1399 904013 0.0022211 1 2 + 1400 904014 0.0021513 1 2 + 1401 904015 0.0021885 1 2 + 1402 904016 0.0020993 1 2 + 1403 904017 0.0021661 1 2 + 1404 904018 0.0020462 1 2 + 1405 904019 0.0000000 0 2 + 1406 904020 0.0020236 1 2 + 1407 904021 0.0019770 1 2 + 1408 904022 0.0019817 1 2 + 1409 904023 0.0020584 1 2 + 1410 904024 0.0019922 1 2 + 1411 904025 0.0020410 1 2 + 1412 904026 0.0019241 1 2 + 1413 904027 0.0019624 1 2 + 1414 904028 0.0018643 1 2 + 1415 904029 0.0018939 1 2 + 1416 904030 0.0018352 1 2 + 1417 904031 0.0019177 1 2 + 1418 904032 0.0000000 0 2 + 1419 904033 0.0018605 1 2 + 1420 904034 0.0018476 1 2 + 1421 904035 0.0018287 1 2 + 1422 904036 0.0017540 1 2 + 1423 904037 0.0018020 1 2 + 1424 904038 0.0016889 1 2 + 1425 904039 0.0017606 1 2 + 1426 904040 0.0016948 1 2 + 1427 904041 0.0017184 1 2 + 1428 904042 0.0016261 1 2 + 1429 904043 0.0016629 1 2 + 1430 904044 0.0000000 0 2 + 1431 904045 0.0016676 1 2 + 1432 904046 0.0013772 1 2 + 1433 904047 0.0016006 1 2 + 1434 904048 0.0015382 1 2 + 1435 904049 0.0016176 1 2 + 1436 904050 0.0015127 1 2 + 1437 904051 0.0015834 1 2 + 1438 904052 0.0014696 1 2 + 1439 904053 0.0015254 1 2 + 1440 904054 0.0014474 1 2 + 1441 904055 0.0000000 0 2 + 1442 904056 0.0014321 1 2 + 1443 904057 0.0014370 1 2 + 1444 904058 0.0013876 1 2 + 1445 904059 0.0014307 1 2 + 1446 904060 0.0013450 1 2 + 1447 904061 0.0013833 1 2 + 1448 904062 0.0012971 1 2 + 1449 904063 0.0013459 1 2 + 1450 904064 0.0012596 1 2 + 1451 904065 0.0013146 1 2 + 1452 904066 0.0000000 0 2 + 1453 904067 0.0000000 0 2 + 1454 904068 0.0000000 0 2 + 1455 904069 0.0000000 0 2 + 1456 904070 0.0000000 0 2 + 1457 904071 0.0000000 0 2 + 1458 904072 0.0000000 0 2 + 1459 904073 0.0000000 0 2 + 1460 904074 0.0000000 0 2 + 1461 904075 0.0000000 0 2 + 1462 904076 0.0007140 1 2 + 1463 904077 0.0011524 1 2 + 1464 904078 0.0010672 1 2 + 1465 904079 0.0011550 1 2 + 1466 904080 0.0010681 1 2 + 1467 904081 0.0011141 1 2 + 1468 904082 0.0010259 1 2 + 1469 904083 0.0010745 1 2 + 1470 904084 0.0010038 1 2 + 1471 904085 0.0010211 1 2 + 1472 904086 0.0009552 1 2 + 1473 904087 0.0009692 1 2 + 1474 904088 0.0009291 1 2 + 1475 904089 0.0009166 1 2 + 1476 904090 0.0009318 1 2 + 1477 904091 0.0009520 1 2 + 1478 904092 0.0008833 1 2 + 1479 904093 0.0009466 1 2 + 1480 904094 0.0008382 1 2 + 1481 904095 0.0008896 1 2 + 1482 904096 0.0008141 1 2 + 1483 904097 0.0009025 1 2 + 1484 904098 0.0007935 1 2 + 1485 904099 0.0008507 1 2 + 1486 904100 0.0007731 1 2 + 1487 904101 0.0008290 1 2 + 1488 904102 0.0007683 1 2 + 1489 904103 0.0008275 1 2 + 1490 904104 0.0007196 1 2 + 1491 904105 0.0007890 1 2 + 1492 904106 0.0006939 1 2 + 1493 904107 0.0007512 1 2 + 1494 904108 0.0006808 1 2 + 1495 904109 0.0007359 1 2 + 1496 904110 0.0006437 1 2 + 1497 904111 0.0006973 1 2 + 1498 904112 0.0006210 1 2 + 1499 904113 0.0006858 1 2 + 1500 904114 0.0005868 1 2 + 1501 904115 0.0006558 1 2 + 1502 904116 0.0005743 1 2 + 1503 904117 0.0006885 1 2 + 1504 904118 0.0009516 1 2 + 1505 904119 0.0016927 1 2 + 1506 905000 0.0000000 0 2 + 1507 905001 0.0000000 0 2 + 1508 905002 0.0000000 0 2 + 1509 905003 0.0000000 0 2 + 1510 905004 0.0000000 0 2 + 1511 905005 0.0000000 0 2 + 1512 905006 0.0000000 0 2 + 1513 905007 0.0022486 1 2 + 1514 905008 0.0022273 1 2 + 1515 905009 0.0022462 1 2 + 1516 905010 0.0021854 1 2 + 1517 905011 0.0022457 1 2 + 1518 905012 0.0021593 1 2 + 1519 905013 0.0022211 1 2 + 1520 905014 0.0021513 1 2 + 1521 905015 0.0021885 1 2 + 1522 905016 0.0020993 1 2 + 1523 905017 0.0021661 1 2 + 1524 905018 0.0020462 1 2 + 1525 905019 0.0000000 0 2 + 1526 905020 0.0020236 1 2 + 1527 905021 0.0019770 1 2 + 1528 905022 0.0019817 1 2 + 1529 905023 0.0020584 1 2 + 1530 905024 0.0019922 1 2 + 1531 905025 0.0020410 1 2 + 1532 905026 0.0019241 1 2 + 1533 905027 0.0019624 1 2 + 1534 905028 0.0018643 1 2 + 1535 905029 0.0018939 1 2 + 1536 905030 0.0018352 1 2 + 1537 905031 0.0019177 1 2 + 1538 905032 0.0000000 0 2 + 1539 905033 0.0018605 1 2 + 1540 905034 0.0018476 1 2 + 1541 905035 0.0018287 1 2 + 1542 905036 0.0017540 1 2 + 1543 905037 0.0018020 1 2 + 1544 905038 0.0016889 1 2 + 1545 905039 0.0017606 1 2 + 1546 905040 0.0016948 1 2 + 1547 905041 0.0017184 1 2 + 1548 905042 0.0016261 1 2 + 1549 905043 0.0016629 1 2 + 1550 905044 0.0000000 0 2 + 1551 905045 0.0016676 1 2 + 1552 905046 0.0013772 1 2 + 1553 905047 0.0016006 1 2 + 1554 905048 0.0015382 1 2 + 1555 905049 0.0016176 1 2 + 1556 905050 0.0015127 1 2 + 1557 905051 0.0015834 1 2 + 1558 905052 0.0014696 1 2 + 1559 905053 0.0015254 1 2 + 1560 905054 0.0014474 1 2 + 1561 905055 0.0000000 0 2 + 1562 905056 0.0014321 1 2 + 1563 905057 0.0014370 1 2 + 1564 905058 0.0013876 1 2 + 1565 905059 0.0014307 1 2 + 1566 905060 0.0013450 1 2 + 1567 905061 0.0013833 1 2 + 1568 905062 0.0012971 1 2 + 1569 905063 0.0013459 1 2 + 1570 905064 0.0012596 1 2 + 1571 905065 0.0013146 1 2 + 1572 905066 0.0000000 0 2 + 1573 905067 0.0000000 0 2 + 1574 905068 0.0000000 0 2 + 1575 905069 0.0000000 0 2 + 1576 905070 0.0000000 0 2 + 1577 905071 0.0000000 0 2 + 1578 905072 0.0000000 0 2 + 1579 905073 0.0000000 0 2 + 1580 905074 0.0000000 0 2 + 1581 905075 0.0000000 0 2 + 1582 905076 0.0007140 1 2 + 1583 905077 0.0011524 1 2 + 1584 905078 0.0010672 1 2 + 1585 905079 0.0011550 1 2 + 1586 905080 0.0010681 1 2 + 1587 905081 0.0011141 1 2 + 1588 905082 0.0010259 1 2 + 1589 905083 0.0010745 1 2 + 1590 905084 0.0010038 1 2 + 1591 905085 0.0010211 1 2 + 1592 905086 0.0009552 1 2 + 1593 905087 0.0009692 1 2 + 1594 905088 0.0009291 1 2 + 1595 905089 0.0009166 1 2 + 1596 905090 0.0009318 1 2 + 1597 905091 0.0009520 1 2 + 1598 905092 0.0008833 1 2 + 1599 905093 0.0009466 1 2 + 1600 905094 0.0008382 1 2 + 1601 905095 0.0008896 1 2 + 1602 905096 0.0008141 1 2 + 1603 905097 0.0009025 1 2 + 1604 905098 0.0007935 1 2 + 1605 905099 0.0008507 1 2 + 1606 905100 0.0007731 1 2 + 1607 905101 0.0008290 1 2 + 1608 905102 0.0007683 1 2 + 1609 905103 0.0008275 1 2 + 1610 905104 0.0007196 1 2 + 1611 905105 0.0007890 1 2 + 1612 905106 0.0006939 1 2 + 1613 905107 0.0007512 1 2 + 1614 905108 0.0006808 1 2 + 1615 905109 0.0007359 1 2 + 1616 905110 0.0006437 1 2 + 1617 905111 0.0006973 1 2 + 1618 905112 0.0006210 1 2 + 1619 905113 0.0006858 1 2 + 1620 905114 0.0005868 1 2 + 1621 905115 0.0006558 1 2 + 1622 905116 0.0005743 1 2 + 1623 905117 0.0006885 1 2 + 1624 905118 0.0009516 1 2 + 1625 905119 0.0016927 1 2 + 1626 906000 0.0000000 0 2 + 1627 906001 0.0000000 0 2 + 1628 906002 0.0000000 0 2 + 1629 906003 0.0000000 0 2 + 1630 906004 0.0000000 0 2 + 1631 906005 0.0000000 0 2 + 1632 906006 0.0000000 0 2 + 1633 906007 0.0022486 1 2 + 1634 906008 0.0022273 1 2 + 1635 906009 0.0022462 1 2 + 1636 906010 0.0021854 1 2 + 1637 906011 0.0022457 1 2 + 1638 906012 0.0021593 1 2 + 1639 906013 0.0022211 1 2 + 1640 906014 0.0021513 1 2 + 1641 906015 0.0021885 1 2 + 1642 906016 0.0020993 1 2 + 1643 906017 0.0021661 1 2 + 1644 906018 0.0020462 1 2 + 1645 906019 0.0000000 0 2 + 1646 906020 0.0020236 1 2 + 1647 906021 0.0019770 1 2 + 1648 906022 0.0019817 1 2 + 1649 906023 0.0020584 1 2 + 1650 906024 0.0019922 1 2 + 1651 906025 0.0020410 1 2 + 1652 906026 0.0019241 1 2 + 1653 906027 0.0019624 1 2 + 1654 906028 0.0018643 1 2 + 1655 906029 0.0018939 1 2 + 1656 906030 0.0018352 1 2 + 1657 906031 0.0019177 1 2 + 1658 906032 0.0000000 0 2 + 1659 906033 0.0018605 1 2 + 1660 906034 0.0018476 1 2 + 1661 906035 0.0018287 1 2 + 1662 906036 0.0017540 1 2 + 1663 906037 0.0018020 1 2 + 1664 906038 0.0016889 1 2 + 1665 906039 0.0017606 1 2 + 1666 906040 0.0016948 1 2 + 1667 906041 0.0017184 1 2 + 1668 906042 0.0016261 1 2 + 1669 906043 0.0016629 1 2 + 1670 906044 0.0000000 0 2 + 1671 906045 0.0016676 1 2 + 1672 906046 0.0013772 1 2 + 1673 906047 0.0016006 1 2 + 1674 906048 0.0015382 1 2 + 1675 906049 0.0016176 1 2 + 1676 906050 0.0015127 1 2 + 1677 906051 0.0015834 1 2 + 1678 906052 0.0014696 1 2 + 1679 906053 0.0015254 1 2 + 1680 906054 0.0014474 1 2 + 1681 906055 0.0000000 0 2 + 1682 906056 0.0014321 1 2 + 1683 906057 0.0014370 1 2 + 1684 906058 0.0013876 1 2 + 1685 906059 0.0014307 1 2 + 1686 906060 0.0013450 1 2 + 1687 906061 0.0013833 1 2 + 1688 906062 0.0012971 1 2 + 1689 906063 0.0013459 1 2 + 1690 906064 0.0012596 1 2 + 1691 906065 0.0013146 1 2 + 1692 906066 0.0000000 0 2 + 1693 906067 0.0000000 0 2 + 1694 906068 0.0000000 0 2 + 1695 906069 0.0000000 0 2 + 1696 906070 0.0000000 0 2 + 1697 906071 0.0000000 0 2 + 1698 906072 0.0000000 0 2 + 1699 906073 0.0000000 0 2 + 1700 906074 0.0000000 0 2 + 1701 906075 0.0000000 0 2 + 1702 906076 0.0007140 1 2 + 1703 906077 0.0011524 1 2 + 1704 906078 0.0010672 1 2 + 1705 906079 0.0011550 1 2 + 1706 906080 0.0010681 1 2 + 1707 906081 0.0011141 1 2 + 1708 906082 0.0010259 1 2 + 1709 906083 0.0010745 1 2 + 1710 906084 0.0010038 1 2 + 1711 906085 0.0010211 1 2 + 1712 906086 0.0009552 1 2 + 1713 906087 0.0009692 1 2 + 1714 906088 0.0009291 1 2 + 1715 906089 0.0009166 1 2 + 1716 906090 0.0009318 1 2 + 1717 906091 0.0009520 1 2 + 1718 906092 0.0008833 1 2 + 1719 906093 0.0009466 1 2 + 1720 906094 0.0008382 1 2 + 1721 906095 0.0008896 1 2 + 1722 906096 0.0008141 1 2 + 1723 906097 0.0009025 1 2 + 1724 906098 0.0007935 1 2 + 1725 906099 0.0008507 1 2 + 1726 906100 0.0007731 1 2 + 1727 906101 0.0008290 1 2 + 1728 906102 0.0007683 1 2 + 1729 906103 0.0008275 1 2 + 1730 906104 0.0007196 1 2 + 1731 906105 0.0007890 1 2 + 1732 906106 0.0006939 1 2 + 1733 906107 0.0007512 1 2 + 1734 906108 0.0006808 1 2 + 1735 906109 0.0007359 1 2 + 1736 906110 0.0006437 1 2 + 1737 906111 0.0006973 1 2 + 1738 906112 0.0006210 1 2 + 1739 906113 0.0006858 1 2 + 1740 906114 0.0005868 1 2 + 1741 906115 0.0006558 1 2 + 1742 906116 0.0005743 1 2 + 1743 906117 0.0006885 1 2 + 1744 906118 0.0009516 1 2 + 1745 906119 0.0016927 1 2 + 1746 907000 0.0000000 0 2 + 1747 907001 0.0000000 0 2 + 1748 907002 0.0000000 0 2 + 1749 907003 0.0000000 0 2 + 1750 907004 0.0000000 0 2 + 1751 907005 0.0000000 0 2 + 1752 907006 0.0000000 0 2 + 1753 907007 0.0022486 1 2 + 1754 907008 0.0022273 1 2 + 1755 907009 0.0022462 1 2 + 1756 907010 0.0021854 1 2 + 1757 907011 0.0022457 1 2 + 1758 907012 0.0021593 1 2 + 1759 907013 0.0022211 1 2 + 1760 907014 0.0021513 1 2 + 1761 907015 0.0021885 1 2 + 1762 907016 0.0020993 1 2 + 1763 907017 0.0021661 1 2 + 1764 907018 0.0020462 1 2 + 1765 907019 0.0000000 0 2 + 1766 907020 0.0020236 1 2 + 1767 907021 0.0019770 1 2 + 1768 907022 0.0019817 1 2 + 1769 907023 0.0020584 1 2 + 1770 907024 0.0019922 1 2 + 1771 907025 0.0020410 1 2 + 1772 907026 0.0019241 1 2 + 1773 907027 0.0019624 1 2 + 1774 907028 0.0018643 1 2 + 1775 907029 0.0018939 1 2 + 1776 907030 0.0018352 1 2 + 1777 907031 0.0019177 1 2 + 1778 907032 0.0000000 0 2 + 1779 907033 0.0018605 1 2 + 1780 907034 0.0018476 1 2 + 1781 907035 0.0018287 1 2 + 1782 907036 0.0017540 1 2 + 1783 907037 0.0018020 1 2 + 1784 907038 0.0016889 1 2 + 1785 907039 0.0017606 1 2 + 1786 907040 0.0016948 1 2 + 1787 907041 0.0017184 1 2 + 1788 907042 0.0016261 1 2 + 1789 907043 0.0016629 1 2 + 1790 907044 0.0000000 0 2 + 1791 907045 0.0016676 1 2 + 1792 907046 0.0013772 1 2 + 1793 907047 0.0016006 1 2 + 1794 907048 0.0015382 1 2 + 1795 907049 0.0016176 1 2 + 1796 907050 0.0015127 1 2 + 1797 907051 0.0015834 1 2 + 1798 907052 0.0014696 1 2 + 1799 907053 0.0015254 1 2 + 1800 907054 0.0014474 1 2 + 1801 907055 0.0000000 0 2 + 1802 907056 0.0014321 1 2 + 1803 907057 0.0014370 1 2 + 1804 907058 0.0013876 1 2 + 1805 907059 0.0014307 1 2 + 1806 907060 0.0013450 1 2 + 1807 907061 0.0013833 1 2 + 1808 907062 0.0012971 1 2 + 1809 907063 0.0013459 1 2 + 1810 907064 0.0012596 1 2 + 1811 907065 0.0013146 1 2 + 1812 907066 0.0000000 0 2 + 1813 907067 0.0000000 0 2 + 1814 907068 0.0000000 0 2 + 1815 907069 0.0000000 0 2 + 1816 907070 0.0000000 0 2 + 1817 907071 0.0000000 0 2 + 1818 907072 0.0000000 0 2 + 1819 907073 0.0000000 0 2 + 1820 907074 0.0000000 0 2 + 1821 907075 0.0000000 0 2 + 1822 907076 0.0007140 1 2 + 1823 907077 0.0011524 1 2 + 1824 907078 0.0010672 1 2 + 1825 907079 0.0011550 1 2 + 1826 907080 0.0010681 1 2 + 1827 907081 0.0011141 1 2 + 1828 907082 0.0010259 1 2 + 1829 907083 0.0010745 1 2 + 1830 907084 0.0010038 1 2 + 1831 907085 0.0010211 1 2 + 1832 907086 0.0009552 1 2 + 1833 907087 0.0009692 1 2 + 1834 907088 0.0009291 1 2 + 1835 907089 0.0009166 1 2 + 1836 907090 0.0009318 1 2 + 1837 907091 0.0009520 1 2 + 1838 907092 0.0008833 1 2 + 1839 907093 0.0009466 1 2 + 1840 907094 0.0008382 1 2 + 1841 907095 0.0008896 1 2 + 1842 907096 0.0008141 1 2 + 1843 907097 0.0009025 1 2 + 1844 907098 0.0007935 1 2 + 1845 907099 0.0008507 1 2 + 1846 907100 0.0007731 1 2 + 1847 907101 0.0008290 1 2 + 1848 907102 0.0007683 1 2 + 1849 907103 0.0008275 1 2 + 1850 907104 0.0007196 1 2 + 1851 907105 0.0007890 1 2 + 1852 907106 0.0006939 1 2 + 1853 907107 0.0007512 1 2 + 1854 907108 0.0006808 1 2 + 1855 907109 0.0007359 1 2 + 1856 907110 0.0006437 1 2 + 1857 907111 0.0006973 1 2 + 1858 907112 0.0006210 1 2 + 1859 907113 0.0006858 1 2 + 1860 907114 0.0005868 1 2 + 1861 907115 0.0006558 1 2 + 1862 907116 0.0005743 1 2 + 1863 907117 0.0006885 1 2 + 1864 907118 0.0009516 1 2 + 1865 907119 0.0016927 1 2 + 1866 911000 0.0000000 0 2 + 1867 911001 0.0000000 0 2 + 1868 911002 0.0000000 0 2 + 1869 911003 0.0039947 1 2 + 1870 911004 0.0039848 1 2 + 1871 911005 0.0040814 1 2 + 1872 911006 0.0039844 1 2 + 1873 911007 0.0040137 1 2 + 1874 911008 0.0039602 1 2 + 1875 911009 0.0040504 1 2 + 1876 911010 0.0039271 1 2 + 1877 911011 0.0039722 1 2 + 1878 911012 0.0039028 1 2 + 1879 911013 0.0040588 1 2 + 1880 911014 0.0039318 1 2 + 1881 911015 0.0039531 1 2 + 1882 911016 0.0000000 0 2 + 1883 911017 0.0039819 1 2 + 1884 911018 0.0038749 1 2 + 1885 911019 0.0039018 1 2 + 1886 911020 0.0038421 1 2 + 1887 911021 0.0039204 1 2 + 1888 911022 0.0038189 1 2 + 1889 911023 0.0038995 1 2 + 1890 911024 0.0038129 1 2 + 1891 911025 0.0038507 1 2 + 1892 911026 0.0037578 1 2 + 1893 911027 0.0038265 1 2 + 1894 911028 0.0037352 1 2 + 1895 911029 0.0038140 1 2 + 1896 911030 0.0000000 0 2 + 1897 911031 0.0000000 0 2 + 1898 911032 0.0000000 0 2 + 1899 911033 0.0000000 0 2 + 1900 911034 0.0000000 0 2 + 1901 911035 0.0000000 0 2 + 1902 911036 0.0000000 0 2 + 1903 911037 0.0000000 0 2 + 1904 911038 0.0000000 0 2 + 1905 911039 0.0000000 0 2 + 1906 911040 0.0000000 0 2 + 1907 911041 0.0000000 0 2 + 1908 911042 0.0000000 0 2 + 1909 911043 0.0035259 1 2 + 1910 911044 0.0034181 1 2 + 1911 911045 0.0034913 1 2 + 1912 911046 0.0033863 1 2 + 1913 911047 0.0034605 1 2 + 1914 911048 0.0033369 1 2 + 1915 911049 0.0033952 1 2 + 1916 911050 0.0033419 1 2 + 1917 911051 0.0034441 1 2 + 1918 911052 0.0033443 1 2 + 1919 911053 0.0033803 1 2 + 1920 911054 0.0033289 1 2 + 1921 911055 0.0034190 1 2 + 1922 911056 0.0033215 1 2 + 1923 911057 0.0033734 1 2 + 1924 911058 0.0032995 1 2 + 1925 911059 0.0033824 1 2 + 1926 911060 0.0032673 1 2 + 1927 911061 0.0033293 1 2 + 1928 911062 0.0032556 1 2 + 1929 911063 0.0033203 1 2 + 1930 911064 0.0032176 1 2 + 1931 911065 0.0033174 1 2 + 1932 911066 0.0031937 1 2 + 1933 911067 0.0032719 1 2 + 1934 911068 0.0031562 1 2 + 1935 911069 0.0032456 1 2 + 1936 911070 0.0031332 1 2 + 1937 911071 0.0031814 1 2 + 1938 911072 0.0030990 1 2 + 1939 911073 0.0031843 1 2 + 1940 911074 0.0030801 1 2 + 1941 911075 0.0031829 1 2 + 1942 911076 0.0030810 1 2 + 1943 911077 0.0031397 1 2 + 1944 911078 0.0030485 1 2 + 1945 911079 0.0031512 1 2 + 1946 911080 0.0030298 1 2 + 1947 911081 0.0031008 1 2 + 1948 911082 0.0029977 1 2 + 1949 911083 0.0030246 1 2 + 1950 911084 0.0029369 1 2 + 1951 911085 0.0029995 1 2 + 1952 911086 0.0028994 1 2 + 1953 911087 0.0029417 1 2 + 1954 911088 0.0028616 1 2 + 1955 911089 0.0029336 1 2 + 1956 911090 0.0028544 1 2 + 1957 911091 0.0029079 1 2 + 1958 911092 0.0028382 1 2 + 1959 911093 0.0028865 1 2 + 1960 911094 0.0028010 1 2 + 1961 911095 0.0028700 1 2 + 1962 911096 0.0027905 1 2 + 1963 911097 0.0028608 1 2 + 1964 911098 0.0027379 1 2 + 1965 911099 0.0028289 1 2 + 1966 911100 0.0027271 1 2 + 1967 911101 0.0027823 1 2 + 1968 911102 0.0026680 1 2 + 1969 911103 0.0026991 1 2 + 1970 911104 0.0026567 1 2 + 1971 911105 0.0027472 1 2 + 1972 911106 0.0026411 1 2 + 1973 911107 0.0026961 1 2 + 1974 911108 0.0026007 1 2 + 1975 911109 0.0026639 1 2 + 1976 911110 0.0025651 1 2 + 1977 911111 0.0026130 1 2 + 1978 911112 0.0025402 1 2 + 1979 911113 0.0026076 1 2 + 1980 911114 0.0025143 1 2 + 1981 911115 0.0025748 1 2 + 1982 911116 0.0024974 1 2 + 1983 911117 0.0025790 1 2 + 1984 911118 0.0000000 0 2 + 1985 911119 0.0000000 0 2 + 1986 912000 0.0000000 0 2 + 1987 912001 0.0000000 0 2 + 1988 912002 0.0000000 0 2 + 1989 912003 0.0039947 1 2 + 1990 912004 0.0039848 1 2 + 1991 912005 0.0040814 1 2 + 1992 912006 0.0039844 1 2 + 1993 912007 0.0040137 1 2 + 1994 912008 0.0039602 1 2 + 1995 912009 0.0040504 1 2 + 1996 912010 0.0039271 1 2 + 1997 912011 0.0039722 1 2 + 1998 912012 0.0039028 1 2 + 1999 912013 0.0040588 1 2 + 2000 912014 0.0039318 1 2 + 2001 912015 0.0039531 1 2 + 2002 912016 0.0000000 0 2 + 2003 912017 0.0039819 1 2 + 2004 912018 0.0038749 1 2 + 2005 912019 0.0039018 1 2 + 2006 912020 0.0038421 1 2 + 2007 912021 0.0039204 1 2 + 2008 912022 0.0038189 1 2 + 2009 912023 0.0038995 1 2 + 2010 912024 0.0038129 1 2 + 2011 912025 0.0038507 1 2 + 2012 912026 0.0037578 1 2 + 2013 912027 0.0038265 1 2 + 2014 912028 0.0037352 1 2 + 2015 912029 0.0038140 1 2 + 2016 912030 0.0000000 0 2 + 2017 912031 0.0000000 0 2 + 2018 912032 0.0000000 0 2 + 2019 912033 0.0000000 0 2 + 2020 912034 0.0000000 0 2 + 2021 912035 0.0000000 0 2 + 2022 912036 0.0000000 0 2 + 2023 912037 0.0000000 0 2 + 2024 912038 0.0000000 0 2 + 2025 912039 0.0000000 0 2 + 2026 912040 0.0000000 0 2 + 2027 912041 0.0000000 0 2 + 2028 912042 0.0000000 0 2 + 2029 912043 0.0035259 1 2 + 2030 912044 0.0034181 1 2 + 2031 912045 0.0034913 1 2 + 2032 912046 0.0033863 1 2 + 2033 912047 0.0034605 1 2 + 2034 912048 0.0033369 1 2 + 2035 912049 0.0033952 1 2 + 2036 912050 0.0033419 1 2 + 2037 912051 0.0034441 1 2 + 2038 912052 0.0033443 1 2 + 2039 912053 0.0033803 1 2 + 2040 912054 0.0033289 1 2 + 2041 912055 0.0034190 1 2 + 2042 912056 0.0033215 1 2 + 2043 912057 0.0033734 1 2 + 2044 912058 0.0032995 1 2 + 2045 912059 0.0033824 1 2 + 2046 912060 0.0032673 1 2 + 2047 912061 0.0033293 1 2 + 2048 912062 0.0032556 1 2 + 2049 912063 0.0033203 1 2 + 2050 912064 0.0032176 1 2 + 2051 912065 0.0033174 1 2 + 2052 912066 0.0031937 1 2 + 2053 912067 0.0032719 1 2 + 2054 912068 0.0031562 1 2 + 2055 912069 0.0032456 1 2 + 2056 912070 0.0031332 1 2 + 2057 912071 0.0031814 1 2 + 2058 912072 0.0030990 1 2 + 2059 912073 0.0031843 1 2 + 2060 912074 0.0030801 1 2 + 2061 912075 0.0031829 1 2 + 2062 912076 0.0030810 1 2 + 2063 912077 0.0031397 1 2 + 2064 912078 0.0030485 1 2 + 2065 912079 0.0031512 1 2 + 2066 912080 0.0030298 1 2 + 2067 912081 0.0031008 1 2 + 2068 912082 0.0029977 1 2 + 2069 912083 0.0030246 1 2 + 2070 912084 0.0029369 1 2 + 2071 912085 0.0029995 1 2 + 2072 912086 0.0028994 1 2 + 2073 912087 0.0029417 1 2 + 2074 912088 0.0028616 1 2 + 2075 912089 0.0029336 1 2 + 2076 912090 0.0028544 1 2 + 2077 912091 0.0029079 1 2 + 2078 912092 0.0028382 1 2 + 2079 912093 0.0028865 1 2 + 2080 912094 0.0028010 1 2 + 2081 912095 0.0028700 1 2 + 2082 912096 0.0027905 1 2 + 2083 912097 0.0028608 1 2 + 2084 912098 0.0027379 1 2 + 2085 912099 0.0028289 1 2 + 2086 912100 0.0027271 1 2 + 2087 912101 0.0027823 1 2 + 2088 912102 0.0026680 1 2 + 2089 912103 0.0026991 1 2 + 2090 912104 0.0026567 1 2 + 2091 912105 0.0027472 1 2 + 2092 912106 0.0026411 1 2 + 2093 912107 0.0026961 1 2 + 2094 912108 0.0026007 1 2 + 2095 912109 0.0026639 1 2 + 2096 912110 0.0025651 1 2 + 2097 912111 0.0026130 1 2 + 2098 912112 0.0025402 1 2 + 2099 912113 0.0026076 1 2 + 2100 912114 0.0025143 1 2 + 2101 912115 0.0025748 1 2 + 2102 912116 0.0024974 1 2 + 2103 912117 0.0025790 1 2 + 2104 912118 0.0000000 0 2 + 2105 912119 0.0000000 0 2 + 2106 913000 0.0000000 0 2 + 2107 913001 0.0000000 0 2 + 2108 913002 0.0000000 0 2 + 2109 913003 0.0039947 1 2 + 2110 913004 0.0039848 1 2 + 2111 913005 0.0040814 1 2 + 2112 913006 0.0039844 1 2 + 2113 913007 0.0040137 1 2 + 2114 913008 0.0039602 1 2 + 2115 913009 0.0040504 1 2 + 2116 913010 0.0039271 1 2 + 2117 913011 0.0039722 1 2 + 2118 913012 0.0039028 1 2 + 2119 913013 0.0040588 1 2 + 2120 913014 0.0039318 1 2 + 2121 913015 0.0039531 1 2 + 2122 913016 0.0000000 0 2 + 2123 913017 0.0039819 1 2 + 2124 913018 0.0038749 1 2 + 2125 913019 0.0039018 1 2 + 2126 913020 0.0038421 1 2 + 2127 913021 0.0039204 1 2 + 2128 913022 0.0038189 1 2 + 2129 913023 0.0038995 1 2 + 2130 913024 0.0038129 1 2 + 2131 913025 0.0038507 1 2 + 2132 913026 0.0037578 1 2 + 2133 913027 0.0038265 1 2 + 2134 913028 0.0037352 1 2 + 2135 913029 0.0038140 1 2 + 2136 913030 0.0000000 0 2 + 2137 913031 0.0000000 0 2 + 2138 913032 0.0000000 0 2 + 2139 913033 0.0000000 0 2 + 2140 913034 0.0000000 0 2 + 2141 913035 0.0000000 0 2 + 2142 913036 0.0000000 0 2 + 2143 913037 0.0000000 0 2 + 2144 913038 0.0000000 0 2 + 2145 913039 0.0000000 0 2 + 2146 913040 0.0000000 0 2 + 2147 913041 0.0000000 0 2 + 2148 913042 0.0000000 0 2 + 2149 913043 0.0035259 1 2 + 2150 913044 0.0034181 1 2 + 2151 913045 0.0034913 1 2 + 2152 913046 0.0033863 1 2 + 2153 913047 0.0034605 1 2 + 2154 913048 0.0033369 1 2 + 2155 913049 0.0033952 1 2 + 2156 913050 0.0033419 1 2 + 2157 913051 0.0034441 1 2 + 2158 913052 0.0033443 1 2 + 2159 913053 0.0033803 1 2 + 2160 913054 0.0033289 1 2 + 2161 913055 0.0034190 1 2 + 2162 913056 0.0033215 1 2 + 2163 913057 0.0033734 1 2 + 2164 913058 0.0032995 1 2 + 2165 913059 0.0033824 1 2 + 2166 913060 0.0032673 1 2 + 2167 913061 0.0033293 1 2 + 2168 913062 0.0032556 1 2 + 2169 913063 0.0033203 1 2 + 2170 913064 0.0032176 1 2 + 2171 913065 0.0033174 1 2 + 2172 913066 0.0031937 1 2 + 2173 913067 0.0032719 1 2 + 2174 913068 0.0031562 1 2 + 2175 913069 0.0032456 1 2 + 2176 913070 0.0031332 1 2 + 2177 913071 0.0031814 1 2 + 2178 913072 0.0030990 1 2 + 2179 913073 0.0031843 1 2 + 2180 913074 0.0030801 1 2 + 2181 913075 0.0031829 1 2 + 2182 913076 0.0030810 1 2 + 2183 913077 0.0031397 1 2 + 2184 913078 0.0030485 1 2 + 2185 913079 0.0031512 1 2 + 2186 913080 0.0030298 1 2 + 2187 913081 0.0031008 1 2 + 2188 913082 0.0029977 1 2 + 2189 913083 0.0030246 1 2 + 2190 913084 0.0029369 1 2 + 2191 913085 0.0029995 1 2 + 2192 913086 0.0028994 1 2 + 2193 913087 0.0029417 1 2 + 2194 913088 0.0028616 1 2 + 2195 913089 0.0029336 1 2 + 2196 913090 0.0028544 1 2 + 2197 913091 0.0029079 1 2 + 2198 913092 0.0028382 1 2 + 2199 913093 0.0028865 1 2 + 2200 913094 0.0028010 1 2 + 2201 913095 0.0028700 1 2 + 2202 913096 0.0027905 1 2 + 2203 913097 0.0028608 1 2 + 2204 913098 0.0027379 1 2 + 2205 913099 0.0028289 1 2 + 2206 913100 0.0027271 1 2 + 2207 913101 0.0027823 1 2 + 2208 913102 0.0026680 1 2 + 2209 913103 0.0026991 1 2 + 2210 913104 0.0026567 1 2 + 2211 913105 0.0027472 1 2 + 2212 913106 0.0026411 1 2 + 2213 913107 0.0026961 1 2 + 2214 913108 0.0026007 1 2 + 2215 913109 0.0026639 1 2 + 2216 913110 0.0025651 1 2 + 2217 913111 0.0026130 1 2 + 2218 913112 0.0025402 1 2 + 2219 913113 0.0026076 1 2 + 2220 913114 0.0025143 1 2 + 2221 913115 0.0025748 1 2 + 2222 913116 0.0024974 1 2 + 2223 913117 0.0025790 1 2 + 2224 913118 0.0000000 0 2 + 2225 913119 0.0000000 0 2 + 2226 914000 0.0000000 0 2 + 2227 914001 0.0000000 0 2 + 2228 914002 0.0000000 0 2 + 2229 914003 0.0039947 1 2 + 2230 914004 0.0039848 1 2 + 2231 914005 0.0040814 1 2 + 2232 914006 0.0039844 1 2 + 2233 914007 0.0040137 1 2 + 2234 914008 0.0039602 1 2 + 2235 914009 0.0040504 1 2 + 2236 914010 0.0039271 1 2 + 2237 914011 0.0039722 1 2 + 2238 914012 0.0039028 1 2 + 2239 914013 0.0040588 1 2 + 2240 914014 0.0039318 1 2 + 2241 914015 0.0039531 1 2 + 2242 914016 0.0000000 0 2 + 2243 914017 0.0039819 1 2 + 2244 914018 0.0038749 1 2 + 2245 914019 0.0039018 1 2 + 2246 914020 0.0038421 1 2 + 2247 914021 0.0039204 1 2 + 2248 914022 0.0038189 1 2 + 2249 914023 0.0038995 1 2 + 2250 914024 0.0038129 1 2 + 2251 914025 0.0038507 1 2 + 2252 914026 0.0037578 1 2 + 2253 914027 0.0038265 1 2 + 2254 914028 0.0037352 1 2 + 2255 914029 0.0038140 1 2 + 2256 914030 0.0000000 0 2 + 2257 914031 0.0000000 0 2 + 2258 914032 0.0000000 0 2 + 2259 914033 0.0000000 0 2 + 2260 914034 0.0000000 0 2 + 2261 914035 0.0000000 0 2 + 2262 914036 0.0000000 0 2 + 2263 914037 0.0000000 0 2 + 2264 914038 0.0000000 0 2 + 2265 914039 0.0000000 0 2 + 2266 914040 0.0000000 0 2 + 2267 914041 0.0000000 0 2 + 2268 914042 0.0000000 0 2 + 2269 914043 0.0035259 1 2 + 2270 914044 0.0034181 1 2 + 2271 914045 0.0034913 1 2 + 2272 914046 0.0033863 1 2 + 2273 914047 0.0034605 1 2 + 2274 914048 0.0033369 1 2 + 2275 914049 0.0033952 1 2 + 2276 914050 0.0033419 1 2 + 2277 914051 0.0034441 1 2 + 2278 914052 0.0033443 1 2 + 2279 914053 0.0033803 1 2 + 2280 914054 0.0033289 1 2 + 2281 914055 0.0034190 1 2 + 2282 914056 0.0033215 1 2 + 2283 914057 0.0033734 1 2 + 2284 914058 0.0032995 1 2 + 2285 914059 0.0033824 1 2 + 2286 914060 0.0032673 1 2 + 2287 914061 0.0033293 1 2 + 2288 914062 0.0032556 1 2 + 2289 914063 0.0033203 1 2 + 2290 914064 0.0032176 1 2 + 2291 914065 0.0033174 1 2 + 2292 914066 0.0031937 1 2 + 2293 914067 0.0032719 1 2 + 2294 914068 0.0031562 1 2 + 2295 914069 0.0032456 1 2 + 2296 914070 0.0031332 1 2 + 2297 914071 0.0031814 1 2 + 2298 914072 0.0030990 1 2 + 2299 914073 0.0031843 1 2 + 2300 914074 0.0030801 1 2 + 2301 914075 0.0031829 1 2 + 2302 914076 0.0030810 1 2 + 2303 914077 0.0031397 1 2 + 2304 914078 0.0030485 1 2 + 2305 914079 0.0031512 1 2 + 2306 914080 0.0030298 1 2 + 2307 914081 0.0031008 1 2 + 2308 914082 0.0029977 1 2 + 2309 914083 0.0030246 1 2 + 2310 914084 0.0029369 1 2 + 2311 914085 0.0029995 1 2 + 2312 914086 0.0028994 1 2 + 2313 914087 0.0029417 1 2 + 2314 914088 0.0028616 1 2 + 2315 914089 0.0029336 1 2 + 2316 914090 0.0028544 1 2 + 2317 914091 0.0029079 1 2 + 2318 914092 0.0028382 1 2 + 2319 914093 0.0028865 1 2 + 2320 914094 0.0028010 1 2 + 2321 914095 0.0028700 1 2 + 2322 914096 0.0027905 1 2 + 2323 914097 0.0028608 1 2 + 2324 914098 0.0027379 1 2 + 2325 914099 0.0028289 1 2 + 2326 914100 0.0027271 1 2 + 2327 914101 0.0027823 1 2 + 2328 914102 0.0026680 1 2 + 2329 914103 0.0026991 1 2 + 2330 914104 0.0026567 1 2 + 2331 914105 0.0027472 1 2 + 2332 914106 0.0026411 1 2 + 2333 914107 0.0026961 1 2 + 2334 914108 0.0026007 1 2 + 2335 914109 0.0026639 1 2 + 2336 914110 0.0025651 1 2 + 2337 914111 0.0026130 1 2 + 2338 914112 0.0025402 1 2 + 2339 914113 0.0026076 1 2 + 2340 914114 0.0025143 1 2 + 2341 914115 0.0025748 1 2 + 2342 914116 0.0024974 1 2 + 2343 914117 0.0025790 1 2 + 2344 914118 0.0000000 0 2 + 2345 914119 0.0000000 0 2 + 2346 915000 0.0000000 0 2 + 2347 915001 0.0000000 0 2 + 2348 915002 0.0000000 0 2 + 2349 915003 0.0039947 1 2 + 2350 915004 0.0039848 1 2 + 2351 915005 0.0040814 1 2 + 2352 915006 0.0039844 1 2 + 2353 915007 0.0040137 1 2 + 2354 915008 0.0039602 1 2 + 2355 915009 0.0040504 1 2 + 2356 915010 0.0039271 1 2 + 2357 915011 0.0039722 1 2 + 2358 915012 0.0039028 1 2 + 2359 915013 0.0040588 1 2 + 2360 915014 0.0039318 1 2 + 2361 915015 0.0039531 1 2 + 2362 915016 0.0000000 0 2 + 2363 915017 0.0039819 1 2 + 2364 915018 0.0038749 1 2 + 2365 915019 0.0039018 1 2 + 2366 915020 0.0038421 1 2 + 2367 915021 0.0039204 1 2 + 2368 915022 0.0038189 1 2 + 2369 915023 0.0038995 1 2 + 2370 915024 0.0038129 1 2 + 2371 915025 0.0038507 1 2 + 2372 915026 0.0037578 1 2 + 2373 915027 0.0038265 1 2 + 2374 915028 0.0037352 1 2 + 2375 915029 0.0038140 1 2 + 2376 915030 0.0000000 0 2 + 2377 915031 0.0000000 0 2 + 2378 915032 0.0000000 0 2 + 2379 915033 0.0000000 0 2 + 2380 915034 0.0000000 0 2 + 2381 915035 0.0000000 0 2 + 2382 915036 0.0000000 0 2 + 2383 915037 0.0000000 0 2 + 2384 915038 0.0000000 0 2 + 2385 915039 0.0000000 0 2 + 2386 915040 0.0000000 0 2 + 2387 915041 0.0000000 0 2 + 2388 915042 0.0000000 0 2 + 2389 915043 0.0035259 1 2 + 2390 915044 0.0034181 1 2 + 2391 915045 0.0034913 1 2 + 2392 915046 0.0033863 1 2 + 2393 915047 0.0034605 1 2 + 2394 915048 0.0033369 1 2 + 2395 915049 0.0033952 1 2 + 2396 915050 0.0033419 1 2 + 2397 915051 0.0034441 1 2 + 2398 915052 0.0033443 1 2 + 2399 915053 0.0033803 1 2 + 2400 915054 0.0033289 1 2 + 2401 915055 0.0034190 1 2 + 2402 915056 0.0033215 1 2 + 2403 915057 0.0033734 1 2 + 2404 915058 0.0032995 1 2 + 2405 915059 0.0033824 1 2 + 2406 915060 0.0032673 1 2 + 2407 915061 0.0033293 1 2 + 2408 915062 0.0032556 1 2 + 2409 915063 0.0033203 1 2 + 2410 915064 0.0032176 1 2 + 2411 915065 0.0033174 1 2 + 2412 915066 0.0031937 1 2 + 2413 915067 0.0032719 1 2 + 2414 915068 0.0031562 1 2 + 2415 915069 0.0032456 1 2 + 2416 915070 0.0031332 1 2 + 2417 915071 0.0031814 1 2 + 2418 915072 0.0030990 1 2 + 2419 915073 0.0031843 1 2 + 2420 915074 0.0030801 1 2 + 2421 915075 0.0031829 1 2 + 2422 915076 0.0030810 1 2 + 2423 915077 0.0031397 1 2 + 2424 915078 0.0030485 1 2 + 2425 915079 0.0031512 1 2 + 2426 915080 0.0030298 1 2 + 2427 915081 0.0031008 1 2 + 2428 915082 0.0029977 1 2 + 2429 915083 0.0030246 1 2 + 2430 915084 0.0029369 1 2 + 2431 915085 0.0029995 1 2 + 2432 915086 0.0028994 1 2 + 2433 915087 0.0029417 1 2 + 2434 915088 0.0028616 1 2 + 2435 915089 0.0029336 1 2 + 2436 915090 0.0028544 1 2 + 2437 915091 0.0029079 1 2 + 2438 915092 0.0028382 1 2 + 2439 915093 0.0028865 1 2 + 2440 915094 0.0028010 1 2 + 2441 915095 0.0028700 1 2 + 2442 915096 0.0027905 1 2 + 2443 915097 0.0028608 1 2 + 2444 915098 0.0027379 1 2 + 2445 915099 0.0028289 1 2 + 2446 915100 0.0027271 1 2 + 2447 915101 0.0027823 1 2 + 2448 915102 0.0026680 1 2 + 2449 915103 0.0026991 1 2 + 2450 915104 0.0026567 1 2 + 2451 915105 0.0027472 1 2 + 2452 915106 0.0026411 1 2 + 2453 915107 0.0026961 1 2 + 2454 915108 0.0026007 1 2 + 2455 915109 0.0026639 1 2 + 2456 915110 0.0025651 1 2 + 2457 915111 0.0026130 1 2 + 2458 915112 0.0025402 1 2 + 2459 915113 0.0026076 1 2 + 2460 915114 0.0025143 1 2 + 2461 915115 0.0025748 1 2 + 2462 915116 0.0024974 1 2 + 2463 915117 0.0025790 1 2 + 2464 915118 0.0000000 0 2 + 2465 915119 0.0000000 0 2 + 2466 916000 0.0000000 0 2 + 2467 916001 0.0000000 0 2 + 2468 916002 0.0000000 0 2 + 2469 916003 0.0039947 1 2 + 2470 916004 0.0039848 1 2 + 2471 916005 0.0040814 1 2 + 2472 916006 0.0039844 1 2 + 2473 916007 0.0040137 1 2 + 2474 916008 0.0039602 1 2 + 2475 916009 0.0040504 1 2 + 2476 916010 0.0039271 1 2 + 2477 916011 0.0039722 1 2 + 2478 916012 0.0039028 1 2 + 2479 916013 0.0040588 1 2 + 2480 916014 0.0039318 1 2 + 2481 916015 0.0039531 1 2 + 2482 916016 0.0000000 0 2 + 2483 916017 0.0039819 1 2 + 2484 916018 0.0038749 1 2 + 2485 916019 0.0039018 1 2 + 2486 916020 0.0038421 1 2 + 2487 916021 0.0039204 1 2 + 2488 916022 0.0038189 1 2 + 2489 916023 0.0038995 1 2 + 2490 916024 0.0038129 1 2 + 2491 916025 0.0038507 1 2 + 2492 916026 0.0037578 1 2 + 2493 916027 0.0038265 1 2 + 2494 916028 0.0037352 1 2 + 2495 916029 0.0038140 1 2 + 2496 916030 0.0000000 0 2 + 2497 916031 0.0000000 0 2 + 2498 916032 0.0000000 0 2 + 2499 916033 0.0000000 0 2 + 2500 916034 0.0000000 0 2 + 2501 916035 0.0000000 0 2 + 2502 916036 0.0000000 0 2 + 2503 916037 0.0000000 0 2 + 2504 916038 0.0000000 0 2 + 2505 916039 0.0000000 0 2 + 2506 916040 0.0000000 0 2 + 2507 916041 0.0000000 0 2 + 2508 916042 0.0000000 0 2 + 2509 916043 0.0035259 1 2 + 2510 916044 0.0034181 1 2 + 2511 916045 0.0034913 1 2 + 2512 916046 0.0033863 1 2 + 2513 916047 0.0034605 1 2 + 2514 916048 0.0033369 1 2 + 2515 916049 0.0033952 1 2 + 2516 916050 0.0033419 1 2 + 2517 916051 0.0034441 1 2 + 2518 916052 0.0033443 1 2 + 2519 916053 0.0033803 1 2 + 2520 916054 0.0033289 1 2 + 2521 916055 0.0034190 1 2 + 2522 916056 0.0033215 1 2 + 2523 916057 0.0033734 1 2 + 2524 916058 0.0032995 1 2 + 2525 916059 0.0033824 1 2 + 2526 916060 0.0032673 1 2 + 2527 916061 0.0033293 1 2 + 2528 916062 0.0032556 1 2 + 2529 916063 0.0033203 1 2 + 2530 916064 0.0032176 1 2 + 2531 916065 0.0033174 1 2 + 2532 916066 0.0031937 1 2 + 2533 916067 0.0032719 1 2 + 2534 916068 0.0031562 1 2 + 2535 916069 0.0032456 1 2 + 2536 916070 0.0031332 1 2 + 2537 916071 0.0031814 1 2 + 2538 916072 0.0030990 1 2 + 2539 916073 0.0031843 1 2 + 2540 916074 0.0030801 1 2 + 2541 916075 0.0031829 1 2 + 2542 916076 0.0030810 1 2 + 2543 916077 0.0031397 1 2 + 2544 916078 0.0030485 1 2 + 2545 916079 0.0031512 1 2 + 2546 916080 0.0030298 1 2 + 2547 916081 0.0031008 1 2 + 2548 916082 0.0029977 1 2 + 2549 916083 0.0030246 1 2 + 2550 916084 0.0029369 1 2 + 2551 916085 0.0029995 1 2 + 2552 916086 0.0028994 1 2 + 2553 916087 0.0029417 1 2 + 2554 916088 0.0028616 1 2 + 2555 916089 0.0029336 1 2 + 2556 916090 0.0028544 1 2 + 2557 916091 0.0029079 1 2 + 2558 916092 0.0028382 1 2 + 2559 916093 0.0028865 1 2 + 2560 916094 0.0028010 1 2 + 2561 916095 0.0028700 1 2 + 2562 916096 0.0027905 1 2 + 2563 916097 0.0028608 1 2 + 2564 916098 0.0027379 1 2 + 2565 916099 0.0028289 1 2 + 2566 916100 0.0027271 1 2 + 2567 916101 0.0027823 1 2 + 2568 916102 0.0026680 1 2 + 2569 916103 0.0026991 1 2 + 2570 916104 0.0026567 1 2 + 2571 916105 0.0027472 1 2 + 2572 916106 0.0026411 1 2 + 2573 916107 0.0026961 1 2 + 2574 916108 0.0026007 1 2 + 2575 916109 0.0026639 1 2 + 2576 916110 0.0025651 1 2 + 2577 916111 0.0026130 1 2 + 2578 916112 0.0025402 1 2 + 2579 916113 0.0026076 1 2 + 2580 916114 0.0025143 1 2 + 2581 916115 0.0025748 1 2 + 2582 916116 0.0024974 1 2 + 2583 916117 0.0025790 1 2 + 2584 916118 0.0000000 0 2 + 2585 916119 0.0000000 0 2 + 2586 917000 0.0000000 0 2 + 2587 917001 0.0000000 0 2 + 2588 917002 0.0000000 0 2 + 2589 917003 0.0039947 1 2 + 2590 917004 0.0039848 1 2 + 2591 917005 0.0040814 1 2 + 2592 917006 0.0039844 1 2 + 2593 917007 0.0040137 1 2 + 2594 917008 0.0039602 1 2 + 2595 917009 0.0040504 1 2 + 2596 917010 0.0039271 1 2 + 2597 917011 0.0039722 1 2 + 2598 917012 0.0039028 1 2 + 2599 917013 0.0040588 1 2 + 2600 917014 0.0039318 1 2 + 2601 917015 0.0039531 1 2 + 2602 917016 0.0000000 0 2 + 2603 917017 0.0039819 1 2 + 2604 917018 0.0038749 1 2 + 2605 917019 0.0039018 1 2 + 2606 917020 0.0038421 1 2 + 2607 917021 0.0039204 1 2 + 2608 917022 0.0038189 1 2 + 2609 917023 0.0038995 1 2 + 2610 917024 0.0038129 1 2 + 2611 917025 0.0038507 1 2 + 2612 917026 0.0037578 1 2 + 2613 917027 0.0038265 1 2 + 2614 917028 0.0037352 1 2 + 2615 917029 0.0038140 1 2 + 2616 917030 0.0000000 0 2 + 2617 917031 0.0000000 0 2 + 2618 917032 0.0000000 0 2 + 2619 917033 0.0000000 0 2 + 2620 917034 0.0000000 0 2 + 2621 917035 0.0000000 0 2 + 2622 917036 0.0000000 0 2 + 2623 917037 0.0000000 0 2 + 2624 917038 0.0000000 0 2 + 2625 917039 0.0000000 0 2 + 2626 917040 0.0000000 0 2 + 2627 917041 0.0000000 0 2 + 2628 917042 0.0000000 0 2 + 2629 917043 0.0035259 1 2 + 2630 917044 0.0034181 1 2 + 2631 917045 0.0034913 1 2 + 2632 917046 0.0033863 1 2 + 2633 917047 0.0034605 1 2 + 2634 917048 0.0033369 1 2 + 2635 917049 0.0033952 1 2 + 2636 917050 0.0033419 1 2 + 2637 917051 0.0034441 1 2 + 2638 917052 0.0033443 1 2 + 2639 917053 0.0033803 1 2 + 2640 917054 0.0033289 1 2 + 2641 917055 0.0034190 1 2 + 2642 917056 0.0033215 1 2 + 2643 917057 0.0033734 1 2 + 2644 917058 0.0032995 1 2 + 2645 917059 0.0033824 1 2 + 2646 917060 0.0032673 1 2 + 2647 917061 0.0033293 1 2 + 2648 917062 0.0032556 1 2 + 2649 917063 0.0033203 1 2 + 2650 917064 0.0032176 1 2 + 2651 917065 0.0033174 1 2 + 2652 917066 0.0031937 1 2 + 2653 917067 0.0032719 1 2 + 2654 917068 0.0031562 1 2 + 2655 917069 0.0032456 1 2 + 2656 917070 0.0031332 1 2 + 2657 917071 0.0031814 1 2 + 2658 917072 0.0030990 1 2 + 2659 917073 0.0031843 1 2 + 2660 917074 0.0030801 1 2 + 2661 917075 0.0031829 1 2 + 2662 917076 0.0030810 1 2 + 2663 917077 0.0031397 1 2 + 2664 917078 0.0030485 1 2 + 2665 917079 0.0031512 1 2 + 2666 917080 0.0030298 1 2 + 2667 917081 0.0031008 1 2 + 2668 917082 0.0029977 1 2 + 2669 917083 0.0030246 1 2 + 2670 917084 0.0029369 1 2 + 2671 917085 0.0029995 1 2 + 2672 917086 0.0028994 1 2 + 2673 917087 0.0029417 1 2 + 2674 917088 0.0028616 1 2 + 2675 917089 0.0029336 1 2 + 2676 917090 0.0028544 1 2 + 2677 917091 0.0029079 1 2 + 2678 917092 0.0028382 1 2 + 2679 917093 0.0028865 1 2 + 2680 917094 0.0028010 1 2 + 2681 917095 0.0028700 1 2 + 2682 917096 0.0027905 1 2 + 2683 917097 0.0028608 1 2 + 2684 917098 0.0027379 1 2 + 2685 917099 0.0028289 1 2 + 2686 917100 0.0027271 1 2 + 2687 917101 0.0027823 1 2 + 2688 917102 0.0026680 1 2 + 2689 917103 0.0026991 1 2 + 2690 917104 0.0026567 1 2 + 2691 917105 0.0027472 1 2 + 2692 917106 0.0026411 1 2 + 2693 917107 0.0026961 1 2 + 2694 917108 0.0026007 1 2 + 2695 917109 0.0026639 1 2 + 2696 917110 0.0025651 1 2 + 2697 917111 0.0026130 1 2 + 2698 917112 0.0025402 1 2 + 2699 917113 0.0026076 1 2 + 2700 917114 0.0025143 1 2 + 2701 917115 0.0025748 1 2 + 2702 917116 0.0024974 1 2 + 2703 917117 0.0025790 1 2 + 2704 917118 0.0000000 0 2 + 2705 917119 0.0000000 0 2 + 2706 10100 0.0000000 0 3 + 2707 10101 0.0000000 0 3 + 2708 10102 -0.0090601 1 3 + 2709 10103 -0.0056713 1 3 + 2710 10104 0.0000000 0 3 + 2711 10105 -0.0050900 1 3 + 2712 10106 0.0000000 0 3 + 2713 10107 -0.0014836 1 3 + 2714 10200 0.0000000 0 3 + 2715 10201 0.0000000 0 3 + 2716 10202 0.0006628 1 3 + 2717 10203 0.0012634 1 3 + 2718 10204 0.0000000 0 3 + 2719 10205 0.0005052 1 3 + 2720 10206 0.0026750 1 3 + 2721 10207 0.0017685 1 3 + 2722 10300 0.0032539 1 3 + 2723 10301 0.0106415 1 3 + 2724 10302 0.0000000 0 3 + 2725 10303 0.0041239 1 3 + 2726 10304 0.0044355 1 3 + 2727 10305 0.0038747 1 3 + 2728 10306 0.0043783 1 3 + 2729 10307 0.0043520 1 3 + 2730 10400 0.0000000 0 3 + 2731 10401 0.0000000 0 3 + 2732 10402 -0.0090601 1 3 + 2733 10403 -0.0056713 1 3 + 2734 10404 0.0000000 0 3 + 2735 10405 -0.0050900 1 3 + 2736 10406 0.0000000 0 3 + 2737 10407 -0.0014836 1 3 + 2738 10500 0.0000000 0 3 + 2739 10501 0.0000000 0 3 + 2740 10502 0.0006628 1 3 + 2741 10503 0.0012634 1 3 + 2742 10504 0.0000000 0 3 + 2743 10505 0.0005052 1 3 + 2744 10506 0.0026750 1 3 + 2745 10507 0.0017685 1 3 + 2746 10600 0.0032539 1 3 + 2747 10601 0.0106415 1 3 + 2748 10602 0.0000000 0 3 + 2749 10603 0.0041239 1 3 + 2750 10604 0.0044355 1 3 + 2751 10605 0.0038747 1 3 + 2752 10606 0.0043783 1 3 + 2753 10607 0.0043520 1 3 + 2754 10700 0.0000000 0 3 + 2755 10701 0.0000000 0 3 + 2756 10702 -0.0090601 1 3 + 2757 10703 -0.0056713 1 3 + 2758 10704 0.0000000 0 3 + 2759 10705 -0.0050900 1 3 + 2760 10706 0.0000000 0 3 + 2761 10707 -0.0014836 1 3 + 2762 10800 0.0000000 0 3 + 2763 10801 0.0000000 0 3 + 2764 10802 0.0006628 1 3 + 2765 10803 0.0012634 1 3 + 2766 10804 0.0000000 0 3 + 2767 10805 0.0005052 1 3 + 2768 10806 0.0026750 1 3 + 2769 10807 0.0017685 1 3 + 2770 10900 0.0032539 1 3 + 2771 10901 0.0106415 1 3 + 2772 10902 0.0000000 0 3 + 2773 10903 0.0041239 1 3 + 2774 10904 0.0044355 1 3 + 2775 10905 0.0038747 1 3 + 2776 10906 0.0043783 1 3 + 2777 10907 0.0043520 1 3 diff --git a/scripts/Diffraction/isis_powder/hrpd_routines/hrpd_algs.py b/scripts/Diffraction/isis_powder/hrpd_routines/hrpd_algs.py index d1fcda6b683030ab32bd421aae5a2b48f74911f8..923004c53a1fe1d34a4d048e40bec7287210ba0e 100644 --- a/scripts/Diffraction/isis_powder/hrpd_routines/hrpd_algs.py +++ b/scripts/Diffraction/isis_powder/hrpd_routines/hrpd_algs.py @@ -4,8 +4,7 @@ import mantid.simpleapi as mantid from isis_powder.hrpd_routines import hrpd_advanced_config from isis_powder.routines import common, absorb_corrections, sample_details, common_enums -from isis_powder.routines.run_details import create_run_details_object, \ - RunDetailsWrappedCommonFuncs, CustomFuncForRunDetails +from isis_powder.routines.run_details import create_run_details_object, get_cal_mapping_dict def calculate_van_absorb_corrections(ws_to_correct, multiple_scattering): @@ -71,38 +70,25 @@ def calculate_slab_absorb_corrections(ws_to_correct, sample_details_obj): def get_run_details(run_number_string, inst_settings, is_vanadium): - cal_mapping_callable = CustomFuncForRunDetails().add_to_func_chain( - user_function=RunDetailsWrappedCommonFuncs.get_cal_mapping_dict, - run_number_string=run_number_string, inst_settings=inst_settings) + # Drill down to relevant section + run_mapping_dict = get_cal_mapping_dict(run_number_string, inst_settings.cal_mapping_path) + inst_mode_dict = common.cal_map_dictionary_key_helper(run_mapping_dict, key=inst_settings.mode) + tof_window = common.cal_map_dictionary_key_helper(dictionary=inst_mode_dict, key=inst_settings.tof_window) - mapping_dict_callable = cal_mapping_callable.add_to_func_chain(user_function=hrpd_get_inst_mode, - inst_settings=inst_settings) + empty_run = _get_run_numbers_for_key(tof_window, key="empty_run_numbers") + vanadium_run = _get_run_numbers_for_key(tof_window, key="vanadium_run_numbers") - tof_dict_callable = mapping_dict_callable.add_to_func_chain(user_function=hrpd_get_tof_window, - inst_settings=inst_settings) - - err_message = "this must be under 'coupled' or 'decoupled' and the time of flight window eg 10-110." - empty_run_callable = tof_dict_callable.add_to_func_chain( - user_function=RunDetailsWrappedCommonFuncs.cal_dictionary_key_helper, key="empty_run_numbers", - append_to_error_message=err_message) - - vanadium_run_callable = tof_dict_callable.add_to_func_chain( - user_function=RunDetailsWrappedCommonFuncs.cal_dictionary_key_helper, key="vanadium_run_numbers", - append_to_error_message=err_message) + grouping_file_name = inst_settings.grouping_file_name return create_run_details_object(run_number_string=run_number_string, inst_settings=inst_settings, - is_vanadium_run=is_vanadium, empty_run_call=empty_run_callable, - vanadium_run_call=vanadium_run_callable) + is_vanadium_run=is_vanadium, empty_run_number=empty_run, + vanadium_string=vanadium_run, grouping_file_name=grouping_file_name) -def hrpd_get_inst_mode(forwarded_value, inst_settings): - cal_mapping = forwarded_value - return common.cal_map_dictionary_key_helper(dictionary=cal_mapping, key=inst_settings.mode) - - -def hrpd_get_tof_window(forwarded_value, inst_settings): - cal_mapping = forwarded_value - return common.cal_map_dictionary_key_helper(dictionary=cal_mapping, key=inst_settings.tof_window) +def _get_run_numbers_for_key(tof_dict, key): + err_message = "this must be under 'coupled' or 'decoupled' and the time of flight window eg 10-110." + return common.cal_map_dictionary_key_helper(tof_dict, key=key, + append_to_error_message=err_message) def process_vanadium_for_focusing(bank_spectra, spline_number): diff --git a/scripts/Diffraction/isis_powder/pearl.py b/scripts/Diffraction/isis_powder/pearl.py index 4d44606046d5eaecee7e81a2fbe4c67bc98125c6..ef5d8fc5fc4901c2431f94227741771b3e188916 100644 --- a/scripts/Diffraction/isis_powder/pearl.py +++ b/scripts/Diffraction/isis_powder/pearl.py @@ -140,8 +140,10 @@ class Pearl(AbstractInst): pearl_output.generate_and_save_focus_output(self, processed_spectra=processed_spectra, run_details=run_details, focus_mode=output_mode, attenuation_filepath=attenuation_path) - group_name = "PEARL" + str(run_details.output_run_string) - group_name += '_' + self._inst_settings.tt_mode + "-Results-D-Grp" + + group_name = "PEARL{0!s}_{1}{2}-Results-D-Grp" + mode = "_long" if self._inst_settings.long_mode else "" + group_name = group_name.format(run_details.output_run_string, self._inst_settings.tt_mode, mode) grouped_d_spacing = mantid.GroupWorkspaces(InputWorkspaces=output_spectra, OutputWorkspace=group_name) return grouped_d_spacing, None @@ -173,5 +175,4 @@ class Pearl(AbstractInst): absorb_ws=absorb_corrections) def _switch_long_mode_inst_settings(self, long_mode_on): - self._inst_settings.update_attributes(advanced_config=pearl_advanced_config.get_long_mode_dict(long_mode_on), - suppress_warnings=True) + self._inst_settings.update_attributes(advanced_config=pearl_advanced_config.get_long_mode_dict(long_mode_on)) diff --git a/scripts/Diffraction/isis_powder/pearl_routines/pearl_algs.py b/scripts/Diffraction/isis_powder/pearl_routines/pearl_algs.py index 125a3fc6f0a3218b3ce94b54d47231aa4953a594..eb7b48d542606a3b932d98087ad5347f57327e4a 100644 --- a/scripts/Diffraction/isis_powder/pearl_routines/pearl_algs.py +++ b/scripts/Diffraction/isis_powder/pearl_routines/pearl_algs.py @@ -3,7 +3,7 @@ from __future__ import (absolute_import, division, print_function) import mantid.simpleapi as mantid import isis_powder.routines.common as common -from isis_powder.routines.run_details import create_run_details_object, CustomFuncForRunDetails +from isis_powder.routines.run_details import create_run_details_object, get_cal_mapping_dict def attenuate_workspace(attenuation_file_path, ws_to_correct): @@ -64,21 +64,6 @@ def generate_vanadium_absorb_corrections(van_ws, output_filename): return absorb_ws -def get_run_details(run_number_string, inst_settings, is_vanadium_run): - spline_identifier = [inst_settings.tt_mode] - if inst_settings.long_mode: - spline_identifier.append("_long") - - grouping_file_name_callable = CustomFuncForRunDetails().add_to_func_chain( - user_function=_pearl_get_tt_grouping_file_name, - inst_settings=inst_settings) - - return create_run_details_object(run_number_string=run_number_string, inst_settings=inst_settings, - is_vanadium_run=is_vanadium_run, splined_name_list=spline_identifier, - grouping_file_name_call=grouping_file_name_callable, - van_abs_file_name=inst_settings.van_absorb_file) - - def _pearl_get_tt_grouping_file_name(inst_settings): tt_grouping_key = str(inst_settings.tt_mode).lower() + '_grouping' try: @@ -88,6 +73,29 @@ def _pearl_get_tt_grouping_file_name(inst_settings): return grouping_file_name +def _get_run_numbers_for_key(current_mode_run_numbers, key): + err_message = "this must be under the relevant Rietveld or PDF mode." + return common.cal_map_dictionary_key_helper(current_mode_run_numbers, key=key, + append_to_error_message=err_message) + + +def get_run_details(run_number_string, inst_settings, is_vanadium_run): + all_run_numbers = get_cal_mapping_dict(run_number_string, inst_settings.cal_mapping_path) + empty_runs = _get_run_numbers_for_key(current_mode_run_numbers=all_run_numbers, key="empty_run_numbers") + vanadium_runs = _get_run_numbers_for_key(current_mode_run_numbers=all_run_numbers, key="vanadium_run_numbers") + + grouping_file_name = _pearl_get_tt_grouping_file_name(inst_settings) + + spline_identifier = [inst_settings.tt_mode] + if inst_settings.long_mode: + spline_identifier.append("_long") + + return create_run_details_object(run_number_string=run_number_string, inst_settings=inst_settings, + is_vanadium_run=is_vanadium_run, splined_name_list=spline_identifier, + grouping_file_name=grouping_file_name, empty_run_number=empty_runs, + vanadium_string=vanadium_runs, van_abs_file_name=inst_settings.van_absorb_file) + + def normalise_ws_current(ws_to_correct, monitor_ws, spline_coeff, lambda_values, integration_range, ex_regions): processed_monitor_ws = mantid.ConvertUnits(InputWorkspace=monitor_ws, Target="Wavelength") processed_monitor_ws = mantid.CropWorkspace(InputWorkspace=processed_monitor_ws, diff --git a/scripts/Diffraction/isis_powder/polaris_routines/polaris_algs.py b/scripts/Diffraction/isis_powder/polaris_routines/polaris_algs.py index b14cc6c229531be6c6bb7c803aa44ad8bc6c3764..17b16008a4d36869532ebb2bda9cc59d36f532bd 100644 --- a/scripts/Diffraction/isis_powder/polaris_routines/polaris_algs.py +++ b/scripts/Diffraction/isis_powder/polaris_routines/polaris_algs.py @@ -4,8 +4,7 @@ import mantid.simpleapi as mantid from isis_powder.routines import absorb_corrections, common from isis_powder.routines.common_enums import WORKSPACE_UNITS -from isis_powder.routines.run_details import create_run_details_object, \ - CustomFuncForRunDetails, RunDetailsWrappedCommonFuncs +from isis_powder.routines.run_details import create_run_details_object, get_cal_mapping_dict from isis_powder.polaris_routines import polaris_advanced_config from six import PY3 @@ -21,32 +20,34 @@ def calculate_van_absorb_corrections(ws_to_correct, multiple_scattering, is_vana return ws_to_correct +def _get_run_numbers_for_key(current_mode_run_numbers, key): + err_message = "this must be under the relevant Rietveld or PDF mode." + return common.cal_map_dictionary_key_helper(current_mode_run_numbers, key=key, + append_to_error_message=err_message) + + +def _get_current_mode_dictionary(run_number_string, inst_settings): + mapping_dict = get_cal_mapping_dict(run_number_string, inst_settings.cal_mapping_path) + # Get the current mode "Rietveld" or "PDF" run numbers + return common.cal_map_dictionary_key_helper(mapping_dict, inst_settings.mode) + + def get_run_details(run_number_string, inst_settings, is_vanadium_run): - cal_mapping_callable = CustomFuncForRunDetails().add_to_func_chain( - user_function=RunDetailsWrappedCommonFuncs.get_cal_mapping_dict, run_number_string=run_number_string, - inst_settings=inst_settings - ).add_to_func_chain(user_function=polaris_get_chopper_config, inst_settings=inst_settings) + mode_run_numbers = _get_current_mode_dictionary(run_number_string, inst_settings) # Get empty and vanadium err_message = "this must be under the relevant Rietveld or PDF mode." - empty_run_callable = cal_mapping_callable.add_to_func_chain( - user_function=RunDetailsWrappedCommonFuncs.cal_dictionary_key_helper, key="empty_run_numbers", - append_to_error_message=err_message) + empty_runs = common.cal_map_dictionary_key_helper(mode_run_numbers, + key="empty_run_numbers", append_to_error_message=err_message) + vanadium_runs = common.cal_map_dictionary_key_helper(mode_run_numbers, key="vanadium_run_numbers", + append_to_error_message=err_message) - vanadium_run_callable = cal_mapping_callable.add_to_func_chain( - user_function=RunDetailsWrappedCommonFuncs.cal_dictionary_key_helper, key="vanadium_run_numbers", - append_to_error_message=err_message) + grouping_file_name = inst_settings.grouping_file_name return create_run_details_object(run_number_string=run_number_string, inst_settings=inst_settings, - is_vanadium_run=is_vanadium_run, empty_run_call=empty_run_callable, - vanadium_run_call=vanadium_run_callable) - - -def polaris_get_chopper_config(forwarded_value, inst_settings): - # Forwarded value should be a cal mapping - cal_mapping = forwarded_value - return common.cal_map_dictionary_key_helper(cal_mapping, inst_settings.mode) + is_vanadium_run=is_vanadium_run, empty_run_number=empty_runs, + vanadium_string=vanadium_runs, grouping_file_name=grouping_file_name) def process_vanadium_for_focusing(bank_spectra, mask_path, spline_number): diff --git a/scripts/Diffraction/isis_powder/routines/instrument_settings.py b/scripts/Diffraction/isis_powder/routines/instrument_settings.py index ab60bda9a291809f7f2bbde1b2a824f46bc6197a..b8d39c5720a7f7245187d69acdc98a9b1586d312 100644 --- a/scripts/Diffraction/isis_powder/routines/instrument_settings.py +++ b/scripts/Diffraction/isis_powder/routines/instrument_settings.py @@ -126,9 +126,12 @@ class InstrumentSettings(object): param_val = _check_value_is_in_enum(param_val, param_map.enum_class) # Does the attribute exist - has it changed and are we suppressing warnings + if not suppress_warnings: + previous_value = getattr(self, attribute_name) if hasattr(self, attribute_name) else None - if previous_value and previous_value != param_val: + if previous_value is not None and previous_value != param_val: + # Print warning of what we value we are replacing for which parameter warnings.warn("Replacing parameter: '" + str(param_map.ext_name) + "' which was previously set to: '" + str(getattr(self, attribute_name)) + "' with new value: '" + str(param_val) + "'") diff --git a/scripts/Diffraction/isis_powder/routines/run_details.py b/scripts/Diffraction/isis_powder/routines/run_details.py index 45079bbe066daa62d69a0e7f5a58f8e683a766ed..82a2bb6d6f8f641c27b14aec20d834332228becc 100644 --- a/scripts/Diffraction/isis_powder/routines/run_details.py +++ b/scripts/Diffraction/isis_powder/routines/run_details.py @@ -4,24 +4,24 @@ from isis_powder.routines import common, yaml_parser import os -def create_run_details_object(run_number_string, inst_settings, is_vanadium_run, empty_run_call=None, - grouping_file_name_call=None, vanadium_run_call=None, - splined_name_list=None, van_abs_file_name=None): +def create_run_details_object(run_number_string, inst_settings, is_vanadium_run, empty_run_number, + grouping_file_name, vanadium_string, splined_name_list=None, van_abs_file_name=None): """ Creates and returns a run details object which holds various properties about the current run. :param run_number_string: The user string for the current run :param inst_settings: The current instrument object :param is_vanadium_run: Boolean of if the current run is a vanadium run - :param empty_run_call: (Optional) Callable to setup custom empty run number(s) from mapping file - :param grouping_file_name_call: (Optional) Callable to setup custom grouping file name - :param vanadium_run_call: (Optional) Callable to setup custom van run number(s) from mapping file + :param empty_run_number: Empty run number(s) from mapping file + :param grouping_file_name: Filename of the grouping file found in the calibration folder + :param vanadium_string: Vanadium run number(s) from mapping file :param splined_name_list: (Optional) List of unique properties to generate a splined vanadium name from :param van_abs_file_name: (Optional) The name of the vanadium absorption file :return: RunDetails object with attributes set to applicable values """ - cal_map_dict = RunDetailsWrappedCommonFuncs.get_cal_mapping_dict( - run_number_string=run_number_string, inst_settings=inst_settings) + cal_map_dict = get_cal_mapping_dict(run_number_string=run_number_string, + cal_mapping_path=inst_settings.cal_mapping_path) + run_number = common.get_first_run_number(run_number_string=run_number_string) # Get names of files we will be using @@ -29,29 +29,18 @@ def create_run_details_object(run_number_string, inst_settings, is_vanadium_run, label = common.cal_map_dictionary_key_helper(dictionary=cal_map_dict, key="label") offset_file_name = common.cal_map_dictionary_key_helper(dictionary=cal_map_dict, key="offset_file_name") - # Always make sure the offset file name is included - if splined_name_list: - # Force Python to make a copy so we don't modify original - new_splined_list = list(splined_name_list) - new_splined_list.append(os.path.basename(offset_file_name)) - else: - new_splined_list = [os.path.basename(offset_file_name)] - - # These can either be generic or custom so defer to another method - results_dict = _get_customisable_attributes( - cal_dict=cal_map_dict, inst_settings=inst_settings, empty_run_call=empty_run_call, - grouping_name_call=grouping_file_name_call, vanadium_run_call=vanadium_run_call, - splined_name_list=new_splined_list) + # Prepend the properties used for creating a van spline so we can fingerprint the file + new_splined_list = splined_name_list if splined_name_list else [] + new_splined_list.append(os.path.basename(offset_file_name)) - vanadium_run_string = results_dict["vanadium_runs"] + splined_van_name = common.generate_splined_name(vanadium_string, new_splined_list) + unsplined_van_name = common.generate_unsplined_name(vanadium_string, new_splined_list) if is_vanadium_run: # The run number should be the vanadium number in this case - run_number = vanadium_run_string - output_run_string = vanadium_run_string - else: - # Otherwise set it to the user input - output_run_string = run_number_string + run_number = vanadium_string + + output_run_string = vanadium_string if is_vanadium_run else run_number_string # Get the file extension if set file_extension = getattr(inst_settings, "file_extension") @@ -65,124 +54,32 @@ def create_run_details_object(run_number_string, inst_settings, is_vanadium_run, # Sample empty if there is one as this is instrument specific sample_empty = getattr(inst_settings, "sample_empty", None) - # Generate the paths - grouping_file_path = os.path.join(calibration_dir, results_dict["grouping_file_name"]) - - # By default, offset file sits in correct label folder, but it can also be given as an absolute path + # By default, offset file sits in the calibration folder, but it can also be given as an absolute path if os.path.exists(offset_file_name): offset_file_path = offset_file_name else: offset_file_path = os.path.join(calibration_dir, label, offset_file_name) - # splined vanadium is within the correct label folder - splined_van_path = os.path.join(calibration_dir, label, results_dict["splined_van_name"]) - unsplined_van_path = os.path.join(calibration_dir, label, results_dict["unsplined_van_name"]) + # Generate the paths + grouping_file_path = os.path.join(calibration_dir, grouping_file_name) + splined_van_path = os.path.join(calibration_dir, label, splined_van_name) + unsplined_van_path = os.path.join(calibration_dir, label, unsplined_van_name) van_absorb_path = os.path.join(calibration_dir, van_abs_file_name) if van_abs_file_name else None - return _RunDetails(empty_run_number=results_dict["empty_runs"], file_extension=file_extension, + return _RunDetails(empty_run_number=empty_run_number, file_extension=file_extension, run_number=run_number, output_run_string=output_run_string, label=label, offset_file_path=offset_file_path, grouping_file_path=grouping_file_path, - splined_vanadium_path=splined_van_path, vanadium_run_number=vanadium_run_string, + splined_vanadium_path=splined_van_path, vanadium_run_number=vanadium_string, sample_empty=sample_empty, vanadium_abs_path=van_absorb_path, unsplined_vanadium_path=unsplined_van_path, output_suffix=suffix) -def _get_customisable_attributes(cal_dict, inst_settings, empty_run_call, grouping_name_call, vanadium_run_call, - splined_name_list): - dict_to_return = {} - if empty_run_call: - empty_runs = empty_run_call.get_result() - else: - empty_runs = common.cal_map_dictionary_key_helper(dictionary=cal_dict, key="empty_run_numbers") - dict_to_return["empty_runs"] = empty_runs - - if vanadium_run_call: - vanadium_runs = vanadium_run_call.get_result() - else: - vanadium_runs = common.cal_map_dictionary_key_helper(dictionary=cal_dict, key="vanadium_run_numbers") - dict_to_return["vanadium_runs"] = vanadium_runs - - if grouping_name_call: - grouping_name = grouping_name_call.get_result() - else: - grouping_name = inst_settings.grouping_file_name - dict_to_return["grouping_file_name"] = grouping_name - - dict_to_return["splined_van_name"] = common.generate_splined_name(vanadium_runs, splined_name_list) - dict_to_return["unsplined_van_name"] = common.generate_unsplined_name(vanadium_runs, splined_name_list) - - return dict_to_return - - -class RunDetailsWrappedCommonFuncs(object): - """ - Creates a compatible signature when using custom functions when - constructing RunDetails objects and calls the common methods underneath. - """ - @staticmethod - def get_cal_mapping_dict(run_number_string, inst_settings): - # Get the python dictionary from the YAML mapping - run_number = common.get_first_run_number(run_number_string=run_number_string) - cal_mapping_dict = yaml_parser.get_run_dictionary(run_number_string=run_number, - file_path=inst_settings.cal_mapping_path) - return cal_mapping_dict - - @staticmethod - def cal_dictionary_key_helper(key, append_to_error_message=None, **kwargs): - dictionary = kwargs.pop("forwarded_value") - return common.cal_map_dictionary_key_helper(dictionary=dictionary, key=key, - append_to_error_message=append_to_error_message) - - -class CustomFuncForRunDetails(object): - # Holds a callable method, associated args and return value so we can pass it in - # as a single method - - def __init__(self, user_function=None, *args, **func_kwargs): - if args: - # If we allow args with position Python gets confused as the forwarded value can be in the first place too - raise RuntimeError("Cannot use un-named arguments with callable methods") - - self.user_function = user_function - self.function_kwargs = func_kwargs - - self._previous_callable = None - self._returned_value = None - self._function_is_executed = False - - def _exec_func(self): - forwarded_value = self._previous_callable.get_result() if self._previous_callable else None - - if not self.user_function: - # We maybe are the 0th case just return any values we hold - return forwarded_value - - if forwarded_value: - self.function_kwargs["forwarded_value"] = forwarded_value - self._returned_value = self.user_function(**self.function_kwargs) - else: - self._returned_value = self.user_function(**self.function_kwargs) - - self._function_is_executed = True - - def _set_previous_callable(self, previous_callable): - if not previous_callable: - return None - elif not isinstance(previous_callable, CustomFuncForRunDetails): - raise ValueError("Previous callable is not a CustomFuncForRunDetails type") - - self._previous_callable = previous_callable - - def add_to_func_chain(self, user_function, *args, **func_kwargs): - # Construct a new object that will be the next in line - next_in_chain = CustomFuncForRunDetails(user_function=user_function, *args, **func_kwargs) - next_in_chain._set_previous_callable(self) - return next_in_chain - - def get_result(self): - if not self._function_is_executed: - self._exec_func() - return self._returned_value +def get_cal_mapping_dict(run_number_string, cal_mapping_path): + # Get the python dictionary from the YAML mapping + run_number = common.get_first_run_number(run_number_string=run_number_string) + cal_mapping_dict = yaml_parser.get_run_dictionary(run_number_string=run_number, + file_path=cal_mapping_path) + return cal_mapping_dict class _RunDetails(object): diff --git a/scripts/test/ISISPowderAbstractInstrumentTest.py b/scripts/test/ISISPowderAbstractInstrumentTest.py index bfaf0946e50432edb3f2d37ae379a2b8a25022b0..233ab828e01c08cacaf1fc03559ff600bced8de7 100644 --- a/scripts/test/ISISPowderAbstractInstrumentTest.py +++ b/scripts/test/ISISPowderAbstractInstrumentTest.py @@ -5,9 +5,11 @@ import mantid from isis_powder.abstract_inst import AbstractInst from isis_powder.routines.instrument_settings import InstrumentSettings from isis_powder.routines.param_map_entry import ParamMapEntry -from isis_powder.routines import run_details +from isis_powder.routines import common, run_details, yaml_parser import os +import random +import string import tempfile import unittest import warnings @@ -30,11 +32,13 @@ class ISISPowderAbstractInstrumentTest(unittest.TestCase): self.fail("Could not find file \"{}\"".format(name)) return full_path - def _setup_mock_inst(self, calibration_dir, output_dir, suffix=None): + def _setup_mock_inst(self, yaml_file_path, calibration_dir, output_dir, suffix=None): calib_file_path = self._find_file_or_die(self.CALIB_FILE_NAME) grouping_file_path = self._find_file_or_die(self.GROUPING_FILE_NAME) - - return _MockInst(group_file=grouping_file_path, cal_dir=calibration_dir, + test_configuration_path = mantid.api.FileFinder.getFullPath(yaml_file_path) + if not test_configuration_path or len(test_configuration_path) <= 0: + self.fail("Could not find the unit test input file called: " + str(yaml_file_path)) + return _MockInst(cal_file_path=test_configuration_path, group_file=grouping_file_path, cal_dir=calibration_dir, out_dir=output_dir, cal_map=calib_file_path, suffix=suffix) def tearDown(self): @@ -49,11 +53,24 @@ class ISISPowderAbstractInstrumentTest(unittest.TestCase): cal_dir = self._create_temp_dir() out_dir = self._create_temp_dir() - mock_inst = self._setup_mock_inst(suffix="-suf", calibration_dir=cal_dir, output_dir=out_dir) + mock_inst = self._setup_mock_inst(suffix="-suf", yaml_file_path="ISISPowderRunDetailsTest.yaml", + calibration_dir=cal_dir, output_dir=out_dir) run_number = 15 + run_number2 = common.get_first_run_number(run_number_string=run_number) + cal_mapping_dict = yaml_parser.get_run_dictionary(run_number_string=run_number2, + file_path=mock_inst.cal_mapping_path) + + grouping_filename = _gen_random_string() + empty_runs = common.cal_map_dictionary_key_helper(dictionary=cal_mapping_dict, key="empty_run_numbers") + vanadium_runs = common.cal_map_dictionary_key_helper(dictionary=cal_mapping_dict, key="vanadium_run_numbers") + run_details_obj = run_details.create_run_details_object(run_number_string=run_number, inst_settings=mock_inst._inst_settings, - is_vanadium_run=False) + is_vanadium_run=False, + grouping_file_name=grouping_filename, + empty_run_number=empty_runs, + vanadium_string=vanadium_runs) + output_paths = mock_inst._generate_out_file_paths(run_details=run_details_obj) expected_nxs_filename = os.path.join(out_dir, @@ -66,7 +83,9 @@ class ISISPowderAbstractInstrumentTest(unittest.TestCase): # Setup basic instrument mock cal_dir = self._create_temp_dir() out_dir = self._create_temp_dir() - mock_inst = self._setup_mock_inst(calibration_dir=cal_dir, output_dir=out_dir) + mock_inst = self._setup_mock_inst(calibration_dir=cal_dir, output_dir=out_dir, + yaml_file_path="ISISPowderRunDetailsTest.yaml" + ) # Test valid parameters are retained mock_inst.set_beam_parameters(height=1.234, width=2) @@ -77,7 +96,8 @@ class ISISPowderAbstractInstrumentTest(unittest.TestCase): # Setup basic instrument mock cal_dir = self._create_temp_dir() out_dir = self._create_temp_dir() - mock_inst = self._setup_mock_inst(calibration_dir=cal_dir, output_dir=out_dir) + mock_inst = self._setup_mock_inst(calibration_dir=cal_dir, output_dir=out_dir, + yaml_file_path="ISISPowderRunDetailsTest.yaml") # Test combination of positive / negative raise exceptions self.assertRaises(ValueError, mock_inst.set_beam_parameters, height=1.234, width=-2) @@ -89,6 +109,10 @@ class ISISPowderAbstractInstrumentTest(unittest.TestCase): self.assertRaises(ValueError, mock_inst.set_beam_parameters, height=-1.234, width=True) +def _gen_random_string(): + return ''.join(random.choice(string.ascii_lowercase) for _ in range(10)) + + class _MockInst(AbstractInst): _param_map = [ @@ -103,10 +127,11 @@ class _MockInst(AbstractInst): _advanced_config = {"user_name": "ISISPowderAbstractInstrumentTest"} INST_PREFIX = "MOCK" - def __init__(self, **kwargs): + def __init__(self, cal_file_path, **kwargs): self._inst_settings = InstrumentSettings(param_map=self._param_map, adv_conf_dict=self._advanced_config, kwargs=kwargs) + self.cal_mapping_path = cal_file_path super(_MockInst, self).__init__(user_name=self._inst_settings.user_name, calibration_dir=self._inst_settings.calibration_dir, diff --git a/scripts/test/ISISPowderRunDetailsTest.py b/scripts/test/ISISPowderRunDetailsTest.py index 305fd52c7c0d987787219b391996522f41e68ce9..a2ca430b060dd9a66ba4f9460cf81214c4be8989 100644 --- a/scripts/test/ISISPowderRunDetailsTest.py +++ b/scripts/test/ISISPowderRunDetailsTest.py @@ -1,14 +1,15 @@ from __future__ import (absolute_import, division, print_function) import mantid.api -import tempfile import os import random import string +import tempfile import unittest import warnings from isis_powder.routines import run_details +from isis_powder.routines import common, yaml_parser class ISISPowderInstrumentRunDetailsTest(unittest.TestCase): @@ -39,9 +40,17 @@ class ISISPowderInstrumentRunDetailsTest(unittest.TestCase): expected_offset_file_name = "offset_file_name" run_number_string = "17-18" mock_inst = self.setup_mock_inst_settings(yaml_file_path="ISISPowderRunDetailsTest.yaml") + run_number = common.get_first_run_number(run_number_string=run_number_string) + cal_mapping_dict = yaml_parser.get_run_dictionary(run_number_string=run_number, + file_path=mock_inst.cal_mapping_path) + + grouping_filename = mock_inst.grouping_file_name + empty_runs = common.cal_map_dictionary_key_helper(dictionary=cal_mapping_dict, key="empty_run_numbers") + vanadium_runs = common.cal_map_dictionary_key_helper(dictionary=cal_mapping_dict, key="vanadium_run_numbers") output_obj = run_details.create_run_details_object(run_number_string=run_number_string, inst_settings=mock_inst, - is_vanadium_run=False) + is_vanadium_run=False, grouping_file_name=grouping_filename, + empty_run_number=empty_runs, vanadium_string=vanadium_runs) self.assertEqual(output_obj.empty_runs, expected_empty_runs) self.assertEqual(output_obj.grouping_file_path, @@ -62,57 +71,43 @@ class ISISPowderInstrumentRunDetailsTest(unittest.TestCase): run_number_string = "17-18" expected_vanadium_runs = "11-12" mock_inst = self.setup_mock_inst_settings(yaml_file_path="ISISPowderRunDetailsTest.yaml") + run_number = common.get_first_run_number(run_number_string=run_number_string) + cal_mapping_dict = yaml_parser.get_run_dictionary(run_number_string=run_number, + file_path=mock_inst.cal_mapping_path) + + grouping_filename = mock_inst.grouping_file_name + empty_runs = common.cal_map_dictionary_key_helper(dictionary=cal_mapping_dict, key="empty_run_numbers") + vanadium_runs = common.cal_map_dictionary_key_helper(dictionary=cal_mapping_dict, key="vanadium_run_numbers") + output_obj = run_details.create_run_details_object(run_number_string=run_number_string, inst_settings=mock_inst, - is_vanadium_run=True) + is_vanadium_run=True, grouping_file_name=grouping_filename, + empty_run_number=empty_runs, vanadium_string=vanadium_runs) self.assertEqual(expected_vanadium_runs, output_obj.run_number) self.assertEqual(output_obj.vanadium_run_numbers, output_obj.run_number) self.assertEqual(expected_vanadium_runs, output_obj.output_run_string) - def test_callable_params_are_used(self): - # These attributes are based on a custom YAML file at the specified path - expected_label = "16_4" - expected_vanadium_runs = "11-12" - expected_empty_runs = "13-14" - expected_grouping_file_name = "grouping_file" - run_number_string = "17-18" - mock_inst = self.setup_mock_inst_settings(yaml_file_path="ISISPowderRunDetailsTestCallable.yaml") - - # Get the YAML file as a dict first - wrapped_funcs = run_details.RunDetailsWrappedCommonFuncs - - yaml_callable = run_details.CustomFuncForRunDetails(user_function=wrapped_funcs.get_cal_mapping_dict, - run_number_string=run_number_string, - inst_settings=mock_inst) - - empty_callable = yaml_callable.add_to_func_chain(user_function=wrapped_funcs.cal_dictionary_key_helper, - key="custom_empty_run_numbers") - vanadium_callable = yaml_callable.add_to_func_chain(user_function=wrapped_funcs.cal_dictionary_key_helper, - key="custom_vanadium_run_numbers") - grouping_callable = run_details.CustomFuncForRunDetails(user_function=lambda: expected_grouping_file_name) - output_obj = run_details.create_run_details_object(run_number_string=run_number_string, inst_settings=mock_inst, - is_vanadium_run=True, empty_run_call=empty_callable, - vanadium_run_call=vanadium_callable, - grouping_file_name_call=grouping_callable) - - self.assertEqual(output_obj.label, expected_label) - self.assertEqual(output_obj.empty_runs, expected_empty_runs) - self.assertEqual(output_obj.grouping_file_path, - os.path.join(mock_inst.calibration_dir, expected_grouping_file_name)) - self.assertEqual(output_obj.vanadium_run_numbers, expected_vanadium_runs) - self.assertEqual(output_obj.run_number, expected_vanadium_runs) - def test_run_details_splined_name_list_is_used(self): expected_vanadium_runs = "11-12" - expected_offset_file_name = "offset_file_name" splined_name_list = ["bar", "bang", "baz"] + run_number_string = "10" mock_inst = self.setup_mock_inst_settings(yaml_file_path="ISISPowderRunDetailsTest.yaml") - output_obj = run_details.create_run_details_object(run_number_string=10, inst_settings=mock_inst, - is_vanadium_run=False, splined_name_list=splined_name_list) + run_number = common.get_first_run_number(run_number_string=run_number_string) + cal_mapping_dict = yaml_parser.get_run_dictionary(run_number_string=run_number, + file_path=mock_inst.cal_mapping_path) + + grouping_filename = mock_inst.grouping_file_name + empty_runs = common.cal_map_dictionary_key_helper(dictionary=cal_mapping_dict, key="empty_run_numbers") + vanadium_runs = common.cal_map_dictionary_key_helper(dictionary=cal_mapping_dict, key="vanadium_run_numbers") + + output_obj = run_details.create_run_details_object(run_number_string, inst_settings=mock_inst, + is_vanadium_run=False, splined_name_list=splined_name_list, + grouping_file_name=grouping_filename, + empty_run_number=empty_runs, vanadium_string=vanadium_runs) expected_splined_out_str = ''.join('_' + val for val in splined_name_list) expected_output_name = "VanSplined_" + expected_vanadium_runs + expected_splined_out_str - expected_output_name += '_' + expected_offset_file_name + ".nxs" + expected_output_name += ".nxs" expected_path = os.path.join(mock_inst.calibration_dir, output_obj.label, expected_output_name) self.assertEqual(expected_path, output_obj.splined_vanadium_file_path) @@ -123,11 +118,18 @@ class MockInstSettings(object): self.cal_mapping_path = cal_file_path self.grouping_file_name = MockInstSettings.gen_random_string() self.file_extension = MockInstSettings.gen_random_string() + self.mode = "PDF" @staticmethod def gen_random_string(): return ''.join(random.choice(string.ascii_lowercase) for _ in range(10)) +def _get_current_mode_dictionary(run_number_string, inst_settings): + mapping_dict = run_details.get_cal_mapping_dict(run_number_string, inst_settings.cal_mapping_path) + # Get the current mode "Rietveld" or "PDF" run numbers + return common.cal_map_dictionary_key_helper(mapping_dict, inst_settings.mode) + + if __name__ == "__main__": unittest.main() diff --git a/scripts/test/Muon/FFTPresenter_test.py b/scripts/test/Muon/FFTPresenter_test.py index 846fd9886c1674570ac08b0205556035121c6b16..d3352a648b69539eaab573c1561c6b1dea71c8cd 100644 --- a/scripts/test/Muon/FFTPresenter_test.py +++ b/scripts/test/Muon/FFTPresenter_test.py @@ -28,6 +28,8 @@ class FFTPresenterTest(unittest.TestCase): self.view.phaseCheckSignal = mock.Mock(return_value=True) # needed for connect in presenter self.view.buttonSignal = mock.Mock() + self.view.tableClickSignal = mock.Mock() + self.view.phaseCheckSignal = mock.Mock() self.view.changed = mock.MagicMock() self.view.changedHideUnTick = mock.MagicMock() self.view.initFFTInput = mock.Mock( @@ -74,9 +76,19 @@ class FFTPresenterTest(unittest.TestCase): row, col = self.view.tableClickSignal() self.presenter.tableClicked(row, col) + def test_connects(self): + assert(self.view.tableClickSignal.connect.call_count==1) + self.view.tableClickSignal.connect.assert_called_with(self.presenter.tableClicked) + + assert(self.view.buttonSignal.connect.call_count==1) + self.view.buttonSignal.connect.assert_called_with(self.presenter.handleButton) + + assert(self.view.phaseCheckSignal.connect.call_count==1) + self.view.phaseCheckSignal.connect.assert_called_with(self.presenter.phaseCheck) + def test_ImBox(self): - self.sendSignal() self.view.tableClickSignal = mock.Mock(return_value=[3, 1]) + self.sendSignal() assert(self.view.changedHideUnTick.call_count == 1) assert(self.view.changed.call_count == 0) diff --git a/scripts/test/Muon/MaxEntPresenter_test.py b/scripts/test/Muon/MaxEntPresenter_test.py index 15e73d7830bb285d7d63e94848c7f8dfa2e51e75..9ee81d594cc8206d028b9d03cab1fa1e32d3fc59 100644 --- a/scripts/test/Muon/MaxEntPresenter_test.py +++ b/scripts/test/Muon/MaxEntPresenter_test.py @@ -49,14 +49,25 @@ class MaxEntPresenterTest(unittest.TestCase): self.thread.threadWrapperSetup = mock.Mock() self.thread.threadWrapperTearDown = mock.Mock() - self.presenter.createThread=mock.Mock(return_value=self.thread) - self.presenter.createPhaseThread=mock.Mock(return_value=self.thread) + def test_connects(self): + assert(self.view.cancelSignal.connect.call_count==1) + self.view.cancelSignal.connect.assert_called_with(self.presenter.cancel) + + assert(self.view.maxEntButtonSignal.connect.call_count==1) + self.view.maxEntButtonSignal.connect.assert_called_with(self.presenter.handleMaxEntButton) + + assert(self.view.phaseSignal.connect.call_count==1) + self.view.phaseSignal.connect.assert_called_with(self.presenter.handlePhase) def test_button(self): + self.presenter.createThread = lambda *args:self.thread + self.presenter.handleMaxEntButton() assert(self.view.initMaxEntInput.call_count==1) assert(self.thread.start.call_count==1) + assert(self.thread.threadWrapperSetUp.call_count==1) + def test_dataHasChanged(self): self.load.hasDataChanged = mock.MagicMock(return_value=True) self.presenter.handleMaxEntButton() diff --git a/scripts/test/Muon/transformWidget_test.py b/scripts/test/Muon/transformWidget_test.py index 94c78456a0b014bf7f858b74453ef776cbe06b93..1e92c0c6a42bb2c63a883e1b00977505ee5fc947 100644 --- a/scripts/test/Muon/transformWidget_test.py +++ b/scripts/test/Muon/transformWidget_test.py @@ -16,7 +16,7 @@ if sys.version_info.major == 3: else: import mock -class FFTTransformTest(unittest.TestCase): +class TransformTest(unittest.TestCase): def setUp(self): self._qapp = mock_widget.mockQapp() self.load= mock.create_autospec( load_utils.LoadUtils,spec_set=True)