From d40bc3e4b86acff831355f693dcaeddaae0bd0e4 Mon Sep 17 00:00:00 2001
From: Martyn Gigg <martyn.gigg@stfc.ac.uk>
Date: Fri, 16 Mar 2012 11:49:34 +0000
Subject: [PATCH] Add Facility and Instrument Info exports to Python. Refs
 #4950

The old api had lowercase 'i' for the facility.instruments but the C++
has uppercase. Lowercase follows our style so the C++ has been changed
so that the new can follow this.
---
 Code/Mantid/Build/python_export_maker.py      |  2 +-
 .../Kernel/inc/MantidKernel/FacilityInfo.h    |  6 +--
 .../Kernel/inc/MantidKernel/InstrumentInfo.h  |  3 ++
 .../Framework/Kernel/src/ConfigService.cpp    |  4 +-
 .../Framework/Kernel/src/FacilityInfo.cpp     |  6 +--
 .../Framework/Kernel/src/InstrumentInfo.cpp   | 15 ++++++
 .../Framework/Kernel/test/FacilitiesTest.h    | 17 +++---
 .../std_operator_definitions.h                | 50 ------------------
 .../inc/MantidPythonAPI/stl_proxies.h         |  1 -
 .../PythonAPI/src/kernel_exports.cpp          |  8 +--
 .../Framework/PythonInterface/CMakeLists.txt  |  2 +
 .../mantid/kernel/CMakeLists.txt              |  2 +
 .../kernel/src/Exports/ConfigService.cpp      | 29 +++++++++++
 .../kernel/src/Exports/FacilityInfo.cpp       | 52 +++++++++++++++++++
 .../kernel/src/Exports/InstrumentInfo.cpp     | 35 +++++++++++++
 .../test/python/ConfigServiceTest.py          | 16 +++++-
 .../test/python/FacilityInfoTest.py           | 29 +++++++++++
 .../test/python/InstrumentInfoTest.py         | 16 ++++++
 .../MantidWidgets/src/InstrumentSelector.cpp  |  8 +--
 19 files changed, 225 insertions(+), 76 deletions(-)
 delete mode 100644 Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/std_operator_definitions.h
 create mode 100644 Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/FacilityInfo.cpp
 create mode 100644 Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/InstrumentInfo.cpp
 create mode 100644 Code/Mantid/Framework/PythonInterface/test/python/FacilityInfoTest.py
 create mode 100644 Code/Mantid/Framework/PythonInterface/test/python/InstrumentInfoTest.py

