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 
27  ParameterSet const& pset,
29  InputFileCatalog const& catalog) :
30  RootInputFileSequence(pset, catalog),
31  input_(input),
32  orderedProcessHistoryIDs_(),
33  sequential_(pset.getUntrackedParameter<bool>("sequential", false)),
34  sameLumiBlock_(pset.getUntrackedParameter<bool>("sameLumiBlock", false)),
35  fptr_(nullptr),
36  eventsRemainingInFile_(0),
37  // The default value provided as the second argument to the getUntrackedParameter function call
38  // is not used when the ParameterSet has been validated and the parameters are not optional
39  // in the description. This is currently true when PoolSource is the primary input source.
40  // The modules that use PoolSource as a SecSource have not defined their fillDescriptions function
41  // yet, so the ParameterSet does not get validated yet. As soon as all the modules with a SecSource
42  // have defined descriptions, the defaults in the getUntrackedParameterSet function calls can
43  // and should be deleted from the code.
44  initialNumberOfEventsToSkip_(pset.getUntrackedParameter<unsigned int>("skipEvents", 0U)),
45  treeCacheSize_(pset.getUntrackedParameter<unsigned int>("cacheSize", roottree::defaultCacheSize)),
46  enablePrefetching_(false) {
47 
48  if(noFiles()) {
49  throw Exception(errors::Configuration) << "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  }
111 
112  void
114  closeFile_();
115  }
116 
118  // delete the RootFile object.
119  if(rootFile()) {
120  rootFile().reset();
121  }
122  }
123 
125  initTheFile(skipBadFiles, false, nullptr, "mixingFiles", InputType::SecondarySource);
126  }
127 
129  RootEmbeddedFileSequence::makeRootFile(std::shared_ptr<InputFile> filePtr) {
130  size_t currentIndexIntoFile = sequenceNumberOfFile();
131  return std::make_shared<RootFile>(
132  fileName(),
134  logicalFileName(),
135  filePtr,
136  input_.nStreams(),
139  input_.runHelper(),
144  currentIndexIntoFile,
148  }
149 
150  void
152  // offset is decremented by the number of events actually skipped.
153  bool completed = rootFile()->skipEntries(offset);
154  while(!completed) {
155  setAtNextFile();
156  if(noMoreFiles()) {
157  setAtFirstFile();
158  }
159  initFile(false);
160  assert(rootFile());
161  rootFile()->setAtEventEntry(IndexIntoFile::invalidEntry);
162  completed = rootFile()->skipEntries(offset);
163  }
164  }
165 
166  bool
167  RootEmbeddedFileSequence::readOneSequential(EventPrincipal& cache, size_t& fileNameHash, CLHEP::HepRandomEngine*, EventID const*) {
168  assert(rootFile());
169  rootFile()->nextEventEntry();
170  bool found = rootFile()->readCurrentEvent(cache);
171  if(!found) {
172  setAtNextFile();
173  if(noMoreFiles()) {
174  setAtFirstFile();
175  }
176  initFile(false);
177  assert(rootFile());
178  rootFile()->setAtEventEntry(IndexIntoFile::invalidEntry);
179  return readOneSequential(cache, fileNameHash, nullptr, nullptr);
180  }
181  fileNameHash = lfnHash();
182  return true;
183  }
184 
185  bool
186  RootEmbeddedFileSequence::readOneSequentialWithID(EventPrincipal& cache, size_t& fileNameHash, CLHEP::HepRandomEngine*, EventID const* idp) {
187  assert(idp);
188  EventID const& id = *idp;
191  if(offset > 0) {
192  assert(rootFile());
193  while(offset > 0) {
194  bool found = readOneSequentialWithID(cache, fileNameHash, nullptr, idp);
195  if(!found) {
196  return false;
197  }
198  --offset;
199  }
200  }
201  assert(rootFile());
202  if(noMoreFiles() ||
203  rootFile()->indexIntoFileIter().run() != id.run() ||
204  rootFile()->indexIntoFileIter().lumi() != id.luminosityBlock()) {
205  bool found = skipToItem(id.run(), id.luminosityBlock(), 0, 0, false);
206  if(!found) {
207  return false;
208  }
209  }
210  assert(rootFile());
211  bool found = rootFile()->setEntryAtNextEventInLumi(id.run(), id.luminosityBlock());
212  if(found) {
213  found = rootFile()->readCurrentEvent(cache);
214  }
215  if(!found) {
216  found = skipToItemInNewFile(id.run(), id.luminosityBlock(), 0);
217  if(!found) {
218  return false;
219  }
220  return readOneSequentialWithID(cache, fileNameHash, nullptr, idp);
221  }
222  fileNameHash = lfnHash();
223  return true;
224  }
225 
226  void
228  EventID const& id = idx.eventID();
229  bool found = skipToItem(id.run(), id.luminosityBlock(), id.event(), idx.fileNameHash());
230  if(!found) {
231  throw Exception(errors::NotFound) <<
232  "RootEmbeddedFileSequence::readOneSpecified(): Secondary Input files" <<
233  " do not contain specified event:\n" << id << "\n";
234  }
235  assert(rootFile());
236  found = rootFile()->readCurrentEvent(cache);
237  assert(found);
238  fileNameHash = idx.fileNameHash();
239  if(fileNameHash == 0U) {
240  fileNameHash = lfnHash();
241  }
242  }
243 
244  bool
245  RootEmbeddedFileSequence::readOneRandom(EventPrincipal& cache, size_t& fileNameHash, CLHEP::HepRandomEngine* engine, EventID const*) {
246  assert(rootFile());
247  assert(engine);
248  unsigned int currentSeqNumber = sequenceNumberOfFile();
249  while(eventsRemainingInFile_ == 0) {
250 
251  unsigned int newSeqNumber = CLHEP::RandFlat::shootInt(engine, fileCatalogItems().size());
252  setAtFileSequenceNumber(newSeqNumber);
253  if(newSeqNumber != currentSeqNumber) {
254  initFile(false);
255  currentSeqNumber = newSeqNumber;
256  }
257  eventsRemainingInFile_ = rootFile()->eventTree().entries();
258  if(eventsRemainingInFile_ == 0) {
259  throw Exception(errors::NotFound) <<
260  "RootEmbeddedFileSequence::readOneRandom(): Secondary Input file " << fileName() << " contains no events.\n";
261  }
262  rootFile()->setAtEventEntry(CLHEP::RandFlat::shootInt(engine, eventsRemainingInFile_) - 1);
263  }
264  rootFile()->nextEventEntry();
265 
266  bool found = rootFile()->readCurrentEvent(cache);
267  if(!found) {
268  rootFile()->setAtEventEntry(0);
269  bool found = rootFile()->readCurrentEvent(cache);
270  assert(found);
271  }
272  fileNameHash = lfnHash();
274  return true;
275  }
276 
277  bool
278  RootEmbeddedFileSequence::readOneRandomWithID(EventPrincipal& cache, size_t& fileNameHash, CLHEP::HepRandomEngine* engine, EventID const* idp) {
279  assert(engine);
280  assert(idp);
281  EventID const& id = *idp;
282  if(noMoreFiles() || !rootFile() ||
283  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())) ++eventsInLumi;
292  found = skipToItem(id.run(), id.luminosityBlock(), 0);
293  assert(found);
294  int eventInLumi = CLHEP::RandFlat::shootInt(engine, eventsInLumi);
295  for(int i = 0; i < eventInLumi; ++i) {
296  bool found = rootFile()->setEntryAtNextEventInLumi(id.run(), id.luminosityBlock());
297  assert(found);
298  }
299  }
300  assert(rootFile());
301  bool found = rootFile()->setEntryAtNextEventInLumi(id.run(), id.luminosityBlock());
302  if(found) {
303  found = rootFile()->readCurrentEvent(cache);
304  }
305  if(!found) {
306  bool found = rootFile()->setEntryAtItem(id.run(), id.luminosityBlock(), 0);
307  if(!found) {
308  return false;
309  }
310  return readOneRandomWithID(cache, fileNameHash, engine, idp);
311  }
312  fileNameHash = lfnHash();
313  return true;
314  }
315 
316  bool
317  RootEmbeddedFileSequence::readOneEvent(EventPrincipal& cache, size_t& fileNameHash, CLHEP::HepRandomEngine* engine, EventID const* id) {
318  assert(!sameLumiBlock_ || id != nullptr);
319  assert(sequential_ || engine != nullptr);
320  return (this->*fptr_)(cache, fileNameHash, engine, id);
321  }
322 
323  void
325  desc.addUntracked<bool>("sequential", false)
326  ->setComment("True: loopEvents() reads events sequentially from beginning of first file.\n"
327  "False: loopEvents() first reads events beginning at random event. New files also chosen randomly");
328  desc.addUntracked<bool>("sameLumiBlock", false)
329  ->setComment("True: loopEvents() reads events only in same lumi as the specified event.\n"
330  "False: loopEvents() reads events regardless of lumi.");
331  desc.addUntracked<unsigned int>("skipEvents", 0U)
332  ->setComment("Skip the first 'skipEvents' events. Used only if 'sequential' is True and 'sameLumiBlock' is False");
333  desc.addUntracked<unsigned int>("cacheSize", roottree::defaultCacheSize)
334  ->setComment("Size of ROOT TTree prefetch cache. Affects performance.");
335  }
336 }
size
Write out results.
ProductRegistry & productRegistryUpdate()
std::string const & logicalFileName() const
virtual RootFileSharedPtr makeRootFile(std::shared_ptr< InputFile > filePtr) override
ProcessHistoryRegistry & processHistoryRegistryForUpdate()
void initFile(bool skipBadFiles)
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
std::vector< std::shared_ptr< IndexIntoFile > > const & indexesIntoFiles() const
virtual void initFile_(bool skipBadFiles) override
#define nullptr
unsigned int const defaultCacheSize
Definition: RootTree.h:45
bool bypassVersionCheck() const
static std::string const input
Definition: EdmProvDump.cc:44
bool readOneRandomWithID(EventPrincipal &cache, size_t &fileNameHash, CLHEP::HepRandomEngine *, EventID const *id)
std::shared_ptr< RootFile > RootFileSharedPtr
bool readOneSequential(EventPrincipal &cache, size_t &fileNameHash, CLHEP::HepRandomEngine *, EventID const *)
bool readOneRandom(EventPrincipal &cache, size_t &fileNameHash, CLHEP::HepRandomEngine *, EventID const *)
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:46
bool readOneEvent(EventPrincipal &cache, size_t &fileNameHash, CLHEP::HepRandomEngine *, EventID const *id)
double f[11][100]
bool(RootEmbeddedFileSequence::* fptr_)(EventPrincipal &, size_t &, CLHEP::HepRandomEngine *, EventID const *)
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
bool readOneSequentialWithID(EventPrincipal &cache, size_t &fileNameHash, CLHEP::HepRandomEngine *, EventID const *id)
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 EntryNumber_t const invalidEntry
bool skipToItemInNewFile(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event)
HLT enums.
ProductSelectorRules const & productSelectorRules() const
void updateFromInput(ProductList const &other)
std::vector< ProcessHistoryID > orderedProcessHistoryIDs_
void skipEntries(unsigned int offset)
RootEmbeddedFileSequence(ParameterSet const &pset, EmbeddedRootSource &input, InputFileCatalog const &catalog)