/* * * Libraries for reading Tektronix internal data format .isf from ROOT * for TDS30XX * * Usage: * #include "isf2RootTDS.cc" * * // In your main program * ISFTDS isf; * isf.open(isfFile); * isf.getPreamble(); * isf.storePreamble(); OR isf.storePreamble(preambleFile); * isf.getCurveData(); * // Then, you can use the following variables: * int isf.nPoints; * float isf.xp[]; * float isf.yp[]; * * To make sample executable * g++ -DISF2ROOTEXAMPLE -o isf2RootTDS_exe isf2RootTDS.cc * * http://hep-www.px.tsukuba.ac.jp/~yuji/myprod/isf2RootTDS.cc * Ver 0.00 2013/5/14 Y. Takeuchi * Ver 0.01 2013/8/22 Y. Takeuchi (minor bug fix) * Ver 0.02 2013/9/05 Y. Takeuchi (minor bug fix) * */ #ifndef ISF2ROOTTDS_CC #define ISF2ROOTTDS_CC #include #include #include #include #include using namespace std; // global variables for getopt extern char *optarg; extern int optind, opterr; // // class // class ISFTDS { public: // // preamble // int BYT_NR; int BIT_NR; char ENCDG[1024]; char BN_FMT[1024]; char BYT_OR[1024]; int NR_PT; char WFID[1024]; char PT_FMT[1024]; double XINCR; int PT_OFF; double XZERO; char XUNIT[1024]; double YMULT; double YZERO; double YOFF; char YUNIT[1024]; int Data_length; int nPoints; // actual # of points // // variables // bool quiet; // char sep; // =','; char preamble[4096]; ofstream* pref; // preamble output file ifstream isfp; float* xp, * yp; // data point // // constructor // ISFTDS() { quiet = false; sep=','; pref = NULL; xp=yp=NULL; } ~ISFTDS() { delete[] xp; delete[] yp; } int open(char* isfFile); int getPreamble(); int storePreamble(char* pFile = NULL); int getCurveData(); int dumpCSV(char* csvFile); }; ///////////////////////////////////////////////////////// // // functions // ///////////////////////////////////////////////////////// // // open input isf file // return 0 if success, 1 if fail // int ISFTDS::open(char* isfFile) { isfp.open(isfFile, ios::binary); if (isfp.fail()) { cerr << isfFile << ": Not found." << endl; return 1; } return 0; } // // get preamble // return 0 : success // 1,2 : No header // int ISFTDS::getPreamble() { // check header char buff[1024]; isfp.read(buff, 8); buff[8]=0; if (strncmp(buff, ":WFMPRE:", 8) !=0) { cerr << "Fatal: Doesn't start from [:WFMPRE:] ." << endl; return 1; } // // get preamble // int cpre=0; while (1) { char ch; isfp.read(&ch, 1); if (ch == ':') break; preamble[cpre++] = ch; } preamble[cpre]=0; if (!quiet) cout << preamble << endl; return 0; } // // storePreamble // 0: success // 1: Fail to open preamble dump file. // int ISFTDS::storePreamble(char* pFile) { // check file to dump preamble if (pFile) { pref = new ofstream(pFile); if (pref->fail()) { cerr << "Fail to open: " << pFile << endl; return 1; } } // if pFile char pre1[1024]; int pnt=0; for(int i=0;; ++i) { char ch=preamble[i]; if (ch == 0) break; if (ch == ';') { pre1[pnt] = 0; if (!quiet) cout << pre1 << endl; // analysis pre1 int d; float f; char buf[1024]; if (sscanf(pre1, "BYT_NR %d", &d)) { BYT_NR = d; if (pref) *pref << "BYT_NR = " << BYT_NR << endl; } if (sscanf(pre1, "BIT_NR %d", &d)) { BIT_NR = d; if (pref) *pref << "BIT_NR = " << BIT_NR << endl; } if (sscanf(pre1, "ENCDG %s", buf)) { strcpy(ENCDG, buf); if (pref) *pref << "ENCDG = " << ENCDG << endl; } if (sscanf(pre1, "BN_FMT %s", buf)) { strcpy(BN_FMT, buf); if (pref) *pref << "BN_FMT = " << BN_FMT << endl; } if (sscanf(pre1, "BYT_OR %s", buf)) { strcpy(BYT_OR, buf); if (pref) *pref << "BYT_OR = " << BYT_OR << endl; } if (sscanf(pre1, "NR_PT %d", &d)) { NR_PT = d; if (pref) *pref << "NR_PT = " << NR_PT << endl; } if (sscanf(pre1, "WFID \"%[^\n\"]", buf)) { strcpy(WFID, buf); if (pref) *pref << "WFID = " << WFID << endl; } if (sscanf(pre1, "PT_FMT %s", buf)) { strcpy(PT_FMT, buf); if (pref) *pref << "PT_FMT = " << PT_FMT << endl; } if (sscanf(pre1, "XINCR %f", &f)) { XINCR = f; if (pref) *pref << "XINCR = " << XINCR << endl; } if (sscanf(pre1, "PT_OFF %d", &d)) { PT_OFF = d; if (pref) *pref << "PT_OFF = " << PT_OFF << endl; } if (sscanf(pre1, "XZERO %f", &f)) { XZERO = f; if (pref) *pref << "XZERO = " << XZERO << endl; } if (sscanf(pre1, "XUNIT \"%[^\n\"]", buf)) { strcpy(XUNIT, buf); if (pref) *pref << "XUNIT = " << XUNIT << endl; } if (sscanf(pre1, "YMULT %f", &f)) { YMULT = f; if (pref) *pref << "YMULT = " << YMULT << endl; } if (sscanf(pre1, "YZERO %f", &f)) { YZERO = f; if (pref) *pref << "YZERO = " << YZERO << endl; } if (sscanf(pre1, "YOFF %f", &f)) { YOFF = f; if (pref) *pref << "YOFF = " << YOFF << endl; } if (sscanf(pre1, "YUNIT \"%[^\n\"]", buf)) { strcpy(YUNIT, buf); if (pref) *pref << "YUNIT = " << YUNIT << endl; } // end of pre1 analysis pnt=0; continue; } // if (ch==';') pre1[pnt++]=ch; } // for i if (pref) pref->close(); return 0; } // // getCurveData // 0: Success // 1: header error // 2: Unsupported data // int ISFTDS::getCurveData() { // header check char buff[1024]; isfp.read(buff, 7); buff[7]=0; if (strncmp(buff, "CURVE #", 7) !=0) { cerr << "Fatal: Curve section doesn't start from [CURVE #] ." << endl; return 1; } // get Data Length char ch; isfp.read(&ch, 1); int dlLen=ch-'0'; isfp.read(buff, dlLen); buff[dlLen]=0; Data_length=atoi(buff); cout << "Data length:" << Data_length << endl; ////// currently only cope with BYT_NR=2 ////// if (BYT_NR !=2) { cerr << "Sorry, this supports data only with BYT_NR=2" << endl; return 2; } int np=Data_length/BYT_NR; xp = new float[np]; yp = new float[np]; // // loop over point // int i=0; for(; ifail()) { cerr << "Fail to open: " << csvFile << endl; return 1; } cout << "Dump " << nPoints << " points into " << csvFile << endl; for(int i=0; iclose(); return 0; } #ifdef ISF2ROOTEXAMPLE /////////////////////////////////////////////////////////////////// // // main // /////////////////////////////////////////////////////////////////// // // help // void showUsage(char* com) { std::cout << com << " ver.0.00" << endl << "Usage: " << com << " [-h] [-q] [-p preamble] [-d]" << " isf_file csv_file"<< endl << endl << "Options:" << endl << " -h ... show this help" << endl << " -q ... don't print preamble" << endl << " -p preamble ... output preamble" << endl << " -d 0|1|2 ... Separator 0=,(default), 1=space, 2=tab" << endl; exit(1); } main(int argc, char** argv) { ISFTDS isf; //////////////// // option/argument analysis //////////////// char* idump = NULL; char ch; int sepNo; while ((ch = getopt(argc, argv, "hqp:d:")) != -1){ switch (ch){ case 'h': showUsage(argv[0]); case 'q': isf.quiet=true; break; case 'p': idump=optarg; break; case 'd': sepNo=atoi(optarg); if (sepNo==1) isf.sep=' '; if (sepNo==2) isf.sep='\t'; break; default: showUsage(argv[0]); } // switch } // while char* isfFile=argv[optind++], *csvFile=argv[optind++]; if (!isfFile || !csvFile) showUsage(argv[0]); if (idump) cout << "Preamble: " << idump << endl; cout << "isf: " << isfFile << endl; cout << "csv: " << csvFile << endl; // input ISF file open if (isf.open(isfFile)) exit(1); if (isf.getPreamble()) exit(1); if (isf.storePreamble(idump)) exit(1); if (isf.getCurveData()) exit(1); if (isf.dumpCSV(csvFile)) exit(1); } #endif // ifdef ISF2ROOTEXAMPLE #endif // ISF2ROOTTDS_CC //EOF