diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadInstrument.h b/Framework/DataHandling/inc/MantidDataHandling/LoadInstrument.h
index 6e2a1c7b6d8e915f9df83392d48aaaa6ed9e4b6c..ad1f34c2c1c737f6721378f56b37847699fe5981 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadInstrument.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadInstrument.h
@@ -9,7 +9,6 @@
 
 #include "MantidAPI/DistributedAlgorithm.h"
 #include "MantidAPI/ExperimentInfo.h"
-#include "MantidGeometry/Instrument/InstrumentDefinitionParser.h"
 
 #include <mutex>
 
@@ -80,13 +79,6 @@ public:
   const std::string category() const override {
     return "DataHandling\\Instrument";
   }
-  /// Load instrument from IDF XML file
-  void idfInstrumentLoader(const boost::shared_ptr<API::MatrixWorkspace> &ws,
-                           std::string filename, std::string instname,
-                           const std::string &xmlString);
-  /// Load instrument from Nexus file
-  void nexusInstrumentLoader(const boost::shared_ptr<API::MatrixWorkspace> &ws,
-                             std::string filename);
 
 private:
   void init() override;
diff --git a/Framework/DataHandling/src/LoadInstrument.cpp b/Framework/DataHandling/src/LoadInstrument.cpp
index e43b8e1a5ed60e38c31bb878c7cfb1c8adb12330..014881b29a6947e02bcbf8c58409b45e69998b8f 100644
--- a/Framework/DataHandling/src/LoadInstrument.cpp
+++ b/Framework/DataHandling/src/LoadInstrument.cpp
@@ -11,6 +11,7 @@
 #include "MantidAPI/Progress.h"
 #include "MantidDataHandling/LoadGeometry.h"
 #include "MantidGeometry/Instrument.h"
+#include "MantidGeometry/Instrument/InstrumentDefinitionParser.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/ConfigService.h"
 #include "MantidKernel/MandatoryValidator.h"
@@ -100,6 +101,7 @@ void LoadInstrument::exec() {
   boost::shared_ptr<API::MatrixWorkspace> ws = getProperty("Workspace");
   std::string filename = getPropertyValue("Filename");
   std::string instname = getPropertyValue("InstrumentName");
+  std::pair <std::string,std::string> loader_type;
 
   // If instrumentXML is not default (i.e. it has been defined), then use that
   // Note: this is part of the IDF loader
@@ -114,8 +116,9 @@ void LoadInstrument::exec() {
     // name
     if (filename.empty())
       filename = instname;
-    // Call IDF loader
-    idfInstrumentLoader(ws, filename, instname, InstrumentXML->value());
+
+    loader_type.first = "idf";
+    loader_type.second = "xml";
 
   } else {
     // This part of the loader searches through the instrument directories for
@@ -145,66 +148,73 @@ void LoadInstrument::exec() {
           "Unable to find an Instrument File for instrument: ", instname);
     }
 
+    // Remove the path from the filename for use with the InstrumentDataService
+    const std::string::size_type stripPath = filename.find_last_of("\\/");
+    std::string instrumentFile =
+        filename.substr(stripPath + 1, filename.size());
+    // Strip off "_Definition.xml"
+    instname = instrumentFile.substr(0, instrumentFile.find("_Def"));
+
     // Now that we have a file name, decide whether to use Nexus or IDF loading
     if (LoadGeometry::isIDF(filename)) {
-      // Remove the path from the filename for use with the
-      // InstrumentDataService
-      const std::string::size_type stripPath = filename.find_last_of("\\/");
-      std::string instrumentFile =
-          filename.substr(stripPath + 1, filename.size());
-      // Strip off "_Definition.xml"
-      instname = instrumentFile.substr(0, instrumentFile.find("_Def"));
       // Call theIDF loader  with the the XML text loaded from the IDF file
-      idfInstrumentLoader(ws, filename, instname, Strings::loadFile(filename));
+      loader_type.first = "idf";
+      loader_type.second = "idffile";
     } else if (LoadGeometry::isNexus(filename)) {
-      nexusInstrumentLoader(ws, filename);
+      // nexusInstrumentLoader(ws, filename, instname);
+      loader_type.first = "nxs";
+      loader_type.second = "nxsfile";
     } else {
       throw Kernel::Exception::FileError(
           "No valid loader found for instrument file ", filename);
     }
   }
 
