Belle II Software development
FileHandler Class Reference

InputHandler which will read XML from plain files, optionally gzip compressed. More...

#include <FileHandler.h>

Inheritance diagram for FileHandler:
InputHandler

Public Types

typedef InputHandlerFactory(const std::string &uri)
 Factory function which takes a backend uri and returns an InputHandler instance.
 

Public Member Functions

 FileHandler (const std::string &uri)
 Instantiate a new file handler, using the uri as base search path.
 
virtual ~FileHandler ()
 empty, virtual destructor
 
virtual InputContextopen (const std::string &path) override
 create a new FileContext by searching the file system for a file named like path.
 

Protected Attributes

std::string m_path
 Search path to look for files.
 
boost::format m_pathformat
 format object in case of run-dependent data path
 
bool m_rundependence {false}
 bool indicating whether the data path is run-dependent
 
std::string m_uri
 URI for the InputHandler.
 

Detailed Description

InputHandler which will read XML from plain files, optionally gzip compressed.

This Handler will try to find the XML files as plain files in the file system. If a file with the exact name cannot be found, the Handler tries to append .gz to the filename and decompress it with gzip.

The uri is the base dir for all files to be searched and can contain the placeholders {EXP} and {RUN} to be replaced with the experiment and run number respectively. Optionally, the placeholders can contain the number of digits the result should have separated by a colon, filled with zeros, e.g. {EXP:4} to have the experiment number starting as 0001

If an file cannot be found (with or without .gz extension), the directory separators "/" will be successively replaced by dashes "-" (starting at the back) to allow for flat file structure. For example, if the uri is /data/ and the filename to be opened is geometry/Belle2.xml, the inputhandler will try to find /data/geometry/Belle2.xml /data/geometry/Belle2.xml.gz /data/geometry-Belle2.xml /data/geometry-Belle2.xml.gz /data-geometry-Belle2.xml /data-geometry-Belle2.xml.gz in that order the search path, stopping at the first success.

Definition at line 67 of file FileHandler.h.

Member Typedef Documentation

◆ Factory

typedef InputHandler * Factory(const std::string &uri)
inherited

Factory function which takes a backend uri and returns an InputHandler instance.

Definition at line 53 of file InputHandler.h.

Constructor & Destructor Documentation

◆ FileHandler()

FileHandler ( const std::string &  uri)
explicit

Instantiate a new file handler, using the uri as base search path.

If uri is empty, the default data search path will be used.

Parameters
uri* path to search files in

Definition at line 35 of file FileHandler.cc.

35 : InputHandler(uri), m_path(uri)
36 {
37
38 if (m_path.empty()) {
39 m_path = "/data/";
40 } else {
41 //Check if we have placeholder for experiment or run information
42 std::regex exp(R"(\{EXP(?::(\d+))?\})");
43 std::regex run(R"(\{RUN(?::(\d+))?\})");
44 m_rundependence = std::regex_search(m_path, exp) || std::regex_search(m_path, run);
45 if (m_rundependence) {
46 //Apparently we do have placeholders, replace them by something
47 //boost::format will understand. The placeholder is something like
48 //{EXP} or {EXP:<n>} where <n> is an integer to make the number
49 //zero-filled with <n> digits, so we replace it with %1$0d or
50 //%1$0<n>d to denote to the first argument in a boost format string.
51 //Same for {RUN} and {RUN:<n>} but as second argument
52 StoreObjPtr<EventMetaData> eventMetaDataPtr;
53 eventMetaDataPtr.isRequired();
54 std::string tmp = std::regex_replace(m_path, exp, std::string("%1$$0$1d"));
55 tmp = std::regex_replace(tmp, run, std::string("%2$$0$1d"));
56 B2DEBUG(300, "Found run-dependence in file path, resulting in " << tmp);
57 m_pathformat = boost::format(tmp);
58 m_pathformat.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit);
59 }
60 }
61 B2DEBUG(300, "Created FileHandler for directory " << m_path);
62 }
std::string m_path
Search path to look for files.
Definition: FileHandler.h:83
boost::format m_pathformat
format object in case of run-dependent data path
Definition: FileHandler.h:85
bool m_rundependence
bool indicating whether the data path is run-dependent
Definition: FileHandler.h:87
InputHandler(const std::string &uri)
Constructor accepting the uri for the InputHandler.
Definition: InputHandler.h:63

