Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
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
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 BareRootProductGetter::BareRootProductGetter() {
00040 }
00041
00042
00043
00044
00045
00046 BareRootProductGetter::~BareRootProductGetter() {
00047 }
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 edm::WrapperHolder
00068 BareRootProductGetter::getIt(edm::ProductID const& iID) const {
00069
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
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
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
00102 if(itBuffer == idToBuffers_.end()) {
00103 buffer = createNewBuffer(iID);
00104
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
00123
00124
00125 edm::WrapperInterfaceBase const* interface = branchMap_.productToBranch(iID).getInterface();
00126
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
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
00158 edm::BranchDescription bdesc = branchMap_.productToBranch(iID);
00159
00160 TBranch* branch= branchMap_.getEventTree()->GetBranch(bdesc.branchName().c_str());
00161 if(0 == branch) {
00162
00163 return 0;
00164 }
00165
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
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
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
00198
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
00208
00209 Buffer b(prod, branch, address, rootClassType);
00210 idToBuffers_[iID] = b;
00211
00212
00213
00214 address = &(idToBuffers_[iID].address_);
00215 branch->SetAddress(address);
00216
00217 return &(idToBuffers_[iID]);
00218 }
00219
00220
00221
00222