-  // Set the monitors output property
-  setProperty("MonitorList", (ws->getInstrument())->getMonitors());
-
-  // Rebuild the spectra map for this workspace so that it matches the
-  // instrument, if required
-  const OptionalBool RewriteSpectraMap = getProperty("RewriteSpectraMap");
-  if (RewriteSpectraMap == OptionalBool::True)
-    ws->rebuildSpectraMapping();
-}
-
-/// Load instrument from IDF XML file
-void LoadInstrument::idfInstrumentLoader(
-    const boost::shared_ptr<API::MatrixWorkspace> &ws, std::string filename,
-    std::string instname, const std::string &xmlString) {
+  InstrumentDefinitionParser parser;
+  std::string instrumentNameMangled;
+  Instrument_sptr instrument;
 
-  auto parser = InstrumentDefinitionParser(filename, instname, xmlString);
+  // Define a parser if using IDFs
+  if (loader_type.second == "xml")
+    parser = InstrumentDefinitionParser(filename, instname, InstrumentXML->value());
+  else if (loader_type.second == "idffile")
+    parser = InstrumentDefinitionParser(filename, instname, Strings::loadFile(filename));
 
   // Find the mangled instrument name that includes the modified date
-  std::string instrumentNameMangled = parser.getMangledName();
+  if (loader_type.first == "idf")
+    instrumentNameMangled = parser.getMangledName();
+  else if (loader_type.first == "nxs")
+    instrumentNameMangled =
+      NexusGeometry::NexusGeometryParser::getMangledName(filename, instname);
+  else
+    throw std::runtime_error("Unknown instrument loader type");
 
-  Instrument_sptr instrument;
-  // Check whether the instrument is already in the InstrumentDataService
   {
     // Make InstrumentService access thread-safe
     std::lock_guard<std::recursive_mutex> lock(m_mutex);
 
+    // Check whether the instrument is already in the InstrumentDataService
     if (InstrumentDataService::Instance().doesExist(instrumentNameMangled)) {
       // If it does, just use the one from the one stored there
       instrument =
           InstrumentDataService::Instance().retrieve(instrumentNameMangled);
     } else {
-      // Really create the instrument
-      Progress prog(this, 0.0, 1.0, 100);
-      instrument = parser.parseXML(&prog);
-      // Parse the instrument tree (internally create ComponentInfo and
-      // DetectorInfo). This is an optimization that avoids duplicate parsing of
-      // the instrument tree when loading multiple workspaces with the same
-      // instrument. As a consequence less time is spent and less memory is
-      // used. Note that this is only possible since the tree in `instrument`
-      // will not be modified once we add it to the IDS.
-      instrument->parseTreeAndCacheBeamline();
+
+      if (loader_type.first == "idf") {
+        // Really create the instrument
+        Progress prog(this, 0.0, 1.0, 100);
+        instrument = parser.parseXML(&prog);
+        // Parse the instrument tree (internally create ComponentInfo and
+        // DetectorInfo). This is an optimization that avoids duplicate parsing of
+        // the instrument tree when loading multiple workspaces with the same
+        // instrument. As a consequence less time is spent and less memory is
+        // used. Note that this is only possible since the tree in `instrument`
+        // will not be modified once we add it to the IDS.
+        instrument->parseTreeAndCacheBeamline();
+      } else {
+        Instrument_const_sptr ins = NexusGeometry::NexusGeometryParser::createInstrument(filename);
+        instrument = boost::const_pointer_cast<Instrument>(ins);
+      }
       // Add to data service for later retrieval
       InstrumentDataService::Instance().add(instrumentNameMangled, instrument);
     }
@@ -216,18 +226,18 @@ void LoadInstrument::idfInstrumentLoader(
     // LoadParameterFile modifies the base instrument stored in the IDS so this
     // must also be protected by the lock until LoadParameterFile is fixed.
     // check if default parameter file is also present, unless loading from
-    if (!filename.empty())
+    if (!filename.empty() && (loader_type.first == "idf"))
       runLoadParameterFile(ws, filename);
-  }
-}
+  } // end of mutex scope
 
