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 filenames = fileSearcher.findRuns(m_parameters.searchText, m_parameters.extensions);
78 valueForProperty = "";
79 for (auto const &filename : filenames) {
80 valueForProperty += QString::fromStdString(filename) + ",";
81 }
82 valueForProperty.chop(1);
83 }
84 // Else try to run a simple parsing on the string, and find the full paths
85 // individually.
86 else {
87 // Tokenise on ","
88 std::vector<std::string> filestext;
89 filestext = boost::split(filestext, m_parameters.searchText, boost::is_any_of(","));
90
91 // Iterate over tokens.
92 auto it = filestext.begin();
93 for (; it != filestext.end(); ++it) {
94 boost::algorithm::trim(*it);
95 std::string result = fileSearcher.getFullPath(*it);
96 if ((!result.empty()) && std::filesystem::exists(result)) {
97 filenames.emplace_back(*it);
98 valueForProperty += QString::fromStdString(*it) + ",";
99 } else {
100 throw std::invalid_argument("File \"" + (*it) + "\" not found");
101 }
102 }
103 valueForProperty.chop(1);
104 }
105 } catch (std::exception &exc) {
106 error = exc.what();
107 filenames.clear();
108 } catch (...) {
109 error = "An unknown error occurred while trying to locate the file(s). "
110 "Please contact the development team";
111 filenames.clear();
112 }
113
114 auto result = createFindFilesSearchResult(error, filenames, valueForProperty.toStdString());
115 finishSearching(result);
116}
117
124std::pair<std::vector<std::string>, std::string> FindFilesWorker::getFilesFromAlgorithm() {
125 std::vector<std::string> filenames;
127 Mantid::API::AlgorithmManager::Instance().createUnmanaged(m_parameters.algorithmName);
128
129 if (!algorithm)
130 throw std::invalid_argument("Cannot create algorithm " + m_parameters.algorithmName + ".");
131
132 algorithm->initialize();
133 const std::string propName = m_parameters.algorithmProperty;
134 algorithm->setProperty(propName, m_parameters.searchText);
135
136 Property *prop = algorithm->getProperty(propName);
137 std::string valueForProperty = prop->value();
138
139 auto *fileProp = dynamic_cast<FileProperty *>(prop);
140 auto const *multiFileProp = dynamic_cast<MultipleFileProperty *>(prop);
141
142 if (fileProp) {
143 filenames.emplace_back(fileProp->value());
144 } else if (multiFileProp) {
145 // This flattens any summed files to a set of single files so that you lose
146 // the information about
147 // what was summed
148 std::vector<std::vector<std::string>> propertyFilenames = algorithm->getProperty(propName);
149 filenames = VectorHelper::flattenVector(propertyFilenames);
150 }
151
152 return std::make_pair(filenames, valueForProperty);
153}
154
160 // Before emitting our search results, we need to check if we have recieved
161 // a signal to disconnect as this search is no longer relevent. By calling
162 // process events here we ensure that if the result is no longer needed the
163 // emitted signal is just ignored.
164 QCoreApplication::processEvents();
165 emit finished(result);
166 QCoreApplication::sendPostedEvents();
167}
168
180 const std::vector<std::string> &filenames,
181 const std::string &valueForProperty) {
183 results.error = error;
184 results.filenames = filenames;
185 results.valueForProperty = valueForProperty;
186 return results;
187}
188
189void 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:36
std::string getFullPath(const std::string &filename, const bool ignoreDirs=false) const
Return the full path to the file given its name.
std::vector< std::string > 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.