143 auto prog = std::make_unique<Progress>(
this, 0.0, 1.0, 6);
148 prog->doReport(
"Loading logs");
150 auto periodLog = std::make_unique<const TimeSeriesProperty<int>>(
"period_log");
151 LoadEventNexus::runLoadNexusLogs<MatrixWorkspace_sptr>(filename, WS, *
this,
false, nPeriods, periodLog,
155 g_log.
warning(
"This algorithm does not correctly handle period data");
169 "Width was calculated to be 0 (XCenter*XWidth). This will result in a invalid bin with zero width");
171 throw std::runtime_error(errmsg);
177 prog->doReport(
"Loading instrument");
178 LoadEventNexus::loadInstrument<MatrixWorkspace_sptr>(filename, WS,
"entry",
this, &descriptor);
181 prog->doReport(
"Loading metadata");
184 }
catch (std::exception &e) {
185 g_log.
warning() <<
"Error while loading meta data: " << e.what() <<
'\n';
189 prog->doReport(
"Creating IndexInfo");
190 const std::vector<int32_t> range;
193 const size_t numHist = indexInfo.size();
198 outWS->setIndexInfo(indexInfo);
201 const auto id_to_wi = outWS->getDetectorIDToWorkspaceIndexMap();
202 detid_t min_detid = std::numeric_limits<detid_t>::max();
203 detid_t max_detid = std::numeric_limits<detid_t>::min();
205 for (
const auto &entry : id_to_wi) {
206 min_detid = std::min(min_detid, entry.first);
207 max_detid = std::max(max_detid, entry.first);
210 const double tof_min =
getProperty(
"FilterByTofMin");
211 const double tof_max =
getProperty(
"FilterByTofMax");
214 double filter_time_start_sec, filter_time_stop_sec;
215 filter_time_start_sec =
getProperty(
"FilterByTimeStart");
216 filter_time_stop_sec =
getProperty(
"FilterByTimeStop");
219 if (!WS->run().hasProperty(
"start_time")) {
220 g_log.
warning(
"This NXS file does not have a start time, first pulse time is used instead.");
223 Types::Core::DateAndTime runstart(WS->run().hasProperty(
"start_time") ? WS->run().getProperty(
"start_time")->value()
224 : WS->run().getFirstPulseTime());
228 Types::Core::DateAndTime endtime;
229 if (WS->run().hasProperty(
"proton_charge") &&
230 WS->run().getLastPulseTime() > WS->run().getProperty(
"end_time")->value()) {
231 endtime = WS->run().getLastPulseTime();
232 g_log.
warning(
"Last pulse time is used because the last pulse time is greater than the end time!");
234 endtime = WS->run().getProperty(
"end_time")->value();
237 Types::Core::DateAndTime filter_time_start;
238 Types::Core::DateAndTime filter_time_stop;
241 if (filter_time_start_sec !=
EMPTY_DBL()) {
242 filter_time_start = runstart + filter_time_start_sec;
244 filter_time_start = runstart;
246 if (filter_time_stop_sec !=
EMPTY_DBL()) {
247 filter_time_stop = runstart + filter_time_stop_sec;
249 filter_time_stop = endtime;
253 std::vector<uint32_t>
Y(max_detid - min_detid + 1, 0);
255 Nexus::File h5file(filename);
257 h5file.openAddress(
"/");
258 h5file.openGroup(
"entry",
"NXentry");
261 prog->doReport(
"Reading and integrating data");
263 std::set<std::string>
const classEntries = h5file.getEntriesByClass(
"NXevent_data");
264 if (!classEntries.empty()) {
265 const std::regex classRegex(
"(/entry/)([^/]*)");
267 for (
const std::string &classEntry : classEntries) {
269 if (std::regex_match(classEntry, groups, classRegex)) {
270 const std::string entry_name(groups[2].str());
272 if (entry_name ==
"bank_error_events" || entry_name ==
"bank_unmapped_events")
274 g_log.
debug() <<
"Loading bank " << entry_name <<
'\n';
275 h5file.openGroup(entry_name,
"NXevent_data");
277 std::vector<uint32_t> event_ids;
279 if (descriptor.
isEntry(
"/entry/" + entry_name +
"/event_id",
"SDS"))
280 event_ids = Nexus::IOHelper::readNexusVector<uint32_t>(h5file,
"event_id");
282 event_ids = Nexus::IOHelper::readNexusVector<uint32_t>(h5file,
"event_pixel_id");
285 if (event_ids.size() <= 1) {
291 const auto bankPulseTimes = std::make_shared<BankPulseTimes>(boost::ref(h5file), std::vector<int>());
294 const auto event_index =
295 std::make_shared<std::vector<uint64_t>>(Nexus::IOHelper::readNexusVector<uint64_t>(h5file,
"event_index"));
298 const auto pulseROI = bankPulseTimes->getPulseIndices(filter_time_start, filter_time_stop);
301 const PulseIndexer pulseIndexer(event_index, event_index->at(0), event_ids.size(), entry_name, pulseROI);
303 std::vector<float> event_times;
305 if (descriptor.
isEntry(
"/entry/" + entry_name +
"/event_time_offset",
"SDS"))
306 event_times = Nexus::IOHelper::readNexusVector<float>(h5file,
"event_time_offset");
308 event_times = Nexus::IOHelper::readNexusVector<float>(h5file,
"event_time_of_flight");
315 for (
const auto &pulse : pulseIndexer) {
316 for (
size_t i = pulse.eventIndexStart; i < pulse.eventIndexStop; i++) {
319 const auto tof = event_times[i];
320 if (tof < tof_min || tof > tof_max)
323 const detid_t det_id = event_ids[i];
324 if (det_id < min_detid || det_id > max_detid)
326 Y[det_id - min_detid]++;
338 const bool is_time_filtered = (filter_time_start_sec !=
EMPTY_DBL() || filter_time_stop_sec !=
EMPTY_DBL());
339 if (is_time_filtered) {
341 outWS->mutableRun().setTimeROI(timeroi);
342 outWS->mutableRun().removeDataOutsideTimeROI();
346 const auto xBins = {center - width / 2, center + width / 2};
348 prog->doReport(
"Setting data to workspace");
350 const auto histX = Mantid::Kernel::make_cow<HistogramX>(xBins);
351 for (
detid_t detid = min_detid; detid <= max_detid; detid++) {
352 const auto id_wi = id_to_wi.find(detid);
353 if (id_wi == id_to_wi.end())
356 const auto wi = id_wi->second;
357 const auto y =
Y[detid - min_detid];
359 outWS->mutableY(wi) =
y;
360 outWS->mutableE(wi) = sqrt(
y);
361 outWS->setSharedX(wi, histX);
366 outWS->setYUnit(
"Counts");
369 outWS->mutableRun().addProperty(
"Filename", filename);