/* * * Tektronix internal data format .isf to csv converter * for DPO4054 * * compile: g++ -o isf2csvDPO isf2csvDPO.cc * * * Ver 0.00 2013/4/27 Y. Takeuchi * */ #include #include #include #include #include using namespace std; // global variables for getopt extern char *optarg; extern int optind, opterr; // // 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); } // // struct PRE // struct PRE { int BYT_N; // 2 int BIT_N; // 16 char ENC[1024]; // BIN char BN_F[1024]; // RI char BYT_O[1024]; // MSB char WFI[1024]; // "Ch1, DC coupling, 20.00uV/div, 4.000us/div, 100000 points, Sample mode" int NR_P; // 100000 char PT_F[1024]; // Y char XUN[1024]; // "s" double XIN; // 400.0000E-12 double XZE; // -20.0000E-6 int PT_O; // 0 char YUN[1024]; // "V" double YMU; // 3.1250E-9 double YOF; // -1.0240E+3 double YZE; // 0.0E+0 double VSCALE; // 20.0000E-6 double HSCALE; // 2.0000E-6 double VPOS; // -160.0000E-3 double VOFFSET; // 0.0E+0 double HDELAY; // 0.0E+0 int Data_length; }; // prototypes void storePreamble(char* preamble, PRE& pre, bool quiet, ofstream* pref); /////////////////////////////////////////////////////////////////// // // main // /////////////////////////////////////////////////////////////////// main(int argc, char** argv) { //////////////// // option/argument analysis //////////////// bool quiet=false; char* idump=NULL; char sep=','; int sepNo=0; char ch; while ((ch = getopt(argc, argv, "hqp:d:")) != -1){ switch (ch){ case 'h': showUsage(argv[0]); case 'q': quiet=true; break; case 'p': idump=optarg; break; case 'd': sepNo=atoi(optarg); if (sepNo==1) sep=' '; if (sepNo==2) 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; //////////////// // main //////////////// ifstream isf; ofstream csv; isf.open(isfFile, ios::binary); if (!isf) { cerr << isfFile << ": Not found." << endl; exit(1); } // check header char buff[1024]; isf.read(buff, 6); buff[6]=0; if (strcmp(buff, ":WFMP:") !=0) { cerr << isfFile << ": Doesn't start from [:WFMP:] ." << endl; exit(1); } // skip to next :WFMP: char preamble0[4096]; int cpre0=0; while (1) { isf.read(&ch, 1); if (ch == ':') break; preamble0[cpre0++] = ch; } // check header of next WFMP: isf.read(buff, 5); buff[5]=0; if (strncmp(buff, "WFMP:", 5) !=0) { cerr << isfFile << ": Can't find the next [:WFMP:] ." << endl; exit(1); } // // get preamble // char preamble[4096]; int cpre=0; PRE pre; while (1) { isf.read(&ch, 1); if (ch == ':') break; preamble[cpre++] = ch; } preamble[cpre]=0; if (!quiet) cout << preamble << endl; ofstream* pref = NULL; if (idump) { pref = new ofstream(idump); if (pref->fail()) { cerr << "Fail to open: " << idump << endl; exit(1); } } // if idump storePreamble(preamble, pre, quiet, pref); if (idump) pref->close(); // // get curve data // isf.read(buff, 6); buff[6]=0; if (strncmp(buff, "CURV #", 6) !=0) { cerr << isfFile << ": Curve section doesn't start from [CURV #] ." << endl; exit(1); } isf.read(&ch, 1); int dlLen=ch-'0'; isf.read(buff, dlLen); buff[dlLen]=0; pre.Data_length=atoi(buff); cout << "Data length:" << pre.Data_length << endl; ////// currently only cope with BYT_NR=2 ////// if (pre.BYT_N !=2) { cerr << "Sorry, this supports only data with BYT_N=2" << endl; exit(1); } // open csv file ofstream* csvf = NULL; csvf = new ofstream(csvFile); if (csvf->fail()) { cerr << "Fail to open: " << csvFile << endl; exit(1); } // loop over point int np=pre.Data_length/pre.BYT_N; int i=0; for(; iclose(); cout << endl << i << " points recorded." << endl; } ///////////////////////////////////////////////////////// // // functions // ///////////////////////////////////////////////////////// void storePreamble(char* preamble, PRE& pre, bool quiet, ofstream* pref) { 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_N %d", &d)) { // Byte # pre.BYT_N = d; if (pref) *pref << "BYT_N = " << pre.BYT_N << endl; } if (sscanf(pre1, "BIT_N %d", &d)) { // BIT # pre.BIT_N = d; if (pref) *pref << "BIT_N = " << pre.BIT_N << endl; } if (sscanf(pre1, "ENC %s", buf)) { // Encoding? BIN strcpy(pre.ENC, buf); if (pref) *pref << "ENC = " << pre.ENC << endl; } if (sscanf(pre1, "BN_F %s", buf)) { // BN?_Format RI strcpy(pre.BN_F, buf); if (pref) *pref << "BN_F = " << pre.BN_F << endl; } if (sscanf(pre1, "BYT_O %s", buf)) { // Byte order MSB strcpy(pre.BYT_O, buf); if (pref) *pref << "BYT_O = " << pre.BYT_O << endl; } if (sscanf(pre1, "WFI \"%[^\n\"]", buf)) { // WFID? strcpy(pre.WFI, buf); if (pref) *pref << "WFI = " << pre.WFI << endl; } if (sscanf(pre1, "NR_P %d", &d)) { // # of Record point pre.NR_P = d; if (pref) *pref << "NR_P = " << pre.NR_P << endl; } if (sscanf(pre1, "PT_F %s", buf)) { // PT_Format? strcpy(pre.PT_F, buf); if (pref) *pref << "PT_F = " << pre.PT_F << endl; } if (sscanf(pre1, "XUN \"%[^\n\"]", buf)) { // Xunit strcpy(pre.XUN, buf); if (pref) *pref << "XUN = " << pre.XUN << endl; } if (sscanf(pre1, "XIN %f", &f)) { // X increment pre.XIN = f; if (pref) *pref << "XIN = " << pre.XIN << endl; } if (sscanf(pre1, "XZE %f", &f)) { // X zero pre.XZE = f; if (pref) *pref << "XZE = " << pre.XZE << endl; } if (sscanf(pre1, "PT_O %d", &d)) { // Point offset pre.PT_O = d; if (pref) *pref << "PT_O = " << pre.PT_O << endl; } if (sscanf(pre1, "YUN \"%[^\n\"]", buf)) { // Y unit strcpy(pre.YUN, buf); if (pref) *pref << "YUN = " << pre.YUN << endl; } if (sscanf(pre1, "YMU %f", &f)) { // Y multiplification? pre.YMU = f; if (pref) *pref << "YMU = " << pre.YMU << endl; } if (sscanf(pre1, "YOF %f", &f)) { // Y offset pre.YOF = f; if (pref) *pref << "YOF = " << pre.YOF << endl; } if (sscanf(pre1, "YZE %f", &f)) { // Y Zero pre.YZE = f; if (pref) *pref << "YZE = " << pre.YZE << endl; } if (sscanf(pre1, "VSCALE %f", &f)) { // V scale pre.VSCALE = f; if (pref) *pref << "VSCALE = " << pre.VSCALE << endl; } if (sscanf(pre1, "HSCALE %f", &f)) { // H scale pre.HSCALE = f; if (pref) *pref << "HSCALE = " << pre.HSCALE << endl; } if (sscanf(pre1, "VPOS %f", &f)) { // V scale pre.VPOS = f; if (pref) *pref << "VPOS = " << pre.VPOS << endl; } if (sscanf(pre1, "VOFFSET %f", &f)) { // V scale pre.VOFFSET = f; if (pref) *pref << "VOFFSET = " << pre.VOFFSET << endl; } if (sscanf(pre1, "HDELAY %f", &f)) { // V scale pre.HDELAY = f; if (pref) *pref << "HDELAY = " << pre.HDELAY << endl; } // end of pre1 analysis pnt=0; continue; } // if (ch==';') pre1[pnt++]=ch; } } //EOF