Mantid
Loading...
Searching...
No Matches
LoadErrorEventsNexus.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2024 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7
9#include "MantidAPI/Axis.h"
11#include "MantidAPI/Run.h"
12#include "MantidAPI/Sample.h"
18
19namespace Mantid {
20namespace DataHandling {
21using namespace API;
24
25// Register the algorithm into the AlgorithmFactory
26DECLARE_ALGORITHM(LoadErrorEventsNexus)
27
28//----------------------------------------------------------------------------------------------
29
30
31const std::string LoadErrorEventsNexus::name() const { return "LoadErrorEventsNexus"; }
32
34int LoadErrorEventsNexus::version() const { return 1; }
35
37const std::string LoadErrorEventsNexus::category() const { return "DataHandling\\Nexus"; }
38
40const std::string LoadErrorEventsNexus::summary() const { return "Load error events from NeXus file"; }
41
42//----------------------------------------------------------------------------------------------
46 const std::vector<std::string> exts{".nxs.h5", ".nxs", "_event.nxs"};
47 declareProperty(std::make_unique<FileProperty>("Filename", "", FileProperty::Load, exts),
48 "The name of the Event NeXus file to read, including its full or "
49 "relative path. ");
50 declareProperty(std::make_unique<WorkspaceProperty<Mantid::DataObjects::EventWorkspace>>("OutputWorkspace", "",
52 "An output workspace.");
53}
54
55//----------------------------------------------------------------------------------------------
59 std::string filename = getPropertyValue("Filename");
60
61 MatrixWorkspace_sptr outWS = WorkspaceFactory::Instance().create("EventWorkspace", 1, 2, 1);
62
63 const Nexus::NexusDescriptor descriptor(filename);
64
65 if (!descriptor.isEntry("/entry/bank_error_events"))
66 throw std::runtime_error("entry bank_error_events does not exist");
67
68 // load logs
69 int nPeriods = 1;
70 auto periodLog = std::make_unique<const TimeSeriesProperty<int>>("period_log");
71 LoadEventNexus::runLoadNexusLogs<MatrixWorkspace_sptr>(filename, outWS, *this, false, nPeriods, periodLog);
72
73 if (nPeriods != 1)
74 g_log.warning("This algorithm does not correctly handle period data");
75
76 // Load the instrument
77 LoadEventNexus::loadInstrument<MatrixWorkspace_sptr>(filename, outWS, "entry", this, &descriptor);
78
79 // load run metadata
80 try {
81 LoadEventNexus::loadEntryMetadata(filename, outWS, "entry", descriptor);
82 } catch (std::exception &e) {
83 g_log.warning() << "Error while loading meta data: " << e.what() << '\n';
84 }
85
86 // load the data
87 Nexus::File file(filename);
88
89 file.openAddress("/");
90 file.openGroup("entry", "NXentry");
91 file.openGroup("bank_error_events", "NXevent_data");
92
93 const auto event_times = Nexus::IOHelper::readNexusVector<float>(file, "event_time_offset");
94 const auto event_index =
95 std::make_shared<std::vector<uint64_t>>(Nexus::IOHelper::readNexusVector<uint64_t>(file, "event_index"));
96 const auto bankPulseTimes = std::make_shared<BankPulseTimes>(boost::ref(file), periodLog->valuesAsVector());
97
98 file.closeGroup(); // bank_error_events
99 file.closeGroup(); // entry
100 file.close();
101
102 // add event data to output workspace
103
104 const auto numEvents = event_times.size();
105
106 // this assumes that pulse indices are sorted
107 if (!std::is_sorted(event_index->cbegin(), event_index->cend()))
108 throw std::runtime_error("Event index is not sorted");
109
110 auto eventWS = std::dynamic_pointer_cast<Mantid::DataObjects::EventWorkspace>(outWS);
111 auto &ev = eventWS->getSpectrum(0);
112
113 auto min_tof = std::numeric_limits<double>::max();
114 auto max_tof = std::numeric_limits<double>::lowest();
115
116 const PulseIndexer pulseIndexer(event_index, event_index->at(0), numEvents, "bank_error_events",
117 std::vector<size_t>());
118
119 for (const auto &pulseIter : pulseIndexer) {
120 // Save the pulse time at this index for creating those events
121 const auto &pulsetime = bankPulseTimes->pulseTime(pulseIter.pulseIndex);
122
123 // loop through events associated with a single pulse
124 for (std::size_t eventIndex = pulseIter.eventIndexStart; eventIndex < pulseIter.eventIndexStop; ++eventIndex) {
125 const auto tof = static_cast<double>(event_times[eventIndex]);
126 ev.addEventQuickly(Mantid::Types::Event::TofEvent(tof, pulsetime));
127 min_tof = std::min(min_tof, tof);
128 max_tof = std::max(max_tof, tof);
129 }
130 }
131
132 g_log.information() << "Loaded " << numEvents << " events with TOF min = " << min_tof << ", max = " << max_tof
133 << "\n";
134
135 if (min_tof < max_tof)
136 eventWS->setAllX(HistogramData::BinEdges{min_tof, max_tof});
137 else
138 eventWS->setAllX(HistogramData::BinEdges{0, 16666.7});
139
140 outWS->getAxis(0)->setUnit("TOF");
141 outWS->setYUnit("Counts");
142 outWS->mutableRun().addProperty("Filename", filename);
143
144 setProperty("OutputWorkspace", outWS);
145}
146
147} // namespace DataHandling
148} // namespace Mantid
std::string name
Definition Run.cpp:60
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
Kernel::Logger & g_log
Definition Algorithm.h:422
@ Load
allowed here which will be passed to the algorithm
A property class for workspaces.
LoadErrorEventsNexus : Load events from bank_error_events.
int version() const override
Algorithm's version for identification.
void init() override
Initialize the algorithm's properties.
const std::string summary() const override
Algorithm's summary for use in the GUI and help.
const std::string category() const override
Algorithm's category for identification.
void exec() override
Execute the algorithm.
static void loadEntryMetadata(const std::string &nexusfilename, T WS, const std::string &entry_name, const Nexus::NexusDescriptor &descriptor)
Load the run number and other meta data from the given bank.
PulseIndexer contains information for mapping from pulse index/number to event index.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
void information(const std::string &msg)
Logs at information level.
Definition Logger.cpp:136
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
A specialised Property class for holding a series of time-value pairs.
bool isEntry(const std::string &entryName, const std::string &groupClass) const noexcept
Checks if a full-address entry exists for a particular groupClass in a Nexus dataset.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::size_t numEvents(Nexus::File &file, bool &hasTotalCounts, bool &oldNeXusFileNames, const std::string &prefix, const Nexus::NexusDescriptor &descriptor)
Get the number of events in the currently opened group.
Helper class which provides the Collimation Length for SANS instruments.
STL namespace.
Describes the direction (within an algorithm) of a Property.
Definition Property.h:50
@ Output
An output workspace.
Definition Property.h:54