19#include <Poco/DOM/AutoPtr.h>
20#include <Poco/DOM/DOMParser.h>
21#include <Poco/DOM/Document.h>
22#include <Poco/DOM/Element.h>
23#include <Poco/DOM/NodeFilter.h>
24#include <Poco/DOM/NodeIterator.h>
25#include <Poco/DOM/NodeList.h>
28#include <Poco/SAX/InputSource.h>
61 const std::string &filename = descriptor.
filename();
62 if (filename.size() > 12 ? (filename.compare(filename.size() - 12, 12,
"_runinfo.xml") == 0) :
false)
72 "The name of the runinfo file to read, including its full or relative "
77 "File containing the pixel mapping (DAS pixels to pixel IDs) file "
78 "(typically INSTRUMENT_TS_YYYY_MM_DD.dat). The filename will be found "
79 "automatically if not specified.");
80 auto mustBePositive = std::make_shared<BoundedValidator<int>>();
81 mustBePositive->setLower(1);
83 "If loading the file by sections ('chunks'), this is the "
84 "section number of this execution of the algorithm.");
86 "If loading the file by sections ('chunks'), this is the "
87 "total number of sections.");
92 std::vector<std::string> propOptions{
"Auto",
"Serial",
"Parallel"};
93 declareProperty(
"UseParallelProcessing",
"Auto", std::make_shared<StringListValidator>(propOptions),
94 "Use multiple cores for loading the data?\n"
95 " Auto: Use serial loading for small data sets, parallel "
96 "for large data sets.\n"
97 " Serial: Use a single core.\n"
98 " Parallel: Use all available cores.");
101 "Load the monitors from the file.");
104 "An output workspace.");
113 int chunkNumber = this->
getProperty(
"ChunkNumber");
118 if (chunkNumber > chunkTotal)
119 throw std::out_of_range(
"ChunkNumber cannot be larger than TotalChunks");
121 string useParallel = this->
getProperty(
"UseParallelProcessing");
122 string wsname = this->
getProperty(
"OutputWorkspace");
123 bool loadmonitors = this->
getProperty(
"LoadMonitors");
127 vector<string> eventFilenames;
130 prog.
doReport(
"parsed runinfo file");
133 size_t numFiles = eventFilenames.size() + 1;
136 double prog_start = .1;
137 double prog_delta = (1. - prog_start) /
static_cast<double>(numFiles);
142 for (
size_t i = 0; i < eventFilenames.size(); i++) {
144 temp_wsname = wsname;
146 temp_wsname =
"__" + wsname +
"_temp__";
149 alg->setProperty(
"EventFilename", dataDir + eventFilenames[i]);
150 alg->setProperty(
"MappingFilename", mapfile);
151 alg->setProperty(
"ChunkNumber", chunkNumber);
152 alg->setProperty(
"TotalChunks", chunkTotal);
153 alg->setProperty(
"UseParallelProcessing", useParallel);
154 alg->setPropertyValue(
"OutputWorkspace", temp_wsname);
155 alg->executeAsChildAlg();
156 prog_start += prog_delta;
163 Run &run = tempws->mutableRun();
174 this->
runLoadNexusLogs(runinfo, dataDir, prog_start, prog_start + prog_delta);
175 prog_start += prog_delta;
195 eventFilenames.clear();
198 Poco::Path runinfoPath(runinfo, Poco::Path::PATH_GUESS);
200 Poco::Path dirPath(runinfoPath.parent());
201 dataDir = dirPath.absolute().toString();
202 g_log.
debug() <<
"Data directory \"" << dataDir <<
"\"\n";
204 std::ifstream in(runinfo.c_str());
205 Poco::XML::InputSource src(in);
207 Poco::XML::DOMParser parser;
208 Poco::AutoPtr<Poco::XML::Document> pDoc = parser.parse(&src);
210 Poco::XML::NodeIterator it(pDoc, Poco::XML::NodeFilter::SHOW_ELEMENT);
211 Poco::XML::Node *pNode = it.nextNode();
213 if (pNode->nodeName() ==
"RunInfo")
215 pNode = pNode->firstChild();
217 if (pNode->nodeName() ==
"FileList") {
218 pNode = pNode->firstChild();
220 if (pNode->nodeName() ==
"DataList") {
221 pNode = pNode->firstChild();
223 if (pNode->nodeName() ==
"scattering") {
224 auto *element =
static_cast<Poco::XML::Element *
>(pNode);
225 eventFilenames.emplace_back(element->getAttribute(
"name"));
227 pNode = pNode->nextSibling();
230 pNode = pNode->nextSibling();
233 pNode = pNode->nextSibling();
236 pNode = pNode->nextSibling();
240 if (eventFilenames.size() == 1) {
241 g_log.
debug() <<
"Found 1 event file: \"" << eventFilenames[0] <<
"\"\n";
243 g_log.
debug() <<
"Found " << eventFilenames.size() <<
" event files:";
244 for (
auto &eventFilename : eventFilenames) {
245 g_log.
debug() <<
"\"" << eventFilename <<
"\" ";
260 const double prog_stop) {
262 string shortName = runinfo.substr(runinfo.find_last_of(
"/\\") + 1);
263 shortName = shortName.substr(0, shortName.find(
"_runinfo.xml"));
264 g_log.
debug() <<
"SHORTNAME = \"" << shortName <<
"\"\n";
267 vector<string> possibilities;
268 possibilities.emplace_back(dataDir + shortName +
"_event.nxs");
269 possibilities.emplace_back(dataDir + shortName +
"_histo.nxs");
270 possibilities.emplace_back(dataDir + shortName +
".nxs");
271 possibilities.emplace_back(dataDir +
"../NeXus/" + shortName +
"_event.nxs");
272 possibilities.emplace_back(dataDir +
"../NeXus/" + shortName +
"_histo.nxs");
273 possibilities.emplace_back(dataDir +
"../NeXus/" + shortName +
".nxs");
276 bool loadedLogs =
false;
277 for (
auto &possibility : possibilities) {
278 if (Poco::File(possibility).
exists()) {
282 alg->setProperty(
"Filename", possibility);
283 alg->setProperty(
"OverwriteLogs",
false);
284 alg->executeAsChildAlg();
294 g_log.
notice() <<
"Did not find a nexus file to load logs from\n";
304 std::string mon_wsname = this->
getProperty(
"OutputWorkspace");
305 mon_wsname.append(
"_monitors");
310 alg->setPropertyValue(
"OutputWorkspace", mon_wsname);
311 alg->executeAsChildAlg();
314 "Monitors from the Event NeXus file");
318 }
catch (std::exception &e) {
319 g_log.
warning() <<
"Failed to load monitors: " << e.what() <<
"\n";
#define DECLARE_FILELOADER_ALGORITHM(classname)
DECLARE_FILELOADER_ALGORITHM should be used in place of the standard DECLARE_ALGORITHM macro when wri...
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.
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.
static bool isEmpty(const NumT toCheck)
checks that the value was not set by users, uses the value in empty double/int.
@ OptionalLoad
to specify a file to read but the file doesn't have to exist
@ Load
allowed here which will be passed to the algorithm
bool hasProperty(const std::string &name) const
Does the property exist on the object.
void removeProperty(const std::string &name, bool delProperty=true)
Remove a named property.
Helper class for reporting progress from algorithms.
void doReport(const std::string &msg="") override
Actually do the reporting, without changing the loop counter.
This class stores information regarding an experimental run as a series of log entries.
A property class for workspaces.
static bool runLoadInstrument(const std::string &nexusfilename, T localWorkspace, const std::string &top_entry_name, Algorithm *alg, const Kernel::NexusHDF5Descriptor *descriptor=nullptr)
Load instrument from IDF file specified by Nexus file.
LoadPreNexus : Workflow algorithm to load a collection of preNeXus files.
void init() override
Virtual method - must be overridden by concrete algorithm.
API::IEventWorkspace_sptr m_outputWorkspace
int version() const override
function to return a version of the algorithm, must be overridden in all algorithms
const std::string category() const override
function to return a category of the algorithm.
int confidence(Kernel::FileDescriptor &descriptor) const override
Returns a confidence value that this algorithm can load a file.
void parseRuninfo(const std::string &runinfo, std::string &dataDir, std::vector< std::string > &eventFilenames)
Parse the runinfo file to find the names of the neutron event files.
void exec() override
Virtual method - must be overridden by concrete algorithm.
void runLoadMonitors(const double prog_start, const double prog_stop)
Load the monitor files.
void runLoadNexusLogs(const std::string &runinfo, const std::string &dataDir, const double prog_start, const double prog_stop)
Load logs from a nexus file onto the workspace.
static std::string getEntryName(const std::string &filename)
Defines a wrapper around an open file.
const std::string & filename() const
Access the filename.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void setPropertySettings(const std::string &name, std::unique_ptr< IPropertySettings > settings)
void debug(const std::string &msg)
Logs at debug level.
void notice(const std::string &msg)
Logs at notice level.
void warning(const std::string &msg)
Logs at warning level.
void information(const std::string &msg)
Logs at information level.
The concrete, templated class for properties.
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< IEventWorkspace > IEventWorkspace_sptr
shared pointer to Mantid::API::IEventWorkspace
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
bool exists(::NeXus::File &file, const std::string &name)
Based on the current group in the file, does the named sub-entry exist?
static const string MAP_PARAM("MappingFilename")
static const string RUNINFO_PARAM("Filename")
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
@ Input
An input workspace.
@ Output
An output workspace.