Skip to content
Snippets Groups Projects
Commit aeb8e567 authored by Simon Heybrock's avatar Simon Heybrock
Browse files

Re #20887. Different method to obtain bank offsets.

This should be more reliable since it does not require specific naming
conventions. However, there does not seem to be a way to ensure that
banks are contiguous based on information available in the Nexus files.
parent 3fc90e72
No related branches found
No related tags found
No related merge requests found
#include "MantidDataHandling/ParallelEventLoader.h" #include "MantidDataHandling/ParallelEventLoader.h"
#include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/EventWorkspace.h"
#include "MantidGeometry/Instrument.h"
#include "MantidGeometry/Instrument/ComponentInfo.h"
#include "MantidGeometry/Instrument/DetectorInfo.h" #include "MantidGeometry/Instrument/DetectorInfo.h"
#include "MantidParallel/IO/EventLoader.h" #include "MantidParallel/IO/EventLoader.h"
#include "MantidTypes/SpectrumDefinition.h"
#include "MantidTypes/Event/TofEvent.h" #include "MantidTypes/Event/TofEvent.h"
namespace Mantid { namespace Mantid {
namespace DataHandling { namespace DataHandling {
std::vector<int32_t> bankOffsets(const API::ExperimentInfo &ws, std::vector<int32_t> bankOffsets(const API::ExperimentInfo &ws,
const std::string &filename,
const std::string &groupName,
const std::vector<std::string> &bankNames) { const std::vector<std::string> &bankNames) {
const auto instrument = ws.getInstrument(); // Build detector ID to spectrum index map. Used only in LoadEventNexus so we
const auto &compInfo = ws.componentInfo(); // know there is a 1:1 mapping, omitting monitors.
const auto &detInfo = ws.detectorInfo(); const auto &detInfo = ws.detectorInfo();
const auto &detIDs = detInfo.detectorIDs(); const auto &detIDs = detInfo.detectorIDs();
std::unordered_map<detid_t, int32_t> map;
int32_t spectrumIndex{0}; // *global* index
for (size_t i = 0; i < detInfo.size(); ++i)
if (!detInfo.isMonitor(i))
map[detIDs[i]] = spectrumIndex++;
// Monitors are not loaded by LoadEventNexus, so we have to exclude them when // Load any event ID and determine offset from it. This is always a detector
// computing an offset based on detector IDs. Currently this is computed in a // ID since the parallel loader is disabled otherwise. It is assumed that
// naive way and works only if all monitors have IDs smaller than any // detector IDs within a bank are contiguous.
// detector.
int32_t monitorOffset{0};
bool sawDetector{false};
for (size_t i = 0; i < detInfo.size(); ++i) {
if (detInfo.isMonitor(i)) {
if (sawDetector)
throw std::runtime_error("Monitors are not corresponding to the first "
"detector IDs in the instrument. This is "
"currently not supported by "
"ParallelEventLoader");
++monitorOffset;
} else {
sawDetector = true;
}
}
std::vector<int32_t> bankOffsets; std::vector<int32_t> bankOffsets;
for (const auto &bankName : bankNames) { for (const auto &eventId : Parallel::IO::EventLoader::anyEventIdFromBanks(
// Removing "_events" from bankName filename, groupName, bankNames)) {
auto bank = // The offset is the difference between the event ID and the spectrum index
instrument->getComponentByName(bankName.substr(0, bankName.size() - 7)); // and can then be used to translate from the former to the latter by simple
if (bank) { // subtraction.
const auto &detectors = // If no eventId could be read for a bank it implies that there are no
compInfo.detectorsInSubtree(compInfo.indexOf(bank->getComponentID())); // events, so any offset will do since it is unused. Set to 0.
const size_t detIndex = detectors.front(); if (eventId)
bankOffsets.push_back(detIDs[detIndex] - static_cast<int32_t>(detIndex) + bankOffsets.emplace_back(*eventId - map.at(*eventId));
monitorOffset); else
if ((detIDs[detectors.back()] - detIDs[detectors.front()]) != bankOffsets.emplace_back(0);
static_cast<int32_t>(detectors.size()) - 1)
throw std::runtime_error("Detector ID range in bank is not contiguous. "
"Cannot use ParallelEventLoader.");
} else {
throw std::runtime_error(
"ParallelEventLoader: Bank " + bankName +
" not found. Cannot determine detector ID offset.");
}
} }
return bankOffsets; return bankOffsets;
} }
...@@ -68,9 +51,9 @@ void ParallelEventLoader::load(DataObjects::EventWorkspace &ws, ...@@ -68,9 +51,9 @@ void ParallelEventLoader::load(DataObjects::EventWorkspace &ws,
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < size; ++i)
DataObjects::getEventsFrom(ws.getSpectrum(i), eventLists[i]); DataObjects::getEventsFrom(ws.getSpectrum(i), eventLists[i]);
Parallel::IO::EventLoader::load(filename, groupName, bankNames, Parallel::IO::EventLoader::load(
bankOffsets(ws, bankNames), filename, groupName, bankNames,
std::move(eventLists)); bankOffsets(ws, filename, groupName, bankNames), std::move(eventLists));
} }
} // namespace DataHandling } // namespace DataHandling
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <boost/optional.hpp>
#include "MantidParallel/DllConfig.h" #include "MantidParallel/DllConfig.h"
namespace Mantid { namespace Mantid {
...@@ -44,6 +46,9 @@ namespace IO { ...@@ -44,6 +46,9 @@ namespace IO {
Code Documentation is available at: <http://doxygen.mantidproject.org> Code Documentation is available at: <http://doxygen.mantidproject.org>
*/ */
namespace EventLoader { namespace EventLoader {
MANTID_PARALLEL_DLL std::vector<boost::optional<int32_t>>
anyEventIdFromBanks(const std::string &filename, const std::string &groupName,
const std::vector<std::string> &bankNames);
MANTID_PARALLEL_DLL void MANTID_PARALLEL_DLL void
load(const std::string &filename, const std::string &groupName, load(const std::string &filename, const std::string &groupName,
const std::vector<std::string> &bankNames, const std::vector<std::string> &bankNames,
......
#include "MantidParallel/IO/EventLoader.h" #include "MantidParallel/IO/EventLoader.h"
#include "MantidParallel/IO/EventLoaderHelpers.h" #include "MantidParallel/IO/EventLoaderHelpers.h"
#include "MantidParallel/IO/NXEventDataLoader.h"
#include <H5Cpp.h> #include <H5Cpp.h>
...@@ -8,6 +9,24 @@ namespace Parallel { ...@@ -8,6 +9,24 @@ namespace Parallel {
namespace IO { namespace IO {
namespace EventLoader { namespace EventLoader {
std::vector<boost::optional<int32_t>>
anyEventIdFromBanks(const std::string &filename, const std::string &groupName,
const std::vector<std::string> &bankNames) {
std::vector<boost::optional<int32_t>> eventIds(bankNames.size());
H5::H5File file(filename, H5F_ACC_RDONLY);
H5::Group group = file.openGroup(groupName);
for (size_t i = 0; i < bankNames.size(); ++i) {
try {
int32_t eventId;
detail::read<int32_t>(&eventId, group, bankNames[i] + "/event_id", 0, 1);
eventIds[i] = eventId;
} catch (const std::out_of_range &) {
// No event in file, keep eventIds uninitialized for this bank.
}
}
return eventIds;
}
void load(const std::string &filename, const std::string &groupName, void load(const std::string &filename, const std::string &groupName,
const std::vector<std::string> &bankNames, const std::vector<std::string> &bankNames,
const std::vector<int32_t> &bankOffsets, const std::vector<int32_t> &bankOffsets,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment