BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
RawFileReader.cxx
Go to the documentation of this file.
1#include "RawFile/RawFileReader.h"
2#include "IRawFile/RawFileExceptions.h"
3#include "RawFile/EvtIdxHandler.h"
4#include "RawFile/RawFileTools.h"
5#include "RawFile/raw_ifstream.h"
6#include <cstdlib>
7#include <unistd.h>
8
9#define DefaultEventBufferSize 1024 * 32
10#define EstimatedEventSize 1024 * 14
11
12std::vector<int> RawFileReader::getEventNumber( const VFileNames_t& idxfnames ) {
13 uint32_t itmp[2];
14 std::vector<int> vNevt;
15
16 const VFileNames_t newfnames = RawFileTools::wildcard_correct( idxfnames );
17 VFileNames_t::const_iterator it = newfnames.begin();
18 while ( it != newfnames.end() )
19 {
20 if ( access( it->c_str(), F_OK ) < 0 )
21 {
22 std::cerr << "[RawFile] Invalid IDX file: " << *it << std::endl;
23 exit( 1 );
24 }
25
26 std::ifstream fs( it->c_str(), std::ios::binary );
27
28 fs.read( (char*)( itmp ), sizeof( uint32_t ) * 2 );
29 if ( itmp[0] != EvtIdxHandler::IdxFileStartMarker() )
30 {
31 std::cerr << "[RawFile] Wrong IdxFileStartMarker!" << std::endl;
32 exit( 1 );
33 }
34 vNevt.push_back( itmp[1] );
35 ++it;
36 }
37
38 return vNevt;
39}
40
41RawFileReader::RawFileReader( const std::string& fname )
42 : m_bufferSize( DefaultEventBufferSize )
43 , m_buffer( new uint32_t[DefaultEventBufferSize] )
44 , m_idxHandler( 0 ) {
45 const VFileNames_t newfnames = RawFileTools::wildcard_correct( fname );
46
47 // in case of idx files
48 VFileNames_t datafnames;
49 for ( int i = 0; i < newfnames.size(); ++i )
50 {
51 int size = newfnames[i].size();
52 if ( size > 4 && newfnames[i].substr( size - 4 ) == ".idx" )
53 { datafnames.push_back( newfnames[i].substr( 0, size - 4 ) ); }
54 }
55 if ( datafnames.size() == newfnames.size() )
56 {
57 m_rfs = raw_ifstream::instance( datafnames );
58 m_idxHandler = EvtIdxHandler::instance( newfnames );
59 }
60 else { m_rfs = raw_ifstream::instance( newfnames ); }
61}
62
64 : m_bufferSize( DefaultEventBufferSize )
65 , m_buffer( new uint32_t[DefaultEventBufferSize] )
66 , m_idxHandler( 0 ) {
67 const VFileNames_t newfnames = RawFileTools::wildcard_correct( fnames );
68
69 // in case of idx files
70 VFileNames_t datafnames;
71 for ( int i = 0; i < newfnames.size(); ++i )
72 {
73 int size = newfnames[i].size();
74 if ( size > 4 && newfnames[i].substr( size - 4 ) == ".idx" )
75 { datafnames.push_back( newfnames[i].substr( 0, size - 4 ) ); }
76 }
77 if ( datafnames.size() == newfnames.size() )
78 {
79 m_rfs = raw_ifstream::instance( datafnames );
80 m_idxHandler = EvtIdxHandler::instance( newfnames );
81 }
82 else { m_rfs = raw_ifstream::instance( newfnames ); }
83}
84
85RawFileReader::RawFileReader( const std::string& fname, const std::string& idxfname )
86 : m_bufferSize( DefaultEventBufferSize )
87 , m_buffer( new uint32_t[DefaultEventBufferSize] ) {
88 const VFileNames_t newfnames = RawFileTools::wildcard_correct( fname );
89 const VFileNames_t newidxfnames = RawFileTools::wildcard_correct( idxfname );
90
91 if ( newidxfnames.size() != newfnames.size() )
92 {
93 std::cerr << "[RawFile] Num(IdxFiles) != Num(DataFiles)" << std::endl;
94 exit( 1 );
95 }
96
97 m_rfs = raw_ifstream::instance( newfnames );
98 m_idxHandler = EvtIdxHandler::instance( newidxfnames );
99}
100
102 : m_bufferSize( DefaultEventBufferSize )
103 , m_buffer( new uint32_t[DefaultEventBufferSize] ) {
104 const VFileNames_t newfnames = RawFileTools::wildcard_correct( fnames );
105 const VFileNames_t newidxfnames = RawFileTools::wildcard_correct( idxfnames );
106
107 if ( newidxfnames.size() != newfnames.size() )
108 {
109 std::cerr << "[RawFile] Num(IdxFiles) != Num(DataFiles)" << std::endl;
110 exit( 1 );
111 }
112
113 m_rfs = raw_ifstream::instance( newfnames );
114 m_idxHandler = EvtIdxHandler::instance( newidxfnames );
115}
116
122
123const uint32_t* RawFileReader::nextEvent() {
124 // thread safe
126
127 try
128 {
129 if ( m_idxHandler == 0 ) { notSafeNextEvent(); }
130 else { nextEvent( 0 ); }
131 } catch ( ReachEndOfFileList& e )
132 {
134 throw e;
135 } catch ( RawFileException& e )
136 {
138 e.print();
139 throw e;
140 }
141
143
144 return m_buffer;
145}
146
147const uint32_t* RawFileReader::nextEvent( int nIgnore ) {
148 // not thread safe !!!
149 int nnIgnore = nIgnore;
150
151 try
152 {
153 if ( m_idxHandler != 0 )
154 {
155 int nleft = m_idxHandler->nEvtLeft( nnIgnore );
156 if ( nleft > 0 )
157 {
158 m_rfs->seekg( m_idxHandler->nextPos( nnIgnore ) );
159 nnIgnore = 0;
160 }
161 else
162 {
163 nnIgnore = -nleft;
164 throw ReachEndOfFile( currentFile().c_str() );
165 }
166 }
167 else
168 {
169 while ( nnIgnore > 0 )
170 {
171 ( *m_rfs ) >> m_dataSeparatorRecord;
172 uint32_t size = m_dataSeparatorRecord.getRecord().data_block_size;
173 m_rfs->seekg( size + m_rfs->tellg() );
174 --nnIgnore;
175 }
176 }
177
178 read_one_event();
179 } catch ( RawFileException& e )
180 { nextFile( e ).nextEvent( nnIgnore ); }
181
182 return m_buffer;
183}
184
185const uint32_t* RawFileReader::findEventById( uint32_t evtId ) {
186 // not thread safe !!!
187 // find an event by ID ( only backward !!! )
188 try
189 {
190 if ( m_idxHandler == 0 )
191 {
192 while ( true )
193 {
194 read_one_event();
195 uint32_t curEvtId = m_buffer[m_buffer[5] + 8];
196 if ( curEvtId == evtId ) { break; }
197 }
198 }
199 else
200 {
201 uint32_t pos = m_idxHandler->findPosById( evtId );
202 if ( pos != 0 )
203 {
204 m_rfs->seekg( pos );
205 read_one_event();
206 }
207 else { throw ReachEndOfFile( currentFile().c_str() ); }
208 }
209 } catch ( RawFileException& e )
210 { return nextFile( e ).findEventById( evtId ); }
211
212 return m_buffer;
213}
214
215const uint32_t* RawFileReader::roughlyNextEvent( int nIgnore, int evtByte ) {
216 // not thread safe !!!
217 if ( evtByte == 0 ) evtByte = EstimatedEventSize;
218
219 assert( ( evtByte & 3 ) == 0 );
220
221 uint32_t prePos = m_rfs->tellg();
222 m_rfs->seekg( prePos + nIgnore * evtByte );
223
224 uint32_t halfEvtWord = evtByte / 8;
225 uint32_t halfEvtByte = halfEvtWord * 4;
226
227 while ( m_rfs->read( (char*)m_buffer, halfEvtByte ).good() )
228 {
229 uint32_t i = 0;
230 while ( i < halfEvtWord && m_buffer[i] != 0x1234cccc ) { ++i; }
231 if ( i < halfEvtWord )
232 {
233 uint32_t curPos = m_rfs->tellg();
234 m_rfs->seekg( curPos - ( halfEvtWord - i ) * 4 );
235 read_one_event();
236 return m_buffer;
237 }
238 }
239
240 // reached the end of current data file! m_rfs->eof()
241 m_rfs->clear();
242 m_rfs->seekg( -40, std::ios::end ); // sizeof(FileEndRecord) == 40
243 uint32_t curPos = m_rfs->tellg();
244
245 int nnIgnore = nIgnore - ( curPos - prePos ) / evtByte;
246 if ( nnIgnore < 0 ) nnIgnore = 0;
247
248 ReachEndOfFile e( currentFile().c_str() );
249 return nextFile( e ).roughlyNextEvent( nnIgnore, evtByte );
250}
251uint32_t RawFileReader::runNo() { return m_rfs->runNo(); }
252
253std::string RawFileReader::currentFile() { return m_rfs->currentFile(); }
254
255uint32_t RawFileReader::tellg() { return m_rfs->tellg(); }
256
258 uint32_t stat = 0;
259
260 if ( m_rfs->eof() ) stat |= 1;
261 if ( m_rfs->fail() ) stat |= 2;
262 if ( m_rfs->bad() ) stat |= 4;
263
264 return stat;
265}
266
267const uint32_t* RawFileReader::notSafeNextEvent() {
268 try
269 { read_one_event(); } catch ( RawFileException& e )
270 { nextFile( e ).notSafeNextEvent(); }
271
272 return m_buffer;
273}
274
275void RawFileReader::read_one_event() {
276 ( *m_rfs ) >> m_dataSeparatorRecord;
277
278 uint32_t size = m_dataSeparatorRecord.getRecord().data_block_size;
279 if ( size > m_bufferSize * 4 )
280 {
281 while ( size > m_bufferSize * 4 ) { m_bufferSize *= 2; }
282 delete[] m_buffer;
283 m_buffer = new uint32_t[m_bufferSize];
284 }
285
286 m_rfs->read( (char*)m_buffer, size );
287 if ( !m_rfs->good() )
288 {
289 // std::cerr << "[RawFile] Failed to read FullEventFragment to buffer" << std::endl;
290 throw BadInputStream( "event_data_block" );
291 }
292}
293
294RawFileReader& RawFileReader::nextFile( RawFileException& e ) {
295 e.print();
296
297 m_rfs->clear();
298 m_rfs->next_file();
299
300 if ( m_idxHandler != 0 ) { m_idxHandler->next_file(); }
301
302 return *this;
303}
#define fs
#define DefaultEventBufferSize
#define EstimatedEventSize
static EvtIdxHandler * instance(const std::vector< std::string > &fnames)
static void release()
virtual void print() const
virtual ~RawFileReader()
const uint32_t * findEventById(uint32_t evtId)
const uint32_t * roughlyNextEvent(int nIgnore, int evtByte=0)
RawFileReader(const std::string &fname)
const uint32_t * nextEvent()
static std::vector< int > getEventNumber(const VFileNames_t &idxfnames)
std::string currentFile()
virtual void print() const
static void release()
static raw_ifstream * instance(const std::vector< std::string > &fnames)
std::vector< std::string > wildcard_correct(const std::string &fname)