Belle II Software development
Belle2::RootIOUtilities Namespace Reference

Some constants and helpers common to the RootInput and RootOutput modules. More...

Classes

class  RootFileInfo
 Helper class to factorize some necessary tasks when working with Belle2 output files. More...
 

Functions

std::set< std::string > filterBranches (const std::set< std::string > &branchesToFilter, const std::vector< std::string > &branches, const std::vector< std::string > &excludeBranches, int durability, bool quiet=false)
 Given a list of input branches and lists of branches to include/exclude, returns a list of branches that are accepted.
 
size_t setBranchStatus (TBranch *branch, bool process)
 Set Branch to be read or not.
 
std::vector< std::string > expandWordExpansions (const std::vector< std::string > &filenames)
 Performs wildcard expansion using wordexp(), returns matches.
 
long getEntryNumberWithEvtRunExp (TTree *tree, long event, long run, long experiment)
 return entry number with given (event, run, experiment) from tree.
 
void buildIndex (TTree *tree)
 Build TTreeIndex on tree (assumes either EventMetaData branch exists or is a ntuple tree).
 
bool hasStreamer (const TClass *cl)
 Returns true if and only if 'cl' or one of its bases has I/O streamers.
 
bool hasCustomStreamer (const TClass *cl)
 Returns true if and only if 'cl' has a user-defined streamer.
 
void setCreationData (FileMetaData &metadata)
 Fill the creation info of a file meta data: site, user, data.
 
std::string getCommitID ()
 Return git SHA1 hashes taking into account local & central release.
 
bool isReservedTreeName (const std::string &name)
 Check whether a tree name is a reserved basf2 tree name as defined in RootIOUtilities::c_treeNames.
 

Variables

const std::string c_treeNames [] = { "tree", "persistent" }
 Names of trees.
 
const std::string c_SteerBranchNames [] = { "branchNames", "branchNamesPersistent" }
 Steering parameter names for m_branchNames.
 
const std::string c_SteerExcludeBranchNames [] = { "excludeBranchNames", "excludeBranchNamesPersistent" }
 Steering parameter names for m_excludeBranchNames.
 
const std::string c_SteerAdditionalBranchNames [] = { "additionalBranchNames", "additionalBranchNamesPersistent" }
 Steering parameter names for m_additionalBranchNames.
 

Detailed Description

Some constants and helpers common to the RootInput and RootOutput modules.

Function Documentation

◆ buildIndex()

void buildIndex ( TTree * tree)

Build TTreeIndex on tree (assumes either EventMetaData branch exists or is a ntuple tree).

Definition at line 154 of file RootIOUtilities.cc.

155{
156 std::string treeName = tree->GetName();
157 TBranch* const EventMetaDataBranch = tree->GetBranch("EventMetaData");
158 if ((strcmp(treeName.c_str(), "tree") == 0) && EventMetaDataBranch) {
159 tree->BuildIndex("1000000*EventMetaData.m_experiment+EventMetaData.m_run", "EventMetaData.m_event");
160 }
161 // for ntuple trees that do not have EventMetaData branch we use the tree level branches
162 else {
163 std::string key = "1000000*" + treeName + ".__experiment__+" + treeName + ".__run__";
164 std::string event = treeName + ".__event__";
165 tree->BuildIndex(key.c_str(), event.c_str());
166 }
167}

◆ expandWordExpansions()

std::vector< std::string > expandWordExpansions ( const std::vector< std::string > & filenames)

Performs wildcard expansion using wordexp(), returns matches.

Definition at line 116 of file RootIOUtilities.cc.

117{
118 std::vector<std::string> out;
119 wordexp_t expansions;
120 wordexp("", &expansions, 0);
121 for (const std::string& pattern : filenames) {
122 if (wordexp(pattern.c_str(), &expansions, WRDE_APPEND | WRDE_NOCMD | WRDE_UNDEF) != 0) {
123 B2ERROR("Failed to expand pattern '" << pattern << "'!");
124 }
125 }
126 out.resize(expansions.we_wordc);
127 for (unsigned int i = 0; i < expansions.we_wordc; i++) {
128 out[i] = expansions.we_wordv[i];
129 }
130 wordfree(&expansions);
131 return out;
132}

◆ filterBranches()

std::set< std::string > filterBranches ( const std::set< std::string > & branchesToFilter,
const std::vector< std::string > & branches,
const std::vector< std::string > & excludeBranches,
int durability,
bool quiet = false )

Given a list of input branches and lists of branches to include/exclude, returns a list of branches that are accepted.

More precisely, an item b from 'branchesToFilter' will be in the returned set if b not in excludeBranches and (b in branches or empty(branches) or b in relationsBetweenAcceptedBranches) and b not in relationsInvolvingExcludedBranches

Parameters
branchesToFilterinput
branchesif not empty, the list of branches to be accepted
excludeBranchesbranches that should never end up in output (takes precedence over everything else)
durabilityDurability being filtered (used for messages only)
quietIf true don't warn about branches which are missing/extra/duplicate in the lists

