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>
26#include <Poco/SAX/InputSource.h>
60 const std::string &filename = descriptor.
filename();
61 if (filename.size() > 12 ? (filename.compare(filename.size() - 12, 12,
"_runinfo.xml") == 0) :
false)
74 "The name of the runinfo file to read, including its full or relative "
79 "File containing the pixel mapping (DAS pixels to pixel IDs) file "
80 "(typically INSTRUMENT_TS_YYYY_MM_DD.dat). The filename will be found "
81 "automatically if not specified.");
82 auto mustBePositive = std::make_shared<BoundedValidator<int>>();
83 mustBePositive->setLower(1);
85 "If loading the file by sections ('chunks'), this is the "
86 "section number of this execution of the algorithm.");
88 "If loading the file by sections ('chunks'), this is the "
89 "total number of sections.");
94 std::vector<std::string> propOptions{
"Auto",
"Serial",
"Parallel"};
95 declareProperty(
"UseParallelProcessing",
"Auto", std::make_shared<StringListValidator>(propOptions),
96 "Use multiple cores for loading the data?\n"
97 " Auto: Use serial loading for small data sets, parallel "
98 "for large data sets.\n"
99 " Serial: Use a single core.\n"
100 " Parallel: Use all available cores.");
103 "Load the monitors from the file.");
106 "An output workspace.");
115 int chunkNumber = this->
getProperty(
"ChunkNumber");
120 if (chunkNumber > chunkTotal)
121 throw std::out_of_range(
"ChunkNumber cannot be larger than TotalChunks");
123 string useParallel = this->
getProperty(
"UseParallelProcessing");
124 string wsname = this->
getProperty(
"OutputWorkspace");
125 bool loadmonitors = this->
getProperty(
"LoadMonitors");
129 vector<string> eventFilenames;
132 prog.
doReport(
"parsed runinfo file");
135 size_t numFiles = eventFilenames.size() + 1;
138 double prog_start = .1;
139 double prog_delta = (1. - prog_start) /
static_cast<double>(numFiles);
144 for (
size_t i = 0; i < eventFilenames.size(); i++) {
146 temp_wsname = wsname;
148 temp_wsname =
"__" + wsname +
"_temp__";
151 alg->setProperty(
"EventFilename", dataDir + eventFilenames[i]);
152 alg->setProperty(
"MappingFilename", mapfile);
153 alg->setProperty(
"ChunkNumber", chunkNumber);
154 alg->setProperty(
"TotalChunks", chunkTotal);
155 alg->setProperty(
"UseParallelProcessing", useParallel);
156 alg->setPropertyValue(
"OutputWorkspace", temp_wsname);
157 alg->executeAsChildAlg();
158 prog_start += prog_delta;
165 Run &run = tempws->mutableRun();
176 this->
runLoadNexusLogs(runinfo, dataDir, prog_start, prog_start + prog_delta);
177 prog_start += prog_delta;
197 eventFilenames.clear();
200 std::filesystem::path runinfoPath(runinfo);
202 std::filesystem::path dirPath(runinfoPath.parent_path());
203 dataDir = std::filesystem::absolute(dirPath).string() +
"/";
204 g_log.
debug() <<
"Data directory \"" << dataDir <<
"\"\n";
206 std::ifstream in(runinfo.c_str());
207 Poco::XML::InputSource src(in);
209 Poco::XML::DOMParser parser;
210 Poco::AutoPtr<Poco::XML::Document> pDoc = parser.parse(&src);
212 Poco::XML::NodeIterator it(pDoc, Poco::XML::NodeFilter::SHOW_ELEMENT);
213 Poco::XML::Node *pNode = it.nextNode();
215 if (pNode->nodeName() ==
"RunInfo")
217 pNode = pNode->firstChild();
219 if (pNode->nodeName() ==
"FileList") {
220 pNode = pNode->firstChild();
222 if (pNode->nodeName() ==
"DataList") {
223 pNode = pNode->firstChild();
225 if (pNode->nodeName() ==
"scattering") {
226 auto *element =
static_cast<Poco::XML::Element *
>(pNode);
227 eventFilenames.emplace_back(element->getAttribute(
"name"));
229 pNode = pNode->nextSibling();
232 pNode = pNode->nextSibling();
235 pNode = pNode->nextSibling();
238 pNode = pNode->nextSibling();
242 if (eventFilenames.size() == 1) {
243 g_log.
debug() <<
"Found 1 event file: \"" << eventFilenames[0] <<
"\"\n";
245 g_log.
debug() <<
"Found " << eventFilenames.size() <<
" event files:";
246 for (
const auto &eventFilename : eventFilenames) {
247 g_log.
debug() <<
"\"" << eventFilename <<
"\" ";
262 const double prog_stop) {
264 string shortName = runinfo.substr(runinfo.find_last_of(
"/\\") + 1);
265 const string runInfoFileExt =
"_runinfo.xml";
266 if (
const auto &pos = shortName.find(runInfoFileExt); pos != string::npos) {
267 shortName.resize(pos);
269 g_log.
debug() <<
"SHORTNAME = \"" << shortName <<
"\"\n";
272 vector<string> possibilities;
273 possibilities.emplace_back(dataDir + shortName +
"_event.nxs");
274 possibilities.emplace_back(dataDir + shortName +
"_histo.nxs");
275 possibilities.emplace_back(dataDir + shortName +
".nxs");
276 possibilities.emplace_back(dataDir +
"../NeXus/" + shortName +
"_event.nxs");
277 possibilities.emplace_back(dataDir +
"../NeXus/" + shortName +
"_histo.nxs");
278 possibilities.emplace_back(dataDir +
"../NeXus/" + shortName +
".nxs");
281 bool loadedLogs =
false;
282 for (
const auto &possibility : possibilities) {
284 if (std::filesystem::exists(possibility)) {
288 alg->setProperty(
"Filename", possibility);
289 alg->setProperty(
"OverwriteLogs",
false);
290 alg->executeAsChildAlg();
300 g_log.
notice() <<
"Did not find a nexus file to load logs from\n";
310 std::string mon_wsname = this->
getProperty(
"OutputWorkspace");
311 mon_wsname.append(
"_monitors");
316 alg->setPropertyValue(
"OutputWorkspace", mon_wsname);
317 alg->executeAsChildAlg();
320 "Monitors from the Event NeXus file");
324 }
catch (std::exception &e) {
325 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.
void deprecatedDate(const std::string &)
The date the algorithm was deprecated on.
@ 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 Nexus::NexusDescriptor *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
LoadPreNexus()
Default constructor.
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.
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
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.