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