wolffd@0: function sMap = som_read_cod(filename) wolffd@0: wolffd@0: %SOM_READ_COD Reads a SOM_PAK format codebook file. wolffd@0: % wolffd@0: % sMap = som_read_cod(filename); wolffd@0: % wolffd@0: % sMap = som_read_cod('map1.cod'); wolffd@0: % wolffd@0: % Input and output arguments: wolffd@0: % filename (string) name of input file wolffd@0: % sMap (struct) self-organizing map structure wolffd@0: % wolffd@0: % The file must be in SOM_PAK format. Empty lines and lines starting wolffd@0: % with a '#' are ignored, except the ones starting with '#n'. The strings wolffd@0: % after '#n' are read to field 'comp_names' of the map structure. wolffd@0: % wolffd@0: % For more help, try 'type som_read_cod' or check out online documentation. wolffd@0: % See also SOM_WRITE_COD, SOM_READ_DATA, SOM_WRITE_DATA, SOM_MAP_STRUCT. wolffd@0: wolffd@0: %%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: % wolffd@0: % som_read_cod wolffd@0: % wolffd@0: % PURPOSE wolffd@0: % wolffd@0: % Reads a Self-Organizing Map from an ascii file in SOM_PAK format. wolffd@0: % wolffd@0: % SYNTAX wolffd@0: % wolffd@0: % sMap = som_read_cod(filename); wolffd@0: % wolffd@0: % DESCRIPTION wolffd@0: % wolffd@0: % This function is offered for compatibility with SOM_PAK, a SOM wolffd@0: % software package in C. It reads map files written in SOM_PAK format. wolffd@0: % wolffd@0: % The SOM_PAK map file format is as follows. The first line must contain wolffd@0: % the input space dimension, lattice type ('rect' or 'hexa'), map grid wolffd@0: % size in x-direction, map grid size in y-direction, and neighborhood wolffd@0: % function ('bubble' or 'gaussian'), in that order. The following lines wolffd@0: % are comment lines, empty lines or data lines. wolffd@0: % wolffd@0: % Each data line contains the weight vector of one map unit and its wolffd@0: % labels. From the beginning of the line, first are values of the vector wolffd@0: % components separated by whitespaces, then labels, again separated by wolffd@0: % whitespaces. The order of map units in the file are one row at a time wolffd@0: % from right to left, from the top to the bottom of the map (x-direction wolffd@0: % first, then y-direction). wolffd@0: % wolffd@0: % Comment lines start with '#'. Comment lines as well as empty lines are wolffd@0: % ignored, except if the comment line starts with '#n'. In that case the wolffd@0: % line should contain names of the vector components separated by wolffd@0: % whitespaces. wolffd@0: % wolffd@0: % In the returned map struct, several fields has to be set to default wolffd@0: % values, since the SOM_PAK file does not contain information on wolffd@0: % them. These include map shape ('sheet'), mask ([1 ... 1]), wolffd@0: % normalizations (none), trainhist (two entries, first with algorithm wolffd@0: % 'init' and the second with 'seq', both with data name 'unknown'), wolffd@0: % possibly also component names ('Var1',...). wolffd@0: % wolffd@0: % REQUIRED INPUT PARAMETERS wolffd@0: % wolffd@0: % filename (string) the name of the input file wolffd@0: % wolffd@0: % OUTPUT ARGUMENTS wolffd@0: % wolffd@0: % sMap (struct) the resulting SOM struct wolffd@0: % wolffd@0: % EXAMPLES wolffd@0: % wolffd@0: % sMap = som_read_cod('map1.cod'); wolffd@0: % wolffd@0: % SEE ALSO wolffd@0: % wolffd@0: % som_write_cod Writes a map struct into a file in SOM_PAK format. wolffd@0: % som_read_data Reads data from an ascii file. wolffd@0: % som_write_data Writes data struct into a file in SOM_PAK format. wolffd@0: % som_map_struct Creates map structs. wolffd@0: wolffd@0: % Copyright (c) 1997-2000 by the SOM toolbox programming team. wolffd@0: % http://www.cis.hut.fi/projects/somtoolbox/ wolffd@0: wolffd@0: % Version 1.0beta ecco 221097 wolffd@0: % Version 2.0beta juuso 151199 250400 wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: %% check arguments wolffd@0: wolffd@0: error(nargchk(1, 1, nargin)) % check no. of input args is correct wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: %% initialize variables wolffd@0: wolffd@0: lnum = 0; % codebook vector counter wolffd@0: comment_start = '#'; % the char a SOM_PAK command line starts with wolffd@0: comp_name_line = '#n'; % string used to start a special command line, wolffd@0: % which contains names of each component wolffd@0: wolffd@0: % open input file wolffd@0: wolffd@0: fid = fopen(filename); wolffd@0: if fid < 0, error(['Cannot open ' filename]); end wolffd@0: wolffd@0: % read header line wolffd@0: wolffd@0: ok_cnt = 0; wolffd@0: lin = fgetl(fid); li = lin; wolffd@0: [dim c err n] = sscanf(li, '%d%[^ \t]'); ok_cnt=ok_cnt+c; li = li(n:end); wolffd@0: [lattice c err n] = sscanf(li,'%s%[^ \t]'); ok_cnt=ok_cnt+c; li = li(n:end); wolffd@0: [msize(2) c err n] = sscanf(li, '%d%[^ \t]'); ok_cnt=ok_cnt+c; li = li(n:end); wolffd@0: [msize(1) c err n] = sscanf(li, '%d%[^ \t]'); ok_cnt=ok_cnt+c; li = li(n:end); wolffd@0: [neigh c err n] = sscanf(li, '%s%[^ \t\n]'); ok_cnt=ok_cnt+c; wolffd@0: wolffd@0: if ok_cnt ~= 5 wolffd@0: error([ 'Invalid header line: ' lin ]); wolffd@0: end wolffd@0: wolffd@0: % create map struct and set its fields according to header line wolffd@0: wolffd@0: munits = prod(msize); wolffd@0: sMap = som_map_struct(dim, 'msize', msize, ... wolffd@0: lattice, 'sheet', 'neigh', neigh); wolffd@0: [sT0, ok] = som_set('som_train','algorithm','init','data_name','unknown'); wolffd@0: sT1 = som_set('som_train','algorithm','seq','data_name','unknown',... wolffd@0: 'neigh',neigh,'mask',ones(dim,1)); wolffd@0: [sMap, ok, msgs] = som_set(sMap,'name',filename,'trainhist',{sT0,sT1}); wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: %% read codebook from the file wolffd@0: wolffd@0: codebook = zeros(munits,dim); wolffd@0: labels = cell(munits,1); wolffd@0: comp_names = sMap.comp_names; wolffd@0: form = [repmat('%f',[1 dim-1]) '%f%[^ \t]']; wolffd@0: wolffd@0: while 1, wolffd@0: li = fgetl(fid); % read next line wolffd@0: if ~isstr(li), break, end; % is this the end of file? wolffd@0: wolffd@0: [data, c, err, n] = sscanf(li, form); wolffd@0: if c < dim % if there were less numbers than dim on the input file line wolffd@0: if c == 0 wolffd@0: if strncmp(li, comp_name_line, 2) % component name line? wolffd@0: li = li(3:end); i = 0; c = 1; wolffd@0: while c wolffd@0: [s, c, e, n] = sscanf(li, '%s%[^ \t]'); wolffd@0: if ~isempty(s), i = i + 1; comp_names{i} = s; li = li(n:end); end wolffd@0: end wolffd@0: wolffd@0: if i ~= dim wolffd@0: error(['Illegal number of component names: ' num2str(i) ... wolffd@0: ' (dimension is ' num2str(dim) ')']); wolffd@0: end wolffd@0: elseif ~strncmp(li, comment_start, 1) % not a comment, is it error? wolffd@0: [s, c, e, n] = sscanf(li, '%s%[^ \t]'); wolffd@0: if c wolffd@0: error(['Invalid vector on input file line ' ... wolffd@0: num2str(lnum+1) ': [' deblank(li) ']']), wolffd@0: end wolffd@0: end wolffd@0: else wolffd@0: error(['Only ' num2str(c) ' vector components on input file line ' ... wolffd@0: num2str(lnum+1) ' (dimension is ' num2str(dim) ')']); wolffd@0: end wolffd@0: wolffd@0: else wolffd@0: wolffd@0: lnum = lnum + 1; % this was a line containing data vector wolffd@0: codebook(lnum, 1:dim) = data'; % add data to struct wolffd@0: wolffd@0: % read labels wolffd@0: wolffd@0: if n < length(li) wolffd@0: li = li(n:end); wolffd@0: i = 0; n = 1; c = 1; wolffd@0: while c wolffd@0: [s, c, e, n_new] = sscanf(li(n:end), '%s%[^ \t]'); wolffd@0: if c, i = i + 1; labels{lnum, i} = s; n = n + n_new - 1; end wolffd@0: end wolffd@0: end wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: % close the input file wolffd@0: wolffd@0: if fclose(fid) < 0 wolffd@0: error(['Cannot close file ' filename]); wolffd@0: else wolffd@0: fprintf(2, '\rmap read ok \n'); wolffd@0: end wolffd@0: wolffd@0: % check that the number of lines read was correct wolffd@0: wolffd@0: if lnum ~= munits wolffd@0: error(['Illegal number of map units: ' num2str(lnum) ' (should be ' num2str(munits) ').']); wolffd@0: end wolffd@0: wolffd@0: % set values wolffd@0: wolffd@0: % in SOM_PAK the xy-indexing is used, while in Matlab ij-indexing wolffd@0: % therefore, the codebook vectors have to be reorganized wolffd@0: wolffd@0: order = reshape([1:munits],msize); wolffd@0: order = reshape(order',[munits 1]); wolffd@0: codebook(order,:) = codebook; wolffd@0: labels(order,:) = labels; wolffd@0: wolffd@0: sMap.codebook = codebook; wolffd@0: sMap.labels = labels; wolffd@0: sMap.comp_names = comp_names; wolffd@0: wolffd@0: return; wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%