Mantid
Loading...
Searching...
No Matches
ISISInstrumentDataCache.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2024 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#include "MantidKernel/Logger.h"
12#include <algorithm>
13#include <fstream>
14#include <json/reader.h>
15
18
19namespace {
20Mantid::Kernel::Logger g_log("ISISInstrumentDataCache");
21} // namespace
22
23std::string ISISInstrumentDataCache::getFileParentDirectoryPath(const std::string &fileName) const {
24 g_log.debug() << "ISISInstrumentDataCache::getFileParentDirectoryPath(" << fileName << ")" << std::endl;
25
26 auto [instrumentInfo, runNumber] = validateInstrumentAndNumber(fileName);
27
28 auto const [jsonPath, json] = openCacheJsonFile(instrumentInfo);
29
30 std::string relativePath = json[runNumber].asString();
31
32 if (relativePath.empty()) {
33 throw std::invalid_argument("Run number " + runNumber + " not found in index file " + jsonPath.filename().string() +
34 ".");
35 }
36
37 std::filesystem::path dirPath = jsonPath.parent_path() / relativePath;
38 std::string dirPathString = dirPath.make_preferred().string();
39
40 g_log.debug() << "Found path to search: " << dirPathString << std::endl;
41 return dirPathString;
42}
43
49std::vector<std::string> ISISInstrumentDataCache::getRunNumbersInCache(const std::string &instrumentName) const {
50 const auto &json = openCacheJsonFile(getInstrumentFromName(instrumentName)).second;
51 return json.getMemberNames();
52}
53
60std::pair<std::filesystem::path, Json::Value>
62 // Open index json file
63 std::filesystem::path jsonPath = makeIndexFilePath(instrument.name());
64 std::ifstream ifstrm{jsonPath};
65 if (!ifstrm.is_open()) { // Try again with shortname
66 jsonPath = makeIndexFilePath(instrument.shortName());
67 ifstrm.open(jsonPath);
68 if (!ifstrm.is_open()) {
69 throw std::invalid_argument("Could not open index file: " + jsonPath.string());
70 }
71 }
72 // Read directory path from json file
73 Json::Value json;
74 ifstrm >> json;
75 g_log.debug() << "Opened instrument index file: " << jsonPath << std::endl;
76 return {jsonPath, json};
77}
78
79std::pair<InstrumentInfo, std::string>
80ISISInstrumentDataCache::validateInstrumentAndNumber(const std::string &fileName) const {
81
82 // Check if suffix eg. -add is present in filename
83 std::string fileNameCopy = fileName;
84 std::string suffix = FileFinder::Instance().extractAllowedSuffix(fileNameCopy);
85 if (!suffix.empty()) {
86 throw std::invalid_argument("Unsuported format: Suffix detected: " + suffix);
87 }
88
89 auto [instrName, runNumber] = splitIntoInstrumentAndNumber(fileName);
90
91 if (runNumber.empty() || !std::all_of(runNumber.begin(), runNumber.end(), ::isdigit)) { // Check run number
92 throw std::invalid_argument("Filename not in correct format.");
93 }
94 runNumber.erase(0, runNumber.find_first_not_of('0')); // Remove padding zeros
95
96 return std::pair(getInstrumentFromName(instrName), runNumber);
97}
98
100 try { // Expand instrument name
101 auto instrumentInfo = FileFinder::Instance().getInstrument(instName, false);
102 return instrumentInfo;
103 } catch (const Kernel::Exception::NotFoundError &) {
104 throw std::invalid_argument("Instrument name not recognized.");
105 }
106}
107
108std::filesystem::path ISISInstrumentDataCache::makeIndexFilePath(const std::string &instrumentName) const {
109 g_log.debug() << "ISISInstrumentDataCache::makeIndexFilePath(" << instrumentName << ")" << std::endl;
110 auto const &indexFilePath =
111 std::filesystem::path(m_dataCachePath) / instrumentName / (instrumentName + "_index.json");
112 return indexFilePath;
113}
114
115std::pair<std::string, std::string>
117
118 // Find the last non-digit as the instrument name can contain numbers
119 const auto itRev = std::find_if(fileName.rbegin(), fileName.rend(), std::not_fn(isdigit));
120 const auto nChars = std::distance(itRev, fileName.rend());
121 std::string runNumber = fileName.substr(nChars);
122
123 std::string fileNameUpperCase = fileName;
124 std::transform(fileNameUpperCase.begin(), fileNameUpperCase.end(), fileNameUpperCase.begin(), toupper);
125 std::string instrName = fileNameUpperCase.substr(0, nChars);
126
127 return std::pair(instrName, runNumber);
128}
129
135bool ISISInstrumentDataCache::isIndexFileAvailable(std::string const &instrumentName) const {
136 return std::filesystem::exists(makeIndexFilePath(instrumentName));
137}
std::pair< Mantid::Kernel::InstrumentInfo, std::string > validateInstrumentAndNumber(const std::string &filename) const
std::vector< std::string > getRunNumbersInCache(std::string const &instrumentName) const
Get a vector of the run numbers' files present in the given instrument's data cache.
bool isIndexFileAvailable(std::string const &instrument) const
Check if the data cache index file is available on the current system for a given instrument.
std::pair< std::filesystem::path, Json::Value > openCacheJsonFile(const Mantid::Kernel::InstrumentInfo &instrument) const
Open the Json file and return the path and the opened file object.
Mantid::Kernel::InstrumentInfo getInstrumentFromName(const std::string &instName) const
std::string getFileParentDirectoryPath(const std::string &filename) const
std::pair< std::string, std::string > splitIntoInstrumentAndNumber(const std::string &filename) const
std::filesystem::path makeIndexFilePath(const std::string &instrumentName) const
Exception for when an item is not found in a collection.
Definition Exception.h:145
A class that holds information about an instrument.
const std::string & shortName() const
Return the short name of the instrument.
const std::string & name() const
Return the name of the instrument.
The Logger class is in charge of the publishing messages from the framework through various channels.
Definition Logger.h:51
void debug(const std::string &msg)
Logs at debug level.
Definition Logger.cpp:145
Kernel::Logger g_log("ExperimentInfo")
static logger object
Kernel::Logger g_log("DetermineSpinStateOrder")