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