CMS 3D CMS Logo

RootInputFileSequence.cc
Go to the documentation of this file.
1 /*----------------------------------------------------------------------
2 ----------------------------------------------------------------------*/
3 #include "RootFile.h"
5 
15 
16 #include "TSystem.h"
17 
18 namespace edm {
19  class BranchIDListHelper;
20  class EventPrincipal;
21  class LuminosityBlockPrincipal;
22  class RunPrincipal;
23 
25  : catalog_(catalog),
26  lfn_("unknown"),
27  lfnHash_(0U),
28  usedFallback_(false),
29  findFileForSpecifiedID_(nullptr),
30  fileIterBegin_(fileCatalogItems().begin()),
31  fileIterEnd_(fileCatalogItems().end()),
32  fileIter_(fileIterEnd_),
33  fileIterLastOpened_(fileIterEnd_),
34  rootFile_(),
35  indexesIntoFiles_(fileCatalogItems().size()) {}
36 
37  std::vector<FileCatalogItem> const& RootInputFileSequence::fileCatalogItems() const {
38  return catalog_.fileCatalogItems();
39  }
40 
41  std::shared_ptr<ProductRegistry const> RootInputFileSequence::fileProductRegistry() const {
42  assert(rootFile());
43  return rootFile()->productRegistry();
44  }
45 
46  std::shared_ptr<BranchIDListHelper const> RootInputFileSequence::fileBranchIDListHelper() const {
47  assert(rootFile());
48  return rootFile()->branchIDListHelper();
49  }
50 
52 
53  std::shared_ptr<RunAuxiliary> RootInputFileSequence::readRunAuxiliary_() {
54  assert(rootFile());
55  return rootFile()->readRunAuxiliary_();
56  }
57 
58  std::shared_ptr<LuminosityBlockAuxiliary> RootInputFileSequence::readLuminosityBlockAuxiliary_() {
59  assert(rootFile());
60  return rootFile()->readLuminosityBlockAuxiliary_();
61  }
62 
64  assert(rootFile());
65  return rootFile()->readRun_(runPrincipal);
66  }
67 
69  assert(rootFile());
70  return rootFile()->fillProcessBlockHelper_();
71  }
72 
74  assert(rootFile());
75  return rootFile()->nextProcessBlock_(processBlockPrincipal);
76  }
77 
79  assert(rootFile());
80  rootFile()->readProcessBlock_(processBlockPrincipal);
81  }
82 
84  assert(rootFile());
85  return rootFile()->readLuminosityBlock_(lumiPrincipal);
86  }
87 
88  // readEvent() is responsible for setting up the EventPrincipal.
89  //
90  // 1. fill an EventPrincipal with a unique EventID
91  // 2. For each entry in the provenance, put in one ProductResolver,
92  // holding the Provenance for the corresponding EDProduct.
93  // 3. set up the caches in the EventPrincipal to know about this
94  // ProductResolver.
95  //
96  // We do *not* create the EDProduct instance (the equivalent of reading
97  // the branch containing this EDProduct. That will be done by the Delayed Reader,
98  // when it is asked to do so.
99  //
100 
102  assert(rootFile());
103  return rootFile()->readEvent(eventPrincipal);
104  }
105 
108  EventNumber_t event) const {
109  if (!rootFile())
110  return false;
111  return rootFile()->containsItem(run, lumi, event);
112  }
113 
117  size_t fileNameHash) {
118  // Look for item in files not yet opened. We have a hash of the logical file name
119  assert(fileNameHash != 0U);
120  // If the lookup table is not yet filled in, fill it.
122  // We use a multimap because there may be hash collisions (Two different LFNs could have the same hash).
123  // We map the hash of the LFN to the index into the list of files.
125  std::make_unique<std::unordered_multimap<size_t, size_t>>(); // propagate_const<T> has no reset() function
126  auto hasher = std::hash<std::string>();
127  for (auto fileIter = fileIterBegin_; fileIter != fileIterEnd_; ++fileIter) {
128  findFileForSpecifiedID_->insert(std::make_pair(hasher(fileIter->logicalFileName()), fileIter - fileIterBegin_));
129  }
130  }
131  // Look up the logical file name in the table
132  auto range = findFileForSpecifiedID_->equal_range(fileNameHash);
133  for (auto iter = range.first; iter != range.second; ++iter) {
134  // Don't look in files previously opened, because those have already been searched.
135  if (!indexesIntoFiles_[iter->second]) {
136  setAtFileSequenceNumber(iter->second);
137  initFile_(false);
138  assert(rootFile());
139  bool found = rootFile()->setEntryAtItem(run, lumi, event);
140  if (found) {
141  return true;
142  }
143  }
144  }
145  // Not found
146  return false;
147  }
148 
150  // Look for item in files not yet opened. We do not have a valid hash of the logical file name.
151  for (auto it = indexesIntoFiles_.begin(), itEnd = indexesIntoFiles_.end(); it != itEnd; ++it) {
152  if (!*it) {
153  // File not yet opened.
155  initFile_(false);
156  assert(rootFile());
157  bool found = rootFile()->setEntryAtItem(run, lumi, event);
158  if (found) {
159  return true;
160  }
161  }
162  }
163  // Not found
164  return false;
165  }
166 
168  RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event, size_t fileNameHash, bool currentFileFirst) {
169  // Attempt to find item in currently open input file.
170  bool found = currentFileFirst && rootFile() && rootFile()->setEntryAtItem(run, lumi, event);
171  if (!found) {
172  // If only one input file, give up now, to save time.
173  if (currentFileFirst && rootFile() && indexesIntoFiles_.size() == 1) {
174  return false;
175  }
176  // Look for item (run/lumi/event) in files previously opened without reopening unnecessary files.
177  for (auto it = indexesIntoFiles_.begin(), itEnd = indexesIntoFiles_.end(); it != itEnd; ++it) {
178  if (*it && (*it)->containsItem(run, lumi, event)) {
179  // We found it. Close the currently open file, and open the correct one.
180  std::vector<FileCatalogItem>::const_iterator currentIter = fileIter_;
182  if (fileIter_ != currentIter) {
183  initFile(false);
184  }
185  // Now get the item from the correct file.
186  assert(rootFile());
187  found = rootFile()->setEntryAtItem(run, lumi, event);
188  assert(found);
189  return true;
190  }
191  }
192  return (fileNameHash != 0U && skipToItemInNewFile(run, lumi, event, fileNameHash)) ||
194  }
195  return true;
196  }
197 
198  //Initiate the file using multiple data catalogs
200  bool skipBadFiles, bool deleteIndexIntoFile, InputSource* input, char const* inputTypeName, InputType inputType) {
201  // We are really going to close the open file.
202 
204  size_t currentIndexIntoFile = fileIterLastOpened_ - fileIterBegin_;
205  if (deleteIndexIntoFile) {
206  indexesIntoFiles_[currentIndexIntoFile].reset();
207  } else {
208  if (indexesIntoFiles_[currentIndexIntoFile])
209  indexesIntoFiles_[currentIndexIntoFile]->inputFileClosed();
210  }
212  }
213  closeFile();
214 
215  if (noMoreFiles()) {
216  // No files specified
217  return;
218  }
219 
220  // Check if the logical file name was found.
221  if (fileNames()[0].empty()) {
222  // LFN not found in catalog.
224  if (!skipBadFiles) {
225  throw cms::Exception("LogicalFileNameNotFound", "RootFileSequenceBase::initTheFile()\n")
226  << "Logical file name '" << logicalFileName() << "' was not found in the file catalog.\n"
227  << "If you wanted a local file, you forgot the 'file:' prefix\n"
228  << "before the file name in your configuration file.\n";
229  }
230  LogWarning("") << "Input logical file: " << logicalFileName()
231  << " was not found in the catalog, and will be skipped.\n";
232  return;
233  }
234 
235  lfn_ = logicalFileName().empty() ? fileNames()[0] : logicalFileName();
236  lfnHash_ = std::hash<std::string>()(lfn_);
237  usedFallback_ = false;
238 
239  std::shared_ptr<InputFile> filePtr;
240  std::list<std::string> originalInfo;
241 
242  std::vector<std::string> const& fNames = fileNames();
243 
244  //this tries to open the file using multiple PFNs corresponding to different data catalogs
245  {
246  std::list<std::string> exInfo;
247  std::list<std::string> additionalMessage;
248  std::unique_ptr<InputSource::FileOpenSentry> sentry(
249  input ? std::make_unique<InputSource::FileOpenSentry>(*input, lfn_) : nullptr);
251  if (service.isAvailable()) {
252  service->openingFile(lfn(), inputType, -1);
253  }
254  for (std::vector<std::string>::const_iterator it = fNames.begin(); it != fNames.end(); ++it) {
255  try {
256  usedFallback_ = (it != fNames.begin());
257  std::unique_ptr<char[]> name(gSystem->ExpandPathName(it->c_str()));
258  filePtr = std::make_shared<InputFile>(name.get(), " Initiating request to open file ", inputType);
259  break;
260  } catch (cms::Exception const& e) {
261  if (!skipBadFiles && std::next(it) == fNames.end()) {
264  Exception ex(errorCode, "", e);
265  ex.addContext("Calling RootInputFileSequence::initTheFile()");
266  std::ostringstream out;
267  out << "Input file " << (*it) << " could not be opened.";
268  ex.addAdditionalInfo(out.str());
269  //report previous exceptions when use other names to open file
270  for (auto const& s : exInfo)
271  ex.addAdditionalInfo(s);
272  //report more information of the earlier file open failures in a log message
273  if (not additionalMessage.empty()) {
274  edm::LogWarning l("RootInputFileSequence");
275  for (auto const& msg : additionalMessage) {
276  l << msg << "\n";
277  }
278  }
279  throw ex;
280  } else {
281  exInfo.push_back("Calling RootInputFileSequence::initTheFile(): fail to open the file with name " + (*it));
282  additionalMessage.push_back(fmt::format(
283  "Input file {} could not be opened, and fallback was attempted.\nAdditional information:", *it));
284  char c = 'a';
285  for (auto const& ai : e.additionalInfo()) {
286  additionalMessage.push_back(fmt::format(" [{}] {}", c, ai));
287  ++c;
288  }
289  }
290  }
291  }
292  }
293  if (filePtr) {
294  size_t currentIndexIntoFile = fileIter_ - fileIterBegin_;
295  rootFile_ = makeRootFile(filePtr);
296  assert(rootFile_);
297  if (input) {
298  rootFile_->setSignals(&(input->preEventReadFromSourceSignal_), &(input->postEventReadFromSourceSignal_));
299  }
301  setIndexIntoFile(currentIndexIntoFile);
302  rootFile_->reportOpened(inputTypeName);
303  } else {
304  std::string fName = !fNames.empty() ? fNames[0] : "";
305  InputFile::reportSkippedFile(fName, logicalFileName()); //0 cause exception?
306  if (!skipBadFiles) {
307  throw Exception(errors::FileOpenError) << "RootFileSequenceBase::initTheFile(): Input file " << fName
308  << " was not found or could not be opened.\n";
309  }
310  LogWarning("RootInputFileSequence")
311  << "Input file: " << fName << " was not found or could not be opened, and will be skipped.\n";
312  }
313  }
314 
317  if (rootFile() and service.isAvailable()) {
318  service->closedFile(lfn(), usedFallback());
319  }
320  closeFile_();
321  }
322 
324  indexesIntoFiles_[index] = rootFile()->indexIntoFileSharedPtr();
325  }
326 
327 } // namespace edm
size
Write out results.
InputType
Definition: InputType.h:5
void initFile(bool skipBadFiles)
void setAtFileSequenceNumber(size_t offset)
bool readLuminosityBlock_(LuminosityBlockPrincipal &lumiPrincipal)
std::vector< FileCatalogItem >::const_iterator fileIter_
std::vector< FileCatalogItem >::const_iterator const fileIterEnd_
std::vector< FileCatalogItem >::const_iterator const fileIterBegin_
std::string const & logicalFileName() const
unsigned long long EventNumber_t
void readProcessBlock_(ProcessBlockPrincipal &)
bool readRun_(RunPrincipal &runPrincipal)
assert(be >=bs)
unsigned int LuminosityBlockNumber_t
std::shared_ptr< ProductRegistry const > fileProductRegistry() const
std::vector< std::string > const & fileNames() const
static std::string const input
Definition: EdmProvDump.cc:50
std::vector< FileCatalogItem >::const_iterator fileIterLastOpened_
bool nextProcessBlock_(ProcessBlockPrincipal &)
void initTheFile(bool skipBadFiles, bool deleteIndexIntoFile, InputSource *input, char const *inputTypeName, InputType inputType)
void addAdditionalInfo(std::string const &info)
Definition: Exception.cc:173
static void reportSkippedFile(std::string const &fileName, std::string const &logicalFileName)
Definition: InputFile.cc:75
virtual RootFileSharedPtr makeRootFile(std::shared_ptr< InputFile > filePtr)=0
virtual void initFile_(bool skipBadFiles)=0
std::shared_ptr< RootFile const > rootFile() const
std::vector< std::shared_ptr< IndexIntoFile > > indexesIntoFiles_
bool skipToItem(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event, size_t fileNameHash=0U, bool currentFileFirst=true)
std::vector< FileCatalogItem > const & fileCatalogItems() const
edm::propagate_const< RootFileSharedPtr > rootFile_
bool skipToItemInNewFile(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event)
std::shared_ptr< RunAuxiliary > readRunAuxiliary_()
void addContext(std::string const &context)
Definition: Exception.cc:169
tuple msg
Definition: mps_check.py:286
bool containedInCurrentFile(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) const
HLT enums.
std::shared_ptr< LuminosityBlockAuxiliary > readLuminosityBlockAuxiliary_()
std::string const & lfn() const
virtual void closeFile_()=0
RootInputFileSequence(ParameterSet const &pset, InputFileCatalog const &catalog)
unsigned int RunNumber_t
std::shared_ptr< BranchIDListHelper const > fileBranchIDListHelper() const
Log< level::Warning, false > LogWarning
edm::propagate_const< std::unique_ptr< std::unordered_multimap< size_t, size_t > > > findFileForSpecifiedID_
bool readEvent(EventPrincipal &cache)
Definition: event.py:1
std::vector< FileCatalogItem > const & fileCatalogItems() const
InputFileCatalog const & catalog_