CMS 3D CMS Logo

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