diff --git a/Framework/DataHandling/test/CMakeLists.txt b/Framework/DataHandling/test/CMakeLists.txt index 069949d50b8b0ccdb96e47bb1d528ba4040d2077..75f98634a22221d34ffad2469c2c323e8ec7fb05 100644 --- a/Framework/DataHandling/test/CMakeLists.txt +++ b/Framework/DataHandling/test/CMakeLists.txt @@ -17,7 +17,8 @@ if(CXXTEST_FOUND) ../../TestHelpers/src/NexusTestHelper.cpp ../../TestHelpers/src/ONCatHelper.cpp ../../TestHelpers/src/ParallelRunner.cpp - NXcanSASTestHelper.cpp) + NXcanSASTestHelper.cpp + ../../TestHelpers/src/FileResource.cpp) cxxtest_add_test(DataHandlingTest ${TEST_FILES}) target_include_directories(DataHandlingTest SYSTEM diff --git a/Framework/DataHandling/test/LoadNexusProcessed2Test.h b/Framework/DataHandling/test/LoadNexusProcessed2Test.h index a5c0ebaac09d013eb4f6e37e214322f0b85a18cc..8321b8e653bb388336ec7bc244c61e86891842a2 100644 --- a/Framework/DataHandling/test/LoadNexusProcessed2Test.h +++ b/Framework/DataHandling/test/LoadNexusProcessed2Test.h @@ -100,7 +100,7 @@ public: using namespace Mantid::HistogramData; - ScopedFileHandle fileInfo("test_ess_instrument.nxs"); + FileResource fileInfo("test_ess_instrument.nxs"); auto wsIn = test_utility::make_workspace("V20_4-tubes_90deg_Definition_v01.xml"); @@ -123,7 +123,7 @@ public: void test_reading_mappings() { using Mantid::SpectrumDefinition; using namespace Mantid::Indexing; - ScopedFileHandle fileInfo("test_no_spectra_mapping.nxs"); + FileResource fileInfo("test_no_spectra_mapping.nxs"); auto wsIn = WorkspaceCreationHelper::create2DWorkspaceWithRectangularInstrument( 2 /*numBanks*/, 10 /*numPixels*/, 12 /*numBins*/); @@ -172,7 +172,7 @@ public: void test_demonstrate_old_loader_incompatible() { - ScopedFileHandle fileInfo("test_demo_file_for_incompatible.nxs"); + FileResource fileInfo("test_demo_file_for_incompatible.nxs"); auto wsIn = test_utility::make_workspace("V20_4-tubes_90deg_Definition_v01.xml"); diff --git a/Framework/DataHandling/test/SaveNexusESSTest.h b/Framework/DataHandling/test/SaveNexusESSTest.h index a9421a9831ecda5524eb79e8b40c4234d120bdb4..b744739f9d1d38d35990ecc6e74170cf16fa3456 100644 --- a/Framework/DataHandling/test/SaveNexusESSTest.h +++ b/Framework/DataHandling/test/SaveNexusESSTest.h @@ -97,7 +97,7 @@ public: void test_exec_rectangular_instrument_details() { using namespace Mantid::NexusGeometry; - ScopedFileHandle fileInfo("test_rectangular_instrument.nxs"); + FileResource fileInfo("test_rectangular_instrument.nxs"); auto ws = WorkspaceCreationHelper::create2DWorkspaceWithRectangularInstrument( 1 /*numBanks*/, 10 /*numPixels*/, 10 /*numBins*/); @@ -124,7 +124,7 @@ public: } void test_exec_rectangular_data() { - ScopedFileHandle fileInfo("test_rectangular_data.nxs"); + FileResource fileInfo("test_rectangular_data.nxs"); auto wsIn = WorkspaceCreationHelper::create2DWorkspaceWithRectangularInstrument( 1 /*numBanks*/, 10 /*numPixels*/, 12 /*numBins*/); @@ -142,7 +142,7 @@ public: using namespace Mantid::HistogramData; - ScopedFileHandle fileInfo("test_ess_instrument.nxs"); + FileResource fileInfo("test_ess_instrument.nxs"); auto wsIn = test_utility::from_instrument_file( "V20_4-tubes_90deg_Definition_v01.xml"); @@ -165,7 +165,7 @@ public: void test_demonstrate_spectra_detector_map_saved() { using namespace Mantid::Indexing; - ScopedFileHandle fileInfo("test_no_spectra_mapping.nxs"); + FileResource fileInfo("test_no_spectra_mapping.nxs"); auto wsIn = WorkspaceCreationHelper::create2DWorkspaceWithRectangularInstrument( 2 /*numBanks*/, 10 /*numPixels*/, 12 /*numBins*/); @@ -211,7 +211,7 @@ public: // This is testing the core routine, but we put it here and not in // NexusGeometrySave because we need access to WorkspaceCreationHelpers for // this. - ScopedFileHandle fileResource("test_with_full_workspace.hdf5"); + FileResource fileResource("test_with_full_workspace.hdf5"); std::string destinationFile = fileResource.fullPath(); // auto ws = WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument( // 10 /*histograms*/, 100 /*bins*/); @@ -225,8 +225,7 @@ public: } void test_regression_iris() { - ScopedFileHandle handle( - "test_regression_iris.nxs"); // IRIS has single monitors + FileResource handle("test_regression_iris.nxs"); // IRIS has single monitors auto iris = test_utility::from_instrument_file2("IRIS"); do_execute(handle.fullPath(), iris); auto iris_reloaded = test_utility::reload(handle.fullPath()); diff --git a/Framework/DataHandling/test/SaveNexusGeometryTest.h b/Framework/DataHandling/test/SaveNexusGeometryTest.h index c9dd2a4203b96eaaa460d22021df227f644c8a8b..039b92e5d2d77927cfa6dcafa41be60d6484c769 100644 --- a/Framework/DataHandling/test/SaveNexusGeometryTest.h +++ b/Framework/DataHandling/test/SaveNexusGeometryTest.h @@ -39,7 +39,7 @@ public: void test_exec() { - ScopedFileHandle fileResource("algorithm_test_file.hdf5"); + FileResource fileResource("algorithm_test_file.hdf5"); auto destinationFile = fileResource.fullPath(); // Create test input if necessary Mantid::API::IEventWorkspace_sptr inputWS = @@ -67,7 +67,7 @@ public: void test_execution_succesful_when_no_h5_root_provided_and_default_root_is_used() { - ScopedFileHandle fileResource("algorithm_no_h5_root_file.hdf5"); + FileResource fileResource("algorithm_no_h5_root_file.hdf5"); auto destinationFile = fileResource.fullPath(); // Create test input if necessary Mantid::API::IEventWorkspace_sptr inputWS = @@ -97,7 +97,7 @@ public: into the Input workspace property. */ - ScopedFileHandle fileResource( + FileResource fileResource( "algorithm_no_instrument_in_workspace_provided_test_file.hdf5"); auto destinationFile = fileResource.fullPath(); // Create test input if necessary @@ -134,7 +134,7 @@ public: when invalid file extension is passed into fileName property. */ - ScopedFileHandle fileResource( + FileResource fileResource( "algorithm_invalid_extension_provided_test_file.txt"); auto destinationFile = fileResource.fullPath(); // Create test workspace @@ -163,7 +163,7 @@ public: void test_eight_pack() { - ScopedFileHandle fileResource("eight_pack.hdf5"); + FileResource fileResource("eight_pack.hdf5"); auto destinationFile = fileResource.fullPath(); Mantid::DataHandling::LoadEmptyInstrument alg; @@ -193,7 +193,7 @@ public: exception. */ - ScopedFileHandle fileResource("duplicate_names_test.hdf5"); + FileResource fileResource("duplicate_names_test.hdf5"); auto destinationFile = fileResource.fullPath(); Mantid::DataHandling::LoadEmptyInstrument loader; diff --git a/Framework/NexusGeometry/src/NexusGeometrySave.cpp b/Framework/NexusGeometry/src/NexusGeometrySave.cpp index cb4962928ee96a69741b04a2b3b3e9ddf0152b67..a1e266d2f94c7282e6ef3746e5c29ef572e8b3c8 100644 --- a/Framework/NexusGeometry/src/NexusGeometrySave.cpp +++ b/Framework/NexusGeometry/src/NexusGeometrySave.cpp @@ -5,7 +5,8 @@ // & Institut Laue - Langevin // SPDX - License - Identifier: GPL - 3.0 + -/** NexusGeometrySave::saveInstrument : +/* + * NexusGeometrySave::saveInstrument : * Save methods to save geometry and metadata from memory * to disk in Nexus file format for Instrument 2.0. * @@ -77,8 +78,8 @@ inline H5::Group tryCreateGroup(const H5::Group &parentGroup, } return parentGroup.createGroup(childGroupName); } - -/** Function toStdVector (Overloaded). Store data in Mantid::Kernel::V3D vector +/* + * Function toStdVector (Overloaded). Store data in Mantid::Kernel::V3D vector * into std::vector<double> vector. Used by saveInstrument to write array-type * datasets to file. * @@ -95,7 +96,8 @@ std::vector<double> toStdVector(const V3D &data) { return stdVector; } -/** Function toStdVector (Overloaded). Store data in Eigen::Vector3d vector +/* + * Function toStdVector (Overloaded). Store data in Eigen::Vector3d vector * into std::vector<double> vector. Used by saveInstrument to write array-type * datasets to file. * @@ -107,7 +109,8 @@ std::vector<double> toStdVector(const Eigen::Vector3d &data) { return toStdVector(Kernel::toV3D(data)); } -/** Function: isApproxZero. returns true if all values in an variable-sized +/* + * Function: isApproxZero. returns true if all values in an variable-sized * std-vector container evaluate to zero with a given level of precision. Used * by SaveInstrument methods to determine whether or not to write a dataset to * file. @@ -134,7 +137,8 @@ bool isApproxZero(const Eigen::Quaterniond &data, const double &precision) { return data.isApprox(Eigen::Quaterniond(1, 0, 0, 0), precision); } -/** Function: strTypeOfSize +/* + * Function: strTypeOfSize * Produces the HDF StrType of size equal to that of the * input string. * @@ -146,7 +150,8 @@ H5::StrType strTypeOfSize(const std::string &str) { return stringType; } -/** Function: writeStrDataset +/* + * Function: writeStrDataset * writes a StrType HDF dataset and dataset value to a HDF group. * * @param grp : HDF group object. @@ -164,7 +169,8 @@ void writeStrDataset(H5::Group &grp, const std::string &dSetName, } } -/** Function: writeStrAttribute +/* + * Function: writeStrAttribute * writes a StrType HDF attribute and attribute value to a HDF group. * * @param grp : HDF group object. @@ -182,7 +188,8 @@ void writeStrAttribute(H5::Group &grp, const std::string &attrName, } } -/** Function: writeStrAttribute +/* + * Function: writeStrAttribute * Overload function which writes a StrType HDF attribute and attribute value * to a HDF dataset. * @@ -200,19 +207,11 @@ void writeStrAttribute(H5::DataSet &dSet, const std::string &attrName, } } -// function to create a simple sub-group that has a nexus class attribute, -// inside a parent group. -inline H5::Group simpleNXSubGroup(H5::Group &parent, const std::string &name, - const std::string &nexusAttribute) { - H5::Group subGroup = tryCreateGroup(parent, name); - writeStrAttribute(subGroup, NX_CLASS, nexusAttribute); - return subGroup; -} - -/** Function: writeXYZPixeloffset +/* + * Function: writeXYZPixeloffset * write the x, y, and z offset of the pixels from the parent detector bank as - * HDF5 datasets to HDF5 group. If all of the pixel offsets in either x, y, or - * z are approximately zero, skips writing that dataset to file. + * HDF5 datasets to HDF5 group. If all of the pixel offsets in either x, y, or z + * are approximately zero, skips writing that dataset to file. * @param grp : HDF5 parent group * @param compInfo : Component Info Instrument cache * @param idx : index of bank in cache. @@ -342,7 +341,8 @@ void writeSpectra(H5::Group &grp, const SpectraMappings &mappings) { write1DIntDataset(grp, SPECTRA_NUMBERS, mappings.spectra_ids); } -/** Function: writeNXMonitorNumber +/* + * Function: writeNXMonitorNumber * For use with NXmonitor group. write 'detector_id's of an NXmonitor, which * is a specific type of pixel, to its group. * @@ -378,13 +378,13 @@ void writeNXMonitorNumber(H5::Group &grp, const int monitorID) { } } -/** Function: writeLocation +/* + * Function: writeLocation * For use with NXdetector group. Writes absolute position of detector bank to * dataset and metadata as attributes. * * @param grp : NXdetector group : (HDF group) - * @param position : Eigen::Vector3d position of component in instrument - * cache. + * @param position : Eigen::Vector3d position of component in instrument cache. */ inline void writeLocation(H5::Group &grp, const Eigen::Vector3d &position) { @@ -445,7 +445,8 @@ inline void writeLocation(H5::Group &grp, const Eigen::Vector3d &position) { dependsOn.write(strSize, dependency); } -/** Function: writeOrientation +/* + * Function: writeOrientation * For use with NXdetector group. Writes the absolute rotation of detector * bank to dataset and metadata as attributes. * @@ -649,38 +650,6 @@ class NexusGeometrySaveImpl { public: enum class Mode { Trunc, Append }; -private: - const Mode m_mode; - - H5::Group openOrCreateGroup(const H5::Group &parent, const std::string &name, - const std::string &classType) { - - if (m_mode == Mode::Append) { - // Find by class and by name - auto results = utilities::findGroups(parent, classType); - for (auto &result : results) { - auto resultName = H5_OBJ_NAME(result); - // resultName gives full path. We match the last name on the path - if (std::regex_match(resultName, std::regex(".*/" + name + "$"))) { - return result; - } - } - } - // We can't find it, or we are writing from scratch anyway. We need to - // verify no-duplicates - return tryCreateGroup(parent, name); - } - - // function to create a simple sub-group that has a nexus class attribute, - // inside a parent group. - H5::Group simpleNXSubGroup(H5::Group &parent, const std::string &name, - const std::string &nexusAttribute) { - H5::Group subGroup = openOrCreateGroup(parent, name, nexusAttribute); - writeStrAttribute(subGroup, NX_CLASS, nexusAttribute); - return subGroup; - } - -public: explicit NexusGeometrySaveImpl(Mode mode) : m_mode(mode) {} NexusGeometrySaveImpl(const NexusGeometrySaveImpl &) = delete; // No intention to suport copies @@ -1010,7 +979,37 @@ public: writeDetectorIndex(childGroup, mappings); writeSpectra(childGroup, mappings); } -}; // namespace + +private: + const Mode m_mode; + + H5::Group openOrCreateGroup(const H5::Group &parent, const std::string &name, + const std::string &classType) { + + if (m_mode == Mode::Append) { + // Find by class and by name + auto results = utilities::findGroups(parent, classType); + for (auto &result : results) { + auto resultName = H5_OBJ_NAME(result); + // resultName gives full path. We match the last name on the path + if (std::regex_match(resultName, std::regex(".*/" + name + "$"))) { + return result; + } + } + } + // We can't find it, or we are writing from scratch anyway + return tryCreateGroup(parent, name); + } + + // function to create a simple sub-group that has a nexus class attribute, + // inside a parent group. + H5::Group simpleNXSubGroup(H5::Group &parent, const std::string &name, + const std::string &nexusAttribute) { + H5::Group subGroup = openOrCreateGroup(parent, name, nexusAttribute); + writeStrAttribute(subGroup, NX_CLASS, nexusAttribute); + return subGroup; + } +}; // class NexusGeometrySaveImpl /* * Function: saveInstrument @@ -1064,8 +1063,7 @@ void saveInstrument(const Geometry::ComponentInfo &compInfo, // Looping from highest to lowest component index is critical for (size_t index = compInfo.root() - 1; index >= detInfo.size(); --index) { if (Geometry::ComponentInfoBankHelpers::isSaveableBank(compInfo, index)) { - const bool needed = isDesiredNXDetector(index, saved_indices, compInfo); - if (needed) { + if (isDesiredNXDetector(index, saved_indices, compInfo)) { if (reporter != nullptr) reporter->report(); writer.detector(instrument, compInfo, detIds, index); @@ -1088,10 +1086,11 @@ void saveInstrument(const Geometry::ComponentInfo &compInfo, } // saveInstrument -/* +/** * Function: saveInstrument (overload) - * calls the save methods to write components to file after exception checking. - * Produces a Nexus format file containing the Instrument geometry and metadata. + * calls the save methods to write components to file after exception + * checking. Produces a Nexus format file containing the Instrument geometry + * and metadata. * * @param instrPair : instrument 2.0 object. * @param fullPath : save destination as full path. @@ -1153,6 +1152,7 @@ void saveInstrument(const Mantid::API::MatrixWorkspace &ws, // save NXdetectors auto detToIndexMap = ws.getDetectorIDToWorkspaceIndexMap(true /*throw if multiples*/); + // save NXdetectors std::list<size_t> saved_indices; // Looping from highest to lowest component index is critical for (size_t index = compInfo.root() - 1; index >= detInfo.size(); --index) { @@ -1163,6 +1163,7 @@ void saveInstrument(const Mantid::API::MatrixWorkspace &ws, SpectraMappings mappings = makeMappings(compInfo, detToIndexMap, ws.indexInfo(), ws.spectrumInfo(), detIds, index); + if (reporter != nullptr) reporter->report(); writer.detector(instrument, compInfo, detIds, index, mappings); diff --git a/Framework/NexusGeometry/test/CMakeLists.txt b/Framework/NexusGeometry/test/CMakeLists.txt index 771686ced99382f0837c0f81b168868175ea3c4d..573d6ccc0d9b8e03557af290fe5386f076466fa6 100644 --- a/Framework/NexusGeometry/test/CMakeLists.txt +++ b/Framework/NexusGeometry/test/CMakeLists.txt @@ -8,7 +8,8 @@ if(CXXTEST_FOUND) set(TESTHELPER_SRCS ../../TestHelpers/src/NexusGeometryTestHelpers.cpp ../../TestHelpers/src/JSONGeometryParserTestHelper.cpp - ../../TestHelpers/src/ComponentCreationHelper.cpp) + ../../TestHelpers/src/ComponentCreationHelper.cpp + ../../TestHelpers/src/FileResource.cpp) cxxtest_add_test(NexusGeometryTest ${TEST_FILES}) diff --git a/Framework/NexusGeometry/test/NexusGeometrySaveTest.h b/Framework/NexusGeometry/test/NexusGeometrySaveTest.h index 4ef7c4963529e15b175a46377cdd8c397fd0a995..17d5d26b6c459ac60f957905066b06cc0de932f8 100644 --- a/Framework/NexusGeometry/test/NexusGeometrySaveTest.h +++ b/Framework/NexusGeometry/test/NexusGeometrySaveTest.h @@ -56,7 +56,7 @@ used. void test_providing_invalid_path_throws() { - ScopedFileHandle fileResource("invalid_path_to_file_test_file.hdf5"); + FileResource fileResource("invalid_path_to_file_test_file.hdf5"); const std::string badDestinationPath = "false_directory\\" + fileResource.fullPath(); @@ -77,7 +77,7 @@ used. EXPECT_CALL(progressRep, doReport(testing::_)) .Times(nbanks); // Progress report once for each bank - ScopedFileHandle fileResource("progress_report_test_file.hdf5"); + FileResource fileResource("progress_report_test_file.hdf5"); std::string destinationFile = fileResource.fullPath(); auto instrument = ComponentCreationHelper::createTestInstrumentRectangular2( @@ -92,7 +92,7 @@ used. void test_false_file_extension_throws() { - ScopedFileHandle fileResource("invalid_extension_test_file.abc"); + FileResource fileResource("invalid_extension_test_file.abc"); std::string destinationFile = fileResource.fullPath(); auto instrument = ComponentCreationHelper::createMinimalInstrument( @@ -120,7 +120,7 @@ used. true, false, true); auto instr = Mantid::Geometry::InstrumentVisitor::makeWrappers(*instrument); - ScopedFileHandle fileResource("check_no_sample_throws_test_file.hdf5"); + FileResource fileResource("check_no_sample_throws_test_file.hdf5"); auto destinationFile = fileResource.fullPath(); // instrument cache @@ -155,7 +155,7 @@ used. // instrument cache auto &compInfo = (*instr.first); - ScopedFileHandle fileResource("check_no_source_throws_test_file.hdf5"); + FileResource fileResource("check_no_source_throws_test_file.hdf5"); auto destinationFile = fileResource.fullPath(); TS_ASSERT(compInfo.hasDetectorInfo()); // rule out throw by no detector info @@ -182,7 +182,7 @@ used. V3D(0, 0, -10), V3D(0, 0, 2), V3D(0, 0, 10)); auto instr = Mantid::Geometry::InstrumentVisitor::makeWrappers(*instrument); - ScopedFileHandle fileResource("check_nxsource_group_test_file.hdf5"); + FileResource fileResource("check_nxsource_group_test_file.hdf5"); std::string destinationFile = fileResource.fullPath(); TS_ASSERT_THROWS(NexusGeometrySave::saveInstrument(instr, destinationFile, @@ -218,7 +218,7 @@ used. // has NXclass attribute of NXentry. as required by the Nexus file format. // RAII file resource for test file destination - ScopedFileHandle fileResource("check_nxentry_group_test_file.nxs"); + FileResource fileResource("check_nxentry_group_test_file.nxs"); std::string destinationFile = fileResource.fullPath(); // test instrument @@ -242,7 +242,7 @@ used. // data is saved to a group of NXclass NXinstrument // RAII file resource for test file destination - ScopedFileHandle fileResource("check_nxinstrument_group_test_file.hdf5"); + FileResource fileResource("check_nxinstrument_group_test_file.hdf5"); std::string destinationFile = fileResource.fullPath(); // test instrument with some geometry @@ -269,7 +269,7 @@ used. // compatibility reasons // RAII file resource for test file destination - ScopedFileHandle fileResource("check_instrument_name_test_file.nxs"); + FileResource fileResource("check_instrument_name_test_file.nxs"); auto destinationFile = fileResource.fullPath(); // test instrument @@ -307,12 +307,34 @@ used. NAME, compInfo.name(compInfo.root()), path)); } + void + test_NXclass_without_name_is_assigned_unique_default_name_for_each_group() { + // this test will try to save and unnamed instrument with multiple unnamed + // detector banks, to verify that the unique group names which + // saveInstrument provides for each NXclass do not throw a H5 error due to + // duplication of group names. If any group in the same tree path share the + // same name, HDF5 will throw a group exception. In this test, we expect no + // such exception to throw. + + // RAII file resource for test file destination. + FileResource fileResource("default_group_names_test.hdf5"); + std::string destinationFile = fileResource.fullPath(); + + // unnamed ("") instrument with multiple unnamed detector banks ("") + auto instrument = ComponentCreationHelper::createTestUnnamedRectangular2( + 2 /*number of banks*/, 2); + auto instr = Mantid::Geometry::InstrumentVisitor::makeWrappers(*instrument); + + TS_ASSERT_THROWS_NOTHING(NexusGeometrySave::saveInstrument( + instr, destinationFile, DEFAULT_ROOT_ENTRY_NAME, m_mockLogger)); + } + void test_nxsource_group_exists_and_is_in_nxinstrument_group() { // this test checks that inside of the NXinstrument group, the the source // data is saved to a group of NXclass NXsource // RAII file resource for test file destination. - ScopedFileHandle fileResource("check_nxsource_group_test_file.hdf5"); + FileResource fileResource("check_nxsource_group_test_file.hdf5"); std::string destinationFile = fileResource.fullPath(); // test instrument @@ -336,7 +358,7 @@ used. void test_nxsample_group_exists_and_is_in_nxentry_group() { - ScopedFileHandle fileResource("check_nxsource_group_test_file.hdf5"); + FileResource fileResource("check_nxsource_group_test_file.hdf5"); std::string destinationFile = fileResource.fullPath(); auto instrument = ComponentCreationHelper::createMinimalInstrument( @@ -357,7 +379,7 @@ used. void test_correct_number_of_detectors_saved() { - ScopedFileHandle fileResource("check_num_of_banks_test.hdf5"); + FileResource fileResource("check_num_of_banks_test.hdf5"); std::string destinationFile = fileResource.fullPath(); int banksInInstrument = 3; @@ -407,7 +429,7 @@ Instrument cache. */ // RAII file resource for test file destination - ScopedFileHandle fileResource( + FileResource fileResource( "check_rotation_written_to_nxdetector_test_file.hdf5"); std::string destinationFile = fileResource.fullPath(); @@ -469,7 +491,7 @@ Instrument cache. */ // RAII file resource for test file destination - ScopedFileHandle fileResource( + FileResource fileResource( "check_rotation_written_to_nx_monitor_test_file.hdf5"); std::string destinationFile = fileResource.fullPath(); @@ -526,7 +548,7 @@ Instrument cache. */ // RAII file resource for test file destination - ScopedFileHandle fileResource( + FileResource fileResource( "check_location_written_to_nxsource_test_file.hdf5"); std::string destinationFile = fileResource.fullPath(); @@ -583,7 +605,7 @@ Instrument cache. */ // RAII file resource for test file destination - ScopedFileHandle fileResource( + FileResource fileResource( "check_rotation_written_to_nxsource_test_file.hdf5"); std::string destinationFile = fileResource.fullPath(); @@ -641,7 +663,7 @@ Instrument cache. */ // RAII file resource for test file destination - ScopedFileHandle fileResource("origin_nx_source_location_file_test.hdf5"); + FileResource fileResource("origin_nx_source_location_file_test.hdf5"); std::string destinationFile = fileResource.fullPath(); // prepare geometry for instrument @@ -690,7 +712,7 @@ Instrument cache. const Quat bankRotation(0, V3D(0, 0, 1)); // set (angle) to zero // RAII file resource for test file destination - ScopedFileHandle fileResource("zero_nx_detector_rotation_file_test.hdf5"); + FileResource fileResource("zero_nx_detector_rotation_file_test.hdf5"); std::string destinationFile = fileResource.fullPath(); // test instrument with zero source rotation @@ -729,7 +751,7 @@ Instrument cache. */ // RAII file resource for test file destination - ScopedFileHandle fileResource("zero_nx_monitor_rotation_file_test.hdf5"); + FileResource fileResource("zero_nx_monitor_rotation_file_test.hdf5"); std::string destinationFile = fileResource.fullPath(); V3D someLocation(0.0, 0.0, -5.0); // arbitrary monitor location @@ -772,7 +794,7 @@ Instrument cache. const Quat sourceRotation(0, V3D(0, 0, 1)); // set (angle) to zero // RAII file resource for test file destination - ScopedFileHandle inFileResource("zero_nx_source_rotation_file_test.hdf5"); + FileResource inFileResource("zero_nx_source_rotation_file_test.hdf5"); std::string destinationFile = inFileResource.fullPath(); // test instrument with zero rotation @@ -811,7 +833,7 @@ Instrument cache. */ // create RAII file resource for testing - ScopedFileHandle fileResource("check_pixel_offset_format_test_file.hdf5"); + FileResource fileResource("check_pixel_offset_format_test_file.hdf5"); std::string destinationFile = fileResource.fullPath(); // prepare geometry for instrument @@ -899,7 +921,7 @@ Instrument cache. const V3D sourceLocation(0, 0, 0); // set to zero // create RAII file resource for testing - ScopedFileHandle fileResource("no_location_dependency_test.hdf5"); + FileResource fileResource("no_location_dependency_test.hdf5"); std::string destinationFile = fileResource.fullPath(); // test instrument with location of source at zero @@ -965,7 +987,7 @@ Instrument cache. const Quat sourceRotation(0.0, V3D(0.0, 1.0, 0.0)); // set to zero // create RAII file resource for testing - ScopedFileHandle fileResource("no_orientation_dependency_test.hdf5"); + FileResource fileResource("no_orientation_dependency_test.hdf5"); std::string destinationFile = fileResource.fullPath(); // test instrument with rotation of source of zero @@ -1034,7 +1056,7 @@ Instrument cache. const Quat sourceRotation(45, V3D(0, 1, 0)); // arbitrary non-zero // create RAII file resource for testing - ScopedFileHandle fileResource("both_transformations_dependency_test.hdf5"); + FileResource fileResource("both_transformations_dependency_test.hdf5"); std::string destinationFile = fileResource.fullPath(); // test instrument with non zero rotation and translation @@ -1105,8 +1127,7 @@ Instrument cache. const Quat sourceRotation(0, V3D(0, 1, 0)); // set to zero // create RAII file resource for testing - ScopedFileHandle fileResource( - "neither_transformations_dependency_test.hdf5"); + FileResource fileResource("neither_transformations_dependency_test.hdf5"); std::string destinationFile = fileResource.fullPath(); // test instrument with zero translation and rotation diff --git a/Framework/TestHelpers/inc/MantidTestHelpers/ComponentCreationHelper.h b/Framework/TestHelpers/inc/MantidTestHelpers/ComponentCreationHelper.h index 04cbc70397cfefa44161ca5d4cfd6435c14ee063..95e7393f4cde9abdf1a20718874401038351648e 100644 --- a/Framework/TestHelpers/inc/MantidTestHelpers/ComponentCreationHelper.h +++ b/Framework/TestHelpers/inc/MantidTestHelpers/ComponentCreationHelper.h @@ -216,6 +216,10 @@ Mantid::Geometry::Instrument_sptr createTestInstrumentRectangular2(int num_banks, int pixels, double pixelSpacing = 0.008); +Mantid::Geometry::Instrument_sptr +createTestUnnamedRectangular2(int num_banks, int pixels, + double pixelSpacing = 0.008); + /// Creates a mimimal valid virtual instrument. Mantid::Geometry::Instrument_sptr createMinimalInstrument(const Mantid::Kernel::V3D &sourcePos, diff --git a/Framework/TestHelpers/inc/MantidTestHelpers/FileResource.h b/Framework/TestHelpers/inc/MantidTestHelpers/FileResource.h index f2939d2adf43b8fed4b8ea9b5e857cbd0acae497..0fa8b39909748b9b8211d15847140bf1d2c64f20 100644 --- a/Framework/TestHelpers/inc/MantidTestHelpers/FileResource.h +++ b/Framework/TestHelpers/inc/MantidTestHelpers/FileResource.h @@ -5,8 +5,7 @@ // & Institut Laue - Langevin // SPDX - License - Identifier: GPL - 3.0 + -/* - * RAII: Gives a clean file destination and removes the file when +/** RAII: Gives a clean file destination and removes the file when * handle is out of scope. Must be stack allocated. * * @author Takudzwa Makoni, RAL (UKRI), ISIS @@ -20,48 +19,17 @@ #include <iostream> #include <string> -class ScopedFileHandle { +class FileResource { public: - 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; - // append full path to temp directory to user input file name - temp_full_path /= fileName; - - // Check proposed location and throw std::invalid argument if file does - // not exist. otherwise set m_full_path to location. - - if (boost::filesystem::is_directory(temp_dir)) { - m_full_path = temp_full_path; - - } else { - throw std::invalid_argument("failed to load temp directory: " + - temp_dir.generic_string()); - } - } - - 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)) { - if (!m_debugMode) - boost::filesystem::remove(m_full_path); - else - std::cout << "Debug file at: " << m_full_path << " not removed. " - << std::endl; - } - } + FileResource(const std::string &fileName, bool debugMode = false); + void setDebugMode(bool mode); + std::string fullPath() const; + ~FileResource(); private: bool m_debugMode; boost::filesystem::path m_full_path; // full path to file - // prevent heap allocation for ScopedFileHandle protected: static void *operator new(std::size_t); // prevent heap allocation of scalar. diff --git a/Framework/TestHelpers/src/FileResource.cpp b/Framework/TestHelpers/src/FileResource.cpp new file mode 100644 index 0000000000000000000000000000000000000000..feddc230d1c8a6077cf2fdbfe09c67b0ff6681bb --- /dev/null +++ b/Framework/TestHelpers/src/FileResource.cpp @@ -0,0 +1,47 @@ +// Mantid Repository : https://github.com/mantidproject/mantid +// +// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI, +// NScD Oak Ridge National Laboratory, European Spallation Source +// & Institut Laue - Langevin +// SPDX - License - Identifier: GPL - 3.0 + + +#include "MantidTestHelpers/FileResource.h" +#include <boost/filesystem.hpp> +#include <string> + +FileResource::FileResource(const std::string &fileName, bool debugMode) + : m_debugMode(debugMode) { + + const auto temp_dir = boost::filesystem::temp_directory_path(); + auto temp_full_path = temp_dir; + // append full path to temp directory to user input file name + temp_full_path /= fileName; + + // Check proposed location and throw std::invalid argument if file does + // not exist. otherwise set m_full_path to location. + + if (boost::filesystem::is_directory(temp_dir)) { + m_full_path = temp_full_path; + + } else { + throw std::invalid_argument("failed to load temp directory: " + + temp_dir.generic_string()); + } +} + +void FileResource::setDebugMode(bool mode) { m_debugMode = mode; } +std::string FileResource::fullPath() const { + return m_full_path.generic_string(); +} + +FileResource::~FileResource() { + + // file is removed at end of file handle's lifetime + if (boost::filesystem::is_regular_file(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; + } +}