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  if (noFiles()) {
48  << "RootEmbeddedFileSequence no input files specified for secondary input source.\n";
49  }
50  //
51  // The SiteLocalConfig controls the TTreeCache size and the prefetching settings.
53  if (pSLC.isAvailable()) {
54  if (treeCacheSize_ != 0U && pSLC->sourceTTreeCacheSize()) {
55  treeCacheSize_ = *(pSLC->sourceTTreeCacheSize());
56  }
57  enablePrefetching_ = pSLC->enablePrefetching();
58  }
59 
60  // Set the pointer to the function that reads an event.
61  if (sameLumiBlock_) {
62  if (sequential_) {
64  } else {
66  }
67  } else {
68  if (sequential_) {
70  } else {
72  }
73  }
74 
75  // For the secondary input source we do not stage in.
76  if (sequential_) {
77  // We open the first file
78  if (!atFirstFile()) {
80  initFile(false);
81  }
82  assert(rootFile());
83  rootFile()->setAtEventEntry(IndexIntoFile::invalidEntry);
84  if (!sameLumiBlock_) {
86  }
87  } else {
88  // We randomly choose the first file to open.
89  // We cannot use the random number service yet.
90  std::ifstream f("/dev/urandom");
91  unsigned int seed;
92  f.read(reinterpret_cast<char*>(&seed), sizeof(seed));
93  std::default_random_engine dre(seed);
94  size_t count = numberOfFiles();
95  std::uniform_int_distribution<int> distribution(0, count - 1);
96  while (!rootFile() && count != 0) {
97  --count;
98  int offset = distribution(dre);
101  }
102  }
103  if (rootFile()) {
104  input_.productRegistryUpdate().updateFromInput(rootFile()->productRegistry()->productList());
105  }
106  }
107 
109 
111 
113  // delete the RootFile object.
114  if (rootFile()) {
115  rootFile().reset();
116  }
117  }
118 
120  initTheFile(skipBadFiles, false, nullptr, "mixingFiles", InputType::SecondarySource);
121  }
122 
124  std::shared_ptr<InputFile> filePtr) {
125  size_t currentIndexIntoFile = sequenceNumberOfFile();
126  return std::make_shared<RootFile>(fileName(),
128  logicalFileName(),
129  filePtr,
130  input_.nStreams(),
133  input_.runHelper(),
138  currentIndexIntoFile,
142  }
143 
145  // offset is decremented by the number of events actually skipped.
146  bool completed = rootFile()->skipEntries(offset);
147  while (!completed) {
148  setAtNextFile();
149  if (noMoreFiles()) {
150  setAtFirstFile();
151  }
152  initFile(false);
153  assert(rootFile());
154  rootFile()->setAtEventEntry(IndexIntoFile::invalidEntry);
155  completed = rootFile()->skipEntries(offset);
156  }
157  }
158 
160  EventPrincipal& cache, size_t& fileNameHash, CLHEP::HepRandomEngine*, EventID const*, bool recycleFiles) {
161  assert(rootFile());
162  rootFile()->nextEventEntry();
163  bool found = rootFile()->readCurrentEvent(cache);
164  if (!found) {
165  setAtNextFile();
166  if (noMoreFiles()) {
167  if (recycleFiles) {
168  setAtFirstFile();
169  } else {
170  return false;
171  }
172  }
173  initFile(false);
174  assert(rootFile());
175  rootFile()->setAtEventEntry(IndexIntoFile::invalidEntry);
176  return readOneSequential(cache, fileNameHash, nullptr, nullptr, recycleFiles);
177  }
178  fileNameHash = lfnHash();
179  return true;
180  }
181 
183  EventPrincipal& cache, size_t& fileNameHash, CLHEP::HepRandomEngine*, EventID const* idp, bool recycleFiles) {
184  assert(idp);
185  EventID const& id = *idp;
188  if (offset > 0) {
189  assert(rootFile());
190  while (offset > 0) {
191  bool found = readOneSequentialWithID(cache, fileNameHash, nullptr, idp, recycleFiles);
192  if (!found) {
193  return false;
194  }
195  --offset;
196  }
197  }
198  assert(rootFile());
199  if (noMoreFiles() || rootFile()->indexIntoFileIter().run() != id.run() ||
200  rootFile()->indexIntoFileIter().lumi() != id.luminosityBlock()) {
201  bool found = skipToItem(id.run(), id.luminosityBlock(), 0, 0, false);
202  if (!found) {
203  return false;
204  }
205  }
206  assert(rootFile());
207  bool found = rootFile()->setEntryAtNextEventInLumi(id.run(), id.luminosityBlock());
208  if (found) {
209  found = rootFile()->readCurrentEvent(cache);
210  }
211  if (!found) {
212  found = skipToItemInNewFile(id.run(), id.luminosityBlock(), 0);
213  if (!found) {
214  return false;
215  }
216  return readOneSequentialWithID(cache, fileNameHash, nullptr, idp, recycleFiles);
217  }
218  fileNameHash = lfnHash();
219  return true;
220  }
221 
223  size_t& fileNameHash,
225  EventID const& id = idx.eventID();
226  bool found = skipToItem(id.run(), id.luminosityBlock(), id.event(), idx.fileNameHash());
227  if (!found) {
228  throw Exception(errors::NotFound) << "RootEmbeddedFileSequence::readOneSpecified(): Secondary Input files"
229  << " do not contain specified event:\n"
230  << id << "\n";
231  }
232  assert(rootFile());
233  found = rootFile()->readCurrentEvent(cache);
234  assert(found);
235  fileNameHash = idx.fileNameHash();
236  if (fileNameHash == 0U) {
237  fileNameHash = lfnHash();
238  }
239  }
240 
242  EventPrincipal& cache, size_t& fileNameHash, CLHEP::HepRandomEngine* engine, EventID const*, bool) {
243  assert(rootFile());
244  assert(engine);
245  unsigned int currentSeqNumber = sequenceNumberOfFile();
246  while (eventsRemainingInFile_ == 0) {
247  unsigned int newSeqNumber = CLHEP::RandFlat::shootInt(engine, fileCatalogItems().size());
248  setAtFileSequenceNumber(newSeqNumber);
249  if (newSeqNumber != currentSeqNumber) {
250  initFile(false);
251  currentSeqNumber = newSeqNumber;
252  }
253  eventsRemainingInFile_ = rootFile()->eventTree().entries();
254  if (eventsRemainingInFile_ == 0) {
255  throw Exception(errors::NotFound) << "RootEmbeddedFileSequence::readOneRandom(): Secondary Input file "
256  << fileName() << " contains no events.\n";
257  }
258  rootFile()->setAtEventEntry(CLHEP::RandFlat::shootInt(engine, eventsRemainingInFile_) - 1);
259  }
260  rootFile()->nextEventEntry();
261 
262  bool found = rootFile()->readCurrentEvent(cache);
263  if (!found) {
264  rootFile()->setAtEventEntry(0);
265  bool found = rootFile()->readCurrentEvent(cache);
266  assert(found);
267  }
268  fileNameHash = lfnHash();
270  return true;
271  }
272 
274  size_t& fileNameHash,
275  CLHEP::HepRandomEngine* engine,
276  EventID const* idp,
277  bool recycleFiles) {
278  assert(engine);
279  assert(idp);
280  EventID const& id = *idp;
281  if (noMoreFiles() || !rootFile() || rootFile()->indexIntoFileIter().run() != id.run() ||
282  rootFile()->indexIntoFileIter().lumi() != id.luminosityBlock()) {
283  bool found = skipToItem(id.run(), id.luminosityBlock(), 0);
284  if (!found) {
285  return false;
286  }
287  int eventsInLumi = 0;
288  assert(rootFile());
289  while (rootFile()->setEntryAtNextEventInLumi(id.run(), id.luminosityBlock()))
290  ++eventsInLumi;
291  found = skipToItem(id.run(), id.luminosityBlock(), 0);
292  assert(found);
293  int eventInLumi = CLHEP::RandFlat::shootInt(engine, eventsInLumi);
294  for (int i = 0; i < eventInLumi; ++i) {
295  bool found = rootFile()->setEntryAtNextEventInLumi(id.run(), id.luminosityBlock());
296  assert(found);
297  }
298  }
299  assert(rootFile());
300  bool found = rootFile()->setEntryAtNextEventInLumi(id.run(), id.luminosityBlock());
301  if (found) {
302  found = rootFile()->readCurrentEvent(cache);
303  }
304  if (!found) {
305  bool found = rootFile()->setEntryAtItem(id.run(), id.luminosityBlock(), 0);
306  if (!found) {
307  return false;
308  }
309  return readOneRandomWithID(cache, fileNameHash, engine, idp, recycleFiles);
310  }
311  fileNameHash = lfnHash();
312  return true;
313  }
314 
316  size_t& fileNameHash,
317  CLHEP::HepRandomEngine* engine,
318  EventID const* id,
319  bool recycleFiles) {
320  assert(!sameLumiBlock_ || id != nullptr);
321  assert(sequential_ || engine != nullptr);
322  return (this->*fptr_)(cache, fileNameHash, engine, id, recycleFiles);
323  }
324 
326  desc.addUntracked<bool>("sequential", false)
327  ->setComment(
328  "True: loopEvents() reads events sequentially from beginning of first file.\n"
329  "False: loopEvents() first reads events beginning at random event. New files also chosen randomly");
330  desc.addUntracked<bool>("sameLumiBlock", false)
331  ->setComment(
332  "True: loopEvents() reads events only in same lumi as the specified event.\n"
333  "False: loopEvents() reads events regardless of lumi.");
334  desc.addUntracked<unsigned int>("skipEvents", 0U)
335  ->setComment(
336  "Skip the first 'skipEvents' events. Used only if 'sequential' is True and 'sameLumiBlock' is False");
337  desc.addUntracked<unsigned int>("cacheSize", roottree::defaultCacheSize)
338  ->setComment("Size of ROOT TTree prefetch cache. Affects performance.");
339  }
340 } // 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)