From 9cb6c60da70fdca12e37ba43fef0f6d2828b1e05 Mon Sep 17 00:00:00 2001
From: Martyn Gigg <martyn.gigg@stfc.ac.uk>
Date: Thu, 2 Dec 2010 09:21:42 +0000
Subject: [PATCH] Adding the SampleEnvironment class plus changes around
 Geometry for the Monte Carlo work. Some changes in Geometry just clear
 warnings surrounding unitialized objects in copy constructors for class with
 virtual base classes. Other changes revolve around materials. Re #1212

---
 Code/Mantid/API/inc/MantidAPI/Sample.h        | 200 ++++++----
 .../API/inc/MantidAPI/SampleEnvironment.h     |  67 ++++
 Code/Mantid/API/src/Sample.cpp                | 377 +++++++++++-------
 Code/Mantid/API/src/SampleEnvironment.cpp     |  77 ++++
 Code/Mantid/API/test/SampleEnvironmentTest.h  |  52 +++
 Code/Mantid/API/test/SampleTest.h             |  91 +++--
 .../Algorithms/src/AbsorptionCorrection.cpp   |   9 +-
 .../Algorithms/src/ConvertSpectrumAxis.cpp    |   1 -
 Code/Mantid/Algorithms/src/PoissonErrors.cpp  |   2 +-
 .../inc/MantidDataHandling/LoadInstrument.h   |   7 +
 .../DataHandling/src/CreateSampleShape.cpp    |  18 +-
 .../DataHandling/src/DefineGaugeVolume.cpp    |   3 +-
 .../DataHandling/src/LoadInstrument.cpp       |  17 +-
 Code/Mantid/DataHandling/src/LoadSPE.cpp      |   8 +-
 .../inc/MantidGeometry/Instrument/Detector.h  |   7 +-
 .../MantidGeometry/Instrument/ObjComponent.h  |  13 +-
 .../inc/MantidGeometry/Objects/Material.h     | 128 +++---
 .../inc/MantidGeometry/Objects/Object.h       |   9 +-
 Code/Mantid/Geometry/src/IObjComponent.cpp    |   5 +-
 .../Geometry/src/Instrument/Detector.cpp      |  11 +-
 .../Geometry/src/Instrument/Instrument.cpp    |   1 -
 .../src/Instrument/ObjCompAssembly.cpp        |   2 +-
 .../Geometry/src/Instrument/ObjComponent.cpp  |  22 +-
 Code/Mantid/Geometry/src/Objects/Material.cpp | 115 +++++-
 Code/Mantid/Geometry/src/Objects/Object.cpp   |  13 +-
 .../src/Rendering/BitmapGeometryHandler.cpp   |   6 +-
 Code/Mantid/Geometry/src/Surfaces/Surface.cpp |   3 -
 .../Geometry/test/ComponentCreationHelpers.hh |  10 +-
 Code/Mantid/Geometry/test/MaterialTest.h      |  47 ++-
 Code/Mantid/Geometry/test/ObjectTest.h        |   6 +-
 .../Kernel/inc/MantidKernel/MersenneTwister.h |   2 +-
 .../Kernel/inc/MantidKernel/NeutronAtom.h     | 159 ++++----
 .../inc/MantidKernel/PhysicalConstants.h      |   4 +
 .../inc/MantidKernel/RandomNumberGenerator.h  |   2 +-
 .../Kernel/inc/MantidKernel/VectorHelper.h    |   5 +-
 Code/Mantid/Kernel/src/MersenneTwister.cpp    |   4 +-
 Code/Mantid/Kernel/src/NeutronAtom.cpp        |  16 +-
 Code/Mantid/Kernel/src/VectorHelper.cpp       |  37 ++
 Code/Mantid/Kernel/test/NeutronAtomTest.h     |   2 +-
 .../Kernel/test/RandomNumberGeneratorTest.h   |   2 +-
 .../Nexus/inc/MantidNexus/NexusClasses.h      |   6 +-
 Code/Mantid/Nexus/src/LoadMuonNexus2.cpp      |   2 +
 Code/Mantid/Nexus/src/LoadSNSNexus.cpp        |   1 +
 Code/Mantid/Nexus/src/NexusClasses.cpp        |   1 +
 Code/Mantid/PythonAPI/MantidFramework.py      |   1 -
 45 files changed, 1061 insertions(+), 510 deletions(-)
 create mode 100644 Code/Mantid/API/inc/MantidAPI/SampleEnvironment.h
 create mode 100644 Code/Mantid/API/src/SampleEnvironment.cpp
 create mode 100644 Code/Mantid/API/test/SampleEnvironmentTest.h

diff --git a/Code/Mantid/API/inc/MantidAPI/Sample.h b/Code/Mantid/API/inc/MantidAPI/Sample.h
index 192845244bc..5f17b262e08 100644
--- a/Code/Mantid/API/inc/MantidAPI/Sample.h
+++ b/Code/Mantid/API/inc/MantidAPI/Sample.h
@@ -1,97 +1,147 @@
 #ifndef MANTID_API_SAMPLE_H_
 #define MANTID_API_SAMPLE_H_
 
-//----------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 // Includes
-//----------------------------------------------------------------------
+//------------------------------------------------------------------------------
+#include "DllExport.h"
+#include "MantidGeometry/V3D.h"
+#include "MantidGeometry/Quat.h"
 #include "MantidGeometry/Objects/Object.h"
+#include "MantidGeometry/Objects/Material.h"
 
 namespace Mantid
 {
-namespace API
-{
-/** This class stores information about the sample used in a particular experimental run,
-    and some of the run parameters.
-    This is mainly garnered from logfiles.
+  //-----------------------------------------------------------------------------
+  // Geometry forward declarations
+  //------------------------------------------------------------------------------
+  namespace Geometry
+  {
+    class IComponent;
+  }
 
-    @author Russell Taylor, Tessella Support Services plc
-    @date 26/11/2007
+  namespace API
+  {
+    //-----------------------------------------------------------------------------
+    // API forward declarations
+    //------------------------------------------------------------------------------
+    class SampleEnvironment;
 
-    Copyright &copy; 2007-2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
+    /** 
 
-    This file is part of Mantid.
+      This class stores information about the sample used in particular 
+      run. It is a type of ObjComponent meaning it has a shape, a position
+      and a material.
 
-    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.
+      @author Russell Taylor, Tessella plc
+      @author Martyn Gigg, Tessella plc
+      @date 26/11/2007
+      
+      Copyright &copy; 2007-2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National 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>
+    */
+    class EXPORT_OPT_MANTID_API Sample
+    {
+    public:
+      /// Default constructor (required for cow_ptr)
+      Sample();
+      /// Copy constructor. 
+      Sample(const Sample& copy);
+      /// Private assignment operator. 
+      Sample& operator=(const Sample& rhs);
 
-    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.
+      /// Returns the name of the sample
+      const std::string & getName() const;
+      /// Set the name of the sample
+      void setName(const std::string & name);
+      /// Return the sample shape
+      const Geometry::Object& getShape() const;
+      /// Update the shape of the object
+      void setShape(const Geometry::Object& shape);
 
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+      /** @name Access the environment information */
+      //@{
+      /// Get a reference to the sample's environment
+      const SampleEnvironment & getEnvironment() const;
+      /// Set the environment used to contain the sample
+      void setEnvironment(SampleEnvironment * env);
+      //@}
 
-    File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid>.
-    Code Documentation is available at: <http://doxygen.mantidproject.org>
-*/
-class DLLExport Sample
-{
-public:
-  /// Default constructor
-  Sample();
-  /// Virtual destructor
-  virtual ~Sample();
+      /** @name Position and rotation information. */
+      //@
+      /// Returns the absolute position of the sample
+      Geometry::V3D getPos() const;
+      /// Returns the absolute rotation of the sample
+      Geometry::Quat getRotation() const;
+      /// Attach the sample to a position defined by the given component.
+      /// There is no transfer of ownership.
+      void attachToPosition(const Geometry::IComponent *const positionComp);
+      //@}
 
-  /// Set the name of the sample
-  void setName( const std::string &name );
-  /// Returns the name of the sample
-  const std::string& getName() const;
-  /// Set the geometrical shape of the sample
-  void setShapeObject(const Geometry::Object & sample_shape);
-  /// Returns the geometrical shape of the sample
-  const Geometry::Object& getShapeObject() const;
+      // Required for SANS work until we define a proper
+      // sample object from the raw file information
+      /**@name Legacy functions */
+      //@{
+      /// Sets the geometry flag
+      void setGeometryFlag(int geom_id);
+      /// Returns the geometry flag
+      int getGeometryFlag() const;
+      /// Sets the thickness
+      void setThickness(double thick);
+      /// Returns the thickness
+      double getThickness() const;
+      /// Sets the height
+      void setHeight(double height);
+      /// Returns the height
+      double getHeight() const;
+      /// Sets the width
+      void setWidth(double width);
+      /// Returns the width
+      double getWidth() const;  
+      //@}
 
-  /// Sets the geometry flag
-  void setGeometryFlag(int geom_id);
-  /// Returns the geometry flag
-  int getGeometryFlag() const;
-  /// Sets the thickness
-  void setThickness(double thick);
-  /// Returns the thickness
-  double getThickness() const;
-  /// Sets the height
-  void setHeight(double height);
-  /// Returns the height
-  double getHeight() const;
-  /// Sets the width
-  void setWidth(double width);
-  /// Returns the width
-  double getWidth() const;
-  
-  /// Copy constructor. 
-  Sample(const Sample& copy);
-  /// Copy assignment operator. 
-  const Sample& operator=(const Sample& rhs);
+    private: 
+      /// The sample name
+      std::string m_name;
+      /// The sample shape object
+      Geometry::Object m_shape;
+      /// The sample composition
+      Geometry::Material m_material;
+      /// An owned pointer to the SampleEnvironment object
+      boost::shared_ptr<SampleEnvironment> m_environment;
 
-private: 
-  /// The name for the sample
-  std::string m_name;
-  /// The sample shape object
-  Geometry::Object m_sample_shape;
-  /// The sample geometry flag
-  int m_geom_id;
-  /// The sample thickness from the SPB_STRUCT in the raw file
-  double m_thick;
-  /// The sample height from the SPB_STRUCT in the raw file
-  double m_height;
-  /// The sample width from the SPB_STRUCT in the raw file
-  double m_width;
-};
+      /// A pointer to the component that is identified as the sample 
+      /// position, not owned.
+      Geometry::IComponent const * m_positionComp;
+      
+      /// The sample geometry flag
+      int m_geom_id;
+      /// The sample thickness from the SPB_STRUCT in the raw file
+      double m_thick;
+      /// The sample height from the SPB_STRUCT in the raw file
+      double m_height;
+      /// The sample width from the SPB_STRUCT in the raw file
+      double m_width;
+    };
 
-} // namespace API
+  } // namespace API
 } // namespace Mantid
 
 #endif /*MANTID_API_SAMPLE_H_*/