◆ ~FileHandler()

virtual ~FileHandler ( )
inlinevirtual

empty, virtual destructor

Definition at line 75 of file FileHandler.h.

75{}

Member Function Documentation

◆ open()

InputContext * open ( const std::string &  path)
overridevirtual

create a new FileContext by searching the file system for a file named like path.

Parameters
pathname of the file, relative to the FileHandler search path

Implements InputHandler.

Definition at line 64 of file FileHandler.cc.

65 {
66 if (m_rundependence) {
67 StoreObjPtr<EventMetaData> eventMetaDataPtr;
68 if (!eventMetaDataPtr.isValid()) {
69 B2DEBUG(300, "No run info, probably initialize? Skipping backend");
70 return nullptr;
71 }
72 int exp = eventMetaDataPtr->getExperiment();
73 int run = eventMetaDataPtr->getRun();
74 m_path = (m_pathformat % exp % run).str();
75 }
76 fs::path basedir(m_path);
77 std::string filename = (basedir / path).string();
78 bool repeat(false);
79 do {
80 //Ok, let's try to find the file
81 B2DEBUG(350, "Trying to find " << filename);
82
83 std::string fullpath = FileSystem::findFile(filename, true);
84 if (!fullpath.empty()) {
85 if (m_rundependence) B2INFO("gearbox::FileHandler: Reading '" << fullpath << "'");
86 return new FileContext(fullpath, false);
87 }
88 fullpath = FileSystem::findFile(filename + ".gz", true);
89 if (!fullpath.empty()) {
90 if (m_rundependence) B2INFO("gearbox::FileHandler: Reading '" << fullpath << "' (gzip)");
91 return new FileContext(fullpath, true);
92 }
93
94 //did not work, replace last slash by a - and try again if such a
95 //replacement was successful. This allows flattening the directory
96 //structure from e.g. data/pxd/PXD-Alignment.xml to
97 //data-pxd-PXD-Alignment.xml to more easily override single files
98 size_t last_slash = filename.find_last_of('/');
99 //If the last slash we found is after the primary path we try again.
100 //This means we try to replace all slashes in the requested filename
101 //but not in the given base path, for example:
102 // - if the base path is "/somedir/data/" and the file to be opened is
103 // "foo/bar/baz.xml", we will look only for files up to
104 // "/somedir/data/foo-bar-baz.xml"
105 // - if the base path does not end in "/", e.g. "/somedir/data" we also
106 // look for "/somedir/data-foo-bar-baz.xml"
107 repeat = (last_slash >= m_path.size()) && (last_slash != std::string::npos);
108 if (repeat) {
109 filename[last_slash] = '-';
110 }
111 } while (repeat);
112 return nullptr;
113 }
static std::string findFile(const std::string &path, bool silent=false)
Search for given file or directory in local or central release directory, and return absolute path if...
Definition: FileSystem.cc:151

Member Data Documentation

◆ m_path

std::string m_path
protected

Search path to look for files.

Definition at line 83 of file FileHandler.h.

◆ m_pathformat

boost::format m_pathformat
protected

format object in case of run-dependent data path

Definition at line 85 of file FileHandler.h.

◆ m_rundependence

bool m_rundependence {false}
protected

bool indicating whether the data path is run-dependent

Definition at line 87 of file FileHandler.h.

◆ m_uri

std::string m_uri
protectedinherited

URI for the InputHandler.

Definition at line 79 of file InputHandler.h.


The documentation for this class was generated from the following files: