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 
38  // The SiteLocalConfig controls the TTreeCache size and the prefetching settings.
40  if(pSLC.isAvailable()) {
41  if(treeCacheSize_ != 0U && pSLC->sourceTTreeCacheSize()) {
42  treeCacheSize_ = *(pSLC->sourceTTreeCacheSize());
43  }
44  enablePrefetching_ = pSLC->enablePrefetching();
45  }
46 
47  std::string branchesMustMatch = pset.getUntrackedParameter<std::string>("branchesMustMatch", std::string("permissive"));
48  if(branchesMustMatch == std::string("strict")) branchesMustMatch_ = BranchDescription::Strict;
49 
50  // Prestage the files
53  }
54  // Open the first file.
57  if(rootFile()) break;
58  }
59  if(rootFile()) {
60  input_.productRegistryUpdate().updateFromInput(rootFile()->productRegistry()->productList());
63  }
64  }
65  }
66 
68  }
69 
70  void
72  closeFile_();
73  }
74 
75  std::unique_ptr<FileBlock>
77  if(firstFile_) {
78  // The first input file has already been opened.
79  firstFile_ = false;
80  if(!rootFile()) {
82  }
83  } else {
84  if(!nextFile()) {
85  assert(0);
86  }
87  }
88  if(!rootFile()) {
89  return std::make_unique<FileBlock>();
90  }
91  return rootFile()->createFileBlock();
92  }
93 
94  void
96  // close the currently open file, if any, and delete the RootFile object.
97  if(rootFile()) {
98  auto sentry = std::make_unique<InputSource::FileCloseSentry>(input_, lfn(), usedFallback());
99  rootFile()->close();
100  if(duplicateChecker_) duplicateChecker_->inputFileClosed();
101  rootFile().reset();
102  }
103  }
104 
105  void
107  // If we are not duplicate checking across files and we are not using random access to find events,
108  // then we can delete the IndexIntoFile for the file we are closing.
109  // If we can't delete all of it, then we can delete the parts we do not need.
110  bool deleteIndexIntoFile = !usingGoToEvent_ && !(duplicateChecker_ && duplicateChecker_->checkingAllFiles() && !duplicateChecker_->checkDisabled());
111  initTheFile(skipBadFiles, deleteIndexIntoFile, &input_, "primaryFiles", InputType::Primary);
112  }
113 
115  RootPrimaryFileSequence::makeRootFile(std::shared_ptr<InputFile> filePtr) {
116  size_t currentIndexIntoFile = sequenceNumberOfFile();
117  return std::make_shared<RootFile>(
118  fileName(),
120  logicalFileName(),
121  filePtr,
124  remainingEvents(),
126  input_.nStreams(),
130  input_.runHelper(),
131  noEventSort_,
136  nullptr, // associationsFromSecondary
141  currentIndexIntoFile,
147  }
148 
150  if(!noMoreFiles()) setAtNextFile();
151  if(noMoreFiles()) {
152  return false;
153  }
154 
156 
157  if(rootFile()) {
158  // make sure the new product registry is compatible with the main one
159  std::string mergeInfo = input_.productRegistryUpdate().merge(*rootFile()->productRegistry(),
160  fileName(),
162  if(!mergeInfo.empty()) {
163  throw Exception(errors::MismatchedInputFiles,"RootPrimaryFileSequence::nextFile()") << mergeInfo;
164  }
165  }
166  return true;
167  }
168 
170  if(atFirstFile()) {
171  return false;
172  }
174 
175  initFile(false);
176 
177  if(rootFile()) {
178  // make sure the new product registry is compatible to the main one
179  std::string mergeInfo = input_.productRegistryUpdate().merge(*rootFile()->productRegistry(),
180  fileName(),
182  if(!mergeInfo.empty()) {
183  throw Exception(errors::MismatchedInputFiles,"RootPrimaryFileSequence::previousEvent()") << mergeInfo;
184  }
185  }
186  if(rootFile()) rootFile()->setToLastEntry();
187  return true;
188  }
189 
192  if(noMoreFiles()) {
193  return InputSource::IsStop;
194  }
195  if(firstFile_) {
196  return InputSource::IsFile;
197  }
198  if(rootFile()) {
199  IndexIntoFile::EntryType entryType = rootFile()->getNextItemType(run, lumi, event);
200  if(entryType == IndexIntoFile::kEvent) {
201  return InputSource::IsEvent;
202  } else if(entryType == IndexIntoFile::kLumi) {
203  return InputSource::IsLumi;
204  } else if(entryType == IndexIntoFile::kRun) {
205  return InputSource::IsRun;
206  }
207  assert(entryType == IndexIntoFile::kEnd);
208  }
209  if(atLastFile()) {
210  return InputSource::IsStop;
211  }
212  return InputSource::IsFile;
213  }
214 
215  // Rewind to before the first event that was read.
216  void
218  if(!atFirstFile()) {
219  closeFile_();
220  setAtFirstFile();
221  }
222  if(!rootFile()) {
223  initFile(false);
224  }
225  rewindFile();
226  firstFile_ = true;
227  if(rootFile()) {
230  }
231  }
232  }
233 
234  // Rewind to the beginning of the current file
235  void
237  if(rootFile()) rootFile()->rewind();
238  }
239 
240  // Advance "offset" events. Offset can be positive or negative (or zero).
241  bool
243  assert(rootFile());
244  while(offset != 0) {
245  bool atEnd = rootFile()->skipEvents(offset);
246  if((offset > 0 || atEnd) && !nextFile()) {
247  return false;
248  }
249  if(offset < 0 && !previousFile()) {
250  setNoMoreFiles();
251  return false;
252  }
253  }
254  return true;
255  }
256 
257  bool
259  usingGoToEvent_ = true;
260  if(rootFile()) {
261  if(rootFile()->goToEvent(eventID)) {
262  return true;
263  }
264  // If only one input file, give up now, to save time.
265  if(rootFile() && indexesIntoFiles().size() == 1) {
266  return false;
267  }
268  // Save the current file and position so that we can restore them
269  // if we fail to restore the desired event
270  bool closedOriginalFile = false;
271  size_t const originalFileSequenceNumber = sequenceNumberOfFile();
272  IndexIntoFile::IndexIntoFileItr originalPosition = rootFile()->indexIntoFileIter();
273 
274  // Look for item (run/lumi/event) in files previously opened without reopening unnecessary files.
275  for(auto it = indexesIntoFiles().begin(), itEnd = indexesIntoFiles().end(); it != itEnd; ++it) {
276  if(*it && (*it)->containsItem(eventID.run(), eventID.luminosityBlock(), eventID.event())) {
277  // We found it. Close the currently open file, and open the correct one.
279  initFile(false);
280  // Now get the item from the correct file.
281  assert(rootFile());
282  bool found = rootFile()->goToEvent(eventID);
283  assert(found);
284  return true;
285  }
286  }
287  // Look for item in files not yet opened.
288  for(auto it = indexesIntoFiles().begin(), itEnd = indexesIntoFiles().end(); it != itEnd; ++it) {
289  if(!*it) {
291  initFile(false);
292  closedOriginalFile = true;
293  if((*it)->containsItem(eventID.run(), eventID.luminosityBlock(), eventID.event())) {
294  assert(rootFile());
295  if(rootFile()->goToEvent(eventID)) {
296  return true;
297  }
298  }
299  }
300  }
301  if(closedOriginalFile) {
302  setAtFileSequenceNumber(originalFileSequenceNumber);
303  initFile(false);
304  assert(rootFile());
305  rootFile()->setPosition(originalPosition);
306  }
307  }
308  return false;
309  }
310 
311  int
313  return input_.remainingEvents();
314  }
315 
316  int
319  }
320 
321  void
323  desc.addUntracked<unsigned int>("skipEvents", 0U)
324  ->setComment("Skip the first 'skipEvents' events that otherwise would have been processed.");
325  desc.addUntracked<bool>("noEventSort", true)
326  ->setComment("True: Process runs, lumis and events in the order they appear in the file (but see notes 1 and 2).\n"
327  "False: Process runs, lumis and events in each file in numerical order (run#, lumi#, event#) (but see note 3).\n"
328  "Note 1: Events within the same lumi will always be processed contiguously.\n"
329  "Note 2: Lumis within the same run will always be processed contiguously.\n"
330  "Note 3: Any sorting occurs independently in each input file (no sorting across input files).");
331  desc.addUntracked<unsigned int>("cacheSize", roottree::defaultCacheSize)
332  ->setComment("Size of ROOT TTree prefetch cache. Affects performance.");
333  std::string defaultString("permissive");
334  desc.addUntracked<std::string>("branchesMustMatch", defaultString)
335  ->setComment("'strict': Branches in each input file must match those in the first file.\n"
336  "'permissive': Branches in each input file may be any subset of those in the first file.");
337 
340  }
341 
344  if(rootFile()) {
345  if(!rootFile()->wasLastEventJustRead()) {
347  }
348  if(noMoreFiles() || atLastFile()) {
350  } else {
352  }
353  }
355  }
356 
359  if(rootFile()) {
360  if(!rootFile()->wasFirstEventJustRead()) {
362  }
363  if(!atFirstFile()) {
365  }
367  }
369  }
370 
371 }
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:344
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)
virtual void closeFile_() override
void setAtFileSequenceNumber(size_t offset)
def create(alignables, pedeDump, additionalData, outputFile, config)
virtual 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:246
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:45
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
virtual 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:37
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:345
BranchDescription::MatchMode branchesMustMatch_
static void fillDescription(ParameterSetDescription &desc)
#define begin
Definition: vmac.h:30
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