CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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 {
24  : RootInputFileSequence(pset, catalog),
25  input_(input),
26  firstFile_(true),
27  branchesMustMatch_(BranchDescription::Permissive),
28  orderedProcessHistoryIDs_(),
29  eventSkipperByID_(EventSkipperByID::create(pset).release()),
30  initialNumberOfEventsToSkip_(pset.getUntrackedParameter<unsigned int>("skipEvents")),
31  noEventSort_(pset.getUntrackedParameter<bool>("noEventSort")),
32  treeCacheSize_(noEventSort_ ? pset.getUntrackedParameter<unsigned int>("cacheSize") : 0U),
33  duplicateChecker_(new DuplicateChecker(pset)),
34  usingGoToEvent_(false),
35  enablePrefetching_(false),
36  enforceGUIDInFileName_(pset.getUntrackedParameter<bool>("enforceGUIDInFileName")) {
37  // The SiteLocalConfig controls the TTreeCache size and the prefetching settings.
39  if (pSLC.isAvailable()) {
40  if (treeCacheSize_ != 0U && pSLC->sourceTTreeCacheSize()) {
41  treeCacheSize_ = *(pSLC->sourceTTreeCacheSize());
42  }
43  enablePrefetching_ = pSLC->enablePrefetching();
44  }
45 
46  std::string branchesMustMatch =
47  pset.getUntrackedParameter<std::string>("branchesMustMatch", std::string("permissive"));
48  if (branchesMustMatch == std::string("strict"))
50 
51  // Prestage the files
54  }
55  // Open the first file.
58  if (rootFile())
59  break;
60  }
61  if (rootFile()) {
62  input_.productRegistryUpdate().updateFromInput(rootFile()->productRegistry()->productList());
65  }
66  }
67  }
68 
70 
72 
73  std::unique_ptr<FileBlock> RootPrimaryFileSequence::readFile_() {
74  if (firstFile_) {
75  // The first input file has already been opened.
76  firstFile_ = false;
77  if (!rootFile()) {
79  }
80  } else {
81  if (!nextFile()) {
82  assert(0);
83  }
84  }
85  if (!rootFile()) {
86  return std::unique_ptr<FileBlock>(new FileBlock);
87  }
88  return rootFile()->createFileBlock();
89  }
90 
92  // close the currently open file, if any, and delete the RootFile object.
93  if (rootFile()) {
94  std::unique_ptr<InputSource::FileCloseSentry>
96  rootFile()->close();
98  duplicateChecker_->inputFileClosed();
99  rootFile().reset();
100  }
101  }
102 
104  // If we are not duplicate checking across files and we are not using random access to find events,
105  // then we can delete the IndexIntoFile for the file we are closing.
106  // If we can't delete all of it, then we can delete the parts we do not need.
107  bool deleteIndexIntoFile = !usingGoToEvent_ && !(duplicateChecker_ && duplicateChecker_->checkingAllFiles() &&
108  !duplicateChecker_->checkDisabled());
109  initTheFile(skipBadFiles, deleteIndexIntoFile, &input_, "primaryFiles", InputType::Primary);
110  }
111 
113  size_t currentIndexIntoFile = sequenceNumberOfFile();
114  return std::make_shared<RootFile>(fileName(),
116  logicalFileName(),
117  filePtr,
120  remainingEvents(),
122  input_.nStreams(),
126  input_.runHelper(),
127  noEventSort_,
132  nullptr, // associationsFromSecondary
137  currentIndexIntoFile,
144  }
145 
147  if (!noMoreFiles())
148  setAtNextFile();
149  if (noMoreFiles()) {
150  return false;
151  }
152 
154 
155  if (rootFile()) {
156  // make sure the new product registry is compatible with the main one
157  std::string mergeInfo =
159  if (!mergeInfo.empty()) {
160  throw Exception(errors::MismatchedInputFiles, "RootPrimaryFileSequence::nextFile()") << mergeInfo;
161  }
162  }
163  return true;
164  }
165 
167  if (atFirstFile()) {
168  return false;
169  }
171 
172  initFile(false);
173 
174  if (rootFile()) {
175  // make sure the new product registry is compatible to the main one
176  std::string mergeInfo =
178  if (!mergeInfo.empty()) {
179  throw Exception(errors::MismatchedInputFiles, "RootPrimaryFileSequence::previousEvent()") << mergeInfo;
180  }
181  }
182  if (rootFile())
183  rootFile()->setToLastEntry();
184  return true;
185  }
186 
189  EventNumber_t& event) {
190  if (noMoreFiles()) {
191  return InputSource::IsStop;
192  }
193  if (firstFile_) {
194  return InputSource::IsFile;
195  }
196  if (rootFile()) {
197  IndexIntoFile::EntryType entryType = rootFile()->getNextItemType(run, lumi, event);
198  if (entryType == IndexIntoFile::kEvent) {
199  return InputSource::IsEvent;
200  } else if (entryType == IndexIntoFile::kLumi) {
201  return InputSource::IsLumi;
202  } else if (entryType == IndexIntoFile::kRun) {
203  return InputSource::IsRun;
204  }
205  assert(entryType == IndexIntoFile::kEnd);
206  }
207  if (atLastFile()) {
208  return InputSource::IsStop;
209  }
210  return InputSource::IsFile;
211  }
212 
213  // Rewind to before the first event that was read.
215  if (!atFirstFile()) {
216  closeFile();
217  setAtFirstFile();
218  }
219  if (!rootFile()) {
220  initFile(false);
221  }
222  rewindFile();
223  firstFile_ = true;
224  if (rootFile()) {
225  if (initialNumberOfEventsToSkip_ != 0) {
227  }
228  }
229  }
230 
231  // Rewind to the beginning of the current file
233  if (rootFile())
234  rootFile()->rewind();
235  }
236 
237  // Advance "offset" events. Offset can be positive or negative (or zero).
239  assert(rootFile());
240  while (offset != 0) {
241  bool atEnd = rootFile()->skipEvents(offset);
242  if ((offset > 0 || atEnd) && !nextFile()) {
243  return false;
244  }
245  if (offset < 0 && !previousFile()) {
246  setNoMoreFiles();
247  return false;
248  }
249  }
250  return true;
251  }
252 
254  usingGoToEvent_ = true;
255  if (rootFile()) {
256  if (rootFile()->goToEvent(eventID)) {
257  return true;
258  }
259  // If only one input file, give up now, to save time.
260  if (rootFile() && indexesIntoFiles().size() == 1) {
261  return false;
262  }
263  // Save the current file and position so that we can restore them
264  // if we fail to restore the desired event
265  bool closedOriginalFile = false;
266  size_t const originalFileSequenceNumber = sequenceNumberOfFile();
267  IndexIntoFile::IndexIntoFileItr originalPosition = rootFile()->indexIntoFileIter();
268 
269  // Look for item (run/lumi/event) in files previously opened without reopening unnecessary files.
270  for (auto it = indexesIntoFiles().begin(), itEnd = indexesIntoFiles().end(); it != itEnd; ++it) {
271  if (*it && (*it)->containsItem(eventID.run(), eventID.luminosityBlock(), eventID.event())) {
272  // We found it. Close the currently open file, and open the correct one.
274  initFile(false);
275  // Now get the item from the correct file.
276  assert(rootFile());
277  bool found = rootFile()->goToEvent(eventID);
278  assert(found);
279  return true;
280  }
281  }
282  // Look for item in files not yet opened.
283  for (auto it = indexesIntoFiles().begin(), itEnd = indexesIntoFiles().end(); it != itEnd; ++it) {
284  if (!*it) {
286  initFile(false);
287  closedOriginalFile = true;
288  if ((*it)->containsItem(eventID.run(), eventID.luminosityBlock(), eventID.event())) {
289  assert(rootFile());
290  if (rootFile()->goToEvent(eventID)) {
291  return true;
292  }
293  }
294  }
295  }
296  if (closedOriginalFile) {
297  setAtFileSequenceNumber(originalFileSequenceNumber);
298  initFile(false);
299  assert(rootFile());
300  rootFile()->setPosition(originalPosition);
301  }
302  }
303  return false;
304  }
305 
307 
309 
311  desc.addUntracked<unsigned int>("skipEvents", 0U)
312  ->setComment("Skip the first 'skipEvents' events that otherwise would have been processed.");
313  desc.addUntracked<bool>("noEventSort", true)
314  ->setComment(
315  "True: Process runs, lumis and events in the order they appear in the file (but see notes 1 and 2).\n"
316  "False: Process runs, lumis and events in each file in numerical order (run#, lumi#, event#) (but see note "
317  "3).\n"
318  "Note 1: Events within the same lumi will always be processed contiguously.\n"
319  "Note 2: Lumis within the same run will always be processed contiguously.\n"
320  "Note 3: Any sorting occurs independently in each input file (no sorting across input files).");
321  desc.addUntracked<unsigned int>("cacheSize", roottree::defaultCacheSize)
322  ->setComment("Size of ROOT TTree prefetch cache. Affects performance.");
323  std::string defaultString("permissive");
324  desc.addUntracked<std::string>("branchesMustMatch", defaultString)
325  ->setComment(
326  "'strict': Branches in each input file must match those in the first file.\n"
327  "'permissive': Branches in each input file may be any subset of those in the first file.");
328  desc.addUntracked<bool>("enforceGUIDInFileName", false)
329  ->setComment(
330  "True: file name part is required to be equal to the GUID of the file\n"
331  "False: file name can be anything");
332 
335  }
336 
338  if (rootFile()) {
339  if (!rootFile()->wasLastEventJustRead()) {
341  }
342  if (noMoreFiles() || atLastFile()) {
344  } else {
346  }
347  }
349  }
350 
352  if (rootFile()) {
353  if (!rootFile()->wasFirstEventJustRead()) {
355  }
356  if (!atFirstFile()) {
358  }
360  }
362  }
363 
364 } // namespace edm
RunNumber_t run() const
Definition: EventID.h:39
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:350
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)
virtual void initFile_(bool skipBadFiles) override
ProcessingController::ForwardState forwardState() const
tuple lumi
Definition: fjr2json.py:35
assert(m_qm.get())
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:256
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:37
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:200
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
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
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:178
bool labelRawDataLikeMC() const
Definition: PoolSource.h:43
edm::propagate_const< std::shared_ptr< DuplicateChecker > > duplicateChecker_
ProcessHistoryRegistry & processHistoryRegistryForUpdate()
Definition: InputSource.h:351
BranchDescription::MatchMode branchesMustMatch_
tuple skipBadFiles
Definition: example_cfg.py:64
static void fillDescription(ParameterSetDescription &desc)
#define begin
Definition: vmac.h:30
std::shared_ptr< ThinnedAssociationsHelper const > thinnedAssociationsHelper() const
Accessors for thinnedAssociationsHelper.
Definition: InputSource.h:182
void updateFromInput(ProductList const &other)
int remainingLuminosityBlocks() const
Definition: InputSource.h:208
unsigned int RunNumber_t
volatile std::atomic< bool > shutdown_flag false
ProcessConfiguration const & processConfiguration() const
Accessor for Process Configuration.
Definition: InputSource.h:214
std::shared_ptr< DuplicateChecker const > duplicateChecker() const
tuple size
Write out results.
ProductSelectorRules const & productSelectorRules() const
Definition: PoolSource.h:46