34#include <nexus/NeXusFile.hpp>
35#include <nexus/NeXusException.hpp>
38#include <boost/iterator/counting_iterator.hpp>
39#include <boost/scoped_array.hpp>
49using namespace DataObjects;
54using namespace Kernel;
57using HistogramData::BinEdges;
58using HistogramData::Counts;
80 if (info.
stat != NX_ERROR) {
81 double dum = root.
getFloat(
"run/histogram_data_1/time_zero");
90 std::string firstGoodBin = counts.
attributes(
"first_good_bin");
91 if (!firstGoodBin.empty() && infoResolution.
stat != NX_ERROR) {
94 switch (infoResolution.
type) {
96 resolution =
static_cast<double>(entry.
getFloat(
"resolution"));
99 resolution =
static_cast<double>(entry.
getInt(
"resolution"));
102 throw std::runtime_error(
"Unsupported data type for resolution");
105 auto bin =
static_cast<double>(boost::lexical_cast<int>(firstGoodBin));
106 double bin_size = resolution / 1000000.0;
110 }
catch (std::exception &e) {
111 g_log.
warning() <<
"Error while loading the FirstGoodData value: " << e.what() <<
"\n";
117 std::string lastGoodBin = counts.
attributes(
"last_good_bin");
118 if (!lastGoodBin.empty() && infoResolution.
stat != NX_ERROR) {
121 switch (infoResolution.
type) {
123 resolution =
static_cast<double>(entry.
getFloat(
"resolution"));
126 resolution =
static_cast<double>(entry.
getInt(
"resolution"));
129 throw std::runtime_error(
"Unsupported data type for resolution");
132 auto bin =
static_cast<double>(boost::lexical_cast<int>(lastGoodBin));
133 double bin_size = resolution / 1000000.0;
137 }
catch (std::exception &e) {
138 g_log.
warning() <<
"Error while loading the LastGoodData value: " << e.what() <<
"\n";
165 throw std::invalid_argument(
"Invalid Entry Number:Enter a valid number");
204 const int channelsPerSpectrum = nxload.
t_ntc1;
206 const int lengthIn = channelsPerSpectrum + 1;
214 localWorkspace->setTitle(title);
215 localWorkspace->setComment(notes);
226 std::shared_ptr<Kernel::Units::Label> lblUnit =
229 localWorkspace->getAxis(0)->unit() = lblUnit;
231 localWorkspace->setYUnit(
"Counts");
252 localWorkspace->populateInstrumentParameters();
257 localWorkspace->setTitle(title);
258 localWorkspace->setComment(notes);
273 auto histToRead =
static_cast<specnum_t>(i - 1 + period * nxload.
t_nsp1);
275 loadData(counter, histToRead, specNo, nxload, lengthIn - 1,
283 auto histToRead =
static_cast<specnum_t>(specid - 1 + period * nxload.
t_nsp1);
284 auto specNo =
static_cast<specnum_t>(specid);
285 loadData(counter, histToRead, specNo, nxload, lengthIn - 1, localWorkspace);
291 assert(counter ==
size_t(total_specs));
299 if (autoGroup || returnGrouping) {
302 if (loadedGrouping && returnGrouping) {
304 setProperty(
"DetectorGroupingTable", loadedGrouping);
307 if (!loadedGrouping && autoGroup) {
309 g_log.
warning(
"Unable to load grouping from the file. Grouping not applied.");
313 if (autoGroup && loadedGrouping) {
316 if (
auto table = std::dynamic_pointer_cast<TableWorkspace>(loadedGrouping)) {
317 groupingTable = table;
318 }
else if (
auto group = std::dynamic_pointer_cast<WorkspaceGroup>(loadedGrouping)) {
319 groupingTable = std::dynamic_pointer_cast<TableWorkspace>(group->getItem(period));
321 std::vector<int> specIDs, detecIDs;
322 for (
size_t i = 0; i < localWorkspace->getNumberHistograms(); i++) {
323 specIDs.emplace_back(localWorkspace->getSpectrum(i).getSpectrumNo());
324 detecIDs.emplace_back(localWorkspace->getSpectrum(i).getSpectrumNo());
327 localWorkspace->updateSpectraUsing(mapping);
330 groupDet->setProperty(
"InputWorkspace", localWorkspace);
331 groupDet->setProperty(
"DetectorGroupingTable", groupingTable);
338 outWs = localWorkspace;
354 wsGrpSptr->addWorkspace(outWs);
359 setProperty(
"OutputWorkspace", std::dynamic_pointer_cast<Workspace>(wsGrpSptr));
375 if (infoDeadTimes.
stat != NX_ERROR) {
377 deadTimesData.
load();
379 int numDeadTimes = deadTimesData.
dim0();
381 std::vector<int> specToLoad;
382 std::vector<double> deadTimes;
387 specToLoad.insert(specToLoad.end(), boost::counting_iterator<specnum_t>(
m_spec_min),
388 boost::counting_iterator<specnum_t>(
m_spec_max));
395 specToLoad.emplace_back(i);
413 deadTimes.reserve(specToLoad.size());
414 std::transform(specToLoad.cbegin(), specToLoad.cend(), std::back_inserter(deadTimes),
415 [&deadTimesData](
const auto &spectra) { return deadTimesData[spectra - 1]; });
424 for (
int i = 1; i < numDeadTimes + 1; i++) {
425 specToLoad.emplace_back(i);
427 deadTimes.reserve(specToLoad.size());
428 std::transform(specToLoad.cbegin(), specToLoad.cend(), std::back_inserter(deadTimes),
429 [deadTimesData](
const auto &spectra) { return deadTimesData[spectra - 1]; });
440 deadTimes.reserve(specToLoad.size());
441 for (
auto spec : specToLoad) {
443 deadTimes.emplace_back(deadTimesData[
index]);
449 tableGroup->addWorkspace(table);
472 if (infoGrouping.
stat != NX_ERROR) {
476 int numGroupingEntries = groupingData.
dim0();
478 std::vector<int> specToLoad;
479 std::vector<int> grouping;
484 specToLoad.insert(specToLoad.end(), boost::counting_iterator<specnum_t>(
m_spec_min),
485 boost::counting_iterator<specnum_t>(
m_spec_max));
492 specToLoad.emplace_back(i);
503 "every spectrum in every period",
510 grouping.reserve(grouping.size() + specToLoad.size());
515 std::transform(specToLoad.cbegin(), specToLoad.cend(), std::back_inserter(grouping),
516 [&groupingData](
const auto spec) { return groupingData[spec - 1]; });
519 for (
auto &spec : specToLoad) {
521 grouping.emplace_back(groupingData[
index]);
527 if (table->rowCount() != 0)
534 specToLoad.emplace_back(i);
536 std::transform(specToLoad.cbegin(), specToLoad.cend(), std::back_inserter(grouping),
537 [&groupingData](
const auto spectrum) { return groupingData[spectrum - 1]; });
540 if (table->rowCount() != 0)
551 for (
auto &spec : specToLoad) {
553 grouping.emplace_back(groupingData[
index]);
560 if (table->rowCount() != 0)
561 tableGroup->addWorkspace(table);
564 if (tableGroup->size() != 0) {
575 const std::string mainFieldDirection =
getProperty(
"MainFieldDirection");
580 return idfGrouping->toTable();
581 }
catch (
const std::runtime_error &) {
583 auto dummyGrouping = std::make_shared<Grouping>();
584 if (inst->getNumberDetectors() != 0) {
588 std::ostringstream oss;
590 dummyGrouping->groups.emplace_back(oss.str());
591 dummyGrouping->description =
"Dummy grouping";
592 dummyGrouping->groupNames.emplace_back(
"all");
594 return dummyGrouping->toTable();
608 deadTimeTable->addColumn(
"int",
"spectrum");
609 deadTimeTable->addColumn(
"double",
"dead-time");
611 for (
size_t i = 0; i < specToLoad.size(); i++) {
612 TableRow row = deadTimeTable->appendRow();
613 row << specToLoad[i] << deadTimes[i];
616 return deadTimeTable;
627 std::vector<int> grouping) {
628 auto detectorGroupingTable =
631 detectorGroupingTable->addColumn(
"vector_int",
"Detectors");
633 std::map<int, std::vector<int>> groupingMap;
635 for (
size_t i = 0; i < specToLoad.size(); i++) {
638 groupingMap[grouping[i]].emplace_back(specToLoad[i]);
641 for (
auto &group : groupingMap) {
642 if (group.first != 0)
644 TableRow newRow = detectorGroupingTable->appendRow();
645 newRow << group.second;
649 return detectorGroupingTable;
669 std::vector<float> timeChannels(lengthIn + 1);
670 nxload.
getTimeChannels(timeChannels.data(),
static_cast<int>(lengthIn + 1));
672 localWorkspace->setHistogram(
673 hist, BinEdges(timeChannels.data(), timeChannels.data() + lengthIn + 1),
674 Counts(nxload.
m_counts.begin() + i * lengthIn, nxload.
m_counts.begin() + i * lengthIn + lengthIn));
676 localWorkspace->getSpectrum(hist).setSpectrumNo(specNo);
678 localWorkspace->getSpectrum(hist).setDetectorID(
static_cast<detid_t>(specNo));
685 API::Run &runDetails = localWorkspace->mutableRun();
687 runDetails.
addProperty(
"run_title", localWorkspace->getTitle(),
true);
689 auto numSpectra =
static_cast<int>(localWorkspace->getNumberHistograms());
694 std::string start_time = root.
getString(
"run/start_time");
696 }
catch (std::runtime_error &) {
697 g_log.
warning(
"run/start_time is not available, run_start log not added.");
701 std::string stop_time = root.
getString(
"run/stop_time");
703 }
catch (std::runtime_error &) {
704 g_log.
warning(
"run/stop_time is not available, run_end log not added.");
708 std::string dur = root.
getString(
"run/duration");
712 }
catch (std::runtime_error &) {
713 g_log.
warning(
"run/duration is not available, dur log not added.");
720 float temperature = runSample.
getFloat(
"temperature");
721 runDetails.
addProperty(
"sample_temp",
static_cast<double>(temperature));
725 float magn_field = runSample.
getFloat(
"magnetic_field");
726 runDetails.
addProperty(
"sample_magn_field",
static_cast<double>(magn_field));
734 loadLog->setPropertyValue(
"Filename",
m_filename);
741 }
catch (std::runtime_error &) {
742 g_log.
error(
"Unable to successfully run LoadMuonLog Child Algorithm");
743 }
catch (std::logic_error &) {
744 g_log.
error(
"Unable to successfully run LoadMuonLog Child Algorithm");
747 if (!loadLog->isExecuted())
748 g_log.
error(
"Unable to successfully run LoadMuonLog Child Algorithm");
753 std::string mainFieldDirection =
"Longitudinal";
760 auto p = std::make_unique<Kernel::TimeSeriesProperty<double>>(
"fromNexus");
761 std::string start_time = root.
getString(
"run/start_time");
762 p->addValue(start_time, -90.0);
763 localWorkspace->mutableRun().addLogData(std::move(p));
764 mainFieldDirection =
"Transverse";
771 auto &run = localWorkspace->mutableRun();
772 setProperty(
"MainFieldDirection", mainFieldDirection);
773 run.addProperty(
"main_field_direction", mainFieldDirection);
785 auto &run = localWorkspace->mutableRun();
790 run.removeLogData(
"period 1");
791 runLogs.
addPeriodLog(
static_cast<int>(period) + 1, run);
805 handle.openPath(
"run/instrument/beam");
807 handle.openData(
"frames_good");
808 }
catch (::NeXus::Exception &) {
810 g_log.
warning(
"Could not read /run/instrument/beam/frames_good");
811 handle.openData(
"frames");
812 g_log.
warning(
"Using run/instrument/beam/frames instead");
816 boost::scoped_array<int> dataVals(
new int[1]);
817 handle.getData(dataVals.get());
819 auto &run = localWorkspace->mutableRun();
820 run.addProperty(
"goodfrm", dataVals[0]);
822 }
catch (::NeXus::Exception &) {
831 handle.openPath(
"run/instrument/beam/");
832 handle.openData(
"frames_period_daq");
834 ::NeXus::Info info = handle.getInfo();
837 if (period >= info.dims[0]) {
838 std::ostringstream
error;
839 error <<
"goodfrm not found for period " << period;
840 throw std::runtime_error(
error.str());
842 if (nperiods != info.dims[0]) {
843 std::ostringstream
error;
844 error <<
"Inconsistent number of period entries found (";
845 error << info.dims[0];
846 error <<
"!=" << nperiods <<
")";
847 throw std::runtime_error(
error.str());
851 boost::scoped_array<int> dataVals(
new int[info.dims[0]]);
852 handle.getData(dataVals.get());
854 auto &run = localWorkspace->mutableRun();
858 run.addProperty(
"goodfrm", dataVals[0]);
863 run.removeLogData(
"goodfrm");
864 run.addProperty(
"goodfrm", dataVals[period]);
866 }
catch (::NeXus::Exception &) {
867 g_log.
warning(
"Could not read /run/instrument/beam/frames_period_daq");
882 const std::string root =
"/" + firstEntryNameType.first;
883 if (!descriptor.
pathExists(root +
"/analysis"))
887 if (descriptor.
pathExists(root +
"/IDF_version"))
890 if (descriptor.
pathExists(root +
"/idf_version"))
897 std::string versionField =
"idf_version";
899 versionField =
"IDF_version";
901 auto &file = descriptor.
data();
902 file.openPath(root +
"/" + versionField);
908 file.openPath(root +
"/analysis");
909 std::string def = file.getStrData();
910 if (def ==
"muonTD" || def ==
"pulsedTD") {
std::map< DeltaEMode::Type, std::string > index
#define DECLARE_NEXUS_FILELOADER_ALGORITHM(classname)
DECLARE_NEXUS_FILELOADER_ALGORITHM should be used in place of the standard DECLARE_ALGORITHM macro wh...
bool existsProperty(const std::string &name) const override
Checks whether the named property is already in the list of managed property.
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.
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.
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
GroupingLoader : Loads instrument grouping from IDF file.
std::shared_ptr< Grouping > getDummyGrouping()
Returns a "dummy" grouping of a single group with all the detectors in it.
std::shared_ptr< Grouping > getGroupingFromIDF() const
Load the grouping from the instrument's IDF.
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.
A minimal class to hold the mapping between the spectrum number and its related detector ID numbers f...
TableRow represents a row in a TableWorkspace.
Class to hold a set of workspaces.
Defines a class to aid in creating ISIS specific run logs for periods, status etc.
void addPeriodLog(const int period, API::Run &exptRun)
Add 'period i' log.
void addStatusLog(API::Run &exptRun)
Adds the status log to the this run.
void addPeriodLogs(const int period, API::Run &exptRun)
Adds period related logs.
void addGoodFrames(const DataObjects::Workspace2D_sptr &localWorkspace, int64_t period, int nperiods)
void exec() override
Overwrites Algorithm method.
API::Workspace_sptr loadDetectorGrouping(Mantid::NeXus::NXRoot &root, const Mantid::Geometry::Instrument_const_sptr &inst)
Loads detector grouping information.
int version() const override
Algorithm's version for identification overriding a virtual method.
DataObjects::TableWorkspace_sptr createDeadTimeTable(std::vector< int > specToLoad, std::vector< double > deadTimes)
Creates Dead Time Table using all the data between begin and end.
void loadRunDetails(const DataObjects::Workspace2D_sptr &localWorkspace)
Log the run details from the file.
int confidence(Kernel::NexusDescriptor &descriptor) const override
Returns a confidence value that this algorithm can load a file.
void addPeriodLog(const DataObjects::Workspace2D_sptr &localWorkspace, int64_t period)
Add the 'period i' log to a workspace.
void loadData(size_t hist, specnum_t &i, specnum_t specNo, MuonNexusReader &nxload, const int64_t lengthIn, const DataObjects::Workspace2D_sptr &localWorkspace)
Load in a single spectrum taken from a NeXus file.
void loadDeadTimes(Mantid::NeXus::NXRoot &root)
Loads dead time table for the detector.
LoadMuonNexus1()
Default constructor.
void runLoadLog(const DataObjects::Workspace2D_sptr &)
Run the LoadLog Child Algorithm.
DataObjects::TableWorkspace_sptr createDetectorGroupingTable(std::vector< int > specToLoad, std::vector< int > grouping)
Creates Detector Grouping Table using all the data from the range.
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_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.
int64_t m_entrynumber
The number of the input entry.
void addToSampleLog(const std::string &logName, const int logNumber, DataObjects::Workspace2D_sptr &ws)
Function to add a single int as a sample log to a workspace.
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 error(const std::string &msg)
Logs at error level.
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.
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.
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.
int getInt(const std::string &name) const
Returns a int.
NXInt openNXInt(const std::string &name) const
Creates and opens an integer dataset.
bool containsDataSet(const std::string &query) const
Returns whether an individual dataset is present.
NXInfo getDataSetInfo(const std::string &name) const
Returns NXInfo for a dataset.
float getFloat(const std::string &name) const
Returns a float.
NXFloat openNXFloat(const std::string &name) const
Creates and opens a float dataset.
NXChar openNXChar(const std::string &name) const
Creates and opens a char 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 dim0() const
Returns the number of elements along the first dimension.
Implements NXentry Nexus class.
NXAttributes attributes
Attributes.
Implements NXroot Nexus class.
NXEntry openEntry(const std::string &name)
Opens an entry – a topmost Nexus class.
MuunNexusReader opens a Nexus file and reads certain fields expected for a ISIS Muon data file (old f...
std::string m_framesPeriodsRaw
std::string m_periodsOutput
std::string m_framesPeriodsRequested
std::string m_periodNames
void getTimeChannels(float *timebnds, const int &nbnds) const
get time bin boundaries return sample name
int t_nper
number of periods in file (=1 at present)
void readFromFile(const std::string &filename)
read histogram data
std::string m_periodTypes
int t_ntc1
number of time channels in time regime 1
int t_nsp1
number of spectra in time regime 1
std::string getInstrumentName() const
return instrument name
std::string m_periodsCounts
std::vector< int > m_counts
temp store of histogram data
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< Algorithm > Algorithm_sptr
Typedef for a shared pointer to an Algorithm.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
DataObjects::TableWorkspace_sptr createTimeZeroTable(const size_t numSpec, const std::vector< double > &timeZeros)
Creates a timezero table for the loaded detectors.
std::shared_ptr< Workspace2D > Workspace2D_sptr
shared pointer to Mantid::DataObjects::Workspace2D
std::shared_ptr< TableWorkspace > TableWorkspace_sptr
shared pointer to Mantid::DataObjects::TableWorkspace
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_GEOMETRY_DLL PolygonEdge::Orientation orientation(const PolygonEdge &focusEdge, const PolygonEdge &refEdge, double &t)
Calculate the orientation type of one edge wrt to another.
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
int32_t detid_t
Typedef for a detector ID.
int32_t specnum_t
Typedef for a spectrum Number.
std::string to_string(const wide_integer< Bits, Signed > &n)
C++ implementation of NeXus classes.
NXstatus stat
return status
int type
type of the data, e.g. NX_CHAR, NX_FLOAT32, see napi.h