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