Code covered by the BSD License  

Highlights from
Flex02-01D Correlator Interface

image thumbnail
from Flex02-01D Correlator Interface by Marcel Leutenegger
A graphical user interface to the Flex02-01D hardware correlator accessing the Windows driver.

f=flex02dc01
%Graphical user interface to the Flex02-01D/C correlator.
%
%   Marcel Leutenegger  29.4.2009
%
function f=flex02dc01
h=findobj(allchild(0),'flat','Tag','Flex02-01D/C');
if any(h)
   figure(h);
else
   h=create;
end
if nargout
   f=h;
end


%__________________________________________________________
%
%           Graphical user interface functions
%__________________________________________________________
%

%Track modification of comments.
%
% o   Editor
% e   Event
% u   Update
%
function comment(o,e,u)
set(u,'Value',0);


%Fetch and merge comments.
%
% f   Figure
% c   Comment
%
function c=comments(f)
c=get(object(f,'comment'),'String');
if ~isempty(c)
   o=cell(size(c,1),1);
   for n=1:numel(o)
      o{n}=deblank(c(n,:));
   end
   c=sprintf('%s\n',o{:});
   c(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
%
w.Color=[0.8 0.8 0.8];
w.DoubleBuffer='on';
w.HandleVisibility='callback';
w.IntegerHandle='off';
w.Menubar='none';
w.NumberTitle='off';
w.Renderer='painters';
w.Toolbar='none';
%
% Axes properties
%
a.Box='on';
a.ColorOrder=[0 0 1;1 0 0];
a.FontSize=8;
a.FontWeight='bold';
a.Units='pixel';
%
% Checkbox properties
%
c.BackgroundColor=[0.8 0.8 0.8];
c.BusyAction='cancel';
c.Interruptible='off';
c.Style='checkbox';
%
% Button properties
%
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';
%
% List properties
%
m.BackgroundColor=[1 1 1];
m.Style='popupmenu';
%
% Text properties
%
x.BackgroundColor=[0.8 0.8 0.8];
x.HorizontalAlignment='left';
x.Style='text';
%
% Figure
%
o=get(0,'ScreenSize');
o=[o(3)/2-404 o(4)/2-244 600 465];
f=figure(w,'Name','Correlator Flex02-01D/C',p,o,'ResizeFcn',@sizecorr,t,'Flex02-01D/C',u,o(3:4),'WindowButtonUpFcn',@zoomcorr);
a.parent=f;
b.Parent=f;
c.Parent=f;
k.Parent=f;
m.Parent=f;
x.Parent=f;
%
% Intensity
%
ha=axes(a,p,[50 335 300 120],'XLim',[0 300],'XTick',150,'XTickLabel',{'Time'},t,'intensity');
hl=line(0:300,repmat(nan,2,301),'HitTest','off','Parent',ha);
ylabel(ha,'Intensity [kHz]');
set(ha,'Children',hl);
%
% Intensity context menu
%
hc=uicontextmenu('Parent',f);
hm=[uimenu(hc,'Interruptible','off','Label','Hide channel &A')
    uimenu(hc,'Interruptible','off','Label','Hide channel &B')];
uimenu(hc,'Callback',{@wipe hl},'Label','&Clear traces','Separator','on');
set(hm,'Callback',{@hide hm hl});
set(ha,'UIContextMenu',hc);
%
% Correlation
%
a.ButtonDownFcn=@zoominit;
ha=axes(a,p,[50 90 300 220],t,'zoominit','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]);
ylabel(ha,'Correlation G(t)');
%
% Comments
%
set(uicontrol(c,e,p,[1 1 600 64],s,'Comments',t,'comment',h,'Comments','HorizontalAlignment','left','Max',2),'Callback',{@comment uicontrol(c,'Callback',{@update f},p,[588 1 13 13],t,'update',h,'Update comments')});
%
% Texts
%
y=o(4);
uicontrol(x,p,[460 y-130 140 14],s,'live operation');
uicontrol(x,p,[460 y-150 140 14],s,'on recordings');
uicontrol(x,p,[460 y-200 140 14],s,'bin time [us]');
uicontrol(x,p,[480 y-220 120 14],s,'format of photon traces');
x.FontWeight='bold';
%
% Operations
%
uicontrol(x,p,[380 y-22 100 14],s,'Operations');
nc=uicontrol(m,p,[390 y-44 40 20],s,{'1x';'2x';'4x'},t,'number',v,1,h,'Number of correlations');
ac=uicontrol(c,p,[440 y-42 50 16],s,'auto-',t,'auto',v,1,h,'Run auto-correlation AxA (and BxB)');
cc=uicontrol(c,p,[490 y-42 105 16],s,'cross-correlation',t,'cross',h,'Run cross-correlation AxB (and BxA)');
av=uicontrol(c,p,[440 y-42 145 16],s,'Average cross-correlations',t,'average',h,'Display the average of the cross-correlations AxB and BxA','Visible','off');
hc=uicontrol(c,p,[440 y-62 155 16],s,'Photon counting histograms',t,'histogram',v,0,h,'Display the intensity histograms');
uicontrol(c,p,[440 y-82 130 16],s,'Record photon traces',t,'trace',v,0,h,'Record raw photon traces','Enable','off');
set(nc,'Callback',{@number [ac cc] av});
set(ac,'Callback',{@autoCross f cc});
set(cc,'Callback',{@autoCross f ac});
%
% Histogram axes
%
o(1)=o(1)+o(3)+8;
o(3)=200;
hf=figure(w,'Name','Histograms','CloseRequestFcn',{@dispose hc},p,o,'ResizeFcn',@sizehist,t,'Flex02-01D histograms','Visible','off','WindowButtonUpFcn',@zoomhist);
set(f,'CloseRequestFcn',{@destroy hf});
set(hc,'Callback',{@histogram f hf},u,hf);
ha=axes(a,'Parent',hf,'XLim',[-0.2 100.2],'YLim',[0.1 1],'YScale','log');
line(0:2047,repmat(nan,2,2048),'HitTest','off','LineStyle',':','Marker','.','MarkerSize',5,'Parent',ha);
ylabel(ha,'Probability P(n)');
sizehist(hf);
%
% Integration time
%
uicontrol(x,p,[380 y-110 120 14],s,'Integration time [s]');
lt=uicontrol(c,e,'Callback',@edittime,p,[390 y-132 48 20],s,'1.0',t,'livetime',v,1,h,'Integration time during live operation');
uicontrol(k,'Callback',{@spintime lt},p,[438 y-132 12 20],'SliderStep',[1 0.1]);
st=uicontrol(c,e,'Callback',@edittime,p,[390 y-152 48 20],s,'10.0',t,'savetime',v,10,h,'Integration time for recordings');
uicontrol(k,'Callback',{@spintime st},p,[438 y-152 12 20],'SliderStep',[1 1]);
%
% Trace format and bin time
%
uicontrol(x,p,[380 y-180 150 14],s,'Histogram and trace');
bt=uicontrol(c,e,'Callback',@edittime,p,[390 y-202 48 20],s,'1.0',t,'bintime',v,1,h,'Histogram and photon trace bin time');
uicontrol(k,'Callback',{@spintime bt},p,[438 y-202 12 20],'SliderStep',[1 0.1]);
uicontrol(m,p,[390 y-223 85 20],s,{'Byte (8bit)';'Word (16bit)'},t,'fileformat',v,1,h,'File format for the photon traces');
%
% Working folder
%
uicontrol(x,p,[380 y-250 100 14],s,'Working folder');
uicontrol(b,'Callback',{@template f},p,[390 y-272 156 20],s,'File name template',t,'template',h,'Set and use a file name template for snap-shots');
fn=uicontrol(c,e,'Callback',{@nextfile 0},p,[546 y-272 32 20],s,'001',t,'nextfile',v,1,h,'Running file number');
uicontrol(k,'Callback',{@spinfile fn},p,[578 y-272 12 20],'SliderStep',[1 1]);
%
% Background
%
uicontrol(x,p,[380 y-300 80 14],s,'Background');
hr=uicontrol(c,'Callback',{@background f},p,[390 y-320 60 16],s,'Remove',t,'background',h,'Remove the background');
mb=uicontrol(b,p,[495 y-322 95 20],s,'Measure',t,'measure',h,'Measure the background');
background(hr,[],f);
%
% Experiment
%
b.Style='pushbutton';
uicontrol(x,p,[380 y-360 80 14],s,'Experiment');
uicontrol(b,'Callback',{@liverun f nc lt},p,[390 y-390 95 24],s,'Live',t,'liverun',h,'Start and stop live operation');
sb=uicontrol(b,'Callback',{@saverun f mb st},p,[495 y-390 95 24],s,'Record',t,'saverun',h,'Record the correlations, histograms and intensity traces');
set(mb,'Callback',{@measure sb f mb st});


%Current time in seconds based on NOW.
%
function t=curtime
t=86400*now;


%Close the correlator interface.
%
% f   Figure
% e   Event
% h   Histogram
%
function destroy(f,e,h)
try
   flex02d01('e');
   pause(0.1);
   clear('flex02d01');
catch
   clear('flex02d01');
end;
delete([f h]);


%Close/hide the histogram window.
%
% f   Figure
% e   Event
% c   Checkbox
%
function dispose(f,e,c)
set(f,'Visible','off');
set(c,'Value',0);


%Update the correlations.
%
% f      Figure handle
% g      Correlations
% I      Intensity [Hz]
% B      Background [Hz]
% a      Correlation axes
% m      Correlation mode
%
function [m,g]=drawcorr(f,g,I,B,a)
N=size(g,2);
m={'AxA','AxB';'AxA BxB','AxB BxA';'AxA AxB BxB BxA','AxA AxB BxB BxA'};
m=m{get(object(f,'number'),'Value'),1 + get(object(f,'cross'),'Value')};
h=get(a,'Children');
h=h(1-N+end:end);
if isempty(I)
   R=[1 1];
else
   I=mean(I,1);
   R=min(5,I./(I - B));
   R(R < 0)=1;
end
switch m
case 'AxA'
   R=R(1).^2;
case 'AxB'
   R=prod(R);
case 'AxA BxB'
   R=R.^2;
case 'AxB BxA'
   R=prod(R);
   R=[R R];
otherwise
   R=[R(1).^2 prod(R) R(2).^2 prod(R)];
   if get(object(f,'average'),'Value')
      g(:,2)=(g(:,2)+g(:,4))/2;
      g(:,4)=nan;
   end
end
g=1 + repmat(R,size(g,1),1).*(g - 1);
for n=1:N
   set(h(n),'YData',g(:,n));
end


%Update the photon counting histograms.
%
% f      Figure handle
% H      Histograms
%
function drawhist(f,H)
h=get(object(f,'histogram'),'UserData');
if isequal(get(h,'Visible'),'on')
   h=get(get(h,'Children'),'Children');
   set(h(end-1),'YData',H(:,1));
   set(h(end),'YData',H(:,2));
end


%Update the intensity traces.
%
% f      Figure handle
% I      Intensity traces [Hz]
% B      Background [Hz]
% T      Elapsed time [s]
%
function [I,B]=drawint(f,I,T)
o=object(f,'measure');
if get(object(f,'background'),'Value') & ~get(o,'Value')
   B=get(o,'UserData');
else
   B=[0 0];
end
a=object(f,'intensity');
h=get(a,'Children');
y=get(h,'YData');
y=cat(1,y{:});
if ~isempty(I)
   y=[y 0.001*(I - repmat(B,size(I,1),1)).'];
end
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      Enable or disable
%
function enable(f,e)
e=any(e);
v={'off','on'};
set(findobj(get(f,'Children'),'flat','Type','uicontrol'),'Enable',v{1+e});
set([object(f,'comment') object(f,'histogram') object(f,'saverun')],'Enable','on');
if e
   n=object(f,'number');
   set(n,'Enable',v{2-running(f)});
   set(object(f,'trace'),'Enable',v{1+get(object(f,'template'),'Value')});
   background(object(f,'background'),[],f);
end


%Hide/show the intensity trace for a channel.
%
% m   Menu
% e   Event
% c   Context
% h   Lines
%
function hide(m,e,c,h)
e=isequal(get(m,'Checked'),'off');
set(c,'Checked','off');
set(h,'ZData',[]);
if e
   set(h(get(m,'Position')),'ZData',repmat(nan,1,301));
   set(m,'Checked','on');
end


%Modifiy the running number.
%
% o   Editbox
% e   Event
% s   Step
%
function nextfile(o,e,s)
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,round(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)
a=object(f,'zoominit');
T=get(a,'UserData');
[g,I,H]=flex02d01;
[I,B]=drawint(f,I,curtime - T);
drawcorr(f,g,I,B,a);
drawhist(f,H);
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      Correlations
% t      Delays [s]
%
function scale(a,g,t)
m=get(a,'XLim');
g=g(t > m(1) & t < m(2),:);
g=g(~isnan(g) & g > 0);
set(a,'YLim',[0.99*max([1 min(g)]) max([1.02 pow2(ceil(8*log2(1.02*max(g)))/8)])]);


%Start the correlator.
%
% f   Figure
% r   Recording
%
function start(f,r)
c='Children';
v='Value';
u='UserData';
flex02d01('e');
a=object(f,'zoominit');
o=object(f,'template');
if get(object(f,'auto'),v);
   m='a';
else
   m='c';
end
t=object(f,'trace');
I.time=get(object(f,'bintime'),v)*1e-6;
if get(object(f,'fileformat'),v) == 1
   I.format='byte';
else
   I.format='word';
   m=char(m-32);        % uppercase: 16bit format
end
if nargin > 1 & any(r) & get(t,v)
   r=get(o,u);
   I.file=sprintf('%s%s %s.trace',r.path,get(object(f,'nextfile'),'String'),r.name);
   set(t,u,I);
   [g,I,H,t]=flex02d01(m,I.time,I.file);
else
   set(t,u,I);
   [g,I,H,t]=flex02d01(m,I.time);
end
T=curtime;
delete(findobj(get(a,c),'Tag',''));
o=get(a,c);
h=[0 0 1;1 0 0];
if size(g,2) > 2
   h=[0 0 1;0 0 0;1 0 0;0 0.5 0];
   if get(object(f,'average'),v)
      g(:,2)=(g(:,2)+g(:,4))/2;
      g(:,4)=nan;
   end
end
for n=1:size(g,2)
   o(end+1)=line(t,g(:,n),'Color',h(n,:),'HitTest','off','Parent',a);
end
set(a,c,o,u,T);
drawint(f,I,0);
drawhist(f,H);
drawnow;


%Stop the correlator.
%
% f      Figure handle
% T      Elapsed time [s]
% g      Correlations
% I      Intensity traces [Hz]
% H      Intensity histograms
% t      Delays [s]
% m      Correlation mode
% B      Background [Hz]
%
function [T,g,I,H,t,m,B]=stop(f)
T=curtime;
[g,I,H,t]=flex02d01('e');
a=object(f,'zoominit');
T=T - get(a,'UserData');
[I,B]=drawint(f,I,T);
[m,k]=drawcorr(f,g,I,B,a);
drawhist(f,H);
scale(a,k,t);
drawnow;


%Store comment modifications with last measurement.
%
% o   Editor
% e   Event
% f   Figure
%
function update(o,e,f)
file=get(o,'UserData');
if get(o,'Value') & numel(file)
   comment=comments(f);
   save(file,'comment','-append');
end
set(o,'Value',~isempty(file));


%Clear the intensity traces for both channels.
%
% m   Menu
% e   Event
% h   Lines
%
function wipe(m,e,h)
set(h,'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
% e      Event data
%
function sizecorr(f,e)
p='Position';
h=get(f,'Children');
s=get(f,'UserData');
S=get(f,p);
S=max(S(3:4),[450 465]);
N=numel(h);
dx=S(1)-s(1);
dy=S(2)-s(2);
d=[dx dy 0 0];
set(f,'Interruptible','off');
for n=1:N-5
   set(h(n),p,get(h(n),p)+d);
end
dx=S(1)-300;
dy=S(2)-465;
set(h(N-4),p,[S(1)-12 1 13 13]);
if S(2) > 565
   set(h(N-3),p,[S(1)-229 1 230 S(2)-400]);
   set(h(N-2),p,[50 25 dx 0.8*dy+265]);
   set(h(N),p,[50 0.8*dy+315 dx 0.2*dy+145]);
else
   set(h(N-3),p,[1 1 S(1) 64]);
   set(h(N-2),p,[50 90 dx 0.8*dy+225]);
   set(h(N),p,[50 0.8*dy+335 dx 0.2*dy+120]);
end
set(f,'UserData',S,'Interruptible','on');


%Resize the photon counting histogram axes.
%
% f      Figure handle
% e      Event data
%
function sizehist(f,e)
s=get(f,'Position');
set(get(f,'Children'),'Position',[50 25 s(3)-58 s(4)-33]);


%Zoom into the selected area.
%
% f      Figure handle
% e      Event data
%
function zoomcorr(f,e)
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=get(a,'Children');
      switch numel(g)
      case 0
         t=g;
      case 1
         t=get(g,'XData');
         g=get(g,'YData');
      otherwise
         t=get(g(1),'XData');
         g=get(g,'YData');
         g=cat(1,g{:});
      end
      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
% e      Event data
%
function zoomdrag(f,e)
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


%Zoom into the selected area.
%
% f      Figure handle
% e      Event data
%
function zoomhist(f,e)
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)
      y=get(get(a,'Children'),'YData');
      x=find(y{1} > 0 | y{2} > 0);
      y=cat(2,y{:});
      y=y(y > 0);
      if isempty(y)
         set(a,'XLim',[-0.2 2047.2],'YLim',[0.1 1]);
      else
         set(a,'XLim',[-0.2 x(end)-0.8],'YLim',[0.9*min(y) min(1,1.1*max(y))]);
      end
   else
      set(a,'XLim',max(-0.2,min(2047.2,sort(x(1:2)))),'YLim',min(1,sort(y(2:3))));
   end
end
set(f,'Pointer','arrow','WindowButtonMotionFcn','');


%Initialize zooming.
%
% a      Axes handle
% e      Event data
%
function zoominit(a,e)
p=get(a,'CurrentPoint');
patch(repmat(p(1),1,4),repmat(p(3),1,4),'black','FaceColor','none','LineStyle',':','Parent',a,'Tag','zoom');
set(get(a,'Parent'),'Pointer','crosshair','WindowButtonMotionFcn',@zoomdrag);


%__________________________________________________________
%
%           Graphical user interface callbacks
%__________________________________________________________
%

%Switch to the cross-correlation mode.
%
% o   Checkbox
% e   Event
% f   Figure
% c   Checkbox
%
function autoCross(o,e,f,c)
set(o,'Value',1);
set(c,'Value',0);
if running(f)
   start(f);
end


%Toggle background removal.
%
% o   Checkbox
% e   Event
% f   Figure
%
function background(o,e,f)
if numel(get(object(f,'measure'),'UserData')) ~= 2
   e='off';
else
   e='on';
end
set(o,'Enable',e);


%Checks the new time.
%
% o   Editor
% e   Event
%
function edittime(o,e)
t=get(o,'SliderStep');
settime(o,t(2));


%Switch the photon counting histogram.
%
% o   Checkbox
% e   Event
% f   Figure
% h   Histogram
%
function histogram(o,e,f,h)
if get(o,'Value')
   set(h,'Visible','on');
   try
      [g,I,H]=flex02d01;
      drawhist(f,H);
   catch
   end
else
   set(h,'Visible','off');
end
figure(f);
drawnow;


%Start and stop live correlation.
%
% o   Button
% e   Event
% f   Figure
% nc  Number
% lt  Lifetime
%
function liverun(o,e,f,nc,lt)
e='Enable';
s='String';
if running(f)
   stop(f);
   shutter(0);
   set(o,s,'Live');
   set(nc,e,'on');
else
   try
      shutter(1);
      start(f);
   catch
      shutter(0);
      error(lasterr);
   end
   v='Value';
   set(nc,e,'off');
   set(o,s,'Stop');
   while isequal(get(o,s),'Stop')
      T=get(lt,v) - read(f);
      if T < 0.15
         pause(max(0,T));
         stop(f);
         start(f);
      end
      pause(0.1);
   end
end


%Measure the background.
%
% o   Button
% e   Event
% b   Button
% f   Figure
% mb  Measure
% st  Savetime
%
function measure(o,e,b,f,mb,st)
v='Value';
if get(o,v)
   saverun(b,e,f,mb,st);
end


%Change the number of correlations.
%
% o   List
% e   Event
% ac  Auto/cross
% av  Average
%
function number(o,e,ac,av)
m='sdq';
m=m(get(o,'Value'));
v='Visible';
if m == 'q'
   set(ac,v,'off');
   set(av,v,'on');
else
   set(av,v,'off');
   set(ac,v,'on');
end
flex02d01(m);


%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);


%Start and stop snap correlator runs.
%
% o   Button
% e   Event
% f   Figure
% mb  Measure
% st  Savetime
%
function saverun(o,e,f,mb,st)
s='String';
if isequal(get(o,s),'Record')
   u='UserData';
   v='Value';
   try
      shutter(1);
      start(f,1);
   catch
      set(mb,v,0);
      shutter(0);
      error(lasterr);
   end
   enable(f,0);
   set(o,s,'Save');
   T=get(st,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,H,t,m,B]=stop(f);
   shutter(0);
   %
   % 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(mb,v)          % Background measure
      I=mean(I,1);
      I(isnan(I))=0;
      set(mb,v,0,u,I);
   elseif isempty(r) | ~get(h,v)
      if ischar(path)
         cd(path);
      end
      [name,path]=uiputfile('*.mat','Save as');
      if ~isequal(name,0)
         cd(path);
         set(o,u,path);
         if numel(name) < 4 | ~isequal(name(end-3:end),'.mat')
            name=[name '.mat'];
         end
         export(name,comments(f),g(n,:),t(n),I,B,H,T,m,get(object(f,'trace'),u));
         set(object(f,'update'),v,1,u,name,'TooltipString',sprintf('Update comments in "%s"',name));
      end
   else
      h=object(f,'nextfile');
      name=sprintf('%s%s %s.mat',r.path,get(h,s),r.name);
      export(name,comments(f),g(n,:),t(n),I,B,H,T,m,get(object(f,'trace'),u));
      set(object(f,'update'),v,1,u,name,'TooltipString',sprintf('Update comments in "%s"',name));
      nextfile(h,[],1);
   end
   cd(back);
   if running(f)
      shutter(1);
      start(f);
   end
   enable(f,1);
end
set(o,s,'Record');


%Spin the running number.
%
% s   Slider
% e   Event
% o   Editbox
%
function spinfile(s,e,o)
nextfile(o,e,get(s,'Value'));
set(s,'Value',0);


%Spin a timer value.
%
% o   Slider
% e   Event
% t   Editbox
%
function spintime(o,e,t)
s=get(o,'SliderStep');
settime(t,s(2),get(o,'Value')*s(2));
set(o,'Value',0);


%Define the file name template.
%
% o   Button
% e   Event
% f   Figure
%
function template(o,e,f)
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
enable(f,1);


Contact us at files@mathworks.com