%Graphical user interface to the Flex99-12C correlator.
%
% Marcel Leutenegger 19.7.2006
%
function f=flex99(cb)
try
o=get(0,'CallbackObject');
if isempty(o)
s='ShowHiddenHandles';
t=get(0,s);
set(0,s,'on');
h=findobj(allchild(0),'flat','Tag','Flex99-12C');
set(0,s,t);
if any(h)
figure(h);
else
h=create;
end
else
h=o;
while get(h,'Parent') ~= 0
h=get(h,'Parent');
end
if o == h
feval(cb,h);
else
feval(get(o,'Tag'),h,o);
end
end
if nargout
f=h;
end
catch
if ishandle(h)
alert;
end
end
%__________________________________________________________
%
% Graphical user interface functions
%__________________________________________________________
%
%Reports the last error occurred.
%
% m Message text {last error message}
% t Figure title {Error report}
% f Figure handle
%
function f=alert(m,t)
f=findobj(get(0,'Children'),'flat','Tag','alert');
if nargout & ~nargin
return
end
if nargin < 1 | isempty(m)
m=get(0,'ErrorMessage');
end
if nargin < 2 | isempty(t)
t='Ouch ...';
end
if ishandle(f)
set(f,'Name',t);
o=get(f,'Children');
set(o(2),'String',m);
figure(f);
else
s=[256 100];
S=get(0,'ScreenSize');
f=figure('DoubleBuffer','on','MenuBar','none','Name',t,'IntegerHandle','off','NumberTitle','off','Resize','off','Position',[floor((S(3:4)-s)/2) s],'Tag','alert','ToolBar','none');
uicontrol('BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','center','Parent',f,'Position',[8 40 240 48],'String',m,'Style','text');
uicontrol('Callback','delete(gcbf);','Parent',f,'Position',[96 8 64 24],'String','Ok','Style','pushbutton');
end
drawnow;
if ~nargout
clear f;
end
%Clean afterpulsing from correlation.
%
% f Figure handle
% g Correlation
% I Intensity [Hz]
%
function g=correct(f,g,I)
v='Value';
o=object(f,'suppress');
if get(o,v) & get(object(f,'auto'),v)
if numel(I) & get(object(f,'adaptive'),v)
g=g - get(o,'UserData')/mean(I(~isnan(I)));
else
g=g - get(object(f,'estimate'),'UserData');
end
end
%Initializes the correlator and create the user interface.
%
function f=create
warning('off');
%
% Property names
%
h='TooltipString';
p='Position';
s='String';
t='Tag';
u='UserData';
v='Value';
%
% Figure properties
%
f.Color=[0.8 0.8 0.8];
f.Name='Correlator Flex99-12C';
f.CloseRequestFcn='try flex99c12(''e''); pause(0.1); clear flex99c12; catch clear flex99c12; end; delete([get(0,''CallbackObject'') findobj(0,''Tag'',''alert'')]);';
f.DoubleBuffer='on';
f.HandleVisibility='callback';
f.IntegerHandle='off';
f.Menubar='none';
f.NumberTitle='off';
f.Position=[-403 -200 600 400];
f.Renderer='painters';
f.ResizeFcn='flex99(''sizecorr'');';
f.Tag='Flex99-12C';
f.Toolbar='none';
f.WindowButtonUpFcn='flex99(''zoomcorr'')';
%
% Axes properties
%
a.Box='on';
a.ColorOrder=[1 0 0;0 0 1];
a.FontSize=8;
a.FontWeight='bold';
a.Units='pixel';
%
% Checkbox properties
%
c.BackgroundColor=[0.8 0.8 0.8];
c.BusyAction='cancel';
c.Callback='flex99';
c.Interruptible='off';
c.Style='checkbox';
%
% Button properties
%
b.Callback='flex99';
b.Style='togglebutton';
%
% Edit properties
%
e.BackgroundColor=[1 1 1];
e.HorizontalAlignment='right';
e.Style='edit';
%
% Slider properties
%
k=c;
k.Min=-1;
k.Style='slider';
%
% Text properties
%
x.BackgroundColor=[0.8 0.8 0.8];
x.HorizontalAlignment='left';
x.Style='text';
%
% Figure
%
o=get(0,'ScreenSize');
f.Position(1:2)=f.Position(1:2)+o(3:4)/2;
f=figure(f,'UserData',f.Position(3:4));
a.parent=f;
b.Parent=f;
c.Parent=f;
k.Parent=f;
x.Parent=f;
%
% Intensity
%
r=axes(a,p,[50 270 300 120],'XLim',[0 300],'XTick',150,'XTickLabel',{'Time'},t,'intensity');
line(0:300,repmat(nan,2,301),'HitTest','off','Parent',r);
ylabel(r,'Intensity [kHz]');
%
% Intensity context menu
%
om.Callback='flex99';
om.Interruptible='off';
hm=uicontextmenu('Parent',f);
uimenu(hm,om,'Label','Hide channel &A',t,'hide');
uimenu(hm,om,'Label','Hide channel &B',t,'hide');
uimenu(hm,om,'Label','&Clear traces','Separator','on',t,'wipe');
set(r,'UIContextMenu',hm);
%
% Correlation
%
g=axes(a,p,[50 25 300 220],'XLim',[1e-7 1e-1],'XScale','log','XTick',[1e-7 10.^(-6:-2) 0.1],'XTickLabel',{'0.1us';'1.0us';'10us';'0.1ms';'1.0ms';'10ms';'0.1s'},'YLim',[0.98 3],'ButtonDownFcn','flex99','Tag','zoominit');
ylabel(g,'Correlation G(t)');
%
% Texts
%
uicontrol(x,p,[460 290 130 14],s,'live operation');
uicontrol(x,p,[460 270 130 14],s,'on recordings');
x.FontWeight='bold';
%
% Correlation type
%
uicontrol(x,p,[380 378 100 14],s,'Correlation type');
uicontrol(c,p,[390 358 100 16],s,'Auto-correlation',t,'auto',v,1,h,'Run auto-correlation AxA');
uicontrol(c,p,[390 338 100 16],s,'Cross-correlation',t,'cross',h,'Run cross-correlation AxB');
%
% Integration time
%
uicontrol(x,p,[380 310 120 14],s,'Integration time [s]');
uicontrol(c,e,p,[390 288 48 20],s,'1.0',t,'livetime',v,1,h,'Integration time during live operation');
uicontrol(k,p,[438 288 12 20],'SliderStep',[1 0.1],t,'spintime',u,'livetime');
uicontrol(c,e,p,[390 268 48 20],s,'10.0',t,'snaptime',v,10,h,'Integration time for recordings');
uicontrol(k,p,[438 268 12 20],'SliderStep',[1 1],t,'spintime',u,'snaptime');
%
% Working folder
%
uicontrol(x,p,[380 240 100 14],s,'Working folder');
uicontrol(b,p,[390 218 156 20],s,'File name template',t,'template',h,'Set and use a file name template for snap-shots');
uicontrol(c,e,p,[546 218 32 20],s,'001',t,'nextfile',v,1,h,'Running file number');
uicontrol(k,p,[578 218 12 20],'SliderStep',[1 1],t,'spinfile');
%
% Parameter extraction
%
uicontrol(x,p,[380 190 120 14],s,'Parameter extraction');
uicontrol(b,p,[390 168 95 20],s,'Live fit',t,'livefit',h,'Set and enable live parameter extraction');
uicontrol(b,p,[495 168 95 20],s,'Snap fit',t,'snapfit',h,'Set and enable parameter extraction on recordings');
%
% Afterpulsing
%
uicontrol(x,p,[380 140 80 14],s,'Afterpulsing');
uicontrol(c,p,[390 120 95 16],s,'Suppress',t,'suppress',h,'Account for the afterpulsing');
uicontrol(b,p,[495 118 95 20],s,'Estimate',t,'estimate',h,'Estimate the afterpulsing contribution');
adaptive(f,uicontrol(c,p,[390 100 95 16],s,'Adaptive',t,'adaptive',h,'Auto-lookup of a suitable estimation',u,'afterpulse.mat'));
%
% Experiment
%
b.Style='pushbutton';
uicontrol(x,p,[380 40 80 14],s,'Experiment');
uicontrol(b,p,[390 10 95 24],s,'Live',t,'liverun',h,'Start and stop live operation');
uicontrol(b,p,[495 10 95 24],s,'Snap',t,'snaprun',h,'Record a correlation and the intensity traces');
%Current time in seconds based on NOW.
%
function t=curtime
t=86400*now;
%Update the correlation.
%
% a Axes handle
% g Correlation
%
function drawcorr(a,g)
set(findobj(a,'Tag',''),'YData',g);
%Update the intensity traces.
%
% f Figure handle
% I Intensity traces [Hz]
% T Elapsed time [s]
%
function I=drawint(f,I,T)
a=object(f,'intensity');
h=get(a,'Children');
y=get(h,'YData');
y=[cat(1,y{:}) 0.001*I.'];
y=y(:,end-300:end);
set(h(1),'YData',y(1,:));
set(h(2),'YData',y(2,:));
if T > 0
I=[get(a,'UserData');I];
end
T=round(10*T);
set(a,'XTickLabel',{sprintf('Time: %d.%ds [ %dkHz, %dkHz ]',fix(T/10),rem(T,10),round(max(0,y(:,end))))},'UserData',I);
%Enables or disables the controls during a snap-shot.
%
% f Figure object
% e 'on' or 'off'
%
function enable(f,e)
set(findobj(get(f,'Children'),'flat','Type','uicontrol'),'Enable',e);
set(object(f,'snaprun'),'Enable','on');
if isequal(e,'on')
adaptive(f,object(f,'adaptive'));
end
%Hide/show the intensity trace for a channel.
%
% f Figure object
% o Menu object
%
function hide(f,o)
c=isequal(get(o,'Checked'),'off');
h=get(object(f,'intensity'),'Children');
set(get(get(o,'Parent'),'Children'),'Checked','off');
set(h,'ZData',[]);
if c
set(o,'Checked','on');
set(h(get(o,'Position')),'ZData',repmat(nan,1,301));
end
%Modifiy the running number.
%
% f Figure handle
% o Editor handle
% s Modification
%
function nextfile(f,o,s)
if nargin < 3
s=0;
end
v=sscanf(get(o,'String'),'%f');
if isempty(v) | any(isnan(v) | isinf(v))
v=get(o,'Value');
end
if isempty(v)
v=1;
else
v=min(999,max(1,v(1)+s));
end
set(o,'String',sprintf('%03d',v),'Value',v);
%Get the handle of an object.
%
% f Figure object
% t Object tag
% o Handle
%
function o=object(f,t)
o=findobj(f,'Tag',t);
%Read the correlator.
%
% f Figure handle
% T Elapsed time [s]
%
function T=read(f)
[g,I]=flex99c12;
a=object(f,'zoominit');
T=get(a,'UserData');
I=drawint(f,I,curtime - T);
drawcorr(a,correct(f,g,I));
drawnow;
T=curtime - T;
%Determine if the correlator is running.
%
% f Figure object
% s True if running
%
function s=running(f)
s=isequal(get(object(f,'liverun'),'String'),'Stop');
%Sets the correlation axes scale.
%
% a Axes handle
% g Correlation
% t Delays [s]
%
function scale(a,g,t)
m=get(a,'XLim');
g=g(t > m(1) & t < m(2));
set(a,'YLim',[0.98*max([1 min(g(:))]) max([1.02 pow2(ceil(8*log2(1.02*max(g(:))))/8)])]);
%Start the correlator.
%
% f Figure handle
%
function start(f)
c='Children';
u='UserData';
v='Value';
flex99c12('e');
a=object(f,'zoominit');
if get(object(f,'auto'),v);
m='a';
else
m='c';
end
[g,I,t]=flex99c12(m);
T=curtime;
delete(findobj(get(a,c),'Tag',''));
set(a,c,[get(a,c);line(t,correct(f,g,I),'Color',[0 0 0],'HitTest','off','Parent',a)],u,T);
drawint(f,I,0);
drawnow;
%Stop the correlator.
%
% f Figure handle
% T Elapsed time [s]
% g Correlation
% I Intensity traces [Hz]
% t Delays [s]
%
function [T,g,I,t]=stop(f)
T=curtime;
[g,I,t]=flex99c12('e');
a=object(f,'zoominit');
T=T - get(a,'UserData');
I=drawint(f,I,T);
g=correct(f,g,I);
drawcorr(a,g);
scale(a,g,t);
drawnow;
%Clear the intensity traces for both channels.
%
% f Figure object
% o Menu object
%
function wipe(f,o)
set(get(object(f,'intensity'),'Children'),'YData',repmat(nan,1,301));
%Label y-axes.
%
% a Axes handle
% y Axes label
%
function ylabel(a,y)
s.FontAngle=get(a,'FontAngle');
s.FontName=get(a,'FontName');
s.FontSize=get(a,'FontSize');
s.FontWeight=get(a,'FontWeight');
set(get(a,'YLabel'),s,'String',y);
%__________________________________________________________
%
% Zoom and resize callbacks
%__________________________________________________________
%
%Resize the user interface.
%
% f Figure handle
%
function sizecorr(f)
p='Position';
h=get(f,'Children');
s=get(f,'UserData');
S=get(f,p);
S=S(3:4);
N=length(h);
dx=S(1)-s(1);
dy=S(2)-s(2);
d=[dx dy 0 0];
set(f,'Interruptible','off');
for n=1:N-3
set(h(n),p,get(h(n),p)+d);
end
set(h(N-2),p,get(h(N-2),p)+[0 0 dx dy*0.8]);
set(h(N),p,get(h(N),p)+[0 dy*0.8 dx dy*0.2]);
set(f,'UserData',S,'Interruptible','on');
%Zoom into the selected area.
%
% f Figure handle
%
function zoomcorr(f)
o=object(f,'zoom');
if ishandle(o)
a=get(o,'Parent');
x=get(o,'XData');
y=get(o,'YData');
delete(o);
if x(1) == x(2) | y(2) == y(3)
x=[1e-7 0.1];
g=findobj(a,'Tag','');
t=get(g,'XData');
g=get(g,'YData');
scale(a,g,t);
else
set(a,'YLim',sort(y(2:3)));
x=sort(x(1:2));
end
x=min(10,max(1e-8,x));
if x(2) < 16*x(1)
x=sqrt(prod(x))*[0.25 4];
end
n=log10(x);
n=ceil(n(1)):floor(n(2));
t={'1.0ns';'10ns';'0.1us';'1.0us';'10us';'0.1ms';'1.0ms';'10ms';'0.1s';'1.0s';'10s'};
set(a,'XLim',x,'XTick',eval(['[' sprintf('1e%d ',n) ']']),'XTickLabel',{t{n+10}});
end
set(f,'Pointer','arrow','WindowButtonMotionFcn','');
%Update selected area.
%
% f Figure handle
%
function zoomdrag(f)
o=object(f,'zoom');
if ishandle(o)
x=get(o,'XData');
y=get(o,'YData');
p=get(get(o,'Parent'),'CurrentPoint');
x(2:3)=p(1);
y(3:4)=p(3);
set(o,'XData',x,'YData',y);
end
%Initialize zooming.
%
% f Figure handle
% o Axes handle
%
function zoominit(f,o)
p=get(o,'CurrentPoint');
patch(repmat(p(1),1,4),repmat(p(3),1,4),'black','FaceColor','none','LineStyle',':','Parent',o,'Tag','zoom');
set(f,'Pointer','crosshair','WindowButtonMotionFcn','flex99(''zoomdrag'')');
%__________________________________________________________
%
% Graphical user interface callbacks
%__________________________________________________________
%
%Toggle auto-lookup of afterpulsing estimations.
%
% f Figure object
% o Checkbox object
%
function adaptive(f,o)
e='Enable';
u='UserData';
v='Value';
n=get(o,u);
s=object(f,'suppress');
if exist(n) == 2
load(n,'ap');
if numel(ap.I)
set(s,u,mean(ap.G.*repmat(ap.I,size(ap.t)),2));
set(o,e,'on');
else
set(o,e,'off',v,0);
set(s,u,0);
end
else
set(o,e,'off',v,0);
set(s,u,0);
end
if get(o,v) | numel(get(object(f,'estimate'),u)) > 1
set(s,e,'on');
else
set(s,e,'off',v,0);
end
%Switch to the auto-correlation mode.
%
% f Figure object
% o Checkbox object
%
function auto(f,o)
set(o,'Value',1);
set(object(f,'cross'),'Value',0);
if running(f)
start(f);
end
%Switch to the cross-correlation mode.
%
% f Figure object
% o Checkbox object
%
function cross(f,o)
set(o,'Value',1);
set(object(f,'auto'),'Value',0);
if running(f)
start(f);
end
%Estimate the afterpulsing contribution.
%
% f Figure handle
% o Button handle
%
function estimate(f,o)
v='Value';
if get(o,v)
auto(f,object(f,'auto'));
s=object(f,'suppress');
t=get(s,v);
set(s,v,0);
snaprun(f,object(f,'snaprun'));
set(s,v,t);
end
%Specify the settings for the online parameter extraction.
%
% f Figure handle
% o Button handle
%
function livefit(f,o)
if get(o,'Value')
a=object(f,'zoominit');
h=get(a,'Children');
set(a,'Children',[line(1,nan,'Color',[0 0 1],'HitTest','off','Parent',a,'Tag','Gl');h]);
fitcorr;
else
delete(object(f,'Gl'));
end
%Start and stop live correlator runs.
%
% f Figure handle
% o Button handle
%
function liverun(f,o)
s='String';
if running(f)
stop(f);
shutter(0);
set(o,s,'Live');
else
try
shutter(1);
start(f);
catch
shutter(0);
alert;
return
end
v='Value';
set(o,s,'Stop');
c=object(f,'livefit');
d=object(f,'livetime');
while isequal(get(o,s),'Stop')
T=get(d,v) - read(f);
if T < 0.15
pause(max(0,T));
[T,g,I,t]=stop(f);
if get(c,v)
fitcorr(object(f,'Gl'),g,t,T);
end
start(f);
end
pause(0.1);
end
end
%Checks the new time in live mode.
%
% f Figure object
% o Editor object
%
function livetime(f,o)
t=get(o,'SliderStep');
settime(o,t(2));
%Modifies the integration timers.
%
% o Editor object
% m Minimal time [s]
% s Modification [s]
%
function settime(o,m,s)
v=sscanf(get(o,'String'),'%f');
if nargin > 2
v=v+s;
end
if isempty(v) | any(isnan(v) | isinf(v))
v=get(o,'Value');
end
v=round(10*max(v(1),m));
set(o,'String',sprintf('%d.%1u',[fix(v/10) rem(v,10)]),'Value',v/10);
%Specify the settings for the parameter extraction.
%
% f Figure handle
% o Button handle
%
function snapfit(f,o)
if get(o,'Value')
a=object(f,'zoominit');
h=get(a,'Children');
set(a,'Children',[line(1,nan,'Color',[1 0 0],'HitTest','off','Parent',a,'Tag','Gs');h]);
fitcorr;
else
delete(object(f,'Gs'));
end
%Start and stop snap correlator runs.
%
% f Figure handle
% o Button handle
% n After-pulsing estimation
%
function snaprun(f,o)
s='String';
if isequal(get(o,s),'Snap')
e=object(f,'estimate');
u='UserData';
v='Value';
try
shutter(1-get(e,v));
start(f);
catch
set(object(f,'estimate'),v,0);
shutter(0);
alert;
return
end
enable(f,'off');
set(o,s,'Save');
T=get(object(f,'snaptime'),v);
while isequal(get(o,s),'Save')
t=T - read(f);
if t < 0.15
pause(max(0,t));
break;
end
pause(0.1);
end
[T,g,I,t]=stop(f);
shutter(0);
m={'AxA','AxB'};
m=m{1 + get(object(f,'cross'),v)};
%
% Get file name and store
%
back=cd;
path=get(o,u);
h=object(f,'template');
n=t < T/8;
r=get(h,u);
if get(e,v) % Afterpulsing estimation
if isequal(questdlg('Use this afterpulsing estimation?','Confirmation','Yes','No','No'),'Yes')
a=object(f,'adaptive');
file=get(a,u);
if exist(file) == 2
load(file);
else
ap.G=[];
ap.I=[];
ap.T=[];
end
g=max(0,g - 1);
n=length(ap.T)+1;
ap.G(:,n)=g;
ap.I(1,n)=mean(I(~isnan(I)));
ap.T(1,n)=T;
ap.t=t(:);
set(e,u,g);
save(file,'ap');
end
set(e,v,0);
elseif isempty(r) | ~get(h,v)
if get(object(f,'snapfit'),v)
fitcorr(object(f,'Gs'),g,t,T);
end
if ischar(path)
cd(path);
end
[name,path]=uiputfile('','Save as');
if ~isequal(name,0)
cd(path);
set(o,u,path);
export(name,g(n,:),t(n),I,T,m);
end
else
h=object(f,'nextfile');
export(sprintf('%s%s %s',r.path,get(h,s),r.name),g(n,:),t(n),I,T,m);
nextfile(f,h,1);
if get(object(f,'snapfit'),v)
fitcorr(object(f,'Gs'),g,t,T);
end
end
cd(back);
if running(f)
shutter(1);
start(f);
end
enable(f,'on');
end
set(o,s,'Snap');
%Checks the new time during a snap.
%
% f Figure object
% o Editor object
%
function snaptime(f,o)
t=get(o,'SliderStep');
settime(o,t(2));
%Spin the running number.
%
% f Figure handle
% o Slider handle
%
function spinfile(f,o)
h=object(f,'nextfile');
nextfile(f,h,get(o,'Value'));
set(o,'Value',0);
%Spin a timer value.
%
% f Figure handle
% o Slider handle
%
function spintime(f,o)
s=get(o,'SliderStep');
settime(object(f,get(o,'UserData')),s(2),get(o,'Value')*s(2));
set(o,'Value',0);
%Suppress afterpulsing on parameter extraction.
%
% f Figure handle
% o Checkbox handle
%
function suppress(f,o)
if get(o,'Value')
o=object(f,'estimate');
if isempty(get(o,'UserData'))
set(o,'UserData',0);
end
end
%Define the file name template.
%
% f Figure handle
% o Button handle
%
function template(f,o)
if get(o,'Value')
back=cd;
r=get(o,'UserData');
if isempty(r)
name='*.*';
else
name=r.name;
cd(r.path);
end
[name,path]=uiputfile(name,'Save as');
cd(back);
if isequal(name,0)
set(o,'Value',0);
else
[ext,name,ext]=fileparts(name);
if ~isequal(ext,'.mat') & ~any(ext == '*')
name=[name ext];
end
r.name=name;
r.path=path;
set(o,'String',name,'UserData',r);
end
end