Surfer 7 Grid file format
I need to load (image) data files that are saved in the Surfer 7 Grid format. The file is binary and contains different sections (e.g. header, grid info and data). The format is well documented,
http://grapherhelp.goldensoftware.com/subsys/surfer_7_grid_file_format…
and I managed to put a simple loader together:
string filepath
Variable refNum
Open/R/F="GRID Files (*.grd):.grd;" refNum as filepath
if (refNum == 0)
return -1
endif
// extract file name from path as wave name
String wName = ParseFilePath(3, S_FileName, ":", 0, 0)
// pre-define byte positions of grid info section and data
variable GridInfoStartByte = 20
variable DataStartByte = 100
// load GRID info section, first two enties are "long",
// rows and columns of grid/image
Make/I/O/N=2/FREE W_RowsCols
FSetPos refNum, GridInfoStartByte
FBinRead/B=3 refNum, W_RowsCols
// load rest of the grid info section as double
Make/D/O/N=8/FREE W_Scaling
FSetPos refnum, GridInfoStartByte+8
FBinRead/B=3 refNum, W_Scaling
// load DATA section
Make/O/N=(W_rowsCols[0] * W_rowsCols[1])/D $wName /Wave = M_Data
FSetPos refNum, DataStartByte
FBinRead/B=3 refNum, M_Data
// redimension to matrix (note that cols and rows are swapped for propper display)
Redimension/N=(W_rowsCols[1],W_rowsCols[0]) M_Data
// ... more code to set wave scaling
Close refNum
return 0
End
However, at the moment the start byte positions of the different section are hardcoded and were identified using the binary file reader (https://www.wavemetrics.com/code-snippet/rudimentary-binary-file-reader). This works for all files I have encountered so far but a more versatile solution is preferred. The sections seem to be tagged by hex values, but I was unable to identify those in the binary files (an example file is attached).
Any hint to what I'm missing is highly appreciated!
Best
Christian
This is not the cleanest code, but may give you a start (sorry - I have not had a chance to check it with your file yet):
string filepath
Variable vRefNum
Open/R/F="GRID Files (*.grd):.grd;" vRefNum as filepath
if (vRefNum == 0)
return -1
endif
// extract file name from path as wave name
String wName = ParseFilePath(3, S_FileName, ":", 0, 0)
// check for minimum length
FStatus vRefNum
variable vFileLength=V_logEOF
if(vFileLength<12)
print "Error: not a GRD file."
Close vRefNum
return -1
endif
// Intel/Windows little endian
variable vByteOrder=3
string sID
variable vLength
variable vError = 0
do
// read tag: ID then length
sID = " " // 4 characters
FBinRead vRefNum, sID // 4-character ID
FBinRead/U/B=(vByteOrder)/F=3 vRefNum, vLength // 32-bit word - length
strswitch (sID)
case "DSRB": // 0x42525344 - Header
variable vVersion
FBinRead/U/B=(vByteOrder)/F=3 vRefNum, vVersion
Print "GRD File Version Number: " + num2str(vVersion)
break
case "GRID": // 0x44495247 - GRID
// load GRID info section, first two enties are "long",
// rows and columns of grid/image
Make/I/O/N=2/FREE W_RowsCols
FBinRead/B=3 vRefNum, W_RowsCols
// load rest of the grid info section as double
Make/D/O/N=8/FREE W_Scaling
FBinRead/B=3 vRefNum, W_Scaling
break
case "DATA": // 0x41544144 - Data
// load DATA section
Make/O/N=(W_rowsCols[0] * W_rowsCols[1])/D $wName /Wave = M_Data
FBinRead/B=3 vRefNum, M_Data
// redimension to matrix (note that cols and rows are swapped for propper display)
Redimension/N=(W_rowsCols[1],W_rowsCols[0]) M_Data
// ... more code to set wave scaling
break
case "FLTI": // 0x49544c46 - Fault Information
// .. code to read fault info section
break
default:
print "Error: Unknown tag."
vError = -1
break
endSwitch
if (vError != 0)
break
endif
// ... code to check end of file
FStatus vRefNum
if (V_filePos >= V_logEOF)
break
endif
while(1)
Close vRefNum
return vError
End
Hope this helps,
Kurt
April 23, 2020 at 02:27 am - Permalink
Hi Kurt,
thanks a lot! Much appreciated!
The obvious never occurred to me that hex is converted to characters (or vice versa), even though I could spot it in the binary reader snippet, however, it seems that I looked at the hex values in the wrong byte order. I also understand now better how FBinRead works!
Thanks again!
C
April 23, 2020 at 04:09 am - Permalink
You are very welcome.
I took inspiration from a TIFF reader that I posted previously here.
Cheers,
Kurt
April 23, 2020 at 04:22 am - Permalink