diff --git a/Code/Mantid/API/inc/MantidAPI/SampleEnvironment.h b/Code/Mantid/API/inc/MantidAPI/SampleEnvironment.h
new file mode 100644
index 00000000000..39a69b4a0d9
--- /dev/null
+++ b/Code/Mantid/API/inc/MantidAPI/SampleEnvironment.h
@@ -0,0 +1,67 @@
+#ifndef MANTID_API_SAMPLEENVIRONMENT_H_
+#define MANTID_API_SAMPLEENVIRONMENT_H_
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include "DllExport.h"
+#include "MantidGeometry/Instrument/CompAssembly.h"
+
+namespace Mantid
+{
+  namespace API
+  {
+    /** 
+      This class stores details regarding the sample environment that was used during
+      a specific run. It is implemented as a type of CompAssembly so that enviroment kits
+      consisting of objects made from different materials can be constructed easily.
+	
+      @author Martyn Gigg, Tessella plc
+      @date 23/11/2010
+      
+      Copyright &copy; 2007-2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National 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>
+    */
+    class EXPORT_OPT_MANTID_API SampleEnvironment : public Geometry::CompAssembly
+    {
+    public:
+      /// Constructor defining the name of the environment
+      SampleEnvironment(const std::string & name);
+      /// Copy constructor
+      SampleEnvironment(const SampleEnvironment& original);
+      /// Clone the assembly
+      virtual Geometry::IComponent* clone() const;
+      /// Type of object
+      virtual std::string type() const {return "SampleEnvironment"; }
+
+      /// Override add a component to the assembly so that we can only add components that
+      /// have a physical shape
+      int add(IComponent* comp);
+
+    private:
+      /// Default constructor
+      SampleEnvironment();
+      /// Assignment operator
+      SampleEnvironment& operator=(const SampleEnvironment&);
+    };
+  }
+}
+
+#endif // MANTID_API_SAMPLEENVIRONMENT_H_
diff --git a/Code/Mantid/API/src/Sample.cpp b/Code/Mantid/API/src/Sample.cpp
index a975be00310..ab77cc40651 100644
--- a/Code/Mantid/API/src/Sample.cpp
+++ b/Code/Mantid/API/src/Sample.cpp
@@ -2,156 +2,239 @@
 // Includes
 //----------------------------------------------------------------------
 #include "MantidAPI/Sample.h"
+#include "MantidAPI/SampleEnvironment.h"
+#include "MantidGeometry/IComponent.h"
 
 namespace Mantid
 {
-namespace API
-{
-
-/// Constructor
-Sample::Sample() :
-  m_name(), m_sample_shape(), m_geom_id(0), m_thick(0.0),
-  m_height(0.0), m_width(0.0)
-{
-}
-
-/**  copy constructor 
-  *  @param copy const reference to the sample object
-*/
-Sample::Sample(const Sample& copy) :
-  m_name(copy.m_name), m_sample_shape(copy.m_sample_shape), m_geom_id(copy.m_geom_id), 
-  m_thick(copy.m_thick), m_height(copy.m_height), m_width(copy.m_width)
-{
-}
 
-/**  assignment operator 
- * @param rhs const reference to the sample object
- * @return copy of sample object
- */
-  const Sample& Sample::operator=(const Sample&rhs)
-{
-  if (this == &rhs) return *this;
-  m_name = rhs.m_name;
-  m_sample_shape = rhs.m_sample_shape;
-  m_geom_id = rhs.m_geom_id;
-  m_thick = rhs.m_thick;
-  m_height = rhs.m_height;
-  m_width = rhs.m_width;
-  return *this;
-}
+  namespace API
+  {
+
+    using Geometry::Object;
+    using Geometry::Material;
+    using Geometry::IComponent;
+    using Geometry::V3D;
+    using Geometry::Quat;
+    
+    /**
+     * Default constructor
+     */
+    Sample::Sample() : 
+      m_name(), m_shape(), m_material(), m_environment(), m_positionComp(NULL), 
+      m_geom_id(0), m_thick(0.0), m_height(0.0), m_width(0.0)
+    {
+    }
+
+    /** 
+     * Copy constructor 
+     *  @param copy const reference to the sample object
+     */
+    Sample::Sample(const Sample& copy) :
+      m_name(copy.m_name), m_shape(copy.m_shape), m_material(copy.m_material), 
+      m_environment(copy.m_environment), m_positionComp(copy.m_positionComp), 
+      m_geom_id(copy.m_geom_id), m_thick(copy.m_thick), m_height(copy.m_height), 
+      m_width(copy.m_width)
+    {
+    }
+
+    /** Assignment operator 
+     * @param rhs const reference to the sample object
+     * @return A reference to this object, which will have the same 
+     * state as the argument
+     */
+    Sample& Sample::operator=(const Sample&rhs)
+    {
+      if (this == &rhs) return *this;
+      m_name = rhs.m_name;
+      m_shape = rhs.m_shape;
+      m_material = rhs.m_material;
+      m_environment = rhs.m_environment;
+      m_positionComp = rhs.m_positionComp;
+      m_geom_id = rhs.m_geom_id;
+      m_thick = rhs.m_thick;
+      m_height = rhs.m_height;
+      m_width = rhs.m_width;
+      return *this;
+    }
   
-/// Destructor
-Sample::~Sample()
-{
-}
-
-/** Set the name of the sample
- *  @param name The name to assign
- */
-void Sample::setName( const std::string &name )
-{
-  m_name = name;
-}
-
-/** Gets the name of the sample
- *  @return The name of the sample
- */
-const std::string& Sample::getName() const
-{
-  return m_name;
-}
-
-/**
- * Set the object that describes the sample shape
- * @param sample_shape The shape object
- */
-void Sample::setShapeObject(const Geometry::Object & sample_shape)
-{
-  m_sample_shape = sample_shape;
-}
-
-/**
- * Get a pointer to the sample shape object
- * @returns A shared pointer to the sample object
- */
-const Geometry::Object& Sample::getShapeObject() const
-{
-  return m_sample_shape;
-}
-
-/**
- * Set the geometry flag that is specfied in the raw file within the SPB_STRUCT
- * 1 = cylinder, 2 = flat plate, 3 = disc, 4 = single crystal
- * @param geom_id The flag for the geometry
- */
-void Sample::setGeometryFlag(int geom_id)
-{
-  m_geom_id = geom_id;
-}
-
-/**
- * Get the geometry flag that is specified in the raw file within the SPB_STRUCT
- * 1 = cylinder, 2 = flat plate, 3 = disc, 4 = single crystal
- * @returns The flag for the sample geometry
- */
-int Sample::getGeometryFlag() const
-{
-  return m_geom_id;
-}
-
-/**
- * Set the thickness value
- * @param thick The parameter e_thick in the SPB_STRUCT
- */
-void Sample::setThickness(double thick)
-{
-  m_thick = thick;
-}
-
-/**
- * Get the thickness value
- * @returns The parameter thickness parameter
- */
-double Sample::getThickness() const
-{
-  return m_thick;
-}
-
-/**
- * Set the height value
- * @param height The parameter e_height in the SPB_STRUCT
- */
-void Sample::setHeight(double height)
-{
-  m_height = height;
-}
-
-/**
- * Get the height value
- * @returns The parameter height parameter
- */
-double Sample::getHeight() const
-{
-  return m_height;
-}
-
-/**
- * Set the width value
- * @param width The parameter e_width in the SPB_STRUCT
- */
-void Sample::setWidth(double width)
-{
-  m_width = width;
-}
-
-/**
- * Get the height value
- * @returns The parameter height parameter
- */
-double Sample::getWidth() const
-{
-  return m_width;
-}
-
-}
+    /** 
+     * Returns the name of the sample
+     * @returns The name of this  sample
+     */
+    const std::string & Sample::getName() const
+    {
+      return m_name;
+    }
+
+    /** 
+     * Update the name of the sample
+     * @param name The name of the sample
+     */
+    void Sample::setName(const std::string & name)
+    {
+      m_name = name;
+    }
+
+    /**
+     * Get a pointer to the sample shape object
+     * @returns A reference to the object describing the shape
+     */
+    const Object& Sample::getShape() const
+    {
+      return m_shape;
+    }
+
+    /**
+     * Set the object that describes the sample shape
+     * @param object The object describing the shape
+     * @throws An std::invalid_argument error if the object does 
+     * not have a valid shape
+     */
+    void Sample::setShape(const Object & object)
+    {
+      if( object.hasValidShape() )
+      {
+	m_shape = object;
+      }
+      else
+      {
+	throw std::invalid_argument("Sample::setShape - Object has an invalid shape.");
+      }
+    }
+
+    /**
+     * Return a reference to the sample environment that this sample is attached to
+     * @returns A const reference to a SampleEnvironment object
+     * @throws std::runtime_error If the environment has not been defined
+     */
+    const SampleEnvironment & Sample::getEnvironment() const
+    {
+      if( !m_environment )
+      {
+	throw std::runtime_error("Sample::getEnvironment - No sample enviroment has been defined.");
+      }
+      return *m_environment;
+    }
+
+    /**
+     * Attach an environment oto this sample
+     * @param env A pointer to a created sample environment. This takes 
+     * ownership of the object.
+     */
+    void Sample::setEnvironment(SampleEnvironment * env)
+    {
+      m_environment = boost::shared_ptr<SampleEnvironment>(env);
+    }
+
+    /**
+     * Returns the absolute position of the sample
+     * @returns A V3D object containing the absolute position of the sample
+     */
+    V3D Sample::getPos() const
+    {
+      if( !m_positionComp ) 
+      {
+	throw std::runtime_error("Sample::getPos - Position component not defined.");
+      }
+      return m_positionComp->getPos();
+    }
+    
+    /** 
+     * Returns the absolute rotation of the sample
+     * @returns A Quaternion containin the absolute rotation of the sample
+     */
+    Quat Sample::getRotation() const
+    {
+      if( !m_positionComp ) 
+      {
+	throw std::runtime_error("Sample::getRoations - Position component not defined.");
+      }
+      return m_positionComp->getRotation();
+    }
+
+    /**
+     * Attach the sample to a position defined by the given component.
+     * @param positionComp The component defining the sample position
+     */
+    void Sample::attachToPosition(const Geometry::IComponent * const positionComp)
+    {
+      m_positionComp = positionComp;
+    }
+        
+    /**
+     * Set the geometry flag that is specfied in the raw file within the SPB_STRUCT
+     * 1 = cylinder, 2 = flat plate, 3 = disc, 4 = single crystal
+     * @param geom_id The flag for the geometry
+     */
+    void Sample::setGeometryFlag(int geom_id)
+    {
+      m_geom_id = geom_id;
+    }
+
+    /**
+     * Get the geometry flag that is specified in the raw file within the SPB_STRUCT
+     * 1 = cylinder, 2 = flat plate, 3 = disc, 4 = single crystal
+     * @returns The flag for the sample geometry
+     */
+    int Sample::getGeometryFlag() const
+    {
+      return m_geom_id;
+    }
+
+    /**
+     * Set the thickness value
+     * @param thick The parameter e_thick in the SPB_STRUCT
+     */
+    void Sample::setThickness(double thick)
+    {
+      m_thick = thick;
+    }
+
+    /**
+     * Get the thickness value
+     * @returns The parameter thickness parameter
+     */
+    double Sample::getThickness() const
+    {
+      return m_thick;
+    }
+
+    /**
+     * Set the height value
+     * @param height The parameter e_height in the SPB_STRUCT
+     */
+    void Sample::setHeight(double height)
+    {
+      m_height = height;
+    }
+
+    /**
+     * Get the height value
+     * @returns The parameter height parameter
+     */
+    double Sample::getHeight() const
+    {
+      return m_height;
+    }
+
+    /**
+     * Set the width value
+     * @param width The parameter e_width in the SPB_STRUCT
+     */
+    void Sample::setWidth(double width)
+    {
+      m_width = width;
+    }
+
+    /**
+     * Get the height value
+     * @returns The parameter height parameter
+     */
+    double Sample::getWidth() const
+    {
+      return m_width;
+    }
+
+  }
 }
