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 ();
00049 delete tree;
00050 #endif
00051 TH2::Class();
00052
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;
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;
00220 rtuple -> fillShape ( shape, index );
00221 for ( unsigned int i = 1; i < shape.size(); i++ ) {
00222 dims.push_back ( shape [ i] );
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
00246 }
00247
00251 void
00252 RootController::
00253 willDelete ( const Observable * obs )
00254 {
00255 const RootNTuple * tuple = dynamic_cast < const RootNTuple * > ( obs );
00256
00257 if ( tuple != 0 ) {
00258 TupleToFileMap_t::iterator first = m_tuple_map.find ( tuple );
00259 assert ( first != m_tuple_map.end () );
00260
00261 const string & filename = first -> second;
00262
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 }