CMS 3D CMS Logo

RootPrimaryFileSequence.cc
Go to the documentation of this file.
1 /*----------------------------------------------------------------------
2 ----------------------------------------------------------------------*/
3 #include "DuplicateChecker.h"
4 #include "InputFile.h"
5 #include "PoolSource.h"
6 #include "RootFile.h"
8 #include "RootTree.h"
9 
19 
20 namespace edm {
22  ParameterSet const& pset,
24  InputFileCatalog const& catalog) :
25  RootInputFileSequence(pset, catalog),
26  input_(input),
27  firstFile_(true),
28  branchesMustMatch_(BranchDescription::Permissive),
29  orderedProcessHistoryIDs_(),
30  eventSkipperByID_(EventSkipperByID::create(pset).release()),
31  initialNumberOfEventsToSkip_(pset.getUntrackedParameter<unsigned int>("skipEvents")),
32  noEventSort_(pset.getUntrackedParameter<bool>("noEventSort")),
33  treeCacheSize_(noEventSort_ ? pset.getUntrackedParameter<unsigned int>("cacheSize") : 0U),
34  duplicateChecker_(new DuplicateChecker(pset)),
35  usingGoToEvent_(false),
36  enablePrefetching_(false),
37  enforceGUIDInFileName_(pset.getUntrackedParameter<bool>("enforceGUIDInFileName")) {
38 
39  // The SiteLocalConfig controls the TTreeCache size and the prefetching settings.
41  if(pSLC.isAvailable()) {
42  if(treeCacheSize_ != 0U && pSLC->sourceTTreeCacheSize()) {
43  treeCacheSize_ = *(pSLC->sourceTTreeCacheSize());
44  }
45  enablePrefetching_ = pSLC->enablePrefetching();
46  }
47 
48  std::string branchesMustMatch = pset.getUntrackedParameter<std::string>("branchesMustMatch", std::string("permissive"));
49  if(branchesMustMatch == std::string("strict")) branchesMustMatch_ = BranchDescription::Strict;
50 
51  // Prestage the files
54  }
55  // Open the first file.
58  if(rootFile()) break;
59  }
60  if(rootFile()) {
61  input_.productRegistryUpdate().updateFromInput(rootFile()->productRegistry()->productList());
64  }
65  }
66  }
67 
69  }
70 
71  void
73  closeFile_();
74  }
75 
76  std::unique_ptr<FileBlock>
78  if(firstFile_) {
79  // The first input file has already been opened.
80  firstFile_ = false;
81  if(!rootFile()) {
83  }
84  } else {
85  if(!nextFile()) {
86  assert(0);
87  }
88  }
89  if(!rootFile()) {
90  return std::make_unique<FileBlock>();
91  }
92  return rootFile()->createFileBlock();
93  }
94 
95  void
97  // close the currently open file, if any, and delete the RootFile object.
98  if(rootFile()) {
99  auto sentry = std::make_unique<InputSource::FileCloseSentry>(input_, lfn(), usedFallback());
100  rootFile()->close();
101  if(duplicateChecker_) duplicateChecker_->inputFileClosed();
102  rootFile().reset();
103  }
104  }
105 
106  void
108  // If we are not duplicate checking across files and we are not using random access to find events,
109  // then we can delete the IndexIntoFile for the file we are closing.
110  // If we can't delete all of it, then we can delete the parts we do not need.
111  bool deleteIndexIntoFile = !usingGoToEvent_ && !(duplicateChecker_ && duplicateChecker_->checkingAllFiles() && !duplicateChecker_->checkDisabled());
112  initTheFile(skipBadFiles, deleteIndexIntoFile, &input_, "primaryFiles", InputType::Primary);
113  }
114 
116  RootPrimaryFileSequence::makeRootFile(std::shared_ptr<InputFile> filePtr) {
117  size_t currentIndexIntoFile = sequenceNumberOfFile();
118  return std::make_shared<RootFile>(
119  fileName(),
121  logicalFileName(),
122  filePtr,
125  remainingEvents(),
127  input_.nStreams(),
131  input_.runHelper(),
132  noEventSort_,
137  nullptr, // associationsFromSecondary
142  currentIndexIntoFile,
149  }
150 
152  if(!noMoreFiles()) setAtNextFile();
153  if(noMoreFiles()) {
154  return false;
155  }
156 
158 
159  if(rootFile()) {
160  // make sure the new product registry is compatible with the main one
161  std::string mergeInfo = input_.productRegistryUpdate().merge(*rootFile()->productRegistry(),
162  fileName(),
164  if(!mergeInfo.empty()) {
165  throw Exception(errors::MismatchedInputFiles,"RootPrimaryFileSequence::nextFile()") << mergeInfo;
166  }
167  }
168  return true;
169  }
170 
172  if(atFirstFile()) {
173  return false;
174  }
176 
177  initFile(false);
178 
179  if(rootFile()) {
180  // make sure the new product registry is compatible to the main one
181  std::string mergeInfo = input_.productRegistryUpdate().merge(*rootFile()->productRegistry(),
182  fileName(),
184  if(!mergeInfo.empty()) {
185  throw Exception(errors::MismatchedInputFiles,"RootPrimaryFileSequence::previousEvent()") << mergeInfo;
186  }
187  }
188  if(rootFile()) rootFile()->setToLastEntry();
189  return true;
190  }
191 
194  if(noMoreFiles()) {
195  return InputSource::IsStop;
196  }
197  if(firstFile_) {
198  return InputSource::IsFile;
199  }
200  if(rootFile()) {
201  IndexIntoFile::EntryType entryType = rootFile()->getNextItemType(run, lumi, event);
202  if(entryType == IndexIntoFile::kEvent) {
203  return InputSource::IsEvent;
204  } else if(entryType == IndexIntoFile::kLumi) {
205  return InputSource::IsLumi;
206  } else if(entryType == IndexIntoFile::kRun) {
207  return InputSource::IsRun;
208  }
209  assert(entryType == IndexIntoFile::kEnd);
210  }
211  if(atLastFile()) {
212  return InputSource::IsStop;
213  }
214  return InputSource::IsFile;
215  }
216 
217  // Rewind to before the first event that was read.
218  void
220  if(!atFirstFile()) {
221  closeFile_();
222  setAtFirstFile();
223  }
224  if(!rootFile()) {
225  initFile(false);
226  }
227  rewindFile();
228  firstFile_ = true;
229  if(rootFile()) {
232  }
233  }
234  }
235 
236  // Rewind to the beginning of the current file
237  void
239  if(rootFile()) rootFile()->rewind();
240  }
241 
242  // Advance "offset" events. Offset can be positive or negative (or zero).
243  bool
245  assert(rootFile());
246  while(offset != 0) {
247  bool atEnd = rootFile()->skipEvents(offset);
248  if((offset > 0 || atEnd) && !nextFile()) {
249  return false;
250  }
251  if(offset < 0 && !previousFile()) {
252  setNoMoreFiles();
253  return false;
254  }
255  }
256  return true;
257  }
258 
259  bool
261  usingGoToEvent_ = true;
262  if(rootFile()) {
263  if(rootFile()->goToEvent(eventID)) {
264  return true;
265  }
266  // If only one input file, give up now, to save time.
267  if(rootFile() && indexesIntoFiles().size() == 1) {
268  return false;
269  }
270  // Save the current file and position so that we can restore them
271  // if we fail to restore the desired event
272  bool closedOriginalFile = false;
273  size_t const originalFileSequenceNumber = sequenceNumberOfFile();
274  IndexIntoFile::IndexIntoFileItr originalPosition = rootFile()->indexIntoFileIter();
275 
276  // Look for item (run/lumi/event) in files previously opened without reopening unnecessary files.
277  for(auto it = indexesIntoFiles().begin(), itEnd = indexesIntoFiles().end(); it != itEnd; ++it) {
278  if(*it && (*it)->containsItem(eventID.run(), eventID.luminosityBlock(), eventID.event())) {
279  // We found it. Close the currently open file, and open the correct one.
281  initFile(false);
282  // Now get the item from the correct file.
283  assert(rootFile());
284  bool found = rootFile()->goToEvent(eventID);
285  assert(found);
286  return true;
287  }
288  }
289  // Look for item in files not yet opened.
290  for(auto it = indexesIntoFiles().begin(), itEnd = indexesIntoFiles().end(); it != itEnd; ++it) {
291  if(!*it) {
293  initFile(false);
294  closedOriginalFile = true;
295  if((*it)->containsItem(eventID.run(), eventID.luminosityBlock(), eventID.event())) {
296  assert(rootFile());
297  if(rootFile()->goToEvent(eventID)) {
298  return true;
299  }
300  }
301  }
302  }
303  if(closedOriginalFile) {
304  setAtFileSequenceNumber(originalFileSequenceNumber);
305  initFile(false);
306  assert(rootFile());
307  rootFile()->setPosition(originalPosition);
308  }
309  }
310  return false;
311  }
312 
313  int
315  return input_.remainingEvents();
316  }
317 
318  int
321  }
322 
323  void
325  desc.addUntracked<unsigned int>("skipEvents", 0U)
326  ->setComment("Skip the first 'skipEvents' events that otherwise would have been processed.");
327  desc.addUntracked<bool>("noEventSort", true)
328  ->setComment("True: Process runs, lumis and events in the order they appear in the file (but see notes 1 and 2).\n"
329  "False: Process runs, lumis and events in each file in numerical order (run#, lumi#, event#) (but see note 3).\n"
330  "Note 1: Events within the same lumi will always be processed contiguously.\n"
331  "Note 2: Lumis within the same run will always be processed contiguously.\n"
332  "Note 3: Any sorting occurs independently in each input file (no sorting across input files).");
333  desc.addUntracked<unsigned int>("cacheSize", roottree::defaultCacheSize)
334  ->setComment("Size of ROOT TTree prefetch cache. Affects performance.");
335  std::string defaultString("permissive");
336  desc.addUntracked<std::string>("branchesMustMatch", defaultString)
337  ->setComment("'strict': Branches in each input file must match those in the first file.\n"
338  "'permissive': Branches in each input file may be any subset of those in the first file.");
339  desc.addUntracked<bool>("enforceGUIDInFileName", false)
340  ->setComment(
341  "True: file name part is required to be equal to the GUID of the file\n"
342  "False: file name can be anything");
343 
346  }
347 
350  if(rootFile()) {
351  if(!rootFile()->wasLastEventJustRead()) {
353  }
354  if(noMoreFiles() || atLastFile()) {
356  } else {
358  }
359  }
361  }
362 
365  if(rootFile()) {
366  if(!rootFile()->wasFirstEventJustRead()) {
368  }
369  if(!atFirstFile()) {
371  }
373  }
375  }
376 
377 }
RunNumber_t run() const
Definition: EventID.h:39
size
Write out results.
EventNumber_t event() const
Definition: EventID.h:41
T getUntrackedParameter(std::string const &, T const &) const
std::string const & logicalFileName() const
void initFile(bool skipBadFiles)
ProductRegistry & productRegistryUpdate()
Definition: InputSource.h:334
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
std::string const & fileName() const
InputSource::ItemType getNextItemType(RunNumber_t &run, LuminosityBlockNumber_t &lumi, EventNumber_t &event)
void setAtFileSequenceNumber(size_t offset)
def create(alignables, pedeDump, additionalData, outputFile, config)
void initFile_(bool skipBadFiles) override
ProcessingController::ForwardState forwardState() const
unsigned long long EventNumber_t
std::vector< std::shared_ptr< IndexIntoFile > > const & indexesIntoFiles() const
ProcessingMode processingMode() const
RunsLumisAndEvents (default), RunsAndLumis, or Runs.
Definition: InputSource.h:240
static void fillDescription(ParameterSetDescription &desc)
static void fillDescription(ParameterSetDescription &desc)
std::unique_ptr< FileBlock > readFile_()
LuminosityBlockNumber_t luminosityBlock() const
Definition: EventID.h:40
unsigned int const defaultCacheSize
Definition: RootTree.h:46
unsigned int LuminosityBlockNumber_t
static std::string const input
Definition: EdmProvDump.cc:44
RunHelperBase * runHelper()
Definition: PoolSource.h:47
ProcessingController::ReverseState reverseState() const
std::shared_ptr< RootFile > RootFileSharedPtr
bool goToEvent(EventID const &eventID)
static const StorageFactory * get(void)
int remainingEvents() const
Definition: InputSource.h:194
void stagein(const std::string &url) const
std::string const & lfn() const
RootFileSharedPtr makeRootFile(std::shared_ptr< InputFile > filePtr) override
void initTheFile(bool skipBadFiles, bool deleteIndexIntoFile, InputSource *input, char const *inputTypeName, InputType inputType)
std::vector< ProcessHistoryID > orderedProcessHistoryIDs_
bool isAvailable() const
Definition: Service.h:46
RootPrimaryFileSequence(ParameterSet const &pset, PoolSource &input, InputFileCatalog const &catalog)
std::string merge(ProductRegistry const &other, std::string const &fileName, BranchDescription::MatchMode branchesMustMatch=BranchDescription::Permissive)
unsigned int nStreams() const
Definition: PoolSource.h:44
bool dropDescendants() const
Definition: PoolSource.h:41
bool bypassVersionCheck() const
Definition: PoolSource.h:42
#define end
Definition: vmac.h:39
std::shared_ptr< RootFile const > rootFile() const
int treeMaxVirtualSize() const
Definition: PoolSource.h:45
bool skipBadFiles() const
Definition: PoolSource.h:40
std::shared_ptr< EventSkipperByID const > eventSkipperByID() const
std::shared_ptr< BranchIDListHelper const > branchIDListHelper() const
Accessors for branchIDListHelper.
Definition: InputSource.h:172
bool labelRawDataLikeMC() const
Definition: PoolSource.h:43
edm::propagate_const< std::shared_ptr< DuplicateChecker > > duplicateChecker_
ProcessHistoryRegistry & processHistoryRegistryForUpdate()
Definition: InputSource.h:335
BranchDescription::MatchMode branchesMustMatch_
static void fillDescription(ParameterSetDescription &desc)
#define begin
Definition: vmac.h:32
HLT enums.
std::shared_ptr< ThinnedAssociationsHelper const > thinnedAssociationsHelper() const
Accessors for thinnedAssociationsHelper.
Definition: InputSource.h:176
void updateFromInput(ProductList const &other)
int remainingLuminosityBlocks() const
Definition: InputSource.h:202
unsigned int RunNumber_t
ProcessConfiguration const & processConfiguration() const
Accessor for Process Configuration.
Definition: InputSource.h:208
std::shared_ptr< DuplicateChecker const > duplicateChecker() const
Definition: event.py:1
ProductSelectorRules const & productSelectorRules() const
Definition: PoolSource.h:46