CMS 3D CMS Logo

Classes | Public Member Functions | Private Types | Private Member Functions | Private Attributes

BareRootProductGetter Class Reference

#include <FWCore/FWLite/interface/BareRootProductGetter.h>

Inheritance diagram for BareRootProductGetter:
edm::EDProductGetter

List of all members.

Classes

struct  Buffer

Public Member Functions

 BareRootProductGetter ()
virtual edm::WrapperHolder getIt (edm::ProductID const &) const
virtual ~BareRootProductGetter ()

Private Types

typedef std::map
< edm::ProductID, Buffer
IdToBuffers

Private Member Functions

 BareRootProductGetter (BareRootProductGetter const &)
BuffercreateNewBuffer (edm::ProductID const &) const
TBranch * findBranch (edm::ProductID const &) const
BareRootProductGetter const & operator= (BareRootProductGetter const &)
void setupNewFile (TFile *) const

Private Attributes

fwlite::BranchMapReader branchMap_
IdToBuffers idToBuffers_

Detailed Description

Description: <one line="" class="" summary>="">

Usage: <usage>

Definition at line 36 of file BareRootProductGetter.h.


Member Typedef Documentation

Definition at line 77 of file BareRootProductGetter.h.


Constructor & Destructor Documentation

BareRootProductGetter::BareRootProductGetter ( )

Definition at line 39 of file BareRootProductGetter.cc.

                                             {
}
BareRootProductGetter::~BareRootProductGetter ( ) [virtual]

Definition at line 46 of file BareRootProductGetter.cc.

                                              {
}
BareRootProductGetter::BareRootProductGetter ( BareRootProductGetter const &  ) [private]

Member Function Documentation

BareRootProductGetter::Buffer * BareRootProductGetter::createNewBuffer ( edm::ProductID const &  iID) const [private]

Definition at line 155 of file BareRootProductGetter.cc.

References b, branchMap_, edm::BranchDescription::branchName(), edm::BranchDescription::className(), Exception, newFWLiteAna::fullName, fwlite::BranchMapReader::getEventTree(), edm::BranchDescription::getInterface(), idToBuffers_, edm::WrapperHolder::isValid(), parseEventContent::prod, fwlite::BranchMapReader::productToBranch(), and edm::wrappedClassName().

Referenced by getIt().

                                                                    {
  //find the branch
  edm::BranchDescription bdesc = branchMap_.productToBranch(iID);

  TBranch* branch= branchMap_.getEventTree()->GetBranch(bdesc.branchName().c_str());
  if(0 == branch) {
     //we do not thrown on missing branches since 'getIt' should not throw under that condition
    return 0;
  }
  //find the class type
  std::string const fullName = edm::wrappedClassName(bdesc.className());
  Reflex::Type classType = Reflex::Type::ByName(fullName);
  if(classType == Reflex::Type()) {
    cms::Exception("MissingDictionary")
       << "could not find dictionary for type '" << fullName << "'"
       << "\n Please make sure all the necessary libraries are available.";
    return 0;
  }

  //We can't use reflex to create the instance since Reflex uses 'malloc' instead of new
  /*
  //use reflex to create an instance of it
  Reflex::Object wrapperObj = classType.Construct();
  if(0 == wrapperObj.Address()) {
    cms::Exception("FailedToCreate") << "could not create an instance of '" << fullName << "'";
    return 0;
  }

  Reflex::Object edProdObj = wrapperObj.CastObject(Reflex::Type::ByName("edm::WrapperHolder"));

  edm::WrapperHolder* prod = reinterpret_cast<edm::WrapperHolder*>(edProdObj.Address());
  */
  TClass* rootClassType = TClass::GetClass(classType.TypeInfo());
  if(0 == rootClassType) {
    throw cms::Exception("MissingRootDictionary")
    << "could not find a ROOT dictionary for type '" << fullName << "'"
    << "\n Please make sure all the necessary libraries are available.";
    return 0;
  }
  void* address = rootClassType->New();

  //static TClass* edproductTClass = TClass::GetClass(typeid(edm::WrapperHolder));
  //edm::WrapperHolder* prod = reinterpret_cast<edm::WrapperHolder*>(rootClassType->DynamicCast(edproductTClass, address, true));
  edm::WrapperOwningHolder prod = edm::WrapperOwningHolder(address, bdesc.getInterface());
  if(!prod.isValid()) {
     cms::Exception("FailedConversion")
        << "failed to convert a '" << fullName
        << "' to a edm::WrapperOwningHolder."
        << "Please contact developers since something is very wrong.";
  }

  //connect the instance to the branch
  //void* address  = wrapperObj.Address();
  Buffer b(prod, branch, address, rootClassType);
  idToBuffers_[iID] = b;

  //As of 5.13 ROOT expects the memory address held by the pointer passed to
  // SetAddress to be valid forever
  address = &(idToBuffers_[iID].address_);
  branch->SetAddress(address);

  return &(idToBuffers_[iID]);
}
TBranch* BareRootProductGetter::findBranch ( edm::ProductID const &  ) const [private]
edm::WrapperHolder BareRootProductGetter::getIt ( edm::ProductID const &  iID) const [virtual]

