InfoDumperInputFile.cc
Go to the documentation of this file.
12 #include "cetlib/HorizontalRule.h"
13 
14 #include <algorithm>
15 #include <iomanip>
16 #include <iostream>
17 
18 namespace {
19 
20  auto
21  openFile(std::string const& fn)
22  {
23  std::unique_ptr<TFile> file{TFile::Open(fn.c_str(), "READ")};
24  if (!file || file->IsZombie()) {
26  << "Unable to open file '" << fn << "' for reading.";
27  }
28 
29  auto* key_ptr = file->GetKey("RootFileDB");
30  if (key_ptr == nullptr) {
32  << "Requested DB, \"RootFileDB\" of type, \"tkeyvfs\", not present in "
33  "file: \""
34  << fn << "\"\n"
35  << "Either this is not an art/ROOT file, it is a corrupt art/ROOT "
36  "file,\n"
37  << "or it is an art/ROOT file produced with a version older than "
38  "v1_00_12.\n";
39  }
40  return file;
41  }
42 
44 
46  getEntryNumbers(art::FileIndex::const_iterator& it,
48  {
49  if (it == end)
50  return {};
51 
52  EntryNumbers entries;
53  auto const eid = it->eventID_;
54  for (; it != end && eid == it->eventID_; ++it) {
55  entries.push_back(it->entry_);
56  }
57  return entries;
58  }
59 } // namespace
60 
62  std::string const& filename)
63  : file_{openFile(filename)}
64 {
65  using namespace art::rootNames;
66  std::unique_ptr<TTree> md{
67  static_cast<TTree*>(file_->Get(metaDataTreeName().data()))};
68 
69  fileFormatVersion_ = detail::readMetadata<FileFormatVersion>(md.get());
70 
71  // Read BranchID lists if they exist
73 
74  // Read file index
75  auto findexPtr = &fileIndex_;
76  art::detail::readFileIndex(file_.get(), md.get(), findexPtr);
77 
78  // Read ProcessHistory
79  pHistMap_ = detail::readMetadata<ProcessHistoryMap>(md.get());
80 }
81 
82 void
84 {
86 }
87 
88 void
90 {
91  os << fileIndex_;
92 }
93 
94 void
96 {
97  auto const& processNamesCollection = orderedProcessNamesCollection(pHistMap_);
98  bool printHistoryLabel{false};
99  if (processNamesCollection.empty()) {
100  os << "\n No process history was recorded for this file.\n";
101  return;
102  } else if (processNamesCollection.size() > 1ull) {
103  printHistoryLabel = true;
104  os << "\n This file was produced with multiple processing histories.\n";
105  }
106 
107  // Relying on a single character will be problematic if the
108  // process-names collection has more than 26 elements. Hopefully,
109  // nobody will produce a job that involves the concatenation of more
110  // than 26 inconsistent process histories. If so, we'll solve the
111  // process-history labeling below issue once we come to it.
112  char hl{'A'};
113 
114  for (auto const& processNames : processNamesCollection) {
115  unsigned i{1u};
116  if (printHistoryLabel) {
117  os << "\n Chronological list of process names for process history: "
118  << hl++ << "\n\n";
119  } else {
120  os << "\n Chronological list of process names for processes that\n"
121  << " produced this file.\n\n";
122  }
123  for (auto const& process : processNames) {
124  os << ' ' << std::setw(4) << std::right << i++ << ". " << process << '\n';
125  }
126  }
127 }
128 
129 void
131 {
132  if (fileFormatVersion_.value_ >= 10) {
133  std::ostringstream oss;
134  oss << " BranchIDLists are not stored for art/ROOT files with a format\n"
135  << " version of \"" << fileFormatVersion_ << "\".\n";
137  "InfoDumperInputFile::print_branchIDLists:\n"}
138  << oss.str();
139  }
140 
141  auto const& processNames = orderedProcessNamesCollection(pHistMap_);
142  // For older file format versions, there cannot be more than one
143  // ordered process name, due to the compatibility requirements that
144  // were enforced in generating the file.
145  assert(processNames.size() == 1ull);
146 
147  os << "\n List of BranchIDs produced for this file. The BranchIDs are\n"
148  << " grouped according to the process in which they were produced. The\n"
149  << " processes are presented in chronological order; however within each "
150  "process,\n"
151  << " the order of listed BranchIDs is not meaningful.\n";
152  unsigned i{};
153  for (auto const& process : processNames.front()) {
154  os << "\n Process " << i + 1 << ": " << process << '\n';
155  for (auto const& bid : branchIDLists_[i]) {
156  os << " " << bid << '\n';
157  }
158  ++i;
159  }
160 }
161 
162 void
164  std::ostream& os,
165  bool const compactRanges) const
166 {
167  auto it = fileIndex_.cbegin();
168  auto const cend = fileIndex_.cend();
169  constexpr cet::HorizontalRule rule{30};
170  std::string const rep{compactRanges ? "compact" : "full (default)"};
171 
172  if (fileFormatVersion_.value_ < 9) {
173  os << '\n'
174  << "*** This file has a format version of \"" << fileFormatVersion_
175  << "\" and therefore\n"
176  << "*** does not contain range-set information. The printout below is\n"
177  << "*** the range set art would assign to this file.\n\n"
178  << "Representation: " << rep << '\n'
179  << rule('-') << '\n';
180 
181  for (auto const& element : fileIndex_) {
182  if (element.getEntryType() != art::FileIndex::kRun)
183  continue;
184  auto const& rs = rangeSetFromFileIndex(
185  fileIndex_, element.eventID_.runID(), compactRanges);
186  os << rs << '\n';
187  }
188  return;
189  }
190 
191  auto* tree =
192  static_cast<TTree*>(file_->Get(BranchTypeToProductTreeName(InRun).c_str()));
193  SQLite3Wrapper db{file_.get(), "RootFileDB"};
194 
195  os << "Representation: " << rep << '\n' << rule('-') << '\n';
196  while (it != cend) {
197  if (it->getEntryType() != art::FileIndex::kRun) {
198  ++it;
199  continue;
200  }
201  // getEntryNumbers increments iterator!
202  auto const& entries = getEntryNumbers(it, cend);
203  auto const& rs =
204  getRangeSet(tree, entries, db, file_->GetName(), compactRanges);
205  os << rs << '\n';
206  }
207 }
208 
211  EntryNumber const entry) const
212 {
213  auto aux = std::make_unique<RunAuxiliary>();
214  auto pAux = aux.get();
215  TBranch* auxBranch =
216  tree->GetBranch(BranchTypeToAuxiliaryBranchName(InRun).c_str());
217  auxBranch->SetAddress(&pAux);
218  tree->LoadTree(entry);
219  auxBranch->GetEntry(entry);
220  return *aux;
221 }
222 
225  EntryNumbers const& entries,
226  sqlite3* db,
227  std::string const& filename,
228  bool const compactRanges) const
229 {
230  auto resolve_info = [db, &filename](auto const id, bool const compact) {
231  return detail::resolveRangeSetInfo(db, filename, InRun, id, compact);
232  };
233 
234  auto auxResult = getAuxiliary(tree, entries[0]);
235  auto rangeSetInfo = resolve_info(auxResult.rangeSetID(), compactRanges);
236 
237  for (auto i = entries.cbegin() + 1, e = entries.cend(); i != e; ++i) {
238  auto const& tmpAux = getAuxiliary(tree, *i);
239  rangeSetInfo.update(resolve_info(tmpAux.rangeSetID(), compactRanges),
240  compactRanges);
241  }
242 
243  return resolveRangeSet(rangeSetInfo);
244 }
std::string const & BranchTypeToProductTreeName(BranchType const bt)
Definition: BranchType.cc:71
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:104
RangeSetInfo resolveRangeSetInfo(sqlite3 *, std::string const &filename, BranchType, unsigned RangeSetID, bool compact)
void print_event_list(std::ostream &) const
std::string string
Definition: nybbler.cc:12
void readFileIndex(TFile *file, TTree *metaDataTree, FileIndex *&findexPtr)
Definition: readFileIndex.h:22
RangeSet rangeSetFromFileIndex(FileIndex const &fileIndex, RunID runID, bool compactRanges)
std::string const & BranchTypeToAuxiliaryBranchName(BranchType const bt)
Definition: BranchType.cc:83
RangeSet resolveRangeSet(RangeSetInfo const &rs)
std::vector< std::vector< std::string > > orderedProcessNamesCollection(ProcessHistoryMap const &pHistMap)
InfoDumperInputFile(std::string const &filename)
std::string const & metaDataTreeName()
Definition: rootNames.cc:40
const double e
std::vector< EntryNumber > EntryNumbers
Definition: Inputfwd.h:42
void print_event_list(std::ostream &os) const
Definition: FileIndex.cc:337
const_iterator cbegin() const
Definition: FileIndex.cc:74
void print_process_history(std::ostream &) const
std::unique_ptr< TFile > file_
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
RangeSet getRangeSet(TTree *tree, EntryNumbers const &entries, sqlite3 *db, std::string const &filename, bool compactRanges) const
std::vector< Element >::const_iterator const_iterator
Definition: FileIndex.h:75
RunAuxiliary getAuxiliary(TTree *tree, EntryNumber const entry) const
void print_range_sets(std::ostream &, bool compactRanges) const
end
Definition: test.py:8
void print_file_index(std::ostream &) const
const_iterator cend() const
Definition: FileIndex.cc:92
T readMetadata(TTree *md, bool const requireDict=true)
Definition: readMetadata.h:14
void print_branchIDLists(std::ostream &os) const