/data3/calcul/jacquem/working_dir/Micromegas/micromegasFrameWork/lcio/src/cpp/src/SIO/SIOReader.cc

Go to the documentation of this file.
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 //#include <limits>
00033 
00034 //#include <sys/stat.h> 
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 //#define EVENTKEY(RN,EN)  ( EVENT::long64( RN ) << 32 ) | EN 
00044  
00045 namespace SIO {
00046 
00047   
00048   //   #define DEBUG 1
00049   
00050   SIOReader::SIOReader( int lcReaderFlag ) :
00051     _readEventMap( lcReaderFlag & LCReader::directAccess  )
00052     //     :     
00053     //     _myFilenames(0), 
00054     //     _currentFileIndex(0) 
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     // debug
00071     //     std::cout << " _runHandler created : " << _runHandler 
00072     //        << " with _runP " << _runP
00073     //        << std::endl ;
00074     //     std::cout << " _evtHandler created : " << _evtHandler 
00075     //        << " with _evtP " << _evtP
00076     //        << std::endl ;
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     // JE: first we check if all files exist
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     // JE: if not raise IOException
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     // ---- we don't require the standard file extension for reading any more
00140     //if( !( filename.rfind(".") filename.length() ))
00141     //  sioFilename = filename + LCSIO::FILE_EXTENSION ;
00142     //else 
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     // read the next record from the stream
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           // if we have a list of filenames open the next file
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       // if the record was an event header, we need to set up the collection handlers
00209       // for the next event record.
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     // set the _runRecord to unpack for this scope
00228     //SIOUnpack runUnp( SIOUnpack::RUN ) ;
00229     SIORecords::Unpack runUnp( SIORecords::Unpack::Run ) ;
00230 
00231 
00232     // this might throw the exceptions
00233     try{ 
00234       readRecord() ;
00235     }
00236     catch(EndOfDataException){
00237       return 0 ;
00238     }
00239     
00240     // set the proper acces mode before returning the event
00241     (*_runP)->setReadOnly(  accessMode == LCIO::READ_ONLY   ) ;
00242     return *_runP ;
00243   }
00244   
00245   void SIOReader::setUpHandlers(){
00246 
00247     // use event *_evtP to setup the block readers from header information ....
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       // check if block handler exists in manager
00255       SIOCollectionHandler* ch = dynamic_cast<SIOCollectionHandler*> 
00256         ( SIO_blockManager::get( name->c_str() )  ) ;
00257       
00258       // if not, create a new block handler
00259       if( ch == 0 ) {
00260         
00261         // create collection handler for event
00262         try{
00263           ch =  new SIOCollectionHandler( *name, col->getTypeName() , _evtP )  ;
00264           // calls   SIO_blockManager::add( ch )  in the c'tor !
00265         }
00266         catch(Exception& ex){   // unsuported type !
00267           delete ch ;
00268           ch =  0 ;
00269         }
00270 
00271       }
00272       // else { // handler already exists
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     // first, we need to read the event header 
00290     // to know what collections are in the event
00291     { // -- scope for unpacking evt header --------
00292       
00293       //      SIOUnpack hdrUnp( SIOUnpack::EVENTHDR ) ;
00294       SIORecords::Unpack hdrUnp( SIORecords::Unpack::Header ) ;
00295 
00296       try{ 
00297         readRecord() ;
00298       }
00299       catch(EndOfDataException){
00300         return 0 ;
00301       }
00302       
00303     }// -- end of scope for unpacking evt header --
00304     
00305     { // now read the event record
00306       //      SIOUnpack evtUnp( SIOUnpack::EVENT ) ;
00307       SIORecords::Unpack evtUnp( SIORecords::Unpack::Event ) ;
00308       
00309       try{ 
00310         readRecord() ;
00311       }
00312       catch(EndOfDataException){
00313         return 0 ;
00314       }
00315       
00316 //       //---debug------------------------
00317 //       LCEventIOImpl* evt = *_evtP ; 
00318 //       const StringVec* colNames = evt->getCollectionNames() ;
00319 //       for( StringVec::const_iterator it = colNames->begin() ;
00320 //       it != colNames->end() ; it++) {
00321 //      LCCollection* col = evt->getCollection( *it ) ; 
00322 //      if( col->getTypeName() == LCIO::MCPARTICLE ) {
00323 //        for(int i=0;i < col->getNumberOfElements() ; i++){
00324 //          std::cout <<  " -- " << i << ": " << col->getElementAt(i) << std::endl ;
00325 //        }
00326 //      }
00327 //       }
00328 //       //---debug------------------------
00329 
00330       // set the proper acces mode before returning the event
00331        (*_evtP)->setAccessMode( accessMode ) ;
00332       
00333 //       // restore the daughter relations from the parent relations
00334 //       SIOParticleHandler::restoreParentDaughterRelations( *_evtP ) ;
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     //    SIOUnpack hdrUnp( SIOUnpack::EVENTHDR ) ;
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     // now we need to also read the next  record which suposedly is an event record
00362     // in order to prevent readStream from reading this event (the last to be skipped)
00363     //    SIOUnpack evtUnp( SIOUnpack::EVENT ) ;
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 //     EventMap::iterator it = _evtMap.find( EVENTKEY( runNumber,evtNumber ) ) ;
00380 //     if( it != _evtMap.end() ) {
00381 //       int status = _stream->seek( it->second ) ;
00382       
00383 //       if( status != SIO_STREAM_SUCCESS ) 
00384 //      throw IOException( std::string( "[SIOReader::readEvent()] Can't seek stream to"
00385 //                                      " requested position" ) ) ;
00386 //       return readNextEvent() ;
00387 //     } 
00388 //     else 
00389       
00390 //       return 0 ;
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         //       std::cout << " could not find event " << runNumber <<  "," << evtNumber << std::endl 
00409         //              << _raMgr ;
00410         
00411         return 0 ;
00412       }
00413 
00414 
00415     } else {  // no event map ------------------
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       // ---- OLD code with fast skip -----------
00424        
00425       bool runFound = false ;
00426       bool evtFound = false ;
00427       // check current run - if any
00428       if( *_runP != 0 ){
00429         if( (*_runP)->getRunNumber() == runNumber ) runFound = true ;
00430       }
00431       // skip through run headers until run found or EOF
00432       while (!runFound ) {
00433         if( readNextRunHeader() == 0 ) break ; 
00434         runFound = ( (*_runP)->getRunNumber() == runNumber ) ;
00435       }
00436       if( !runFound ){
00437         //       std::stringstream message ;
00438         //       message << " run not found: " << runNumber << std::ends ;
00439         //       throw NotAvailableException( message.str()  ) ;
00440         return 0 ;
00441       }
00442       { // -- scope for unpacking evt header --------
00443         //      SIORecordUnpack hdrUnp( SIOWriter::_hdrRecord ) ;
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       }// -- end of scope for unpacking evt header --
00458       
00459       if( !evtFound ) return 0 ;
00460       
00461       { // now read the event record
00462         SIORecords::Unpack evtUnp( SIORecords::Unpack::Event ) ;
00463 
00464         try{ 
00465           readRecord() ;
00466         }
00467         catch(EndOfDataException){
00468           return 0 ;
00469         }
00470         
00471         // set the proper acces mode before returning the event
00472         // FIXME : need update mode as well
00473         // (*_evtP)->setAccessMode( accessMode ) ;
00474         (*_evtP)->setAccessMode( LCIO::READ_ONLY ) ;
00475         
00476         //       // restore the daughter relations from the parent relations
00477         //       SIOParticleHandler::restoreParentDaughterRelations( *_evtP ) ;
00478         postProcessEvent() ;
00479         
00480         return *_evtP ;      
00481       }
00482      
00483 
00484     } //----------   end fast skip --------------------------------------------------   
00485    
00486   }
00487   
00488   void SIOReader::close() throw (IOException, std::exception ){
00489   
00490     int status  =  SIO_streamManager::remove( _stream ) ;
00491     
00492     if(! (status &1) ) //  return LCIO::ERROR ;
00493       throw IOException( std::string("couldn't remove stream") ) ;
00494     // return LCIO::SUCCESS ; 
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 ; // numeric_limits<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     // here we need to read all the records on the stream
00527     // and then notify the listeners depending on the type ....
00528     
00529     // set all known records to unpack 
00530 //    SIOUnpack allUnp( SIOUnpack::RUN + SIOUnpack::EVENT + SIOUnpack::EVENTHDR ) ;
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         // only throw exception if a 'finite' number of records was 
00544         // specified that couldn't be read from the file
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       // notify LCRunListeners 
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       // notify LCEventListeners 
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 //        // restore the daughter relations from the parent relations
00581 //        SIOParticleHandler::restoreParentDaughterRelations( *_evtP ) ;
00582           postProcessEvent() ;
00583 
00584           // fg20070813 changed order of update and process (needed for 
00585           // Marlin modifying processors )
00586           (*_evtP)->setAccessMode( LCIO::UPDATE ) ;
00587           (*iter)->modifyEvent( *_evtP ) ;
00588 
00589           (*_evtP)->setAccessMode( LCIO::READ_ONLY ) ; // set the proper acces mode
00590           (*iter)->processEvent( *_evtP ) ;
00591 
00592 
00593           iter++ ;
00594           
00595         }
00596       }
00597     }
00598   }
00599   
00600   void  SIOReader::postProcessEvent() {
00601     // restore the daughter relations from the parent relations
00602     SIOParticleHandler::restoreParentDaughterRelations( *_evtP ) ;
00603 //     // fill the relation map from intermediate vector
00604 //     SIOLCRelationHandler::fillRelationMap(  *_evtP ) ;
00605   }
00606 
00607 } // namespace

Generated on Mon Jan 7 13:15:21 2013 for MicromegasFramework by  doxygen 1.4.7