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()) {
48  throw Exception(errors::Configuration) << "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,
143  }
144 
146  // offset is decremented by the number of events actually skipped.
147  bool completed = rootFile()->skipEntries(offset);
148  while (!completed) {
149  setAtNextFile();
150  if (noMoreFiles()) {
151  setAtFirstFile();
152  }
153  initFile(false);
154  assert(rootFile());
155  rootFile()->setAtEventEntry(IndexIntoFile::invalidEntry);
156  completed = rootFile()->skipEntries(offset);
157  }
158  }
159 
161  EventPrincipal& cache, size_t& fileNameHash, CLHEP::HepRandomEngine*, EventID const*, bool recycleFiles) {
162  assert(rootFile());
163  rootFile()->nextEventEntry();
164  bool found = rootFile()->readCurrentEvent(cache);
165  if (!found) {
166  setAtNextFile();
167  if (noMoreFiles()) {
168  if (recycleFiles) {
169  setAtFirstFile();
170  } else {
171  return false;
172  }
173  }
174  initFile(false);
175  assert(rootFile());
176  rootFile()->setAtEventEntry(IndexIntoFile::invalidEntry);
177  return readOneSequential(cache, fileNameHash, nullptr, nullptr, recycleFiles);
178  }
179  fileNameHash = lfnHash();
180  return true;
181  }
182 
184  EventPrincipal& cache, size_t& fileNameHash, CLHEP::HepRandomEngine*, EventID const* idp, bool recycleFiles) {
185  assert(idp);
186  EventID const& id = *idp;
189  if (offset > 0) {
190  assert(rootFile());
191  while (offset > 0) {
192  bool found = readOneSequentialWithID(cache, fileNameHash, nullptr, idp, recycleFiles);
193  if (!found) {
194  return false;
195  }
196  --offset;
197  }
198  }
199  assert(rootFile());
200  if (noMoreFiles() || rootFile()->indexIntoFileIter().run() != id.run() ||
201  rootFile()->indexIntoFileIter().lumi() != id.luminosityBlock()) {
202  bool found = skipToItem(id.run(), id.luminosityBlock(), 0, 0, false);
203  if (!found) {
204  return false;
205  }
206  }
207  assert(rootFile());
208  bool found = rootFile()->setEntryAtNextEventInLumi(id.run(), id.luminosityBlock());
209  if (found) {
210  found = rootFile()->readCurrentEvent(cache);
211  }
212  if (!found) {
213  found = skipToItemInNewFile(id.run(), id.luminosityBlock(), 0);
214  if (!found) {
215  return false;
216  }
217  return readOneSequentialWithID(cache, fileNameHash, nullptr, idp, recycleFiles);
218  }
219  fileNameHash = lfnHash();
220  return true;
221  }
222 
224  size_t& fileNameHash,
226  EventID const& id = idx.eventID();
227  bool found = skipToItem(id.run(), id.luminosityBlock(), id.event(), idx.fileNameHash());
228  if (!found) {
229  throw Exception(errors::NotFound) << "RootEmbeddedFileSequence::readOneSpecified(): Secondary Input files"
230  << " do not contain specified event:\n"
231  << id << "\n";
232  }
233  assert(rootFile());
234  found = rootFile()->readCurrentEvent(cache);
235  assert(found);
236  fileNameHash = idx.fileNameHash();
237  if (fileNameHash == 0U) {
238  fileNameHash = lfnHash();
239  }
240  }
241 
243  EventPrincipal& cache, size_t& fileNameHash, CLHEP::HepRandomEngine* engine, EventID const*, bool) {
244  assert(rootFile());
245  assert(engine);
246  unsigned int currentSeqNumber = sequenceNumberOfFile();
247  while (eventsRemainingInFile_ == 0) {
248  unsigned int newSeqNumber = CLHEP::RandFlat::shootInt(engine, fileCatalogItems().size());
249  setAtFileSequenceNumber(newSeqNumber);
250  if (newSeqNumber != currentSeqNumber) {
251  initFile(false);
252  currentSeqNumber = newSeqNumber;
253  }
254  eventsRemainingInFile_ = rootFile()->eventTree().entries();
255  if (eventsRemainingInFile_ == 0) {
256  throw Exception(errors::NotFound) << "RootEmbeddedFileSequence::readOneRandom(): Secondary Input file "
257  << fileName() << " contains no events.\n";
258  }
259  rootFile()->setAtEventEntry(CLHEP::RandFlat::shootInt(engine, eventsRemainingInFile_) - 1);
260  }
261  rootFile()->nextEventEntry();
262 
263  bool found = rootFile()->readCurrentEvent(cache);
264  if (!found) {
265  rootFile()->setAtEventEntry(0);
266  bool found = rootFile()->readCurrentEvent(cache);
267  assert(found);
268  }
269  fileNameHash = lfnHash();
271  return true;
272  }
273 
275  size_t& fileNameHash,
276  CLHEP::HepRandomEngine* engine,
277  EventID const* idp,
278  bool recycleFiles) {
279  assert(engine);
280  assert(idp);
281  EventID const& id = *idp;
282  if (noMoreFiles() || !rootFile() || rootFile()->indexIntoFileIter().run() != id.run() ||
283  rootFile()->indexIntoFileIter().lumi() != id.luminosityBlock()) {
284  bool found = skipToItem(id.run(), id.luminosityBlock(), 0);
285  if (!found) {
286  return false;
287  }
288  int eventsInLumi = 0;
289  assert(rootFile());
290  while (rootFile()->setEntryAtNextEventInLumi(id.run(), id.luminosityBlock()))
291  ++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, recycleFiles);
311  }
312  fileNameHash = lfnHash();
313  return true;
314  }
315 
317  size_t& fileNameHash,
318  CLHEP::HepRandomEngine* engine,
319  EventID const* id,
320  bool recycleFiles) {
321  assert(!sameLumiBlock_ || id != nullptr);
322  assert(sequential_ || engine != nullptr);
323  return (this->*fptr_)(cache, fileNameHash, engine, id, recycleFiles);
324  }
325 
327  desc.addUntracked<bool>("sequential", false)
328  ->setComment(
329  "True: loopEvents() reads events sequentially from beginning of first file.\n"
330  "False: loopEvents() first reads events beginning at random event. New files also chosen randomly");
331  desc.addUntracked<bool>("sameLumiBlock", false)
332  ->setComment(
333  "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(
337  "Skip the first 'skipEvents' events. Used only if 'sequential' is True and 'sameLumiBlock' is False");
338  desc.addUntracked<unsigned int>("cacheSize", roottree::defaultCacheSize)
339  ->setComment("Size of ROOT TTree prefetch cache. Affects performance.");
340  desc.addUntracked<bool>("enforceGUIDInFileName", false)
341  ->setComment(
342  "True: file name part is required to be equal to the GUID of the file\n"
343  "False: file name can be anything");
344  }
345 } // 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(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 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)