Go to the documentation of this file.00001
00002 #include <boost/numeric/conversion/bounds.hpp>
00003 #include <boost/filesystem.hpp>
00004 #include <boost/foreach.hpp>
00005 #include <boost/lexical_cast.hpp>
00006
00007
00008 #include "GaudiKernel/AlgFactory.h"
00009 #include "GaudiKernel/IRegistry.h"
00010 #include "GaudiKernel/IDataManagerSvc.h"
00011 #include "GaudiKernel/IDataProviderSvc.h"
00012 #include "GaudiKernel/IOpaqueAddress.h"
00013 #include "GaudiKernel/DataStoreItem.h"
00014 #include "GaudiKernel/DataObject.h"
00015 #include "GaudiKernel/MsgStream.h"
00016 #include "SequentialOutputStream.h"
00017
00018
00019 DECLARE_ALGORITHM_FACTORY( SequentialOutputStream )
00020
00021 using namespace std;
00022 namespace bf = boost::filesystem;
00023 using boost::lexical_cast;
00024 using boost::bad_lexical_cast;
00025
00026
00027 SequentialOutputStream::SequentialOutputStream( const string& name,
00028 ISvcLocator* svc )
00029 : OutputStream( name, svc ), m_events( 0 ), m_iFile( 1 )
00030 {
00031 declareProperty( "EventsPerFile", m_eventsPerFile
00032 = boost::numeric::bounds< unsigned int>::highest() );
00033 declareProperty( "NumericFilename", m_numericFilename = false );
00034 declareProperty( "NumbersAdded", m_nNumbersAdded = 6 );
00035 }
00036
00037
00038 StatusCode SequentialOutputStream::writeObjects()
00039 {
00040 try {
00041 makeFilename();
00042 } catch ( const GaudiException& except ) {
00043 MsgStream log(msgSvc(), name());
00044 log << MSG::ERROR << except.message() << endmsg;
00045 return StatusCode::FAILURE;
00046 }
00047 return OutputStream::writeObjects();
00048 }
00049
00050
00051 StatusCode SequentialOutputStream::execute()
00052 {
00053
00054 clearSelection();
00055
00056 if ( isEventAccepted() ) {
00057 StatusCode sc = writeObjects();
00058 clearSelection();
00059 m_events++;
00060 return sc;
00061 }
00062 return StatusCode::SUCCESS;
00063 }
00064
00065
00066 void SequentialOutputStream::makeFilename()
00067 {
00068 if ( m_events % m_eventsPerFile != 0 ) return;
00069
00070 bf::path outputPath( m_outputName );
00071 string filename = outputPath.filename();
00072 bf::path dir = outputPath.parent_path();
00073 string stem = outputPath.stem();
00074 string extension = outputPath.extension();
00075
00076 if ( !dir.empty() ) {
00077 if ( !bf::exists( dir ) ) {
00078 stringstream stream;
00079 stream << "Directory " << dir << " does not exist.";
00080 throw GaudiException( stream.str(), "error", StatusCode::FAILURE );
00081 }
00082 }
00083
00084 if ( m_numericFilename ) {
00085 if ( m_events == 0 ) {
00086 try {
00087 m_iFile = lexical_cast< unsigned int >( stem );
00088 } catch( const bad_lexical_cast& ) {
00089 stringstream stream;
00090 stream << "Filename " << filename
00091 << " is not a number, which was needed.";
00092 throw GaudiException( stream.str(), "error", StatusCode::FAILURE );
00093 }
00094 }
00095 stringstream iFileStream;
00096 iFileStream << m_iFile;
00097 string iFile( iFileStream.str() );
00098 unsigned int length = 0;
00099
00100 if ( stem.length() > iFile.length() ) {
00101 length = stem.length() - iFile.length();
00102 }
00103
00104 stringstream name;
00105 if ( !dir.empty() ) {
00106 name << dir << "/";
00107 }
00108 for ( unsigned int i = 0; i < length; ++i ) {
00109 name << "0";
00110 }
00111 name << iFile << extension;
00112 m_outputName = name.str();
00113 } else {
00114 if ( m_iFile != 1 ) {
00115 size_t pos = stem.rfind( "_" );
00116 stem = stem.substr( 0, pos );
00117 }
00118
00119 stringstream iFileStream;
00120 iFileStream << m_iFile;
00121 string iFile( iFileStream.str() );
00122
00123 unsigned int length = 0;
00124 if ( m_nNumbersAdded > iFile.length() ) {
00125 length = m_nNumbersAdded - iFile.length();
00126 }
00127
00128 stringstream name;
00129 name << dir << "/" << stem;
00130 for ( unsigned int i = 0; i < length; ++i ) {
00131 if ( i == 0 ) name << "_";
00132 name << "0";
00133 }
00134 name << iFile << extension;
00135 m_outputName = name.str();
00136 }
00137 ++m_iFile;
00138 }