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