diff --git a/Code/Mantid/Build/python_export_maker.py b/Code/Mantid/Build/python_export_maker.py
index d2a30b3f1a8..92a70f54d73 100644
--- a/Code/Mantid/Build/python_export_maker.py
+++ b/Code/Mantid/Build/python_export_maker.py
@@ -131,7 +131,7 @@ def write_unittest(headerfile, overwrite):
 """import unittest
 from mantid import %(classname)s
 
-class %(classname)sTest(object):
+class %(classname)sTest(unittest.TestCase):
 
     def test_something(self):
         self.fail("Test something")
diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/FacilityInfo.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/FacilityInfo.h
index b91e9b2a880..a4d7f79d2c8 100644
--- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/FacilityInfo.h
+++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/FacilityInfo.h
@@ -74,11 +74,11 @@ public:
   /// Return the archive search interface names
   const std::vector<std::string> & archiveSearch() const { return m_archiveSearch; }
   /// Returns a list of instruments of this facility
-  const std::vector<InstrumentInfo> & Instruments() const { return m_instruments; }
+  const std::vector<InstrumentInfo> & instruments() const { return m_instruments; }
   /// Returns a list of instruments of given technique
-  std::vector<InstrumentInfo> Instruments(const std::string& tech) const;
+  std::vector<InstrumentInfo> instruments(const std::string& tech) const;
   /// Returns instruments with given name
-  const InstrumentInfo & Instrument(const std::string& iName = "") const;
+  const InstrumentInfo & instrument(const std::string& iName = "") const;
 
   /// Returns the catalog name
   const std::string & catalogName()const {return m_catalogName;}
diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/InstrumentInfo.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/InstrumentInfo.h
index c581b619322..b17a7bef3eb 100644
--- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/InstrumentInfo.h
+++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/InstrumentInfo.h
@@ -84,6 +84,9 @@ private:
   static Logger& g_log;                    ///< logger
 };
 
+/// Allow this object to be printed to a stream
+std::ostream & operator<<(std::ostream & buffer, const InstrumentInfo & instrumentDescriptor);
+
 } // namespace Kernel
 } // namespace Mantid
 
diff --git a/Code/Mantid/Framework/Kernel/src/ConfigService.cpp b/Code/Mantid/Framework/Kernel/src/ConfigService.cpp
index a9771bb0b25..3ec7252bb2d 100644
--- a/Code/Mantid/Framework/Kernel/src/ConfigService.cpp
+++ b/Code/Mantid/Framework/Kernel/src/ConfigService.cpp
@@ -1584,7 +1584,7 @@ const InstrumentInfo & ConfigServiceImpl::getInstrument(const std::string& instr
     try
     {
       g_log.debug() << "Looking for " << instrumentName << " at " << defaultFacility << "." << std::endl;
-      return getFacility(defaultFacility).Instrument(instrumentName);
+      return getFacility(defaultFacility).instrument(instrumentName);
     }
     catch (Exception::NotFoundError &)
     {
@@ -1600,7 +1600,7 @@ const InstrumentInfo & ConfigServiceImpl::getInstrument(const std::string& instr
     try
     {
       g_log.debug() << "Looking for " << instrumentName << " at " << (**it).name() << "." << std::endl;
-      return (**it).Instrument(instrumentName);
+      return (**it).instrument(instrumentName);
     }
     catch (Exception::NotFoundError &)
     {
diff --git a/Code/Mantid/Framework/Kernel/src/FacilityInfo.cpp b/Code/Mantid/Framework/Kernel/src/FacilityInfo.cpp
index f8adec44e32..5fc875023d8 100644
--- a/Code/Mantid/Framework/Kernel/src/FacilityInfo.cpp
+++ b/Code/Mantid/Framework/Kernel/src/FacilityInfo.cpp
@@ -160,12 +160,12 @@ void FacilityInfo::addExtension(const std::string& ext)
 }
 
 /**
-  * Returns instruments with given name
+  * Returns instrument with given name
   * @param  iName Instrument name
   * @return the instrument information object
   * @throw NotFoundError if iName was not found
   */
-const InstrumentInfo & FacilityInfo::Instrument(const std::string& iName)const
+const InstrumentInfo & FacilityInfo::instrument(const std::string& iName)const
 {
   std::string iname;
   if (iName.empty())
@@ -211,7 +211,7 @@ const InstrumentInfo & FacilityInfo::Instrument(const std::string& iName)const
   * @param tech :: Technique name
   * @return a list of instrument information objects
   */
-std::vector<InstrumentInfo> FacilityInfo::Instruments(const std::string& tech)const
+std::vector<InstrumentInfo> FacilityInfo::instruments(const std::string& tech)const
 {
   std::vector<InstrumentInfo> out;
   std::vector<InstrumentInfo>::const_iterator it = m_instruments.begin();
diff --git a/Code/Mantid/Framework/Kernel/src/InstrumentInfo.cpp b/Code/Mantid/Framework/Kernel/src/InstrumentInfo.cpp
index 8c86d8a634a..e499612494d 100644
--- a/Code/Mantid/Framework/Kernel/src/InstrumentInfo.cpp
+++ b/Code/Mantid/Framework/Kernel/src/InstrumentInfo.cpp
@@ -128,5 +128,20 @@ namespace Mantid
       return *m_facility;
     }
 
+    //-------------------------------------------------------------------------
+    // Non-member functions
+    //-------------------------------------------------------------------------
+    /**
+     * Prints the instrument name to the stream
+     * @param buffer :: A reference to an output stream
+     * @param instrumentDescriptor :: A reference to an InstrumentInfo object
+     * @return A reference to the stream written to
+     */
+    std::ostream & operator<<(std::ostream & buffer, const InstrumentInfo & instrumentDescriptor)
+    {
+      buffer << instrumentDescriptor.name();
+      return buffer;
+    }
+
   } // namespace Kernel
 } // namespace Mantid
diff --git a/Code/Mantid/Framework/Kernel/test/FacilitiesTest.h b/Code/Mantid/Framework/Kernel/test/FacilitiesTest.h
index e1bbb6d3230..4ce036ba1e6 100644
--- a/Code/Mantid/Framework/Kernel/test/FacilitiesTest.h
+++ b/Code/Mantid/Framework/Kernel/test/FacilitiesTest.h
@@ -5,6 +5,7 @@
 
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidKernel/ConfigService.h"
+#include "MantidKernel/Exception.h"
 
 #include <Poco/DOM/DOMParser.h>
 #include <Poco/DOM/Document.h>
@@ -58,27 +59,29 @@ public:
     TS_ASSERT_EQUALS(*it,"ADataSearch");
     TS_ASSERT_EQUALS(*++it,"BDataSearch");
 
-    const std::vector<InstrumentInfo> instrums = fac->Instruments();
+    const std::vector<InstrumentInfo> instrums = fac->instruments();
     TS_ASSERT_EQUALS(instrums.size(),2);
 
-    TS_ASSERT_THROWS_NOTHING(fac->Instrument("HRPD"));
-    InstrumentInfo instr = fac->Instrument("HRPD");
+    TS_ASSERT_THROWS_NOTHING(fac->instrument("HRPD"));
+    InstrumentInfo instr = fac->instrument("HRPD");
     TS_ASSERT_EQUALS(instr.name(),"HRPD");
     TS_ASSERT_EQUALS(instr.shortName(),"HRP");
     TS_ASSERT_EQUALS(instr.zeroPadding(),5);
 
-    TS_ASSERT_THROWS_NOTHING(fac->Instrument("WISH"));
-    instr = fac->Instrument("WISH");
+    TS_ASSERT_THROWS_NOTHING(fac->instrument("WISH"));
+    instr = fac->instrument("WISH");
     TS_ASSERT_EQUALS(instr.name(),"WISH");
     TS_ASSERT_EQUALS(instr.shortName(),"WISH");
     TS_ASSERT_EQUALS(instr.zeroPadding(),8);
 
-    const std::vector<InstrumentInfo> pwdInstr = fac->Instruments("Powder Diffraction");
+    const std::vector<InstrumentInfo> pwdInstr = fac->instruments("Powder Diffraction");
     TS_ASSERT_EQUALS(pwdInstr.size(),2);
 
-    const std::vector<InstrumentInfo> crysInstr = fac->Instruments("Single Crystal Diffraction");
+    const std::vector<InstrumentInfo> crysInstr = fac->instruments("Single Crystal Diffraction");
     TS_ASSERT_EQUALS(crysInstr.size(),1);
 
+    TS_ASSERT_THROWS(fac->instruments("rubbish category"), Exception::NotFoundError);
+
     // Test default live listener is empty
     TS_ASSERT( fac->liveListener().empty() )
 
diff --git a/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/std_operator_definitions.h b/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/std_operator_definitions.h
deleted file mode 100644
index 2ca80cda9e5..00000000000
--- a/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/std_operator_definitions.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef STD_OPERATOR_DEFINES_H_
-#define STD_OPERATOR_DEFINES_H_
-
-#include <MantidKernel/InstrumentInfo.h>
-
-/** @file
-
-    Some classes that are exported to Python do not define certain operators that are necessary
-    to wrap them. These operators are added here.
-
-    @author Martyn Gigg, Tessella plc
-    @date 12/08/2010
-
-    Copyright &copy; 2010 STFC Rutherford Appleton Laboratory
-
-    This file is part of Mantid.
-
-    Mantid is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 3 of the License, or
-    (at your option) any later version.
-
-    Mantid is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-    File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid>.
-    Code Documentation is available at: <http://doxygen.mantidproject.org>
- */
-namespace std
-{
-  /**
-   * Output an InstrumentInfo object to a stream
-   * @param os :: The output stream.
-   * @param instr :: The object to write out.
-   * @returns A reference to the stream that was written to.
-   */
-  inline ostream & operator<<(ostream & os, const Mantid::Kernel::InstrumentInfo& instr)
-  {
-    os << instr.name();
-    return os;
-  }
-}
-
-
-#endif //STD_OPERATOR_DEFINES_H_
diff --git a/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/stl_proxies.h b/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/stl_proxies.h
index c01c3352f03..dc21d381aa7 100644
--- a/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/stl_proxies.h
+++ b/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/stl_proxies.h
@@ -5,7 +5,6 @@
 #include <set>
 #include <sstream>
 
-#include "std_operator_definitions.h"
 #include "MantidPythonAPI/BoostPython_Silent.h"
 
 namespace Mantid
diff --git a/Code/Mantid/Framework/PythonAPI/src/kernel_exports.cpp b/Code/Mantid/Framework/PythonAPI/src/kernel_exports.cpp
index a0d812cb89f..6baac1b29ce 100644
--- a/Code/Mantid/Framework/PythonAPI/src/kernel_exports.cpp
+++ b/Code/Mantid/Framework/PythonAPI/src/kernel_exports.cpp
@@ -270,7 +270,7 @@ namespace PythonAPI
       ;
    }
 
-  BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(FacilityInfo_instrumentOverloads, Mantid::Kernel::FacilityInfo::Instrument, 0, 1)
+  BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(FacilityInfo_instrumentOverloads, Mantid::Kernel::FacilityInfo::instrument, 0, 1)
 
   void export_facilityinfo()
   {
@@ -279,9 +279,9 @@ namespace PythonAPI
       .def("zeroPadding", &FacilityInfo::zeroPadding)
       .def("extensions", &FacilityInfo::extensions)
       .def("preferredExt", &FacilityInfo::preferredExtension, return_value_policy<copy_const_reference>())
-      .def("instrument", &FacilityInfo::Instrument, FacilityInfo_instrumentOverloads()[return_value_policy<copy_const_reference>()])
-      .def("instruments", (const std::vector<InstrumentInfo>& (FacilityInfo::*)() const)&FacilityInfo::Instruments, return_value_policy<copy_const_reference>())
-      .def("instruments", (std::vector<InstrumentInfo> (FacilityInfo::*)(const std::string &) const)&FacilityInfo::Instruments)
+      .def("instrument", &FacilityInfo::instrument, FacilityInfo_instrumentOverloads()[return_value_policy<copy_const_reference>()])
+      .def("instruments", (const std::vector<InstrumentInfo>& (FacilityInfo::*)() const)&FacilityInfo::instruments, return_value_policy<copy_const_reference>())
+      .def("instruments", (std::vector<InstrumentInfo> (FacilityInfo::*)(const std::string &) const)&FacilityInfo::instruments)
       ;
   }
 
diff --git a/Code/Mantid/Framework/PythonInterface/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/CMakeLists.txt
index 97122198756..943f98a9011 100644
--- a/Code/Mantid/Framework/PythonInterface/CMakeLists.txt
+++ b/Code/Mantid/Framework/PythonInterface/CMakeLists.txt
@@ -82,6 +82,7 @@ set ( TEST_PY_FILES
   test/python/ConfigServiceTest.py
   test/python/CreateWorkspaceTest.py
   test/python/ExperimentInfoTest.py
+  test/python/FacilityInfoTest.py
   test/python/FilePropertyTest.py
   test/python/FileFinderTest.py
   test/python/FrameworkManagerTest.py
@@ -89,6 +90,7 @@ set ( TEST_PY_FILES
   test/python/IEventWorkspaceTest.py
   test/python/ImportModuleTest.py
   test/python/IPeaksWorkspaceTest.py
+  test/python/InstrumentInfoTest.py
   test/python/InstrumentTest.py
   test/python/ITableWorkspaceTest.py
   test/python/LoggerTest.py
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt
index 4ed208dbe5a..29a42074c03 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt
+++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt
@@ -23,6 +23,8 @@ set ( EXPORT_FILES
   src/Exports/BoundedValidator.cpp
   src/Exports/TimeSeriesProperty.cpp
   src/Exports/DateAndTime.cpp
+  src/Exports/InstrumentInfo.cpp
+  src/Exports/FacilityInfo.cpp
 )  
 
 set ( SRC_FILES
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigService.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigService.cpp
index 22fd15be40c..1d4e44116fa 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigService.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigService.cpp
@@ -1,13 +1,16 @@
 #include "MantidKernel/ConfigService.h"
+#include "MantidKernel/FacilityInfo.h"
 #include "MantidPythonInterface/kernel/Converters/PySequenceToVector.h"
 #include <boost/python/class.hpp>
 #include <boost/python/def.hpp>
 #include <boost/python/reference_existing_object.hpp>
 #include <boost/python/copy_const_reference.hpp>
 #include <boost/python/list.hpp>
+#include <boost/python/overloads.hpp>
 
 using Mantid::Kernel::ConfigService;
 using Mantid::Kernel::ConfigServiceImpl;
+using Mantid::Kernel::FacilityInfo;
 using namespace boost::python;
 
 namespace
@@ -18,28 +21,54 @@ namespace
     using namespace Mantid::PythonInterface;
     self.setDataSearchDirs(Converters::PySequenceToVectorConverter<std::string>(paths)());
   }
+
+  /// Overload generator for getInstrument
+  BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(getInstrument_Overload, getInstrument, 0, 1);
 }
 
 void export_ConfigService()
 {
   class_<ConfigServiceImpl, boost::noncopyable>("ConfigServiceImpl", no_init)
     .def("getLocalFilename", &ConfigServiceImpl::getLocalFilename, "Returns the path to the system wide properties file.")
+
     .def("getUserFilename", &ConfigServiceImpl::getUserFilename, "Returns the path to the user properties file")
+
     .def("getInstrumentDirectory", &ConfigServiceImpl::getInstrumentDirectory,
          "Returns the directory used for the instrument definitions")
+
+    .def("getFacility", (const FacilityInfo&(ConfigServiceImpl::*)() const)&ConfigServiceImpl::getFacility,
+        return_value_policy<reference_existing_object>(), "Returns the default facility")
+
+    .def("getFacility", (const FacilityInfo&(ConfigServiceImpl::*)(const std::string&) const)&ConfigServiceImpl::getFacility,
+         (arg("facilityName")), return_value_policy<reference_existing_object>(),
+         "Returns the named facility. Raises an RuntimeError if it does not exist")
+
+    .def("setFacility", &ConfigServiceImpl::setString, (arg("facilityName")), "Sets the current facility to the given name")
+
+    .def("getInstrument", &ConfigServiceImpl::getInstrument,
+          getInstrument_Overload("Returns the named instrument. If name = \"\" then the default.instrument is returned",
+                                 (arg("instrumentName")=""))[return_value_policy<copy_const_reference>()])
+
     .def("getString", (std::string (ConfigServiceImpl::*)(const std::string &))&ConfigServiceImpl::getString,
          "Return the given property")
+
     .def("setString", &ConfigServiceImpl::setString, "Set the given property name. "
          "If it does not exist it is added to the current configuration")
+
     .def("hasProperty", &ConfigServiceImpl::hasProperty)
+
     .def("getDataSearchDirs",&ConfigServiceImpl::getDataSearchDirs, return_value_policy<copy_const_reference>(),
          "Return the current list of data search paths")
+
     .def("appendDataSearchDir", &ConfigServiceImpl::appendDataSearchDir,
          "Append a directory to the current list of data search paths")
+
     .def("setDataSearchDirs", (void (ConfigServiceImpl::*)(const std::string &))&ConfigServiceImpl::setDataSearchDirs,
          "Set the whole datasearch.directories property from a single string. Entries should be separated by a ; character")
+
     .def("setDataSearchDirs", &setDataSearchDirs,
          "Set the  datasearch.directories property from a list of strings.")
+
     // Treat this as a dictionary
     .def("__getitem__", (std::string (ConfigServiceImpl::*)(const std::string &))&ConfigServiceImpl::getString)
     .def("__setitem__", &ConfigServiceImpl::setString)
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/FacilityInfo.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/FacilityInfo.cpp
new file mode 100644
index 00000000000..6e1511c725f
--- /dev/null
+++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/FacilityInfo.cpp
@@ -0,0 +1,52 @@
+#include "MantidKernel/FacilityInfo.h"
+#include <boost/python/class.hpp>
+#include <boost/python/copy_const_reference.hpp>
+
+using Mantid::Kernel::FacilityInfo;
+using Mantid::Kernel::InstrumentInfo;
+using namespace boost::python;
+
+void export_FacilityInfo()
+{
+
+  class_<FacilityInfo>("FacilityInfo", no_init)
+
+    .def("name", &FacilityInfo::name, return_value_policy<copy_const_reference>(),
+         "Returns name of the facility as definined in the Facilities.xml file")
+
+    .def("zeroPadding", &FacilityInfo::zeroPadding,
+         "Returns default zero padding for this facility")
+
+    .def("delimiter", &FacilityInfo::delimiter, return_value_policy<copy_const_reference>(),
+         "Returns the delimiter between the instrument name and the run number.")
+
+    .def("extensions", &FacilityInfo::extensions,
+         "Returns the list of file extensions that are considered as instrument data files.")
+
+    .def("preferredExtension",&FacilityInfo::preferredExtension, return_value_policy<copy_const_reference>(),
+         "Returns the extension that is preferred for this facility")
+
+    .def("getSoapEndPoint", &FacilityInfo::getSoapEndPoint, return_value_policy<copy_const_reference>(),
+         "Returns the name of the SOAP end point")
+
+    .def("archiveSearch", &FacilityInfo::archiveSearch, return_value_policy<copy_const_reference>(),
+         "Return the archive search interface names")
+
+    .def("instruments", (const std::vector<InstrumentInfo> & (FacilityInfo::*)()const)&FacilityInfo::instruments,
+         return_value_policy<copy_const_reference>(),
+         "Returns a list of instruments of this facility as defined in the Facilities.xml file")
+
+    .def("instruments", (std::vector<InstrumentInfo> (FacilityInfo::*)(const std::string&)const)&FacilityInfo::instruments,
+         "Returns a list of instruments of given technique")
+
+    .def("instrument", &FacilityInfo::instrument, return_value_policy<copy_const_reference>(),
+         "Returns the instrument with the given name")
+
+    .def("catalogName", &FacilityInfo::catalogName, return_value_policy<copy_const_reference>(),
+         "Returns the catalog name used at this facility")
+
+    .def("liveListener", &FacilityInfo::liveListener, return_value_policy<copy_const_reference>(),
+         "Returns the name of the default live listener")
+   ;
+}
+
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/InstrumentInfo.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/InstrumentInfo.cpp
new file mode 100644
index 00000000000..61f0f6b81c5
--- /dev/null
+++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/InstrumentInfo.cpp
@@ -0,0 +1,35 @@
+#include "MantidKernel/InstrumentInfo.h"
+#include "MantidKernel/FacilityInfo.h"
+#include "MantidPythonInterface/kernel/StlExportDefinitions.h"
+#include <boost/python/class.hpp>
+#include <boost/python/copy_const_reference.hpp>
+
+using Mantid::Kernel::InstrumentInfo;
+using namespace boost::python;
+
+void export_InstrumentInfo()
+{
+  using namespace Mantid::PythonInterface;
+  std_vector_exporter<InstrumentInfo>::wrap("std_vector_InstrumentInfo");
+
+  class_<InstrumentInfo>("InstrumentInfo", no_init)
+    .def("name", &InstrumentInfo::name, ""
+         "Returns the full name of the instrument as defined in the Facilites.xml file")
+
+    .def("shortName", &InstrumentInfo::shortName,
+         "Returns the abbreviated name of the instrument as definined in the Facilites.xml file")
+
+    .def("zeroPadding", &InstrumentInfo::zeroPadding,
+          "Returns zero padding for this instrument")
+
+    .def("delimiter", &InstrumentInfo::delimiter,
+         "Returns the delimiter between the instrument name and the run number.")
+
+    .def("techniques", &InstrumentInfo::techniques, return_value_policy<copy_const_reference>(),
+         "Return list of techniques this instrument supports")
+
+    .def("facility", &InstrumentInfo::facility, return_value_policy<copy_const_reference>(),
+         "Returns the facility that contains this instrument.")
+  ;
+}
+
diff --git a/Code/Mantid/Framework/PythonInterface/test/python/ConfigServiceTest.py b/Code/Mantid/Framework/PythonInterface/test/python/ConfigServiceTest.py
index 13a8d2dd0a6..9422dd2d085 100644
--- a/Code/Mantid/Framework/PythonInterface/test/python/ConfigServiceTest.py
+++ b/Code/Mantid/Framework/PythonInterface/test/python/ConfigServiceTest.py
@@ -1,7 +1,8 @@
 import unittest
 import os
 
-from mantid import ConfigService, ConfigServiceImpl, config, std_vector_str
+from mantid import (ConfigService, ConfigServiceImpl, config, 
+                    std_vector_str, FacilityInfo, InstrumentInfo)
 
 class ConfigServiceTest(unittest.TestCase):
 
@@ -19,6 +20,19 @@ class ConfigServiceTest(unittest.TestCase):
         user = config.getUserFilename().lower()
         self.assertTrue('user' in user)
 
+    def test_getFacilityReturns_A_FacilityInfo_Object(self):
+        facility = config.getFacility()
+        self.assertTrue(isinstance(facility, FacilityInfo))
+
+    def test_getFacility_With_Name_Returns_A_FacilityInfo_Object(self):
+        facility = config.getFacility("ISIS")
+        self.assertTrue(isinstance(facility, FacilityInfo))
+        self.assertRaises(RuntimeError, config.getFacility, "MadeUpFacility")
+
+    def test_getInstrumentReturns_A_InstrumentInfo_Object(self):
+        self.assertTrue(isinstance(config.getInstrument("WISH"), InstrumentInfo))
+        self.assertRaises(RuntimeError, config.getInstrument, "MadeUpInstrument")
+
     def test_service_acts_like_dictionary(self):
         test_prop = "algorithms.retained"
         self.assertTrue(config.hasProperty(test_prop))
diff --git a/Code/Mantid/Framework/PythonInterface/test/python/FacilityInfoTest.py b/Code/Mantid/Framework/PythonInterface/test/python/FacilityInfoTest.py
new file mode 100644
index 00000000000..c0f290d3ff6
--- /dev/null
+++ b/Code/Mantid/Framework/PythonInterface/test/python/FacilityInfoTest.py
@@ -0,0 +1,29 @@
+import unittest
+from mantid import FacilityInfo, InstrumentInfo, ConfigService
+
+class FacilityInfoTest(unittest.TestCase):
+
+    def test_construction_raies_an_error(self):
+        self.assertRaises(RuntimeError, FacilityInfo)
+
+    def _get_test_facility(self):
+        return ConfigService.getFacility("ISIS")
+    
+    def test_attributes_are_as_expected(self):
+        test_facility = self._get_test_facility()
+        
+        self.assertEquals(test_facility.name(), "ISIS")
+        self.assertEquals(test_facility.zeroPadding(), 5)
+        self.assertEquals(test_facility.delimiter(), "")
+        self.assertEquals(len(test_facility.extensions()), 12)
+        self.assertEquals(test_facility.preferredExtension(), ".nxs")
+        self.assertEquals(test_facility.getSoapEndPoint(), "https://facilities01.esc.rl.ac.uk:443/ICATService/ICAT")
+        self.assertEquals(len(test_facility.archiveSearch()), 1)
+        self.assertEquals(len(test_facility.instruments()), 30)
+        self.assertEquals(len(test_facility.instruments("Neutron Diffraction")), 11)
+        self.assertTrue(isinstance(test_facility.instrument("WISH"), InstrumentInfo))
+        self.assertEquals(test_facility.catalogName(), "ICat3Catalog")
+        self.assertEquals(test_facility.liveListener(), "")
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/Code/Mantid/Framework/PythonInterface/test/python/InstrumentInfoTest.py b/Code/Mantid/Framework/PythonInterface/test/python/InstrumentInfoTest.py
new file mode 100644
index 00000000000..e96d85d1f4d
--- /dev/null
+++ b/Code/Mantid/Framework/PythonInterface/test/python/InstrumentInfoTest.py
@@ -0,0 +1,16 @@
+import unittest
+from mantid import InstrumentInfo, ConfigService
+
+class InstrumentInfoTest(object):
+
+    def test_construction_raies_an_error(self):
+        self.assertRaises(RuntimeError, InstrumentInfo)
+
+    def test_instrument_name(self):
+        pass
+    
+    def test_instrument_shortName(self):
+        pass
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/InstrumentSelector.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/InstrumentSelector.cpp
index 0dffe5847d5..73bf86b639d 100644
--- a/Code/Mantid/MantidQt/MantidWidgets/src/InstrumentSelector.cpp
+++ b/Code/Mantid/MantidQt/MantidWidgets/src/InstrumentSelector.cpp
@@ -125,7 +125,7 @@ namespace MantidWidgets
       m_currentFacility = &(mantidSettings.getFacility(name.toStdString()));
     }
 
-    const std::vector<InstrumentInfo> & instruments = m_currentFacility->Instruments();
+    const std::vector<InstrumentInfo> & instruments = m_currentFacility->instruments();
     std::vector<InstrumentInfo>::const_iterator iend = instruments.end();
     std::set<std::string> alphabetizedNames;
     for( std::vector<InstrumentInfo>::const_iterator itr = instruments.begin(); itr != iend; ++itr )
@@ -136,7 +136,7 @@ namespace MantidWidgets
     for( std::set<std::string>::const_iterator itr = alphabetizedNames.begin(); itr != namesEnd; ++itr )
     {
       QString name = QString::fromStdString(*itr);
-      std::string prefix = m_currentFacility->Instrument(*itr).shortName();
+      std::string prefix = m_currentFacility->instrument(*itr).shortName();
       QString shortName = QString::fromStdString(prefix);
       this->addItem(name, QVariant(shortName));
     }
@@ -145,7 +145,7 @@ namespace MantidWidgets
     QString defaultName;
     try
     {
-      defaultName = QString::fromStdString(m_currentFacility->Instrument().name());
+      defaultName = QString::fromStdString(m_currentFacility->instrument().name());
     }
     catch( Exception::NotFoundError &)
     {
@@ -194,7 +194,7 @@ namespace MantidWidgets
     QStringListIterator techItr(techniques);
     while( techItr.hasNext() )
     {
-      const std::vector<InstrumentInfo> instruments = facility.Instruments(techItr.next().toStdString());
+      const std::vector<InstrumentInfo> instruments = facility.instruments(techItr.next().toStdString());
       const size_t nInstrs = instruments.size();
       for( size_t i = 0; i < nInstrs; ++i )
       {
-- 
GitLab