0001 function obj = paint(obj, params)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 fig_struct_fields = {'Position', 'Units'};
0022
0023 if nargin < 2
0024 params = [];
0025 end
0026 params = mars_struct('fillafromb', params, ...
0027 struct('refreshf', obj.refreshf,...
0028 'clf', obj.clf, ...
0029 'userdata', obj.userdata));
0030
0031
0032 obj = fill_defaults(obj);
0033
0034
0035 if isempty(obj.img)
0036 warning('No images, object cannot be painted')
0037 return
0038 end
0039
0040
0041 X=1;Y=2;Z=3;
0042 dims = obj.slicedef;
0043 xmm = dims(X,1):dims(X,2):dims(X,3);
0044 ymm = dims(Y,1):dims(Y,2):dims(Y,3);
0045 zmm = obj.slices;
0046 [y x] = meshgrid(ymm,xmm');
0047 vdims = [length(xmm),length(ymm),length(zmm)];
0048
0049
0050 nslices = vdims(Z);
0051 minnpanels = nslices;
0052 cbars = 0;
0053 if ~isempty(obj.cbar)
0054 cbars = length(obj.cbar);
0055 minnpanels = minnpanels+cbars;
0056 end
0057
0058
0059
0060
0061 dead_f = ~ishandle(obj.figure);
0062 figno = figure(obj.figure);
0063 if dead_f
0064 set(figno, obj.figure_struct);
0065 end
0066
0067
0068
0069
0070 if ~params.refreshf
0071 axisd = flipud(findobj(obj.figure, 'Type','axes','Tag', 'slice overlay panel'));
0072 npanels = length(axisd);
0073 if npanels < vdims(Z)+cbars;
0074 params.refreshf = 1;
0075 end
0076 end
0077 if params.refreshf
0078
0079 if params.clf, clf; end
0080 axisd = [];
0081
0082
0083 set(figno,'InvertHardCopy','off');
0084
0085
0086 if params.userdata
0087 set(figno, 'UserData', obj);
0088 end
0089
0090
0091 parea = obj.area.position;
0092 if ~strcmp(obj.area.units, 'pixels')
0093 ubu = get(obj.figure, 'units');
0094 set(obj.figure, 'units','pixels');
0095 tmp = get(obj.figure, 'Position');
0096 ascf = tmp(3:4);
0097 if ~strcmp(obj.area.units, 'normalized')
0098 set(obj.figure, 'units',obj.area.units);
0099 tmp = get(obj.figure, 'Position');
0100 ascf = ascf ./ tmp(3:4);
0101 end
0102 set(figno, 'Units', ubu);
0103 parea = parea .* repmat(ascf, 1, 2);
0104 end
0105 asz = parea(3:4);
0106
0107
0108 yxratio = length(ymm)*dims(Y,2)/(length(xmm)*dims(X,2));
0109 if isempty(obj.xslices)
0110
0111 axlen(X,:)=asz(1):-1:1;
0112 axlen(Y,:)=yxratio*axlen(X,:);
0113 panels = floor(asz'*ones(1,size(axlen,2))./axlen);
0114 estnpanels = prod(panels);
0115 tmp = find(estnpanels >= minnpanels);
0116 if isempty(tmp)
0117 error('Whoops, cannot fit panels onto figure');
0118 end
0119 b = tmp(1);
0120 panels = panels(:,b);
0121 axlen = axlen(:, b);
0122 else
0123
0124 panels([X:Y],1) = [obj.xslices; 0];
0125 axlen([X:Y],1) = [asz(X)/panels(X); 0];
0126 end
0127
0128
0129 panels(Y) = ceil(minnpanels/panels(X));
0130 axlen(Y) = axlen(X)*yxratio;
0131
0132
0133 divs = [Inf 2 1];the_ds = [0;0];
0134 the_ds(X) = divs(strcmp(obj.area.halign, {'left','center','right'}));
0135 the_ds(Y) = divs(strcmp(obj.area.valign, {'bottom','middle','top'}));
0136 startc = parea(1:2)' + (asz'-(axlen.*panels))./the_ds;
0137
0138
0139 r=0;c=1;
0140 npanels = prod(panels);
0141 lastempty = npanels-cbars;
0142 for i = 1:npanels
0143
0144 if i<=nslices
0145 u.type = 'slice';
0146 u.no = zmm(i);
0147 elseif i > lastempty
0148 u.type = 'cbar';
0149 u.no = i - lastempty;
0150 else
0151 u.type = 'empty';
0152 u.no = i - nslices;
0153 end
0154 axpos = [r*axlen(X)+startc(X) (panels(Y)-c)*axlen(Y)+startc(Y) axlen'];
0155 axisd(i) = axes(...
0156 'Parent',figno,...
0157 'XTick',[],...
0158 'XTickLabel',[],...
0159 'YTick',[],...
0160 'YTickLabel',[],...
0161 'Box','on',...
0162 'XLim',[1 vdims(X)],...
0163 'YLim',[1 vdims(Y)],...
0164 'Units', 'pixels',...
0165 'Position',axpos,...
0166 'Tag','slice overlay panel',...
0167 'UserData',u);
0168 r = r+1;
0169 if r >= panels(X)
0170 r = 0;
0171 c = c+1;
0172 end
0173 end
0174 end
0175
0176
0177 if ischar(obj.labels)
0178 do_labels = ~strcmp(lower(obj.labels), 'none');
0179 else
0180 do_labels = 1;
0181 end
0182 if do_labels
0183 labels = obj.labels;
0184 if iscell(labels.format)
0185 if length(labels.format)~=vdims(Z)
0186 error(...
0187 sprintf('Oh dear, expecting %d labels, but found %d',...
0188 vdims(Z), length(labels.contents)));
0189 end
0190 else
0191
0192 fstr = labels.format;
0193 labels.format = cell(vdims(Z),1);
0194 acpt = obj.transform * [0 0 0 1]';
0195 for i = 1:vdims(Z)
0196 labels.format(i) = {sprintf(fstr,zmm(i)-acpt(Z))};
0197 end
0198 end
0199 end
0200
0201
0202 itypes = {obj.img(:).type};
0203 tmp = strcmpi(itypes, 'contour');
0204 contimgs = find(tmp);
0205 pictimgs = find(~tmp);
0206
0207
0208 npimgs = length(pictimgs);
0209 lrn = zeros(npimgs,3);
0210 cmaps = cell(npimgs);
0211 for i = 1:npimgs
0212 cmaps(i)={obj.img(pictimgs(i)).cmap};
0213 lrnv = {obj.img(pictimgs(i)).outofrange{:}, obj.img(pictimgs(i)).nancol};
0214 for j = 1:length(lrnv)
0215 if prod(size(lrnv{j}))==1
0216 lrn(i,j) = lrnv{j};
0217 else
0218 cmaps(i) = {[cmaps{i}; lrnv{j}(1:3)]};
0219 lrn(i,j) = size(cmaps{i},1);
0220 end
0221 end
0222 end
0223
0224
0225 nvox = prod(vdims(1:2));
0226 pandims = [vdims([2 1]) 3];
0227
0228 zimg = zeros(pandims);
0229 for i = 1:nslices
0230 ixyzmm = [x(:)';y(:)';ones(1,nvox)*zmm(i);ones(1,nvox)];
0231 img = zimg;
0232 for j = 1:npimgs
0233 thisimg = obj.img(pictimgs(j));
0234 i1 = sf_slice2panel(thisimg, ixyzmm, obj.transform, vdims);
0235
0236 [csdata badvals]= pr_scaletocmap(...
0237 i1,...
0238 thisimg.range(1),...
0239 thisimg.range(2),...
0240 thisimg.cmap,...
0241 lrn(j,:));
0242
0243 iimg = reshape(cmaps{j}(csdata(:),:),pandims);
0244 tmp = repmat(logical(~badvals),[1 1 3]);
0245 if strcmpi(thisimg.type, 'truecolour')
0246 img(tmp) = img(tmp) + iimg(tmp)*thisimg.prop;
0247 else
0248 img(tmp) = iimg(tmp)*thisimg.prop;
0249 end
0250 end
0251
0252 img(img>1) = 1;
0253
0254 image('Parent', axisd(i),...
0255 'ButtonDownFcn', obj.callback,...
0256 'CData',img);
0257
0258
0259
0260 for j=1:length(contimgs)
0261 thisimg = obj.img(contimgs(j));
0262 i1 = sf_slice2panel(thisimg, ixyzmm, obj.transform, vdims);
0263 if any(any(isfinite(i1)))
0264 i1(i1<min(thisimg.range))=min(thisimg.range);
0265 i1(i1>max(thisimg.range))=max(thisimg.range);
0266 if mars_struct('isthere', thisimg, 'linespec')
0267 linespec = thisimg.linespec;
0268 else
0269 linespec = 'w-';
0270 end
0271 axes(axisd(i));
0272 set(axisd(i),'NextPlot','add');
0273 if mars_struct('isthere', thisimg, 'contours')
0274 [c h] = contour(i1, thisimg.contours, linespec);
0275 else
0276 [c h] = contour(i1, linespec);
0277 end
0278 if ~isempty(h)
0279 if ~mars_struct('isthere', thisimg, 'linespec')
0280
0281
0282
0283 convals = get(h, 'UserData');
0284 if ~iscell(convals),convals = {convals};end
0285 if ~isempty(convals)
0286 [csdata badvals] = pr_scaletocmap(...
0287 cat(1, convals{:}), ...
0288 thisimg.range(1),...
0289 thisimg.range(2),...
0290 thisimg.cmap,...
0291 [1 size(thisimg.cmap,1) 1]);
0292 colvals = thisimg.cmap(csdata(:),:)*thisimg.prop;
0293 set(h, {'Color'}, num2cell(colvals, 2));
0294 end
0295 end
0296 if mars_struct('isthere', thisimg, 'linewidth')
0297 set(h, 'LineWidth', thisimg.linewidth);
0298 end
0299 end
0300 end
0301 end
0302
0303 if do_labels
0304 text('Parent',axisd(i),...
0305 'Color', labels.colour,...
0306 'FontUnits', 'normalized',...
0307 'VerticalAlignment','bottom',...
0308 'HorizontalAlignment','left',...
0309 'Position', [1 1],...
0310 'FontSize',labels.size,...
0311 'ButtonDownFcn', obj.callback,...
0312 'String', labels.format{i});
0313 end
0314 end
0315 for i = (nslices+1):npanels
0316 set(axisd(i),'Color',[0 0 0]);
0317 end
0318
0319 for i = 1:cbars
0320 axno = axisd(end-cbars+i);
0321 cbari = obj.img(obj.cbar(i));
0322 cml = size(cbari.cmap,1);
0323 p = get(axno, 'Position');;
0324 cw = p(3)*0.2;
0325 ch = p(4)*0.75;
0326 pc = p(3:4)/2;
0327 [axlims idxs] = sort(cbari.range);
0328 a=axes(...
0329 'Parent',figno,...
0330 'XTick',[],...
0331 'XTickLabel',[],...
0332 'Units', 'pixels',...
0333 'YLim', axlims,...
0334 'FontUnits', 'normalized',...
0335 'FontSize', 0.075,...
0336 'YColor',[1 1 1],...
0337 'Tag', 'cbar',...
0338 'Box', 'off',...
0339 'Position',[p(1)+pc(1)-cw/2,p(2)+pc(2)-ch/2,cw,ch]...
0340 );
0341 ih = image('Parent', a,...
0342 'YData', axlims(idxs),...
0343 'CData', reshape(cbari.cmap,[cml,1,3]));
0344 end
0345
0346
0347 obj.figure_struct = mars_struct('split', get(figno), fig_struct_fields);
0348
0349 return
0350
0351
0352
0353
0354 function i1 = sf_slice2panel(img, xyzmm, transform, vdims)
0355
0356 vixyz = inv(transform*img.vol.mat)*xyzmm;
0357
0358 if mars_struct('isthere', img.vol, 'imgdata')
0359 V = img.vol.imgdata;
0360 else
0361 V = img.vol;
0362 end
0363 i1 = spm_sample_vol(V,vixyz(1,:),vixyz(2,:),vixyz(3,:), ...
0364 [img.hold img.background]);
0365 if mars_struct('isthere', img, 'func')
0366 eval(img.func);
0367 end
0368
0369 i1 = reshape(i1, vdims(1:2))';
0370 return