00001 #include "SIO/SIOReader.h"
00002
00003
00004 #include "SIO/LCSIO.h"
00005 #include "SIO/SIOEventHandler.h"
00006 #include "SIO/SIOCollectionHandler.h"
00007
00008 #include "SIO/SIORunHeaderHandler.h"
00009 #include "SIO/SIOParticleHandler.h"
00010
00011 #include "SIO/SIORandomAccessHandler.h"
00012 #include "SIO/SIOIndexHandler.h"
00013
00014 #include "LCIOSTLTypes.h"
00015
00016 #include "EVENT/LCIO.h"
00017
00018 #include "SIO_streamManager.h"
00019 #include "SIO_recordManager.h"
00020 #include "SIO_blockManager.h"
00021 #include "SIO_stream.h"
00022 #include "SIO_record.h"
00023 #include "IMPL/LCIOExceptionHandler.h"
00024
00025
00026 #include <iostream>
00027 #include <sstream>
00028 #include <vector>
00029 #include <algorithm>
00030 #include <cstring>
00031 #include <climits>
00032
00033
00034
00035
00036 using namespace EVENT ;
00037 using namespace IO ;
00038 using namespace IOIMPL ;
00039 using namespace IMPL ;
00040
00041 typedef EVENT::long64 long64 ;
00042
00043
00044
00045 namespace SIO {
00046
00047
00048
00049
00050 SIOReader::SIOReader( int lcReaderFlag ) :
00051 _readEventMap( lcReaderFlag & LCReader::directAccess )
00052
00053
00054
00055 {
00056 _myFilenames = 0 ;
00057 _currentFileIndex = 0 ;
00058
00059 _evtP = new LCEventIOImpl* ;
00060 *_evtP = 0 ;
00061
00062 _runP = new LCRunHeaderIOImpl* ;
00063 *_runP = 0 ;
00064
00065
00066 _runHandler = new SIORunHeaderHandler( LCSIO_RUNBLOCKNAME, _runP ) ;
00067 _evtHandler = new SIOEventHandler( LCSIO_HEADERBLOCKNAME, _evtP ) ;
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 #ifdef DEBUG
00081 SIO_streamManager::setVerbosity( SIO_ALL ) ;
00082 SIO_recordManager::setVerbosity( SIO_ALL ) ;
00083 SIO_blockManager::setVerbosity( SIO_ALL ) ;
00084 #else
00085 SIO_streamManager::setVerbosity( SIO_SILENT ) ;
00086 SIO_recordManager::setVerbosity( SIO_SILENT ) ;
00087 SIO_blockManager::setVerbosity( SIO_SILENT ) ;
00088 #endif
00089
00090
00091 LCIOExceptionHandler::createInstance() ;
00092
00093
00094 }
00095
00096 SIOReader::~SIOReader(){
00097
00098 delete *_evtP ;
00099 delete *_runP ;
00100 delete _evtP ;
00101 delete _runP ;
00102 delete _runHandler ;
00103 delete _evtHandler ;
00104
00105
00106 SIO_blockManager::clear() ;
00107 }
00108
00109 void SIOReader::open(const std::vector<std::string>& filenames)
00110 throw( IOException , std::exception){
00111
00112 unsigned int i;
00113 struct stat fileinfo ;
00114 std::string missing_files;
00115
00116
00117 for(i=0; i < filenames.size(); i++){
00118
00119 if ( FSTAT( filenames[i].c_str(), &fileinfo ) != 0 ){
00120 missing_files += filenames[i] ;
00121 missing_files += " " ;
00122 }
00123 }
00124
00125
00126 if( missing_files.size() != 0 ){
00127 throw IOException( std::string( "[SIOReader::open()] File(s) not found: " + missing_files )) ;
00128 }
00129
00130 _myFilenames = &filenames ;
00131 _currentFileIndex = 0 ;
00132 open( (*_myFilenames)[ _currentFileIndex ] ) ;
00133 }
00134
00135 void SIOReader::open(const std::string& filename) throw( IOException , std::exception) {
00136
00137
00138 std::string sioFilename ;
00139
00140
00141
00142
00143 sioFilename = filename ;
00144
00145 std::string stream_name = LCSIO::getValidSIOName(sioFilename) ;
00146 _stream = SIO_streamManager::add( stream_name.c_str() , 64 * SIO_KBYTE ) ;
00147
00148 if( _stream == 0 )
00149 throw IOException( std::string( "[SIOReader::open()] Bad stream name: "
00150 + stream_name )) ;
00151
00152 int status = _stream->open( sioFilename.c_str() , SIO_MODE_READ ) ;
00153
00154 if( status != SIO_STREAM_SUCCESS )
00155 throw IOException( std::string( "[SIOReader::open()] Can't open stream: "
00156 + sioFilename ) ) ;
00157
00158 LCSIO::records() ;
00159
00160 if( _readEventMap ){
00161
00162 getEventMap() ;
00163 }
00164
00165 }
00166
00167 void SIOReader::getEventMap() {
00168
00169 _raMgr.getEventMap( _stream ) ;
00170 }
00171
00172
00173
00174 void SIOReader::readRecord() throw (IOException , EndOfDataException , std::exception) {
00175
00176 SIO_blockManager::remove( LCSIO_RUNBLOCKNAME ) ;
00177 SIO_blockManager::add( _runHandler ) ;
00178
00179 SIO_blockManager::remove( LCSIO_HEADERBLOCKNAME ) ;
00180 SIO_blockManager::add( _evtHandler ) ;
00181
00182
00183 if( _stream->getState()== SIO_STATE_OPEN ){
00184
00185 unsigned int status = _stream->read( &_dummyRecord ) ;
00186
00187 if( ! (status & 1) ){
00188
00189 if( status & SIO_STREAM_EOF ){
00190
00191
00192 if( _myFilenames != 0 && ++_currentFileIndex < _myFilenames->size() ){
00193 close() ;
00194
00195 open( (*_myFilenames)[ _currentFileIndex ] ) ;
00196
00197 readRecord() ;
00198 return ;
00199 }
00200
00201 throw EndOfDataException("EOF") ;
00202 }
00203
00204 throw IOException( std::string(" io error on stream: ") + *_stream->getName() ) ;
00205
00206 }
00207
00208
00209
00210 if( ! strcmp( _dummyRecord->getName()->c_str() , LCSIO_HEADERRECORDNAME )){
00211 setUpHandlers() ;
00212 }
00213
00214
00215 }else{
00216 throw IOException( std::string(" stream not open: ")+ *_stream->getName() ) ;
00217 }
00218 }
00219
00220
00221 LCRunHeader* SIOReader::readNextRunHeader() throw (IOException , std::exception ) {
00222 return readNextRunHeader( LCIO::READ_ONLY ) ;
00223 }
00224
00225 LCRunHeader* SIOReader::readNextRunHeader(int accessMode) throw (IOException , std::exception ) {
00226
00227
00228
00229 SIORecords::Unpack runUnp( SIORecords::Unpack::Run ) ;
00230
00231
00232
00233 try{
00234 readRecord() ;
00235 }
00236 catch(EndOfDataException){
00237 return 0 ;
00238 }
00239
00240
00241 (*_runP)->setReadOnly( accessMode == LCIO::READ_ONLY ) ;
00242 return *_runP ;
00243 }
00244
00245 void SIOReader::setUpHandlers(){
00246
00247
00248 const std::vector<std::string>* strVec = (*_evtP)->getCollectionNames() ;
00249 for( std::vector<std::string>::const_iterator name = strVec->begin() ; name != strVec->end() ; name++){
00250
00251 const LCCollection* col = (*_evtP)->getCollection( *name ) ;
00252
00253
00254
00255 SIOCollectionHandler* ch = dynamic_cast<SIOCollectionHandler*>
00256 ( SIO_blockManager::get( name->c_str() ) ) ;
00257
00258
00259 if( ch == 0 ) {
00260
00261
00262 try{
00263 ch = new SIOCollectionHandler( *name, col->getTypeName() , _evtP ) ;
00264
00265 }
00266 catch(Exception& ex){
00267 delete ch ;
00268 ch = 0 ;
00269 }
00270
00271 }
00272
00273 if( ch != 0 )
00274 ch->setEvent( _evtP ) ;
00275
00276 }
00277 }
00278
00279
00280 LCEvent* SIOReader::readNextEvent() throw (IOException , std::exception ) {
00281
00282 return readNextEvent( LCIO::READ_ONLY ) ;
00283
00284 }
00285
00286 LCEvent* SIOReader::readNextEvent(int accessMode) throw (IOException, std::exception ) {
00287
00288
00289
00290
00291 {
00292
00293
00294 SIORecords::Unpack hdrUnp( SIORecords::Unpack::Header ) ;
00295
00296 try{
00297 readRecord() ;
00298 }
00299 catch(EndOfDataException){
00300 return 0 ;
00301 }
00302
00303 }
00304
00305 {
00306
00307 SIORecords::Unpack evtUnp( SIORecords::Unpack::Event ) ;
00308
00309 try{
00310 readRecord() ;
00311 }
00312 catch(EndOfDataException){
00313 return 0 ;
00314 }
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331 (*_evtP)->setAccessMode( accessMode ) ;
00332
00333
00334
00335 postProcessEvent() ;
00336
00337 return *_evtP ;
00338 }
00339 }
00340
00341 void SIOReader::skipNEvents(int n) throw (IO::IOException, std::exception) {
00342
00343 int eventsSkipped = 0 ;
00344
00345
00346 SIORecords::Unpack hdrUnp( SIORecords::Unpack::Header ) ;
00347
00348 while( eventsSkipped++ < n ){
00349
00350 try {
00351
00352 readRecord() ;
00353
00354 }
00355 catch(EndOfDataException){
00356
00357 return ;
00358 }
00359 }
00360
00361
00362
00363
00364 SIORecords::Unpack evtUnp( SIORecords::Unpack::Event ) ;
00365
00366 try{
00367 readRecord() ;
00368 }
00369 catch(EndOfDataException){
00370 return ;
00371 }
00372
00373 }
00374
00375 EVENT::LCEvent * SIOReader::readEvent(int runNumber, int evtNumber)
00376 throw (IOException , std::exception) {
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 if( _readEventMap ) {
00393
00394
00395 EVENT::long64 pos = _raMgr.getPosition( RunEvent( runNumber,evtNumber ) ) ;
00396
00397 if( pos != RunEventMap::NPos ) {
00398
00399 int status = _stream->seek( pos ) ;
00400
00401 if( status != SIO_STREAM_SUCCESS )
00402 throw IOException( std::string( "[SIOReader::readEvent()] Can't seek stream to"
00403 " requested position" ) ) ;
00404 return readNextEvent() ;
00405 }
00406 else {
00407
00408
00409
00410
00411 return 0 ;
00412 }
00413
00414
00415 } else {
00416
00417
00418 std::cout << " WARNING : LCReader::readEvent(run,evt) called but not in direct access Mode - " << std::endl
00419 << " use fast skip mechanism instead ..." << std::endl
00420 << " Too avoid this WARNING create the LCReader with: " << std::endl
00421 << " LCFactory::getInstance()->createLCReader( IO::LCReader::directAccess ) ; " << std::endl ;
00422
00423
00424
00425 bool runFound = false ;
00426 bool evtFound = false ;
00427
00428 if( *_runP != 0 ){
00429 if( (*_runP)->getRunNumber() == runNumber ) runFound = true ;
00430 }
00431
00432 while (!runFound ) {
00433 if( readNextRunHeader() == 0 ) break ;
00434 runFound = ( (*_runP)->getRunNumber() == runNumber ) ;
00435 }
00436 if( !runFound ){
00437
00438
00439
00440 return 0 ;
00441 }
00442 {
00443
00444 SIORecords::Unpack hdrUnp( SIORecords::Unpack::Header ) ;
00445
00446 while( !evtFound ){
00447
00448 try{
00449 readRecord() ;
00450 }
00451 catch(EndOfDataException){
00452 return 0 ;
00453 }
00454
00455 evtFound = ( (*_evtP)->getEventNumber() == evtNumber ) ;
00456 }
00457 }
00458
00459 if( !evtFound ) return 0 ;
00460
00461 {
00462 SIORecords::Unpack evtUnp( SIORecords::Unpack::Event ) ;
00463
00464 try{
00465 readRecord() ;
00466 }
00467 catch(EndOfDataException){
00468 return 0 ;
00469 }
00470
00471
00472
00473
00474 (*_evtP)->setAccessMode( LCIO::READ_ONLY ) ;
00475
00476
00477
00478 postProcessEvent() ;
00479
00480 return *_evtP ;
00481 }
00482
00483
00484 }
00485
00486 }
00487
00488 void SIOReader::close() throw (IOException, std::exception ){
00489
00490 int status = SIO_streamManager::remove( _stream ) ;
00491
00492 if(! (status &1) )
00493 throw IOException( std::string("couldn't remove stream") ) ;
00494
00495 }
00496
00497
00498
00499
00500 void SIOReader::registerLCEventListener(LCEventListener * ls){
00501 _evtListeners.insert( _evtListeners.end() , ls );
00502 }
00503 void SIOReader::removeLCEventListener(LCEventListener * ls){
00504 _evtListeners.erase( _evtListeners.find( ls ) );
00505 }
00506
00507 void SIOReader::registerLCRunListener(LCRunListener * ls){
00508 _runListeners.insert( _runListeners.end() , ls );
00509 }
00510
00511 void SIOReader::removeLCRunListener(LCRunListener * ls){
00512 _runListeners.erase( _runListeners.find( ls ) );
00513 }
00514
00515 void SIOReader::readStream() throw ( IO::IOException, std::exception ){
00516
00517 int maxInt = INT_MAX ;
00518 readStream( maxInt ) ;
00519 }
00520 void SIOReader::readStream(int maxRecord) throw (IOException, std::exception ){
00521
00522
00523 bool readUntilEOF = false ;
00524 if( maxRecord == INT_MAX ) readUntilEOF = true ;
00525
00526
00527
00528
00529
00530
00531 SIORecords::Unpack allUnp( SIORecords::Unpack::Event +
00532 SIORecords::Unpack::Header +
00533 SIORecords::Unpack::Run ) ;
00534
00535 int recordsRead = 0 ;
00536 while( recordsRead < maxRecord ){
00537
00538 try{
00539 readRecord() ;
00540 }
00541 catch(EndOfDataException){
00542
00543
00544
00545 if( readUntilEOF ){
00546 return ;
00547 }else{
00548 std::stringstream message ;
00549 message << "SIOReader::readStream(int maxRecord) : EOF before "
00550 << maxRecord << " records read from file" << std::ends ;
00551 throw EndOfDataException( message.str()) ;
00552 }
00553 }
00554
00555
00556 if( ! strcmp( _dummyRecord->getName()->c_str() , LCSIO_RUNRECORDNAME )){
00557
00558 recordsRead++ ;
00559
00560 std::set<IO::LCRunListener*>::iterator iter = _runListeners.begin() ;
00561 while( iter != _runListeners.end() ){
00562
00563 (*_runP)->setReadOnly( false ) ;
00564 (*iter)->modifyRunHeader( *_runP ) ;
00565
00566 (*_runP)->setReadOnly( true ) ;
00567 (*iter)->processRunHeader( *_runP ) ;
00568
00569 iter++ ;
00570 }
00571 }
00572
00573 if( ! strcmp( _dummyRecord->getName()->c_str() , LCSIO_EVENTRECORDNAME )){
00574
00575 recordsRead++ ;
00576
00577 std::set<IO::LCEventListener*>::iterator iter = _evtListeners.begin() ;
00578 while( iter != _evtListeners.end() ){
00579
00580
00581
00582 postProcessEvent() ;
00583
00584
00585
00586 (*_evtP)->setAccessMode( LCIO::UPDATE ) ;
00587 (*iter)->modifyEvent( *_evtP ) ;
00588
00589 (*_evtP)->setAccessMode( LCIO::READ_ONLY ) ;
00590 (*iter)->processEvent( *_evtP ) ;
00591
00592
00593 iter++ ;
00594
00595 }
00596 }
00597 }
00598 }
00599
00600 void SIOReader::postProcessEvent() {
00601
00602 SIOParticleHandler::restoreParentDaughterRelations( *_evtP ) ;
00603
00604
00605 }
00606
00607 }