30#include <nexus/NeXusFile.hpp>
31#include <nexus/NeXusException.hpp>
37using Mantid::Types::Core::DateAndTime;
43using namespace Kernel;
44using namespace DateAndTimeHelpers;
46using Geometry::Instrument;
47using Mantid::HistogramData::BinEdges;
48using Mantid::HistogramData::Counts;
49using Mantid::HistogramData::Histogram;
51using Mantid::Types::Core::DateAndTime;
54inline std::string getLoadAlgName(
int confidence1,
int confidenceV2) {
55 return confidence1 > confidenceV2 ?
"LoadMuonNexus" :
"LoadMuonNexusV2";
75 int confidence1 = load1.
confidence(descriptor);
76 int confidence2 = this->
confidence(descriptor);
82 confidenceV2 = loadV2.
confidence(descriptorHDF5);
86 if (confidence1 < 80 && confidence2 < 80 && confidenceV2 < 80) {
90 if (confidence2 > std::max(confidence1, confidenceV2)) {
96 auto loader = std::dynamic_pointer_cast<API::Algorithm>(childAlg);
97 loader->copyPropertiesFrom(*
this);
98 loader->executeAsChildAlg();
116 if (iEntry >=
static_cast<int64_t
>(root.
groups().size())) {
117 throw std::invalid_argument(
"EntryNumber is out of range");
131 }
catch (::NeXus::Exception &) {
141 std::string localWSName = ws->
value();
143 std::shared_ptr<Instrument> instrument;
144 std::shared_ptr<Sample> sample;
146 std::string detectorName;
148 for (
auto &group : entry.
groups()) {
149 std::string className = group.nxclass;
150 if (className ==
"NXdata") {
151 detectorName = group.nxname;
158 spectrum_index.
load();
169 int nBins = raw_time.
dim0();
170 std::vector<double> timeBins;
171 timeBins.assign(raw_time(), raw_time() + nBins);
172 timeBins.emplace_back(raw_time[nBins - 1] + raw_time[1] - raw_time[0]);
178 total_specs =
static_cast<int>(
m_spec_list.size());
196 std::shared_ptr<Kernel::Units::Label> lblUnit =
199 localWorkspace->getAxis(0)->unit() = lblUnit;
201 localWorkspace->setYUnit(
"Counts");
206 wsGrpSptr->setTitle(entry.
getString(
"title"));
210 wsGrpSptr->setComment(entry.
getString(
"notes"));
214 setProperty(
"OutputWorkspace", std::dynamic_pointer_cast<Workspace>(wsGrpSptr));
229 double dum = detector.
getFloat(
"time_zero");
233 double dum = detector.
getFloat(
"first_good_time");
238 double dum = detector.
getFloat(
"last_good_time");
252 loadLogs(localWorkspace, entry, period);
261 std::string outputWorkspace =
"OutputWorkspace";
262 std::stringstream suffix;
263 suffix << (period + 1);
264 outws = outputWorkspace +
"_" + suffix.str();
265 std::string WSName = localWSName +
"_" + suffix.str();
268 wsGrpSptr->addWorkspace(localWorkspace);
272 std::map<int, int> index_spectrum;
274 index_spectrum[spectrum_index[i]] = i;
278 localWorkspace->mutableX(0) = timeBins;
280 int i = index_spectrum[spec];
281 localWorkspace->setHistogram(wsIndex,
loadData(localWorkspace->binEdges(0), counts, period, i));
282 localWorkspace->getSpectrum(wsIndex).setSpectrumNo(spectrum_index[i]);
283 localWorkspace->getSpectrum(wsIndex).setDetectorIDs(detMapping.at(i));
291 int k = index_spectrum[spec];
292 localWorkspace->setHistogram(wsIndex,
loadData(localWorkspace->binEdges(0), counts, period, k));
293 localWorkspace->getSpectrum(wsIndex).setSpectrumNo(spectrum_index[k]);
294 localWorkspace->getSpectrum(wsIndex).setDetectorIDs(detMapping.at(k));
300 assert(wsIndex == total_specs);
305 g_log.
warning(
"Autogrouping is not implemented for muon NeXus version 2 files");
310 setProperty(outws, std::static_pointer_cast<Workspace>(localWorkspace));
312 setProperty(
"OutputWorkspace", std::dynamic_pointer_cast<Workspace>(localWorkspace));
323 const int *data =
nullptr;
325 if (counts.
rank() == 3) {
326 nBins = counts.
dim2();
327 data = &counts(period, spec, 0);
328 }
else if (counts.
rank() == 2) {
329 nBins = counts.
dim1();
330 data = &counts(spec, 0);
332 throw std::runtime_error(
"Data have unsupported dimensionality");
335 return Histogram(edges, Counts(data, data + nBins));
348 std::string start_time = entry.
getString(
"start_time");
350 std::string sampleName = entry.
getString(
"sample/name");
352 ws->mutableSample().setName(sampleName);
354 for (std::vector<NXClassInfo>::const_iterator it = runlogs.
groups().begin(); it != runlogs.
groups().end(); ++it) {
359 ws->mutableRun().addLogData(logv);
365 ws->setComment(entry.
getString(
"notes"));
372 ws->populateInstrumentParameters();
379 API::Run &runDetails = localWorkspace->mutableRun();
381 runDetails.
addProperty(
"run_title", localWorkspace->getTitle(),
true);
383 auto numSpectra =
static_cast<int>(localWorkspace->getNumberHistograms());
390 std::string start_time = entry.
getString(
"start_time");
393 std::string stop_time = entry.
getString(
"end_time");
400 int dum = runRun.
getInt(
"good_total_frames");
405 int dum = runRun.
getInt(
"number_periods");
413 double duration_in_secs = DateAndTime::secondsFromDuration(end - start);
414 runDetails.
addProperty(
"dur_secs", duration_in_secs);
426 const std::string root =
"/" + firstEntryNameType.first;
427 if (!descriptor.
pathExists(root +
"/definition"))
431 if (descriptor.
pathExists(root +
"/IDF_version"))
434 if (descriptor.
pathExists(root +
"/idf_version"))
441 std::string versionField =
"idf_version";
443 versionField =
"IDF_version";
445 auto &file = descriptor.
data();
446 file.openPath(root +
"/" + versionField);
452 file.openPath(root +
"/definition");
453 std::string def = file.getStrData();
454 if (def ==
"muonTD" || def ==
"pulsedTD") {
478 std::map<int, std::set<int>> mapping;
484 const std::string detectorName = [&entry]() {
486 for (
auto &group : entry.
groups()) {
487 std::string className = group.nxclass;
488 if (className ==
"NXdata") {
492 throw std::runtime_error(
"No NXdata found in file");
499 const bool hasDetectorMapping = dataGroup.
containsDataSet(
"detector_index") &&
502 if (hasDetectorMapping) {
505 const auto detIndex = dataGroup.
openNXInt(
"detector_index");
506 const auto detCount = dataGroup.
openNXInt(
"detector_count");
507 const auto detList = dataGroup.
openNXInt(
"detector_list");
508 const int nDet = detIndex.
dim0();
509 for (
int i = 0; i < nDet; ++i) {
510 const int start = detIndex[i];
511 const int nDetectors = detCount[i];
512 std::set<int> detIDs;
513 for (
int jDet = 0; jDet < nDetectors; ++jDet) {
514 detIDs.insert(detList[start + jDet]);
518 }
catch (const ::NeXus::Exception &err) {
520 std::ostringstream message;
521 message <<
"Failed to read detector mapping: " << err.what();
522 throw std::runtime_error(message.str());
525 for (
int i = 0; i <
nSpectra; ++i) {
526 mapping[i] = std::set<int>{spectrumIndex[i]};
#define DECLARE_NEXUS_FILELOADER_ALGORITHM(classname)
DECLARE_NEXUS_FILELOADER_ALGORITHM should be used in place of the standard DECLARE_ALGORITHM macro wh...
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.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
void initialize() override
Initialization method invoked by the framework.
virtual std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1)
Create a Child Algorithm.
virtual void copyPropertiesFrom(const Algorithm &alg)
Make m_properties point to the same PropertyManager as alg.m_properties.
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
void addProperty(Kernel::Property *prop, bool overwrite=false)
Add data to the object in the form of a property.
Helper class for reporting progress from algorithms.
This class stores information regarding an experimental run as a series of log entries.
Class to hold a set of workspaces.
A property class for workspaces.
int confidence(Kernel::NexusDescriptor &descriptor) const override
Returns a confidence value that this algorithm can load a file.
std::map< int, std::set< int > > loadDetectorMapping(const Mantid::NeXus::NXInt &spectrumIndex)
Loads the mapping between index -> set of detector IDs.
void doExec()
Execute this version of the algorithm.
void loadLogs(const API::MatrixWorkspace_sptr &ws, Mantid::NeXus::NXEntry &entry, int period)
Load logs from Nexus file.
HistogramData::Histogram loadData(const Mantid::HistogramData::BinEdges &edges, const Mantid::NeXus::NXInt &counts, int period, int spec)
loadData Load the counts data from an NXInt into a workspace
void loadRunDetails(const DataObjects::Workspace2D_sptr &localWorkspace)
Log the run details from the file.
int version() const override
Algorithm's version for identification overriding a virtual method.
int confidence(Kernel::NexusDescriptor &descriptor) const override
Returns a confidence value that this algorithm can load a file.
LoadMuonNexus2()
Default constructor.
void exec() override
Overwrites Algorithm method.
Loads a file in the Nexus Muon format V2 and stores it in a 2D workspace (Workspace2D class).
int confidence(Kernel::NexusHDF5Descriptor &descriptor) const override
Returns a confidence value that this algorithm can load a file.
It is a base class for loaders for versions 1 and 2 of the muon nexus file format.
std::string m_filename
The name and path of the input file.
specnum_t m_spec_min
The value of the spectrum_min property.
void runLoadInstrument(const DataObjects::Workspace2D_sptr &)
Run the Child Algorithm LoadInstrument.
std::string m_entry_name
The first top-level entry name in the file.
std::string m_instrument_name
The instrument name from Nexus.
int64_t m_numberOfPeriods
The number of periods in the raw file.
bool m_interval
Have the spectrum_min/max properties been set?
bool m_list
Has the spectrum_list property been set?
specnum_t m_spec_max
The value of the spectrum_max property.
void checkOptionalProperties()
Validates the optional 'spectra to read' properties, if they have been set.
std::vector< specnum_t > m_spec_list
The value of the spectrum_list property.
specnum_t m_numberOfSpectra
The number of spectra in the raw file.
Records the filename and the description of failure.
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.
Defines a wrapper around a file whose internal structure can be accessed using the NeXus API.
static bool isReadable(const std::string &filename, const Version version=AnyVersion)
Returns true if the file is considered to store data in a hierarchy.
inline ::NeXus::File & data()
Access the open NeXus File object.
const std::pair< std::string, std::string > & firstEntryNameType() const
Returns the name & type of the first entry in the file.
bool pathExists(const std::string &path) const
Query if a path exists.
The concrete, templated class for properties.
Base class for properties.
virtual std::string value() const =0
Returns the value of the property as a string.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
static const UnitLabel Microsecond
Microsecond.
The base class for a Nexus class (group).
int getInt(const std::string &name) const
Returns a int.
NX openNXClass(const std::string &name) const
Templated method for creating derived NX classes.
NXInt openNXInt(const std::string &name) const
Creates and opens an integer dataset.
NXClass openNXGroup(const std::string &name) const
Creates and opens an arbitrary (non-standard) class (group).
bool containsGroup(const std::string &query) const
Returns whether an individual group (or group) is present.
std::vector< NXClassInfo > & groups() const
Returns a list of all classes (or groups) in this NXClass.
bool containsDataSet(const std::string &query) const
Returns whether an individual dataset is present.
float getFloat(const std::string &name) const
Returns a float.
NXFloat openNXFloat(const std::string &name) const
Creates and opens a float dataset.
std::string getString(const std::string &name) const
Returns a string.
Templated class implementation of NXDataSet.
void load(const int blocksize=1, int i=-1, int j=-1, int k=-1, int l=-1) override
Implementation of the virtual NXDataSet::load(...) method.
int dim2() const
Returns the number of elements along the third dimension.
int dim0() const
Returns the number of elements along the first dimension.
int rank() const
Returns the rank (number of dimensions) of the data. The maximum is 4.
int dim1() const
Returns the number of elements along the second dimension.
Implements NXdata Nexus class.
NXInt openIntData()
Opens data of int type.
Implements NXdetector Nexus class.
Implements NXentry Nexus class.
NXData openNXData(const std::string &name) const
Opens a NXData.
NXInstrument openNXInstrument(const std::string &name) const
Opens a NXInstrument.
Implements NXinstrument Nexus class.
NXDetector openNXDetector(const std::string &name)
Opens a NXDetector.
Implements NXlog Nexus class.
Kernel::Property * createTimeSeries(const std::string &start_time="", const std::string &new_name="")
Creates a TimeSeriesProperty and returns a pointer to it.
Main class is the one that can contain auxiliary classes.
NXLog openNXLog(const std::string &name)
Opens a NXLog class.
Implements NXroot Nexus class.
NXEntry openEntry(const std::string &name)
Opens an entry – a topmost Nexus class.
std::shared_ptr< WorkspaceGroup > WorkspaceGroup_sptr
shared pointer to Mantid::API::WorkspaceGroup
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< Workspace2D > Workspace2D_sptr
shared pointer to Mantid::DataObjects::Workspace2D
std::unique_ptr< T > create(const P &parent, const IndexArg &indexArg, const HistArg &histArg)
This is the create() method that all the other create() methods call.
MANTID_KERNEL_DLL Types::Core::DateAndTime createFromSanitizedISO8601(const std::string &date)
Creates a DateAndTime object from a date string even if the string does not exactly conform to ISO860...
std::string to_string(const wide_integer< Bits, Signed > &n)
@ Output
An output workspace.