CMS 3D CMS Logo

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
BareRootProductGetter.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: FWLite
4 // Class : BareRootProductGetter
5 //
6 // Implementation:
7 // <Notes on implementation>
8 //
9 // Original Author: Chris Jones
10 // Created: Tue May 23 11:03:31 EDT 2006
11 //
12 
13 // system include files
14 
15 #include "TFile.h"
16 #include "TTree.h"
17 #include "TBranch.h"
18 #include "TClass.h"
19 #include "Reflex/Type.h"
20 #include "TROOT.h"
21 
22 // user include files
27 
28 //
29 // constants, enums and typedefs
30 //
31 
32 //
33 // static data member definitions
34 //
35 
36 //
37 // constructors and destructor
38 //
40 {
41 }
42 
43 // BareRootProductGetter::BareRootProductGetter(const BareRootProductGetter& rhs)
44 // {
45 // // do actual copying here;
46 // }
47 
49 {
50 }
51 
52 //
53 // assignment operators
54 //
55 // const BareRootProductGetter& BareRootProductGetter::operator=(const BareRootProductGetter& rhs)
56 // {
57 // //An exception safe implementation is
58 // BareRootProductGetter temp(rhs);
59 // swap(rhs);
60 //
61 // return *this;
62 // }
63 
64 //
65 // member functions
66 //
67 
68 //
69 // const member functions
70 //
71 edm::EDProduct const*
73  // std::cout <<"getIt called"<<std::endl;
74  TFile* currentFile = dynamic_cast<TFile*>(gROOT->GetListOfFiles()->Last());
75 
76  if (branchMap_.updateFile(currentFile)) {
77  idToBuffers_.clear();
78  }
79  TTree* eventTree = branchMap_.getEventTree();
80  // std::cout << "eventTree " << eventTree << std::endl;
81  if (0 == eventTree) {
82  throw cms::Exception("NoEventsTree")
83  <<"unable to find the TTree '"<<edm::poolNames::eventTreeName() << "' in the last open file, \n"
84  <<"file: '"<< branchMap_.getFile()->GetName()
85  <<"'\n Please check that the file is a standard CMS ROOT format.\n"
86  <<"If the above is not the file you expect then please open your data file after all other files.";
87  return 0;
88  }
89  Long_t eventEntry = eventTree->GetReadEntry();
90  // std::cout << "eventEntry " << eventEntry << std::endl;
91  branchMap_.updateEvent(eventEntry);
92  if( eventEntry < 0 ) {
93  throw cms::Exception("GetEntryNotCalled")
94  <<"please call GetEntry for the 'Events' TTree for each event in order to make edm::Ref's work."
95  <<"\n Also be sure to call 'SetAddress' for all Branches after calling the GetEntry."
96  ;
97  return 0;
98  }
99 
100  Buffer* buffer = 0;
101  IdToBuffers::iterator itBuffer = idToBuffers_.find(iID);
102  // std::cout << "Buffers" << std::endl;
103  if( itBuffer == idToBuffers_.end() ) {
104  buffer = createNewBuffer(iID);
105  // std::cout << "buffer " << buffer << std::endl;
106  if( 0 == buffer ) {
107  return 0;
108  }
109  } else {
110  buffer = &(itBuffer->second);
111  }
112  if(0==buffer) {
113  throw cms::Exception("NullBuffer")
114  <<"Found a null buffer which is supposed to hold the data item."
115  <<"\n Please contact developers since this message should not happen.";
116  return 0;
117  }
118  if(0==buffer->branch_) {
119  throw cms::Exception("NullBranch")
120  <<"The TBranch which should hold the data item is null."
121  <<"\n Please contact the developers since this message should not happen.";
122  return 0;
123  }
124  if(buffer->eventEntry_ != eventEntry) {
125  //NOTE: Need to reset address because user could have set the address themselves
126  //std::cout <<"new event"<<std::endl;
127 
128  //ROOT WORKAROUND: Create new objects so any internal data cache will get cleared
129  void* address = buffer->class_->New();
130 
131  static TClass* edproductTClass = TClass::GetClass( typeid(edm::EDProduct));
132  edm::EDProduct* prod = reinterpret_cast<edm::EDProduct*>( buffer->class_->DynamicCast(edproductTClass,address,true));
133  if(0 == prod) {
134  cms::Exception("FailedConversion")
135  <<"failed to convert a '"<<buffer->class_->GetName()
136  <<"' to a edm::EDProduct."
137  <<"Please contact developers since something is very wrong.";
138  }
139  buffer->address_ = address;
140  buffer->product_ = boost::shared_ptr<edm::EDProduct const>(prod);
141  //END WORKAROUND
142 
143  address = &(buffer->address_);
144  buffer->branch_->SetAddress( address );
145 
146  buffer->branch_->GetEntry( eventEntry );
147  buffer->eventEntry_=eventEntry;
148  }
149  if(0 == buffer->product_.get()) {
150  throw cms::Exception("BranchGetEntryFailed")
151  <<"Calling GetEntry with index "<<eventEntry
152  <<"for branch "<<buffer->branch_->GetName()<<" failed.";
153  }
154 
155  return buffer->product_.get();
156 }
157 
160 {
161  //find the branch
163 
164  TBranch* branch= branchMap_.getEventTree()->GetBranch( bdesc.branchName().c_str() );
165  if( 0 == branch) {
166  //we do not thrown on missing branches since 'getIt' should not throw under that condition
167  return 0;
168  }
169  //find the class type
170  const std::string fullName = edm::wrappedClassName(bdesc.className());
171  Reflex::Type classType = Reflex::Type::ByName(fullName);
172  if( classType == Reflex::Type() ) {
173  cms::Exception("MissingDictionary")
174  <<"could not find dictionary for type '"<<fullName<<"'"
175  <<"\n Please make sure all the necessary libraries are available.";
176  return 0;
177  }
178 
179  //We can't use reflex to create the instance since Reflex uses 'malloc' instead of new
180  /*
181  //use reflex to create an instance of it
182  Reflex::Object wrapperObj = classType.Construct();
183  if( 0 == wrapperObj.Address() ) {
184  cms::Exception("FailedToCreate") <<"could not create an instance of '"<<fullName<<"'";
185  return 0;
186  }
187 
188  Reflex::Object edProdObj = wrapperObj.CastObject( Reflex::Type::ByName("edm::EDProduct") );
189 
190  edm::EDProduct* prod = reinterpret_cast<edm::EDProduct*>(edProdObj.Address());
191  */
192  TClass* rootClassType=TClass::GetClass(classType.TypeInfo());
193  if( 0 == rootClassType) {
194  throw cms::Exception("MissingRootDictionary")
195  <<"could not find a ROOT dictionary for type '"<<fullName<<"'"
196  <<"\n Please make sure all the necessary libraries are available.";
197  return 0;
198  }
199  void* address = rootClassType->New();
200 
201  static TClass* edproductTClass = TClass::GetClass( typeid(edm::EDProduct));
202  edm::EDProduct* prod = reinterpret_cast<edm::EDProduct*>( rootClassType->DynamicCast(edproductTClass,address,true));
203  if(0 == prod) {
204  cms::Exception("FailedConversion")
205  <<"failed to convert a '"<<fullName
206  <<"' to a edm::EDProduct."
207  <<"Please contact developers since something is very wrong.";
208  }
209 
210  //connect the instance to the branch
211  //void* address = wrapperObj.Address();
212  Buffer b(prod, branch,address,rootClassType);
213  idToBuffers_[iID]=b;
214 
215  //As of 5.13 ROOT expects the memory address held by the pointer passed to
216  // SetAddress to be valid forever
217  address = &(idToBuffers_[iID].address_);
218  branch->SetAddress( address );
219 
220  return &(idToBuffers_[iID]);
221 }
222 
223 //
224 // static member functions
225 //
char * address
Definition: mlp_lapack.h:14
std::string & branchName() const
Buffer * createNewBuffer(const edm::ProductID &) const
bool updateEvent(Long_t eventEntry)
bool updateFile(TFile *file)
const edm::BranchDescription productToBranch(const edm::ProductID &pid)
TFile * getFile() const
virtual edm::EDProduct const * getIt(edm::ProductID const &) const
TTree * getEventTree() const
std::string const & className() const
boost::shared_ptr< edm::EDProduct const > product_
tuple prod
Definition: CrabTask.py:87
string fullName
std::string wrappedClassName(std::string const &iFullName)
double b
Definition: hdecay.h:120
std::string const & eventTreeName()
Definition: BranchType.cc:244
fwlite::BranchMapReader branchMap_