00001 00012 #include "RootBranch.h" 00013 00014 #include "axes/Range.h" 00015 #include "datasrcs/DataSourceException.h" 00016 00017 #include <TLeaf.h> 00018 00019 00020 #include <vector> 00021 #include <string> 00022 00023 #include <cassert> 00024 00025 using std::string; 00026 using std::vector; 00027 00028 using namespace hippodraw; 00029 00030 RootBranch:: 00031 RootBranch ( TBranch * branch ) 00032 : m_branch ( branch ), 00033 m_releventIndex ( -1 ), 00034 m_branch_set ( false ) 00035 { 00036 TObjArray * leaves = branch -> GetListOfLeaves (); 00037 m_number_leaves = leaves -> GetEntries (); 00038 00039 if ( m_number_leaves == 1 ) 00040 { 00041 TObject * object = leaves -> At ( 0 ); 00042 m_leaf = dynamic_cast < TLeaf * > ( object ); 00043 assert ( m_leaf != 0 ); 00044 const string type = m_leaf -> GetTypeName (); 00045 00046 if ( type == "Double_t" ) m_leaf_type = RootData::Double; 00047 else if ( type == "Float_t" ) m_leaf_type = RootData::Float; 00048 else if ( type == "Int_t" ) m_leaf_type = RootData::Int; 00049 else if ( type == "UInt_t" ) m_leaf_type = RootData::UInt; 00050 else assert ( false ); 00051 00052 m_number_elements = m_leaf -> GetLen(); 00053 } 00054 00055 if( m_number_elements > 1 ) // we are dealing with multidimensional data 00056 getDimSize( m_leaf -> GetTitle() ); 00057 } 00058 00059 RootBranch:: 00060 RootBranch () 00061 : m_branch ( 0 ), 00062 m_releventIndex ( -1 ), 00063 m_branch_set ( false ) 00064 { 00065 } 00066 00067 RootBranch:: 00068 ~RootBranch() 00069 { 00070 } 00071 00072 unsigned int 00073 RootBranch:: 00074 size () const 00075 { 00076 assert ( false ); // branch doesn't know its size yet 00077 00078 return 0; 00079 } 00080 00081 00082 bool 00083 RootBranch:: 00084 empty () const 00085 { 00086 return false; 00087 } 00088 00089 bool 00090 RootBranch:: 00091 isFilled ( ) const 00092 { 00093 return true; 00094 } 00095 00096 bool 00097 RootBranch:: 00098 isMultiDimensional() const 00099 { 00100 return ! ( m_number_elements == 1 ); 00101 } 00102 00103 00104 int 00105 RootBranch:: 00106 numberOfElements() const 00107 { 00108 return m_number_elements; 00109 } 00110 00111 TBranch * 00112 RootBranch:: 00113 getTBranch() 00114 { 00115 return m_branch; 00116 } 00117 00118 int 00119 RootBranch:: 00120 getDimSize( const char* title ) 00121 { 00122 string s( title ); 00123 00124 //Creating the list of dropped delimiters. 00125 boost::char_separator< char > sep( "][" ); 00126 00127 // A tokenizer with above dropped delimiters. 00128 typedef boost::tokenizer< boost::char_separator< char > > tokenizer; 00129 tokenizer tok( s, sep ); 00130 00131 // Start extracting the dimension sizes. 00132 for( tokenizer::iterator tok_iter = tok.begin(); 00133 tok_iter != tok.end(); 00134 ++tok_iter ) 00135 if( tok_iter != tok.begin() ) 00136 m_dims.push_back( boost::lexical_cast< unsigned int >( *tok_iter ) ); 00137 00138 return EXIT_SUCCESS; 00139 } 00140 00141 void 00142 RootBranch:: 00143 setBranchAddress () const 00144 { 00145 if( m_number_elements == 1 ) 00146 { 00147 switch ( m_leaf_type ) 00148 { 00149 case RootData::Double: 00150 m_branch -> SetAddress ( & m_double_data ); 00151 break; 00152 case RootData::Float: 00153 m_branch -> SetAddress ( & m_float_data ); 00154 break; 00155 case RootData::Int: 00156 m_branch -> SetAddress ( & m_int_data ); 00157 break; 00158 case RootData::UInt: 00159 m_branch -> SetAddress ( & m_uint_data ); 00160 break; 00161 default: 00162 assert ( false ); 00163 break; 00164 } 00165 } 00166 00167 else if( m_number_elements > 1 ) 00168 { 00169 switch ( m_leaf_type ) 00170 { 00171 case RootData::Double: 00172 m_vector_double_data = new Double_t [ m_number_elements ]; 00173 m_branch -> SetAddress ( m_vector_double_data ); 00174 break; 00175 case RootData::Float: 00176 m_vector_float_data = new Float_t [ m_number_elements ]; 00177 m_branch -> SetAddress ( m_vector_float_data ); 00178 break; 00179 case RootData::Int: 00180 m_vector_int_data = new Int_t [ m_number_elements ]; 00181 m_branch -> SetAddress ( m_vector_int_data ); 00182 break; 00183 case RootData::UInt: 00184 m_vector_uint_data = new UInt_t [ m_number_elements ]; 00185 m_branch -> SetAddress ( m_vector_uint_data ); 00186 break; 00187 default: 00188 assert ( false ); 00189 break; 00190 } 00191 00192 } 00193 00194 m_branch_set = true; 00195 } 00196 00197 unsigned int 00198 RootBranch:: 00199 rowDataDimension() const 00200 { 00201 unsigned int size = 0; 00202 if ( m_number_elements > 1 ) { // we are dealing with multidimensional data 00203 size = m_dims.size(); 00204 } 00205 00206 return size; 00207 } 00208 00209 const vector < int > & 00210 RootBranch::rowDataDimSize() 00211 { 00212 return m_dims; 00213 } 00214 00215 void 00216 RootBranch:: 00217 setReleventIndex( const std::vector< unsigned int > & index ) 00218 { 00219 // This function makes sense only for multi dimenstional data 00220 assert( rowDataDimension() > 0 ); 00221 00222 // Index should completely specify the entry of the data in the matrix 00223 // So it should have as many enteries as the dimensions of the data 00224 assert( rowDataDimension() == index.size() ); 00225 00226 // Clear old relevent entry and put in this new ones. 00227 m_releventIndex = index[0]; 00228 for ( unsigned int d = 1; d < rowDataDimension(); d++ ) { 00229 m_releventIndex = m_releventIndex * m_dims [ d ] + index[ d ]; 00230 } 00231 } 00232 00233 double 00234 RootBranch:: 00235 valueAt ( unsigned int row ) const 00236 { 00237 if ( m_branch_set == false ) setBranchAddress (); 00238 00239 Int_t entry = row; 00240 //Int_t bytes = 00241 m_branch -> GetEntry ( entry, 1 ); 00242 00243 double value = -1; 00244 if( m_number_elements == 1 ) 00245 { 00246 switch ( m_leaf_type ) 00247 { 00248 case RootData::Double: 00249 value = m_double_data; 00250 break; 00251 case RootData::Float: 00252 value = m_float_data; 00253 break; 00254 case RootData::Int: 00255 value = m_int_data; 00256 break; 00257 case RootData::UInt: 00258 value = m_uint_data; 00259 break; 00260 default: 00261 assert ( false ); 00262 break; 00263 } 00264 } 00265 else 00266 { 00267 if ( m_releventIndex < 0 || m_number_elements <= m_releventIndex ) 00268 { 00269 std::string what ( "RootBranch: `" ); 00270 what += m_leaf -> GetTitle (); 00271 what += "' indices not set properly."; 00272 throw DataSourceException ( what ); 00273 } 00274 00275 // The basic conversion formulae 00276 switch ( m_leaf_type ) 00277 { 00278 case RootData::Double: 00279 value = m_vector_double_data [ m_releventIndex ]; 00280 break; 00281 case RootData::Float: 00282 value = m_vector_float_data [ m_releventIndex ]; 00283 break; 00284 case RootData::Int: 00285 value = m_vector_int_data [ m_releventIndex ]; 00286 break; 00287 case RootData::UInt: 00288 value = m_vector_uint_data [ m_releventIndex ]; 00289 break; 00290 default: 00291 assert ( false ); 00292 } 00293 } 00294 00295 return value; 00296 } 00297 00298 double * 00299 RootBranch:: 00300 doubleArrayAt ( unsigned int row ) 00301 { 00302 if ( m_branch_set == false ) setBranchAddress (); 00303 Int_t entry = row; 00304 // Int_t bytes = 00305 m_branch -> GetEntry ( entry, 1 ); 00306 00307 return m_vector_double_data; 00308 } 00309 00310 float * 00311 RootBranch:: 00312 floatArrayAt ( unsigned int row ) 00313 { 00314 if ( m_branch_set == false ) setBranchAddress (); 00315 Int_t entry = row; 00316 // Int_t bytes = 00317 m_branch -> GetEntry ( entry, 1 ); 00318 00319 return m_vector_float_data; 00320 } 00321 00322 int * 00323 RootBranch:: 00324 intArrayAt ( unsigned int row ) 00325 { 00326 if ( m_branch_set == false ) setBranchAddress (); 00327 Int_t entry = row; 00328 // Int_t bytes = 00329 m_branch -> GetEntry ( entry, 1 ); 00330 00331 return m_vector_int_data; 00332 } 00333 00334 00335 00336 RootData::Type 00337 RootBranch:: 00338 getType () const 00339 { 00340 return m_leaf_type; 00341 }