CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/FWCore/TFWLiteSelector/src/TFWLiteSelectorBasic.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //
00004 // Package:     TFWLiteSelector
00005 // Class  :     TFWLiteSelectorBasic
00006 //
00007 // Implementation:
00008 //     <Notes on implementation>
00009 //
00010 // Original Author:  Chris Jones
00011 //         Created:  Tue Jun 27 17:58:10 EDT 2006
00012 //
00013 
00014 // system include files
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 // user include files
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" // kludge to allow compilation
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       //find the class type
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       //use reflex to create an instance of it
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 // constants, enums and typedefs
00156 //
00157 
00158 //
00159 // static data member definitions
00160 //
00161 
00162 //
00163 // constructors and destructor
00164 //
00165 TFWLiteSelectorBasic::TFWLiteSelectorBasic() : m_(new edm::root::TFWLiteSelectorMembers),
00166                                      everythingOK_(false) {
00167 }
00168 
00169 // TFWLiteSelectorBasic::TFWLiteSelectorBasic(TFWLiteSelectorBasic const& rhs)
00170 // {
00171 //    // do actual copying here;
00172 // }
00173 
00174 TFWLiteSelectorBasic::~TFWLiteSelectorBasic()
00175 {
00176 }
00177 
00178 //
00179 // assignment operators
00180 //
00181 // TFWLiteSelectorBasic const& TFWLiteSelectorBasic::operator=(TFWLiteSelectorBasic const& rhs)
00182 // {
00183 //   //An exception safe implementation is
00184 //   TFWLiteSelectorBasic temp(rhs);
00185 //   swap(rhs);
00186 //
00187 //   return *this;
00188 // }
00189 
00190 //
00191 // member functions
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   //std::cout <<"Notify start"<<std::endl;
00215   //we have switched to a new file
00216   //get new file from Tree
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      //When in Rome, do as the Romans
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    //std::cout <<"Process start"<<std::endl;
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 //NEW      m_->processNames_ = aux.processHistory();
00263 
00264 //      std::cout <<"ProcessNames\n";
00265 //      for(edm::ProcessNameList::const_iterator itName = m_->processNames_.begin(),
00266 //        itNameEnd = m_->processNames_.end();
00267 //          itName != itNameEnd;
00268 //          ++itName) {
00269 //         std::cout <<"  "<<*itName<< std::endl;
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          //Make the event principal accessible to edm::Ref's
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   //look up meta-data
00331   //get product registry
00332 
00333   //std::vector<edm::EventProcessHistoryID> eventProcessHistoryIDs_;
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   // Merge into the registries. For now, we do NOT merge the product registry.
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          //std::cout << "productname = "<<it->second<<" end "<<std::endl;
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            // Need to call init to get old branch name.
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       //NEED to do this and check to see if branch exists
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       //std::cout <<"id "<<it->first<<" branch "<<it->second<<std::endl;
00459       //m_->pointerToBranchBuffer_.push_back(& (*itB));
00460       //void* tmp = &(m_->pointerToBranchBuffer_.back());
00461       //edm::EventEntryDescription* tmp = & (*itB);
00462       //CDJ need to fix provenance and be backwards compatible, for now just don't read the branch
00463       //m_->metaTree_->SetBranchAddress(prod.branchName().c_str(), tmp);
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 // const member functions
00473 //
00474 
00475 //
00476 // static member functions
00477 //