00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "TFile.h"
00016 #include "TTree.h"
00017 #include "TChain.h"
00018 #include "TBranch.h"
00019 #include "TClass.h"
00020 #include "Reflex/Type.h"
00021
00022 #include "FWCore/TFWLiteSelector/interface/TFWLiteSelectorBasic.h"
00023
00024 #include "DataFormats/Provenance/interface/BranchType.h"
00025 #include "DataFormats/Provenance/interface/BranchDescription.h"
00026 #include "DataFormats/Provenance/interface/ProductRegistry.h"
00027 #include "DataFormats/Provenance/interface/EventAuxiliary.h"
00028 #include "DataFormats/Provenance/interface/EventEntryDescription.h"
00029 #include "DataFormats/Provenance/interface/EventSelectionID.h"
00030 #include "DataFormats/Provenance/interface/BranchListIndex.h"
00031 #include "DataFormats/Provenance/interface/LuminosityBlockAuxiliary.h"
00032 #include "DataFormats/Provenance/interface/RunAuxiliary.h"
00033 #include "DataFormats/Provenance/interface/FileFormatVersion.h"
00034 #include "DataFormats/Common/interface/EDProduct.h"
00035 #include "FWCore/Utilities/interface/WrappedClassName.h"
00036 #include "FWCore/Utilities/interface/EDMException.h"
00037 #include "FWCore/Utilities/interface/FriendlyName.h"
00038 #include "FWCore/Framework/interface/DelayedReader.h"
00039 #include "DataFormats/Provenance/interface/ProcessConfiguration.h"
00040 #include "DataFormats/Provenance/interface/ProcessHistory.h"
00041 #include "DataFormats/Provenance/interface/BranchMapper.h"
00042 #include "FWCore/Framework/interface/Event.h"
00043 #include "FWCore/Framework/interface/EventPrincipal.h"
00044 #include "FWCore/Framework/interface/LuminosityBlockPrincipal.h"
00045 #include "DataFormats/Provenance/interface/ProcessHistoryRegistry.h"
00046 #include "DataFormats/Provenance/interface/BranchIDListRegistry.h"
00047 #include "DataFormats/Provenance/interface/ParameterSetBlob.h"
00048 #include "DataFormats/Provenance/interface/ModuleDescription.h"
00049 #include "FWCore/ParameterSet/interface/Registry.h"
00050 #include "FWCore/ParameterSet/interface/FillProductRegistryTransients.h"
00051 #include "FWCore/Framework/interface/RunPrincipal.h"
00052 #include "DataFormats/Common/interface/RefCoreStreamer.h"
00053
00054 namespace edm {
00055 namespace root {
00056 class FWLiteDelayedReader : public DelayedReader {
00057 public:
00058 FWLiteDelayedReader(): entry_(-1),eventTree_(0),reg_() {}
00059 void setEntry(Long64_t iEntry) { entry_ = iEntry; }
00060 void setTree(TTree* iTree) {eventTree_ = iTree;}
00061 void set(boost::shared_ptr<ProductRegistry const> iReg) { reg_ = iReg;}
00062 private:
00063 virtual std::auto_ptr<EDProduct> getProduct_(BranchKey const& k, EDProductGetter const* ep) const;
00064 virtual std::auto_ptr<EventEntryDescription> getProvenance_(BranchKey const&) const {
00065 return std::auto_ptr<EventEntryDescription>();
00066 }
00067 Long64_t entry_;
00068 TTree* eventTree_;
00069 boost::shared_ptr<ProductRegistry const>(reg_);
00070 };
00071
00072 std::auto_ptr<EDProduct>
00073 FWLiteDelayedReader::getProduct_(BranchKey const& k, EDProductGetter const* ep) const {
00074 ProductRegistry::ProductList::const_iterator itFind= reg_->productList().find(k);
00075 if(itFind == reg_->productList().end()) {
00076 throw Exception(errors::ProductNotFound)<<"could not find entry for product "<<k;
00077 }
00078 BranchDescription const& bDesc = itFind->second;
00079
00080 TBranch* branch= eventTree_->GetBranch(bDesc.branchName().c_str());
00081 if(0 == branch) {
00082 throw cms::Exception("MissingBranch")
00083 <<"could not find branch named '"<<bDesc.branchName()<<"'"
00084 <<"\n Perhaps the data being requested was not saved in this file?";
00085 }
00086
00087 std::string const fullName = wrappedClassName(bDesc.className());
00088 Reflex::Type classType = Reflex::Type::ByName(fullName);
00089 if(classType == Reflex::Type()) {
00090 throw cms::Exception("MissingDictionary")
00091 <<"could not find dictionary for type '"<<fullName<<"'"
00092 <<"\n Please make sure all the necessary libraries are available.";
00093 return std::auto_ptr<EDProduct>();
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 TClass* rootClassType=TClass::GetClass(classType.TypeInfo());
00106 if(0 == rootClassType) {
00107 throw cms::Exception("MissingRootDictionary")
00108 <<"could not find a ROOT dictionary for type '"<<fullName<<"'"
00109 <<"\n Please make sure all the necessary libraries are available.";
00110 return std::auto_ptr<EDProduct>();
00111 }
00112 void* address = rootClassType->New();
00113 branch->SetAddress(&address);
00114
00115
00116
00117
00118
00119
00120 static TClass* edproductTClass = TClass::GetClass(typeid(EDProduct));
00121 EDProduct* prod = reinterpret_cast<EDProduct*>(rootClassType->DynamicCast(edproductTClass,address,true));
00122
00123 if(0 == prod) {
00124 throw cms::Exception("FailedConversion")
00125 << "failed to convert a '" << fullName
00126 << "' to a edm::EDProduct."
00127 << "Please contact developers since something is very wrong.";
00128 }
00129 branch->GetEntry(entry_);
00130 return std::auto_ptr<EDProduct>(prod);
00131 }
00132
00133 struct TFWLiteSelectorMembers {
00134 TFWLiteSelectorMembers():
00135 tree_(0),
00136 metaTree_(0),
00137 reg_(new ProductRegistry()),
00138 processNames_(),
00139 reader_(new FWLiteDelayedReader),
00140 productMap_(),
00141 prov_(),
00142 pointerToBranchBuffer_()
00143 {
00144 reader_->set(reg_);}
00145 void setTree(TTree* iTree) {
00146 tree_ = iTree;
00147 reader_->setTree(iTree);
00148 }
00149 void setMetaTree(TTree* iTree) {
00150 metaTree_ = iTree;
00151 }
00152 TTree* tree_;
00153 TTree* metaTree_;
00154 boost::shared_ptr<ProductRegistry> reg_;
00155 ProcessHistory processNames_;
00156 boost::shared_ptr<FWLiteDelayedReader> reader_;
00157 typedef std::map<ProductID, BranchDescription> ProductMap;
00158 ProductMap productMap_;
00159 std::vector<EventEntryDescription> prov_;
00160 std::vector<EventEntryDescription*> pointerToBranchBuffer_;
00161 FileFormatVersion fileFormatVersion_;
00162 };
00163 }
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 TFWLiteSelectorBasic::TFWLiteSelectorBasic() : m_(new edm::root::TFWLiteSelectorMembers),
00179 everythingOK_(false) {
00180 }
00181
00182
00183
00184
00185
00186
00187 TFWLiteSelectorBasic::~TFWLiteSelectorBasic()
00188 {
00189 }
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 void
00207 TFWLiteSelectorBasic::Begin(TTree * iTree) {
00208 Init(iTree);
00209 begin(fInput);
00210 }
00211
00212 void
00213 TFWLiteSelectorBasic::SlaveBegin(TTree *iTree) {
00214 Init(iTree);
00215 preProcessing(fInput,*fOutput);
00216 }
00217
00218 void
00219 TFWLiteSelectorBasic::Init(TTree *iTree) {
00220 if(iTree==0) return;
00221 m_->setTree(iTree);
00222 }
00223
00224
00225 Bool_t
00226 TFWLiteSelectorBasic::Notify() {
00227
00228
00229
00230 if(0==m_->tree_) {
00231 std::cout <<"No tree"<<std::endl;
00232 return kFALSE;
00233 }
00234 TFile* file = m_->tree_->GetCurrentFile();
00235 if(0 == file) {
00236
00237 TChain* chain = dynamic_cast<TChain*>(m_->tree_);
00238 if(0 == chain) {
00239 std::cout <<"No file"<<std::endl;
00240 return kFALSE;
00241 }
00242 file = chain->GetFile();
00243 if(0==file) {
00244 std::cout <<"No file"<<std::endl;
00245 return kFALSE;
00246 }
00247 }
00248 setupNewFile(*file);
00249 return everythingOK_ ? kTRUE: kFALSE;
00250 }
00251
00252 namespace {
00253 struct Operate {
00254 Operate(edm::EDProductGetter const* iGetter): old_(setRefCoreStreamer(iGetter)) {
00255 }
00256
00257 ~Operate() {setRefCoreStreamer(old_);}
00258 private:
00259 edm::EDProductGetter const* old_;
00260 };
00261 }
00262
00263 Bool_t
00264 TFWLiteSelectorBasic::Process(Long64_t iEntry) {
00265
00266 if(everythingOK_) {
00267 std::auto_ptr<edm::EventAuxiliary> eaux(new edm::EventAuxiliary());
00268 edm::EventAuxiliary& aux = *eaux;
00269 edm::EventAuxiliary* pAux= eaux.get();
00270 TBranch* branch = m_->tree_->GetBranch(edm::BranchTypeToAuxiliaryBranchName(edm::InEvent).c_str());
00271
00272 branch->SetAddress(&pAux);
00273 branch->GetEntry(iEntry);
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 boost::shared_ptr<edm::EventSelectionIDVector> eventSelectionIDs_(new edm::EventSelectionIDVector);
00286 edm::EventSelectionIDVector* pEventSelectionIDVector = eventSelectionIDs_.get();
00287 TBranch* eventSelectionsBranch = m_->tree_->GetBranch(edm::poolNames::eventSelectionsBranchName().c_str());
00288 if (!eventSelectionsBranch) {
00289 throw edm::Exception(edm::errors::FatalRootError)
00290 << "Failed to find event Selections branch in event tree";
00291 }
00292 eventSelectionsBranch->SetAddress(&pEventSelectionIDVector);
00293 eventSelectionsBranch->GetEntry(iEntry);
00294
00295 boost::shared_ptr<edm::BranchListIndexes> branchListIndexes_(new edm::BranchListIndexes);
00296 edm::BranchListIndexes* pBranchListIndexes = branchListIndexes_.get();
00297 TBranch* branchListIndexBranch = m_->tree_->GetBranch(edm::poolNames::branchListIndexesBranchName().c_str());
00298 if (!branchListIndexBranch) {
00299 throw edm::Exception(edm::errors::FatalRootError)
00300 << "Failed to find branch list index branch in event tree";
00301 }
00302 branchListIndexBranch->SetAddress(&pBranchListIndexes);
00303 branchListIndexBranch->GetEntry(iEntry);
00304
00305 try {
00306 m_->reader_->setEntry(iEntry);
00307 edm::ProcessConfiguration pc;
00308 boost::shared_ptr<edm::ProductRegistry const> reg(m_->reg_);
00309 boost::shared_ptr<edm::RunAuxiliary> runAux(new edm::RunAuxiliary(aux.run(), aux.time(), aux.time()));
00310 boost::shared_ptr<edm::RunPrincipal> rp(new edm::RunPrincipal(runAux, reg, pc));
00311 boost::shared_ptr<edm::LuminosityBlockAuxiliary> lumiAux(
00312 new edm::LuminosityBlockAuxiliary(rp->run(), 1, aux.time(), aux.time()));
00313 boost::shared_ptr<edm::LuminosityBlockPrincipal>lbp(
00314 new edm::LuminosityBlockPrincipal(lumiAux, reg, pc, rp));
00315 boost::shared_ptr<edm::BranchMapper> mapper(new edm::BranchMapper);
00316 edm::EventPrincipal ep(reg, pc);
00317 ep.fillEventPrincipal(eaux, lbp, eventSelectionIDs_, branchListIndexes_, mapper, m_->reader_);
00318 m_->processNames_ = ep.processHistory();
00319
00320 edm::ModuleDescription md;
00321 edm::Event event(ep,md);
00322
00323
00324 Operate sentry(ep.prodGetter());
00325 process(event);
00326 } catch(std::exception const& iEx) {
00327 std::cout << "While processing entry "<<iEntry<<" the following exception was caught \n"
00328 << iEx.what() << std::endl;
00329 } catch(...) {
00330 std::cout <<"While processing entry "<<iEntry<<" an unknown exception was caught" << std::endl;
00331 }
00332 }
00333 return kTRUE;
00334 }
00335
00336 void
00337 TFWLiteSelectorBasic::SlaveTerminate() {
00338 postProcessing(*fOutput);
00339 }
00340
00341 void
00342 TFWLiteSelectorBasic::Terminate() {
00343 terminate(*fOutput);
00344 }
00345
00346 void
00347 TFWLiteSelectorBasic::setupNewFile(TFile& iFile) {
00348
00349
00350
00351
00352 TTree* metaDataTree = dynamic_cast<TTree*>(iFile.Get(edm::poolNames::metaDataTreeName().c_str()));
00353 if (!metaDataTree) {
00354 std::cout <<"could not find TTree "<<edm::poolNames::metaDataTreeName() <<std::endl;
00355 everythingOK_ = false;
00356 return;
00357 }
00358 edm::FileFormatVersion* fftPtr = &(m_->fileFormatVersion_);
00359 if(metaDataTree->FindBranch(edm::poolNames::fileFormatVersionBranchName().c_str()) != 0) {
00360 metaDataTree->SetBranchAddress(edm::poolNames::fileFormatVersionBranchName().c_str(), &fftPtr);
00361 }
00362
00363
00364 edm::ProductRegistry* pReg = &(*m_->reg_);
00365 metaDataTree->SetBranchAddress(edm::poolNames::productDescriptionBranchName().c_str(), &(pReg));
00366
00367 m_->reg_->setFrozen();
00368 typedef std::map<edm::ParameterSetID, edm::ParameterSetBlob> PsetMap;
00369 PsetMap psetMap;
00370 PsetMap *psetMapPtr = &psetMap;
00371 if(metaDataTree->FindBranch(edm::poolNames::parameterSetMapBranchName().c_str()) != 0) {
00372 metaDataTree->SetBranchAddress(edm::poolNames::parameterSetMapBranchName().c_str(), &psetMapPtr);
00373 } else {
00374 TTree* psetTree = dynamic_cast<TTree *>(iFile.Get(edm::poolNames::parameterSetsTreeName().c_str()));
00375 if(0==psetTree) {
00376 throw edm::Exception(edm::errors::FileReadError) << "Could not find tree " << edm::poolNames::parameterSetsTreeName()
00377 << " in the input file.\n";
00378 }
00379 typedef std::pair<edm::ParameterSetID, edm::ParameterSetBlob> IdToBlobs;
00380 IdToBlobs idToBlob;
00381 IdToBlobs* pIdToBlob = &idToBlob;
00382 psetTree->SetBranchAddress(edm::poolNames::idToParameterSetBlobsBranchName().c_str(), &pIdToBlob);
00383 for(long long i = 0; i != psetTree->GetEntries(); ++i) {
00384 psetTree->GetEntry(i);
00385 psetMap.insert(idToBlob);
00386 }
00387 }
00388
00389 edm::ProcessHistoryRegistry::vector_type pHistVector;
00390 edm::ProcessHistoryRegistry::vector_type *pHistVectorPtr = &pHistVector;
00391 if(metaDataTree->FindBranch(edm::poolNames::processHistoryBranchName().c_str()) != 0) {
00392 metaDataTree->SetBranchAddress(edm::poolNames::processHistoryBranchName().c_str(), &pHistVectorPtr);
00393 }
00394
00395
00396 edm::ProcessConfigurationVector procConfigVector;
00397 edm::ProcessConfigurationVector * procConfigVectorPtr=&procConfigVector;
00398 if(metaDataTree->FindBranch(edm::poolNames::processConfigurationBranchName().c_str()) != 0) {
00399 metaDataTree->SetBranchAddress(edm::poolNames::processConfigurationBranchName().c_str(), &procConfigVectorPtr);
00400 }
00401
00402 std::auto_ptr<edm::BranchIDListRegistry::collection_type> branchIDListsAPtr(new edm::BranchIDListRegistry::collection_type);
00403 edm::BranchIDListRegistry::collection_type *branchIDListsPtr = branchIDListsAPtr.get();
00404 if(metaDataTree->FindBranch(edm::poolNames::branchIDListBranchName().c_str()) != 0) {
00405 metaDataTree->SetBranchAddress(edm::poolNames::branchIDListBranchName().c_str(), &branchIDListsPtr);
00406 }
00407
00408 metaDataTree->GetEntry(0);
00409
00410 m_->metaTree_ = dynamic_cast<TTree*>(iFile.Get(edm::poolNames::eventMetaDataTreeName().c_str()));
00411
00412 if(0 == m_->metaTree_) {
00413 std::cout <<"could not find TTree "<<edm::poolNames::eventMetaDataTreeName() <<std::endl;
00414 everythingOK_ = false;
00415 return;
00416 }
00417
00418
00419 edm::pset::Registry& psetRegistry = *edm::pset::Registry::instance();
00420 for (PsetMap::const_iterator i = psetMap.begin(), iEnd = psetMap.end();
00421 i != iEnd; ++i) {
00422 edm::ParameterSet pset(i->second.pset());
00423 pset.setID(i->first);
00424 psetRegistry.insertMapped(pset);
00425 }
00426
00427 edm::ProcessHistoryRegistry::instance()->insertCollection(pHistVector);
00428 edm::ProcessConfigurationRegistry::instance()->insertCollection(procConfigVector);
00429
00430 m_->productMap_.erase(m_->productMap_.begin(),m_->productMap_.end());
00431 m_->pointerToBranchBuffer_.erase(m_->pointerToBranchBuffer_.begin(),
00432 m_->pointerToBranchBuffer_.end());
00433
00434 fillProductRegistryTransients(procConfigVector,*m_->reg_);
00435 std::auto_ptr<edm::ProductRegistry> newReg(new edm::ProductRegistry());
00436
00437
00438 edm::ProductRegistry::ProductList const& prodList = m_->reg_->productList();
00439 {
00440 for(edm::ProductRegistry::ProductList::const_iterator it = prodList.begin(), itEnd = prodList.end();
00441 it != itEnd; ++it) {
00442 edm::BranchDescription const& prod = it->second;
00443
00444 std::string newFriendlyName = edm::friendlyname::friendlyName(prod.className());
00445 if(newFriendlyName == prod.friendlyClassName()) {
00446 newReg->copyProduct(prod);
00447 } else {
00448
00449 if(m_->fileFormatVersion_.splitProductIDs()) {
00450 throw edm::Exception(edm::errors::UnimplementedFeature)
00451 << "Cannot change friendly class name algorithm without more development work\n"
00452 << "to update BranchIDLists. Contact the framework group.\n";
00453 }
00454 edm::BranchDescription newBD(prod);
00455 newBD.updateFriendlyClassName();
00456 newReg->copyProduct(newBD);
00457
00458 prod.init();
00459 }
00460 }
00461
00462 newReg->setFrozen();
00463 m_->reg_.reset(newReg.release());
00464 }
00465
00466 edm::ProductRegistry::ProductList const& prodList2 = m_->reg_->productList();
00467 std::vector<edm::EventEntryDescription> temp(prodList2.size(), edm::EventEntryDescription());
00468 m_->prov_.swap(temp);
00469 std::vector<edm::EventEntryDescription>::iterator itB = m_->prov_.begin();
00470 m_->pointerToBranchBuffer_.reserve(prodList2.size());
00471
00472 for (edm::ProductRegistry::ProductList::const_iterator it = prodList2.begin(), itEnd = prodList2.end();
00473 it != itEnd; ++it, ++itB) {
00474 edm::BranchDescription const& prod = it->second;
00475 if(prod.branchType() == edm::InEvent) {
00476 prod.init();
00477
00478 if (m_->tree_->GetBranch(prod.branchName().c_str())==0) {
00479 prod.setDropped();
00480 }
00481 m_->productMap_.insert(std::make_pair(it->second.oldProductID(), it->second));
00482
00483
00484
00485
00486
00487
00488
00489 }
00490 }
00491
00492 everythingOK_ = true;
00493 }
00494
00495
00496
00497
00498
00499
00500
00501