function varargout = emit_meas_phase4p(varargin)
% EMIT_MEAS_PHASE4 M-file for emit_meas_phase4.fig
%      EMIT_MEAS_PHASE4, by itself, creates a new EMIT_MEAS_PHASE4 or raises the existing
%      singleton*.
%
%      H = EMIT_MEAS_PHASE4 returns the handle to a new EMIT_MEAS_PHASE4 or the handle to
%      the existing singleton*.
%
%      EMIT_MEAS_PHASE4('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in EMIT_MEAS_PHASE4.M with the given input arguments.
%
%      EMIT_MEAS_PHASE4('Property','Value',...) creates a new EMIT_MEAS_PHASE4 or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before emit_meas_phase4_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to emit_meas_phase4_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help emit_meas_phase4

% Last Modified by GUIDE v2.5 15-Jan-2014 11:43:41

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
   'gui_Singleton',  gui_Singleton, ...
   'gui_OpeningFcn', @emit_meas_phase4_OpeningFcn, ...
   'gui_OutputFcn',  @emit_meas_phase4_OutputFcn, ...
   'gui_LayoutFcn',  [] , ...
   'gui_Callback',   []);
if nargin && ischar(varargin{1})
   gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
   [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
   gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before emit_meas_phase4 is made visible.
function emit_meas_phase4_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to emit_meas_phase4 (see VARARGIN)

% Choose default command line output for emit_meas_phase4
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes emit_meas_phase4 wait for user response (see UIRESUME)
% uiwait(handles.emit_meas);


% --- Outputs from this function are returned to the command line.
function varargout = emit_meas_phase4_OutputFcn(hObject, eventdata, handles)
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;


% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


global LOCATION SYSTEM APPNAME DAQFILENAME energy nmeas coupling nslices meas_type
global phase0 phase_steps phase_dif phase_range
global bunch_l bunch_l_err cal cal_error oper right_q
global PROFILEMONITOR K_STEPS
global background screen
global TDC_cal

freq = 2997.912e6; %frequency of TDC

if meas_type==1 % projected multi quad
   quad_names = {'F10D1_MQUA35','F10D1_MQUA45','F10D1_MQUA55'}; % EPICs names
elseif meas_type==0 % projected single quad
   quad_names = {'F10D1_MQUA55'}; % EPICs name
elseif meas_type==2 % slice in x using the TDC
   quad_names = {'F10D1_MQUA35','F10D1_MQUA40','F10D1_MQUA45','F10D1_MQUA50','F10D1_MQUA55'}; % EPICs names
elseif meas_type==3 %slice in y using dispersion
   quad_names = {'F10D1_MQUA10','F10D1_MQUA20','F10D1_MQUA30','F10D1_MQUA40','F10D1_MQUA50'}; % EPICs names
elseif meas_type==4 % slice in x using dispersion
   quad_names = {'F10D1_MQUA35','F10D1_MQUA40','F10D1_MQUA45','F10D1_MQUA50','F10D1_MQUA55'}; % EPICs names
end
screen = PROFILEMONITOR;

% set proper values for quadrupoles
if right_q==0
   % measurement kl-values for the 10 quads between BC and FODO
   if meas_type==4
       kld(1) = 4.525199912180098*0.15;       %F10D1.MQUA10
       kld(2) = 3.874148656932072*0.15;       %F10D1.MQUA20
       kld(3) = -3.249774821515966*0.15;      %F10D1.MQUA30
       kld(4) = -4.797555982557675*0.15;      %F10D1.MQUA40
       kld(5) = 3.615370265142409*0.15;       %F10D1.MQUA50
       kld(6) = 0;                            %F10D1.MQUA60
       kld(7) = 0;                            %F10D1.MQUA70
       kld(8) = 0;                            %F10D1.MQUA80
       kld(9) = 0;                            %F10D1.MQUA90
       kld(10) = 0;                           %F10D1.MQUA100
   else
       kld(1) = 1.335685250670285*0.15;       %F10D1.MQUA10
       kld(2) = 5.211233759043508e-001*0.15;  %F10D1.MQUA20
       kld(3) = -3.108334644187179e-001*0.15; %F10D1.MQUA30
       kld(4) = 0;                            %F10D1.MQUA40
       kld(5) = -9.113260060549501e-001*0.15; %F10D1.MQUA50
       kld(6) = -2.190291790302469*0.15;      %F10D1.MQUA60
       kld(7) = 0.3966673632905451*0.15;      %F10D1.MQUA70
       kld(8) = 2.731046534825306*0.15;       %F10D1.MQUA80
       kld(9) = -0.5417341705156887*0.15;     %F10D1.MQUA90
       kld(10) = 0;                           %F10D1.MQUA100
   end
   qnames0 =  {'F10D1-MQUA10','F10D1-MQUA15','F10D1-MQUA20','F10D1-MQUA25','F10D1-MQUA30',...
      'F10D1-MQUA35','F10D1-MQUA40','F10D1-MQUA45','F10D1-MQUA50','F10D1-MQUA55','F10D1-MQUA60','F10D1-MQUA65',...
     'F10D1-MQUA70','F10D1-MQUA80','F10D1-MQUA85','F10D1-MQUA90','F10D1-MQUA95'};
  
  % I exclude the quads upstream the TDC, since sometimes are used to match the beam
  exc5 = 0;
  if exc5
      qnames0 = qnames0(6:12);
      kld = kld(6:10);
  end
  for i=1:length(kld)
      Id(i)=KLquad2Curr(kld(i),energy);
  end
  
  % since the safe-set button is less reliable than the mood of my
  % girlfriend, I will first cycle all quads, and then set the current
  
  % delay the gun before cycling
  SetPV('FINSS-RLLE-RIOC:RF-ENABLE',2)
  BeamOnOff(0); % close the shutter before cycling
  for i=1:length(qnames0)
      ch=[qnames0{i} ':B-CYC'];
      SetPV(ch,0)
      SetPV(ch,1)
  end
  pause(20); % wait 20 seconds until cycling is done (15s should be fine)
  BeamOnOff; % restore the previous state
  
   if (meas_type==1)||(meas_type==2)||(meas_type==4)
      %set design optics for the 5 quads between BC and TDC
      if ~exc5
          for i=1:5
              ch=[qnames0{i} ':I-SET'];
              %ch=[qnames0{i} ':SEQ-ISET'];
              ch = regexprep(ch, '\.', '-');
              SetPV(ch, Id(i))
          end
      end
   elseif meas_type==0
      %set design for the 10 quads
      if ~exc5
          for i=1:10
              ch=[qnames0{i} ':I-SET'];
              SetPV(ch,Id(i))
          end
      else
          for i=1:5
              ch=[qnames0{i} ':I-SET'];
              SetPV(ch,Id(i))
          end
      end
   end
   % put the gun at the right timing again
   SetPV('FINSS-RLLE-RIOC:RF-ENABLE',1)
end


%knob definition ---------------------------------------------------------
knob = LoadKnobDefinition('PhaseAdvanceScanXYquads103050screen10');

switch screen
    case {'F10D1_DSCR75_CCAM1', 'F10D1_DSCR75_CCAM2'}
        Ldx = 0; % additional drift as compared to the pre-calculated files
        Ld = 10.831-0.15; % drift between the used quad and the screen
    case 'F10D1_DSCR80_CCAM1'
        Ldx = 0.386;
        Ld = 11.217-0.15;
    otherwise
        error('unknown screen')
end


if meas_type==1 % projected multi quad
    load proj_emitx_20110905.mat
    k0 = k;
    load proj_emity_20110905.mat
    kini = [[k0];[k]];
elseif meas_type==0 % projected single quad
    Lq = 0.15;
    beta_x = 15;
    %beta_y = 15;
    %alpha_x = 1.38490;
    %alpha_y = 1.38490;
    mu = [15:5:165];
    k0 = ((1 - (Ld./(sind(mu).*beta_x)) .* (cosd(mu)+beta_x.*sind(mu)/Ld)) / Ld)/Lq;
    kini = k0';
    quads = {'F10D1.MQUA100'};
elseif meas_type==2 % slice in x using the TDC
    load slice_emit_20110905.mat
    kini = k;
elseif meas_type==3 % slice in y using dispersion
    %load slice_emit_20121218.mat % this was for optics in phase3
    load slice_emit_20130515.mat % this is for optics in phase 4
    kini = k;
elseif meas_type==4
    load slice_emit_20130430.mat
    kini = k;
end

k = kini([1:K_STEPS:length(kini)],:);

if meas_type==0
   k=k';
end
Lm = 0.15;

% prepare Knobs for daq.m
for i=1:length(quads)
   temp = size(k);
   if (meas_type==1)||(meas_type==2)||(meas_type==3)||(meas_type==4)
      for j=1:length(k(:,1))
         I(j,i) = KLquad2Curr(k(j,i)*Lm,energy);
      end
      knob.Conversions{i} = [[1:1:temp(1)]',[I(:,i)]];
      knob.SetpointValues = 1:temp(1);
   elseif meas_type==0
      for j=1:length(k)
         I(j,i) = KLquad2Curr(k(j)*Lm,energy);
      end
      knob.Conversions{i} = [[1:1:length(k)]',[I(:)]];
      knob.SetpointValues = [1:1:length(k)];
   end
   knob.Knobs{i}=LoadKnobDefinition(quad_names{i});
   
   if meas_type==0
      knob.Knobs(3) = [];
      knob.Knobs(2) = [];
      knob.Conversions(3) = [];
      knob.Conversions(2) = [];
   end
end


% define knobs for slice emittance measurement (add TDC phase and more)
if meas_type==2
    if TDC_cal
        temp = knob.Conversions;
        
        ind_p = length(quad_names) + 1;
        knob.Knobs{ind_p}.Name = 'F10D1_RLLE_RUPC_PHASE';
        knob.Knobs{ind_p}.Description = 'Phase from Transverse Deflector F10D1';
        knob.Knobs{ind_p}.Author = 'Eduard Prat';
        knob.Knobs{ind_p}.SetpointAddress = 'F10D1-RLLE-RUPC:PHASE';
        knob.Knobs{ind_p}.HowToDetermineSuccess = 'SetAndForget';
        knob.Knobs{ind_p}.WaitTime = 0.2;
        knob.Knobs{ind_p}.ReadbackAddress = 'F10D1-RLLE-RUPC:PHASE';
        knob.Knobs{ind_p}.Max = 360;
        knob.Knobs{ind_p}.Min = -360;
        
        phase_range = [(phase0-phase_steps*phase_dif):phase_dif:(phase0+phase_steps*phase_dif)];
        
        for i=1:length(quads)
            for m=1:size(k,1)
                for j=1:length(phase_range)
                    ind0 = length(phase_range)*(m-1)+j;
                    temp2 =  temp{i}(m,2);
                    knob.Conversions{i}(ind0,2) = temp2;
                    knob.Conversions{i}(ind0,1) = ind0;
                    
                    % values for the phase
                    knob.Conversions{length(quads)+1}(ind0,1) = ind0;
                    knob.Conversions{length(quads)+1}(ind0,2) = phase_range(j);
                    knob.SetpointValues(ind0) = ind0;
                end
                
            end
        end
    end
end

% instrument definition --------------------------------------------------
instrument = LoadInstrumentDefinition(screen);

if (meas_type == 2)||(meas_type)==0 ||(meas_type==3)||(meas_type==4)
   coupling = 0;
end


instrument.Actions = [];
N=0;
instrument.Actions{N+1}.Function = 'StartServer';
instrument.Actions{N+1}.Active = 0; % not required for DSCR80
instrument.Actions{N+1}.Parameters = [];
N=N+1;
instrument.Actions{N+1}.Function = 'StoreCameraData';
instrument.Actions{N+1}.Active = 1;
instrument.Actions{N+1}.Parameters = [];

if background == 1 
   N=N+1;
   instrument.Actions{N+1}.Function = 'MultipleBackgroundImages';
   instrument.Actions{N+1}.Active = 0;
   instrument.Actions{N+1}.Parameters.NumberBackgroundImages = 5;
   instrument.Actions{N+1}.Parameters.StoreBackgroundImages = 1;
   N=N+1;
   instrument.Actions{N+1}.Function = 'SubtractBackgroundImage';
   instrument.Actions{N+1}.Active = 1;
   instrument.Actions{N+1}.Parameters.NumberBackgroundImages = 10;
   instrument.Actions{N+1}.Parameters.StoreBackgroundImages = 1;
elseif background == 2
   N=N+1;
   instrument.Actions{N+1}.Function = 'MultipleBackgroundImages';
   instrument.Actions{N+1}.Active = 1;
   instrument.Actions{N+1}.Parameters.NumberBackgroundImages = 5;
   instrument.Actions{N+1}.Parameters.StoreBackgroundImages = 1;
   N=N+1;
   instrument.Actions{N+1}.Function = 'SubtractBackgroundImage';
   instrument.Actions{N+1}.Active = 0;
   instrument.Actions{N+1}.Parameters.NumberBackgroundImages = 10;
   instrument.Actions{N+1}.Parameters.StoreBackgroundImages = 1;
end

N=N+1;
instrument.Actions{N+1}.Function = 'SubtractOffset';
instrument.Actions{N+1}.Active = 0;
instrument.Actions{N+1}.Parameters = [];
N=N+1;
instrument.Actions{N+1}.Function = 'GaussFit';
instrument.Actions{N+1}.Active = 1;
if coupling
   instrument.Actions{N+1}.Parameters.AdaptiveROI = 1;
   instrument.Actions{N+1}.Parameters.AllowOffset = 0;
else
   instrument.Actions{N+1}.Parameters = [];
end
if coupling
   N=N+1;
   instrument.Actions{N+1}.Function = 'NoiseCut';
   instrument.Actions{N+1}.Active = 1;
   instrument.Actions{N+1}.Parameters.Threshold = 0.2;
   N=N+1;
   instrument.Actions{N+1}.Function = 'xy_slope';
   instrument.Actions{N+1}.Active = 1;
   instrument.Actions{N+1}.Parameters = [];
end


%info --------------------------------------------------------------------
if oper
   Info.OperatorPresent = 1;
else
   Info.OperatorPresent = 0;
end
Info.Author = APPNAME;
Info.Title = 'Multiknob Emittance Measurement';
Info.eLog = Localize('eLog',LOCATION);
Info.Text = [];
Info.StartTime = now;

%set up ------------------------------------------------------------------
Setup.Function = 'scan';
Setup.Repeat = nmeas;
Setup.SaveSR = 1;


% load transfer matrices to put them in Setup
if meas_type==1
   load mat_f10d165_quad6080100.mat
elseif meas_type==2
   load mat_slice_phase3.mat
elseif meas_type==3
   %load mat_slicey_phase3.mat % this is for phase 3 optics
   load mat_slicey_phase4.mat % this is for phase 4 optics
   R11=R33;
   R12=R34;
   R22=R44;
   R21=R43;
elseif meas_type==4
   load mat_slicex_phase3.mat
end

% add an additional drift (this depends on the screen; see the definition of Ldx above)
if meas_type==1 || meas_type==2 || meas_type==3 || meas_type==4
   Mdx = Drift(Ldx); % additional drift between DSCR75 and DSCR80
   for i=1:length(kini)
      M0 = [R11(i) R12(i) 0 0; R21(i) R22(i) 0 0; 0 0 R33(i) R34(i); 0 0 R43(i) R44(i)];
      M = Mdx * M0;
      R11(i) = M(1,1);
      R12(i) = M(1,2);
      R21(i) = M(2,1);
      R22(i) = M(2,2);
      R33(i) = M(3,3);
      R34(i) = M(3,4);
      R43(i) = M(4,3);
      R44(i) = M(4,4);
   end
elseif meas_type==0 %in this case I calculate the matrices directly here
   phi10 = Lq*sqrt(abs(kini));
   Md1 = [[1 Ld 0 0 0 0];[0 1 0 0 0 0];[0 0 1 Ld 0 0];[0 0 0 1 0 0];[0 0 0 0 1 0];[0 0 0 0 0 1]];
   for i=1:length(kini)
      
      if kini(i)<0
         Mq10 = [[cosh(phi10(i)) sinh(phi10(i))/sqrt(abs(kini(i))) 0 0 0 0]; [sqrt(abs(kini(i)))*sinh(phi10(i)) cosh(phi10(i)) 0 0 0 0];[0 0 cos(phi10(i)) sin(phi10(i))/sqrt(abs(kini(i))) 0 0];[0 0 -sin(phi10(i))*sqrt(abs(kini(i))) cos(phi10(i)) 0 0];[0 0 0 0 1 0];[0 0 0 0 0 1]];
      elseif kini(i)==0
         Mq10 = [[1 Lq 0 0 0 0];[0 1 0 0 0 0];[0 0 1 Lq 0 0];[0 0 0 1 0 0];[0 0 0 0 1 0];[0 0 0 0 0 1]];
      else
         Mq10 = [[cos(phi10(i)) sin(phi10(i))/sqrt(abs(kini(i))) 0 0 0 0];[-sin(phi10(i))*sqrt(abs(kini(i))) cos(phi10(i)) 0 0 0 0];[0 0 cosh(phi10(i)) sinh(phi10(i))/sqrt(abs(kini(i))) 0 0]; [0 0 sqrt(abs(kini(i)))*sinh(phi10(i)) cosh(phi10(i)) 0 0];[0 0 0 0 1 0];[0 0 0 0 0 1]];
      end
      M=Md1*Mq10;
      R11(i) = M(1,1);
      R12(i) = M(1,2);
      R21(i) = M(2,1);
      R22(i) = M(2,2);
      R33(i) = M(3,3);
      R34(i) = M(3,4);
      R43(i) = M(4,3);
      R44(i) = M(4,4);
   end
end

R11 = R11([1:K_STEPS:length(kini)]);
R12 = R12([1:K_STEPS:length(kini)]);
R21 = R21([1:K_STEPS:length(kini)]);
R22 = R22([1:K_STEPS:length(kini)]);
R33 = R33([1:K_STEPS:length(kini)]);
R34 = R34([1:K_STEPS:length(kini)]);
R43 = R43([1:K_STEPS:length(kini)]);
R44 = R44([1:K_STEPS:length(kini)]);

Setup.AnalyzeTripleQuadScan.R = {R11, R12, 0, 0; R21, R22, 0, 0; 0, 0, R33, R34; 0, 0, R43, R44};
Setup.AnalyzeTripleQuadScan.k = k;
Setup.AnalyzeTripleQuadScan.energy = energy;
%design optical functions and emittance (entrance of F10D1.MQUA60)
if meas_type==0
   Setup.AnalyzeTripleQuadScan.beta_x0 = 15*1;
   Setup.AnalyzeTripleQuadScan.beta_y0 = 15*1;
   Setup.AnalyzeTripleQuadScan.alpha_x0 = 1.3849*1;
   Setup.AnalyzeTripleQuadScan.alpha_y0 = 1.3849*1;
elseif (meas_type==1)||(meas_type==2)
   Setup.AnalyzeTripleQuadScan.beta_x0 = 9.4801;
   Setup.AnalyzeTripleQuadScan.beta_y0 = 40.0155;
   Setup.AnalyzeTripleQuadScan.alpha_x0 = -1.0220;
   Setup.AnalyzeTripleQuadScan.alpha_y0 = -0.0207;
elseif meas_type==3 % entrance of quad10
   Setup.AnalyzeTripleQuadScan.beta_y0 = 8.5084;
   Setup.AnalyzeTripleQuadScan.beta_x0 = 19.2849;
   Setup.AnalyzeTripleQuadScan.alpha_y0 = -1.4147;
   Setup.AnalyzeTripleQuadScan.alpha_x0 = 0.6847;
elseif meas_type==4
   Setup.AnalyzeTripleQuadScan.beta_x0 = 31.4326;
   Setup.AnalyzeTripleQuadScan.beta_y0 = 17.12275;
   Setup.AnalyzeTripleQuadScan.alpha_x0 = -9.497579;
   Setup.AnalyzeTripleQuadScan.alpha_y0 = 6.811337; 
end

Setup.AnalyzeTripleQuadScan.gamma_x0 = (1+Setup.AnalyzeTripleQuadScan.alpha_x0^2)/Setup.AnalyzeTripleQuadScan.beta_x0;
Setup.AnalyzeTripleQuadScan.gamma_y0 = (1+Setup.AnalyzeTripleQuadScan.alpha_y0^2)/Setup.AnalyzeTripleQuadScan.beta_y0;

% data acquisition -------------------------------------------------------
[DAQFileName, Setup, knob, instrument, Info] = daq(Setup,{knob},{instrument},Info);
%[Setup, Info, knob, instrument] = RetrieveData('/afs/psi.ch/intranet/FIN/Data/FIN250-Phase4+/2014-10-08/MKE20141008T132836.h5');

% put the quadrupole back to zero in the single quad scan
if meas_type==0
    SetPV('F10D1-MQUA55:I-SET.VAL',0)
end
    

% get TDC calibration and other longitudinal parameters for the different
% quad configurations
clear bunch_l bunch_l_err
if meas_type==2
    if TDC_cal
        indg = find(abs(phase_range-phase0)<0.001);
        % first get all vertical centroids and beam sizes
        for i=1:length(phase_range)*size(k,1)
            % all values are in mm
            rms_y0(i) = mean(instrument{1}.BeamSizeGaussfit(2,:,i));
            rms_err_y0(i) = sqrt(var(instrument{1}.BeamSizeGaussfit(2,:,i)));
            
            y0(i) = mean(instrument{1}.BeamPositionGaussfit(2,:,i));
            y_err0(i) = sqrt(var(instrument{1}.BeamPositionGaussfit(2,:,i)));
        end
        
        rms_y = reshape(rms_y0,length(phase_range),size(k,1))';
        rms_err_y = reshape(rms_err_y0,length(phase_range),size(k,1))';
        y = reshape(y0,length(phase_range),size(k,1))';
        y_err = reshape(y_err0,length(phase_range),size(k,1))';
        
        for i=1:size(k,1)
            y2 = y(i,:);
            y_err2 = y_err(i,:);
            
            if nmeas>1
                [p,s] = polyfit3(phase_range,y2,1,[],1./y_err2); % linear fit weighthing with measurement errors
            elseif nmeas==1
                [p,s] = polyfit(phase_range,y2,1);
            end
            %y_pred = polyval(p,phase_range);
            
            % error of the fit
            ste = sqrt(diag(inv(s.R)*inv(s.R')).*s.normr.^2./s.df);
            
            % calibration in mm per ps
            cal(i) = p(1)*360*freq/1e12;
            % calibration error
            cal_err(i) = ste(1)*360*freq/1e12;
            
            % bunch length (in ps)
            bunch_l(i,:) = abs(rms_y(i,:)/cal(i));
            
            % bunch length error (assuming no correlation between calibration error and vertical beam size measurement error)
            bunch_l_err(i,:) = bunch_l(i,:) .* ( (cal_err(i)/cal(i))^2 + (rms_err_y(i,:)./rms_y(i,:)).^2 ) .^ 0.5;
            % slice separation for the analysis
            y_sep0(i,:) = rms_y(i,:) / nslices;
            for j=1:length(phase_range)
                % determine valid measurements (no significant bunch length variation from zero phase)
                if (bunch_l(i,indg) < (bunch_l(i,j)+bunch_l_err(i,j)))
                    if (bunch_l(i,indg) > (bunch_l(i,j)-bunch_l_err(i,j)))
                        indb0(i,j) = i;
                    else
                        indb0(i,j) = 0;
                    end
                else
                    indb0(i,j) = 0;
                end
            end
            %ysep1(i) = mean(y_sep0(~(indb0(i,:)==0)));
        end
        % slice image analysis
        input.ind = reshape(indb0',length(phase_range)*size(k,1),1);
        input.y_sep = reshape(y_sep0',1,length(phase_range)*size(k,1))';
        input.cur_cut = 0.3;
        %
        [output] = Slicer(instrument,input);
        instrument{1}.input = input;
        output.y_sep = mean(mean(bunch_l))/nslices;
        instrument{1}.slice = output;
        instrument{1}.ind_val = input.ind;
    else
        for i=1:size(k,1)
            % all values are in mm
            rms_y0(i) = mean(instrument{1}.BeamSizeGaussfit(2,:,i));
            rms_err_y0(i) = sqrt(var(instrument{1}.BeamSizeGaussfit(2,:,i)));
            
            y0(i) = mean(instrument{1}.BeamPositionGaussfit(2,:,i));
            y_err0(i) = sqrt(var(instrument{1}.BeamPositionGaussfit(2,:,i)));
        end
        
        rms_y = reshape(rms_y0,1,size(k,1))';
        rms_err_y = reshape(rms_err_y0,1,size(k,1))';
        y = reshape(y0,1,size(k,1))';
        y_err = reshape(y_err0,1,size(k,1))';
        
        
        % slice image analysis
        input.y_sep = reshape(rms_y' / nslices,1,size(k,1))';
        input.yflip = 0;
        [output] = Slicer(instrument,input);
        instrument{1}.input = input;
        instrument{1}.slice = output;
    end
end

if meas_type==3
   % first get all horizontal centroids and beam sizes
   for i=1:size(k,1)
      % all values are in mm
      rms_x0(i) = mean(instrument{1}.BeamSizeGaussfit(1,:,i));
      rms_err_x0(i) = sqrt(var(instrument{1}.BeamSizeGaussfit(1,:,i)));
      
      x0(i) = mean(instrument{1}.BeamPositionGaussfit(1,:,i));
      x_err0(i) = sqrt(var(instrument{1}.BeamPositionGaussfit(1,:,i)));
   end
   
   rms_x = reshape(rms_x0,1,size(k,1))';
   rms_err_x = reshape(rms_err_x0,1,size(k,1))';
   x = reshape(x0,1,size(k,1))';
   x_err = reshape(x_err0,1,size(k,1))';
   
   
   % slice image analysis
   input.y_sep = reshape(rms_x' / nslices,1,size(k,1))'; 
   input.yflip = 1;
   [output] = Slicer(instrument,input);
   instrument{1}.input = input;
   instrument{1}.slice = output;
end

if meas_type==4
   % first get all horizontal centroids and beam sizes
   for i=1:size(k,1)
      % all values are in mm
      rms_y0(i) = mean(instrument{1}.BeamSizeGaussfit(2,:,i));
      rms_err_y0(i) = sqrt(var(instrument{1}.BeamSizeGaussfit(2,:,i)));
      
      y0(i) = mean(instrument{1}.BeamPositionGaussfit(2,:,i));
      y_err0(i) = sqrt(var(instrument{1}.BeamPositionGaussfit(2,:,i)));
   end
   
   rms_y = reshape(rms_y0,1,size(k,1))';
   rms_err_y = reshape(rms_err_y0,1,size(k,1))';
   y = reshape(y0,1,size(k,1))';
   y_err = reshape(y_err0,1,size(k,1))';
   
   
   % slice image analysis
   input.y_sep = reshape(rms_y' / nslices,1,size(k,1))'; 
   input.yflip = 0;
   [output] = Slicer(instrument,input);
   instrument{1}.input = input;
   instrument{1}.slice = output;
end

%-------------------------------------------------------------------------
% calculation of emittance and optics

%save workspace

if (meas_type==1)||(meas_type==0)
   [ResultStructure, figh, analfile] ...
      = AnalyzeTripleQuadScanCoupling(Setup, knob, instrument, Info)
elseif meas_type==2 || meas_type==3 || meas_type==4
   [ResultStructure, figh, analfile] ...
   = AnalyzeTripleQuadScanCouplingSliceEnergy(Setup, knob, instrument, Info)
end


% make entry in the logbook
eLog = Localize('eLog',LOCATION);
MakeLogbookEntry(eLog,'Multiknob Emittance Measurement','','Nice operator',DAQFileName,analfile,figh)

%set(handles.pushbutton2,'Enable','on')



function edit1_Callback(hObject, eventdata, handles)
% hObject    handle to edit1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit1 as text
%        str2double(get(hObject,'String')) returns contents of edit1 as a double
global energy
energy = str2double(get(hObject,'String'));

% --- Executes during object creation, after setting all properties.
function edit1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called
global energy
set(hObject,'String',energy)

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end


% --- Executes during object creation, after setting all properties.
function emit_meas_CreateFcn(hObject, eventdata, handles)
% hObject    handle to emit_meas (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called
%addpath /afs/psi.ch/intranet/FIN/Applications/Development/Eduard/MatchingTool/trunk

% set useful defaults

global LOCATION SYSTEM APPNAME DAQFILENAME energy nmeas coupling
global meas_type nslices phase0 phase_dif phase_steps oper right_q
global PROFILEMONITOR K_STEPS
global background en_chirp
global TDC_cal

TDC_cal = 1;
energy = 220; % energy in MeV  -- if this is changed, change also the GUI default string
en_chirp = 0; % energgy chirp along the bunch in %
nmeas = 10; %number of measurements per measurement point
coupling = 0; %include coupling?
meas_type = 0; % 1 is projected measurement with triple quads scan, 0 is projected with single quad, 2 is slice
nslices = 5; % number of slices for slice emittance measurement
oper=0; %operator present
right_q = 1; %right initial values for quads?
K_STEPS = 2; % skip every other setpoint
background = 1; % 1 is single background subtraction, 2 is multiple

SetPath

LOCATION= 'wlha';
SYSTEM = 'epics';
APPNAME = 'Multiknob emittance measurement';
DAQFILENAME = 'MKE';

% phase control parameters (for TDC calibration measurements)
phase0 = GetPV('F10D1-RLLE-RUPC:PHASE');
phase_dif = 1;
phase_steps = 1;

PROFILEMONITOR = 'F10D1_DSCR80_CCAM1';







function edit2_Callback(hObject, eventdata, handles)
% hObject    handle to edit2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global nmeas
nmeas = str2double(get(hObject,'String'));

% --- Executes during object creation, after setting all properties.
function edit2_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

global nmeas
set(hObject,'String',nmeas)


% --- Executes on button press in check_coupling.
function check_coupling_Callback(hObject, eventdata, handles)
% hObject    handle to check_coupling (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global coupling

if get(hObject,'Value')
   coupling =1;
else
   coupling=0;
end
% Hint: get(hObject,'Value') returns toggle state of check_coupling


% --- Executes during object creation, after setting all properties.
function check_coupling_CreateFcn(hObject, eventdata, handles)
global coupling all_objects meas_type

all_objects.coupling = hObject;

if coupling
   set(hObject,'Value',1)
else
   set(hObject,'Value',0)
end

if (meas_type==0)||(meas_type==2)
   set(hObject,'Enable','off')
else
   set(hObject,'Enable','on')
end

% hObject    handle to check_coupling (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called


% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
matching_phase4p
% hObject    handle to pushbutton2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)






function edit3_Callback(hObject, eventdata, handles)
global nslices
nslices = str2double(get(hObject,'String'));
% hObject    handle to edit3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit3 as text
%        str2double(get(hObject,'String')) returns contents of edit3 as a double


% --- Executes during object creation, after setting all properties.
function edit3_CreateFcn(hObject, eventdata, handles)
global nslices all_objects
set(hObject,'String',nslices)
all_objects.nslices = hObject;
% hObject    handle to edit3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



function edit4_Callback(hObject, eventdata, handles)
global phase_steps
phase_steps = str2double(get(hObject,'String'));
% hObject    handle to edit4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit4 as text
%        str2double(get(hObject,'String')) returns contents of edit4 as a double


% --- Executes during object creation, after setting all properties.
function edit4_CreateFcn(hObject, eventdata, handles)
global phase_steps all_objects
set(hObject,'String',phase_steps)
all_objects.phase_steps = hObject;

% hObject    handle to edit4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



function edit5_Callback(hObject, eventdata, handles)
global phase_dif
phase_dif = str2double(get(hObject,'String'));
% hObject    handle to edit5 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit5 as text
%        str2double(get(hObject,'String')) returns contents of edit5 as a double


% --- Executes during object creation, after setting all properties.
function edit5_CreateFcn(hObject, eventdata, handles)
global phase_dif all_objects
set(hObject,'String',phase_dif)
all_objects.phase_dif = hObject;

% hObject    handle to edit5 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



function edit6_Callback(hObject, eventdata, handles)
global phase0
phase0 = str2double(get(hObject,'String'));
% hObject    handle to edit6 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit6 as text
%        str2double(get(hObject,'String')) returns contents of edit6 as a double


% --- Executes during object creation, after setting all properties.
function edit6_CreateFcn(hObject, eventdata, handles)
global phase0 all_objects
set(hObject,'String',phase0)
all_objects.phase0 = hObject;

% hObject    handle to edit6 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end

% --- Executes during object creation, after setting all properties.
function pushbutton2_CreateFcn(hObject, eventdata, handles)
global all_objects
all_objects.matching = hObject;
% hObject    handle to pushbutton2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called


% --- Executes when selected object is changed in uipanel4.
function uipanel4_SelectionChangeFcn(hObject, eventdata, handles)
global meas_type
if strcmp(get(hObject,'String'),'Projected multi quad')
   meas_type = 1;
elseif strcmp(get(hObject,'String'),'Slice X (TDC)')
   meas_type = 2;
elseif strcmp(get(hObject,'String'),'Projected single quad')
   meas_type = 0;
elseif strcmp(get(hObject,'String'),'Slice Y (disp.)')
   meas_type = 3;
elseif strcmp(get(hObject,'String'),'Slice X (disp.)')
   meas_type = 4;  
end

en_dis(hObject, eventdata, handles)

% hObject    handle to the selected object in uipanel4
% eventdata  structure with the following fields (see UIBUTTONGROUP)
%	EventName: string 'SelectionChanged' (read only)
%	OldValue: handle of the previously selected object or empty if none was selected
%	NewValue: handle of the currently selected object
% handles    structure with handles and user data (see GUIDATA)


% --- Executes on button press in checkbox2.
function checkbox2_Callback(hObject, eventdata, handles)
global oper

if get(hObject,'Value')
   oper =1;
else
   oper = 0;
end
% hObject    handle to checkbox2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of checkbox2


% --- Executes during object creation, after setting all properties.
function checkbox2_CreateFcn(hObject, eventdata, handles)
global oper all_objects

all_objects.oper = hObject;

if oper
   set(hObject,'Value',1)
else
   set(hObject,'Value',0)
end

% hObject    handle to checkbox2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called


% --- Executes on button press in checkbox3.
function checkbox3_Callback(hObject, eventdata, handles)
global right_q

if get(hObject,'Value')
   right_q =1;
else
   right_q = 0;
end
% hObject    handle to checkbox3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of checkbox3


% --- Executes during object creation, after setting all properties.
function checkbox3_CreateFcn(hObject, eventdata, handles)
global right_q all_objects

all_objects.right_q = hObject;

if right_q
   set(hObject,'Value',1)
else
   set(hObject,'Value',0)
end

% hObject    handle to checkbox3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called


% --- Executes on selection change in SelectProfileMonitor.
function SelectProfileMonitor_Callback(hObject, eventdata, handles)
global PROFILEMONITOR
% we can just take the instrument name from the string of this menu
contents = cellstr(get(hObject,'String'));
PROFILEMONITOR = contents{get(hObject,'Value')};


function SelectStepSize_Callback(hObject, eventdata, handles)
global K_STEPS
K_STEPS = str2double(get(hObject,'String'));

% --- Bogus functions
function SelectProfileMonitor_CreateFcn(hObject, eventdata, handles)
function SelectStepSize_CreateFcn(hObject, eventdata, handles)


% --- Executes on selection change in popupmenu3.
function popupmenu3_Callback(hObject, eventdata, handles)
% hObject    handle to popupmenu3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global background
background = get(hObject,'Value');

% Hints: contents = cellstr(get(hObject,'String')) returns popupmenu3 contents as cell array
%        contents{get(hObject,'Value')} returns selected item from popupmenu3


% --- Executes during object creation, after setting all properties.
function popupmenu3_CreateFcn(hObject, eventdata, handles)
% hObject    handle to popupmenu3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes during object creation, after setting all properties.
function radiobutton1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to radiobutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called


% --- Executes during object creation, after setting all properties.
function meas_type_CreateFcn(hObject, eventdata, handles)
% hObject    handle to meas_type (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called



function edit8_Callback(hObject, eventdata, handles)
global en_chirp
en_chirp = str2double(get(hObject,'String'));
% hObject    handle to edit8 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit8 as text
%        str2double(get(hObject,'String')) returns contents of edit8 as a double


% --- Executes during object creation, after setting all properties.
function edit8_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit8 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

global en_chirp all_objects
set(hObject,'String',en_chirp)

all_objects.en_chirp = hObject;


% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in checkbox4.
function checkbox4_Callback(hObject, eventdata, handles)
global TDC_cal

if get(hObject,'Value')
   TDC_cal =1;
else
   TDC_cal = 0;
end
% hObject    handle to checkbox4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of checkbox4


% --- Executes during object creation, after setting all properties.
function checkbox4_CreateFcn(hObject, eventdata, handles)
global TDC_cal all_objects

all_objects.TDC_cal = hObject;

if TDC_cal
   set(hObject,'Value',1)
else
   set(hObject,'Value',0)
end
% hObject    handle to checkbox4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called
