//"OpenHSDC" function written by Ben Ohler at Veeco Metrology Inc. 06/07/2006 // // Use: Opens Nanoscope High Speed Data Capture (HSDC) files in IGOR and loads data into waves with appropriate scaling // // Compatibility: Developed and tested using HSDC files from NanoScope v7r2 and Igor Pro v 4 running under Windows XP. // Import code should be tolerant of additions and re-ordering of parms in data header. // The header text strings are declared and assigned at the beginning of the function. These could be changed as needed to update compatibility with future file formats. // // Syntax: OpenHSDC("prefix",scale,owr) // // where: // "prefix": Optional text sting containing characters to be used as prefixes for the wave names. // "prefix_" : Text must be enclosed in double quotes and should begin with a letter. An trailing underscore is recommended. // "" : If no prefix is desired an empty string must still be entered // // scale: controls whether or not the "hard" scale (Volts) or "soft" scale (typically nm) is used in the wave scaling // 0: Use hard scale // 1: Use soft scale (for data channels where a soft scale is given) // // owr: controls whether or not existing waves get overwritten or if numerical suffix is incremented instead // 0: Do not overwrite existing waves, use next available numerical suffix. // 1: Overwrite existing waves, if any. This will always result in wave names ending in zero. // // Notes: // Waves are named automatically according to their data type (i.e.- VerticalDeflection, Input3, etc.) followed by a numerical suffix that enables unique wave names // and with the prefix described above. // // The following global waves are created by this function: // // HSDC, HSDC_offset, HSDC_datatype, HSDC_rate, HSDC_samples, HSDC_hard, HSDC_hardlabel, HSDC_soft, HSDC_softlabel // // !!!Any existing waves by the same name will be overwritten!!! // // // Example: // // HSDC("titin_",1,1) // // -This will prompt for a data file, load the data into waves prefixed by "titin_" with the soft scaling enabled where available. // // Typical Output: // // C:Documents and Settings:ohler:Desktop:4chan // File contains: 4 HSDC channels // // Parsing data files header... // // Channel 1 (VerticalDeflection ): Offset= 40960 bytes; Rate= 6.25 MHz; Samples= 626688 pts; Hard scale= -4.000 V; Soft scale= -4.000 V // Channel 2 (LateralDeflection ): Offset= 1294336 bytes; Rate= 6.25 MHz; Samples= 626688 pts; Hard scale= -4.000 V; Soft scale= -4.000 V // Channel 3 (SignalSum ): Offset= 2547712 bytes; Rate= 500.00 kHz; Samples= 50016 pts; Hard scale= 24.576 V; Soft scale= 24.576 V // Channel 4 (Height ): Offset= 2647744 bytes; Rate= 500.00 kHz; Samples= 50016 pts; Hard scale= 440.000 V; Soft scale= 12.260 nm/V // // // Loading data into waves... // // Channel 1 (VerticalDeflection ) has been imported with the wave name: "titin_VerticalDeflection0" and has been scaled to use units of V // Channel 2 (LateralDeflection ) has been imported with the wave name: "titin_LateralDeflection0" and has been scaled to use units of V // Channel 3 (SignalSum ) has been imported with the wave name: "titin_SignalSum0" and has been scaled to use units of V // Channel 4 (Height ) has been imported with the wave name: "titin_Height0" and has been scaled to use units of nm #pragma rtGlobals=1 // Use modern global access method. Function OpenHSDC(prefix,scale,owr) String prefix Variable scale Variable owr Variable refNum Variable i String str // Search strings used for parsing data file String sOL1HSDC = "\Start context: OL1HSDC" String sOL2HSDC = "\Start context: OL2HSDC" String sHSDCCiao = "\*Ciao HSDC list" String sHSDC_offset = "\Data offset:" String sHSDC_datalength = "\Data length:" String sHSDC_bytesperpixel = "\Bytes/pixel:" String sHSDC_datatype = "\High Speed Data Type:" String sHSDC_rate = "\High Speed Data Channel Rate:" String sHSDC_samples = "\Number of samples:" String sHSDC_hard = "\High Speed Data Hard Scale:" String sHSDC_soft = "\High Speed Data Soft Scale:" String sEOF = "\*File list end" Variable HSDC_count = 0 Make/O/N=5/D HSDC = 0 Make/O/N=5/D HSDC_offset = 0 Make/O/N=5/T HSDC_datatype = "null" Make/O/N=5/D HSDC_rate = 0 Make/O/N=5/D HSDC_samples= 0 Make/O/N=5/D HSDC_hard = 0 Make/O/N=5/T HSDC_hardlabel = "null" Make/O/N=5/D HSDC_soft = 0 Make/O/N=5/T HSDC_softlabel = "null" // Open file for read. Open/R/Z=2 refNum // Store results from Open in a safe place, report any errors Variable err = V_flag String sHSDCfilename = S_fileName if (err == -1) Print "HSDC file open cancelled by user." return -1 endif if (err != 0) DoAlert 0, "Unknown error opening HSDC file." return err endif // Look in the first 10 lines to see if it's really a HSDC file for (i=0;i<10;i+=1) FReadLine refNum, str // Read line into string variable if(strsearch(str,sOL1HSDC,0)!=-1) Break elseif(strsearch(str,sOL2HSDC,0)!=-1) Break endif endfor if(i==10) DoAlert 0, "Not a valid Nanoscope HSDC file." return err endif //Start parsing header to find HSDC ciao data do FReadLine refNum, str // Read line into string variable if(strsearch(str,sHSDCCiao,0)!=-1) HSDC_count+=1 HSDC[HSDC_count]=1 //HSDC channel found variable looptimer = 0 do FReadLine refNum, str // Read line into string variable looptimer+=1 if(strsearch(str,sHSDC_offset,0)!=-1) HSDC[HSDC_count]+=1 //HSDC offset for channel found variable offset=0 sscanf str, sHSDC_offset+" %f", offset //parse ciao line for offset HSDC_offset[HSDC_count]=offset //store offset in offset wave endif if(strsearch(str,sHSDC_datalength,0)!=-1) HSDC[HSDC_count]+=1 //HSDC data length for channel found variable datalength=0 sscanf str, sHSDC_datalength+" %f", datalength //parse ciao line for data length endif if(strsearch(str,sHSDC_bytesperpixel,0)!=-1) HSDC[HSDC_count]+=1 //HSDC bytes per pixel for channel found variable bytesperpixel=0 sscanf str, sHSDC_bytesperpixel+" %f", bytesperpixel //parse ciao line for bytes per pixel endif if(strsearch(str,sHSDC_datatype,0)!=-1) HSDC[HSDC_count]+=1 //HSDC data type for channel found string datatype = "null" string datatype2 = "null" sscanf str, sHSDC_datatype+" %s%s", datatype, datatype2 //parse ciao line for data type datatype=datatype+datatype2 HSDC_datatype[HSDC_count]=datatype //store data type in wave endif if(strsearch(str,sHSDC_rate,0)!=-1) HSDC[HSDC_count]+=1 //HSDC rate for channel found variable rate=0 sscanf str, sHSDC_rate+" %f", rate //parse ciao line for rate HSDC_rate[HSDC_count]=rate //store rate in rate wave endif //if(strsearch(str,sHSDC_samples,0)!=-1) // HSDC[HSDC_count]+=1 //HSDC samples for channel found // variable samples=0 // sscanf str, sHSDC_samples+" %f", samples //parse ciao line for samples //samples parm in data file is bogus // //printf "samples= %d ;", samples // HSDC_samples[HSDC_count]=samples //store samples in samples wave //endif if(strsearch(str,sHSDC_hard,0)!=-1) HSDC[HSDC_count]+=1 //HSDC hard scale for channel found variable hard=0 string hardlabel="null" sscanf str, sHSDC_hard+" %f %s", hard, hardlabel //parse ciao line for hard scale HSDC_hard[HSDC_count]=hard //store hard scale in hard scale wave HSDC_hardlabel[HSDC_count]=hardlabel endif if(strsearch(str,sHSDC_soft,0)!=-1) HSDC[HSDC_count]+=1 //HSDC soft scale for channel found variable soft=0 string softlabel = "null" sscanf str, sHSDC_soft+" %f %s", soft, softlabel //parse ciao line for soft scale HSDC_soft[HSDC_count]=soft //store soft scale in soft scale wave HSDC_softlabel[HSDC_count]=softlabel endif if(looptimer>50) DoAlert 0, "Failed to find one or more HSDC parameters. Aborting Load." return err endif while(HSDC[HSDC_count]!=8) //continues to read lines until all 7 parms are found for channel HSDC_samples[HSDC_count]=datalength/bytesperpixel //calculate number of samples from data length and bytes per pixel because the sample parm is bogus endif while(strsearch(str,sEOF,0)==-1) printf "\r%s" sHSDCfilename printf "\rFile contains: %d HSDC channels\r",HSDC_count printf "\rParsing data files header...\r" variable n for(n=1;n<HSDC_count+1;n+=1) printf "\r Channel %2d (%-20s): Offset= %8d bytes; Rate= %6.2W1PHz; Samples= %8d pts; Hard scale= %7.3f %s; Soft scale= %7.3f %s",n,HSDC_datatype[n],HSDC_offset[n],HSDC_rate[n],HSDC_samples[n],HSDC_hard[n],HSDC_hardlabel[n],HSDC_soft[n],HSDC_softlabel[n] endfor Close refNum // Close file variable b printf "\r\r\rLoading data into waves...\r" for(b=1;b<HSDC_count+1;b+=1) String sHSDCwavename=prefix+HSDC_datatype[b] //appends optional prefix to waves name String cmd if(owr!=1) //use function overwrite parm to determine whether waves should be overwritten sprintf cmd, "GBLoadWave/Q/B/A=%s/T={16,4}/S=%d/W=1/U=%d \"%s\"", sHSDCwavename,HSDC_offset[b],HSDC_samples[b],sHSDCfilename else sprintf cmd, "GBLoadWave/Q/O/B/A=%s/T={16,4}/S=%d/W=1/U=%d \"%s\"", sHSDCwavename,HSDC_offset[b],HSDC_samples[b],sHSDCfilename endif Execute cmd //can't execute GBLoadWave direct from function SVAR S_waveNames variable l l=strlen(S_waveNames) S_waveNames=S_waveNames[0,l-2] //strips the trailing semicolon from wave string Wave w=$S_waveNames w=w/(2^16)*HSDC_hard[b] //Scale waves by hard scale SetScale/P x 0,1/HSDC_rate[b],"s", w;DelayUpdate //Scales time axis SetScale d 0,0,HSDC_hardlabel[b], w //Applies data units if(scale!=0&&HSDC_soft[b]!=HSDC_hard[b]) //check function scale parm to see if soft scale should be applied: 0: use hard scale , !=0: use soft scale w=w*HSDC_soft[b] //scales by soft scale String newunits newunits=HSDC_softlabel[b] l=strlen(newunits) newunits=newunits[0,l-3] SetScale d 0,0,newunits, w //Applies soft data units endif if(scale!=0&&HSDC_soft[b]!=HSDC_hard[b]) //check function scale parm to see if soft scale should be applied: 0: use hard scale , !=0: use soft scale printf "\r Channel %2d (%-20s) has been imported with the wave name: \"%s\" and has been scaled to use units of %s", b, HSDC_datatype[b],S_waveNames,newunits else printf "\r Channel %2d (%-20s) has been imported with the wave name: \"%s\" and has been scaled to use units of %s", b, HSDC_datatype[b],S_waveNames,HSDC_hardlabel[b] endif endfor printf "\r" End