diff --git a/Framework/DataHandling/src/LoadInstrument.cpp b/Framework/DataHandling/src/LoadInstrument.cpp index f76587344bdf33e2f28d7519e350d3987aa97f8a..dfccb255d8c2ba8e9a8e7ea619b0a55aa3a0cd98 100644 --- a/Framework/DataHandling/src/LoadInstrument.cpp +++ b/Framework/DataHandling/src/LoadInstrument.cpp @@ -19,6 +19,8 @@ #include "MantidKernel/Strings.h" #include "MantidNexusGeometry/NexusGeometryParser.h" +#include <boost/algorithm/string.hpp> + namespace Mantid { namespace DataHandling { @@ -150,8 +152,21 @@ void LoadInstrument::exec() { 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")); + auto definitionRange = boost::ifind_first(instrumentFile, "_Def"); + if (definitionRange) { + // We need to find the position this occurs in the string and we + // can't pass begin() to substr. So take a performance pessimism + // and create a copy which find is guaranteed to find + const std::string foundDefTagCase(definitionRange.begin(), + definitionRange.end()); + instname = instrumentFile.substr(0, instrumentFile.find(foundDefTagCase)); + } else { + g_log.warning("The instrument definition filename does not contain " + "_Definition. Your instrument name may be incorrect"); + instname = instrumentFile; + } // Now that we have a file name, decide whether to use Nexus or IDF loading if (LoadGeometry::isIDF(filename)) { diff --git a/Framework/DataHandling/test/LoadInstrumentTest.h b/Framework/DataHandling/test/LoadInstrumentTest.h index f41aaeb271bac765a60fa76c6953a4dc1f902259..9d5ee1554178420ef31bb59ae1490ec1568ac3f3 100644 --- a/Framework/DataHandling/test/LoadInstrumentTest.h +++ b/Framework/DataHandling/test/LoadInstrumentTest.h @@ -9,6 +9,7 @@ #include "MantidAPI/Axis.h" #include "MantidAPI/ExperimentInfo.h" +#include "MantidAPI/FileFinder.h" #include "MantidAPI/InstrumentDataService.h" #include "MantidAPI/SpectrumInfo.h" #include "MantidDataHandling/LoadInstrument.h" @@ -23,6 +24,9 @@ #include "MantidKernel/OptionalBool.h" #include "MantidKernel/Strings.h" #include "MantidTestHelpers/WorkspaceCreationHelper.h" + +#include <Poco/File.h> +#include <Poco/Path.h> #include <cxxtest/TestSuite.h> #include <string> @@ -46,6 +50,86 @@ public: TS_ASSERT(loader.isInitialized()); } + void testInstNameIsCaseInsensitive() { + LoadInstrument loader; + loader.initialize(); + loader.setChild(true); + + // create a workspace with some sample data + int histogramNumber = 2584; + int timechannels = 100; + MatrixWorkspace_sptr ws2D = DataObjects::create<Workspace2D>( + histogramNumber, HistogramData::Points(timechannels, timechannels)); + + Points timeChannelsVec(timechannels, LinearGenerator(0.0, 100.0)); + // loop to create data + for (int i = 0; i < histogramNumber; i++) { + std::vector<double> v(timechannels); + std::vector<double> e(timechannels); + // timechannels + for (int j = 0; j < timechannels; j++) { + v[j] = (i + j) % 256; + e[j] = (i + j) % 78; + } + // Populate the workspace. + ws2D->setPoints(i, timeChannelsVec); + ws2D->dataY(i) = v; + ws2D->dataE(i) = e; + } + + // We want to test if the spectra mapping changes + TS_ASSERT_EQUALS(ws2D->getSpectrum(0).getSpectrumNo(), 1); + TS_ASSERT_EQUALS(ws2D->getSpectrum(256).getSpectrumNo(), 257); + TS_ASSERT_EQUALS(ws2D->getNumberHistograms(), 2584); + + const auto &fileFinder = Mantid::API::FileFinder::Instance(); + const std::string originalFilePath = + fileFinder.getFullPath("HET_Definition.xml"); + + const std::string tmpDir = Poco::Path::temp(); + auto generateFiles = [&tmpDir, &originalFilePath](const std::string &name) { + Poco::Path tmpFilePath(tmpDir, name); + + Poco::File originalFile(originalFilePath); + originalFile.copyTo(tmpFilePath.toString()); + + Poco::File tmpFile(tmpFilePath); + return tmpFile; + }; + + auto runAlg = [&generateFiles, &loader, &ws2D]( + const std::string &name, const std::string &expected) { + auto fileHandle = generateFiles(name); + const std::string path = fileHandle.path(); + + loader.setPropertyValue("Filename", path); + loader.setProperty("RewriteSpectraMap", OptionalBool(true)); + loader.setProperty("Workspace", ws2D); + + loader.execute(); + TS_ASSERT(loader.isExecuted()); + + fileHandle.remove(); + + MatrixWorkspace_sptr output = loader.getProperty("Workspace"); + const std::string loadedName = output->getInstrument()->getName(); + TS_ASSERT_EQUALS(expected, loadedName); + }; + + const std::string allLowerInstrFilename = "het_definition.xml"; + const std::string mixCaseInstrFilename = "Het_definition.xml"; + const std::string uppercaseInstrFilename = "HET_DEFINITION.xml"; + const std::string normalInstrFilename = "HET_Definition.xml"; + + // Something internal will always convert to lowercase + const std::string expectedName = "het"; + + runAlg(allLowerInstrFilename, expectedName); + runAlg(mixCaseInstrFilename, expectedName); + runAlg(uppercaseInstrFilename, expectedName); + runAlg(normalInstrFilename, expectedName); + } + void testExecHET() { LoadInstrument loader; loader.initialize(); diff --git a/docs/source/release/v4.2.0/framework.rst b/docs/source/release/v4.2.0/framework.rst index dd0a72879211e45749e032e908a00c6beb442a70..8eb0f9656d6452feef0425db079599eb0f3579dc 100644 --- a/docs/source/release/v4.2.0/framework.rst +++ b/docs/source/release/v4.2.0/framework.rst @@ -40,7 +40,8 @@ It is now possible to have MultipleFileProperty configured in such a way, that i Bug Fixes --------- -* ref:`LoadNexusMonitors <algm-LoadNexusMonitors>` bug fix for user provided top-level NXentry name +* ref:`LoadNexusMonitors <algm-LoadNexusMonitors>` bug fix for user provided top-level NXentry name. +* ref:`LoadInstrument <algm-LoadInstrument>` correctly handles IDF files which use all lowercase naming. :ref:`Release 4.2.0 <v4.2.0>`