BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
CgemIndexFile.cxx
Go to the documentation of this file.
1#include "RawFile/CgemIndexFile.h"
2#include "RawFile/raw_ifstream.h"
3#include "IRawFile/RawFileExceptions.h"
4#include <filesystem>
5#include <iostream>
6
8 m_meta = new RawDataCache( kMaxNumFiles * sizeof( CgemSubFileMeta ) );
9 m_data = new RawDataCache( 512 * 1024 );
10}
11
13 this->close();
14 delete m_meta;
15 delete m_data;
16}
17
18bool CgemIndexFile::open4read( const std::string& file ) {
19 if ( !std::filesystem::exists( file ) ) {
20 std::cerr << "Error: CgemIndexFile can find " << file << std::endl;
21 return false;
22 }
23
24 uint32_t fheader[8];
25
26 m_fs.open( file.c_str(), std::ios::binary | std::ios::in );
27 m_fs.read( reinterpret_cast<char*>(fheader), sizeof(uint32_t) * 8 );
28
29 if (fheader[0] != kIndexFileMarker) {
30 std::cerr << "Error: CgemIndexFile wrong header marker" << std::endl;
31 return false;
32 }
33
34 m_numFiles = fheader[7];
35
36 uint32_t metaSize = kMaxNumFiles * sizeof( CgemSubFileMeta );
37 m_fs.read( m_meta->data<char>(), metaSize );
38
39 m_subFiles.resize( m_numFiles, nullptr );
40
41 return true;
42}
43
44bool CgemIndexFile::open4write( const std::string& file ) {
45 if ( std::filesystem::exists( file ) ) {
46 std::cerr << "Error: CgemIndexFile can not overwrite an exist file " << file << std::endl;
47 return false;
48 }
49
50 m_fs.open( file.c_str(), std::ios::binary | std::ios::in | std::ios::out | std::ios::trunc );
51 m_fs.write( reinterpret_cast<const char*>( &kIndexFileMarker ), sizeof( uint32_t ) );
52 for ( int i = 0; i < 7; i++ ) {
53 // six for the reserved bytes and one for the real numfiles
54 m_fs.write( reinterpret_cast<const char*>( &m_numFiles ), sizeof( uint32_t ) );
55 }
56
57 auto _subfMeta = m_meta->data<CgemSubFileMeta>();
58 for ( int i = 0; i < kMaxNumFiles; i++ ) {
59 _subfMeta[i].lastL1id = 0;
60 _subfMeta[i].pos = 0;
61 }
62
63 uint32_t metaSize = kMaxNumFiles * sizeof( CgemSubFileMeta );
64 m_fs.write( reinterpret_cast<char *>(_subfMeta), metaSize );
65
66 if ( m_fs.good() ) {
67 m_isWrite = true;
68 m_subFile = new CgemSubFileContext;
69 m_subFile->i_fidx->reserve<CgemEventIndex>( 1024 * 1024 );
70 }
71
72 return m_isWrite;
73}
74
75bool CgemIndexFile::append_from( const std::string& file ) {
76 if ( m_numFiles+1 >= kMaxNumFiles ) {
77 std::cerr << "Error: too many files, the supported max file number is " << kMaxNumFiles << std::endl;
78 return false;
79 }
80
81 const uint32_t HeaderSize = 18;
82 uint32_t evtHeader[HeaderSize];
84
85 auto& _numEvents = m_subFile->i_numEvents;
86 auto _fidx = m_subFile->i_fidx->data<CgemEventIndex>();
87
88 _numEvents = 0;
89 m_subFile->i_datafn = file;
90 uint32_t maxNumEvents = m_subFile->i_fidx->capacity() / sizeof(CgemEventIndex);
91
92 raw_ifstream ifs( std::vector<std::string>{ file } );
93
94 while (true) {
95 try {
96 ifs >> dsr;
97 }
98 catch ( ReachEndOfFile& e ) {
99 break;
100 }
101 catch ( ... ) {
102 std::cerr << "Error: invalid data in file " << file << std::endl;
103 return false;
104 }
105 ifs.read( reinterpret_cast<char*>( evtHeader ), HeaderSize * sizeof( uint32_t ) );
106 ++_numEvents;
107 if ( _numEvents > maxNumEvents ) {
108 do {
109 maxNumEvents *= 2;
110 } while (_numEvents > maxNumEvents);
111 _fidx = m_subFile->i_fidx->expand<CgemEventIndex>(maxNumEvents);
112 }
113 uint32_t dataSize = (evtHeader[1] - evtHeader[2]) * sizeof( uint32_t );
114 auto _eidx = _fidx + _numEvents - 1;
115 _eidx->l1id = evtHeader[10 + evtHeader[5]];
116 _eidx->pos = ifs.tellg();
117 _eidx->size = dataSize;
118 ifs.seekg( dataSize, std::ios::cur );
119 }
120
121 auto _meta = m_meta->data<CgemSubFileMeta>();
122 _meta[m_numFiles].lastL1id = _fidx[_numEvents-1].l1id;
123 _meta[m_numFiles].pos = m_fs.tellp();
124
125 m_fs.write(reinterpret_cast<const char*>(&kSubIndexFileMarker), sizeof(uint32_t));
126 m_fs.write(reinterpret_cast<const char*>(&_numEvents), sizeof(uint32_t));
127 m_fs << file << '\n';
128 int sleft = 256 - sizeof(uint32_t) * 2 - 1 - file.size();
129 for (int i = 0; i < sleft; ++i) {
130 m_fs.put('Z');
131 }
132 m_fs.write(reinterpret_cast<char*>(_fidx), _numEvents * sizeof(CgemEventIndex));
133
134 ++m_numFiles;
135 std::cout << "CgemIndexFile: total " << _numEvents << " events in file " << file << std::endl;
136
137 return true;
138}
139
141 if ( m_isWrite ) {
142 m_fs.seekp( 7 * sizeof(uint32_t) );
143 m_fs.write(reinterpret_cast<char*>(&m_numFiles), sizeof(uint32_t));
144 uint32_t metaSize = kMaxNumFiles * sizeof( CgemSubFileMeta );
145 m_fs.write(m_meta->data<char>(), metaSize);
146 delete m_subFile;
147 m_isWrite = false;
148 }
149 else {
150 for ( auto& f : m_subFiles ) {
151 delete f;
152 }
153 m_subFiles.clear();
154 }
155 m_numFiles = 0;
156 m_subFile = nullptr;
157 m_fs.close();
158}
159
161 if ( m_numFiles != 0 ) {
162 std::cout << "CgemIndexFile: " << m_numFiles << " SubFiles" << std::endl;
163 auto _meta = m_meta->data<CgemSubFileMeta>();
164 for ( uint32_t i = 0; i < m_numFiles; ++i ) {
165 std::cout << " SubFile " << std::setw( 3 ) << i << ": lastL1ID " << _meta[i].lastL1id << std::endl;
166 }
167 }
168}
169
171 auto& _numEvents = m_subFile->i_numEvents;
172 std::cout << "Related Data File: " << m_subFile->i_datafn
173 << "\nNumber of Events: " << _numEvents << std::endl;
174
175 if (_numEvents > 10) {
176 showSubFileRange(0, 3);
177 std::cout << " ..." << std::endl;
178 showSubFileRange(_numEvents - 3, _numEvents);
179 }
180 else {
181 showSubFileRange(0, _numEvents);
182 }
183}
184
185void CgemIndexFile::showSubFileRange( const uint32_t start, const uint32_t end )
186{
187 if ( end > m_subFile->i_numEvents ) {
188 std::cerr << "Error: CgemIndexFile exceeds the max event number " << m_subFile->i_numEvents << std::endl;
189 return;
190 }
191
192 auto _fidx = m_subFile->i_fidx->data<CgemEventIndex>();
193 for (uint32_t i = start; i < end; ++i) {
194 std::cout << std::setw( 12 ) << i << ": L1ID" << std::setw( 12 ) << _fidx[i].l1id
195 << " Pos" << std::setw( 12 ) << _fidx[i].pos << " Size " << _fidx[i].size << std::endl;
196 }
197}
198
199bool CgemIndexFile::loadSubFile(const uint32_t n) {
200
201 if ( n < m_numFiles ) {
202 if ( m_subFiles[n] != nullptr ) {
203 m_subFile = m_subFiles[n];
204 return true;
205 }
206 m_subFiles[n] = new CgemSubFileContext();
207 m_subFile = m_subFiles[n];
208 auto _meta = m_meta->data<CgemSubFileMeta>();
209 m_fs.seekg(_meta[n].pos);
210
211 uint32_t subFileMeta[2];
212 m_fs.read( reinterpret_cast<char*>(subFileMeta), sizeof(uint32_t) * 2 );
213 if (subFileMeta[0] == kSubIndexFileMarker) {
214 m_fs >> m_subFile->i_datafn;
215 if ( std::filesystem::exists( m_subFile->i_datafn ) ) {
216 m_subFile->i_numEvents = subFileMeta[1];
217 m_fs.seekg( _meta[n].pos + 256 );
218 m_subFile->i_fidx->reserve<CgemEventIndex>(m_subFile->i_numEvents);
219 m_fs.read( m_subFile->i_fidx->data<char>(), m_subFile->i_numEvents * sizeof( CgemEventIndex ) );
220 return m_fs.good();
221 }
222 else {
223 std::cerr << "Error: CgemIndexFile can not find data file " << m_subFile->i_datafn << std::endl;
224 }
225 }
226 else {
227 std::cerr << "Error: CgemIndexFile wrong SubFile marker" << std::endl;
228 }
229 }
230 else {
231 std::cerr << "Error: CgemIndexFile exceeds the max SubFile number " << m_numFiles << std::endl;
232 }
233
234 return false;
235}
236
237uint32_t* CgemIndexFile::getCgemData( const uint32_t l1id ) {
238 uint32_t* _noCGEM = m_data->data<uint32_t>();
239 _noCGEM[1] = 0; // set the data size to 0, so that it will effectively be ignored
240
241 auto _idx = ( m_subFile != nullptr ) ? m_subFile->i_fidx->data<CgemEventIndex>() : nullptr;
242 if ( _idx == nullptr || _idx[0].l1id > l1id || _idx[m_subFile->i_numEvents - 1].l1id < l1id ) {
243 auto _meta = m_meta->data<CgemSubFileMeta>();
244 int _n = 0;
245 while ( _meta[_n].lastL1id < l1id ) {
246 if ( ++_n >= m_numFiles ) {
247 std::cerr << "Warning: CgemIndexFile can not find the index for L1ID+ " << l1id << std::endl;
248 return _noCGEM;
249 }
250 }
251 if ( !loadSubFile( _n ) ) { return _noCGEM; }
252 if ( !m_subFile->i_datafs.is_open() ) {
253 m_subFile->i_datafs.open( m_subFile->i_datafn.c_str(), std::ios::binary );
254 }
255 _idx = m_subFile->i_fidx->data<CgemEventIndex>();
256 }
257
258 uint32_t ii = l1id - _idx[0].l1id;
259 // while ( _idx[ii].l1id != l1id && ii != 0) --ii; // there exists lost trigger in CGEM data
260
261 if ( _idx[ii].l1id == l1id ) {
262 auto _cache = m_data->reserve<char>( _idx[ii].size );
263 m_subFile->i_datafs.seekg( _idx[ii].pos );
264 m_subFile->i_datafs.read( _cache, _idx[ii].size );
265 uint32_t* _data = reinterpret_cast<uint32_t*>( _cache );
266 if ( _data[0] == 0xbb1234bb ) {
267 return _data;
268 }
269 else {
270 std::cerr << "Error: CgemIndexFile wrong SubDetector marker" << std::endl;
271 }
272 }
273 else {
274 std::cerr << "Warning: CgemIndexFile can not find the index for L1ID- " << l1id << std::endl;
275 }
276
277 return _noCGEM;
278}
TFile f("ana_bhabha660a_dqa_mcPat_zy_old.root")
char * file
Definition DQA_TO_DB.cxx:16
const Int_t n
bool append_from(const std::string &file)
bool open4read(const std::string &file)
bool open4write(const std::string &file)
bool loadSubFile(const uint32_t n)
void showSubFileRange(const uint32_t start, const uint32_t end)
uint32_t * getCgemData(const uint32_t l1id)