diff --git a/Code/Mantid/API/src/SampleEnvironment.cpp b/Code/Mantid/API/src/SampleEnvironment.cpp
new file mode 100644
index 00000000000..0b2d34d639b
--- /dev/null
+++ b/Code/Mantid/API/src/SampleEnvironment.cpp
@@ -0,0 +1,77 @@
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include "MantidAPI/SampleEnvironment.h"
+#include "MantidGeometry/IObjComponent.h"
+#include "MantidGeometry/Objects/Object.h"
+
+namespace Mantid
+{
+  namespace API
+  {
+    
+    using Geometry::IComponent;
+    using Geometry::IObjComponent;
+
+    //------------------------------------------------------------------------------
+    // Public methods
+    //------------------------------------------------------------------------------
+    
+    /**
+     * Constructor specifying a name for the environment
+     * @param name A name for the environment kit
+     */
+    SampleEnvironment::SampleEnvironment(const std::string & name) : 
+      CompAssembly(name, NULL)
+    {
+    }
+
+    /**
+     * Copy constructor
+     * @param original The object whose state is to be copied.
+     */
+    SampleEnvironment::SampleEnvironment(const SampleEnvironment & original) : 
+      CompAssembly(original)
+    {
+    }
+
+    /**
+     * Clone the environment assembly
+     * @returns A pointer to the clone object
+     */
+    Geometry::IComponent* SampleEnvironment::clone() const
+    {
+      return new SampleEnvironment(*this);
+    }
+    
+    /**
+     * Override the add method so that we can only add physical components that
+     * have a defined shape, i.e. an ObjComponent with a valid shape
+     * @param comp A pointer to the phyiscal component. This object will take 
+     * ownership of the pointer
+     * @returns The number of items within the assembly, after this component has 
+     * been added
+     */
+    int SampleEnvironment::add(IComponent * comp)
+    {
+      // Check if this is a component with a shape
+      IObjComponent * physicalComp = dynamic_cast<IObjComponent*>(comp);
+      if( !physicalComp )
+      {
+	throw std::invalid_argument("CompAssembly::add - Invalid component, it must implement "
+				    "the IObjComponent interface");
+      }
+      if( physicalComp->shape() && physicalComp->shape()->hasValidShape() )
+      {
+	// Accept this component
+	return CompAssembly::add(comp);
+      }
+      else
+      {
+	throw std::invalid_argument("CompAssembly::add - Component does not have a defined shape.");
+      }
+    }
+    
+  }
+
+}
diff --git a/Code/Mantid/API/test/SampleEnvironmentTest.h b/Code/Mantid/API/test/SampleEnvironmentTest.h
new file mode 100644
index 00000000000..6679d05491c
--- /dev/null
+++ b/Code/Mantid/API/test/SampleEnvironmentTest.h
@@ -0,0 +1,52 @@
+#ifndef TESTSAMPLEENVIRONMENT_H_
+#define TESTSAMPLEENVIRONMENT_H_
+
+#include <cxxtest/TestSuite.h>
+#include "MantidAPI/SampleEnvironment.h"
+#include "MantidGeometry/Instrument/Component.h"
+#include "../../Geometry/test/ComponentCreationHelpers.hh"
+
+using Mantid::API::SampleEnvironment;
+using namespace Mantid::Geometry;
+
+class SampleEnvironmentTest : public CxxTest::TestSuite
+{
+
+public:
+  
+  void test_That_Constructor_Giving_Name_Creates_The_Correct_Name()
+  {
+    SampleEnvironment kit("TestKit");
+    TS_ASSERT_EQUALS(kit.getName(), "TestKit");
+  }
+
+  void test_That_Type_Is_SampleEnvironment()
+  {
+    SampleEnvironment kit("kit1");
+    TS_ASSERT_EQUALS(kit.type(), "SampleEnvironment");
+  }
+
+  void test_That_Adding_A_Component_Without_A_Shape_Throws_Invalid_Argument()
+  {
+    Component *part = new Component("part");
+    SampleEnvironment kit("TestKit");
+    TS_ASSERT_THROWS(kit.add(part), std::invalid_argument);    
+  }
+
+  void test_That_Adding_Valid_Components_Gives_The_Correct_Number_Of_Elements_In_The_Environment()
+  {
+    ObjComponent *physicalObject = ComponentCreationHelper::createSingleObjectComponent();
+    SampleEnvironment kit("TestKit");
+    
+    int numElements(0);
+    TS_ASSERT_THROWS_NOTHING(numElements = kit.add(physicalObject));
+    TS_ASSERT_EQUALS(numElements, 1);
+  }
+
+
+
+};
+
+
+
+#endif // TESTSAMPLEENVIRONMENT_H_
diff --git a/Code/Mantid/API/test/SampleTest.h b/Code/Mantid/API/test/SampleTest.h
index bfc75f781ae..f5de3863f2a 100644
--- a/Code/Mantid/API/test/SampleTest.h
+++ b/Code/Mantid/API/test/SampleTest.h
@@ -5,23 +5,21 @@
 
 #include "MantidAPI/Sample.h"
 #include "MantidKernel/Exception.h"
-#include "MantidGeometry/Objects/ShapeFactory.h"
-#include "Poco/DOM/DOMParser.h"
-#include "Poco/DOM/Document.h"
-#include "Poco/DOM/Element.h"
-#include "Poco/Path.h"
-#include "Poco/File.h"
+#include "MantidAPI/SampleEnvironment.h"
 
+#include "../../Geometry/test/ComponentCreationHelpers.hh"
 
 using namespace Mantid::Kernel;
 using namespace Mantid::Geometry;
 using Mantid::API::Sample;
