18#include <boost/algorithm/string.hpp>
22#include <unordered_map>
57 std::shared_ptr<TFile>
getFile(
const std::string& identifier )
override;
60 bool hasIdentifier(
const std::string& identifier )
const override;
65 this,
"Config", {},
"Map of keywords to file paths for file access" };
76 std::shared_ptr<TFile>
openFile(
const std::string& filePath,
const std::string& option,
int compress );
89 std::vector<std::shared_ptr<TFile>>
m_files;
101 std::map<std::string, std::string> parseFilePath(
const std::string& path ) {
102 std::vector<std::string> parts;
103 boost::split( parts, path, boost::is_any_of(
"?" ) );
104 std::map<std::string, std::string> result;
105 if ( parts.size() > 1 ) {
106 std::vector<std::string> params;
107 boost::split( params, parts[1], boost::is_any_of(
"&" ) );
108 for (
auto& param : params ) {
109 std::vector<std::string> kv;
110 boost::split( kv, param, boost::is_any_of(
"=" ) );
111 if ( kv.size() == 2 ) { result[boost::trim_copy( kv[0] )] = boost::trim_copy( kv[1] ); }
114 result[
"mode"] = ( result.find(
"mode" ) == result.end() ) ?
"CREATE" : result[
"mode"];
115 result[
"path"] = boost::trim_copy( parts[0] );
128 StatusCode checkConfig(
const std::map<std::string, std::string>& configMap,
const FileSvc& svc ) {
129 std::map<std::string, std::map<std::string, std::string>> fileParams;
130 for (
const auto& [identifier, path] : configMap ) {
131 auto params = parseFilePath( path );
133 auto& existingParams = fileParams[params[
"path"]];
134 if ( !existingParams.empty() ) {
135 if ( existingParams != params ) {
136 svc.
error() <<
"Conflicting configurations for file path: " << params[
"path"] <<
endmsg;
140 existingParams = std::move( params );
153 std::optional<size_t> findFileIndex(
const std::vector<std::shared_ptr<TFile>>& files,
const std::string& filePath ) {
154 auto it = std::find_if( files.begin(), files.end(),
155 [&filePath](
const auto& file ) { return file && file->GetName() == filePath; } );
156 if ( it != files.end() ) {
return std::distance( files.begin(), it ); }
169 for (
const auto& [identifier, path] :
m_config ) {
170 auto params = parseFilePath( path );
173 if (
auto fileIndex = findFileIndex(
m_files, params[
"path"] ) ) {
175 m_identifiers[boost::to_lower_copy( identifier )] = *fileIndex;
178 int compress = ( params.find(
"compress" ) != params.end() )
179 ? std::stoi( params[
"compress"] )
180 : ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault;
181 if (
auto file =
openFile( path, params[
"mode"], compress ) ) {
182 m_files.push_back( std::move( file ) );
184 auto* outputFile =
m_files.back().get();
186 incidentSvc->fireIncident(
190 error() <<
"Failed to open file: " << params[
"path"] <<
endmsg;
203 auto it =
m_identifiers.find( boost::to_lower_copy( identifier ) );
205 error() <<
"No file associated with identifier: " << identifier <<
endmsg;
213std::shared_ptr<TFile>
FileSvc::openFile(
const std::string& filePath,
const std::string& option,
int compress ) {
214 auto file = std::make_shared<TFile>( filePath.c_str(), option.c_str(),
"", compress );
215 if ( !file || file->IsZombie() ) {
return nullptr; }
220 for (
const auto& file :
m_files ) {
221 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.
SmartIF< IFace > service(const std::string &name, bool createIf=true) const
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.