wolffd@0
|
1 function sMap = som_read_cod(filename)
|
wolffd@0
|
2
|
wolffd@0
|
3 %SOM_READ_COD Reads a SOM_PAK format codebook file.
|
wolffd@0
|
4 %
|
wolffd@0
|
5 % sMap = som_read_cod(filename);
|
wolffd@0
|
6 %
|
wolffd@0
|
7 % sMap = som_read_cod('map1.cod');
|
wolffd@0
|
8 %
|
wolffd@0
|
9 % Input and output arguments:
|
wolffd@0
|
10 % filename (string) name of input file
|
wolffd@0
|
11 % sMap (struct) self-organizing map structure
|
wolffd@0
|
12 %
|
wolffd@0
|
13 % The file must be in SOM_PAK format. Empty lines and lines starting
|
wolffd@0
|
14 % with a '#' are ignored, except the ones starting with '#n'. The strings
|
wolffd@0
|
15 % after '#n' are read to field 'comp_names' of the map structure.
|
wolffd@0
|
16 %
|
wolffd@0
|
17 % For more help, try 'type som_read_cod' or check out online documentation.
|
wolffd@0
|
18 % See also SOM_WRITE_COD, SOM_READ_DATA, SOM_WRITE_DATA, SOM_MAP_STRUCT.
|
wolffd@0
|
19
|
wolffd@0
|
20 %%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
21 %
|
wolffd@0
|
22 % som_read_cod
|
wolffd@0
|
23 %
|
wolffd@0
|
24 % PURPOSE
|
wolffd@0
|
25 %
|
wolffd@0
|
26 % Reads a Self-Organizing Map from an ascii file in SOM_PAK format.
|
wolffd@0
|
27 %
|
wolffd@0
|
28 % SYNTAX
|
wolffd@0
|
29 %
|
wolffd@0
|
30 % sMap = som_read_cod(filename);
|
wolffd@0
|
31 %
|
wolffd@0
|
32 % DESCRIPTION
|
wolffd@0
|
33 %
|
wolffd@0
|
34 % This function is offered for compatibility with SOM_PAK, a SOM
|
wolffd@0
|
35 % software package in C. It reads map files written in SOM_PAK format.
|
wolffd@0
|
36 %
|
wolffd@0
|
37 % The SOM_PAK map file format is as follows. The first line must contain
|
wolffd@0
|
38 % the input space dimension, lattice type ('rect' or 'hexa'), map grid
|
wolffd@0
|
39 % size in x-direction, map grid size in y-direction, and neighborhood
|
wolffd@0
|
40 % function ('bubble' or 'gaussian'), in that order. The following lines
|
wolffd@0
|
41 % are comment lines, empty lines or data lines.
|
wolffd@0
|
42 %
|
wolffd@0
|
43 % Each data line contains the weight vector of one map unit and its
|
wolffd@0
|
44 % labels. From the beginning of the line, first are values of the vector
|
wolffd@0
|
45 % components separated by whitespaces, then labels, again separated by
|
wolffd@0
|
46 % whitespaces. The order of map units in the file are one row at a time
|
wolffd@0
|
47 % from right to left, from the top to the bottom of the map (x-direction
|
wolffd@0
|
48 % first, then y-direction).
|
wolffd@0
|
49 %
|
wolffd@0
|
50 % Comment lines start with '#'. Comment lines as well as empty lines are
|
wolffd@0
|
51 % ignored, except if the comment line starts with '#n'. In that case the
|
wolffd@0
|
52 % line should contain names of the vector components separated by
|
wolffd@0
|
53 % whitespaces.
|
wolffd@0
|
54 %
|
wolffd@0
|
55 % In the returned map struct, several fields has to be set to default
|
wolffd@0
|
56 % values, since the SOM_PAK file does not contain information on
|
wolffd@0
|
57 % them. These include map shape ('sheet'), mask ([1 ... 1]),
|
wolffd@0
|
58 % normalizations (none), trainhist (two entries, first with algorithm
|
wolffd@0
|
59 % 'init' and the second with 'seq', both with data name 'unknown'),
|
wolffd@0
|
60 % possibly also component names ('Var1',...).
|
wolffd@0
|
61 %
|
wolffd@0
|
62 % REQUIRED INPUT PARAMETERS
|
wolffd@0
|
63 %
|
wolffd@0
|
64 % filename (string) the name of the input file
|
wolffd@0
|
65 %
|
wolffd@0
|
66 % OUTPUT ARGUMENTS
|
wolffd@0
|
67 %
|
wolffd@0
|
68 % sMap (struct) the resulting SOM struct
|
wolffd@0
|
69 %
|
wolffd@0
|
70 % EXAMPLES
|
wolffd@0
|
71 %
|
wolffd@0
|
72 % sMap = som_read_cod('map1.cod');
|
wolffd@0
|
73 %
|
wolffd@0
|
74 % SEE ALSO
|
wolffd@0
|
75 %
|
wolffd@0
|
76 % som_write_cod Writes a map struct into a file in SOM_PAK format.
|
wolffd@0
|
77 % som_read_data Reads data from an ascii file.
|
wolffd@0
|
78 % som_write_data Writes data struct into a file in SOM_PAK format.
|
wolffd@0
|
79 % som_map_struct Creates map structs.
|
wolffd@0
|
80
|
wolffd@0
|
81 % Copyright (c) 1997-2000 by the SOM toolbox programming team.
|
wolffd@0
|
82 % http://www.cis.hut.fi/projects/somtoolbox/
|
wolffd@0
|
83
|
wolffd@0
|
84 % Version 1.0beta ecco 221097
|
wolffd@0
|
85 % Version 2.0beta juuso 151199 250400
|
wolffd@0
|
86
|
wolffd@0
|
87 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
88 %% check arguments
|
wolffd@0
|
89
|
wolffd@0
|
90 error(nargchk(1, 1, nargin)) % check no. of input args is correct
|
wolffd@0
|
91
|
wolffd@0
|
92 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
93 %% initialize variables
|
wolffd@0
|
94
|
wolffd@0
|
95 lnum = 0; % codebook vector counter
|
wolffd@0
|
96 comment_start = '#'; % the char a SOM_PAK command line starts with
|
wolffd@0
|
97 comp_name_line = '#n'; % string used to start a special command line,
|
wolffd@0
|
98 % which contains names of each component
|
wolffd@0
|
99
|
wolffd@0
|
100 % open input file
|
wolffd@0
|
101
|
wolffd@0
|
102 fid = fopen(filename);
|
wolffd@0
|
103 if fid < 0, error(['Cannot open ' filename]); end
|
wolffd@0
|
104
|
wolffd@0
|
105 % read header line
|
wolffd@0
|
106
|
wolffd@0
|
107 ok_cnt = 0;
|
wolffd@0
|
108 lin = fgetl(fid); li = lin;
|
wolffd@0
|
109 [dim c err n] = sscanf(li, '%d%[^ \t]'); ok_cnt=ok_cnt+c; li = li(n:end);
|
wolffd@0
|
110 [lattice c err n] = sscanf(li,'%s%[^ \t]'); ok_cnt=ok_cnt+c; li = li(n:end);
|
wolffd@0
|
111 [msize(2) c err n] = sscanf(li, '%d%[^ \t]'); ok_cnt=ok_cnt+c; li = li(n:end);
|
wolffd@0
|
112 [msize(1) c err n] = sscanf(li, '%d%[^ \t]'); ok_cnt=ok_cnt+c; li = li(n:end);
|
wolffd@0
|
113 [neigh c err n] = sscanf(li, '%s%[^ \t\n]'); ok_cnt=ok_cnt+c;
|
wolffd@0
|
114
|
wolffd@0
|
115 if ok_cnt ~= 5
|
wolffd@0
|
116 error([ 'Invalid header line: ' lin ]);
|
wolffd@0
|
117 end
|
wolffd@0
|
118
|
wolffd@0
|
119 % create map struct and set its fields according to header line
|
wolffd@0
|
120
|
wolffd@0
|
121 munits = prod(msize);
|
wolffd@0
|
122 sMap = som_map_struct(dim, 'msize', msize, ...
|
wolffd@0
|
123 lattice, 'sheet', 'neigh', neigh);
|
wolffd@0
|
124 [sT0, ok] = som_set('som_train','algorithm','init','data_name','unknown');
|
wolffd@0
|
125 sT1 = som_set('som_train','algorithm','seq','data_name','unknown',...
|
wolffd@0
|
126 'neigh',neigh,'mask',ones(dim,1));
|
wolffd@0
|
127 [sMap, ok, msgs] = som_set(sMap,'name',filename,'trainhist',{sT0,sT1});
|
wolffd@0
|
128
|
wolffd@0
|
129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
130 %% read codebook from the file
|
wolffd@0
|
131
|
wolffd@0
|
132 codebook = zeros(munits,dim);
|
wolffd@0
|
133 labels = cell(munits,1);
|
wolffd@0
|
134 comp_names = sMap.comp_names;
|
wolffd@0
|
135 form = [repmat('%f',[1 dim-1]) '%f%[^ \t]'];
|
wolffd@0
|
136
|
wolffd@0
|
137 while 1,
|
wolffd@0
|
138 li = fgetl(fid); % read next line
|
wolffd@0
|
139 if ~isstr(li), break, end; % is this the end of file?
|
wolffd@0
|
140
|
wolffd@0
|
141 [data, c, err, n] = sscanf(li, form);
|
wolffd@0
|
142 if c < dim % if there were less numbers than dim on the input file line
|
wolffd@0
|
143 if c == 0
|
wolffd@0
|
144 if strncmp(li, comp_name_line, 2) % component name line?
|
wolffd@0
|
145 li = li(3:end); i = 0; c = 1;
|
wolffd@0
|
146 while c
|
wolffd@0
|
147 [s, c, e, n] = sscanf(li, '%s%[^ \t]');
|
wolffd@0
|
148 if ~isempty(s), i = i + 1; comp_names{i} = s; li = li(n:end); end
|
wolffd@0
|
149 end
|
wolffd@0
|
150
|
wolffd@0
|
151 if i ~= dim
|
wolffd@0
|
152 error(['Illegal number of component names: ' num2str(i) ...
|
wolffd@0
|
153 ' (dimension is ' num2str(dim) ')']);
|
wolffd@0
|
154 end
|
wolffd@0
|
155 elseif ~strncmp(li, comment_start, 1) % not a comment, is it error?
|
wolffd@0
|
156 [s, c, e, n] = sscanf(li, '%s%[^ \t]');
|
wolffd@0
|
157 if c
|
wolffd@0
|
158 error(['Invalid vector on input file line ' ...
|
wolffd@0
|
159 num2str(lnum+1) ': [' deblank(li) ']']),
|
wolffd@0
|
160 end
|
wolffd@0
|
161 end
|
wolffd@0
|
162 else
|
wolffd@0
|
163 error(['Only ' num2str(c) ' vector components on input file line ' ...
|
wolffd@0
|
164 num2str(lnum+1) ' (dimension is ' num2str(dim) ')']);
|
wolffd@0
|
165 end
|
wolffd@0
|
166
|
wolffd@0
|
167 else
|
wolffd@0
|
168
|
wolffd@0
|
169 lnum = lnum + 1; % this was a line containing data vector
|
wolffd@0
|
170 codebook(lnum, 1:dim) = data'; % add data to struct
|
wolffd@0
|
171
|
wolffd@0
|
172 % read labels
|
wolffd@0
|
173
|
wolffd@0
|
174 if n < length(li)
|
wolffd@0
|
175 li = li(n:end);
|
wolffd@0
|
176 i = 0; n = 1; c = 1;
|
wolffd@0
|
177 while c
|
wolffd@0
|
178 [s, c, e, n_new] = sscanf(li(n:end), '%s%[^ \t]');
|
wolffd@0
|
179 if c, i = i + 1; labels{lnum, i} = s; n = n + n_new - 1; end
|
wolffd@0
|
180 end
|
wolffd@0
|
181 end
|
wolffd@0
|
182 end
|
wolffd@0
|
183 end
|
wolffd@0
|
184
|
wolffd@0
|
185 % close the input file
|
wolffd@0
|
186
|
wolffd@0
|
187 if fclose(fid) < 0
|
wolffd@0
|
188 error(['Cannot close file ' filename]);
|
wolffd@0
|
189 else
|
wolffd@0
|
190 fprintf(2, '\rmap read ok \n');
|
wolffd@0
|
191 end
|
wolffd@0
|
192
|
wolffd@0
|
193 % check that the number of lines read was correct
|
wolffd@0
|
194
|
wolffd@0
|
195 if lnum ~= munits
|
wolffd@0
|
196 error(['Illegal number of map units: ' num2str(lnum) ' (should be ' num2str(munits) ').']);
|
wolffd@0
|
197 end
|
wolffd@0
|
198
|
wolffd@0
|
199 % set values
|
wolffd@0
|
200
|
wolffd@0
|
201 % in SOM_PAK the xy-indexing is used, while in Matlab ij-indexing
|
wolffd@0
|
202 % therefore, the codebook vectors have to be reorganized
|
wolffd@0
|
203
|
wolffd@0
|
204 order = reshape([1:munits],msize);
|
wolffd@0
|
205 order = reshape(order',[munits 1]);
|
wolffd@0
|
206 codebook(order,:) = codebook;
|
wolffd@0
|
207 labels(order,:) = labels;
|
wolffd@0
|
208
|
wolffd@0
|
209 sMap.codebook = codebook;
|
wolffd@0
|
210 sMap.labels = labels;
|
wolffd@0
|
211 sMap.comp_names = comp_names;
|
wolffd@0
|
212
|
wolffd@0
|
213 return;
|
wolffd@0
|
214
|
wolffd@0
|
215 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|