19template <
typename T>
struct DescriptorCallback {
20 void apply(std::shared_ptr<T> & ) {}
22template <>
struct DescriptorCallback<Kernel::FileDescriptor> {
23 void apply(std::shared_ptr<Kernel::FileDescriptor> &descriptor) { descriptor->resetStreamToStart(); }
28template <
typename T>
struct DescriptorSetter {
30 void apply(std::shared_ptr<NexusFileLoader> & , std::shared_ptr<T> & ) {}
32template <>
struct DescriptorSetter<Kernel::NexusHDF5Descriptor> {
33 void apply(std::shared_ptr<NexusFileLoader> &loader,
const std::shared_ptr<Kernel::NexusHDF5Descriptor> &descriptor) {
34 loader->setFileInfo(descriptor);
47template <
typename DescriptorType,
typename FileLoaderType>
48const IAlgorithm_sptr searchForLoader(
const std::string &filename,
const std::multimap<std::string, int> &names,
49 Kernel::Logger &logger) {
53 auto descriptor = std::make_shared<DescriptorType>(filename);
54 DescriptorCallback<DescriptorType> callback;
55 DescriptorSetter<DescriptorType> setdescriptor;
57 auto iend = names.end();
58 for (
auto it = names.begin(); it != iend; ++it) {
59 const std::string &name = it->first;
60 const int version = it->second;
61 logger.debug() <<
"Checking " << name <<
" version " << version <<
'\n';
65 auto alg = std::static_pointer_cast<FileLoaderType>(factory.create(name, version));
67 const int confidence = alg->confidence(*(descriptor.get()));
68 logger.debug() << name <<
" returned with confidence=" << confidence <<
'\n';
69 if (confidence > maxConfidence)
72 maxConfidence = confidence;
74 }
catch (std::exception &exc) {
75 logger.warning() <<
"Checking loader '" << name <<
"' raised an error: '" << exc.what() <<
"'. Loader skipped.\n";
77 callback.apply(descriptor);
80 auto nxsLoader = std::dynamic_pointer_cast<NexusFileLoader>(bestLoader);
82 setdescriptor.apply(nxsLoader, descriptor);
100 for (
auto it =
m_names.begin(); it != iend; ++it) {
117 m_log.
debug() <<
"Trying to find loader for '" << filename <<
"'\n";
121 m_log.
debug() << filename <<
" looks like a Nexus file. Checking registered Nexus loaders\n";
127 searchForLoader<NexusHDF5Descriptor, IFileLoader<NexusHDF5Descriptor>>(filename,
m_names[
NexusHDF5],
m_log);
128 }
catch (
const std::invalid_argument &e) {
129 m_log.
debug() <<
"Error in looking for HDF5 based NeXus files: " << e.what() <<
'\n';
135 bestLoader = searchForLoader<NexusDescriptor, IFileLoader<NexusDescriptor>>(filename,
m_names[
Nexus],
m_log);
138 m_log.
debug() <<
"Checking registered non-HDF loaders\n";
139 bestLoader = searchForLoader<FileDescriptor, IFileLoader<FileDescriptor>>(filename,
m_names[
Generic],
m_log);
145 m_log.
debug() <<
"Found loader " << bestLoader->name() <<
" for file '" << filename <<
"'\n";
166 if (!(nexus || nexusHDF5 || nonHDF))
167 throw std::invalid_argument(
"FileLoaderRegistryImpl::canLoad - Algorithm '" + algorithmName +
168 "' is not registered as a loader.");
170 std::multimap<std::string, int> names{{algorithmName, -1}};
174 loader = searchForLoader<NexusDescriptor, IFileLoader<NexusDescriptor>>(filename, names,
m_log);
176 }
else if (nexusHDF5) {
179 loader = searchForLoader<NexusHDF5Descriptor, IFileLoader<NexusHDF5Descriptor>>(filename, names,
m_log);
180 }
catch (
const std::invalid_argument &e) {
181 m_log.
debug() <<
"Error in looking for HDF5 based NeXus files: " << e.what() <<
'\n';
185 loader = searchForLoader<FileDescriptor, IFileLoader<FileDescriptor>>(filename, names,
m_log);
187 return static_cast<bool>(loader);
208 std::multimap<std::string, int> &typedLoaders) {
211 typedLoaders.erase(name);
214 auto range = typedLoaders.equal_range(name);
215 for (
auto ritr = range.first; ritr != range.second; ++ritr) {
216 if (ritr->second == version) {
217 typedLoaders.erase(ritr);
std::array< std::multimap< std::string, int >, 3 > m_names
The list of names.
const std::shared_ptr< IAlgorithm > chooseLoader(const std::string &filename) const
Returns the name of an Algorithm that can load the given filename.
FileLoaderRegistryImpl()
Default constructor (for singleton)
void unsubscribe(const std::string &name, const int version=-1)
Unsubscribe a named algorithm and version from the loader registration.
bool canLoad(const std::string &algorithmName, const std::string &filename) const
Checks whether the given algorithm can load the file.
void removeAlgorithm(const std::string &name, const int version, std::multimap< std::string, int > &typedLoaders)
Remove a named algorithm & version from the given map.
Kernel::Logger m_log
Reference to a logger.
~FileLoaderRegistryImpl()
Destructor.
Exception for when an item is not found in a collection.
Defines a wrapper around an open file.
void debug(const std::string &msg)
Logs at debug level.
Defines a wrapper around a file whose internal structure can be accessed using the NeXus API.
static bool isReadable(const std::string &filename, const Version version=AnyVersion)
Returns true if the file is considered to store data in a hierarchy.
static bool isReadable(const std::string &filename)
Returns true if the file is considered to store data in a hierarchy.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< IAlgorithm > IAlgorithm_sptr
shared pointer to Mantid::API::IAlgorithm