00001
00012 #ifdef HAVE_CONFIG_H
00013 #include "config.h"
00014 #endif
00015
00016
00017 #ifdef _MSC_VER
00018 #include "msdevstudio/MSconfig.h"
00019 #endif
00020
00021 #include "NTupleController.h"
00022
00023 #include "CircularBuffer.h"
00024 #include "DataSourceController.h"
00025
00026 #include <algorithm>
00027 #include <fstream>
00028
00029 #ifdef SSTREAM_DEFECT
00030 #include <strstream>
00031 using std::ostrstream;
00032 #else
00033 #include <sstream>
00034 using std::ostringstream;
00035 #endif
00036
00037 #include <utility>
00038 #include <cassert>
00039
00040 using std::endl;
00041 using std::map;
00042 using std::ofstream;
00043 using std::string;
00044 using std::vector;
00045
00046 NTupleController * NTupleController::s_instance = 0;
00047
00048 NTupleController::NTupleController ( )
00049 {
00050 }
00051
00054 NTupleController::NTupleController ( const NTupleController & )
00055 {
00056 assert ( false );
00057 }
00058
00059 NTupleController * NTupleController::instance ( )
00060 {
00061 if ( s_instance == 0 ) {
00062 s_instance = new NTupleController ( );
00063 }
00064 return s_instance;
00065 }
00066
00067 string::size_type
00068 NTupleController::
00069 findWhite ( const std::string & line, unsigned int left, bool tabs_only )
00070 {
00071 string::size_type right = line.find( '\t', left );
00072
00073 if( line.find( '\n', left ) < right ) right = line.find( '\n', left );
00074
00075 if ( tabs_only == false ) {
00076 if( line.find( ' ', left ) < right ) right = line.find( ' ', left );
00077 }
00078
00079 return right;
00080 }
00081
00099 int
00100 NTupleController::
00101 readAsciiNTuple ( NTuple * ntuple, const std::string & filename )
00102 {
00103 string dir_name = filename;
00104 vector<double> vals;
00105
00106 string::size_type pos = dir_name.find_last_of( '/' );
00107 if ( pos == string::npos ) {
00108 dir_name = ".";
00109 } else {
00110 dir_name.erase( pos );
00111 }
00112 dir_name += "/";
00113
00114 std::ifstream infile( filename.c_str() );
00115 if( !infile.is_open() ) {
00116 return -1;
00117 }
00118 string line;
00119 if( !std::getline( infile, line ) ) {
00120 return -2;
00121 }
00122 while( findWhite( line, 0, false ) == 0 ) line = line.substr( 1 );
00123 ntuple->setTitle ( line );
00124
00125
00126 if( !std::getline( infile, line ) ) {
00127 return -2;
00128 }
00129
00130 string::size_type size = line.size ();
00131 if ( line[size-1] == '\r' ) {
00132 line.erase ( size-1 );
00133 }
00134 line += "\n";
00135
00136 string::size_type right = findWhite( line, 0, true );
00137
00138 vector< string > labels;
00139
00140 string::size_type left = 0;
00141 while( right != line.npos ){
00142 if( right == left ){
00143 left++;
00144 right = findWhite( line, left, true );
00145 continue;
00146 }
00147 string label = line.substr( left, right - left );
00148 labels.push_back ( label );
00149
00150 left = right + 1;
00151 right = findWhite( line, left, true );
00152 }
00153 if ( labels.size () == 0 ) {
00154 return -2;
00155 }
00156
00157 ntuple->setLabels ( labels );
00158
00159 vals.resize ( labels.size() );
00160 string::size_type col = 0;
00161 while( std::getline( infile, line ) ) {
00162 line += "\n";
00163 left = 0;
00164 right = findWhite( line );
00165 while( right != line.npos ){
00166 if( right == left ){
00167 left++;
00168 right = findWhite( line, left );
00169 continue;
00170 }
00171 vals[col++] = atof( line.substr( left, right - left ).c_str() );
00172 if( col == labels.size() ){
00173 col = 0;
00174 ntuple->addRow ( vals );
00175 }
00176 left = right + 1;
00177 right = findWhite( line, left );
00178 }
00179 }
00180 if( col != 0 ){
00181
00182 return -2;
00183 }
00184 vector < unsigned int > shape ( 2 );
00185 shape[0] = ntuple -> rows();
00186 shape[1] = ntuple -> columns ();
00187 ntuple -> setShape ( shape );
00188
00189 return 0;
00190 }
00191
00192 DataSource *
00193 NTupleController::
00194 createNTuple ( const std::string & filename )
00195 {
00196 unsigned int columns = 0;
00197 NTuple * nt = new NTuple ( columns );
00198 int retval = readAsciiNTuple ( nt, filename );
00199
00200 if ( retval < 0 ) {
00201 std::string what ( "NTupleController: File\n" );
00202 what += filename + "\n";
00203 if ( retval == -1 ) {
00204 what += "could not be found.";
00205 }
00206 else {
00207 what += "has bad format.";
00208 }
00209 delete nt;
00210 throw DataSourceException ( what );
00211 }
00212
00213 DataSourceController * controller = DataSourceController::instance ();
00214 DataSource * ds = controller -> getDataSource ( filename );
00215
00216
00217 string name ( filename );
00218 while ( ds != 0 ) {
00219 name += "tnt";
00220 ds = controller -> getDataSource ( name );
00221 }
00222
00223 nt->setName ( name );
00224 controller -> registerNTuple ( name, nt );
00225 controller -> registerDataSourceFile ( nt );
00226
00227 return nt;
00228 }
00229
00230 NTuple *
00231 NTupleController::
00232 createNTuple ( const std::vector < std::string > & labels )
00233 {
00234 NTuple * nt = new NTuple ( labels );
00235 DataSourceController * controller = DataSourceController::instance ();
00236 controller -> registerNTuple ( nt );
00237
00238 return nt;
00239 }
00240
00241 CircularBuffer *
00242 NTupleController::
00243 createCircularBuffer ( const std::vector < std::string > & labels )
00244 {
00245 CircularBuffer * nt = new CircularBuffer ( labels );
00246 DataSourceController * controller = DataSourceController::instance ();
00247 controller -> registerNTuple ( nt );
00248
00249 return nt;
00250 }
00251
00252 NTuple *
00253 NTupleController::
00254 createNTuple ( unsigned int columns )
00255 {
00256 NTuple * nt = new NTuple ( columns );
00257 DataSourceController * controller = DataSourceController::instance ();
00258 controller -> registerNTuple ( nt );
00259
00260 return nt;
00261 }
00262
00263 CircularBuffer *
00264 NTupleController::
00265 createCircularBuffer ( unsigned int columns )
00266 {
00267 CircularBuffer * nt = new CircularBuffer ( columns );
00268 DataSourceController * controller = DataSourceController::instance ();
00269 controller -> registerNTuple ( nt );
00270
00271 return nt;
00272 }
00273
00274 NTuple *
00275 NTupleController::
00276 createNTuple ( )
00277 {
00278 NTuple * nt = new NTuple ();
00279 DataSourceController * controller = DataSourceController::instance ();
00280 controller -> registerNTuple ( nt );
00281
00282 return nt;
00283 }
00284
00285 CircularBuffer *
00286 NTupleController::
00287 createCircularBuffer ( )
00288 {
00289 CircularBuffer * nt = new CircularBuffer ();
00290 DataSourceController * controller = DataSourceController::instance ();
00291 controller -> registerNTuple ( nt );
00292
00293 return nt;
00294 }
00295
00296 DataSource *
00297 NTupleController::
00298 findDataSource ( const std::string & name ) const
00299 {
00300 DataSourceController * controller = DataSourceController::instance ();
00301
00302 return controller -> findDataSource ( name );
00303 }
00304
00305 void
00306 NTupleController::
00307 changeName ( DataSource * ntuple, const std::string & new_name )
00308 {
00309 ntuple -> setName ( new_name );
00310 }
00311
00312 int
00313 NTupleController::
00314 writeNTupleToFile ( const std::string & name,
00315 const std::string & filename )
00316 {
00317 DataSourceController * controller = DataSourceController::instance ();
00318 DataSource * ntuple
00319 = controller -> findDataSource ( name );
00320 if ( ntuple == 0 ) return -1;
00321
00322 return writeNTupleToFile ( ntuple, filename );
00323 }
00324
00326 int
00327 NTupleController::
00328 writeNTupleToFile ( DataSource * ntuple,
00329 const std::string & filename )
00330 {
00331 ofstream file ( filename.c_str() );
00332 if ( file.is_open () == false ) {
00333 return 1;
00334 }
00335 file << ntuple->title() << endl;
00336
00337 const vector < string > & labels = ntuple->getLabels ();
00338 #ifdef ITERATOR_MEMBER_DEFECT
00339 std::
00340 #endif
00341 vector < string > ::const_iterator first = labels.begin ();
00342 string label = *first++;
00343 file << label;
00344 while ( first != labels.end() ) {
00345 label = *first++;
00346 file << "\t" << label;
00347 }
00348 file << endl;
00349
00350 unsigned int rows = ntuple->rows ();
00351 for ( unsigned int i = 0; i < rows; i++ ) {
00352 const vector < double > & row = ntuple->getRow ( i );
00353
00354 #ifdef ITERATOR_MEMBER_DEFECT
00355 std::
00356 #endif
00357 vector < double > ::const_iterator first = row.begin();
00358 while ( first != row.end() ) {
00359 file << "\t" << *first++;
00360 }
00361 file << endl;
00362 }
00363
00364 return 0;
00365 }
00366
00370 void
00371 NTupleController::
00372 saveNTuples ( const std::string & fileprefix, const std::string & filesuffix )
00373 {
00374 string::size_type pos = fileprefix.find_last_of ( '/' );
00375 const string path = fileprefix.substr ( 0, pos + 1 );
00376 const string basename = fileprefix.substr ( pos + 1 );
00377
00378 DataSourceController * controller = DataSourceController::instance ();
00379 const vector < DataSource * > & tuples
00380 = controller->getDataSources ( false );
00381 unsigned int size = tuples.size();
00382
00383 for ( unsigned int i = 0; i < size; i++ ) {
00384 DataSource * ntuple = tuples[i];
00385 const string & tuple_name = ntuple->getName ();
00386
00387 #ifdef SSTREAM_DEFECT
00388 ostrstream strm_text;
00389 #else
00390 ostringstream strm_text;
00391 #endif
00392 strm_text << basename
00393 << i
00394 << filesuffix
00395 << std::ends;
00396 const string filename ( strm_text.str() );
00397 string tuple_file ( path );
00398 tuple_file += filename;
00399
00400 NTupleController::instance ()
00401 -> writeNTupleToFile ( tuple_name, tuple_file );
00402 controller -> changeName ( tuple_name, filename );
00403 }
00404 }
00405
00406 string
00407 NTupleController::
00408 registerNTuple ( DataSource * ds )
00409 {
00410 DataSourceController * controller = DataSourceController::instance ();
00411 controller -> registerNTuple ( ds );
00412
00413 return ds -> getName ();
00414 }
00415
00416 void
00417 NTupleController::
00418 registerNTuple ( const std::string & key, DataSource * ntuple )
00419 {
00420 DataSourceController * controller = DataSourceController::instance ();
00421 controller -> registerNTuple ( key, ntuple );
00422 }