00001
00002
00003
00004 #include "RootFile.h"
00005 #include "DuplicateChecker.h"
00006 #include "InputFile.h"
00007 #include "ProvenanceAdaptor.h"
00008
00009 #include "DataFormats/Common/interface/WrapperOwningHolder.h"
00010 #include "DataFormats/Common/interface/RefCoreStreamer.h"
00011 #include "DataFormats/Provenance/interface/BranchDescription.h"
00012 #include "DataFormats/Provenance/interface/BranchIDListHelper.h"
00013 #include "DataFormats/Provenance/interface/BranchType.h"
00014 #include "DataFormats/Provenance/interface/EventEntryInfo.h"
00015 #include "DataFormats/Provenance/interface/FullHistoryToReducedHistoryMap.h"
00016 #include "DataFormats/Provenance/interface/ParameterSetBlob.h"
00017 #include "DataFormats/Provenance/interface/ParentageRegistry.h"
00018 #include "DataFormats/Provenance/interface/ProcessConfigurationRegistry.h"
00019 #include "DataFormats/Provenance/interface/ProcessHistoryID.h"
00020 #include "DataFormats/Provenance/interface/ProcessHistoryRegistry.h"
00021 #include "DataFormats/Provenance/interface/ProductRegistry.h"
00022 #include "DataFormats/Provenance/interface/StoredProductProvenance.h"
00023 #include "DataFormats/Provenance/interface/RunID.h"
00024 #include "FWCore/Framework/interface/FileBlock.h"
00025 #include "FWCore/Framework/interface/EventPrincipal.h"
00026 #include "FWCore/Framework/interface/GroupSelector.h"
00027 #include "FWCore/Framework/interface/LuminosityBlockPrincipal.h"
00028 #include "FWCore/Framework/interface/RunPrincipal.h"
00029 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00030 #include "FWCore/ParameterSet/interface/FillProductRegistryTransients.h"
00031 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00032 #include "FWCore/ParameterSet/interface/Registry.h"
00033 #include "FWCore/Sources/interface/EventSkipperByID.h"
00034 #include "FWCore/Sources/interface/DaqProvenanceHelper.h"
00035 #include "FWCore/Utilities/interface/Algorithms.h"
00036 #include "FWCore/Utilities/interface/do_nothing_deleter.h"
00037 #include "FWCore/Utilities/interface/EDMException.h"
00038 #include "FWCore/Utilities/interface/FriendlyName.h"
00039 #include "FWCore/Utilities/interface/GlobalIdentifier.h"
00040 #include "FWCore/Utilities/interface/ReleaseVersion.h"
00041 #include "FWCore/Version/interface/GetReleaseVersion.h"
00042
00043
00044 #include "DataFormats/Provenance/interface/EntryDescriptionRegistry.h"
00045 #include "DataFormats/Provenance/interface/EventAux.h"
00046 #include "DataFormats/Provenance/interface/LuminosityBlockAux.h"
00047 #include "DataFormats/Provenance/interface/RunAux.h"
00048 #include "DataFormats/Provenance/interface/RunLumiEntryInfo.h"
00049 #include "FWCore/ParameterSet/interface/ParameterSetConverter.h"
00050
00051 #include "TROOT.h"
00052 #include "Rtypes.h"
00053 #include "TClass.h"
00054 #include "TString.h"
00055 #include "TTree.h"
00056 #include "TTreeCache.h"
00057
00058 #include <algorithm>
00059 #include <list>
00060
00061 namespace edm {
00062
00063
00064 class MakeDummyProvenanceReader : public MakeProvenanceReader {
00065 public:
00066 virtual std::unique_ptr<ProvenanceReaderBase> makeReader(RootTree& eventTree, DaqProvenanceHelper const* daqProvenanceHelper) const;
00067 };
00068 class MakeOldProvenanceReader : public MakeProvenanceReader {
00069 public:
00070 virtual std::unique_ptr<ProvenanceReaderBase> makeReader(RootTree& eventTree, DaqProvenanceHelper const* daqProvenanceHelper) const;
00071 };
00072 class MakeFullProvenanceReader : public MakeProvenanceReader {
00073 public:
00074 virtual std::unique_ptr<ProvenanceReaderBase> makeReader(RootTree& eventTree, DaqProvenanceHelper const* daqProvenanceHelper) const;
00075 };
00076 class MakeReducedProvenanceReader : public MakeProvenanceReader {
00077 public:
00078 MakeReducedProvenanceReader(std::vector<ParentageID> const& parentageIDLookup) : parentageIDLookup_(parentageIDLookup) {}
00079 virtual std::unique_ptr<ProvenanceReaderBase> makeReader(RootTree& eventTree, DaqProvenanceHelper const* daqProvenanceHelper) const;
00080 private:
00081 std::vector<ParentageID> const& parentageIDLookup_;
00082 };
00083
00084 namespace {
00085 int
00086 forcedRunOffset(RunNumber_t const& forcedRunNumber, IndexIntoFile::IndexIntoFileItr inxBegin, IndexIntoFile::IndexIntoFileItr inxEnd) {
00087 if(inxBegin == inxEnd) return 0;
00088 int defaultOffset = (inxBegin.run() != 0 ? 0 : 1);
00089 int offset = (forcedRunNumber != 0U ? forcedRunNumber - inxBegin.run() : defaultOffset);
00090 if(offset < 0) {
00091 throw Exception(errors::Configuration)
00092 << "The value of the 'setRunNumber' parameter must not be\n"
00093 << "less than the first run number in the first input file.\n"
00094 << "'setRunNumber' was " << forcedRunNumber <<", while the first run was "
00095 << forcedRunNumber - offset << ".\n";
00096 }
00097 return offset;
00098 }
00099 }
00100
00101
00102 class RootFileEventFinder : public IndexIntoFile::EventFinder {
00103 public:
00104 explicit RootFileEventFinder(RootTree& eventTree) : eventTree_(eventTree) {}
00105 virtual ~RootFileEventFinder() {}
00106 virtual
00107 EventNumber_t getEventNumberOfEntry(roottree::EntryNumber entry) const {
00108 roottree::EntryNumber saveEntry = eventTree_.entryNumber();
00109 eventTree_.setEntryNumber(entry);
00110 EventAuxiliary eventAux;
00111 EventAuxiliary *pEvAux = &eventAux;
00112 eventTree_.fillAux<EventAuxiliary>(pEvAux);
00113 eventTree_.setEntryNumber(saveEntry);
00114 return eventAux.event();
00115 }
00116
00117 private:
00118 RootTree& eventTree_;
00119 };
00120
00121
00122 RootFile::RootFile(std::string const& fileName,
00123 ProcessConfiguration const& processConfiguration,
00124 std::string const& logicalFileName,
00125 boost::shared_ptr<InputFile> filePtr,
00126 boost::shared_ptr<EventSkipperByID> eventSkipperByID,
00127 bool skipAnyEvents,
00128 int remainingEvents,
00129 int remainingLumis,
00130 unsigned int treeCacheSize,
00131 int treeMaxVirtualSize,
00132 InputSource::ProcessingMode processingMode,
00133 RunNumber_t const& forcedRunNumber,
00134 bool noEventSort,
00135 GroupSelectorRules const& groupSelectorRules,
00136 InputType::InputType inputType,
00137 boost::shared_ptr<BranchIDListHelper> branchIDListHelper,
00138 boost::shared_ptr<DuplicateChecker> duplicateChecker,
00139 bool dropDescendants,
00140 std::vector<boost::shared_ptr<IndexIntoFile> > const& indexesIntoFiles,
00141 std::vector<boost::shared_ptr<IndexIntoFile> >::size_type currentIndexIntoFile,
00142 std::vector<ProcessHistoryID>& orderedProcessHistoryIDs,
00143 bool labelRawDataLikeMC,
00144 bool usingGoToEvent,
00145 bool enablePrefetching) :
00146 file_(fileName),
00147 logicalFile_(logicalFileName),
00148 processConfiguration_(processConfiguration),
00149 processConfigurations_(),
00150 filePtr_(filePtr),
00151 eventSkipperByID_(eventSkipperByID),
00152 fileFormatVersion_(),
00153 fid_(),
00154 indexIntoFileSharedPtr_(new IndexIntoFile),
00155 indexIntoFile_(*indexIntoFileSharedPtr_),
00156 orderedProcessHistoryIDs_(orderedProcessHistoryIDs),
00157 indexIntoFileBegin_(indexIntoFile_.begin(noEventSort ? IndexIntoFile::firstAppearanceOrder : IndexIntoFile::numericalOrder)),
00158 indexIntoFileEnd_(indexIntoFileBegin_),
00159 indexIntoFileIter_(indexIntoFileBegin_),
00160 eventProcessHistoryIDs_(),
00161 eventProcessHistoryIter_(eventProcessHistoryIDs_.begin()),
00162 savedRunAuxiliary_(),
00163 skipAnyEvents_(skipAnyEvents),
00164 noEventSort_(noEventSort),
00165 whyNotFastClonable_(0),
00166 hasNewlyDroppedBranch_(),
00167 branchListIndexesUnchanged_(false),
00168 eventAux_(),
00169 eventTree_(filePtr_, InEvent, treeMaxVirtualSize, treeCacheSize, roottree::defaultLearningEntries, enablePrefetching),
00170 lumiTree_(filePtr_, InLumi, treeMaxVirtualSize, roottree::defaultNonEventCacheSize, roottree::defaultNonEventLearningEntries, enablePrefetching),
00171 runTree_(filePtr_, InRun, treeMaxVirtualSize, roottree::defaultNonEventCacheSize, roottree::defaultNonEventLearningEntries, enablePrefetching),
00172 treePointers_(),
00173 lastEventEntryNumberRead_(-1LL),
00174 productRegistry_(),
00175 branchIDLists_(),
00176 branchIDListHelper_(branchIDListHelper),
00177 processingMode_(processingMode),
00178 forcedRunOffset_(0),
00179 newBranchToOldBranch_(),
00180 eventHistoryTree_(0),
00181 eventSelectionIDs_(new EventSelectionIDVector),
00182 branchListIndexes_(new BranchListIndexes),
00183 history_(),
00184 branchChildren_(new BranchChildren),
00185 duplicateChecker_(duplicateChecker),
00186 provenanceAdaptor_(),
00187 provenanceReaderMaker_(),
00188 secondaryEventPrincipal_(),
00189 eventBranchMapper_(),
00190 parentageIDLookup_(),
00191 daqProvenanceHelper_() {
00192
00193 hasNewlyDroppedBranch_.fill(false);
00194
00195 treePointers_[InEvent] = &eventTree_;
00196 treePointers_[InLumi] = &lumiTree_;
00197 treePointers_[InRun] = &runTree_;
00198
00199
00200
00201 std::unique_ptr<TTree> metaDataTree(dynamic_cast<TTree *>(filePtr_->Get(poolNames::metaDataTreeName().c_str())));
00202 if(0 == metaDataTree.get()) {
00203 throw Exception(errors::FileReadError) << "Could not find tree " << poolNames::metaDataTreeName()
00204 << " in the input file.\n";
00205 }
00206
00207
00208
00209
00210 FileFormatVersion *fftPtr = &fileFormatVersion_;
00211 if(metaDataTree->FindBranch(poolNames::fileFormatVersionBranchName().c_str()) != 0) {
00212 TBranch *fft = metaDataTree->GetBranch(poolNames::fileFormatVersionBranchName().c_str());
00213 fft->SetAddress(&fftPtr);
00214 roottree::getEntry(fft, 0);
00215 metaDataTree->SetBranchAddress(poolNames::fileFormatVersionBranchName().c_str(), &fftPtr);
00216 }
00217
00218 FileID *fidPtr = &fid_;
00219 if(metaDataTree->FindBranch(poolNames::fileIdentifierBranchName().c_str()) != 0) {
00220 metaDataTree->SetBranchAddress(poolNames::fileIdentifierBranchName().c_str(), &fidPtr);
00221 }
00222
00223 IndexIntoFile *iifPtr = &indexIntoFile_;
00224 if(metaDataTree->FindBranch(poolNames::indexIntoFileBranchName().c_str()) != 0) {
00225 metaDataTree->SetBranchAddress(poolNames::indexIntoFileBranchName().c_str(), &iifPtr);
00226 }
00227
00228
00229
00230 ProductRegistry inputProdDescReg;
00231 ProductRegistry *ppReg = &inputProdDescReg;
00232 metaDataTree->SetBranchAddress(poolNames::productDescriptionBranchName().c_str(), (&ppReg));
00233
00234 typedef std::map<ParameterSetID, ParameterSetBlob> PsetMap;
00235 PsetMap psetMap;
00236 PsetMap *psetMapPtr = &psetMap;
00237 if(metaDataTree->FindBranch(poolNames::parameterSetMapBranchName().c_str()) != 0) {
00238
00239 assert(!fileFormatVersion().parameterSetsTree());
00240 metaDataTree->SetBranchAddress(poolNames::parameterSetMapBranchName().c_str(), &psetMapPtr);
00241 } else {
00242 assert(fileFormatVersion().parameterSetsTree());
00243
00244 std::unique_ptr<TTree> psetTree(dynamic_cast<TTree *>(filePtr_->Get(poolNames::parameterSetsTreeName().c_str())));
00245 if(0 == psetTree.get()) {
00246 throw Exception(errors::FileReadError) << "Could not find tree " << poolNames::parameterSetsTreeName()
00247 << " in the input file.\n";
00248 }
00249
00250 typedef std::pair<ParameterSetID, ParameterSetBlob> IdToBlobs;
00251 IdToBlobs idToBlob;
00252 IdToBlobs* pIdToBlob = &idToBlob;
00253 psetTree->SetBranchAddress(poolNames::idToParameterSetBlobsBranchName().c_str(), &pIdToBlob);
00254
00255 std::unique_ptr<TTreeCache> psetTreeCache = roottree::trainCache(psetTree.get(), *filePtr_, roottree::defaultNonEventCacheSize, "*");
00256 psetTreeCache->SetEnablePrefetching(false);
00257 filePtr_->SetCacheRead(psetTreeCache.get());
00258 for(Long64_t i = 0; i != psetTree->GetEntries(); ++i) {
00259 psetTree->GetEntry(i);
00260 psetMap.insert(idToBlob);
00261 }
00262 filePtr_->SetCacheRead(0);
00263 }
00264
00265
00266 ProcessHistoryRegistry::collection_type pHistMap;
00267 ProcessHistoryRegistry::collection_type *pHistMapPtr = &pHistMap;
00268 if(metaDataTree->FindBranch(poolNames::processHistoryMapBranchName().c_str()) != 0) {
00269 metaDataTree->SetBranchAddress(poolNames::processHistoryMapBranchName().c_str(), &pHistMapPtr);
00270 }
00271
00272 ProcessHistoryRegistry::vector_type pHistVector;
00273 ProcessHistoryRegistry::vector_type *pHistVectorPtr = &pHistVector;
00274 if(metaDataTree->FindBranch(poolNames::processHistoryBranchName().c_str()) != 0) {
00275 metaDataTree->SetBranchAddress(poolNames::processHistoryBranchName().c_str(), &pHistVectorPtr);
00276 }
00277
00278 ProcessConfigurationVector* procConfigVectorPtr = &processConfigurations_;
00279 if(metaDataTree->FindBranch(poolNames::processConfigurationBranchName().c_str()) != 0) {
00280 metaDataTree->SetBranchAddress(poolNames::processConfigurationBranchName().c_str(), &procConfigVectorPtr);
00281 }
00282
00283 std::unique_ptr<BranchIDLists> branchIDListsAPtr(new BranchIDLists);
00284 BranchIDLists* branchIDListsPtr = branchIDListsAPtr.get();
00285 if(metaDataTree->FindBranch(poolNames::branchIDListBranchName().c_str()) != 0) {
00286 metaDataTree->SetBranchAddress(poolNames::branchIDListBranchName().c_str(), &branchIDListsPtr);
00287 }
00288
00289 BranchChildren* branchChildrenBuffer = branchChildren_.get();
00290 if(metaDataTree->FindBranch(poolNames::productDependenciesBranchName().c_str()) != 0) {
00291 metaDataTree->SetBranchAddress(poolNames::productDependenciesBranchName().c_str(), &branchChildrenBuffer);
00292 }
00293
00294
00295 std::vector<EventProcessHistoryID> *eventHistoryIDsPtr = &eventProcessHistoryIDs_;
00296 if(metaDataTree->FindBranch(poolNames::eventHistoryBranchName().c_str()) != 0) {
00297 metaDataTree->SetBranchAddress(poolNames::eventHistoryBranchName().c_str(), &eventHistoryIDsPtr);
00298 }
00299
00300 if(metaDataTree->FindBranch(poolNames::moduleDescriptionMapBranchName().c_str()) != 0) {
00301 if(metaDataTree->GetBranch(poolNames::moduleDescriptionMapBranchName().c_str())->GetSplitLevel() != 0) {
00302 metaDataTree->SetBranchStatus((poolNames::moduleDescriptionMapBranchName() + ".*").c_str(), 0);
00303 } else {
00304 metaDataTree->SetBranchStatus(poolNames::moduleDescriptionMapBranchName().c_str(), 0);
00305 }
00306 }
00307
00308
00309 roottree::getEntry(metaDataTree.get(), 0);
00310
00311 checkReleaseVersion();
00312
00313 eventProcessHistoryIter_ = eventProcessHistoryIDs_.begin();
00314
00315
00316 readEventHistoryTree();
00317
00318 ParameterSetConverter::ParameterSetIdConverter psetIdConverter;
00319 if(!fileFormatVersion().triggerPathsTracked()) {
00320 ParameterSetConverter converter(psetMap, psetIdConverter, fileFormatVersion().parameterSetsByReference());
00321 } else {
00322
00323 pset::Registry& psetRegistry = *pset::Registry::instance();
00324 for(PsetMap::const_iterator i = psetMap.begin(), iEnd = psetMap.end(); i != iEnd; ++i) {
00325 ParameterSet pset(i->second.pset());
00326 pset.setID(i->first);
00327 psetRegistry.insertMapped(pset);
00328 }
00329 }
00330 if(!fileFormatVersion().splitProductIDs()) {
00331
00332 provenanceAdaptor_.reset(new ProvenanceAdaptor(
00333 inputProdDescReg, pHistMap, pHistVector, processConfigurations_, psetIdConverter, true));
00334
00335 branchIDLists_ = provenanceAdaptor_->branchIDLists();
00336 } else {
00337 if(!fileFormatVersion().triggerPathsTracked()) {
00338
00339 provenanceAdaptor_.reset(new ProvenanceAdaptor(
00340 inputProdDescReg, pHistMap, pHistVector, processConfigurations_, psetIdConverter, false));
00341 }
00342
00343 if(metaDataTree->FindBranch(poolNames::branchIDListBranchName().c_str()) == 0) {
00344 throw Exception(errors::EventCorruption)
00345 << "Failed to find branchIDLists branch in metaData tree.\n";
00346 }
00347 branchIDLists_.reset(branchIDListsAPtr.release());
00348 }
00349
00350 if(labelRawDataLikeMC) {
00351 std::string const rawData("FEDRawDataCollection");
00352 std::string const source("source");
00353 ProductRegistry::ProductList& pList = inputProdDescReg.productListUpdator();
00354 BranchKey finder(rawData, source, "", "");
00355 ProductRegistry::ProductList::iterator it = pList.lower_bound(finder);
00356 if(it != pList.end() && it->first.friendlyClassName_ == rawData && it->first.moduleLabel_ == source) {
00357
00358
00359
00360 it->second.init();
00361 daqProvenanceHelper_.reset(new DaqProvenanceHelper(it->second.unwrappedTypeID()));
00362
00363 BranchDescription const& newBD = daqProvenanceHelper_->constBranchDescription_.me();
00364
00365 daqProvenanceHelper_->saveInfo(it->second, newBD);
00366
00367 it->second.init();
00368 newBranchToOldBranch_.insert(std::make_pair(newBD.branchName(), it->second.branchName()));
00369
00370 pList.erase(it);
00371
00372 it = pList.lower_bound(finder);
00373 assert(!(it != pList.end() && it->first.friendlyClassName_ == rawData && it->first.moduleLabel_ == source));
00374
00375 inputProdDescReg.copyProduct(newBD);
00376
00377 daqProvenanceHelper_->fixMetaData(processConfigurations_);
00378 daqProvenanceHelper_->fixMetaData(pHistVector);
00379 daqProvenanceHelper_->fixMetaData(*branchIDLists_);
00380 daqProvenanceHelper_->fixMetaData(*branchChildren_);
00381 }
00382 }
00383
00384 ProcessHistoryRegistry::instance()->insertCollection(pHistVector);
00385 ProcessConfigurationRegistry::instance()->insertCollection(processConfigurations_);
00386
00387 eventTree_.trainCache(BranchTypeToAuxiliaryBranchName(InEvent).c_str());
00388
00389 validateFile(inputType, usingGoToEvent);
00390
00391
00392 readParentageTree();
00393
00394
00395 if(eventSkipperByID_ && eventSkipperByID_->somethingToSkip()) {
00396 whyNotFastClonable_ += FileBlock::EventsOrLumisSelectedByID;
00397 }
00398
00399 initializeDuplicateChecker(indexesIntoFiles, currentIndexIntoFile);
00400 indexIntoFileIter_ = indexIntoFileBegin_ = indexIntoFile_.begin(noEventSort ? IndexIntoFile::firstAppearanceOrder : IndexIntoFile::numericalOrder);
00401 indexIntoFileEnd_ = indexIntoFile_.end(noEventSort ? IndexIntoFile::firstAppearanceOrder : IndexIntoFile::numericalOrder);
00402 forcedRunOffset_ = forcedRunOffset(forcedRunNumber, indexIntoFileBegin_, indexIntoFileEnd_);
00403 eventProcessHistoryIter_ = eventProcessHistoryIDs_.begin();
00404
00405
00406 ProductRegistry::ProductList const& pList = inputProdDescReg.productList();
00407 for(ProductRegistry::ProductList::const_iterator it = pList.begin(), itEnd = pList.end();
00408 it != itEnd; ++it) {
00409 BranchDescription const& prod = it->second;
00410 prod.init();
00411 treePointers_[prod.branchType()]->setPresence(prod, newBranchToOldBranch(prod.branchName()));
00412 }
00413
00414 fillProductRegistryTransients(processConfigurations_, inputProdDescReg);
00415
00416 std::unique_ptr<ProductRegistry> newReg(new ProductRegistry);
00417
00418
00419 {
00420 ProductRegistry::ProductList const& prodList = inputProdDescReg.productList();
00421 for(ProductRegistry::ProductList::const_iterator it = prodList.begin(), itEnd = prodList.end();
00422 it != itEnd; ++it) {
00423 BranchDescription const& prod = it->second;
00424 std::string newFriendlyName = friendlyname::friendlyName(prod.className());
00425 if(newFriendlyName == prod.friendlyClassName()) {
00426 newReg->copyProduct(prod);
00427 } else {
00428 if(fileFormatVersion().splitProductIDs()) {
00429 throw Exception(errors::UnimplementedFeature)
00430 << "Cannot change friendly class name algorithm without more development work\n"
00431 << "to update BranchIDLists. Contact the framework group.\n";
00432 }
00433 BranchDescription newBD(prod);
00434 newBD.updateFriendlyClassName();
00435 newReg->copyProduct(newBD);
00436 newBranchToOldBranch_.insert(std::make_pair(newBD.branchName(), prod.branchName()));
00437 }
00438 }
00439 dropOnInput(*newReg, groupSelectorRules, dropDescendants, inputType);
00440
00441 newReg->setFrozen(inputType != InputType::Primary);
00442 productRegistry_.reset(newReg.release());
00443 }
00444
00445
00446 provenanceReaderMaker_.reset(makeProvenanceReaderMaker().release());
00447
00448
00449 ProductRegistry::ProductList const& prodList = productRegistry()->productList();
00450 for(ProductRegistry::ProductList::const_iterator it = prodList.begin(), itEnd = prodList.end();
00451 it != itEnd; ++it) {
00452 BranchDescription const& prod = it->second;
00453 treePointers_[prod.branchType()]->addBranch(it->first, prod,
00454 newBranchToOldBranch(prod.branchName()));
00455 }
00456
00457
00458 if(inputType == InputType::SecondarySource) {
00459 secondaryEventPrincipal_.reset(new EventPrincipal(productRegistry(), branchIDListHelper_, processConfiguration));
00460 }
00461
00462
00463 setIfFastClonable(remainingEvents, remainingLumis);
00464
00465
00466 if(inputType == InputType::Primary) {
00467 branchListIndexesUnchanged_ = branchIDListHelper_->updateFromInput(*branchIDLists_);
00468 }
00469
00470 setRefCoreStreamer(true);
00471
00472
00473 indexIntoFile_.doneFileInitialization();
00474
00475
00476 eventTree_.resetTraining();
00477
00478
00479 runTree_.trainCache("*");
00480 lumiTree_.trainCache("*");
00481 }
00482
00483 RootFile::~RootFile() {
00484 }
00485
00486 void
00487 RootFile::readEntryDescriptionTree() {
00488
00489 if(!fileFormatVersion().perEventProductIDs()) return;
00490
00491 std::unique_ptr<TTree> entryDescriptionTree(dynamic_cast<TTree*>(filePtr_->Get(poolNames::entryDescriptionTreeName().c_str())));
00492 if(0 == entryDescriptionTree.get()) {
00493 throw Exception(errors::FileReadError) << "Could not find tree " << poolNames::entryDescriptionTreeName()
00494 << " in the input file.\n";
00495 }
00496
00497 EntryDescriptionID idBuffer;
00498 EntryDescriptionID* pidBuffer = &idBuffer;
00499 entryDescriptionTree->SetBranchAddress(poolNames::entryDescriptionIDBranchName().c_str(), &pidBuffer);
00500
00501 EntryDescriptionRegistry& oldregistry = *EntryDescriptionRegistry::instance();
00502
00503 EventEntryDescription entryDescriptionBuffer;
00504 EventEntryDescription *pEntryDescriptionBuffer = &entryDescriptionBuffer;
00505 entryDescriptionTree->SetBranchAddress(poolNames::entryDescriptionBranchName().c_str(), &pEntryDescriptionBuffer);
00506
00507
00508 ParentageRegistry& registry = *ParentageRegistry::instance();
00509
00510 for(Long64_t i = 0, numEntries = entryDescriptionTree->GetEntries(); i < numEntries; ++i) {
00511 roottree::getEntry(entryDescriptionTree.get(), i);
00512 if(idBuffer != entryDescriptionBuffer.id()) {
00513 throw Exception(errors::EventCorruption) << "Corruption of EntryDescription tree detected.\n";
00514 }
00515 oldregistry.insertMapped(entryDescriptionBuffer);
00516 Parentage parents;
00517 parents.parents() = entryDescriptionBuffer.parents();
00518 if(daqProvenanceHelper_) {
00519 ParentageID const oldID = parents.id();
00520 daqProvenanceHelper_->fixMetaData(parents.parents());
00521 ParentageID newID = parents.id();
00522 if(newID != oldID) {
00523 daqProvenanceHelper_->parentageIDMap_.insert(std::make_pair(oldID, newID));
00524 }
00525 }
00526 registry.insertMapped(parents);
00527 }
00528 entryDescriptionTree->SetBranchAddress(poolNames::entryDescriptionIDBranchName().c_str(), 0);
00529 entryDescriptionTree->SetBranchAddress(poolNames::entryDescriptionBranchName().c_str(), 0);
00530 }
00531
00532 void
00533 RootFile::readParentageTree() {
00534 if(!fileFormatVersion().splitProductIDs()) {
00535
00536 readEntryDescriptionTree();
00537 return;
00538 }
00539
00540
00541 std::unique_ptr<TTree> parentageTree(dynamic_cast<TTree*>(filePtr_->Get(poolNames::parentageTreeName().c_str())));
00542 if(0 == parentageTree.get()) {
00543 throw Exception(errors::FileReadError) << "Could not find tree " << poolNames::parentageTreeName()
00544 << " in the input file.\n";
00545 }
00546
00547 Parentage parents;
00548 Parentage *pParentageBuffer = &parents;
00549 parentageTree->SetBranchAddress(poolNames::parentageBranchName().c_str(), &pParentageBuffer);
00550
00551 ParentageRegistry& registry = *ParentageRegistry::instance();
00552
00553 parentageIDLookup_.reserve(parentageTree->GetEntries());
00554 for(Long64_t i = 0, numEntries = parentageTree->GetEntries(); i < numEntries; ++i) {
00555 roottree::getEntry(parentageTree.get(), i);
00556 if(daqProvenanceHelper_) {
00557 ParentageID const oldID = parents.id();
00558 daqProvenanceHelper_->fixMetaData(parents.parents());
00559 ParentageID newID = parents.id();
00560 if(newID != oldID) {
00561 daqProvenanceHelper_->parentageIDMap_.insert(std::make_pair(oldID, newID));
00562 }
00563 }
00564 registry.insertMapped(parents);
00565 parentageIDLookup_.push_back(parents.id());
00566 }
00567 parentageTree->SetBranchAddress(poolNames::parentageBranchName().c_str(), 0);
00568 }
00569
00570 void
00571 RootFile::setIfFastClonable(int remainingEvents, int remainingLumis) {
00572 if(fileFormatVersion().noMetaDataTrees() and !fileFormatVersion().storedProductProvenanceUsed()) {
00573
00574 whyNotFastClonable_ += FileBlock::FileTooOld;
00575 return;
00576 }
00577 if(!fileFormatVersion().splitProductIDs()) {
00578 whyNotFastClonable_ += FileBlock::FileTooOld;
00579 return;
00580 }
00581 if(processingMode_ != InputSource::RunsLumisAndEvents) {
00582 whyNotFastClonable_ += FileBlock::NotProcessingEvents;
00583 return;
00584 }
00585
00586 IndexIntoFile::IndexIntoFileItr it = indexIntoFileBegin_;
00587 while(it != indexIntoFileEnd_ && it.getEntryType() != IndexIntoFile::kEvent) {
00588 ++it;
00589 }
00590 if(it == indexIntoFileEnd_) {
00591 whyNotFastClonable_ += FileBlock::NoEventsInFile;
00592 return;
00593 }
00594
00595
00596 IndexIntoFile::SortOrder sortOrder = (noEventSort_ ? IndexIntoFile::firstAppearanceOrder : IndexIntoFile::numericalOrder);
00597 if(!indexIntoFile_.iterationWillBeInEntryOrder(sortOrder)) {
00598 whyNotFastClonable_ += (noEventSort_ ? FileBlock::RunOrLumiNotContiguous : FileBlock::EventsToBeSorted);
00599 }
00600 if(skipAnyEvents_) {
00601 whyNotFastClonable_ += FileBlock::InitialEventsSkipped;
00602 }
00603 if(remainingEvents >= 0 && eventTree_.entries() > remainingEvents) {
00604 whyNotFastClonable_ += FileBlock::MaxEventsTooSmall;
00605 }
00606 if(remainingLumis >= 0 && lumiTree_.entries() > remainingLumis) {
00607 whyNotFastClonable_ += FileBlock::MaxLumisTooSmall;
00608 }
00609
00610
00611
00612
00613
00614
00615
00616
00617 if(duplicateChecker_ &&
00618 !duplicateChecker_->checkDisabled() &&
00619 !duplicateChecker_->noDuplicatesInFile()) {
00620 whyNotFastClonable_ += FileBlock::DuplicateEventsRemoved;
00621 }
00622 }
00623
00624 boost::shared_ptr<FileBlock>
00625 RootFile::createFileBlock() const {
00626 return boost::shared_ptr<FileBlock>(new FileBlock(fileFormatVersion(),
00627 eventTree_.tree(),
00628 eventTree_.metaTree(),
00629 lumiTree_.tree(),
00630 lumiTree_.metaTree(),
00631 runTree_.tree(),
00632 runTree_.metaTree(),
00633 whyNotFastClonable(),
00634 hasNewlyDroppedBranch(),
00635 file_,
00636 branchListIndexesUnchanged(),
00637 modifiedIDs(),
00638 branchChildren_,
00639 branchIDLists_));
00640 }
00641
00642 std::string const&
00643 RootFile::newBranchToOldBranch(std::string const& newBranch) const {
00644 std::map<std::string, std::string>::const_iterator it = newBranchToOldBranch_.find(newBranch);
00645 if(it != newBranchToOldBranch_.end()) {
00646 return it->second;
00647 }
00648 return newBranch;
00649 }
00650
00651 IndexIntoFile::IndexIntoFileItr
00652 RootFile::indexIntoFileIter() const {
00653 return indexIntoFileIter_;
00654 }
00655
00656 void
00657 RootFile::setPosition(IndexIntoFile::IndexIntoFileItr const& position) {
00658 indexIntoFileIter_.copyPosition(position);
00659 }
00660
00661 bool
00662 RootFile::skipThisEntry() {
00663 if(indexIntoFileIter_ == indexIntoFileEnd_) {
00664 return false;
00665 }
00666 if(eventSkipperByID_ && eventSkipperByID_->somethingToSkip()) {
00667
00668
00669 if(eventSkipperByID_->skipIt(indexIntoFileIter_.run(), indexIntoFileIter_.lumi(), 0U)) {
00670 return true;
00671 }
00672
00673
00674 if(indexIntoFileIter_.getEntryType() == IndexIntoFile::kEvent) {
00675 fillEventAuxiliary();
00676 if(eventSkipperByID_->skipIt(indexIntoFileIter_.run(),
00677 indexIntoFileIter_.lumi(),
00678 eventAux_.id().event())) {
00679 return true;
00680 }
00681 }
00682
00683
00684 if(indexIntoFileIter_.getEntryType() == IndexIntoFile::kRun &&
00685 eventSkipperByID_->skippingLumis()) {
00686 IndexIntoFile::IndexIntoFileItr iterLumi = indexIntoFileIter_;
00687
00688
00689 if(iterLumi.peekAheadAtLumi() == IndexIntoFile::invalidLumi) {
00690 return true;
00691 }
00692
00693 do {
00694 if(!eventSkipperByID_->skipIt(iterLumi.run(), iterLumi.peekAheadAtLumi(), 0U)) {
00695 return false;
00696 }
00697 }
00698 while(iterLumi.skipLumiInRun());
00699 return true;
00700 }
00701 }
00702 return false;
00703 }
00704
00705 IndexIntoFile::EntryType
00706 RootFile::getEntryTypeWithSkipping() {
00707 while(skipThisEntry()) {
00708 if(indexIntoFileIter_.getEntryType() == IndexIntoFile::kRun) {
00709 indexIntoFileIter_.advanceToNextRun();
00710 }
00711 else if(indexIntoFileIter_.getEntryType() == IndexIntoFile::kLumi) {
00712 indexIntoFileIter_.advanceToNextLumiOrRun();
00713 }
00714 else {
00715 ++indexIntoFileIter_;
00716 }
00717 }
00718 return indexIntoFileIter_.getEntryType();
00719 }
00720
00721 bool
00722 RootFile::isDuplicateEvent() {
00723 assert(indexIntoFileIter_.getEntryType() == IndexIntoFile::kEvent);
00724 if(duplicateChecker_.get() == 0) {
00725 return false;
00726 }
00727 fillEventAuxiliary();
00728 return duplicateChecker_->isDuplicateAndCheckActive(indexIntoFileIter_.processHistoryIDIndex(),
00729 indexIntoFileIter_.run(), indexIntoFileIter_.lumi(), eventAux_.id().event(), file_);
00730 }
00731
00732 IndexIntoFile::EntryType
00733 RootFile::getNextEntryTypeWanted() {
00734 IndexIntoFile::EntryType entryType = getEntryTypeWithSkipping();
00735 if(entryType == IndexIntoFile::kEnd) {
00736 return IndexIntoFile::kEnd;
00737 }
00738 if(entryType == IndexIntoFile::kRun) {
00739 return IndexIntoFile::kRun;
00740 } else if(processingMode_ == InputSource::Runs) {
00741 indexIntoFileIter_.advanceToNextRun();
00742 return getNextEntryTypeWanted();
00743 }
00744 if(entryType == IndexIntoFile::kLumi) {
00745 return IndexIntoFile::kLumi;
00746 } else if(processingMode_ == InputSource::RunsAndLumis) {
00747 indexIntoFileIter_.advanceToNextLumiOrRun();
00748 return getNextEntryTypeWanted();
00749 }
00750 if(isDuplicateEvent()) {
00751 ++indexIntoFileIter_;
00752 return getNextEntryTypeWanted();
00753 }
00754 return IndexIntoFile::kEvent;
00755 }
00756
00757 bool
00758 RootFile::wasLastEventJustRead() const {
00759 IndexIntoFile::IndexIntoFileItr itr(indexIntoFileIter_);
00760 itr.advanceToEvent();
00761 return itr.getEntryType() == IndexIntoFile::kEnd;
00762 }
00763
00764 bool
00765 RootFile::wasFirstEventJustRead() const {
00766 IndexIntoFile::IndexIntoFileItr itr(indexIntoFileIter_);
00767 int phIndex;
00768 RunNumber_t run;
00769 LuminosityBlockNumber_t lumi;
00770 IndexIntoFile::EntryNumber_t eventEntry;
00771 itr.skipEventBackward(phIndex,
00772 run,
00773 lumi,
00774 eventEntry);
00775 itr.skipEventBackward(phIndex,
00776 run,
00777 lumi,
00778 eventEntry);
00779 return eventEntry == IndexIntoFile::invalidEntry;
00780 }
00781
00782 namespace {
00783 typedef IndexIntoFile::EntryNumber_t EntryNumber_t;
00784 struct RunItem {
00785 RunItem(ProcessHistoryID const& phid, RunNumber_t const& run) :
00786 phid_(phid), run_(run) {}
00787 ProcessHistoryID phid_;
00788 RunNumber_t run_;
00789 };
00790 struct RunItemSortByRun {
00791 bool operator()(RunItem const& a, RunItem const& b) const {
00792 return a.run_ < b.run_;
00793 }
00794 };
00795 struct RunItemSortByRunPhid {
00796 bool operator()(RunItem const& a, RunItem const& b) const {
00797 return a.run_ < b.run_ || (!(b.run_ < a.run_) && a.phid_ < b.phid_);
00798 }
00799 };
00800 struct LumiItem {
00801 LumiItem(ProcessHistoryID const& phid, RunNumber_t const& run,
00802 LuminosityBlockNumber_t const& lumi, EntryNumber_t const& entry) :
00803 phid_(phid), run_(run), lumi_(lumi), firstEventEntry_(entry),
00804 lastEventEntry_(entry == -1LL ? -1LL : entry + 1) {}
00805 ProcessHistoryID phid_;
00806 RunNumber_t run_;
00807 LuminosityBlockNumber_t lumi_;
00808 EntryNumber_t firstEventEntry_;
00809 EntryNumber_t lastEventEntry_;
00810 };
00811 struct LumiItemSortByRunLumi {
00812 bool operator()(LumiItem const& a, LumiItem const& b) const {
00813 return a.run_ < b.run_ || (!(b.run_ < a.run_) && a.lumi_ < b.lumi_);
00814 }
00815 };
00816 struct LumiItemSortByRunLumiPhid {
00817 bool operator()(LumiItem const& a, LumiItem const& b) const {
00818 if(a.run_ < b.run_) return true;
00819 if(b.run_ < a.run_) return false;
00820 if(a.lumi_ < b.lumi_) return true;
00821 if(b.lumi_ < a.lumi_) return false;
00822 return a.phid_ < b.phid_;
00823 }
00824 };
00825 }
00826
00827 void
00828 RootFile::fillIndexIntoFile() {
00829
00830
00831
00832
00833
00834
00835
00836 assert(!fileFormatVersion().hasIndexIntoFile());
00837
00838 typedef std::list<LumiItem> LumiList;
00839 LumiList lumis;
00840
00841 typedef std::set<LuminosityBlockID> RunLumiSet;
00842 RunLumiSet runLumiSet;
00843
00844 typedef std::list<RunItem> RunList;
00845 RunList runs;
00846
00847 typedef std::set<RunNumber_t> RunSet;
00848 RunSet runSet;
00849
00850 typedef std::set<RunItem, RunItemSortByRunPhid> RunItemSet;
00851 RunItemSet runItemSet;
00852
00853 typedef std::map<RunNumber_t, ProcessHistoryID> PHIDMap;
00854 PHIDMap phidMap;
00855
00856 RunNumber_t prevRun = 0;
00857 LuminosityBlockNumber_t prevLumi = 0;
00858 ProcessHistoryID prevPhid;
00859 bool iFirst = true;
00860
00861 indexIntoFile_.unsortedEventNumbers().clear();
00862 indexIntoFile_.unsortedEventNumbers().reserve(eventTree_.entries());
00863
00864
00865 while(eventTree_.next()) {
00866 bool newRun = false;
00867 bool newLumi = false;
00868 fillThisEventAuxiliary();
00869 fillHistory();
00870
00871
00872
00873
00874 indexIntoFile_.unsortedEventNumbers().push_back(eventAux().event());
00875
00876 ProcessHistoryID reducedPHID = ProcessHistoryRegistry::instance()->extra().reduceProcessHistoryID(eventAux().processHistoryID());
00877
00878 if(iFirst || prevPhid != reducedPHID || prevRun != eventAux().run()) {
00879 iFirst = false;
00880 newRun = newLumi = true;
00881 } else if(prevLumi != eventAux().luminosityBlock()) {
00882 newLumi = true;
00883 }
00884 prevPhid = reducedPHID;
00885 prevRun = eventAux().run();
00886 prevLumi = eventAux().luminosityBlock();
00887 if(newLumi) {
00888 lumis.emplace_back(reducedPHID,
00889 eventAux().run(), eventAux().luminosityBlock(), eventTree_.entryNumber());
00890 runLumiSet.insert(LuminosityBlockID(eventAux().run(), eventAux().luminosityBlock()));
00891 } else {
00892 LumiItem& currentLumi = lumis.back();
00893 assert(currentLumi.lastEventEntry_ == eventTree_.entryNumber());
00894 ++currentLumi.lastEventEntry_;
00895 }
00896 if(newRun) {
00897
00898 RunItem item(reducedPHID, eventAux().run());
00899 if(runItemSet.insert(item).second) {
00900 runs.push_back(std::move(item));
00901 runSet.insert(eventAux().run());
00902 phidMap.insert(std::make_pair(eventAux().run(), reducedPHID));
00903 }
00904 }
00905 }
00906
00907 eventTree_.setEntryNumber(-1);
00908 eventAux_ = EventAuxiliary();
00909 lastEventEntryNumberRead_ = -1LL;
00910
00911
00912
00913 typedef std::map<RunNumber_t, EntryNumber_t> RunMap;
00914 RunMap runMap;
00915
00916 typedef std::vector<RunItem> RunVector;
00917 RunVector emptyRuns;
00918
00919 if(runTree_.isValid()) {
00920 while(runTree_.next()) {
00921
00922
00923 boost::shared_ptr<RunAuxiliary> runAux = fillRunAuxiliary();
00924 ProcessHistoryID reducedPHID = ProcessHistoryRegistry::instance()->extra().reduceProcessHistoryID(runAux->processHistoryID());
00925
00926 if(runSet.insert(runAux->run()).second) {
00927
00928 emptyRuns.emplace_back(reducedPHID, runAux->run());
00929 }
00930 runMap.insert(std::make_pair(runAux->run(), runTree_.entryNumber()));
00931 phidMap.insert(std::make_pair(runAux->run(), reducedPHID));
00932 }
00933
00934 runTree_.setEntryNumber(-1);
00935 }
00936
00937
00938 RunItemSortByRun runItemSortByRun;
00939 stable_sort_all(emptyRuns, runItemSortByRun);
00940
00941 RunList::iterator itRuns = runs.begin(), endRuns = runs.end();
00942 for(RunVector::const_iterator i = emptyRuns.begin(), iEnd = emptyRuns.end(); i != iEnd; ++i) {
00943 for(; itRuns != endRuns; ++itRuns) {
00944 if(runItemSortByRun(*i, *itRuns)) {
00945 break;
00946 }
00947 }
00948 runs.insert(itRuns, *i);
00949 }
00950
00951
00952
00953 typedef std::vector<LumiItem> LumiVector;
00954 LumiVector emptyLumis;
00955
00956 typedef std::map<LuminosityBlockID, EntryNumber_t> RunLumiMap;
00957 RunLumiMap runLumiMap;
00958
00959 if(lumiTree_.isValid()) {
00960 while(lumiTree_.next()) {
00961
00962 boost::shared_ptr<LuminosityBlockAuxiliary> lumiAux = fillLumiAuxiliary();
00963 LuminosityBlockID lumiID = LuminosityBlockID(lumiAux->run(), lumiAux->luminosityBlock());
00964 if(runLumiSet.insert(lumiID).second) {
00965
00966
00967
00968
00969 PHIDMap::const_iterator iPhidMap = phidMap.find(lumiAux->run());
00970 assert(iPhidMap != phidMap.end());
00971 emptyLumis.emplace_back(iPhidMap->second, lumiAux->run(), lumiAux->luminosityBlock(), -1LL);
00972 }
00973 runLumiMap.insert(std::make_pair(lumiID, lumiTree_.entryNumber()));
00974 }
00975
00976 lumiTree_.setEntryNumber(-1);
00977 }
00978
00979
00980 LumiItemSortByRunLumi lumiItemSortByRunLumi;
00981 stable_sort_all(emptyLumis, lumiItemSortByRunLumi);
00982
00983 LumiList::iterator itLumis = lumis.begin(), endLumis = lumis.end();
00984 for(LumiVector::const_iterator i = emptyLumis.begin(), iEnd = emptyLumis.end(); i != iEnd; ++i) {
00985 for(; itLumis != endLumis; ++itLumis) {
00986 if(lumiItemSortByRunLumi(*i, *itLumis)) {
00987 break;
00988 }
00989 }
00990 lumis.insert(itLumis, *i);
00991 }
00992
00993
00994
00995 typedef std::map<RunItem, int, RunItemSortByRunPhid> RunCountMap;
00996 RunCountMap runCountMap;
00997 std::vector<ProcessHistoryID>& phids = indexIntoFile_.setProcessHistoryIDs();
00998 assert(phids.empty());
00999 std::vector<IndexIntoFile::RunOrLumiEntry>& entries = indexIntoFile_.setRunOrLumiEntries();
01000 assert(entries.empty());
01001 int rcount = 0;
01002 for(RunList::iterator it = runs.begin(), itEnd = runs.end(); it != itEnd; ++it) {
01003 RunCountMap::const_iterator countMapItem = runCountMap.find(*it);
01004 if(countMapItem == runCountMap.end()) {
01005 countMapItem = runCountMap.insert(std::make_pair(*it, rcount)).first;
01006 assert(countMapItem != runCountMap.end());
01007 ++rcount;
01008 }
01009 std::vector<ProcessHistoryID>::const_iterator phidItem = find_in_all(phids, it->phid_);
01010 if(phidItem == phids.end()) {
01011 phids.push_back(it->phid_);
01012 phidItem = phids.end() - 1;
01013 }
01014 entries.emplace_back(
01015 countMapItem->second,
01016 -1LL,
01017 runMap[it->run_],
01018 phidItem - phids.begin(),
01019 it->run_,
01020 0U,
01021 -1LL,
01022 -1LL);
01023 }
01024
01025
01026 typedef std::map<LumiItem, int, LumiItemSortByRunLumiPhid> LumiCountMap;
01027 LumiCountMap lumiCountMap;
01028 int lcount = 0;
01029 for(LumiList::iterator it = lumis.begin(), itEnd = lumis.end(); it != itEnd; ++it) {
01030 RunCountMap::const_iterator runCountMapItem = runCountMap.find(RunItem(it->phid_, it->run_));
01031 assert(runCountMapItem != runCountMap.end());
01032 LumiCountMap::const_iterator countMapItem = lumiCountMap.find(*it);
01033 if(countMapItem == lumiCountMap.end()) {
01034 countMapItem = lumiCountMap.insert(std::make_pair(*it, lcount)).first;
01035 assert(countMapItem != lumiCountMap.end());
01036 ++lcount;
01037 }
01038 std::vector<ProcessHistoryID>::const_iterator phidItem = find_in_all(phids, it->phid_);
01039 assert(phidItem != phids.end());
01040 entries.emplace_back(
01041 runCountMapItem->second,
01042 countMapItem->second,
01043 runLumiMap[LuminosityBlockID(it->run_, it->lumi_)],
01044 phidItem - phids.begin(),
01045 it->run_,
01046 it->lumi_,
01047 it->firstEventEntry_,
01048 it->lastEventEntry_);
01049 }
01050 stable_sort_all(entries);
01051 }
01052
01053 void
01054 RootFile::validateFile(InputType::InputType inputType, bool usingGoToEvent) {
01055 if(!fid_.isValid()) {
01056 fid_ = FileID(createGlobalIdentifier());
01057 }
01058 if(!eventTree_.isValid()) {
01059 throw Exception(errors::EventCorruption) <<
01060 "'Events' tree is corrupted or not present\n" << "in the input file.\n";
01061 }
01062
01063 if(fileFormatVersion().hasIndexIntoFile()) {
01064 if(runTree().entries() > 0) {
01065 assert(!indexIntoFile_.empty());
01066 }
01067 if(!fileFormatVersion().useReducedProcessHistoryID()) {
01068 if(daqProvenanceHelper_) {
01069 std::vector<ProcessHistoryID>& phidVec = indexIntoFile_.setProcessHistoryIDs();
01070 for(std::vector<ProcessHistoryID>::iterator it = phidVec.begin(), itEnd = phidVec.end();
01071 it != itEnd;
01072 ++it) {
01073 *it = daqProvenanceHelper_->mapProcessHistoryID(*it);
01074 }
01075 }
01076 indexIntoFile_.reduceProcessHistoryIDs();
01077 }
01078 }
01079 else {
01080 assert(indexIntoFile_.empty());
01081 fillIndexIntoFile();
01082 }
01083
01084 indexIntoFile_.fixIndexes(orderedProcessHistoryIDs_);
01085 indexIntoFile_.setNumberOfEvents(eventTree_.entries());
01086 indexIntoFile_.setEventFinder(boost::shared_ptr<IndexIntoFile::EventFinder>(new RootFileEventFinder(eventTree_)));
01087
01088
01089 bool needEventNumbers = false;
01090 bool needIndexesForDuplicateChecker = duplicateChecker_ && duplicateChecker_->checkingAllFiles() && !duplicateChecker_->checkDisabled();
01091 if(inputType != InputType::Primary || needIndexesForDuplicateChecker || usingGoToEvent) {
01092 needEventNumbers = true;
01093 }
01094 bool needEventEntries = false;
01095 if(inputType != InputType::Primary || !noEventSort_) {
01096
01097 needEventEntries = true;
01098 }
01099 indexIntoFile_.fillEventNumbersOrEntries(needEventNumbers, needEventEntries);
01100 }
01101
01102 void
01103 RootFile::reportOpened(std::string const& inputType) {
01104
01105 std::string const label = "source";
01106 std::string moduleName = "PoolSource";
01107 filePtr_->inputFileOpened(
01108 logicalFile_,
01109 inputType,
01110 moduleName,
01111 label,
01112 fid_.fid(),
01113 eventTree_.branchNames());
01114 }
01115
01116 void
01117 RootFile::close() {
01118
01119 eventHistoryTree_ = 0;
01120 for(RootTreePtrArray::iterator it = treePointers_.begin(), itEnd = treePointers_.end(); it != itEnd; ++it) {
01121 (*it)->close();
01122 (*it) = 0;
01123 }
01124 filePtr_->Close();
01125 filePtr_.reset();
01126 }
01127
01128 void
01129 RootFile::fillThisEventAuxiliary() {
01130 if(lastEventEntryNumberRead_ == eventTree_.entryNumber()) {
01131
01132 return;
01133 }
01134 if(fileFormatVersion().newAuxiliary()) {
01135 EventAuxiliary *pEvAux = &eventAux_;
01136 eventTree_.fillAux<EventAuxiliary>(pEvAux);
01137 } else {
01138
01139 EventAux eventAux;
01140 EventAux *pEvAux = &eventAux;
01141 eventTree_.fillAux<EventAux>(pEvAux);
01142 conversion(eventAux, eventAux_);
01143 }
01144 lastEventEntryNumberRead_ = eventTree_.entryNumber();
01145 }
01146
01147 void
01148 RootFile::fillEventAuxiliary() {
01149 eventTree_.setEntryNumber(indexIntoFileIter_.entry());
01150 fillThisEventAuxiliary();
01151 }
01152
01153 void
01154 RootFile::fillHistory() {
01155
01156
01157
01158
01159 if(fileFormatVersion().eventHistoryBranch()) {
01160
01161 EventID id(eventAux().id().run(), 0, eventAux().id().event());
01162 if(eventProcessHistoryIter_->eventID() != id) {
01163 EventProcessHistoryID target(id, ProcessHistoryID());
01164 eventProcessHistoryIter_ = lower_bound_all(eventProcessHistoryIDs_, target);
01165 assert(eventProcessHistoryIter_->eventID() == id);
01166 }
01167 eventAux_.setProcessHistoryID(eventProcessHistoryIter_->processHistoryID());
01168 ++eventProcessHistoryIter_;
01169 } else if(fileFormatVersion().eventHistoryTree()) {
01170
01171 History* pHistory = history_.get();
01172 TBranch* eventHistoryBranch = eventHistoryTree_->GetBranch(poolNames::eventHistoryBranchName().c_str());
01173 if(!eventHistoryBranch) {
01174 throw Exception(errors::EventCorruption)
01175 << "Failed to find history branch in event history tree.\n";
01176 }
01177 eventHistoryBranch->SetAddress(&pHistory);
01178 roottree::getEntry(eventHistoryTree_, eventTree_.entryNumber());
01179 eventAux_.setProcessHistoryID(history_->processHistoryID());
01180 eventSelectionIDs_.reset(&history_->eventSelectionIDs(), do_nothing_deleter());
01181 branchListIndexes_.reset(&history_->branchListIndexes(), do_nothing_deleter());
01182 } else if(fileFormatVersion().noMetaDataTrees()) {
01183
01184 EventSelectionIDVector* pESV = eventSelectionIDs_.get();
01185 TBranch* eventSelectionIDBranch = eventTree_.tree()->GetBranch(poolNames::eventSelectionsBranchName().c_str());
01186 assert(eventSelectionIDBranch != 0);
01187 eventTree_.fillBranchEntry(eventSelectionIDBranch, pESV);
01188 BranchListIndexes* pBLI = branchListIndexes_.get();
01189 TBranch* branchListIndexesBranch = eventTree_.tree()->GetBranch(poolNames::branchListIndexesBranchName().c_str());
01190 assert(branchListIndexesBranch != 0);
01191 eventTree_.fillBranchEntry(branchListIndexesBranch, pBLI);
01192 }
01193 if(provenanceAdaptor_) {
01194 eventAux_.setProcessHistoryID(provenanceAdaptor_->convertID(eventAux().processHistoryID()));
01195 for(EventSelectionIDVector::iterator i = eventSelectionIDs_->begin(), e = eventSelectionIDs_->end(); i != e; ++i) {
01196 (*i) = provenanceAdaptor_->convertID(*i);
01197 }
01198 }
01199 if(daqProvenanceHelper_) {
01200 eventAux_.setProcessHistoryID(daqProvenanceHelper_->mapProcessHistoryID(eventAux_.processHistoryID()));
01201 }
01202 if(!fileFormatVersion().splitProductIDs()) {
01203
01204 provenanceAdaptor_->branchListIndexes(*branchListIndexes_);
01205 }
01206 branchIDListHelper_->fixBranchListIndexes(*branchListIndexes_);
01207 }
01208
01209 boost::shared_ptr<LuminosityBlockAuxiliary>
01210 RootFile::fillLumiAuxiliary() {
01211 boost::shared_ptr<LuminosityBlockAuxiliary> lumiAuxiliary(new LuminosityBlockAuxiliary);
01212 if(fileFormatVersion().newAuxiliary()) {
01213 LuminosityBlockAuxiliary *pLumiAux = lumiAuxiliary.get();
01214 lumiTree_.fillAux<LuminosityBlockAuxiliary>(pLumiAux);
01215 } else {
01216 LuminosityBlockAux lumiAux;
01217 LuminosityBlockAux *pLumiAux = &lumiAux;
01218 lumiTree_.fillAux<LuminosityBlockAux>(pLumiAux);
01219 conversion(lumiAux, *lumiAuxiliary);
01220 }
01221 if(provenanceAdaptor_) {
01222 lumiAuxiliary->setProcessHistoryID(provenanceAdaptor_->convertID(lumiAuxiliary->processHistoryID()));
01223 }
01224 if(daqProvenanceHelper_) {
01225 lumiAuxiliary->setProcessHistoryID(daqProvenanceHelper_->mapProcessHistoryID(lumiAuxiliary->processHistoryID()));
01226 }
01227 if(lumiAuxiliary->luminosityBlock() == 0 && !fileFormatVersion().runsAndLumis()) {
01228 lumiAuxiliary->id() = LuminosityBlockID(RunNumber_t(1), LuminosityBlockNumber_t(1));
01229 }
01230 return lumiAuxiliary;
01231 }
01232
01233 boost::shared_ptr<RunAuxiliary>
01234 RootFile::fillRunAuxiliary() {
01235 boost::shared_ptr<RunAuxiliary> runAuxiliary(new RunAuxiliary);
01236 if(fileFormatVersion().newAuxiliary()) {
01237 RunAuxiliary *pRunAux = runAuxiliary.get();
01238 runTree_.fillAux<RunAuxiliary>(pRunAux);
01239 } else {
01240 RunAux runAux;
01241 RunAux *pRunAux = &runAux;
01242 runTree_.fillAux<RunAux>(pRunAux);
01243 conversion(runAux, *runAuxiliary);
01244 }
01245 if(provenanceAdaptor_) {
01246 runAuxiliary->setProcessHistoryID(provenanceAdaptor_->convertID(runAuxiliary->processHistoryID()));
01247 }
01248 if(daqProvenanceHelper_) {
01249 runAuxiliary->setProcessHistoryID(daqProvenanceHelper_->mapProcessHistoryID(runAuxiliary->processHistoryID()));
01250 }
01251 return runAuxiliary;
01252 }
01253
01254 bool
01255 RootFile::skipEvents(int& offset) {
01256 while(offset > 0 && indexIntoFileIter_ != indexIntoFileEnd_) {
01257
01258 int phIndexOfSkippedEvent = IndexIntoFile::invalidIndex;
01259 RunNumber_t runOfSkippedEvent = IndexIntoFile::invalidRun;
01260 LuminosityBlockNumber_t lumiOfSkippedEvent = IndexIntoFile::invalidLumi;
01261 IndexIntoFile::EntryNumber_t skippedEventEntry = IndexIntoFile::invalidEntry;
01262
01263 indexIntoFileIter_.skipEventForward(phIndexOfSkippedEvent,
01264 runOfSkippedEvent,
01265 lumiOfSkippedEvent,
01266 skippedEventEntry);
01267
01268
01269 if(skippedEventEntry == IndexIntoFile::invalidEntry) break;
01270
01271 if(eventSkipperByID_ && eventSkipperByID_->somethingToSkip()) {
01272 eventTree_.setEntryNumber(skippedEventEntry);
01273 fillThisEventAuxiliary();
01274 if(eventSkipperByID_->skipIt(runOfSkippedEvent, lumiOfSkippedEvent, eventAux_.id().event())) {
01275 continue;
01276 }
01277 }
01278 if(duplicateChecker_ &&
01279 !duplicateChecker_->checkDisabled() &&
01280 !duplicateChecker_->noDuplicatesInFile()) {
01281
01282 eventTree_.setEntryNumber(skippedEventEntry);
01283 fillThisEventAuxiliary();
01284 if(duplicateChecker_->isDuplicateAndCheckActive(phIndexOfSkippedEvent,
01285 runOfSkippedEvent,
01286 lumiOfSkippedEvent,
01287 eventAux_.id().event(),
01288 file_)) {
01289 continue;
01290 }
01291 }
01292 --offset;
01293 }
01294
01295 while(offset < 0) {
01296
01297 if(duplicateChecker_) {
01298 duplicateChecker_->disable();
01299 }
01300
01301 int phIndexOfEvent = IndexIntoFile::invalidIndex;
01302 RunNumber_t runOfEvent = IndexIntoFile::invalidRun;
01303 LuminosityBlockNumber_t lumiOfEvent = IndexIntoFile::invalidLumi;
01304 EntryNumber_t eventEntry = IndexIntoFile::invalidEntry;
01305
01306 indexIntoFileIter_.skipEventBackward(phIndexOfEvent,
01307 runOfEvent,
01308 lumiOfEvent,
01309 eventEntry);
01310
01311 if(eventEntry == IndexIntoFile::invalidEntry) break;
01312
01313 if(eventSkipperByID_ && eventSkipperByID_->somethingToSkip()) {
01314 eventTree_.setEntryNumber(eventEntry);
01315 fillEventAuxiliary();
01316 if(eventSkipperByID_->skipIt(runOfEvent, lumiOfEvent, eventAux_.id().event())) {
01317 continue;
01318 }
01319 }
01320 ++offset;
01321 }
01322 return(indexIntoFileIter_ == indexIntoFileEnd_);
01323 }
01324
01325 bool
01326 RootFile::goToEvent(EventID const& eventID) {
01327
01328 indexIntoFile_.fillEventNumbers();
01329
01330 if(duplicateChecker_) {
01331 duplicateChecker_->disable();
01332 }
01333
01334 IndexIntoFile::SortOrder sortOrder = IndexIntoFile::numericalOrder;
01335 if(noEventSort_) sortOrder = IndexIntoFile::firstAppearanceOrder;
01336
01337 IndexIntoFile::IndexIntoFileItr iter =
01338 indexIntoFile_.findPosition(sortOrder, eventID.run(), eventID.luminosityBlock(), eventID.event());
01339
01340 if(iter == indexIntoFile_.end(sortOrder)) {
01341 return false;
01342 }
01343 indexIntoFileIter_ = iter;
01344 return true;
01345 }
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360 EventPrincipal*
01361 RootFile::readEvent(EventPrincipal& cache) {
01362 assert(indexIntoFileIter_ != indexIntoFileEnd_);
01363 assert(indexIntoFileIter_.getEntryType() == IndexIntoFile::kEvent);
01364
01365 eventTree_.setEntryNumber(indexIntoFileIter_.entry());
01366 EventPrincipal* ep = readCurrentEvent(cache);
01367
01368 assert(ep != 0);
01369 assert(eventAux().run() == indexIntoFileIter_.run() + forcedRunOffset_);
01370 assert(eventAux().luminosityBlock() == indexIntoFileIter_.lumi());
01371
01372
01373
01374 ProcessHistoryID idToCheck = (daqProvenanceHelper_ && fileFormatVersion().useReducedProcessHistoryID() ? *daqProvenanceHelper_->oldProcessHistoryID_ : eventAux().processHistoryID());
01375 ProcessHistoryID const& reducedPHID = ProcessHistoryRegistry::instance()->extra().reduceProcessHistoryID(idToCheck);
01376 assert(reducedPHID == indexIntoFile_.processHistoryID(indexIntoFileIter_.processHistoryIDIndex()));
01377
01378 ++indexIntoFileIter_;
01379 return ep;
01380 }
01381
01382
01383 EventPrincipal*
01384 RootFile::readCurrentEvent(EventPrincipal& cache) {
01385 if(!eventTree_.current()) {
01386 return 0;
01387 }
01388 fillThisEventAuxiliary();
01389 if(!fileFormatVersion().lumiInEventID()) {
01390
01391 const_cast<EventID&>(eventAux_.id()).setLuminosityBlockNumber(eventAux_.oldLuminosityBlock());
01392 eventAux_.resetObsoleteInfo();
01393 }
01394 fillHistory();
01395 overrideRunNumber(eventAux_.id(), eventAux().isRealData());
01396
01397
01398 cache.fillEventPrincipal(eventAux(),
01399 eventSelectionIDs_,
01400 branchListIndexes_,
01401 makeBranchMapper(),
01402 eventTree_.rootDelayedReader());
01403
01404
01405 filePtr_->eventReadFromFile(eventID().run(), eventID().event());
01406 return &cache;
01407 }
01408
01409 EventPrincipal*
01410 RootFile::clearAndReadCurrentEvent(EventPrincipal& cache) {
01411 cache.clearEventPrincipal();
01412 return readCurrentEvent(cache);
01413 }
01414
01415 void
01416 RootFile::setAtEventEntry(IndexIntoFile::EntryNumber_t entry) {
01417 eventTree_.setEntryNumber(entry);
01418 }
01419
01420 boost::shared_ptr<RunAuxiliary>
01421 RootFile::readRunAuxiliary_() {
01422 assert(indexIntoFileIter_ != indexIntoFileEnd_);
01423 assert(indexIntoFileIter_.getEntryType() == IndexIntoFile::kRun);
01424
01425
01426 if(!runTree_.isValid()) {
01427
01428
01429
01430 IndexIntoFile::EntryNumber_t eventEntry = indexIntoFileIter_.firstEventEntryThisRun();
01431 assert(eventEntry != IndexIntoFile::invalidEntry);
01432 RootTree::EntryNumber savedEntry = eventTree_.entryNumber();
01433 eventTree_.setEntryNumber(eventEntry);
01434 assert(eventTree_.current());
01435 fillThisEventAuxiliary();
01436 eventTree_.setEntryNumber(savedEntry);
01437
01438 RunID run = RunID(indexIntoFileIter_.run());
01439 overrideRunNumber(run);
01440 return boost::shared_ptr<RunAuxiliary>(new RunAuxiliary(run.run(), eventAux().time(), Timestamp::invalidTimestamp()));
01441 }
01442
01443 runTree_.setEntryNumber(indexIntoFileIter_.entry());
01444 boost::shared_ptr<RunAuxiliary> runAuxiliary = fillRunAuxiliary();
01445 assert(runAuxiliary->run() == indexIntoFileIter_.run());
01446 overrideRunNumber(runAuxiliary->id());
01447 filePtr_->reportInputRunNumber(runAuxiliary->run());
01448
01449 if(runAuxiliary->beginTime() == Timestamp::invalidTimestamp()) {
01450 runAuxiliary->setEndTime(Timestamp::invalidTimestamp());
01451 }
01452
01453
01454
01455
01456 if(runAuxiliary->beginTime() == Timestamp::invalidTimestamp() ||
01457 !fileFormatVersion().processHistorySameWithinRun()) {
01458
01459 IndexIntoFile::EntryNumber_t eventEntry = indexIntoFileIter_.firstEventEntryThisRun();
01460
01461 if(eventEntry != IndexIntoFile::invalidEntry) {
01462 RootTree::EntryNumber savedEntry = eventTree_.entryNumber();
01463 eventTree_.setEntryNumber(eventEntry);
01464 assert(eventTree_.current());
01465 fillThisEventAuxiliary();
01466
01467
01468 if(runAuxiliary->beginTime() == Timestamp::invalidTimestamp()) {
01469 runAuxiliary->setBeginTime(eventAux().time());
01470 }
01471
01472
01473
01474
01475
01476 if(!fileFormatVersion().processHistorySameWithinRun()) {
01477 fillHistory();
01478 runAuxiliary->setProcessHistoryID(eventAux().processHistoryID());
01479 savedRunAuxiliary_ = runAuxiliary;
01480 }
01481 eventTree_.setEntryNumber(savedEntry);
01482 } else {
01483
01484 savedRunAuxiliary_ = runAuxiliary;
01485 }
01486 }
01487 return runAuxiliary;
01488 }
01489
01490 boost::shared_ptr<RunPrincipal>
01491 RootFile::readRun_(boost::shared_ptr<RunPrincipal> runPrincipal) {
01492 assert(indexIntoFileIter_ != indexIntoFileEnd_);
01493 assert(indexIntoFileIter_.getEntryType() == IndexIntoFile::kRun);
01494
01495 if(!runTree_.isValid()) {
01496 ++indexIntoFileIter_;
01497 return runPrincipal;
01498 }
01499
01500 runPrincipal->fillRunPrincipal(runTree_.rootDelayedReader());
01501
01502 runPrincipal->readImmediate();
01503 ++indexIntoFileIter_;
01504 return runPrincipal;
01505 }
01506
01507 boost::shared_ptr<LuminosityBlockAuxiliary>
01508 RootFile::readLuminosityBlockAuxiliary_() {
01509 assert(indexIntoFileIter_ != indexIntoFileEnd_);
01510 assert(indexIntoFileIter_.getEntryType() == IndexIntoFile::kLumi);
01511
01512 if(!lumiTree_.isValid()) {
01513 IndexIntoFile::EntryNumber_t eventEntry = indexIntoFileIter_.firstEventEntryThisLumi();
01514 assert(eventEntry != IndexIntoFile::invalidEntry);
01515 RootTree::EntryNumber savedEntry = eventTree_.entryNumber();
01516 eventTree_.setEntryNumber(eventEntry);
01517 assert(eventTree_.current());
01518 fillThisEventAuxiliary();
01519 eventTree_.setEntryNumber(savedEntry);
01520
01521 LuminosityBlockID lumi = LuminosityBlockID(indexIntoFileIter_.run(), indexIntoFileIter_.lumi());
01522 overrideRunNumber(lumi);
01523 return boost::shared_ptr<LuminosityBlockAuxiliary>(new LuminosityBlockAuxiliary(lumi.run(), lumi.luminosityBlock(), eventAux().time(), Timestamp::invalidTimestamp()));
01524 }
01525
01526 lumiTree_.setEntryNumber(indexIntoFileIter_.entry());
01527 boost::shared_ptr<LuminosityBlockAuxiliary> lumiAuxiliary = fillLumiAuxiliary();
01528 assert(lumiAuxiliary->run() == indexIntoFileIter_.run());
01529 assert(lumiAuxiliary->luminosityBlock() == indexIntoFileIter_.lumi());
01530 overrideRunNumber(lumiAuxiliary->id());
01531 filePtr_->reportInputLumiSection(lumiAuxiliary->run(), lumiAuxiliary->luminosityBlock());
01532 if(lumiAuxiliary->beginTime() == Timestamp::invalidTimestamp()) {
01533 IndexIntoFile::EntryNumber_t eventEntry = indexIntoFileIter_.firstEventEntryThisLumi();
01534 if(eventEntry != IndexIntoFile::invalidEntry) {
01535 RootTree::EntryNumber savedEntry = eventTree_.entryNumber();
01536 eventTree_.setEntryNumber(eventEntry);
01537 assert(eventTree_.current());
01538 fillThisEventAuxiliary();
01539 eventTree_.setEntryNumber(savedEntry);
01540
01541 lumiAuxiliary->setBeginTime(eventAux().time());
01542 }
01543 lumiAuxiliary->setEndTime(Timestamp::invalidTimestamp());
01544 }
01545 if(!fileFormatVersion().processHistorySameWithinRun() && savedRunAuxiliary_) {
01546 lumiAuxiliary->setProcessHistoryID(savedRunAuxiliary_->processHistoryID());
01547 }
01548 return lumiAuxiliary;
01549 }
01550
01551 boost::shared_ptr<LuminosityBlockPrincipal>
01552 RootFile::readLumi(boost::shared_ptr<LuminosityBlockPrincipal> lumiPrincipal) {
01553 assert(indexIntoFileIter_ != indexIntoFileEnd_);
01554 assert(indexIntoFileIter_.getEntryType() == IndexIntoFile::kLumi);
01555
01556 if(!lumiTree_.isValid()) {
01557 ++indexIntoFileIter_;
01558 return lumiPrincipal;
01559 }
01560
01561 lumiTree_.setEntryNumber(indexIntoFileIter_.entry());
01562 lumiPrincipal->fillLuminosityBlockPrincipal(lumiTree_.rootDelayedReader());
01563
01564 lumiPrincipal->readImmediate();
01565 ++indexIntoFileIter_;
01566 return lumiPrincipal;
01567 }
01568
01569 bool
01570 RootFile::setEntryAtEvent(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) {
01571 indexIntoFileIter_ = indexIntoFile_.findEventPosition(run, lumi, event);
01572 if(indexIntoFileIter_ == indexIntoFileEnd_) return false;
01573 eventTree_.setEntryNumber(indexIntoFileIter_.entry());
01574 return true;
01575 }
01576
01577 bool
01578 RootFile::setEntryAtLumi(RunNumber_t run, LuminosityBlockNumber_t lumi) {
01579 indexIntoFileIter_ = indexIntoFile_.findLumiPosition(run, lumi);
01580 if(indexIntoFileIter_ == indexIntoFileEnd_) return false;
01581 lumiTree_.setEntryNumber(indexIntoFileIter_.entry());
01582 return true;
01583 }
01584
01585 bool
01586 RootFile::setEntryAtRun(RunNumber_t run) {
01587 indexIntoFileIter_ = indexIntoFile_.findRunPosition(run);
01588 if(indexIntoFileIter_ == indexIntoFileEnd_) return false;
01589 runTree_.setEntryNumber(indexIntoFileIter_.entry());
01590 return true;
01591 }
01592
01593 bool
01594 RootFile::setEntryAtNextEventInLumi(RunNumber_t run, LuminosityBlockNumber_t lumi) {
01595 if(indexIntoFileIter_.getEntryType() == IndexIntoFile::kEvent) {
01596 ++indexIntoFileIter_;
01597 }
01598 indexIntoFileIter_.advanceToEvent();
01599 if(indexIntoFileIter_.getEntryType() != IndexIntoFile::kEvent) return false;
01600 if(run != indexIntoFileIter_.run()) return false;
01601 if(lumi != indexIntoFileIter_.lumi()) return false;
01602 eventTree_.setEntryNumber(indexIntoFileIter_.entry());
01603 return true;
01604 }
01605
01606 void
01607 RootFile::overrideRunNumber(RunID& id) {
01608 if(forcedRunOffset_ != 0) {
01609 id = RunID(id.run() + forcedRunOffset_);
01610 }
01611 if(id < RunID::firstValidRun()) id = RunID::firstValidRun();
01612 }
01613
01614 void
01615 RootFile::overrideRunNumber(LuminosityBlockID& id) {
01616 if(forcedRunOffset_ != 0) {
01617 id = LuminosityBlockID(id.run() + forcedRunOffset_, id.luminosityBlock());
01618 }
01619 if(RunID(id.run()) < RunID::firstValidRun()) id = LuminosityBlockID(RunID::firstValidRun().run(), id.luminosityBlock());
01620 }
01621
01622 void
01623 RootFile::overrideRunNumber(EventID& id, bool isRealData) {
01624 if(forcedRunOffset_ != 0) {
01625 if(isRealData) {
01626 throw Exception(errors::Configuration, "RootFile::RootFile()")
01627 << "The 'setRunNumber' parameter of PoolSource cannot be used with real data.\n";
01628 }
01629 id = EventID(id.run() + forcedRunOffset_, id.luminosityBlock(), id.event());
01630 }
01631 if(RunID(id.run()) < RunID::firstValidRun()) {
01632 id = EventID(RunID::firstValidRun().run(), LuminosityBlockID::firstValidLuminosityBlock().luminosityBlock(), id.event());
01633 }
01634 }
01635
01636
01637 void
01638 RootFile::readEventHistoryTree() {
01639
01640 if(fileFormatVersion().eventHistoryTree()) {
01641 history_.reset(new History);
01642 eventHistoryTree_ = dynamic_cast<TTree*>(filePtr_->Get(poolNames::eventHistoryTreeName().c_str()));
01643 if(!eventHistoryTree_) {
01644 throw Exception(errors::EventCorruption)
01645 << "Failed to find the event history tree.\n";
01646 }
01647 }
01648 }
01649
01650 void
01651 RootFile::checkReleaseVersion() {
01652 std::string releaseVersion = getReleaseVersion();
01653 releaseversion::DecomposedReleaseVersion currentRelease(releaseVersion);
01654 for(ProcessConfigurationVector::const_iterator it = processConfigurations_.begin(), itEnd = processConfigurations_.end();
01655 it != itEnd; ++it) {
01656 if(releaseversion::isEarlierRelease(currentRelease, it->releaseVersion())) {
01657 throw Exception(errors::FormatIncompatibility)
01658 << "The release you are using, " << getReleaseVersion() << " , predates\n"
01659 << "a release (" << it->releaseVersion() << ") used in writing the input file, " << file() <<".\n"
01660 << "Forward compatibility cannot be supported.\n";
01661 }
01662 }
01663 }
01664
01665 void
01666 RootFile::initializeDuplicateChecker(
01667 std::vector<boost::shared_ptr<IndexIntoFile> > const& indexesIntoFiles,
01668 std::vector<boost::shared_ptr<IndexIntoFile> >::size_type currentIndexIntoFile) {
01669 if(duplicateChecker_) {
01670 if(eventTree_.next()) {
01671 fillThisEventAuxiliary();
01672 duplicateChecker_->inputFileOpened(eventAux().isRealData(),
01673 indexIntoFile_,
01674 indexesIntoFiles,
01675 currentIndexIntoFile);
01676 }
01677 eventTree_.setEntryNumber(-1);
01678 }
01679 }
01680
01681 void
01682 RootFile::dropOnInput (ProductRegistry& reg, GroupSelectorRules const& rules, bool dropDescendants, InputType::InputType inputType) {
01683
01684 GroupSelector groupSelector;
01685 groupSelector.initialize(rules, reg.allBranchDescriptions());
01686
01687 ProductRegistry::ProductList& prodList = reg.productListUpdator();
01688
01689 std::set<BranchID> branchesToDrop;
01690 for(ProductRegistry::ProductList::const_iterator it = prodList.begin(), itEnd = prodList.end();
01691 it != itEnd; ++it) {
01692 BranchDescription const& prod = it->second;
01693 if(!groupSelector.selected(prod)) {
01694 if(dropDescendants) {
01695 branchChildren_->appendToDescendants(prod.branchID(), branchesToDrop);
01696 } else {
01697 branchesToDrop.insert(prod.branchID());
01698 }
01699 }
01700 }
01701
01702
01703 std::set<BranchID>::const_iterator branchesToDropEnd = branchesToDrop.end();
01704 for(ProductRegistry::ProductList::iterator it = prodList.begin(), itEnd = prodList.end(); it != itEnd;) {
01705 BranchDescription const& prod = it->second;
01706 bool drop = branchesToDrop.find(prod.branchID()) != branchesToDropEnd;
01707 if(drop) {
01708 if(groupSelector.selected(prod)) {
01709 LogWarning("RootFile")
01710 << "Branch '" << prod.branchName() << "' is being dropped from the input\n"
01711 << "of file '" << file_ << "' because it is dependent on a branch\n"
01712 << "that was explicitly dropped.\n";
01713 }
01714 treePointers_[prod.branchType()]->dropBranch(newBranchToOldBranch(prod.branchName()));
01715 hasNewlyDroppedBranch_[prod.branchType()] = true;
01716 ProductRegistry::ProductList::iterator icopy = it;
01717 ++it;
01718 prodList.erase(icopy);
01719 } else {
01720 ++it;
01721 }
01722 }
01723
01724
01725 if(inputType == InputType::SecondaryFile) {
01726 TString tString;
01727 for(ProductRegistry::ProductList::iterator it = prodList.begin(), itEnd = prodList.end(); it != itEnd;) {
01728 BranchDescription const& prod = it->second;
01729 if(prod.branchType() != InEvent) {
01730 TClass *cp = gROOT->GetClass(prod.wrappedName().c_str());
01731 WrapperOwningHolder edp(cp->New(), prod.getInterface());
01732 if(edp.isMergeable()) {
01733 treePointers_[prod.branchType()]->dropBranch(newBranchToOldBranch(prod.branchName()));
01734 ProductRegistry::ProductList::iterator icopy = it;
01735 ++it;
01736 prodList.erase(icopy);
01737 } else {
01738 ++it;
01739 }
01740 }
01741 else ++it;
01742 }
01743 }
01744 }
01745
01746 std::unique_ptr<MakeProvenanceReader>
01747 RootFile::makeProvenanceReaderMaker() const {
01748 if(fileFormatVersion_.storedProductProvenanceUsed()) {
01749 return std::unique_ptr<MakeProvenanceReader>(new MakeReducedProvenanceReader(parentageIDLookup_));
01750 } else if(fileFormatVersion_.splitProductIDs()) {
01751 return std::unique_ptr<MakeProvenanceReader>(new MakeFullProvenanceReader);
01752 } else if(fileFormatVersion_.perEventProductIDs()) {
01753 return std::unique_ptr<MakeProvenanceReader>(new MakeOldProvenanceReader);
01754 } else {
01755 return std::unique_ptr<MakeProvenanceReader>(new MakeDummyProvenanceReader);
01756 }
01757 }
01758
01759 boost::shared_ptr<BranchMapper>
01760 RootFile::makeBranchMapper() {
01761 if(!eventBranchMapper_) {
01762 eventBranchMapper_.reset(new BranchMapper(provenanceReaderMaker_->makeReader(eventTree_, daqProvenanceHelper_.get())));
01763 }
01764 eventBranchMapper_->reset();
01765 return eventBranchMapper_;
01766 }
01767
01768 class ReducedProvenanceReader : public ProvenanceReaderBase {
01769 public:
01770 ReducedProvenanceReader(RootTree* iRootTree, std::vector<ParentageID> const& iParentageIDLookup, DaqProvenanceHelper const* daqProvenanceHelper);
01771 private:
01772 virtual void readProvenance(BranchMapper const& mapper) const;
01773 RootTree* rootTree_;
01774 TBranch* provBranch_;
01775 StoredProductProvenanceVector provVector_;
01776 StoredProductProvenanceVector* pProvVector_;
01777 std::vector<ParentageID> const& parentageIDLookup_;
01778 DaqProvenanceHelper const* daqProvenanceHelper_;
01779 };
01780
01781 ReducedProvenanceReader::ReducedProvenanceReader(
01782 RootTree* iRootTree,
01783 std::vector<ParentageID> const& iParentageIDLookup,
01784 DaqProvenanceHelper const* daqProvenanceHelper) :
01785 ProvenanceReaderBase(),
01786 rootTree_(iRootTree),
01787 pProvVector_(&provVector_),
01788 parentageIDLookup_(iParentageIDLookup),
01789 daqProvenanceHelper_(daqProvenanceHelper) {
01790 provBranch_ = rootTree_->tree()->GetBranch(BranchTypeToProductProvenanceBranchName(rootTree_->branchType()).c_str());
01791 }
01792
01793 void
01794 ReducedProvenanceReader::readProvenance(BranchMapper const& mapper) const {
01795 ReducedProvenanceReader* me = const_cast<ReducedProvenanceReader*>(this);
01796 me->rootTree_->fillBranchEntry(me->provBranch_, me->pProvVector_);
01797 setRefCoreStreamer(true);
01798 if(daqProvenanceHelper_) {
01799 for(StoredProductProvenanceVector::const_iterator it = provVector_.begin(), itEnd = provVector_.end();
01800 it != itEnd; ++it) {
01801 BranchID bid(it->branchID_);
01802 mapper.insertIntoSet(ProductProvenance(daqProvenanceHelper_->mapBranchID(BranchID(it->branchID_)),
01803 daqProvenanceHelper_->mapParentageID(parentageIDLookup_[it->parentageIDIndex_])));
01804 }
01805 } else {
01806 for(StoredProductProvenanceVector::const_iterator it = provVector_.begin(), itEnd = provVector_.end();
01807 it != itEnd; ++it) {
01808 if(it->parentageIDIndex_ >= parentageIDLookup_.size()) {
01809 throw edm::Exception(errors::LogicError)
01810 << "ReducedProvenanceReader::ReadProvenance\n"
01811 << "The parentage ID index value " << it->parentageIDIndex_ << " is out of bounds. The maximum value is " << parentageIDLookup_.size()-1 << ".\n"
01812 << "This should never happen.\n"
01813 << "Please report this to the framework hypernews forum 'hn-cms-edmFramework@cern.ch'.\n";
01814 }
01815 mapper.insertIntoSet(ProductProvenance(BranchID(it->branchID_), parentageIDLookup_[it->parentageIDIndex_]));
01816 }
01817 }
01818 }
01819
01820 class FullProvenanceReader : public ProvenanceReaderBase {
01821 public:
01822 explicit FullProvenanceReader(RootTree* rootTree, DaqProvenanceHelper const* daqProvenanceHelper);
01823 virtual ~FullProvenanceReader() {}
01824 private:
01825 virtual void readProvenance(BranchMapper const& mapper) const;
01826 RootTree* rootTree_;
01827 ProductProvenanceVector infoVector_;
01828 mutable ProductProvenanceVector* pInfoVector_;
01829 DaqProvenanceHelper const* daqProvenanceHelper_;
01830 };
01831
01832 FullProvenanceReader::FullProvenanceReader(RootTree* rootTree, DaqProvenanceHelper const* daqProvenanceHelper) :
01833 ProvenanceReaderBase(),
01834 rootTree_(rootTree),
01835 infoVector_(),
01836 pInfoVector_(&infoVector_),
01837 daqProvenanceHelper_(daqProvenanceHelper) {
01838 }
01839
01840 void
01841 FullProvenanceReader::readProvenance(BranchMapper const& mapper) const {
01842 rootTree_->fillBranchEntryMeta(rootTree_->branchEntryInfoBranch(), pInfoVector_);
01843 setRefCoreStreamer(true);
01844 if(daqProvenanceHelper_) {
01845 for(ProductProvenanceVector::const_iterator it = infoVector_.begin(), itEnd = infoVector_.end();
01846 it != itEnd; ++it) {
01847 mapper.insertIntoSet(ProductProvenance(daqProvenanceHelper_->mapBranchID(it->branchID()),
01848 daqProvenanceHelper_->mapParentageID(it->parentageID())));
01849 }
01850 } else {
01851 for(ProductProvenanceVector::const_iterator it = infoVector_.begin(), itEnd = infoVector_.end();
01852 it != itEnd; ++it) {
01853 mapper.insertIntoSet(*it);
01854 }
01855 }
01856 }
01857
01858 class OldProvenanceReader : public ProvenanceReaderBase {
01859 public:
01860 explicit OldProvenanceReader(RootTree* rootTree, DaqProvenanceHelper const* daqProvenanceHelper);
01861 virtual ~OldProvenanceReader() {}
01862 private:
01863 virtual void readProvenance(BranchMapper const& mapper) const;
01864 RootTree* rootTree_;
01865 std::vector<EventEntryInfo> infoVector_;
01866 mutable std::vector<EventEntryInfo> *pInfoVector_;
01867 DaqProvenanceHelper const* daqProvenanceHelper_;
01868 };
01869
01870 OldProvenanceReader::OldProvenanceReader(RootTree* rootTree, DaqProvenanceHelper const* daqProvenanceHelper) :
01871 ProvenanceReaderBase(),
01872 rootTree_(rootTree),
01873 infoVector_(),
01874 pInfoVector_(&infoVector_),
01875 daqProvenanceHelper_(daqProvenanceHelper) {
01876 }
01877
01878 void
01879 OldProvenanceReader::readProvenance(BranchMapper const& mapper) const {
01880 rootTree_->branchEntryInfoBranch()->SetAddress(&pInfoVector_);
01881 roottree::getEntry(rootTree_->branchEntryInfoBranch(), rootTree_->entryNumber());
01882 setRefCoreStreamer(true);
01883 for(std::vector<EventEntryInfo>::const_iterator it = infoVector_.begin(), itEnd = infoVector_.end();
01884 it != itEnd; ++it) {
01885 EventEntryDescription eed;
01886 EntryDescriptionRegistry::instance()->getMapped(it->entryDescriptionID(), eed);
01887 Parentage parentage(eed.parents());
01888 if(daqProvenanceHelper_) {
01889 ProductProvenance entry(daqProvenanceHelper_->mapBranchID(it->branchID()),
01890 daqProvenanceHelper_->mapParentageID(parentage.id()));
01891 mapper.insertIntoSet(entry);
01892 } else {
01893 ProductProvenance entry(it->branchID(), parentage.id());
01894 mapper.insertIntoSet(entry);
01895 }
01896
01897 }
01898 }
01899
01900 class DummyProvenanceReader : public ProvenanceReaderBase {
01901 public:
01902 DummyProvenanceReader();
01903 virtual ~DummyProvenanceReader() {}
01904 private:
01905 virtual void readProvenance(BranchMapper const& mapper) const;
01906 };
01907
01908 DummyProvenanceReader::DummyProvenanceReader() :
01909 ProvenanceReaderBase() {
01910 }
01911
01912 void
01913 DummyProvenanceReader::readProvenance(BranchMapper const&) const {
01914
01915 }
01916
01917 std::unique_ptr<ProvenanceReaderBase>
01918 MakeDummyProvenanceReader::makeReader(RootTree&, DaqProvenanceHelper const*) const {
01919 return std::unique_ptr<ProvenanceReaderBase>(new DummyProvenanceReader);
01920 }
01921
01922 std::unique_ptr<ProvenanceReaderBase>
01923 MakeOldProvenanceReader::makeReader(RootTree& rootTree, DaqProvenanceHelper const* daqProvenanceHelper) const {
01924 return std::unique_ptr<ProvenanceReaderBase>(new OldProvenanceReader(&rootTree, daqProvenanceHelper));
01925 }
01926
01927 std::unique_ptr<ProvenanceReaderBase>
01928 MakeFullProvenanceReader::makeReader(RootTree& rootTree, DaqProvenanceHelper const* daqProvenanceHelper) const {
01929 return std::unique_ptr<ProvenanceReaderBase>(new FullProvenanceReader(&rootTree, daqProvenanceHelper));
01930 }
01931
01932 std::unique_ptr<ProvenanceReaderBase>
01933 MakeReducedProvenanceReader::makeReader(RootTree& rootTree, DaqProvenanceHelper const* daqProvenanceHelper) const {
01934 return std::unique_ptr<ProvenanceReaderBase>(new ReducedProvenanceReader(&rootTree, parentageIDLookup_, daqProvenanceHelper));
01935 }
01936 }