Skip to content

Commit ed79cc2

Browse files
Merge pull request #13 from ThFriedrich/master
Adds optional Peak finder
2 parents 77c4a49 + a72cf1c commit ed79cc2

4 files changed

Lines changed: 488 additions & 36 deletions

File tree

GUI/LeftPanels/Preparation/panelPFR.m

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,7 @@
2525
% Define buttons, etc for the first row per option. Each row has a maximum
2626
% width of 162 pixels
2727

28-
panel.row(1).option1 = pushbutton('name','Execute routine','width',162,'func','RunPeakFinder','input','input','output','input',...
29-
'figEnd','Observation','figOptEnd',{'Input coordinates'},'reshowFigEnd',true);
28+
panel.row(1).option1 = pushbutton('name','Execute routine 1','width',162,'func','RunPeakFinder','input','input','output','input',...
29+
'figEnd','Observation','figOptEnd',{'Input coordinates'},'reshowFigEnd',true);
30+
panel.row(2).option1 = pushbutton('name','Execute routine 2','width',162,'func','tfm_PeakFinder2','input','input','output','input',...
31+
'figEnd','Observation','figOptEnd',{'Input coordinates'},'reshowFigEnd',true);

GUI/generalFunc/turnOffFigureSelection.m

100644100755
Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,36 @@
11
function [h_pan,h_zoom,h_cursor] = turnOffFigureSelection(h)
2-
% turnOffFigureSelection - Turn off zoom, pan and datacursor
3-
%
4-
% syntax: [h_pan,h_zoom,h_cursor] = turnOffFigureSelection(h)
5-
% h - structure holding references to GUI interface
6-
% h_pan - reference to pan object
7-
% h_zoom - reference to zoom buttons
8-
% h_cursor - reference to datacrusor object
9-
%
10-
11-
%--------------------------------------------------------------------------
12-
% This file is part of StatSTEM
13-
%
14-
% Copyright: 2016, EMAT, University of Antwerp
15-
% License: Open Source under GPLv3
16-
% Contact: sandra.vanaert@uantwerpen.be
17-
%--------------------------------------------------------------------------
18-
19-
% Determine Matlab version for compatibility
20-
v = version('-release');
21-
v = str2double(v(1:4));
22-
23-
% First turn off zoom, pan and datacursor
24-
h_pan = pan(h.fig);
25-
h_zoom = [h.zoom.in;h.zoom.out];
26-
h_cursor = datacursormode(h.fig);
27-
h_cursor.removeAllDataCursors();
28-
set(h_pan,'Enable','off')
29-
set(h_cursor,'Enable','off')
30-
31-
if v < 2019
32-
zoomAxinFig(h,'off')
33-
else
34-
h_z = zoom(h.fig);
35-
h_z.Enable = 'off';
2+
% turnOffFigureSelection - Turn off zoom, pan and datacursor
3+
%
4+
% syntax: [h_pan,h_zoom,h_cursor] = turnOffFigureSelection(h)
5+
% h - structure holding references to GUI interface
6+
% h_pan - reference to pan object
7+
% h_zoom - reference to zoom buttons
8+
% h_cursor - reference to datacrusor object
9+
%
10+
11+
%--------------------------------------------------------------------------
12+
% This file is part of StatSTEM
13+
%
14+
% Copyright: 2016, EMAT, University of Antwerp
15+
% License: Open Source under GPLv3
16+
% Contact: sandra.vanaert@uantwerpen.be
17+
%--------------------------------------------------------------------------
18+
19+
v = version('-release');
20+
v = str2double(v(1:4));
21+
22+
% First turn off zoom, pan and datacursor
23+
h_pan = pan(h.fig);
24+
h_zoom = [h.zoom.in;h.zoom.out];
25+
h_cursor = datacursormode(h.fig);
26+
h_cursor.removeAllDataCursors();
27+
set(h_pan,'Enable','off')
28+
set(h_cursor,'Enable','off')
29+
30+
if v < 2019
31+
zoomAxinFig(h,'off')
32+
else
33+
h_z = zoom(h.fig);
34+
h_z.Enable = 'off';
35+
end
3636
end
Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
function obj = tfm_PeakFinder2(obj)
2+
% tfm_PeakFinder2 - Interactive interface to for the peak finding routine
3+
%
4+
% syntax: obj = tfm_PeakFinder2(obj)
5+
% Input:
6+
% obj - StatSTEM structure
7+
% Output:
8+
% obj - StatSTEM structure
9+
10+
%--------------------------------------------------------------------------
11+
% This file is part of StatSTEM
12+
%
13+
% Copyright: 2019, EMAT, University of Antwerp
14+
% Author: Thomas Friedrich
15+
% License: Open Source under GPLv3
16+
% Contact: sandra.vanaert@uantwerpen.be
17+
%--------------------------------------------------------------------------
18+
global thr d_min sigma xy hpf gr_cm cdat_0
19+
obs = obj.obs;
20+
[ny,nx] = size(obs);
21+
22+
thr = 0;
23+
sigma = 10;
24+
d_min = 0;
25+
26+
%%%%%%%%%%%%%%%%%%
27+
% Figure Window %
28+
%%%%%%%%%%%%%%%%%%
29+
30+
% Create a new figure with given size and minimum size
31+
screensize = get(0, 'Screensize');
32+
s = round(screensize(3:4)*0.8);
33+
hpf.fig = figure('units','pixels','outerposition',[screensize(3)/2-s(1)/2 screensize(4)/2-s(2)/2 s(1) s(2)],'Name','Peak Finder','NumberTitle','off','Visible','on','Resize','on','DeleteFCN',@deleteFigure,'MenuBar','none','ToolBar','figure');
34+
figRSfun = @(~,~) set(hpf.fig, 'position', max([0 0 900 550], hpf.fig.Position));
35+
hpf.fig.SizeChangedFcn = figRSfun;
36+
37+
% Normalized vertical panel split position and border width
38+
v_sec = 0.22;
39+
br = 0.01;
40+
41+
% Create two sub-panels
42+
% Image Panel & Axis
43+
hpf.image.pan = uipanel('Parent',hpf.fig,'units','normalized','Position',[br v_sec 1-br*2 1-br*2-v_sec],'ShadowColor',[0 0 0],'ForegroundColor',[0 0 0],'HighlightColor',[0.95 0.95 0.95],'BackgroundColor',[0.8 0.8 0.8]);
44+
hpf.image.ax1 = subplot(1,2,1,'Parent',hpf.image.pan);
45+
hpf.image.ax2 = subplot(1,2,2,'Parent',hpf.image.pan);
46+
47+
% Parameter Panel
48+
hpf.par.pan = uipanel('Parent',hpf.fig,'units','normalized','Position',[br br*2 1-br*2 v_sec-br],'ShadowColor',[0 0 0],'ForegroundColor',[0 0 0],'HighlightColor',[0.95 0.95 0.95],'BackgroundColor',[0.8 0.8 0.8]);
49+
hpf.par.wb = axes('Parent',hpf.par.pan,'Position',[1-0.38 br*6 .38-br .15]);
50+
% Makeshift Waitbar
51+
gr_cm = [linspace(0,0.1,64)' linspace(0,0.5,64)' linspace(0,1,64)' ];
52+
cdat_0 = zeros(1,128);
53+
cdat = cdat_0;
54+
cdat(1:32) = sin(linspace(0,pi,32));
55+
imagesc(hpf.par.wb,cdat); axis off; colormap(gr_cm); caxis([0 1]);
56+
hpf.par.wb.Toolbar = [];
57+
58+
% Info panel
59+
hpf.help.pan = uipanel('Parent',hpf.par.pan,'units','normalized','Position',[0.62 0.3 0.38-br 0.6],'ShadowColor',[0 0 0],'ForegroundColor',[0 0 0],'HighlightColor',[0.95 0.95 0.95],'BackgroundColor',[0.8 0.8 0.8]);
60+
str = 'To help the peak finder program to detect the correct local maxima, set the approximate radius and minimum distance of the atomic columns in pixel units. Further, you can filter the peaks by a threshold value (normalized). The radius value alters the noise filter and is the most critical parameter. Rerun the Peak finder manually after changing this value!';
61+
hpf.help.text = uicontrol('Parent',hpf.help.pan,'Style','text','String',str,'units','normalized','Position',[0 0 1 1],'FontSize',10,'BackgroundColor',[0.8 0.8 0.8],'horizontalAlignment', 'left');
62+
63+
%%%%%%%%%%%%%%%%%%%%%%%%
64+
% Interactive Elements %
65+
%%%%%%%%%%%%%%%%%%%%%%%%
66+
67+
68+
% Slider & Label %
69+
%%%%%%%%%%%%%%%%%%
70+
%Sigma
71+
est_lim_s = mean(nx,ny)*0.1;
72+
SliderSi = uicontrol('Parent',hpf.par.pan,'Style','slider','units','normalized','Position',[br 0.38 0.2 0.15],'Min',3,'Max',est_lim_s);
73+
uicontrol('Parent',hpf.par.pan,'Style','text','String','Estimated Radius (px):','units','normalized','Position',[br 0.8 0.2 0.15],'FontSize',10,'HorizontalAlignment','left','BackgroundColor',[0.8 0.8 0.8]);
74+
% uicontrol('Parent',hpf.par.pan,'Style','text','units','normalized','Position',[br 0.27 0.01 0.1],'String',num2str(3,0),'BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','right');
75+
% uicontrol('Parent',hpf.par.pan,'Style','text','units','normalized','Position',[0.2 0.27 0.01 0.1],'String',num2str(est_lim_s,1),'BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','left');
76+
77+
%Threshold
78+
SliderTh = uicontrol('Parent',hpf.par.pan,'Style','slider','units','normalized','Position',[br+0.2 0.38 0.2 0.15],'Min',0,'Max',1);
79+
uicontrol('Parent',hpf.par.pan,'Style','text','String','Threshold value:','units','normalized','Position',[br+0.2 0.8 0.2 0.15],'FontSize',10,'HorizontalAlignment','left','BackgroundColor',[0.8 0.8 0.8]);
80+
% uicontrol('Parent',hpf.par.pan,'Style','text','units','normalized','Position',[br+0.2 0.27 0.01 0.1],'String','0','BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','right');
81+
% uicontrol('Parent',hpf.par.pan,'Style','text','units','normalized','Position',[0.4 0.27 0.01 0.1],'String','1','BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','left');
82+
83+
%Peak Distance
84+
est_lim_d = mean(nx,ny)*0.1;
85+
SliderDm = uicontrol('Parent',hpf.par.pan,'Style','slider','units','normalized','Position',[br+0.4 0.38 0.2 0.15],'Min',0,'Max',est_lim_d);
86+
uicontrol('Parent',hpf.par.pan,'Style','text','String','Minimum Distance (px):','units','normalized','Position',[br+0.4 0.8 0.2 0.15],'FontSize',10,'HorizontalAlignment','left','BackgroundColor',[0.8 0.8 0.8]);
87+
% uicontrol('Parent',hpf.par.pan,'Style','text','units','normalized','Position',[br+0.4 0.27 0.01 0.1],'String','0','BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','right');
88+
% uicontrol('Parent',hpf.par.pan,'Style','text','units','normalized','Position',[0.6 0.27 0.01 0.1],'String','1','BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','left');
89+
90+
% Textboxes %
91+
%%%%%%%%%%%%%%%%%%
92+
txt_sig = uicontrol('Parent',hpf.par.pan,'Style','edit','String',num2str(thr),'units','normalized','Position',[br 0.6 0.2 0.15],'FontSize',10);
93+
txt_th = uicontrol('Parent',hpf.par.pan,'Style','edit','String',num2str(sigma),'units','normalized','Position',[0.2+br 0.6 0.2 0.15],'FontSize',10);
94+
txt_d_min = uicontrol('Parent',hpf.par.pan,'Style','edit','String',num2str(d_min),'units','normalized','Position',[0.4+br 0.6 0.2 0.15],'FontSize',10);
95+
96+
% Buttons %
97+
%%%%%%%%%%%%%%%%%%
98+
btn_width = 1/(5+br*7);
99+
hpf.par.findPeaks = uicontrol('Parent',hpf.par.pan,'Style','pushbutton','String','Run peak finder','units','normalized','Position',[br br*6 btn_width 0.2],'FontSize',10);
100+
hpf.close = uicontrol('Parent',hpf.par.pan,'Style','pushbutton','String','Cancel','units','normalized','Position',[br+btn_width br*6 btn_width 0.2],'FontSize',10);
101+
hpf.storeClose = uicontrol('Parent',hpf.par.pan,'Style','pushbutton','String','Confirm values','units','normalized','Position',[br+btn_width*2 br*6 btn_width 0.2],'FontSize',10);
102+
103+
104+
105+
%%%%%%%%%%%%%%%%%%%%%%%%
106+
% Set & Draw %
107+
%%%%%%%%%%%%%%%%%%%%%%%%
108+
109+
% Textbox & Slider Values
110+
set(SliderTh,'Value',thr)
111+
set(txt_th,'String',num2str(thr))
112+
set(SliderSi,'Value',sigma)
113+
set(txt_sig,'String',num2str(sigma))
114+
set(SliderDm,'Value',d_min)
115+
set(txt_d_min,'String',num2str(d_min))
116+
117+
% Callbacks
118+
set(txt_th,'Callback',{@upTXTbox,SliderTh,1,hpf})
119+
set(SliderTh,'Callback',{@slideThres,txt_th,1,hpf})
120+
set(txt_sig,'Callback',{@upTXTbox,SliderSi,2,hpf})
121+
set(SliderSi,'Callback',{@slideThres,txt_sig,2,hpf})
122+
set(txt_d_min,'Callback',{@upTXTbox,SliderDm,3,hpf})
123+
set(SliderDm,'Callback',{@slideThres,txt_d_min,3,hpf})
124+
125+
set(hpf.close,'Callback',{@closeFig,hpf.fig})
126+
set(hpf.storeClose,'Callback',{@closeStoreFig,hpf.fig})
127+
set(hpf.par.findPeaks,'Callback',{@findPeaks,obs,hpf})
128+
129+
% Draw
130+
drawnow();
131+
132+
% Show the images, initial peak finding
133+
findPeaks([],[],obs,hpf)
134+
uiwait(hpf.fig)
135+
136+
%%%%%%%%%%%%%%%%%%%%%%%%
137+
% Functions %
138+
%%%%%%%%%%%%%%%%%%%%%%%%
139+
140+
141+
function slideThres(hObject,~,h_valThres,prm,hpf)
142+
switch prm
143+
case 1
144+
thr = get(hObject,'Value');
145+
set(h_valThres,'String',num2str(thr))
146+
findPeaks([],[],obs, hpf)
147+
case 2
148+
tim = run_waitbar(hpf.par.wb,cdat);
149+
sigma = get(hObject,'Value');
150+
set(h_valThres,'String',num2str(sigma))
151+
obs_fil = tfm_find_peaks_2d(obs, sigma, thr, d_min);
152+
xy = [];
153+
updatePlot(hpf,obs_fil)
154+
stop(tim);
155+
delete(tim);
156+
waitbar_out
157+
case 3
158+
d_min = get(hObject,'Value');
159+
set(h_valThres,'String',num2str(d_min))
160+
findPeaks([],[],obs, hpf)
161+
end
162+
end
163+
164+
function upTXTbox(hObject,~,h_slidThres,prm, hpf)
165+
switch prm
166+
case 1
167+
thr = str2double(get(hObject,'String'));
168+
set(h_slidThres,'Value',thr)
169+
findPeaks([],[],obs, hpf)
170+
case 2
171+
tim = run_waitbar(hpf.par.wb,cdat);
172+
sigma = str2double(get(hObject,'String'));
173+
set(h_slidThres,'Value',sigma)
174+
obs_fil = tfm_find_peaks_2d(obs, sigma, thr, d_min);
175+
xy = [];
176+
updatePlot(hpf,obs_fil)
177+
stop(tim);
178+
delete(tim);
179+
waitbar_out
180+
case 3
181+
d_min = str2double(get(hObject,'String'));
182+
set(h_slidThres,'Value',d_min)
183+
findPeaks([],[],obs, hpf)
184+
end
185+
186+
updatePlot(hpf,obs_fil)
187+
end
188+
189+
function updatePlot(hpf,obs_fil)
190+
191+
subplot(hpf.image.ax1);
192+
imagesc(obs);colormap gray;axis equal off;
193+
194+
subplot(hpf.image.ax2);
195+
imagesc(obs_fil);colormap gray;axis equal off;
196+
197+
if ~isempty(xy)
198+
hold on;
199+
plot(xy(:,1),xy(:,2),'.r')
200+
hold off;
201+
end
202+
203+
waitbar_out;
204+
205+
end
206+
207+
function findPeaks(~,~,obs,hpf)
208+
209+
tim = run_waitbar(hpf.par.wb,cdat);
210+
211+
[obs_fil, xy] = tfm_find_peaks_2d(obs, sigma, thr, d_min);
212+
213+
updatePlot(hpf,obs_fil)
214+
215+
stop(tim);
216+
delete(tim);
217+
218+
waitbar_out;
219+
end
220+
221+
function closeStoreFig(~,~,fig)
222+
obj.coordinates = [xy*obj.dx,ones(length(xy),1)];
223+
close(fig)
224+
end
225+
226+
function closeFig(~,~,fig)
227+
close(fig)
228+
end
229+
230+
function deleteFigure(hObject,~)
231+
uiresume(hObject)
232+
delete(hObject)
233+
end
234+
235+
236+
function waitbar_out()
237+
hpf.par.wb.Children.CData = cdat_0;
238+
set(hpf.par.wb,'visible','off')
239+
hpf.par.wb.Colormap = gr_cm;
240+
drawnow;
241+
end
242+
243+
function timerObject = run_waitbar(wb_axis,cdat)
244+
245+
timerDat.axes = wb_axis;
246+
timerDat.im_dat = cdat;
247+
timerDat.n_tick = 1;
248+
timerObject = timer('TimerFcn',@tick,...
249+
'ExecutionMode','fixedRate',...
250+
'Period',0.01,...
251+
'UserData', timerDat);
252+
start(timerObject);
253+
254+
function tick(timerObj,event)
255+
256+
timerData = get(timerObj, 'UserData');
257+
im = timerData.im_dat;
258+
im = circshift(im,timerData.n_tick,2);
259+
timerData.axes.Children.CData = im;
260+
timerData.axes.Colormap = gr_cm;
261+
timerData.n_tick = timerData.n_tick + 1;
262+
set(timerObj, 'UserData', timerData);
263+
drawnow
264+
end
265+
end
266+
end

0 commit comments

Comments
 (0)