CMS 3D CMS Logo

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