Definition at line 32 of file RootIOUtilities.cc.

35{
36 std::set<std::string> branchSet, excludeBranchSet;
37 for (const std::string& b : branches) {
38 if (branchesToFilter.count(b) == 0 and not quiet)
39 B2WARNING("The branch " << b << " given in " << c_SteerBranchNames[durability] << " does not exist.");
40 if (!branchSet.insert(b).second and not quiet)
41 B2WARNING(c_SteerBranchNames[durability] << " has duplicate entry " << b);
42 }
43 for (const std::string& b : excludeBranches) {
44 // FIXME: ProcessStatistics is excluded by default but not always present. We should switch that to not write it out
45 // in the first place but the info message is meaningless for almost everyone
46 if (branchesToFilter.count(b) == 0 and not quiet and b != "ProcessStatistics")
47 B2INFO("The branch " << b << " given in " << c_SteerExcludeBranchNames[durability] << " does not exist.");
48 if (!excludeBranchSet.insert(b).second and not quiet)
49 B2WARNING(c_SteerExcludeBranchNames[durability] << " has duplicate entry " << b);
50 }
51
52 std::set<std::string> out;
53 for (const std::string& branch : branchesToFilter) {
54 if (excludeBranchSet.count(branch))
55 continue;
56 if (branchSet.empty() or branchSet.count(branch))
57 out.insert(branch);
58 }
59 std::set<std::string> excluderelations;
60 if (!excludeBranchSet.empty()) {
61 //remove relations for excluded things
62 for (const std::string& from : branchesToFilter) {
63 for (const std::string& to : branchesToFilter) {
64 std::string branch = DataStore::relationName(from, to);
65 if (out.count(branch) == 0)
66 continue; //not selected
67 if (excludeBranchSet.count(from) == 0 and excludeBranchSet.count(to) == 0)
68 continue; //at least one side should be excluded
69 if (branchSet.count(branch) != 0)
70 continue; //specifically included
71 excluderelations.insert(branch);
72 }
73 }
74 for (const std::string& rel : excluderelations) {
75 out.erase(rel);
76 }
77 }
78 //add relations between accepted branches
79 std::set<std::string> relations;
80 for (const std::string& from : out) {
81 for (const std::string& to : out) {
82 std::string branch = DataStore::relationName(from, to);
83 if (branchesToFilter.count(branch) == 0)
84 continue; //not in input
85 if (excludeBranchSet.count(branch))
86 continue;
87 relations.insert(branch);
88 }
89 }
90 out.insert(relations.begin(), relations.end());
91 return out;
92}
static std::string relationName(const std::string &fromName, const std::string &toName, std::string const &namedRelation="")
Return storage name for a relation between two arrays of the given names.
Definition DataStore.h:180
const std::string c_SteerExcludeBranchNames[]
Steering parameter names for m_excludeBranchNames.
const std::string c_SteerBranchNames[]
Steering parameter names for m_branchNames.

◆ getCommitID()

std::string getCommitID ( )

Return git SHA1 hashes taking into account local & central release.

ID is a combined hash $CENTRAL_SHA1[+$LOCAL_SHA1][-modified], or just SHA1[-modified] if only one release or they are on the same revision. Empty string denotes at least one untracked release directory.

Definition at line 219 of file RootIOUtilities.cc.

220{
221 return GIT_COMMITID;
222}

◆ getEntryNumberWithEvtRunExp()

long getEntryNumberWithEvtRunExp ( TTree * tree,
long event,
long run,
long experiment )

return entry number with given (event, run, experiment) from tree.

Returns -1 if not found.

Definition at line 135 of file RootIOUtilities.cc.

136{
137 const long major = 1000000 * experiment + run;
138 const long minor = event;
139
140 if (!tree->GetTreeIndex()) {
141 B2DEBUG(100, "No TTreeIndex found, rebuild it...");
142 buildIndex(tree);
143 }
144 long entry = tree->GetEntryNumberWithIndex(major, minor);
145
146 if (entry == -1) {
147 //should be handled by caller
148 B2DEBUG(100, "Couldn't find entry (" << event << ", " << run << ", " << experiment << ") in file! (major index: " << major <<
149 ", minor index: " << minor << ")");
150 }
151 return entry;
152}
void buildIndex(TTree *tree)
Build TTreeIndex on tree (assumes either EventMetaData branch exists or is a ntuple tree).

◆ hasCustomStreamer()

bool hasCustomStreamer ( const TClass * cl)

Returns true if and only if 'cl' has a user-defined streamer.

In that case, TClonesArrays of this type should be written with BypassStreamer(false) and split-level -1 (no splitting).

Definition at line 190 of file RootIOUtilities.cc.

191{
192 // Does this class have a custom streamer?
193 return cl->HasCustomStreamerMember();
194}

◆ hasStreamer()

bool hasStreamer ( const TClass * cl)