Implements edm::EDProductGetter.

Definition at line 68 of file BareRootProductGetter.cc.

References BareRootProductGetter::Buffer::address_, BareRootProductGetter::Buffer::branch_, branchMap_, BareRootProductGetter::Buffer::class_, createNewBuffer(), BareRootProductGetter::Buffer::eventEntry_, edm::poolNames::eventTreeName(), Exception, fwlite::BranchMapReader::getEventTree(), fwlite::BranchMapReader::getFile(), edm::BranchDescription::getInterface(), idToBuffers_, edm::WrapperHolder::interface(), edm::WrapperHolder::isValid(), parseEventContent::prod, BareRootProductGetter::Buffer::product_, fwlite::BranchMapReader::productToBranch(), fwlite::BranchMapReader::updateEvent(), fwlite::BranchMapReader::updateFile(), and edm::WrapperHolder::wrapper().

                                                           {
  // std::cout << "getIt called" << std::endl;
  TFile* currentFile = dynamic_cast<TFile*>(gROOT->GetListOfFiles()->Last());

  if(branchMap_.updateFile(currentFile)) {
    idToBuffers_.clear();
  }
  TTree* eventTree = branchMap_.getEventTree();
  // std::cout << "eventTree " << eventTree << std::endl;
  if(0 == eventTree) {
     throw cms::Exception("NoEventsTree")
        << "unable to find the TTree '" << edm::poolNames::eventTreeName() << "' in the last open file, \n"
        << "file: '" << branchMap_.getFile()->GetName()
        << "'\n Please check that the file is a standard CMS ROOT format.\n"
        << "If the above is not the file you expect then please open your data file after all other files.";
     return edm::WrapperHolder();
  }
  Long_t eventEntry = eventTree->GetReadEntry();
  // std::cout << "eventEntry " << eventEntry << std::endl;
  branchMap_.updateEvent(eventEntry);
  if(eventEntry < 0) {
     throw cms::Exception("GetEntryNotCalled")
        << "please call GetEntry for the 'Events' TTree for each event in order to make edm::Ref's work."
        << "\n Also be sure to call 'SetAddress' for all Branches after calling the GetEntry."
        ;
     return edm::WrapperHolder();
  }

  Buffer* buffer = 0;
  IdToBuffers::iterator itBuffer = idToBuffers_.find(iID);
  // std::cout << "Buffers" << std::endl;
  if(itBuffer == idToBuffers_.end()) {
    buffer = createNewBuffer(iID);
    // std::cout << "buffer " << buffer << std::endl;
    if(0 == buffer) {
       return edm::WrapperHolder();
    }
  } else {
    buffer = &(itBuffer->second);
  }
  if(0 == buffer) {
     throw cms::Exception("NullBuffer")
        << "Found a null buffer which is supposed to hold the data item."
        << "\n Please contact developers since this message should not happen.";
    return edm::WrapperHolder();
  }
  if(0 == buffer->branch_) {
     throw cms::Exception("NullBranch")
        << "The TBranch which should hold the data item is null."
        << "\n Please contact the developers since this message should not happen.";
    return edm::WrapperHolder();
  }
  if(buffer->eventEntry_ != eventEntry) {
    //NOTE: Need to reset address because user could have set the address themselves
    //std::cout << "new event" << std::endl;

    edm::WrapperInterfaceBase const* interface = branchMap_.productToBranch(iID).getInterface();
    //ROOT WORKAROUND: Create new objects so any internal data cache will get cleared
    void* address = buffer->class_->New();

    edm::WrapperOwningHolder prod = edm::WrapperOwningHolder(address, interface);
    if(!prod.isValid()) {
      cms::Exception("FailedConversion")
      << "failed to convert a '" << buffer->class_->GetName()
      << "' to a edm::WrapperHolder."
      << "Please contact developers since something is very wrong.";
    }
    buffer->address_ = address;
    buffer->product_ = prod;
    //END WORKAROUND

    address = &(buffer->address_);
    buffer->branch_->SetAddress(address);

    buffer->branch_->GetEntry(eventEntry);
    buffer->eventEntry_ = eventEntry;
  }
  if(!buffer->product_.isValid()) {
     throw cms::Exception("BranchGetEntryFailed")
        << "Calling GetEntry with index " << eventEntry
        << "for branch " << buffer->branch_->GetName() << " failed.";
  }

  return edm::WrapperHolder(buffer->product_.wrapper(), buffer->product_.interface());
}
BareRootProductGetter const& BareRootProductGetter::operator= ( BareRootProductGetter const &  ) [private]
void BareRootProductGetter::setupNewFile ( TFile *  ) const [private]

Member Data Documentation

Definition at line 79 of file BareRootProductGetter.h.

Referenced by createNewBuffer(), and getIt().

Definition at line 78 of file BareRootProductGetter.h.

Referenced by createNewBuffer(), and getIt().