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 std::vector<uint32_t>
Y(max_detid - min_detid + 1, 0);
243 Nexus::File h5file(filename);
245 h5file.openAddress(
"/");
246 h5file.openGroup(
"entry",
"NXentry");
249 const std::map<std::string, std::set<std::string>> &allEntries = descriptor.
getAllEntries();
251 prog->doReport(
"Reading and integrating data");
252 auto itClassEntries = allEntries.find(
"NXevent_data");
253 if (itClassEntries != allEntries.end()) {
255 const std::set<std::string> &classEntries = itClassEntries->second;
256 const std::regex classRegex(
"(/entry/)([^/]*)");
258 for (
const std::string &classEntry : classEntries) {
260 if (std::regex_match(classEntry, groups, classRegex)) {
261 const std::string entry_name(groups[2].str());
263 if (entry_name ==
"bank_error_events" || entry_name ==
"bank_unmapped_events")
265 g_log.
debug() <<
"Loading bank " << entry_name <<
'\n';
266 h5file.openGroup(entry_name,
"NXevent_data");
268 std::vector<uint32_t> event_ids;
270 if (descriptor.
isEntry(
"/entry/" + entry_name +
"/event_id",
"SDS"))
271 event_ids = Nexus::IOHelper::readNexusVector<uint32_t>(h5file,
"event_id");
273 event_ids = Nexus::IOHelper::readNexusVector<uint32_t>(h5file,
"event_pixel_id");
276 if (event_ids.size() <= 1) {
282 const auto bankPulseTimes = std::make_shared<BankPulseTimes>(boost::ref(h5file), std::vector<int>());
285 const auto event_index =
286 std::make_shared<std::vector<uint64_t>>(Nexus::IOHelper::readNexusVector<uint64_t>(h5file,
"event_index"));
289 if (filter_time_start_sec !=
EMPTY_DBL()) {
290 filter_time_start = runstart + filter_time_start_sec;
292 filter_time_start = runstart;
296 if (filter_time_stop_sec !=
EMPTY_DBL()) {
297 filter_time_stop = runstart + filter_time_stop_sec;
299 filter_time_stop = endtime;
303 const auto TimeROI = bankPulseTimes->getPulseIndices(filter_time_start, filter_time_stop);
306 const PulseIndexer pulseIndexer(event_index, event_index->at(0), event_ids.size(), entry_name,
TimeROI);
308 std::vector<float> event_times;
310 if (descriptor.
isEntry(
"/entry/" + entry_name +
"/event_time_offset",
"SDS"))
311 event_times = Nexus::IOHelper::readNexusVector<float>(h5file,
"event_time_offset");
313 event_times = Nexus::IOHelper::readNexusVector<float>(h5file,
"event_time_of_flight");
320 for (
const auto &pulse : pulseIndexer) {
321 for (
size_t i = pulse.eventIndexStart; i < pulse.eventIndexStop; i++) {
324 const auto tof = event_times[i];
325 if (tof < tof_min || tof > tof_max)
328 const detid_t det_id = event_ids[i];
329 if (det_id < min_detid || det_id > max_detid)
331 Y[det_id - min_detid]++;
343 const auto xBins = {center - width / 2, center + width / 2};
345 prog->doReport(
"Setting data to workspace");
347 const auto histX = Mantid::Kernel::make_cow<HistogramX>(xBins);
348 for (
detid_t detid = min_detid; detid <= max_detid; detid++) {
349 const auto id_wi = id_to_wi.find(detid);
350 if (id_wi == id_to_wi.end())
353 const auto wi = id_wi->second;
354 const auto y =
Y[detid - min_detid];
356 outWS->mutableY(wi) =
y;
357 outWS->mutableE(wi) = sqrt(
y);
358 outWS->setSharedX(wi, histX);
363 outWS->setYUnit(
"Counts");
366 outWS->mutableRun().addProperty(
"Filename", filename);