%**************************************************************************
%This function determines the shims required to set the gap so that the
%peak fields are constant and at the proper value to get the nominal K.
%Its output is plots of required shim adjustments to properly set the gap.
%A second analysis is done in which the gap is set to eliminate phase
%errors relative to the nominal radiation wave.  The two methods are
%complimentary ways to the same result.
%
%Input:
%dat_file, data file
%plt_file, plot file
%param, parameter structure
%shim_param, shim parameter structure
%field, magnetic field structure
%rad, radiation information structure
%
%Output:
%setgap_shim, structure containing shim information to set the gap
%   z_peak_no_ends      %Peak field z positions, no ends
%   dbrel_no_ends       %Relative field change required at the poles
%   dgap_no_ends        %Required gap change at the poles
%   dx_no_ends          %Required tapered shim motions at the poles
%
%Zachary Wolf
%10/21/06

function [setgap_shim] = pid_shim_setgap(dat_file, plt_file, param, shim_param, field, rad)

%Field -----

%Parameters
nom_k_value = param.nom_k_value;
nom_lambda_u = param.nom_lambda_u;
nom_gap = shim_param.phaserr_gap_shim_nom_gap;
cant_angle = shim_param.k_shim_cant_angle;

%Extract the required field information
z_peak = field.z_peak;
by_peak = field.by_peak;

%Extract the measured K value
k_eff = rad.k_eff;

%Find the magnitudes of the peak fields excluding the ends
z_peak_no_ends = z_peak(param.num_end_poles + 1 : length(z_peak) - param.num_end_poles);
by_peak_no_ends = by_peak(param.num_end_poles + 1 : length(by_peak) - param.num_end_poles);
abs_by_peak_no_ends = abs(by_peak_no_ends);

%Calculate the nominal peak field strengths from the nominal and measured K values
nom_abs_by_peak_no_ends_ave = mean(abs_by_peak_no_ends) * nom_k_value / k_eff;

%Calculate the required magnitude of the field change at each pole
field_shim_dbrel_no_ends = (nom_abs_by_peak_no_ends_ave - abs_by_peak_no_ends) ./ abs_by_peak_no_ends;

%Calculate the gap change required to get the field change
field_shim_dgap_no_ends = setgap_calc_shim_relfield_dgap(nom_gap, nom_lambda_u, field_shim_dbrel_no_ends);

%Calculate the shim motion required to get the gap change
field_shim_dx_no_ends = setgap_calc_shim_dx(cant_angle, field_shim_dgap_no_ends);

%Plot the measured and required peak fields
setgap_plot_shim_field_db(plt_file, param, z_peak_no_ends, abs_by_peak_no_ends, nom_abs_by_peak_no_ends_ave, field_shim_dbrel_no_ends);

%Plot the required gap changes
setgap_plot_shim_field_dgap(plt_file, param, z_peak_no_ends, field_shim_dgap_no_ends, field_shim_dx_no_ends);

%Phase -----

%Extract the phase error relative to the nominal radiation wave
phaserr_peak_no_ends = rad.phase_nom_error_peak_no_ends;
z_peak_no_ends = rad.z_peak_no_ends;

%Fit the phase error and calculate the derivative
[phaserr_fit_peak_no_ends, dphaserr_dz_fit_peak_no_ends] = setgap_calc_shim_phaserr_deriv(z_peak_no_ends, phaserr_peak_no_ends);

%The required phase change is the negative of the phase error
phasechange_peak_no_ends = - phaserr_peak_no_ends;
phasechange_fit_peak_no_ends = - phaserr_fit_peak_no_ends;
dphasechange_dz_fit_peak_no_ends = - dphaserr_dz_fit_peak_no_ends;

%Use the slope of the fitted phase change to determine required relative field changes
phaserr_shim_dbrel_no_ends = setgap_calc_shim_phaserr_dbrel(nom_k_value, nom_lambda_u, dphasechange_dz_fit_peak_no_ends);

%Calculate the gap changes required to give the relative field changes
phaserr_shim_dgap_no_ends = setgap_calc_shim_relfield_dgap(nom_gap, nom_lambda_u, phaserr_shim_dbrel_no_ends);

%Calculate the shim motion required to get the gap change
phaserr_shim_dx_no_ends = setgap_calc_shim_dx(cant_angle, phaserr_shim_dgap_no_ends);

%Plot the required phase change and phase change slope
setgap_plot_shim_phaserr(plt_file, param, z_peak_no_ends, phasechange_peak_no_ends, phasechange_fit_peak_no_ends, dphasechange_dz_fit_peak_no_ends);

%Plot the required gap changes
setgap_plot_shim_phaserr_dgap(plt_file, param, z_peak_no_ends, phaserr_shim_dgap_no_ends, phaserr_shim_dx_no_ends);

%Results -----

%Calculate the lcls specific shim information required to set the gap
[setgap_shim_num, setgap_mag_num, setgap_shim_dgap, setgap_shim_dx] = setgap_calc_shim_lcls_pos(dat_file, param, phaserr_shim_dgap_no_ends, phaserr_shim_dx_no_ends);

%Write the results to the data file
setgap_dat_shim_lcls_pos(dat_file, setgap_shim_num, setgap_mag_num, setgap_shim_dgap, setgap_shim_dx);

%Calculate required shim replacements
[setgap_shim_replace, setgap_shim_dgap_after_replace] = setgap_calc_shim_replace(shim_param, setgap_shim_dgap);

%Calculate the shim motion required to get the gap change after the replacement
setgap_shim_dx_after_replace = setgap_calc_shim_dx(cant_angle, setgap_shim_dgap_after_replace);

%Write shim replacements to the data file
setgap_dat_shim_replace_lcls_pos(dat_file, setgap_shim_num, setgap_mag_num, setgap_shim_dgap, setgap_shim_replace, setgap_shim_dgap_after_replace, setgap_shim_dx_after_replace);

%Save the results
setgap_shim.z_peak_no_ends = z_peak_no_ends;
setgap_shim.dbrel_no_ends = phaserr_shim_dbrel_no_ends;
setgap_shim.dgap_no_ends = phaserr_shim_dgap_no_ends;
setgap_shim.dx_no_ends = phaserr_shim_dx_no_ends;

%Done
