Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
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
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 BareRootProductGetter::BareRootProductGetter()
00040 {
00041 }
00042
00043
00044
00045
00046
00047
00048 BareRootProductGetter::~BareRootProductGetter()
00049 {
00050 }
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 edm::EDProduct const*
00072 BareRootProductGetter::getIt(edm::ProductID const& iID) const {
00073
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
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
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
00103 if( itBuffer == idToBuffers_.end() ) {
00104 buffer = createNewBuffer(iID);
00105
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
00126
00127
00128
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
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
00162 edm::BranchDescription bdesc = branchMap_.productToBranch(iID);
00163
00164 TBranch* branch= branchMap_.getEventTree()->GetBranch( bdesc.branchName().c_str() );
00165 if( 0 == branch) {
00166
00167 return 0;
00168 }
00169
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
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
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
00211
00212 Buffer b(prod, branch,address,rootClassType);
00213 idToBuffers_[iID]=b;
00214
00215
00216
00217 address = &(idToBuffers_[iID].address_);
00218 branch->SetAddress( address );
00219
00220 return &(idToBuffers_[iID]);
00221 }
00222
00223
00224
00225