Mantid
Loading...
Searching...
No Matches
FacilityInfo.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7//----------------------------------------------------------------------
8// Includes
9//----------------------------------------------------------------------
10#include <algorithm>
11
15#include "MantidKernel/Logger.h"
17
18#include <boost/algorithm/string.hpp>
19#include <memory>
20
22#include <Poco/DOM/Element.h>
23#include <Poco/DOM/NodeList.h>
24#include <Poco/DOM/Text.h>
25
26using Poco::XML::Element;
27
28namespace Mantid::Kernel {
29
30namespace {
32Logger g_log("FacilityInfo");
33} // namespace
34
39FacilityInfo::FacilityInfo(const Poco::XML::Element *elem)
40 : m_catalogs(elem), m_name(elem->getAttribute("name")), m_timezone(), m_zeroPadding(0), m_delimiter(),
41 m_extensions(), m_archiveSearch(), m_instruments(), m_noFilePrefix(), m_multiFileLimit(100) {
42
43 // Fill the various fields from the XML
44 fillZeroPadding(elem);
45 fillDelimiter(elem);
46 fillExtensions(elem);
47 fillArchiveNames(elem);
48 fillTimezone(elem);
49 fillNoFilePrefix(elem);
51 fillInstruments(elem); // Make sure this is last as it picks up some defaults
52 // that are set above
53}
54
56void FacilityInfo::fillZeroPadding(const Poco::XML::Element *elem) {
57 std::string paddingStr = elem->getAttribute("zeropadding");
58 if (paddingStr.empty() || !Mantid::Kernel::Strings::convert(paddingStr, m_zeroPadding)) {
59 m_zeroPadding = 0;
60 }
61}
62
64void FacilityInfo::fillNoFilePrefix(const Poco::XML::Element *elem) {
65 std::string noFilePrefixStr = elem->getAttribute("nofileprefix");
66 m_noFilePrefix = (noFilePrefixStr == "True");
67}
68
70void FacilityInfo::fillMultiFileLimit(const Poco::XML::Element *elem) {
71 const std::string multiFileLimitStr = elem->getAttribute("multifilelimit");
72 if (!multiFileLimitStr.empty()) {
73 size_t limit;
74 if (Mantid::Kernel::Strings::convert(multiFileLimitStr, limit)) {
75 m_multiFileLimit = limit;
76 }
77 }
78}
79
81void FacilityInfo::fillDelimiter(const Poco::XML::Element *elem) {
82 // The string to separate the instrument name and the run number.
83 m_delimiter = elem->getAttribute("delimiter");
84}
85
87void FacilityInfo::fillExtensions(const Poco::XML::Element *elem) {
88 std::string extsStr = elem->getAttribute("FileExtensions");
89 if (extsStr.empty()) {
90 g_log.error("No file extensions defined");
91 throw std::runtime_error("No file extensions defined");
92 }
95 for (const auto &ext : exts) {
96 addExtension(ext);
97 }
98}
99
104void FacilityInfo::addExtension(const std::string &ext) {
105 auto it = std::find(m_extensions.begin(), m_extensions.end(), ext);
106 if (it == m_extensions.end())
107 m_extensions.emplace_back(ext);
108}
109
111void FacilityInfo::fillArchiveNames(const Poco::XML::Element *elem) {
112 Poco::AutoPtr<Poco::XML::NodeList> pNL_archives = elem->getElementsByTagName("archive");
113 if (pNL_archives->length() > 1) {
114 g_log.error("Facility must have only one archive tag");
115 throw std::runtime_error("Facility must have only one archive tag");
116 } else if (pNL_archives->length() == 1) {
117 Poco::AutoPtr<Poco::XML::NodeList> pNL_interfaces = elem->getElementsByTagName("archiveSearch");
118 for (unsigned int i = 0; i < pNL_interfaces->length(); ++i) {
119 auto *elemenent = dynamic_cast<Poco::XML::Element *>(pNL_interfaces->item(i));
120 std::string plugin = elemenent->getAttribute("plugin");
121 if (!plugin.empty()) {
122 m_archiveSearch.emplace_back(plugin);
123 }
124 }
125 }
126}
127
128void FacilityInfo::fillTimezone(const Poco::XML::Element *elem) {
129 Poco::AutoPtr<Poco::XML::NodeList> pNL_timezones = elem->getElementsByTagName("timezone");
130 if (pNL_timezones->length() == 0) {
131 g_log.notice() << "No timezone specified for " << m_name << " in Facilities.xml\n";
132 } else if (pNL_timezones->length() == 1) {
133 pNL_timezones = pNL_timezones->item(0)->childNodes();
134 if (pNL_timezones->length() > 0) {
135 auto *txt = dynamic_cast<Poco::XML::Text *>(pNL_timezones->item(0));
136 m_timezone = txt->getData();
137 }
138 } else {
139 throw std::runtime_error("Facility " + m_name + " has more than one timezone specified");
140 }
141}
142
144void FacilityInfo::fillInstruments(const Poco::XML::Element *elem) {
145 Poco::AutoPtr<Poco::XML::NodeList> pNL_instrument = elem->getElementsByTagName("instrument");
146 unsigned long n = pNL_instrument->length();
147 m_instruments.reserve(n);
148
149 for (unsigned long i = 0; i < n; ++i) {
150 auto *elemenent = dynamic_cast<Poco::XML::Element *>(pNL_instrument->item(i));
151 if (elemenent) {
152 try {
153 InstrumentInfo instr(this, elemenent);
154 m_instruments.emplace_back(instr);
155 } catch (std::runtime_error &e) { /*skip this instrument*/
156 g_log.warning("Failed to load instument for: " + m_name + ": " + e.what());
157 }
158 }
159 }
160
161 if (m_instruments.empty()) {
162 throw std::runtime_error("Facility " + m_name + " does not have any instruments;");
163 }
164}
165
172const InstrumentInfo &FacilityInfo::instrument(std::string iName) const {
173 if (iName.empty()) {
174 iName = ConfigService::Instance().getString("default.instrument");
175 g_log.debug() << "Blank instrument specified, using default instrument of " << iName << ".\n";
176 if (iName.empty()) {
177 return m_instruments.front();
178 }
179 }
180
181 auto instrument = std::find_if(m_instruments.cbegin(), m_instruments.cend(),
182 [&iName](const auto &inst) { return boost::iequals(inst.name(), iName); });
183
184 // if unsuccessful try lookup by short name
185 if (instrument == m_instruments.cend()) {
186 instrument = std::find_if(m_instruments.cbegin(), m_instruments.cend(),
187 [&iName](const auto &inst) { return boost::iequals(inst.shortName(), iName); });
188 }
189
190 if (instrument != m_instruments.cend()) {
191 g_log.debug() << "Instrument '" << iName << "' found as " << instrument->name() << " at " << name() << ".\n";
192 return *instrument;
193 }
194
195 g_log.debug("Instrument " + iName + " not found in facility " + name());
196 throw Exception::NotFoundError("FacilityInfo", iName);
197}
198
204std::vector<InstrumentInfo> FacilityInfo::instruments(const std::string &tech) const {
205 std::vector<InstrumentInfo> out;
206 auto it = m_instruments.begin();
207 for (; it != m_instruments.end(); ++it) {
208 if (it->techniques().count(tech)) {
209 out.emplace_back(*it);
210 }
211 }
212 return out;
213}
214
215} // namespace Mantid::Kernel
Exception for when an item is not found in a collection.
Definition: Exception.h:145
std::vector< std::string > m_extensions
file extensions in order of preference
Definition: FacilityInfo.h:92
std::string m_timezone
Timezone designation in pytz.
Definition: FacilityInfo.h:89
void fillMultiFileLimit(const Poco::XML::Element *elem)
Called from constructor to fill the multifile limit.
const std::vector< InstrumentInfo > & instruments() const
Returns a list of instruments of this facility.
Definition: FacilityInfo.h:58
void fillNoFilePrefix(const Poco::XML::Element *elem)
Called from constructor to fill the noFilePrefix flag.
void fillInstruments(const Poco::XML::Element *elem)
Called from constructor to fill instrument list.
void fillTimezone(const Poco::XML::Element *elem)
FacilityInfo(const Poco::XML::Element *elem)
Constructor.
const std::string m_name
facility name
Definition: FacilityInfo.h:88
bool m_noFilePrefix
flag indicating if prefix is required in file names
Definition: FacilityInfo.h:95
int m_zeroPadding
default zero padding for this facility
Definition: FacilityInfo.h:90
void addExtension(const std::string &ext)
Add new extension.
void fillZeroPadding(const Poco::XML::Element *elem)
Called from constructor to fill zero padding field.
std::vector< std::string > m_archiveSearch
names of the archive search interface
Definition: FacilityInfo.h:93
std::vector< InstrumentInfo > m_instruments
list of instruments of this facility
Definition: FacilityInfo.h:94
void fillDelimiter(const Poco::XML::Element *elem)
Called from constructor to fill default delimiter.
size_t m_multiFileLimit
the multiple file limit
Definition: FacilityInfo.h:96
const std::string & name() const
Return the name of the facility.
Definition: FacilityInfo.h:41
void fillArchiveNames(const Poco::XML::Element *elem)
Called from constructor to fill archive interface names.
std::string m_delimiter
default delimiter between instrument name and run number
Definition: FacilityInfo.h:91
const InstrumentInfo & instrument(std::string iName="") const
Returns instruments with given name.
void fillExtensions(const Poco::XML::Element *elem)
Called from constructor to fill file extensions.
A class that holds information about an instrument.
const std::string name() const
Return the name of the instrument.
void debug(const std::string &msg)
Logs at debug level.
Definition: Logger.cpp:114
void notice(const std::string &msg)
Logs at notice level.
Definition: Logger.cpp:95
void error(const std::string &msg)
Logs at error level.
Definition: Logger.cpp:77
void warning(const std::string &msg)
Logs at warning level.
Definition: Logger.cpp:86
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
@ TOK_IGNORE_EMPTY
ignore empty tokens
@ TOK_TRIM
remove leading and trailing whitespace from tokens
int convert(const std::string &A, T &out)
Convert a string into a number.
Definition: Strings.cpp:665