CMS 3D CMS Logo

RootEmbeddedFileSequence.cc
Go to the documentation of this file.
1 /*----------------------------------------------------------------------
2 ----------------------------------------------------------------------*/
3 #include "EmbeddedRootSource.h"
4 #include "InputFile.h"
5 #include "RootFile.h"
7 #include "RootTree.h"
8 
18 
19 #include "CLHEP/Random/RandFlat.h"
20 
21 #include <random>
22 
23 namespace edm {
24  class EventPrincipal;
25 
29  : RootInputFileSequence(pset, catalog),
30  input_(input),
31  orderedProcessHistoryIDs_(),
32  sequential_(pset.getUntrackedParameter<bool>("sequential", false)),
33  sameLumiBlock_(pset.getUntrackedParameter<bool>("sameLumiBlock", false)),
34  fptr_(nullptr),
35  eventsRemainingInFile_(0),
36  // The default value provided as the second argument to the getUntrackedParameter function call
37  // is not used when the ParameterSet has been validated and the parameters are not optional
38  // in the description. This is currently true when PoolSource is the primary input source.
39  // The modules that use PoolSource as a SecSource have not defined their fillDescriptions function
40  // yet, so the ParameterSet does not get validated yet. As soon as all the modules with a SecSource
41  // have defined descriptions, the defaults in the getUntrackedParameterSet function calls can
42  // and should be deleted from the code.
43  initialNumberOfEventsToSkip_(pset.getUntrackedParameter<unsigned int>("skipEvents", 0U)),
44  treeCacheSize_(pset.getUntrackedParameter<unsigned int>("cacheSize", roottree::defaultCacheSize)),
45  enablePrefetching_(false),
46  enforceGUIDInFileName_(pset.getUntrackedParameter<bool>("enforceGUIDInFileName", false)) {
47  if (noFiles()) {
49  << "RootEmbeddedFileSequence no input files specified for secondary input source.\n";
50  }
51  //
52  // The SiteLocalConfig controls the TTreeCache size and the prefetching settings.
54  if (pSLC.isAvailable()) {
55  if (treeCacheSize_ != 0U && pSLC->sourceTTreeCacheSize()) {
56  treeCacheSize_ = *(pSLC->sourceTTreeCacheSize());
57  }
58  enablePrefetching_ = pSLC->enablePrefetching();
59  }
60 
61  // Set the pointer to the function that reads an event.
62  if (sameLumiBlock_) {
63  if (sequential_) {
65  } else {
67  }
68  } else {
69  if (sequential_) {
71  } else {
73  }
74  }
75 
76  // For the secondary input source we do not stage in.
77  if (sequential_) {
78  // We open the first file
79  if (!atFirstFile()) {
81  initFile(false);
82  }
83  assert(rootFile());
84  rootFile()->setAtEventEntry(IndexIntoFile::invalidEntry);
85  if (!sameLumiBlock_) {
87  }
88  } else {
89  // We randomly choose the first file to open.
90  // We cannot use the random number service yet.
91  std::ifstream f("/dev/urandom");
92  unsigned int seed;
93  f.read(reinterpret_cast<char*>(&seed), sizeof(seed));
94  std::default_random_engine dre(seed);
95  size_t count = numberOfFiles();
96  std::uniform_int_distribution<int> distribution(0, count - 1);
97  while (!rootFile() && count != 0) {
98  --count;
99  int offset = distribution(dre);
100  setAtFileSequenceNumber(offset);
102  }
103  }
104  if (rootFile()) {
105  input_.productRegistryUpdate().updateFromInput(rootFile()->productRegistry()->productList());
106  }
107  }
108 
110 
112 
114  // delete the RootFile object.
115  if (rootFile()) {
116  rootFile().reset();
117  }
118  }
119 
121  initTheFile(skipBadFiles, false, nullptr, "mixingFiles", InputType::SecondarySource);
122  }
123 
125  std::shared_ptr<InputFile> filePtr) {
126  size_t currentIndexIntoFile = sequenceNumberOfFile();
127  return std::make_shared<RootFile>(fileName(),
129  logicalFileName(),
130  filePtr,
131  input_.nStreams(),
134  input_.runHelper(),
139  currentIndexIntoFile,
144  }
145 
147  // offset is decremented by the number of events actually skipped.
148  bool completed = rootFile()->skipEntries(offset);
149  while (!completed) {
150  setAtNextFile();
151  if (noMoreFiles()) {
152  setAtFirstFile();
153  }
154  initFile(false);
155  assert(rootFile());
156  rootFile()->setAtEventEntry(IndexIntoFile::invalidEntry);
157  completed = rootFile()->skipEntries(offset);
158  }
159  }
160 
162  EventPrincipal& cache, size_t& fileNameHash, CLHEP::HepRandomEngine*, EventID const*, bool recycleFiles) {
163  assert(rootFile());
164  rootFile()->nextEventEntry();
165  bool found = rootFile()->readCurrentEvent(cache);
166  if (!found) {
167  setAtNextFile();
168  if (noMoreFiles()) {
169  if (recycleFiles) {
170  setAtFirstFile();
171  } else {
172  return false;
173  }
174  }
175  initFile(false);
176  assert(rootFile());
177  rootFile()->setAtEventEntry(IndexIntoFile::invalidEntry);
178  return readOneSequential(cache, fileNameHash, nullptr, nullptr, recycleFiles);
179  }
180  fileNameHash = lfnHash();
181  return true;
182  }
183 
185  EventPrincipal& cache, size_t& fileNameHash, CLHEP::HepRandomEngine*, EventID const* idp, bool recycleFiles) {
186  assert(idp);
187  EventID const& id = *idp;
190  if (offset > 0) {
191  assert(rootFile());
192  while (offset > 0) {
193  bool found = readOneSequentialWithID(cache, fileNameHash, nullptr, idp, recycleFiles);
194  if (!found) {
195  return false;
196  }
197  --offset;
198  }
199  }
200  assert(rootFile());
201  if (noMoreFiles() || rootFile()->indexIntoFileIter().run() != id.run() ||
202  rootFile()->indexIntoFileIter().lumi() != id.luminosityBlock()) {
203  bool found = skipToItem(id.run(), id.luminosityBlock(), 0, 0, false);
204  if (!found) {
205  return false;
206  }
207  }
208  assert(rootFile());
209  bool found = rootFile()->setEntryAtNextEventInLumi(id.run(), id.luminosityBlock());
210  if (found) {
211  found = rootFile()->readCurrentEvent(cache);
212  }
213  if (!found) {
214  found = skipToItemInNewFile(id.run(), id.luminosityBlock(), 0);
215  if (!found) {
216  return false;
217  }
218  return readOneSequentialWithID(cache, fileNameHash, nullptr, idp, recycleFiles);
219  }
220  fileNameHash = lfnHash();
221  return true;
222  }
223 
225  size_t& fileNameHash,
227  EventID const& id = idx.eventID();
228  bool found = skipToItem(id.run(), id.luminosityBlock(), id.event(), idx.fileNameHash());
229  if (!found) {
230  throw Exception(errors::NotFound) << "RootEmbeddedFileSequence::readOneSpecified(): Secondary Input files"
231  << " do not contain specified event:\n"
232  << id << "\n";
233  }
234  assert(rootFile());
235  found = rootFile()->readCurrentEvent(cache);
236  assert(found);
237  fileNameHash = idx.fileNameHash();
238  if (fileNameHash == 0U) {
239  fileNameHash = lfnHash();
240  }
241  }
242 
244  EventPrincipal& cache, size_t& fileNameHash, CLHEP::HepRandomEngine* engine, EventID const*, bool) {
245  assert(rootFile());
246  assert(engine);
247  unsigned int currentSeqNumber = sequenceNumberOfFile();
248  while (eventsRemainingInFile_ == 0) {
249  unsigned int newSeqNumber = CLHEP::RandFlat::shootInt(engine, fileCatalogItems().size());
250  setAtFileSequenceNumber(newSeqNumber);
251  if (newSeqNumber != currentSeqNumber) {
252  initFile(false);
253  currentSeqNumber = newSeqNumber;
254  }
255  eventsRemainingInFile_ = rootFile()->eventTree().entries();
256  if (eventsRemainingInFile_ == 0) {
257  throw Exception(errors::NotFound) << "RootEmbeddedFileSequence::readOneRandom(): Secondary Input file "
258  << fileName() << " contains no events.\n";
259  }
260  rootFile()->setAtEventEntry(CLHEP::RandFlat::shootInt(engine, eventsRemainingInFile_) - 1);
261  }
262  rootFile()->nextEventEntry();
263 
264  bool found = rootFile()->readCurrentEvent(cache);
265  if (!found) {
266  rootFile()->setAtEventEntry(0);
267  bool found = rootFile()->readCurrentEvent(cache);
268  assert(found);
269  }
270  fileNameHash = lfnHash();
272  return true;
273  }
274 
276  size_t& fileNameHash,
277  CLHEP::HepRandomEngine* engine,
278  EventID const* idp,
279  bool recycleFiles) {
280  assert(engine);
281  assert(idp);
282  EventID const& id = *idp;
283  if (noMoreFiles() || !rootFile() || rootFile()->indexIntoFileIter().run() != id.run() ||
284  rootFile()->indexIntoFileIter().lumi() != id.luminosityBlock()) {
285  bool found = skipToItem(id.run(), id.luminosityBlock(), 0);
286  if (!found) {
287  return false;
288  }
289  int eventsInLumi = 0;
290  assert(rootFile());
291  while (rootFile()->setEntryAtNextEventInLumi(id.run(), id.luminosityBlock()))
292  ++eventsInLumi;
293  found = skipToItem(id.run(), id.luminosityBlock(), 0);
294  assert(found);
295  int eventInLumi = CLHEP::RandFlat::shootInt(engine, eventsInLumi);
296  for (int i = 0; i < eventInLumi; ++i) {
297  bool found = rootFile()->setEntryAtNextEventInLumi(id.run(), id.luminosityBlock());
298  assert(found);
299  }
300  }
301  assert(rootFile());
302  bool found = rootFile()->setEntryAtNextEventInLumi(id.run(), id.luminosityBlock());
303  if (found) {
304  found = rootFile()->readCurrentEvent(cache);
305  }
306  if (!found) {
307  bool found = rootFile()->setEntryAtItem(id.run(), id.luminosityBlock(), 0);
308  if (!found) {
309  return false;
310  }
311  return readOneRandomWithID(cache, fileNameHash, engine, idp, recycleFiles);
312  }
313  fileNameHash = lfnHash();
314  return true;
315  }
316 
318  size_t& fileNameHash,
319  CLHEP::HepRandomEngine* engine,
320  EventID const* id,
321  bool recycleFiles) {
322  assert(!sameLumiBlock_ || id != nullptr);
323  assert(sequential_ || engine != nullptr);
324  return (this->*fptr_)(cache, fileNameHash, engine, id, recycleFiles);
325  }
326 
328  desc.addUntracked<bool>("sequential", false)
329  ->setComment(
330  "True: loopEvents() reads events sequentially from beginning of first file.\n"
331  "False: loopEvents() first reads events beginning at random event. New files also chosen randomly");
332  desc.addUntracked<bool>("sameLumiBlock", false)
333  ->setComment(
334  "True: loopEvents() reads events only in same lumi as the specified event.\n"
335  "False: loopEvents() reads events regardless of lumi.");
336  desc.addUntracked<unsigned int>("skipEvents", 0U)
337  ->setComment(
338  "Skip the first 'skipEvents' events. Used only if 'sequential' is True and 'sameLumiBlock' is False");
339  desc.addUntracked<unsigned int>("cacheSize", roottree::defaultCacheSize)
340  ->setComment("Size of ROOT TTree prefetch cache. Affects performance.");
341  desc.addUntracked<bool>("enforceGUIDInFileName", false)
342  ->setComment(
343  "True: file name part is required to be equal to the GUID of the file\n"
344  "False: file name can be anything");
345  }
346 } // namespace edm
size
Write out results.
ProductRegistry & productRegistryUpdate()
std::string const & logicalFileName() const
RootFileSharedPtr makeRootFile(std::shared_ptr< InputFile > filePtr) override
ProcessHistoryRegistry & processHistoryRegistryForUpdate()
void initFile(bool skipBadFiles)
bool readOneRandomWithID(EventPrincipal &cache, size_t &fileNameHash, CLHEP::HepRandomEngine *, EventID const *id, bool)
void readOneSpecified(EventPrincipal &cache, size_t &fileNameHash, SecondaryEventIDAndFileInfo const &id)
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
std::string const & fileName() const
void setAtFileSequenceNumber(size_t offset)
unsigned int nStreams() const
bool readOneSequentialWithID(EventPrincipal &cache, size_t &fileNameHash, CLHEP::HepRandomEngine *, EventID const *id, bool)
#define nullptr
std::vector< std::shared_ptr< IndexIntoFile > > const & indexesIntoFiles() const
void initFile_(bool skipBadFiles) override
unsigned int const defaultCacheSize
Definition: RootTree.h:46
bool readOneRandom(EventPrincipal &cache, size_t &fileNameHash, CLHEP::HepRandomEngine *, EventID const *, bool)
bool bypassVersionCheck() const
static std::string const input
Definition: EdmProvDump.cc:48
std::shared_ptr< RootFile > RootFileSharedPtr
bool readOneEvent(EventPrincipal &cache, size_t &fileNameHash, CLHEP::HepRandomEngine *, EventID const *id, bool recycleFiles)
bool readOneSequential(EventPrincipal &cache, size_t &fileNameHash, CLHEP::HepRandomEngine *, EventID const *, bool recycleFiles)
std::vector< FileCatalogItem > const & fileCatalogItems() const
RunHelperBase * runHelper()
void initTheFile(bool skipBadFiles, bool deleteIndexIntoFile, InputSource *input, char const *inputTypeName, InputType inputType)
bool isAvailable() const
Definition: Service.h:40
double f[11][100]
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
bool skipToItem(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event, size_t fileNameHash=0U, bool currentFileFirst=true)
static void fillDescription(ParameterSetDescription &desc)
static constexpr EntryNumber_t invalidEntry
bool skipToItemInNewFile(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event)
HLT enums.
ProductSelectorRules const & productSelectorRules() const
def cache(function)
Definition: utilities.py:3
void updateFromInput(ProductList const &other)
std::vector< ProcessHistoryID > orderedProcessHistoryIDs_
void skipEntries(unsigned int offset)
RootEmbeddedFileSequence(ParameterSet const &pset, EmbeddedRootSource &input, InputFileCatalog const &catalog)
bool(RootEmbeddedFileSequence::* fptr_)(EventPrincipal &, size_t &, CLHEP::HepRandomEngine *, EventID const *, bool)