+using Mantid::API::SampleEnvironment;
 
 class SampleTest : public CxxTest::TestSuite
 {
 public:
   void testSetGetName()
   {
+    Sample sample;
     TS_ASSERT( ! sample.getName().compare("") )
     sample.setName("test");
     TS_ASSERT( ! sample.getName().compare("test") )
@@ -29,38 +27,63 @@ public:
 
   void testShape()
   {
-    
-    std::string xmlShape = "<cylinder id=\"shape\"> ";
-    xmlShape +=	"<centre-of-bottom-base x=\"0.0\" y=\"0.0\" z=\"0.0\" /> " ; 
-    xmlShape +=	"<axis x=\"0.0\" y=\"1.0\" z=\"0\" /> " ;
-    xmlShape +=	"<radius val=\"0.0127\" /> " ;
-    xmlShape +=	"<height val=\"1\" /> " ;
-    xmlShape +=	"</cylinder>";
-    xmlShape +=	"<algebra val=\"shape\" /> ";  
-    std::string shapeXML = "<type name=\"userShape\"> " + xmlShape + " </type>";
-    
-    // Set up the DOM parser and parse xml string
-    Poco::XML::DOMParser pParser;
-    Poco::XML::Document* pDoc;
-    
-    pDoc = pParser.parseString(shapeXML);
-    
-    // Get pointer to root element
-    Poco::XML::Element* pRootElem = pDoc->documentElement();
-    
-    //convert into a Geometry object
-    ShapeFactory sFactory;
-    boost::shared_ptr<Object> shape_sptr = sFactory.createShape(pRootElem);
-    pDoc->release();
-    
-    TS_ASSERT_THROWS_NOTHING(sample.setShapeObject(*shape_sptr))
-    const Object & sampleShape = sample.getShapeObject();
+    Object_sptr shape_sptr = 
+      ComponentCreationHelper::createCappedCylinder(0.0127, 1.0, V3D(), V3D(0.0, 1.0, 0.0), "cyl");
+    Sample sample;
+    TS_ASSERT_THROWS_NOTHING(sample.setShape(*shape_sptr))
+    const Object & sampleShape = sample.getShape();
     TS_ASSERT_EQUALS(shape_sptr->getName(), sampleShape.getName());
   }
 
-private:
+  void test_That_An_Setting_An_Invalid_Shape_Throws_An_Invalid_Argument()
+  {
+    Sample sample;
+    Object object;
+    TS_ASSERT_EQUALS(object.hasValidShape(), false);
+    TS_ASSERT_THROWS(sample.setShape(object), std::invalid_argument);
+  }
 
-  Sample sample;
+  void test_Requests_For_Pos_Information_With_Valid_Component_Link_Do_Not_Throw()
+  {
+    const V3D pos(0.0,0.0,1.0);
+    const Quat rot(10., V3D(0.,1.0,0.0));
+    Component *sampleHolder = new Component("SamplePos", pos, rot);
+    Sample sample;
+    sample.attachToPosition(sampleHolder);
+
+    TS_ASSERT_EQUALS(sample.getPos(), pos);
+    TS_ASSERT_EQUALS(sample.getRotation(), rot);
+  }
+
+  void test_Requests_For_Pos_Information_Without_Attaching_A_Component_Throw()
+  {
+    Sample sample;
+    TS_ASSERT_THROWS(sample.getPos(), std::runtime_error);
+    TS_ASSERT_THROWS(sample.getRotation(), std::runtime_error);
+  }
+  
+  void test_That_Requests_For_An_Undefined_Environment_Throw()
+  {
+    Sample sample;
+    TS_ASSERT_THROWS(sample.getEnvironment(), std::runtime_error);
+  }
+
+  void test_That_An_Environment_Can_Be_Set_And_The_Same_Environment_Is_Returned()
+  {
+    Sample sample;
+    const std::string envName("TestKit");
+    SampleEnvironment *kit = new SampleEnvironment(envName);
+    kit->add(ComponentCreationHelper::createSingleObjectComponent());
+    
+    TS_ASSERT_THROWS_NOTHING(sample.setEnvironment(kit));
+    
+    const SampleEnvironment & sampleKit = sample.getEnvironment();
+    // Test that this references the correct object
+    TS_ASSERT_EQUALS(&sampleKit, kit);
+    TS_ASSERT_EQUALS(sampleKit.getName(), envName);
+    TS_ASSERT_EQUALS(sampleKit.nelements(), 1);
+  }
+  
 };
 
 #endif /*TESTSAMPLE_H_*/
diff --git a/Code/Mantid/Algorithms/src/AbsorptionCorrection.cpp b/Code/Mantid/Algorithms/src/AbsorptionCorrection.cpp
index af7ea6acf97..7cfdf9d0127 100644
--- a/Code/Mantid/Algorithms/src/AbsorptionCorrection.cpp
+++ b/Code/Mantid/Algorithms/src/AbsorptionCorrection.cpp
@@ -6,6 +6,7 @@
 #include "MantidGeometry/Objects/ShapeFactory.h"
 #include "MantidKernel/UnitFactory.h"
 #include "MantidKernel/Fast_Exponential.h"
+#include "MantidKernel/VectorHelper.h"
 
 namespace Mantid
 {
@@ -189,7 +190,7 @@ void AbsorptionCorrection::exec()
 
     if (x_step > 1) // Interpolate linearly between points separated by x_step, last point required
     {
-      interpolate(X, Y, isHist);
+      VectorHelper::linearlyInterpolateY(X, Y, x_step);
     }
 
     prog.report();
@@ -252,7 +253,7 @@ void AbsorptionCorrection::constructSample(API::Sample& sample)
   if (xmlstring.empty())
   {
     // This means that we should use the shape already defined on the sample.
-    m_sampleObject = &sample.getShapeObject();
+    m_sampleObject = &sample.getShape();
     // Check there is one, and fail if not
     if ( ! m_sampleObject->topRule() )
     {
@@ -264,8 +265,8 @@ void AbsorptionCorrection::constructSample(API::Sample& sample)
   else
   {
     boost::shared_ptr<Object> shape = ShapeFactory().createShape(xmlstring);
-    sample.setShapeObject( *shape );
-    m_sampleObject = &sample.getShapeObject();
+    sample.setShape( *shape );
+    m_sampleObject = &sample.getShape();
 
     g_log.information("Successfully constructed the sample object");
   }
diff --git a/Code/Mantid/Algorithms/src/ConvertSpectrumAxis.cpp b/Code/Mantid/Algorithms/src/ConvertSpectrumAxis.cpp
index ba5bdefbe49..c791f4d0c2c 100644
--- a/Code/Mantid/Algorithms/src/ConvertSpectrumAxis.cpp
+++ b/Code/Mantid/Algorithms/src/ConvertSpectrumAxis.cpp
@@ -64,7 +64,6 @@ namespace Algorithms
     // Get the input workspace
     MatrixWorkspace_const_sptr inputWS = getProperty("InputWorkspace");
     std::string unitTarget = getProperty("Target");
-    const Axis* const specAxis = inputWS->getAxis(1);
     // Loop over the original spectrum axis, finding the theta (n.b. not 2theta!) for each spectrum
     // and storing it's corresponding workspace index
     // Map will be sorted on theta, so resulting axis will be ordered as well
diff --git a/Code/Mantid/Algorithms/src/PoissonErrors.cpp b/Code/Mantid/Algorithms/src/PoissonErrors.cpp
index 98f6a1a05e5..c0861bd4f1c 100644
--- a/Code/Mantid/Algorithms/src/PoissonErrors.cpp
+++ b/Code/Mantid/Algorithms/src/PoissonErrors.cpp
@@ -43,7 +43,7 @@ namespace Mantid
     void PoissonErrors::performBinaryOperation(const MantidVec& lhsX, const MantidVec& lhsY, const MantidVec& lhsE,
                                                const double& rhsY, const double& rhsE, MantidVec& YOut, MantidVec& EOut)
     {
-      (void) lhsE; //Avoid compiler warning
+      (void) lhsE; (void) lhsX; //Avoid compiler warning
 
       assert( lhsX.size() == 1 );
       // If we get here we've got two single column workspaces so it's easy.
diff --git a/Code/Mantid/DataHandling/inc/MantidDataHandling/LoadInstrument.h b/Code/Mantid/DataHandling/inc/MantidDataHandling/LoadInstrument.h
index c9dc964b647..d2ef38c4b2e 100644
--- a/Code/Mantid/DataHandling/inc/MantidDataHandling/LoadInstrument.h
+++ b/Code/Mantid/DataHandling/inc/MantidDataHandling/LoadInstrument.h
@@ -18,6 +18,10 @@ namespace XML {
 
 namespace Mantid
 {
+  namespace API
+  {
+    class MatrixWorkspace;
+  }
 
   namespace Geometry
   {
@@ -217,6 +221,9 @@ namespace Mantid
       /// when this const equals 1 it means that angle=degree (default) is set in IDF
       /// otherwise if this const equals 180/pi it means that angle=radian is set in IDF 
       double m_angleConvertConst; 
+      
+      /// Everything can reference the workspace if it needs to
+      boost::shared_ptr<API::MatrixWorkspace> m_workspace;
     };
 
   } // namespace DataHandling
diff --git a/Code/Mantid/DataHandling/src/CreateSampleShape.cpp b/Code/Mantid/DataHandling/src/CreateSampleShape.cpp
index 255ff8c8568..df561979349 100644
--- a/Code/Mantid/DataHandling/src/CreateSampleShape.cpp
+++ b/Code/Mantid/DataHandling/src/CreateSampleShape.cpp
@@ -37,14 +37,24 @@ void CreateSampleShape::init()
 void CreateSampleShape::exec()
 {  
   // Get the input workspace
-  const MatrixWorkspace_sptr workspace = getProperty("InputWorkspace");
+  MatrixWorkspace_sptr workspace = getProperty("InputWorkspace");
   // Get the XML definition
   std::string shapeXML = getProperty("ShapeXML");
   Geometry::ShapeFactory sFactory;
+  // Create the object
   boost::shared_ptr<Geometry::Object> shape_sptr = sFactory.createShape(shapeXML);
-
-  workspace->mutableSample().setShapeObject(*shape_sptr);
-
+  // Check it's valid and attach it to the workspace sample
+  if( shape_sptr->hasValidShape() )
+  {
+    workspace->mutableSample().setShape(*shape_sptr);
+  }
+  else
+  {
+    g_log.warning() << "Object has invalid shape. TopRule = " << shape_sptr->topRule() 
+		    << ", number of surfaces = " << shape_sptr->getSurfacePtr().size() << "\n";
+    throw std::runtime_error("Shape object is invalid, cannot attach it to workspace."); 
+  }
+  // Done!
   progress(1);
 }
 
diff --git a/Code/Mantid/DataHandling/src/DefineGaugeVolume.cpp b/Code/Mantid/DataHandling/src/DefineGaugeVolume.cpp
index 077a8875dd7..d7e043bd9e6 100644
--- a/Code/Mantid/DataHandling/src/DefineGaugeVolume.cpp
+++ b/Code/Mantid/DataHandling/src/DefineGaugeVolume.cpp
@@ -35,8 +35,7 @@ void DefineGaugeVolume::exec()
   const std::string shapeXML = getProperty("ShapeXML");
   // Try creating the shape to make sure the input's valid
   boost::shared_ptr<Geometry::Object> shape_sptr = Geometry::ShapeFactory().createShape(shapeXML);
-  // Assume invalid shape if object has no 'TopRule' or surfaces
-  if ( !(shape_sptr->topRule()) && shape_sptr->getSurfacePtr().empty() )
+  if ( !shape_sptr->hasValidShape() )
   {
     g_log.error("Invalid shape definition provided. Gauge Volume NOT added to workspace.");
     throw std::invalid_argument("Invalid shape definition provided.");
diff --git a/Code/Mantid/DataHandling/src/LoadInstrument.cpp b/Code/Mantid/DataHandling/src/LoadInstrument.cpp
index 2f260d95f98..a971f179d2f 100644
--- a/Code/Mantid/DataHandling/src/LoadInstrument.cpp
+++ b/Code/Mantid/DataHandling/src/LoadInstrument.cpp
@@ -91,17 +91,17 @@ namespace Mantid
       m_filename = getPropertyValue("Filename");
 
       // Get the input workspace
-      const MatrixWorkspace_sptr localWorkspace = getProperty("Workspace");
+      m_workspace = getProperty("Workspace");
 
       // Clear off any existing instrument for this workspace
-      localWorkspace->setInstrument(boost::shared_ptr<Instrument>(new Instrument));
+      m_workspace->setInstrument(boost::shared_ptr<Instrument>(new Instrument));
 
       // Remove the path from the filename for use with the InstrumentDataService
       const int stripPath = m_filename.find_last_of("\\/");
       std::string instrumentFile = m_filename.substr(stripPath+1,m_filename.size());
 
       // Get reference to Instrument and set its name
-      m_instrument = localWorkspace->getBaseInstrument();
+      m_instrument = m_workspace->getBaseInstrument();
 
       // Set up the DOM parser and parse xml file
       DOMParser pParser;
@@ -164,9 +164,9 @@ namespace Mantid
       if ( InstrumentDataService::Instance().doesExist(instrumentFile) )
       {
         // If it does, just use the one from the one stored there
-        localWorkspace->setInstrument(InstrumentDataService::Instance().retrieve(instrumentFile));
+        m_workspace->setInstrument(InstrumentDataService::Instance().retrieve(instrumentFile));
         // Get reference to Instrument 
-        m_instrument = localWorkspace->getBaseInstrument();
+        m_instrument = m_workspace->getBaseInstrument();
         //get list of monitors and set the property
         std::vector<int>monitordetIdList=m_instrument->getMonitors();
         setProperty("MonitorList",monitordetIdList);
@@ -414,7 +414,7 @@ namespace Mantid
       }
 
       // populate parameter map of workspace 
-      localWorkspace->populateInstrumentParameters();
+      m_workspace->populateInstrumentParameters();
 
       // check if default parameter file is also present
       runLoadParameterFile();
@@ -823,6 +823,8 @@ namespace Mantid
         if ( category.compare("SamplePos") == 0 )
         {
           m_instrument->markAsSamplePos(comp);
+	  API::Sample & sample = m_workspace->mutableSample();
+	  sample.attachToPosition(comp);
         }
 
         // set location for this newly added comp and set facing if specified in instrument def. file. Also
@@ -1738,8 +1740,7 @@ namespace Mantid
       try
       {
         loadInstParam->setPropertyValue("Filename", fullPathIDF);
-        const MatrixWorkspace_sptr localWorkspace = getProperty("Workspace");
-        loadInstParam->setProperty<MatrixWorkspace_sptr> ("Workspace", localWorkspace);
+        loadInstParam->setProperty<MatrixWorkspace_sptr> ("Workspace", m_workspace);
         loadInstParam->execute();
       } catch (std::invalid_argument& e)
       {
diff --git a/Code/Mantid/DataHandling/src/LoadSPE.cpp b/Code/Mantid/DataHandling/src/LoadSPE.cpp
index 71ae430b089..35a30e4429c 100644
--- a/Code/Mantid/DataHandling/src/LoadSPE.cpp
+++ b/Code/Mantid/DataHandling/src/LoadSPE.cpp
@@ -19,10 +19,10 @@ namespace
     const std::string unitID() const { return ""; }
     const std::string caption() const { return "Phi"; }
     const std::string label() const { return "degrees"; }
-    void toTOF(std::vector<double>& xdata, std::vector<double>& ydata, const double& l1, const double& l2,
-      const double& twoTheta, const int& emode, const double& efixed, const double& delta) const {}
-    void fromTOF(std::vector<double>& xdata, std::vector<double>& ydata, const double& l1, const double& l2,
-      const double& twoTheta, const int& emode, const double& efixed, const double& delta) const {}
+    void toTOF(std::vector<double>&, std::vector<double>&, const double&, const double&,
+      const double&, const int&, const double&, const double&) const {}
+    void fromTOF(std::vector<double>&, std::vector<double>&, const double&, const double&,
+      const double&, const int&, const double&, const double&) const {}
   };
 } // end anonynmous namespace
 /// @endcond
diff --git a/Code/Mantid/Geometry/inc/MantidGeometry/Instrument/Detector.h b/Code/Mantid/Geometry/inc/MantidGeometry/Instrument/Detector.h
index 2f084803d02..8398fbefb0b 100644
--- a/Code/Mantid/Geometry/inc/MantidGeometry/Instrument/Detector.h
+++ b/Code/Mantid/Geometry/inc/MantidGeometry/Instrument/Detector.h
@@ -49,9 +49,9 @@ public:
 	virtual std::string type() const {return "DetectorComponent";}
 
 	/// Constructor for parametrized version
-  Detector(const IComponent* base, const ParameterMap * map);
+	Detector(const IComponent* base, const ParameterMap * map);
 	Detector(const std::string& name, IComponent* parent);
-  Detector(const std::string& name, boost::shared_ptr<Object> shape, IComponent* parent);
+	Detector(const std::string& name, boost::shared_ptr<Object> shape, IComponent* parent);
 	virtual ~Detector();
 	// functions inherited from IObjectComponent
 	virtual Component* clone() const {return new Detector(*this);}
@@ -60,10 +60,9 @@ public:
 
 	// IDetector methods
 	int getID() const;
-  double getDistance(const IComponent& comp) const;
+	double getDistance(const IComponent& comp) const;
 	double getTwoTheta(const V3D& observer, const V3D& axis) const;
 	double getPhi() const;
-	double solidAngle(const V3D& observer) const;
 	bool isMasked() const;
 	bool isMonitor() const;
 	/// Returns a reference to itself
diff --git a/Code/Mantid/Geometry/inc/MantidGeometry/Instrument/ObjComponent.h b/Code/Mantid/Geometry/inc/MantidGeometry/Instrument/ObjComponent.h
index fc9f79e4636..efdf457dd6c 100644
--- a/Code/Mantid/Geometry/inc/MantidGeometry/Instrument/ObjComponent.h
+++ b/Code/Mantid/Geometry/inc/MantidGeometry/Instrument/ObjComponent.h
@@ -8,6 +8,8 @@
 #include "MantidGeometry/Instrument/Component.h"
 #include "MantidGeometry/IObjComponent.h"
 #include "MantidGeometry/Objects/Track.h"
+#include "MantidGeometry/Objects/Material.h"
+#include "MantidGeometry/Objects/Object.h"
 #include "boost/shared_ptr.hpp"
 
 #ifdef _WIN32
@@ -60,7 +62,8 @@ public:
   ObjComponent(const IComponent* base, const ParameterMap * map);
   // Looking to get rid of the first of these constructors in due course (and probably add others)
   explicit ObjComponent(const std::string& name, IComponent* parent=0);
-  explicit ObjComponent(const std::string& name, boost::shared_ptr<Object> shape, IComponent* parent=0);
+  explicit ObjComponent(const std::string& name, Object_sptr shape, IComponent* parent=0,
+			Material_sptr material = Material_sptr());
   virtual ~ObjComponent();
 
   /** Virtual Copy Constructor
@@ -81,10 +84,10 @@ public:
   void initDraw() const;
   V3D getScaleFactorP() const;
 
-
   ///Return the shape of the component
   const boost::shared_ptr<const Object> shape()const;
-
+  /// Return the material this component is made from
+  const Material_const_sptr material() const;
 
 protected:
   ObjComponent(const ObjComponent&);
@@ -92,7 +95,9 @@ protected:
   /// The phyical geometry representation
   // Made a const pointer to a const object. Since this is a shared object we shouldn't be
   // exposing non-const methods of Object through this class.
-  /*const*/ boost::shared_ptr<const Object> m_shape;
+  Object_const_sptr m_shape;
+  /// The material this object is made of
+  Material_const_sptr m_material;
 
 private:
   /// Private, unimplemented copy assignment operator
diff --git a/Code/Mantid/Geometry/inc/MantidGeometry/Objects/Material.h b/Code/Mantid/Geometry/inc/MantidGeometry/Objects/Material.h
index 596a67667a9..27787fe176b 100644
--- a/Code/Mantid/Geometry/inc/MantidGeometry/Objects/Material.h
+++ b/Code/Mantid/Geometry/inc/MantidGeometry/Objects/Material.h
@@ -1,26 +1,30 @@
 #ifndef MANTID_GEOMETRY_MATERIAL_H_
 #define MANTID_GEOMETRY_MATERIAL_H_
 
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
 #include "MantidKernel/System.h"
-#include <string>
+#include "MantidKernel/NeutronAtom.h"
+#include "MantidKernel/PhysicalConstants.h"
+#include <boost/shared_ptr.hpp>
+
 
 namespace Mantid
 {
-
   namespace Geometry
   {
     /**
-    Simple class defining a material. It holds basic information:
-    <UL>
-    <LI>Temperature (Kelvin)</LI>
-    <LI>Pressure (KPa) </LI>
-    <LI>Density (kg/m^3)</LI>
-    <LI>Coherent scattering cross section</LI>
-    <LI>Incoherent scattering cross section</LI>
-    <LI>Absorption cross section</LI>
-    </UL>
-
-    Copyright &copy; 2007-2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
+      A material is defined as being composed of a given element, defined as a
+      PhysicalConstants::NeutronAtom, with the following properties:
+      
+      <UL>
+        <LI>temperature (Kelvin)</LI>
+        <LI>pressure (KPa) </LI>
+        <LI>number density (A^-3)</LI>
+      </UL>
+
+    Copyright &copy; 2007-2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
 
     This file is part of Mantid.
 
@@ -43,74 +47,58 @@ namespace Mantid
     class DLLExport Material
     {
     public:
-      /// Constructor
-      explicit Material(const std::string & name, const double density, 
-        const double temperature, const double pressure,
-        const double coherentXsec, const double incoherentXsec,
-        const double absorbXsec);
-
-      /** 
-      * Returns the name 
-      * @returns A string containing the name of the material
-      */
-      inline const std::string& name() const { return m_name; }
-      /** 
-      * Get the density
-      * @returns The density of the material
-      */
-      inline double density() const { return m_density; }
-      /** 
-      * Get the temperature
-      * @returns The temperature of the material
-      */
-      inline double temperature() const { return m_temperature; }
-      /** 
-      * Get the pressure
-      * @returns The pressure of the material
-      */
-      inline double pressure() const { return m_pressure; }
-      /**
-      * Get the total cross section
-      * @returns The sum of the coherent and incoherent scattering cross section
-      */
-      inline double totalCrossSection() const { return m_coherentXsec + m_incoherentXsec; }
-      /**
-      * Get the coherent cross section
-      * @returns The coherent scattering cross section
-      */
-      inline double coherentCrossSection() const { return m_coherentXsec; }
-      /**
-      * Get the incoherent cross section
-      * @returns The incoherent scattering cross section
-      */
-      inline double incoherentCrossSection() const { return m_incoherentXsec; }
-      /**
-      * Get the absorption cross section
-      * @returns The absorption scattering cross section
-      */
-      inline double absorptionCrossSection() const { return m_absorbXsec; }
-
-    private:
-      /// Default constructor
+      /// Default constructor. Required for other parts of the code to 
+      /// function correctly. The material is considered "empty"
       Material();
 
+      /// Construct a material from a known element, with optional 
+      /// temperature and pressure
+      explicit Material(
+	const std::string & name, 
+	const PhysicalConstants::NeutronAtom & element,
+	const double numberDensity, 
+	const double temperature = 300, 
+	const double pressure = PhysicalConstants::StandardAtmosphere
+	);
+      /// Virtual destructor.
+      virtual ~Material() {};
+
+      /// Returns the name of the material 
+      const std::string& name() const;
+      
+      /** @name Material properties */
+      //@{
+      /// Get the number density
+      double numberDensity() const;
+      /// Get the temperature
+      double temperature() const;
+      /// Get the pressure
+      double pressure() const;
+      /// Get the coherent cross section for a given wavelength
+      double coherentCrossSection(const double lambda) const;
+      /// Get the incoherent cross section for a given wavelength
+      double incoherentCrossSection(const double lambda) const;
+      /// Get the absorption cross section at a given wavelength
+      double absorptionCrossSection(const double lambda) const;
+      //@}
+
     private:
       /// Material name
       std::string m_name;
-      /// Density in kg/m^3
-      double m_density;
+      /// Reference to an element
+      const PhysicalConstants::NeutronAtom * m_element;
+      /// Number density in A^-3
+      double m_numberDensity;
       /// Temperature
       double m_temperature;
       /// Pressure
       double m_pressure;
-      /// Coherent scattering cross section
-      double m_coherentXsec;
-      /// Incoherent scattering cross section
-      double m_incoherentXsec;
-      /// Absorption cross section
-      double m_absorbXsec;     
     };
 
+    /// Typedef for a shared pointer
+    typedef boost::shared_ptr<Material> Material_sptr;
+    /// Typedef for a shared pointer to a const object
+    typedef boost::shared_ptr<const Material> Material_const_sptr;
 
   }
 }
diff --git a/Code/Mantid/Geometry/inc/MantidGeometry/Objects/Object.h b/Code/Mantid/Geometry/inc/MantidGeometry/Objects/Object.h
index dc219b2556b..b9d02faf73b 100644
--- a/Code/Mantid/Geometry/inc/MantidGeometry/Objects/Object.h
+++ b/Code/Mantid/Geometry/inc/MantidGeometry/Objects/Object.h
@@ -81,6 +81,8 @@ namespace Mantid
       void setName(const int nx) { ObjName=nx; }           ///< Set Name
       int getName() const  { return ObjName; }             ///< Get Name
 
+      /// Return whether this object has a valid shape
+      bool hasValidShape() const;
       int setObject(const int ON,const std::string& Ln);
       int procString(const std::string& Line);
       int complementaryObject(const int Cnum,std::string& Ln); ///< Process a complementary object
@@ -156,9 +158,7 @@ namespace Mantid
       void GetObjectGeom(int& type, std::vector<Geometry::V3D>& vectors, double& myradius, double & myheight) const;
     private:
       static Kernel::Logger& PLog;           ///< The official logger
-
       int ObjName;       ///< Creation number
-
       Rule* TopRule;     ///< Top rule [ Geometric scope of object]
 
       int procPair(std::string& Ln,std::map<int,Rule*>& Rlist,int& compUnit) const;
@@ -207,6 +207,11 @@ namespace Mantid
       std::vector<const Surface*> SurList;  ///< Full surfaces (make a map including complementary object ?)
     };
 
+    /// Typdef for a shared pointer
+    typedef boost::shared_ptr<Object> Object_sptr;
+    /// Typdef for a shared pointer to a const object
+    typedef boost::shared_ptr<const Object> Object_const_sptr;
+
   }  // NAMESPACE Geometry
 }  // NAMESPACE Mantid
 
diff --git a/Code/Mantid/Geometry/src/IObjComponent.cpp b/Code/Mantid/Geometry/src/IObjComponent.cpp
index 55108cb7c7a..52613db2d5e 100644
--- a/Code/Mantid/Geometry/src/IObjComponent.cpp
+++ b/Code/Mantid/Geometry/src/IObjComponent.cpp
@@ -61,8 +61,11 @@ namespace Mantid
      * @param origin The object to initialize this with
      */
     IObjComponent::IObjComponent(const IObjComponent& origin) : 
-      m_ScaleFactor(origin.m_ScaleFactor), handle(origin.handle)
+      m_ScaleFactor(origin.m_ScaleFactor)
     {
+      // Handler contains a pointer to 'this' therefore needs regenerating
+      // with new object
+      handle = origin.handle->createInstance(this);
     }
 
     
diff --git a/Code/Mantid/Geometry/src/Instrument/Detector.cpp b/Code/Mantid/Geometry/src/Instrument/Detector.cpp
index 61490172c3a..a202ec90d8b 100644
--- a/Code/Mantid/Geometry/src/Instrument/Detector.cpp
+++ b/Code/Mantid/Geometry/src/Instrument/Detector.cpp
@@ -40,7 +40,8 @@ Detector::Detector(const std::string& name, boost::shared_ptr<Object> shape, ICo
 
 /// Copy constructor
 Detector::Detector(const Detector& rhs) :
-  ObjComponent(rhs), m_id(rhs.m_id), m_isMonitor(rhs.m_isMonitor)
+  IObjComponent(rhs), IDetector(rhs), ObjComponent(rhs), m_id(rhs.m_id), 
+  m_isMonitor(rhs.m_isMonitor)
 {
 }
 
@@ -102,14 +103,6 @@ double Detector::getPhi() const
   return phi*M_PI/180.0;
 }
 
-///Get the solid angle between the detector and an observer
-///@param observer The observer position
-///@return The solid angle
-double Detector::solidAngle(const V3D& observer) const
-{
-	return ObjComponent::solidAngle(observer);
-}
-
 /** Returns true if the detector is masked. Only Parametrized instruments
  * can have masked detectors.
  *  @return false
diff --git a/Code/Mantid/Geometry/src/Instrument/Instrument.cpp b/Code/Mantid/Geometry/src/Instrument/Instrument.cpp
index 014742993b4..8e84d60db8b 100644
--- a/Code/Mantid/Geometry/src/Instrument/Instrument.cpp
+++ b/Code/Mantid/Geometry/src/Instrument/Instrument.cpp
@@ -1,7 +1,6 @@
 #include "MantidGeometry/Instrument/Instrument.h"
 #include "MantidGeometry/V3D.h"
 #include "MantidKernel/Exception.h"
-#include "MantidGeometry/Instrument/DetectorGroup.h"
 #include "MantidGeometry/Instrument/ParComponentFactory.h"
 #include "MantidGeometry/Objects/BoundingBox.h"
 #include "MantidGeometry/Instrument/CompAssembly.h"
diff --git a/Code/Mantid/Geometry/src/Instrument/ObjCompAssembly.cpp b/Code/Mantid/Geometry/src/Instrument/ObjCompAssembly.cpp
index 413bb60ff20..5915712de90 100644
--- a/Code/Mantid/Geometry/src/Instrument/ObjCompAssembly.cpp
+++ b/Code/Mantid/Geometry/src/Instrument/ObjCompAssembly.cpp
@@ -60,7 +60,7 @@ ObjCompAssembly::ObjCompAssembly(const std::string& n, Component* reference) :
  *  @param ass :: assembly to copy
  */
 ObjCompAssembly::ObjCompAssembly(const ObjCompAssembly& ass) :
-  ICompAssembly(ass), ObjComponent(ass)
+  ICompAssembly(ass), IObjComponent(ass), ObjComponent(ass)
 {
   group=ass.group;
   // Need to do a deep copy
diff --git a/Code/Mantid/Geometry/src/Instrument/ObjComponent.cpp b/Code/Mantid/Geometry/src/Instrument/ObjComponent.cpp
index 8d94d37e96e..ebe1332b90a 100644
--- a/Code/Mantid/Geometry/src/Instrument/ObjComponent.cpp
+++ b/Code/Mantid/Geometry/src/Instrument/ObjComponent.cpp
@@ -18,7 +18,7 @@ namespace Mantid
      * @param map: pointer to the ParameterMap
      * */
     ObjComponent::ObjComponent(const IComponent* base, const ParameterMap * map)
-    : Component(base,map), m_shape()
+      : Component(base,map), m_shape(), m_material()
     {
 
     }
@@ -29,7 +29,7 @@ namespace Mantid
     *  @param parent The Parent geometry object of this component
     */
     ObjComponent::ObjComponent(const std::string& name, IComponent* parent)
-    : IObjComponent(), Component(name,parent), m_shape()
+      : IObjComponent(), Component(name,parent), m_shape(), m_material()
     {
     }
 
@@ -37,15 +37,17 @@ namespace Mantid
     *  @param name   The name of the component
     *  @param shape  A pointer to the object describing the shape of this component
     *  @param parent The Parent geometry object of this component
+    *  @param material An optional pointer to the material object of this component
     */
-    ObjComponent::ObjComponent(const std::string& name, boost::shared_ptr<Object> shape, IComponent* parent)
-    : IObjComponent(), Component(name,parent), m_shape(shape)
+    ObjComponent::ObjComponent(const std::string& name, Object_sptr shape, 
+			       IComponent* parent, Material_sptr material)
+      : IObjComponent(), Component(name,parent), m_shape(shape), m_material(material)
     {
     }
 
     /// Copy constructor
     ObjComponent::ObjComponent(const ObjComponent& rhs) :
-    IObjComponent(),Component(rhs), m_shape(rhs.m_shape)
+      IObjComponent(rhs),Component(rhs), m_shape(rhs.m_shape), m_material(rhs.m_material)
     {
     }
 
@@ -57,7 +59,7 @@ namespace Mantid
 
     /** Return the shape of the component
      */
-    const boost::shared_ptr<const Object> ObjComponent::shape()const
+    const Object_const_sptr ObjComponent::shape()const
     {
       if (m_isParametrized)
         return dynamic_cast<const ObjComponent*>(m_base)->m_shape;
@@ -65,6 +67,14 @@ namespace Mantid
         return m_shape;
     }
 
+    /** 
+     * Return the material of the component. Currently 
+     * unaffacted by parametrization
+     */
+    const Material_const_sptr ObjComponent::material() const
+    {
+      return m_material;
+    }
 
     /// Does the point given lie within this object component?
     bool ObjComponent::isValid(const V3D& point) const
diff --git a/Code/Mantid/Geometry/src/Objects/Material.cpp b/Code/Mantid/Geometry/src/Objects/Material.cpp
index d8122b0bc0a..e785d9dd902 100644
--- a/Code/Mantid/Geometry/src/Objects/Material.cpp
+++ b/Code/Mantid/Geometry/src/Objects/Material.cpp
@@ -1,5 +1,7 @@
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
 #include "MantidGeometry/Objects/Material.h"
-#include <cmath>
 
 namespace Mantid
 {
@@ -7,25 +9,110 @@ namespace Mantid
   namespace Geometry
   {
 
+    using PhysicalConstants::NeutronAtom;
+
+    /**
+     * Construct an "empty" material. Everything returns zero
+     */
+    Material::Material() : 
+      m_name(), m_element(NULL), m_numberDensity(0.0), m_temperature(0.0), 
+      m_pressure(0.0)
+    {
+    }
+
     /**
     * Construct a material object
     * @param name The name of the material
-    * @param density Density in kg/m^3
-    * @param temperature The temperature in Kelvin
-    * @param pressure Pressure in kPa
-    * @param coherentXsec The coherent scattering cross section 
-    * @param incoherentXsec The incoherent scattering cross section 
-    * @param absorbXsec The absorption scattering cross section 
+    * @param element The element it is composed from
+    * @param numberDensity Density in A^-3
+    * @param temperature The temperature in Kelvin (Default = 300K)
+    * @param pressure Pressure in kPa (Default: 101.325 kPa)
     */
-    Material::Material(const std::string & name, const double density, 
-      const double temperature, const double pressure,
-      const double coherentXsec, const double incoherentXsec,
-      const double absorbXsec) :
-    m_name(name), m_density(density), m_temperature(temperature), m_pressure(pressure),
-      m_coherentXsec(coherentXsec), m_incoherentXsec(incoherentXsec), m_absorbXsec(absorbXsec)
+    Material::Material(const std::string & name, const NeutronAtom & element, 
+		       const double numberDensity, const double temperature, 
+		       const double pressure) :
+      m_name(name), m_element(&element), m_numberDensity(numberDensity), 
+      m_temperature(temperature), m_pressure(pressure)
     {
     }   
+    
+    /** 
+     * Returns the name 
+     * @returns A string containing the name of the material
+     */
+    const std::string & Material::name() const 
+    { 
+      return m_name; 
+    }
+
+    /** 
+     * Get the number density
+     * @returns The number density of the material in A^-3
+     */
+    double Material::numberDensity() const
+    { 
+      return m_numberDensity; 
+    }
+    
+    /** 
+     * Get the temperature
+     * @returns The temperature of the material in Kelvin
+     */
+    double Material::temperature() const 
+    { 
+      return m_temperature; 
+    }
+    
+    /** 
+     * Get the pressure
+     * @returns The pressure of the material
+     */
+    double Material::pressure() const
+    { 
+      return m_pressure; 
+    }
+
+    /**
+     * Get the coherent cross section for a given wavelength.
+     * CURRENTLY this simply returns the value for the underlying element
+     * @param lambda The wavelength to evaluate the cross section
+     * @returns The value of the coherent scattering cross section at 
+     * the given wavelength
+     */ 
+    double Material::coherentCrossSection(const double lambda) const
+    {
+      (void)lambda;
+      return m_element ? m_element->coh_scatt_xs : 0.0;
+      
+    }
+    
+    /**
+     * Get the incoherent cross section for a given wavelength
+     * CURRENTLY this simply returns the value for the underlying element
+     * @param lambda The wavelength to evaluate the cross section
+     * @returns The value of the coherent scattering cross section at 
+     * the given wavelength
+     */
+    double Material::incoherentCrossSection(const double lambda) const
+    {
+      (void)lambda;
+      return m_element ? m_element->inc_scatt_xs : 0.0;
+    }
+
+    /**
+     * Get the absorption cross section for a given wavelength.
+     * CURRENTLY This assumes a linear dependence on the wavelength with the reference
+     * wavelegnth = 1.7982 angstroms.
+     * @param lambda The wavelength to evaluate the cross section
+     * @returns The value of the absoprtioncross section at 
+     * the given wavelength
+     */
+    double Material::absorptionCrossSection(const double lambda) const
+    {
+      return m_element ?
+	m_element->abs_scatt_xs * (lambda / NeutronAtom::ReferenceLambda) : 0.0;
+    }
 
   } 
 
-}  
\ No newline at end of file
+}  
diff --git a/Code/Mantid/Geometry/src/Objects/Object.cpp b/Code/Mantid/Geometry/src/Objects/Object.cpp
index 56463e4a800..ecdc13ed82c 100644
--- a/Code/Mantid/Geometry/src/Objects/Object.cpp
+++ b/Code/Mantid/Geometry/src/Objects/Object.cpp
@@ -31,7 +31,7 @@ namespace Mantid
     *  Default constuctor
     */
     Object::Object() :
-    ObjName(0), TopRule(0), m_boundingBox(), AABBxMax(0), AABByMax(0), AABBzMax(0),
+      ObjName(0), TopRule(0), m_boundingBox(), AABBxMax(0), AABByMax(0), AABBzMax(0),
       AABBxMin(0), AABByMin(0), AABBzMin(0), boolBounded(false), bGeometryCaching(false),
       vtkCacheReader(boost::shared_ptr<vtkGeometryCacheReader>()), vtkCacheWriter(boost::shared_ptr<
       vtkGeometryCacheWriter>())
@@ -104,6 +104,17 @@ namespace Mantid
       delete TopRule;
     }
 
+    /**
+     * Returns whether this object has a valid shape
+     * @returns True if the surface list is populated and there is a 
+     * defined TopRule, false otherwise.
+     */
+    bool Object::hasValidShape() const
+    {
+      // Assume invalid shape if object has no 'TopRule' or surfaces
+      return (TopRule != NULL && !SurList.empty());
+    }
+
      /**
      * Object line ==  cell
      * @param ON :: Object name
diff --git a/Code/Mantid/Geometry/src/Rendering/BitmapGeometryHandler.cpp b/Code/Mantid/Geometry/src/Rendering/BitmapGeometryHandler.cpp
index 096361fdc9f..ff8a27e625f 100644
--- a/Code/Mantid/Geometry/src/Rendering/BitmapGeometryHandler.cpp
+++ b/Code/Mantid/Geometry/src/Rendering/BitmapGeometryHandler.cpp
@@ -37,13 +37,15 @@ namespace Geometry
   ///< Create an instance of concrete geometry handler for ObjComponent
   BitmapGeometryHandler* BitmapGeometryHandler::createInstance(IObjComponent *comp)
   {
-    return new BitmapGeometryHandler(); //comp);
+    (void)comp;
+    return new BitmapGeometryHandler();
   }
 
   ///< Create an instance of concrete geometry handler for Object
   BitmapGeometryHandler* BitmapGeometryHandler::createInstance(boost::shared_ptr<Object> obj )
   {
-    return new BitmapGeometryHandler(); //obj);
+    (void)obj;
+    return new BitmapGeometryHandler();
   }
 
   //----------------------------------------------------------------------------------------------
diff --git a/Code/Mantid/Geometry/src/Surfaces/Surface.cpp b/Code/Mantid/Geometry/src/Surfaces/Surface.cpp
index 2788990bd73..f0ebc6c9c97 100644
--- a/Code/Mantid/Geometry/src/Surfaces/Surface.cpp
+++ b/Code/Mantid/Geometry/src/Surfaces/Surface.cpp
@@ -30,9 +30,6 @@ namespace Geometry
 
 Kernel::Logger& Surface::PLog = Kernel::Logger::get("Surface"); 
 
-/// Tolerance for floating point, now set by getSurfaceTolerance()
-//const double STolerance(1e-6);
-
 Surface::Surface() : 
   Name(-1)
   /*!
diff --git a/Code/Mantid/Geometry/test/ComponentCreationHelpers.hh b/Code/Mantid/Geometry/test/ComponentCreationHelpers.hh
index ee776e07db2..8c8d80bf2e1 100644
--- a/Code/Mantid/Geometry/test/ComponentCreationHelpers.hh
+++ b/Code/Mantid/Geometry/test/ComponentCreationHelpers.hh
@@ -13,7 +13,6 @@ namespace ComponentCreationHelper
 {
 
   using namespace Mantid::Geometry;
-  typedef boost::shared_ptr<Object> Object_sptr;
 
   /** 
   A set of helper functions for creating various component structures for the unit tests.
@@ -119,6 +118,15 @@ namespace ComponentCreationHelper
     return bank;
   }
 
+  /**
+   * Create an object component that has a defined shape
+   */
+  static ObjComponent * createSingleObjectComponent()
+  {
+    Object_sptr pixelShape = ComponentCreationHelper::createCappedCylinder(0.5, 1.5, V3D(0.0,0.0,0.0), V3D(0.,1.0,0.), "tube");
+    return new ObjComponent("pixel", pixelShape);
+  }
+
   //----------------------------------------------------------------------------------------------
   /**
    * Create a detector group containing 5 detectors
diff --git a/Code/Mantid/Geometry/test/MaterialTest.h b/Code/Mantid/Geometry/test/MaterialTest.h
index 05f2f92c4ea..899139e977a 100644
--- a/Code/Mantid/Geometry/test/MaterialTest.h
+++ b/Code/Mantid/Geometry/test/MaterialTest.h
@@ -5,28 +5,43 @@
 #include <cmath>
 
 #include "MantidGeometry/Objects/Material.h"
+#include "MantidKernel/NeutronAtom.h"
 
-
-using namespace Mantid;
-using namespace Geometry;
+using Mantid::Geometry::Material;
 
 class testMaterial: public CxxTest::TestSuite
 {
 public:
-	void testConstructor()
+
+  void test_Empty_Constructor()
   {
-    const double testDensity(1e-03), testTemp(300.), testPressure(1e+5), 
-      testCohXsec(20.), testIncohXsec(2.0), testAbsXsec(1.5); 
-		Material fake("fake", testDensity, testTemp, testPressure, testCohXsec, testIncohXsec, testAbsXsec); 
-		TS_ASSERT_EQUALS(fake.name(), "fake");
-    TS_ASSERT_EQUALS(fake.density(), testDensity);
-    TS_ASSERT_EQUALS(fake.temperature(), testTemp);
-    TS_ASSERT_EQUALS(fake.pressure(), testPressure);
-    TS_ASSERT_EQUALS(fake.coherentCrossSection(), testCohXsec);
-    TS_ASSERT_EQUALS(fake.incoherentCrossSection(), testIncohXsec);
-    TS_ASSERT_EQUALS(fake.absorptionCrossSection(), testAbsXsec);
-    TS_ASSERT_DELTA(fake.totalCrossSection(), testCohXsec + testIncohXsec, 1e-08);
-	}
+    Material empty;
+    TS_ASSERT_EQUALS(empty.name(), "");
+    TS_ASSERT_EQUALS(empty.numberDensity(), 0.0);
+    TS_ASSERT_EQUALS(empty.temperature(), 0.0);
+    TS_ASSERT_EQUALS(empty.pressure(), 0.0);
+
+    const double lambda(2.1);
+    TS_ASSERT_EQUALS(empty.coherentCrossSection(lambda), 0.0);
+    TS_ASSERT_EQUALS(empty.incoherentCrossSection(lambda), 0.0);
+    TS_ASSERT_EQUALS(empty.absorptionCrossSection(lambda), 0.0);
+    
+  }
+
+  void test_That_Construction_By_Known_Element_Gives_Expected_Values()
+  {
+    Material vanBlock("vanBlock", Mantid::PhysicalConstants::getNeutronAtom(23, 0), 0.072);
+
+    TS_ASSERT_EQUALS(vanBlock.name(), "vanBlock");
+    TS_ASSERT_EQUALS(vanBlock.numberDensity(), 0.072);
+    TS_ASSERT_EQUALS(vanBlock.temperature(), 300);
+    TS_ASSERT_EQUALS(vanBlock.pressure(), Mantid::PhysicalConstants::StandardAtmosphere);
+
+    const double lambda(2.1);
+    TS_ASSERT_DELTA(vanBlock.coherentCrossSection(lambda), 0.0184,  1e-02);
+    TS_ASSERT_DELTA(vanBlock.incoherentCrossSection(lambda), 5.08,  1e-02);
+    TS_ASSERT_DELTA(vanBlock.absorptionCrossSection(lambda), 5.93, 1e-02);
+  }
 
 };
 #endif
diff --git a/Code/Mantid/Geometry/test/ObjectTest.h b/Code/Mantid/Geometry/test/ObjectTest.h
index bc945092329..fe6c117b8c0 100644
--- a/Code/Mantid/Geometry/test/ObjectTest.h
+++ b/Code/Mantid/Geometry/test/ObjectTest.h
@@ -24,12 +24,8 @@
 using namespace Mantid;
 using namespace Geometry;
 
-typedef boost::shared_ptr<Object> Object_sptr;
-
-class testObject: public CxxTest::TestSuite
+class TestObject: public CxxTest::TestSuite
 {
-private:
-
 
 public:
 
diff --git a/Code/Mantid/Kernel/inc/MantidKernel/MersenneTwister.h b/Code/Mantid/Kernel/inc/MantidKernel/MersenneTwister.h
index b72f68cbb9d..36e2b597350 100644
--- a/Code/Mantid/Kernel/inc/MantidKernel/MersenneTwister.h
+++ b/Code/Mantid/Kernel/inc/MantidKernel/MersenneTwister.h
@@ -58,7 +58,7 @@ namespace Mantid
       /// Default constructor
       MersenneTwister();
       /// Set the random number seed
-      virtual void setSeed(long seed);
+      virtual void setSeed(unsigned int seed);
       /// Sets the range of the subsequent calls to next 
       virtual void setRange(double start, double end);
       /// Generate the next random number in the sequence within the given range, (default=[0.0,1.0]).
diff --git a/Code/Mantid/Kernel/inc/MantidKernel/NeutronAtom.h b/Code/Mantid/Kernel/inc/MantidKernel/NeutronAtom.h
index 326536b9ea7..160286eb147 100644
--- a/Code/Mantid/Kernel/inc/MantidKernel/NeutronAtom.h
+++ b/Code/Mantid/Kernel/inc/MantidKernel/NeutronAtom.h
@@ -1,80 +1,97 @@
-/*
- * NeutronAtom.h
- *
- *  Created on: Oct 21, 2010
- *      Author: pf9
- */
-
-#ifndef NEUTRONATOM_H_
-#define NEUTRONATOM_H_
+#ifndef MANTID_KERNEL_NEUTRONATOM_H_
+#define MANTID_KERNEL_NEUTRONATOM_H_
 
+//------------------------------------------------------------------------------
+// Include
+//------------------------------------------------------------------------------
 #include <string>
 #include "MantidKernel/System.h"
 
-
 namespace Mantid
 {
-namespace Kernel
-{
-namespace PhysicalConstants
-{
-
-/**
- * Structure to store neutronic scattering information for the various elements.
- * This is taken from http://www.ncnr.nist.gov/resources/n-lengths/list.html.
- */
-struct NeutronAtom {
-  NeutronAtom(const uint8_t z,
-              const double coh_b_real, const double inc_b_real,
-              const double coh_xs, const double inc_xs,
-              const double tot_xs, const double abs_xs);
-
-  NeutronAtom(const uint8_t z, const uint8_t a,
-              const double coh_b_real, const double inc_b_real,
-              const double coh_xs, const double inc_xs,
-              const double tot_xs, const double abs_xs);
-
-  NeutronAtom(const uint8_t z, const uint8_t a,
-              const double coh_b_real, const double coh_b_img,
-              const double inc_b_real, const double inc_b_img,
-              const double coh_xs, const double inc_xs,
-              const double tot_xs, const double abs_xs);
-
-  /// The atomic number, or number of protons, for the atom.
-  uint8_t z_number;
-
-  /// The total number of protons and neutrons, or mass number, for the atom for isotopic averages this is set to zero.
-  uint8_t a_number;
-
-  /// The real part of the coherent scattering length in fm.
-  double coh_scatt_length_real;
-
-  /// The imaginary part of the coherent scattering length in fm.
-  double coh_scatt_length_img;
-
-  /// The real part of the incoherent scattering length in fm.
-  double inc_scatt_length_real;
-
-  /// The imaginary part of the incoherent scattering length in fm.
-  double inc_scatt_length_img;
-
-  /// The coherent scattering cross section in barns.
-  double coh_scatt_xs;
-
-  /// The incoherent scattering cross section in barns.
-  double inc_scatt_xs;
-
-  /// The total scattering cross section in barns.
-  double tot_scatt_xs;
-
-  /// The absorption cross section for 2200m/s neutrons in barns.
-  double abs_scatt_xs;
-};
-
-DLLExport NeutronAtom getNeutronAtom(const int z_number, const int a_number = 0);
-
-} //Namespace PhysicalConstants
-} //Namespace Kernel
+  namespace PhysicalConstants
+  {
+
+    /** 
+      Structure to store neutronic scattering information for the various elements.
+      This is taken from http://www.ncnr.nist.gov/resources/n-lengths/list.html.
+     
+      Copyright &copy; 2007-2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National 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>
+    */
+    struct NeutronAtom {
+
+      /// The reference wavelength value for absorption cross sections
+      static const double ReferenceLambda;
+
+      NeutronAtom(const uint8_t z,
+		  const double coh_b_real, const double inc_b_real,
+		  const double coh_xs, const double inc_xs,
+		  const double tot_xs, const double abs_xs);
+
+      NeutronAtom(const uint8_t z, const uint8_t a,
+		  const double coh_b_real, const double inc_b_real,
+		  const double coh_xs, const double inc_xs,
+		  const double tot_xs, const double abs_xs);
+
+      NeutronAtom(const uint8_t z, const uint8_t a,
+		  const double coh_b_real, const double coh_b_img,
+		  const double inc_b_real, const double inc_b_img,
+		  const double coh_xs, const double inc_xs,
+		  const double tot_xs, const double abs_xs);
+
+      /// The atomic number, or number of protons, for the atom.
+      uint8_t z_number;
+
+      /// The total number of protons and neutrons, or mass number, 
+      /// for the atom for isotopic averages this is set to zero.
+      uint8_t a_number;
+
+      /// The real part of the coherent scattering length in fm.
+      double coh_scatt_length_real;
+
+      /// The imaginary part of the coherent scattering length in fm.
+      double coh_scatt_length_img;
+
+      /// The real part of the incoherent scattering length in fm.
+      double inc_scatt_length_real;
+
+      /// The imaginary part of the incoherent scattering length in fm.
+      double inc_scatt_length_img;
+
+      /// The coherent scattering cross section in barns.
+      double coh_scatt_xs;
+
+      /// The incoherent scattering cross section in barns.
+      double inc_scatt_xs;
+
+      /// The total scattering cross section in barns.
+      double tot_scatt_xs;
+
+      /// The absorption cross section for 2200m/s neutrons in barns.
+      double abs_scatt_xs;
+    };
+
+    DLLExport NeutronAtom getNeutronAtom(const int z_number, const int a_number = 0);
+
+  } //Namespace PhysicalConstants
 } //Namespace Mantid
 
 #endif /* NEUTRONATOM_H_ */
diff --git a/Code/Mantid/Kernel/inc/MantidKernel/PhysicalConstants.h b/Code/Mantid/Kernel/inc/MantidKernel/PhysicalConstants.h
index 379acf444ab..203235ff37a 100644
--- a/Code/Mantid/Kernel/inc/MantidKernel/PhysicalConstants.h
+++ b/Code/Mantid/Kernel/inc/MantidKernel/PhysicalConstants.h
@@ -52,6 +52,10 @@ namespace PhysicalConstants
 	
   /**  Muon lifetime. Taken from MuLan experiment on 08/12/2008. */
   static const double MuonLifetime = 2.197019e-6;
+
+  /** Standard atmospheric pressure in kPa. 
+   * Taken from <http://physics.nist.gov/cgi-bin/cuu/Value?stdatm|search_for=adopted_in!> on 01/12/2010 **/
+  static const double StandardAtmosphere = 101.325;
   
 } // namespace PhysicalConstants
 } // namespace Mantid
