16#include <boost/algorithm/string.hpp>
20#include <unordered_map>
54 std::shared_ptr<TFile>
getFile(
const std::string& identifier )
override;
57 bool hasIdentifier(
const std::string& identifier )
const override;
62 this,
"Config", {},
"Map of keywords to file paths for file access" };
73 std::shared_ptr<TFile>
openFile(
const std::string& filePath,
const std::string& option,
int compress );
86 std::vector<std::shared_ptr<TFile>>
m_files;
98 std::map<std::string, std::string> parseFilePath(
const std::string& path ) {
99 std::vector<std::string> parts;
100 boost::split( parts, path, boost::is_any_of(
"?" ) );
101 std::map<std::string, std::string> result;
102 if ( parts.size() > 1 ) {
103 std::vector<std::string> params;
104 boost::split( params, parts[1], boost::is_any_of(
"&" ) );
105 for (
auto& param : params ) {
106 std::vector<std::string> kv;
107 boost::split( kv, param, boost::is_any_of(
"=" ) );
108 if ( kv.size() == 2 ) { result[boost::trim_copy( kv[0] )] = boost::trim_copy( kv[1] ); }
111 result[
"mode"] = ( result.find(
"mode" ) == result.end() ) ?
"CREATE" : result[
"mode"];
112 result[
"path"] = boost::trim_copy( parts[0] );
125 StatusCode checkConfig(
const std::map<std::string, std::string>& configMap,
const FileSvc& svc ) {
126 std::map<std::string, std::map<std::string, std::string>> fileParams;
127 for (
const auto& [identifier, path] : configMap ) {
128 auto params = parseFilePath( path );
130 auto& existingParams = fileParams[params[
"path"]];
131 if ( !existingParams.empty() ) {
132 if ( existingParams != params ) {
133 svc.
error() <<
"Conflicting configurations for file path: " << params[
"path"] <<
endmsg;
137 existingParams = std::move( params );
150 std::optional<size_t> findFileIndex(
const std::vector<std::shared_ptr<TFile>>& files,
const std::string& filePath ) {
151 auto it = std::find_if( files.begin(), files.end(),
152 [&filePath](
const auto& file ) { return file && file->GetName() == filePath; } );
153 if ( it != files.end() ) {
return std::distance( files.begin(), it ); }
164 for (
const auto& [identifier, path] :
m_config ) {
165 auto params = parseFilePath( path );
168 if (
auto fileIndex = findFileIndex(
m_files, params[
"path"] ) ) {
170 m_identifiers[boost::to_lower_copy( identifier )] = *fileIndex;
173 int compress = ( params.find(
"compress" ) != params.end() )
174 ? std::stoi( params[
"compress"] )
175 : ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault;
176 if (
auto file =
openFile( path, params[
"mode"], compress ) ) {
177 m_files.push_back( std::move( file ) );
180 error() <<
"Failed to open file: " << params[
"path"] <<
endmsg;
193 auto it =
m_identifiers.find( boost::to_lower_copy( identifier ) );
195 error() <<
"No file associated with identifier: " << identifier <<
endmsg;
203std::shared_ptr<TFile>
FileSvc::openFile(
const std::string& filePath,
const std::string& option,
int compress ) {
204 auto file = std::make_shared<TFile>( filePath.c_str(), option.c_str(),
"", compress );
205 if ( !file || file->IsZombie() ) {
return nullptr; }
210 for (
const auto& file :
m_files ) {
211 if ( file ) { file->Close(); }
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
#define DECLARE_COMPONENT(type)
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
Implementation of the IFileSvc interface, allowing algorithms to access ROOT files via a centralized ...
Gaudi::Property< std::map< std::string, std::string > > m_config
StatusCode closeFiles()
Close all files.
std::vector< std::shared_ptr< TFile > > m_files
StatusCode initialize() override
bool hasIdentifier(const std::string &identifier) const override
Check if a given identifier is known to the service.
StatusCode finalize() override
std::unordered_map< std::string, size_t > m_identifiers
FileSvc(const std::string &name, ISvcLocator *svc)
std::shared_ptr< TFile > getFile(const std::string &identifier) override
Get a TFile pointer based on an identifier.
std::shared_ptr< TFile > openFile(const std::string &filePath, const std::string &option, int compress)
Open a file based on a specified path and opening mode.
Implementation of property with value of concrete type.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
const std::string & name() const override
Retrieve name of the service.
StatusCode initialize() override
This class is used for returning status codes from appropriate routines.
StatusCode andThen(F &&f, ARGS &&... args) const
Chain code blocks making the execution conditional a success result.
constexpr static const auto SUCCESS
constexpr static const auto FAILURE
Base class used to extend a class implementing other interfaces.