%**************************************************************************
%This function determines the shims required to maintain the proper phase
%relation between the light and the electrons in the body of the undulator.
%
%Input:
%dat_file, data file
%plt_file, plot file
%param, parameter structure
%shim_param, shim parameter structure
%field, magnetic field structure
%traj, trajectory structure
%rad, structure containing radiation information
%
%Output:
%seg_phaserr, structure containing the segmented phase error information
%   num_seg             %Number of segments
%   z_start             %Z position of the start of each segment
%   z_end               %Z position of the end of each segment
%   phaserr_slope_orig  %Phase error slope of the segment before shimming
%   phaserr_start_orig  %Phase error at the start of the segment before shimming
%   phaserr_end_orig    %Phase error at the end of the segment before shimming
%   gap_shim_num        %Gap shim number, gap shims can extend over several segments
%   gap_shim_slope      %Gap shim at each segment, effect on slope
%   gap_shim_dbrel      %Gap shim at each segment, delta B / B
%   phase_shim_delta    %Phase shim at each segment, change in phase
%   phase_shim_dbrel    %Phase shim at each segment, delta B / B
%   phaserr_slope_shimmed  %Phase error slope of the segment after shimming
%   phaserr_start_shimmed  %Phase error at the start of the segment after shimming
%   phaserr_end_shimmed    %Phase error at the end of the segment after shimming
%
%phaserr_shim, structure containing the shim information
%   num_gap_shim        %Number of gap shims
%   gap_shim_z_start    %Z position the gap shim starts at
%   gap_shim_z_end      %Z position the gap shim ends at
%   gap_shim_pole_start %Pole number the gap shim starts at
%   gap_shim_pole_end   %Pole number the gap shim ends at
%   gap_shim_slope      %Phase error slope change from the gap shim
%   gap_shim_dbrel      %Fractional field change from the gap shim
%   gap_shim_dim        %Gap size change from the shim
%   num_phase_shim      %Number of phase shims
%   phase_shim_z        %Z position of the phase shim
%   phase_shim_pole_start  %Pole number the phase shim starts at
%   phase_shim_pole_end %Pole number the phase shim ends at
%   phase_shim_delta    %Phase error change from the phase shim
%   phase_shim_dbrel    %Fractional field change from the phase shim
%   phase_shim_dim      %Dimension of the phase shim
%
%Zachary Wolf
%12/28/05

function [seg_phaserr, phaserr_shim] = pid_shim_phaserr(dat_file, plt_file, param, shim_param, field, traj, rad)

%Parameters
phaserr_num_seg = shim_param.phaserr_num_seg;

%Extract the required phase error information
z_peak_no_ends = rad.z_peak_no_ends;
phase_error_peak_no_ends = rad.phase_error_peak_no_ends;

%Fix a problem
%If the phase error at the beginning of the undulator is negative, there is
%no way to suddenly increase it.  We must shim the undulator to that
%constant phase error.
phase_error_peak_no_ends = phase_error_peak_no_ends - mean(phase_error_peak_no_ends(1 : 4));

%Plot the phase error at each pole
pole_num_no_ends = [param.num_end_poles + 1 : param.num_poles - param.num_end_poles];
phaserr_shim_plot_phaserr(plt_file, param, pole_num_no_ends, phase_error_peak_no_ends);

%Divide the phase error into segments and fit a line to each segment
seg_phaserr = phaserr_shim_seg_phaserr_init(phaserr_num_seg, z_peak_no_ends, phase_error_peak_no_ends);

%Plot the segmented phase errors and compare to the original
phaserr_shim_plot_seg_phaserr(plt_file, param, z_peak_no_ends, phase_error_peak_no_ends, seg_phaserr);

%First pass, use phase shims to correct positive phase error changes -----

%Use phase shims to remove positive phaserr excursions
seg_phaserr = phaserr_shim_calc_phaserr_shim_pos_delta(shim_param, seg_phaserr);

%Calculate the magnetic field effect of each shim
seg_phaserr = phaserr_shim_calc_phaserr_shim_dbrel(param, seg_phaserr);

%Plot the original and shimmed segmented phase errors
phaserr_shim_plot_phaserr_orig_shim(plt_file, param, seg_phaserr);

%Second pass, use gap shims to correct negative phase error changes -----

%Use gap shims to remove negative phaserr excursions
seg_phaserr = phaserr_shim_calc_phaserr_shim_neg_delta(shim_param, seg_phaserr);

%Calculate the magnetic field effect of each shim
seg_phaserr = phaserr_shim_calc_phaserr_shim_dbrel(param, seg_phaserr);

%Plot the original and shimmed segmented phase errors
phaserr_shim_plot_phaserr_orig_shim(plt_file, param, seg_phaserr);

%Third pass, distribute large shims, combine small shims -----

%Distribute/combine shims
seg_phaserr = phaserr_shim_calc_phaserr_shim_dist(shim_param.phaserr_phase_shim_par, seg_phaserr);

%Calculate the magnetic field effect of each shim
seg_phaserr = phaserr_shim_calc_phaserr_shim_dbrel(param, seg_phaserr);

%Plot the shim strengths
phaserr_shim_plot_phaserr_shim(plt_file, param, seg_phaserr);

%Locate shims and determine their dimensions -----

%Locate the shims explicitly
phaserr_shim = phaserr_shim_calc_phaserr_shim_loc(field.z_peak, seg_phaserr);

%Adjust the phase shim position to mininize phase errors
phaserr_shim = phaserr_shim_calc_phase_shim_loc_adj(pole_num_no_ends, z_peak_no_ends, phase_error_peak_no_ends, phaserr_shim);

%Determine the shim dimensions
phaserr_shim.gap_shim_dim = phaserr_shim_calc_gap_shim_dim(param, shim_param, phaserr_shim.num_gap_shim, phaserr_shim.gap_shim_dbrel);
phaserr_shim.phase_shim_dim = phaserr_shim_calc_phase_shim_dim(shim_param, phaserr_shim.num_phase_shim, phaserr_shim.phase_shim_delta);

%Results -----

%Write a table of required shims to the data file
phaserr_shim_dat_phaserr_shim(dat_file, shim_param, phaserr_shim);

%Done