diff --git a/Code/Mantid/Kernel/inc/MantidKernel/RandomNumberGenerator.h b/Code/Mantid/Kernel/inc/MantidKernel/RandomNumberGenerator.h
index d76519bbdbd..697db703330 100644
--- a/Code/Mantid/Kernel/inc/MantidKernel/RandomNumberGenerator.h
+++ b/Code/Mantid/Kernel/inc/MantidKernel/RandomNumberGenerator.h
@@ -43,7 +43,7 @@ namespace Mantid
       /// Virtual destructor to ensure that all inheriting classes have one
       virtual ~RandomNumberGenerator() {};
       /// Set the random number seed
-      virtual void setSeed(long seedValue) = 0;
+      virtual void setSeed(unsigned int seedValue) = 0;
       /// Sets the range of the subsequent calls to next;
       virtual void setRange(double start, double end) = 0;
       /// Generate the next random number in the sequence within the given range.
diff --git a/Code/Mantid/Kernel/inc/MantidKernel/VectorHelper.h b/Code/Mantid/Kernel/inc/MantidKernel/VectorHelper.h
index 77284842f45..813a00a9397 100644
--- a/Code/Mantid/Kernel/inc/MantidKernel/VectorHelper.h
+++ b/Code/Mantid/Kernel/inc/MantidKernel/VectorHelper.h
@@ -49,7 +49,7 @@ namespace VectorHelper
 
   // New method to rebin Histogram data, should be faster than previous one
   void DLLExport rebinHistogram(const std::vector<double>& xold, const std::vector<double>& yold, const std::vector<double>& eold,
-          const std::vector<double>& xnew, std::vector<double>& ynew, std::vector<double>& enew,bool addition);
+				const std::vector<double>& xnew, std::vector<double>& ynew, std::vector<double>& enew,bool addition);
 
   /// Convert an array of bin boundaries to bin centre values.
   void DLLExport convertToBinCentre(const std::vector<double> & bin_edges, std::vector<double> & bin_centres);
