Mantid
Loading...
Searching...
No Matches
SampleEnvironmentFactory.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 +
11
12#include "Poco/File.h"
13#include "Poco/Path.h"
14
15#include <fstream>
16#include <utility>
17
18namespace Mantid::DataHandling {
19
20//------------------------------------------------------------------------------
21// Anonyomous
22//------------------------------------------------------------------------------
23namespace {
24// static logger object
25Mantid::Kernel::Logger g_log("SampleEnvironment");
26
27// Typedef for cache
28using SampleEnvironmentSpecCache = std::unordered_map<std::string, SampleEnvironmentSpec_uptr>;
29
35SampleEnvironmentSpecCache &retrieveSpecCache() {
36 static SampleEnvironmentSpecCache cache;
37 return cache;
38}
39
47std::string createCacheKey(const std::string &facility, const std::string &instrument, const std::string &specName) {
48 return facility + "/" + instrument + "/" + specName;
49}
50} // namespace
51
52//------------------------------------------------------------------------------
53// SampleEnvironmentFactory
54//------------------------------------------------------------------------------
61 : m_finder(std::move(specFinder)) {}
62
73 const std::string &instrument,
74 const std::string &specName,
75 const std::string &canName) {
76 assert(m_finder);
77 auto &specCache = retrieveSpecCache();
78 auto cacheKey = createCacheKey(facility, instrument, specName);
79
80 SampleEnvironmentSpec *spec(nullptr);
81 auto iter = specCache.find(cacheKey);
82 if (iter != specCache.end()) {
83 spec = iter->second.get();
84 } else {
85 auto specUPtr = m_finder->find(facility, instrument, specName);
86 spec = specUPtr.get();
87 specCache.emplace(cacheKey, std::move(specUPtr));
88 }
89 return spec->buildEnvironment(canName);
90}
91
95size_t SampleEnvironmentFactory::cacheSize() const { return retrieveSpecCache().size(); }
96
100void SampleEnvironmentFactory::clearCache() { retrieveSpecCache().clear(); }
101
109 const std::string &filepath) const {
110 assert(m_finder);
111 Poco::File fullpath(Poco::Path(filepath, filename + ".xml"));
112 return m_finder->parseSpec(filename, fullpath.path());
113}
114
115//------------------------------------------------------------------------------
116// SampleEnvironmentSpecFileFinder
117//------------------------------------------------------------------------------
118
128 : m_rootDirs(std::move(directories)) {
129 if (m_rootDirs.empty()) {
130 throw std::invalid_argument("SampleEnvironmentSpecFileFinder() - Empty directory search list.");
131 }
132}
133
142 const std::string &instrument,
143 const std::string &name) const {
144 using Poco::File;
145 using Poco::Path;
146
147 Path relpath_instr(facility);
148 relpath_instr.append(instrument).append(name + m_fileext);
149
150 Path relpath_facil(facility);
151 relpath_facil.append(name + m_fileext);
152
153 // check for the instrument environment, then facility environment
154 for (const auto &rel_path : {relpath_instr, relpath_facil}) {
155 for (const auto &prefixStr : m_rootDirs) {
156 Path prefix(prefixStr);
157 // Ensure the path is a directory (note that this does not create it!)
158 prefix.makeDirectory();
159 File fullpath(Poco::Path(prefix, rel_path));
160 if (fullpath.exists()) {
161 g_log.debug() << "Found environment at \"" << fullpath.path() << "\"\n";
162 return parseSpec(name, fullpath.path());
163 } else {
164 g_log.debug() << "Failed to find environment at \"" << fullpath.path() << "\"\n";
165 }
166 }
167 }
168
169 // no match if we get here
170 std::ostringstream msg;
171 msg << "Unable to find sample environment file '" << name << "' for facility '" << facility << "' and instrument '"
172 << instrument << "'";
173 throw std::runtime_error(msg.str());
174}
175
183 const std::string &filename) const {
184 std::ifstream reader(filename, std::ios_base::in);
185 if (!reader) {
186 throw std::runtime_error("SampleEnvironmentSpecFileFinder() - Error accessing file '" + filename + "'");
187 }
189 return parser.parse(name, filename, reader);
190}
191
192} // namespace Mantid::DataHandling
SampleEnvironmentSpec_uptr parseSpec(const std::string &filename, const std::string &filepath) const
Calls SampleEnvironmentSpecFileFinder::parseSpec.
void clearCache()
Clear the cache of SampleEnvironmentSpec objects.
Geometry::SampleEnvironment_uptr create(const std::string &facility, const std::string &instrument, const std::string &specName, const std::string &canName)
Create a new SampleEnvironment instance from the given specification and can.
SampleEnvironmentSpecFileFinder(std::vector< std::string > directories)
Constructor accepting a list of directories to search.
SampleEnvironmentSpec_uptr parseSpec(const std::string &name, const std::string &filename) const override
Parses the specification from the given file.
SampleEnvironmentSpec_uptr find(const std::string &facility, const std::string &instrument, const std::string &name) const override
Find a named specification in a file.
Read an XML definition of a SampleEnvironmentSpec and produce a new SampleEnvironmentSpec object.
SampleEnvironmentSpec_uptr parse(const std::string &name, const std::string &filename, std::istream &istr)
Takes a stream that is assumed to contain a single complete SampleEnvironmentSpec definition,...
Defines the properties of a named SampleEnvironment setup.
Geometry::SampleEnvironment_uptr buildEnvironment(const std::string &canID) const
Build a new SampleEnvironment instance from a given can ID.
The Logger class is in charge of the publishing messages from the framework through various channels.
Definition: Logger.h:52
void debug(const std::string &msg)
Logs at debug level.
Definition: Logger.cpp:114
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::unique_ptr< SampleEnvironmentSpec > SampleEnvironmentSpec_uptr
unique_ptr to a SampleEnvironmentSpec
std::unique_ptr< ISampleEnvironmentSpecFinder > ISampleEnvironmentSpecFinder_uptr
std::unique_ptr< SampleEnvironment > SampleEnvironment_uptr
STL namespace.