-/// Load instrument from Nexus file
-void LoadInstrument::nexusInstrumentLoader(
-    const boost::shared_ptr<API::MatrixWorkspace> &ws, std::string filename) {
-  Instrument_const_sptr instrument =
-      NexusGeometry::NexusGeometryParser::createInstrument(filename);
-  ws->setInstrument(instrument);
-  ws->populateInstrumentParameters();
+  // Set the monitors output property
+  setProperty("MonitorList", (ws->getInstrument())->getMonitors());
+
+  // Rebuild the spectra map for this workspace so that it matches the
+  // instrument, if required
+  const OptionalBool RewriteSpectraMap = getProperty("RewriteSpectraMap");
+  if (RewriteSpectraMap == OptionalBool::True)
+    ws->rebuildSpectraMapping();
 }
 
 //-----------------------------------------------------------------------------------------------------------------------
diff --git a/Framework/DataHandling/test/LoadInstrumentTest.h b/Framework/DataHandling/test/LoadInstrumentTest.h
index a455f294fdd9979ce02313dee2db4a7ebf5b8d44..948e8411c27839363f1842ecf88c6670fa8b4858 100644
--- a/Framework/DataHandling/test/LoadInstrumentTest.h
+++ b/Framework/DataHandling/test/LoadInstrumentTest.h
@@ -243,9 +243,6 @@ public:
     loaderNIMROD.execute();
     TS_ASSERT(loaderNIMROD.isExecuted());
 
-    // Get back the saved workspace
-    // MatrixWorkspace_sptr output = loaderNIMROD.getProperty("Workspace");
-
     const auto &detectorInfo = ws2D->detectorInfo();
     const auto &ptrDet = detectorInfo.detector(detectorInfo.indexOf(20201001));
     TS_ASSERT_EQUALS(ptrDet.getName(), "det 1");
@@ -255,6 +252,36 @@ public:
     TS_ASSERT_DELTA(ptrDet.getPos().Z(), 4.8888, 0.0001);
   }
 
+  void testExecNIMRODandRetrieveFromIDS() {
+    // Make sure the IDS is empty
+    InstrumentDataServiceImpl &IDS = InstrumentDataService::Instance();
+    IDS.clear();
+
+    LoadInstrument loaderNIMROD;
+    loaderNIMROD.initialize();
+    loaderNIMROD.setChild(true);
+
+    // create a workspace with some sample data
+    MatrixWorkspace_sptr ws2D =
+        DataObjects::create<Workspace2D>(1, HistogramData::Points(1));
+
+    const std::string instrFilename = "NIM_Definition.xml";
+    loaderNIMROD.setPropertyValue("Filename", instrFilename);
+    loaderNIMROD.setProperty("RewriteSpectraMap", OptionalBool(true));
+    loaderNIMROD.setProperty("Workspace", ws2D);
+    loaderNIMROD.execute();
+    TS_ASSERT(loaderNIMROD.isExecuted());
+
+    TS_ASSERT_EQUALS(IDS.size(), 1);
+    if (IDS.size() != 1)
+      return;
+    // Retrieve the instrument from the InstrumentDataService
+    Instrument_const_sptr nimrodInst = IDS.getObjects()[0];
+    TS_ASSERT_EQUALS(nimrodInst->getName(), "NIM");
+    TS_ASSERT_EQUALS(nimrodInst->getNumberDetectors(),1521);
+    TS_ASSERT_EQUALS((nimrodInst->getDetector(20201001))->getID(),20201001);
+  }
+
   void testExecMARIFromInstrName() {
     LoadInstrument loaderMARI;
     loaderMARI.initialize();
@@ -299,53 +326,6 @@ public:
     TS_ASSERT_DELTA(ptrDet2.getPos().Z(), 3.9211, 0.0001);
   }
 
