diff --git a/Framework/API/inc/MantidAPI/ExperimentInfo.h b/Framework/API/inc/MantidAPI/ExperimentInfo.h index c3946648a93234d65880d20468f1d7a1f3ddcfe0..8964b807e404b40300c65ad6e5367651f8038e2a 100644 --- a/Framework/API/inc/MantidAPI/ExperimentInfo.h +++ b/Framework/API/inc/MantidAPI/ExperimentInfo.h @@ -118,7 +118,7 @@ public: void saveExperimentInfoNexus(::NeXus::File *file) const; /// Saves this experiment description to the open NeXus file void saveExperimentInfoNexus(::NeXus::File *file, bool saveInstrument, - bool saveSample, bool saveLogs) const; + bool saveSample, bool saveLogs, bool saveLegacyInstrument=true) const; /// Loads an experiment description from the open NeXus file void loadExperimentInfoNexus(const std::string &nxFilename, ::NeXus::File *file, std::string ¶meterStr); diff --git a/Framework/API/src/ExperimentInfo.cpp b/Framework/API/src/ExperimentInfo.cpp index f983d0958a3b85382d24f2a41d96f8bb31bbb865..70254c848ab9d2faecea502cd8f278bf5022e053 100644 --- a/Framework/API/src/ExperimentInfo.cpp +++ b/Framework/API/src/ExperimentInfo.cpp @@ -1149,9 +1149,12 @@ void ExperimentInfo::invalidateAllSpectrumDefinitions() { /** Save the object to an open NeXus file. * @param file :: open NeXus file */ -void ExperimentInfo::saveExperimentInfoNexus(::NeXus::File *file) const { +void ExperimentInfo::saveExperimentInfoNexus(::NeXus::File *file, + bool saveLegacyInstrument) const { Instrument_const_sptr instrument = getInstrument(); - instrument->saveNexus(file, "instrument"); + if (saveLegacyInstrument) { + instrument->saveNexus(file, "instrument"); + } sample().saveNexus(file, "sample"); run().saveNexus(file, "logs"); } diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadNexusProcessed.h b/Framework/DataHandling/inc/MantidDataHandling/LoadNexusProcessed.h index ae7d384249179271e0ffad423c1962c66a66b666..7c7a455bebd31144a39a26fd5b42001c4d53aba8 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadNexusProcessed.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadNexusProcessed.h @@ -97,7 +97,8 @@ private: API::Workspace_sptr loadEntry(Mantid::NeXus::NXRoot &root, const std::string &entry_name, const double &progressStart, - const double &progressRange); + const double &progressRange, + const std::string &filename); API::Workspace_sptr loadTableEntry(Mantid::NeXus::NXEntry &entry); diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveNexusESS.h b/Framework/DataHandling/inc/MantidDataHandling/SaveNexusESS.h index 7fd155689a55240601833b2f46dcd1200c8ccd0e..9d33a93308064903d96dd3852993be12b5cc4083 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveNexusESS.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveNexusESS.h @@ -35,6 +35,7 @@ protected: private: void saveNexusGeometry(const Mantid::API::MatrixWorkspace &ws, const std::string &filename) override; + virtual bool saveLegacyInstrument() override; void init() override; void exec() override; }; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveNexusProcessed.h b/Framework/DataHandling/inc/MantidDataHandling/SaveNexusProcessed.h index aa8469b93def4b3332658b1c0bb10a655510b490..53ecc2abc315af2eb9bfb5294098c04d29bddc88 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveNexusProcessed.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveNexusProcessed.h @@ -63,14 +63,16 @@ public: const std::vector<int> &wsIndices, const ::NeXus::NXcompression compression = ::NeXus::LZW) const; -protected: - /// Override process groups - bool processGroups() override; - virtual void saveNexusGeometry(const Mantid::API::MatrixWorkspace &, const std::string &){ /* Do nothing by default */}; + virtual bool saveLegacyInstrument() { return true; } + +protected: + /// Override process groups + bool processGroups() override; + /// Overwrites Algorithm method. void init() override; /// Overwrites Algorithm method diff --git a/Framework/DataHandling/src/LoadNexusProcessed.cpp b/Framework/DataHandling/src/LoadNexusProcessed.cpp index 4e474279b7ee0ef28c557f4344ea2ff21bcdb945..043ff5648f06dae0c5a19d556df311c1993f5b58 100644 --- a/Framework/DataHandling/src/LoadNexusProcessed.cpp +++ b/Framework/DataHandling/src/LoadNexusProcessed.cpp @@ -32,11 +32,14 @@ #include "MantidKernel/UnitFactory.h" #include "MantidNexus/NexusClasses.h" #include "MantidNexus/NexusFileIO.h" +#include "MantidNexusGeometry/AbstractLogger.h" +#include "MantidNexusGeometry/NexusGeometryParser.h" #include <boost/regex.hpp> #include <boost/shared_array.hpp> #include <boost/shared_ptr.hpp> +#include <H5Cpp.h> #include <nexus/NeXusException.hpp> #include <map> @@ -374,7 +377,8 @@ void LoadNexusProcessed::exec() { progress(0, "Opening file..."); // Throws an approriate exception if there is a problem with file access - NXRoot root(getPropertyValue("Filename")); + const std::string filename = getPropertyValue("Filename"); + NXRoot root(filename); // "Open" the same file but with the C++ interface m_cppFile = new ::NeXus::File(root.m_fileID); @@ -406,7 +410,7 @@ void LoadNexusProcessed::exec() { // Take the first real workspace obtainable. We need it even if loading // groups. - API::Workspace_sptr tempWS = loadEntry(root, targetEntryName, 0, 1); + API::Workspace_sptr tempWS = loadEntry(root, targetEntryName, 0, 1, filename); if (nWorkspaceEntries == 1 || !bDefaultEntryNumber) { // We have what we need. @@ -488,7 +492,7 @@ void LoadNexusProcessed::exec() { local_workspace = loadEntry(root, basename + indexStr, static_cast<double>(p - 1) / nWorkspaceEntries_d, - 1. / nWorkspaceEntries_d); + 1. / nWorkspaceEntries_d, filename); } declareProperty(std::make_unique<WorkspaceProperty<API::Workspace>>( @@ -1434,12 +1438,14 @@ API::MatrixWorkspace_sptr LoadNexusProcessed::loadNonEventEntry( * for this entry * @param progressRange :: The percentage range that the progress reporting * should cover + * @param filename :: name of loaded File * @returns A 2D workspace containing the loaded data */ API::Workspace_sptr LoadNexusProcessed::loadEntry(NXRoot &root, const std::string &entry_name, const double &progressStart, - const double &progressRange) { + const double &progressRange, + const std::string &filename) { progress(progressStart, "Opening entry " + entry_name + "..."); NXEntry mtd_entry = root.openEntry(entry_name); @@ -1585,6 +1591,17 @@ API::Workspace_sptr LoadNexusProcessed::loadEntry(NXRoot &root, g_log.warning(e.what()); g_log.warning("Try running LoadInstrument Algorithm on the Workspace to " "update the geometry"); + try { + using namespace Mantid::NexusGeometry; + auto instrument = NexusGeometry::NexusGeometryParser::createInstrument( + filename, NexusGeometry::makeLogger(&g_log)); + local_workspace->setInstrument( + Geometry::Instrument_const_sptr(std::move(instrument))); + } catch (std::exception &e) { + g_log.warning(e.what()); + } catch (H5::Exception &e) { + g_log.warning(e.getDetailMsg()); + } } // Now assign the spectra-detector map diff --git a/Framework/DataHandling/src/SaveNexusESS.cpp b/Framework/DataHandling/src/SaveNexusESS.cpp index ab9e2b68964bcf42028afe0b69fae1ca088b6630..47af11920b9725b842d6b2e69d4a725920fd4c7e 100644 --- a/Framework/DataHandling/src/SaveNexusESS.cpp +++ b/Framework/DataHandling/src/SaveNexusESS.cpp @@ -52,7 +52,7 @@ void SaveNexusESS::saveNexusGeometry(const Mantid::API::MatrixWorkspace &ws, NexusGeometry::LogAdapter<Kernel::Logger> adapter(&g_log); NexusGeometry::NexusGeometrySave::saveInstrument( ws.componentInfo(), ws.detectorInfo(), filename, "mantid_workspace_1", - adapter, false); + adapter, true); } catch (std::exception &e) { g_log.error(std::string(e.what()) + " Nexus Geometry may be absent or incomplete " @@ -64,6 +64,13 @@ void SaveNexusESS::saveNexusGeometry(const Mantid::API::MatrixWorkspace &ws, } } +bool SaveNexusESS::saveLegacyInstrument() { + /*A hard No on this one. Mantids's current NXDetector, NXMonitor ... types do + * not have information needed for loading and just cause down-stream + * problems. Best not to save them in the first place.*/ + return false; +} + //---------------------------------------------------------------------------------------------- /** Initialize the algorithm's properties. */ diff --git a/Framework/DataHandling/src/SaveNexusProcessed.cpp b/Framework/DataHandling/src/SaveNexusProcessed.cpp index 3377de9ac7a8b24d86693c3ef83f9de4f566c911..a9a4d403f032e454706cf0d43226966653090540 100644 --- a/Framework/DataHandling/src/SaveNexusProcessed.cpp +++ b/Framework/DataHandling/src/SaveNexusProcessed.cpp @@ -240,7 +240,7 @@ bool SaveNexusProcessed::doExec( // write instrument data, if present and writer enabled if (matrixWorkspace) { // Save the instrument names, ParameterMap, sample, run - matrixWorkspace->saveExperimentInfoNexus(&cppFile); + matrixWorkspace->saveExperimentInfoNexus(&cppFile, saveLegacyInstrument()); prog_init.reportIncrement(1, "Writing sample and instrument"); // check if all X() are in fact the same array @@ -268,14 +268,18 @@ bool SaveNexusProcessed::doExec( workspaceTypeGroupName.c_str(), true); } - cppFile.openGroup("instrument", "NXinstrument"); - cppFile.makeGroup("detector", "NXdetector", true); - cppFile.putAttr("version", 1); - saveSpectraDetectorMapNexus(*matrixWorkspace, &cppFile, indices, - ::NeXus::LZW); - saveSpectrumNumbersNexus(*matrixWorkspace, &cppFile, indices, ::NeXus::LZW); - cppFile.closeGroup(); - cppFile.closeGroup(); + if (saveLegacyInstrument()) { + cppFile.openGroup("instrument", "NXinstrument"); + cppFile.makeGroup("detector", "NXdetector", true); + + cppFile.putAttr("version", 1); + saveSpectraDetectorMapNexus(*matrixWorkspace, &cppFile, indices, + ::NeXus::LZW); + saveSpectrumNumbersNexus(*matrixWorkspace, &cppFile, indices, + ::NeXus::LZW); + cppFile.closeGroup(); + cppFile.closeGroup(); + } } // finish matrix workspace specifics diff --git a/Framework/DataHandling/test/SaveNexusESSTest.h b/Framework/DataHandling/test/SaveNexusESSTest.h index 7a1fb570c0efa10ad194f0194a4fd442dc849fa2..964173534e35e2bb33136362208d7abba490b7b9 100644 --- a/Framework/DataHandling/test/SaveNexusESSTest.h +++ b/Framework/DataHandling/test/SaveNexusESSTest.h @@ -9,7 +9,9 @@ #include <cxxtest/TestSuite.h> +#include "MantidDataHandling/LoadNexusProcessed.h" #include "MantidDataHandling/SaveNexusESS.h" +#include "MantidDataHandling/SaveNexusProcessed.h" #include "MantidGeometry/Instrument.h" #include "MantidGeometry/Instrument/ComponentInfo.h" #include "MantidGeometry/Instrument/DetectorInfo.h" @@ -19,7 +21,8 @@ #include "MantidTestHelpers/WorkspaceCreationHelper.h" #include <boost/filesystem.hpp> #include <memory> -using Mantid::DataHandling::SaveNexusESS; + +using namespace Mantid::DataHandling; class SaveNexusESSTest : public CxxTest::TestSuite { public: @@ -40,15 +43,15 @@ public: alg.isExecuted(); } - void test_Init() { + void xtest_Init() { SaveNexusESS alg; TS_ASSERT_THROWS_NOTHING(alg.initialize()); TS_ASSERT(alg.isInitialized()) } - void test_exec_instrument_details() { + void test_exec_rectangular_instrument_details() { using namespace Mantid::NexusGeometry; - const ScopedFileHandle fileInfo("test_rectangular.nxs"); + ScopedFileHandle fileInfo("test_rectangular.nxs"); auto ws = WorkspaceCreationHelper::create2DWorkspaceWithRectangularInstrument( 1 /*numBanks*/, 10 /*numPixels*/, 10 /*numBins*/); @@ -73,6 +76,31 @@ public: // Rectangular detector bank. Hence subtranction from output. TS_ASSERT_EQUALS(outCompInfo->size(), inCompInfo.size() - 10); } + + void test_exec_rectangular_data() { + ScopedFileHandle fileInfo("test_rectangular_data.nxs"); + auto wsIn = + WorkspaceCreationHelper::create2DWorkspaceWithRectangularInstrument( + 1 /*numBanks*/, 10 /*numPixels*/, 12 /*numBins*/); + + do_execute(fileInfo.fullPath(), wsIn); + + LoadNexusProcessed loader; + loader.setChild(true); + loader.setRethrows(true); + loader.initialize(); + loader.setProperty("Filename", fileInfo.fullPath()); + loader.setPropertyValue("OutputWorkspace", "dummy"); + loader.execute(); + + Mantid::API::Workspace_sptr wsOut = loader.getProperty("OutputWorkspace"); + auto matrixWSOut = + boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(wsOut); + + TS_ASSERT_EQUALS(matrixWSOut->blocksize(), 12); + TS_ASSERT_EQUALS(matrixWSOut->getNumberHistograms(), 10 * 10); + TS_ASSERT(matrixWSOut->detectorInfo().isEquivalent(wsIn->detectorInfo())); + } }; #endif /* MANTID_DATAHANDLING_SAVENEXUSESSTEST_H_ */ diff --git a/Framework/TestHelpers/inc/MantidTestHelpers/FileResource.h b/Framework/TestHelpers/inc/MantidTestHelpers/FileResource.h index c5b0bb68f8007623127c379376cc04fc9ebff95e..f2939d2adf43b8fed4b8ea9b5e857cbd0acae497 100644 --- a/Framework/TestHelpers/inc/MantidTestHelpers/FileResource.h +++ b/Framework/TestHelpers/inc/MantidTestHelpers/FileResource.h @@ -17,12 +17,14 @@ #define MANTID_NEXUSGEOMETRY_FILERESOURCE_H_ #include <boost/filesystem.hpp> +#include <iostream> #include <string> class ScopedFileHandle { public: - ScopedFileHandle(const std::string &fileName) { + ScopedFileHandle(const std::string &fileName, bool debugMode = false) + : m_debugMode(debugMode) { const auto temp_dir = boost::filesystem::temp_directory_path(); auto temp_full_path = temp_dir; @@ -41,17 +43,23 @@ public: } } + void setDebugMode(bool mode) { m_debugMode = mode; } std::string fullPath() const { return m_full_path.generic_string(); } ~ScopedFileHandle() { // file is removed at end of file handle's lifetime if (boost::filesystem::is_regular_file(m_full_path)) { - boost::filesystem::remove(m_full_path); + if (!m_debugMode) + boost::filesystem::remove(m_full_path); + else + std::cout << "Debug file at: " << m_full_path << " not removed. " + << std::endl; } } private: + bool m_debugMode; boost::filesystem::path m_full_path; // full path to file // prevent heap allocation for ScopedFileHandle