Fork me on GitHub

source: svn/trunk/external/ProMC/ProMCBook.cc@ 1225

Last change on this file since 1225 was 1173, checked in by Pavel Demin, 11 years ago

add external/ProMC

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision Date
File size: 12.7 KB
Line 
1/* ---------------------------------------------------------------------------
2** This software is in the public domain, furnished "as is", without technical
3** support, and with no warranty, express or implied, as to its usefulness for
4** any purpose.
5**
6** A library for HEP events storage and processing based on Google's ProtocolBuffers
7**
8** Author: S.Chekanov (ANL). chekanov@anl.gov
9** Copyright March, 2013
10** -------------------------------------------------------------------------*/
11
12
13
14#include "ProMCBook.h"
15
16bool replace(std::string& str, const std::string& from, const std::string& to) {
17 size_t start_pos = str.find(from);
18 if(start_pos == std::string::npos)
19 return false;
20 str.replace(start_pos, from.length(), to);
21 return true;
22}
23
24
25
26ProMCBook::ProMCBook(){ nev=0; isToWrite=false; }
27
28ProMCBook::~ProMCBook(){ }
29
30ProMCBook::ProMCBook(const char* filename, const char* option){
31
32 open(filename,option);
33
34}
35
36
37/* This is a function to read or write ProMC file */
38void ProMCBook::open(const char* filename, const char* option) {
39
40 //cout << "PoMC Version: " << PROMCBOOK_VERSION << endl;
41
42
43 GOOGLE_PROTOBUF_VERIFY_VERSION;
44 nev=0;
45
46 if (strcmp(option,"w")==0) {
47 isToWrite=true;
48 cout << "ProMCBook: Writing file = " << filename << endl;
49 outzip = new ZipOutputStream(filename);
50 description="none";
51
52 outzip->putNextEntry( "version" ) ;
53 std::stringstream out;
54 out << current_version;
55 (*outzip) << out.str();
56
57
58 } else if (strcmp(option,"r")==0) {
59 isToWrite=false;
60 ifstream file(filename);
61 if (!file)
62 {
63 cout << "-> Error: File =" << filename << " does not exist " << endl;
64 cout << "-> The program will exit.." << endl;
65 exit(1);
66 }
67 file.close();
68 cout << "ProMCBook: Reading file = " << filename << endl;
69
70
71 zfile = new ZipFile( filename );
72 unsigned nlength=zfile->size();
73 // reverse iteration over all entries
74 // we loop until the last event is found.
75 // this is triggered by promc_description entry which follows
76 // after the last event
77 ConstEntries entries =zfile->entries() ;
78 ConstEntries::iterator it ;
79 vector<string> metatext;
80 for( it = entries.end() ; it != entries.begin();) {
81 --it;
82 // cout << *(*it) << endl ;
83 std::stringstream sout;
84 sout << *(*it);
85 string ss=sout.str();
86 metatext.push_back(ss);
87 std::size_t found = ss.find("promc_description");
88 if (found != std::string::npos) {
89 // istream * stt= zf.getInputStream(ss);
90 // cout << stt->rdbuf() << endl;
91 // cout << "Contents of entry 1: " << cout << stt->rdbuf() << endl;
92 // sentry=ss;
93 //ConstEntryPointer ent = zf.getEntry(ss, FileCollection::MATCH );
94 //if ( ent == 0 ) break;
95 //auto_ptr< istream > is( zf.getInputStream( ent ) ) ;
96 //cout << "Contents of entry 1: " << ent->getName() << " :" << endl ;
97 //cout << is->rdbuf() ;
98 break;
99 }
100 }
101
102
103 // calculate the total number of entries from the file
104 nev=nlength-metatext.size()-3; // 3 is the count for version,description,header
105 // this is intresting: to get promc_nevents, you must call previous entry promc_description
106 istream * stt = zfile->getInputStream( "promc_description", FileCollection::IGNORE );
107 // ConstEntryPointer ent = zfile->getEntry( "promc_description", FileCollection::IGNORE ) ;
108 if ( stt != 0 ) {
109 // auto_ptr< istream > is( zfile->getInputStream( ent ) ) ;
110 // cout << is->rdbuf() ;
111 std::stringstream sout;
112 sout << stt->rdbuf();
113 string ss=sout.str();
114 cout << "DEBUG=" << ss << endl;
115 // int nnev = atoi(ss.c_str());
116 }
117
118
119 // do not close to allow for random access. Close at the very end.
120 // zfile->close();
121
122
123
124 // read it
125 inpzip = new ZipInputStream(filename);
126 try {
127 // version
128 std::stringstream sout;
129 sout << inpzip->rdbuf();
130 string ss=sout.str();
131 version = atoi(ss.c_str());
132
133
134 next();
135
136
137
138
139 try {
140
141 ProMCDescription h;
142 std::stringstream sout;
143 sout << inpzip->rdbuf();
144 h.ParseFromIstream(&sout);
145
146 // get info
147 version = h.version();
148 description=h.description();
149 timestamp=h.timestamp();
150 requested_nev=h.events();
151 cout << "ProMCBook: version = " << version << endl;
152 cout << "ProMCBook: Nr entries = " << nev << endl;
153 cout << "ProMCBook: description = " << description << endl;
154
155
156 } catch( IOException &e ) {
157 cerr << "IOException caught in fetching description:" << endl ;
158 cerr << e.what() << endl ;
159 }
160 catch( ... ) {
161 cerr << "Unspecified exception caught in fetching description:" << endl ;
162 }
163
164
165
166
167
168
169
170
171 } catch( IOException &e ) {
172 cerr << "IOException caught in ProMCBook:" << endl ;
173 cerr << e.what() << endl ;
174 }
175 catch( ... ) {
176 cerr << "Unspecified exception caught in ProMCBook:" << endl ;
177 }
178
179 }
180
181
182
183 /*
184 try {
185 zipios::ConstEntryPointer entry =inpzip->getNextEntry() ;
186 if(entry->isValid()) {
187 std::stringstream sout;
188 sout << inpzip->rdbuf();
189 header.ParseFromIstream(&sout);
190 }
191 } catch( IOException &e ) {
192 cerr << "IOException caught in ProMCBook:" << endl ;
193 cerr << e.what() << endl ;
194 }
195 catch( ... ) {
196 cerr << "Unspecified exception caught in ProMCBook:" << endl ;
197 }
198 */
199
200
201}
202
203
204
205
206/**
207
208Return the number of records.
209
210@return Return the size of all records (excluding metadata)
211**/
212unsigned int ProMCBook::size()
213{
214 return nev;
215}
216
217
218
219
220/**
221 Get the next record.
222
223 @return 0 if the record was extracted OK. 6, or 7 if there is a problem
224
225**/
226
227int ProMCBook::next(){
228
229
230 try {
231 if (inpzip == NULL) return 1;
232 if (inpzip->eof()) return 2;
233 if (inpzip->fail()) return 3;
234 if (inpzip->bad()) return 4;
235 zipios::ConstEntryPointer entry =inpzip->getNextEntry() ;
236 if(!entry->isValid()) return 5;
237
238 } catch( IOException &e ) {
239 // cerr << "IOException caught in main:" << endl ;
240 // cerr << e.what() << endl ;
241 return 6;
242 }
243 catch( ... ) {
244 //cerr << "Unspecified exception caught in main:" << endl ;
245 return 7;
246 }
247
248
249 return 0;
250}
251
252
253
254/**
255 Get the record with the header file.
256 @param Header file record.
257**/
258ProMCHeader ProMCBook::getHeader(){
259
260 // go to next event
261 next();
262
263 ProMCHeader h;
264
265 try {
266 std::stringstream sout;
267 sout << inpzip->rdbuf();
268 h.ParseFromIstream(&sout);
269 } catch( IOException &e ) {
270 cerr << "IOException caught in main:" << endl ;
271 cerr << e.what() << endl ;
272 }
273 catch( ... ) {
274 cerr << "Unspecified exception caught in main:" << endl ;
275 }
276
277 return h;
278
279}
280
281
282
283/**
284 Get a data record (event) using a random access.
285 Use a key to extract the record. The key value
286 runs from "0" to size()-1.
287
288 @param key (long) of the record
289 @return ProMCEvent record corresponding to this key.
290**/
291ProMCEvent ProMCBook::event(long idx){
292
293 ProMCEvent eve;
294
295 idx=idx-1;
296
297 std::stringstream ss;
298 ss << idx;
299 string key=ss.str();
300
301 if (idx==-1) key="header";
302
303
304
305 try {
306
307 istream * stt = zfile->getInputStream( key, FileCollection::IGNORE );
308 std::stringstream sout;
309 sout << stt->rdbuf();
310 eve.ParseFromIstream(&sout);
311 return eve;
312 } catch( ... ) {
313 cerr << "Unspecified exception caught in main for the key:" << key << endl ;
314 return eve;
315 }
316}
317
318
319/**
320 Get the next record. Make sure you can next() first.
321 @return ProMCEvent record.
322
323**/
324ProMCEvent ProMCBook::get(){
325
326 ProMCEvent eve;
327
328 try {
329
330 std::stringstream sout;
331 sout << inpzip->rdbuf();
332 eve.ParseFromIstream(&sout);
333 return eve;
334
335 // if (inpzip->good())
336 // return eve;
337
338
339 } catch( IOException &e ) {
340 cerr << "IOException caught in main:" << endl ;
341 cerr << e.what() << endl ;
342 }
343 catch( ... ) {
344 cerr << "Unspecified exception caught in main:" << endl ;
345 }
346
347
348 /*
349 zipios::ConstEntryPointer entry =inpzip->getNextEntry() ;
350
351 if (entry->isValid()) {
352
353 ProMCEvent eve;
354
355 // entry->toString().c_str()
356 fstream input;
357 input<<entry;
358 // std::istream *str = &zipstream;
359
360 eve.ParseFromIstream(&input);
361
362
363 }
364 */
365
366 return eve;
367
368}
369
370
371
372/**
373 Clear all streams (dummmy)
374**/
375void ProMCBook::clear()
376{
377
378}
379
380/**
381 Set a header file.
382
383 @param h Header file.
384
385**/
386void ProMCBook::setHeader( ProMCHeader h ) {
387
388 std::string out;
389 if (!h.SerializeToString(&out)) {
390 cerr << "Failed to write header" << endl;
391 }
392 outzip->putNextEntry( "header" ) ;
393 (*outzip) << out;
394 h.Clear();
395}
396
397
398/**
399 Set statistics information
400 @param h Statistics info
401**/
402void ProMCBook::setStatistics( ProMCStat h ) {
403 hStat=h;
404}
405
406
407/**
408
409 Set the description information.
410 @param requested_events Requested events (not the actual!)
411 @param describe description
412
413**/
414void ProMCBook::setDescription( int requested_events, string describe ) {
415
416
417 description=describe;
418
419 std::time_t t = std::time(0); // t is an integer type
420
421 ProMCDescription eve;
422 eve.set_version(current_version);
423 eve.set_description(description);
424 eve.set_events(requested_events);
425 eve.set_timestamp((int)t);
426 std::string out;
427 if (!eve.SerializeToString(&out)) {
428 cerr << "Failed to write description" << endl;
429 }
430 outzip->putNextEntry( "description" ) ;
431 (*outzip) << out;
432 eve.Clear();
433
434
435
436}
437
438
439
440
441
442/**
443 Write an event.
444
445 @param eve Event to be written.
446
447**/
448void ProMCBook::write( ProMCEvent eve ) {
449
450 std::string out;
451 if (!eve.SerializeToString(&out)) {
452 cerr << "Failed to write event" << endl;
453 }
454
455 std::stringstream sout;
456 sout << nev;
457 outzip->putNextEntry( sout.str() ) ;
458 (*outzip) << out;
459 nev++;
460 eve.Clear();
461}
462
463
464
465/**
466 Close all files and write metadata.
467
468**/
469void ProMCBook::close() {
470
471
472 if (isToWrite==true) {
473
474
475
476 cout << " ##### Closing ProMC ##### " << endl;
477 string filename;
478
479
480 // description. always comes after the last event
481 outzip->putNextEntry( "promc_description" ) ;
482 std::stringstream out2;
483 out2 << description;
484 (*outzip) << out2.str();
485
486 // write number of processed events
487 outzip->putNextEntry( "promc_nevents" ) ;
488 std::stringstream out1;
489 out1 << nev;
490 (*outzip) << out1.str();
491
492
493 // write statistics
494 std::string outS;
495 if (!hStat.SerializeToString(&outS)) {
496 cerr << "Failed to write statistics information" << endl;
497 ProMCStat stat; // write dummy stattistics
498 stat.SerializeToString(&outS);
499 outzip->putNextEntry( "statistics" ) ;
500 (*outzip) << outS;
501 stat.Clear();
502 }
503 outzip->putNextEntry( "statistics" ) ;
504 (*outzip) << outS;
505
506
507
508 bool ierr=false;
509
510 filename="proto/ProMCHeader.proto";
511 ifstream ifs2( filename.c_str(), ios::in | ios::binary ) ;
512 if(!ifs2.fail()) {
513 replace(filename, "proto/", "");
514 outzip->putNextEntry(filename);
515 (*outzip) << ifs2.rdbuf() ;
516 ifs2.close();
517 if (outzip->fail())
518 cout << " Problem with writing "<< filename << endl;
519 //ierr=true;
520 } else {
521 cout << " Header file=" << filename << " not found" << endl;
522 ierr=true;
523 }
524
525 filename="proto/ProMC.proto";
526 ifstream ifs3( filename.c_str(), ios::in | ios::binary ) ;
527 if(!ifs3.fail()) {
528 replace(filename, "proto/", "");
529 outzip->putNextEntry(filename);
530 (*outzip) << ifs3.rdbuf() ;
531 ifs3.close();
532 if (outzip->fail())
533 cout << " Problem with writing "<< filename << endl;
534 //ierr=true;
535 } else {
536 cout << " Event record file=" << filename << " not found" << endl;
537 ierr=true;
538 }
539
540
541 filename="proto/ProMCStat.proto";
542 ifstream ifs4( filename.c_str(), ios::in | ios::binary ) ;
543 if(!ifs4.fail()) {
544 replace(filename, "proto/", "");
545 outzip->putNextEntry(filename);
546 (*outzip) << ifs4.rdbuf() ;
547 ifs4.close();
548 if (outzip->fail())
549 cout << " Problem with writing "<< filename << endl;
550 //ierr=true;
551 } else {
552 cout << " Statistics file=" << filename << " not found" << endl;
553 ierr=true;
554 }
555
556
557 filename="proto/ProMCDescription.proto";
558 ifstream ifs5( filename.c_str(), ios::in | ios::binary ) ;
559 if(!ifs5.fail()) {
560 replace(filename, "proto/", "");
561 outzip->putNextEntry(filename);
562 (*outzip) << ifs5.rdbuf() ;
563 ifs5.close();
564 if (outzip->fail())
565 cout << " Problem with writing "<< filename << endl;
566 //ierr=true;
567 } else {
568 cout << " Description file=" << filename << " not found" << endl;
569 ierr=true;
570 }
571
572
573 if (ierr){
574 cout << " -> Warning: Not self-describing file format." << endl;
575 cout << " To make it self-describing, put *.proto files to the directory proto/" << endl;
576 }
577
578
579
580 // write a log file if exists. Always the last one.
581 filename="logfile.txt";
582 ifstream ifs1( filename.c_str(), ios::in | ios::binary );
583 if(!ifs1.fail()) {
584 outzip->putNextEntry(filename);
585 (*outzip) << ifs1.rdbuf() ;
586 ifs1.close();
587 cout << " Info: File=" << filename << " is attached" << endl;
588 if (outzip->fail() || outzip->bad())
589 cout << "Problem with writing "<< filename << endl;
590 } else {
591 cout << " Info: File=" << filename << " not found. No logfile info is written" << endl;
592 }
593
594
595
596 outzip->close();
597 cout << " ##### ProMC file is closed #####" << endl;
598
599 }
600
601
602 // delete outzip;
603 // delete inpzip;
604 if (isToWrite==false) { zfile->close();
605 inpzip->close(); };
606 clear();
607}
608
609
610
611
Note: See TracBrowser for help on using the repository browser.