diff --git a/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h b/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h
index 8405138254935c2a04fa3557d21661b8b09a7e74..b824292889070d21f007d2a98f585ed9260b9b21 100644
--- a/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h
+++ b/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h
@@ -9,6 +9,7 @@
 #include <utility>
 #include <cstddef>
 #include <Eigen/Geometry>
+#include <string>
 
 namespace Mantid {
 namespace Beamline {
@@ -54,6 +55,7 @@ private:
   Mantid::Kernel::cow_ptr<std::vector<Eigen::Quaterniond>> m_rotations;
   Mantid::Kernel::cow_ptr<std::vector<Eigen::Vector3d>> m_scaleFactors;
   Mantid::Kernel::cow_ptr<std::vector<bool>> m_isStructuredBank;
+  boost::shared_ptr<const std::vector<std::string>> m_names;
 
   const size_t m_size = 0;
   const int64_t m_sourceIndex = -1;
@@ -96,6 +98,7 @@ public:
                 boost::shared_ptr<std::vector<Eigen::Quaterniond>> rotations,
                 boost::shared_ptr<std::vector<Eigen::Vector3d>> scaleFactors,
                 boost::shared_ptr<std::vector<bool>> isStructuredBank,
+                boost::shared_ptr<const std::vector<std::string>> names,
                 int64_t sourceIndex, int64_t sampleIndex);
   /// Copy assignment not permitted because of the way DetectorInfo stored
   ComponentInfo &operator=(const ComponentInfo &other) = delete;
@@ -138,6 +141,8 @@ public:
   size_t sample() const;
   size_t root() const;
   double l1() const;
+  std::string name(const size_t componentIndex) const;
+  size_t indexOf(const std::string &name) const;
   Eigen::Vector3d scaleFactor(const size_t componentIndex) const;
   void setScaleFactor(const size_t componentIndex,
                       const Eigen::Vector3d &scaleFactor);
diff --git a/Framework/Beamline/src/ComponentInfo.cpp b/Framework/Beamline/src/ComponentInfo.cpp
index baea0884a8819cf536252233dea8347aa4eeb7ca..c6c71b9fa7868deca4f29a10b57626d419d66552 100644
--- a/Framework/Beamline/src/ComponentInfo.cpp
+++ b/Framework/Beamline/src/ComponentInfo.cpp
@@ -3,8 +3,11 @@
 #include "MantidKernel/make_cow.h"
 #include <boost/make_shared.hpp>
 #include <numeric>
+#include <algorithm>
 #include <utility>
 #include <vector>
+#include <sstream>
+#include <iterator>
 
 namespace Mantid {
 namespace Beamline {
@@ -39,8 +42,9 @@ ComponentInfo::ComponentInfo(
     boost::shared_ptr<std::vector<Eigen::Vector3d>> positions,
     boost::shared_ptr<std::vector<Eigen::Quaterniond>> rotations,
     boost::shared_ptr<std::vector<Eigen::Vector3d>> scaleFactors,
-    boost::shared_ptr<std::vector<bool>> isStructuredBank, int64_t sourceIndex,
-    int64_t sampleIndex)
+    boost::shared_ptr<std::vector<bool>> isStructuredBank,
+    boost::shared_ptr<const std::vector<std::string>> names,
+    int64_t sourceIndex, int64_t sampleIndex)
     : m_assemblySortedDetectorIndices(std::move(assemblySortedDetectorIndices)),
       m_assemblySortedComponentIndices(
           std::move(assemblySortedComponentIndices)),
@@ -50,6 +54,7 @@ ComponentInfo::ComponentInfo(
       m_positions(std::move(positions)), m_rotations(std::move(rotations)),
       m_scaleFactors(std::move(scaleFactors)),
       m_isStructuredBank(std::move(isStructuredBank)),
+      m_names(std::move(names)),
       m_size(m_assemblySortedDetectorIndices->size() +
              m_detectorRanges->size()),
       m_sourceIndex(sourceIndex), m_sampleIndex(sampleIndex),
@@ -83,6 +88,10 @@ ComponentInfo::ComponentInfo(
                                 "of rectangular bank flags as number of "
                                 "non-detector components");
   }
+  if (m_names->size() != m_size) {
+    throw std::invalid_argument("ComponentInfo should be provided same number "
+                                "of names as number of components");
+  }
 }
 
 std::unique_ptr<ComponentInfo> ComponentInfo::cloneWithoutDetectorInfo() const {
@@ -494,6 +503,20 @@ Eigen::Vector3d ComponentInfo::scaleFactor(const size_t componentIndex) const {
   return (*m_scaleFactors)[componentIndex];
 }
 
+std::string ComponentInfo::name(const size_t componentIndex) const {
+  return (*m_names)[componentIndex];
+}
+
+size_t ComponentInfo::indexOf(const std::string &name) const {
+  auto it = std::find(m_names->begin(), m_names->end(), name);
+  if (it == m_names->end()) {
+    std::stringstream buffer;
+    buffer << name << " does not exist";
+    throw std::invalid_argument(buffer.str());
+  }
+  return std::distance(m_names->begin(), it);
+}
+
 void ComponentInfo::setScaleFactor(const size_t componentIndex,
                                    const Eigen::Vector3d &scaleFactor) {
   m_scaleFactors.access()[componentIndex] = scaleFactor;
diff --git a/Framework/Beamline/test/ComponentInfoTest.h b/Framework/Beamline/test/ComponentInfoTest.h
index 7ef75e03362f1d25e0ca1f0436fe56e8134e5e1a..44187c9aa69d9bd17619355f3df354d569da2a71 100644
--- a/Framework/Beamline/test/ComponentInfoTest.h
+++ b/Framework/Beamline/test/ComponentInfoTest.h
@@ -9,6 +9,7 @@
 #include <boost/make_shared.hpp>
 #include <numeric>
 #include <tuple>
+#include <string>
 
 using namespace Mantid::Beamline;
 
@@ -16,6 +17,7 @@ namespace {
 
 using PosVec = std::vector<Eigen::Vector3d>;
 using RotVec = std::vector<Eigen::Quaterniond>;
+using StrVec = std::vector<std::string>;
 
 /*
  * Makes a tree which in which all detectors are arranged in a single flat
@@ -50,6 +52,12 @@ makeFlatTree(PosVec detPositions, RotVec detRotations) {
   // Component scale factors
   auto scaleFactors = boost::make_shared<PosVec>(
       PosVec(detPositions.size() + 1, Eigen::Vector3d{1, 1, 1}));
+  // Component names
+  auto names = boost::make_shared<StrVec>();
+  for (size_t detIndex = 0; detIndex < detPositions.size(); ++detIndex) {
+    names->emplace_back("det" + std::to_string(detIndex));
+  }
+  names->emplace_back("root");
   auto detectorInfo =
       boost::make_shared<DetectorInfo>(detPositions, detRotations);
   // Rectangular bank flag
@@ -62,8 +70,8 @@ makeFlatTree(PosVec detPositions, RotVec detRotations) {
       bankSortedComponentIndices,
       boost::make_shared<const std::vector<std::pair<size_t, size_t>>>(
           componentRanges),
-      parentIndices, positions, rotations, scaleFactors, isRectangularBank, -1,
-      -1);
+      parentIndices, positions, rotations, scaleFactors, isRectangularBank,
+      names, -1, -1);
 
   componentInfo->setDetectorInfo(detectorInfo.get());
 
@@ -125,7 +133,8 @@ makeTreeExampleAndReturnGeometricArguments() {
   // Component scale factors
   auto scaleFactors =
       boost::make_shared<PosVec>(PosVec(5, Eigen::Vector3d{1, 1, 1}));
-
+  // Component names
+  auto names = boost::make_shared<StrVec>(5);
   // Rectangular bank flag
   auto isRectangularBank = boost::make_shared<std::vector<bool>>(2, false);
 
@@ -137,7 +146,7 @@ makeTreeExampleAndReturnGeometricArguments() {
       boost::make_shared<const std::vector<std::pair<size_t, size_t>>>(
           componentRanges),
       parentIndices, compPositions, compRotations, scaleFactors,
-      isRectangularBank, -1, -1);
+      isRectangularBank, names, -1, -1);
 
   compInfo->setDetectorInfo(detectorInfo.get());
 
@@ -187,6 +196,8 @@ makeTreeExample() {
   // Component scale factors
   auto scaleFactors =
       boost::make_shared<PosVec>(PosVec(5, Eigen::Vector3d{1, 1, 1}));
+  // Component names
+  auto names = boost::make_shared<StrVec>(5);
   auto detectorInfo =
       boost::make_shared<DetectorInfo>(detPositions, detRotations);
   // Rectangular bank flag
@@ -199,8 +210,8 @@ makeTreeExample() {
       bankSortedComponentIndices,
       boost::make_shared<const std::vector<std::pair<size_t, size_t>>>(
           componentRanges),
-      parentIndices, positions, rotations, scaleFactors, isRectangularBank, -1,
-      -1);
+      parentIndices, positions, rotations, scaleFactors, isRectangularBank,
+      names, -1, -1);
 
   componentInfo->setDetectorInfo(detectorInfo.get());
 
@@ -269,11 +280,12 @@ public:
     auto positions = boost::make_shared<PosVec>();
     auto rotations = boost::make_shared<RotVec>();
     auto scaleFactors = boost::make_shared<PosVec>(3);
+    auto names = boost::make_shared<StrVec>(3);
     auto isRectangularBank = boost::make_shared<std::vector<bool>>();
     ComponentInfo componentInfo(bankSortedDetectorIndices, detectorRanges,
                                 bankSortedComponentIndices, componentRanges,
                                 parentIndices, positions, rotations,
-                                scaleFactors, isRectangularBank, -1, -1);
+                                scaleFactors, isRectangularBank, names, -1, -1);
 
     DetectorInfo detectorInfo; // Detector info size 0
     TS_ASSERT_THROWS(componentInfo.setDetectorInfo(&detectorInfo),
@@ -305,11 +317,13 @@ public:
     auto rotations = boost::make_shared<RotVec>(0); // 0 rotations provided
 
     auto scaleFactors = boost::make_shared<PosVec>();
+    auto names = boost::make_shared<StrVec>();
     auto isRectangularBank = boost::make_shared<std::vector<bool>>(2, false);
     TS_ASSERT_THROWS(ComponentInfo(detectorsInSubtree, detectorRanges,
                                    bankSortedComponentIndices, componentRanges,
                                    parentIndices, positions, rotations,
-                                   scaleFactors, isRectangularBank, -1, -1),
+                                   scaleFactors, isRectangularBank, names, -1,
+                                   -1),
                      std::invalid_argument &);
   }
 
@@ -338,17 +352,18 @@ public:
     auto rotations = boost::make_shared<RotVec>(1); // 1 rotation provided
 
     auto scaleFactors = boost::make_shared<PosVec>();
+    auto names = boost::make_shared<StrVec>();
     // Only one component. So single empty component range.
     auto componentRanges =
         boost::make_shared<const std::vector<std::pair<size_t, size_t>>>(
             std::vector<std::pair<size_t, size_t>>{{0, 0}});
     auto isRectangularBank = boost::make_shared<std::vector<bool>>(2, false);
 
-    TS_ASSERT_THROWS(ComponentInfo(detectorsInSubtree, detectorRanges,
-                                   componentsInSubtree, componentRanges,
-                                   parentIndices, positions, rotations,
-                                   scaleFactors, isRectangularBank, -1, -1),
-                     std::invalid_argument &);
+    TS_ASSERT_THROWS(
+        ComponentInfo(detectorsInSubtree, detectorRanges, componentsInSubtree,
+                      componentRanges, parentIndices, positions, rotations,
+                      scaleFactors, isRectangularBank, names, -1, -1),
+        std::invalid_argument &);
   }
 
   void test_read_positions_rotations() {
@@ -733,6 +748,30 @@ public:
     TS_ASSERT_EQUALS(compInfo.scaleFactor(0), newFactor);
   }
 
+  void test_name() {
+    auto infos = makeFlat(PosVec(1), RotVec(1));
+    ComponentInfo &compInfo = *std::get<0>(infos);
+    TS_ASSERT_EQUALS(compInfo.name(compInfo.root()), "root");
+    TS_ASSERT_EQUALS(compInfo.name(0), "det0");
+  }
+
+  void test_indexOf_name_throws_when_name_invalid() {
+    auto infos = makeFlat(PosVec(1), RotVec(1));
+    ComponentInfo &compInfo = *std::get<0>(infos);
+    TSM_ASSERT_THROWS("Should throw, this name does not exist",
+                      compInfo.indexOf("phantom"), std::invalid_argument &)
+    // Sanity check.
+    TSM_ASSERT_THROWS_NOTHING("Should NOT throw if provided with a valid name",
+                              compInfo.indexOf(compInfo.name(0)));
+  }
+
+  void test_indexOf() {
+    auto infos = makeFlat(PosVec(1), RotVec(1));
+    ComponentInfo &compInfo = *std::get<0>(infos);
+    TS_ASSERT_EQUALS(compInfo.indexOf("det0"), 0);
+    TS_ASSERT_EQUALS(compInfo.indexOf("root"), compInfo.root());
+  }
+
   void test_scan_count_no_scanning() {
     ComponentInfo info;
     TS_ASSERT_EQUALS(info.scanCount(0), 1);
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h
index b2d9c5b3b7ceb199552497083ebde26e0b2f1a2b..c6d709f784f962c078a57baf79b35971dad468b3 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h
@@ -87,6 +87,7 @@ public:
   std::vector<size_t> componentsInSubtree(size_t componentIndex) const;
   size_t size() const;
   size_t indexOf(Geometry::IComponent *id) const;
+  size_t indexOf(const std::string &name) const;
   bool isDetector(const size_t componentIndex) const;
   Kernel::V3D position(const size_t componentIndex) const;
   Kernel::V3D position(const std::pair<size_t, size_t> index) const;
@@ -111,6 +112,7 @@ public:
   size_t sample() const;
   double l1() const;
   Kernel::V3D scaleFactor(const size_t componentIndex) const;
+  std::string name(const size_t componentIndex) const;
   void setScaleFactor(const size_t componentIndex,
                       const Kernel::V3D &scaleFactor);
   size_t root();
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h b/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h
index d44302c5ba18422fc5a9a3326876fc280ad3bdb7..e8e13363c2e5304624516d571a9da0bc909c0cc0 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h
@@ -136,6 +136,9 @@ private:
   /// Structured bank flag
   boost::shared_ptr<std::vector<bool>> m_isStructuredBank;
 
+  /// Component names
+  boost::shared_ptr<std::vector<std::string>> m_names;
+
   void markAsSourceOrSample(Mantid::Geometry::IComponent *componentId,
                             const size_t componentIndex);
 
diff --git a/Framework/Geometry/src/Instrument/ComponentInfo.cpp b/Framework/Geometry/src/Instrument/ComponentInfo.cpp
index 4a7d5b38debcd36308b7f608d00a1af4435c456e..08a9ab755b73cd0d5b8ab5df9c612969e690bf15 100644
--- a/Framework/Geometry/src/Instrument/ComponentInfo.cpp
+++ b/Framework/Geometry/src/Instrument/ComponentInfo.cpp
@@ -111,6 +111,10 @@ size_t ComponentInfo::indexOf(Geometry::IComponent *id) const {
   return m_compIDToIndex->at(id);
 }
 
+size_t ComponentInfo::indexOf(const std::string &name) const {
+  return m_componentInfo->indexOf(name);
+}
+
 bool ComponentInfo::isDetector(const size_t componentIndex) const {
   return m_componentInfo->isDetector(componentIndex);
 }
@@ -207,6 +211,10 @@ Kernel::V3D ComponentInfo::scaleFactor(const size_t componentIndex) const {
   return Kernel::toV3D(m_componentInfo->scaleFactor(componentIndex));
 }
 
+std::string ComponentInfo::name(const size_t componentIndex) const {
+  return m_componentInfo->name(componentIndex);
+}
+
 void ComponentInfo::setScaleFactor(const size_t componentIndex,
                                    const Kernel::V3D &scaleFactor) {
   m_componentInfo->setScaleFactor(componentIndex,
diff --git a/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp b/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp
index 13adc7e538800b24e92c5da9b3489683ff17ad1a..a95dddac502ecdc85ee2b71ab02b321841e039d9 100644
--- a/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp
+++ b/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp
@@ -85,8 +85,9 @@ InstrumentVisitor::InstrumentVisitor(
           m_orderedDetectorIds->size(), m_nullShape)),
       m_scaleFactors(boost::make_shared<std::vector<Eigen::Vector3d>>(
           m_orderedDetectorIds->size(), Eigen::Vector3d{1, 1, 1})),
-      m_isStructuredBank(boost::make_shared<std::vector<bool>>()) {
-
+      m_isStructuredBank(boost::make_shared<std::vector<bool>>()),
+      m_names(boost::make_shared<std::vector<std::string>>(
+          m_orderedDetectorIds->size())) {
   if (m_instrument->isParametrized()) {
     m_pmap = m_instrument->getParameterMap().get();
   }
@@ -109,7 +110,6 @@ InstrumentVisitor::InstrumentVisitor(
   const auto nDetectors = m_orderedDetectorIds->size();
   m_assemblySortedDetectorIndices->reserve(nDetectors); // Exact
   m_componentIdToIndexMap->reserve(nDetectors);         // Approximation
-  m_shapes->reserve(nDetectors);                        // Approximation
 }
 
 void InstrumentVisitor::walkInstrument() {
@@ -160,6 +160,7 @@ InstrumentVisitor::registerComponentAssembly(const ICompAssembly &assembly) {
   m_shapes->emplace_back(m_nullShape);
   m_isStructuredBank->push_back(false);
   m_scaleFactors->emplace_back(Kernel::toVector3d(assembly.getScaleFactor()));
+  m_names->emplace_back(assembly.getName());
   clearLegacyParameters(m_pmap, assembly);
   return componentIndex;
 }
@@ -194,6 +195,7 @@ InstrumentVisitor::registerGenericComponent(const IComponent &component) {
   m_shapes->emplace_back(m_nullShape);
   m_isStructuredBank->push_back(false);
   m_scaleFactors->emplace_back(Kernel::toVector3d(component.getScaleFactor()));
+  m_names->emplace_back(component.getName());
   clearLegacyParameters(m_pmap, component);
   return componentIndex;
 }
@@ -261,6 +263,7 @@ size_t InstrumentVisitor::registerDetector(const IDetector &detector) {
   if (m_instrument->isMonitorViaIndex(detectorIndex)) {
     m_monitorIndices->push_back(detectorIndex);
   }
+  (*m_names)[detectorIndex] = detector.getName();
   clearLegacyParameters(m_pmap, detector);
 
   /* Note that positions and rotations for detectors are currently
@@ -314,7 +317,7 @@ InstrumentVisitor::componentInfo() const {
       m_assemblySortedDetectorIndices, m_detectorRanges,
       m_assemblySortedComponentIndices, m_componentRanges,
       m_parentComponentIndices, m_positions, m_rotations, m_scaleFactors,
-      m_isStructuredBank, m_sourceIndex, m_sampleIndex);
+      m_isStructuredBank, m_names, m_sourceIndex, m_sampleIndex);
 }
 
 std::unique_ptr<Beamline::DetectorInfo>
diff --git a/Framework/Geometry/test/ComponentInfoTest.h b/Framework/Geometry/test/ComponentInfoTest.h
index ae8a2baea24a14f673dae8273a5611a4594050a4..543b1c56b0394d3650886985ab7dd0dce32dc528 100644
--- a/Framework/Geometry/test/ComponentInfoTest.h
+++ b/Framework/Geometry/test/ComponentInfoTest.h
@@ -104,11 +104,12 @@ std::unique_ptr<Beamline::ComponentInfo> makeSingleBeamlineComponentInfo(
       boost::make_shared<std::vector<Eigen::Quaterniond>>(1, rotation);
   auto scaleFactors =
       boost::make_shared<std::vector<Eigen::Vector3d>>(1, scaleFactor);
+  auto names = boost::make_shared<std::vector<std::string>>(1);
   auto isStructuredBank = boost::make_shared<std::vector<bool>>(1, false);
   return Kernel::make_unique<Beamline::ComponentInfo>(
       detectorIndices, detectorRanges, componentIndices, componentRanges,
-      parentIndices, positions, rotations, scaleFactors, isStructuredBank, -1,
-      -1);
+      parentIndices, positions, rotations, scaleFactors, isStructuredBank,
+      names, -1, -1);
 }
 }
 
@@ -146,10 +147,12 @@ public:
     auto positions = boost::make_shared<std::vector<Eigen::Vector3d>>(2);
     auto rotations = boost::make_shared<std::vector<Eigen::Quaterniond>>(2);
     auto scaleFactors = boost::make_shared<std::vector<Eigen::Vector3d>>(2);
+    auto names = boost::make_shared<std::vector<std::string>>(2);
     auto isRectBank = boost::make_shared<std::vector<bool>>(2);
     auto internalInfo = Kernel::make_unique<Beamline::ComponentInfo>(
         detectorIndices, detectorRanges, componentIndices, componentRanges,
-        parentIndices, positions, rotations, scaleFactors, isRectBank, -1, -1);
+        parentIndices, positions, rotations, scaleFactors, isRectBank, names,
+        -1, -1);
     Mantid::Geometry::ObjComponent comp1("component1");
     Mantid::Geometry::ObjComponent comp2("component2");
 
diff --git a/Framework/Geometry/test/InstrumentVisitorTest.h b/Framework/Geometry/test/InstrumentVisitorTest.h
index 352c57dbd6658b452a226317ce047ef7adbb32c6..cdc74a72501fd7a01a26a058d457ce4c6124ad6f 100644
--- a/Framework/Geometry/test/InstrumentVisitorTest.h
+++ b/Framework/Geometry/test/InstrumentVisitorTest.h
@@ -384,6 +384,30 @@ public:
                       &componentInfo->shape(1 /*another detector*/));
   }
 
+  void test_names() {
+
+    const int nPixelsWide = 10; // Gives 10*10 detectors in total
+    auto instrument = ComponentCreationHelper::createTestInstrumentRectangular(
+        1 /*n banks*/, nPixelsWide, 1 /*sample-bank distance*/);
+
+    // Visit everything
+    auto wrappers =
+        InstrumentVisitor::makeWrappers(*instrument, nullptr /*parameter map*/);
+    auto componentInfo = std::move(std::get<0>(wrappers));
+
+    // Check root name
+    TS_ASSERT_EQUALS("basic_rect", componentInfo->name(componentInfo->root()));
+    // Backward check that we get the right index
+    TS_ASSERT_EQUALS(componentInfo->indexOf("basic_rect"),
+                     componentInfo->root());
+
+    // Check all names are the same in old instrument and component info
+    for (size_t index = 0; index < componentInfo->size(); ++index) {
+      TS_ASSERT_EQUALS(componentInfo->componentID(index)->getName(),
+                       componentInfo->name(index));
+    }
+  }
+
   void test_purge_scale_factors() {
 
     // Create a very basic instrument to visit