00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <signal.h>
00013 #include <string>
00014 #include <cstring>
00015 #include <cstdlib>
00016 #include <sstream>
00017 #include <fstream>
00018 #include <iomanip>
00019 #include "lcio.h"
00020
00021
00022 #include <sys/types.h>
00023 #include <sys/stat.h>
00024 #include <fcntl.h>
00025 #include <unistd.h>
00026
00027
00028 #include "EVENT/LCCollection.h"
00029 #include "EVENT/SimTrackerHit.h"
00030 #include "EVENT/SimCalorimeterHit.h"
00031
00032 #include "IO/LCReader.h"
00033 #include "UTIL/LCTOOLS.h"
00034 #include "EVENT/LCRunHeader.h"
00035 #include "UTIL/LCTime.h"
00036
00037
00038 extern "C" {
00039 #include <readline/readline.h>
00040 #include <readline/history.h>
00041 }
00042
00043
00044 using namespace std ;
00045 using namespace lcio ;
00046
00047
00048
00049 typedef pair<int, string> level;
00050
00051 struct pagerInfo{
00052 char *filename;
00053 int fd_temp;
00054 int fd_old;
00055 bool save;
00056 } ;
00057
00058
00059 const int TOP = 0;
00060 const int RUN = 1;
00061 const int EVT = 2;
00062 const int COL = 3;
00063 vector<level> position;
00064
00065 map<int, string> mapRuns;
00066 map<int, int> mapEventsInRun;
00067 int numEvents = 0;
00068 bool withEvents = true;
00069 bool interrupt = false;
00070 bool pageOutput = false;
00071
00072 string pager = "less";
00073 string egg = "egg";
00074
00075
00076 LCReader* lcReader;
00077 LCRunHeader *runHdr ;
00078 LCEvent *event;
00079 LCCollection *col;
00080
00081
00082
00083
00084
00085 const char * print_prompt() {
00086 string prompt = "";
00087
00088 vector<level>::iterator levelIt;
00089 vector<level>::iterator levelItEnd = position.end();
00090 for( levelIt = position.begin(); levelIt != levelItEnd ; levelIt++ ){
00091 prompt += levelIt->second ;
00092 }
00093 prompt += "$ ";
00094
00095 return prompt.c_str();
00096 }
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 void leave(int ret) {
00108 cout << endl;
00109 try {
00110 lcReader->close() ;
00111 }
00112 catch (exception& e) {
00113 }
00114 delete lcReader;
00115
00116 exit(ret);
00117 }
00118
00119
00120
00121
00122
00123
00124
00125
00126 void int_handler(int sig) {
00127 cout << "interrupting.." << sig << endl;
00128 interrupt = true;
00129 }
00130
00131 void term_handler(int sig) {
00132 cout << "leaving.." << endl;
00133 leave(1);
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143 void begin_paging(pagerInfo*file) {
00144 if (!(file->save)) {
00145 file->filename = tmpnam (NULL);
00146 }
00147
00148
00149 file->fd_temp = open(file->filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR );
00150 file->fd_old = open(file->filename, O_RDONLY);
00151 dup2(1, file->fd_old);
00152 dup2(file->fd_temp, 1);
00153
00154 }
00155
00156
00157 bool end_paging(pagerInfo*file) {
00158 dup2(file->fd_old, 1);
00159
00160
00161 close(file->fd_temp);
00162 close(file->fd_old);
00163
00164 string lessCommand = pager;
00165 lessCommand.append(" ");
00166 lessCommand.append(file->filename);
00167
00168 int res = system(lessCommand.c_str());
00169
00170 if (!(file->save)) {
00171 remove (file->filename);
00172 }
00173
00174 return !res;
00175 }
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 void simplePrintCol(LCCollection* col) {
00187 int nElements;
00188 const std::string colType = col->getTypeName();
00189
00190 SimTrackerHit *trackerHit;
00191 SimCalorimeterHit *calHit;
00192
00193
00194 cout << "elements: " << (nElements = col->getNumberOfElements()) << endl;
00195 if (colType == LCIO::SIMTRACKERHIT ) {
00196 cout << " Hit \tCell"<< endl;
00197 for (int i=0; i<nElements; i++) {
00198 trackerHit = dynamic_cast<SimTrackerHit*> ( col->getElementAt(i) );
00199 cout << setw(4) << i << "\t" << setw(10) << trackerHit->getCellID() << endl;
00200 }
00201 } else if (colType == LCIO::SIMCALORIMETERHIT ) {
00202 cout << " Hit \tCell \tEnergy" << endl;
00203 for (int i=0; i<nElements; i++) {
00204 calHit = dynamic_cast<SimCalorimeterHit*> ( col->getElementAt(i) );
00205 cout << setw(4) << i << "\t" << setw(10) << calHit->getCellID0() << "\t" << setw(6) << calHit->getEnergy() << endl;
00206 }
00207 }
00208 }
00209
00210
00211
00212
00213 void normalPrintCol(LCCollection *col) {
00214 if( col->getTypeName() == LCIO::MCPARTICLE ){
00215 LCTOOLS::printMCParticles( col ) ;
00216
00217 }
00218 else if( col->getTypeName() == LCIO::SIMTRACKERHIT ){
00219
00220 LCTOOLS::printSimTrackerHits( col ) ;
00221
00222 }
00223 else if( col->getTypeName() == LCIO::TPCHIT ){
00224
00225 LCTOOLS::printTPCHits( col ) ;
00226
00227 }
00228 else if( col->getTypeName() == LCIO::TRACKERHIT ){
00229
00230 LCTOOLS::printTrackerHits( col ) ;
00231
00232 }
00233 else if( col->getTypeName() == LCIO::SIMCALORIMETERHIT ){
00234
00235 LCTOOLS::printSimCalorimeterHits( col ) ;
00236
00237 }
00238 else if( col->getTypeName() == LCIO::CALORIMETERHIT ){
00239
00240 LCTOOLS::printCalorimeterHits( col ) ;
00241
00242 }
00243 else if( col->getTypeName() == LCIO::RAWCALORIMETERHIT ){
00244
00245 LCTOOLS::printRawCalorimeterHits( col ) ;
00246
00247 }
00248 else if( col->getTypeName() == LCIO::LCFLOATVEC ){
00249
00250 LCTOOLS::printLCFloatVecs( col ) ;
00251
00252 }
00253 else if( col->getTypeName() == LCIO::LCINTVEC ){
00254
00255 LCTOOLS::printLCIntVecs( col ) ;
00256
00257 }
00258 else if( col->getTypeName() == LCIO::LCSTRVEC ){
00259
00260 LCTOOLS::printLCStrVecs( col ) ;
00261
00262 }
00263 else if( col->getTypeName() == LCIO::TRACK ){
00264
00265 LCTOOLS::printTracks( col ) ;
00266
00267 }
00268 else if( col->getTypeName() == LCIO::CLUSTER ){
00269
00270 LCTOOLS::printClusters( col ) ;
00271
00272 }
00273 else if( col->getTypeName() == LCIO::RECONSTRUCTEDPARTICLE ){
00274
00275 LCTOOLS::printReconstructedParticles( col ) ;
00276
00277 }
00278 else if( col->getTypeName() == LCIO::VERTEX ){
00279
00280 LCTOOLS::printVertices( col ) ;
00281
00282 }
00283 else if( col->getTypeName() == LCIO::LCGENERICOBJECT ){
00284
00285 LCTOOLS::printLCGenericObjects( col ) ;
00286
00287 }
00288 else if( col->getTypeName() == LCIO::LCRELATION ){
00289
00290 LCTOOLS::printRelation( col ) ;
00291 }
00292 else if( col->getTypeName() == LCIO::TRACKERRAWDATA ){
00293
00294 LCTOOLS::printTrackerRawData( col ) ;
00295 }
00296 else if( col->getTypeName() == LCIO::TRACKERDATA ){
00297
00298 LCTOOLS::printTrackerData( col ) ;
00299 }
00300 else if( col->getTypeName() == LCIO::TRACKERPULSE ){
00301
00302 LCTOOLS::printTrackerPulse( col ) ;
00303 }
00304 }
00305
00306
00307
00308
00309 void printTop() {
00310 if (withEvents) {
00311 cout << mapRuns.size() << " Runs - " << numEvents << " Events" << endl;
00312 } else {
00313 cout << mapRuns.size() << " Runs - ?? Events" << endl;
00314 }
00315 }
00316
00317
00318
00319
00320 void fun_print(string colNr, string flag) {
00321 if ((position.size() < 3)) {
00322 return;
00323 }
00324 unsigned int c;
00325 istringstream i(colNr);
00326 i >> c;
00327 lcReader->open( position[TOP].second ) ;
00328 if ((event = lcReader->readEvent( position[RUN].first, position[EVT].first )) != 0) {
00329 const vector<string> *colVec = event->getCollectionNames();
00330 if (c < colVec->size()) {
00331 col = event->getCollection((*colVec)[c]);
00332 cout << "name: " << (*colVec)[c] << endl;
00333 cout << "type: " << col->getTypeName() << endl;
00334
00335 if (flag == "-s") {
00336 simplePrintCol(col);
00337 } else {
00338 normalPrintCol(col);
00339 }
00340 }
00341 }
00342
00343 lcReader->close() ;
00344 }
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357 void lsRuns() {
00358 map<int, string>::iterator it;
00359 map<int, string>::iterator itEnd = mapRuns.end();
00360 for( it = mapRuns.begin() ; it != itEnd ; it++ ) {
00361 if (withEvents) {
00362 stringstream sstream;
00363 sstream << "(" << mapEventsInRun[it->first] << " events)";
00364 string tempEvents = sstream.str() ;
00365 cout << "[" << setw(2) << it->first << "] " << left << setw(40) << it->second << " " << right << setw(13) << tempEvents << endl;
00366 } else {
00367 cout << "[" << setw(2) << it->first << "] " << left << setw(40) << it->second << " " << endl;
00368 }
00369 }
00370 }
00371
00372
00373
00374
00375 void lsEvents() {
00376 lcReader->open( position[TOP].second ) ;
00377 while ( (event = lcReader->readNextEvent() ) != 0 && !interrupt) {
00378 if (event->getRunNumber() == (position[RUN].first)) {
00379 cout << "[" << setw(2) << event->getEventNumber() << "] " << setw(3) << (event->getCollectionNames())->size() << " Collections" << endl;
00380 }
00381 }
00382 interrupt = false;
00383 lcReader->close() ;
00384 }
00385
00386
00387
00388
00389 void lsCollections() {
00390 lcReader->open( position[TOP].second ) ;
00391 if ((event = lcReader->readEvent( position[RUN].first, position[EVT].first )) != 0) {
00392 const vector<string> *colVec = event->getCollectionNames();
00393 int i = 0;
00394 vector<string>::const_iterator it;
00395 vector<string>::const_iterator itEnd = colVec->end();
00396 for( it = colVec->begin(); it != itEnd ; it++ ){
00397 col = event->getCollection(*it);
00398 cout << "[" << setw(2) << i << "] " << left << setw(25) << *it << " " << setw(20) << col->getTypeName() << " " << right << setw(3) << col->getNumberOfElements () << endl;
00399 i++;
00400 }
00401 } else {
00402 cout << "this event does not exist" << endl;
00403 }
00404 lcReader->close() ;
00405 }
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416 void fun_ls() {
00417 switch( position.size()-1 ){
00418 case TOP:
00419 printTop();
00420 lsRuns();
00421 break;
00422 case RUN:
00423 lsEvents();
00424 break;
00425 case EVT:
00426 lsCollections();
00427 break;
00428 case COL:
00429 string s;
00430 stringstream n;
00431 n << position[COL].first;
00432 n >> s;
00433 fun_print(s, "-s");
00434 break;
00435 }
00436 }
00437
00438
00439
00440
00441 void fun_cd(string str) {
00442 unsigned n;
00443
00444 if (str.size() < 1) {
00445 return;
00446 }
00447
00448 char *cstr, *p;
00449 cstr = new char [str.size()+1];
00450 strcpy (cstr, str.c_str());
00451 p=strtok (cstr,"/");
00452 while (p!=NULL)
00453 {
00454 string next;
00455 stringstream sstream;
00456 sstream << p;
00457 sstream >> next;
00458
00459 if (next == "..") {
00460 if (position.size() == 1) {
00461 leave(0);
00462 }
00463 position.pop_back();
00464 } else {
00465
00466 istringstream i(next);
00467 i >> n;
00468 switch( position.size()-1 ){
00469 case TOP:
00470 position.push_back(level(n, "/run_"+next));
00471 break;
00472 case RUN:
00473 position.push_back(level(n, "/evt_"+next));
00474 break;
00475 case EVT:
00476 lcReader->open( position[TOP].second ) ;
00477 if ((event = lcReader->readEvent( position[RUN].first, position[EVT].first )) != 0) {
00478 const vector<string> *colVec = event->getCollectionNames();
00479 if (n < colVec->size()) {
00480 position.push_back(level(n, "/"+(*colVec)[n] ));
00481 } else {
00482 cout << "No collection with number " << n << endl;
00483 }
00484 }
00485 lcReader->close();
00486 break;
00487 }
00488 }
00489
00490 p=strtok(NULL,"/");
00491 }
00492
00493 delete[] cstr;
00494
00495 }
00496
00497
00498
00499
00500 void fun_dump(string arg) {
00501 switch( position.size()-1 ){
00502 case RUN:
00503
00504 lcReader->open( position[TOP].second ) ;
00505 while (( runHdr = lcReader->readNextRunHeader() ) != 0 && !interrupt) {
00506 int run = runHdr->getRunNumber();
00507 if (run == position[RUN].first) {
00508 interrupt = true;
00509 LCTOOLS::dumpRunHeader(runHdr);
00510 }
00511 }
00512 lcReader->close() ;
00513 interrupt = false;
00514 break;
00515 case EVT:
00516 lcReader->open( position[TOP].second ) ;
00517 if ((event = lcReader->readEvent( position[RUN].first, position[EVT].first )) != 0) {
00518 if(arg == "-d"){
00519 LCTOOLS::dumpEventDetailed(event);
00520 } else {
00521 LCTOOLS::dumpEvent(event);
00522 }
00523 }
00524 lcReader->close() ;
00525 break;
00526 case COL:
00527 string s;
00528 stringstream n;
00529 n << position[COL].first;
00530 n >> s;
00531 fun_print(s, "-d");
00532 break;
00533 }
00534 }
00535
00536
00537 void fun_egg() {
00538 for (int i = 0; i < 4; i++ ) {
00539 cout << "Glugg...." << endl;
00540 sleep(1);
00541 }
00542 cout << "Ahhh\n" << endl;
00543 }
00544
00545
00546
00547
00548 void fun_open(string filename) {
00549 position.clear();
00550 mapRuns.clear();
00551 mapEventsInRun.clear();
00552
00553 FILE * pFile;
00554 long size;
00555
00556
00557
00558 pFile = fopen (filename.c_str(),"rb");
00559 if (pFile==NULL) perror ("Error opening file");
00560 else
00561 {
00562 fseek (pFile, 0, SEEK_END);
00563 size= ftell(pFile);
00564 fclose (pFile);
00565 if (size > 50000000) {
00566 cout << "Large file: not preparing map of events in runs!" << endl;
00567 cout << "(Initialising will still take some time though." << endl;
00568 cout << " You can skip it using [ctrl]-[c].)" << endl;
00569 withEvents = false;
00570 }
00571 }
00572
00573
00574 egg.replace(1,2,2,'e');
00575 position.push_back(level(0, filename));
00576
00577 lcReader->open( position[TOP].second ) ;
00578 while (( runHdr = lcReader->readNextRunHeader() ) != 0 && !interrupt) {
00579 int run = runHdr->getRunNumber();
00580 mapRuns.insert ( pair<int, string>(run, runHdr->getDescription()) );
00581 mapEventsInRun.insert( pair<int, int>(run, 0));
00582 }
00583 interrupt = false;
00584 lcReader->close() ;
00585
00586 if (withEvents) {
00587 lcReader->open( position[TOP].second ) ;
00588 while ( (event = lcReader->readNextEvent()) != 0 && !interrupt) {
00589 (mapEventsInRun[event->getRunNumber()])++;
00590 numEvents++;
00591 }
00592 interrupt = false;
00593 lcReader->close() ;
00594 }
00595 }
00596
00597
00598
00599
00600 void fun_help() {
00601 cout << " COMMANDS:" << endl;
00602 cout << " cd | cl <number of OBJECT|..> change into OBJECT | leave object; multiple levels can be given at once" << endl;
00603 cout << " e.g.: file.slcio/run1$ cd ../3/1" << endl;
00604 cout << " ls list elements on next level | list content of active collection" << endl;
00605 cout << " dump [-d] dump data of active level; -d triggers detailed dump of event" << endl;
00606 cout << " print | cat [-s] <collection nr> print content of collection given; -s triggers short print-out" << endl;
00607 cout << endl;
00608 cout << " open <filename> open new file" << endl;
00609 cout << " exit | quit exit program" << endl;
00610 cout << " help print this help text" << endl;
00611 cout << " pager <command> use pager <command> when paging output" << endl;
00612 cout << endl;
00613 cout << " REDIRECTION:" <<endl;
00614 cout << " If '|' or '>' is appended to the a command, the output will be redirected to a file and then"<<endl;
00615 cout << " displayed with the pager (see above)." << endl;
00616 cout << " If a string is given after the redirect token, it is used as filename and the file is stored." <<endl;
00617 cout << " (existing files will get overwritten without prompt). If no filename is given, a temporary " << endl;
00618 cout << " file will be used for paging." << endl;
00619 cout << " e.g.: file.slcio/run1/evt1$ dump -d > event1.txt "<<endl;
00620 }
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634 int main(int argc, char** argv ) {
00635 string temp = egg;
00636
00637
00638 signal(SIGINT, int_handler);
00639 signal(SIGTERM, term_handler);
00640 temp.push_back('r');
00641
00642
00643
00644 if (argc != 2) {
00645 cout << "usage: lsh <file name>|-h" << endl;
00646 exit(1);
00647 }
00648 temp.insert(1,"b");
00649 if (!strcmp(argv[1], "-h")) {
00650 fun_help();
00651 exit(0);
00652 }
00653 temp.erase(0,1);
00654
00655
00656
00657 cout << setprecision(3) << fixed;
00658 lcReader = LCFactory::getInstance()->createLCReader() ;
00659 egg = temp;
00660
00661 fun_open(argv[1]);
00662 printTop();
00663
00664
00665
00666
00667 do {
00668
00669 vector<string> commandVec;
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688 char *line = readline (print_prompt());
00689
00690
00691 if( line == '\0' ) {
00692 free(line);
00693 cout << "exit" << endl;
00694 leave(0);
00695 }
00696
00697 if (!(line && *line)) {
00698 free(line);
00699 cout << endl;
00700 continue;
00701 }
00702 add_history(line);
00703
00704 string buf;
00705 stringstream sstream(line);
00706 while (sstream >> buf) {
00707 commandVec.push_back(buf);
00708 }
00709 free(line);
00710
00711
00712
00713 pagerInfo data;
00714 data.save = false;
00715
00716 int cvSize = commandVec.size();
00717 if (cvSize > 1) {
00718
00719 if ((commandVec[cvSize-1] == "|") || (commandVec[cvSize-1] == ">")) {
00720 pageOutput = true;
00721 commandVec.pop_back();
00722 } else
00723
00724
00725
00726 if ((commandVec[cvSize-2] == "|") || (commandVec[cvSize-2] == ">")) {
00727 pageOutput = true;
00728 data.save = true;
00729 strcpy(data.filename, commandVec[cvSize-1].c_str());
00730 }
00731 }
00732
00733
00734
00735
00736
00737 int run = 0;
00738 bool outputSuccess;
00739 do {
00740 if (pageOutput) {
00741 begin_paging(&data);
00742 }
00743
00744
00745
00746
00747
00748 if ((commandVec[0] == "exit") || (commandVec[0] == "quit")) {
00749 leave(0);
00750 }
00751 if (commandVec[0] == "ls") {
00752 fun_ls();
00753 }
00754 if ((commandVec[0] == "cl") || (commandVec[0] == "cd")) {
00755 fun_cd(commandVec[1]);
00756 }
00757 if ((commandVec[0] == "print") || (commandVec[0] == "cat")) {
00758
00759 if (commandVec.size() == 2) {
00760 vector<string>::iterator it;
00761 it = ++(commandVec.begin());
00762 commandVec.insert ( it , "-d" );
00763 }
00764 fun_print(commandVec[2], commandVec[1]);
00765 }
00766 if ((commandVec[0] == "dump")) {
00767 if (commandVec.size() < 2) {
00768 commandVec.push_back("-s");
00769 }
00770 fun_dump(commandVec[1]);
00771 }
00772 if ((commandVec[0] == "open") || (commandVec[0] == "file")) {
00773 fun_open(commandVec[1]);
00774 }
00775 if ((commandVec[0] == egg)) {
00776 fun_egg();
00777 }
00778 if ((commandVec[0] == "help")) {
00779 fun_help();
00780 }
00781 if ((commandVec[0] == "pager")) {
00782 pager = commandVec[1];
00783 }
00784 if (!cin) {
00785 leave(0);
00786 }
00787
00788 if (pageOutput) {
00789 outputSuccess = end_paging(&data);
00790 } else {
00791 outputSuccess = true;
00792 }
00793 pageOutput = false;
00794 ++run;
00795 } while (!outputSuccess);
00796 if (run != 1) {
00797 cout << " paging failed - active pager: " << pager << endl;
00798 cout << " You can set another pager with: pager <command>" << endl;
00799 }
00800
00801 } while (1 == 1);
00802
00803 }