RootController.cxx

Go to the documentation of this file.
00001 
00012 #include "RootController.h"
00013 
00014 #include "RootNTuple.h"
00015 
00016 #include "datasrcs/DataSourceController.h"
00017 
00018 #include "TFile.h"
00019 #include "TKey.h"
00020 #include "TTree.h"
00021 
00022 #include "TH2.h"
00023 
00024 #include <fstream>
00025 #include <stdexcept>
00026 
00027 #include <cassert>
00028 
00029 using std::string;
00030 using std::vector;
00031 
00032 using namespace hippodraw;
00033 
00036 typedef std::map < std::string, TFile * > ::iterator FileMapIterator_t;
00037 
00038 RootController * RootController::s_instance = 0;
00039 
00040 RootController *
00041 RootController::
00042 instance ()
00043 {
00044   if ( s_instance == 0 ) {
00045     s_instance = new RootController ();
00046   }
00047 #ifdef _MSC_VER
00048   TTree * tree = new TTree (); // force loading of dll
00049   delete tree;
00050 #endif
00051   TH2::Class(); // This is needed to avoid ROOT crashing upon reading
00052                 // a second file that contains a TH2 object.
00053   return s_instance;
00054 }
00055 
00056 RootController::
00057 ~RootController()
00058 {
00059 }
00060 
00061 const std::string &
00062 RootController::
00063 version () const
00064 {
00065   m_version = ROOT_RELEASE;
00066   return m_version;
00067 }
00068 
00069 TFile *
00070 RootController::
00071 openFile ( const std::string & name )
00072 {
00073   TFile * file = 0;
00074   FileMapIterator_t first = m_file_map.find ( name );
00075 
00076   if ( first == m_file_map.end() ) {
00077     ifstream test ( name.c_str (), std::ios::in );
00078     if ( test.is_open () == false ) {
00079       string what ( "RootController: File `" );
00080       what += name;
00081       what += "' was not found.";
00082 
00083       throw std::runtime_error ( what );
00084     }
00085     file = new TFile ( name.c_str() );
00086     m_file_map [ name ] = file;
00087   }
00088   else {
00089     file = first -> second;
00090   }
00091 
00092   return file;
00093 }
00094 
00095 void
00096 RootController::
00097 closeFile ( const std::string & name )
00098 {
00099   FileMapIterator_t where = m_file_map.find ( name );
00100   if ( where != m_file_map.end () ) {
00101     TFile * file = where -> second; // do before following for VC++ debugger.
00102     m_file_map.erase ( where );
00103     delete file;
00104   }
00105 }
00106 
00110 const vector < string > & 
00111 RootController::
00112 getNTupleNames ( const std::string & file_name )
00113 {
00114   m_ntuple_names.clear();
00115 
00116   TFile * file = openFile ( file_name );
00117 
00118   if ( file != 0 ) {
00119     TList * keys = file -> GetListOfKeys ();
00120     Int_t size = keys -> GetSize ();
00121 
00122     for ( Int_t i = 0; i < size; i++ ) {
00123       TObject * obj = keys -> At ( i );
00124       TKey * key = dynamic_cast < TKey * > ( obj );
00125       const string class_name = key -> GetClassName ();
00126       if ( class_name == "TTree" || 
00127            class_name == "TNtuple" ||
00128            class_name == "TNtupleD" ) {
00129         const string name = key -> GetName ();
00130         m_ntuple_names.push_back ( name );
00131       }
00132     }
00133   }
00134   closeFile ( file_name );
00135 
00136   return m_ntuple_names;
00137 }
00138 
00139 TTree *
00140 RootController::
00141 getTree ( const std::string & filename,
00142           const std::string & treename )
00143 {
00144   TFile * file =  openFile ( filename );
00145   if ( file == NULL ) return NULL;
00146 
00147   TObject * object = file -> Get ( treename.c_str() );
00148   TTree * tree = dynamic_cast < TTree * > ( object );
00149 
00150   return tree;
00151 }
00152 
00153 DataSource *
00154 RootController::
00155 createNTuple ( const std::string & filename, const std::string & treename )
00156 {
00157   TTree * tree = getTree ( filename, treename );
00158   if ( tree == NULL ) return NULL;
00159 
00160   DataSource * ntuple = new RootNTuple ( tree );
00161 
00162   return initNTuple ( ntuple, filename, treename );
00163 }
00164 
00165 DataSource *
00166 RootController::
00167 initNTuple ( DataSource * ntuple, const std::string & filename,
00168              const std::string & treename )
00169 {
00170   string ds_name = filename;
00171   ds_name += ": ";
00172   ds_name += treename;
00173 
00174   ntuple -> setTitle ( treename );
00175   ntuple -> setName ( ds_name );
00176   DataSourceController * controller = DataSourceController::instance();
00177   controller -> registerNTuple ( ds_name, ntuple );
00178   controller -> registerDataSourceFile ( ntuple );
00179 
00180   m_tuple_map [ ntuple ] = filename;
00181   ntuple -> addObserver ( this );
00182 
00183   return ntuple;
00184 }
00185 
00186 DataSource *
00187 RootController::
00188 createNTuple ( const std::string & name )
00189 {
00190   DataSource * rtuple = 0;
00191 
00192   string::size_type pos = name.find_last_of ( ':' );
00193   if ( pos == string::npos ) {
00194     const vector < string > & tree_names = getNTupleNames ( name );
00195     rtuple = createNTuple ( name, tree_names[0] );
00196   }
00197   else {
00198     const string filename = name.substr ( 0, pos );
00199     string tree_name = name.substr ( pos + 1 );
00200     pos = tree_name.find_first_not_of ( ' ' );
00201     tree_name.erase ( 0, pos );
00202     rtuple = createNTuple ( filename, tree_name );
00203   }
00204 
00205   return rtuple;
00206 }
00207 
00208 void
00209 RootController::
00210 fillDimSize ( std::vector < int > & dims, 
00211               const DataSource * source,
00212               const std::string & column )
00213 {
00214   dims.clear();
00215 
00216   const RootNTuple * rtuple = dynamic_cast < const RootNTuple * > ( source );
00217   if ( rtuple != 0 ) {
00218     int index = rtuple -> indexOf ( column );
00219     vector < int > shape; // complete shape include events
00220     rtuple -> fillShape ( shape, index );
00221     for ( unsigned int i = 1; i < shape.size(); i++ ) {
00222       dims.push_back ( shape [ i] ); // just shape of variable
00223     }
00224   }
00225 }
00226 
00227 bool
00228 RootController::
00229 smartExpandRootNTuple ( DataSource * source, std::string & column )
00230 {
00231   bool yes = false;
00232   RootNTuple * rtuple = dynamic_cast < RootNTuple * > ( source );
00233   if ( rtuple != 0 ) {
00234     rtuple -> smartExpandRootNTuple ( column );
00235     yes = true;
00236   }
00237 
00238   return yes;
00239 }
00240 
00241 void
00242 RootController::
00243 update ( const Observable * )
00244 {
00245   // nothing to be done.
00246 }
00247 
00251 void
00252 RootController::
00253 willDelete ( const Observable * obs )
00254 {
00255   const RootNTuple * tuple = dynamic_cast < const RootNTuple * > ( obs );
00256 //   assert ( tuple != 0 ); // only observing this type
00257   if ( tuple != 0 ) {
00258     TupleToFileMap_t::iterator first = m_tuple_map.find ( tuple );
00259     assert ( first != m_tuple_map.end () ); // should be there.
00260 
00261     const string & filename = first -> second;
00262     // Are there any others
00263     int count = 0;
00264     first = m_tuple_map.begin();
00265     while ( first != m_tuple_map.end () ) {
00266       const string & name = first -> second;
00267       if ( name == filename ) {
00268         count ++;
00269       }
00270       ++first;
00271     }
00272 
00273     if ( count == 1 ) {
00274       closeFile ( filename );
00275     }
00276   }
00277 }

Generated for HippoDraw Class Library by doxygen