
Load Tek ISF File


hrodstein
I recommend that you download the attached file rather than copying this code because I had some formatting problems with the URLs in the comments.
#pragma rtGlobals=3 // Use modern global access method. // File Loader for Tektronix ISF files // A Tektronix ISF file is the contents of what a Tek oscilloscope sends in response // to a WAVFrm? command. See https://www.tek.com/support/faqs/what-format-isf-file // // A Tek ISF file is not the same as a Tek WFM file. There exists a loader for Tek WFM files. // See https://www.wavemetrics.com/project/LoadTekWaveform. // // It is recommended that you name your Tek ISF files with the ".isf" extension to make // it clear what kind of file it is. // The way to determine the header length is to look for the ":CURVE" keyword. It is formatted like this: // ":CURVE <digit><number>" .e.g., ":CURVE 41000" // where <digit> represents the number of digits is the following number and <number> represents the number of // samples of binary data that follow. In this case, "4" is the number of digits in "1000" and 1000 is the number of samples. static Constant kHeaderLength = 282 // Length of header in bytes. Empirically determined. static Constant kWaveDataType = 2 // Single precision floating point // LoadTekISFFile(pathName, fileName, createTable, createGraph) // // pathName is the name of an Igor symbolic path or "". // fileName is one of the following: // The name of a file in the folder designated by pathName. // A partial path from the folder designated by pathName to the file to be loaded. // A full path to the file to be loaded. // "" to get an Open File dialog. // Add an item to Igor's Load Waves submenu (Data menu) Menu "Load Waves" "Load Tek ISF File...", LoadTekISFFileMenuItem() "Load All Tek ISF Files In Folder...", LoadAllTekISFFiles("", "", 0, 0) End Function/S StripDoubleQuotes(str) String str // A string starting and ending with double quotes if (CmpStr(str[0], "\"") != 0) return str // String did not start with double quotes endif Variable len = strlen(str) str = str[1,len-2] return str End Structure TekISFHeaderInfo Variable encoding // 0 = binary. -1 = unknown. Currently the only encoding I know about is binary. From ENCDG keyword. Variable byteOrder // 0 = big-endian, 1 = little-endian. From BYT_OR keyword. Variable dataType // See WaveType for possible values. From BIT_NR and BN_FMT keywords. Variable numPoints // Number of points in waveform. From NR_PT keyword. String xUnits // From XUNIT keyword. Variable x0 // From XZERO keyword. Variable dx // From XINCR keyword. String yUnits // From YUNIT keyword. Variable yOffset // From YOFF keyword. Variable yZero // From YZERO keyword. Variable yMultiplier // From YMULT keyword. EndStructure Function ExtractISFHeaderInfo(refNum, headerInfo, quiet) Variable refNum // File reference number STRUCT TekISFHeaderInfo &headerInfo Variable quiet // 0 - print information about errors Variable result = 0 Variable originalPos FStatus refNum originalPos = V_filePos // Read header string String headerStr = "" Variable headerStrLength = kHeaderLength FSetPos refNum, 0 headerStr = PadString(headerStr, kHeaderLength, 0x20) FBinRead refNum, headerStr FSetPos refNum, originalPos // Parse header string String str str = StringByKey("ENCDG", headerStr, " ") strswitch(str) case "BIN": headerInfo.encoding = 0 break default: headerInfo.encoding = -1 // Unknown encoding result -= 1 break endswitch str = StringByKey("BYT_OR", headerStr, " ") strswitch(str) case "MSB": headerInfo.byteOrder = 0 break case "LSB": headerInfo.byteOrder = 1 break default: headerInfo.byteOrder = -1 // Unknown byte order result -= 1 break endswitch headerInfo.numPoints = NumberByKey("NR_PT", headerStr, " ") headerInfo.xUnits = StripDoubleQuotes(StringByKey("XUNIT", headerStr, " ")) headerInfo.x0 = NumberByKey("XZERO", headerStr, " ") headerInfo.dx = NumberByKey("XINCR", headerStr, " ") headerInfo.yUnits = StripDoubleQuotes(StringByKey("YUNIT", headerStr, " ")) headerInfo.yOffset = NumberByKey("YOFF", headerStr, " ") headerInfo.yZero = NumberByKey("YZERO", headerStr, " ") headerInfo.yMultiplier = NumberByKey("YMULT", headerStr, " ") Variable numBitsPerPoint = NumberByKey("BIT_NR", headerStr, " ") String binaryFormat = StringByKey("BN_FMT", headerStr, " ") strswitch(binaryFormat) case "RI": // Presumably "real integer" switch (numBitsPerPoint) case 8: headerInfo.dataType = 8 // 8 bit signed integer break case 16: headerInfo.dataType = 16 // 16 bit signed integer break case 32: headerInfo.dataType = 32 // 32 bit signed integer break default: headerInfo.dataType = -1 // Unknown type result -= 1 break endswitch break default: headerInfo.dataType = -1 // Don't understand datatype result -= 1 break endswitch return result End // LoadTekISFFileDialog(createTable, createGraph) // Displays a dialog in which the user can enter parameters. // All of the parameters function both as inputs, to preset the dialog values, // and as output, to return the values to the calling routine. // The function result is 0 if OK or -1 if cancel. Function LoadTekISFFileDialog(createTable, createGraph) Variable &createTable // Input and output. Variable &createGraph // Input and output. if ( (createTable<1) || (createTable>2) ) createTable = 1 endif if ( (createGraph<1) || (createGraph>2) ) createGraph = 1 endif // This is necessary because you can't pass an & parameter to Prompt. Variable createTable2 = createTable Variable createGraph2 = createGraph Prompt createTable2, "Create table", popup "Yes;No" Prompt createGraph2, "Create graph", popup "Yes;No" DoPrompt "Load Tek ISF File", createTable2, createGraph2 if (V_Flag != 0) return -1 // User cancelled. endif createTable = createTable2 createGraph = createGraph2 return 0 End Function LoadTekISFFile(pathName, fileName, createTable, createGraph, quiet, newWaveName) String pathName // Igor symbolic path name or "" for dialog. String fileName // file name, partial path and file name, or full path or "" for dialog. Variable createTable // 1 = Yes, 2 = No, 0 for dialog. Variable createGraph // 1 = Yes, 2 = No, 0 for dialog. Variable quiet // 0 = print diagnostic and error messages, 1 = print error messages only, 2 = do not print diagnostic or error messages String &newWaveName // Output: Name of wave created. newWaveName = "" Variable err if ( (createTable==0) || (createGraph==0) ) err = LoadTekISFFileDialog(createTable, createGraph) if (err != 0) return err endif endif // This puts up a dialog if the pathName and fileName do not specify a file. String message = "Select a Tek ISF file" Variable refNum Open /R /Z=2 /P=$pathName /T="????" /M=message refNum as fileName // /T flag presents "All files" in Open File dialog. // Save outputs from Open in a safe place. err = V_Flag String fullPath = S_fileName if (err != 0) return err // -1 means user canceled. endif // Load the header information STRUCT TekISFHeaderInfo headerInfo if (ExtractISFHeaderInfo(refNum, headerInfo, quiet!=2) != 0) if (quiet != 2) Print "Error while loading header section of the file." endif Close refNum return -1 endif Close refNum switch (headerInfo.encoding) case 0: // Binary break default: if (quiet != 2) Print "The file's encoding is unknown. Only binary encoding is supported." endif return -1 endswitch if (quiet == 0) Printf "Loading Tek ISF data from \"%s\"\r", fullPath endif GBLoadWave /B=(headerInfo.byteOrder) /A=tekWave /T={headerInfo.dataType,kWaveDataType} /S=(kHeaderLength) /W=1 /U=(headerInfo.numPoints) /Q fullPath if (V_flag == 0) if (quiet != 2) Print "Error while loading binary data section of the file." endif return -1 endif newWaveName = StringFromList(0, S_waveNames) Wave w = $newWaveName SetScale/P x, headerInfo.x0, headerInfo.dx, ""+headerInfo.xUnits, w SetScale d, 0, 0, ""+headerInfo.yUnits, w // I don't know what headerInfo.yZero is all about (YZERO keyword). w = (w - headerInfo.yOffset) * headerInfo.yMultiplier if (quiet == 0) Printf "Created wave %s, %d points.\r", newWaveName, numpnts(w) endif if (createTable == 1) Edit w.id ModifyTable format[1]=3,digits[1]=9 // Display time in suitable format. endif if (createGraph == 1) Display w endif return 0 // Zero signifies no error. End Function LoadTekISFFileMenuItem() String newWaveName LoadTekISFFile("", "", 1, 1, 0, newWaveName) End // LoadAllTekISFFilesDialog(extension, createTable, createGraph) // Displays a dialog in which the user can enter parameters. // All of the parameters function both as inputs, to preset the dialog values, // and as output, to return the values to the calling routine. // The function result is 0 if OK or -1 if cancel. Function LoadAllTekISFFilesDialog(extension, createTable, createGraph) String &extension // Input and output Variable &createTable // Input and output. Variable &createGraph // Input and output. if (CmpStr(extension,".isf")!=0 && CmpStr(extension,"????")!=0) extension = ".isf" endif if ( (createTable<1) || (createTable>2) ) createTable = 1 endif if ( (createGraph<1) || (createGraph>2) ) createGraph = 1 endif // This is necessary because you can't pass an & parameter to Prompt. String extension2 = extension Variable createTable2 = createTable Variable createGraph2 = createGraph Prompt extension2, "Tek ISF file name extension", popup ".isf;Any extension" Prompt createTable2, "Create table", popup "Yes;No" Prompt createGraph2, "Create graph", popup "Yes;No" DoPrompt "Load All Tek ISF Files", extension2, createTable2, createGraph2 if (V_Flag != 0) return -1 // User cancelled. endif if (CmpStr(extension2, "Any extension") == 0) extension2 = "????" endif extension = extension2 createTable = createTable2 createGraph = createGraph2 return 0 End Function LoadAllTekISFFiles(pathName, extension, createTable, createGraph) String pathName // Name of an Igor symbolic folder created by Misc->NewPath String extension // e.g., ".isf". Pass "????" for any extension. Pass "" for dialog. Variable createTable // 1 = Yes, 2 = No, 0 for dialog. Variable createGraph // 1 = Yes, 2 = No, 0 for dialog. if (CmpStr(extension,"")==0 || createTable<1 || createTable>2 || createGraph<1 || createGraph>2) if (LoadAllTekISFFilesDialog(extension, createTable, createGraph) != 0) return -1 // User cancelled. endif endif if (strlen(pathName) == 0) String message if (CmpStr(extension, "????") == 0) message = "Select a directory containing Tek ISF files with any extension" else sprintf message, "Select a directory containing Tek ISF files with %s extension", extension endif NewPath/O/M=message TekISFDataPath // This displays a dialog in which you can select a folder if (V_flag != 0) return V_flag // -1 means user canceled endif pathName = "TekISFDataPath" endif Variable err = 0 String newWaveName String fileName Variable i = 0 do fileName = IndexedFile($pathName, i, extension) if (strlen(fileName) == 0) break // No more files endif err = LoadTekISFFile(pathName, fileName, 2, 2, 1, newWaveName) if (err != 0) return err endif if (createTable == 1) if (i == 0) Edit $newWaveName else AppendToTable $newWaveName endif endif if (createGraph == 1) if (i == 0) Display $newWaveName else AppendToGraph $newWaveName endif endif i += 1 while(1) return 0 End

Forum

Support

Gallery
Igor Pro 9
Learn More
Igor XOP Toolkit
Learn More
Igor NIDAQ Tools MX
Learn More