@@ -59,7 +59,8 @@ namespace VectorHelper
   DLLExport std::vector<double> splitStringIntoVector(std::string listString);
 
   DLLExport int getBinIndex(std::vector<double>& bins, const double X );
-
+  // Linearly interpolate between a set of Y values. Assumes the values are set for the calculated nodes
+  DLLExport void linearlyInterpolateY(const std::vector<double> & x, std::vector<double> & y, const double stepSize);
 
   //! Functor used for computing the sum of the square values of a vector, using the accumulate algorithm
   template <class T> struct SumGaussError: public std::binary_function<T,T,T>
diff --git a/Code/Mantid/Kernel/src/MersenneTwister.cpp b/Code/Mantid/Kernel/src/MersenneTwister.cpp
index 4b6a7611c3f..955f7a7a047 100644
--- a/Code/Mantid/Kernel/src/MersenneTwister.cpp
+++ b/Code/Mantid/Kernel/src/MersenneTwister.cpp
@@ -24,10 +24,10 @@ namespace Mantid
      * (Re-)seed the generator
      * @param seedValue A seed for the generator
      */
-    void MersenneTwister::setSeed(long seedValue)
+    void MersenneTwister::setSeed(unsigned int seedValue)
     {
       // Bug in earlier versions of this implementation meant
-      // that a long could not be past to the seed function
+      // that a unsigned int could not be past to the seed function
       m_generator.seed((boost::mt19937::result_type)seedValue);
     }
 
