%usage: data = open_di(file_name) %This program extracts the data from a NanoScope data file. The scaled %results are placed in the matrix data, an N x M x L matrix, where N is %the number of lines, M is the number of points per line (N = M in most %cases), and L is the number of simultaneous data channels recorded. %This program assumes that the first data channel is topgraphy and all %the other channels are not topography. The data output is nm for the %first channel and V for all subsequent channels. %This program is based on the get_image_data m file which is a part of the %Carpick Lab Toolbox, with changes made to the data scaling. %Jennifer R. Hampton 2/16/09 function data = open_di(file_name) %The scaling of binary data to physical units is based on Appendix B "Data %File Format" from the NanoScope Command Reference Manual (Section B.6.3) %The Z scale conversion factors for topography are in the following two %header lines: %\@Sens. Zscan: V XXX nm/V %\@2:Z scale: V [Sens. Zscan] (XXX V/LSB) YYY V %There will be one version of the second line for each simultaneous data %channel that is recorded. For example, a for a friction channel, the %second header line is: %\@2:Z scale: V [Sens. Friction] (XXX V/LSB) YYY V %The first header line in this case isn't needed: %\@Sens. Friction: V 1.000000 %To convert from binary (LSB) to hardware units (V), the second line is %used. The XXX value in parentheses is the conversion factor that was used %when the data were taken. However, a rescaling is performed when the %data are saved to use the full range of the 2-byte binary data. So the %scaling factor to convert saved LSB data to V is %YYY V/2^16 LSB = YYY V/65536 LSB. %In the topography case, to convert from hardware units (V) to physical %units (nm), the first line is used. The scaling factor is %XXX nm/V. %maximum integer stored in 2-byte number maxlsb = 2^16; %open file for reading fid = fopen(file_name,'r'); if (fid == -1) disp('Error reading file, exiting'); return; end %locations of scaling factors %in nm/V (for topographic data) scal_data1 = di_header_find(file_name,'\@Sens. Zsens: V'); %in V/LSB for all data scal_data2 = di_header_find(file_name,'\@2:Z scale: V [Sens.'); %locations of number of points per line %(number of lines on next header line) pos_spl = di_header_find(file_name,'\Samps'); %different positions of data sets pos_data = di_header_find(file_name,'\Data offset'); %number of different data sets L = length(pos_data); fseek(fid, pos_spl(1),-1); line = fgets(fid); spl = get_num(line); line = fgets(fid); linno = get_num(line); %scaling factor for topographic data in nm/V fseek(fid,scal_data1,-1); line = fgets(fid); scaling1 = get_num(line); for i = 1:L fseek(fid,pos_data(i),-1); line = fgets(fid); imag_pos = get_num(line); %scaling factor in V/LSB fseek(fid,scal_data2(i),-1); line = fgets(fid); scaling2 = get_num(line)/maxlsb; if i==1 %combined scaling factor in nm/LSB for topographic data scaling = scaling1*scaling2; else %single scaling factor in V/LSB for nontopographic data scaling = scaling2; end fseek(fid,imag_pos,-1); A = fread(fid, [spl linno],'int16'); data(:,:,i) = rot90(scaling*A); end fclose('all');