-  // // Test loading from XML
-  // void testExecFromXML() {
-  //   LoadInstrument loaderXML;
-  //   loaderXML.initialize();
-  //   loaderXML.setChild(true);
-  //
-  //   // create a workspace with some sample data
-  //   MatrixWorkspace_sptr ws2D =
-  //       DataObjects::create<Workspace2D>(1, HistogramData::Points(1));
-  //
-  //
-  //   const std::string instrumentXML =
-  //   Kernel::Strings::loadFile(Kernel::ConfigService::Instance().getFullPath("REFL_Definition.xml"));
-  //   loaderMARI.setPropertyValue("InstrumentName", instrName);
-  //   loaderMARI.setProperty("RewriteSpectraMap", OptionalBool(true));
-  //   loaderMARI.setProperty("Workspace", ws2D);
-  //
-  //   loaderMARI.execute();
-  //   TS_ASSERT(loaderMARI.isExecuted());
-  //
-  //   std::string result = loaderMARI.getPropertyValue("Filename");
-  //   const std::string::size_type stripPath = result.find_last_of("\\/");
-  //   result = result.substr(stripPath + 1, result.size());
-  //   TS_ASSERT_EQUALS(result, "MARI_Definition.xml");
-  //
-  //   auto &componentInfo = ws2D->componentInfo();
-  //   auto &detectorInfo = ws2D->detectorInfo();
-  //   TS_ASSERT_EQUALS(componentInfo.name(componentInfo.root()), "MARI");
-  //   TS_ASSERT_EQUALS(detectorInfo.size(), 921);
-  //   TS_ASSERT_EQUALS(1, detectorInfo.detectorIDs()[0]);
-  //   TS_ASSERT_EQUALS(4816, detectorInfo.detectorIDs()[920]);
-  //
-  //   const auto &ptrDet1 = detectorInfo.detector(detectorInfo.indexOf(1));
-  //   TS_ASSERT_EQUALS(ptrDet1.getName(), "monitor");
-  //   TS_ASSERT_EQUALS(ptrDet1.getID(), 1);
-  //   TS_ASSERT_DELTA(ptrDet1.getPos().X(), 0.0000, 0.0001);
-  //   TS_ASSERT_DELTA(ptrDet1.getPos().Y(), 0.0000, 0.0001);
-  //   TS_ASSERT_DELTA(ptrDet1.getPos().Z(), -4.7390, 0.0001);
-  //
-  //   const auto &ptrDet2 = detectorInfo.detector(detectorInfo.indexOf(4816));
-  //   TS_ASSERT_EQUALS(ptrDet2.getName(), "tall He3 element");
-  //   TS_ASSERT_EQUALS(ptrDet2.getID(), 4816);
-  //   TS_ASSERT_DELTA(ptrDet2.getPos().X(), 0.6330, 0.0001);
-  //   TS_ASSERT_DELTA(ptrDet2.getPos().Y(), 0.6330, 0.0001);
-  //   TS_ASSERT_DELTA(ptrDet2.getPos().Z(), 3.9211, 0.0001);
-  // }
-
   /// Common initialisation for Nexus loading tests
   MatrixWorkspace_sptr doLoadNexus(const std::string filename) {
     LoadInstrument nexusLoader;
@@ -429,6 +409,23 @@ public:
     TS_ASSERT_EQUALS(1, detectorInfo.detectorIDs()[1]);
   }
 
