diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/BoxController.h b/Code/Mantid/Framework/API/inc/MantidAPI/BoxController.h index 7c41027c5ab1ef0d9797c7cb0d02b40ae25ab401..434c1044199f832b258b8d89c1b3833799897574 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/BoxController.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/BoxController.h @@ -9,6 +9,7 @@ #include "MantidAPI/IBoxControllerIO.h" #include <nexus/NeXusFile.hpp> +#include <boost/optional.hpp> #include <vector> namespace Mantid { @@ -32,8 +33,8 @@ public: * @return BoxController instance */ BoxController(size_t nd) - : nd(nd), m_maxId(0), m_SplitThreshold(1024), m_numSplit(1), - m_fileIO(boost::shared_ptr<API::IBoxControllerIO>()) { + : nd(nd), m_maxId(0), m_SplitThreshold(1024), m_splitTopInto(boost::none), m_numSplit(1), m_numTopSplit(1), + m_fileIO(boost::shared_ptr<API::IBoxControllerIO>()) { // TODO: Smarter ways to determine all of these values m_maxDepth = 5; m_addingEvents_eventsPerTask = 1000; @@ -116,6 +117,19 @@ public: return m_splitInto[dim]; } + //----------------------------------------------------------------------------------- + /** Return into how many to split along a dimension for the top level + * + * @return the splits in each dimesion for the top level + */ + boost::optional<std::vector<size_t>> getSplitTopInto() const { + // if (dim >= nd) + // throw std::invalid_argument("BoxController::setSplitInto() called + // with too high of a dimension index."); + return m_splitTopInto; + } + + /// Return how many boxes (total) a MDGridBox will contain. size_t getNumSplit() const { return m_numSplit; } @@ -143,6 +157,25 @@ public: calcNumSplit(); } + + //----------------------------------------------------------------------------------- + /** Set the way splitting will be done for the top level + * + * @param dim :: dimension to set + * @param num :: amount in which to split + */ + void setSplitTopInto(size_t dim, size_t num) { + if (dim >= nd) + throw std::invalid_argument("BoxController::setSplitTopInto() called with " + "too high of a dimension index."); + // If the vector is not created, then create it + if (!m_splitTopInto) { + m_splitTopInto = std::vector<size_t>(nd,1); + } + m_splitTopInto.get()[dim] = num; + calcNumTopSplit(); + } + //----------------------------------------------------------------------------------- /** When adding events, how many events per task should be done? * @@ -257,7 +290,19 @@ public: m_numMDBoxes[depth]--; } m_numMDGridBoxes[depth]++; + + // We need to account for optional top level splitting + if (depth == 0 && m_splitTopInto) { + + size_t numSplitTop = 1; + for (size_t d = 0; d < m_splitTopInto.get().size(); d++) + numSplitTop *= m_splitTopInto.get()[d]; + + m_numMDBoxes[depth + 1] += numSplitTop; + } + else { m_numMDBoxes[depth + 1] += m_numSplit; + } m_mutexNumMDBoxes.unlock(); } @@ -359,13 +404,32 @@ private: resetMaxNumBoxes(); } + /// When you split an MDBox by force, it becomes this many sub boxes + void calcNumTopSplit() { + m_numTopSplit = 1; + for (size_t d = 0; d < nd; d++) { + m_numTopSplit *= m_splitTopInto.get()[d]; + } + /// And this changes the max # of boxes too + resetMaxNumBoxes(); + } + /// Calculate the vector of the max # of MDBoxes per level. void resetMaxNumBoxes() { // Now calculate the max # of boxes m_maxNumMDBoxes.resize(m_maxDepth + 1, 0); // Reset to 0 m_maxNumMDBoxes[0] = 1; for (size_t depth = 1; depth < m_maxNumMDBoxes.size(); depth++) - m_maxNumMDBoxes[depth] = m_maxNumMDBoxes[depth - 1] * double(m_numSplit); + { + if (depth ==1 && m_splitTopInto) + { + m_maxNumMDBoxes[depth] = m_maxNumMDBoxes[depth - 1] * double(m_numTopSplit); + } + else + { + m_maxNumMDBoxes[depth] = m_maxNumMDBoxes[depth - 1] * double(m_numSplit); + } + } } protected: @@ -406,9 +470,15 @@ private: /// Splitting # for all dimensions std::vector<size_t> m_splitInto; + /// Splittin # for all dimensions in the top level + boost::optional<std::vector<size_t>> m_splitTopInto; + /// When you split a MDBox, it becomes this many sub-boxes size_t m_numSplit; + /// When you split a top level MDBox by force, it becomes this many sub boxes + size_t m_numTopSplit; + /// For adding events tasks size_t m_addingEvents_eventsPerTask; diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/RemoteJobManagerFactory.h b/Code/Mantid/Framework/API/inc/MantidAPI/RemoteJobManagerFactory.h index ad47020a15114edea00c07822098f76e43a1a053..abd60bde318b5ba9ef1b8d92d0054586dc37de08 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/RemoteJobManagerFactory.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/RemoteJobManagerFactory.h @@ -115,7 +115,7 @@ typedef MANTID_API_DLL Mantid::Kernel::SingletonHolder< */ #define DECLARE_REMOTEJOBMANAGER(classname) \ namespace { \ - Mantid::Kernel::RegistrationHelper register_job_manger_##classname( \ + Mantid::Kernel::RegistrationHelper register_job_manager_##classname( \ ((Mantid::API::RemoteJobManagerFactory::Instance().subscribe<classname>( \ #classname)), \ 0)); \ diff --git a/Code/Mantid/Framework/API/src/BoxController.cpp b/Code/Mantid/Framework/API/src/BoxController.cpp index b7a1ffc301a3cef40480411163fe51e737840653..5b49ba41142d35346e32dcbb60a9eb67385acddb 100644 --- a/Code/Mantid/Framework/API/src/BoxController.cpp +++ b/Code/Mantid/Framework/API/src/BoxController.cpp @@ -7,7 +7,7 @@ #include <boost/algorithm/string.hpp> #include <boost/format.hpp> - +#include <boost/optional.hpp> #include <Poco/DOM/Attr.h> #include <Poco/DOM/AutoPtr.h> #include <Poco/DOM/Document.h> @@ -15,6 +15,7 @@ #include <Poco/DOM/DOMWriter.h> #include <Poco/DOM/Element.h> #include <Poco/DOM/Text.h> +#include <Poco/DOM/NodeList.h> using namespace Mantid::Kernel; using Mantid::Kernel::Strings::convert; @@ -36,7 +37,7 @@ BoxController *BoxController::clone() const { BoxController::BoxController(const BoxController &other) : nd(other.nd), m_maxId(other.m_maxId), m_SplitThreshold(other.m_SplitThreshold), m_maxDepth(other.m_maxDepth), - m_splitInto(other.m_splitInto), m_numSplit(other.m_numSplit), + m_splitInto(other.m_splitInto), m_splitTopInto(other.m_splitTopInto), m_numSplit(other.m_numSplit), m_addingEvents_eventsPerTask(other.m_addingEvents_eventsPerTask), m_addingEvents_numTasksPerBlock(other.m_addingEvents_numTasksPerBlock), m_numMDBoxes(other.m_numMDBoxes), @@ -67,6 +68,24 @@ bool BoxController::operator==(const BoxController &other) const { if (m_maxNumMDBoxes[i] != other.m_maxNumMDBoxes[i]) return false; } + + // Check top level splitting if they are set in both or not + if ((m_splitTopInto && !other.m_splitTopInto) || + (!m_splitTopInto && other.m_splitTopInto)) { + return false; + } + + if (m_splitTopInto && other.m_splitTopInto) { + if (m_splitTopInto.get().size() != other.m_splitTopInto.get().size()) { + return false; + } else { + for (size_t i = 0; i < m_splitTopInto.get().size(); i++) { + if (m_splitTopInto.get()[i] != other.m_splitTopInto.get()[i]) + return false; + } + } + } + // There are number of variables which are // 1) derived: // Number of events sitting in the boxes which should be split but are already @@ -146,6 +165,20 @@ std::string BoxController::toXMLString() const { element->appendChild(text); pBoxElement->appendChild(element); + element = pDoc->createElement("SplitTopInto"); + if (m_splitTopInto) + { + vecStr = Kernel::Strings::join(this->m_splitTopInto.get().begin(), + this->m_splitTopInto.get().end(), ","); + } + else + { + vecStr = ""; + } + text = pDoc->createTextNode(vecStr); + element->appendChild(text); + pBoxElement->appendChild(element); + element = pDoc->createElement("NumMDBoxes"); vecStr = Kernel::Strings::join(this->m_numMDBoxes.begin(), this->m_numMDBoxes.end(), ","); @@ -216,6 +249,20 @@ void BoxController::fromXMLString(const std::string &xml) { s = pBoxElement->getChildElement("SplitInto")->innerText(); this->m_splitInto = splitStringIntoVector<size_t>(s); + // Need to make sure that we handle box controllers which did not have the SplitTopInto + // attribute + Poco::XML::NodeList* nodes = pBoxElement->getElementsByTagName("SplitTopInto"); + if (nodes->length() > 0) { + s = pBoxElement->getChildElement("SplitTopInto")->innerText(); + if (s.empty()) { + this->m_splitTopInto = boost::none; + } else { + this->m_splitTopInto = splitStringIntoVector<size_t>(s); + } + } else { + this->m_splitTopInto = boost::none; + } + s = pBoxElement->getChildElement("NumMDBoxes")->innerText(); this->m_numMDBoxes = splitStringIntoVector<size_t>(s); @@ -223,6 +270,10 @@ void BoxController::fromXMLString(const std::string &xml) { this->m_numMDGridBoxes = splitStringIntoVector<size_t>(s); this->calcNumSplit(); + + if (m_splitTopInto) { + this->calcNumTopSplit(); + } } /** function clears the file-backed status of the box controller */ void BoxController::clearFileBacked() { diff --git a/Code/Mantid/Framework/API/test/BoxControllerTest.h b/Code/Mantid/Framework/API/test/BoxControllerTest.h index 0a6b46390458da4a290d8e4ef75acbfaf73ae195..96c479a8634b49e074cae1b878a76b0760260b42 100644 --- a/Code/Mantid/Framework/API/test/BoxControllerTest.h +++ b/Code/Mantid/Framework/API/test/BoxControllerTest.h @@ -7,8 +7,11 @@ #include "MantidTestHelpers/BoxControllerDummyIO.h" #include <cxxtest/TestSuite.h> #include <map> +#include <vector> #include <memory> +#include <stdexcept> #include <boost/make_shared.hpp> +#include <boost/optional.hpp> using namespace Mantid; using namespace Mantid::API; @@ -101,7 +104,26 @@ public: } } + void test_setSplitTopIntoWorksCorrectly() + { + BoxController sc(3); + sc.setSplitTopInto(0,10); + sc.setSplitTopInto(1,20); + sc.setSplitTopInto(2,30); + + boost::optional<std::vector<size_t>> splitTopInto = sc.getSplitTopInto(); + + TSM_ASSERT_EQUALS("Should have three dimensions", splitTopInto.get().size(), 3); + TSM_ASSERT_EQUALS("Should have a value of 10 in the first dimension", splitTopInto.get()[0], 10); + TSM_ASSERT_EQUALS("Should have a value of 20 in the second dimension", splitTopInto.get()[1], 20); + TSM_ASSERT_EQUALS("Should have a value of 30 in the third dimension", splitTopInto.get()[2], 30); + } + void test_setSplitTopIntoThrowsForWrongDimension() + { + BoxController sc(1); + TSM_ASSERT_THROWS("Should throw for setting a wrong dimension", sc.setSplitTopInto(1,10), std::invalid_argument); + } void doTest_numBoxes(BoxController & bc, size_t expectedNumEntries) { @@ -149,6 +171,58 @@ public: doTest_numBoxes(bc, 11); } + /// Make sure that the correct number of boxes are recorded when we use splitting + void test_trackNumBoxesWithTopLevelSplitting() + { + BoxController bc(2); + bc.setSplitInto(10); + + bc.setSplitTopInto(0,4); + bc.setSplitTopInto(1,12); + + // This includes a forced top level split and a subsequent split of two boxes + TSM_ASSERT_DELTA("The average depth should be 0", bc.getAverageDepth(), 0.0, 1e-5 ); + bc.trackNumBoxes(0); + TSM_ASSERT_DELTA("The average depth should be about 1", bc.getAverageDepth(), 1.0, 1e-5 ); + + bc.trackNumBoxes(1); + bc.trackNumBoxes(1); + + const std::vector<size_t> & num = bc.getNumMDBoxes(); + const std::vector<size_t> & numGridBoxes = bc.getNumMDGridBoxes(); + TSM_ASSERT_EQUALS("Should be 1 MDGridBox structure at the 0th level", numGridBoxes[0], 1); + TSM_ASSERT_EQUALS("Should be 48 - 2 MDBox structures at the 1st level", num[1], 46); + TSM_ASSERT_EQUALS("Should be 2 MDGridBox structure at the 1st level", numGridBoxes[1], 2); + TSM_ASSERT_EQUALS("Should be 2 * 100 MDBox structures at the 2nd level.", num[2], 200); + } + + void test_trackNumBoxesWithTopLevelSplittingAndSettingMaxDepth() + { + BoxController bc(2); + + bc.setMaxDepth(4); + bc.setSplitInto(10); + + bc.setSplitTopInto(0,4); + bc.setSplitTopInto(1,12); + bc.setMaxDepth(10); + + // This includes a forced top level split and a subsequent split of two boxes + TSM_ASSERT_DELTA("The average depth should be 0", bc.getAverageDepth(), 0.0, 1e-5 ); + bc.trackNumBoxes(0); + TSM_ASSERT_DELTA("The average depth should be about 1", bc.getAverageDepth(), 1.0, 1e-5 ); + + bc.trackNumBoxes(1); + bc.trackNumBoxes(1); + + const std::vector<size_t> & num = bc.getNumMDBoxes(); + const std::vector<size_t> & numGridBoxes = bc.getNumMDGridBoxes(); + TSM_ASSERT_EQUALS("Should be 1 MDGridBox structure at the 0th level", numGridBoxes[0], 1); + TSM_ASSERT_EQUALS("Should be 48 - 2 MDBox structures at the 1st level", num[1], 46); + TSM_ASSERT_EQUALS("Should be 2 MDGridBox structure at the 1st level", numGridBoxes[1], 2); + TSM_ASSERT_EQUALS("Should be 2 * 100 MDBox structures at the 2nd level.", num[2], 200); + } + /// Compare two box controllers and assert each part of them. void compareBoxControllers(BoxController & a, BoxController & b) { @@ -167,6 +241,19 @@ public: { TS_ASSERT_DIFFERS(a.getFileIO(),b.getFileIO()); } + + // Check for top level splitting + if (a.getSplitTopInto() && b.getSplitTopInto()) + { + for (size_t d=0; d < a.getNDims(); d++) + { + TS_ASSERT_EQUALS(a.getSplitTopInto().get()[d], b.getSplitTopInto().get()[d]); + } + } + else + { + TS_ASSERT_EQUALS(a.getSplitTopInto(), b.getSplitTopInto()); + } } /// Generate XML and read it back @@ -188,6 +275,26 @@ public: compareBoxControllers(a, b); } + void test_xmlWithSplitTopIntoBeingSet() + { + BoxController a(2); + a.setMaxDepth(4); + a.setSplitInto(10); + a.setMaxDepth(10); + a.setMaxId(123456); + TSM_ASSERT_THROWS_NOTHING("Should add the first dimension", a.setSplitTopInto(0,10)); + TSM_ASSERT_THROWS_NOTHING("Should add the second dimension", a.setSplitTopInto(1,20)); + + std::string xml = a.toXMLString(); + TS_ASSERT(!xml.empty()); + + // Read it back + BoxController b(2); + b.fromXMLString(xml); + // Check that it is the same + compareBoxControllers(a, b); + } + void test_Clone() { BoxController a(2); @@ -200,6 +307,21 @@ public: compareBoxControllers(a, *b); } + void test_CloneWithSplitTopIntoBeingSet() + { + BoxController a(2); + a.setMaxDepth(4); + a.setSplitInto(10); + a.setMaxDepth(10); + a.setMaxId(123456); + TSM_ASSERT_THROWS_NOTHING("Should add the first dimension", a.setSplitTopInto(0,10)); + TSM_ASSERT_THROWS_NOTHING("Should add the second dimension", a.setSplitTopInto(1,20)); + + auto b = BoxController_sptr(a.clone()); + // Check that settings are the same but BC are different + compareBoxControllers(a, *b); + } + void test_CloneFileBased() { auto a = boost::make_shared<BoxController>(2); @@ -222,9 +344,6 @@ public: // Check that settings are the same but BC are different compareBoxControllers(*a, *b); TS_ASSERT(b->isFileBacked()); - - - } void test_MRU_access() @@ -243,6 +362,9 @@ public: { // Check the constructor defaults. BoxController box_controller(2); + + boost::optional<std::vector<size_t>> splitTopInto = box_controller.getSplitTopInto(); + TS_ASSERT(!splitTopInto) TS_ASSERT_EQUALS(2, box_controller.getNDims()); TS_ASSERT_EQUALS(1, box_controller.getNumSplit()); TS_ASSERT_EQUALS(0, box_controller.getMaxId()); @@ -265,8 +387,6 @@ public: TS_ASSERT(!a->isFileBacked()); TSM_ASSERT("Box controller should now close the faked file",!pS->isOpened()); } - - }; #endif diff --git a/Code/Mantid/Framework/API/test/RemoteJobManagerFactoryTest.h b/Code/Mantid/Framework/API/test/RemoteJobManagerFactoryTest.h index c7d13a39dd953ae914ae71c28f9818ae3064bfdc..90153f606e93124b98a2dcd09ad6d8dfec268a55 100644 --- a/Code/Mantid/Framework/API/test/RemoteJobManagerFactoryTest.h +++ b/Code/Mantid/Framework/API/test/RemoteJobManagerFactoryTest.h @@ -9,107 +9,93 @@ using namespace Mantid::API; // Just a minimal implementation of IRemoteJobManager, sufficient for the // factory -class TestJM : public IRemoteJobManager { +// TODO: use gmock for this +class FakeJM : public IRemoteJobManager { public: - virtual void authenticate(const std::string &username, - const std::string &password) { - UNUSED_ARG(username); - UNUSED_ARG(password); - } - - virtual std::string - submitRemoteJob(const std::string &transactionID, const std::string &runnable, - const std::string ¶m, const std::string &taskName = "", - const int numNodes = 1, const int coresPerNode = 1) { - UNUSED_ARG(transactionID); - UNUSED_ARG(runnable); - UNUSED_ARG(param); - UNUSED_ARG(taskName); - UNUSED_ARG(numNodes); - UNUSED_ARG(coresPerNode); + virtual void authenticate(const std::string & /*username*/, + const std::string & /*password*/) {} + + virtual std::string submitRemoteJob(const std::string & /*transactionID*/, + const std::string & /*runnable*/, + const std::string & /*param*/, + const std::string & /*taskName*/ = "", + const int /*numNodes*/ = 1, + const int /*coresPerNode*/ = 1) { return ""; } - virtual void downloadRemoteFile(const std::string &transactionID, - const std::string &remoteFileName, - const std::string &localFileName) { - UNUSED_ARG(transactionID); - UNUSED_ARG(remoteFileName); - UNUSED_ARG(localFileName); - } + virtual void downloadRemoteFile(const std::string & /*transactionID*/, + const std::string & /*remoteFileName*/, + const std::string & /*localFileName*/) {} virtual std::vector<RemoteJobInfo> queryAllRemoteJobs() const { return std::vector<RemoteJobInfo>(); } virtual std::vector<std::string> - queryRemoteFile(const std::string &transactionID) const { - UNUSED_ARG(transactionID); + queryRemoteFile(const std::string & /*transactionID*/) const { return std::vector<std::string>(); } - virtual RemoteJobInfo queryRemoteJob(const std::string &jobID) const { - UNUSED_ARG(jobID); + virtual RemoteJobInfo queryRemoteJob(const std::string & /*jobID*/) const { return RemoteJobInfo(); } virtual std::string startRemoteTransaction() { return ""; } - virtual void stopRemoteTransaction(const std::string &transactionID) { - UNUSED_ARG(transactionID); - } + virtual void stopRemoteTransaction(const std::string & /*transactionID*/) {} - virtual void abortRemoteJob(const std::string &jobID) { UNUSED_ARG(jobID); } + virtual void abortRemoteJob(const std::string & /*jobID*/) {} - virtual void uploadRemoteFile(const std::string &transactionID, - const std::string &remoteFileName, - const std::string &localFileName) { - UNUSED_ARG(transactionID); - UNUSED_ARG(remoteFileName); - UNUSED_ARG(localFileName); - } + virtual void uploadRemoteFile(const std::string & /*transactionID*/, + const std::string & /*remoteFileName*/, + const std::string & /*localFileName*/) {} }; -class TestJMDeriv : public TestJM {}; +class FakeJMDeriv : public FakeJM {}; -class TestJM3 : public TestJMDeriv {}; +class FakeJM3 : public FakeJMDeriv {}; -DECLARE_REMOTEJOBMANAGER(TestJM) -DECLARE_REMOTEJOBMANAGER(TestJMDeriv) -DECLARE_REMOTEJOBMANAGER(TestJM3) +DECLARE_REMOTEJOBMANAGER(FakeJM) +DECLARE_REMOTEJOBMANAGER(FakeJMDeriv) +DECLARE_REMOTEJOBMANAGER(FakeJM3) class RemoteJobManagerFactoryTest : public CxxTest::TestSuite { public: void test_unsubscribeDeclared() { // subscribed with DECLARE_... TS_ASSERT_THROWS_NOTHING( - Mantid::API::RemoteJobManagerFactory::Instance().unsubscribe("TestJM")); + Mantid::API::RemoteJobManagerFactory::Instance().unsubscribe("FakeJM")); TS_ASSERT_THROWS_NOTHING( Mantid::API::RemoteJobManagerFactory::Instance().unsubscribe( - "TestJMDeriv")); + "FakeJMDeriv")); TS_ASSERT_THROWS_NOTHING( Mantid::API::RemoteJobManagerFactory::Instance().unsubscribe( - "TestJM3")); + "FakeJM3")); } void test_unsubscribed() { IRemoteJobManager_sptr jobManager; - TS_ASSERT_THROWS( + TSM_ASSERT_THROWS( + "create() with inexistent and unsubscribed class should " + "throw", jobManager = RemoteJobManagerFactory::Instance().create("Inexistent"), std::runtime_error); - TS_ASSERT_THROWS(jobManager = - RemoteJobManagerFactory::Instance().create("TestJM"), - std::runtime_error); + TSM_ASSERT_THROWS("create() with unsubscribed class should throw", + jobManager = + RemoteJobManagerFactory::Instance().create("FakeJM"), + std::runtime_error); } // minimal positive test - void test_createTestJM() { - TS_ASSERT_THROWS_NOTHING( - RemoteJobManagerFactory::Instance().subscribe<TestJM>("TestJM")); + void test_createFakeJM() { + RemoteJobManagerFactory::Instance().subscribe<FakeJM>("FakeJM"); // throws not found cause it is not in facilities.xml, but otherwise fine - TS_ASSERT_THROWS( - jm = Mantid::API::RemoteJobManagerFactory::Instance().create("TestJM"), + TSM_ASSERT_THROWS( + "create() with class name that is not defined in facilities should " + "throw", + jm = Mantid::API::RemoteJobManagerFactory::Instance().create("FakeJM"), Mantid::Kernel::Exception::NotFoundError); } @@ -117,46 +103,46 @@ public: // a bit of stress, unsubscribe after being subscribed with DECLARE_..., // then subscribe and the unsubscribe again TS_ASSERT_THROWS_NOTHING( - Mantid::API::RemoteJobManagerFactory::Instance().unsubscribe("TestJM")); + Mantid::API::RemoteJobManagerFactory::Instance().unsubscribe("FakeJM")); TS_ASSERT_THROWS_NOTHING( - Mantid::API::RemoteJobManagerFactory::Instance().subscribe<TestJM>( - "TestJM")); + Mantid::API::RemoteJobManagerFactory::Instance().subscribe<FakeJM>( + "FakeJM")); std::vector<std::string> keys = Mantid::API::RemoteJobManagerFactory::Instance().getKeys(); size_t count = keys.size(); TS_ASSERT_THROWS( - Mantid::API::RemoteJobManagerFactory::Instance().subscribe<TestJM>( - "TestJM"), + Mantid::API::RemoteJobManagerFactory::Instance().subscribe<FakeJM>( + "FakeJM"), std::runtime_error); TS_ASSERT_THROWS_NOTHING( - Mantid::API::RemoteJobManagerFactory::Instance().unsubscribe("TestJM")); + Mantid::API::RemoteJobManagerFactory::Instance().unsubscribe("FakeJM")); TS_ASSERT_THROWS_NOTHING( - Mantid::API::RemoteJobManagerFactory::Instance().subscribe<TestJM>( - "TestJM")); + Mantid::API::RemoteJobManagerFactory::Instance().subscribe<FakeJM>( + "FakeJM")); TS_ASSERT_THROWS_NOTHING( - Mantid::API::RemoteJobManagerFactory::Instance().subscribe<TestJMDeriv>( - "TestJMDeriv")); + Mantid::API::RemoteJobManagerFactory::Instance().subscribe<FakeJMDeriv>( + "FakeJMDeriv")); TS_ASSERT_THROWS_NOTHING( - Mantid::API::RemoteJobManagerFactory::Instance().subscribe<TestJMDeriv>( - "TestJM3")); + Mantid::API::RemoteJobManagerFactory::Instance().subscribe<FakeJMDeriv>( + "FakeJM3")); TS_ASSERT( - Mantid::API::RemoteJobManagerFactory::Instance().exists("TestJM")); + Mantid::API::RemoteJobManagerFactory::Instance().exists("FakeJM")); TS_ASSERT( - Mantid::API::RemoteJobManagerFactory::Instance().exists("TestJMDeriv")); + Mantid::API::RemoteJobManagerFactory::Instance().exists("FakeJMDeriv")); TS_ASSERT( - Mantid::API::RemoteJobManagerFactory::Instance().exists("TestJM3")); + Mantid::API::RemoteJobManagerFactory::Instance().exists("FakeJM3")); // these are not in the facilities file TS_ASSERT_THROWS( - jm = Mantid::API::RemoteJobManagerFactory::Instance().create("TestJM"), + jm = Mantid::API::RemoteJobManagerFactory::Instance().create("FakeJM"), std::runtime_error); TS_ASSERT_THROWS( jm = Mantid::API::RemoteJobManagerFactory::Instance().create( - "TestJMDeriv"), + "FakeJMDeriv"), std::runtime_error); keys = Mantid::API::RemoteJobManagerFactory::Instance().getKeys(); @@ -165,13 +151,13 @@ public: TS_ASSERT_EQUALS(count + 2, after); TS_ASSERT_THROWS_NOTHING( - Mantid::API::RemoteJobManagerFactory::Instance().unsubscribe("TestJM")); + Mantid::API::RemoteJobManagerFactory::Instance().unsubscribe("FakeJM")); TS_ASSERT_THROWS_NOTHING( Mantid::API::RemoteJobManagerFactory::Instance().unsubscribe( - "TestJMDeriv")); + "FakeJMDeriv")); TS_ASSERT_THROWS_NOTHING( Mantid::API::RemoteJobManagerFactory::Instance().unsubscribe( - "TestJM3")); + "FakeJM3")); keys = Mantid::API::RemoteJobManagerFactory::Instance().getKeys(); size_t newCount = keys.size(); @@ -185,16 +171,19 @@ public: const Mantid::Kernel::FacilityInfo &prevFac = Mantid::Kernel::ConfigService::Instance().getFacility(); - Mantid::Kernel::ConfigService::Instance().setFacility("ISIS"); - TS_ASSERT_THROWS( - jm = Mantid::API::RemoteJobManagerFactory::Instance().create("Fermi"), + Mantid::Kernel::ConfigService::Instance().setFacility(ISISFac); + TSM_ASSERT_THROWS( + "create() with " + FermiName + "in a facility other than " + SNSFac + + " should fail", + jm = Mantid::API::RemoteJobManagerFactory::Instance().create(FermiName), Mantid::Kernel::Exception::NotFoundError); - Mantid::Kernel::ConfigService::Instance().setFacility("SNS"); - TS_ASSERT_THROWS( + Mantid::Kernel::ConfigService::Instance().setFacility(SNSFac); + TSM_ASSERT_THROWS( + "create() with " + SCARFName + "in a facility other than " + ISISFac + + " should fail", Mantid::API::IRemoteJobManager_sptr jobManager = - Mantid::API::RemoteJobManagerFactory::Instance().create( - "SCARF@STFC"), + Mantid::API::RemoteJobManagerFactory::Instance().create(SCARFName), Mantid::Kernel::Exception::NotFoundError); // restore facility, always do this at the end @@ -209,18 +198,26 @@ public: Mantid::Kernel::ConfigService::Instance().getFacility(); Mantid::Kernel::ConfigService::Instance().setFacility("SNS"); - // TODO: at the moment this throws a NotFoundError for Fermi - // because the RemoteJobManager class for the Mantid web service - // API is missing and there is no DECLARE_REMOTEJOBMANAGER for - // it. Change this (move to the MantidAPIWebServiceJobManager unit test) - // when that is done (ticket #11391 etc.) - TS_ASSERT_THROWS( + + // These two create should throw a NotFoundError because the + // RemoteJobManager classes are missing and have not done a + // DECLARE_REMOTEJOBMANAGER. A positive test is done in the tests + // of the job managers + TSM_ASSERT_THROWS( + "create() with " + FermiName + + " should throw because its job manager is not declared", Mantid::API::IRemoteJobManager_sptr jobManager = Mantid::API::RemoteJobManagerFactory::Instance().create("Fermi"), Mantid::Kernel::Exception::NotFoundError); - // Important: don't feel tempted to use this job manager, it will - // interact/send jobs to the actual cluster and will only work - // within SNS. + + Mantid::Kernel::ConfigService::Instance().setFacility("ISIS"); + TSM_ASSERT_THROWS( + "create() with " + SCARFName + + " should throw because its job manager is not declared", + Mantid::API::IRemoteJobManager_sptr jobManager = + Mantid::API::RemoteJobManagerFactory::Instance().create( + "SCARF@STFC"), + Mantid::Kernel::Exception::NotFoundError); // restore facility, always do this at the end Mantid::Kernel::ConfigService::Instance().setFacility(prevFac.name()); @@ -228,6 +225,16 @@ public: private: Mantid::API::IRemoteJobManager_sptr jm; + + static const std::string SNSFac; + static const std::string ISISFac; + static const std::string FermiName; + static const std::string SCARFName; }; +const std::string RemoteJobManagerFactoryTest::SNSFac = "SNS"; +const std::string RemoteJobManagerFactoryTest::ISISFac = "ISIS"; +const std::string RemoteJobManagerFactoryTest::FermiName = "Fermi"; +const std::string RemoteJobManagerFactoryTest::SCARFName = "SCARF@STFC"; + #endif /* REMOTEJOBMANAGERFACTORYTEST_H_ */ diff --git a/Code/Mantid/Framework/DataObjects/src/MDGridBox.cpp b/Code/Mantid/Framework/DataObjects/src/MDGridBox.cpp index 23d4223f503939e8c7876a1fe6b36b6c376b5153..ffbbbb5348b0136a4c05eb416a06582456fba397 100644 --- a/Code/Mantid/Framework/DataObjects/src/MDGridBox.cpp +++ b/Code/Mantid/Framework/DataObjects/src/MDGridBox.cpp @@ -10,6 +10,7 @@ #include "MantidDataObjects/MDEvent.h" #include "MantidDataObjects/MDGridBox.h" #include <boost/math/special_functions/round.hpp> +#include <boost/optional.hpp> #include <ostream> #include "MantidKernel/Strings.h" @@ -67,9 +68,18 @@ template <typename MDE, size_t nd> void MDGridBox<MDE, nd>::initGridBox() { "MDGridBox::ctor(): No BoxController specified in box."); // How many is it split? - for (size_t d = 0; d < nd; d++) + // If we are at the top level and we have a specific top level split, then set it. + boost::optional<std::vector<size_t>> splitTopInto = this->m_BoxController->getSplitTopInto(); + if (this->getDepth() == 0 && splitTopInto) + { + for (size_t d = 0; d < nd; d++) + split[d] = splitTopInto.get()[d]; + } + else + { + for (size_t d = 0; d < nd; d++) split[d] = this->m_BoxController->getSplitInto(d); - + } // Compute sizes etc. size_t tot = computeSizesFromSplit(); @@ -92,8 +102,18 @@ TMDE(MDGridBox)::MDGridBox(MDBox<MDE, nd> *box) // box->getNPoints() << " events into MDGridBox" << std::endl; // How many is it split? - for (size_t d = 0; d < nd; d++) + // If we are at the top level and we have a specific top level split, then set it. + boost::optional<std::vector<size_t>> splitTopInto = this->m_BoxController->getSplitTopInto(); + if (this->getDepth() == 0 && splitTopInto) + { + for (size_t d = 0; d < nd; d++) + split[d] = splitTopInto.get()[d]; + } + else + { + for (size_t d = 0; d < nd; d++) split[d] = this->m_BoxController->getSplitInto(d); + } // Compute sizes etc. size_t tot = computeSizesFromSplit(); @@ -192,7 +212,8 @@ TMDE(MDGridBox)::MDGridBox(const MDGridBox<MDE, nd> &other, Mantid::API::BoxController *const otherBC) : MDBoxBase<MDE, nd>(other, otherBC), numBoxes(other.numBoxes), diagonalSquared(other.diagonalSquared), nPoints(other.nPoints) { - for (size_t d = 0; d < nd; d++) { + for (size_t d = 0; d < nd; d++) + { split[d] = other.split[d]; splitCumul[d] = other.splitCumul[d]; m_SubBoxSize[d] = other.m_SubBoxSize[d]; diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/Group.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/Group.h index dba8a798bac88bbb80932ffb5edd1388f1e73432..0e7e562c557e102be9092f3716d62cc91351ad02 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/Group.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/Group.h @@ -3,6 +3,7 @@ #include "MantidGeometry/DllConfig.h" #include "MantidGeometry/Crystal/SymmetryOperation.h" +#include "MantidKernel/Tolerance.h" #include <vector> #include <set> @@ -13,6 +14,25 @@ namespace Mantid { namespace Geometry { +/// Functor for fuzzy comparison of V3D-objects using Kernel::Tolerance +struct MANTID_GEOMETRY_DLL FuzzyV3DLessThan { + bool operator()(const Kernel::V3D &lhs, const Kernel::V3D &rhs) { + if (fabs(lhs.X() - rhs.X()) > Kernel::Tolerance) { + return lhs.X() < rhs.X(); + } + + if (fabs(lhs.Y() - rhs.Y()) > Kernel::Tolerance) { + return lhs.Y() < rhs.Y(); + } + + if (fabs(lhs.Z() - rhs.Z()) > Kernel::Tolerance) { + return lhs.Z() < rhs.Z(); + } + + return false; + } +}; + /** @class Group diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroup.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroup.h index 654f3b40279ee42d46a457ceea54d3250d773b0b..173250ca70bfef696de6946fdc98b4aa4a83f5ab 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroup.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroup.h @@ -73,13 +73,18 @@ public: const std::vector<SymmetryOperation> &symmetryOperations = getSymmetryOperations(); - std::set<T> equivalents; + std::vector<T> equivalents; for (auto it = symmetryOperations.begin(); it != symmetryOperations.end(); ++it) { - equivalents.insert(Geometry::getWrappedVector((*it) * position)); + equivalents.push_back(Geometry::getWrappedVector((*it) * position)); } - return std::vector<T>(equivalents.begin(), equivalents.end()); + // Use fuzzy compare with the same condition as V3D::operator==(). + std::sort(equivalents.begin(), equivalents.end(), FuzzyV3DLessThan()); + equivalents.erase(std::unique(equivalents.begin(), equivalents.end()), + equivalents.end()); + + return equivalents; } protected: diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/CrystalStructure.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/CrystalStructure.cpp index 22dd7a91ae6cef5f0a6224b938921f96634a3de3..b96af9560f93ad6924231343df56054504477351 100644 --- a/Code/Mantid/Framework/Geometry/src/Crystal/CrystalStructure.cpp +++ b/Code/Mantid/Framework/Geometry/src/Crystal/CrystalStructure.cpp @@ -265,6 +265,10 @@ void CrystalStructure::setReflectionConditionFromSpaceGroup( // First letter is centering std::string centering = spaceGroup->hmSymbol().substr(0, 1); + if(centering == "R") { + centering = "Robv"; + } + std::vector<ReflectionCondition_sptr> reflectionConditions = getAllReflectionConditions(); for (auto it = reflectionConditions.begin(); it != reflectionConditions.end(); diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/Group.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/Group.cpp index 687ea943cbd1fe8f3dfa10072ee5b3060972b0f4..79a42fa39fbf31aada7bb6fa7974a6b34c583667 100644 --- a/Code/Mantid/Framework/Geometry/src/Crystal/Group.cpp +++ b/Code/Mantid/Framework/Geometry/src/Crystal/Group.cpp @@ -44,7 +44,9 @@ Group &Group::operator=(const Group &other) { size_t Group::order() const { return m_allOperations.size(); } /// Returns the axis system of the group (either orthogonal or hexagonal). -Group::CoordinateSystem Group::getCoordinateSystem() const { return m_axisSystem; } +Group::CoordinateSystem Group::getCoordinateSystem() const { + return m_axisSystem; +} /// Returns a vector with all symmetry operations. std::vector<SymmetryOperation> Group::getSymmetryOperations() const { @@ -78,13 +80,16 @@ Group Group::operator*(const Group &other) const { /// Returns a unique set of Kernel::V3D resulting from applying all symmetry /// operations, vectors are wrapped to [0, 1). std::vector<Kernel::V3D> Group::operator*(const Kernel::V3D &vector) const { - std::set<Kernel::V3D> result; + std::vector<Kernel::V3D> result; for (auto op = m_allOperations.begin(); op != m_allOperations.end(); ++op) { - result.insert(Geometry::getWrappedVector((*op) * vector)); + result.push_back(Geometry::getWrappedVector((*op) * vector)); } - return std::vector<Kernel::V3D>(result.begin(), result.end()); + std::sort(result.begin(), result.end(), FuzzyV3DLessThan()); + result.erase(std::unique(result.begin(), result.end()), result.end()); + + return result; } /// Returns true if both groups contain the same set of symmetry operations. diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/PointGroupFactory.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/PointGroupFactory.cpp index 928c3f214579a9019729ed7d488f551c5db0a14c..09ecd5d7fb2bfb41c72ff9fd174f94b9494e0685 100644 --- a/Code/Mantid/Framework/Geometry/src/Crystal/PointGroupFactory.cpp +++ b/Code/Mantid/Framework/Geometry/src/Crystal/PointGroupFactory.cpp @@ -21,7 +21,7 @@ PointGroupFactoryImpl::createPointGroup(const std::string &hmSymbol) { PointGroup_sptr PointGroupFactoryImpl::createPointGroupFromSpaceGroup( const SpaceGroup_const_sptr &spaceGroup) { - return createPointGroupFromSpaceGroup(*spaceGroup); + return createPointGroupFromSpaceGroup(*spaceGroup); } PointGroup_sptr PointGroupFactoryImpl::createPointGroupFromSpaceGroup( @@ -216,10 +216,13 @@ DECLARE_POINTGROUP("4/mmm", "-y,x,z; x,y,-z; x,-y,-z", "Tetragonal") DECLARE_POINTGROUP("3", "-y,x-y,z", "Trigonal - Hexagonal") DECLARE_POINTGROUP("-3", "y,y-x,-z", "Trigonal - Hexagonal") DECLARE_POINTGROUP("321", "-y,x-y,z; x-y,-y,-z", "Trigonal - Hexagonal") +DECLARE_POINTGROUP("32", "-y,x-y,z; x-y,-y,-z", "Trigonal - Hexagonal") DECLARE_POINTGROUP("312", "-y,x-y,z; x,x-y,-z", "Trigonal - Hexagonal") DECLARE_POINTGROUP("3m1", "-y,x-y,z; y-x,y,z", "Trigonal - Hexagonal") +DECLARE_POINTGROUP("3m", "-y,x-y,z; y-x,y,z", "Trigonal - Hexagonal") DECLARE_POINTGROUP("31m", "-y,x-y,z; -x,y-x,z", "Trigonal - Hexagonal") DECLARE_POINTGROUP("-3m1", "y,y-x,-z; x-y,-y,-z", "Trigonal - Hexagonal") +DECLARE_POINTGROUP("-3m", "y,y-x,-z; x-y,-y,-z", "Trigonal - Hexagonal") DECLARE_POINTGROUP("-31m", "y,y-x,-z; x,x-y,-z", "Trigonal - Hexagonal") DECLARE_POINTGROUP("3 r", "z,x,y", "Trigonal - Rhombohedral") diff --git a/Code/Mantid/Framework/Geometry/test/CrystalStructureTest.h b/Code/Mantid/Framework/Geometry/test/CrystalStructureTest.h index a503e0a014b660b0ef85f61b388a25e752ebe3d8..f8d11780315e2a369f26b347de8736ae467277f5 100644 --- a/Code/Mantid/Framework/Geometry/test/CrystalStructureTest.h +++ b/Code/Mantid/Framework/Geometry/test/CrystalStructureTest.h @@ -344,6 +344,27 @@ public: } + void testTrigonal() + { + UnitCell cellAl2O3(4.759355, 4.759355, 12.99231, 90.0, 90.0, 120.0); + CompositeBraggScatterer_sptr scatterers = CompositeBraggScatterer::create(); + scatterers->addScatterer(BraggScattererFactory::Instance().createScatterer("IsotropicAtomBraggScatterer", "Element=Al;Position=[0,0,0.35217];U=0.005")); + scatterers->addScatterer(BraggScattererFactory::Instance().createScatterer("IsotropicAtomBraggScatterer", "Element=O;Position=[0.69365,0,0.25];U=0.005")); + SpaceGroup_const_sptr sgAl2O3 = SpaceGroupFactory::Instance().createSpaceGroup("R -3 c"); + + std::cout << sgAl2O3->order() << std::endl; + + // O is on the 18e wyckoff position + std::vector<V3D> positions = sgAl2O3 * V3D(0.69365000,0,0.25000); + TS_ASSERT_EQUALS(positions.size(), 18); + + CrystalStructure mg(cellAl2O3, sgAl2O3, scatterers); + + std::vector<V3D> hkls = mg.getUniqueHKLs(0.885, 10.0, CrystalStructure::UseStructureFactor); + + TS_ASSERT_EQUALS(hkls.size(), 44); + } + private: UnitCell m_CsCl; PointGroup_sptr m_pg; diff --git a/Code/Mantid/Framework/Geometry/test/GroupTest.h b/Code/Mantid/Framework/Geometry/test/GroupTest.h index 12566f10e5ee3e21cf9d665422001d9c1ecd38e4..3ea24cf65c5c0fb5e82b68264bde3b72abc8f39c 100644 --- a/Code/Mantid/Framework/Geometry/test/GroupTest.h +++ b/Code/Mantid/Framework/Geometry/test/GroupTest.h @@ -3,11 +3,13 @@ #include <cxxtest/TestSuite.h> +#include "MantidKernel/V3D.h" #include "MantidGeometry/Crystal/Group.h" #include "MantidGeometry/Crystal/SymmetryOperationFactory.h" #include <boost/make_shared.hpp> using namespace Mantid::Geometry; +using namespace Mantid::Kernel; class GroupTest : public CxxTest::TestSuite { public: @@ -183,6 +185,41 @@ public: TS_ASSERT_EQUALS(two.getCoordinateSystem(), Group::Hexagonal); } + void testFuzzyV3DLessThan() { + FuzzyV3DLessThan lessThan; + + V3D v1(0.654321, 0.0, 0.0); + V3D v2(0.654320, 0.0, 0.0); + TS_ASSERT(v1 != v2); + TS_ASSERT(lessThan(v2, v1)); + + // 7th digit is not compared. + V3D v3(0.6543211, 0.0, 0.0); + TS_ASSERT(v1 == v3); + TS_ASSERT(!lessThan(v1, v3)); + TS_ASSERT(!lessThan(v3, v1)); + + // Same for y + V3D v4(0.654321, 0.0000010001, 0.0); + TS_ASSERT(v1 != v4); + TS_ASSERT(lessThan(v1, v4)); + + V3D v5(0.654321, 0.0000001, 0.0); + TS_ASSERT(v1 == v5); + TS_ASSERT(!lessThan(v1, v5)); + TS_ASSERT(!lessThan(v5, v1)); + + // Same for z + V3D v6(0.654321, 0.0, 0.0000010001); + TS_ASSERT(v1 != v6); + TS_ASSERT(lessThan(v1, v6)); + + V3D v7(0.654321, 0.0, 0.0000001); + TS_ASSERT(v1 == v7); + TS_ASSERT(!lessThan(v1, v7)); + TS_ASSERT(!lessThan(v7, v1)); + } + void testSmartPointerOperators() { // We take pointgroup -1 std::vector<SymmetryOperation> inversion; diff --git a/Code/Mantid/Framework/Geometry/test/PointGroupFactoryTest.h b/Code/Mantid/Framework/Geometry/test/PointGroupFactoryTest.h index ada6ff46fbf341f3d52e96c0a7a7e2da182371d1..0203852a6c2b6de4fede1ed507cf56204e909ee0 100644 --- a/Code/Mantid/Framework/Geometry/test/PointGroupFactoryTest.h +++ b/Code/Mantid/Framework/Geometry/test/PointGroupFactoryTest.h @@ -120,6 +120,11 @@ public: TS_ASSERT_EQUALS(pointGroup->getCoordinateSystem(), Group::CoordinateSystem::Hexagonal); TS_ASSERT_EQUALS(pointGroup->getSymbol(), "3"); + + PointGroup_sptr pointGroupAl2O3 = checkSpaceGroupSymbol("R -3 c"); + TS_ASSERT_EQUALS(pointGroupAl2O3->getCoordinateSystem(), + Group::CoordinateSystem::Hexagonal); + TS_ASSERT_EQUALS(pointGroupAl2O3->getSymbol(), "-3m"); } private: diff --git a/Code/Mantid/Framework/Geometry/test/PointGroupTest.h b/Code/Mantid/Framework/Geometry/test/PointGroupTest.h index ffaac8d2e1ceb61b7ff0137a5be0663749a74bd2..31a1f945dd5551cbd98370ac9c603b8133943004 100644 --- a/Code/Mantid/Framework/Geometry/test/PointGroupTest.h +++ b/Code/Mantid/Framework/Geometry/test/PointGroupTest.h @@ -131,10 +131,13 @@ public: crystalSystemsMap["3"] = PointGroup::Trigonal; crystalSystemsMap["-3"] = PointGroup::Trigonal; crystalSystemsMap["321"] = PointGroup::Trigonal; + crystalSystemsMap["32"] = PointGroup::Trigonal; crystalSystemsMap["312"] = PointGroup::Trigonal; crystalSystemsMap["3m1"] = PointGroup::Trigonal; + crystalSystemsMap["3m"] = PointGroup::Trigonal; crystalSystemsMap["31m"] = PointGroup::Trigonal; crystalSystemsMap["-3m1"] = PointGroup::Trigonal; + crystalSystemsMap["-3m"] = PointGroup::Trigonal; crystalSystemsMap["-31m"] = PointGroup::Trigonal; crystalSystemsMap["3 r"] = PointGroup::Trigonal; crystalSystemsMap["-3 r"] = PointGroup::Trigonal; @@ -178,8 +181,8 @@ public: TS_ASSERT_EQUALS(pgMap.count(PointGroup::Orthorhombic), 3); TS_ASSERT_EQUALS(pgMap.count(PointGroup::Tetragonal), 8); - // 5 with rhombohedral axes and 8 with hexagonal - TS_ASSERT_EQUALS(pgMap.count(PointGroup::Trigonal), 5 + 8); + // 5 with rhombohedral axes and 8 with hexagonal and 3 for defaults + TS_ASSERT_EQUALS(pgMap.count(PointGroup::Trigonal), 5 + 8 + 3); TS_ASSERT_EQUALS(pgMap.count(PointGroup::Hexagonal), 8); TS_ASSERT_EQUALS(pgMap.count(PointGroup::Cubic), 5); } diff --git a/Code/Mantid/Framework/Geometry/test/SpaceGroupTest.h b/Code/Mantid/Framework/Geometry/test/SpaceGroupTest.h index 92aabd1b36c90ae9ad77204fe7eddd27a2e8772d..ad97bf38b82c9966f793dd618d0738cbba38edfd 100644 --- a/Code/Mantid/Framework/Geometry/test/SpaceGroupTest.h +++ b/Code/Mantid/Framework/Geometry/test/SpaceGroupTest.h @@ -6,72 +6,115 @@ #include "MantidGeometry/Crystal/SpaceGroup.h" #include "MantidGeometry/Crystal/SymmetryOperationFactory.h" #include "MantidGeometry/Crystal/CyclicGroup.h" +#include "MantidGeometry/Crystal/ProductOfCyclicGroups.h" +#include "MantidGeometry/Crystal/CenteringGroup.h" + #include "MantidKernel/V3D.h" using namespace Mantid::Geometry; using Mantid::Kernel::V3D; -class SpaceGroupTest : public CxxTest::TestSuite -{ +class SpaceGroupTest : public CxxTest::TestSuite { public: - // This pair of boilerplate methods prevent the suite being created statically - // This means the constructor isn't called when running other tests - static SpaceGroupTest *createSuite() { return new SpaceGroupTest(); } - static void destroySuite( SpaceGroupTest *suite ) { delete suite; } - - - void testConstruction() - { - Group_const_sptr inversion = GroupFactory::create<CyclicGroup>("-x,-y,-z"); - SpaceGroup p1bar(2, "P-1", *inversion); - - TS_ASSERT_EQUALS(p1bar.number(), 2); - TS_ASSERT_EQUALS(p1bar.hmSymbol(), "P-1"); - TS_ASSERT_EQUALS(p1bar.order(), 2); - TS_ASSERT_EQUALS(p1bar.getSymmetryOperations().size(), 2); + // This pair of boilerplate methods prevent the suite being created statically + // This means the constructor isn't called when running other tests + static SpaceGroupTest *createSuite() { return new SpaceGroupTest(); } + static void destroySuite(SpaceGroupTest *suite) { delete suite; } + + void testConstruction() { + Group_const_sptr inversion = GroupFactory::create<CyclicGroup>("-x,-y,-z"); + SpaceGroup p1bar(2, "P-1", *inversion); + + TS_ASSERT_EQUALS(p1bar.number(), 2); + TS_ASSERT_EQUALS(p1bar.hmSymbol(), "P-1"); + TS_ASSERT_EQUALS(p1bar.order(), 2); + TS_ASSERT_EQUALS(p1bar.getSymmetryOperations().size(), 2); + } + + void testNumber() { + TestableSpaceGroup empty; + TS_ASSERT_EQUALS(empty.number(), 0); + + empty.m_number = 2; + TS_ASSERT_EQUALS(empty.number(), 2); + } + + void testSymbol() { + TestableSpaceGroup empty; + TS_ASSERT_EQUALS(empty.hmSymbol(), ""); + + empty.m_hmSymbol = "Test"; + TS_ASSERT_EQUALS(empty.hmSymbol(), "Test"); + } + + void testAssignmentOperator() { + Group_const_sptr inversion = GroupFactory::create<CyclicGroup>("-x,-y,-z"); + SpaceGroup p1bar(2, "P-1", *inversion); + + SpaceGroup other = p1bar; + + TS_ASSERT_EQUALS(other.number(), p1bar.number()); + TS_ASSERT_EQUALS(other.hmSymbol(), p1bar.hmSymbol()); + TS_ASSERT_EQUALS(other.order(), p1bar.order()); + } + + void testGetEquivalentsR3c() { + Group_const_sptr group = GroupFactory::create<ProductOfCyclicGroups>( + "-y,x-y,z; y,x,-z+1/2; -x,-y,-z"); + Group_const_sptr centering = GroupFactory::create<CenteringGroup>("R"); + + SpaceGroup spaceGroup(167, "R-3c", *(group * centering)); + + std::vector<V3D> byOperator = spaceGroup * V3D(0.3, 0.0, 0.25); + for (size_t i = 0; i < byOperator.size(); ++i) { + byOperator[i] = getWrappedVector(byOperator[i]); } + std::sort(byOperator.begin(), byOperator.end()); - void testNumber() - { - TestableSpaceGroup empty; - TS_ASSERT_EQUALS(empty.number(), 0); + std::vector<V3D> byEquivalents = + spaceGroup.getEquivalentPositions(V3D(0.3, 0.0, 0.25)); + std::sort(byEquivalents.begin(), byEquivalents.end()); - empty.m_number = 2; - TS_ASSERT_EQUALS(empty.number(), 2); + TS_ASSERT_EQUALS(byOperator.size(), 18); + TS_ASSERT_EQUALS(byOperator.size(), byEquivalents.size()); + for (size_t i = 0; i < byEquivalents.size(); ++i) { + TS_ASSERT_EQUALS(byOperator[i], byEquivalents[i]); } + } - void testSymbol() - { - TestableSpaceGroup empty; - TS_ASSERT_EQUALS(empty.hmSymbol(), ""); + void testGetEquivalentsR3m9e() { + Group_const_sptr group = GroupFactory::create<ProductOfCyclicGroups>( + "-y,x-y,z; y,x,-z; -x,-y,-z"); + Group_const_sptr centering = GroupFactory::create<CenteringGroup>("R"); - empty.m_hmSymbol = "Test"; - TS_ASSERT_EQUALS(empty.hmSymbol(), "Test"); - } + SpaceGroup spaceGroup(167, "R-3m", *(group * centering)); - void testAssignmentOperator() - { - Group_const_sptr inversion = GroupFactory::create<CyclicGroup>("-x,-y,-z"); - SpaceGroup p1bar(2, "P-1", *inversion); + std::vector<V3D> byOperator = spaceGroup * V3D(0.5, 0.0, 0.0); + for (size_t i = 0; i < byOperator.size(); ++i) { + byOperator[i] = getWrappedVector(byOperator[i]); + } + std::sort(byOperator.begin(), byOperator.end()); - SpaceGroup other = p1bar; + std::vector<V3D> byEquivalents = + spaceGroup.getEquivalentPositions(V3D(0.5, 0.0, 0.0)); + std::sort(byEquivalents.begin(), byEquivalents.end()); - TS_ASSERT_EQUALS(other.number(), p1bar.number()); - TS_ASSERT_EQUALS(other.hmSymbol(), p1bar.hmSymbol()); - TS_ASSERT_EQUALS(other.order(), p1bar.order()); + TS_ASSERT_EQUALS(byOperator.size(), 9); + TS_ASSERT_EQUALS(byOperator.size(), byEquivalents.size()); + for (size_t i = 0; i < byEquivalents.size(); ++i) { + TS_ASSERT_EQUALS(byOperator[i], byEquivalents[i]); } + } private: - class TestableSpaceGroup : public SpaceGroup { - friend class SpaceGroupTest; - public: - TestableSpaceGroup() : - SpaceGroup(0, "", Group()) - { } - - ~TestableSpaceGroup() { } - }; -}; + class TestableSpaceGroup : public SpaceGroup { + friend class SpaceGroupTest; + public: + TestableSpaceGroup() : SpaceGroup(0, "", Group()) {} + + ~TestableSpaceGroup() {} + }; +}; #endif /* MANTID_GEOMETRY_SPACEGROUPTEST_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMD.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMD.h index 0d5e15b0c2d9fffe6bd209d7c175922043a457b9..9fe01fa089e7abcec0fc910483c8b374ce9e812c 100644 --- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMD.h +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMD.h @@ -114,8 +114,8 @@ protected: // for testing, otherwise private: const std::vector<std::string> &otherDim, std::vector<double> &minVal, std::vector<double> &maxVal); - /// Splits the initial box at level 0 into a defined number of subboxes for the the first level. - void performInitialSplitting(API::IMDEventWorkspace_sptr spws, Mantid::API::BoxController_sptr bc); + /// Sets up the top level splitting, i.e. of level 0, for the box controller + void setupTopLevelSplitting(Mantid::API::BoxController_sptr bc); }; } // namespace Mantid diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Integrate3DEvents.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Integrate3DEvents.h index 3e81114c826cd43c9663e259d6fbba5b198630e3..0a2623c8aeb1c3145bbf073514cc1d5bcdbfc55f 100644 --- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Integrate3DEvents.h +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Integrate3DEvents.h @@ -67,7 +67,7 @@ public: ~Integrate3DEvents(); /// Add event Q's to lists of events near peaks - void addEvents(std::vector<std::pair<double, Mantid::Kernel::V3D> > const &event_qs); + void addEvents(std::vector<std::pair<double, Mantid::Kernel::V3D> > const &event_qs, bool hkl_integ); /// Find the net integrated intensity of a peak, using ellipsoidal volumes boost::shared_ptr<const Mantid::Geometry::PeakShape> ellipseIntegrateEvents(Mantid::Kernel::V3D const &peak_q, bool specify_size, @@ -99,9 +99,10 @@ private: /// Form a map key for the specified q_vector. int64_t getHklKey(Mantid::Kernel::V3D const &q_vector); + int64_t getHklKey2(Mantid::Kernel::V3D const &q_vector); /// Add an event to the vector of events for the closest h,k,l - void addEvent(std::pair<double, Mantid::Kernel::V3D> event_Q); + void addEvent(std::pair<double, Mantid::Kernel::V3D> event_Q, bool hkl_integ); /// Find the net integrated intensity of a list of Q's using ellipsoids boost::shared_ptr<const Mantid::DataObjects::PeakShapeEllipsoid> ellipseIntegrateEvents( diff --git a/Code/Mantid/Framework/MDAlgorithms/src/ConvertToMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/ConvertToMD.cpp index b7bab452fc40d8e1160b02bffde7f1f91430273b..8bb8c06e4fcf21e049bca29426019e498af4a558 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/ConvertToMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/ConvertToMD.cpp @@ -85,9 +85,8 @@ void ConvertToMD::init() { setPropertyGroup("MinRecursionDepth", getBoxSettingsGroupName()); declareProperty( - new PropertyWithValue<bool>("InitialSplitting", 0, Direction::Input), - "This option causes an initial split of 50 for the first four dimensions " - "at level 0."); + new PropertyWithValue<bool>("TopLevelSplitting", 0, Direction::Input), + "This option causes a split of the top level, i.e. level0, of 50 for the first four dimensions."); } //---------------------------------------------------------------------------------------------- /** Destructor @@ -471,17 +470,17 @@ API::IMDEventWorkspace_sptr ConvertToMD::createNewMDWorkspace( // BoxControllerSettingsAlgorithm this->setBoxController(bc, m_InWS2D->getInstrument()); - // Check if the user want sto force an initial split or not - bool initialSplittingChecked = this->getProperty("InitialSplitting"); + // Check if the user want sto force a top level split or not + bool topLevelSplittingChecked = this->getProperty("TopLevelSplitting"); - if (!initialSplittingChecked) { - // split boxes; - spws->splitBox(); - } else { + if (topLevelSplittingChecked) { // Perform initial split with the forced settings - performInitialSplitting(spws, bc); + setupTopLevelSplitting(bc); } + // split boxes; + spws->splitBox(); + // Do we split more due to MinRecursionDepth? int minDepth = this->getProperty("MinRecursionDepth"); int maxDepth = this->getProperty("MaxRecursionDepth"); @@ -494,36 +493,23 @@ API::IMDEventWorkspace_sptr ConvertToMD::createNewMDWorkspace( } /** - * Splits the initial box at level 0 into a defined number of subboxes for the + * Splits the top level box at level 0 into a defined number of subboxes for the * the first level. - * @param spws A pointer to the newly created event workspace. * @param bc A pointer to the box controller. */ -void ConvertToMD::performInitialSplitting(API::IMDEventWorkspace_sptr spws, - Mantid::API::BoxController_sptr bc) { - const size_t initialSplitSetting = 50; +void ConvertToMD::setupTopLevelSplitting(Mantid::API::BoxController_sptr bc) { + const size_t topLevelSplitSetting = 50; const size_t dimCutoff = 4; - // Record the split settings of the box controller in a buffer and set the new - // value - std::vector<size_t> splitBuffer; - + // Set the Top level splitting for (size_t dim = 0; dim < bc->getNDims(); dim++) { - splitBuffer.push_back(bc->getSplitInto(dim)); - - // Replace the box controller setting only for a max of the first three - // dimensions if (dim < dimCutoff) { - bc->setSplitInto(dim, initialSplitSetting); + bc->setSplitTopInto(dim, topLevelSplitSetting); + } + else + { + bc->setSplitTopInto(dim, bc->getSplitInto(dim)); } - } - - // Perform the initial splitting - spws->splitBox(); - - // Revert changes on the box controller - for (size_t dim = 0; dim < bc->getNDims(); ++dim) { - bc->setSplitInto(dim, splitBuffer[dim]); } } diff --git a/Code/Mantid/Framework/MDAlgorithms/src/Integrate3DEvents.cpp b/Code/Mantid/Framework/MDAlgorithms/src/Integrate3DEvents.cpp index 8343d4646f21869815e01df8578b8dc4966a923e..29fdbe5effbce181392d476fce231a655ccbd762 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/Integrate3DEvents.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/Integrate3DEvents.cpp @@ -68,9 +68,9 @@ Integrate3DEvents::~Integrate3DEvents() {} * @param event_qs List of event Q vectors to add to lists of Q's associated * with peaks. */ -void Integrate3DEvents::addEvents(std::vector<std::pair<double, V3D> > const &event_qs) { +void Integrate3DEvents::addEvents(std::vector<std::pair<double, V3D> > const &event_qs, bool hkl_integ) { for (size_t i = 0; i < event_qs.size(); i++) { - addEvent(event_qs[i]); + addEvent(event_qs[i], hkl_integ); } } @@ -123,7 +123,7 @@ Mantid::Geometry::PeakShape_const_sptr Integrate3DEvents::ellipseIntegrateEvents std::vector<std::pair<double, V3D> > &some_events = event_lists[hkl_key]; for (size_t it = 0; it != some_events.size(); ++it) { - hkl_key = getHklKey(some_events[it].second); + hkl_key = getHklKey2(some_events[it].second); if (hkl_key != 0) // only save if hkl != (0,0,0) peak_qs[hkl_key] = some_events[it].second; } @@ -323,7 +323,19 @@ int64_t Integrate3DEvents::getHklKey(int h, int k, int l) { return key; } - +/** + * Form a map key for the specified q_vector. The q_vector is mapped to + * h,k,l by UBinv and the map key is then formed from those rounded h,k,l + * values. + * + * @param q_vector The q_vector to be mapped to h,k,l + */ +int64_t Integrate3DEvents::getHklKey2(V3D const &hkl) { + int h = boost::math::iround<double>(hkl[0]); + int k = boost::math::iround<double>(hkl[1]); + int l = boost::math::iround<double>(hkl[2]); + return getHklKey(h, k, l); +} /** * Form a map key for the specified q_vector. The q_vector is mapped to * h,k,l by UBinv and the map key is then formed from those rounded h,k,l @@ -352,8 +364,10 @@ int64_t Integrate3DEvents::getHklKey(V3D const &q_vector) { * @param event_Q The Q-vector for the event that may be added to the * event_lists map, if it is close enough to some peak */ -void Integrate3DEvents::addEvent(std::pair<double, V3D> event_Q) { - int64_t hkl_key = getHklKey(event_Q.second); +void Integrate3DEvents::addEvent(std::pair<double, V3D> event_Q, bool hkl_integ) { + int64_t hkl_key; + if (hkl_integ) hkl_key = getHklKey2(event_Q.second); + else hkl_key = getHklKey(event_Q.second); if (hkl_key == 0) // don't keep events associated with 0,0,0 return; @@ -362,7 +376,8 @@ void Integrate3DEvents::addEvent(std::pair<double, V3D> event_Q) { if (peak_it != peak_qs.end()) { if (!peak_it->second.nullVector()) { - event_Q.second = event_Q.second - peak_it->second; + if (hkl_integ) event_Q.second = event_Q.second - UBinv * peak_it->second; + else event_Q.second = event_Q.second - peak_it->second; if (event_Q.second.norm() < radius) { event_lists[hkl_key].push_back(event_Q); } diff --git a/Code/Mantid/Framework/MDAlgorithms/src/IntegrateEllipsoids.cpp b/Code/Mantid/Framework/MDAlgorithms/src/IntegrateEllipsoids.cpp index ec31dd315c1f69eef926ceafdcb683bccd6dadb9..e71dfda095e136b1c5949b69db3cc69aaa04d7d6 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/IntegrateEllipsoids.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/IntegrateEllipsoids.cpp @@ -47,7 +47,7 @@ const std::size_t DIMS(3); void qListFromEventWS(Integrate3DEvents &integrator, Progress &prog, EventWorkspace_sptr &wksp, UnitsConversionHelper &unitConverter, - MDTransf_sptr &qConverter) { + MDTransf_sptr &qConverter, DblMatrix const &UBinv, bool hkl_integ) { // loop through the eventlists std::vector<double> buffer(DIMS); @@ -82,10 +82,11 @@ void qListFromEventWS(Integrate3DEvents &integrator, Progress &prog, buffer[dim] = locCoord[dim]; } V3D qVec(buffer[0], buffer[1], buffer[2]); + if (hkl_integ) qVec = UBinv * qVec; qList.push_back(std::make_pair(event->m_weight, qVec)); } // end of loop over events in list - integrator.addEvents(qList); + integrator.addEvents(qList, hkl_integ); prog.report(); } // end of loop over spectra @@ -103,7 +104,7 @@ void qListFromEventWS(Integrate3DEvents &integrator, Progress &prog, void qListFromHistoWS(Integrate3DEvents &integrator, Progress &prog, Workspace2D_sptr &wksp, UnitsConversionHelper &unitConverter, - MDTransf_sptr &qConverter) { + MDTransf_sptr &qConverter, DblMatrix const &UBinv, bool hkl_integ) { // loop through the eventlists std::vector<double> buffer(DIMS); @@ -146,17 +147,18 @@ void qListFromHistoWS(Integrate3DEvents &integrator, Progress &prog, // qVec } V3D qVec(buffer[0], buffer[1], buffer[2]); + if (hkl_integ) qVec = UBinv * qVec; int yValCounts = int(yVal); // we deliberately truncate. // Account for counts in histograms by increasing the qList with the // same q-point qList.push_back(std::make_pair( yValCounts, qVec)); // Not ideal to control the size dynamically? } - integrator.addEvents(qList); // We would have to put a lock around this. + integrator.addEvents(qList, hkl_integ); // We would have to put a lock around this. prog.report(); } - integrator.addEvents(qList); + integrator.addEvents(qList, hkl_integ); prog.report(); } @@ -248,6 +250,10 @@ void IntegrateEllipsoids::init() { declareProperty("NumSigmas", 3, "Number of sigmas to add to mean of half-length of " "major radius for second pass when SpecifySize is false."); + + declareProperty( + "IntegrateInHKL", false, + "If true, integrate in HKL space not Q space."); } //--------------------------------------------------------------------- @@ -288,6 +294,7 @@ void IntegrateEllipsoids::exec() { double peak_radius = getProperty("PeakSize"); double back_inner_radius = getProperty("BackgroundInnerSize"); double back_outer_radius = getProperty("BackgroundOuterSize"); + bool hkl_integ = getProperty("IntegrateInHKL"); // get UBinv and the list of // peak Q's for the integrator std::vector<Peak> &peaks = peak_ws->getPeaks(); @@ -364,10 +371,10 @@ void IntegrateEllipsoids::exec() { if (eventWS) { // process as EventWorkspace - qListFromEventWS(integrator, prog, eventWS, unitConv, qConverter); + qListFromEventWS(integrator, prog, eventWS, unitConv, qConverter, UBinv, hkl_integ); } else { // process as Workspace2D - qListFromHistoWS(integrator, prog, histoWS, unitConv, qConverter); + qListFromHistoWS(integrator, prog, histoWS, unitConv, qConverter, UBinv, hkl_integ); } double inti; diff --git a/Code/Mantid/Framework/MDAlgorithms/test/ConvertToMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/ConvertToMDTest.h index f112f167ca79e8cdcbf8b5a4b3fe7c7454fec50c..abbcc48112b3eb7532361bb7af1c0f87ef0ab5e2 100644 --- a/Code/Mantid/Framework/MDAlgorithms/test/ConvertToMDTest.h +++ b/Code/Mantid/Framework/MDAlgorithms/test/ConvertToMDTest.h @@ -191,7 +191,7 @@ void testInitialSplittingEnabled() convertAlg.setProperty("dEAnalysisMode", "Direct"); convertAlg.setPropertyValue("MinValues","-10,-10,-10, 0"); convertAlg.setPropertyValue("MaxValues"," 10, 10, 10, 1"); - convertAlg.setPropertyValue("InitialSplitting", "1"); + convertAlg.setPropertyValue("TopLevelSplitting", "1"); convertAlg.execute(); IMDEventWorkspace_sptr outEventWS = convertAlg.getProperty("OutputWorkspace"); @@ -231,7 +231,7 @@ void testInitialSplittingDisabled() TS_ASSERT_THROWS_NOTHING(pAlg->setPropertyValue("dEAnalysisMode", "Direct")); pAlg->setPropertyValue("MinValues","-10,-10,-10, 0,-10,-10"); pAlg->setPropertyValue("MaxValues"," 10, 10, 10, 20, 40, 20"); - TS_ASSERT_THROWS_NOTHING(pAlg->setPropertyValue("InitialSplitting", "0")); + TS_ASSERT_THROWS_NOTHING(pAlg->setPropertyValue("TopLevelSplitting", "0")); pAlg->setRethrows(false); pAlg->execute(); TSM_ASSERT("Should finish successfully",pAlg->isExecuted()); diff --git a/Code/Mantid/Framework/MDAlgorithms/test/Integrate3DEventsTest.h b/Code/Mantid/Framework/MDAlgorithms/test/Integrate3DEventsTest.h index 0847a05d3600e12020fc8a955c58591dc3f2507a..7bdbc2900e398d299ff41e765e1cfc8252e4a103 100644 --- a/Code/Mantid/Framework/MDAlgorithms/test/Integrate3DEventsTest.h +++ b/Code/Mantid/Framework/MDAlgorithms/test/Integrate3DEventsTest.h @@ -81,7 +81,7 @@ public: double radius = 1.3; Integrate3DEvents integrator( peak_q_list, UBinv, radius ); - integrator.addEvents( event_Qs ); + integrator.addEvents( event_Qs, false ); // With fixed size ellipsoids, all the // events are counted. diff --git a/Code/Mantid/Framework/MDAlgorithms/test/IntegrateEllipsoidsTest.h b/Code/Mantid/Framework/MDAlgorithms/test/IntegrateEllipsoidsTest.h index feceab27592e4fe8e315b8f138b94d3c2bd11415..bb36ebbce9d868a18c2d01b8c8090e56f4c6ebc6 100644 --- a/Code/Mantid/Framework/MDAlgorithms/test/IntegrateEllipsoidsTest.h +++ b/Code/Mantid/Framework/MDAlgorithms/test/IntegrateEllipsoidsTest.h @@ -254,6 +254,68 @@ public: do_test_n_peaks(integratedPeaksWS, 3 /*check first 3 peaks*/); } + void test_execution_events_hkl() { + + IntegrateEllipsoids alg; + alg.setChild(true); + alg.setRethrows(true); + alg.initialize(); + alg.setProperty("InputWorkspace", m_eventWS); + alg.setProperty("PeaksWorkspace", m_peaksWS); + alg.setPropertyValue("OutputWorkspace", "dummy"); + alg.setProperty("IntegrateInHKL", true); // Check hkl option + alg.execute(); + PeaksWorkspace_sptr integratedPeaksWS = alg.getProperty("OutputWorkspace"); + TSM_ASSERT_EQUALS("Wrong number of peaks in output workspace", + integratedPeaksWS->getNumberPeaks(), + m_peaksWS->getNumberPeaks()); + + TSM_ASSERT_DELTA("Wrong intensity for peak 0", + integratedPeaksWS->getPeak(0).getIntensity(), -2, 0.01); + TSM_ASSERT_DELTA("Wrong intensity for peak 1", + integratedPeaksWS->getPeak(1).getIntensity(), 2, 0.01); + TSM_ASSERT_DELTA("Wrong intensity for peak 2", + integratedPeaksWS->getPeak(2).getIntensity(), -2, 0.01); + //Answer is 16 on Mac ??? + //TSM_ASSERT_DELTA("Wrong intensity for peak 3", + //integratedPeaksWS->getPeak(3).getIntensity(), 6, 0.01); + TSM_ASSERT_DELTA("Wrong intensity for peak 4", + integratedPeaksWS->getPeak(4).getIntensity(), 11, 0.01); + TSM_ASSERT_DELTA("Wrong intensity for peak 5", + integratedPeaksWS->getPeak(5).getIntensity(), 10, 0.01); + + } + + void test_execution_histograms_hkl() { + + IntegrateEllipsoids alg; + alg.setChild(true); + alg.setRethrows(true); + alg.initialize(); + alg.setProperty("InputWorkspace", m_histoWS); + alg.setProperty("PeaksWorkspace", m_peaksWS); + alg.setPropertyValue("OutputWorkspace", "dummy"); + alg.setProperty("IntegrateInHKL", true); // Check hkl option + alg.execute(); + PeaksWorkspace_sptr integratedPeaksWS = alg.getProperty("OutputWorkspace"); + TSM_ASSERT_EQUALS("Wrong number of peaks in output workspace", + integratedPeaksWS->getNumberPeaks(), + m_peaksWS->getNumberPeaks()); + TSM_ASSERT_DELTA("Wrong intensity for peak 0", + integratedPeaksWS->getPeak(0).getIntensity(), 163, 0.01); + TSM_ASSERT_DELTA("Wrong intensity for peak 1", + integratedPeaksWS->getPeak(1).getIntensity(), 0, 0.01); + TSM_ASSERT_DELTA("Wrong intensity for peak 2", + integratedPeaksWS->getPeak(2).getIntensity(), 163, 0.01); + //Answer is 951 on Mac ??? + //TSM_ASSERT_DELTA("Wrong intensity for peak 3", + //integratedPeaksWS->getPeak(3).getIntensity(), 711, 0.01); + TSM_ASSERT_DELTA("Wrong intensity for peak 4", + integratedPeaksWS->getPeak(4).getIntensity(), 694, 0.01); + TSM_ASSERT_DELTA("Wrong intensity for peak 5", + integratedPeaksWS->getPeak(5).getIntensity(), 218, 0.01); + + } }; class IntegrateEllipsoidsTestPerformance : public CxxTest::TestSuite { diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/Group.cpp b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/Group.cpp index 5a0cbef5c8d3b3d4e0575c92519cbc7c75358c4a..1c12be9b7f0860221c5099dc084c30f5df556215 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/Group.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/Group.cpp @@ -1,3 +1,4 @@ + #include "MantidGeometry/Crystal/Group.h" #include <boost/python/class.hpp> @@ -5,16 +6,31 @@ #include <boost/python/scope.hpp> using Mantid::Geometry::Group; +using Mantid::Geometry::SymmetryOperation; using namespace boost::python; +namespace { + std::vector<std::string> getSymmetryOperationStrings(Group &self) { + const std::vector<SymmetryOperation> &symOps = self.getSymmetryOperations(); + + std::vector<std::string> pythonSymOps; + for (auto it = symOps.begin(); it != symOps.end(); ++it) { + pythonSymOps.push_back((*it).identifier()); + } + + return pythonSymOps; + } +} + void export_Group() { enum_<Group::CoordinateSystem>("CoordinateSystem") - .value("Orthogonal", Group::Orthogonal) - .value("Hexagonal", Group::Hexagonal); + .value("Orthogonal", Group::Orthogonal) + .value("Hexagonal", Group::Hexagonal); class_<Group, boost::noncopyable>("Group", no_init) - .def("coordinateSystem", &Group::getCoordinateSystem); + .def("getOrder", &Group::order, "Returns the order of the group.") + .def("getCoordinateSystem", &Group::getCoordinateSystem, "Returns the type of coordinate system to distinguish groups with hexagonal system definition.") + .def("getSymmetryOperationStrings", &getSymmetryOperationStrings, "Returns the x,y,z-strings for the contained symmetry operations."); } - diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroup.cpp b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroup.cpp index 074c9aae7c1f8b678156c9566167a67948345bd1..ded37c8fca9067066849990fb059517312f1aa46 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroup.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroup.cpp @@ -57,8 +57,8 @@ void export_PointGroup() class_<PointGroup, boost::noncopyable, bases<Group> >("PointGroup", no_init) .def("getName", &PointGroup::getName) - .def("getSymbol", &PointGroup::getSymbol) - .def("crystalSystem", &PointGroup::crystalSystem) + .def("getHMSymbol", &PointGroup::getSymbol) + .def("getCrystalSystem", &PointGroup::crystalSystem) .def("isEquivalent", &isEquivalent, "Check whether the two HKLs are symmetrically equivalent.") .def("getEquivalents", &getEquivalents, "Returns an array with all symmetry equivalents of the supplied HKL.") .def("getReflectionFamily", &getReflectionFamily, "Returns the same HKL for all symmetry equivalents."); diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroupFactory.cpp b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroupFactory.cpp index 8700da8f509361a5dbe35f4554ef28d002b9b8dc..17097ab43f2e4de31f0efacd06bde5818b7a0ebf 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroupFactory.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroupFactory.cpp @@ -23,12 +23,12 @@ void export_PointGroupFactory() { class_<PointGroupFactoryImpl,boost::noncopyable>("PointGroupFactoryImpl", no_init) - .def("exists", &PointGroupFactoryImpl::isSubscribed) - .def("createPointGroup", &PointGroupFactoryImpl::createPointGroup) - .def("createPointGroupFromSpaceGroup", &getPointGroupFromSpaceGroup) - .def("createPointGroupFromSpaceGroupSymbol", &getPointGroupFromSpaceGroupSymbol) - .def("getAllPointGroupSymbols", &PointGroupFactoryImpl::getAllPointGroupSymbols) - .def("getPointGroupSymbols", &PointGroupFactoryImpl::getPointGroupSymbols) + .def("isSubscribed", &PointGroupFactoryImpl::isSubscribed, "Returns true of the point group with the given symbol is subscribed.") + .def("createPointGroup", &PointGroupFactoryImpl::createPointGroup, "Creates a point group if registered.") + .def("createPointGroupFromSpaceGroup", &getPointGroupFromSpaceGroup, "Creates the point group that corresponds to the given space group.") + .def("createPointGroupFromSpaceGroupSymbol", &getPointGroupFromSpaceGroupSymbol, "Creates a point group directly from the space group symbol.") + .def("getAllPointGroupSymbols", &PointGroupFactoryImpl::getAllPointGroupSymbols, "Returns all registered point group symbols.") + .def("getPointGroupSymbols", &PointGroupFactoryImpl::getPointGroupSymbols, "Returns all point groups registered for the given crystal system.") .def("Instance", &PointGroupFactory::Instance, return_value_policy<reference_existing_object>(), "Returns a reference to the PointGroupFactory singleton") .staticmethod("Instance") diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroup.cpp b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroup.cpp index 2608650efae0afb655e41a3022890f6b1da3ceb5..ba7a58c1575649ee82b1da7ffd4db39926f54df5 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroup.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroup.cpp @@ -31,18 +31,6 @@ namespace //<unnamed> return pythonEquivalents; } - std::vector<std::string> getSymmetryOperationStrings(SpaceGroup & self) - { - const std::vector<SymmetryOperation> &symOps = self.getSymmetryOperations(); - - std::vector<std::string> pythonSymOps; - for(auto it = symOps.begin(); it != symOps.end(); ++it) { - pythonSymOps.push_back((*it).identifier()); - } - - return pythonSymOps; - } - } void export_SpaceGroup() @@ -50,10 +38,8 @@ void export_SpaceGroup() register_ptr_to_python<boost::shared_ptr<SpaceGroup> >(); class_<SpaceGroup, boost::noncopyable, bases<Group> >("SpaceGroup", no_init) - .def("order", &SpaceGroup::order) - .def("getSymmetryOperationStrings", &getSymmetryOperationStrings) - .def("number", &SpaceGroup::number) - .def("hmSymbol", &SpaceGroup::hmSymbol) + .def("getNumber", &SpaceGroup::number) + .def("getHMSymbol", &SpaceGroup::hmSymbol) .def("getEquivalentPositions", &getEquivalentPositions, "Returns an array with all symmetry equivalents of the supplied HKL.") ; } diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroupFactory.cpp b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroupFactory.cpp index 0f906422a0f69a1d79769f36b661ce17fd57242e..52fa370c732bb545b6e2a748b09d82211b66eec0 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroupFactory.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroupFactory.cpp @@ -42,12 +42,12 @@ void export_SpaceGroupFactory() { class_<SpaceGroupFactoryImpl,boost::noncopyable>("SpaceGroupFactoryImpl", no_init) - .def("isSubscribedSymbol", &isSubscribedSymbol) - .def("isSubscribedNumber", &isSubscribedNumber) - .def("createSpaceGroup", &createSpaceGroup) - .def("allSubscribedSpaceGroupSymbols", &allSpaceGroupSymbols) - .def("subscribedSpaceGroupSymbols", &spaceGroupSymbolsForNumber) - .def("subscribedSpaceGroupNumbers", &SpaceGroupFactoryImpl::subscribedSpaceGroupNumbers) + .def("isSubscribedSymbol", &isSubscribedSymbol, "Returns true if the space group the supplied symbol is subscribed.") + .def("isSubscribedNumber", &isSubscribedNumber, "Returns true if a space group with the given number is subscribed.") + .def("createSpaceGroup", &createSpaceGroup, "Creates a space group.") + .def("getAllSpaceGroupSymbols", &allSpaceGroupSymbols, "Returns all subscribed space group symbols.") + .def("getAllSpaceGroupNumbers", &SpaceGroupFactoryImpl::subscribedSpaceGroupNumbers, "Returns all subscribed space group numbers.") + .def("subscribedSpaceGroupSymbols", &spaceGroupSymbolsForNumber, "Returns all space group symbols that are registered under the given number.") .def("Instance", &SpaceGroupFactory::Instance, return_value_policy<reference_existing_object>(), "Returns a reference to the SpaceGroupFactory singleton") .staticmethod("Instance") diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryElement.cpp b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryElement.cpp index eb0ea8480b791962cd67e3c3182c97bd46a9fb53..b32232a7c01866bedabbe3ea396a3f88e9ecf81e 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryElement.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryElement.cpp @@ -24,6 +24,6 @@ void export_SymmetryElement() register_ptr_to_python<boost::shared_ptr<SymmetryElement> >(); scope symmetryElementScope = class_<SymmetryElement, boost::noncopyable>("SymmetryElement", no_init); class_<SymmetryElement, boost::noncopyable>("SymmetryElement", no_init) - .def("hmSymbol", &SymmetryElement::hmSymbol) - .def("getAxis", &getAxis); + .def("getHMSymbol", &SymmetryElement::hmSymbol, "Returns the Hermann-Mauguin symbol for the element.") + .def("getAxis", &getAxis, "Returns the symmetry axis or [0,0,0] for identiy, inversion and translations."); } diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryElementFactory.cpp b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryElementFactory.cpp index b91d49193ae6888fbdff973bc5afb007be68e1d5..e9b8fbce249e81ace70b3bcab0fc9b544baeda4d 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryElementFactory.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryElementFactory.cpp @@ -8,7 +8,7 @@ using namespace boost::python; void export_SymmetryElementFactory() { class_<SymmetryElementFactoryImpl,boost::noncopyable>("SymmetryElementFactoryImpl", no_init) - .def("createSymElement", &SymmetryElementFactoryImpl::createSymElement) + .def("createSymElement", &SymmetryElementFactoryImpl::createSymElement, "Creates the symmetry element that corresponds to the supplied symmetry operation.") .def("Instance", &SymmetryElementFactory::Instance, return_value_policy<reference_existing_object>(), "Returns a reference to the SymmetryElementFactory singleton") .staticmethod("Instance") diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryOperation.cpp b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryOperation.cpp index 0b1d516b7bd51297ce7d29c9051ffd095a408f08..59d759176210a16b552ab252dac6957fd97e6553 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryOperation.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryOperation.cpp @@ -33,10 +33,10 @@ void export_SymmetryOperation() register_ptr_to_python<boost::shared_ptr<SymmetryOperation> >(); class_<SymmetryOperation>("SymmetryOperation") - .def("order", &SymmetryOperation::order) - .def("identifier", &SymmetryOperation::identifier) - .def("transformCoordinates", &applyToCoordinates) - .def("transformHKL", &applyToVector) - .def("apply", &applyToVector); + .def("getOrder", &SymmetryOperation::order, "Returns the order of the symmetry operation, which indicates how often the operation needs to be applied to a point to arrive at identity.") + .def("getIdentifier", &SymmetryOperation::identifier, "The identifier of the operation in x,y,z-notation.") + .def("transformCoordinates", &applyToCoordinates, "Returns transformed coordinates. For transforming HKLs, use transformHKL.") + .def("transformHKL", &applyToVector, "Returns transformed HKLs. For transformation of coordinates use transformCoordinates.") + .def("apply", &applyToVector, "An alias for transformHKL."); } diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryOperationFactory.cpp b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryOperationFactory.cpp index 70429347e117ab4ece4cd21107bb2a3bb55a3c29..436815a0ae22a737785ec0dad16d97b16b714684 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryOperationFactory.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryOperationFactory.cpp @@ -2,16 +2,32 @@ #include "MantidPythonInterface/kernel/PythonObjectInstantiator.h" #include <boost/python/class.hpp> +#include <boost/python/list.hpp> using namespace Mantid::Geometry; using namespace boost::python; +namespace { + boost::python::list createSymOps(SymmetryOperationFactoryImpl &self, const std::string &identifiers) { + std::vector<SymmetryOperation> symOps = self.createSymOps(identifiers); + + boost::python::list pythonOperations; + for(auto it = symOps.begin(); it != symOps.end(); ++it) { + pythonOperations.append(*it); + } + + return pythonOperations; + } + +} + void export_SymmetryOperationFactory() { class_<SymmetryOperationFactoryImpl,boost::noncopyable>("SymmetryOperationFactoryImpl", no_init) - .def("exists", &SymmetryOperationFactoryImpl::isSubscribed) - .def("createSymOp", &SymmetryOperationFactoryImpl::createSymOp) - .def("subscribedSymbols", &SymmetryOperationFactoryImpl::subscribedSymbols) + .def("exists", &SymmetryOperationFactoryImpl::isSubscribed, "Returns true if the symmetry operation is supplied.") + .def("createSymOp", &SymmetryOperationFactoryImpl::createSymOp, "Creates the symmetry operation from the supplied x,y,z-identifier.") + .def("createSymOps", &createSymOps, "Creates a vector of SymmetryOperation objects from a semi-colon separated list of x,y,z-identifiers.") + .def("subscribedSymbols", &SymmetryOperationFactoryImpl::subscribedSymbols, "Return all subscribed symbols.") .def("Instance", &SymmetryOperationFactory::Instance, return_value_policy<reference_existing_object>(), "Returns a reference to the SymmetryOperationFactory singleton") .staticmethod("Instance") diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/LRPrimaryFraction.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/LRPrimaryFraction.py new file mode 100644 index 0000000000000000000000000000000000000000..9c0c3994fd85a2a27fa2582fa5c4515fe3b9eb0a --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/LRPrimaryFraction.py @@ -0,0 +1,99 @@ +#pylint: disable=no-init,invalid-name +import math +from mantid.api import * +from mantid.simpleapi import * +from mantid.kernel import * + +class LRPrimaryFraction(PythonAlgorithm): + + def category(self): + return "Reflectometry\\SNS" + + def name(self): + return "LRPrimaryFraction" + + def version(self): + return 1 + + def summary(self): + return "Liquids Reflectometer primary fraction ('clocking') calculation" + + def PyInit(self): + self.declareProperty(WorkspaceProperty("InputWorkspace", "",Direction.Input), "The workspace to check.") + self.declareProperty(IntArrayProperty("SignalRange", [117, 197], + IntArrayLengthValidator(2), direction=Direction.Input), + "Pixel range defining the reflected signal") + self.declareProperty("BackgroundWidth", 3, + doc="Number of pixels defining width of the background on each side of the signal") + self.declareProperty(FloatArrayProperty("ScalingFactor", [1.0, 0.0], direction=Direction.Output), + "Calculated scaling factor and error") + + def PyExec(self): + workspace = self.getProperty("InputWorkspace").value + + # Background offset in number of pixels + bck_width = self.getProperty("BackgroundWidth").value + + # Signal region + [peak_from_pixel, peak_to_pixel] = self.getProperty("SignalRange").value + + # Background outer region + bck_from_pixel = peak_from_pixel - bck_width + bck_to_pixel = peak_to_pixel + bck_width + + # Number of pixels in each direction + #TODO: revisit this when we update the IDF + number_of_pixels_x = int(workspace.getInstrument().getNumberParameter("number-of-x-pixels")[0]) + number_of_pixels_y = int(workspace.getInstrument().getNumberParameter("number-of-y-pixels")[0]) + + # Sum up the low-resolution axis and sum up all the wavelengths + workspace = Integration(InputWorkspace=workspace) + workspace = RefRoi(InputWorkspace=workspace, + NXPixel=number_of_pixels_x, NYPixel=number_of_pixels_y, + IntegrateY=False, ConvertToQ=False) + workspace = Transpose(InputWorkspace=workspace) + + data_y = workspace.dataY(0) + data_e = workspace.dataE(0) + + # Compute average background on each side + avg_bck = 0 + avg_bck_err = 0 + for i in range(bck_from_pixel, peak_from_pixel): + if data_e[i] == 0: data_e[i] = 1.0 + avg_bck += data_y[i] / data_e[i] / data_e[i] + avg_bck_err += 1.0 / data_e[i] / data_e[i] + + for i in range(peak_to_pixel+1, bck_to_pixel+1): + if data_e[i] == 0: data_e[i] = 1 + avg_bck += data_y[i] / data_e[i] / data_e[i] + avg_bck_err += 1.0 / data_e[i] / data_e[i] + + if avg_bck_err > 0: + avg_bck /= avg_bck_err + avg_bck_err = math.sqrt(1.0/avg_bck_err) + + # Subtract average background from specular peak pixels and sum + specular_counts = 0 + specular_counts_err = 0 + for i in range(peak_from_pixel, peak_to_pixel+1): + specular_counts += data_y[i] - avg_bck + if data_e[i] == 0: data_e[i] = 1.0 + specular_counts_err += data_e[i] * data_e[i] + avg_bck_err * avg_bck_err + specular_counts_err = math.sqrt(specular_counts_err) + + total_counts = sum(data_y) + + # Specular ratio + r = specular_counts / total_counts + r_err = r * math.sqrt(specular_counts_err * specular_counts_err / specular_counts / specular_counts) + 1.0/total_counts + + self.setProperty("ScalingFactor", [r, r_err]) + + logger.information("Total counts: %s" % total_counts) + logger.information("Average background: %s +- %s" % (avg_bck, avg_bck_err)) + logger.information("Primary counts: %s +- %s" % (specular_counts, specular_counts_err)) + logger.information("Primary fraction: %s +- %s" % (r, r_err)) + + +AlgorithmFactory.subscribe(LRPrimaryFraction) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/LiquidsReflectometryReduction.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/LiquidsReflectometryReduction.py index c3a4bc826f7138a0a5fb2230eb129f61debba476..501337fc13ab5bed411f8ae26931cd4c070c92cf 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/LiquidsReflectometryReduction.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/LiquidsReflectometryReduction.py @@ -48,7 +48,7 @@ class LiquidsReflectometryReduction(PythonAlgorithm): self.declareProperty(IntArrayProperty("LowResNormAxisPixelRange", [115, 210], IntArrayLengthValidator(2), direction=Direction.Input), "Pixel range to use in the low resolution direction of the normalizaion run") - self.declareProperty(FloatArrayProperty("TOFRange", [9000., 23600.], + self.declareProperty(FloatArrayProperty("TOFRange", [0., 340000.], FloatArrayLengthValidator(2), direction=Direction.Input), "TOF range to use") self.declareProperty("TofRangeFlag", True, @@ -67,6 +67,10 @@ class LiquidsReflectometryReduction(PythonAlgorithm): self.declareProperty("BackSlitName", "Si", doc="Name of the back slit") self.declareProperty("TOFSteps", 40.0, doc="TOF step size") self.declareProperty("CropFirstAndLastPoints", True, doc="If true, we crop the first and last points") + self.declareProperty("ApplyPrimaryFraction", False, doc="If true, the primary fraction correction will be applied") + self.declareProperty(IntArrayProperty("PrimaryFractionRange", [117, 197], + IntArrayLengthValidator(2), direction=Direction.Input), + "Pixel range to use for calculating the primary fraction correction.") def PyExec(self): # The old reflectivity reduction has an offset between the input @@ -101,6 +105,14 @@ class LiquidsReflectometryReduction(PythonAlgorithm): file_list.append(data_file) runs = reduce((lambda x, y: '%s+%s' % (x, y)), file_list) ws_event_data = Load(Filename=runs) + + # Compute the primary fraction using the unprocessed workspace + apply_primary_fraction = self.getProperty("ApplyPrimaryFraction").value + primary_fraction = [1.0, 0.0] + if apply_primary_fraction: + signal_range = self.getProperty("PrimaryFractionRange").value + primary_fraction = LRPrimaryFraction(InputWorkspace=ws_event_data, + SignalRange=signal_range) # Get the TOF range TOFrangeFlag = self.getProperty("TofRangeFlag") @@ -127,27 +139,31 @@ class LiquidsReflectometryReduction(PythonAlgorithm): dataPeakRange, bck_request, dataBackRange) # ----- Normalization ------------------------------------------------- - # Load normalization - ws_event_norm = LoadEventNexus("REF_L_%s" % normalizationRunNumber, - OutputWorkspace="REF_L_%s" % normalizationRunNumber) - crop_request = self.getProperty("LowResNormAxisPixelRangeFlag") - low_res_range = self.getProperty("LowResNormAxisPixelRange").value - bck_request = self.getProperty("SubtractNormBackground").value - norm_cropped = self.process_data(ws_event_norm, TOFrange, - crop_request, low_res_range, - normPeakRange, bck_request, normBackRange) - # Avoid leaving trash behind - AnalysisDataService.remove(str(ws_event_norm)) - - # Sum up the normalization peak - norm_summed = SumSpectra(InputWorkspace = norm_cropped) + perform_normalization = self.getProperty("NormFlag").value + if perform_normalization: + # Load normalization + ws_event_norm = LoadEventNexus("REF_L_%s" % normalizationRunNumber, + OutputWorkspace="REF_L_%s" % normalizationRunNumber) + crop_request = self.getProperty("LowResNormAxisPixelRangeFlag") + low_res_range = self.getProperty("LowResNormAxisPixelRange").value + bck_request = self.getProperty("SubtractNormBackground").value + norm_cropped = self.process_data(ws_event_norm, TOFrange, + crop_request, low_res_range, + normPeakRange, bck_request, normBackRange) + # Avoid leaving trash behind + AnalysisDataService.remove(str(ws_event_norm)) + + # Sum up the normalization peak + norm_summed = SumSpectra(InputWorkspace = norm_cropped) - # Normalize the data - normalized_data = data_cropped / norm_summed - # Avoid leaving trash behind - AnalysisDataService.remove(str(data_cropped)) - AnalysisDataService.remove(str(norm_cropped)) - AnalysisDataService.remove(str(norm_summed)) + # Normalize the data + normalized_data = data_cropped / norm_summed + # Avoid leaving trash behind + AnalysisDataService.remove(str(data_cropped)) + AnalysisDataService.remove(str(norm_cropped)) + AnalysisDataService.remove(str(norm_summed)) + else: + normalized_data = data_cropped normalized_data = ConvertToPointData(InputWorkspace=normalized_data, OutputWorkspace=str(normalized_data)) @@ -191,6 +207,13 @@ class LiquidsReflectometryReduction(PythonAlgorithm): q_rebin = Rebin(InputWorkspace=q_workspace, Params=q_range, OutputWorkspace=name_output_ws) + # Apply the primary fraction + if apply_primary_fraction: + ws_fraction = CreateSingleValuedWorkspace(DataValue=primary_fraction[0], + ErrorValue=primary_fraction[1]) + q_rebin = Multiply(LHSWorkspace=q_rebin, RHSWorkspace=ws_fraction, + OutputWorkspace=name_output_ws) + # Crop to non-zero values data_y = q_rebin.readY(0) low_q = None @@ -430,10 +453,10 @@ class LiquidsReflectometryReduction(PythonAlgorithm): scaling_factor_file = scaling_factor_files[0] if not os.path.isfile(scaling_factor_file): logger.error("Could not find scaling factor file %s" % scaling_factor_file) - return + return workspace else: logger.error("Could not find scaling factor file %s" % scaling_factor_file) - return + return workspace # Get the incident medium incident_medium = self.getProperty("IncidentMediumSelected").value diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/LoadVesuvio.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/LoadVesuvio.py index 8100c0d2728c2936144e44d428c70674cfa101aa..0ebd8ec810b2a217e98ddfe3e91782c875906208 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/LoadVesuvio.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/LoadVesuvio.py @@ -153,6 +153,7 @@ class LoadVesuvio(PythonAlgorithm): ip_file = self.getPropertyValue(INST_PAR_PROP) if len(ip_file) > 0: self._load_ip_file(ip_file) + if self._sumspectra: self._sum_all_spectra() @@ -213,6 +214,9 @@ class LoadVesuvio(PythonAlgorithm): np.sqrt(dataE, dataE) foil_out.setX(ws_index, x_values) + if self._sumspectra: + self._sum_all_spectra() + DeleteWorkspace(Workspace=SUMMED_WS) self._store_results() @@ -728,13 +732,20 @@ class LoadVesuvio(PythonAlgorithm): # foil_out has all spectra in order specified by input foil_start = 0 for idx_out in range(len(self._spectra)): + ws_out.setX(idx_out, self.foil_out.readX(foil_start)) summed_set = self._spectra[idx_out] nsummed = len(summed_set) y_out, e_out = ws_out.dataY(idx_out), ws_out.dataE(idx_out) + spec_out = ws_out.getSpectrum(idx_out) + spec_out.setSpectrumNo(self.foil_out.getSpectrum(foil_start).getSpectrumNo()) + spec_out.clearDetectorIDs() for foil_idx in range(foil_start, foil_start+nsummed): y_out += self.foil_out.readY(foil_idx) foil_err = self.foil_out.readE(foil_idx) e_out += foil_err*foil_err # gaussian errors + in_ids = self.foil_out.getSpectrum(foil_idx).getDetectorIDs() + for det_id in in_ids: + spec_out.addDetectorID(det_id) #endfor np.sqrt(e_out, e_out) foil_start += nsummed diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TimeSlice.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TimeSlice.py index d318ac36ca345b91dd1dc01194f2c1aa67f718c1..37d251ba070c55f1e3b6f5cf9b21b55b84157e9b 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TimeSlice.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TimeSlice.py @@ -115,7 +115,7 @@ class TimeSlice(PythonAlgorithm): return '' - def validateInput(self): + def validateInputs(self): issues = dict() issues['SpectraRange'] = self._validate_range('SpectraRange') diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TransformToIqt.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TransformToIqt.py index ab2d4a4c5129930c1eb751de12641d099251eecf..d8ec5def96a9334a6c2330ae2ed9e83556a85ee0 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TransformToIqt.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TransformToIqt.py @@ -23,7 +23,7 @@ class TransformToIqt(PythonAlgorithm): def category(self): - return "Workflow\\Inelastic;PythonAlgorithms" + return "Workflow\\Inelastic;PythonAlgorithms;Workflow\\MIDAS" def summary(self): diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/PointGroupTest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/PointGroupTest.py index 2a35a5bc0a7976b27e9b4c5455c223523423eec1..d8750f8d9db7ba77b31bd3f65a5da7643c598b97 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/PointGroupTest.py +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/PointGroupTest.py @@ -12,8 +12,8 @@ class PointGroupTest(unittest.TestCase): def test_getInfo(self): pg = PointGroupFactory.createPointGroup("m-3m") self.assertEquals(pg.getName(), "m-3m (Cubic)") - self.assertEquals(pg.getSymbol(), "m-3m") - self.assertEquals(pg.crystalSystem(), PointGroup.CrystalSystem.Cubic) + self.assertEquals(pg.getHMSymbol(), "m-3m") + self.assertEquals(pg.getCrystalSystem(), PointGroup.CrystalSystem.Cubic) def test_isEquivalent(self): hkl1 = V3D(1, 1, 1) diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SpaceGroupTest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SpaceGroupTest.py index a3a24ed6d47b343a0cc5a5830dd38f6a866d9adc..f0bcd652ea9cd1e2ae58411d8f8a598aa56c3794 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SpaceGroupTest.py +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SpaceGroupTest.py @@ -1,8 +1,9 @@ +#pylint: disable=no-init,invalid-name,too-many-public-methods import unittest -from mantid.geometry import SpaceGroup, SpaceGroupFactory +from mantid.geometry import SpaceGroupFactory -class SpaceGroupTest(unittest.TestCase): +class SpaceGroupTest(unittest.TestCase): def test_creation(self): self.assertRaises(ValueError, SpaceGroupFactory.createSpaceGroup, "none") @@ -10,8 +11,8 @@ class SpaceGroupTest(unittest.TestCase): def test_interface(self): spaceGroup = SpaceGroupFactory.createSpaceGroup("P -1") - self.assertEquals(spaceGroup.hmSymbol(), "P -1") - self.assertEquals(spaceGroup.order(), 2) + self.assertEquals(spaceGroup.getHMSymbol(), "P -1") + self.assertEquals(spaceGroup.getOrder(), 2) symOpStrings = spaceGroup.getSymmetryOperationStrings() @@ -19,13 +20,104 @@ class SpaceGroupTest(unittest.TestCase): self.assertTrue("x,y,z" in symOpStrings) self.assertTrue("-x,-y,-z" in symOpStrings) - def test_equivalentPositions(self): + def test_equivalentPositions_Triclinic(self): + wyckoffs = [([0.3, 0.4, 0.45], 2), + ([0.5, 0.5, 0.5], 1), + ([0.0, 0.5, 0.5], 1), + ([0.5, 0.0, 0.5], 1), + ([0.5, 0.5, 0.0], 1), + ([0.5, 0.0, 0.0], 1), + ([0.0, 0.5, 0.0], 1), + ([0.0, 0.0, 0.5], 1), + ([0.0, 0.0, 0.0], 1)] + spaceGroup = SpaceGroupFactory.createSpaceGroup("P -1") + self.checkWyckoffPositions(spaceGroup, wyckoffs) + + def test_equivalentPositions_Monoclinic(self): + wyckoffs = [([0.3, 0.4, 0.45], 8), + ([0.0, 0.4, 0.25], 4), + ([0.25, 0.25, 0.5], 4), + ([0.25, 0.25, 0.0], 4), + ([0.0, 0.5, 0.0], 4), + ([0.0, 0.0, 0.0], 4)] + + spaceGroup = SpaceGroupFactory.createSpaceGroup("C 1 2/c 1") + self.checkWyckoffPositions(spaceGroup, wyckoffs) + + def test_equivalentPositions_Orthorhombic(self): + wyckoffs = [([0.3, 0.4, 0.45], 16), + ([0.3, 0.25, 0.45], 8), + ([0.0, 0.4, 0.45], 8), + ([0.25, 0.4, 0.25], 8), + ([0.3, 0.0, 0.0], 8), + ([0.0, 0.25, 0.45], 4), + ([0.25, 0.25, 0.75], 4), + ([0.25, 0.25, 0.25], 4), + ([0.0, 0.0, 0.5], 4), + ([0.0, 0.0, 0.0], 4)] + + spaceGroup = SpaceGroupFactory.createSpaceGroup("I m m a") + self.checkWyckoffPositions(spaceGroup, wyckoffs) + + def test_equivalentPositions_Tetragonal(self): + wyckoffs = [([0.3, 0.4, 0.45], 32), + ([0.3, 0.3, 0.25], 16), + ([0.25, 0.4, 0.125], 16), + ([0.0, 0.0, 0.45], 16), + ([0.0, 0.25, 0.125], 16), + ([0.0, 0.0, 0.25], 8), + ([0.0, 0.0, 0.0], 8)] + + spaceGroup = SpaceGroupFactory.createSpaceGroup("I 41/a c d") + self.checkWyckoffPositions(spaceGroup, wyckoffs) + + def test_equivalentPositions_Trigonal(self): + wyckoffs = [([0.3, 0.4, 0.45], 36), + ([0.3, 0.0, 0.25], 18), + ([0.5, 0.0, 0.0], 18), + ([0.0, 0.0, 0.45], 12), + ([0.0, 0.0, 0.0], 6), + ([0.0, 0.0, 0.25], 6)] + + spaceGroup = SpaceGroupFactory.createSpaceGroup("R -3 c") + self.checkWyckoffPositions(spaceGroup, wyckoffs) + + def test_equivalentPositions_Hexagonal(self): + wyckoffs = [([0.3, 0.4, 0.45], 24), + ([0.3, 0.6, 0.45], 12), + ([0.3, 0.4, 0.25], 12), + ([0.3, 0.0, 0.0], 12), + ([0.3, 0.6, 0.25], 6), + ([0.5, 0.0, 0.0], 6), + ([1. / 3., 2. / 3., 0.45], 4), + ([0.0, 0.0, 0.45], 4), + ([1. / 3, 2. / 3., 0.75], 2), + ([1. / 3, 2. / 3., 0.25], 2), + ([0.0, 0.0, 0.25], 2), + ([0.0, 0.0, 0.0], 2)] + + spaceGroup = SpaceGroupFactory.createSpaceGroup("P 63/m m c") + self.checkWyckoffPositions(spaceGroup, wyckoffs) + + def test_equivalentPositions_Cubic(self): + wyckoffs = [([0.3, 0.4, 0.45], 96), + ([0.3, 0.25, 0.25], 48), + ([0.3, 0.0, 0.0], 48), + ([0.3, 0.3, 0.3], 32), + ([0.25, 0.0, 0.0], 24), + ([0.0, 0.25, 0.25], 24), + ([0.25, 0.25, 0.25], 8), + ([0.0, 0.0, 0.0], 8)] + + spaceGroup = SpaceGroupFactory.createSpaceGroup("F -4 3 c") + self.checkWyckoffPositions(spaceGroup, wyckoffs) - position = [0.34, 0.3, 0.4] - equivalentPositions = spaceGroup.getEquivalentPositions(position) + def checkWyckoffPositions(self, spaceGroup, wyckoffs): + for wp in wyckoffs: + equivalentPositions = spaceGroup.getEquivalentPositions(wp[0]) + self.assertEqual(len(equivalentPositions), wp[1]) - self.assertEqual(len(equivalentPositions), 2) if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main() diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SymmetryElementTest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SymmetryElementTest.py index f5874c853df22b4893f19afbc9bfcded0e64f263..56196d1653a8a89d5a5afa145663d01aafbf9f90 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SymmetryElementTest.py +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SymmetryElementTest.py @@ -9,20 +9,20 @@ class SymmetryElementTest(unittest.TestCase): symOp = SymmetryOperationFactory.createSymOp("x,y,-z") symEle = SymmetryElementFactory.createSymElement(symOp) - self.assertEquals(symEle.hmSymbol(), "m") + self.assertEquals(symEle.getHMSymbol(), "m") self.assertEquals(symEle.getAxis(), V3D(0,0,1)) rotation = SymmetryOperationFactory.createSymOp("x,-y,-z") rotationElement = SymmetryElementFactory.createSymElement(rotation) - self.assertEquals(rotationElement.hmSymbol(), "2") + self.assertEquals(rotationElement.getHMSymbol(), "2") self.assertEquals(rotationElement.getAxis(), V3D(1,0,0)) def test_creation_no_axis(self): symOp = SymmetryOperationFactory.createSymOp("-x,-y,-z") symEle = SymmetryElementFactory.createSymElement(symOp) - self.assertEquals(symEle.hmSymbol(), "-1") + self.assertEquals(symEle.getHMSymbol(), "-1") self.assertEquals(symEle.getAxis(), V3D(0,0,0)) diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SymmetryOperationTest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SymmetryOperationTest.py index b2dbbf58bc6674f8231dffe9369c235c456886a8..51809123afa5836430e80ddff6751b6e558a1de4 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SymmetryOperationTest.py +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SymmetryOperationTest.py @@ -11,8 +11,8 @@ class SymmetryOperationTest(unittest.TestCase): def test_getInfo(self): symOp = SymmetryOperationFactory.createSymOp("x, y, -z") - self.assertEquals(symOp.order(), 2) - self.assertEquals(symOp.identifier(), "x,y,-z") + self.assertEquals(symOp.getOrder(), 2) + self.assertEquals(symOp.getIdentifier(), "x,y,-z") def test_apply(self): symOp = SymmetryOperationFactory.createSymOp("x,y,-z") @@ -21,7 +21,7 @@ class SymmetryOperationTest(unittest.TestCase): hkl2 = symOp.apply(hkl1) self.assertEquals(hkl2, V3D(1, 1, -1)) - self.assertEquals(symOp.apply(hkl2), hkl1) + self.assertEquals(symOp.transformHKL(hkl2), hkl1) if __name__ == '__main__': diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/TimeSliceTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/TimeSliceTest.py index 9a30f00dc6ba2eccb3128e779816286e5ae43ddd..0fd5466292de74df852c0a5705b8a5f5b37afb14 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/TimeSliceTest.py +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/TimeSliceTest.py @@ -18,6 +18,7 @@ class TimeSliceTest(unittest.TestCase): self.assertTrue(mtd.doesExist('SliceTestOut')) self.assertTrue(mtd.doesExist('irs26173_slice')) + def test_suffix(self): """ Tests to ensure that output names have a suffic appended correctly. @@ -32,5 +33,66 @@ class TimeSliceTest(unittest.TestCase): self.assertTrue(mtd.doesExist('irs26173_graphite002_slice')) + + def test_validation_peak_range_order(self): + """ + Tests validation of the PeakRange property. + """ + + self.assertRaises(RuntimeError, + TimeSlice, + InputFiles=['IRS26173.raw'], + SpectraRange=[3, 53], + PeakRange=[65000, 62500], + BackgroundRange=[59000, 61500], + OutputNameSuffix='_graphite002_slice', + OutputWorkspace='SliceTestOut') + + + def test_validation_peak_range_count(self): + """ + Tests validation of the PeakRange property. + """ + + self.assertRaises(RuntimeError, + TimeSlice, + InputFiles=['IRS26173.raw'], + SpectraRange=[3, 53], + PeakRange=[65000], + BackgroundRange=[59000, 61500], + OutputNameSuffix='_graphite002_slice', + OutputWorkspace='SliceTestOut') + + + def test_validation_background_range_order(self): + """ + Tests validation of the BackgroundRange property. + """ + + self.assertRaises(RuntimeError, + TimeSlice, + InputFiles=['IRS26173.raw'], + SpectraRange=[3, 53], + PeakRange=[65000, 62500], + BackgroundRange=[61500, 59000], + OutputNameSuffix='_graphite002_slice', + OutputWorkspace='SliceTestOut') + + + def test_validation_peak_range_count(self): + """ + Tests validation of the BackgroundRange property. + """ + + self.assertRaises(RuntimeError, + TimeSlice, + InputFiles=['IRS26173.raw'], + SpectraRange=[3, 53], + PeakRange=[65000, 62500], + BackgroundRange=[59000], + OutputNameSuffix='_graphite002_slice', + OutputWorkspace='SliceTestOut') + + if __name__ == '__main__': unittest.main() diff --git a/Code/Mantid/Framework/RemoteJobManagers/CMakeLists.txt b/Code/Mantid/Framework/RemoteJobManagers/CMakeLists.txt index f8af33ea0dde8f79ea4a49ef6498481a3b16cd0e..0b1a10dcb73f7681e010c5b1015afb048cdede7d 100644 --- a/Code/Mantid/Framework/RemoteJobManagers/CMakeLists.txt +++ b/Code/Mantid/Framework/RemoteJobManagers/CMakeLists.txt @@ -1,14 +1,22 @@ set( SRC_FILES + src/MantidWebServiceAPIHelper.cpp + src/MantidWebServiceAPIJobManager.cpp src/LSFJobManager.cpp src/SCARFLSFJobManager.cpp + src/SimpleJSON.cpp ) set( INC_FILES + inc/MantidRemoteJobManagers/MantidWebServiceAPIHelper.h + inc/MantidRemoteJobManagers/MantidWebServiceAPIJobManager.h inc/MantidRemoteJobManagers/LSFJobManager.h inc/MantidRemoteJobManagers/SCARFLSFJobManager.h + inc/MantidRemoteJobManagers/SimpleJSON.h ) set ( TEST_FILES + MantidWebServiceAPIHelperTest.h + MantidWebServiceAPIJobManagerTest.h LSFJobManagerTest.h SCARFLSFJobManagerTest.h ) diff --git a/Code/Mantid/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/MantidWebServiceAPIHelper.h b/Code/Mantid/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/MantidWebServiceAPIHelper.h new file mode 100644 index 0000000000000000000000000000000000000000..9c97eedf87b1cfbb8c954200ae63ef246584d0ee --- /dev/null +++ b/Code/Mantid/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/MantidWebServiceAPIHelper.h @@ -0,0 +1,142 @@ +#ifndef MANTID_REMOTEJOBMANAGERS_MANTIDWEBSERVICEAPIHELPER_H +#define MANTID_REMOTEJOBMANAGERS_MANTIDWEBSERVICEAPIHELPER_H + +#include <string> +#include <vector> +#include <map> + +#include "MantidKernel/DllConfig.h" + +#include <Poco/Net/HTTPResponse.h> + +namespace Poco { +namespace XML { +class Element; +} + +namespace Net { +class HTTPCookie; +class NameValueCollection; +class HTTPClientSession; +class HTTPRequest; +} +} + +namespace Mantid { +namespace RemoteJobManagers { +/** +MantidWebServiceAPIHelper handles HTTP requests and has been crated +starting from chunks of the class RemoteJobManager. This should/could +(ideally) be replaced by the newer InternetHelper class. + +implements a remote job manager that +knows how to talk to the Mantid web service / job submission API +(http://www.mantidproject.org/Remote_Job_Submission_API). This is +being used for example for the Fermi cluster at SNS. + +Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge +National Laboratory & European Spallation Source + +This file is part of Mantid. + +Mantid is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. + +Mantid is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + +File change history is stored at: <https://github.com/mantidproject/mantid>. +Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ + +class DLLExport MantidWebServiceAPIHelper { +public: + MantidWebServiceAPIHelper(); + + virtual ~MantidWebServiceAPIHelper(); + + // Name/Value pairs for POST data. Note that the second string might be + // binary, and might be + // fairly large. (If it were a JPG image for example...) + typedef std::map<std::string, std::string> PostDataMap; + + // Low level HTTP functions - GET, POST, etc... + // It's up to the various algorithms to know what to do with these functions + + // Perform an HTTP GET request (with optional HTTP Basic Auth) + std::istream &httpGet(const std::string &path, + const std::string &query_str = "", + const std::string &username = "", + const std::string &password = "") const; + + // Perform an HTTP POST request + std::istream &httpPost(const std::string &path, const PostDataMap &postData, + const PostDataMap &fileData = PostDataMap(), + const std::string &username = "", + const std::string &password = "") const; + + // Return the status code (200, 404, etc..) from the most recent request + Poco::Net::HTTPResponse::HTTPStatus lastStatus() const { + return m_response.getStatus(); + } + const std::string &lastStatusReason() { + return m_response.getReasonForStatus(m_response.getStatus()); + } + + const std::string &getDisplayName() const { return m_displayName; } + +private: + // Wraps up some of the boilerplate code needed to execute HTTP GET and POST + // requests + void initGetRequest(Poco::Net::HTTPRequest &req, std::string extraPath, + std::string queryString) const; + void initPostRequest(Poco::Net::HTTPRequest &req, + std::string extraPath) const; + void initHTTPRequest(Poco::Net::HTTPRequest &req, const std::string &method, + std::string extraPath, + std::string queryString = "") const; + + std::string m_displayName; + std::string + m_serviceBaseUrl; // What we're going to connect to. The full URL will be + // built by appending a path (and possibly a query string) + // to this string. + + // Store any cookies that the HTTP server sends us so we can send them back + // on future requests. (In particular, the ORNL servers use session cookies + // so we don't have to authenticate to the LDAP server on every single + // request.) + // + // NOTE: For reasons that are unclear, Poco's HTTPResponse class returns + // cookies + // in a vector of HTTPCookie objects, but its HTTPRequest::setCookies() + // function + // takes a NameValueCollection object, so we have to convert. (WTF Poco + // devs?!?) + static std::vector<Poco::Net::HTTPCookie> m_cookies; + Poco::Net::NameValueCollection getCookies() const; + + mutable Poco::Net::HTTPClientSession * + m_session; // Pointer to session object for all our HTTP requests + // (Has to be a pointer because we allocate and delete + // it multiple times) + Poco::Net::HTTPResponse + m_response; // Response object for all of our HTTP requests + + // No default copy constructor or assignment operator (mainly because + // HTTPResponse doesn't have them + MantidWebServiceAPIHelper(const MantidWebServiceAPIHelper &rjm); + MantidWebServiceAPIHelper &operator=(const MantidWebServiceAPIHelper &rjm); +}; + +} // end namespace RemoteJobManagers +} // end namespace Mantid + +#endif // MANTID_REMOTEJOBMANAGERS_MANTIDWEBSERVICEAPIHELPER_H diff --git a/Code/Mantid/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/MantidWebServiceAPIJobManager.h b/Code/Mantid/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/MantidWebServiceAPIJobManager.h new file mode 100644 index 0000000000000000000000000000000000000000..164f8d245e67b636486f9e4868d80f324b474568 --- /dev/null +++ b/Code/Mantid/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/MantidWebServiceAPIJobManager.h @@ -0,0 +1,101 @@ +#ifndef MANTID_REMOTEJOBMANAGERS_MANTIDWEBSERVICEAPIJOBMANAGER_H +#define MANTID_REMOTEJOBMANAGERS_MANTIDWEBSERVICEAPIJOBMANAGER_H + +#include "MantidAPI/IRemoteJobManager.h" +#include "MantidRemoteJobManagers/MantidWebServiceAPIHelper.h" + +namespace Mantid { +namespace RemoteJobManagers { +/** +MantidWebServiceAPIJobManager implements a remote job manager that +knows how to talk to the Mantid web service / job submission API +(http://www.mantidproject.org/Remote_Job_Submission_API). This is +being used for example for the Fermi cluster at SNS. + +Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge +National Laboratory & European Spallation Source + +This file is part of Mantid. + +Mantid is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. + +Mantid is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + +File change history is stored at: <https://github.com/mantidproject/mantid>. +Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class DLLExport MantidWebServiceAPIJobManager + : public Mantid::API::IRemoteJobManager { +public: + virtual ~MantidWebServiceAPIJobManager() {}; + + void authenticate(const std::string &username, const std::string &password); + + std::string + submitRemoteJob(const std::string &transactionID, const std::string &runnable, + const std::string ¶m, const std::string &taskName = "", + const int numNodes = 1, const int coresPerNode = 1); + + void downloadRemoteFile(const std::string &transactionID, + const std::string &remoteFileName, + const std::string &localFileName); + + std::vector<Mantid::API::IRemoteJobManager::RemoteJobInfo> + queryAllRemoteJobs() const; + + std::vector<std::string> + queryRemoteFile(const std::string &transactionID) const; + + Mantid::API::IRemoteJobManager::RemoteJobInfo + queryRemoteJob(const std::string &jobID) const; + + std::string startRemoteTransaction(); + + void stopRemoteTransaction(const std::string &transactionID); + + void abortRemoteJob(const std::string &jobID); + + void uploadRemoteFile(const std::string &transactionID, + const std::string &remoteFileName, + const std::string &localFileName); + +protected: + /// Use the helper for these operations + virtual std::istream &httpGet(const std::string &path, + const std::string &query_str = "", + const std::string &username = "", + const std::string &password = "") const { + return m_helper.httpGet(path, query_str, username, password); + } + + virtual std::istream & + httpPost(const std::string &path, + const MantidWebServiceAPIHelper::PostDataMap &postData, + const MantidWebServiceAPIHelper::PostDataMap &fileData = + MantidWebServiceAPIHelper::PostDataMap(), + const std::string &username = "", + const std::string &password = "") const { + return m_helper.httpPost(path, postData, fileData, username, password); + } + + virtual Poco::Net::HTTPResponse::HTTPStatus lastStatus() const { + return m_helper.lastStatus(); + } + +private: + MantidWebServiceAPIHelper m_helper; +}; + +} // namespace RemoteJobManagers +} // namespace Mantid + +#endif // MANTID_REMOTEJOBMANAGERS_MANTIDWEBSERVICEAPIJOBMANAGER_H diff --git a/Code/Mantid/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/SimpleJSON.h b/Code/Mantid/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/SimpleJSON.h new file mode 100644 index 0000000000000000000000000000000000000000..293b7b7ce26abfe32cabdeea86f4c8768ddac0ff --- /dev/null +++ b/Code/Mantid/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/SimpleJSON.h @@ -0,0 +1,121 @@ +/******************************************************************* + A cross-platform JSON parser that uses nothing more than C++ and + STL templates. It's probably slower than other JSON parsers, but + it's a heck of a lot smaller and simpler and works on Linux, MacOS + and Windows. + + I think it completely implements the JSON spec, but all I'm really + concerned with is whether it can parse the output from Moab Web + Services. + + RGM - 23 July 2012 + ******************************************************************/ + +#ifndef SIMPLEJSON_H +#define SIMPLEJSON_H + +#include <map> +#include <string> +#include <vector> +#include <istream> +#include <ostream> + +class JSONValue; +typedef std::map<std::string, JSONValue> JSONObject; +typedef std::vector<JSONValue> JSONArray; +// Note: according to the JSON spec, an array is a type of value. +// That isn't strictly true in the C++ sense here (ie: JSONArray +// doesn't inherit from JSONValue), but I think we'll be all right. + +// This is the "public" initialization function. Since JSONObject +// is just a typedef, there's no way to make it a constructor. +void initFromStream(JSONObject &obj, std::istream &istr); + +// A "public" function for formatted output. It's sort of assumed +// that ostr will actually be std::cout or std::cerr, but it can +// be any output stream. This function mostly exists for debugging +// purposes. +void prettyPrint(const JSONObject &obj, std::ostream &ostr, + unsigned indentLevel); + +class JSONException; + +class JSONValue { +public: + enum VALUE_TYPE { NULLTYPE, BOOL, NUMBER, STRING, ARRAY, OBJECT }; + + JSONValue(); // Initialize with the NULL value + JSONValue(bool v); // Initialize w/ true or false + JSONValue(double v); + JSONValue(const std::string &v); + JSONValue(const JSONArray &v); // Initialize w/ an array + JSONValue(const JSONObject &v); // Initialize w/ another JSON object + + JSONValue(std::istream &istr); // Initialize from a stream (and presumably + // create a whole hierarchy) + + // Formatted output to a stream - presumably cout. (Mostly for debugging + // purposes) + void prettyPrint(std::ostream &ostr, unsigned indentLevel) const; + + // Destructor, copy constructor and assignment operator + ~JSONValue(); + JSONValue(const JSONValue &v); + JSONValue &operator=(const JSONValue &v); + + // Accessors... + VALUE_TYPE getType() const { return m_type; } + + bool getValue(bool &v) const; + bool getValue(double &v) const; + bool getValue(std::string &v) const; + bool getValue(JSONArray &v) const; + bool getValue(JSONObject &v) const; + // If the object does not contain the requested type, then the accessor + // functions + // return false and leave v unchanged. + +private: + void assignmentOpHelper(); // Used by operator= (and by no-one else) + + VALUE_TYPE m_type; + + // This is where the actual value is stored + union { + bool m_bool; + double m_num; + std::string *mp_string; + JSONArray *mp_array; + JSONObject *mp_object; + }; +}; + +class JSONException : public std::exception { +public: + JSONException(const std::string &msg) : m_msg(msg) {} + const std::string &getMsg() const { return m_msg; } + + // Default constructor, copy constructor & assignment operator are fine + + virtual ~JSONException() throw() {} + +private: + std::string m_msg; +}; + +class JSONCopyException : public JSONException { +public: + JSONCopyException(const std::string &msg) : JSONException(msg) {} +}; + +class JSONAssignmentException : public JSONException { +public: + JSONAssignmentException(const std::string &msg) : JSONException(msg) {} +}; + +class JSONParseException : public JSONException { +public: + JSONParseException(const std::string &msg) : JSONException(msg) {} +}; + +#endif diff --git a/Code/Mantid/Framework/RemoteJobManagers/src/MantidWebServiceAPIHelper.cpp b/Code/Mantid/Framework/RemoteJobManagers/src/MantidWebServiceAPIHelper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..76fc0b074470c62601011a0d468ab4b63efe302a --- /dev/null +++ b/Code/Mantid/Framework/RemoteJobManagers/src/MantidWebServiceAPIHelper.cpp @@ -0,0 +1,238 @@ +#include "MantidKernel/ConfigService.h" +#include "MantidKernel/Logger.h" +#include "MantidKernel/RemoteJobManager.h" +#include "MantidRemoteJobManagers/MantidWebServiceAPIHelper.h" + +#include <Poco/Base64Encoder.h> +#include <Poco/Net/HTTPSClientSession.h> +#include <Poco/Net/HTTPRequest.h> +#include <Poco/Net/HTTPResponse.h> +#include <Poco/Net/HTTPCookie.h> +#include <Poco/Net/NameValueCollection.h> +#include <Poco/URI.h> + +#include <ostream> +#include <sstream> + +namespace Mantid { +namespace RemoteJobManagers { + +std::vector<Poco::Net::HTTPCookie> MantidWebServiceAPIHelper::m_cookies; + +MantidWebServiceAPIHelper::MantidWebServiceAPIHelper() + : m_session( + NULL) // Make sure this is always either NULL or a valid pointer. +{ + // TODO: the job manager factory or someone else should set this, and then + // this class would be usable with any other compute resource that implements + // the Mantid job submission API (web service). This could be done as part of + // ticket #11373 + // this is the name of the compute resource in the facilities file + m_displayName = "Fermi"; + // this is the baseURL from the facilities file - take it from there + m_serviceBaseUrl = "https://fermi.ornl.gov/MantidRemote"; +} + +MantidWebServiceAPIHelper::~MantidWebServiceAPIHelper() { delete m_session; } + +std::istream &MantidWebServiceAPIHelper::httpGet( + const std::string &path, const std::string &query_str, + const std::string &username, const std::string &password) const { + Poco::Net::HTTPRequest req; + initGetRequest(req, path, query_str); + + if (username.length() > 0) { + // Set the Authorization header (base64 encoded) + std::ostringstream encodedAuth; + Poco::Base64Encoder encoder(encodedAuth); + encoder << username << ":" << password; + encoder.close(); + req.setCredentials("Basic", encodedAuth.str()); + } + + m_session->sendRequest(req); + + std::istream &respStream = m_session->receiveResponse( + const_cast<Poco::Net::HTTPResponse &>(m_response)); + + // For as yet unknown reasons, we don't always get a session cookie back from + // the + // server. In that case, we don't want to overwrite the cookie we're currently + // using... + // Note: This won't work properly if we ever use cookies other than a + // session cookie. + std::vector<Poco::Net::HTTPCookie> newCookies; + m_response.getCookies(newCookies); + if (newCookies.size() > 0) { + m_cookies = newCookies; + } + + return respStream; +} + +std::istream &MantidWebServiceAPIHelper::httpPost( + const std::string &path, const PostDataMap &postData, + const PostDataMap &fileData, const std::string &username, + const std::string &password) const { + Poco::Net::HTTPRequest req; + initPostRequest(req, path); + + if (username.length() > 0) { + // Set the Authorization header (base64 encoded) + std::ostringstream encodedAuth; + Poco::Base64Encoder encoder(encodedAuth); + encoder << username << ":" << password; + encoder.close(); + req.setCredentials("Basic", encodedAuth.str()); + } + + // We have to do a POST with multipart MIME encoding. MIME is rather picky + // about + // how the parts are delimited. See RFC 2045 & 2046 for details. + + char httpLineEnd[3] = {0x0d, 0x0a, + 0x00}; // HTTP uses CRLF for its line endings + + // boundary can be almost anything (again, see RFC 2046). The important part + // is that it + // cannot appear anywhere in the actual data + std::string boundary = "112233MantidHTTPBoundary44556677"; + std::string boundaryLine = "--" + boundary + httpLineEnd; + std::string finalBoundaryLine = "--" + boundary + "--" + httpLineEnd; + + req.setContentType("multipart/form-data; boundary=" + boundary); + + // Need to be able to specify the content length, so build up the post body + // here. + std::ostringstream postBody; + PostDataMap::const_iterator it = postData.begin(); + while (it != postData.end()) { + postBody << boundaryLine; + postBody << "Content-Disposition: form-data; name=\"" << (*it).first + << "\""; + postBody << httpLineEnd << httpLineEnd; + postBody << (*it).second; + postBody << httpLineEnd; + ++it; + } + + // file data is treated the same as post data, except that we set the filename + // field + // in the Content-Disposition header and add the Content-Type header + it = fileData.begin(); + while (it != fileData.end()) { + postBody << boundaryLine; + postBody << "Content-Disposition: form-data; name=\"" << (*it).first + << "\"; filename=\"" << (*it).first << "\""; + postBody << httpLineEnd; + postBody << "Content-Type: application/octet-stream"; + postBody << httpLineEnd << httpLineEnd; + postBody << (*it).second; + postBody << httpLineEnd; + ++it; + } + + postBody << finalBoundaryLine; + + req.setContentLength(static_cast<int>(postBody.str().size())); + + std::ostream &postStream = m_session->sendRequest(req); + + // upload the actual HTTP body + postStream << postBody.str() << std::flush; + + std::istream &respStream = m_session->receiveResponse( + const_cast<Poco::Net::HTTPResponse &>(m_response)); + + // For as yet unknown reasons, we don't always get a session cookie back from + // the + // server. In that case, we don't want to overwrite the cookie we're currently + // using... + // Note: This won't work properly if we ever use cookies other than a + // session cookie. + std::vector<Poco::Net::HTTPCookie> newCookies; + m_response.getCookies(newCookies); + if (newCookies.size() > 0) { + m_cookies = newCookies; + } + + return respStream; +} + +// Wrappers for a lot of the boilerplate code needed to perform an HTTPS GET or +// POST +void MantidWebServiceAPIHelper::initGetRequest(Poco::Net::HTTPRequest &req, + std::string extraPath, + std::string queryString) const { + return initHTTPRequest(req, Poco::Net::HTTPRequest::HTTP_GET, extraPath, + queryString); +} + +void MantidWebServiceAPIHelper::initPostRequest(Poco::Net::HTTPRequest &req, + std::string extraPath) const { + return initHTTPRequest(req, Poco::Net::HTTPRequest::HTTP_POST, extraPath); +} + +void MantidWebServiceAPIHelper::initHTTPRequest(Poco::Net::HTTPRequest &req, + const std::string &method, + std::string extraPath, + std::string queryString) const { + // Set up the session object + if (m_session) { + delete m_session; + m_session = NULL; + } + + if (Poco::URI(m_serviceBaseUrl).getScheme() == "https") { + // Create an HTTPS session + // TODO: Notice that we've set the context to VERIFY_NONE. I think that + // means we're not checking the SSL certificate that the server + // sends to us. That's BAD!! + Poco::Net::Context::Ptr context = + new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, "", "", "", + Poco::Net::Context::VERIFY_NONE, 9, false, + "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); + m_session = new Poco::Net::HTTPSClientSession( + Poco::URI(m_serviceBaseUrl).getHost(), + Poco::URI(m_serviceBaseUrl).getPort(), context); + } else { + // Create a regular HTTP client session. (NOTE: Using unencrypted HTTP is a + // really bad idea! We'll be sending passwords in the clear!) + m_session = + new Poco::Net::HTTPClientSession(Poco::URI(m_serviceBaseUrl).getHost(), + Poco::URI(m_serviceBaseUrl).getPort()); + } + + Poco::URI uri(m_serviceBaseUrl); + std::string path = uri.getPath(); + // Path should be something like "/mws/rest", append extraPath to it. + path += extraPath; + + uri.setPath(path); + if (method == Poco::Net::HTTPRequest::HTTP_GET && queryString.size() > 0) { + uri.setQuery(queryString); + } + + req.setVersion(Poco::Net::HTTPRequest::HTTP_1_1); + req.setMethod(method); + req.setURI(uri.toString()); + + // Attach any cookies we've got from previous responses + req.setCookies(getCookies()); + + return; +} + +// Converts the vector of HTTPCookie objects into a NameValueCollection +Poco::Net::NameValueCollection MantidWebServiceAPIHelper::getCookies() const { + Poco::Net::NameValueCollection nvc; + std::vector<Poco::Net::HTTPCookie>::const_iterator it = m_cookies.begin(); + while (it != m_cookies.end()) { + nvc.add((*it).getName(), (*it).getValue()); + ++it; + } + return nvc; +} + +} // end of namespace RemoteJobManagers +} // end of namespace Mantid diff --git a/Code/Mantid/Framework/RemoteJobManagers/src/MantidWebServiceAPIJobManager.cpp b/Code/Mantid/Framework/RemoteJobManagers/src/MantidWebServiceAPIJobManager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4b604dabd601c8269b2e9605f4229606a34e8891 --- /dev/null +++ b/Code/Mantid/Framework/RemoteJobManagers/src/MantidWebServiceAPIJobManager.cpp @@ -0,0 +1,473 @@ +#include "MantidAPI/RemoteJobManagerFactory.h" +#include "MantidKernel/Logger.h" +#include "MantidRemoteJobManagers/MantidWebServiceAPIHelper.h" +#include "MantidRemoteJobManagers/MantidWebServiceAPIJobManager.h" +#include "MantidRemoteJobManagers/SimpleJSON.h" + +#include <fstream> + +namespace Mantid { +namespace RemoteJobManagers { + +// Register this job manager into the RemoteJobManagerFactory +DECLARE_REMOTEJOBMANAGER(MantidWebServiceAPIJobManager) + +namespace { +// static logger object +Mantid::Kernel::Logger g_log("MantidWebServiceAPIJobManager"); +} + +using namespace Mantid::Kernel; + +/** + * Abort a previously submitted job + * + * @param ID of the job to abort (as produced by submitRemoteJob()) + * + * @throws std::runtime_error if there are issues in the communication with the + * (remote) compute resource. + */ +void MantidWebServiceAPIJobManager::abortRemoteJob(const std::string &jobID) { + std::istream &respStream = + httpGet("/abort", std::string("JobID=") + jobID); + if (lastStatus() != Poco::Net::HTTPResponse::HTTP_OK) { + JSONObject resp; + initFromStream(resp, respStream); + std::string errMsg; + resp["Err_Msg"].getValue(errMsg); + throw(std::runtime_error(errMsg)); + } +} + +/** + * Authenticate to the remote compute resource + * + * @param username name of the user to authenticate as + * @param password password associated with the specified user + * + * @throws std::runtime_error if there are issues in the communication with the + * (remote) compute resource. + */ +void MantidWebServiceAPIJobManager::authenticate(const std::string &username, + const std::string &password) { + MantidWebServiceAPIHelper helper; + + std::istream &respStream = + httpGet("/authenticate", "", username, password); + if (lastStatus() != Poco::Net::HTTPResponse::HTTP_OK) { + JSONObject resp; + initFromStream(resp, respStream); + std::string errMsg; + resp["Err_Msg"].getValue(errMsg); + throw(std::runtime_error(errMsg)); + } +} + +/** + * Download a file from a remote compute resource + * + * @param transactionID ID of the transaction that owns the file + * + * @param remoteFileName name of the file on the remote machine. (Filename only; + * no path) + * + * @param localFileName full pathname on the local machine where the downloaded + * file should be saved. + * + * @throws std::runtime_error if there are file I/O issues or any + * issues in the communication with the (remote) compute resource. + */ +void MantidWebServiceAPIJobManager::downloadRemoteFile( + const std::string &transactionID, const std::string &remoteFileName, + const std::string &localFileName) { + + std::istream &respStream = + httpGet("/download", std::string("TransID=") + transactionID + + "&File=" + remoteFileName); + + if (lastStatus() == Poco::Net::HTTPResponse::HTTP_OK) { + + std::ofstream outfile(localFileName.c_str()); + if (outfile.good()) { + outfile << respStream.rdbuf(); + outfile.close(); + g_log.information() << "Downloaded '" << remoteFileName << "' to '" + << localFileName << "'" << std::endl; + } else { + throw(std::runtime_error(std::string("Failed to open " + localFileName))); + } + } else { + JSONObject resp; + initFromStream(resp, respStream); + std::string errMsg; + resp["Err_Msg"].getValue(errMsg); + throw(std::runtime_error(errMsg)); + } +} + +/** + * Query a remote compute resource for all jobs the user has submitted + * + * @return information for all the jobs found. Note that the date/time + * fields (submission, start, completion) are optional and may not be + * provided + * + * @throws std::runtime_error if there are issues in the communication with the + * (remote) compute resource. + */ +std::vector<Mantid::API::IRemoteJobManager::RemoteJobInfo> +MantidWebServiceAPIJobManager::queryAllRemoteJobs() const { + + std::istream &respStream = httpGet(std::string("/query")); + JSONObject resp; + try { + initFromStream(resp, respStream); + } catch (JSONParseException &) { + // Nobody else knows what a JSONParseException is, so rethrow as a + // runtime_error + throw(std::runtime_error("Error parsing data returned from the server. " + "This probably indicates a server-side error of " + "some kind.")); + } + + if (Poco::Net::HTTPResponse::HTTP_OK != lastStatus()) { + std::string errMsg; + resp["Err_Msg"].getValue(errMsg); + throw(std::runtime_error(errMsg)); + } + + std::vector<Mantid::API::IRemoteJobManager::RemoteJobInfo> result; + + std::vector<std::string> jobIds; + std::vector<std::string> jobStatusStrs; + std::vector<std::string> jobNames; + std::vector<std::string> scriptNames; + std::vector<std::string> transIds; + std::vector<std::string> submitDates; + std::vector<std::string> startDates; + std::vector<std::string> completionDates; + + JSONObject::const_iterator it = resp.begin(); + while (it != resp.end()) { + jobIds.push_back((*it).first); + JSONObject jobData; + (*it).second.getValue(jobData); + + std::string value; + jobData["JobStatus"].getValue(value); + jobStatusStrs.push_back(value); + + jobData["JobName"].getValue(value); + jobNames.push_back(value); + + jobData["ScriptName"].getValue(value); + scriptNames.push_back(value); + + jobData["TransID"].getValue(value); + transIds.push_back(value); + + // The time stuff is actually an optional extension. We could check the + // info + // URL and see if the server implements it, but it's easier to just look + // in + // the output and see if the values are there... + if (jobData.find("SubmitDate") != jobData.end()) { + jobData["SubmitDate"].getValue(value); + submitDates.push_back(value); + + jobData["StartDate"].getValue(value); + startDates.push_back(value); + + jobData["CompletionDate"].getValue(value); + completionDates.push_back(value); + } else { + // push back empty strings just so all the array properties have the + // same + // number of elements + submitDates.push_back(""); + startDates.push_back(""); + completionDates.push_back(""); + } + + ++it; + } + + // this is done here, very inefficiently, to avoid messing up the last loop + for (size_t i = 0; i < resp.size(); ++i) { + Mantid::API::IRemoteJobManager::RemoteJobInfo info; + info.id = jobIds[i]; + info.status = jobStatusStrs[i]; + info.name = jobNames[i]; + info.runnableName = scriptNames[i]; + info.transactionID = transIds[i]; + info.submitDate = DateAndTime(submitDates[i]); + info.startDate = DateAndTime(startDates[i]); + info.completionTime = DateAndTime(completionDates[i]); + result.push_back(info); + } + + return result; +} + +/** + * Retrieve a list of the files from a remote compute resource. + * + * @param transactionID ID of the transaction who’s files we want to list. Must + * have been created with startRemoteTransaction() + * + * @return names of all the files that were found + * + * @throws std::runtime_error if there are issues in the communication with the + * (remote) compute resource. + */ +std::vector<std::string> MantidWebServiceAPIJobManager::queryRemoteFile( + const std::string &transactionID) const { + + std::istream &respStream = + httpGet("/files", std::string("TransID=") + transactionID); + JSONObject resp; + initFromStream(resp, respStream); + std::vector<std::string> filenames; + if (lastStatus() == Poco::Net::HTTPResponse::HTTP_OK) { + + JSONArray files; + std::string oneFile; + resp["Files"].getValue(files); + for (unsigned int i = 0; i < files.size(); i++) { + files[i].getValue(oneFile); + filenames.push_back(oneFile); + } + + } else { + std::string errMsg; + resp["Err_Msg"].getValue(errMsg); + throw(std::runtime_error(errMsg)); + } + + return filenames; +} + +/** + * Query a remote compute resource for a specific job + * + * @return job information. Note that the date/time information (submission, + * start, completion) is optional and may not be provided + * + * @throws std::runtime_error if there are issues in the communication with the + * (remote) compute resource. + */ +Mantid::API::IRemoteJobManager::RemoteJobInfo +MantidWebServiceAPIJobManager::queryRemoteJob(const std::string &jobID) const { + std::istream &respStream = + httpGet("/query", std::string("JobID=") + jobID); + JSONObject resp; + initFromStream(resp, respStream); + + if (Poco::Net::HTTPResponse::HTTP_OK != lastStatus()) { + std::string errMsg; + resp["Err_Msg"].getValue(errMsg); + throw(std::runtime_error(errMsg)); + } + + if (resp[jobID].getType() != JSONValue::OBJECT) { + throw(std::runtime_error("Expected value not found in return stream. " + "Has the client/server protocol changed?!?")); + } + + Mantid::API::IRemoteJobManager::RemoteJobInfo info; + + JSONObject status; + resp[jobID].getValue(status); + + std::string value; + status["JobStatus"].getValue(value); + info.status = value; + + status["JobName"].getValue(value); + info.name = value; + + status["ScriptName"].getValue(value); + info.runnableName = value; + + status["TransID"].getValue(value); + info.transactionID = value; + + // The time stuff is actually an optional extension. We could check the + // info + // URL and see if the server implements it, but it's easier to just look in + // the output and see if the values are there... + if (status.find("SubmitDate") != status.end()) { + status["SubmitDate"].getValue(value); + info.submitDate = DateAndTime(value); + + status["StartDate"].getValue(value); + info.startDate = DateAndTime(value); + + status["CompletionDate"].getValue(value); + info.completionTime = DateAndTime(value); + } + + return info; +} + +/** + * Start a job transaction on a remote compute resource. + * + * @return ID of the new transaction + * + * @throws std::runtime_error if there are issues in the communication with the + * (remote) compute resource. + */ +std::string MantidWebServiceAPIJobManager::startRemoteTransaction() { + std::istream &respStream = httpGet("/transaction", "Action=Start"); + JSONObject resp; + initFromStream(resp, respStream); + + if (Poco::Net::HTTPResponse::HTTP_OK != lastStatus()) { + std::string errMsg; + resp["Err_Msg"].getValue(errMsg); + throw(std::runtime_error(errMsg)); + } + std::string transId; + resp["TransID"].getValue(transId); + g_log.information() << "Transaction ID " << transId << " started." + << std::endl; + + return transId; +} + +/** + * Stop a job transaction on a remote compute resource. + * + * @param transactionID ID string returned when the transaction was created with + * startRemoteTransaction() + * + * @throws std::runtime_error if there are issues in the communication with the + * (remote) compute resource. + */ +void MantidWebServiceAPIJobManager::stopRemoteTransaction( + const std::string &transactionID) { + std::string transId = transactionID; + std::istream &respStream = httpGet( + "/transaction", std::string("Action=Stop&TransID=") + transId); + + if (lastStatus() == Poco::Net::HTTPResponse::HTTP_OK) { + g_log.information() << "Transaction ID " << transId << " stopped." + << std::endl; + } else { + JSONObject resp; + initFromStream(resp, respStream); + std::string errMsg; + resp["Err_Msg"].getValue(errMsg); + throw(std::runtime_error(errMsg)); + } +} + +/** + * Submit a job, which in this context means a Mantid Python script + * + * @param transactionID transaction ID to associate with this job (obtained with + * startRemoteTransaction()) + * + * @param runnable name of the runnable (Python script that will be executed) + * + * @param param content of the Python script (as plain text, the actual python + * code to execute) + * + * @param taskName a shot name to give to the job on the compute resource + * @param numNodes number of computing nodes to request + * @param coresPerNode number of cores to use in every node + * + * @return an ID string for this job + * + * @throws std::runtime_error if there are issues in the communication with the + * (remote) compute resource. + */ +std::string MantidWebServiceAPIJobManager::submitRemoteJob( + const std::string &transactionID, const std::string &runnable, + const std::string ¶m, const std::string &taskName, const int numNodes, + const int coresPerNode) { + + MantidWebServiceAPIHelper::PostDataMap postData; + + postData["TransID"] = transactionID; + postData["NumNodes"] = boost::lexical_cast<std::string>(numNodes); + postData["CoresPerNode"] = boost::lexical_cast<std::string>(coresPerNode); + + postData["ScriptName"] = runnable; + postData[runnable] = param; + + // Job name is optional + std::string jobName = taskName; + if (jobName.length() > 0) { + postData["JobName"] = jobName; + } + + std::istream &respStream = httpPost("/submit", postData); + JSONObject resp; + initFromStream(resp, respStream); + if (Poco::Net::HTTPResponse::HTTP_CREATED != lastStatus()) { + std::string errMsg; + resp["Err_Msg"].getValue(errMsg); + throw(std::runtime_error(errMsg)); + } + + std::string jobId; + resp["JobID"].getValue(jobId); + g_log.information() << "Job submitted. Job ID = " << jobId << std::endl; + + return jobId; +} + +/** + * Uploads a file to the (remote) compute resource + * + * @param transactionID The transaction the file will be associated + * with. It must have been created with startRemoteTransaction + * + * @param remoteFileName name to save the file as on the remote computer. + * (Filename only; no path information) + * + * @param localFileName full pathname (on the local machine) of the file to + * upload + * + * @throws std::runtime_error if there are issues in the communication with the + * (remote) compute resource, or file I/O issues. + */ +void MantidWebServiceAPIJobManager::uploadRemoteFile( + const std::string &transactionID, const std::string &remoteFileName, + const std::string &localFileName) { + MantidWebServiceAPIHelper::PostDataMap postData; + postData["TransID"] = transactionID; + + std::ifstream infile(localFileName.c_str()); + if (infile.good()) { + // Yes, we're reading the entire file into memory. Obviously, this is only + // feasible for fairly small files... + MantidWebServiceAPIHelper::PostDataMap fileData; + fileData[remoteFileName] = + std::string(std::istreambuf_iterator<char>(infile), + std::istreambuf_iterator<char>()); + infile.close(); + + std::istream &respStream = httpPost("/upload", postData, fileData); + if (lastStatus() == + Poco::Net::HTTPResponse::HTTP_CREATED) // Upload returns a "201 - + // Created" code on success + { + g_log.information() << "Uploaded '" << remoteFileName << "' to '" + << localFileName << "'" << std::endl; + } else { + JSONObject resp; + initFromStream(resp, respStream); + std::string errMsg; + resp["Err_Msg"].getValue(errMsg); + throw(std::runtime_error(errMsg)); + } + } else { + throw(std::runtime_error(std::string("Failed to open " + localFileName))); + } +} + +} // end namespace RemoteJobManagers +} // end namespace Mantid diff --git a/Code/Mantid/Framework/RemoteJobManagers/src/SimpleJSON.cpp b/Code/Mantid/Framework/RemoteJobManagers/src/SimpleJSON.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7c86266e3fae1401c1cc3d9d45c2de1f4a888f4e --- /dev/null +++ b/Code/Mantid/Framework/RemoteJobManagers/src/SimpleJSON.cpp @@ -0,0 +1,704 @@ +/******************************************************************* + A cross-platform JSON parser that uses nothing more than C++ and + STL templates. It's probably slower than other JSON parsers, but + it's a heck of a lot smaller and simpler and works on Linux, MacOS + and Windows. + + I think it completely implements the JSON spec, but all I'm really + concerned with is whether it can parse the output from Moab Web + Services. + + RGM - 23 July 2012 + ******************************************************************/ + +#include "MantidRemoteJobManagers/SimpleJSON.h" + +#include <algorithm> // for transform() function +#include <sstream> +#include <map> +using namespace std; + +JSONValue::JSONValue() : m_type(JSONValue::NULLTYPE) {} +JSONValue::JSONValue(bool v) : m_type(JSONValue::BOOL), m_bool(v) {} +JSONValue::JSONValue(double v) : m_type(JSONValue::NUMBER), m_num(v) {} + +JSONValue::JSONValue(const string &v) : m_type(JSONValue::STRING) { + mp_string = new string(v); +} + +JSONValue::JSONValue(const JSONArray &v) : m_type(JSONValue::ARRAY) { + mp_array = new JSONArray(v); +} + +JSONValue::JSONValue(const JSONObject &v) : m_type(JSONValue::OBJECT) { + mp_object = new JSONObject(v); +} + +JSONValue::~JSONValue() { + switch (m_type) { + case JSONValue::STRING: + delete mp_string; + break; + + case JSONValue::ARRAY: + delete mp_array; + break; + + case JSONValue::OBJECT: + delete mp_object; + break; + + default: + // Do nothing + break; + } +} + +JSONValue::JSONValue(const JSONValue &v) { + m_type = v.getType(); + + switch (m_type) { + case JSONValue::NULLTYPE: + break; // nothing to do + case JSONValue::BOOL: + if (!v.getValue(m_bool)) + throw(JSONCopyException("Failed to copy boolean")); + break; + case JSONValue::NUMBER: + if (!v.getValue(m_num)) + throw(JSONCopyException("Failed to copy float")); + break; + case JSONValue::STRING: + mp_string = new string; + if (!v.getValue(*mp_string)) { + delete mp_string; // Make sure we don't leak memory in the event of a + // failure + throw(JSONCopyException("Failed to copy string")); + } + break; + case JSONValue::ARRAY: + mp_array = new JSONArray; + if (!v.getValue(*mp_array)) { + delete mp_array; + throw(JSONCopyException("Failed to copy array")); + } + break; + case JSONValue::OBJECT: + mp_object = new JSONObject; + if (!v.getValue(*mp_object)) { + delete mp_object; + throw(JSONCopyException("Failed to copy object")); + } + break; + default: + // Should never hit this! + throw(JSONCopyException("Unknown JSON type!!")); + } +} + +JSONValue &JSONValue::operator=(const JSONValue &v) { + // This gets a little tricky: In the case where v's type is different from + // our own, we need to make sure we don't stomp on any of the existing + // pointers + // until we're sure the getValue() call has succeeded. Once getValue() does + // succeeed, we may need to delete the existing memory. + // Note: This also allows the code to handle the case of self-assignment. + + JSONValue::VALUE_TYPE newType = v.getType(); + + // Temporary values (only one of which will actually get used, but gcc + // complains if new variables are declared down inside a case statement) + bool tBool; + double tFloat; + std::string *tpString; + JSONArray *tpArray; + JSONObject *tpObject; + + switch (newType) { + case JSONValue::NULLTYPE: + assignmentOpHelper(); + m_type = newType; + break; + + case JSONValue::BOOL: + if (v.getValue(tBool)) { + assignmentOpHelper(); + m_bool = tBool; + m_type = newType; + } else + throw(JSONAssignmentException("Failed to assign boolean")); + break; + + case JSONValue::NUMBER: + if (v.getValue(tFloat)) { + assignmentOpHelper(); + m_num = tFloat; + m_type = newType; + } else + throw(JSONAssignmentException("Failed to assign float")); + break; + + case JSONValue::STRING: + tpString = new string; + if (v.getValue(*tpString)) { + assignmentOpHelper(); + mp_string = tpString; + m_type = newType; + } else { + delete tpString; // Make sure we don't leak memory in the event of a + // failure + throw(JSONAssignmentException("Failed to assign string")); + } + break; + + case JSONValue::ARRAY: + tpArray = new JSONArray; + if (v.getValue(*tpArray)) { + assignmentOpHelper(); + mp_array = tpArray; + m_type = newType; + } else { + delete tpArray; + throw(JSONAssignmentException("Failed to assign array")); + } + break; + + case JSONValue::OBJECT: + tpObject = new JSONObject; + if (v.getValue(*tpObject)) { + assignmentOpHelper(); + mp_object = tpObject; + m_type = newType; + } else { + delete tpObject; + throw(JSONAssignmentException("Failed to assign object")); + } + break; + + default: + // Should never hit this! + throw(JSONAssignmentException("Unknown JSON type!!")); + } + + return *this; +} + +// A helper function for the assignment operator +// Its job is to delete memory holding the current value (in cases where it is +// a +// pointer, ie: strings, arrays & objects); +// It assumed this will be called after the call to getValue() succeeds, but +// before +// the new value is copied in to the appropriate slot in the union. +void JSONValue::assignmentOpHelper() { + switch (m_type) { + case JSONValue::STRING: + delete mp_string; + break; + case JSONValue::ARRAY: + delete mp_array; + break; + case JSONValue::OBJECT: + delete mp_object; + break; + default: + break; // do nothing + } +} + +bool JSONValue::getValue(bool &v) const { + if (m_type != JSONValue::BOOL) + return false; + + v = m_bool; + return true; +} + +bool JSONValue::getValue(double &v) const { + if (m_type != JSONValue::NUMBER) + return false; + + v = m_num; + return true; +} + +bool JSONValue::getValue(std::string &v) const { + // Since booleans and numbers can be easily converted to strings, + // we'll make this function a little smarter and have it do the + // conversion if necessary (instead of just returning false) + bool rv = true; // assume success + std::ostringstream convert; + switch (m_type) { + case JSONValue::STRING: + v = *mp_string; + break; + + case JSONValue::NUMBER: + convert << m_num << std::flush; + v = convert.str(); + break; + + case JSONValue::BOOL: + if (m_bool) + v = "true"; + else + v = "false"; + break; + + default: + rv = false; + } + + return rv; +} + +bool JSONValue::getValue(JSONArray &v) const { + if (m_type != JSONValue::ARRAY) + return false; + + v = *mp_array; + return true; +} + +bool JSONValue::getValue(JSONObject &v) const { + if (m_type != JSONValue::OBJECT) + return false; + + v = *mp_object; + return true; +} + +// Formatted output to a stream (presumably cout) +void JSONValue::prettyPrint(ostream &ostr, unsigned indentLevel) const { + JSONArray::const_iterator it; + + switch (m_type) { + case NULLTYPE: + ostr << "NULL"; + break; + + case BOOL: + ostr << (m_bool ? "TRUE" : "FALSE"); + break; + + case NUMBER: + ostr << m_num; + break; + + case STRING: + ostr << "\"" << *mp_string << "\""; + break; + + case ARRAY: + + if (mp_array->size() <= 1) { + // Special handling for small arrays - print on one line + ostr << "[ "; + it = mp_array->begin(); + if (it != mp_array->end()) { + it->prettyPrint(ostr, indentLevel + 1); + } + ostr << " ]"; + } else { + ostr << "[" << endl; + + it = mp_array->begin(); + while (it != mp_array->end()) { + for (unsigned i = 0; i < indentLevel + 1; i++) { + ostr << "\t"; + } + it->prettyPrint(ostr, indentLevel + 1); + ostr << endl; + ++it; + } + + for (unsigned i = 0; i < indentLevel + 1; i++) { + ostr << "\t"; + } + ostr << "]"; + } + break; + + case OBJECT: + if (mp_object->size() <= 1) { + // special handling for small objects - print on one line + ostr << "{ "; + ::prettyPrint(*mp_object, ostr, 0); + ostr << " }"; + + } else { + ostr << "{" << endl; + ::prettyPrint(*mp_object, ostr, indentLevel + 1); + + for (unsigned i = 0; i < indentLevel + 1; i++) { + ostr << "\t"; + } + ostr << "}"; + } + break; + + default: + ostr << "<UNKNOWN TYPE!! (This should never happen.)>"; + } +} + +// ----- End of JSONValue member definitions ---------- + +// Prototypes for some 'private' helper functions that initFromStream() +// may use (either directly or indirectly) +void skipWhiteSpace(istream &istr); +void checkChar(char found, char expected); +string readString(istream &istr); +string readUntilCloseChar(istream &istr); +void initArrayFromStream(JSONArray &arr, istream &istr); +JSONValue initValueFromStream(istream &istr); + +// Initialize a JSON object from a stream (presumably creating a whole +// hierarchy) +// +// This is the big one. :) The expectation is that the first character +// will be a '{' and the function will run until if finds a matching '}' +// char. Along the way, it may create nested objects and/or arrays +// (which means it may be called recursively - by way of +// initValueFromStream()) +// Note: The function will consume the closing brace from the stream +void initFromStream(JSONObject &obj, istream &istr) { + char nextChar; + istr >> nextChar; + checkChar(nextChar, '{'); // sanity check + skipWhiteSpace(istr); + + // Check for empty object (and make sure we consume the }) + nextChar = (char)istr.peek(); + if (nextChar == '}') { + istr.ignore(); + } + + while (nextChar != '}') // process the stream + { + // Quick sanity check + if (istr.eof()) { + throw JSONParseException("Unexpected end of data stream"); + } + + // We expect to start the loop with the stream pointing to the opening quote + // of the key + nextChar = (char)istr.peek(); + checkChar(nextChar, '"'); + + string key = readString(istr); + istr >> nextChar; // >> operator automatically skips white space + checkChar(nextChar, ':'); // the separator between the key and the value + + skipWhiteSpace(istr); + + // Now. we're at the start of the value. + // Add the key and value to our object + obj[key] = initValueFromStream(istr); + istr >> nextChar; + // nextChar is guaranteed to be either a comma, close brace or close + // bracket. + //(If it was anything else, initValueFromStream() would have thrown an + // exception.) + // A bracket is an error, a brace means the object is done (and will be + // checked at + // the start of the while loop) and a comma needs to be thrown out (along + // with any + // following whitespace) to position us for the next key/value pair + if (nextChar == ']') + throw JSONParseException( + "Invalid closing bracket while initializing object"); + else if (nextChar == ',') { + skipWhiteSpace(istr); + // Check to see if another key/value pair really follows the comma + // (because if one doesn't, the parser will get screwed up and may not + // actually detect the problem). + if (istr.peek() != '"') { + throw JSONParseException( + "Invalid comma (no key/value pair following it)"); + } + } + } +} + +// Initialize a JSON array from a stream +// This is similar to initFromStream() above and may also be called +// recursively by way of initValueFromStream() +// The expectation is that the first character will be a '[' and it +// will run until if finds a matching ']' char. Along the way it +// may create nested objects and/or arrays. +// Note: It will consume the closing bracket from the stream +void initArrayFromStream(JSONArray &arr, istream &istr) { + char nextChar; + istr >> nextChar; + checkChar(nextChar, '['); // sanity check + skipWhiteSpace(istr); + + // Check for empty array (and make sure we consume the ]) + nextChar = (char)istr.peek(); + if (nextChar == ']') { + istr.ignore(); + } + + while (nextChar != ']') // process the stream + { + // Quick sanity check + if (istr.eof()) { + throw JSONParseException("Unexpected end of data stream"); + } + + // We expect to start the loop with the stream pointing to the + // first character of the value + // Add the value to our array + arr.push_back(initValueFromStream(istr)); + + istr >> nextChar; + // nextChar is guaranteed to be either a comma, close brace or close + // bracket. + //(If it was anything else, initValueFromStream() would have thrown an + // exception.) + // A brace is an error, a bracket means the array is done (and will be + // checked at + // the start of the while loop) and a comma needs to be thrown out (along + // with any + // following whitespace) to position us for the next value + if (nextChar == '}') + throw JSONParseException( + "Invalid closing brace while initializing array"); + else if (nextChar == ',') { + skipWhiteSpace(istr); + // Check to see if another key/value pair really follows the comma + // (because if one doesn't, the parser will get screwed up and may not + // actually detect the problem). + if (istr.peek() == ']') { + throw JSONParseException( + "Invalid comma (array ended with no further values)"); + } + } + } +} + +// Initialize a single JSONValue from an input stream. Note that JSONObject +// and JSONArray are both valid values, and this function may call +// initFromStream() +// and initArrayFromStream(). +// Function expects the stream to be pointing at the first character in the +// value +JSONValue initValueFromStream(istream &istr) { + JSONValue value; + // We expect the stream to be at the start of the value. + + // Need to determine what kind of value it is. + char nextChar = (char)istr.peek(); + if (nextChar == '"') // value is a string + { + // Read until we get the closing '"' + value = JSONValue(readString(istr)); + } else if (nextChar == '[') // value is an array of stuff + { + JSONArray newArray; + initArrayFromStream(newArray, istr); // Initialize the array... + value = JSONValue(newArray); + } else if (nextChar == '{') // value is another JSON object + { + JSONObject newJsonObj; + initFromStream(newJsonObj, istr); // Initialize the object... + value = JSONValue(newJsonObj); + } else { + // Now it gets a little trickier. It's either a number or the special + // values + // true, false or null (case insensitive) + // Read until we find the comma, closing bracket or closing brace + string val = readUntilCloseChar(istr); + std::transform(val.begin(), val.end(), val.begin(), + ::tolower); // convert to lower case for easy comparing + if (val == "false") + value = JSONValue(false); + else if (val == "true") + value = JSONValue(true); + else if (val == "null") + value = JSONValue(); // actually, this assignment isn't necessary - value + // is already null + else { + // At this point, the only valid option is a number of some kind... + istringstream numericValue(val); + double theNumber; + numericValue >> theNumber; + // check to see if there are any characters let in numbericValue. + // If there are, it was an invalid value + if (!numericValue.eof()) { + string msg = "Invalid characters in a numeric value: "; + msg += numericValue.str(); + throw JSONParseException(msg); + } + + value = JSONValue(theNumber); + } + } + + // Done processing the value. Verify that it ends properly (ie, we + // get a comma or a closing brace) + skipWhiteSpace(istr); + nextChar = (char)istr.peek(); + if ((nextChar != ',') && (nextChar != '}') && (nextChar != ']')) { + string message = "Improperly terminated key/value pair. Expected comma or " + "closing brace. Received: "; + message += nextChar; + message.append("\n"); + char tempBuf[64]; + istr.read(tempBuf, 63); + tempBuf[63] = '\0'; + message.append("Remaining stream: "); + message.append(tempBuf); + throw(JSONParseException(message)); + } + + return value; +} + +// Consume whitespace characters from stream. Leaves the stream +// pointing at the next non-whitespace char (or possibly eof()); +void skipWhiteSpace(istream &istr) { + + char next; + istr >> next; // take advantage of the fact that >> uses whitespace as a field + // separator + if (!istr.eof()) { + // If eof() is set, it means we didn't find any tokens after the whitespace. + // In this case + // there's nother to put back, and doing so would unset the eof bit. + istr.putback(next); + } +} + +void checkChar(char found, char expected) { + if (found != expected) { + string msg = "Was expecting "; + msg += expected; + msg += " char, but received "; + msg += found; + throw(JSONParseException(msg)); + } +} + +// Expects istr to be pointing at the first " of a string (either a key or +// a value of type string). Reads until the closing " and returns the +// characters between as a string. It consumes the closing " and leaves the +// stream pointing at the character that follows it. +string readString(istream &istr) { + string str; + char next; + istr.get(next); + checkChar(next, '"'); + // Note: can't use operator>> here, becuase whitespace is significant + istr.get(next); + while (next != '"') { + // Check for escaped chars... + if (next != '\\') { + str += next; // character isn't escaped, so just append to the string + } else { + istr.get(next); + switch (next) { + case 't': + str += '\t'; + break; + + case 'n': + str += '\n'; + break; + + case 'r': + str += '\r'; + break; + + case 'b': + str += '\b'; + break; + + case 'f': + str += '\f'; + break; + + case '\\': + str += '\\'; + break; + + case '/': + str += '/'; + break; + + case '"': + str += '"'; + break; + + case 'u': + throw JSONParseException("Parser cannot handle the \\u<hex> notation"); + break; + + default: + throw JSONParseException(string("Unknown escape value: \\") + next); + } + } + + istr.get(next); + if (istr.eof()) { + throw JSONParseException( + "Stream unexpectedly ended without a closing quote."); + } + } + return str; +} + +// reads chars from the stream until one of the closing chars is found +// (either a comma, closing bracket or closing brace). The closing char +// is NOT consumed. Function assumes the stream is pointing at the +// first character of the value. +// Note: This function is not used for strings. See readString() for that. +string readUntilCloseChar(istream &istr) { + string value; + char next = (char)istr.peek(); + while ((next != ',') && (next != '}') && (next != ']')) { + if (istr.eof()) { + throw JSONParseException( + "Stream unexpectedly ended without a closing char."); + } + + if ((value.size() > 0) || + (!isspace( + next))) // don't add white space to the start of the value string + { + value += next; + } + istr.get(); // consume the char from the stream + next = (char)istr.peek(); + } + + // Strip any whitespace off the end of the value string + while (isspace(value[value.size() - 1])) { + value.resize(value.size() - 1); + } + + return value; +} + +void prettyPrint(const JSONObject &obj, std::ostream &ostr, + unsigned indentLevel) { + // Prints keys/value pairs. One pair per line (Does not print opening or + // closing braces...) + JSONObject::const_iterator it = obj.begin(); + while (it != obj.end()) { + for (unsigned i = 0; i < indentLevel; i++) { + ostr << "\t"; + } + ostr << (*it).first << " : "; + (*it).second.prettyPrint(ostr, indentLevel); + if (obj.size() > 1) { + // if there's only one key/value pair in the object, then don't print + // a trailing newline. (The rationale being that such small objects + // will be printed with their key, value and braces all on one line.) + ostr << endl; + } + ++it; + } + ostr.flush(); +} diff --git a/Code/Mantid/Framework/RemoteJobManagers/test/MantidWebServiceAPIHelperTest.h b/Code/Mantid/Framework/RemoteJobManagers/test/MantidWebServiceAPIHelperTest.h new file mode 100644 index 0000000000000000000000000000000000000000..09606ab17a327bbd6f91c8efa3911d74cd0d0f05 --- /dev/null +++ b/Code/Mantid/Framework/RemoteJobManagers/test/MantidWebServiceAPIHelperTest.h @@ -0,0 +1,46 @@ +#ifndef MANTID_REMOTEJOBMANAGERS_MANTIDWEBSERVICEAPIHELPERTEST_H_ +#define MANTID_REMOTEJOBMANAGERS_MANTIDWEBSERVICEAPIHELPERTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidRemoteJobManagers/MantidWebServiceAPIHelper.h" + +#include <boost/make_shared.hpp> +#include <Poco/Net/HTTPResponse.h> + +using namespace Mantid::RemoteJobManagers; + +/// This is just an overly simple test that objects can be +/// created. Not bothering to improve this, as this +/// MantidWebServiceAPIHelper should be replaced/merged into the more +/// generic Kernel::InternetHelper. +class MantidWebServiceAPIHelperTest : 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 MantidWebServiceAPIHelperTest *createSuite() { return new MantidWebServiceAPIHelperTest(); } + static void destroySuite(MantidWebServiceAPIHelperTest *suite) { delete suite; } + + void test_construct() { + // can create + boost::shared_ptr<MantidWebServiceAPIHelper> help; + TS_ASSERT(help = boost::make_shared<MantidWebServiceAPIHelper>()); + // can cast to inherited interfaces and base classes + + MantidWebServiceAPIHelper h; + } + + void test_defaultValues() { + MantidWebServiceAPIHelper h; + + Poco::Net::HTTPResponse::HTTPStatus sts; + TS_ASSERT_THROWS_NOTHING(sts = h.lastStatus()); + TS_ASSERT_EQUALS(sts, Poco::Net::HTTPResponse::HTTP_OK); + + std::string reason; + TS_ASSERT_THROWS_NOTHING(reason = h.lastStatusReason()); + TS_ASSERT_EQUALS(reason, h.lastStatusReason()); + } +}; + +#endif // MANTID_REMOTEJOGMANAGERS_MANTIDWEBSERVICEAPIHELPERTEST_H_ diff --git a/Code/Mantid/Framework/RemoteJobManagers/test/MantidWebServiceAPIJobManagerTest.h b/Code/Mantid/Framework/RemoteJobManagers/test/MantidWebServiceAPIJobManagerTest.h new file mode 100644 index 0000000000000000000000000000000000000000..6dce917831e912878cf8b1f8802c09c762abf298 --- /dev/null +++ b/Code/Mantid/Framework/RemoteJobManagers/test/MantidWebServiceAPIJobManagerTest.h @@ -0,0 +1,475 @@ +#ifndef MANTID_REMOTEJOBMANAGERS_MANTIDWEBSERVICEAPIJOBMANAGERTEST_H_ +#define MANTID_REMOTEJOBMANAGERS_MANTIDWEBSERVICEAPIJOBMANAGERTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidAPI/RemoteJobManagerFactory.h" +#include "MantidKernel/ConfigService.h" +#include "MantidKernel/FacilityInfo.h" +#include "MantidRemoteJobManagers/MantidWebServiceAPIJobManager.h" +#include "MantidRemoteJobManagers/SimpleJSON.h" + +#include <boost/make_shared.hpp> + +using namespace Mantid::API; +using namespace Mantid::RemoteJobManagers; + +// TODO: use gmock + +// This very simple mock returns an error status code and does not +// return any error message, which causes bad exception in the job +// manager (in most methods, while in for example queryAllRemoteJobs +// the JSON parsing exception is caught and turned into an +// std::runtime_error +class MockMantidAPIStatusNotFound : public MantidWebServiceAPIJobManager { +protected: + std::istream &httpGet(const std::string & /*path*/, + const std::string & /*query_str*/ = "", + const std::string & /*username*/ = "", + const std::string & /*password*/ = "") const { + return is; + } + + std::istream & + httpPost(const std::string & /*path*/, + const MantidWebServiceAPIHelper::PostDataMap & /*postData*/, + const MantidWebServiceAPIHelper::PostDataMap & /*fileData*/ = + MantidWebServiceAPIHelper::PostDataMap(), + const std::string & /*username*/ = "", + const std::string & /*password*/ = "") const { + return is; + } + + Poco::Net::HTTPResponse::HTTPStatus lastStatus() const { + return Poco::Net::HTTPResponse::HTTP_NOT_FOUND; + } + +private: + mutable std::istringstream is; +}; + +// This one returns an error status code with an error message as +// expected from a Mantid WS API, including the parameter 'Err_Msg'. +class MockMantidAPIStatusNotFoundWithErrMsg + : public MantidWebServiceAPIJobManager { +public: + MockMantidAPIStatusNotFoundWithErrMsg() : MantidWebServiceAPIJobManager() { + is.str("{\"foo\": \"err_msg\", \"Err_Msg\"=\"fake error\", \"param\": " + "\"1\", }"); + } + +protected: + std::istream &httpGet(const std::string & /*path*/, + const std::string & /*query_str*/ = "", + const std::string & /*username*/ = "", + const std::string & /*password*/ = "") const { + return is; + } + + std::istream & + httpPost(const std::string & /*path*/, + const MantidWebServiceAPIHelper::PostDataMap & /*postData*/, + const MantidWebServiceAPIHelper::PostDataMap & /*fileData*/ = + MantidWebServiceAPIHelper::PostDataMap(), + const std::string & /*username*/ = "", + const std::string & /*password*/ = "") const { + return is; + } + + Poco::Net::HTTPResponse::HTTPStatus lastStatus() const { + return Poco::Net::HTTPResponse::HTTP_NOT_FOUND; + } + +private: + mutable std::istringstream is; +}; + +// Very simple mock that always returns an HTTP_OK=200 status code, +// but empty response body. There is no generic response body that +// would work for many or all of the methods of the +// MantidWebServiceAPIJobManager. More sophisticated "OK" mocks would +// need to be able to provide different response bodies (JSON output +// parameters). +class MockMantidAPIStatusOK : public MantidWebServiceAPIJobManager { +protected: + std::istream &httpGet(const std::string & /*path*/, + const std::string & /*query_str*/ = "", + const std::string & /*username*/ = "", + const std::string & /*password*/ = "") const { + return is; + } + + std::istream & + httpPost(const std::string & /*path*/, + const MantidWebServiceAPIHelper::PostDataMap & /*postData*/, + const MantidWebServiceAPIHelper::PostDataMap & /*fileData*/ = + MantidWebServiceAPIHelper::PostDataMap(), + const std::string & /*username*/ = "", + const std::string & /*password*/ = "") const { + return is; + } + + Poco::Net::HTTPResponse::HTTPStatus lastStatus() const { + return Poco::Net::HTTPResponse::HTTP_OK; + } + +private: + mutable std::istringstream is; +}; + +class MantidWebServiceAPIJobManagerTest : 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 MantidWebServiceAPIJobManagerTest *createSuite() { + return new MantidWebServiceAPIJobManagerTest(); + } + static void destroySuite(MantidWebServiceAPIJobManagerTest *suite) { + delete suite; + } + + void test_constructCasts() { + // can create + boost::shared_ptr<MockMantidAPIStatusOK> djm; + TS_ASSERT(djm = boost::make_shared<MockMantidAPIStatusOK>()); + // can cast to inherited interfaces and base classes + + MockMantidAPIStatusOK wsapi; + TSM_ASSERT( + "Job manager constructed dynamically should cast to IRemoteJobManager", + dynamic_cast<Mantid::API::IRemoteJobManager *>(djm.get())); + TSM_ASSERT( + "Job manager constructed statically should cast to IRemoteJobManger", + dynamic_cast<Mantid::API::IRemoteJobManager *>(&wsapi)); + + TSM_ASSERT("Job manager constructed dynamically should cast to " + "MantidWebServiceAPIJobManager", + dynamic_cast< + Mantid::RemoteJobManagers::MantidWebServiceAPIJobManager *>( + djm.get())); + TSM_ASSERT("Job manager constructed statically should cast to " + "MantidWebServiceAPIJobManager", + dynamic_cast< + Mantid::RemoteJobManagers::MantidWebServiceAPIJobManager *>( + &wsapi)); + } + + void test_createWithFactory() { + // The factory is tested in its own unit test, but here we can specifically + // test the creation of Mantid WS API objects. + + // save facility before test + const Mantid::Kernel::FacilityInfo &prevFac = + Mantid::Kernel::ConfigService::Instance().getFacility(); + + Mantid::Kernel::ConfigService::Instance().setFacility(SNSFac); + TSM_ASSERT_THROWS_NOTHING( + "create() with " + FermiName + " in the facility " + SNSFac + + " should not throw", + IRemoteJobManager_sptr jobManager = + RemoteJobManagerFactory::Instance().create(FermiName)); + // Important: don't feel tempted to use this job manager, it will + // interact/send jobs to the actual compute resource (and will only work + // within its facility). + + // it should not be available here... + Mantid::Kernel::ConfigService::Instance().setFacility(ISISFac); + TSM_ASSERT_THROWS("create() with " + FermiName + + " in a facility other than " + SNSFac + + " should fail", + IRemoteJobManager_sptr jobManager = + RemoteJobManagerFactory::Instance().create(FermiName), + std::runtime_error); + + // restore facility to what it was before test + Mantid::Kernel::ConfigService::Instance().setFacility(prevFac.name()); + } + + // if the response code is HTTP_OK, it ignores the response content + void test_OKResponse() { + + MockMantidAPIStatusOK jm; + checkJMOKResponseNoMsg(jm); + } + + // If the response code is not ok, a JSON string is expected in the + // response, with the parameter 'Err_Msg' + void test_errorResponseWithErrMsg() { + + MockMantidAPIStatusNotFoundWithErrMsg jmErrMsg; + checkJMWithErrResponse(jmErrMsg); + } + + // what if 'Err_Msg' is not included in the response + void test_errorResponseNoErrMsg() { + + MockMantidAPIStatusNotFound jmErr; + checkJMErrWithoutErrMessage(jmErr); + } + + void test_missingOrWrongParamsWithoutLogin() { + + // Note well: here and below these tests throw JSONParseException + // because the current behavior of these methods is that the + // request is sent (httpGet() or httpPost()). So an exception is thrown when + // trying to parse the (wrong) response from the server. This test cases + // should not be interpreted as "this should be the behavior" but rather + // as "this is the present behavior". + + // Note also that many of these checks will not throw if using + // MockMantidAPIStatusOK (HTTP_OK status from server, even if the + // response is empty or inconsistent). + MockMantidAPIStatusNotFound jm; + TSM_ASSERT_THROWS("abort job without job ID should throw", + jm.abortRemoteJob(""), JSONParseException); + TSM_ASSERT_THROWS("abort job with wrong job ID should throw", + jm.abortRemoteJob("anything_wrong"), JSONParseException); + + TSM_ASSERT_THROWS("download with wrong transaction ID should throw", + jm.downloadRemoteFile("any_wrong_transID", "remote_fname", + "local_fname"), + JSONParseException); + + // Note that as an exception queryAllRemoteJobs does a bit more of + // checking and throws std::runtime_error when something is wrong + // in the server response. + std::vector<IRemoteJobManager::RemoteJobInfo> infos; + TSM_ASSERT_THROWS("query all jobs without logging in should throw", + infos = jm.queryAllRemoteJobs(), std::runtime_error); + TSM_ASSERT_EQUALS( + "there should not be any job information returned from the remote", + infos.size(), 0); + + std::vector<std::string> files; + TSM_ASSERT_THROWS( + "query remote files with wrong transaction ID should throw", + files = jm.queryRemoteFile("any_wrong_transID"), JSONParseException); + TSM_ASSERT_EQUALS("The file list for a wrong transaction should be empty", + files.size(), 0); + + IRemoteJobManager::RemoteJobInfo info; + TSM_ASSERT_THROWS("query job info should throw for wrong job ID", + info = jm.queryRemoteJob("any_wrong_jobID"), + JSONParseException); + + std::string id; + TSM_ASSERT_THROWS("start transaction without logging in should throw", + id = jm.startRemoteTransaction(), JSONParseException); + TSM_ASSERT_EQUALS("failed start transaction should not return any ID", id, + ""); + + TSM_ASSERT_THROWS("stop transaction without logging in should throw", + jm.stopRemoteTransaction("a_wrong_transID"), + JSONParseException); + + std::string jobID; + TSM_ASSERT_THROWS("submit job without logging in should throw", + id = jm.submitRemoteJob("a_wrong_transID", "executable", + "--params 0", "name_for_job"), + JSONParseException); + TSM_ASSERT_EQUALS("failed submit job should not return any ID", jobID, ""); + + TSM_ASSERT_THROWS( + "upload file without logging in should throw", + jm.uploadRemoteFile("wrong_transID", "remote_fname", "local_fname"), + JSONParseException); + + // and failed login at the end + TSM_ASSERT_THROWS("authenticate with empty credentials should throw", + jm.authenticate("", ""), JSONParseException); + TSM_ASSERT_THROWS("mocked authenticate should throw", + jm.authenticate("wrong_user", "no_pass"), + JSONParseException); + } + +private: + // for when the server returns status == HTTP_OK + void checkJMOKResponseNoMsg(MantidWebServiceAPIJobManager &jm) { + TSM_ASSERT_THROWS_NOTHING( + "abort job with ok response code from server should not throw", + jm.abortRemoteJob("anything")); + + TSM_ASSERT_THROWS_NOTHING( + "authenticate with ok response code from server should not throw", + jm.authenticate("any_user", "any_pass")); + + TSM_ASSERT_THROWS_NOTHING( + "download with ok response code from server should not throw", + jm.downloadRemoteFile("any_transID", "remote_fname", "local_fname")); + + std::vector<IRemoteJobManager::RemoteJobInfo> infos; + TSM_ASSERT_THROWS("query all jobs with ok response code but no content " + "from server should throw", + infos = jm.queryAllRemoteJobs(), std::runtime_error); + + std::vector<std::string> files; + TSM_ASSERT_THROWS("query remote files with ok response code but no content " + "from server should throw", + files = jm.queryRemoteFile("any"), JSONParseException); + TSM_ASSERT_EQUALS("The file list for a transaction should be empty", + files.size(), 0); + + IRemoteJobManager::RemoteJobInfo info; + TSM_ASSERT_THROWS("query job info with ok response code from but no " + "content from server should throw", + info = jm.queryRemoteJob("any"), JSONParseException); + + std::string id; + TSM_ASSERT_THROWS("start transaction with ok response code but no content " + "from server should throw", + id = jm.startRemoteTransaction(), JSONParseException); + TSM_ASSERT_EQUALS("failed start transaction should not return any ID", id, + ""); + + TSM_ASSERT_THROWS_NOTHING( + "stop transaction with ok response code from server should not throw", + jm.stopRemoteTransaction("a_wrong_transID")); + + std::string jobID; + TSM_ASSERT_THROWS("submit job with ok response code but no content from " + "server should throw", + id = jm.submitRemoteJob("a_wrong_transID", "executable", + "--params 0", "name_for_job"), + JSONParseException); + TSM_ASSERT_EQUALS("mock submit job should not return non-empty ID", jobID, + ""); + + TSM_ASSERT_THROWS( + "upload file with ok response code but no content from server should " + "throw", + jm.uploadRemoteFile("wrong_transID", "remote_fname", "local_fname"), + JSONParseException); + } + + // for when the server returns status != HTTP_OK and a correctly + // formated error response body + void checkJMWithErrResponse(MantidWebServiceAPIJobManager &jm) { + TSM_ASSERT_THROWS( + "abort job with error response code from server should throw", + jm.abortRemoteJob("anything"), JSONParseException); + + TSM_ASSERT_THROWS( + "authenticate with error response code from server should throw", + jm.authenticate("any_user", "any_pass"), JSONParseException); + + TSM_ASSERT_THROWS( + "download with error response code from server should throw", + jm.downloadRemoteFile("any_transID", "remote_fname", "local_fname"), + JSONParseException); + + std::vector<IRemoteJobManager::RemoteJobInfo> infos; + TSM_ASSERT_THROWS( + "query all jobs with error response from server should throw", + infos = jm.queryAllRemoteJobs(), std::runtime_error); + + std::vector<std::string> files; + TSM_ASSERT_THROWS( + "query remote files with error response code from server should throw", + files = jm.queryRemoteFile("any"), JSONParseException); + TSM_ASSERT_EQUALS("The file list for a wrong transaction should be empty", + files.size(), 0); + + IRemoteJobManager::RemoteJobInfo info; + TSM_ASSERT_THROWS( + "query job info with error response from server should throw", + info = jm.queryRemoteJob("any"), JSONParseException); + + std::string id; + TSM_ASSERT_THROWS( + "start transaction with error response from server should throw", + id = jm.startRemoteTransaction(), JSONParseException); + TSM_ASSERT_EQUALS("failed start transaction should not return any ID", id, + ""); + + TSM_ASSERT_THROWS( + "stop transaction with error response from server should throw", + jm.stopRemoteTransaction("a_wrong_transID"), JSONParseException); + + std::string jobID; + TSM_ASSERT_THROWS("submit job with error response from server should throw", + id = jm.submitRemoteJob("a_wrong_transID", "executable", + "--params 0", "name_for_job"), + JSONParseException); + TSM_ASSERT_EQUALS("failed submit job should not return any ID", jobID, ""); + + TSM_ASSERT_THROWS( + "upload file with error response from server should throw", + jm.uploadRemoteFile("wrong_transID", "remote_fname", "local_fname"), + JSONParseException); + } + + // for when the server returns an status code != HTTP_OK but the + // response body is empty or an unexpected/badly formated JSON + // output + void checkJMErrWithoutErrMessage(MantidWebServiceAPIJobManager &jm) { + TSM_ASSERT_THROWS("abort job with error response code but no content from " + "server should throw", + jm.abortRemoteJob("anything"), JSONParseException); + + TSM_ASSERT_THROWS( + "authenticate with error response code but no content from server but " + "no content should throw", + jm.authenticate("any_user", "any_pass"), JSONParseException); + + TSM_ASSERT_THROWS( + "download with error response code but no content from server should " + "throw", + jm.downloadRemoteFile("any_transID", "remote_fname", "local_fname"), + JSONParseException); + + std::vector<IRemoteJobManager::RemoteJobInfo> infos; + TSM_ASSERT_THROWS("query all jobs with error response from but no content " + "server should throw", + infos = jm.queryAllRemoteJobs(), std::runtime_error); + + std::vector<std::string> files; + TSM_ASSERT_THROWS("query remote files with error response code but no " + "content from server should throw", + files = jm.queryRemoteFile("any"), JSONParseException); + TSM_ASSERT_EQUALS("The file list for a wrong transaction should be empty", + files.size(), 0); + + IRemoteJobManager::RemoteJobInfo info; + TSM_ASSERT_THROWS("query job info with error response but no content from " + "server should throw", + info = jm.queryRemoteJob("any"), JSONParseException); + + std::string id; + TSM_ASSERT_THROWS("start transaction with error response but no content " + "from server should throw", + id = jm.startRemoteTransaction(), JSONParseException); + TSM_ASSERT_EQUALS("failed start transaction should not return any ID", id, + ""); + + TSM_ASSERT_THROWS("stop transaction with error response but no content " + "from server should throw", + jm.stopRemoteTransaction("a_wrong_transID"), + JSONParseException); + + std::string jobID; + TSM_ASSERT_THROWS("submit job with error response but no content from " + "server should throw", + id = jm.submitRemoteJob("a_wrong_transID", "executable", + "--params 0", "name_for_job"), + JSONParseException); + TSM_ASSERT_EQUALS("failed submit job should not return any ID", jobID, ""); + + TSM_ASSERT_THROWS( + "upload file with error response but no content from server should " + "throw", + jm.uploadRemoteFile("wrong_transID", "remote_fname", "local_fname"), + JSONParseException); + } + + static const std::string SNSFac; + static const std::string ISISFac; + static const std::string FermiName; + static const std::string SCARFName; +}; + +const std::string MantidWebServiceAPIJobManagerTest::SNSFac = "SNS"; +const std::string MantidWebServiceAPIJobManagerTest::ISISFac = "ISIS"; +const std::string MantidWebServiceAPIJobManagerTest::FermiName = "Fermi"; +const std::string MantidWebServiceAPIJobManagerTest::SCARFName = "SCARF@STFC"; + +#endif // MANTID_REMOTEJOGMANAGERS_MANTIDWEBSERVICEJOBMANAGERTEST_H_ diff --git a/Code/Mantid/MantidQt/CustomInterfaces/CMakeLists.txt b/Code/Mantid/MantidQt/CustomInterfaces/CMakeLists.txt index 1526855475ab4ea071b8cc85c0426944c839a817..5e8b2f8a9af70eb5f63fd89ea3d67c4ad3098531 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/CMakeLists.txt +++ b/Code/Mantid/MantidQt/CustomInterfaces/CMakeLists.txt @@ -8,8 +8,6 @@ set ( SRC_FILES src/Indirect/ConvFit.cpp src/Indirect/DensityOfStates.cpp src/Indirect/Elwin.cpp - src/Indirect/Fury.cpp - src/Indirect/FuryFit.cpp src/Indirect/IDATab.cpp src/Indirect/ILLEnergyTransfer.cpp src/Indirect/IndirectBayes.cpp @@ -34,6 +32,8 @@ set ( SRC_FILES src/Indirect/ISISCalibration.cpp src/Indirect/ISISDiagnostics.cpp src/Indirect/ISISEnergyTransfer.cpp + src/Indirect/Iqt.cpp + src/Indirect/IqtFit.cpp src/Indirect/JumpFit.cpp src/Indirect/MSDFit.cpp src/Indirect/Quasi.cpp @@ -91,8 +91,6 @@ set ( INC_FILES inc/MantidQtCustomInterfaces/Indirect/ConvFit.h inc/MantidQtCustomInterfaces/Indirect/DensityOfStates.h inc/MantidQtCustomInterfaces/Indirect/Elwin.h - inc/MantidQtCustomInterfaces/Indirect/Fury.h - inc/MantidQtCustomInterfaces/Indirect/FuryFit.h inc/MantidQtCustomInterfaces/Indirect/ILLEnergyTransfer.h inc/MantidQtCustomInterfaces/Indirect/IndirectBayes.h inc/MantidQtCustomInterfaces/Indirect/IndirectBayesTab.h @@ -121,6 +119,8 @@ set ( INC_FILES inc/MantidQtCustomInterfaces/Indirect/ISISCalibration.h inc/MantidQtCustomInterfaces/Indirect/ISISDiagnostics.h inc/MantidQtCustomInterfaces/Indirect/ISISEnergyTransfer.h + inc/MantidQtCustomInterfaces/Indirect/Iqt.h + inc/MantidQtCustomInterfaces/Indirect/IqtFit.h inc/MantidQtCustomInterfaces/IReflPresenter.h inc/MantidQtCustomInterfaces/IReflSearcher.h inc/MantidQtCustomInterfaces/MantidEV.h @@ -181,8 +181,6 @@ set ( MOC_FILES inc/MantidQtCustomInterfaces/Background.h inc/MantidQtCustomInterfaces/Indirect/ConvFit.h inc/MantidQtCustomInterfaces/Indirect/DensityOfStates.h inc/MantidQtCustomInterfaces/Indirect/Elwin.h - inc/MantidQtCustomInterfaces/Indirect/Fury.h - inc/MantidQtCustomInterfaces/Indirect/FuryFit.h inc/MantidQtCustomInterfaces/Indirect/ILLEnergyTransfer.h inc/MantidQtCustomInterfaces/Indirect/IndirectBayes.h inc/MantidQtCustomInterfaces/Indirect/IndirectBayesTab.h @@ -203,6 +201,8 @@ set ( MOC_FILES inc/MantidQtCustomInterfaces/Background.h inc/MantidQtCustomInterfaces/Indirect/IndirectTools.h inc/MantidQtCustomInterfaces/Indirect/IndirectToolsTab.h inc/MantidQtCustomInterfaces/Indirect/IndirectTab.h + inc/MantidQtCustomInterfaces/Indirect/Iqt.h + inc/MantidQtCustomInterfaces/Indirect/IqtFit.h inc/MantidQtCustomInterfaces/Indirect/JumpFit.h inc/MantidQtCustomInterfaces/Indirect/MSDFit.h inc/MantidQtCustomInterfaces/Indirect/Quasi.h @@ -250,8 +250,6 @@ set ( UI_FILES inc/MantidQtCustomInterfaces/AddWorkspace.ui inc/MantidQtCustomInterfaces/Indirect/ConvFit.ui inc/MantidQtCustomInterfaces/Indirect/DensityOfStates.ui inc/MantidQtCustomInterfaces/Indirect/Elwin.ui - inc/MantidQtCustomInterfaces/Indirect/Fury.ui - inc/MantidQtCustomInterfaces/Indirect/FuryFit.ui inc/MantidQtCustomInterfaces/Indirect/ILLEnergyTransfer.ui inc/MantidQtCustomInterfaces/Indirect/IndirectBayes.ui inc/MantidQtCustomInterfaces/Indirect/IndirectDataAnalysis.ui @@ -267,6 +265,8 @@ set ( UI_FILES inc/MantidQtCustomInterfaces/AddWorkspace.ui inc/MantidQtCustomInterfaces/Indirect/IndirectTools.ui inc/MantidQtCustomInterfaces/Indirect/IndirectTransmission.ui inc/MantidQtCustomInterfaces/Indirect/IndirectTransmissionCalc.ui + inc/MantidQtCustomInterfaces/Indirect/Iqt.ui + inc/MantidQtCustomInterfaces/Indirect/IqtFit.ui inc/MantidQtCustomInterfaces/Indirect/JumpFit.ui inc/MantidQtCustomInterfaces/Indirect/MSDFit.ui inc/MantidQtCustomInterfaces/Indirect/Quasi.ui diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDataAnalysis.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDataAnalysis.h index 5ddb491ba82239fb9034180b3890db35adf09198..b7a6e8d38dcad15f3dad547f513f198be5b434a5 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDataAnalysis.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDataAnalysis.h @@ -27,8 +27,8 @@ namespace IDA { ELWIN, MSD_FIT, - FURY, - FURY_FIT, + IQT, + IQT_FIT, CONV_FIT, CALC_CORR, APPLY_CORR, diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDataAnalysis.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDataAnalysis.ui index d5dee6ffa715539633279184c1b38f51b9efa666..0c5b776da6731ffdc733f600a9968daae3e76e6e 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDataAnalysis.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDataAnalysis.ui @@ -36,14 +36,14 @@ <string>MSD Fit</string> </attribute> </widget> - <widget class="QWidget" name="tabFury"> + <widget class="QWidget" name="tabIqt"> <attribute name="title"> - <string>Fury</string> + <string>I(Q, t)</string> </attribute> </widget> - <widget class="QWidget" name="tabFuryFit"> + <widget class="QWidget" name="tabIqtFit"> <attribute name="title"> - <string>FuryFit</string> + <string>I(Q, t) Fit</string> </attribute> </widget> <widget class="QWidget" name="tabConvFit"> diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectTab.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectTab.h index 0eadf6a74807bc919534095834b32a7b65e51051..49f4af6321455c56f529ea016a88fb7801ddbdd5 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectTab.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectTab.h @@ -94,18 +94,23 @@ namespace CustomInterfaces /// Add a SaveNexusProcessed step to the batch queue void addSaveWorkspaceToQueue(const QString & wsName, const QString & filename = ""); - /// Plot a spectrum plot given a list of workspace names + /// Plot a spectrum plot with a given spectrum index void plotSpectrum(const QStringList & workspaceNames, int specIndex = 0); /// Plot a spectrum plot of a given workspace void plotSpectrum(const QString & workspaceName, int specIndex = 0); + /// Plot a spectrum plot with a given spectra range + void plotSpectrum(const QStringList & workspaceNames, int specStart, int specEnd); + /// Plot a spectrum plot with a given spectra range of a given workspace + void plotSpectrum(const QString & workspaceName, int specStart, int specEnd); + /// Plot a time bin plot given a list of workspace names void plotTimeBin(const QStringList & workspaceNames, int specIndex = 0); /// Plot a time bin plot of a given workspace void plotTimeBin(const QString & workspaceName, int specIndex = 0); /// Plot a contour plot of a given workspace - void plotContour(const QString & workspaceName); + void plot2D(const QString & workspaceName); /// Function to set the range limits of the plot void setPlotPropertyRange(MantidQt::MantidWidgets::RangeSelector * rs, diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/Fury.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/Iqt.h similarity index 72% rename from Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/Fury.h rename to Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/Iqt.h index 3bcfe61271368d0730da4e052e703235dcc48842..95fbf39837b272dbd5428729a59c3a9343ecfd7b 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/Fury.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/Iqt.h @@ -1,7 +1,7 @@ -#ifndef MANTIDQTCUSTOMINTERFACESIDA_FURY_H_ -#define MANTIDQTCUSTOMINTERFACESIDA_FURY_H_ +#ifndef MANTIDQTCUSTOMINTERFACESIDA_IQT_H_ +#define MANTIDQTCUSTOMINTERFACESIDA_IQT_H_ -#include "ui_Fury.h" +#include "ui_Iqt.h" #include "IDATab.h" namespace MantidQt @@ -10,12 +10,12 @@ namespace CustomInterfaces { namespace IDA { - class DLLExport Fury : public IDATab + class DLLExport Iqt : public IDATab { Q_OBJECT public: - Fury(QWidget * parent = 0); + Iqt(QWidget * parent = 0); private: virtual void setup(); @@ -31,7 +31,7 @@ namespace IDA void calculateBinning(); private: - Ui::Fury m_uiForm; + Ui::Iqt m_uiForm; QtTreePropertyBrowser* m_furTree; bool m_furyResFileType; @@ -40,4 +40,4 @@ namespace IDA } // namespace CustomInterfaces } // namespace MantidQt -#endif /* MANTIDQTCUSTOMINTERFACESIDA_FURY_H_ */ +#endif /* MANTIDQTCUSTOMINTERFACESIDA_IQT_H_ */ diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/Fury.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/Iqt.ui similarity index 98% rename from Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/Fury.ui rename to Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/Iqt.ui index a3ae0af137d7761fc6d9c3d8bf0d3fc00158d6c9..409072ced09994b2ac8ca26040ecebce11fccfb4 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/Fury.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/Iqt.ui @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> - <class>Fury</class> - <widget class="QWidget" name="Fury"> + <class>Iqt</class> + <widget class="QWidget" name="Iqt"> <property name="geometry"> <rect> <x>0</x> diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/FuryFit.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IqtFit.h similarity index 83% rename from Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/FuryFit.h rename to Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IqtFit.h index 66cf514feca432e108fb5b031b27be0bede39d02..16119b74a27d3f677ed22b4b0c10a26cefe688a8 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/FuryFit.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IqtFit.h @@ -1,7 +1,7 @@ -#ifndef MANTIDQTCUSTOMINTERFACESIDA_FURYFIT_H_ -#define MANTIDQTCUSTOMINTERFACESIDA_FURYFIT_H_ +#ifndef MANTIDQTCUSTOMINTERFACESIDA_IQTFIT_H_ +#define MANTIDQTCUSTOMINTERFACESIDA_IQTFIT_H_ -#include "ui_FuryFit.h" +#include "ui_IqtFit.h" #include "IDATab.h" #include "MantidAPI/CompositeFunction.h" #include "MantidAPI/MatrixWorkspace.h" @@ -21,12 +21,12 @@ namespace CustomInterfaces { namespace IDA { - class DLLExport FuryFit : public IDATab + class DLLExport IqtFit : public IDATab { Q_OBJECT public: - FuryFit(QWidget * parent = 0); + IqtFit(QWidget * parent = 0); private: virtual void setup(); @@ -59,10 +59,10 @@ namespace IDA QString fitTypeString() const; void constrainIntensities(Mantid::API::CompositeFunction_sptr func); - Ui::FuryFit m_uiForm; + Ui::IqtFit m_uiForm; QtStringPropertyManager* m_stringManager; - QtTreePropertyBrowser* m_ffTree; ///< FuryFit Property Browser - QtDoublePropertyManager* m_ffRangeManager; ///< StartX and EndX for FuryFit + QtTreePropertyBrowser* m_ffTree; ///< IqtFit Property Browser + QtDoublePropertyManager* m_ffRangeManager; ///< StartX and EndX for IqtFit QMap<QtProperty*, QtProperty*> m_fixedProps; Mantid::API::MatrixWorkspace_sptr m_ffInputWS; Mantid::API::MatrixWorkspace_sptr m_ffOutputWS; @@ -74,4 +74,4 @@ namespace IDA } // namespace CustomInterfaces } // namespace MantidQt -#endif /* MANTIDQTCUSTOMINTERFACESIDA_FURYFIT_H_ */ +#endif /* MANTIDQTCUSTOMINTERFACESIDA_IQTFIT_H_ */ diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/FuryFit.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IqtFit.ui similarity index 99% rename from Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/FuryFit.ui rename to Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IqtFit.ui index 8bda7e0a38e58685317853d5d4dfe3ea6cbff994..01c7d73a7d4f0023d0555b999beeb81fd8220623 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/FuryFit.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IqtFit.ui @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> - <class>FuryFit</class> - <widget class="QWidget" name="FuryFit"> + <class>IqtFit</class> + <widget class="QWidget" name="IqtFit"> <property name="geometry"> <rect> <x>0</x> diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCPeakFittingView.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCPeakFittingView.h index 4768632e3b7790dba370202c497aee51d41ece50..102df05d9b3fca7ea77189a98ac6843b71b3ed62 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCPeakFittingView.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCPeakFittingView.h @@ -59,6 +59,7 @@ namespace CustomInterfaces void setParameter(const QString& funcIndex, const QString& paramName, double value); void setPeakPickerEnabled(bool enabled); void setPeakPicker(const IPeakFunction_const_sptr& peak); + void displayError(const QString& message); void help(); // -- End of IALCPeakFitting interface --------------------------------------------------------- diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/IALCPeakFittingView.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/IALCPeakFittingView.h index 34a4704f73582f8e8db260a0b73dcfad0aea9097..d03360376a02a6d2f5f54c33b75d7e5d50b9a738 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/IALCPeakFittingView.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/IALCPeakFittingView.h @@ -86,6 +86,12 @@ namespace CustomInterfaces /// @param peak :: A new peak to represent virtual void setPeakPicker(const IPeakFunction_const_sptr& peak) = 0; + /** + * Pops-up an error box + * @param message :: Error message to display + */ + virtual void displayError(const QString& message) = 0; + /// Opens the Mantid Wiki web page virtual void help() = 0; diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ApplyCorr.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ApplyCorr.cpp index 3b425f1a40911a97143ebc4425b056f4289d0052..fa888e2368ab4f8065d811aed6b3717a8c581e6d 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ApplyCorr.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ApplyCorr.cpp @@ -303,7 +303,7 @@ namespace IDA plotSpectrum(QString::fromStdString(m_pythonExportWsName)); if(plotType == "Contour" || plotType == "Both") - plotContour(QString::fromStdString(m_pythonExportWsName)); + plot2D(QString::fromStdString(m_pythonExportWsName)); } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/DensityOfStates.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/DensityOfStates.cpp index 9b77f0ea66ae48b53ebcd7ab3fb1a2f9d1169ff6..412fc565ca8c06bc32d3b33caed44f3d37954fe2 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/DensityOfStates.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/DensityOfStates.cpp @@ -163,12 +163,7 @@ namespace CustomInterfaces // Handle spectra plotting if(m_uiForm.ckPlot->isChecked()) - { - QString pyInput = "from mantidplot import plotSpectrum, plot2D\n" - "plotSpectrum('" + m_outputWsName + "', 0)\n"; - - runPythonCode(pyInput); - } + plotSpectrum(m_outputWsName); } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISCalibration.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISCalibration.cpp index e314f961f1178053c045b732cc7fc5400d4c9d7c..11a8d425db0a29e383bbc6099e4cde2766e74a59 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISCalibration.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISCalibration.cpp @@ -290,8 +290,10 @@ namespace CustomInterfaces // Plot the smoothed workspace if required if(m_uiForm.ckSmoothResolution->isChecked() && m_uiForm.ckPlot->isChecked()) { - std::string pyInput = "from mantidplot import plotSpectrum\nplotSpectrum(['" + m_pythonExportWsName + "', '" + m_pythonExportWsName + "_pre_smooth'], 0)\n"; - m_pythonRunner.runPythonCode(QString::fromStdString(pyInput)); + QStringList plotWorkspaces; + plotWorkspaces << QString::fromStdString(m_pythonExportWsName) + << QString::fromStdString(m_pythonExportWsName) + "_pre_smooth"; + plotSpectrum(plotWorkspaces); } } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISEnergyTransfer.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISEnergyTransfer.cpp index d277978e14fd6c6b964cbd5702ab83fc52ec053d..80faa69cca76c886ef5bf97b9d450cae2a63e6d0 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISEnergyTransfer.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISEnergyTransfer.cpp @@ -472,8 +472,7 @@ namespace CustomInterfaces QFileInfo rawFileInfo(rawFile); std::string name = rawFileInfo.baseName().toStdString(); - std::string pyInput = "from mantidplot import plotSpectrum\nplotSpectrum('" + name + "_grp', 0)\n"; - m_pythonRunner.runPythonCode(QString::fromStdString(pyInput)); + plotSpectrum(QString::fromStdString(name) + "_grp"); } /** diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDataAnalysis.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDataAnalysis.cpp index c74a02eaf835cf91acadf40476a8e1a77dab2120..927466e1bc11a887420308535eea620d1ed1bd5c 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDataAnalysis.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDataAnalysis.cpp @@ -6,8 +6,8 @@ // IDATab subclasses: #include "MantidQtCustomInterfaces/Indirect/Elwin.h" #include "MantidQtCustomInterfaces/Indirect/MSDFit.h" -#include "MantidQtCustomInterfaces/Indirect/Fury.h" -#include "MantidQtCustomInterfaces/Indirect/FuryFit.h" +#include "MantidQtCustomInterfaces/Indirect/Iqt.h" +#include "MantidQtCustomInterfaces/Indirect/IqtFit.h" #include "MantidQtCustomInterfaces/Indirect/ConvFit.h" #include "MantidQtCustomInterfaces/Indirect/CalcCorr.h" #include "MantidQtCustomInterfaces/Indirect/ApplyCorr.h" @@ -47,8 +47,8 @@ namespace IDA // We make the assumption that each map key corresponds to the order in which the tabs appear. m_tabs.insert(std::make_pair(ELWIN, new Elwin(m_uiForm.twIDATabs->widget(ELWIN)))); m_tabs.insert(std::make_pair(MSD_FIT, new MSDFit(m_uiForm.twIDATabs->widget(MSD_FIT)))); - m_tabs.insert(std::make_pair(FURY, new Fury(m_uiForm.twIDATabs->widget(FURY)))); - m_tabs.insert(std::make_pair(FURY_FIT, new FuryFit(m_uiForm.twIDATabs->widget(FURY_FIT)))); + m_tabs.insert(std::make_pair(IQT, new Iqt(m_uiForm.twIDATabs->widget(IQT)))); + m_tabs.insert(std::make_pair(IQT_FIT, new IqtFit(m_uiForm.twIDATabs->widget(IQT_FIT)))); m_tabs.insert(std::make_pair(CONV_FIT, new ConvFit(m_uiForm.twIDATabs->widget(CONV_FIT)))); m_tabs.insert(std::make_pair(CALC_CORR, new CalcCorr(m_uiForm.twIDATabs->widget(CALC_CORR)))); m_tabs.insert(std::make_pair(APPLY_CORR, new ApplyCorr(m_uiForm.twIDATabs->widget(APPLY_CORR)))); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectSassena.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectSassena.cpp index ad7c83269025d46a3b1dab1d74967e154f6dd396..e4121cc5867c5f38ad6950c065f57e744b514e89 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectSassena.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectSassena.cpp @@ -88,9 +88,7 @@ namespace MantidQt if(error || !plot) return; - // Plot the output workspace group - QString pyInput = "plotSpectrum('" + m_outWsName + "', 0)\n"; - emit runAsPythonScript(pyInput); + plotSpectrum(m_outWsName); } /** diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectSqw.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectSqw.cpp index 9b6025664acec32a1f41befc34991a6bcf837194..1958d94efca0e6be134d9aabc79e8ef55ee85b33 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectSqw.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectSqw.cpp @@ -160,22 +160,17 @@ namespace CustomInterfaces QString sampleWsName = m_uiForm.dsSampleInput->getCurrentDataName(); QString sqwWsName = sampleWsName.left(sampleWsName.length() - 4) + "_sqw"; - QString pyInput = "sqw_ws = '" + sqwWsName + "'\n"; QString plotType = m_uiForm.cbPlotType->currentText(); if(plotType == "Contour") - { - pyInput += "plot2D(sqw_ws)\n"; - } + plot2D(sqwWsName); else if(plotType == "Spectra") { - pyInput += - "n_spec = mtd[sqw_ws].getNumberHistograms()\n" - "plotSpectrum(sqw_ws, range(0, n_spec))\n"; + auto ws = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(sqwWsName.toStdString()); + int numHist = static_cast<int>(ws->getNumberHistograms()); + plotSpectrum(sqwWsName, 0, numHist); } - - m_pythonRunner.runPythonCode(pyInput); } /** diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectTab.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectTab.cpp index c8cea6ff3cc5e5ab18970861b673ec8b68a57559..c9a58d50a270da211997e4603f6579a8543fad58 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectTab.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectTab.cpp @@ -220,6 +220,50 @@ namespace CustomInterfaces } + /** + * Creates a spectrum plot of one or more workspaces with the range of + * spectra [specStart, specEnd) + * + * This uses the plotSpectrum function from the Python API. + * + * @param workspaceNames List of names of workspaces to plot + * @param specStart Range start index + * @param specEnd Range end index + */ + void IndirectTab::plotSpectrum(const QStringList & workspaceNames, int specStart, int specEnd) + { + QString pyInput = "from mantidplot import plotSpectrum\n"; + + pyInput += "plotSpectrum('"; + pyInput += workspaceNames.join("','"); + pyInput += "', range("; + pyInput += QString::number(specStart); + pyInput += ","; + pyInput += QString::number(specEnd); + pyInput += "))\n"; + + m_pythonRunner.runPythonCode(pyInput); + } + + + /** + * Creates a spectrum plot of a single workspace with the range of + * spectra [specStart, specEnd) + * + * This uses the plotSpectrum function from the Python API. + * + * @param workspaceName Names of workspace to plot + * @param specStart Range start index + * @param specEnd Range end index + */ + void IndirectTab::plotSpectrum(const QString & workspaceName, int specStart, int specEnd) + { + QStringList workspaceNames; + workspaceNames << workspaceName; + plotSpectrum(workspaceNames, specStart, specEnd); + } + + /** * Plots a contour (2D) plot of a given workspace. * @@ -227,7 +271,7 @@ namespace CustomInterfaces * * @param workspaceName Name of workspace to plot */ - void IndirectTab::plotContour(const QString & workspaceName) + void IndirectTab::plot2D(const QString & workspaceName) { QString pyInput = "from mantidplot import plot2D\n"; diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Fury.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Iqt.cpp similarity index 95% rename from Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Fury.cpp rename to Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Iqt.cpp index d1f64dc1bcc2e7b197c66ee3d8896b230585af8f..ced56c51a16d6fd996cdd61ccf86f82c22644ee4 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Fury.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Iqt.cpp @@ -1,4 +1,4 @@ -#include "MantidQtCustomInterfaces/Indirect/Fury.h" +#include "MantidQtCustomInterfaces/Indirect/Iqt.h" #include "MantidQtCustomInterfaces/UserInputValidator.h" #include "MantidQtMantidWidgets/RangeSelector.h" @@ -12,7 +12,7 @@ namespace { - Mantid::Kernel::Logger g_log("Fury"); + Mantid::Kernel::Logger g_log("Iqt"); } using namespace Mantid::API; @@ -23,14 +23,14 @@ namespace CustomInterfaces { namespace IDA { - Fury::Fury(QWidget * parent) : IDATab(parent), + Iqt::Iqt(QWidget * parent) : IDATab(parent), m_furTree(NULL), m_furyResFileType() { m_uiForm.setupUi(parent); } - void Fury::setup() + void Iqt::setup() { m_furTree = new QtTreePropertyBrowser(); m_uiForm.properties->addWidget(m_furTree); @@ -78,7 +78,7 @@ namespace IDA connect(m_uiForm.dsResolution, SIGNAL(dataReady(const QString&)), this, SLOT(calculateBinning())); } - void Fury::run() + void Iqt::run() { using namespace Mantid::API; @@ -118,10 +118,10 @@ namespace IDA /** * Ensure we have present and valid file/ws inputs. * - * The underlying Fourier transform of Fury + * The underlying Fourier transform of Iqt * also means we must enforce several rules on the parameters. */ - bool Fury::validate() + bool Iqt::validate() { UserInputValidator uiv; @@ -140,7 +140,7 @@ namespace IDA * @param prop Qt property that was changed * @param val New value of that property */ - void Fury::updatePropertyValues(QtProperty *prop, double val) + void Iqt::updatePropertyValues(QtProperty *prop, double val) { disconnect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updatePropertyValues(QtProperty*, double))); @@ -175,7 +175,7 @@ namespace IDA /** * Calculates binning parameters. */ - void Fury::calculateBinning() + void Iqt::calculateBinning() { using namespace Mantid::API; @@ -230,13 +230,13 @@ namespace IDA showMessageBox("Number of resolution bins is less than 5.\nResults may be inaccurate."); } - void Fury::loadSettings(const QSettings & settings) + void Iqt::loadSettings(const QSettings & settings) { m_uiForm.dsInput->readSettings(settings.group()); m_uiForm.dsResolution->readSettings(settings.group()); } - void Fury::plotInput(const QString& wsname) + void Iqt::plotInput(const QString& wsname) { MatrixWorkspace_sptr workspace; try @@ -315,7 +315,7 @@ namespace IDA * @param min Range selector min value * @param max Range selector amx value */ - void Fury::rsRangeChangedLazy(double min, double max) + void Iqt::rsRangeChangedLazy(double min, double max) { double oldMin = m_dblManager->value(m_properties["ELow"]); double oldMax = m_dblManager->value(m_properties["EHigh"]); @@ -327,7 +327,7 @@ namespace IDA m_dblManager->setValue(m_properties["EHigh"], max); } - void Fury::updateRS(QtProperty* prop, double val) + void Iqt::updateRS(QtProperty* prop, double val) { auto xRangeSelector = m_uiForm.ppPlot->getRangeSelector("FuryRange"); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/FuryFit.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IqtFit.cpp similarity index 95% rename from Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/FuryFit.cpp rename to Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IqtFit.cpp index e806dabff5c11fc2f283f0d9b54ef741095ab6bf..2be248cd4e8bd868f36857abe893affdae718f9a 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/FuryFit.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IqtFit.cpp @@ -1,4 +1,4 @@ -#include "MantidQtCustomInterfaces/Indirect/FuryFit.h" +#include "MantidQtCustomInterfaces/Indirect/IqtFit.h" #include "MantidQtCustomInterfaces/UserInputValidator.h" #include "MantidQtMantidWidgets/RangeSelector.h" @@ -19,7 +19,7 @@ using namespace Mantid::API; namespace { - Mantid::Kernel::Logger g_log("FuryFit"); + Mantid::Kernel::Logger g_log("IqtFit"); } namespace MantidQt @@ -28,7 +28,7 @@ namespace CustomInterfaces { namespace IDA { - FuryFit::FuryFit(QWidget * parent) : + IqtFit::IqtFit(QWidget * parent) : IDATab(parent), m_stringManager(NULL), m_ffTree(NULL), m_ffRangeManager(NULL), @@ -40,7 +40,7 @@ namespace IDA m_uiForm.setupUi(parent); } - void FuryFit::setup() + void IqtFit::setup() { m_stringManager = new QtStringPropertyManager(m_parentWidget); @@ -115,7 +115,7 @@ namespace IDA connect(m_ffTree, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(fitContextMenu(const QPoint &))); } - void FuryFit::run() + void IqtFit::run() { if ( m_ffInputWS == NULL ) { @@ -175,7 +175,7 @@ namespace IDA updatePlot(); } - bool FuryFit::validate() + bool IqtFit::validate() { UserInputValidator uiv; @@ -190,7 +190,7 @@ namespace IDA return error.isEmpty(); } - void FuryFit::loadSettings(const QSettings & settings) + void IqtFit::loadSettings(const QSettings & settings) { m_uiForm.dsSampleInput->readSettings(settings.group()); } @@ -202,7 +202,7 @@ namespace IDA * * @param wsName Name of new workspace loaded */ - void FuryFit::newDataLoaded(const QString wsName) + void IqtFit::newDataLoaded(const QString wsName) { m_ffInputWSName = wsName; m_ffInputWS = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(m_ffInputWSName.toStdString()); @@ -223,7 +223,7 @@ namespace IDA updatePlot(); } - CompositeFunction_sptr FuryFit::createFunction(bool tie) + CompositeFunction_sptr IqtFit::createFunction(bool tie) { CompositeFunction_sptr result( new CompositeFunction ); QString fname; @@ -252,7 +252,7 @@ namespace IDA return result; } - IFunction_sptr FuryFit::createUserFunction(const QString & name, bool tie) + IFunction_sptr IqtFit::createUserFunction(const QString & name, bool tie) { IFunction_sptr result = FunctionFactory::Instance().createFunction("UserFunction"); std::string formula; @@ -281,7 +281,7 @@ namespace IDA return result; } - QtProperty* FuryFit::createExponential(const QString & name) + QtProperty* IqtFit::createExponential(const QString & name) { QtProperty* expGroup = m_grpManager->addProperty(name); m_properties[name+".Intensity"] = m_dblManager->addProperty("Intensity"); @@ -293,7 +293,7 @@ namespace IDA return expGroup; } - QtProperty* FuryFit::createStretchedExp(const QString & name) + QtProperty* IqtFit::createStretchedExp(const QString & name) { QtProperty* prop = m_grpManager->addProperty(name); m_properties[name+".Intensity"] = m_dblManager->addProperty("Intensity"); @@ -309,7 +309,7 @@ namespace IDA return prop; } - QString FuryFit::fitTypeString() const + QString IqtFit::fitTypeString() const { switch ( m_uiForm.cbFitType->currentIndex() ) { @@ -326,7 +326,7 @@ namespace IDA }; } - void FuryFit::typeSelection(int index) + void IqtFit::typeSelection(int index) { m_ffTree->clear(); @@ -382,7 +382,7 @@ namespace IDA plotGuess(NULL); } - void FuryFit::updatePlot() + void IqtFit::updatePlot() { if(!m_ffInputWS) { @@ -427,7 +427,7 @@ namespace IDA } } - void FuryFit::setDefaultParameters(const QString& name) + void IqtFit::setDefaultParameters(const QString& name) { double background = m_dblManager->value(m_properties["BackgroundA0"]); //intensity is always 1-background @@ -452,7 +452,7 @@ namespace IDA * * @param value Minimum spectrum index */ - void FuryFit::specMinChanged(int value) + void IqtFit::specMinChanged(int value) { m_uiForm.spSpectraMax->setMinimum(value); } @@ -464,22 +464,22 @@ namespace IDA * * @param value Maximum spectrum index */ - void FuryFit::specMaxChanged(int value) + void IqtFit::specMaxChanged(int value) { m_uiForm.spSpectraMin->setMaximum(value); } - void FuryFit::xMinSelected(double val) + void IqtFit::xMinSelected(double val) { m_ffRangeManager->setValue(m_properties["StartX"], val); } - void FuryFit::xMaxSelected(double val) + void IqtFit::xMaxSelected(double val) { m_ffRangeManager->setValue(m_properties["EndX"], val); } - void FuryFit::backgroundSelected(double val) + void IqtFit::backgroundSelected(double val) { m_ffRangeManager->setValue(m_properties["BackgroundA0"], val); m_dblManager->setValue(m_properties["Exponential1.Intensity"], 1.0-val); @@ -487,7 +487,7 @@ namespace IDA m_dblManager->setValue(m_properties["StretchedExp.Intensity"], 1.0-val); } - void FuryFit::propertyChanged(QtProperty* prop, double val) + void IqtFit::propertyChanged(QtProperty* prop, double val) { auto fitRangeSelector = m_uiForm.ppPlot->getRangeSelector("FuryFitRange"); auto backgroundRangeSelector = m_uiForm.ppPlot->getRangeSelector("FuryFitBackground"); @@ -518,7 +518,7 @@ namespace IDA } } - void FuryFit::constrainIntensities(CompositeFunction_sptr func) + void IqtFit::constrainIntensities(CompositeFunction_sptr func) { std::string paramName = "f1.Intensity"; size_t index = func->parameterIndex(paramName); @@ -554,7 +554,7 @@ namespace IDA } } - void FuryFit::singleFit() + void IqtFit::singleFit() { if(!validate()) return; @@ -668,7 +668,7 @@ namespace IDA m_pythonExportWsName = ""; } - void FuryFit::plotGuess(QtProperty*) + void IqtFit::plotGuess(QtProperty*) { // Do nothing if there is no sample data curve if(!m_uiForm.ppPlot->hasCurve("Sample")) @@ -721,7 +721,7 @@ namespace IDA m_uiForm.ppPlot->addSpectrum("Guess", guessWs, 0, Qt::green); } - void FuryFit::fitContextMenu(const QPoint &) + void IqtFit::fitContextMenu(const QPoint &) { QtBrowserItem* item(NULL); @@ -740,7 +740,7 @@ namespace IDA return; // Create the menu - QMenu* menu = new QMenu("FuryFit", m_ffTree); + QMenu* menu = new QMenu("IqtFit", m_ffTree); QAction* action; if ( ! fixed ) @@ -760,7 +760,7 @@ namespace IDA menu->popup(QCursor::pos()); } - void FuryFit::fixItem() + void IqtFit::fixItem() { QtBrowserItem* item = m_ffTree->currentItem(); @@ -777,7 +777,7 @@ namespace IDA item->parent()->property()->removeSubProperty(prop); } - void FuryFit::unFixItem() + void IqtFit::unFixItem() { QtBrowserItem* item = m_ffTree->currentItem(); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCBaselineModellingView.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCBaselineModellingView.cpp index 136de6465559dbb12334db32d3f0c59af23b1c4b..23ad825c53491c49e4c0ca9eb0dccfb402d4e536 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCBaselineModellingView.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCBaselineModellingView.cpp @@ -129,6 +129,8 @@ namespace CustomInterfaces void ALCBaselineModellingView::setSectionRow(int row, IALCBaselineModellingView::SectionRow values) { m_ui.sections->blockSignals(true); // Setting values, no need for 'modified' signals + m_ui.sections->setFocus(); + m_ui.sections->selectRow(row); m_ui.sections->setItem(row, 0, new QTableWidgetItem(values.first)); m_ui.sections->setItem(row, 1, new QTableWidgetItem(values.second)); m_ui.sections->blockSignals(false); @@ -139,6 +141,14 @@ namespace CustomInterfaces { RangeSelector* newSelector = new RangeSelector(m_ui.dataPlot); + if (index%3==0) { + newSelector->setColour(Qt::blue); + } else if ( (index-1)%3==0 ) { + newSelector->setColour(Qt::red); + } else { + newSelector->setColour(Qt::green); + } + m_selectorModifiedMapper->setMapping(newSelector,index); connect(newSelector, SIGNAL(selectionChanged(double,double)), m_selectorModifiedMapper, SLOT(map())); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCPeakFittingPresenter.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCPeakFittingPresenter.cpp index 1e71ccfa51709b97de049d6ddc2301cad22a9855..d9e6894ab05bffd76db4c765c16885fe031f6cbe 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCPeakFittingPresenter.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCPeakFittingPresenter.cpp @@ -31,7 +31,12 @@ namespace CustomInterfaces void ALCPeakFittingPresenter::fit() { - m_model->fitPeaks(m_view->function("")); + IFunction_const_sptr func = m_view->function(""); + if ( func ) { + m_model->fitPeaks(func); + } else { + m_view->displayError("Couldn't fit an empty function"); + } } void ALCPeakFittingPresenter::onCurrentFunctionChanged() diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCPeakFittingView.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCPeakFittingView.cpp index d8183fe40bf20cce35c5a291c4c6d091cfea6cd6..c965b9d93e921ee4a2ae80ce7224c85f09f55812 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCPeakFittingView.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCPeakFittingView.cpp @@ -2,6 +2,8 @@ #include "MantidQtAPI/HelpWindow.h" +#include <QMessageBox> + #include <qwt_symbol.h> namespace MantidQt @@ -109,6 +111,11 @@ void ALCPeakFittingView::help() MantidQt::API::HelpWindow::showCustomInterface(NULL, QString("Muon_ALC")); } +void ALCPeakFittingView::displayError(const QString& message) +{ + QMessageBox::critical(m_widget, "Error", message); +} + } // namespace CustomInterfaces } // namespace Mantid diff --git a/Code/Mantid/MantidQt/CustomInterfaces/test/ALCPeakFittingPresenterTest.h b/Code/Mantid/MantidQt/CustomInterfaces/test/ALCPeakFittingPresenterTest.h index 36b8851b2caf33b3371c1e855787d6afe2417340..d28fd640b27691fe2298d7021159d485e45c0c5a 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/test/ALCPeakFittingPresenterTest.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/test/ALCPeakFittingPresenterTest.h @@ -50,6 +50,7 @@ public: MOCK_METHOD1(setPeakPicker, void(const IPeakFunction_const_sptr&)); MOCK_METHOD1(setFunction, void(const IFunction_const_sptr&)); MOCK_METHOD3(setParameter, void(const QString&, const QString&, double)); + MOCK_METHOD1(displayError, void(const QString&)); MOCK_METHOD0(help, void()); }; @@ -127,6 +128,14 @@ public: presenter.initialize(); } + void test_fitEmptyFunction() + { + ON_CALL(*m_view, function(QString(""))).WillByDefault(Return(IFunction_const_sptr())); + EXPECT_CALL(*m_view, displayError(QString("Couldn't fit an empty function"))).Times(1); + + m_view->requestFit(); + } + void test_fit() { IFunction_sptr peaks = createGaussian(1,2,3); diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/SelectWorkspacesDialog.h b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/SelectWorkspacesDialog.h index 1fecd46e3728529a271edf6e32268f76206c6e01..4c3bc0eda4410294c4a71754e4335711ef9dd118 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/SelectWorkspacesDialog.h +++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/SelectWorkspacesDialog.h @@ -47,9 +47,11 @@ class EXPORT_OPT_MANTIDQT_MANTIDWIDGETS SelectWorkspacesDialog : public QDialog Q_OBJECT public: + ///return value of the Custom button + static const int CustomButton = 45654; /// Constructor - SelectWorkspacesDialog (QWidget* parent = NULL, const std::string& typeFilter = ""); + SelectWorkspacesDialog (QWidget* parent = NULL, const std::string& typeFilter = "", const std::string& customButtonLabel = ""); /// Return the selected names QStringList getSelectedNames()const; @@ -59,12 +61,17 @@ private slots: /// Slot to monitor the workspace selection status void selectionChanged(); + /// slot to handle the custom button press + void customButtonPress(); + private: /// Displays available workspace names QListWidget* m_wsList; /// The OK button QPushButton* m_okButton; + /// The OK button + QPushButton* m_customButton; }; diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/SelectWorkspacesDialog.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/SelectWorkspacesDialog.cpp index d6a595be46b303829445012168ccd4bed8e49654..529d6af69f61f5319341b8f691d447f8332c9887 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/src/SelectWorkspacesDialog.cpp +++ b/Code/Mantid/MantidQt/MantidWidgets/src/SelectWorkspacesDialog.cpp @@ -49,8 +49,10 @@ namespace MantidWidgets /** Constructor @param parent : Parent widget @param typeFilter : optional filter for filtering workspaces by type. +@param customButtonLabel : optional label for another custom button, return code for this is defined by CustomButton. */ -SelectWorkspacesDialog::SelectWorkspacesDialog(QWidget* parent, const std::string& typeFilter) : +SelectWorkspacesDialog::SelectWorkspacesDialog(QWidget* parent, const std::string& typeFilter, + const std::string& customButtonLabel) : QDialog(parent) { setWindowTitle("MantidPlot - Select workspace"); @@ -72,9 +74,16 @@ QDialog(parent) m_wsList->addItems(tmp); m_wsList->setSelectionMode(QAbstractItemView::MultiSelection); + QDialogButtonBox* btnBox = new QDialogButtonBox(Qt::Horizontal); + + if (!customButtonLabel.empty()) { + m_customButton = new QPushButton(QString::fromStdString(customButtonLabel)); + btnBox->addButton(m_customButton,QDialogButtonBox::DestructiveRole); + connect(m_customButton, SIGNAL(clicked()), this, SLOT(customButtonPress())); + } + m_okButton = new QPushButton("Select"); QPushButton* cancelButton = new QPushButton("Cancel"); - QDialogButtonBox* btnBox = new QDialogButtonBox(Qt::Horizontal); btnBox->addButton(m_okButton,QDialogButtonBox::AcceptRole); btnBox->addButton(cancelButton,QDialogButtonBox::RejectRole); connect(btnBox, SIGNAL(accepted()), this, SLOT(accept())); @@ -109,5 +118,11 @@ void SelectWorkspacesDialog::selectionChanged() m_okButton->setEnabled( m_wsList->selectionModel()->hasSelection() ); } +/// slot to handle the custom button press +void SelectWorkspacesDialog::customButtonPress() +{ + this->done(CustomButton); +} + } } diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/Colour zoom-select.pdn b/Code/Mantid/MantidQt/SliceViewer/icons/Colour zoom-select.pdn new file mode 100644 index 0000000000000000000000000000000000000000..f07867561bbac0648045cbc605faead476a22fd5 Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/Colour zoom-select.pdn differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/Peak List 32x32.png b/Code/Mantid/MantidQt/SliceViewer/icons/Peak List 32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..766d4720bf739970b9f2b0c98140dcb40f72eabf Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/Peak List 32x32.png differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/Peak List on 32x32.png b/Code/Mantid/MantidQt/SliceViewer/icons/Peak List on 32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..26eb0a589d988a05d5832cca030303cfcd803490 Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/Peak List on 32x32.png differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/Peak List on.png b/Code/Mantid/MantidQt/SliceViewer/icons/Peak List on.png new file mode 100644 index 0000000000000000000000000000000000000000..263e43691e6b3e7256d7da451b370cc716ef28bd Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/Peak List on.png differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/Peak List.pdn b/Code/Mantid/MantidQt/SliceViewer/icons/Peak List.pdn new file mode 100644 index 0000000000000000000000000000000000000000..e2cde1a323e93d212cda161c310edea4b6a89375 Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/Peak List.pdn differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/Peak List.png b/Code/Mantid/MantidQt/SliceViewer/icons/Peak List.png new file mode 100644 index 0000000000000000000000000000000000000000..0af102633f78d70e9b307993eacf69b9d7b15443 Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/Peak List.png differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/Scale colour to visible 32x32.png b/Code/Mantid/MantidQt/SliceViewer/icons/Scale colour to visible 32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..07d6f480aafd77983634807dfa9201f8baf48f69 Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/Scale colour to visible 32x32.png differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/SliceViewerIcons.qrc b/Code/Mantid/MantidQt/SliceViewer/icons/SliceViewerIcons.qrc index db9a3459a49ed22e280062e285847abdac92d047..4555ad98b47e021ea9ccf165abb624f704b47715 100644 --- a/Code/Mantid/MantidQt/SliceViewer/icons/SliceViewerIcons.qrc +++ b/Code/Mantid/MantidQt/SliceViewer/icons/SliceViewerIcons.qrc @@ -1,22 +1,31 @@ <RCC> - <qresource prefix="/SliceViewer/icons"> - <file>peak_disabled.png</file> - <file>auto_rebin.png</file> - <file>peak.png</file> - <file>view-fullscreen.png</file> - <file>color-pallette.png</file> - <file>color-pallette-part.png</file> - <file>stock-tool-pencil-16.png</file> - <file>stock-lock.png</file> - <file>cross.png</file> - <file>refresh.png</file> - <file>document-new.png</file> - <file>grid.png</file> - <file>letter_x.png</file> - <file>letter_y.png</file> - <file>SliceViewerWindow_icon.png</file> - <file>peak-cross-faded.png</file> - <file>peak-cross-small.png</file> - <file>peak-cross.png</file> - </qresource> + <qresource prefix="/SliceViewer/icons"> + <file>Peak List on 32x32.png</file> + <file>cut on 32x32.png</file> + <file>grid on 32x32.png</file> + <file>rebin on 32x32.png</file> + <file>rebin finer 32x32.png</file> + <file>rebin auto 32x32.png</file> + <file>rebin 32x32.png</file> + <file>grid 32x32.png</file> + <file>cut remove 32x32.png</file> + <file>cut 32x32.png</file> + <file>Peak List 32x32.png</file> + <file>colour zoom minus scale 32x32.png</file> + <file>colour zoom plus scale 32x32.png</file> + <file>Scale colour to visible 32x32.png</file> + <file>zoom-select 32x32.png</file> + <file>zoom-out 32x32.png</file> + <file>zoom-in 32x32.png</file> + <file>view-fullscreen.png</file> + <file>refresh.png</file> + <file>document-new.png</file> + <file>grid.png</file> + <file>letter_x.png</file> + <file>letter_y.png</file> + <file>SliceViewerWindow_icon.png</file> + <file>peak-cross-faded.png</file> + <file>peak-cross-small.png</file> + <file>peak-cross.png</file> + </qresource> </RCC> diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/colour zoom minus scale 32x32.png b/Code/Mantid/MantidQt/SliceViewer/icons/colour zoom minus scale 32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..2e8918c0b326695b2856c3538ba4cbf18988c53f Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/colour zoom minus scale 32x32.png differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/colour zoom plus scale 32x32.png b/Code/Mantid/MantidQt/SliceViewer/icons/colour zoom plus scale 32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..6f0670d7a3fc0d932b71a6d874410e94e8381168 Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/colour zoom plus scale 32x32.png differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/colour zoom-select scale.pdn b/Code/Mantid/MantidQt/SliceViewer/icons/colour zoom-select scale.pdn new file mode 100644 index 0000000000000000000000000000000000000000..74c93e152ff16b63047e98525eb478e588235e72 Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/colour zoom-select scale.pdn differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/cut 32x32.png b/Code/Mantid/MantidQt/SliceViewer/icons/cut 32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..ac24684c29c5862c5f041399913c7883d786fb7c Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/cut 32x32.png differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/cut on 32x32.png b/Code/Mantid/MantidQt/SliceViewer/icons/cut on 32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..62d794e9cb5f09d70c523d37ca2d48ab031351b5 Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/cut on 32x32.png differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/cut remove 32x32.png b/Code/Mantid/MantidQt/SliceViewer/icons/cut remove 32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..57e7251f92143496c4aec2528c882cd256105605 Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/cut remove 32x32.png differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/cut remove.pdn b/Code/Mantid/MantidQt/SliceViewer/icons/cut remove.pdn new file mode 100644 index 0000000000000000000000000000000000000000..70519acae08ab7370f92f5d7a5eab83f20e28da8 Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/cut remove.pdn differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/grid 32x32.png b/Code/Mantid/MantidQt/SliceViewer/icons/grid 32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..ab7687022f01ac49c3df8c769ac9c29f6ffe1fc5 Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/grid 32x32.png differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/grid on 32x32.png b/Code/Mantid/MantidQt/SliceViewer/icons/grid on 32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..27a42968236f524276b081130cb6be551e37299f Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/grid on 32x32.png differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/grid on 48x48.pdn b/Code/Mantid/MantidQt/SliceViewer/icons/grid on 48x48.pdn new file mode 100644 index 0000000000000000000000000000000000000000..1deebef8fb4feeec63514d8a786855bba3da6c0c Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/grid on 48x48.pdn differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/rebin 32x32.png b/Code/Mantid/MantidQt/SliceViewer/icons/rebin 32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..88f9cf14bfb67d93df685bf8053c796637145b0e Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/rebin 32x32.png differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/rebin auto 32x32.png b/Code/Mantid/MantidQt/SliceViewer/icons/rebin auto 32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..549124c9f52bbe1901dd77e238337d6e6c410e05 Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/rebin auto 32x32.png differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/rebin finer 32x32.png b/Code/Mantid/MantidQt/SliceViewer/icons/rebin finer 32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..8dbc02a37e3c47112fad2a07e81f313f1ae99b29 Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/rebin finer 32x32.png differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/rebin on 32x32.png b/Code/Mantid/MantidQt/SliceViewer/icons/rebin on 32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..310869fe7283ad24acf5a8ce5070295bdb4486fb Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/rebin on 32x32.png differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/rebin.pdn b/Code/Mantid/MantidQt/SliceViewer/icons/rebin.pdn new file mode 100644 index 0000000000000000000000000000000000000000..8eb67b2725b8faafe44d2b04c46f92375bef2ae0 Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/rebin.pdn differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/scale colour to visible.pdn b/Code/Mantid/MantidQt/SliceViewer/icons/scale colour to visible.pdn new file mode 100644 index 0000000000000000000000000000000000000000..bf58c9c24d2b0d5463859d680627deb29ae398e2 Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/scale colour to visible.pdn differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/view-fullscreen-24x24.png b/Code/Mantid/MantidQt/SliceViewer/icons/view-fullscreen-24x24.png index 373c9ca2bcfbfbbcca4868afaf266a20c8e6e78d..ceda8189fb647c66682fa85b2e33e8271f9d5b93 100644 Binary files a/Code/Mantid/MantidQt/SliceViewer/icons/view-fullscreen-24x24.png and b/Code/Mantid/MantidQt/SliceViewer/icons/view-fullscreen-24x24.png differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/view-fullscreen.png b/Code/Mantid/MantidQt/SliceViewer/icons/view-fullscreen.png index 27ec2ef04a435ee7dccdff93f12d732e192d0ad2..e7758fe2b3a29e9231e3cb1144b3790eb89f97e1 100644 Binary files a/Code/Mantid/MantidQt/SliceViewer/icons/view-fullscreen.png and b/Code/Mantid/MantidQt/SliceViewer/icons/view-fullscreen.png differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/zoom to all 32x32.png b/Code/Mantid/MantidQt/SliceViewer/icons/zoom to all 32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..17e36931b95f6e347d43ad1f5e625ae4cb35aaf4 Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/zoom to all 32x32.png differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/zoom-in 32x32.png b/Code/Mantid/MantidQt/SliceViewer/icons/zoom-in 32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..d90f8094c1d068342fb499c30734e91c986ea357 Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/zoom-in 32x32.png differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/zoom-out 32x32.png b/Code/Mantid/MantidQt/SliceViewer/icons/zoom-out 32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..e3eb0202c7bb861009dbd02a478a58fd93e90b97 Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/zoom-out 32x32.png differ diff --git a/Code/Mantid/MantidQt/SliceViewer/icons/zoom-select 32x32.png b/Code/Mantid/MantidQt/SliceViewer/icons/zoom-select 32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..00bae20bffafd11b53b434a417fa285d8a25aeaf Binary files /dev/null and b/Code/Mantid/MantidQt/SliceViewer/icons/zoom-select 32x32.png differ diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.h index ba322744687a13fce6bde0ceda930b82fc42b246..44d1de62fe2318853fca5e5bede13cbcd861fdff 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.h +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.h @@ -51,6 +51,21 @@ namespace SliceViewer class CompositePeaksPresenter; class ProxyCompositePeaksPresenter; +// Static Const values +static const std::string g_iconPathPrefix = ":/SliceViewer/icons/"; +static const std::string g_iconZoomPlus = g_iconPathPrefix + "colour zoom plus scale 32x32.png"; +static const std::string g_iconZoomMinus = g_iconPathPrefix + "colour zoom minus scale 32x32.png"; +static const std::string g_iconViewFull = g_iconPathPrefix + "view-fullscreen.png"; +static const std::string g_iconCutOn = g_iconPathPrefix + "cut on 32x32.png"; +static const std::string g_iconCut = g_iconPathPrefix + "cut 32x32.png"; +static const std::string g_iconGridOn = g_iconPathPrefix + "grid on 32x32.png"; +static const std::string g_iconGrid = g_iconPathPrefix + "grid 32x32.png"; +static const std::string g_iconRebinOn = g_iconPathPrefix + "rebin on 32x32.png"; +static const std::string g_iconRebin = g_iconPathPrefix + "rebin 32x32.png"; +static const std::string g_iconPeakListOn = g_iconPathPrefix + "Peak List on 32x32.png"; +static const std::string g_iconPeakList = g_iconPathPrefix + "Peak List 32x32.png"; + + /** GUI for viewing a 2D slice out of a multi-dimensional workspace. * You can select which dimension to plot as X,Y, and the cut point * along the other dimension(s). @@ -171,6 +186,7 @@ public slots: void copyImageToClipboard(); void onPeaksViewerOverlayOptions(); + // Synced checkboxes void LineMode_toggled(bool); void SnapToGrid_toggled(bool); @@ -216,6 +232,7 @@ private: QString ensurePngExtension(const QString& fname) const; private: + // -------------------------- Widgets ---------------------------- diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.ui b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.ui index 6daad8bff4b1c93644f8cc5c45ca46a99a9899a0..2101640e5e8e15a10b8557f0c3b5bab025e1a102 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.ui +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>834</width> - <height>814</height> + <width>931</width> + <height>676</height> </rect> </property> <property name="windowTitle"> @@ -17,16 +17,7 @@ <property name="spacing"> <number>3</number> </property> - <property name="leftMargin"> - <number>0</number> - </property> - <property name="topMargin"> - <number>0</number> - </property> - <property name="rightMargin"> - <number>0</number> - </property> - <property name="bottomMargin"> + <property name="margin"> <number>0</number> </property> <item> @@ -62,16 +53,7 @@ <property name="sizeConstraint"> <enum>QLayout::SetMinimumSize</enum> </property> - <property name="leftMargin"> - <number>0</number> - </property> - <property name="topMargin"> - <number>0</number> - </property> - <property name="rightMargin"> - <number>0</number> - </property> - <property name="bottomMargin"> + <property name="margin"> <number>0</number> </property> </layout> @@ -87,16 +69,7 @@ <property name="spacing"> <number>2</number> </property> - <property name="leftMargin"> - <number>0</number> - </property> - <property name="topMargin"> - <number>0</number> - </property> - <property name="rightMargin"> - <number>0</number> - </property> - <property name="bottomMargin"> + <property name="margin"> <number>0</number> </property> <item> @@ -116,20 +89,78 @@ <enum>QFrame::Raised</enum> </property> <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="spacing"> + <number>0</number> + </property> + <property name="leftMargin"> + <number>9</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>9</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> <item> <widget class="QToolButton" name="btnZoom"> <property name="enabled"> <bool>true</bool> </property> + <property name="minimumSize"> + <size> + <width>45</width> + <height>45</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>45</width> + <height>45</height> + </size> + </property> + <property name="toolTip"> + <string>Zoom in by dragging a box</string> + </property> <property name="text"> <string>Zoom</string> </property> + <property name="icon"> + <iconset resource="../../icons/SliceViewerIcons.qrc"> + <normaloff>:/SliceViewer/icons/zoom-in 32x32.png</normaloff>:/SliceViewer/icons/zoom-in 32x32.png</iconset> + </property> + <property name="iconSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>true</bool> + </property> </widget> </item> <item> <widget class="QToolButton" name="btnResetZoom"> + <property name="minimumSize"> + <size> + <width>45</width> + <height>45</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>45</width> + <height>45</height> + </size> + </property> <property name="toolTip"> - <string>Reset the zoom to the extents of the data</string> + <string>Zoom out to the extents of the data</string> </property> <property name="text"> <string>Reset</string> @@ -140,48 +171,72 @@ </property> <property name="iconSize"> <size> - <width>18</width> - <height>18</height> + <width>32</width> + <height>32</height> </size> </property> </widget> </item> <item> - <widget class="QToolButton" name="btnRangeFull"> + <widget class="QToolButton" name="btnRangeSlice"> + <property name="minimumSize"> + <size> + <width>45</width> + <height>45</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>45</width> + <height>45</height> + </size> + </property> <property name="toolTip"> - <string>Reset the color range to the full range of the workspace</string> + <string>Zooms the color scale to the range of the currently view</string> </property> <property name="text"> - <string>RngFull</string> + <string>RngSlice</string> </property> <property name="icon"> <iconset resource="../../icons/SliceViewerIcons.qrc"> - <normaloff>:/SliceViewer/icons/color-pallette.png</normaloff>:/SliceViewer/icons/color-pallette.png</iconset> + <normaloff>:/SliceViewer/icons/colour zoom plus scale 32x32.png</normaloff>:/SliceViewer/icons/colour zoom plus scale 32x32.png</iconset> </property> <property name="iconSize"> <size> - <width>18</width> - <height>18</height> + <width>32</width> + <height>32</height> </size> </property> </widget> </item> <item> - <widget class="QToolButton" name="btnRangeSlice"> + <widget class="QToolButton" name="btnRangeFull"> + <property name="minimumSize"> + <size> + <width>45</width> + <height>45</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>45</width> + <height>45</height> + </size> + </property> <property name="toolTip"> - <string>Reset the color scale to the range of the currently visible slice</string> + <string>Reset the color range to the full range of the data</string> </property> <property name="text"> - <string>RngSlice</string> + <string>RngFull</string> </property> <property name="icon"> <iconset resource="../../icons/SliceViewerIcons.qrc"> - <normaloff>:/SliceViewer/icons/color-pallette-part.png</normaloff>:/SliceViewer/icons/color-pallette-part.png</iconset> + <normaloff>:/SliceViewer/icons/colour zoom minus scale 32x32.png</normaloff>:/SliceViewer/icons/colour zoom minus scale 32x32.png</iconset> </property> <property name="iconSize"> <size> - <width>18</width> - <height>18</height> + <width>32</width> + <height>32</height> </size> </property> </widget> @@ -204,20 +259,32 @@ </item> <item> <widget class="QToolButton" name="btnDoLine"> + <property name="minimumSize"> + <size> + <width>45</width> + <height>45</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>45</width> + <height>45</height> + </size> + </property> <property name="toolTip"> - <string>Draw a 1D integration line</string> + <string>Draw a 1D cut line</string> </property> <property name="text"> <string>...</string> </property> <property name="icon"> <iconset resource="../../icons/SliceViewerIcons.qrc"> - <normaloff>:/SliceViewer/icons/stock-tool-pencil-16.png</normaloff>:/SliceViewer/icons/stock-tool-pencil-16.png</iconset> + <normaloff>:/SliceViewer/icons/cut 32x32.png</normaloff>:/SliceViewer/icons/cut 32x32.png</iconset> </property> <property name="iconSize"> <size> - <width>18</width> - <height>18</height> + <width>32</width> + <height>32</height> </size> </property> <property name="checkable"> @@ -230,40 +297,64 @@ </item> <item> <widget class="QToolButton" name="btnClearLine"> + <property name="minimumSize"> + <size> + <width>45</width> + <height>45</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>45</width> + <height>45</height> + </size> + </property> <property name="toolTip"> - <string>Remove the currently drawn line</string> + <string>Remove the current cut line</string> </property> <property name="text"> <string>...</string> </property> <property name="icon"> <iconset resource="../../icons/SliceViewerIcons.qrc"> - <normaloff>:/SliceViewer/icons/cross.png</normaloff>:/SliceViewer/icons/cross.png</iconset> + <normaloff>:/SliceViewer/icons/cut remove 32x32.png</normaloff>:/SliceViewer/icons/cut remove 32x32.png</iconset> </property> <property name="iconSize"> <size> - <width>18</width> - <height>18</height> + <width>32</width> + <height>32</height> </size> </property> </widget> </item> <item> <widget class="QToolButton" name="btnSnapToGrid"> + <property name="minimumSize"> + <size> + <width>45</width> + <height>45</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>45</width> + <height>45</height> + </size> + </property> <property name="toolTip"> - <string>Snap to grid when drawing line</string> + <string>Snap to grid when drawing cut line</string> </property> <property name="text"> <string>...</string> </property> <property name="icon"> <iconset resource="../../icons/SliceViewerIcons.qrc"> - <normaloff>:/SliceViewer/icons/grid.png</normaloff>:/SliceViewer/icons/grid.png</iconset> + <normaloff>:/SliceViewer/icons/grid 32x32.png</normaloff>:/SliceViewer/icons/grid 32x32.png</iconset> </property> <property name="iconSize"> <size> - <width>18</width> - <height>18</height> + <width>32</width> + <height>32</height> </size> </property> <property name="checkable"> @@ -289,20 +380,32 @@ </item> <item> <widget class="QToolButton" name="btnRebinMode"> + <property name="minimumSize"> + <size> + <width>45</width> + <height>45</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>45</width> + <height>45</height> + </size> + </property> <property name="toolTip"> - <string>Dynamically rebin the viewed slice</string> + <string>Enable/Disable Rebin Mode</string> </property> <property name="text"> <string>...</string> </property> <property name="icon"> <iconset resource="../../icons/SliceViewerIcons.qrc"> - <normaloff>:/SliceViewer/icons/document-new.png</normaloff>:/SliceViewer/icons/document-new.png</iconset> + <normaloff>:/SliceViewer/icons/rebin 32x32.png</normaloff>:/SliceViewer/icons/rebin 32x32.png</iconset> </property> <property name="iconSize"> <size> - <width>18</width> - <height>18</height> + <width>32</width> + <height>32</height> </size> </property> <property name="checkable"> @@ -315,17 +418,32 @@ <property name="enabled"> <bool>false</bool> </property> + <property name="minimumSize"> + <size> + <width>45</width> + <height>45</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>45</width> + <height>45</height> + </size> + </property> + <property name="toolTip"> + <string>Rebin the current view</string> + </property> <property name="text"> <string>...</string> </property> <property name="icon"> <iconset resource="../../icons/SliceViewerIcons.qrc"> - <normaloff>:/SliceViewer/icons/refresh.png</normaloff>:/SliceViewer/icons/refresh.png</iconset> + <normaloff>:/SliceViewer/icons/rebin finer 32x32.png</normaloff>:/SliceViewer/icons/rebin finer 32x32.png</iconset> </property> <property name="iconSize"> <size> - <width>18</width> - <height>18</height> + <width>32</width> + <height>32</height> </size> </property> </widget> @@ -335,6 +453,18 @@ <property name="enabled"> <bool>false</bool> </property> + <property name="minimumSize"> + <size> + <width>45</width> + <height>45</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>45</width> + <height>45</height> + </size> + </property> <property name="toolTip"> <string>Auto rebin</string> </property> @@ -343,12 +473,12 @@ </property> <property name="icon"> <iconset resource="../../icons/SliceViewerIcons.qrc"> - <normaloff>:/SliceViewer/icons/auto_rebin.png</normaloff>:/SliceViewer/icons/auto_rebin.png</iconset> + <normaloff>:/SliceViewer/icons/rebin auto 32x32.png</normaloff>:/SliceViewer/icons/rebin auto 32x32.png</iconset> </property> <property name="iconSize"> <size> - <width>18</width> - <height>18</height> + <width>32</width> + <height>32</height> </size> </property> <property name="checkable"> @@ -364,6 +494,18 @@ <property name="enabled"> <bool>false</bool> </property> + <property name="minimumSize"> + <size> + <width>45</width> + <height>45</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>45</width> + <height>45</height> + </size> + </property> <property name="toolTip"> <string>Lock the rebinned workspace in place (use the refresh button to refresh)</string> </property> @@ -371,13 +513,13 @@ <string>...</string> </property> <property name="icon"> - <iconset resource="../../icons/SliceViewerIcons.qrc"> + <iconset> <normaloff>:/SliceViewer/icons/stock-lock.png</normaloff>:/SliceViewer/icons/stock-lock.png</iconset> </property> <property name="iconSize"> <size> - <width>18</width> - <height>18</height> + <width>32</width> + <height>32</height> </size> </property> <property name="checkable"> @@ -409,25 +551,36 @@ <property name="enabled"> <bool>true</bool> </property> + <property name="minimumSize"> + <size> + <width>45</width> + <height>45</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>45</width> + <height>45</height> + </size> + </property> <property name="toolTip"> - <string>Overlay PeaksWorkspaces</string> + <string>Overlay Peaks</string> </property> <property name="text"> <string>...</string> </property> <property name="icon"> <iconset resource="../../icons/SliceViewerIcons.qrc"> - <normaloff>:/SliceViewer/icons/peak.png</normaloff> - <disabledoff>:/SliceViewer/icons/peak_disabled.png</disabledoff>:/SliceViewer/icons/peak.png</iconset> + <normaloff>:/SliceViewer/icons/Peak List 32x32.png</normaloff>:/SliceViewer/icons/Peak List 32x32.png</iconset> </property> <property name="iconSize"> <size> - <width>18</width> - <height>18</height> + <width>32</width> + <height>32</height> </size> </property> <property name="checkable"> - <bool>false</bool> + <bool>true</bool> </property> </widget> </item> @@ -445,118 +598,128 @@ </spacer> </item> <item> - <widget class="QLabel" name="label"> - <property name="text"> - <string>x=</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="lblInfoX"> - <property name="minimumSize"> - <size> - <width>55</width> - <height>0</height> - </size> - </property> - <property name="toolTip"> - <string>X-coordinate of point under the mouse</string> - </property> - <property name="autoFillBackground"> - <bool>false</bool> - </property> - <property name="styleSheet"> - <string notr="true">QLabel { + <layout class="QFormLayout" name="formLayout_3"> + <property name="sizeConstraint"> + <enum>QLayout::SetMinimumSize</enum> + </property> + <property name="fieldGrowthPolicy"> + <enum>QFormLayout::FieldsStayAtSizeHint</enum> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>x=</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="lblInfoX"> + <property name="minimumSize"> + <size> + <width>70</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>X-coordinate of point under the mouse</string> + </property> + <property name="autoFillBackground"> + <bool>false</bool> + </property> + <property name="styleSheet"> + <string notr="true">QLabel { background-color : rgb(255, 255, 186); color : black; }</string> - </property> - <property name="frameShape"> - <enum>QFrame::StyledPanel</enum> - </property> - <property name="text"> - <string>-</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>y=</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="lblInfoY"> - <property name="minimumSize"> - <size> - <width>55</width> - <height>0</height> - </size> - </property> - <property name="toolTip"> - <string>Y-coordinate of point under the mouse</string> - </property> - <property name="autoFillBackground"> - <bool>false</bool> - </property> - <property name="styleSheet"> - <string notr="true">QLabel { + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="text"> + <string>-</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>y=</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="lblInfoY"> + <property name="minimumSize"> + <size> + <width>70</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Y-coordinate of point under the mouse</string> + </property> + <property name="autoFillBackground"> + <bool>false</bool> + </property> + <property name="styleSheet"> + <string notr="true">QLabel { background-color : rgb(255, 255, 186); color : black; }</string> - </property> - <property name="frameShape"> - <enum>QFrame::StyledPanel</enum> - </property> - <property name="text"> - <string>-</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_3"> - <property name="text"> - <string>z=</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="lblInfoSignal"> - <property name="minimumSize"> - <size> - <width>55</width> - <height>0</height> - </size> - </property> - <property name="toolTip"> - <string>Signal at the point under the mouse</string> - </property> - <property name="autoFillBackground"> - <bool>false</bool> - </property> - <property name="styleSheet"> - <string notr="true">QLabel { + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="text"> + <string>-</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>z=</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLabel" name="lblInfoSignal"> + <property name="minimumSize"> + <size> + <width>70</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Signal at the point under the mouse</string> + </property> + <property name="autoFillBackground"> + <bool>false</bool> + </property> + <property name="styleSheet"> + <string notr="true">QLabel { background-color : rgb(255, 255, 186); color : black; }</string> - </property> - <property name="frameShape"> - <enum>QFrame::StyledPanel</enum> - </property> - <property name="text"> - <string>-</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="text"> + <string>-</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + </layout> </item> </layout> </widget> @@ -573,16 +736,7 @@ <property name="spacing"> <number>4</number> </property> - <property name="leftMargin"> - <number>2</number> - </property> - <property name="topMargin"> - <number>2</number> - </property> - <property name="rightMargin"> - <number>2</number> - </property> - <property name="bottomMargin"> + <property name="margin"> <number>2</number> </property> <item> diff --git a/Code/Mantid/MantidQt/SliceViewer/src/SliceViewer.cpp b/Code/Mantid/MantidQt/SliceViewer/src/SliceViewer.cpp index 0efa8cadb6fdacc33c0feb2d3d6c0d38fd4a5544..9650d810c0c03bfe8715ee14d154aae00e801fba 100644 --- a/Code/Mantid/MantidQt/SliceViewer/src/SliceViewer.cpp +++ b/Code/Mantid/MantidQt/SliceViewer/src/SliceViewer.cpp @@ -106,8 +106,22 @@ SliceViewer::SliceViewer(QWidget *parent) // Make the splitter use the minimum size for the controls and not stretch out ui.splitter->setStretchFactor(0, 0); ui.splitter->setStretchFactor(1, 1); + QSplitterHandle *handle = ui.splitter->handle(1); + QVBoxLayout *layout = new QVBoxLayout(handle); + layout->setSpacing(0); + layout->setMargin(0); + + QFrame *line = new QFrame(handle); + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); + layout->addWidget(line); + initZoomer(); - ui.btnZoom->hide(); + + //hide unused buttons + ui.btnZoom->hide(); // hidden for a long time + ui.btnRebinLock->hide(); // now replaced by auto rebin mode + //ui.btnClearLine->hide(); // turning off line mode now removes line // ----------- Toolbar button signals ---------------- QObject::connect(ui.btnResetZoom, SIGNAL(clicked()), this, SLOT(resetZoom())); @@ -260,9 +274,10 @@ void SliceViewer::initMenus() { connect(action, SIGNAL(triggered()), this, SLOT(resetZoom())); { QIcon icon; - icon.addFile(QString::fromUtf8(":/SliceViewer/icons/view-fullscreen.png"), + icon.addFile(QString::fromStdString(g_iconViewFull), QSize(), QIcon::Normal, QIcon::Off); action->setIcon(icon); + } m_menuView->addAction(action); @@ -289,7 +304,7 @@ void SliceViewer::initMenus() { m_menuView->addSeparator(); - action = new QAction(QPixmap(), "Dynamic R&ebin Mode", this); + action = new QAction(QPixmap(), "Enable/Disable R&ebin Mode", this); m_syncRebinMode = new SyncedCheckboxes(action, ui.btnRebinMode, false); connect(m_syncRebinMode, SIGNAL(toggled(bool)), this, SLOT(RebinMode_toggled(bool))); @@ -299,9 +314,10 @@ void SliceViewer::initMenus() { m_syncRebinLock = new SyncedCheckboxes(action, ui.btnRebinLock, true); connect(m_syncRebinLock, SIGNAL(toggled(bool)), this, SLOT(RebinLock_toggled(bool))); + action->setVisible(false); //hide this action m_menuView->addAction(action); - action = new QAction(QPixmap(), "Refresh Rebin", this); + action = new QAction(QPixmap(), "Rebin Current View", this); action->setShortcut(Qt::Key_R + Qt::ControlModifier); action->setEnabled(false); connect(action, SIGNAL(triggered()), this, SLOT(rebinParamsChanged())); @@ -353,24 +369,24 @@ void SliceViewer::initMenus() { connect(action, SIGNAL(triggered()), this, SLOT(loadColorMapSlot())); m_menuColorOptions->addAction(action); - action = new QAction(QPixmap(), "&Full range", this); - connect(action, SIGNAL(triggered()), this, SLOT(setColorScaleAutoFull())); + action = new QAction(QPixmap(), "&Current View range", this); + connect(action, SIGNAL(triggered()), this, SLOT(setColorScaleAutoSlice())); + action->setIconVisibleInMenu(true); { QIcon icon; - icon.addFile(QString::fromUtf8(":/SliceViewer/icons/color-pallette.png"), - QSize(), QIcon::Normal, QIcon::Off); + icon.addFile( + QString::fromStdString(g_iconZoomPlus), + QSize(), QIcon::Normal, QIcon::Off); action->setIcon(icon); } m_menuColorOptions->addAction(action); - action = new QAction(QPixmap(), "&Slice range", this); - connect(action, SIGNAL(triggered()), this, SLOT(setColorScaleAutoSlice())); - action->setIconVisibleInMenu(true); + action = new QAction(QPixmap(), "&Full range", this); + connect(action, SIGNAL(triggered()), this, SLOT(setColorScaleAutoFull())); { QIcon icon; - icon.addFile( - QString::fromUtf8(":/SliceViewer/icons/color-pallette-part.png"), - QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(QString::fromStdString(g_iconZoomMinus), + QSize(), QIcon::Normal, QIcon::Off); action->setIcon(icon); } m_menuColorOptions->addAction(action); @@ -872,18 +888,28 @@ void SliceViewer::refreshRebin() { this->rebinParamsChanged(); } /// Slot called when the btnDoLine button is checked/unchecked void SliceViewer::LineMode_toggled(bool checked) { m_lineOverlay->setShown(checked); + + QIcon icon; if (checked) { + icon.addFile(QString::fromStdString(g_iconCutOn), + QSize(), QIcon::Normal, QIcon::On); + ui.btnDoLine->setIcon(icon); QString text; if (m_lineOverlay->getCreationMode()) - text = "Click and drag to draw an integration line.\n" + text = "Click and drag to draw an cut line.\n" "Hold Shift key to limit to 45 degree angles."; - else - text = "Drag the existing line with its handles,\n" - "or click the red X to delete it."; // Show a tooltip near the button QToolTip::showText(ui.btnDoLine->mapToGlobal(ui.btnDoLine->pos()), text, this); } + if (!checked) + { + //clear the old line + clearLine(); + icon.addFile(QString::fromStdString(g_iconCut), + QSize(), QIcon::Normal, QIcon::Off); + ui.btnDoLine->setIcon(icon); + } emit showLineViewer(checked); } @@ -896,6 +922,7 @@ void SliceViewer::toggleLineMode(bool lineMode) { // This should send events to start line mode m_syncLineMode->toggle(lineMode); m_lineOverlay->setCreationMode(false); + } //------------------------------------------------------------------------------------ @@ -908,6 +935,8 @@ void SliceViewer::clearLine() { //------------------------------------------------------------------------------------ /// Slot called when the snap to grid is checked void SliceViewer::SnapToGrid_toggled(bool checked) { + + QIcon icon; if (checked) { SnapToGridDialog *dlg = new SnapToGridDialog(this); dlg->setSnap(m_lineOverlay->getSnapX(), m_lineOverlay->getSnapY()); @@ -915,14 +944,22 @@ void SliceViewer::SnapToGrid_toggled(bool checked) { m_lineOverlay->setSnapEnabled(true); m_lineOverlay->setSnapX(dlg->getSnapX()); m_lineOverlay->setSnapY(dlg->getSnapY()); + icon.addFile(QString::fromStdString(g_iconGridOn), + QSize(), QIcon::Normal, QIcon::On); } else { // Uncheck - the user clicked cancel ui.btnSnapToGrid->setChecked(false); m_lineOverlay->setSnapEnabled(false); + icon.addFile(QString::fromStdString(g_iconGrid), + QSize(), QIcon::Normal, QIcon::Off); } } else { m_lineOverlay->setSnapEnabled(false); + icon.addFile(QString::fromStdString(g_iconGrid), + QSize(), QIcon::Normal, QIcon::Off); } + ui.btnSnapToGrid->setIcon(icon); + } //------------------------------------------------------------------------------------ @@ -936,7 +973,11 @@ void SliceViewer::RebinMode_toggled(bool checked) { m_actionRefreshRebin->setEnabled(checked); m_rebinMode = checked; + QIcon icon; if (!m_rebinMode) { + icon.addFile(QString::fromStdString(g_iconRebin), + QSize(), QIcon::Normal, QIcon::Off); + ui.btnRebinMode->setIcon(icon); // uncheck auto-rebin ui.btnAutoRebin->setChecked(false); // Remove the overlay WS @@ -944,6 +985,9 @@ void SliceViewer::RebinMode_toggled(bool checked) { this->m_data->setOverlayWorkspace(m_overlayWS); this->updateDisplay(); } else { + icon.addFile(QString::fromStdString(g_iconRebinOn), + QSize(), QIcon::Normal, QIcon::On); + ui.btnRebinMode->setIcon(icon); // Start the rebin this->rebinParamsChanged(); } @@ -1040,7 +1084,7 @@ void SliceViewer::updateDisplaySlot(int index, double value) { UNUSED_ARG(value) this->updateDisplay(); // Trigger a rebin on each movement of the slice point - if (m_rebinMode && !m_rebinLocked) + if (m_rebinMode && ui.btnAutoRebin->isOn()) this->rebinParamsChanged(); } @@ -2066,6 +2110,12 @@ void SliceViewer::disablePeakOverlays() { m_peaksPresenter->clear(); emit showPeaksViewer(false); m_menuPeaks->setEnabled(false); + + QIcon icon; + icon.addFile(QString::fromStdString(g_iconPeakList), + QSize(), QIcon::Normal, QIcon::Off); + ui.btnPeakOverlay->setIcon(icon); + ui.btnPeakOverlay->setChecked(false); } /** @@ -2138,6 +2188,12 @@ SliceViewer::setPeaksWorkspaces(const QStringList &list) { updatePeakOverlaySliderWidget(); emit showPeaksViewer(true); m_menuPeaks->setEnabled(true); + + QIcon icon; + icon.addFile(QString::fromStdString(g_iconPeakList), + QSize(), QIcon::Normal, QIcon::Off); + ui.btnPeakOverlay->setIcon(icon); + ui.btnPeakOverlay->setChecked(true); return m_proxyPeaksPresenter.get(); } @@ -2148,7 +2204,8 @@ Allow user to choose a suitable input peaks workspace */ void SliceViewer::peakOverlay_clicked() { - MantidQt::MantidWidgets::SelectWorkspacesDialog dlg(this, "PeaksWorkspace"); + MantidQt::MantidWidgets::SelectWorkspacesDialog dlg(this, "PeaksWorkspace", "Remove All"); + int ret = dlg.exec(); if (ret == QDialog::Accepted) { QStringList list = dlg.getSelectedNames(); @@ -2157,6 +2214,22 @@ void SliceViewer::peakOverlay_clicked() { setPeaksWorkspaces(list); } } + if (ret == MantidQt::MantidWidgets::SelectWorkspacesDialog::CustomButton) { + disablePeakOverlays(); + } + QIcon icon; + if (m_peaksPresenter->size()>0) { + icon.addFile(QString::fromStdString(g_iconPeakListOn), + QSize(), QIcon::Normal, QIcon::On); + ui.btnPeakOverlay->setIcon(icon); + ui.btnPeakOverlay->setChecked(true); + } else { + + icon.addFile(QString::fromStdString(g_iconPeakList), + QSize(), QIcon::Normal, QIcon::Off); + ui.btnPeakOverlay->setIcon(icon); + ui.btnPeakOverlay->setChecked(false); + } } /** diff --git a/Code/Mantid/Testing/Data/SystemTest/REF_L_123711_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/REF_L_123711_event.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..c24237d9e69ebf0ca43a837927136593955e45c3 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/REF_L_123711_event.nxs.md5 @@ -0,0 +1 @@ +841de4c66d723bdae98bfea7878ca7ca diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/LRPrimaryFractionTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/LRPrimaryFractionTest.py new file mode 100644 index 0000000000000000000000000000000000000000..9506955fc61da05526c78a82d5e3d3bdada24cba --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/LRPrimaryFractionTest.py @@ -0,0 +1,88 @@ +#pylint: disable=no-init +import stresstesting +from mantid import * +from mantid.simpleapi import * + +class LRPrimaryFractionTest(stresstesting.MantidStressTest): + def runTest(self): + workspace = LoadEventNexus(Filename="REF_L_123711") + self.scaling_factor = LRPrimaryFraction(InputWorkspace=workspace) + + def validate(self): + ref = [0.887220655191, 0.00257167461136] + for i in range(2): + if abs(self.scaling_factor[i]-ref[i])>0.00001: + logger.error("Output did not match [%s +- %s]: got [%s +- %s]" % (ref[0], ref[1], + self.scaling_factor[0], + self.scaling_factor[1])) + return False + return True + +class LRPrimaryFractionWithRangeTest(stresstesting.MantidStressTest): + def runTest(self): + workspace = LoadEventNexus(Filename="REF_L_119816") + self.scaling_factor = LRPrimaryFraction(InputWorkspace=workspace, + SignalRange=[120, 190]) + + def validate(self): + ref = [0.970345598555, 0.00524646496021] + for i in range(2): + if abs(self.scaling_factor[i]-ref[i])>0.00001: + logger.error("Output did not match [%s +- %s]: got [%s +- %s]" % (ref[0], ref[1], + self.scaling_factor[0], + self.scaling_factor[1])) + return False + return True + +class ApplyToReducedDataTest(stresstesting.MantidStressTest): + def runTest(self): + #TODO: The reduction algorithm should not require an absolute path + scaling_factor_file = FileFinder.getFullPath("directBeamDatabaseFall2014_IPTS_11601_2.cfg") + + LiquidsReflectometryReduction(RunNumbers=[119816], + NormalizationRunNumber=119692, + SignalPeakPixelRange=[155, 165], + SubtractSignalBackground=True, + SignalBackgroundPixelRange=[146, 165], + NormFlag=True, + NormPeakPixelRange=[154, 162], + NormBackgroundPixelRange=[151, 165], + SubtractNormBackground=True, + LowResDataAxisPixelRangeFlag=True, + LowResDataAxisPixelRange=[99, 158], + LowResNormAxisPixelRangeFlag=True, + LowResNormAxisPixelRange=[118, 137], + TOFRange=[9610, 22425], + IncidentMediumSelected='2InDiamSi', + GeometryCorrectionFlag=False, + QMin=0.005, + QStep=0.01, + AngleOffset=0.009, + AngleOffsetError=0.001, + ScalingFactorFile=scaling_factor_file, + SlitsWidthFlag=True, + CropFirstAndLastPoints=False, + ApplyPrimaryFraction=True, + PrimaryFractionRange=[120,190], + OutputWorkspace='reflectivity_119816') + + ws_fraction = CreateSingleValuedWorkspace(DataValue=0.970345598555, + ErrorValue=0.00524646496021) + Divide(LHSWorkspace='reflectivity_119816', RHSWorkspace=ws_fraction, + OutputWorkspace='reflectivity_119816') + + def validate(self): + # Because we a re-using the reference data from another test, + # the errors won't quite be the same. Increase the tolerance value + # and replace the error on the first and last points by 1.0. + self.tolerance = 0.00001 + data_e = mtd["reflectivity_119816"].dataE(0) + data_e[0] = 1.0 + data_e[len(data_e)-1] = 1.0 + + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "reflectivity_119816", 'LiquidsReflectometryReductionTestWithBackground.nxs' + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/LiquidsReflectometryReductionWithBackgroundTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/LiquidsReflectometryReductionWithBackgroundTest.py index 0d09d62bec2c46703814a59c927399e289099fa5..21d582dc6efe27d9e0801574be9d72b8a8121822 100644 --- a/Code/Mantid/Testing/SystemTests/tests/analysis/LiquidsReflectometryReductionWithBackgroundTest.py +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/LiquidsReflectometryReductionWithBackgroundTest.py @@ -4,6 +4,10 @@ from mantid import * from mantid.simpleapi import * class LiquidsReflectometryReductionWithBackgroundTest(stresstesting.MantidStressTest): + """ + This test checks that the new liquids reflectometer reduction produces + the same results as the old code. It's more tolerant than the test below. + """ def runTest(self): #TODO: The reduction algorithm should not require an absolute path scaling_factor_file = FileFinder.getFullPath("directBeamDatabaseFall2014_IPTS_11601_2.cfg") @@ -47,3 +51,46 @@ class LiquidsReflectometryReductionWithBackgroundTest(stresstesting.MantidStress self.disableChecking.append('Axes') return "reflectivity_119816", 'REFL_119816.nxs' + + +class LiquidsReflectometryReductionWithBackgroundPreciseTest(stresstesting.MantidStressTest): + """ + This test checks that the new liquids reflectometer reduction code + always produces the same results. + """ + def runTest(self): + #TODO: The reduction algorithm should not require an absolute path + scaling_factor_file = FileFinder.getFullPath("directBeamDatabaseFall2014_IPTS_11601_2.cfg") + + LiquidsReflectometryReduction(RunNumbers=[119816], + NormalizationRunNumber=119692, + SignalPeakPixelRange=[155, 165], + SubtractSignalBackground=True, + SignalBackgroundPixelRange=[146, 165], + NormFlag=True, + NormPeakPixelRange=[154, 162], + NormBackgroundPixelRange=[151, 165], + SubtractNormBackground=True, + LowResDataAxisPixelRangeFlag=True, + LowResDataAxisPixelRange=[99, 158], + LowResNormAxisPixelRangeFlag=True, + LowResNormAxisPixelRange=[118, 137], + TOFRange=[9610, 22425], + IncidentMediumSelected='2InDiamSi', + GeometryCorrectionFlag=False, + QMin=0.005, + QStep=0.01, + AngleOffset=0.009, + AngleOffsetError=0.001, + ScalingFactorFile=scaling_factor_file, + SlitsWidthFlag=True, + CropFirstAndLastPoints=False, + OutputWorkspace='reflectivity_precise_119816') + + def validate(self): + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "reflectivity_precise_119816", 'LiquidsReflectometryReductionTestWithBackground.nxs' + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/LoadVesuvioTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/LoadVesuvioTest.py index 43595bda9287eacd32f15acaf47dc450a7f779da..3b7256195fcd9b47d68587637139475a1fb9975b 100644 --- a/Code/Mantid/Testing/SystemTests/tests/analysis/LoadVesuvioTest.py +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/LoadVesuvioTest.py @@ -118,6 +118,8 @@ class VesuvioTests(unittest.TestCase): # Verify self.assertEquals(1, evs_raw.getNumberHistograms()) + self.assertAlmostEqual(5.0, evs_raw.readX(0)[0], places=DIFF_PLACES) + self.assertAlmostEqual(599.5, evs_raw.readX(0)[-1], places=DIFF_PLACES) self.assertAlmostEqual(-1.5288171762918328, evs_raw.readY(0)[0], places=DIFF_PLACES) self.assertAlmostEqual(-0.079412793053402098, evs_raw.readY(0)[-1], places=DIFF_PLACES) self.assertAlmostEqual(0.52109203357613976, evs_raw.readE(0)[0], places=DIFF_PLACES) @@ -125,16 +127,68 @@ class VesuvioTests(unittest.TestCase): def test_sumspectra_with_multiple_groups_gives_number_output_spectra_as_input_groups(self): self._run_load("14188", "135-148;152-165", "SingleDifference","IP0005.dat",sum=True) - evs_raw = mtd[self.ws_name] # Verify self.assertEquals(2, evs_raw.getNumberHistograms()) + self.assertAlmostEqual(5.0, evs_raw.readX(0)[0], places=DIFF_PLACES) + self.assertAlmostEqual(5.0, evs_raw.readX(1)[0], places=DIFF_PLACES) + self.assertAlmostEqual(599.5, evs_raw.readX(0)[-1], places=DIFF_PLACES) + self.assertAlmostEqual(599.5, evs_raw.readX(1)[-1], places=DIFF_PLACES) self.assertAlmostEqual(-0.713877795283, evs_raw.readY(0)[0], places=DIFF_PLACES) self.assertAlmostEqual(-3.00125465604, evs_raw.readY(1)[0], places=DIFF_PLACES) self.assertAlmostEqual(0.6219299465, evs_raw.readE(0)[0], places=DIFF_PLACES) self.assertAlmostEqual(0.676913729914, evs_raw.readE(1)[0], places=DIFF_PLACES) + # Spectrum numbers + self._verify_spectra_numbering(evs_raw.getSpectrum(0), 135, + range(3101,3115)) + self._verify_spectra_numbering(evs_raw.getSpectrum(1), 152, + range(3118,3132)) + + def test_sumspectra_set_to_true_gives_single_spectra_summed_over_all_inputs_with_foil_in(self): + self._run_load("14188", "3-15", "FoilIn", "IP0005.dat", sum=True) + evs_raw = mtd[self.ws_name] + + # Verify + self.assertEquals(1, evs_raw.getNumberHistograms()) + self.assertAlmostEqual(5.0, evs_raw.readX(0)[0], places=DIFF_PLACES) + self.assertAlmostEqual(19990.0, evs_raw.readX(0)[-1], places=DIFF_PLACES) + self.assertAlmostEqual(497722.0, evs_raw.readY(0)[0], places=DIFF_PLACES) + self.assertAlmostEqual(2072.0, evs_raw.readY(0)[-1], places=DIFF_PLACES) + self.assertAlmostEqual(705.49415305869115, evs_raw.readE(0)[0], places=DIFF_PLACES) + self.assertAlmostEqual(45.519226706964169, evs_raw.readE(0)[-1], places=DIFF_PLACES) + + self._verify_spectra_numbering(evs_raw.getSpectrum(0), 3, + range(2101,2114)) + + + def test_sumspectra_with_multiple_groups_gives_number_output_spectra_as_input_groups_with_foil_in(self): + self._run_load("14188", "3-15;30-50", "FoilIn", "IP0005.dat", sum=True) + evs_raw = mtd[self.ws_name] + + # Verify + self.assertEquals(2, evs_raw.getNumberHistograms()) + self.assertAlmostEqual(5.0, evs_raw.readX(0)[0], places=DIFF_PLACES) + self.assertAlmostEqual(5.0, evs_raw.readX(1)[0], places=DIFF_PLACES) + self.assertAlmostEqual(19990.0, evs_raw.readX(0)[-1], places=DIFF_PLACES) + self.assertAlmostEqual(19990.0, evs_raw.readX(1)[-1], places=DIFF_PLACES) + self.assertAlmostEqual(497722.0, evs_raw.readY(0)[0], places=DIFF_PLACES) + self.assertAlmostEqual(1332812.0, evs_raw.readY(1)[0], places=DIFF_PLACES) + self.assertAlmostEqual(705.49415305869115, evs_raw.readE(0)[0], places=DIFF_PLACES) + self.assertAlmostEqual(1154.4747723532116, evs_raw.readE(1)[0], places=DIFF_PLACES) + + self._verify_spectra_numbering(evs_raw.getSpectrum(0), 3, + range(2101,2114)) + self._verify_spectra_numbering(evs_raw.getSpectrum(1), 30, + range(2128,2145) + range(2201,2205)) + + def _verify_spectra_numbering(self, spectrum, expected_no, expected_ids): + self.assertEquals(expected_no, spectrum.getSpectrumNo()) + det_ids = spectrum.getDetectorIDs() + for expected_id, det_id in zip(expected_ids, det_ids): + self.assertEqual(expected_id, det_id) + def _run_load(self, runs, spectra, diff_opt, ip_file="", sum=False): LoadVesuvio(Filename=runs,OutputWorkspace=self.ws_name, SpectrumList=spectra,Mode=diff_opt,InstrumentParFile=ip_file, diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SpaceGroupFactoryTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SpaceGroupFactoryTest.py index d48904649d2680658170e39dd5938f38bd96c62b..65609fce93531b59158f07ae28d26aed94b85a68 100644 --- a/Code/Mantid/Testing/SystemTests/tests/analysis/SpaceGroupFactoryTest.py +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SpaceGroupFactoryTest.py @@ -1,43 +1,47 @@ -#pylint: disable=no-init +# pylint: disable=no-init import stresstesting -import os import re from mantid.simpleapi import * from mantid.geometry import * -'''Check that the space groups generated by Mantid are correct.''' + class SpaceGroupFactoryTest(stresstesting.MantidStressTest): + '''Check that the space groups generated by Mantid are correct.''' + + spaceGroupData = None + def runTest(self): self.spaceGroupData = self.loadReferenceData() - availableSpaceGroups = SpaceGroupFactoryImpl.Instance().allSubscribedSpaceGroupSymbols() + availableSpaceGroups = SpaceGroupFactory.getAllSpaceGroupSymbols() for symbol in availableSpaceGroups: self.checkSpaceGroup(symbol) def checkSpaceGroup(self, symbol): - group = SpaceGroupFactoryImpl.Instance().createSpaceGroup(symbol) + group = SpaceGroupFactory.createSpaceGroup(symbol) groupOperations = set(group.getSymmetryOperationStrings()) - referenceOperations = self.spaceGroupData[group.number()] + referenceOperations = self.spaceGroupData[group.getNumber()] differenceOne = groupOperations - referenceOperations differenceTwo = referenceOperations - groupOperations - self.assertTrue(len(differenceOne) == 0, "Problem in space group " + str(group.number()) + " (" + symbol + ")") - self.assertTrue(len(differenceTwo) == 0, "Problem in space group " + str(group.number()) + " (" + symbol + ")") - self.assertTrue(groupOperations == referenceOperations, "Problem in space group " + str(group.number()) + " (" + symbol + ")") + self.assertTrue(len(differenceOne) == 0, + "Problem in space group " + str(group.getNumber()) + " (" + symbol + ")") + self.assertTrue(len(differenceTwo) == 0, + "Problem in space group " + str(group.getNumber()) + " (" + symbol + ")") + self.assertTrue(groupOperations == referenceOperations, + "Problem in space group " + str(group.getNumber()) + " (" + symbol + ")") def loadReferenceData(self): from mantid.api import FileFinder - # Reference data. - # Dictionary has a string set for each space group number. - separatorMatcher = re.compile("(\d+)") + # Reference data. + # Dictionary has a string set for each space group number. + separatorMatcher = re.compile(r"(\d+)") fileName = FileFinder.Instance().getFullPath('SpaceGroupSymmetryOperations.txt') - print fileName - fileHandle = open(fileName, 'r') spaceGroups = {} currentGroup = 0 @@ -48,7 +52,8 @@ class SpaceGroupFactoryTest(stresstesting.MantidStressTest): currentGroup = int(matchedSeparator.group(1)) spaceGroups[currentGroup] = set() else: - spaceGroups[currentGroup].add(SymmetryOperationFactoryImpl.Instance().createSymOp(currentLine.strip().replace(" ", "")).identifier()) + spaceGroups[currentGroup].add( + SymmetryOperationFactory.createSymOp(currentLine.strip().replace(" ", "")).getIdentifier()) return spaceGroups diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LiquidsReflectometryReductionTestWithBackground.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LiquidsReflectometryReductionTestWithBackground.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..940997695321557922c5ad265728675c64dcd8a2 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LiquidsReflectometryReductionTestWithBackground.nxs.md5 @@ -0,0 +1 @@ +791a2b2fe751b8af599a5b97aa2ce3a4 diff --git a/Code/Mantid/docs/source/algorithms/LRPrimaryFraction-v1.rst b/Code/Mantid/docs/source/algorithms/LRPrimaryFraction-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..476f57cd51e1b21b51114827f3c69681763a5cb7 --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/LRPrimaryFraction-v1.rst @@ -0,0 +1,17 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Used in the Liquids Reflectometer reduction at the SNS, this algorithm +computes the primary fraction (aka 'clocking correction') for the given data. +The primary fraction is the fraction of the counts within a specified range +that should contain the reflected beam to the total number of counts on the detector. + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/LiquidsRelectometryReduction-v1.rst b/Code/Mantid/docs/source/algorithms/LiquidsRelectometryReduction-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..7403666008f6d574a716136f23c5baab824b273d --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/LiquidsRelectometryReduction-v1.rst @@ -0,0 +1,39 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +The workflow proceeds as follows: + +1. Load the data to be reduced. + +2. Crop to the specified TOF range. + +3. Subtract the background and integrate over the low-resolution axis. + +4. Normalize by the integrated current. + +5. Crop to the reflectivity peak using the specified range. + +6. Repeat steps 1 to 6 for the direct beam normalization run. + +7. Sum up the pixels contained in the peak of the normalization run to + obtain a TOF distribution. + +8. Divide the TOF distribution of each signal pixel by the normalization distribution. + +9. Apply the scaling factor. + +10. Sum up the pixels within the reflectivity peak of the data. + +11. Convert to Q. + +12. Rebin the Q axis to the specified binning and crop out the first and last Q point. + +.. categories:: diff --git a/Code/Mantid/docs/source/concepts/PointGroups.rst b/Code/Mantid/docs/source/concepts/PointGroups.rst index 65a6c9540f93e3ae3b9d7921620a24832d972c1d..6904bc58deef63c146bd075771539316cce8d323 100644 --- a/Code/Mantid/docs/source/concepts/PointGroups.rst +++ b/Code/Mantid/docs/source/concepts/PointGroups.rst @@ -47,7 +47,7 @@ To describe the rotational and translational components of the symmetry operatio Note that the translational component is not used for transforming HKLs and :math:`\mathbf{W}_i` is inverted and transposed. Coordinates :math:`\mathbf{x}` are transformed differently, they are affected by the translational component: .. math:: - \mathbf{x}' = \mathbf{W}_i \cdot \mathbf{h} + \mathbf{w}_i + \mathbf{x}' = \mathbf{W}_i \cdot \mathbf{x} + \mathbf{w}_i A point group is an ensemble of symmetry operations. The number of operations present in this collection is the so called order :math:`N` of the corresponding point group. Applying all symmetry operations of a point group to a given vector :math:`\mathbf{h}` results in :math:`N` new vectors :math:`\mathbf{h}'`, some of which may be identical (this depends on the symmetry and also on the vectors, e.g. if one or more index is 0). This means that the symmetry operations of a point group generate a set of :math:`N'` (where :math:`N' < N`) non-identical vectors :math:`\mathbf{h}'` for a given vector :math:`\mathbf{h}` - these vectors are called symmetry equivalents. @@ -108,7 +108,9 @@ The script prints the transformed coordinates: .. testoutput :: ExSymmetryOperationPoint Transformed coordinates: [-0.1,0.3,0.5] - + +Please note that in case of hexagonal or trigonal point groups, it is best to provide the often occuring values 1/3 and 2/3 actually as ``1./3.`` instead of ``0.33333``, as there may be problems with floating point precision in those cases. + Sometimes it is easier to think about symmetry in terms of the elements that cause certain symmetry. These are commonly described with Herrman-Mauguin symbols. A symmetry element can be derived from the matrix/vector pair that described the symmetry operation, according to the International Tables for Crystallography A, section 11.2. Expanding a bit on the above example, it's possible to get information about the symmetry element associated to the operation ``x,y,-z``: .. testcode :: ExSymmetryElement @@ -119,7 +121,7 @@ Sometimes it is easier to think about symmetry in terms of the elements that cau symOp = SymmetryOperationFactory.createSymOp("x,y,-z") element = SymmetryElementFactory.createSymElement(symOp) - print "The element corresponding to 'x,y,-z' has the following symbol:", element.hmSymbol() + print "The element corresponding to 'x,y,-z' has the following symbol:", element.getHMSymbol() print "The mirror plane is perpendicular to:", element.getAxis() Executing this code yields the following output: @@ -145,8 +147,8 @@ Point groups are represented in Mantid by the ``PointGroup``-interface, which is pg = PointGroupFactory.createPointGroup("-1") print "Name:", pg.getName() - print "Hermann-Mauguin symbol:", pg.getSymbol() - print "Crystal system:", pg.crystalSystem() + print "Hermann-Mauguin symbol:", pg.getHMSymbol() + print "Crystal system:", pg.getCrystalSystem() When this code is executed, some information about the point group is printed: @@ -170,11 +172,11 @@ Which results in the following output: .. testoutput :: ExQueryPointGroups - All point groups: ['-1','-3','-3 r','-31m','-3m r','-3m1','-4','-42m','-43m','-4m2','-6','-62m','-6m2','1','112/m','2','2/m','222','23','3','3 r','312','31m','32 r','321','3m r','3m1','4','4/m','4/mmm','422','432','4mm','6','6/m','6/mmm','622','6mm','m','m-3','m-3m','mm2','mmm'] + All point groups: ['-1','-3','-3 r','-31m','-3m','-3m r','-3m1','-4','-42m','-43m','-4m2','-6','-62m','-6m2','1','112/m','2','2/m','222','23','3','3 r','312','31m','32','32 r','321','3m','3m r','3m1','4','4/m','4/mmm','422','432','4mm','6','6/m','6/mmm','622','6mm','m','m-3','m-3m','mm2','mmm'] Cubic point groups: ['-43m','23','432','m-3','m-3m'] Tetragonal point groups: ['-4','-42m','-4m2','4','4/m','4/mmm','422','4mm'] -The point groups with an extra ``r`` at the end are trigonal point groups with rhombohedral axes. Trigonal point groups without that additional letter use the hexagonal coordinate system. +The point groups with an extra ``r`` at the end are trigonal point groups with rhombohedral axes. Trigonal point groups without that additional letter use the hexagonal coordinate system. For some of them there are two different axis choices, for example :math:`\bar{3}m`, which can be defined as :math:`\bar{3}m1` or :math:`\bar{3}1m`. Creating it by the symbol ``-3m`` defaults to :math:`\bar{3}m1`. After having obtained a ``PointGroup``-object, it can be used for working with reflection data, more specifically :math:`hkl`-indices. It's possible to check whether two reflections are equivalent in a certain point group: diff --git a/Code/Mantid/docs/source/interfaces/Indirect_DataAnalysis.rst b/Code/Mantid/docs/source/interfaces/Indirect_DataAnalysis.rst index 6d631430172bd5b320a3a9c83df6b9beb72ae286..a623e531775b760cd13cb86e69d7373f294a0950 100644 --- a/Code/Mantid/docs/source/interfaces/Indirect_DataAnalysis.rst +++ b/Code/Mantid/docs/source/interfaces/Indirect_DataAnalysis.rst @@ -134,11 +134,11 @@ Save Result If enabled the result will be saved as a NeXus file in the default save directory. -Fury ----- +I(Q, t) +------- .. interface:: Data Analysis - :widget: tabFury + :widget: tabIqt Given sample and resolution inputs, carries out a fit as per the theory detailed in the :ref:`TransformToIqt <algm-TransformToIqt>` algorithm. @@ -188,13 +188,13 @@ ResolutionBins Number of bins in the resolution after rebinning, typically this should be at least 5 and a warning will be shown if it is less. -Fury Fit --------- +I(Q, t) Fit +----------- .. interface:: Data Analysis - :widget: tabFuryFit + :widget: tabIqtFit -FuryFit provides a simplified interface for controlling various fitting +I(Q, t) Fit provides a simplified interface for controlling various fitting functions (see the :ref:`Fit <algm-Fit>` algorithm for more info). The functions are also available via the fit wizard. diff --git a/Code/Mantid/instrument/VISION_Definition_20131021-.xml b/Code/Mantid/instrument/VISION_Definition_20131021-.xml index f858e03089e414fb91e73d8bc5886dae6345e9c0..3b148bb7929d4cda0d51547fffee4c49d561bd44 100644 --- a/Code/Mantid/instrument/VISION_Definition_20131021-.xml +++ b/Code/Mantid/instrument/VISION_Definition_20131021-.xml @@ -20,10 +20,10 @@ </component> <type is="Source" name="moderator"/> <component type="sample-position"> - <location y="0.0" x="0.0" z="0.0"/> + <location x="0.0" y="0.0" z="0.0"/> </component> <type is="SamplePos" name="sample-position"/> - <component type="elastic-backscattering" idlist="elastic-backscattering"> + <component idlist="elastic-backscattering" type="elastic-backscattering"> <location/> </component> <type name="elastic-backscattering"> @@ -270,10 +270,10 @@ </type> <type name="bank15-tube1"> <component type="tube-long-bs-elastic"> - <location y="0.329945427767" x="-0.0129635911636" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="2.25"/> + <location x="-0.0129635911636" y="0.329945427767" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="2.25"/> </rot> </rot> </location> @@ -281,10 +281,10 @@ </type> <type name="bank15-tube2"> <component type="tube-short-bs-elastic"> - <location y="0.365747112696" x="-0.0432890234837" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="6.75"/> + <location x="-0.0432890234837" y="0.365747112696" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="6.75"/> </rot> </rot> </location> @@ -292,10 +292,10 @@ </type> <type name="bank15-tube3"> <component type="tube-long-bs-elastic"> - <location y="0.323855299589" x="-0.0644188243297" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="11.25"/> + <location x="-0.0644188243297" y="0.323855299589" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="11.25"/> </rot> </rot> </location> @@ -303,10 +303,10 @@ </type> <type name="bank15-tube4"> <component type="tube-short-bs-elastic"> - <location y="0.354472263586" x="-0.0999715176853" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="15.75"/> + <location x="-0.0999715176853" y="0.354472263586" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="15.75"/> </rot> </rot> </location> @@ -314,10 +314,10 @@ </type> <type name="bank15-tube5"> <component type="tube-long-bs-elastic"> - <location y="0.309790779122" x="-0.114287852247" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="20.25"/> + <location x="-0.114287852247" y="0.309790779122" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="20.25"/> </rot> </rot> </location> @@ -325,10 +325,10 @@ </type> <type name="bank15-tube6"> <component type="tube-short-bs-elastic"> - <location y="0.33446913092" x="-0.154192381335" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="24.75"/> + <location x="-0.154192381335" y="0.33446913092" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="24.75"/> </rot> </rot> </location> @@ -336,10 +336,10 @@ </type> <type name="bank15-tube7"> <component type="tube-long-bs-elastic"> - <location y="0.288098181535" x="-0.161342733942" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="29.25"/> + <location x="-0.161342733942" y="0.288098181535" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="29.25"/> </rot> </rot> </location> @@ -347,10 +347,10 @@ </type> <type name="bank15-tube8"> <component type="tube-short-bs-elastic"> - <location y="0.306230258211" x="-0.204616516821" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="33.75"/> + <location x="-0.204616516821" y="0.306230258211" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="33.75"/> </rot> </rot> </location> @@ -358,10 +358,10 @@ </type> <type name="bank16-tube9"> <component type="tube-long-bs-elastic"> - <location y="0.259311650577" x="-0.204424822062" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="38.25"/> + <location x="-0.204424822062" y="0.259311650577" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="38.25"/> </rot> </rot> </location> @@ -369,10 +369,10 @@ </type> <type name="bank16-tube10"> <component type="tube-short-bs-elastic"> - <location y="0.270450980225" x="-0.25000231458" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="42.75"/> + <location x="-0.25000231458" y="0.270450980225" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="42.75"/> </rot> </rot> </location> @@ -380,10 +380,10 @@ </type> <type name="bank16-tube11"> <component type="tube-long-bs-elastic"> - <location y="0.224140006175" x="-0.242473292616" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="47.25"/> + <location x="-0.242473292616" y="0.224140006175" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="47.25"/> </rot> </rot> </location> @@ -391,10 +391,10 @@ </type> <type name="bank16-tube12"> <component type="tube-short-bs-elastic"> - <location y="0.228012301531" x="-0.289232225643" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="51.75"/> + <location x="-0.289232225643" y="0.228012301531" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="51.75"/> </rot> </rot> </location> @@ -402,10 +402,10 @@ </type> <type name="bank16-tube13"> <component type="tube-long-bs-elastic"> - <location y="0.183449290943" x="-0.274551265982" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="56.25"/> + <location x="-0.274551265982" y="0.183449290943" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="56.25"/> </rot> </rot> </location> @@ -413,10 +413,10 @@ </type> <type name="bank16-tube14"> <component type="tube-short-bs-elastic"> - <location y="0.179959203243" x="-0.321340279405" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="60.75"/> + <location x="-0.321340279405" y="0.179959203243" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="60.75"/> </rot> </rot> </location> @@ -424,10 +424,10 @@ </type> <type name="bank16-tube15"> <component type="tube-long-bs-elastic"> - <location y="0.138241445335" x="-0.299868875997" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="65.25"/> + <location x="-0.299868875997" y="0.138241445335" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="65.25"/> </rot> </rot> </location> @@ -435,10 +435,10 @@ </type> <type name="bank16-tube16"> <component type="tube-short-bs-elastic"> - <location y="0.127474912122" x="-0.34553586902" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="69.75"/> + <location x="-0.34553586902" y="0.127474912122" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="69.75"/> </rot> </rot> </location> @@ -446,10 +446,10 @@ </type> <type name="bank17-tube17"> <component type="tube-long-bs-elastic"> - <location y="0.0896296365454" x="-0.317802719077" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="74.25"/> + <location x="-0.317802719077" y="0.0896296365454" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="74.25"/> </rot> </rot> </location> @@ -457,10 +457,10 @@ </type> <type name="bank17-tube18"> <component type="tube-short-bs-elastic"> - <location y="0.0718517655985" x="-0.361223218773" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="78.75"/> + <location x="-0.361223218773" y="0.0718517655985" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="78.75"/> </rot> </rot> </location> @@ -468,10 +468,10 @@ </type> <type name="bank17-tube19"> <component type="tube-long-bs-elastic"> - <location y="0.0388108486406" x="-0.327911204487" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="83.25"/> + <location x="-0.327911204487" y="0.0388108486406" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="83.25"/> </rot> </rot> </location> @@ -479,10 +479,10 @@ </type> <type name="bank17-tube20"> <component type="tube-short-bs-elastic"> - <location y="0.0144593901441" x="-0.368016054047" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="87.75"/> + <location x="-0.368016054047" y="0.0144593901441" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="87.75"/> </rot> </rot> </location> @@ -490,10 +490,10 @@ </type> <type name="bank17-tube21"> <component type="tube-long-bs-elastic"> - <location y="-0.0129635911636" x="-0.329945427767" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="92.25"/> + <location x="-0.329945427767" y="-0.0129635911636" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="92.25"/> </rot> </rot> </location> @@ -501,10 +501,10 @@ </type> <type name="bank17-tube22"> <component type="tube-short-bs-elastic"> - <location y="-0.0432890234837" x="-0.365747112696" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="96.75"/> + <location x="-0.365747112696" y="-0.0432890234837" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="96.75"/> </rot> </rot> </location> @@ -512,10 +512,10 @@ </type> <type name="bank17-tube23"> <component type="tube-long-bs-elastic"> - <location y="-0.0644188243297" x="-0.323855299589" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="101.25"/> + <location x="-0.323855299589" y="-0.0644188243297" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="101.25"/> </rot> </rot> </location> @@ -523,10 +523,10 @@ </type> <type name="bank17-tube24"> <component type="tube-short-bs-elastic"> - <location y="-0.0999715176853" x="-0.354472263586" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="105.75"/> + <location x="-0.354472263586" y="-0.0999715176853" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="105.75"/> </rot> </rot> </location> @@ -534,10 +534,10 @@ </type> <type name="bank18-tube25"> <component type="tube-long-bs-elastic"> - <location y="-0.114287852247" x="-0.309790779122" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="110.25"/> + <location x="-0.309790779122" y="-0.114287852247" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="110.25"/> </rot> </rot> </location> @@ -545,10 +545,10 @@ </type> <type name="bank18-tube26"> <component type="tube-short-bs-elastic"> - <location y="-0.154192381335" x="-0.33446913092" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="114.75"/> + <location x="-0.33446913092" y="-0.154192381335" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="114.75"/> </rot> </rot> </location> @@ -556,10 +556,10 @@ </type> <type name="bank18-tube27"> <component type="tube-long-bs-elastic"> - <location y="-0.161342733942" x="-0.288098181535" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="119.25"/> + <location x="-0.288098181535" y="-0.161342733942" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="119.25"/> </rot> </rot> </location> @@ -567,10 +567,10 @@ </type> <type name="bank18-tube28"> <component type="tube-short-bs-elastic"> - <location y="-0.204616516821" x="-0.306230258211" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="123.75"/> + <location x="-0.306230258211" y="-0.204616516821" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="123.75"/> </rot> </rot> </location> @@ -578,10 +578,10 @@ </type> <type name="bank18-tube29"> <component type="tube-long-bs-elastic"> - <location y="-0.204424822062" x="-0.259311650577" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="128.25"/> + <location x="-0.259311650577" y="-0.204424822062" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="128.25"/> </rot> </rot> </location> @@ -589,10 +589,10 @@ </type> <type name="bank18-tube30"> <component type="tube-short-bs-elastic"> - <location y="-0.25000231458" x="-0.270450980225" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="132.75"/> + <location x="-0.270450980225" y="-0.25000231458" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="132.75"/> </rot> </rot> </location> @@ -600,10 +600,10 @@ </type> <type name="bank18-tube31"> <component type="tube-long-bs-elastic"> - <location y="-0.242473292616" x="-0.224140006175" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="137.25"/> + <location x="-0.224140006175" y="-0.242473292616" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="137.25"/> </rot> </rot> </location> @@ -611,10 +611,10 @@ </type> <type name="bank18-tube32"> <component type="tube-short-bs-elastic"> - <location y="-0.289232225643" x="-0.228012301531" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="141.75"/> + <location x="-0.228012301531" y="-0.289232225643" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="141.75"/> </rot> </rot> </location> @@ -622,10 +622,10 @@ </type> <type name="bank19-tube33"> <component type="tube-long-bs-elastic"> - <location y="-0.274551265982" x="-0.183449290943" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="146.25"/> + <location x="-0.183449290943" y="-0.274551265982" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="146.25"/> </rot> </rot> </location> @@ -633,10 +633,10 @@ </type> <type name="bank19-tube34"> <component type="tube-short-bs-elastic"> - <location y="-0.321340279405" x="-0.179959203243" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="150.75"/> + <location x="-0.179959203243" y="-0.321340279405" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="150.75"/> </rot> </rot> </location> @@ -644,10 +644,10 @@ </type> <type name="bank19-tube35"> <component type="tube-long-bs-elastic"> - <location y="-0.299868875997" x="-0.138241445335" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="155.25"/> + <location x="-0.138241445335" y="-0.299868875997" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="155.25"/> </rot> </rot> </location> @@ -655,10 +655,10 @@ </type> <type name="bank19-tube36"> <component type="tube-short-bs-elastic"> - <location y="-0.34553586902" x="-0.127474912122" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="159.75"/> + <location x="-0.127474912122" y="-0.34553586902" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="159.75"/> </rot> </rot> </location> @@ -666,10 +666,10 @@ </type> <type name="bank19-tube37"> <component type="tube-long-bs-elastic"> - <location y="-0.317802719077" x="-0.0896296365454" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="164.25"/> + <location x="-0.0896296365454" y="-0.317802719077" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="164.25"/> </rot> </rot> </location> @@ -677,10 +677,10 @@ </type> <type name="bank19-tube38"> <component type="tube-short-bs-elastic"> - <location y="-0.361223218773" x="-0.0718517655985" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="168.75"/> + <location x="-0.0718517655985" y="-0.361223218773" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="168.75"/> </rot> </rot> </location> @@ -688,10 +688,10 @@ </type> <type name="bank19-tube39"> <component type="tube-long-bs-elastic"> - <location y="-0.327911204487" x="-0.0388108486406" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="173.25"/> + <location x="-0.0388108486406" y="-0.327911204487" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="173.25"/> </rot> </rot> </location> @@ -699,10 +699,10 @@ </type> <type name="bank19-tube40"> <component type="tube-short-bs-elastic"> - <location y="-0.368016054047" x="-0.0144593901441" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="177.75"/> + <location x="-0.0144593901441" y="-0.368016054047" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="177.75"/> </rot> </rot> </location> @@ -710,10 +710,10 @@ </type> <type name="bank20-tube41"> <component type="tube-long-bs-elastic"> - <location y="-0.329945427767" x="0.0129635911636" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="182.25"/> + <location x="0.0129635911636" y="-0.329945427767" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="182.25"/> </rot> </rot> </location> @@ -721,10 +721,10 @@ </type> <type name="bank20-tube42"> <component type="tube-short-bs-elastic"> - <location y="-0.365747112696" x="0.0432890234837" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="186.75"/> + <location x="0.0432890234837" y="-0.365747112696" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="186.75"/> </rot> </rot> </location> @@ -732,10 +732,10 @@ </type> <type name="bank20-tube43"> <component type="tube-long-bs-elastic"> - <location y="-0.323855299589" x="0.0644188243297" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="191.25"/> + <location x="0.0644188243297" y="-0.323855299589" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="191.25"/> </rot> </rot> </location> @@ -743,10 +743,10 @@ </type> <type name="bank20-tube44"> <component type="tube-short-bs-elastic"> - <location y="-0.354472263586" x="0.0999715176853" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="195.75"/> + <location x="0.0999715176853" y="-0.354472263586" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="195.75"/> </rot> </rot> </location> @@ -754,10 +754,10 @@ </type> <type name="bank20-tube45"> <component type="tube-long-bs-elastic"> - <location y="-0.309790779122" x="0.114287852247" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="200.25"/> + <location x="0.114287852247" y="-0.309790779122" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="200.25"/> </rot> </rot> </location> @@ -765,10 +765,10 @@ </type> <type name="bank20-tube46"> <component type="tube-short-bs-elastic"> - <location y="-0.33446913092" x="0.154192381335" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="204.75"/> + <location x="0.154192381335" y="-0.33446913092" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="204.75"/> </rot> </rot> </location> @@ -776,10 +776,10 @@ </type> <type name="bank20-tube47"> <component type="tube-long-bs-elastic"> - <location y="-0.288098181535" x="0.161342733942" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="209.25"/> + <location x="0.161342733942" y="-0.288098181535" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="209.25"/> </rot> </rot> </location> @@ -787,10 +787,10 @@ </type> <type name="bank20-tube48"> <component type="tube-short-bs-elastic"> - <location y="-0.306230258211" x="0.204616516821" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="213.75"/> + <location x="0.204616516821" y="-0.306230258211" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="213.75"/> </rot> </rot> </location> @@ -798,10 +798,10 @@ </type> <type name="bank21-tube49"> <component type="tube-long-bs-elastic"> - <location y="-0.259311650577" x="0.204424822062" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="218.25"/> + <location x="0.204424822062" y="-0.259311650577" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="218.25"/> </rot> </rot> </location> @@ -809,10 +809,10 @@ </type> <type name="bank21-tube50"> <component type="tube-short-bs-elastic"> - <location y="-0.270450980225" x="0.25000231458" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="222.75"/> + <location x="0.25000231458" y="-0.270450980225" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="222.75"/> </rot> </rot> </location> @@ -820,10 +820,10 @@ </type> <type name="bank21-tube51"> <component type="tube-long-bs-elastic"> - <location y="-0.224140006175" x="0.242473292616" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="227.25"/> + <location x="0.242473292616" y="-0.224140006175" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="227.25"/> </rot> </rot> </location> @@ -831,10 +831,10 @@ </type> <type name="bank21-tube52"> <component type="tube-short-bs-elastic"> - <location y="-0.228012301531" x="0.289232225643" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="231.75"/> + <location x="0.289232225643" y="-0.228012301531" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="231.75"/> </rot> </rot> </location> @@ -842,10 +842,10 @@ </type> <type name="bank21-tube53"> <component type="tube-long-bs-elastic"> - <location y="-0.183449290943" x="0.274551265982" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="236.25"/> + <location x="0.274551265982" y="-0.183449290943" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="236.25"/> </rot> </rot> </location> @@ -853,10 +853,10 @@ </type> <type name="bank21-tube54"> <component type="tube-short-bs-elastic"> - <location y="-0.179959203243" x="0.321340279405" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="240.75"/> + <location x="0.321340279405" y="-0.179959203243" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="240.75"/> </rot> </rot> </location> @@ -864,10 +864,10 @@ </type> <type name="bank21-tube55"> <component type="tube-long-bs-elastic"> - <location y="-0.138241445335" x="0.299868875997" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="245.25"/> + <location x="0.299868875997" y="-0.138241445335" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="245.25"/> </rot> </rot> </location> @@ -875,10 +875,10 @@ </type> <type name="bank21-tube56"> <component type="tube-short-bs-elastic"> - <location y="-0.127474912122" x="0.34553586902" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="249.75"/> + <location x="0.34553586902" y="-0.127474912122" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="249.75"/> </rot> </rot> </location> @@ -886,10 +886,10 @@ </type> <type name="bank22-tube57"> <component type="tube-long-bs-elastic"> - <location y="-0.0896296365454" x="0.317802719077" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="254.25"/> + <location x="0.317802719077" y="-0.0896296365454" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="254.25"/> </rot> </rot> </location> @@ -897,10 +897,10 @@ </type> <type name="bank22-tube58"> <component type="tube-short-bs-elastic"> - <location y="-0.0718517655985" x="0.361223218773" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="258.75"/> + <location x="0.361223218773" y="-0.0718517655985" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="258.75"/> </rot> </rot> </location> @@ -908,10 +908,10 @@ </type> <type name="bank22-tube59"> <component type="tube-long-bs-elastic"> - <location y="-0.0388108486406" x="0.327911204487" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="263.25"/> + <location x="0.327911204487" y="-0.0388108486406" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="263.25"/> </rot> </rot> </location> @@ -919,10 +919,10 @@ </type> <type name="bank22-tube60"> <component type="tube-short-bs-elastic"> - <location y="-0.0144593901441" x="0.368016054047" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="267.75"/> + <location x="0.368016054047" y="-0.0144593901441" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="267.75"/> </rot> </rot> </location> @@ -930,10 +930,10 @@ </type> <type name="bank22-tube61"> <component type="tube-long-bs-elastic"> - <location y="0.0129635911636" x="0.329945427767" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="272.25"/> + <location x="0.329945427767" y="0.0129635911636" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="272.25"/> </rot> </rot> </location> @@ -941,10 +941,10 @@ </type> <type name="bank22-tube62"> <component type="tube-short-bs-elastic"> - <location y="0.0432890234837" x="0.365747112696" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="276.75"/> + <location x="0.365747112696" y="0.0432890234837" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="276.75"/> </rot> </rot> </location> @@ -952,10 +952,10 @@ </type> <type name="bank22-tube63"> <component type="tube-long-bs-elastic"> - <location y="0.0644188243297" x="0.323855299589" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="281.25"/> + <location x="0.323855299589" y="0.0644188243297" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="281.25"/> </rot> </rot> </location> @@ -963,10 +963,10 @@ </type> <type name="bank22-tube64"> <component type="tube-short-bs-elastic"> - <location y="0.0999715176853" x="0.354472263586" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="285.75"/> + <location x="0.354472263586" y="0.0999715176853" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="285.75"/> </rot> </rot> </location> @@ -974,10 +974,10 @@ </type> <type name="bank23-tube65"> <component type="tube-long-bs-elastic"> - <location y="0.114287852247" x="0.309790779122" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="290.25"/> + <location x="0.309790779122" y="0.114287852247" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="290.25"/> </rot> </rot> </location> @@ -985,10 +985,10 @@ </type> <type name="bank23-tube66"> <component type="tube-short-bs-elastic"> - <location y="0.154192381335" x="0.33446913092" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="294.75"/> + <location x="0.33446913092" y="0.154192381335" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="294.75"/> </rot> </rot> </location> @@ -996,10 +996,10 @@ </type> <type name="bank23-tube67"> <component type="tube-long-bs-elastic"> - <location y="0.161342733942" x="0.288098181535" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="299.25"/> + <location x="0.288098181535" y="0.161342733942" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="299.25"/> </rot> </rot> </location> @@ -1007,10 +1007,10 @@ </type> <type name="bank23-tube68"> <component type="tube-short-bs-elastic"> - <location y="0.204616516821" x="0.306230258211" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="303.75"/> + <location x="0.306230258211" y="0.204616516821" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="303.75"/> </rot> </rot> </location> @@ -1018,10 +1018,10 @@ </type> <type name="bank23-tube69"> <component type="tube-long-bs-elastic"> - <location y="0.204424822062" x="0.259311650577" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="308.25"/> + <location x="0.259311650577" y="0.204424822062" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="308.25"/> </rot> </rot> </location> @@ -1029,10 +1029,10 @@ </type> <type name="bank23-tube70"> <component type="tube-short-bs-elastic"> - <location y="0.25000231458" x="0.270450980225" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="312.75"/> + <location x="0.270450980225" y="0.25000231458" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="312.75"/> </rot> </rot> </location> @@ -1040,10 +1040,10 @@ </type> <type name="bank23-tube71"> <component type="tube-long-bs-elastic"> - <location y="0.242473292616" x="0.224140006175" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="317.25"/> + <location x="0.224140006175" y="0.242473292616" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="317.25"/> </rot> </rot> </location> @@ -1051,10 +1051,10 @@ </type> <type name="bank23-tube72"> <component type="tube-short-bs-elastic"> - <location y="0.289232225643" x="0.228012301531" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="321.75"/> + <location x="0.228012301531" y="0.289232225643" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="321.75"/> </rot> </rot> </location> @@ -1062,10 +1062,10 @@ </type> <type name="bank24-tube73"> <component type="tube-long-bs-elastic"> - <location y="0.274551265982" x="0.183449290943" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="326.25"/> + <location x="0.183449290943" y="0.274551265982" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="326.25"/> </rot> </rot> </location> @@ -1073,10 +1073,10 @@ </type> <type name="bank24-tube74"> <component type="tube-short-bs-elastic"> - <location y="0.321340279405" x="0.179959203243" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="330.75"/> + <location x="0.179959203243" y="0.321340279405" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="330.75"/> </rot> </rot> </location> @@ -1084,10 +1084,10 @@ </type> <type name="bank24-tube75"> <component type="tube-long-bs-elastic"> - <location y="0.299868875997" x="0.138241445335" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="335.25"/> + <location x="0.138241445335" y="0.299868875997" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="335.25"/> </rot> </rot> </location> @@ -1095,10 +1095,10 @@ </type> <type name="bank24-tube76"> <component type="tube-short-bs-elastic"> - <location y="0.34553586902" x="0.127474912122" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="339.75"/> + <location x="0.127474912122" y="0.34553586902" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="339.75"/> </rot> </rot> </location> @@ -1106,10 +1106,10 @@ </type> <type name="bank24-tube77"> <component type="tube-long-bs-elastic"> - <location y="0.317802719077" x="0.0896296365454" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="344.25"/> + <location x="0.0896296365454" y="0.317802719077" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="344.25"/> </rot> </rot> </location> @@ -1117,10 +1117,10 @@ </type> <type name="bank24-tube78"> <component type="tube-short-bs-elastic"> - <location y="0.361223218773" x="0.0718517655985" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="348.75"/> + <location x="0.0718517655985" y="0.361223218773" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="348.75"/> </rot> </rot> </location> @@ -1128,10 +1128,10 @@ </type> <type name="bank24-tube79"> <component type="tube-long-bs-elastic"> - <location y="0.327911204487" x="0.0388108486406" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="353.25"/> + <location x="0.0388108486406" y="0.327911204487" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="353.25"/> </rot> </rot> </location> @@ -1139,28 +1139,28 @@ </type> <type name="bank24-tube80"> <component type="tube-short-bs-elastic"> - <location y="0.368016054047" x="0.0144593901441" z="-0.998"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="357.75"/> + <location x="0.0144593901441" y="0.368016054047" z="-0.998"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="357.75"/> </rot> </rot> </location> </component> </type> <idlist idname="elastic-backscattering"> - <id start="14336" end="16383"/> - <id start="16384" end="18431"/> - <id start="18432" end="20479"/> - <id start="20480" end="22527"/> - <id start="22528" end="24575"/> - <id start="24576" end="26623"/> - <id start="26624" end="28671"/> - <id start="28672" end="30719"/> - <id start="30720" end="32767"/> - <id start="32768" end="34815"/> + <id end="16383" start="14336"/> + <id end="18431" start="16384"/> + <id end="20479" start="18432"/> + <id end="22527" start="20480"/> + <id end="24575" start="22528"/> + <id end="26623" start="24576"/> + <id end="28671" start="26624"/> + <id end="30719" start="28672"/> + <id end="32767" start="30720"/> + <id end="34815" start="32768"/> </idlist> - <component type="elastic" idlist="elastic"> + <component idlist="elastic" type="elastic"> <location/> </component> <type name="elastic"> @@ -1185,85 +1185,85 @@ </type> <type name="bank25"> <component type="eightpack-elastic"> - <location y="0.243003979552" x="-0.586663503145" z="0.0"> - <rot axis-z="0" axis-x="0" axis-y="1" val="180"> - <rot axis-z="0" axis-x="1" axis-y="0" val="-90.0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="0.0"/> + <location x="-0.586663503145" y="0.243003979552" z="0.0"> + <rot axis-x="0" axis-y="1" axis-z="0" val="180"> + <rot axis-x="1" axis-y="0" axis-z="0" val="-90.0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="0.0"/> </rot> </rot> - <facing y="0.0" x="0.0" z="0.0"/> + <facing x="0.0" y="0.0" z="0.0"/> </location> </component> </type> <type name="bank26"> <component type="eightpack-elastic"> - <location y="-0.243003979552" x="-0.586663503145" z="0.0"> - <rot axis-z="0" axis-x="0" axis-y="1" val="180"> - <rot axis-z="0" axis-x="1" axis-y="0" val="-90.0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="0.0"/> + <location x="-0.586663503145" y="-0.243003979552" z="0.0"> + <rot axis-x="0" axis-y="1" axis-z="0" val="180"> + <rot axis-x="1" axis-y="0" axis-z="0" val="-90.0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="0.0"/> </rot> </rot> - <facing y="0.0" x="0.0" z="0.0"/> + <facing x="0.0" y="0.0" z="0.0"/> </location> </component> </type> <type name="bank27"> <component type="eightpack-elastic"> - <location y="-0.586663503145" x="0.243003979552" z="0.0"> - <rot axis-z="0" axis-x="0" axis-y="1" val="180"> - <rot axis-z="0" axis-x="1" axis-y="0" val="-90.0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="0.0"/> + <location x="0.243003979552" y="-0.586663503145" z="0.0"> + <rot axis-x="0" axis-y="1" axis-z="0" val="180"> + <rot axis-x="1" axis-y="0" axis-z="0" val="-90.0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="0.0"/> </rot> </rot> - <facing y="0.0" x="0.0" z="0.0"/> + <facing x="0.0" y="0.0" z="0.0"/> </location> </component> </type> <type name="bank28"> <component type="eightpack-elastic"> - <location y="-0.586663503145" x="-0.243003979552" z="0.0"> - <rot axis-z="0" axis-x="0" axis-y="1" val="180"> - <rot axis-z="0" axis-x="1" axis-y="0" val="-90.0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="0.0"/> + <location x="-0.243003979552" y="-0.586663503145" z="0.0"> + <rot axis-x="0" axis-y="1" axis-z="0" val="180"> + <rot axis-x="1" axis-y="0" axis-z="0" val="-90.0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="0.0"/> </rot> </rot> - <facing y="0.0" x="0.0" z="0.0"/> + <facing x="0.0" y="0.0" z="0.0"/> </location> </component> </type> <type name="bank29"> <component type="eightpack-elastic"> - <location y="-0.243003979552" x="0.586663503145" z="0.0"> - <rot axis-z="0" axis-x="0" axis-y="1" val="180"> - <rot axis-z="0" axis-x="1" axis-y="0" val="-90.0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="0.0"/> + <location x="0.586663503145" y="-0.243003979552" z="0.0"> + <rot axis-x="0" axis-y="1" axis-z="0" val="180"> + <rot axis-x="1" axis-y="0" axis-z="0" val="-90.0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="0.0"/> </rot> </rot> - <facing y="0.0" x="0.0" z="0.0"/> + <facing x="0.0" y="0.0" z="0.0"/> </location> </component> </type> <type name="bank30"> <component type="eightpack-elastic"> - <location y="0.243003979552" x="0.586663503145" z="0.0"> - <rot axis-z="0" axis-x="0" axis-y="1" val="180"> - <rot axis-z="0" axis-x="1" axis-y="0" val="-90.0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="0.0"/> + <location x="0.586663503145" y="0.243003979552" z="0.0"> + <rot axis-x="0" axis-y="1" axis-z="0" val="180"> + <rot axis-x="1" axis-y="0" axis-z="0" val="-90.0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="0.0"/> </rot> </rot> - <facing y="0.0" x="0.0" z="0.0"/> + <facing x="0.0" y="0.0" z="0.0"/> </location> </component> </type> <idlist idname="elastic"> - <id start="34816" end="36863"/> - <id start="36864" end="38911"/> - <id start="38912" end="40959"/> - <id start="40960" end="43007"/> - <id start="43008" end="45055"/> - <id start="45056" end="47103"/> + <id end="36863" start="34816"/> + <id end="38911" start="36864"/> + <id end="40959" start="38912"/> + <id end="43007" start="40960"/> + <id end="45055" start="43008"/> + <id end="47103" start="45056"/> </idlist> - <component type="inelastic" idlist="inelastic"> + <component idlist="inelastic" type="inelastic"> <location/> </component> <type name="inelastic"> @@ -1312,284 +1312,214 @@ </type> <type name="bank1"> <component type="eightpack-inelastic"> - <location y="0.365857048586" x="-0.365857048586" z="0.01"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="-135.0"/> + <location x="-0.365857048586" y="0.365857048586" z="0.01"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="-135.0"/> </rot> </rot> - <neutronic y="0.365857048586" x="-0.365857048586" z="-0.5174"/> + <neutronic x="-0.365857048586" y="0.365857048586" z="-0.5174"/> </location> </component> </type> - <component-link name="bank1"> - <parameter name="Efixed"> - <value units="meV" val="3.64"/> - </parameter> - </component-link> <type name="bank2"> <component type="eightpack-inelastic"> - <location y="0.0" x="-0.5174" z="0.01"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="90.0"/> + <location x="-0.5174" y="0.0" z="0.01"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="90.0"/> </rot> </rot> - <neutronic y="0.0" x="-0.5174" z="-0.5174"/> + <neutronic x="-0.5174" y="0.0" z="-0.5174"/> </location> </component> </type> - <component-link name="bank2"> - <parameter name="Efixed"> - <value units="meV" val="3.64"/> - </parameter> - </component-link> <type name="bank3"> <component type="eightpack-inelastic"> - <location y="-0.365857048586" x="-0.365857048586" z="0.01"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="-225.0"/> + <location x="-0.365857048586" y="-0.365857048586" z="0.01"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="-225.0"/> </rot> </rot> - <neutronic y="-0.365857048586" x="-0.365857048586" z="-0.5174"/> + <neutronic x="-0.365857048586" y="-0.365857048586" z="-0.5174"/> </location> </component> </type> - <component-link name="bank3"> - <parameter name="Efixed"> - <value units="meV" val="3.64"/> - </parameter> - </component-link> <type name="bank4"> <component type="eightpack-inelastic"> - <location y="-0.5174" x="-3.16816126939e-17" z="0.01"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="-180.0"/> + <location x="-3.16816126939e-17" y="-0.5174" z="0.01"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="-180.0"/> </rot> </rot> - <neutronic y="-0.5174" x="-3.16816126939e-17" z="-0.5174"/> + <neutronic x="-3.16816126939e-17" y="-0.5174" z="-0.5174"/> </location> </component> </type> - <component-link name="bank4"> - <parameter name="Efixed"> - <value units="meV" val="3.64"/> - </parameter> - </component-link> <type name="bank5"> <component type="eightpack-inelastic"> - <location y="-0.365857048586" x="0.365857048586" z="0.01"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="-315.0"/> + <location x="0.365857048586" y="-0.365857048586" z="0.01"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="-315.0"/> </rot> </rot> - <neutronic y="-0.365857048586" x="0.365857048586" z="-0.5174"/> + <neutronic x="0.365857048586" y="-0.365857048586" z="-0.5174"/> </location> </component> </type> - <component-link name="bank5"> - <parameter name="Efixed"> - <value units="meV" val="3.64"/> - </parameter> - </component-link> <type name="bank6"> <component type="eightpack-inelastic"> - <location y="-6.33632253879e-17" x="0.5174" z="0.01"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="-90.0"/> + <location x="0.5174" y="-6.33632253879e-17" z="0.01"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="-90.0"/> </rot> </rot> - <neutronic y="-6.33632253879e-17" x="0.5174" z="-0.5174"/> + <neutronic x="0.5174" y="-6.33632253879e-17" z="-0.5174"/> </location> </component> </type> - <component-link name="bank6"> - <parameter name="Efixed"> - <value units="meV" val="3.64"/> - </parameter> - </component-link> <type name="bank7"> <component type="eightpack-inelastic"> - <location y="0.365857048586" x="0.365857048586" z="0.01"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="-45.0"/> + <location x="0.365857048586" y="0.365857048586" z="0.01"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="-45.0"/> </rot> </rot> - <neutronic y="0.365857048586" x="0.365857048586" z="-0.5174"/> + <neutronic x="0.365857048586" y="0.365857048586" z="-0.5174"/> </location> </component> </type> - <component-link name="bank7"> - <parameter name="Efixed"> - <value units="meV" val="3.64"/> - </parameter> - </component-link> <type name="bank8"> <component type="eightpack-inelastic"> - <location y="0.365857048586" x="-0.365857048586" z="-0.01"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="-135.0"/> + <location x="-0.365857048586" y="0.365857048586" z="-0.01"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="-135.0"/> </rot> </rot> - <neutronic y="0.365857048586" x="-0.365857048586" z="0.5174"/> + <neutronic x="-0.365857048586" y="0.365857048586" z="0.5174"/> </location> </component> </type> - <component-link name="bank8"> - <parameter name="Efixed"> - <value units="meV" val="3.64"/> - </parameter> - </component-link> <type name="bank9"> <component type="eightpack-inelastic"> - <location y="0.0" x="-0.5174" z="-0.01"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="90.0"/> + <location x="-0.5174" y="0.0" z="-0.01"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="90.0"/> </rot> </rot> - <neutronic y="0.0" x="-0.5174" z="0.5174"/> + <neutronic x="-0.5174" y="0.0" z="0.5174"/> </location> </component> </type> - <component-link name="bank9"> - <parameter name="Efixed"> - <value units="meV" val="3.64"/> - </parameter> - </component-link> <type name="bank10"> <component type="eightpack-inelastic"> - <location y="-0.365857048586" x="-0.365857048586" z="-0.01"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="-225.0"/> + <location x="-0.365857048586" y="-0.365857048586" z="-0.01"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="-225.0"/> </rot> </rot> - <neutronic y="-0.365857048586" x="-0.365857048586" z="0.5174"/> + <neutronic x="-0.365857048586" y="-0.365857048586" z="0.5174"/> </location> </component> </type> - <component-link name="bank10"> - <parameter name="Efixed"> - <value units="meV" val="3.64"/> - </parameter> - </component-link> <type name="bank11"> <component type="eightpack-inelastic"> - <location y="-0.5174" x="-3.16816126939e-17" z="-0.01"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="-180.0"/> + <location x="-3.16816126939e-17" y="-0.5174" z="-0.01"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="-180.0"/> </rot> </rot> - <neutronic y="-0.5174" x="-3.16816126939e-17" z="0.5174"/> + <neutronic x="-3.16816126939e-17" y="-0.5174" z="0.5174"/> </location> </component> </type> - <component-link name="bank11"> - <parameter name="Efixed"> - <value units="meV" val="3.64"/> - </parameter> - </component-link> <type name="bank12"> <component type="eightpack-inelastic"> - <location y="-0.365857048586" x="0.365857048586" z="-0.01"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="-315.0"/> + <location x="0.365857048586" y="-0.365857048586" z="-0.01"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="-315.0"/> </rot> </rot> - <neutronic y="-0.365857048586" x="0.365857048586" z="0.5174"/> + <neutronic x="0.365857048586" y="-0.365857048586" z="0.5174"/> </location> </component> </type> - <component-link name="bank12"> - <parameter name="Efixed"> - <value units="meV" val="3.64"/> - </parameter> - </component-link> <type name="bank13"> <component type="eightpack-inelastic"> - <location y="-6.33632253879e-17" x="0.5174" z="-0.01"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="-90.0"/> + <location x="0.5174" y="-6.33632253879e-17" z="-0.01"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="-90.0"/> </rot> </rot> - <neutronic y="-6.33632253879e-17" x="0.5174" z="0.5174"/> + <neutronic x="0.5174" y="-6.33632253879e-17" z="0.5174"/> </location> </component> </type> - <component-link name="bank13"> - <parameter name="Efixed"> - <value units="meV" val="3.64"/> - </parameter> - </component-link> <type name="bank14"> <component type="eightpack-inelastic"> - <location y="0.365857048586" x="0.365857048586" z="-0.01"> - <rot axis-z="0" axis-x="0" axis-y="1" val="0"> - <rot axis-z="0" axis-x="1" axis-y="0" val="0"> - <rot axis-z="1" axis-x="0" axis-y="0" val="-45.0"/> + <location x="0.365857048586" y="0.365857048586" z="-0.01"> + <rot axis-x="0" axis-y="1" axis-z="0" val="0"> + <rot axis-x="1" axis-y="0" axis-z="0" val="0"> + <rot axis-x="0" axis-y="0" axis-z="1" val="-45.0"/> </rot> </rot> - <neutronic y="0.365857048586" x="0.365857048586" z="0.5174"/> + <neutronic x="0.365857048586" y="0.365857048586" z="0.5174"/> </location> </component> </type> - <component-link name="bank14"> - <parameter name="Efixed"> - <value units="meV" val="3.64"/> - </parameter> - </component-link> <idlist idname="inelastic"> - <id start="0" end="1023"/> - <id start="1024" end="2047"/> - <id start="2048" end="3071"/> - <id start="3072" end="4095"/> - <id start="4096" end="5119"/> - <id start="5120" end="6143"/> - <id start="6144" end="7167"/> - <id start="7168" end="8191"/> - <id start="8192" end="9215"/> - <id start="9216" end="10239"/> - <id start="10240" end="11263"/> - <id start="11264" end="12287"/> - <id start="12288" end="13311"/> - <id start="13312" end="14335"/> + <id end="1023" start="0"/> + <id end="2047" start="1024"/> + <id end="3071" start="2048"/> + <id end="4095" start="3072"/> + <id end="5119" start="4096"/> + <id end="6143" start="5120"/> + <id end="7167" start="6144"/> + <id end="8191" start="7168"/> + <id end="9215" start="8192"/> + <id end="10239" start="9216"/> + <id end="11263" start="10240"/> + <id end="12287" start="11264"/> + <id end="13311" start="12288"/> + <id end="14335" start="13312"/> </idlist> <!--INELASTIC 8-PACK--> <type name="eightpack-inelastic"> <properties/> <component type="tube-inelastic"> - <location x="-0.04445" name="tube1"> + <location name="tube1" x="-0.04445"> <neutronic x="0.0"/> </location> - <location x="-0.03175" name="tube2"> + <location name="tube2" x="-0.03175"> <neutronic x="0.0"/> </location> - <location x="-0.01905" name="tube3"> + <location name="tube3" x="-0.01905"> <neutronic x="0.0"/> </location> - <location x="-0.00635" name="tube4"> + <location name="tube4" x="-0.00635"> <neutronic x="0.0"/> </location> - <location x="0.00635" name="tube5"> + <location name="tube5" x="0.00635"> <neutronic x="0.0"/> </location> - <location x="0.01905" name="tube6"> + <location name="tube6" x="0.01905"> <neutronic x="0.0"/> </location> - <location x="0.03175" name="tube7"> + <location name="tube7" x="0.03175"> <neutronic x="0.0"/> </location> - <location x="0.04445" name="tube8"> + <location name="tube8" x="0.04445"> <neutronic x="0.0"/> </location> </component> @@ -1598,28 +1528,28 @@ <type name="eightpack-elastic"> <properties/> <component type="tube-elastic"> - <location x="-0.056896" name="tube1"> + <location name="tube1" x="-0.056896"> <neutronic x="-0.056896"/> </location> - <location x="-0.04064" name="tube2"> + <location name="tube2" x="-0.04064"> <neutronic x="-0.04064"/> </location> - <location x="-0.024384" name="tube3"> + <location name="tube3" x="-0.024384"> <neutronic x="-0.024384"/> </location> - <location x="-0.008128" name="tube4"> + <location name="tube4" x="-0.008128"> <neutronic x="-0.008128"/> </location> - <location x="0.008128" name="tube5"> + <location name="tube5" x="0.008128"> <neutronic x="0.008128"/> </location> - <location x="0.024384" name="tube6"> + <location name="tube6" x="0.024384"> <neutronic x="0.024384"/> </location> - <location x="0.04064" name="tube7"> + <location name="tube7" x="0.04064"> <neutronic x="0.04064"/> </location> - <location x="0.056896" name="tube8"> + <location name="tube8" x="0.056896"> <neutronic x="0.056896"/> </location> </component> @@ -1628,388 +1558,388 @@ <type name="tube-inelastic" outline="yes"> <properties/> <component type="pixel-inelastic-tube"> - <location y="-0.0803299804687" name="pixel1"> + <location name="pixel1" y="-0.0803299804687"> <neutronic y="0.0"/> </location> - <location y="-0.0790649414062" name="pixel2"> + <location name="pixel2" y="-0.0790649414062"> <neutronic y="0.0"/> </location> - <location y="-0.0777999023437" name="pixel3"> + <location name="pixel3" y="-0.0777999023437"> <neutronic y="0.0"/> </location> - <location y="-0.0765348632812" name="pixel4"> + <location name="pixel4" y="-0.0765348632812"> <neutronic y="0.0"/> </location> - <location y="-0.0752698242187" name="pixel5"> + <location name="pixel5" y="-0.0752698242187"> <neutronic y="0.0"/> </location> - <location y="-0.0740047851562" name="pixel6"> + <location name="pixel6" y="-0.0740047851562"> <neutronic y="0.0"/> </location> - <location y="-0.0727397460937" name="pixel7"> + <location name="pixel7" y="-0.0727397460937"> <neutronic y="0.0"/> </location> - <location y="-0.0714747070313" name="pixel8"> + <location name="pixel8" y="-0.0714747070313"> <neutronic y="0.0"/> </location> - <location y="-0.0702096679688" name="pixel9"> + <location name="pixel9" y="-0.0702096679688"> <neutronic y="0.0"/> </location> - <location y="-0.0689446289062" name="pixel10"> + <location name="pixel10" y="-0.0689446289062"> <neutronic y="0.0"/> </location> - <location y="-0.0676795898437" name="pixel11"> + <location name="pixel11" y="-0.0676795898437"> <neutronic y="0.0"/> </location> - <location y="-0.0664145507812" name="pixel12"> + <location name="pixel12" y="-0.0664145507812"> <neutronic y="0.0"/> </location> - <location y="-0.0651495117187" name="pixel13"> + <location name="pixel13" y="-0.0651495117187"> <neutronic y="0.0"/> </location> - <location y="-0.0638844726562" name="pixel14"> + <location name="pixel14" y="-0.0638844726562"> <neutronic y="0.0"/> </location> - <location y="-0.0626194335937" name="pixel15"> + <location name="pixel15" y="-0.0626194335937"> <neutronic y="0.0"/> </location> - <location y="-0.0613543945312" name="pixel16"> + <location name="pixel16" y="-0.0613543945312"> <neutronic y="0.0"/> </location> - <location y="-0.0600893554687" name="pixel17"> + <location name="pixel17" y="-0.0600893554687"> <neutronic y="0.0"/> </location> - <location y="-0.0588243164062" name="pixel18"> + <location name="pixel18" y="-0.0588243164062"> <neutronic y="0.0"/> </location> - <location y="-0.0575592773437" name="pixel19"> + <location name="pixel19" y="-0.0575592773437"> <neutronic y="0.0"/> </location> - <location y="-0.0562942382812" name="pixel20"> + <location name="pixel20" y="-0.0562942382812"> <neutronic y="0.0"/> </location> - <location y="-0.0550291992187" name="pixel21"> + <location name="pixel21" y="-0.0550291992187"> <neutronic y="0.0"/> </location> - <location y="-0.0537641601562" name="pixel22"> + <location name="pixel22" y="-0.0537641601562"> <neutronic y="0.0"/> </location> - <location y="-0.0524991210937" name="pixel23"> + <location name="pixel23" y="-0.0524991210937"> <neutronic y="0.0"/> </location> - <location y="-0.0512340820312" name="pixel24"> + <location name="pixel24" y="-0.0512340820312"> <neutronic y="0.0"/> </location> - <location y="-0.0499690429687" name="pixel25"> + <location name="pixel25" y="-0.0499690429687"> <neutronic y="0.0"/> </location> - <location y="-0.0487040039062" name="pixel26"> + <location name="pixel26" y="-0.0487040039062"> <neutronic y="0.0"/> </location> - <location y="-0.0474389648437" name="pixel27"> + <location name="pixel27" y="-0.0474389648437"> <neutronic y="0.0"/> </location> - <location y="-0.0461739257812" name="pixel28"> + <location name="pixel28" y="-0.0461739257812"> <neutronic y="0.0"/> </location> - <location y="-0.0449088867187" name="pixel29"> + <location name="pixel29" y="-0.0449088867187"> <neutronic y="0.0"/> </location> - <location y="-0.0436438476562" name="pixel30"> + <location name="pixel30" y="-0.0436438476562"> <neutronic y="0.0"/> </location> - <location y="-0.0423788085937" name="pixel31"> + <location name="pixel31" y="-0.0423788085937"> <neutronic y="0.0"/> </location> - <location y="-0.0411137695312" name="pixel32"> + <location name="pixel32" y="-0.0411137695312"> <neutronic y="0.0"/> </location> - <location y="-0.0398487304687" name="pixel33"> + <location name="pixel33" y="-0.0398487304687"> <neutronic y="0.0"/> </location> - <location y="-0.0385836914062" name="pixel34"> + <location name="pixel34" y="-0.0385836914062"> <neutronic y="0.0"/> </location> - <location y="-0.0373186523437" name="pixel35"> + <location name="pixel35" y="-0.0373186523437"> <neutronic y="0.0"/> </location> - <location y="-0.0360536132812" name="pixel36"> + <location name="pixel36" y="-0.0360536132812"> <neutronic y="0.0"/> </location> - <location y="-0.0347885742187" name="pixel37"> + <location name="pixel37" y="-0.0347885742187"> <neutronic y="0.0"/> </location> - <location y="-0.0335235351562" name="pixel38"> + <location name="pixel38" y="-0.0335235351562"> <neutronic y="0.0"/> </location> - <location y="-0.0322584960937" name="pixel39"> + <location name="pixel39" y="-0.0322584960937"> <neutronic y="0.0"/> </location> - <location y="-0.0309934570312" name="pixel40"> + <location name="pixel40" y="-0.0309934570312"> <neutronic y="0.0"/> </location> - <location y="-0.0297284179687" name="pixel41"> + <location name="pixel41" y="-0.0297284179687"> <neutronic y="0.0"/> </location> - <location y="-0.0284633789062" name="pixel42"> + <location name="pixel42" y="-0.0284633789062"> <neutronic y="0.0"/> </location> - <location y="-0.0271983398437" name="pixel43"> + <location name="pixel43" y="-0.0271983398437"> <neutronic y="0.0"/> </location> - <location y="-0.0259333007812" name="pixel44"> + <location name="pixel44" y="-0.0259333007812"> <neutronic y="0.0"/> </location> - <location y="-0.0246682617188" name="pixel45"> + <location name="pixel45" y="-0.0246682617188"> <neutronic y="0.0"/> </location> - <location y="-0.0234032226563" name="pixel46"> + <location name="pixel46" y="-0.0234032226563"> <neutronic y="0.0"/> </location> - <location y="-0.0221381835937" name="pixel47"> + <location name="pixel47" y="-0.0221381835937"> <neutronic y="0.0"/> </location> - <location y="-0.0208731445312" name="pixel48"> + <location name="pixel48" y="-0.0208731445312"> <neutronic y="0.0"/> </location> - <location y="-0.0196081054687" name="pixel49"> + <location name="pixel49" y="-0.0196081054687"> <neutronic y="0.0"/> </location> - <location y="-0.0183430664062" name="pixel50"> + <location name="pixel50" y="-0.0183430664062"> <neutronic y="0.0"/> </location> - <location y="-0.0170780273437" name="pixel51"> + <location name="pixel51" y="-0.0170780273437"> <neutronic y="0.0"/> </location> - <location y="-0.0158129882812" name="pixel52"> + <location name="pixel52" y="-0.0158129882812"> <neutronic y="0.0"/> </location> - <location y="-0.0145479492187" name="pixel53"> + <location name="pixel53" y="-0.0145479492187"> <neutronic y="0.0"/> </location> - <location y="-0.0132829101562" name="pixel54"> + <location name="pixel54" y="-0.0132829101562"> <neutronic y="0.0"/> </location> - <location y="-0.0120178710937" name="pixel55"> + <location name="pixel55" y="-0.0120178710937"> <neutronic y="0.0"/> </location> - <location y="-0.0107528320312" name="pixel56"> + <location name="pixel56" y="-0.0107528320312"> <neutronic y="0.0"/> </location> - <location y="-0.00948779296875" name="pixel57"> + <location name="pixel57" y="-0.00948779296875"> <neutronic y="0.0"/> </location> - <location y="-0.00822275390625" name="pixel58"> + <location name="pixel58" y="-0.00822275390625"> <neutronic y="0.0"/> </location> - <location y="-0.00695771484375" name="pixel59"> + <location name="pixel59" y="-0.00695771484375"> <neutronic y="0.0"/> </location> - <location y="-0.00569267578125" name="pixel60"> + <location name="pixel60" y="-0.00569267578125"> <neutronic y="0.0"/> </location> - <location y="-0.00442763671875" name="pixel61"> + <location name="pixel61" y="-0.00442763671875"> <neutronic y="0.0"/> </location> - <location y="-0.00316259765625" name="pixel62"> + <location name="pixel62" y="-0.00316259765625"> <neutronic y="0.0"/> </location> - <location y="-0.00189755859375" name="pixel63"> + <location name="pixel63" y="-0.00189755859375"> <neutronic y="0.0"/> </location> - <location y="-0.00063251953125" name="pixel64"> + <location name="pixel64" y="-0.00063251953125"> <neutronic y="0.0"/> </location> - <location y="0.00063251953125" name="pixel65"> + <location name="pixel65" y="0.00063251953125"> <neutronic y="0.0"/> </location> - <location y="0.00189755859375" name="pixel66"> + <location name="pixel66" y="0.00189755859375"> <neutronic y="0.0"/> </location> - <location y="0.00316259765625" name="pixel67"> + <location name="pixel67" y="0.00316259765625"> <neutronic y="0.0"/> </location> - <location y="0.00442763671875" name="pixel68"> + <location name="pixel68" y="0.00442763671875"> <neutronic y="0.0"/> </location> - <location y="0.00569267578125" name="pixel69"> + <location name="pixel69" y="0.00569267578125"> <neutronic y="0.0"/> </location> - <location y="0.00695771484375" name="pixel70"> + <location name="pixel70" y="0.00695771484375"> <neutronic y="0.0"/> </location> - <location y="0.00822275390625" name="pixel71"> + <location name="pixel71" y="0.00822275390625"> <neutronic y="0.0"/> </location> - <location y="0.00948779296875" name="pixel72"> + <location name="pixel72" y="0.00948779296875"> <neutronic y="0.0"/> </location> - <location y="0.0107528320313" name="pixel73"> + <location name="pixel73" y="0.0107528320313"> <neutronic y="0.0"/> </location> - <location y="0.0120178710937" name="pixel74"> + <location name="pixel74" y="0.0120178710937"> <neutronic y="0.0"/> </location> - <location y="0.0132829101562" name="pixel75"> + <location name="pixel75" y="0.0132829101562"> <neutronic y="0.0"/> </location> - <location y="0.0145479492187" name="pixel76"> + <location name="pixel76" y="0.0145479492187"> <neutronic y="0.0"/> </location> - <location y="0.0158129882812" name="pixel77"> + <location name="pixel77" y="0.0158129882812"> <neutronic y="0.0"/> </location> - <location y="0.0170780273437" name="pixel78"> + <location name="pixel78" y="0.0170780273437"> <neutronic y="0.0"/> </location> - <location y="0.0183430664062" name="pixel79"> + <location name="pixel79" y="0.0183430664062"> <neutronic y="0.0"/> </location> - <location y="0.0196081054687" name="pixel80"> + <location name="pixel80" y="0.0196081054687"> <neutronic y="0.0"/> </location> - <location y="0.0208731445312" name="pixel81"> + <location name="pixel81" y="0.0208731445312"> <neutronic y="0.0"/> </location> - <location y="0.0221381835937" name="pixel82"> + <location name="pixel82" y="0.0221381835937"> <neutronic y="0.0"/> </location> - <location y="0.0234032226563" name="pixel83"> + <location name="pixel83" y="0.0234032226563"> <neutronic y="0.0"/> </location> - <location y="0.0246682617188" name="pixel84"> + <location name="pixel84" y="0.0246682617188"> <neutronic y="0.0"/> </location> - <location y="0.0259333007813" name="pixel85"> + <location name="pixel85" y="0.0259333007813"> <neutronic y="0.0"/> </location> - <location y="0.0271983398438" name="pixel86"> + <location name="pixel86" y="0.0271983398438"> <neutronic y="0.0"/> </location> - <location y="0.0284633789063" name="pixel87"> + <location name="pixel87" y="0.0284633789063"> <neutronic y="0.0"/> </location> - <location y="0.0297284179688" name="pixel88"> + <location name="pixel88" y="0.0297284179688"> <neutronic y="0.0"/> </location> - <location y="0.0309934570312" name="pixel89"> + <location name="pixel89" y="0.0309934570312"> <neutronic y="0.0"/> </location> - <location y="0.0322584960937" name="pixel90"> + <location name="pixel90" y="0.0322584960937"> <neutronic y="0.0"/> </location> - <location y="0.0335235351562" name="pixel91"> + <location name="pixel91" y="0.0335235351562"> <neutronic y="0.0"/> </location> - <location y="0.0347885742187" name="pixel92"> + <location name="pixel92" y="0.0347885742187"> <neutronic y="0.0"/> </location> - <location y="0.0360536132812" name="pixel93"> + <location name="pixel93" y="0.0360536132812"> <neutronic y="0.0"/> </location> - <location y="0.0373186523437" name="pixel94"> + <location name="pixel94" y="0.0373186523437"> <neutronic y="0.0"/> </location> - <location y="0.0385836914062" name="pixel95"> + <location name="pixel95" y="0.0385836914062"> <neutronic y="0.0"/> </location> - <location y="0.0398487304687" name="pixel96"> + <location name="pixel96" y="0.0398487304687"> <neutronic y="0.0"/> </location> - <location y="0.0411137695312" name="pixel97"> + <location name="pixel97" y="0.0411137695312"> <neutronic y="0.0"/> </location> - <location y="0.0423788085937" name="pixel98"> + <location name="pixel98" y="0.0423788085937"> <neutronic y="0.0"/> </location> - <location y="0.0436438476562" name="pixel99"> + <location name="pixel99" y="0.0436438476562"> <neutronic y="0.0"/> </location> - <location y="0.0449088867187" name="pixel100"> + <location name="pixel100" y="0.0449088867187"> <neutronic y="0.0"/> </location> - <location y="0.0461739257812" name="pixel101"> + <location name="pixel101" y="0.0461739257812"> <neutronic y="0.0"/> </location> - <location y="0.0474389648438" name="pixel102"> + <location name="pixel102" y="0.0474389648438"> <neutronic y="0.0"/> </location> - <location y="0.0487040039063" name="pixel103"> + <location name="pixel103" y="0.0487040039063"> <neutronic y="0.0"/> </location> - <location y="0.0499690429688" name="pixel104"> + <location name="pixel104" y="0.0499690429688"> <neutronic y="0.0"/> </location> - <location y="0.0512340820313" name="pixel105"> + <location name="pixel105" y="0.0512340820313"> <neutronic y="0.0"/> </location> - <location y="0.0524991210938" name="pixel106"> + <location name="pixel106" y="0.0524991210938"> <neutronic y="0.0"/> </location> - <location y="0.0537641601563" name="pixel107"> + <location name="pixel107" y="0.0537641601563"> <neutronic y="0.0"/> </location> - <location y="0.0550291992188" name="pixel108"> + <location name="pixel108" y="0.0550291992188"> <neutronic y="0.0"/> </location> - <location y="0.0562942382813" name="pixel109"> + <location name="pixel109" y="0.0562942382813"> <neutronic y="0.0"/> </location> - <location y="0.0575592773438" name="pixel110"> + <location name="pixel110" y="0.0575592773438"> <neutronic y="0.0"/> </location> - <location y="0.0588243164063" name="pixel111"> + <location name="pixel111" y="0.0588243164063"> <neutronic y="0.0"/> </location> - <location y="0.0600893554688" name="pixel112"> + <location name="pixel112" y="0.0600893554688"> <neutronic y="0.0"/> </location> - <location y="0.0613543945312" name="pixel113"> + <location name="pixel113" y="0.0613543945312"> <neutronic y="0.0"/> </location> - <location y="0.0626194335937" name="pixel114"> + <location name="pixel114" y="0.0626194335937"> <neutronic y="0.0"/> </location> - <location y="0.0638844726562" name="pixel115"> + <location name="pixel115" y="0.0638844726562"> <neutronic y="0.0"/> </location> - <location y="0.0651495117187" name="pixel116"> + <location name="pixel116" y="0.0651495117187"> <neutronic y="0.0"/> </location> - <location y="0.0664145507812" name="pixel117"> + <location name="pixel117" y="0.0664145507812"> <neutronic y="0.0"/> </location> - <location y="0.0676795898437" name="pixel118"> + <location name="pixel118" y="0.0676795898437"> <neutronic y="0.0"/> </location> - <location y="0.0689446289062" name="pixel119"> + <location name="pixel119" y="0.0689446289062"> <neutronic y="0.0"/> </location> - <location y="0.0702096679687" name="pixel120"> + <location name="pixel120" y="0.0702096679687"> <neutronic y="0.0"/> </location> - <location y="0.0714747070312" name="pixel121"> + <location name="pixel121" y="0.0714747070312"> <neutronic y="0.0"/> </location> - <location y="0.0727397460937" name="pixel122"> + <location name="pixel122" y="0.0727397460937"> <neutronic y="0.0"/> </location> - <location y="0.0740047851562" name="pixel123"> + <location name="pixel123" y="0.0740047851562"> <neutronic y="0.0"/> </location> - <location y="0.0752698242187" name="pixel124"> + <location name="pixel124" y="0.0752698242187"> <neutronic y="0.0"/> </location> - <location y="0.0765348632812" name="pixel125"> + <location name="pixel125" y="0.0765348632812"> <neutronic y="0.0"/> </location> - <location y="0.0777999023437" name="pixel126"> + <location name="pixel126" y="0.0777999023437"> <neutronic y="0.0"/> </location> - <location y="0.0790649414062" name="pixel127"> + <location name="pixel127" y="0.0790649414062"> <neutronic y="0.0"/> </location> - <location y="0.0803299804687" name="pixel128"> + <location name="pixel128" y="0.0803299804687"> <neutronic y="0.0"/> </location> </component> @@ -2018,772 +1948,772 @@ <type name="tube-long-bs-elastic" outline="yes"> <properties/> <component type="pixel-bs-elastic-long-tube"> - <location y="-0.22770703125" name="pixel1"> + <location name="pixel1" y="-0.22770703125"> <neutronic y="-0.22770703125"/> </location> - <location y="-0.22592109375" name="pixel2"> + <location name="pixel2" y="-0.22592109375"> <neutronic y="-0.22592109375"/> </location> - <location y="-0.22413515625" name="pixel3"> + <location name="pixel3" y="-0.22413515625"> <neutronic y="-0.22413515625"/> </location> - <location y="-0.22234921875" name="pixel4"> + <location name="pixel4" y="-0.22234921875"> <neutronic y="-0.22234921875"/> </location> - <location y="-0.22056328125" name="pixel5"> + <location name="pixel5" y="-0.22056328125"> <neutronic y="-0.22056328125"/> </location> - <location y="-0.21877734375" name="pixel6"> + <location name="pixel6" y="-0.21877734375"> <neutronic y="-0.21877734375"/> </location> - <location y="-0.21699140625" name="pixel7"> + <location name="pixel7" y="-0.21699140625"> <neutronic y="-0.21699140625"/> </location> - <location y="-0.21520546875" name="pixel8"> + <location name="pixel8" y="-0.21520546875"> <neutronic y="-0.21520546875"/> </location> - <location y="-0.21341953125" name="pixel9"> + <location name="pixel9" y="-0.21341953125"> <neutronic y="-0.21341953125"/> </location> - <location y="-0.21163359375" name="pixel10"> + <location name="pixel10" y="-0.21163359375"> <neutronic y="-0.21163359375"/> </location> - <location y="-0.20984765625" name="pixel11"> + <location name="pixel11" y="-0.20984765625"> <neutronic y="-0.20984765625"/> </location> - <location y="-0.20806171875" name="pixel12"> + <location name="pixel12" y="-0.20806171875"> <neutronic y="-0.20806171875"/> </location> - <location y="-0.20627578125" name="pixel13"> + <location name="pixel13" y="-0.20627578125"> <neutronic y="-0.20627578125"/> </location> - <location y="-0.20448984375" name="pixel14"> + <location name="pixel14" y="-0.20448984375"> <neutronic y="-0.20448984375"/> </location> - <location y="-0.20270390625" name="pixel15"> + <location name="pixel15" y="-0.20270390625"> <neutronic y="-0.20270390625"/> </location> - <location y="-0.20091796875" name="pixel16"> + <location name="pixel16" y="-0.20091796875"> <neutronic y="-0.20091796875"/> </location> - <location y="-0.19913203125" name="pixel17"> + <location name="pixel17" y="-0.19913203125"> <neutronic y="-0.19913203125"/> </location> - <location y="-0.19734609375" name="pixel18"> + <location name="pixel18" y="-0.19734609375"> <neutronic y="-0.19734609375"/> </location> - <location y="-0.19556015625" name="pixel19"> + <location name="pixel19" y="-0.19556015625"> <neutronic y="-0.19556015625"/> </location> - <location y="-0.19377421875" name="pixel20"> + <location name="pixel20" y="-0.19377421875"> <neutronic y="-0.19377421875"/> </location> - <location y="-0.19198828125" name="pixel21"> + <location name="pixel21" y="-0.19198828125"> <neutronic y="-0.19198828125"/> </location> - <location y="-0.19020234375" name="pixel22"> + <location name="pixel22" y="-0.19020234375"> <neutronic y="-0.19020234375"/> </location> - <location y="-0.18841640625" name="pixel23"> + <location name="pixel23" y="-0.18841640625"> <neutronic y="-0.18841640625"/> </location> - <location y="-0.18663046875" name="pixel24"> + <location name="pixel24" y="-0.18663046875"> <neutronic y="-0.18663046875"/> </location> - <location y="-0.18484453125" name="pixel25"> + <location name="pixel25" y="-0.18484453125"> <neutronic y="-0.18484453125"/> </location> - <location y="-0.18305859375" name="pixel26"> + <location name="pixel26" y="-0.18305859375"> <neutronic y="-0.18305859375"/> </location> - <location y="-0.18127265625" name="pixel27"> + <location name="pixel27" y="-0.18127265625"> <neutronic y="-0.18127265625"/> </location> - <location y="-0.17948671875" name="pixel28"> + <location name="pixel28" y="-0.17948671875"> <neutronic y="-0.17948671875"/> </location> - <location y="-0.17770078125" name="pixel29"> + <location name="pixel29" y="-0.17770078125"> <neutronic y="-0.17770078125"/> </location> - <location y="-0.17591484375" name="pixel30"> + <location name="pixel30" y="-0.17591484375"> <neutronic y="-0.17591484375"/> </location> - <location y="-0.17412890625" name="pixel31"> + <location name="pixel31" y="-0.17412890625"> <neutronic y="-0.17412890625"/> </location> - <location y="-0.17234296875" name="pixel32"> + <location name="pixel32" y="-0.17234296875"> <neutronic y="-0.17234296875"/> </location> - <location y="-0.17055703125" name="pixel33"> + <location name="pixel33" y="-0.17055703125"> <neutronic y="-0.17055703125"/> </location> - <location y="-0.16877109375" name="pixel34"> + <location name="pixel34" y="-0.16877109375"> <neutronic y="-0.16877109375"/> </location> - <location y="-0.16698515625" name="pixel35"> + <location name="pixel35" y="-0.16698515625"> <neutronic y="-0.16698515625"/> </location> - <location y="-0.16519921875" name="pixel36"> + <location name="pixel36" y="-0.16519921875"> <neutronic y="-0.16519921875"/> </location> - <location y="-0.16341328125" name="pixel37"> + <location name="pixel37" y="-0.16341328125"> <neutronic y="-0.16341328125"/> </location> - <location y="-0.16162734375" name="pixel38"> + <location name="pixel38" y="-0.16162734375"> <neutronic y="-0.16162734375"/> </location> - <location y="-0.15984140625" name="pixel39"> + <location name="pixel39" y="-0.15984140625"> <neutronic y="-0.15984140625"/> </location> - <location y="-0.15805546875" name="pixel40"> + <location name="pixel40" y="-0.15805546875"> <neutronic y="-0.15805546875"/> </location> - <location y="-0.15626953125" name="pixel41"> + <location name="pixel41" y="-0.15626953125"> <neutronic y="-0.15626953125"/> </location> - <location y="-0.15448359375" name="pixel42"> + <location name="pixel42" y="-0.15448359375"> <neutronic y="-0.15448359375"/> </location> - <location y="-0.15269765625" name="pixel43"> + <location name="pixel43" y="-0.15269765625"> <neutronic y="-0.15269765625"/> </location> - <location y="-0.15091171875" name="pixel44"> + <location name="pixel44" y="-0.15091171875"> <neutronic y="-0.15091171875"/> </location> - <location y="-0.14912578125" name="pixel45"> + <location name="pixel45" y="-0.14912578125"> <neutronic y="-0.14912578125"/> </location> - <location y="-0.14733984375" name="pixel46"> + <location name="pixel46" y="-0.14733984375"> <neutronic y="-0.14733984375"/> </location> - <location y="-0.14555390625" name="pixel47"> + <location name="pixel47" y="-0.14555390625"> <neutronic y="-0.14555390625"/> </location> - <location y="-0.14376796875" name="pixel48"> + <location name="pixel48" y="-0.14376796875"> <neutronic y="-0.14376796875"/> </location> - <location y="-0.14198203125" name="pixel49"> + <location name="pixel49" y="-0.14198203125"> <neutronic y="-0.14198203125"/> </location> - <location y="-0.14019609375" name="pixel50"> + <location name="pixel50" y="-0.14019609375"> <neutronic y="-0.14019609375"/> </location> - <location y="-0.13841015625" name="pixel51"> + <location name="pixel51" y="-0.13841015625"> <neutronic y="-0.13841015625"/> </location> - <location y="-0.13662421875" name="pixel52"> + <location name="pixel52" y="-0.13662421875"> <neutronic y="-0.13662421875"/> </location> - <location y="-0.13483828125" name="pixel53"> + <location name="pixel53" y="-0.13483828125"> <neutronic y="-0.13483828125"/> </location> - <location y="-0.13305234375" name="pixel54"> + <location name="pixel54" y="-0.13305234375"> <neutronic y="-0.13305234375"/> </location> - <location y="-0.13126640625" name="pixel55"> + <location name="pixel55" y="-0.13126640625"> <neutronic y="-0.13126640625"/> </location> - <location y="-0.12948046875" name="pixel56"> + <location name="pixel56" y="-0.12948046875"> <neutronic y="-0.12948046875"/> </location> - <location y="-0.12769453125" name="pixel57"> + <location name="pixel57" y="-0.12769453125"> <neutronic y="-0.12769453125"/> </location> - <location y="-0.12590859375" name="pixel58"> + <location name="pixel58" y="-0.12590859375"> <neutronic y="-0.12590859375"/> </location> - <location y="-0.12412265625" name="pixel59"> + <location name="pixel59" y="-0.12412265625"> <neutronic y="-0.12412265625"/> </location> - <location y="-0.12233671875" name="pixel60"> + <location name="pixel60" y="-0.12233671875"> <neutronic y="-0.12233671875"/> </location> - <location y="-0.12055078125" name="pixel61"> + <location name="pixel61" y="-0.12055078125"> <neutronic y="-0.12055078125"/> </location> - <location y="-0.11876484375" name="pixel62"> + <location name="pixel62" y="-0.11876484375"> <neutronic y="-0.11876484375"/> </location> - <location y="-0.11697890625" name="pixel63"> + <location name="pixel63" y="-0.11697890625"> <neutronic y="-0.11697890625"/> </location> - <location y="-0.11519296875" name="pixel64"> + <location name="pixel64" y="-0.11519296875"> <neutronic y="-0.11519296875"/> </location> - <location y="-0.11340703125" name="pixel65"> + <location name="pixel65" y="-0.11340703125"> <neutronic y="-0.11340703125"/> </location> - <location y="-0.11162109375" name="pixel66"> + <location name="pixel66" y="-0.11162109375"> <neutronic y="-0.11162109375"/> </location> - <location y="-0.10983515625" name="pixel67"> + <location name="pixel67" y="-0.10983515625"> <neutronic y="-0.10983515625"/> </location> - <location y="-0.10804921875" name="pixel68"> + <location name="pixel68" y="-0.10804921875"> <neutronic y="-0.10804921875"/> </location> - <location y="-0.10626328125" name="pixel69"> + <location name="pixel69" y="-0.10626328125"> <neutronic y="-0.10626328125"/> </location> - <location y="-0.10447734375" name="pixel70"> + <location name="pixel70" y="-0.10447734375"> <neutronic y="-0.10447734375"/> </location> - <location y="-0.10269140625" name="pixel71"> + <location name="pixel71" y="-0.10269140625"> <neutronic y="-0.10269140625"/> </location> - <location y="-0.10090546875" name="pixel72"> + <location name="pixel72" y="-0.10090546875"> <neutronic y="-0.10090546875"/> </location> - <location y="-0.09911953125" name="pixel73"> + <location name="pixel73" y="-0.09911953125"> <neutronic y="-0.09911953125"/> </location> - <location y="-0.09733359375" name="pixel74"> + <location name="pixel74" y="-0.09733359375"> <neutronic y="-0.09733359375"/> </location> - <location y="-0.09554765625" name="pixel75"> + <location name="pixel75" y="-0.09554765625"> <neutronic y="-0.09554765625"/> </location> - <location y="-0.09376171875" name="pixel76"> + <location name="pixel76" y="-0.09376171875"> <neutronic y="-0.09376171875"/> </location> - <location y="-0.09197578125" name="pixel77"> + <location name="pixel77" y="-0.09197578125"> <neutronic y="-0.09197578125"/> </location> - <location y="-0.09018984375" name="pixel78"> + <location name="pixel78" y="-0.09018984375"> <neutronic y="-0.09018984375"/> </location> - <location y="-0.08840390625" name="pixel79"> + <location name="pixel79" y="-0.08840390625"> <neutronic y="-0.08840390625"/> </location> - <location y="-0.08661796875" name="pixel80"> + <location name="pixel80" y="-0.08661796875"> <neutronic y="-0.08661796875"/> </location> - <location y="-0.08483203125" name="pixel81"> + <location name="pixel81" y="-0.08483203125"> <neutronic y="-0.08483203125"/> </location> - <location y="-0.08304609375" name="pixel82"> + <location name="pixel82" y="-0.08304609375"> <neutronic y="-0.08304609375"/> </location> - <location y="-0.08126015625" name="pixel83"> + <location name="pixel83" y="-0.08126015625"> <neutronic y="-0.08126015625"/> </location> - <location y="-0.07947421875" name="pixel84"> + <location name="pixel84" y="-0.07947421875"> <neutronic y="-0.07947421875"/> </location> - <location y="-0.07768828125" name="pixel85"> + <location name="pixel85" y="-0.07768828125"> <neutronic y="-0.07768828125"/> </location> - <location y="-0.07590234375" name="pixel86"> + <location name="pixel86" y="-0.07590234375"> <neutronic y="-0.07590234375"/> </location> - <location y="-0.07411640625" name="pixel87"> + <location name="pixel87" y="-0.07411640625"> <neutronic y="-0.07411640625"/> </location> - <location y="-0.07233046875" name="pixel88"> + <location name="pixel88" y="-0.07233046875"> <neutronic y="-0.07233046875"/> </location> - <location y="-0.07054453125" name="pixel89"> + <location name="pixel89" y="-0.07054453125"> <neutronic y="-0.07054453125"/> </location> - <location y="-0.06875859375" name="pixel90"> + <location name="pixel90" y="-0.06875859375"> <neutronic y="-0.06875859375"/> </location> - <location y="-0.06697265625" name="pixel91"> + <location name="pixel91" y="-0.06697265625"> <neutronic y="-0.06697265625"/> </location> - <location y="-0.06518671875" name="pixel92"> + <location name="pixel92" y="-0.06518671875"> <neutronic y="-0.06518671875"/> </location> - <location y="-0.06340078125" name="pixel93"> + <location name="pixel93" y="-0.06340078125"> <neutronic y="-0.06340078125"/> </location> - <location y="-0.06161484375" name="pixel94"> + <location name="pixel94" y="-0.06161484375"> <neutronic y="-0.06161484375"/> </location> - <location y="-0.05982890625" name="pixel95"> + <location name="pixel95" y="-0.05982890625"> <neutronic y="-0.05982890625"/> </location> - <location y="-0.05804296875" name="pixel96"> + <location name="pixel96" y="-0.05804296875"> <neutronic y="-0.05804296875"/> </location> - <location y="-0.05625703125" name="pixel97"> + <location name="pixel97" y="-0.05625703125"> <neutronic y="-0.05625703125"/> </location> - <location y="-0.05447109375" name="pixel98"> + <location name="pixel98" y="-0.05447109375"> <neutronic y="-0.05447109375"/> </location> - <location y="-0.05268515625" name="pixel99"> + <location name="pixel99" y="-0.05268515625"> <neutronic y="-0.05268515625"/> </location> - <location y="-0.05089921875" name="pixel100"> + <location name="pixel100" y="-0.05089921875"> <neutronic y="-0.05089921875"/> </location> - <location y="-0.04911328125" name="pixel101"> + <location name="pixel101" y="-0.04911328125"> <neutronic y="-0.04911328125"/> </location> - <location y="-0.04732734375" name="pixel102"> + <location name="pixel102" y="-0.04732734375"> <neutronic y="-0.04732734375"/> </location> - <location y="-0.04554140625" name="pixel103"> + <location name="pixel103" y="-0.04554140625"> <neutronic y="-0.04554140625"/> </location> - <location y="-0.04375546875" name="pixel104"> + <location name="pixel104" y="-0.04375546875"> <neutronic y="-0.04375546875"/> </location> - <location y="-0.04196953125" name="pixel105"> + <location name="pixel105" y="-0.04196953125"> <neutronic y="-0.04196953125"/> </location> - <location y="-0.04018359375" name="pixel106"> + <location name="pixel106" y="-0.04018359375"> <neutronic y="-0.04018359375"/> </location> - <location y="-0.03839765625" name="pixel107"> + <location name="pixel107" y="-0.03839765625"> <neutronic y="-0.03839765625"/> </location> - <location y="-0.03661171875" name="pixel108"> + <location name="pixel108" y="-0.03661171875"> <neutronic y="-0.03661171875"/> </location> - <location y="-0.03482578125" name="pixel109"> + <location name="pixel109" y="-0.03482578125"> <neutronic y="-0.03482578125"/> </location> - <location y="-0.03303984375" name="pixel110"> + <location name="pixel110" y="-0.03303984375"> <neutronic y="-0.03303984375"/> </location> - <location y="-0.03125390625" name="pixel111"> + <location name="pixel111" y="-0.03125390625"> <neutronic y="-0.03125390625"/> </location> - <location y="-0.02946796875" name="pixel112"> + <location name="pixel112" y="-0.02946796875"> <neutronic y="-0.02946796875"/> </location> - <location y="-0.02768203125" name="pixel113"> + <location name="pixel113" y="-0.02768203125"> <neutronic y="-0.02768203125"/> </location> - <location y="-0.02589609375" name="pixel114"> + <location name="pixel114" y="-0.02589609375"> <neutronic y="-0.02589609375"/> </location> - <location y="-0.02411015625" name="pixel115"> + <location name="pixel115" y="-0.02411015625"> <neutronic y="-0.02411015625"/> </location> - <location y="-0.02232421875" name="pixel116"> + <location name="pixel116" y="-0.02232421875"> <neutronic y="-0.02232421875"/> </location> - <location y="-0.02053828125" name="pixel117"> + <location name="pixel117" y="-0.02053828125"> <neutronic y="-0.02053828125"/> </location> - <location y="-0.01875234375" name="pixel118"> + <location name="pixel118" y="-0.01875234375"> <neutronic y="-0.01875234375"/> </location> - <location y="-0.01696640625" name="pixel119"> + <location name="pixel119" y="-0.01696640625"> <neutronic y="-0.01696640625"/> </location> - <location y="-0.01518046875" name="pixel120"> + <location name="pixel120" y="-0.01518046875"> <neutronic y="-0.01518046875"/> </location> - <location y="-0.01339453125" name="pixel121"> + <location name="pixel121" y="-0.01339453125"> <neutronic y="-0.01339453125"/> </location> - <location y="-0.01160859375" name="pixel122"> + <location name="pixel122" y="-0.01160859375"> <neutronic y="-0.01160859375"/> </location> - <location y="-0.00982265625" name="pixel123"> + <location name="pixel123" y="-0.00982265625"> <neutronic y="-0.00982265625"/> </location> - <location y="-0.00803671875" name="pixel124"> + <location name="pixel124" y="-0.00803671875"> <neutronic y="-0.00803671875"/> </location> - <location y="-0.00625078125" name="pixel125"> + <location name="pixel125" y="-0.00625078125"> <neutronic y="-0.00625078125"/> </location> - <location y="-0.00446484375" name="pixel126"> + <location name="pixel126" y="-0.00446484375"> <neutronic y="-0.00446484375"/> </location> - <location y="-0.00267890625" name="pixel127"> + <location name="pixel127" y="-0.00267890625"> <neutronic y="-0.00267890625"/> </location> - <location y="-0.00089296875" name="pixel128"> + <location name="pixel128" y="-0.00089296875"> <neutronic y="-0.00089296875"/> </location> - <location y="0.00089296875" name="pixel129"> + <location name="pixel129" y="0.00089296875"> <neutronic y="0.00089296875"/> </location> - <location y="0.00267890625" name="pixel130"> + <location name="pixel130" y="0.00267890625"> <neutronic y="0.00267890625"/> </location> - <location y="0.00446484375" name="pixel131"> + <location name="pixel131" y="0.00446484375"> <neutronic y="0.00446484375"/> </location> - <location y="0.00625078125" name="pixel132"> + <location name="pixel132" y="0.00625078125"> <neutronic y="0.00625078125"/> </location> - <location y="0.00803671875" name="pixel133"> + <location name="pixel133" y="0.00803671875"> <neutronic y="0.00803671875"/> </location> - <location y="0.00982265625" name="pixel134"> + <location name="pixel134" y="0.00982265625"> <neutronic y="0.00982265625"/> </location> - <location y="0.01160859375" name="pixel135"> + <location name="pixel135" y="0.01160859375"> <neutronic y="0.01160859375"/> </location> - <location y="0.01339453125" name="pixel136"> + <location name="pixel136" y="0.01339453125"> <neutronic y="0.01339453125"/> </location> - <location y="0.01518046875" name="pixel137"> + <location name="pixel137" y="0.01518046875"> <neutronic y="0.01518046875"/> </location> - <location y="0.01696640625" name="pixel138"> + <location name="pixel138" y="0.01696640625"> <neutronic y="0.01696640625"/> </location> - <location y="0.01875234375" name="pixel139"> + <location name="pixel139" y="0.01875234375"> <neutronic y="0.01875234375"/> </location> - <location y="0.02053828125" name="pixel140"> + <location name="pixel140" y="0.02053828125"> <neutronic y="0.02053828125"/> </location> - <location y="0.02232421875" name="pixel141"> + <location name="pixel141" y="0.02232421875"> <neutronic y="0.02232421875"/> </location> - <location y="0.02411015625" name="pixel142"> + <location name="pixel142" y="0.02411015625"> <neutronic y="0.02411015625"/> </location> - <location y="0.02589609375" name="pixel143"> + <location name="pixel143" y="0.02589609375"> <neutronic y="0.02589609375"/> </location> - <location y="0.02768203125" name="pixel144"> + <location name="pixel144" y="0.02768203125"> <neutronic y="0.02768203125"/> </location> - <location y="0.02946796875" name="pixel145"> + <location name="pixel145" y="0.02946796875"> <neutronic y="0.02946796875"/> </location> - <location y="0.03125390625" name="pixel146"> + <location name="pixel146" y="0.03125390625"> <neutronic y="0.03125390625"/> </location> - <location y="0.03303984375" name="pixel147"> + <location name="pixel147" y="0.03303984375"> <neutronic y="0.03303984375"/> </location> - <location y="0.03482578125" name="pixel148"> + <location name="pixel148" y="0.03482578125"> <neutronic y="0.03482578125"/> </location> - <location y="0.03661171875" name="pixel149"> + <location name="pixel149" y="0.03661171875"> <neutronic y="0.03661171875"/> </location> - <location y="0.03839765625" name="pixel150"> + <location name="pixel150" y="0.03839765625"> <neutronic y="0.03839765625"/> </location> - <location y="0.04018359375" name="pixel151"> + <location name="pixel151" y="0.04018359375"> <neutronic y="0.04018359375"/> </location> - <location y="0.04196953125" name="pixel152"> + <location name="pixel152" y="0.04196953125"> <neutronic y="0.04196953125"/> </location> - <location y="0.04375546875" name="pixel153"> + <location name="pixel153" y="0.04375546875"> <neutronic y="0.04375546875"/> </location> - <location y="0.04554140625" name="pixel154"> + <location name="pixel154" y="0.04554140625"> <neutronic y="0.04554140625"/> </location> - <location y="0.04732734375" name="pixel155"> + <location name="pixel155" y="0.04732734375"> <neutronic y="0.04732734375"/> </location> - <location y="0.04911328125" name="pixel156"> + <location name="pixel156" y="0.04911328125"> <neutronic y="0.04911328125"/> </location> - <location y="0.05089921875" name="pixel157"> + <location name="pixel157" y="0.05089921875"> <neutronic y="0.05089921875"/> </location> - <location y="0.05268515625" name="pixel158"> + <location name="pixel158" y="0.05268515625"> <neutronic y="0.05268515625"/> </location> - <location y="0.05447109375" name="pixel159"> + <location name="pixel159" y="0.05447109375"> <neutronic y="0.05447109375"/> </location> - <location y="0.05625703125" name="pixel160"> + <location name="pixel160" y="0.05625703125"> <neutronic y="0.05625703125"/> </location> - <location y="0.05804296875" name="pixel161"> + <location name="pixel161" y="0.05804296875"> <neutronic y="0.05804296875"/> </location> - <location y="0.05982890625" name="pixel162"> + <location name="pixel162" y="0.05982890625"> <neutronic y="0.05982890625"/> </location> - <location y="0.06161484375" name="pixel163"> + <location name="pixel163" y="0.06161484375"> <neutronic y="0.06161484375"/> </location> - <location y="0.06340078125" name="pixel164"> + <location name="pixel164" y="0.06340078125"> <neutronic y="0.06340078125"/> </location> - <location y="0.06518671875" name="pixel165"> + <location name="pixel165" y="0.06518671875"> <neutronic y="0.06518671875"/> </location> - <location y="0.06697265625" name="pixel166"> + <location name="pixel166" y="0.06697265625"> <neutronic y="0.06697265625"/> </location> - <location y="0.06875859375" name="pixel167"> + <location name="pixel167" y="0.06875859375"> <neutronic y="0.06875859375"/> </location> - <location y="0.07054453125" name="pixel168"> + <location name="pixel168" y="0.07054453125"> <neutronic y="0.07054453125"/> </location> - <location y="0.07233046875" name="pixel169"> + <location name="pixel169" y="0.07233046875"> <neutronic y="0.07233046875"/> </location> - <location y="0.07411640625" name="pixel170"> + <location name="pixel170" y="0.07411640625"> <neutronic y="0.07411640625"/> </location> - <location y="0.07590234375" name="pixel171"> + <location name="pixel171" y="0.07590234375"> <neutronic y="0.07590234375"/> </location> - <location y="0.07768828125" name="pixel172"> + <location name="pixel172" y="0.07768828125"> <neutronic y="0.07768828125"/> </location> - <location y="0.07947421875" name="pixel173"> + <location name="pixel173" y="0.07947421875"> <neutronic y="0.07947421875"/> </location> - <location y="0.08126015625" name="pixel174"> + <location name="pixel174" y="0.08126015625"> <neutronic y="0.08126015625"/> </location> - <location y="0.08304609375" name="pixel175"> + <location name="pixel175" y="0.08304609375"> <neutronic y="0.08304609375"/> </location> - <location y="0.08483203125" name="pixel176"> + <location name="pixel176" y="0.08483203125"> <neutronic y="0.08483203125"/> </location> - <location y="0.08661796875" name="pixel177"> + <location name="pixel177" y="0.08661796875"> <neutronic y="0.08661796875"/> </location> - <location y="0.08840390625" name="pixel178"> + <location name="pixel178" y="0.08840390625"> <neutronic y="0.08840390625"/> </location> - <location y="0.09018984375" name="pixel179"> + <location name="pixel179" y="0.09018984375"> <neutronic y="0.09018984375"/> </location> - <location y="0.09197578125" name="pixel180"> + <location name="pixel180" y="0.09197578125"> <neutronic y="0.09197578125"/> </location> - <location y="0.09376171875" name="pixel181"> + <location name="pixel181" y="0.09376171875"> <neutronic y="0.09376171875"/> </location> - <location y="0.09554765625" name="pixel182"> + <location name="pixel182" y="0.09554765625"> <neutronic y="0.09554765625"/> </location> - <location y="0.09733359375" name="pixel183"> + <location name="pixel183" y="0.09733359375"> <neutronic y="0.09733359375"/> </location> - <location y="0.09911953125" name="pixel184"> + <location name="pixel184" y="0.09911953125"> <neutronic y="0.09911953125"/> </location> - <location y="0.10090546875" name="pixel185"> + <location name="pixel185" y="0.10090546875"> <neutronic y="0.10090546875"/> </location> - <location y="0.10269140625" name="pixel186"> + <location name="pixel186" y="0.10269140625"> <neutronic y="0.10269140625"/> </location> - <location y="0.10447734375" name="pixel187"> + <location name="pixel187" y="0.10447734375"> <neutronic y="0.10447734375"/> </location> - <location y="0.10626328125" name="pixel188"> + <location name="pixel188" y="0.10626328125"> <neutronic y="0.10626328125"/> </location> - <location y="0.10804921875" name="pixel189"> + <location name="pixel189" y="0.10804921875"> <neutronic y="0.10804921875"/> </location> - <location y="0.10983515625" name="pixel190"> + <location name="pixel190" y="0.10983515625"> <neutronic y="0.10983515625"/> </location> - <location y="0.11162109375" name="pixel191"> + <location name="pixel191" y="0.11162109375"> <neutronic y="0.11162109375"/> </location> - <location y="0.11340703125" name="pixel192"> + <location name="pixel192" y="0.11340703125"> <neutronic y="0.11340703125"/> </location> - <location y="0.11519296875" name="pixel193"> + <location name="pixel193" y="0.11519296875"> <neutronic y="0.11519296875"/> </location> - <location y="0.11697890625" name="pixel194"> + <location name="pixel194" y="0.11697890625"> <neutronic y="0.11697890625"/> </location> - <location y="0.11876484375" name="pixel195"> + <location name="pixel195" y="0.11876484375"> <neutronic y="0.11876484375"/> </location> - <location y="0.12055078125" name="pixel196"> + <location name="pixel196" y="0.12055078125"> <neutronic y="0.12055078125"/> </location> - <location y="0.12233671875" name="pixel197"> + <location name="pixel197" y="0.12233671875"> <neutronic y="0.12233671875"/> </location> - <location y="0.12412265625" name="pixel198"> + <location name="pixel198" y="0.12412265625"> <neutronic y="0.12412265625"/> </location> - <location y="0.12590859375" name="pixel199"> + <location name="pixel199" y="0.12590859375"> <neutronic y="0.12590859375"/> </location> - <location y="0.12769453125" name="pixel200"> + <location name="pixel200" y="0.12769453125"> <neutronic y="0.12769453125"/> </location> - <location y="0.12948046875" name="pixel201"> + <location name="pixel201" y="0.12948046875"> <neutronic y="0.12948046875"/> </location> - <location y="0.13126640625" name="pixel202"> + <location name="pixel202" y="0.13126640625"> <neutronic y="0.13126640625"/> </location> - <location y="0.13305234375" name="pixel203"> + <location name="pixel203" y="0.13305234375"> <neutronic y="0.13305234375"/> </location> - <location y="0.13483828125" name="pixel204"> + <location name="pixel204" y="0.13483828125"> <neutronic y="0.13483828125"/> </location> - <location y="0.13662421875" name="pixel205"> + <location name="pixel205" y="0.13662421875"> <neutronic y="0.13662421875"/> </location> - <location y="0.13841015625" name="pixel206"> + <location name="pixel206" y="0.13841015625"> <neutronic y="0.13841015625"/> </location> - <location y="0.14019609375" name="pixel207"> + <location name="pixel207" y="0.14019609375"> <neutronic y="0.14019609375"/> </location> - <location y="0.14198203125" name="pixel208"> + <location name="pixel208" y="0.14198203125"> <neutronic y="0.14198203125"/> </location> - <location y="0.14376796875" name="pixel209"> + <location name="pixel209" y="0.14376796875"> <neutronic y="0.14376796875"/> </location> - <location y="0.14555390625" name="pixel210"> + <location name="pixel210" y="0.14555390625"> <neutronic y="0.14555390625"/> </location> - <location y="0.14733984375" name="pixel211"> + <location name="pixel211" y="0.14733984375"> <neutronic y="0.14733984375"/> </location> - <location y="0.14912578125" name="pixel212"> + <location name="pixel212" y="0.14912578125"> <neutronic y="0.14912578125"/> </location> - <location y="0.15091171875" name="pixel213"> + <location name="pixel213" y="0.15091171875"> <neutronic y="0.15091171875"/> </location> - <location y="0.15269765625" name="pixel214"> + <location name="pixel214" y="0.15269765625"> <neutronic y="0.15269765625"/> </location> - <location y="0.15448359375" name="pixel215"> + <location name="pixel215" y="0.15448359375"> <neutronic y="0.15448359375"/> </location> - <location y="0.15626953125" name="pixel216"> + <location name="pixel216" y="0.15626953125"> <neutronic y="0.15626953125"/> </location> - <location y="0.15805546875" name="pixel217"> + <location name="pixel217" y="0.15805546875"> <neutronic y="0.15805546875"/> </location> - <location y="0.15984140625" name="pixel218"> + <location name="pixel218" y="0.15984140625"> <neutronic y="0.15984140625"/> </location> - <location y="0.16162734375" name="pixel219"> + <location name="pixel219" y="0.16162734375"> <neutronic y="0.16162734375"/> </location> - <location y="0.16341328125" name="pixel220"> + <location name="pixel220" y="0.16341328125"> <neutronic y="0.16341328125"/> </location> - <location y="0.16519921875" name="pixel221"> + <location name="pixel221" y="0.16519921875"> <neutronic y="0.16519921875"/> </location> - <location y="0.16698515625" name="pixel222"> + <location name="pixel222" y="0.16698515625"> <neutronic y="0.16698515625"/> </location> - <location y="0.16877109375" name="pixel223"> + <location name="pixel223" y="0.16877109375"> <neutronic y="0.16877109375"/> </location> - <location y="0.17055703125" name="pixel224"> + <location name="pixel224" y="0.17055703125"> <neutronic y="0.17055703125"/> </location> - <location y="0.17234296875" name="pixel225"> + <location name="pixel225" y="0.17234296875"> <neutronic y="0.17234296875"/> </location> - <location y="0.17412890625" name="pixel226"> + <location name="pixel226" y="0.17412890625"> <neutronic y="0.17412890625"/> </location> - <location y="0.17591484375" name="pixel227"> + <location name="pixel227" y="0.17591484375"> <neutronic y="0.17591484375"/> </location> - <location y="0.17770078125" name="pixel228"> + <location name="pixel228" y="0.17770078125"> <neutronic y="0.17770078125"/> </location> - <location y="0.17948671875" name="pixel229"> + <location name="pixel229" y="0.17948671875"> <neutronic y="0.17948671875"/> </location> - <location y="0.18127265625" name="pixel230"> + <location name="pixel230" y="0.18127265625"> <neutronic y="0.18127265625"/> </location> - <location y="0.18305859375" name="pixel231"> + <location name="pixel231" y="0.18305859375"> <neutronic y="0.18305859375"/> </location> - <location y="0.18484453125" name="pixel232"> + <location name="pixel232" y="0.18484453125"> <neutronic y="0.18484453125"/> </location> - <location y="0.18663046875" name="pixel233"> + <location name="pixel233" y="0.18663046875"> <neutronic y="0.18663046875"/> </location> - <location y="0.18841640625" name="pixel234"> + <location name="pixel234" y="0.18841640625"> <neutronic y="0.18841640625"/> </location> - <location y="0.19020234375" name="pixel235"> + <location name="pixel235" y="0.19020234375"> <neutronic y="0.19020234375"/> </location> - <location y="0.19198828125" name="pixel236"> + <location name="pixel236" y="0.19198828125"> <neutronic y="0.19198828125"/> </location> - <location y="0.19377421875" name="pixel237"> + <location name="pixel237" y="0.19377421875"> <neutronic y="0.19377421875"/> </location> - <location y="0.19556015625" name="pixel238"> + <location name="pixel238" y="0.19556015625"> <neutronic y="0.19556015625"/> </location> - <location y="0.19734609375" name="pixel239"> + <location name="pixel239" y="0.19734609375"> <neutronic y="0.19734609375"/> </location> - <location y="0.19913203125" name="pixel240"> + <location name="pixel240" y="0.19913203125"> <neutronic y="0.19913203125"/> </location> - <location y="0.20091796875" name="pixel241"> + <location name="pixel241" y="0.20091796875"> <neutronic y="0.20091796875"/> </location> - <location y="0.20270390625" name="pixel242"> + <location name="pixel242" y="0.20270390625"> <neutronic y="0.20270390625"/> </location> - <location y="0.20448984375" name="pixel243"> + <location name="pixel243" y="0.20448984375"> <neutronic y="0.20448984375"/> </location> - <location y="0.20627578125" name="pixel244"> + <location name="pixel244" y="0.20627578125"> <neutronic y="0.20627578125"/> </location> - <location y="0.20806171875" name="pixel245"> + <location name="pixel245" y="0.20806171875"> <neutronic y="0.20806171875"/> </location> - <location y="0.20984765625" name="pixel246"> + <location name="pixel246" y="0.20984765625"> <neutronic y="0.20984765625"/> </location> - <location y="0.21163359375" name="pixel247"> + <location name="pixel247" y="0.21163359375"> <neutronic y="0.21163359375"/> </location> - <location y="0.21341953125" name="pixel248"> + <location name="pixel248" y="0.21341953125"> <neutronic y="0.21341953125"/> </location> - <location y="0.21520546875" name="pixel249"> + <location name="pixel249" y="0.21520546875"> <neutronic y="0.21520546875"/> </location> - <location y="0.21699140625" name="pixel250"> + <location name="pixel250" y="0.21699140625"> <neutronic y="0.21699140625"/> </location> - <location y="0.21877734375" name="pixel251"> + <location name="pixel251" y="0.21877734375"> <neutronic y="0.21877734375"/> </location> - <location y="0.22056328125" name="pixel252"> + <location name="pixel252" y="0.22056328125"> <neutronic y="0.22056328125"/> </location> - <location y="0.22234921875" name="pixel253"> + <location name="pixel253" y="0.22234921875"> <neutronic y="0.22234921875"/> </location> - <location y="0.22413515625" name="pixel254"> + <location name="pixel254" y="0.22413515625"> <neutronic y="0.22413515625"/> </location> - <location y="0.22592109375" name="pixel255"> + <location name="pixel255" y="0.22592109375"> <neutronic y="0.22592109375"/> </location> - <location y="0.22770703125" name="pixel256"> + <location name="pixel256" y="0.22770703125"> <neutronic y="0.22770703125"/> </location> </component> @@ -2792,772 +2722,772 @@ <type name="tube-short-bs-elastic" outline="yes"> <properties/> <component type="pixel-bs-elastic-short-tube"> - <location y="-0.189755859375" name="pixel1"> + <location name="pixel1" y="-0.189755859375"> <neutronic y="-0.189755859375"/> </location> - <location y="-0.188267578125" name="pixel2"> + <location name="pixel2" y="-0.188267578125"> <neutronic y="-0.188267578125"/> </location> - <location y="-0.186779296875" name="pixel3"> + <location name="pixel3" y="-0.186779296875"> <neutronic y="-0.186779296875"/> </location> - <location y="-0.185291015625" name="pixel4"> + <location name="pixel4" y="-0.185291015625"> <neutronic y="-0.185291015625"/> </location> - <location y="-0.183802734375" name="pixel5"> + <location name="pixel5" y="-0.183802734375"> <neutronic y="-0.183802734375"/> </location> - <location y="-0.182314453125" name="pixel6"> + <location name="pixel6" y="-0.182314453125"> <neutronic y="-0.182314453125"/> </location> - <location y="-0.180826171875" name="pixel7"> + <location name="pixel7" y="-0.180826171875"> <neutronic y="-0.180826171875"/> </location> - <location y="-0.179337890625" name="pixel8"> + <location name="pixel8" y="-0.179337890625"> <neutronic y="-0.179337890625"/> </location> - <location y="-0.177849609375" name="pixel9"> + <location name="pixel9" y="-0.177849609375"> <neutronic y="-0.177849609375"/> </location> - <location y="-0.176361328125" name="pixel10"> + <location name="pixel10" y="-0.176361328125"> <neutronic y="-0.176361328125"/> </location> - <location y="-0.174873046875" name="pixel11"> + <location name="pixel11" y="-0.174873046875"> <neutronic y="-0.174873046875"/> </location> - <location y="-0.173384765625" name="pixel12"> + <location name="pixel12" y="-0.173384765625"> <neutronic y="-0.173384765625"/> </location> - <location y="-0.171896484375" name="pixel13"> + <location name="pixel13" y="-0.171896484375"> <neutronic y="-0.171896484375"/> </location> - <location y="-0.170408203125" name="pixel14"> + <location name="pixel14" y="-0.170408203125"> <neutronic y="-0.170408203125"/> </location> - <location y="-0.168919921875" name="pixel15"> + <location name="pixel15" y="-0.168919921875"> <neutronic y="-0.168919921875"/> </location> - <location y="-0.167431640625" name="pixel16"> + <location name="pixel16" y="-0.167431640625"> <neutronic y="-0.167431640625"/> </location> - <location y="-0.165943359375" name="pixel17"> + <location name="pixel17" y="-0.165943359375"> <neutronic y="-0.165943359375"/> </location> - <location y="-0.164455078125" name="pixel18"> + <location name="pixel18" y="-0.164455078125"> <neutronic y="-0.164455078125"/> </location> - <location y="-0.162966796875" name="pixel19"> + <location name="pixel19" y="-0.162966796875"> <neutronic y="-0.162966796875"/> </location> - <location y="-0.161478515625" name="pixel20"> + <location name="pixel20" y="-0.161478515625"> <neutronic y="-0.161478515625"/> </location> - <location y="-0.159990234375" name="pixel21"> + <location name="pixel21" y="-0.159990234375"> <neutronic y="-0.159990234375"/> </location> - <location y="-0.158501953125" name="pixel22"> + <location name="pixel22" y="-0.158501953125"> <neutronic y="-0.158501953125"/> </location> - <location y="-0.157013671875" name="pixel23"> + <location name="pixel23" y="-0.157013671875"> <neutronic y="-0.157013671875"/> </location> - <location y="-0.155525390625" name="pixel24"> + <location name="pixel24" y="-0.155525390625"> <neutronic y="-0.155525390625"/> </location> - <location y="-0.154037109375" name="pixel25"> + <location name="pixel25" y="-0.154037109375"> <neutronic y="-0.154037109375"/> </location> - <location y="-0.152548828125" name="pixel26"> + <location name="pixel26" y="-0.152548828125"> <neutronic y="-0.152548828125"/> </location> - <location y="-0.151060546875" name="pixel27"> + <location name="pixel27" y="-0.151060546875"> <neutronic y="-0.151060546875"/> </location> - <location y="-0.149572265625" name="pixel28"> + <location name="pixel28" y="-0.149572265625"> <neutronic y="-0.149572265625"/> </location> - <location y="-0.148083984375" name="pixel29"> + <location name="pixel29" y="-0.148083984375"> <neutronic y="-0.148083984375"/> </location> - <location y="-0.146595703125" name="pixel30"> + <location name="pixel30" y="-0.146595703125"> <neutronic y="-0.146595703125"/> </location> - <location y="-0.145107421875" name="pixel31"> + <location name="pixel31" y="-0.145107421875"> <neutronic y="-0.145107421875"/> </location> - <location y="-0.143619140625" name="pixel32"> + <location name="pixel32" y="-0.143619140625"> <neutronic y="-0.143619140625"/> </location> - <location y="-0.142130859375" name="pixel33"> + <location name="pixel33" y="-0.142130859375"> <neutronic y="-0.142130859375"/> </location> - <location y="-0.140642578125" name="pixel34"> + <location name="pixel34" y="-0.140642578125"> <neutronic y="-0.140642578125"/> </location> - <location y="-0.139154296875" name="pixel35"> + <location name="pixel35" y="-0.139154296875"> <neutronic y="-0.139154296875"/> </location> - <location y="-0.137666015625" name="pixel36"> + <location name="pixel36" y="-0.137666015625"> <neutronic y="-0.137666015625"/> </location> - <location y="-0.136177734375" name="pixel37"> + <location name="pixel37" y="-0.136177734375"> <neutronic y="-0.136177734375"/> </location> - <location y="-0.134689453125" name="pixel38"> + <location name="pixel38" y="-0.134689453125"> <neutronic y="-0.134689453125"/> </location> - <location y="-0.133201171875" name="pixel39"> + <location name="pixel39" y="-0.133201171875"> <neutronic y="-0.133201171875"/> </location> - <location y="-0.131712890625" name="pixel40"> + <location name="pixel40" y="-0.131712890625"> <neutronic y="-0.131712890625"/> </location> - <location y="-0.130224609375" name="pixel41"> + <location name="pixel41" y="-0.130224609375"> <neutronic y="-0.130224609375"/> </location> - <location y="-0.128736328125" name="pixel42"> + <location name="pixel42" y="-0.128736328125"> <neutronic y="-0.128736328125"/> </location> - <location y="-0.127248046875" name="pixel43"> + <location name="pixel43" y="-0.127248046875"> <neutronic y="-0.127248046875"/> </location> - <location y="-0.125759765625" name="pixel44"> + <location name="pixel44" y="-0.125759765625"> <neutronic y="-0.125759765625"/> </location> - <location y="-0.124271484375" name="pixel45"> + <location name="pixel45" y="-0.124271484375"> <neutronic y="-0.124271484375"/> </location> - <location y="-0.122783203125" name="pixel46"> + <location name="pixel46" y="-0.122783203125"> <neutronic y="-0.122783203125"/> </location> - <location y="-0.121294921875" name="pixel47"> + <location name="pixel47" y="-0.121294921875"> <neutronic y="-0.121294921875"/> </location> - <location y="-0.119806640625" name="pixel48"> + <location name="pixel48" y="-0.119806640625"> <neutronic y="-0.119806640625"/> </location> - <location y="-0.118318359375" name="pixel49"> + <location name="pixel49" y="-0.118318359375"> <neutronic y="-0.118318359375"/> </location> - <location y="-0.116830078125" name="pixel50"> + <location name="pixel50" y="-0.116830078125"> <neutronic y="-0.116830078125"/> </location> - <location y="-0.115341796875" name="pixel51"> + <location name="pixel51" y="-0.115341796875"> <neutronic y="-0.115341796875"/> </location> - <location y="-0.113853515625" name="pixel52"> + <location name="pixel52" y="-0.113853515625"> <neutronic y="-0.113853515625"/> </location> - <location y="-0.112365234375" name="pixel53"> + <location name="pixel53" y="-0.112365234375"> <neutronic y="-0.112365234375"/> </location> - <location y="-0.110876953125" name="pixel54"> + <location name="pixel54" y="-0.110876953125"> <neutronic y="-0.110876953125"/> </location> - <location y="-0.109388671875" name="pixel55"> + <location name="pixel55" y="-0.109388671875"> <neutronic y="-0.109388671875"/> </location> - <location y="-0.107900390625" name="pixel56"> + <location name="pixel56" y="-0.107900390625"> <neutronic y="-0.107900390625"/> </location> - <location y="-0.106412109375" name="pixel57"> + <location name="pixel57" y="-0.106412109375"> <neutronic y="-0.106412109375"/> </location> - <location y="-0.104923828125" name="pixel58"> + <location name="pixel58" y="-0.104923828125"> <neutronic y="-0.104923828125"/> </location> - <location y="-0.103435546875" name="pixel59"> + <location name="pixel59" y="-0.103435546875"> <neutronic y="-0.103435546875"/> </location> - <location y="-0.101947265625" name="pixel60"> + <location name="pixel60" y="-0.101947265625"> <neutronic y="-0.101947265625"/> </location> - <location y="-0.100458984375" name="pixel61"> + <location name="pixel61" y="-0.100458984375"> <neutronic y="-0.100458984375"/> </location> - <location y="-0.098970703125" name="pixel62"> + <location name="pixel62" y="-0.098970703125"> <neutronic y="-0.098970703125"/> </location> - <location y="-0.097482421875" name="pixel63"> + <location name="pixel63" y="-0.097482421875"> <neutronic y="-0.097482421875"/> </location> - <location y="-0.095994140625" name="pixel64"> + <location name="pixel64" y="-0.095994140625"> <neutronic y="-0.095994140625"/> </location> - <location y="-0.094505859375" name="pixel65"> + <location name="pixel65" y="-0.094505859375"> <neutronic y="-0.094505859375"/> </location> - <location y="-0.093017578125" name="pixel66"> + <location name="pixel66" y="-0.093017578125"> <neutronic y="-0.093017578125"/> </location> - <location y="-0.091529296875" name="pixel67"> + <location name="pixel67" y="-0.091529296875"> <neutronic y="-0.091529296875"/> </location> - <location y="-0.090041015625" name="pixel68"> + <location name="pixel68" y="-0.090041015625"> <neutronic y="-0.090041015625"/> </location> - <location y="-0.088552734375" name="pixel69"> + <location name="pixel69" y="-0.088552734375"> <neutronic y="-0.088552734375"/> </location> - <location y="-0.087064453125" name="pixel70"> + <location name="pixel70" y="-0.087064453125"> <neutronic y="-0.087064453125"/> </location> - <location y="-0.085576171875" name="pixel71"> + <location name="pixel71" y="-0.085576171875"> <neutronic y="-0.085576171875"/> </location> - <location y="-0.084087890625" name="pixel72"> + <location name="pixel72" y="-0.084087890625"> <neutronic y="-0.084087890625"/> </location> - <location y="-0.082599609375" name="pixel73"> + <location name="pixel73" y="-0.082599609375"> <neutronic y="-0.082599609375"/> </location> - <location y="-0.081111328125" name="pixel74"> + <location name="pixel74" y="-0.081111328125"> <neutronic y="-0.081111328125"/> </location> - <location y="-0.079623046875" name="pixel75"> + <location name="pixel75" y="-0.079623046875"> <neutronic y="-0.079623046875"/> </location> - <location y="-0.078134765625" name="pixel76"> + <location name="pixel76" y="-0.078134765625"> <neutronic y="-0.078134765625"/> </location> - <location y="-0.076646484375" name="pixel77"> + <location name="pixel77" y="-0.076646484375"> <neutronic y="-0.076646484375"/> </location> - <location y="-0.075158203125" name="pixel78"> + <location name="pixel78" y="-0.075158203125"> <neutronic y="-0.075158203125"/> </location> - <location y="-0.073669921875" name="pixel79"> + <location name="pixel79" y="-0.073669921875"> <neutronic y="-0.073669921875"/> </location> - <location y="-0.072181640625" name="pixel80"> + <location name="pixel80" y="-0.072181640625"> <neutronic y="-0.072181640625"/> </location> - <location y="-0.070693359375" name="pixel81"> + <location name="pixel81" y="-0.070693359375"> <neutronic y="-0.070693359375"/> </location> - <location y="-0.069205078125" name="pixel82"> + <location name="pixel82" y="-0.069205078125"> <neutronic y="-0.069205078125"/> </location> - <location y="-0.067716796875" name="pixel83"> + <location name="pixel83" y="-0.067716796875"> <neutronic y="-0.067716796875"/> </location> - <location y="-0.066228515625" name="pixel84"> + <location name="pixel84" y="-0.066228515625"> <neutronic y="-0.066228515625"/> </location> - <location y="-0.064740234375" name="pixel85"> + <location name="pixel85" y="-0.064740234375"> <neutronic y="-0.064740234375"/> </location> - <location y="-0.063251953125" name="pixel86"> + <location name="pixel86" y="-0.063251953125"> <neutronic y="-0.063251953125"/> </location> - <location y="-0.061763671875" name="pixel87"> + <location name="pixel87" y="-0.061763671875"> <neutronic y="-0.061763671875"/> </location> - <location y="-0.060275390625" name="pixel88"> + <location name="pixel88" y="-0.060275390625"> <neutronic y="-0.060275390625"/> </location> - <location y="-0.058787109375" name="pixel89"> + <location name="pixel89" y="-0.058787109375"> <neutronic y="-0.058787109375"/> </location> - <location y="-0.057298828125" name="pixel90"> + <location name="pixel90" y="-0.057298828125"> <neutronic y="-0.057298828125"/> </location> - <location y="-0.055810546875" name="pixel91"> + <location name="pixel91" y="-0.055810546875"> <neutronic y="-0.055810546875"/> </location> - <location y="-0.054322265625" name="pixel92"> + <location name="pixel92" y="-0.054322265625"> <neutronic y="-0.054322265625"/> </location> - <location y="-0.052833984375" name="pixel93"> + <location name="pixel93" y="-0.052833984375"> <neutronic y="-0.052833984375"/> </location> - <location y="-0.051345703125" name="pixel94"> + <location name="pixel94" y="-0.051345703125"> <neutronic y="-0.051345703125"/> </location> - <location y="-0.049857421875" name="pixel95"> + <location name="pixel95" y="-0.049857421875"> <neutronic y="-0.049857421875"/> </location> - <location y="-0.048369140625" name="pixel96"> + <location name="pixel96" y="-0.048369140625"> <neutronic y="-0.048369140625"/> </location> - <location y="-0.046880859375" name="pixel97"> + <location name="pixel97" y="-0.046880859375"> <neutronic y="-0.046880859375"/> </location> - <location y="-0.045392578125" name="pixel98"> + <location name="pixel98" y="-0.045392578125"> <neutronic y="-0.045392578125"/> </location> - <location y="-0.043904296875" name="pixel99"> + <location name="pixel99" y="-0.043904296875"> <neutronic y="-0.043904296875"/> </location> - <location y="-0.042416015625" name="pixel100"> + <location name="pixel100" y="-0.042416015625"> <neutronic y="-0.042416015625"/> </location> - <location y="-0.040927734375" name="pixel101"> + <location name="pixel101" y="-0.040927734375"> <neutronic y="-0.040927734375"/> </location> - <location y="-0.039439453125" name="pixel102"> + <location name="pixel102" y="-0.039439453125"> <neutronic y="-0.039439453125"/> </location> - <location y="-0.037951171875" name="pixel103"> + <location name="pixel103" y="-0.037951171875"> <neutronic y="-0.037951171875"/> </location> - <location y="-0.036462890625" name="pixel104"> + <location name="pixel104" y="-0.036462890625"> <neutronic y="-0.036462890625"/> </location> - <location y="-0.034974609375" name="pixel105"> + <location name="pixel105" y="-0.034974609375"> <neutronic y="-0.034974609375"/> </location> - <location y="-0.033486328125" name="pixel106"> + <location name="pixel106" y="-0.033486328125"> <neutronic y="-0.033486328125"/> </location> - <location y="-0.031998046875" name="pixel107"> + <location name="pixel107" y="-0.031998046875"> <neutronic y="-0.031998046875"/> </location> - <location y="-0.030509765625" name="pixel108"> + <location name="pixel108" y="-0.030509765625"> <neutronic y="-0.030509765625"/> </location> - <location y="-0.029021484375" name="pixel109"> + <location name="pixel109" y="-0.029021484375"> <neutronic y="-0.029021484375"/> </location> - <location y="-0.027533203125" name="pixel110"> + <location name="pixel110" y="-0.027533203125"> <neutronic y="-0.027533203125"/> </location> - <location y="-0.026044921875" name="pixel111"> + <location name="pixel111" y="-0.026044921875"> <neutronic y="-0.026044921875"/> </location> - <location y="-0.024556640625" name="pixel112"> + <location name="pixel112" y="-0.024556640625"> <neutronic y="-0.024556640625"/> </location> - <location y="-0.023068359375" name="pixel113"> + <location name="pixel113" y="-0.023068359375"> <neutronic y="-0.023068359375"/> </location> - <location y="-0.021580078125" name="pixel114"> + <location name="pixel114" y="-0.021580078125"> <neutronic y="-0.021580078125"/> </location> - <location y="-0.020091796875" name="pixel115"> + <location name="pixel115" y="-0.020091796875"> <neutronic y="-0.020091796875"/> </location> - <location y="-0.018603515625" name="pixel116"> + <location name="pixel116" y="-0.018603515625"> <neutronic y="-0.018603515625"/> </location> - <location y="-0.017115234375" name="pixel117"> + <location name="pixel117" y="-0.017115234375"> <neutronic y="-0.017115234375"/> </location> - <location y="-0.015626953125" name="pixel118"> + <location name="pixel118" y="-0.015626953125"> <neutronic y="-0.015626953125"/> </location> - <location y="-0.014138671875" name="pixel119"> + <location name="pixel119" y="-0.014138671875"> <neutronic y="-0.014138671875"/> </location> - <location y="-0.012650390625" name="pixel120"> + <location name="pixel120" y="-0.012650390625"> <neutronic y="-0.012650390625"/> </location> - <location y="-0.011162109375" name="pixel121"> + <location name="pixel121" y="-0.011162109375"> <neutronic y="-0.011162109375"/> </location> - <location y="-0.009673828125" name="pixel122"> + <location name="pixel122" y="-0.009673828125"> <neutronic y="-0.009673828125"/> </location> - <location y="-0.008185546875" name="pixel123"> + <location name="pixel123" y="-0.008185546875"> <neutronic y="-0.008185546875"/> </location> - <location y="-0.006697265625" name="pixel124"> + <location name="pixel124" y="-0.006697265625"> <neutronic y="-0.006697265625"/> </location> - <location y="-0.005208984375" name="pixel125"> + <location name="pixel125" y="-0.005208984375"> <neutronic y="-0.005208984375"/> </location> - <location y="-0.003720703125" name="pixel126"> + <location name="pixel126" y="-0.003720703125"> <neutronic y="-0.003720703125"/> </location> - <location y="-0.002232421875" name="pixel127"> + <location name="pixel127" y="-0.002232421875"> <neutronic y="-0.002232421875"/> </location> - <location y="-0.000744140625" name="pixel128"> + <location name="pixel128" y="-0.000744140625"> <neutronic y="-0.000744140625"/> </location> - <location y="0.000744140625" name="pixel129"> + <location name="pixel129" y="0.000744140625"> <neutronic y="0.000744140625"/> </location> - <location y="0.002232421875" name="pixel130"> + <location name="pixel130" y="0.002232421875"> <neutronic y="0.002232421875"/> </location> - <location y="0.003720703125" name="pixel131"> + <location name="pixel131" y="0.003720703125"> <neutronic y="0.003720703125"/> </location> - <location y="0.005208984375" name="pixel132"> + <location name="pixel132" y="0.005208984375"> <neutronic y="0.005208984375"/> </location> - <location y="0.006697265625" name="pixel133"> + <location name="pixel133" y="0.006697265625"> <neutronic y="0.006697265625"/> </location> - <location y="0.008185546875" name="pixel134"> + <location name="pixel134" y="0.008185546875"> <neutronic y="0.008185546875"/> </location> - <location y="0.009673828125" name="pixel135"> + <location name="pixel135" y="0.009673828125"> <neutronic y="0.009673828125"/> </location> - <location y="0.011162109375" name="pixel136"> + <location name="pixel136" y="0.011162109375"> <neutronic y="0.011162109375"/> </location> - <location y="0.012650390625" name="pixel137"> + <location name="pixel137" y="0.012650390625"> <neutronic y="0.012650390625"/> </location> - <location y="0.014138671875" name="pixel138"> + <location name="pixel138" y="0.014138671875"> <neutronic y="0.014138671875"/> </location> - <location y="0.015626953125" name="pixel139"> + <location name="pixel139" y="0.015626953125"> <neutronic y="0.015626953125"/> </location> - <location y="0.017115234375" name="pixel140"> + <location name="pixel140" y="0.017115234375"> <neutronic y="0.017115234375"/> </location> - <location y="0.018603515625" name="pixel141"> + <location name="pixel141" y="0.018603515625"> <neutronic y="0.018603515625"/> </location> - <location y="0.020091796875" name="pixel142"> + <location name="pixel142" y="0.020091796875"> <neutronic y="0.020091796875"/> </location> - <location y="0.021580078125" name="pixel143"> + <location name="pixel143" y="0.021580078125"> <neutronic y="0.021580078125"/> </location> - <location y="0.023068359375" name="pixel144"> + <location name="pixel144" y="0.023068359375"> <neutronic y="0.023068359375"/> </location> - <location y="0.024556640625" name="pixel145"> + <location name="pixel145" y="0.024556640625"> <neutronic y="0.024556640625"/> </location> - <location y="0.026044921875" name="pixel146"> + <location name="pixel146" y="0.026044921875"> <neutronic y="0.026044921875"/> </location> - <location y="0.027533203125" name="pixel147"> + <location name="pixel147" y="0.027533203125"> <neutronic y="0.027533203125"/> </location> - <location y="0.029021484375" name="pixel148"> + <location name="pixel148" y="0.029021484375"> <neutronic y="0.029021484375"/> </location> - <location y="0.030509765625" name="pixel149"> + <location name="pixel149" y="0.030509765625"> <neutronic y="0.030509765625"/> </location> - <location y="0.031998046875" name="pixel150"> + <location name="pixel150" y="0.031998046875"> <neutronic y="0.031998046875"/> </location> - <location y="0.033486328125" name="pixel151"> + <location name="pixel151" y="0.033486328125"> <neutronic y="0.033486328125"/> </location> - <location y="0.034974609375" name="pixel152"> + <location name="pixel152" y="0.034974609375"> <neutronic y="0.034974609375"/> </location> - <location y="0.036462890625" name="pixel153"> + <location name="pixel153" y="0.036462890625"> <neutronic y="0.036462890625"/> </location> - <location y="0.037951171875" name="pixel154"> + <location name="pixel154" y="0.037951171875"> <neutronic y="0.037951171875"/> </location> - <location y="0.039439453125" name="pixel155"> + <location name="pixel155" y="0.039439453125"> <neutronic y="0.039439453125"/> </location> - <location y="0.040927734375" name="pixel156"> + <location name="pixel156" y="0.040927734375"> <neutronic y="0.040927734375"/> </location> - <location y="0.042416015625" name="pixel157"> + <location name="pixel157" y="0.042416015625"> <neutronic y="0.042416015625"/> </location> - <location y="0.043904296875" name="pixel158"> + <location name="pixel158" y="0.043904296875"> <neutronic y="0.043904296875"/> </location> - <location y="0.045392578125" name="pixel159"> + <location name="pixel159" y="0.045392578125"> <neutronic y="0.045392578125"/> </location> - <location y="0.046880859375" name="pixel160"> + <location name="pixel160" y="0.046880859375"> <neutronic y="0.046880859375"/> </location> - <location y="0.048369140625" name="pixel161"> + <location name="pixel161" y="0.048369140625"> <neutronic y="0.048369140625"/> </location> - <location y="0.049857421875" name="pixel162"> + <location name="pixel162" y="0.049857421875"> <neutronic y="0.049857421875"/> </location> - <location y="0.051345703125" name="pixel163"> + <location name="pixel163" y="0.051345703125"> <neutronic y="0.051345703125"/> </location> - <location y="0.052833984375" name="pixel164"> + <location name="pixel164" y="0.052833984375"> <neutronic y="0.052833984375"/> </location> - <location y="0.054322265625" name="pixel165"> + <location name="pixel165" y="0.054322265625"> <neutronic y="0.054322265625"/> </location> - <location y="0.055810546875" name="pixel166"> + <location name="pixel166" y="0.055810546875"> <neutronic y="0.055810546875"/> </location> - <location y="0.057298828125" name="pixel167"> + <location name="pixel167" y="0.057298828125"> <neutronic y="0.057298828125"/> </location> - <location y="0.058787109375" name="pixel168"> + <location name="pixel168" y="0.058787109375"> <neutronic y="0.058787109375"/> </location> - <location y="0.060275390625" name="pixel169"> + <location name="pixel169" y="0.060275390625"> <neutronic y="0.060275390625"/> </location> - <location y="0.061763671875" name="pixel170"> + <location name="pixel170" y="0.061763671875"> <neutronic y="0.061763671875"/> </location> - <location y="0.063251953125" name="pixel171"> + <location name="pixel171" y="0.063251953125"> <neutronic y="0.063251953125"/> </location> - <location y="0.064740234375" name="pixel172"> + <location name="pixel172" y="0.064740234375"> <neutronic y="0.064740234375"/> </location> - <location y="0.066228515625" name="pixel173"> + <location name="pixel173" y="0.066228515625"> <neutronic y="0.066228515625"/> </location> - <location y="0.067716796875" name="pixel174"> + <location name="pixel174" y="0.067716796875"> <neutronic y="0.067716796875"/> </location> - <location y="0.069205078125" name="pixel175"> + <location name="pixel175" y="0.069205078125"> <neutronic y="0.069205078125"/> </location> - <location y="0.070693359375" name="pixel176"> + <location name="pixel176" y="0.070693359375"> <neutronic y="0.070693359375"/> </location> - <location y="0.072181640625" name="pixel177"> + <location name="pixel177" y="0.072181640625"> <neutronic y="0.072181640625"/> </location> - <location y="0.073669921875" name="pixel178"> + <location name="pixel178" y="0.073669921875"> <neutronic y="0.073669921875"/> </location> - <location y="0.075158203125" name="pixel179"> + <location name="pixel179" y="0.075158203125"> <neutronic y="0.075158203125"/> </location> - <location y="0.076646484375" name="pixel180"> + <location name="pixel180" y="0.076646484375"> <neutronic y="0.076646484375"/> </location> - <location y="0.078134765625" name="pixel181"> + <location name="pixel181" y="0.078134765625"> <neutronic y="0.078134765625"/> </location> - <location y="0.079623046875" name="pixel182"> + <location name="pixel182" y="0.079623046875"> <neutronic y="0.079623046875"/> </location> - <location y="0.081111328125" name="pixel183"> + <location name="pixel183" y="0.081111328125"> <neutronic y="0.081111328125"/> </location> - <location y="0.082599609375" name="pixel184"> + <location name="pixel184" y="0.082599609375"> <neutronic y="0.082599609375"/> </location> - <location y="0.084087890625" name="pixel185"> + <location name="pixel185" y="0.084087890625"> <neutronic y="0.084087890625"/> </location> - <location y="0.085576171875" name="pixel186"> + <location name="pixel186" y="0.085576171875"> <neutronic y="0.085576171875"/> </location> - <location y="0.087064453125" name="pixel187"> + <location name="pixel187" y="0.087064453125"> <neutronic y="0.087064453125"/> </location> - <location y="0.088552734375" name="pixel188"> + <location name="pixel188" y="0.088552734375"> <neutronic y="0.088552734375"/> </location> - <location y="0.090041015625" name="pixel189"> + <location name="pixel189" y="0.090041015625"> <neutronic y="0.090041015625"/> </location> - <location y="0.091529296875" name="pixel190"> + <location name="pixel190" y="0.091529296875"> <neutronic y="0.091529296875"/> </location> - <location y="0.093017578125" name="pixel191"> + <location name="pixel191" y="0.093017578125"> <neutronic y="0.093017578125"/> </location> - <location y="0.094505859375" name="pixel192"> + <location name="pixel192" y="0.094505859375"> <neutronic y="0.094505859375"/> </location> - <location y="0.095994140625" name="pixel193"> + <location name="pixel193" y="0.095994140625"> <neutronic y="0.095994140625"/> </location> - <location y="0.097482421875" name="pixel194"> + <location name="pixel194" y="0.097482421875"> <neutronic y="0.097482421875"/> </location> - <location y="0.098970703125" name="pixel195"> + <location name="pixel195" y="0.098970703125"> <neutronic y="0.098970703125"/> </location> - <location y="0.100458984375" name="pixel196"> + <location name="pixel196" y="0.100458984375"> <neutronic y="0.100458984375"/> </location> - <location y="0.101947265625" name="pixel197"> + <location name="pixel197" y="0.101947265625"> <neutronic y="0.101947265625"/> </location> - <location y="0.103435546875" name="pixel198"> + <location name="pixel198" y="0.103435546875"> <neutronic y="0.103435546875"/> </location> - <location y="0.104923828125" name="pixel199"> + <location name="pixel199" y="0.104923828125"> <neutronic y="0.104923828125"/> </location> - <location y="0.106412109375" name="pixel200"> + <location name="pixel200" y="0.106412109375"> <neutronic y="0.106412109375"/> </location> - <location y="0.107900390625" name="pixel201"> + <location name="pixel201" y="0.107900390625"> <neutronic y="0.107900390625"/> </location> - <location y="0.109388671875" name="pixel202"> + <location name="pixel202" y="0.109388671875"> <neutronic y="0.109388671875"/> </location> - <location y="0.110876953125" name="pixel203"> + <location name="pixel203" y="0.110876953125"> <neutronic y="0.110876953125"/> </location> - <location y="0.112365234375" name="pixel204"> + <location name="pixel204" y="0.112365234375"> <neutronic y="0.112365234375"/> </location> - <location y="0.113853515625" name="pixel205"> + <location name="pixel205" y="0.113853515625"> <neutronic y="0.113853515625"/> </location> - <location y="0.115341796875" name="pixel206"> + <location name="pixel206" y="0.115341796875"> <neutronic y="0.115341796875"/> </location> - <location y="0.116830078125" name="pixel207"> + <location name="pixel207" y="0.116830078125"> <neutronic y="0.116830078125"/> </location> - <location y="0.118318359375" name="pixel208"> + <location name="pixel208" y="0.118318359375"> <neutronic y="0.118318359375"/> </location> - <location y="0.119806640625" name="pixel209"> + <location name="pixel209" y="0.119806640625"> <neutronic y="0.119806640625"/> </location> - <location y="0.121294921875" name="pixel210"> + <location name="pixel210" y="0.121294921875"> <neutronic y="0.121294921875"/> </location> - <location y="0.122783203125" name="pixel211"> + <location name="pixel211" y="0.122783203125"> <neutronic y="0.122783203125"/> </location> - <location y="0.124271484375" name="pixel212"> + <location name="pixel212" y="0.124271484375"> <neutronic y="0.124271484375"/> </location> - <location y="0.125759765625" name="pixel213"> + <location name="pixel213" y="0.125759765625"> <neutronic y="0.125759765625"/> </location> - <location y="0.127248046875" name="pixel214"> + <location name="pixel214" y="0.127248046875"> <neutronic y="0.127248046875"/> </location> - <location y="0.128736328125" name="pixel215"> + <location name="pixel215" y="0.128736328125"> <neutronic y="0.128736328125"/> </location> - <location y="0.130224609375" name="pixel216"> + <location name="pixel216" y="0.130224609375"> <neutronic y="0.130224609375"/> </location> - <location y="0.131712890625" name="pixel217"> + <location name="pixel217" y="0.131712890625"> <neutronic y="0.131712890625"/> </location> - <location y="0.133201171875" name="pixel218"> + <location name="pixel218" y="0.133201171875"> <neutronic y="0.133201171875"/> </location> - <location y="0.134689453125" name="pixel219"> + <location name="pixel219" y="0.134689453125"> <neutronic y="0.134689453125"/> </location> - <location y="0.136177734375" name="pixel220"> + <location name="pixel220" y="0.136177734375"> <neutronic y="0.136177734375"/> </location> - <location y="0.137666015625" name="pixel221"> + <location name="pixel221" y="0.137666015625"> <neutronic y="0.137666015625"/> </location> - <location y="0.139154296875" name="pixel222"> + <location name="pixel222" y="0.139154296875"> <neutronic y="0.139154296875"/> </location> - <location y="0.140642578125" name="pixel223"> + <location name="pixel223" y="0.140642578125"> <neutronic y="0.140642578125"/> </location> - <location y="0.142130859375" name="pixel224"> + <location name="pixel224" y="0.142130859375"> <neutronic y="0.142130859375"/> </location> - <location y="0.143619140625" name="pixel225"> + <location name="pixel225" y="0.143619140625"> <neutronic y="0.143619140625"/> </location> - <location y="0.145107421875" name="pixel226"> + <location name="pixel226" y="0.145107421875"> <neutronic y="0.145107421875"/> </location> - <location y="0.146595703125" name="pixel227"> + <location name="pixel227" y="0.146595703125"> <neutronic y="0.146595703125"/> </location> - <location y="0.148083984375" name="pixel228"> + <location name="pixel228" y="0.148083984375"> <neutronic y="0.148083984375"/> </location> - <location y="0.149572265625" name="pixel229"> + <location name="pixel229" y="0.149572265625"> <neutronic y="0.149572265625"/> </location> - <location y="0.151060546875" name="pixel230"> + <location name="pixel230" y="0.151060546875"> <neutronic y="0.151060546875"/> </location> - <location y="0.152548828125" name="pixel231"> + <location name="pixel231" y="0.152548828125"> <neutronic y="0.152548828125"/> </location> - <location y="0.154037109375" name="pixel232"> + <location name="pixel232" y="0.154037109375"> <neutronic y="0.154037109375"/> </location> - <location y="0.155525390625" name="pixel233"> + <location name="pixel233" y="0.155525390625"> <neutronic y="0.155525390625"/> </location> - <location y="0.157013671875" name="pixel234"> + <location name="pixel234" y="0.157013671875"> <neutronic y="0.157013671875"/> </location> - <location y="0.158501953125" name="pixel235"> + <location name="pixel235" y="0.158501953125"> <neutronic y="0.158501953125"/> </location> - <location y="0.159990234375" name="pixel236"> + <location name="pixel236" y="0.159990234375"> <neutronic y="0.159990234375"/> </location> - <location y="0.161478515625" name="pixel237"> + <location name="pixel237" y="0.161478515625"> <neutronic y="0.161478515625"/> </location> - <location y="0.162966796875" name="pixel238"> + <location name="pixel238" y="0.162966796875"> <neutronic y="0.162966796875"/> </location> - <location y="0.164455078125" name="pixel239"> + <location name="pixel239" y="0.164455078125"> <neutronic y="0.164455078125"/> </location> - <location y="0.165943359375" name="pixel240"> + <location name="pixel240" y="0.165943359375"> <neutronic y="0.165943359375"/> </location> - <location y="0.167431640625" name="pixel241"> + <location name="pixel241" y="0.167431640625"> <neutronic y="0.167431640625"/> </location> - <location y="0.168919921875" name="pixel242"> + <location name="pixel242" y="0.168919921875"> <neutronic y="0.168919921875"/> </location> - <location y="0.170408203125" name="pixel243"> + <location name="pixel243" y="0.170408203125"> <neutronic y="0.170408203125"/> </location> - <location y="0.171896484375" name="pixel244"> + <location name="pixel244" y="0.171896484375"> <neutronic y="0.171896484375"/> </location> - <location y="0.173384765625" name="pixel245"> + <location name="pixel245" y="0.173384765625"> <neutronic y="0.173384765625"/> </location> - <location y="0.174873046875" name="pixel246"> + <location name="pixel246" y="0.174873046875"> <neutronic y="0.174873046875"/> </location> - <location y="0.176361328125" name="pixel247"> + <location name="pixel247" y="0.176361328125"> <neutronic y="0.176361328125"/> </location> - <location y="0.177849609375" name="pixel248"> + <location name="pixel248" y="0.177849609375"> <neutronic y="0.177849609375"/> </location> - <location y="0.179337890625" name="pixel249"> + <location name="pixel249" y="0.179337890625"> <neutronic y="0.179337890625"/> </location> - <location y="0.180826171875" name="pixel250"> + <location name="pixel250" y="0.180826171875"> <neutronic y="0.180826171875"/> </location> - <location y="0.182314453125" name="pixel251"> + <location name="pixel251" y="0.182314453125"> <neutronic y="0.182314453125"/> </location> - <location y="0.183802734375" name="pixel252"> + <location name="pixel252" y="0.183802734375"> <neutronic y="0.183802734375"/> </location> - <location y="0.185291015625" name="pixel253"> + <location name="pixel253" y="0.185291015625"> <neutronic y="0.185291015625"/> </location> - <location y="0.186779296875" name="pixel254"> + <location name="pixel254" y="0.186779296875"> <neutronic y="0.186779296875"/> </location> - <location y="0.188267578125" name="pixel255"> + <location name="pixel255" y="0.188267578125"> <neutronic y="0.188267578125"/> </location> - <location y="0.189755859375" name="pixel256"> + <location name="pixel256" y="0.189755859375"> <neutronic y="0.189755859375"/> </location> </component> @@ -3566,772 +3496,772 @@ <type name="tube-elastic" outline="yes"> <properties/> <component type="pixel-elastic-tube"> - <location y="-0.0948779296875" name="pixel1"> + <location name="pixel1" y="-0.0948779296875"> <neutronic y="-0.0948779296875"/> </location> - <location y="-0.0941337890625" name="pixel2"> + <location name="pixel2" y="-0.0941337890625"> <neutronic y="-0.0941337890625"/> </location> - <location y="-0.0933896484375" name="pixel3"> + <location name="pixel3" y="-0.0933896484375"> <neutronic y="-0.0933896484375"/> </location> - <location y="-0.0926455078125" name="pixel4"> + <location name="pixel4" y="-0.0926455078125"> <neutronic y="-0.0926455078125"/> </location> - <location y="-0.0919013671875" name="pixel5"> + <location name="pixel5" y="-0.0919013671875"> <neutronic y="-0.0919013671875"/> </location> - <location y="-0.0911572265625" name="pixel6"> + <location name="pixel6" y="-0.0911572265625"> <neutronic y="-0.0911572265625"/> </location> - <location y="-0.0904130859375" name="pixel7"> + <location name="pixel7" y="-0.0904130859375"> <neutronic y="-0.0904130859375"/> </location> - <location y="-0.0896689453125" name="pixel8"> + <location name="pixel8" y="-0.0896689453125"> <neutronic y="-0.0896689453125"/> </location> - <location y="-0.0889248046875" name="pixel9"> + <location name="pixel9" y="-0.0889248046875"> <neutronic y="-0.0889248046875"/> </location> - <location y="-0.0881806640625" name="pixel10"> + <location name="pixel10" y="-0.0881806640625"> <neutronic y="-0.0881806640625"/> </location> - <location y="-0.0874365234375" name="pixel11"> + <location name="pixel11" y="-0.0874365234375"> <neutronic y="-0.0874365234375"/> </location> - <location y="-0.0866923828125" name="pixel12"> + <location name="pixel12" y="-0.0866923828125"> <neutronic y="-0.0866923828125"/> </location> - <location y="-0.0859482421875" name="pixel13"> + <location name="pixel13" y="-0.0859482421875"> <neutronic y="-0.0859482421875"/> </location> - <location y="-0.0852041015625" name="pixel14"> + <location name="pixel14" y="-0.0852041015625"> <neutronic y="-0.0852041015625"/> </location> - <location y="-0.0844599609375" name="pixel15"> + <location name="pixel15" y="-0.0844599609375"> <neutronic y="-0.0844599609375"/> </location> - <location y="-0.0837158203125" name="pixel16"> + <location name="pixel16" y="-0.0837158203125"> <neutronic y="-0.0837158203125"/> </location> - <location y="-0.0829716796875" name="pixel17"> + <location name="pixel17" y="-0.0829716796875"> <neutronic y="-0.0829716796875"/> </location> - <location y="-0.0822275390625" name="pixel18"> + <location name="pixel18" y="-0.0822275390625"> <neutronic y="-0.0822275390625"/> </location> - <location y="-0.0814833984375" name="pixel19"> + <location name="pixel19" y="-0.0814833984375"> <neutronic y="-0.0814833984375"/> </location> - <location y="-0.0807392578125" name="pixel20"> + <location name="pixel20" y="-0.0807392578125"> <neutronic y="-0.0807392578125"/> </location> - <location y="-0.0799951171875" name="pixel21"> + <location name="pixel21" y="-0.0799951171875"> <neutronic y="-0.0799951171875"/> </location> - <location y="-0.0792509765625" name="pixel22"> + <location name="pixel22" y="-0.0792509765625"> <neutronic y="-0.0792509765625"/> </location> - <location y="-0.0785068359375" name="pixel23"> + <location name="pixel23" y="-0.0785068359375"> <neutronic y="-0.0785068359375"/> </location> - <location y="-0.0777626953125" name="pixel24"> + <location name="pixel24" y="-0.0777626953125"> <neutronic y="-0.0777626953125"/> </location> - <location y="-0.0770185546875" name="pixel25"> + <location name="pixel25" y="-0.0770185546875"> <neutronic y="-0.0770185546875"/> </location> - <location y="-0.0762744140625" name="pixel26"> + <location name="pixel26" y="-0.0762744140625"> <neutronic y="-0.0762744140625"/> </location> - <location y="-0.0755302734375" name="pixel27"> + <location name="pixel27" y="-0.0755302734375"> <neutronic y="-0.0755302734375"/> </location> - <location y="-0.0747861328125" name="pixel28"> + <location name="pixel28" y="-0.0747861328125"> <neutronic y="-0.0747861328125"/> </location> - <location y="-0.0740419921875" name="pixel29"> + <location name="pixel29" y="-0.0740419921875"> <neutronic y="-0.0740419921875"/> </location> - <location y="-0.0732978515625" name="pixel30"> + <location name="pixel30" y="-0.0732978515625"> <neutronic y="-0.0732978515625"/> </location> - <location y="-0.0725537109375" name="pixel31"> + <location name="pixel31" y="-0.0725537109375"> <neutronic y="-0.0725537109375"/> </location> - <location y="-0.0718095703125" name="pixel32"> + <location name="pixel32" y="-0.0718095703125"> <neutronic y="-0.0718095703125"/> </location> - <location y="-0.0710654296875" name="pixel33"> + <location name="pixel33" y="-0.0710654296875"> <neutronic y="-0.0710654296875"/> </location> - <location y="-0.0703212890625" name="pixel34"> + <location name="pixel34" y="-0.0703212890625"> <neutronic y="-0.0703212890625"/> </location> - <location y="-0.0695771484375" name="pixel35"> + <location name="pixel35" y="-0.0695771484375"> <neutronic y="-0.0695771484375"/> </location> - <location y="-0.0688330078125" name="pixel36"> + <location name="pixel36" y="-0.0688330078125"> <neutronic y="-0.0688330078125"/> </location> - <location y="-0.0680888671875" name="pixel37"> + <location name="pixel37" y="-0.0680888671875"> <neutronic y="-0.0680888671875"/> </location> - <location y="-0.0673447265625" name="pixel38"> + <location name="pixel38" y="-0.0673447265625"> <neutronic y="-0.0673447265625"/> </location> - <location y="-0.0666005859375" name="pixel39"> + <location name="pixel39" y="-0.0666005859375"> <neutronic y="-0.0666005859375"/> </location> - <location y="-0.0658564453125" name="pixel40"> + <location name="pixel40" y="-0.0658564453125"> <neutronic y="-0.0658564453125"/> </location> - <location y="-0.0651123046875" name="pixel41"> + <location name="pixel41" y="-0.0651123046875"> <neutronic y="-0.0651123046875"/> </location> - <location y="-0.0643681640625" name="pixel42"> + <location name="pixel42" y="-0.0643681640625"> <neutronic y="-0.0643681640625"/> </location> - <location y="-0.0636240234375" name="pixel43"> + <location name="pixel43" y="-0.0636240234375"> <neutronic y="-0.0636240234375"/> </location> - <location y="-0.0628798828125" name="pixel44"> + <location name="pixel44" y="-0.0628798828125"> <neutronic y="-0.0628798828125"/> </location> - <location y="-0.0621357421875" name="pixel45"> + <location name="pixel45" y="-0.0621357421875"> <neutronic y="-0.0621357421875"/> </location> - <location y="-0.0613916015625" name="pixel46"> + <location name="pixel46" y="-0.0613916015625"> <neutronic y="-0.0613916015625"/> </location> - <location y="-0.0606474609375" name="pixel47"> + <location name="pixel47" y="-0.0606474609375"> <neutronic y="-0.0606474609375"/> </location> - <location y="-0.0599033203125" name="pixel48"> + <location name="pixel48" y="-0.0599033203125"> <neutronic y="-0.0599033203125"/> </location> - <location y="-0.0591591796875" name="pixel49"> + <location name="pixel49" y="-0.0591591796875"> <neutronic y="-0.0591591796875"/> </location> - <location y="-0.0584150390625" name="pixel50"> + <location name="pixel50" y="-0.0584150390625"> <neutronic y="-0.0584150390625"/> </location> - <location y="-0.0576708984375" name="pixel51"> + <location name="pixel51" y="-0.0576708984375"> <neutronic y="-0.0576708984375"/> </location> - <location y="-0.0569267578125" name="pixel52"> + <location name="pixel52" y="-0.0569267578125"> <neutronic y="-0.0569267578125"/> </location> - <location y="-0.0561826171875" name="pixel53"> + <location name="pixel53" y="-0.0561826171875"> <neutronic y="-0.0561826171875"/> </location> - <location y="-0.0554384765625" name="pixel54"> + <location name="pixel54" y="-0.0554384765625"> <neutronic y="-0.0554384765625"/> </location> - <location y="-0.0546943359375" name="pixel55"> + <location name="pixel55" y="-0.0546943359375"> <neutronic y="-0.0546943359375"/> </location> - <location y="-0.0539501953125" name="pixel56"> + <location name="pixel56" y="-0.0539501953125"> <neutronic y="-0.0539501953125"/> </location> - <location y="-0.0532060546875" name="pixel57"> + <location name="pixel57" y="-0.0532060546875"> <neutronic y="-0.0532060546875"/> </location> - <location y="-0.0524619140625" name="pixel58"> + <location name="pixel58" y="-0.0524619140625"> <neutronic y="-0.0524619140625"/> </location> - <location y="-0.0517177734375" name="pixel59"> + <location name="pixel59" y="-0.0517177734375"> <neutronic y="-0.0517177734375"/> </location> - <location y="-0.0509736328125" name="pixel60"> + <location name="pixel60" y="-0.0509736328125"> <neutronic y="-0.0509736328125"/> </location> - <location y="-0.0502294921875" name="pixel61"> + <location name="pixel61" y="-0.0502294921875"> <neutronic y="-0.0502294921875"/> </location> - <location y="-0.0494853515625" name="pixel62"> + <location name="pixel62" y="-0.0494853515625"> <neutronic y="-0.0494853515625"/> </location> - <location y="-0.0487412109375" name="pixel63"> + <location name="pixel63" y="-0.0487412109375"> <neutronic y="-0.0487412109375"/> </location> - <location y="-0.0479970703125" name="pixel64"> + <location name="pixel64" y="-0.0479970703125"> <neutronic y="-0.0479970703125"/> </location> - <location y="-0.0472529296875" name="pixel65"> + <location name="pixel65" y="-0.0472529296875"> <neutronic y="-0.0472529296875"/> </location> - <location y="-0.0465087890625" name="pixel66"> + <location name="pixel66" y="-0.0465087890625"> <neutronic y="-0.0465087890625"/> </location> - <location y="-0.0457646484375" name="pixel67"> + <location name="pixel67" y="-0.0457646484375"> <neutronic y="-0.0457646484375"/> </location> - <location y="-0.0450205078125" name="pixel68"> + <location name="pixel68" y="-0.0450205078125"> <neutronic y="-0.0450205078125"/> </location> - <location y="-0.0442763671875" name="pixel69"> + <location name="pixel69" y="-0.0442763671875"> <neutronic y="-0.0442763671875"/> </location> - <location y="-0.0435322265625" name="pixel70"> + <location name="pixel70" y="-0.0435322265625"> <neutronic y="-0.0435322265625"/> </location> - <location y="-0.0427880859375" name="pixel71"> + <location name="pixel71" y="-0.0427880859375"> <neutronic y="-0.0427880859375"/> </location> - <location y="-0.0420439453125" name="pixel72"> + <location name="pixel72" y="-0.0420439453125"> <neutronic y="-0.0420439453125"/> </location> - <location y="-0.0412998046875" name="pixel73"> + <location name="pixel73" y="-0.0412998046875"> <neutronic y="-0.0412998046875"/> </location> - <location y="-0.0405556640625" name="pixel74"> + <location name="pixel74" y="-0.0405556640625"> <neutronic y="-0.0405556640625"/> </location> - <location y="-0.0398115234375" name="pixel75"> + <location name="pixel75" y="-0.0398115234375"> <neutronic y="-0.0398115234375"/> </location> - <location y="-0.0390673828125" name="pixel76"> + <location name="pixel76" y="-0.0390673828125"> <neutronic y="-0.0390673828125"/> </location> - <location y="-0.0383232421875" name="pixel77"> + <location name="pixel77" y="-0.0383232421875"> <neutronic y="-0.0383232421875"/> </location> - <location y="-0.0375791015625" name="pixel78"> + <location name="pixel78" y="-0.0375791015625"> <neutronic y="-0.0375791015625"/> </location> - <location y="-0.0368349609375" name="pixel79"> + <location name="pixel79" y="-0.0368349609375"> <neutronic y="-0.0368349609375"/> </location> - <location y="-0.0360908203125" name="pixel80"> + <location name="pixel80" y="-0.0360908203125"> <neutronic y="-0.0360908203125"/> </location> - <location y="-0.0353466796875" name="pixel81"> + <location name="pixel81" y="-0.0353466796875"> <neutronic y="-0.0353466796875"/> </location> - <location y="-0.0346025390625" name="pixel82"> + <location name="pixel82" y="-0.0346025390625"> <neutronic y="-0.0346025390625"/> </location> - <location y="-0.0338583984375" name="pixel83"> + <location name="pixel83" y="-0.0338583984375"> <neutronic y="-0.0338583984375"/> </location> - <location y="-0.0331142578125" name="pixel84"> + <location name="pixel84" y="-0.0331142578125"> <neutronic y="-0.0331142578125"/> </location> - <location y="-0.0323701171875" name="pixel85"> + <location name="pixel85" y="-0.0323701171875"> <neutronic y="-0.0323701171875"/> </location> - <location y="-0.0316259765625" name="pixel86"> + <location name="pixel86" y="-0.0316259765625"> <neutronic y="-0.0316259765625"/> </location> - <location y="-0.0308818359375" name="pixel87"> + <location name="pixel87" y="-0.0308818359375"> <neutronic y="-0.0308818359375"/> </location> - <location y="-0.0301376953125" name="pixel88"> + <location name="pixel88" y="-0.0301376953125"> <neutronic y="-0.0301376953125"/> </location> - <location y="-0.0293935546875" name="pixel89"> + <location name="pixel89" y="-0.0293935546875"> <neutronic y="-0.0293935546875"/> </location> - <location y="-0.0286494140625" name="pixel90"> + <location name="pixel90" y="-0.0286494140625"> <neutronic y="-0.0286494140625"/> </location> - <location y="-0.0279052734375" name="pixel91"> + <location name="pixel91" y="-0.0279052734375"> <neutronic y="-0.0279052734375"/> </location> - <location y="-0.0271611328125" name="pixel92"> + <location name="pixel92" y="-0.0271611328125"> <neutronic y="-0.0271611328125"/> </location> - <location y="-0.0264169921875" name="pixel93"> + <location name="pixel93" y="-0.0264169921875"> <neutronic y="-0.0264169921875"/> </location> - <location y="-0.0256728515625" name="pixel94"> + <location name="pixel94" y="-0.0256728515625"> <neutronic y="-0.0256728515625"/> </location> - <location y="-0.0249287109375" name="pixel95"> + <location name="pixel95" y="-0.0249287109375"> <neutronic y="-0.0249287109375"/> </location> - <location y="-0.0241845703125" name="pixel96"> + <location name="pixel96" y="-0.0241845703125"> <neutronic y="-0.0241845703125"/> </location> - <location y="-0.0234404296875" name="pixel97"> + <location name="pixel97" y="-0.0234404296875"> <neutronic y="-0.0234404296875"/> </location> - <location y="-0.0226962890625" name="pixel98"> + <location name="pixel98" y="-0.0226962890625"> <neutronic y="-0.0226962890625"/> </location> - <location y="-0.0219521484375" name="pixel99"> + <location name="pixel99" y="-0.0219521484375"> <neutronic y="-0.0219521484375"/> </location> - <location y="-0.0212080078125" name="pixel100"> + <location name="pixel100" y="-0.0212080078125"> <neutronic y="-0.0212080078125"/> </location> - <location y="-0.0204638671875" name="pixel101"> + <location name="pixel101" y="-0.0204638671875"> <neutronic y="-0.0204638671875"/> </location> - <location y="-0.0197197265625" name="pixel102"> + <location name="pixel102" y="-0.0197197265625"> <neutronic y="-0.0197197265625"/> </location> - <location y="-0.0189755859375" name="pixel103"> + <location name="pixel103" y="-0.0189755859375"> <neutronic y="-0.0189755859375"/> </location> - <location y="-0.0182314453125" name="pixel104"> + <location name="pixel104" y="-0.0182314453125"> <neutronic y="-0.0182314453125"/> </location> - <location y="-0.0174873046875" name="pixel105"> + <location name="pixel105" y="-0.0174873046875"> <neutronic y="-0.0174873046875"/> </location> - <location y="-0.0167431640625" name="pixel106"> + <location name="pixel106" y="-0.0167431640625"> <neutronic y="-0.0167431640625"/> </location> - <location y="-0.0159990234375" name="pixel107"> + <location name="pixel107" y="-0.0159990234375"> <neutronic y="-0.0159990234375"/> </location> - <location y="-0.0152548828125" name="pixel108"> + <location name="pixel108" y="-0.0152548828125"> <neutronic y="-0.0152548828125"/> </location> - <location y="-0.0145107421875" name="pixel109"> + <location name="pixel109" y="-0.0145107421875"> <neutronic y="-0.0145107421875"/> </location> - <location y="-0.0137666015625" name="pixel110"> + <location name="pixel110" y="-0.0137666015625"> <neutronic y="-0.0137666015625"/> </location> - <location y="-0.0130224609375" name="pixel111"> + <location name="pixel111" y="-0.0130224609375"> <neutronic y="-0.0130224609375"/> </location> - <location y="-0.0122783203125" name="pixel112"> + <location name="pixel112" y="-0.0122783203125"> <neutronic y="-0.0122783203125"/> </location> - <location y="-0.0115341796875" name="pixel113"> + <location name="pixel113" y="-0.0115341796875"> <neutronic y="-0.0115341796875"/> </location> - <location y="-0.0107900390625" name="pixel114"> + <location name="pixel114" y="-0.0107900390625"> <neutronic y="-0.0107900390625"/> </location> - <location y="-0.0100458984375" name="pixel115"> + <location name="pixel115" y="-0.0100458984375"> <neutronic y="-0.0100458984375"/> </location> - <location y="-0.0093017578125" name="pixel116"> + <location name="pixel116" y="-0.0093017578125"> <neutronic y="-0.0093017578125"/> </location> - <location y="-0.0085576171875" name="pixel117"> + <location name="pixel117" y="-0.0085576171875"> <neutronic y="-0.0085576171875"/> </location> - <location y="-0.0078134765625" name="pixel118"> + <location name="pixel118" y="-0.0078134765625"> <neutronic y="-0.0078134765625"/> </location> - <location y="-0.0070693359375" name="pixel119"> + <location name="pixel119" y="-0.0070693359375"> <neutronic y="-0.0070693359375"/> </location> - <location y="-0.0063251953125" name="pixel120"> + <location name="pixel120" y="-0.0063251953125"> <neutronic y="-0.0063251953125"/> </location> - <location y="-0.0055810546875" name="pixel121"> + <location name="pixel121" y="-0.0055810546875"> <neutronic y="-0.0055810546875"/> </location> - <location y="-0.0048369140625" name="pixel122"> + <location name="pixel122" y="-0.0048369140625"> <neutronic y="-0.0048369140625"/> </location> - <location y="-0.0040927734375" name="pixel123"> + <location name="pixel123" y="-0.0040927734375"> <neutronic y="-0.0040927734375"/> </location> - <location y="-0.0033486328125" name="pixel124"> + <location name="pixel124" y="-0.0033486328125"> <neutronic y="-0.0033486328125"/> </location> - <location y="-0.0026044921875" name="pixel125"> + <location name="pixel125" y="-0.0026044921875"> <neutronic y="-0.0026044921875"/> </location> - <location y="-0.0018603515625" name="pixel126"> + <location name="pixel126" y="-0.0018603515625"> <neutronic y="-0.0018603515625"/> </location> - <location y="-0.0011162109375" name="pixel127"> + <location name="pixel127" y="-0.0011162109375"> <neutronic y="-0.0011162109375"/> </location> - <location y="-0.0003720703125" name="pixel128"> + <location name="pixel128" y="-0.0003720703125"> <neutronic y="-0.0003720703125"/> </location> - <location y="0.0003720703125" name="pixel129"> + <location name="pixel129" y="0.0003720703125"> <neutronic y="0.0003720703125"/> </location> - <location y="0.0011162109375" name="pixel130"> + <location name="pixel130" y="0.0011162109375"> <neutronic y="0.0011162109375"/> </location> - <location y="0.0018603515625" name="pixel131"> + <location name="pixel131" y="0.0018603515625"> <neutronic y="0.0018603515625"/> </location> - <location y="0.0026044921875" name="pixel132"> + <location name="pixel132" y="0.0026044921875"> <neutronic y="0.0026044921875"/> </location> - <location y="0.0033486328125" name="pixel133"> + <location name="pixel133" y="0.0033486328125"> <neutronic y="0.0033486328125"/> </location> - <location y="0.0040927734375" name="pixel134"> + <location name="pixel134" y="0.0040927734375"> <neutronic y="0.0040927734375"/> </location> - <location y="0.0048369140625" name="pixel135"> + <location name="pixel135" y="0.0048369140625"> <neutronic y="0.0048369140625"/> </location> - <location y="0.0055810546875" name="pixel136"> + <location name="pixel136" y="0.0055810546875"> <neutronic y="0.0055810546875"/> </location> - <location y="0.0063251953125" name="pixel137"> + <location name="pixel137" y="0.0063251953125"> <neutronic y="0.0063251953125"/> </location> - <location y="0.0070693359375" name="pixel138"> + <location name="pixel138" y="0.0070693359375"> <neutronic y="0.0070693359375"/> </location> - <location y="0.0078134765625" name="pixel139"> + <location name="pixel139" y="0.0078134765625"> <neutronic y="0.0078134765625"/> </location> - <location y="0.0085576171875" name="pixel140"> + <location name="pixel140" y="0.0085576171875"> <neutronic y="0.0085576171875"/> </location> - <location y="0.0093017578125" name="pixel141"> + <location name="pixel141" y="0.0093017578125"> <neutronic y="0.0093017578125"/> </location> - <location y="0.0100458984375" name="pixel142"> + <location name="pixel142" y="0.0100458984375"> <neutronic y="0.0100458984375"/> </location> - <location y="0.0107900390625" name="pixel143"> + <location name="pixel143" y="0.0107900390625"> <neutronic y="0.0107900390625"/> </location> - <location y="0.0115341796875" name="pixel144"> + <location name="pixel144" y="0.0115341796875"> <neutronic y="0.0115341796875"/> </location> - <location y="0.0122783203125" name="pixel145"> + <location name="pixel145" y="0.0122783203125"> <neutronic y="0.0122783203125"/> </location> - <location y="0.0130224609375" name="pixel146"> + <location name="pixel146" y="0.0130224609375"> <neutronic y="0.0130224609375"/> </location> - <location y="0.0137666015625" name="pixel147"> + <location name="pixel147" y="0.0137666015625"> <neutronic y="0.0137666015625"/> </location> - <location y="0.0145107421875" name="pixel148"> + <location name="pixel148" y="0.0145107421875"> <neutronic y="0.0145107421875"/> </location> - <location y="0.0152548828125" name="pixel149"> + <location name="pixel149" y="0.0152548828125"> <neutronic y="0.0152548828125"/> </location> - <location y="0.0159990234375" name="pixel150"> + <location name="pixel150" y="0.0159990234375"> <neutronic y="0.0159990234375"/> </location> - <location y="0.0167431640625" name="pixel151"> + <location name="pixel151" y="0.0167431640625"> <neutronic y="0.0167431640625"/> </location> - <location y="0.0174873046875" name="pixel152"> + <location name="pixel152" y="0.0174873046875"> <neutronic y="0.0174873046875"/> </location> - <location y="0.0182314453125" name="pixel153"> + <location name="pixel153" y="0.0182314453125"> <neutronic y="0.0182314453125"/> </location> - <location y="0.0189755859375" name="pixel154"> + <location name="pixel154" y="0.0189755859375"> <neutronic y="0.0189755859375"/> </location> - <location y="0.0197197265625" name="pixel155"> + <location name="pixel155" y="0.0197197265625"> <neutronic y="0.0197197265625"/> </location> - <location y="0.0204638671875" name="pixel156"> + <location name="pixel156" y="0.0204638671875"> <neutronic y="0.0204638671875"/> </location> - <location y="0.0212080078125" name="pixel157"> + <location name="pixel157" y="0.0212080078125"> <neutronic y="0.0212080078125"/> </location> - <location y="0.0219521484375" name="pixel158"> + <location name="pixel158" y="0.0219521484375"> <neutronic y="0.0219521484375"/> </location> - <location y="0.0226962890625" name="pixel159"> + <location name="pixel159" y="0.0226962890625"> <neutronic y="0.0226962890625"/> </location> - <location y="0.0234404296875" name="pixel160"> + <location name="pixel160" y="0.0234404296875"> <neutronic y="0.0234404296875"/> </location> - <location y="0.0241845703125" name="pixel161"> + <location name="pixel161" y="0.0241845703125"> <neutronic y="0.0241845703125"/> </location> - <location y="0.0249287109375" name="pixel162"> + <location name="pixel162" y="0.0249287109375"> <neutronic y="0.0249287109375"/> </location> - <location y="0.0256728515625" name="pixel163"> + <location name="pixel163" y="0.0256728515625"> <neutronic y="0.0256728515625"/> </location> - <location y="0.0264169921875" name="pixel164"> + <location name="pixel164" y="0.0264169921875"> <neutronic y="0.0264169921875"/> </location> - <location y="0.0271611328125" name="pixel165"> + <location name="pixel165" y="0.0271611328125"> <neutronic y="0.0271611328125"/> </location> - <location y="0.0279052734375" name="pixel166"> + <location name="pixel166" y="0.0279052734375"> <neutronic y="0.0279052734375"/> </location> - <location y="0.0286494140625" name="pixel167"> + <location name="pixel167" y="0.0286494140625"> <neutronic y="0.0286494140625"/> </location> - <location y="0.0293935546875" name="pixel168"> + <location name="pixel168" y="0.0293935546875"> <neutronic y="0.0293935546875"/> </location> - <location y="0.0301376953125" name="pixel169"> + <location name="pixel169" y="0.0301376953125"> <neutronic y="0.0301376953125"/> </location> - <location y="0.0308818359375" name="pixel170"> + <location name="pixel170" y="0.0308818359375"> <neutronic y="0.0308818359375"/> </location> - <location y="0.0316259765625" name="pixel171"> + <location name="pixel171" y="0.0316259765625"> <neutronic y="0.0316259765625"/> </location> - <location y="0.0323701171875" name="pixel172"> + <location name="pixel172" y="0.0323701171875"> <neutronic y="0.0323701171875"/> </location> - <location y="0.0331142578125" name="pixel173"> + <location name="pixel173" y="0.0331142578125"> <neutronic y="0.0331142578125"/> </location> - <location y="0.0338583984375" name="pixel174"> + <location name="pixel174" y="0.0338583984375"> <neutronic y="0.0338583984375"/> </location> - <location y="0.0346025390625" name="pixel175"> + <location name="pixel175" y="0.0346025390625"> <neutronic y="0.0346025390625"/> </location> - <location y="0.0353466796875" name="pixel176"> + <location name="pixel176" y="0.0353466796875"> <neutronic y="0.0353466796875"/> </location> - <location y="0.0360908203125" name="pixel177"> + <location name="pixel177" y="0.0360908203125"> <neutronic y="0.0360908203125"/> </location> - <location y="0.0368349609375" name="pixel178"> + <location name="pixel178" y="0.0368349609375"> <neutronic y="0.0368349609375"/> </location> - <location y="0.0375791015625" name="pixel179"> + <location name="pixel179" y="0.0375791015625"> <neutronic y="0.0375791015625"/> </location> - <location y="0.0383232421875" name="pixel180"> + <location name="pixel180" y="0.0383232421875"> <neutronic y="0.0383232421875"/> </location> - <location y="0.0390673828125" name="pixel181"> + <location name="pixel181" y="0.0390673828125"> <neutronic y="0.0390673828125"/> </location> - <location y="0.0398115234375" name="pixel182"> + <location name="pixel182" y="0.0398115234375"> <neutronic y="0.0398115234375"/> </location> - <location y="0.0405556640625" name="pixel183"> + <location name="pixel183" y="0.0405556640625"> <neutronic y="0.0405556640625"/> </location> - <location y="0.0412998046875" name="pixel184"> + <location name="pixel184" y="0.0412998046875"> <neutronic y="0.0412998046875"/> </location> - <location y="0.0420439453125" name="pixel185"> + <location name="pixel185" y="0.0420439453125"> <neutronic y="0.0420439453125"/> </location> - <location y="0.0427880859375" name="pixel186"> + <location name="pixel186" y="0.0427880859375"> <neutronic y="0.0427880859375"/> </location> - <location y="0.0435322265625" name="pixel187"> + <location name="pixel187" y="0.0435322265625"> <neutronic y="0.0435322265625"/> </location> - <location y="0.0442763671875" name="pixel188"> + <location name="pixel188" y="0.0442763671875"> <neutronic y="0.0442763671875"/> </location> - <location y="0.0450205078125" name="pixel189"> + <location name="pixel189" y="0.0450205078125"> <neutronic y="0.0450205078125"/> </location> - <location y="0.0457646484375" name="pixel190"> + <location name="pixel190" y="0.0457646484375"> <neutronic y="0.0457646484375"/> </location> - <location y="0.0465087890625" name="pixel191"> + <location name="pixel191" y="0.0465087890625"> <neutronic y="0.0465087890625"/> </location> - <location y="0.0472529296875" name="pixel192"> + <location name="pixel192" y="0.0472529296875"> <neutronic y="0.0472529296875"/> </location> - <location y="0.0479970703125" name="pixel193"> + <location name="pixel193" y="0.0479970703125"> <neutronic y="0.0479970703125"/> </location> - <location y="0.0487412109375" name="pixel194"> + <location name="pixel194" y="0.0487412109375"> <neutronic y="0.0487412109375"/> </location> - <location y="0.0494853515625" name="pixel195"> + <location name="pixel195" y="0.0494853515625"> <neutronic y="0.0494853515625"/> </location> - <location y="0.0502294921875" name="pixel196"> + <location name="pixel196" y="0.0502294921875"> <neutronic y="0.0502294921875"/> </location> - <location y="0.0509736328125" name="pixel197"> + <location name="pixel197" y="0.0509736328125"> <neutronic y="0.0509736328125"/> </location> - <location y="0.0517177734375" name="pixel198"> + <location name="pixel198" y="0.0517177734375"> <neutronic y="0.0517177734375"/> </location> - <location y="0.0524619140625" name="pixel199"> + <location name="pixel199" y="0.0524619140625"> <neutronic y="0.0524619140625"/> </location> - <location y="0.0532060546875" name="pixel200"> + <location name="pixel200" y="0.0532060546875"> <neutronic y="0.0532060546875"/> </location> - <location y="0.0539501953125" name="pixel201"> + <location name="pixel201" y="0.0539501953125"> <neutronic y="0.0539501953125"/> </location> - <location y="0.0546943359375" name="pixel202"> + <location name="pixel202" y="0.0546943359375"> <neutronic y="0.0546943359375"/> </location> - <location y="0.0554384765625" name="pixel203"> + <location name="pixel203" y="0.0554384765625"> <neutronic y="0.0554384765625"/> </location> - <location y="0.0561826171875" name="pixel204"> + <location name="pixel204" y="0.0561826171875"> <neutronic y="0.0561826171875"/> </location> - <location y="0.0569267578125" name="pixel205"> + <location name="pixel205" y="0.0569267578125"> <neutronic y="0.0569267578125"/> </location> - <location y="0.0576708984375" name="pixel206"> + <location name="pixel206" y="0.0576708984375"> <neutronic y="0.0576708984375"/> </location> - <location y="0.0584150390625" name="pixel207"> + <location name="pixel207" y="0.0584150390625"> <neutronic y="0.0584150390625"/> </location> - <location y="0.0591591796875" name="pixel208"> + <location name="pixel208" y="0.0591591796875"> <neutronic y="0.0591591796875"/> </location> - <location y="0.0599033203125" name="pixel209"> + <location name="pixel209" y="0.0599033203125"> <neutronic y="0.0599033203125"/> </location> - <location y="0.0606474609375" name="pixel210"> + <location name="pixel210" y="0.0606474609375"> <neutronic y="0.0606474609375"/> </location> - <location y="0.0613916015625" name="pixel211"> + <location name="pixel211" y="0.0613916015625"> <neutronic y="0.0613916015625"/> </location> - <location y="0.0621357421875" name="pixel212"> + <location name="pixel212" y="0.0621357421875"> <neutronic y="0.0621357421875"/> </location> - <location y="0.0628798828125" name="pixel213"> + <location name="pixel213" y="0.0628798828125"> <neutronic y="0.0628798828125"/> </location> - <location y="0.0636240234375" name="pixel214"> + <location name="pixel214" y="0.0636240234375"> <neutronic y="0.0636240234375"/> </location> - <location y="0.0643681640625" name="pixel215"> + <location name="pixel215" y="0.0643681640625"> <neutronic y="0.0643681640625"/> </location> - <location y="0.0651123046875" name="pixel216"> + <location name="pixel216" y="0.0651123046875"> <neutronic y="0.0651123046875"/> </location> - <location y="0.0658564453125" name="pixel217"> + <location name="pixel217" y="0.0658564453125"> <neutronic y="0.0658564453125"/> </location> - <location y="0.0666005859375" name="pixel218"> + <location name="pixel218" y="0.0666005859375"> <neutronic y="0.0666005859375"/> </location> - <location y="0.0673447265625" name="pixel219"> + <location name="pixel219" y="0.0673447265625"> <neutronic y="0.0673447265625"/> </location> - <location y="0.0680888671875" name="pixel220"> + <location name="pixel220" y="0.0680888671875"> <neutronic y="0.0680888671875"/> </location> - <location y="0.0688330078125" name="pixel221"> + <location name="pixel221" y="0.0688330078125"> <neutronic y="0.0688330078125"/> </location> - <location y="0.0695771484375" name="pixel222"> + <location name="pixel222" y="0.0695771484375"> <neutronic y="0.0695771484375"/> </location> - <location y="0.0703212890625" name="pixel223"> + <location name="pixel223" y="0.0703212890625"> <neutronic y="0.0703212890625"/> </location> - <location y="0.0710654296875" name="pixel224"> + <location name="pixel224" y="0.0710654296875"> <neutronic y="0.0710654296875"/> </location> - <location y="0.0718095703125" name="pixel225"> + <location name="pixel225" y="0.0718095703125"> <neutronic y="0.0718095703125"/> </location> - <location y="0.0725537109375" name="pixel226"> + <location name="pixel226" y="0.0725537109375"> <neutronic y="0.0725537109375"/> </location> - <location y="0.0732978515625" name="pixel227"> + <location name="pixel227" y="0.0732978515625"> <neutronic y="0.0732978515625"/> </location> - <location y="0.0740419921875" name="pixel228"> + <location name="pixel228" y="0.0740419921875"> <neutronic y="0.0740419921875"/> </location> - <location y="0.0747861328125" name="pixel229"> + <location name="pixel229" y="0.0747861328125"> <neutronic y="0.0747861328125"/> </location> - <location y="0.0755302734375" name="pixel230"> + <location name="pixel230" y="0.0755302734375"> <neutronic y="0.0755302734375"/> </location> - <location y="0.0762744140625" name="pixel231"> + <location name="pixel231" y="0.0762744140625"> <neutronic y="0.0762744140625"/> </location> - <location y="0.0770185546875" name="pixel232"> + <location name="pixel232" y="0.0770185546875"> <neutronic y="0.0770185546875"/> </location> - <location y="0.0777626953125" name="pixel233"> + <location name="pixel233" y="0.0777626953125"> <neutronic y="0.0777626953125"/> </location> - <location y="0.0785068359375" name="pixel234"> + <location name="pixel234" y="0.0785068359375"> <neutronic y="0.0785068359375"/> </location> - <location y="0.0792509765625" name="pixel235"> + <location name="pixel235" y="0.0792509765625"> <neutronic y="0.0792509765625"/> </location> - <location y="0.0799951171875" name="pixel236"> + <location name="pixel236" y="0.0799951171875"> <neutronic y="0.0799951171875"/> </location> - <location y="0.0807392578125" name="pixel237"> + <location name="pixel237" y="0.0807392578125"> <neutronic y="0.0807392578125"/> </location> - <location y="0.0814833984375" name="pixel238"> + <location name="pixel238" y="0.0814833984375"> <neutronic y="0.0814833984375"/> </location> - <location y="0.0822275390625" name="pixel239"> + <location name="pixel239" y="0.0822275390625"> <neutronic y="0.0822275390625"/> </location> - <location y="0.0829716796875" name="pixel240"> + <location name="pixel240" y="0.0829716796875"> <neutronic y="0.0829716796875"/> </location> - <location y="0.0837158203125" name="pixel241"> + <location name="pixel241" y="0.0837158203125"> <neutronic y="0.0837158203125"/> </location> - <location y="0.0844599609375" name="pixel242"> + <location name="pixel242" y="0.0844599609375"> <neutronic y="0.0844599609375"/> </location> - <location y="0.0852041015625" name="pixel243"> + <location name="pixel243" y="0.0852041015625"> <neutronic y="0.0852041015625"/> </location> - <location y="0.0859482421875" name="pixel244"> + <location name="pixel244" y="0.0859482421875"> <neutronic y="0.0859482421875"/> </location> - <location y="0.0866923828125" name="pixel245"> + <location name="pixel245" y="0.0866923828125"> <neutronic y="0.0866923828125"/> </location> - <location y="0.0874365234375" name="pixel246"> + <location name="pixel246" y="0.0874365234375"> <neutronic y="0.0874365234375"/> </location> - <location y="0.0881806640625" name="pixel247"> + <location name="pixel247" y="0.0881806640625"> <neutronic y="0.0881806640625"/> </location> - <location y="0.0889248046875" name="pixel248"> + <location name="pixel248" y="0.0889248046875"> <neutronic y="0.0889248046875"/> </location> - <location y="0.0896689453125" name="pixel249"> + <location name="pixel249" y="0.0896689453125"> <neutronic y="0.0896689453125"/> </location> - <location y="0.0904130859375" name="pixel250"> + <location name="pixel250" y="0.0904130859375"> <neutronic y="0.0904130859375"/> </location> - <location y="0.0911572265625" name="pixel251"> + <location name="pixel251" y="0.0911572265625"> <neutronic y="0.0911572265625"/> </location> - <location y="0.0919013671875" name="pixel252"> + <location name="pixel252" y="0.0919013671875"> <neutronic y="0.0919013671875"/> </location> - <location y="0.0926455078125" name="pixel253"> + <location name="pixel253" y="0.0926455078125"> <neutronic y="0.0926455078125"/> </location> - <location y="0.0933896484375" name="pixel254"> + <location name="pixel254" y="0.0933896484375"> <neutronic y="0.0933896484375"/> </location> - <location y="0.0941337890625" name="pixel255"> + <location name="pixel255" y="0.0941337890625"> <neutronic y="0.0941337890625"/> </location> - <location y="0.0948779296875" name="pixel256"> + <location name="pixel256" y="0.0948779296875"> <neutronic y="0.0948779296875"/> </location> </component> @@ -4340,7 +4270,7 @@ <type is="detector" name="pixel-inelastic-tube"> <cylinder id="cyl-approx"> <centre-of-bottom-base p="0.0" r="0.0" t="0.0"/> - <axis y="1.0" x="0.0" z="0.0"/> + <axis x="0.0" y="1.0" z="0.0"/> <radius val="0.00635"/> <height val="0.0012650390625"/> </cylinder> @@ -4350,7 +4280,7 @@ <type is="detector" name="pixel-bs-elastic-long-tube"> <cylinder id="cyl-approx"> <centre-of-bottom-base p="0.0" r="0.0" t="0.0"/> - <axis y="1.0" x="0.0" z="0.0"/> + <axis x="0.0" y="1.0" z="0.0"/> <radius val="0.00635"/> <height val="0.0017859375"/> </cylinder> @@ -4360,7 +4290,7 @@ <type is="detector" name="pixel-bs-elastic-short-tube"> <cylinder id="cyl-approx"> <centre-of-bottom-base p="0.0" r="0.0" t="0.0"/> - <axis y="1.0" x="0.0" z="0.0"/> + <axis x="0.0" y="1.0" z="0.0"/> <radius val="0.00635"/> <height val="0.00148828125"/> </cylinder> @@ -4370,22 +4300,22 @@ <type is="detector" name="pixel-elastic-tube"> <cylinder id="cyl-approx"> <centre-of-bottom-base p="0.0" r="0.0" t="0.0"/> - <axis y="1.0" x="0.0" z="0.0"/> + <axis x="0.0" y="1.0" z="0.0"/> <radius val="0.00635"/> <height val="0.000744140625"/> </cylinder> <algebra val="cyl-approx"/> </type> <!-- ##### MONITORS ##### --> - <component type="monitors" idlist="monitors"> + <component idlist="monitors" type="monitors"> <location/> </component> <type name="monitors"> <component type="monitor"> - <location z="-6.71625" name="monitor1"> + <location name="monitor1" z="-6.71625"> <neutronic z="-6.71625"/> </location> - <location z="0.287" name="monitor4"> + <location name="monitor4" z="0.287"> <neutronic z="0.287"/> </location> </component> @@ -4394,10 +4324,10 @@ <!--FIXME: All monitors share the dimensions of monitor4.--> <type is="monitor" name="monitor"> <cuboid id="shape"> - <left-front-bottom-point y="-0.027" x="-0.0255" z="-0.0065"/> - <left-front-top-point y="0.027" x="-0.0255" z="-0.0065"/> - <left-back-bottom-point y="-0.027" x="-0.0255" z="0.0065"/> - <right-front-bottom-point y="-0.027" x="0.0255" z="-0.0065"/> + <left-front-bottom-point x="-0.0255" y="-0.027" z="-0.0065"/> + <left-front-top-point x="-0.0255" y="0.027" z="-0.0065"/> + <left-back-bottom-point x="-0.0255" y="-0.027" z="0.0065"/> + <right-front-bottom-point x="0.0255" y="-0.027" z="-0.0065"/> </cuboid> <algebra val="shape"/> </type> diff --git a/Code/Mantid/scripts/FilterEvents/eventFilterGUI.py b/Code/Mantid/scripts/FilterEvents/eventFilterGUI.py index cc246846f9aa808a77cb27f7efe791f895e374d1..eec342adbde464590c847830ec922310f2a7260b 100644 --- a/Code/Mantid/scripts/FilterEvents/eventFilterGUI.py +++ b/Code/Mantid/scripts/FilterEvents/eventFilterGUI.py @@ -19,7 +19,7 @@ import os HUGE_FAST = 10000 HUGE_PARALLEL = 100000 -MAXTIMEBINSIZE = 20000 +MAXTIMEBINSIZE = 3000 try: _fromUtf8 = QtCore.QString.fromUtf8 @@ -957,10 +957,10 @@ class MainWindow(QtGui.QMainWindow): sumwsname = "_Summed_%s"%(str(wksp)) if AnalysisDataService.doesExist(sumwsname) is False: - sumws = api.RebinByPulseTimes(InputWorkspace=wksp, OutputWorkspace = sumwsname,\ - Params="0, %f, %d"%(timeres, timeduration)) - sumws = api.SumSpectra(InputWorkspace=sumws, OutputWorkspace=str(sumws)) - sumws = api.ConvertToPointData(InputWorkspace=sumws, OutputWorkspace=str(sumws)) + sumws = api.SumSpectra(InputWorkspace=wksp, OutputWorkspace=sumwsname) + sumws = api.RebinByPulseTimes(InputWorkspace=sumws, OutputWorkspace = sumwsname,\ + Params="%f"%(timeres)) + sumws = api.ConvertToPointData(InputWorkspace=sumws, OutputWorkspace=sumwsname) else: sumws = AnalysisDataService.retrieve(sumwsname) except Exception as e: