20template <
typename T>
struct DescriptorCallback {
21 void apply(std::shared_ptr<T> & ) {}
23template <>
struct DescriptorCallback<Kernel::FileDescriptor> {
24 void apply(std::shared_ptr<Kernel::FileDescriptor> &descriptor) { descriptor->resetStreamToStart(); }
29template <
typename T>
struct DescriptorSetter {
31 void apply(std::shared_ptr<NexusFileLoader> & , std::shared_ptr<T> & ) {}
33template <>
struct DescriptorSetter<Nexus::NexusDescriptor> {
34 void apply(std::shared_ptr<NexusFileLoader> &loader,
const std::shared_ptr<Nexus::NexusDescriptor> &descriptor) {
35 loader->setFileInfo(descriptor);
48template <
typename DescriptorType,
typename FileLoaderType>
49std::pair<IAlgorithm_sptr, int> searchForLoader(
const std::string &filename,
50 const std::multimap<std::string, int> &names, Kernel::Logger &logger) {
51 const auto &factory = AlgorithmFactory::Instance();
54 auto descriptor = std::make_shared<DescriptorType>(filename);
55 DescriptorCallback<DescriptorType> callback;
56 DescriptorSetter<DescriptorType> setdescriptor;
58 auto iend = names.end();
59 for (
auto it = names.begin(); it != iend; ++it) {
60 const std::string &
name = it->first;
61 const int version = it->second;
62 logger.debug() <<
"Checking " <<
name <<
" version " << version <<
'\n';
66 auto alg = std::static_pointer_cast<FileLoaderType>(factory.create(
name, version));
68 const int confidence = alg->confidence(*(descriptor.get()));
69 logger.debug() <<
name <<
" returned with confidence=" << confidence <<
'\n';
70 if (confidence > maxConfidence)
73 maxConfidence = confidence;
75 }
catch (std::exception &exc) {
76 logger.warning() <<
"Checking loader '" <<
name <<
"' raised an error: '" << exc.what() <<
"'. Loader skipped.\n";
78 callback.apply(descriptor);
81 auto nxsLoader = std::dynamic_pointer_cast<NexusFileLoader>(bestLoader);
83 setdescriptor.apply(nxsLoader, descriptor);
85 return {bestLoader, maxConfidence};
101 for (
auto it =
m_names.begin(); it != iend; ++it) {
118 m_log.
debug() <<
"Trying to find loader for '" << filename <<
"'\n";
122 if (H5::H5File::isHdf5(filename)) {
123 std::pair<IAlgorithm_sptr, int> NexusResult =
124 searchForLoader<NexusDescriptor, IFileLoader<NexusDescriptor>>(filename,
m_names[
Nexus],
m_log);
126 if (NexusResult.second < 80) {
130 std::pair<IAlgorithm_sptr, int> LegacyNexusResult =
131 searchForLoader<LegacyNexusDescriptor, IFileLoader<LegacyNexusDescriptor>>(filename,
m_names[
LegacyNexus],
134 if (NexusResult.second > LegacyNexusResult.second)
135 bestLoader = NexusResult.first;
137 bestLoader = LegacyNexusResult.first;
139 bestLoader = NexusResult.first;
142 bestLoader = searchForLoader<LegacyNexusDescriptor, IFileLoader<LegacyNexusDescriptor>>(
145 }
catch (std::exception
const &e) {
146 m_log.
debug() <<
"Error in looking for NeXus files: " << e.what() <<
'\n';
151 bestLoader = searchForLoader<FileDescriptor, IFileLoader<FileDescriptor>>(filename,
m_names[
Generic],
m_log).first;
156 m_log.
debug() <<
"Found loader " << bestLoader->name() <<
" for file '" << filename <<
"'\n";
177 if (!(legacynexus || nexus || nonHDF))
178 throw std::invalid_argument(
"FileLoaderRegistryImpl::canLoad - Algorithm '" + algorithmName +
179 "' is not registered as a loader.");
181 std::multimap<std::string, int> names{{algorithmName, -1}};
185 loader = searchForLoader<LegacyNexusDescriptor, IFileLoader<LegacyNexusDescriptor>>(filename, names,
m_log).first;
186 }
catch (std::exception
const &e) {
187 m_log.
debug() <<
"Error in looking for NeXus files: " << e.what() <<
'\n';
190 if (H5::H5File::isHdf5(filename)) {
192 loader = searchForLoader<NexusDescriptor, IFileLoader<NexusDescriptor>>(filename, names,
m_log).first;
193 }
catch (
const std::invalid_argument &e) {
194 m_log.
debug() <<
"Error in looking for HDF5 based NeXus files: " << e.what() <<
'\n';
198 loader = searchForLoader<FileDescriptor, IFileLoader<FileDescriptor>>(filename, names,
m_log).first;
200 return static_cast<bool>(loader);
221 std::multimap<std::string, int> &typedLoaders) {
224 typedLoaders.erase(
name);
227 auto range = typedLoaders.equal_range(
name);
228 for (
auto ritr = range.first; ritr != range.second; ++ritr) {
229 if (ritr->second == version) {
230 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.
Defines a wrapper around a file whose internal structure can be accessed using the NeXus API.
void debug(const std::string &msg)
Logs at debug level.
std::shared_ptr< IAlgorithm > IAlgorithm_sptr
shared pointer to Mantid::API::IAlgorithm