CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/FWCore/FWLite/src/BareRootProductGetter.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     FWLite
00004 // Class  :     BareRootProductGetter
00005 // 
00006 // Implementation:
00007 //     <Notes on implementation>
00008 //
00009 // Original Author:  Chris Jones
00010 //         Created:  Tue May 23 11:03:31 EDT 2006
00011 //
00012 
00013 // system include files
00014 
00015 #include "TFile.h"
00016 #include "TTree.h"
00017 #include "TBranch.h"
00018 #include "TClass.h"
00019 #include "Reflex/Type.h"
00020 #include "TROOT.h"
00021 
00022 // user include files
00023 #include "FWCore/FWLite/src/BareRootProductGetter.h"
00024 #include "DataFormats/Provenance/interface/BranchType.h"
00025 #include "FWCore/Utilities/interface/WrappedClassName.h"
00026 #include "FWCore/Utilities/interface/Exception.h"
00027 
00028 //
00029 // constants, enums and typedefs
00030 //
00031 
00032 //
00033 // static data member definitions
00034 //
00035 
00036 //
00037 // constructors and destructor
00038 //
00039 BareRootProductGetter::BareRootProductGetter()
00040 {
00041 }
00042 
00043 // BareRootProductGetter::BareRootProductGetter(const BareRootProductGetter& rhs)
00044 // {
00045 //    // do actual copying here;
00046 // }
00047 
00048 BareRootProductGetter::~BareRootProductGetter()
00049 {
00050 }
00051 
00052 //
00053 // assignment operators
00054 //
00055 // const BareRootProductGetter& BareRootProductGetter::operator=(const BareRootProductGetter& rhs)
00056 // {
00057 //   //An exception safe implementation is
00058 //   BareRootProductGetter temp(rhs);
00059 //   swap(rhs);
00060 //
00061 //   return *this;
00062 // }
00063 
00064 //
00065 // member functions
00066 //
00067 
00068 //
00069 // const member functions
00070 //
00071 edm::EDProduct const*
00072 BareRootProductGetter::getIt(edm::ProductID const& iID) const  {
00073   // std::cout <<"getIt called"<<std::endl;
00074   TFile* currentFile = dynamic_cast<TFile*>(gROOT->GetListOfFiles()->Last());
00075 
00076   if (branchMap_.updateFile(currentFile)) {
00077     idToBuffers_.clear();
00078   }
00079   TTree* eventTree = branchMap_.getEventTree();
00080   // std::cout << "eventTree " << eventTree << std::endl;
00081   if (0 == eventTree) {
00082      throw cms::Exception("NoEventsTree")
00083         <<"unable to find the TTree '"<<edm::poolNames::eventTreeName() << "' in the last open file, \n"
00084         <<"file: '"<< branchMap_.getFile()->GetName()
00085         <<"'\n Please check that the file is a standard CMS ROOT format.\n"
00086         <<"If the above is not the file you expect then please open your data file after all other files.";
00087     return 0;
00088   }
00089   Long_t eventEntry = eventTree->GetReadEntry();
00090   // std::cout << "eventEntry " << eventEntry << std::endl;
00091   branchMap_.updateEvent(eventEntry);
00092   if( eventEntry < 0 ) {
00093      throw cms::Exception("GetEntryNotCalled") 
00094         <<"please call GetEntry for the 'Events' TTree for each event in order to make edm::Ref's work."
00095         <<"\n Also be sure to call 'SetAddress' for all Branches after calling the GetEntry."
00096         ;
00097     return 0;
00098   }
00099 
00100   Buffer* buffer = 0;
00101   IdToBuffers::iterator itBuffer = idToBuffers_.find(iID);
00102   // std::cout << "Buffers" << std::endl;
00103   if( itBuffer == idToBuffers_.end() ) {
00104     buffer = createNewBuffer(iID);
00105     // std::cout << "buffer " << buffer << std::endl;
00106     if( 0 == buffer ) {
00107       return 0;
00108     }
00109   } else {
00110     buffer = &(itBuffer->second);
00111   }
00112   if(0==buffer) {
00113      throw cms::Exception("NullBuffer")
00114         <<"Found a null buffer which is supposed to hold the data item."
00115         <<"\n Please contact developers since this message should not happen.";
00116     return 0;
00117   }
00118   if(0==buffer->branch_) {
00119      throw cms::Exception("NullBranch")
00120         <<"The TBranch which should hold the data item is null."
00121         <<"\n Please contact the developers since this message should not happen.";
00122     return 0;
00123   }
00124   if(buffer->eventEntry_ != eventEntry) {
00125     //NOTE: Need to reset address because user could have set the address themselves
00126     //std::cout <<"new event"<<std::endl;
00127     
00128     //ROOT WORKAROUND: Create new objects so any internal data cache will get cleared
00129     void* address = buffer->class_->New();
00130     
00131     static TClass* edproductTClass = TClass::GetClass( typeid(edm::EDProduct)); 
00132     edm::EDProduct* prod = reinterpret_cast<edm::EDProduct*>( buffer->class_->DynamicCast(edproductTClass,address,true));
00133     if(0 == prod) {
00134       cms::Exception("FailedConversion")
00135       <<"failed to convert a '"<<buffer->class_->GetName()
00136       <<"' to a edm::EDProduct."
00137       <<"Please contact developers since something is very wrong.";
00138     }
00139     buffer->address_ = address;
00140     buffer->product_ = boost::shared_ptr<edm::EDProduct const>(prod);
00141     //END WORKAROUND
00142     
00143     address = &(buffer->address_);
00144     buffer->branch_->SetAddress( address );
00145 
00146     buffer->branch_->GetEntry( eventEntry );
00147     buffer->eventEntry_=eventEntry;
00148   }
00149   if(0 == buffer->product_.get()) {
00150      throw cms::Exception("BranchGetEntryFailed")
00151         <<"Calling GetEntry with index "<<eventEntry
00152         <<"for branch "<<buffer->branch_->GetName()<<" failed.";
00153   }
00154 
00155   return buffer->product_.get();
00156 }
00157 
00158 BareRootProductGetter::Buffer* 
00159 BareRootProductGetter::createNewBuffer(const edm::ProductID& iID) const
00160 {
00161   //find the branch
00162   edm::BranchDescription bdesc = branchMap_.productToBranch(iID);
00163 
00164   TBranch* branch= branchMap_.getEventTree()->GetBranch( bdesc.branchName().c_str() );
00165   if( 0 == branch) {
00166      //we do not thrown on missing branches since 'getIt' should not throw under that condition
00167     return 0;
00168   }
00169   //find the class type
00170   const std::string fullName = edm::wrappedClassName(bdesc.className());
00171   Reflex::Type classType = Reflex::Type::ByName(fullName);
00172   if( classType == Reflex::Type() ) {
00173     cms::Exception("MissingDictionary") 
00174        <<"could not find dictionary for type '"<<fullName<<"'"
00175        <<"\n Please make sure all the necessary libraries are available.";
00176     return 0;
00177   }
00178    
00179   //We can't use reflex to create the instance since Reflex uses 'malloc' instead of new
00180   /*
00181   //use reflex to create an instance of it
00182   Reflex::Object wrapperObj = classType.Construct();
00183   if( 0 == wrapperObj.Address() ) {
00184     cms::Exception("FailedToCreate") <<"could not create an instance of '"<<fullName<<"'";
00185     return 0;
00186   }
00187       
00188   Reflex::Object edProdObj = wrapperObj.CastObject( Reflex::Type::ByName("edm::EDProduct") );
00189   
00190   edm::EDProduct* prod = reinterpret_cast<edm::EDProduct*>(edProdObj.Address());
00191   */
00192   TClass* rootClassType=TClass::GetClass(classType.TypeInfo());
00193   if( 0 == rootClassType) {
00194     throw cms::Exception("MissingRootDictionary")
00195     <<"could not find a ROOT dictionary for type '"<<fullName<<"'"
00196     <<"\n Please make sure all the necessary libraries are available.";
00197     return 0;
00198   }
00199   void* address = rootClassType->New();
00200   
00201   static TClass* edproductTClass = TClass::GetClass( typeid(edm::EDProduct)); 
00202   edm::EDProduct* prod = reinterpret_cast<edm::EDProduct*>( rootClassType->DynamicCast(edproductTClass,address,true));
00203   if(0 == prod) {
00204      cms::Exception("FailedConversion")
00205         <<"failed to convert a '"<<fullName
00206         <<"' to a edm::EDProduct."
00207         <<"Please contact developers since something is very wrong.";
00208   }
00209 
00210   //connect the instance to the branch
00211   //void* address  = wrapperObj.Address();
00212   Buffer b(prod, branch,address,rootClassType);
00213   idToBuffers_[iID]=b;
00214   
00215   //As of 5.13 ROOT expects the memory address held by the pointer passed to
00216   // SetAddress to be valid forever
00217   address = &(idToBuffers_[iID].address_);
00218   branch->SetAddress( address );
00219   
00220   return &(idToBuffers_[iID]);
00221 }
00222 
00223 //
00224 // static member functions
00225 //