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

Go to the documentation of this file.
00001 #include "SIO/SIOWriter.h" 
00002 
00003 #include "EVENT/LCEvent.h"
00004 #include "EVENT/LCRunHeader.h"
00005 #include "EVENT/LCIO.h"
00006 #include "EVENT/LCCollection.h"
00007 
00008 #include "SIO/LCSIO.h"
00009 #include "SIO/SIOEventHandler.h" 
00010 #include "SIO/SIOCollectionHandler.h" 
00011 //#include "SIO/SIOLCRelationHandler.h" 
00012 #include "SIO/SIORunHeaderHandler.h" 
00013 
00014 #include "SIO/SIORandomAccessHandler.h"
00015 #include "SIO/SIOIndexHandler.h"
00016 
00017 #include "LCIOSTLTypes.h"
00018 
00019 #include "SIO_streamManager.h" 
00020 #include "SIO_recordManager.h" 
00021 #include "SIO_blockManager.h" 
00022 #include "SIO_stream.h" 
00023 #include "SIO_record.h" 
00024 #include "IMPL/LCIOExceptionHandler.h"
00025 
00026 //#define DEBUG 1
00027 #include "IMPL/LCTOOLS.h"
00028 #include "IMPL/LCRelationImpl.h" 
00029 
00030 #include <cstring>
00031 
00032 using namespace EVENT ;
00033 using namespace IO ;
00034 using namespace IMPL ;
00035 
00036 namespace SIO {
00037 
00038   SIOWriter::SIOWriter() :  _stream(0),
00039                             _compressionLevel(-1), 
00040                             _hdrHandler(0), 
00041                             _runHandler(0)  {
00042     
00043 #ifdef DEBUG
00044     SIO_streamManager::setVerbosity( SIO_ALL ) ;
00045     SIO_recordManager::setVerbosity( SIO_ALL ) ;
00046     SIO_blockManager::setVerbosity( SIO_ALL ) ;
00047 #else
00048     SIO_streamManager::setVerbosity( SIO_SILENT ) ;
00049     SIO_recordManager::setVerbosity( SIO_SILENT ) ;
00050     SIO_blockManager::setVerbosity(  SIO_SILENT ) ;
00051 #endif
00052 //     SIO_streamManager::setVerbosity( SIO_ERRORS ) ;
00053 //     SIO_recordManager::setVerbosity( SIO_ERRORS ) ;
00054 //     SIO_blockManager::setVerbosity(  SIO_ERRORS ) ;
00055 
00056 
00057     _runHandler = new SIORunHeaderHandler( LCSIO_RUNBLOCKNAME  ) ;
00058     _hdrHandler = new SIOEventHandler( LCSIO_HEADERBLOCKNAME ) ;
00059   
00060 //     _evtRecord = LCSIO::records()[ SIORecords::Event ] ;
00061 //     _hdrRecord = LCSIO::records()[ SIORecords::Header ] ;
00062 //     _runRecord = LCSIO::records()[ SIORecords::Run ] ;
00063     
00064     LCSIO::records() ; // initialize global SIO records
00065 
00066     LCIOExceptionHandler::createInstance() ;
00067 
00068   }
00069 
00070   SIOWriter::~SIOWriter(){
00071     
00072     delete _hdrHandler ;
00073     delete _runHandler ;
00074     SIO_blockManager::clear();
00075     
00076   }
00077 
00078 
00079 
00080   void SIOWriter::open(const std::string & filename) throw(IOException, std::exception){
00081 
00082     std::string sioFilename ;  
00083     getSIOFileName( filename, sioFilename ) ;
00084 
00085     // if the file exists we throw an exception
00086 
00087     FILE* f = FOPEN( sioFilename.c_str() , "r") ;
00088     if( f != 0 ){
00089       FCLOSE(f) ;
00090       throw IOException( std::string( "[SIOWriter::open()] File already exists: " 
00091                                       + sioFilename
00092                                       + " \n              open it in append or new mode !\n"
00093                                       )) ;
00094     }
00095     // open new file for writing
00096     return open( filename, EVENT::LCIO::WRITE_NEW ) ;
00097   }
00098 
00099   void SIOWriter::getSIOFileName(const std::string& filename, 
00100                                  std::string& sioFilename ) {
00101 
00102 
00103     if( filename.rfind(LCSIO::FILE_EXTENSION) == std::string::npos ||  // .slcio not found at all
00104         !(  filename.rfind(LCSIO::FILE_EXTENSION)
00105             + strlen( LCSIO::FILE_EXTENSION ) == filename.length() ) ) {  // found, but not at end 
00106       
00107       // find_last_of looks for characters and not substrings !!
00108 //     if( filename.find_last_of(LCSIO::FILE_EXTENSION) != filename.length() - 1  ) {
00109 
00110       sioFilename = filename + LCSIO::FILE_EXTENSION ;
00111     } 
00112     else 
00113       sioFilename = filename ;    
00114   } 
00115 
00116   void SIOWriter::open(const std::string& filename, int writeMode) throw(IOException, std::exception) {
00117 
00118     
00119     // make sure filename has the proper extension (.slcio) 
00120     std::string sioFilename ;  
00121     getSIOFileName( filename, sioFilename ) ;
00122 
00123     // SIO has some rules about valid names for streams, records, etc ...
00124     //    const char* stream_name = LCSIO::getValidSIOName(sioFilename) ;
00125     std::string stream_name = LCSIO::getValidSIOName(sioFilename) ;
00126     _stream = SIO_streamManager::add(  stream_name.c_str() , 32*SIO_KBYTE*SIO_KBYTE ) ;
00127     
00128     if( _stream == 0 )
00129       throw IOException( std::string( "[SIOWriter::open()] Bad or duplicate stream name: " 
00130                                       + stream_name  )) ;
00131 
00132     // SIO_stream takes any value and maps it to [-1,0,1...,9]
00133     _stream->setCompressionLevel( _compressionLevel ) ;
00134     
00135 
00136     unsigned int  status = 0  ;
00137     
00138 
00139     switch( writeMode ) 
00140       {
00141       case EVENT::LCIO::WRITE_NEW : 
00142 
00143         status  = _stream->open( sioFilename.c_str() , SIO_MODE_WRITE_NEW ) ; 
00144 
00145         break ;
00146 
00147       case EVENT::LCIO::WRITE_APPEND : 
00148 
00149         // try to read the last LCIORandomAccess record at the end --------------------
00150         status  = _stream->open( sioFilename.c_str() , SIO_MODE_READ ) ; 
00151 
00152         if( status != SIO_STREAM_SUCCESS ) 
00153           throw IOException( std::string( "[SIOWriter::open()] Can't open stream for reading TOC: "
00154                                           + sioFilename ) ) ;
00155 
00156         bool hasRandomAccess = _raMgr.initAppend( _stream ) ;
00157         
00158         _stream->close() ;
00159 
00160         if( hasRandomAccess ) {
00161           status  = _stream->open( sioFilename.c_str() , SIO_MODE_READ_WRITE ) ; // SIO_MODE_WRITE_APPEND ) ; 
00162           // position at the beginnning of the file record which will then be overwritten with the next record ...
00163           LCSIO::seekStream( _stream, -LCSIO_RANDOMACCESS_SIZE ) ; 
00164         } else {
00165 
00166           // --- old files: ll simjopen the file in append mode         
00167           status  = _stream->open( sioFilename.c_str() , SIO_MODE_WRITE_APPEND ) ; 
00168 
00169         }
00170 
00171         break ;
00172       }
00173 
00174     if( !(status &1) )
00175       throw IOException( std::string( "[SIOWriter::open()] Couldn't open file: " 
00176                                       +  sioFilename ) ) ;
00177     
00178     
00179     LCSIO::records().setCompress( _compressionLevel != 0 ) ;  
00180   }
00181 
00182   void SIOWriter::setCompressionLevel(int level) {
00183     _compressionLevel = level ;
00184   }
00185 
00186 
00187   void SIOWriter::writeRunHeader(const EVENT::LCRunHeader * hdr)  throw(IOException, std::exception) {
00188 
00189 
00190     SIO_record* runRecord = LCSIO::records()[ SIORecords::Run ] ;
00191     runRecord->connect( _runHandler );
00192 
00193     _runHandler->setRunHeader(  hdr ) ;
00194     
00195     if( _stream->getState()== SIO_STATE_OPEN ){
00196       
00197       LCSIO::records().setCompress( _compressionLevel != 0 ) ; 
00198       
00199       // write LCRunHeader record
00200       unsigned int status =  _stream->write( LCSIO_RUNRECORDNAME    ) ;
00201       
00202 
00203       // store position for random access records
00204       _raMgr.add( RunEvent(  hdr->getRunNumber(), -1 ) , _stream->lastRecordStart() ) ;
00205 
00206 //       std::cout << " writeRunHeader " << hdr->getRunNumber()   << " at position : " << _stream->lastRecordStart()  
00207 //              << std::endl ;
00208 
00209       if( !(status & 1)  )
00210         throw IOException( std::string( "[SIOWriter::writeRunHeader] couldn't write run header to stream: "
00211                                         +  *_stream->getName() ) ) ;
00212     } else {
00213       
00214       throw IOException( std::string( "[SIOWriter::writeRunHeader] stream not opened: "
00215                                       +  *_stream->getName() ) ) ;
00216       
00217     }
00218   }
00219 
00220 
00221 
00222   /** Creates Handlers needed for writing the event on this stream.
00223    * Needs to be called for every event.
00224    */
00225   void SIOWriter::setUpHandlers(const LCEvent * evt){
00226   
00227     
00228     //    _hdrRecord->disconnect( LCSIO_HEADERBLOCKNAME ) ;
00229 
00230     SIO_record* hdrRecord = LCSIO::records()[ SIORecords::Header ] ;
00231     hdrRecord->connect( _hdrHandler ) ;
00232     
00233     // need to disconnect all blocks for multiple I/O streams
00234     SIO_record* evtRecord = LCSIO::records()[ SIORecords::Event ] ;
00235     evtRecord->disconnectAll() ;
00236     
00237     const std::vector<std::string>* strVec = evt->getCollectionNames() ;
00238     
00239     for( std::vector<std::string>::const_iterator name = strVec->begin() ; name != strVec->end() ; name++){
00240       
00241       
00242       SIOCollectionHandler* ch = dynamic_cast<SIOCollectionHandler*> 
00243         ( SIO_blockManager::get( name->c_str() )  ) ;
00244       
00245       LCCollection* col = evt->getCollection( *name ) ;
00246       
00247       if(! col->isTransient() ){ // if a collection is transient we simply ignore it
00248 
00249         try{
00250 
00251           if( ch == 0 ) {
00252             ch =  new SIOCollectionHandler( *name, col->getTypeName())  ;
00253           }
00254 
00255           evtRecord->connect( ch ) ;
00256 
00257           ch->setCollection( col ) ; 
00258           
00259         } 
00260         catch(Exception& ex){   // unsuported type !
00261           delete ch ;
00262           ch =  0 ;
00263         }
00264         
00265       }
00266     } 
00267   }
00268 
00269   void SIOWriter::writeEvent(const LCEvent* evt)  throw(IOException, std::exception) {
00270 
00271     
00272     //here we set up the collection handlers 
00273     
00274     try{   setUpHandlers( evt) ;
00275     
00276     }catch(...){
00277       throw IOException(  "[SIOWriter::writeEvent] could not set up handlers " ) ;
00278     }
00279 
00280     LCSIO::records().setCompress( _compressionLevel != 0 ) ; 
00281 
00282     if( _stream->getState()== SIO_STATE_OPEN ){
00283    
00284       // need to set the event in event header handler
00285       _hdrHandler->setEvent( evt ) ;
00286 
00287       unsigned int  status = 0  ;
00288 
00289 
00290       // write LCEventHeader record
00291       status =  _stream->write( LCSIO_HEADERRECORDNAME    ) ;
00292 
00293       _raMgr.add( RunEvent(  evt->getRunNumber(), evt->getEventNumber()  ) , _stream->lastRecordStart() ) ;
00294 
00295 //       std::cout << " writeEventHeader " << evt->getRunNumber() << " - " << evt->getEventNumber()    
00296 //              << " at position : " << _stream->lastRecordStart()  
00297 //              << std::endl ;      
00298 
00299       if( ! (status & 1) )
00300         throw IOException(  std::string("[SIOWriter::writeEvent] couldn't write event header to stream: "
00301                                         +  *_stream->getName() )) ;
00302       
00303       
00304       // write the event record
00305       status =  _stream->write( LCSIO_EVENTRECORDNAME    ) ;
00306 
00307       if( ! (status & 1) )
00308         throw IOException(  std::string("[SIOWriter::writeEvent] couldn't write event header to stream: "
00309                                         +  *_stream->getName() )) ;
00310     }
00311     else      
00312 
00313       throw IOException(  std::string("[SIOWriter::writeEvent] stream not opened : "
00314                                       +  *_stream->getName()  )) ;
00315     
00316   }
00317 
00318 
00319   void SIOWriter::close() throw (IOException, std::exception) {
00320   
00321     
00322     _raMgr.writeRandomAccessRecords( _stream ) ;
00323 
00324 
00325     const std::string* streamName  = _stream->getName() ;
00326 
00327     int status  =  SIO_streamManager::remove( _stream ) ;
00328     
00329     if(! (status &1) ) 
00330       throw IOException(  std::string("[SIOWriter::close] couldn't close stream  : "
00331                                       + *streamName  )) ;
00332 
00333   }
00334 
00335   void SIOWriter::flush() throw (IOException, std::exception) {
00336   
00337     const std::string* streamName  = _stream->getName() ;
00338 
00339     int status =  _stream->flush() ;
00340     
00341     if(! (status &1) ) 
00342       throw IOException(  std::string("[SIOWriter::flush] couldn't flush stream  : "
00343                                       + *streamName  )) ;
00344 
00345   }
00346 
00347 } // namespace
00348 

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