/* * * Tektronix internal data format .isf to csv converter * TDS3034 * * compile: g++ -o isf2csv isf2csv.cc * * * Ver 0.02 2013/4/24 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.02" << 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_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; }; // 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, 8); buff[8]=0; if (strncmp(buff, ":WFMPRE:", 8) !=0) { cerr << isfFile << ": Doesn't start from [:WFMPRE:] ." << 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, 7); buff[7]=0; if (strncmp(buff, "CURVE #", 7) !=0) { cerr << isfFile << ": Curve section doesn't start from [CURVE #] ." << 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_NR !=2) { cerr << "Sorry, this supports only data with BYT_NR=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_NR; 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_NR %d", &d)) { pre.BYT_NR = d; if (pref) *pref << "BYT_NR = " << pre.BYT_NR << endl; } if (sscanf(pre1, "BIT_NR %d", &d)) { pre.BIT_NR = d; if (pref) *pref << "BIT_NR = " << pre.BIT_NR << endl; } if (sscanf(pre1, "ENCDG %s", buf)) { strcpy(pre.ENCDG, buf); if (pref) *pref << "ENCDG = " << pre.ENCDG << endl; } if (sscanf(pre1, "BN_FMT %s", buf)) { strcpy(pre.BN_FMT, buf); if (pref) *pref << "BN_FMT = " << pre.BN_FMT << endl; } if (sscanf(pre1, "BYT_OR %s", buf)) { strcpy(pre.BYT_OR, buf); if (pref) *pref << "BYT_OR = " << pre.BYT_OR << endl; } if (sscanf(pre1, "NR_PT %d", &d)) { pre.NR_PT = d; if (pref) *pref << "NR_PT = " << pre.NR_PT << endl; } if (sscanf(pre1, "WFID \"%[^\n\"]", buf)) { strcpy(pre.WFID, buf); if (pref) *pref << "WFID = " << pre.WFID << endl; } if (sscanf(pre1, "PT_FMT %s", buf)) { strcpy(pre.PT_FMT, buf); if (pref) *pref << "PT_FMT = " << pre.PT_FMT << endl; } if (sscanf(pre1, "XINCR %f", &f)) { pre.XINCR = f; if (pref) *pref << "XINCR = " << pre.XINCR << endl; } if (sscanf(pre1, "PT_OFF %d", &d)) { pre.PT_OFF = d; if (pref) *pref << "PT_OFF = " << pre.PT_OFF << endl; } if (sscanf(pre1, "XZERO %f", &f)) { pre.XZERO = f; if (pref) *pref << "XZERO = " << pre.XZERO << endl; } if (sscanf(pre1, "XUNIT \"%[^\n\"]", buf)) { strcpy(pre.XUNIT, buf); if (pref) *pref << "XUNIT = " << pre.XUNIT << endl; } if (sscanf(pre1, "YMULT %f", &f)) { pre.YMULT = f; if (pref) *pref << "YMULT = " << pre.YMULT << endl; } if (sscanf(pre1, "YZERO %f", &f)) { pre.YZERO = f; if (pref) *pref << "YZERO = " << pre.YZERO << endl; } if (sscanf(pre1, "YOFF %f", &f)) { pre.YOFF = f; if (pref) *pref << "YOFF = " << pre.YOFF << endl; } if (sscanf(pre1, "YUNIT \"%[^\n\"]", buf)) { strcpy(pre.YUNIT, buf); if (pref) *pref << "YUNIT = " << pre.YUNIT << endl; } // end of pre1 analysis pnt=0; continue; } // if (ch==';') pre1[pnt++]=ch; } } //EOF