function varargout = tracer(varargin)
% TRACER Application for tracer.fig GUI
%
% Michi Tracer is an interactive Matlab tool to acquire the
% quantitative 2D morphology of cultured neuron.
%
% Michele Giugliano, PhD, Brain Mind Institute, EPFL, Lausanne (CH)
% Maura Arsiero, Institute of Physiology, University of Bern, Bern (CH)
%
% Contact: michele@giugliano.info
%
% SEE ALSO: MichiShapePlot
%
if nargin == 0 % LAUNCH GUI
fig = openfig(mfilename,'reuse');
% Use system color scheme for figure:
set(fig,'Color',get(0,'defaultUicontrolBackgroundColor'));
% Generate a structure of handles to pass to callbacks, and store it.
handles = guihandles(fig);
guidata(fig, handles);
global CALIBRATED GOTDIAMETER PICLOADED SOMAAQUIRED;
global PIC f;
global outfilename;
global DD fp;
CALIBRATED = 0;
PICLOADED = 0;
SOMAAQUIRED= 0;
GOTDIAMETER= 0;
PIC = [];
f = 0.;
DD = 0.1;
outfilename = 'mytest.asc';
fr = fopen('tmp.x', 'w'); fclose(fr);
if nargout > 0
varargout{1} = fig;
end
elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK
try
if (nargout)
[varargout{1:nargout}] = feval(varargin{:}); % FEVAL switchyard
else
feval(varargin{:}); % FEVAL switchyard
end
catch
disp(lasterr);
end
end
% --------------------------------------------------------------------
function varargout = LoadPic_Callback(h, eventdata, handles, varargin)
global PICLOADED PIC CALIBRATED outfilename DD;
set(handles.FileName, 'string', outfilename);
set(handles.diameter, 'String', num2str(DD));
[filename, pathname] = uigetfile('*', 'Pick a picture..');
fullname = sprintf('%s\\%s', pathname, filename);
if (exist(fullname, 'file')),
PIC = imread( fullname, fullname(end-2:end));
PICC = imfinfo(fullname, fullname(end-2:end));
PICLOADED = 1;
CALBRATED = 0;
figure(10); clf; set(gcf, 'DoubleBuffer', 'on');
set(gcf, 'KeyPressFcn', '1;');
set(gcf, 'CurrentCharacter',' ');
image(PIC);
colormap(PICC.Colormap);
end
% --------------------------------------------------------------------
function varargout = Calibrate_Callback(h, eventdata, handles, varargin)
global PICLOADED CALIBRATED f;
if (~PICLOADED), warndlg('A pic must be loaded first!', 'Tracer'); return; end;
if (exist('calibration.mat')),
answ = questdlg('Do you want to recover calibration from *.mat file?', 'Calibration', 'Yes', 'No', 'No');
if (strcmp(answ, 'Yes')), load('calibration.mat'); CALIBRATED = 1; return; end;
end
figure(10);
set(gcf, 'KeyPressFcn', '1;');
set(gcf, 'CurrentCharacter',' ');
x = []; y = []; P = [];
hold on;
for k=1:2,
[x(k), y(k)] = ginput(1);
P(k) = plot(x(k), y(k), 'ro'); set(P(k), 'MarkerFaceColor', [1 0 0], 'MarkerEdgeColor', [1 0 0]);
end
hold off;
delete(P);
d = inputdlg('CALIBRATION: Please enter the corresponding (horizontal) distance in um: ');
d = str2num(d{1});
hold on; P = line(x,y); set(P, 'Color', [1 0 0], 'LineWidth', 3); hold off;
T = text(x(2)*1.1, y(2), sprintf('{%.1f \\mum}', d)); set(T, 'Color', [1 0 0], 'FontSize', 15);
dx = abs(diff(x));
f = d / dx;
CALIBRATED = 1;
save('calibration.mat', 'f');
%------------------------------------------------------------------------------------------------------
%------------------------------------------------------------------------------------------------------
function varargout = tracesoma_Callback(h, eventdata, handles, varargin)
global outfilename f DD;
global PICLOADED CALIBRATED;
global fp;
if (~PICLOADED), warndlg('A pic must be loaded first!', 'Tracer'); return; end;
if (~CALIBRATED), warndlg('The calibration must be performed first!', 'Tracer'); return; end;
figure(10);
set(gcf, 'KeyPressFcn', '1;');
set(gcf, 'CurrentCharacter',' ');
outfilename = get(handles.FileName, 'string');
fp = fopen(outfilename, 'w');
fprintf(fp, '; V3 text file written by Matlab Procedure by M.G.\n');
fprintf(fp, '; \n');
fprintf(fp, '\n\n\n');
figure(10);
set(gcf, 'KeyPressFcn', '1;');
set(gcf, 'CurrentCharacter',' ');
x = []; y = []; P = [];
hold on;
tmq = []; tmp = 0.; k = 1;
while (~tmp),
tmq = ginput(1);
if (~isempty(tmq)),
x(k) = tmq(1); y(k) = tmq(2);
P(k) = plot(x(k), y(k), 'ro'); set(P(k), 'MarkerFaceColor', [1 0 0], 'MarkerEdgeColor', [1 0 0], 'MarkerSize', 5);
else
tmp = 1;
end;
k = k + 1;
end
plot(x, y, 'r')
hold off;
fprintf(fp, '("CellBody"\n');
fprintf(fp, '(Color White)\n');
fprintf(fp, '(CellBody)\n');
for i=1:length(x), fprintf(fp, '( %f %f 0.00 0.19) ;\n', x(i)*f, y(i)*f); end
fprintf(fp, ') ; End of contour\n\n');
fclose(fp);
% --------------------------------------------------------------------
function varargout = adddend_Callback(h, eventdata, handles, varargin)
global outfilename f DD ok fp QQQ;
global PICLOADED CALIBRATED;
if (length(varargin) == 0), Nchildren = 1; else Nchildren = varargin{1}; end;
if (length(varargin) == 0),
QQQ = 8328329;
if (~PICLOADED), warndlg('A pic must be loaded first!', 'Tracer'); return; end;
if (~CALIBRATED), warndlg('The calibration must be performed first!', 'Tracer'); return; end;
ok = 0;
figure(10);
set(gcf, 'KeyPressFcn', '1;');
set(gcf, 'CurrentCharacter',' ');
outfilename = get(handles.FileName, 'string');
fp = fopen(outfilename, 'a');
fprintf(fp, '\n\n\n');
fprintf(fp, '( (Color White)\n');
fprintf(fp, '(Dendrite)\n');
end
figure(10);
set(gcf, 'KeyPressFcn', '1;');
set(gcf, 'CurrentCharacter',' ');
while (Nchildren > 1)
x = []; y = []; dm = []; P = [];
hold on;
tmq = []; tmp = 0.; k = 1;
while (~tmp),
tmq = ginput(1);
if (~isempty(tmq)),
x(k) = tmq(1); y(k) = tmq(2);
msize = DD / f;
R = rectangle('Position', [x(k)-msize/2, y(k)-msize/2, msize, msize]);
set(R, 'FaceColor', [1 0 0], 'EdgeColor', [1 0 0]);
set(R, 'ButtonDownFcn', 'Clickme');
ok = 0;
while(~ok)
cha = get(gcf, 'CurrentCharacter');
set(R,'Position', [x(k)-msize/2, y(k)-msize/2, msize, msize],'Curvature', [1 1]);
if (strcmp(cha, 'q')), ok = 1; k = k - 1; end
if (strcmp(cha, '+')), msize = msize * 1.1; end
if (strcmp(cha, '-')), msize = msize * .9; end
DD = msize * f; dm(k) = DD;
set(gcf, 'CurrentCharacter', ' ');
pause(0.1);
end % while
set(handles.diameter, 'String', num2str(DD));
else
tmp = 1;
end;
k = k + 1;
end %
plot(x, y, 'r')
hold off;
for i=1:length(x), fprintf(fp, '(%.2f %.2f 0.00 %.2f) ;\n', x(i)*f, y(i)*f, dm(i)); end
tmp1 = questdlg('Was the last point a node ?');
if (strcmp(tmp1, 'No')), % No, the last point was not a node..
fprintf(fp, 'Normal\n |\n');
else
fprintf(fp, '(\n');
ttt = inputdlg('How many children? ');
%if ishandle(QQQ), delete(QQQ); end;
hold on;
QQQ = plot(x(end), y(end), 'go'); set(QQQ, 'MarkerEdgeColor', [0 1 0], 'MarkerFaceColor', [0 1 0], 'MarkerSize',8);
TT = text(x(end), y(end), ttt{1}); set(TT, 'Color', [0 0 0], 'FontWeight', 'bold', 'FontSize', 7);
hold off;
adddend_Callback(h, eventdata, handles, str2num(ttt{1}));
fprintf(fp, '|\n');
end
Nchildren = Nchildren - 1;
end % while
x = []; y = []; dm = []; P = [];
hold on;
tmq = []; tmp = 0.; k = 1;
while (~tmp),
tmq = ginput(1);
if (~isempty(tmq)),
x(k) = tmq(1); y(k) = tmq(2);
msize = DD / f;
R = rectangle('Position', [x(k)-msize/2, y(k)-msize/2, msize, msize]);
set(R, 'FaceColor', [1 0 0], 'EdgeColor', [1 0 0]);
set(R, 'ButtonDownFcn', 'Clickme');
ok = 0;
while(~ok)
cha = get(gcf, 'CurrentCharacter');
set(R,'Position', [x(k)-msize/2, y(k)-msize/2, msize, msize],'Curvature', [1 1]);
if (strcmp(cha, 'q')), ok = 1; k = k - 1; end
if (strcmp(cha, '+')), msize = msize * 1.1; end
if (strcmp(cha, '-')), msize = msize * .9; end
DD = msize * f; dm(k) = DD;
set(gcf, 'CurrentCharacter', ' ');
pause(0.1);
end % while
set(handles.diameter, 'String', num2str(DD));
else
tmp = 1;
end;
k = k + 1;
end %
plot(x, y, 'r')
hold off;
for i=1:length(x), fprintf(fp, '(%.2f %.2f 0.00 %.2f) ;\n', x(i)*f, y(i)*f, dm(i)); end
tmp1 = questdlg('Was the last point a node ?');
if (strcmp(tmp1, 'No')), % No, the last point was not a node..
fprintf(fp, 'Normal\n )\n');
else
fprintf(fp, '(\n');
ttt = inputdlg('How many children? ');
%if ishandle(QQQ), delete(QQQ); end;
hold on;
QQQ = plot(x(end), y(end), 'go'); set(QQQ, 'MarkerEdgeColor', [0 1 0], 'MarkerFaceColor', [0 1 0], 'MarkerSize',8);
TT = text(x(end), y(end), ttt{1}); set(TT, 'Color', [0 0 0], 'FontWeight', 'bold', 'FontSize', 7);
hold off;
adddend_Callback(h, eventdata, handles, str2num(ttt{1}));
fprintf(fp, ')\n');
end
if (length(varargin) == 0), %fprintf(fp, ') ; End of tree\n\n\n');
fclose(fp); end;
% --------------------------------------------------------------------
% --------------------------------------------------------------------
% --------------------------------------------------------------------
% --------------------------------------------------------------------
function varargout = GetDiameter_Callback(h, eventdata, handles, varargin)
global DD;
global f;
figure(10);
set(gcf, 'KeyPressFcn', '1;');
set(gcf, 'CurrentCharacter',' ');
xx = []; yy = []; PP = [];
hold on;
for k=1:2,
[xx(k), yy(k)] = ginput(1);
PP(k) = plot(xx(k), yy(k), 'g.'); set(PP(k), 'MarkerFaceColor', [0 0 1], 'MarkerEdgeColor', [0 0 1]);
end
hold off;
delete(PP);
DD = (f * sqrt(diff(xx)^2 + diff(yy)^2));
set(handles.diameter, 'String', num2str(DD));
% --------------------------------------------------------------------
% --------------------------------------------------------------------
function varargout = FileName_Callback(h, eventdata, handles, varargin)
global outfilename;
outfilename = get(handles.FileName, 'string');
% --------------------------------------------------------------------
% --------------------------------------------------------------------