CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/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/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       //find the class type
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       //We can't use reflex to create the instance since Reflex uses 'malloc' instead of new
00097       /*
00098       //use reflex to create an instance of it
00099       Reflex::Object wrapperObj = classType.Construct();
00100       if(0 == wrapperObj.Address()) {
00101         throw cms::Exception("FailedToCreate") <<"could not create an instance of '"<<fullName<<"'";
00102       }
00103       void* address  = wrapperObj.Address();
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       Reflex::Object edProdObj = wrapperObj.CastObject(Reflex::Type::ByName("edm::EDProduct"));
00117 
00118       EDProduct* prod = reinterpret_cast<EDProduct*>(edProdObj.Address());
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 // constants, enums and typedefs
00169 //
00170 
00171 //
00172 // static data member definitions
00173 //
00174 
00175 //
00176 // constructors and destructor
00177 //
00178 TFWLiteSelectorBasic::TFWLiteSelectorBasic() : m_(new edm::root::TFWLiteSelectorMembers),
00179                                      everythingOK_(false) {
00180 }
00181 
00182 // TFWLiteSelectorBasic::TFWLiteSelectorBasic(TFWLiteSelectorBasic const& rhs)
00183 // {
00184 //    // do actual copying here;
00185 // }
00186 
00187 TFWLiteSelectorBasic::~TFWLiteSelectorBasic()
00188 {
00189 }
00190 
00191 //
00192 // assignment operators
00193 //
00194 // TFWLiteSelectorBasic const& TFWLiteSelectorBasic::operator=(TFWLiteSelectorBasic const& rhs)
00195 // {
00196 //   //An exception safe implementation is
00197 //   TFWLiteSelectorBasic temp(rhs);
00198 //   swap(rhs);
00199 //
00200 //   return *this;
00201 // }
00202 
00203 //
00204 // member functions
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   //std::cout <<"Notify start"<<std::endl;
00228   //we have switched to a new file
00229   //get new file from Tree
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      //When in Rome, do as the Romans
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    //std::cout <<"Process start"<<std::endl;
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 //NEW      m_->processNames_ = aux.processHistory();
00276 
00277 //      std::cout <<"ProcessNames\n";
00278 //      for(edm::ProcessNameList::const_iterator itName = m_->processNames_.begin(),
00279 //        itNameEnd = m_->processNames_.end();
00280 //          itName != itNameEnd;
00281 //          ++itName) {
00282 //         std::cout <<"  "<<*itName<< std::endl;
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          //Make the event principal accessible to edm::Ref's
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   //look up meta-data
00349   //get product registry
00350 
00351   //std::vector<edm::EventProcessHistoryID> eventProcessHistoryIDs_;
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       //provBranch->GetEntry(iEntry);
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   // Merge into the registries. For now, we do NOT merge the product registry.
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          //std::cout << "productname = "<<it->second<<" end "<<std::endl;
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            // Need to call init to get old branch name.
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       //NEED to do this and check to see if branch exists
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       //std::cout <<"id "<<it->first<<" branch "<<it->second<<std::endl;
00484       //m_->pointerToBranchBuffer_.push_back(& (*itB));
00485       //void* tmp = &(m_->pointerToBranchBuffer_.back());
00486       //edm::EventEntryDescription* tmp = & (*itB);
00487       //CDJ need to fix provenance and be backwards compatible, for now just don't read the branch
00488       //m_->metaTree_->SetBranchAddress(prod.branchName().c_str(), tmp);
00489     }
00490   }
00491 
00492   everythingOK_ = true;
00493 }
00494 
00495 //
00496 // const member functions
00497 //
00498 
00499 //
00500 // static member functions
00501 //