+  /// Test the Nexus geometry loader from LOKI file
+  void testExecNexusLOKIandRetrieveFromIDS() {
+    // Make sure the IDS is empty
+    InstrumentDataServiceImpl &IDS = InstrumentDataService::Instance();
+    IDS.clear();
+    MatrixWorkspace_sptr outputWs = doLoadNexus("LOKI_Definition.hdf5");
+    TS_ASSERT_EQUALS(IDS.size(), 1);
+    if (IDS.size() != 1)
+      return;
+    // Retrieve the instrument from the InstrumentDataService
+    Instrument_const_sptr lokiInst = IDS.getObjects()[0];
+    TS_ASSERT_EQUALS(lokiInst->getName(), "LOKI");
+    TS_ASSERT_EQUALS(lokiInst->getNumberDetectors(),8000);
+    TS_ASSERT_EQUALS((lokiInst->getDetector(1001))->getID(),1001);
+    TS_ASSERT_EQUALS((lokiInst->getDetector(7777))->getID(),7777);
+  }
+
   void testExecHRP2() {
     // Test Parameter file in instrument folder is used by an IDF file not in
     // the instrument folder
diff --git a/Framework/NexusGeometry/inc/MantidNexusGeometry/NexusGeometryParser.h b/Framework/NexusGeometry/inc/MantidNexusGeometry/NexusGeometryParser.h
index 29666462225a27448584b66d348b56419523d198..8676f38c21d6ab1a485d1e384932c8c9e955edaf 100644
--- a/Framework/NexusGeometry/inc/MantidNexusGeometry/NexusGeometryParser.h
+++ b/Framework/NexusGeometry/inc/MantidNexusGeometry/NexusGeometryParser.h
@@ -22,6 +22,8 @@ namespace NexusGeometry {
 namespace NexusGeometryParser {
 MANTID_NEXUSGEOMETRY_DLL std::unique_ptr<const Mantid::Geometry::Instrument>
 createInstrument(const std::string &fileName);
+MANTID_NEXUSGEOMETRY_DLL std::string getMangledName(const std::string &fileName,
+    const std::string &instName);
 } // namespace NexusGeometryParser
 } // namespace NexusGeometry
 } // namespace Mantid
diff --git a/Framework/NexusGeometry/src/NexusGeometryParser.cpp b/Framework/NexusGeometry/src/NexusGeometryParser.cpp
index 407a648ff4f387584c4a99c4e2dd1680191deab5..199d483f9d35ad9e0899e8bf388e411713012187 100644
--- a/Framework/NexusGeometry/src/NexusGeometryParser.cpp
+++ b/Framework/NexusGeometry/src/NexusGeometryParser.cpp
@@ -10,6 +10,7 @@
 #include "MantidGeometry/Objects/ShapeFactory.h"
 #include "MantidGeometry/Rendering/GeometryHandler.h"
 #include "MantidGeometry/Rendering/ShapeInfo.h"
+#include "MantidKernel/ChecksumHelper.h"
 #include "MantidKernel/EigenConversionHelpers.h"
 #include "MantidKernel/make_unique.h"
 #include "MantidNexusGeometry/InstrumentBuilder.h"
@@ -672,5 +673,16 @@ NexusGeometryParser::createInstrument(const std::string &fileName) {
   auto rootGroup = file.openGroup("/");
   return extractInstrument(file, rootGroup);
 }
+
+// Create a unique instrument name from Nexus file
+std::string NexusGeometryParser::getMangledName(const std::string &fileName,
+    const std::string &instName) {
+  std::string mangledName = instName;
+  if (!fileName.empty()) {
+    std::string checksum = Mantid::Kernel::ChecksumHelper::sha1FromFile(fileName, false);
+    mangledName += checksum;
+  }
+  return mangledName;
+}
 } // namespace NexusGeometry
 } // namespace Mantid