00001 #include "RawFile/RawFileReader.h"
00002 #include "RawFile/raw_ifstream.h"
00003 #include "RawFile/EvtIdxHandler.h"
00004 #include "RawFile/RawFileTools.h"
00005 #include "IRawFile/RawFileExceptions.h"
00006 #include <cstdlib>
00007
00008 #define DefaultEventBufferSize 1024*32
00009 #define EstimatedEventSize 1024*14
00010
00011 std::vector<int> RawFileReader::getEventNumber(const VFileNames_t& idxfnames)
00012 {
00013 uint32_t itmp[2];
00014 std::vector<int> vNevt;
00015
00016 const VFileNames_t newfnames = RawFileTools::wildcard_correct(idxfnames);
00017 VFileNames_t::const_iterator it = newfnames.begin();
00018 while ( it != newfnames.end() ) {
00019 if ( access( it->c_str(), F_OK ) < 0 ) {
00020 std::cerr << "[RawFile] Invalid IDX file: " << *it << std::endl;
00021 exit(1);
00022 }
00023
00024 std::ifstream fs( it->c_str(), std::ios::binary );
00025
00026 fs.read( (char*)(itmp), sizeof(uint32_t)*2 );
00027 if ( itmp[0] != EvtIdxHandler::IdxFileStartMarker() ) {
00028 std::cerr << "[RawFile] Wrong IdxFileStartMarker!" << std::endl;
00029 exit(1);
00030 }
00031 vNevt.push_back(itmp[1]);
00032 ++it;
00033 }
00034
00035 return vNevt;
00036 }
00037
00038 RawFileReader::RawFileReader(const std::string& fname)
00039 : m_bufferSize(DefaultEventBufferSize),
00040 m_buffer( new uint32_t[DefaultEventBufferSize] ),
00041 m_idxHandler(0)
00042 {
00043 const VFileNames_t newfnames = RawFileTools::wildcard_correct(fname);
00044
00045 m_rfs = raw_ifstream::instance(newfnames);
00046 }
00047
00048 RawFileReader::RawFileReader(const VFileNames_t& fnames)
00049 : m_bufferSize(DefaultEventBufferSize),
00050 m_buffer( new uint32_t[DefaultEventBufferSize] ),
00051 m_idxHandler(0)
00052 {
00053 const VFileNames_t newfnames = RawFileTools::wildcard_correct(fnames);
00054
00055 m_rfs = raw_ifstream::instance(newfnames);
00056 }
00057
00058 RawFileReader::RawFileReader(const std::string& fname, const std::string& idxfname)
00059 : m_bufferSize(DefaultEventBufferSize),
00060 m_buffer( new uint32_t[DefaultEventBufferSize] )
00061 {
00062 const VFileNames_t newfnames = RawFileTools::wildcard_correct(fname);
00063 const VFileNames_t newidxfnames = RawFileTools::wildcard_correct(idxfname);
00064
00065 if ( newidxfnames.size() != newfnames.size() ) {
00066 std::cerr << "[RawFile] Num(IdxFiles) != Num(DataFiles)" << std::endl;
00067 exit(1);
00068 }
00069
00070 m_rfs = raw_ifstream::instance(newfnames);
00071 m_idxHandler = EvtIdxHandler::instance(newidxfnames);
00072 }
00073
00074 RawFileReader::RawFileReader(const VFileNames_t& fnames, const VFileNames_t& idxfnames)
00075 : m_bufferSize(DefaultEventBufferSize),
00076 m_buffer( new uint32_t[DefaultEventBufferSize] )
00077 {
00078 const VFileNames_t newfnames = RawFileTools::wildcard_correct(fnames);
00079 const VFileNames_t newidxfnames = RawFileTools::wildcard_correct(idxfnames);
00080
00081 if ( newidxfnames.size() != newfnames.size() ) {
00082 std::cerr << "[RawFile] Num(IdxFiles) != Num(DataFiles)" << std::endl;
00083 exit(1);
00084 }
00085
00086 m_rfs = raw_ifstream::instance(newfnames);
00087 m_idxHandler = EvtIdxHandler::instance(newidxfnames);
00088 }
00089
00090 RawFileReader::~RawFileReader()
00091 {
00092 delete[] m_buffer;
00093 raw_ifstream::release();
00094 EvtIdxHandler::release();
00095 }
00096
00097 const uint32_t* RawFileReader::nextEvent()
00098 {
00099
00100 raw_ifstream::lock();
00101
00102 try {
00103 notSafeNextEvent();
00104 }
00105 catch ( ReachEndOfFileList& e) {
00106 raw_ifstream::unlock();
00107 throw e;
00108 }
00109 catch ( RawFileException& e) {
00110 raw_ifstream::unlock();
00111 e.print();
00112 throw e;
00113 }
00114
00115 raw_ifstream::unlock();
00116
00117 return m_buffer;
00118 }
00119
00120 const uint32_t* RawFileReader::nextEvent(int nIgnore)
00121 {
00122
00123 int nnIgnore = nIgnore;
00124
00125 try {
00126 if ( m_idxHandler != 0 ) {
00127 int nleft = m_idxHandler->nEvtLeft(nnIgnore);
00128 if ( nleft > 0 ) {
00129 m_rfs->seekg( m_idxHandler->nextPos( nnIgnore ) );
00130 nnIgnore = 0;
00131 }
00132 else {
00133 nnIgnore = -nleft;
00134 throw ReachEndOfFile( currentFile().c_str() );
00135 }
00136 }
00137 else {
00138 while ( nnIgnore > 0 ) {
00139 (*m_rfs) >> m_dataSeparatorRecord;
00140 uint32_t size = m_dataSeparatorRecord.getRecord().data_block_size;
00141 m_rfs->seekg( size + m_rfs->tellg() );
00142 --nnIgnore;
00143 }
00144 }
00145
00146 read_one_event();
00147 }
00148 catch (RawFileException& e) {
00149 nextFile(e).nextEvent(nnIgnore);
00150 }
00151
00152 return m_buffer;
00153 }
00154
00155 const uint32_t* RawFileReader::findEventById(uint32_t evtId)
00156 {
00157
00158
00159 try {
00160 if ( m_idxHandler == 0 ) {
00161 while ( true ) {
00162 read_one_event();
00163 uint32_t curEvtId = m_buffer[ m_buffer[5] + 8 ];
00164 if ( curEvtId == evtId ) {
00165 break;
00166 }
00167 }
00168 }
00169 else {
00170 uint32_t pos = m_idxHandler->findPosById( evtId );
00171 if ( pos != 0 ) {
00172 m_rfs->seekg( pos );
00173 read_one_event();
00174 }
00175 else {
00176 throw ReachEndOfFile( currentFile().c_str() );
00177 }
00178 }
00179 }
00180 catch (RawFileException& e) {
00181 return nextFile(e).findEventById(evtId);
00182 }
00183
00184 return m_buffer;
00185 }
00186
00187 const uint32_t* RawFileReader::roughlyNextEvent(int nIgnore, int evtByte)
00188 {
00189
00190 if ( evtByte == 0 ) evtByte = EstimatedEventSize;
00191
00192 assert( (evtByte&3) == 0 );
00193
00194 uint32_t prePos = m_rfs->tellg();
00195 m_rfs->seekg( prePos + nIgnore*evtByte);
00196
00197 uint32_t halfEvtWord = evtByte / 8;
00198 uint32_t halfEvtByte = halfEvtWord * 4;
00199
00200 while ( m_rfs->read((char*)m_buffer, halfEvtByte).good() ) {
00201 uint32_t i = 0;
00202 while ( i < halfEvtWord && m_buffer[i] != 0x1234cccc ) {
00203 ++i;
00204 }
00205 if ( i < halfEvtWord ) {
00206 uint32_t curPos = m_rfs->tellg();
00207 m_rfs->seekg( curPos - (halfEvtWord-i)*4 );
00208 read_one_event();
00209 return m_buffer;
00210 }
00211 }
00212
00213
00214 m_rfs->clear();
00215 m_rfs->seekg( -40, std::ios::end );
00216 uint32_t curPos = m_rfs->tellg();
00217
00218 int nnIgnore = nIgnore - (curPos - prePos) / evtByte;
00219 if ( nnIgnore < 0 ) nnIgnore = 0;
00220
00221 ReachEndOfFile e( currentFile().c_str() );
00222 return nextFile(e).roughlyNextEvent(nnIgnore, evtByte);
00223 }
00224 uint32_t RawFileReader::runNo()
00225 {
00226 return m_rfs->runNo();
00227 }
00228
00229 std::string RawFileReader::currentFile()
00230 {
00231 return m_rfs->currentFile();
00232 }
00233
00234 uint32_t RawFileReader::tellg()
00235 {
00236 return m_rfs->tellg();
00237 }
00238
00239 uint32_t RawFileReader::stat()
00240 {
00241 uint32_t stat = 0;
00242
00243 if ( m_rfs->eof() ) stat |= 1;
00244 if ( m_rfs->fail() ) stat |= 2;
00245 if ( m_rfs->bad() ) stat |= 4;
00246
00247 return stat;
00248 }
00249
00250 const uint32_t* RawFileReader::notSafeNextEvent()
00251 {
00252 try {
00253 read_one_event();
00254 }
00255 catch (RawFileException& e) {
00256 nextFile(e).notSafeNextEvent();
00257 }
00258
00259 return m_buffer;
00260 }
00261
00262 void RawFileReader::read_one_event()
00263 {
00264 (*m_rfs) >> m_dataSeparatorRecord;
00265
00266 uint32_t size = m_dataSeparatorRecord.getRecord().data_block_size;
00267 if ( size > m_bufferSize*4 ) {
00268 while ( size > m_bufferSize*4 ) {
00269 m_bufferSize *= 2;
00270 }
00271 delete[] m_buffer;
00272 m_buffer = new uint32_t[m_bufferSize];
00273 }
00274
00275 m_rfs->read((char*)m_buffer, size);
00276 if ( ! m_rfs->good() ) {
00277
00278 throw BadInputStream("event_data_block");
00279 }
00280 }
00281
00282 RawFileReader& RawFileReader::nextFile(RawFileException& e)
00283 {
00284 e.print();
00285
00286 m_rfs->clear();
00287 m_rfs->next_file();
00288
00289 if ( m_idxHandler != 0 ) {
00290 m_idxHandler->next_file();
00291 }
00292
00293 return *this;
00294 }