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*, bool recycleFiles) {
168  assert(rootFile());
169  rootFile()->nextEventEntry();
170  bool found = rootFile()->readCurrentEvent(cache);
171  if(!found) {
172  setAtNextFile();
173  if(noMoreFiles()) {
174  if (recycleFiles) {
175  setAtFirstFile();
176  } else {
177  return false;
178  }
179  }
180  initFile(false);
181  assert(rootFile());
182  rootFile()->setAtEventEntry(IndexIntoFile::invalidEntry);
183  return readOneSequential(cache, fileNameHash, nullptr, nullptr, recycleFiles);
184  }
185  fileNameHash = lfnHash();
186  return true;
187  }
188 
189  bool
190  RootEmbeddedFileSequence::readOneSequentialWithID(EventPrincipal& cache, size_t& fileNameHash, CLHEP::HepRandomEngine*, EventID const* idp, bool recycleFiles) {
191  assert(idp);
192  EventID const& id = *idp;
195  if(offset > 0) {
196  assert(rootFile());
197  while(offset > 0) {
198  bool found = readOneSequentialWithID(cache, fileNameHash, nullptr, idp, recycleFiles);
199  if(!found) {
200  return false;
201  }
202  --offset;
203  }
204  }
205  assert(rootFile());
206  if(noMoreFiles() ||
207  rootFile()->indexIntoFileIter().run() != id.run() ||
208  rootFile()->indexIntoFileIter().lumi() != id.luminosityBlock()) {
209  bool found = skipToItem(id.run(), id.luminosityBlock(), 0, 0, false);
210  if(!found) {
211  return false;
212  }
213  }
214  assert(rootFile());
215  bool found = rootFile()->setEntryAtNextEventInLumi(id.run(), id.luminosityBlock());
216  if(found) {
217  found = rootFile()->readCurrentEvent(cache);
218  }
219  if(!found) {
220  found = skipToItemInNewFile(id.run(), id.luminosityBlock(), 0);
221  if(!found) {
222  return false;
223  }
224  return readOneSequentialWithID(cache, fileNameHash, nullptr, idp, recycleFiles);
225  }
226  fileNameHash = lfnHash();
227  return true;
228  }
229 
230  void
232  EventID const& id = idx.eventID();
233  bool found = skipToItem(id.run(), id.luminosityBlock(), id.event(), idx.fileNameHash());
234  if(!found) {
235  throw Exception(errors::NotFound) <<
236  "RootEmbeddedFileSequence::readOneSpecified(): Secondary Input files" <<
237  " do not contain specified event:\n" << id << "\n";
238  }
239  assert(rootFile());
240  found = rootFile()->readCurrentEvent(cache);
241  assert(found);
242  fileNameHash = idx.fileNameHash();
243  if(fileNameHash == 0U) {
244  fileNameHash = lfnHash();
245  }
246  }
247 
248  bool
249  RootEmbeddedFileSequence::readOneRandom(EventPrincipal& cache, size_t& fileNameHash, CLHEP::HepRandomEngine* engine, EventID const*, bool) {
250  assert(rootFile());
251  assert(engine);
252  unsigned int currentSeqNumber = sequenceNumberOfFile();
253  while(eventsRemainingInFile_ == 0) {
254 
255  unsigned int newSeqNumber = CLHEP::RandFlat::shootInt(engine, fileCatalogItems().size());
256  setAtFileSequenceNumber(newSeqNumber);
257  if(newSeqNumber != currentSeqNumber) {
258  initFile(false);
259  currentSeqNumber = newSeqNumber;
260  }
261  eventsRemainingInFile_ = rootFile()->eventTree().entries();
262  if(eventsRemainingInFile_ == 0) {
263  throw Exception(errors::NotFound) <<
264  "RootEmbeddedFileSequence::readOneRandom(): Secondary Input file " << fileName() << " contains no events.\n";
265  }
266  rootFile()->setAtEventEntry(CLHEP::RandFlat::shootInt(engine, eventsRemainingInFile_) - 1);
267  }
268  rootFile()->nextEventEntry();
269 
270  bool found = rootFile()->readCurrentEvent(cache);
271  if(!found) {
272  rootFile()->setAtEventEntry(0);
273  bool found = rootFile()->readCurrentEvent(cache);
274  assert(found);
275  }
276  fileNameHash = lfnHash();
278  return true;
279  }
280 
281  bool
282  RootEmbeddedFileSequence::readOneRandomWithID(EventPrincipal& cache, size_t& fileNameHash, CLHEP::HepRandomEngine* engine, EventID const* idp, bool recycleFiles) {
283  assert(engine);
284  assert(idp);
285  EventID const& id = *idp;
286  if(noMoreFiles() || !rootFile() ||
287  rootFile()->indexIntoFileIter().run() != id.run() ||
288  rootFile()->indexIntoFileIter().lumi() != id.luminosityBlock()) {
289  bool found = skipToItem(id.run(), id.luminosityBlock(), 0);
290  if(!found) {
291  return false;
292  }
293  int eventsInLumi = 0;
294  assert(rootFile());
295  while(rootFile()->setEntryAtNextEventInLumi(id.run(), id.luminosityBlock())) ++eventsInLumi;
296  found = skipToItem(id.run(), id.luminosityBlock(), 0);
297  assert(found);
298  int eventInLumi = CLHEP::RandFlat::shootInt(engine, eventsInLumi);
299  for(int i = 0; i < eventInLumi; ++i) {
300  bool found = rootFile()->setEntryAtNextEventInLumi(id.run(), id.luminosityBlock());
301  assert(found);
302  }
303  }
304  assert(rootFile());
305  bool found = rootFile()->setEntryAtNextEventInLumi(id.run(), id.luminosityBlock());
306  if(found) {
307  found = rootFile()->readCurrentEvent(cache);
308  }
309  if(!found) {
310  bool found = rootFile()->setEntryAtItem(id.run(), id.luminosityBlock(), 0);
311  if(!found) {
312  return false;
313  }
314  return readOneRandomWithID(cache, fileNameHash, engine, idp, recycleFiles);
315  }
316  fileNameHash = lfnHash();
317  return true;
318  }
319 
320  bool
321  RootEmbeddedFileSequence::readOneEvent(EventPrincipal& cache, size_t& fileNameHash, CLHEP::HepRandomEngine* engine, EventID const* id, bool recycleFiles) {
322  assert(!sameLumiBlock_ || id != nullptr);
323  assert(sequential_ || engine != nullptr);
324  return (this->*fptr_)(cache, fileNameHash, engine, id, recycleFiles);
325  }
326 
327  void
329  desc.addUntracked<bool>("sequential", false)
330  ->setComment("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("True: loopEvents() reads events only in same lumi as the specified event.\n"
334  "False: loopEvents() reads events regardless of lumi.");
335  desc.addUntracked<unsigned int>("skipEvents", 0U)
336  ->setComment("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 }
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(RootEmbeddedFileSequence::* fptr_)(EventPrincipal &, size_t &, CLHEP::HepRandomEngine *, EventID const *, bool)
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)
std::vector< std::shared_ptr< IndexIntoFile > > const & indexesIntoFiles() const
void initFile_(bool skipBadFiles) override
#define nullptr
unsigned int const defaultCacheSize
Definition: RootTree.h:45
bool readOneRandom(EventPrincipal &cache, size_t &fileNameHash, CLHEP::HepRandomEngine *, EventID const *, bool)
bool bypassVersionCheck() const
static std::string const input
Definition: EdmProvDump.cc:44
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:46
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
def cache(function)
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
void updateFromInput(ProductList const &other)
std::vector< ProcessHistoryID > orderedProcessHistoryIDs_
void skipEntries(unsigned int offset)
RootEmbeddedFileSequence(ParameterSet const &pset, EmbeddedRootSource &input, InputFileCatalog const &catalog)