RootController.cxx
Go to the documentation of this file.
1 
12 #include "RootController.h"
13 
14 #include "RootNTuple.h"
15 
17 
18 #include "TFile.h"
19 #include "TKey.h"
20 #include "TTree.h"
21 
22 #include "TH2.h"
23 
24 #include <fstream>
25 #include <stdexcept>
26 
27 #include <cassert>
28 
29 using std::string;
30 using std::vector;
31 
32 using namespace hippodraw;
33 
36 typedef std::map < std::string, TFile * > ::iterator FileMapIterator_t;
37 
39 
43 {
44  if ( s_instance == 0 ) {
45  s_instance = new RootController ();
46  }
47 #ifdef _MSC_VER
48  TTree * tree = new TTree (); // force loading of dll
49  delete tree;
50 #endif
51  TH2::Class(); // This is needed to avoid ROOT crashing upon reading
52  // a second file that contains a TH2 object.
53  return s_instance;
54 }
55 
58 {
59 }
60 
61 const std::string &
63 version () const
64 {
65  m_version = ROOT_RELEASE;
66  return m_version;
67 }
68 
69 TFile *
71 openFile ( const std::string & name )
72 {
73  TFile * file = 0;
74  FileMapIterator_t first = m_file_map.find ( name );
75 
76  if ( first == m_file_map.end() ) {
77  ifstream test ( name.c_str (), std::ios::in );
78  if ( test.is_open () == false ) {
79  string what ( "RootController: File `" );
80  what += name;
81  what += "' was not found.";
82 
83  throw std::runtime_error ( what );
84  }
85  file = new TFile ( name.c_str() );
86  m_file_map [ name ] = file;
87  }
88  else {
89  file = first -> second;
90  }
91 
92  return file;
93 }
94 
95 void
97 closeFile ( const std::string & name )
98 {
99  FileMapIterator_t where = m_file_map.find ( name );
100  if ( where != m_file_map.end () ) {
101  TFile * file = where -> second; // do before following for VC++ debugger.
102  m_file_map.erase ( where );
103  delete file;
104  }
105 }
106 
110 const vector < string > &
112 getNTupleNames ( const std::string & file_name )
113 {
114  m_ntuple_names.clear();
115 
116  TFile * file = openFile ( file_name );
117 
118  if ( file != 0 ) {
119  TList * keys = file -> GetListOfKeys ();
120  Int_t size = keys -> GetSize ();
121 
122  for ( Int_t i = 0; i < size; i++ ) {
123  TObject * obj = keys -> At ( i );
124  TKey * key = dynamic_cast < TKey * > ( obj );
125  const string class_name = key -> GetClassName ();
126  if ( class_name == "TTree" ||
127  class_name == "TNtuple" ||
128  class_name == "TNtupleD" ) {
129  const string name = key -> GetName ();
130  m_ntuple_names.push_back ( name );
131  }
132  }
133  }
134  closeFile ( file_name );
135 
136  return m_ntuple_names;
137 }
138 
139 TTree *
141 getTree ( const std::string & filename,
142  const std::string & treename )
143 {
144  TFile * file = openFile ( filename );
145  if ( file == NULL ) return NULL;
146 
147  TObject * object = file -> Get ( treename.c_str() );
148  TTree * tree = dynamic_cast < TTree * > ( object );
149 
150  return tree;
151 }
152 
153 DataSource *
155 createNTuple ( const std::string & filename, const std::string & treename )
156 {
157  TTree * tree = getTree ( filename, treename );
158  if ( tree == NULL ) return NULL;
159 
160  DataSource * ntuple = new RootNTuple ( tree );
161 
162  return initNTuple ( ntuple, filename, treename );
163 }
164 
165 DataSource *
167 initNTuple ( DataSource * ntuple, const std::string & filename,
168  const std::string & treename )
169 {
170  string ds_name = filename;
171  ds_name += ": ";
172  ds_name += treename;
173 
174  ntuple -> setTitle ( treename );
175  ntuple -> setName ( ds_name );
177  controller -> registerNTuple ( ds_name, ntuple );
178  controller -> registerDataSourceFile ( ntuple );
179 
180  m_tuple_map [ ntuple ] = filename;
181  ntuple -> addObserver ( this );
182 
183  return ntuple;
184 }
185 
186 DataSource *
188 createNTuple ( const std::string & name )
189 {
190  DataSource * rtuple = 0;
191 
192  string::size_type pos = name.find_last_of ( ':' );
193  if ( pos == string::npos ) {
194  const vector < string > & tree_names = getNTupleNames ( name );
195  rtuple = createNTuple ( name, tree_names[0] );
196  }
197  else {
198  const string filename = name.substr ( 0, pos );
199  string tree_name = name.substr ( pos + 1 );
200  pos = tree_name.find_first_not_of ( ' ' );
201  tree_name.erase ( 0, pos );
202  rtuple = createNTuple ( filename, tree_name );
203  }
204 
205  return rtuple;
206 }
207 
208 void
210 fillDimSize ( std::vector < int > & dims,
211  const DataSource * source,
212  const std::string & column )
213 {
214  dims.clear();
215 
216  const RootNTuple * rtuple = dynamic_cast < const RootNTuple * > ( source );
217  if ( rtuple != 0 ) {
218  int index = rtuple -> indexOf ( column );
219  vector < int > shape; // complete shape include events
220  rtuple -> fillShape ( shape, index );
221  for ( unsigned int i = 1; i < shape.size(); i++ ) {
222  dims.push_back ( shape [ i] ); // just shape of variable
223  }
224  }
225 }
226 
227 bool
229 smartExpandRootNTuple ( DataSource * source, std::string & column )
230 {
231  bool yes = false;
232  RootNTuple * rtuple = dynamic_cast < RootNTuple * > ( source );
233  if ( rtuple != 0 ) {
234  rtuple -> smartExpandRootNTuple ( column );
235  yes = true;
236  }
237 
238  return yes;
239 }
240 
241 void
243 update ( const Observable * )
244 {
245  // nothing to be done.
246 }
247 
251 void
253 willDelete ( const Observable * obs )
254 {
255  const RootNTuple * tuple = dynamic_cast < const RootNTuple * > ( obs );
256 // assert ( tuple != 0 ); // only observing this type
257  if ( tuple != 0 ) {
258  TupleToFileMap_t::iterator first = m_tuple_map.find ( tuple );
259  assert ( first != m_tuple_map.end () ); // should be there.
260 
261  const string & filename = first -> second;
262  // Are there any others
263  int count = 0;
264  first = m_tuple_map.begin();
265  while ( first != m_tuple_map.end () ) {
266  const string & name = first -> second;
267  if ( name == filename ) {
268  count ++;
269  }
270  ++first;
271  }
272 
273  if ( count == 1 ) {
274  closeFile ( filename );
275  }
276  }
277 }

Generated for HippoDraw Class Library by doxygen