diff --git a/Code/Mantid/Kernel/src/NeutronAtom.cpp b/Code/Mantid/Kernel/src/NeutronAtom.cpp
index 2c154a99ccb..f652823bd49 100644
--- a/Code/Mantid/Kernel/src/NeutronAtom.cpp
+++ b/Code/Mantid/Kernel/src/NeutronAtom.cpp
@@ -1,9 +1,6 @@
-/*
- * NeutronAtom.cpp
- *
- *, Created on: Oct 21, 2010
- *, , Author: pf9
- */
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
 #include "MantidKernel/NeutronAtom.h"
 #include <algorithm>
 #include <limits>
@@ -12,11 +9,13 @@
 
 namespace Mantid
 {
-namespace Kernel
-{
+
 namespace PhysicalConstants
 {
 
+/// Reference wavelength for absorption cross section values.
+const double NeutronAtom::ReferenceLambda = 1.7982;
+
 /**
  * Atom constructor
  * @param z The atomic number of the atom
@@ -527,5 +526,4 @@ NeutronAtom getNeutronAtom(const int z_number, const int a_number)
 }
 
 } // namespace PhysicalConstants
-} // namespace Kernel
 } // namespace Mantid
diff --git a/Code/Mantid/Kernel/src/VectorHelper.cpp b/Code/Mantid/Kernel/src/VectorHelper.cpp
index 8788fcc83d6..64cb115b68b 100644
--- a/Code/Mantid/Kernel/src/VectorHelper.cpp
+++ b/Code/Mantid/Kernel/src/VectorHelper.cpp
@@ -409,6 +409,43 @@ int getBinIndex(std::vector<double>& bins, const double X )
   return index;
 }
 
+//-------------------------------------------------------------------------------------------------
+/**
+ * Linearly interpolates between Y points separated by the given step size.
+ * @param x The X array
+ * @param y The Y array with end points and values at stepSize intervals calculated
+ * @param stepSize The distance between each pre-calculated point
+ */
+void linearlyInterpolateY(const std::vector<double> & x, std::vector<double> & y, const double stepSize)
+{
+  int specSize = static_cast<int>(y.size());
+  int xSize = static_cast<int>(x.size());
+  bool isHistogram(xSize == specSize + 1);
+  int step(stepSize), index2(0);
+  double x1 = 0, x2 = 0, y1 = 0, y2 = 0, xp = 0, overgap = 0;
+
+  for (int i = 0; i < specSize - 1; ++i) // Last point has been calculated
+  {
+    if(step == stepSize) //Point numerically integrated, does not need interpolation
+    {
+      x1 = (isHistogram ? (0.5 * (x[i] + x[i + 1])) : x[i]);
+      index2 = ((i + stepSize) >= specSize ? specSize - 1 : (i + stepSize));
+      x2 = (isHistogram ? (0.5 * (x[index2] + x[index2 + 1])) : x[index2]);
+      overgap = 1.0 / (x2 - x1);
+      y1 = y[i];
+      y2 = y[index2];
+      step = 1;
+      continue;
+    }
+    xp = (isHistogram ? (0.5 * (x[i] + x[i + 1])) : x[i]);
+    // Linear interpolation
+    y[i] = (xp - x1) * y2 + (x2 - xp) * y1;
+    y[i] *= overgap;
+    step++;
+  }
+
+}
+
 
 } // End namespace VectorHelper
 } // End namespace Kernel
diff --git a/Code/Mantid/Kernel/test/NeutronAtomTest.h b/Code/Mantid/Kernel/test/NeutronAtomTest.h
index 103fe204da0..a041311bdc0 100644
--- a/Code/Mantid/Kernel/test/NeutronAtomTest.h
+++ b/Code/Mantid/Kernel/test/NeutronAtomTest.h
@@ -5,7 +5,7 @@
 #include <stdexcept>
 #include "MantidKernel/NeutronAtom.h"
 
-using namespace Mantid::Kernel::PhysicalConstants;
+using namespace Mantid::PhysicalConstants;
 
 class NeutronAtomTest : public CxxTest::TestSuite
 {
diff --git a/Code/Mantid/Kernel/test/RandomNumberGeneratorTest.h b/Code/Mantid/Kernel/test/RandomNumberGeneratorTest.h
index 002d9868a81..05ee3631410 100644
--- a/Code/Mantid/Kernel/test/RandomNumberGeneratorTest.h
+++ b/Code/Mantid/Kernel/test/RandomNumberGeneratorTest.h
@@ -13,7 +13,7 @@ private:
   class FakeRandomNumberGenerator : public Mantid::Kernel::RandomNumberGenerator
   {
   public:
-    void setSeed(long seedValue)
+    void setSeed(unsigned int seedValue)
     {
     }
     void setRange(double start, double end)
diff --git a/Code/Mantid/Nexus/inc/MantidNexus/NexusClasses.h b/Code/Mantid/Nexus/inc/MantidNexus/NexusClasses.h
index 785c8694d30..e9f7aea88f7 100644
--- a/Code/Mantid/Nexus/inc/MantidNexus/NexusClasses.h
+++ b/Code/Mantid/Nexus/inc/MantidNexus/NexusClasses.h
@@ -180,7 +180,11 @@ namespace Mantid
       *   @param l Non-negative value makes it read a chunk of dimension rank()-4. i,j,k and l are its indices. 
       *            The rank of the data must be 4
       */
-      virtual void load(const int blocksize = 1, int i = -1, int j = -1, int k = -1,int l = -1) {};
+      virtual void load(const int blocksize = 1, int i = -1, int j = -1, int k = -1,int l = -1) 
+      {
+	// Avoid compiler warnings
+	(void)blocksize; (void)i; (void)j; (void)k; (void)l;
+      };
     protected:
       void getData(void* data);
       void getSlab(void* data, int start[], int size[]);
diff --git a/Code/Mantid/Nexus/src/LoadMuonNexus2.cpp b/Code/Mantid/Nexus/src/LoadMuonNexus2.cpp
index 8e1fc5e7d65..6bb93054015 100644
--- a/Code/Mantid/Nexus/src/LoadMuonNexus2.cpp
+++ b/Code/Mantid/Nexus/src/LoadMuonNexus2.cpp
@@ -273,6 +273,8 @@ namespace Mantid
     */
     void LoadMuonNexus2::loadLogs(API::MatrixWorkspace_sptr ws, NXEntry & entry,int period)
     {
+      //Avoid compiler warning 
+      (void)period;
 
       std::string start_time = entry.getString("start_time");
 
diff --git a/Code/Mantid/Nexus/src/LoadSNSNexus.cpp b/Code/Mantid/Nexus/src/LoadSNSNexus.cpp
index c663d4a236c..5a6c8ce5784 100644
--- a/Code/Mantid/Nexus/src/LoadSNSNexus.cpp
+++ b/Code/Mantid/Nexus/src/LoadSNSNexus.cpp
@@ -109,6 +109,7 @@ void LoadSNSNexus::exec()
  */
 API::Workspace_sptr LoadSNSNexus::loadEntry(NXEntry entry,int period, double progress_start, double progress_end)
 {
+    (void)period;
     std::cerr << "loadEntry00:" << std::endl;// REMOVE
     // To keep sorted bank names
     std::set<std::string,CompareBanks> banks;
diff --git a/Code/Mantid/Nexus/src/NexusClasses.cpp b/Code/Mantid/Nexus/src/NexusClasses.cpp
index 284ff0cdce3..7b3242766e7 100644
--- a/Code/Mantid/Nexus/src/NexusClasses.cpp
+++ b/Code/Mantid/Nexus/src/NexusClasses.cpp
@@ -417,6 +417,7 @@ NXRoot::NXRoot(const std::string& fname)
 NXRoot::NXRoot(const std::string& fname,const std::string& entry)
     :m_filename(fname)
 {
+    (void)entry;
     // Open NeXus file
     NXstatus stat=NXopen(m_filename.c_str(), NXACC_CREATE5, &m_fileID);
     if(stat==NX_ERROR)
diff --git a/Code/Mantid/PythonAPI/MantidFramework.py b/Code/Mantid/PythonAPI/MantidFramework.py
index 1e228c56269..db25215e635 100644
--- a/Code/Mantid/PythonAPI/MantidFramework.py
+++ b/Code/Mantid/PythonAPI/MantidFramework.py
@@ -5,7 +5,6 @@ import platform
 import sys
 import types
 import copy
-import sets
 import warnings
 import __builtin__
 import __main__
-- 
GitLab