Mantid
Loading...
Searching...
No Matches
FindFilesWorker.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 +
15
16#include <QApplication>
17#include <boost/algorithm/string.hpp>
18#include <filesystem>
19
20#include <utility>
21
22using namespace Mantid::Kernel;
23using namespace Mantid::API;
24using namespace MantidQt::API;
25
32 : QRunnable(), m_parameters(std::move(parameters)) {
33 qRegisterMetaType<MantidQt::API::FindFilesSearchResults>("FindFilesSearchResults");
34}
35
49 // Reset result member vars.
50 std::string error;
51 std::vector<std::string> filenames;
52 QString valueForProperty;
53
54 if (m_parameters.searchText.empty()) {
56 error = "";
57 else
58 error = "No files specified.";
59
60 const auto result = createFindFilesSearchResult(error, filenames, valueForProperty.toStdString());
61 finishSearching(result);
62 return;
63 }
64
65 const Mantid::API::FileFinderImpl &fileSearcher = Mantid::API::FileFinder::Instance();
66
67 try {
68 // Use the property of the algorithm to find files, if one has been
69 // specified.
70 if (m_parameters.algorithmName.length() != 0 && m_parameters.algorithmProperty.length() != 0) {
71 auto searchResult = getFilesFromAlgorithm();
72 filenames = std::get<0>(searchResult);
73 valueForProperty = QString::fromStdString(std::get<1>(searchResult));
74 }
75 // Else if we are loading run files, then use findRuns.
76 else if (m_parameters.isForRunFiles) {
77 auto paths = fileSearcher.findRuns(m_parameters.searchText, m_parameters.extensions);
78 std::transform(paths.begin(), paths.end(), std::back_inserter(filenames),
79 [](const auto &p) { return p.string(); });
80 valueForProperty = "";
81 for (auto const &filename : filenames) {
82 valueForProperty += QString::fromStdString(filename) + ",";
83 }
84 valueForProperty.chop(1);
85 }
86 // Else try to run a simple parsing on the string, and find the full paths
87 // individually.
88 else {
89 // Tokenise on ","
90 std::vector<std::string> filestext;
91 filestext = boost::split(filestext, m_parameters.searchText, boost::is_any_of(","));
92
93 // Iterate over tokens.
94 auto it = filestext.begin();
95 for (; it != filestext.end(); ++it) {
96 boost::algorithm::trim(*it);
97 auto result = fileSearcher.getFullPath(*it);
98 if ((!result.empty()) && std::filesystem::exists(result)) {
99 filenames.emplace_back(*it);
100 valueForProperty += QString::fromStdString(*it) + ",";
101 } else {
102 throw std::invalid_argument("File \"" + (*it) + "\" not found");
103 }
104 }
105 valueForProperty.chop(1);
106 }
107 } catch (std::exception &exc) {
108 error = exc.what();
109 filenames.clear();
110 } catch (...) {
111 error = "An unknown error occurred while trying to locate the file(s). "
112 "Please contact the development team";
113 filenames.clear();
114 }
115
116 auto result = createFindFilesSearchResult(error, filenames, valueForProperty.toStdString());
117 finishSearching(result);
118}
119
126std::pair<std::vector<std::string>, std::string> FindFilesWorker::getFilesFromAlgorithm() {
127 std::vector<std::string> filenames;
129 Mantid::API::AlgorithmManager::Instance().createUnmanaged(m_parameters.algorithmName);
130
131 if (!algorithm)
132 throw std::invalid_argument("Cannot create algorithm " + m_parameters.algorithmName + ".");
133
134 algorithm->initialize();
135 const std::string propName = m_parameters.algorithmProperty;
136 algorithm->setProperty(propName, m_parameters.searchText);
137
138 Property *prop = algorithm->getProperty(propName);
139 std::string valueForProperty = prop->value();
140
141 auto *fileProp = dynamic_cast<FileProperty *>(prop);
142 auto const *multiFileProp = dynamic_cast<MultipleFileProperty *>(prop);
143
144 if (fileProp) {
145 filenames.emplace_back(fileProp->value());
146 } else if (multiFileProp) {
147 // This flattens any summed files to a set of single files so that you lose
148 // the information about
149 // what was summed
150 std::vector<std::vector<std::string>> propertyFilenames = algorithm->getProperty(propName);
151 filenames = VectorHelper::flattenVector(propertyFilenames);
152 }
153
154 return std::make_pair(filenames, valueForProperty);
155}
156
162 // Before emitting our search results, we need to check if we have recieved
163 // a signal to disconnect as this search is no longer relevent. By calling
164 // process events here we ensure that if the result is no longer needed the
165 // emitted signal is just ignored.
166 QCoreApplication::processEvents();
167 emit finished(result);
168 QCoreApplication::sendPostedEvents();
169}
170
182 const std::vector<std::string> &filenames,
183 const std::string &valueForProperty) {
185 results.error = error;
186 results.filenames = filenames;
187 results.valueForProperty = valueForProperty;
188 return results;
189}
190
191void FindFilesWorker::disconnectWorker() { this->disconnect(); }
double error
FindFilesWorker(FindFilesSearchParameters parameters)
Constructor.
std::pair< std::vector< std::string >, std::string > getFilesFromAlgorithm()
Use the specified algorithm and property to find files instead of using the FileFinder.
FindFilesSearchParameters m_parameters
Struct to hold the parameters of the search.
void finished(const FindFilesSearchResults &)
Signal emitted after the search is finished, regardless of whether any file was found.
FindFilesSearchResults createFindFilesSearchResult(const std::string &error, const std::vector< std::string > &filenames, const std::string &valueForProperty)
Helper method to create a search result object.
virtual void run() override
Override parent class run().
void finishSearching(const FindFilesSearchResults &result)
Emit search result if required.
This class finds data files given an instrument name (optionally) and a run number.
Definition FileFinder.h:37
std::filesystem::path getFullPath(const std::string &filename, const bool ignoreDirs=false) const
Return the full path to the file given its name.
std::vector< std::filesystem::path > findRuns(const std::string &hintstr, const std::vector< std::string > &exts={}, const bool useExtsOnly=false) const
Find a list of files file given a hint.
A specialized class for dealing with file properties.
A property to allow a user to specify multiple files to load.
Base class for properties.
Definition Property.h:94
virtual std::string value() const =0
Returns the value of the property as a string.
std::shared_ptr< IAlgorithm > IAlgorithm_sptr
shared pointer to Mantid::API::IAlgorithm
std::vector< T > flattenVector(const std::vector< std::vector< T > > &v)
A convenience function to "flatten" the given vector of vectors into a single vector.
STL namespace.
POD struct to hold details about the parameters of a file search.
bool isForRunFiles
Whether the search is for experimental run data.
std::string algorithmName
The name of the algorithm to load files with.
std::vector< std::string > extensions
any additional extensions that we want to consider
bool isOptional
Whether the search is optional (i.e. a failed search means no error).
std::string algorithmProperty
The name of the property on the algorithm to use for searching.
std::string searchText
The text to use as a hint to search for files.
POD struct to hold details about the results of a file search.
std::vector< std::string > filenames
A list of filenames that matched the search hint.
std::string valueForProperty
The value to set the algorithm property to.
std::string error
A string repsresenting the error message. Empty if the search succeded.