Returns true if and only if 'cl' or one of its bases has I/O streamers.

TObject is not considered to have any.

Definition at line 169 of file RootIOUtilities.cc.

170{
171 if (cl == TObject::Class())
172 return false;
173
174 if (cl->GetClassVersion() <= 0) {
175 // version number == 0 means no streamers for this class, check base classes
176 TList* baseClasses = const_cast<TClass*>(cl)->GetListOfBases(); //method might update an internal cache, but is const otherwise
177 TIter it(baseClasses);
178 while (auto* base = static_cast<TBaseClass*>(it())) {
179 if (hasStreamer(base->GetClassPointer()))
180 return true;
181 }
182 //nothing found
183 return false;
184 } else {
185 return true;
186 }
187}
bool hasStreamer(const TClass *cl)
Returns true if and only if 'cl' or one of its bases has I/O streamers.

◆ isReservedTreeName()

bool isReservedTreeName ( const std::string & name)

Check whether a tree name is a reserved basf2 tree name as defined in RootIOUtilities::c_treeNames.

Definition at line 224 of file RootIOUtilities.cc.

225{
226 return std::any_of(std::begin(RootIOUtilities::c_treeNames),
228 [&name](const std::string & s) { return s == name; });
229}
const std::string c_treeNames[]
Names of trees.

◆ setBranchStatus()

size_t setBranchStatus ( TBranch * branch,
bool process )

Set Branch to be read or not.

TTree::SetBranchAddress doesn't do what we want it to do because our branch names seem to not be conform to their expectations. But we don't need to use name matching, we know our structure and it's simple enough so we just recursively go through the branch and all children and set processing on or off.

Parameters
branchThe branch to change the status for
processWhether or not to read/process this branch
Returns
the number of branches enabled/disabled

Definition at line 94 of file RootIOUtilities.cc.

95{
96 size_t found{0};
97 std::queue<TBranch*> branches;
98 branches.emplace(branch);
99 while (!branches.empty()) {
100 ++found;
101 auto* current = branches.front();
102 branches.pop();
103 // set the flag we need
104 if (process) current->ResetBit(kDoNotProcess);
105 else current->SetBit(kDoNotProcess);
106 // add all children to the queue
107 auto* children = current->GetListOfBranches();
108 const auto nchildren = children->GetEntriesFast();
109 for (int i = 0; i < nchildren; ++i) {
110 branches.emplace(dynamic_cast<TBranch*>(children->UncheckedAt(i)));
111 }
112 }
113 return found;
114}

◆ setCreationData()

void setCreationData ( FileMetaData & metadata)

Fill the creation info of a file meta data: site, user, data.

Definition at line 196 of file RootIOUtilities.cc.

197{
198 std::string site;
199 char date[100];
200 auto now = time(nullptr);
201 strftime(date, 100, "%Y-%m-%d %H:%M:%S", gmtime(&now));
202 const char* belle2_site = getenv("BELLE2_SITE");
203 if (belle2_site) {
204 site = belle2_site;
205 } else {
206 char hostname[1024];
207 gethostname(hostname, 1023); //will not work well for ipv6
208 hostname[1023] = '\0'; //if result is truncated, terminating null byte may be missing
209 site = hostname;
210 }
211 const char* user = getenv("BELLE2_USER");
212 if (!user) user = getenv("USER");
213 if (!user) user = getlogin();
214 if (!user) user = "unknown";
215 auto commitid = RootIOUtilities::getCommitID();
216 metadata.setCreationData(date, site, user, commitid);
217}
void setCreationData(const std::string &date, const std::string &site, const std::string &user, const std::string &release)
Creation data setter.
std::string getCommitID()
Return git SHA1 hashes taking into account local & central release.

Variable Documentation

◆ c_SteerAdditionalBranchNames

const std::string c_SteerAdditionalBranchNames = { "additionalBranchNames", "additionalBranchNamesPersistent" }
extern

Steering parameter names for m_additionalBranchNames.

Definition at line 30 of file RootIOUtilities.cc.

30{ "additionalBranchNames", "additionalBranchNamesPersistent" };

◆ c_SteerBranchNames

const std::string c_SteerBranchNames = { "branchNames", "branchNamesPersistent" }
extern

Steering parameter names for m_branchNames.

Definition at line 28 of file RootIOUtilities.cc.

28{ "branchNames", "branchNamesPersistent" };

◆ c_SteerExcludeBranchNames

const std::string c_SteerExcludeBranchNames = { "excludeBranchNames", "excludeBranchNamesPersistent" }
extern

Steering parameter names for m_excludeBranchNames.

Definition at line 29 of file RootIOUtilities.cc.

29{ "excludeBranchNames", "excludeBranchNamesPersistent" };

◆ c_treeNames

const std::string c_treeNames = { "tree", "persistent" }
extern

Names of trees.

Definition at line 27 of file RootIOUtilities.cc.

27{ "tree", "persistent" };