%**************************************************************************
%Planar Insertion Device Shimming
%
%This program calculates the shims required to correct an insertion device.
%Both of the transverse trajectories are corrected, then the phase is
%corrected.
%
%The program uses the convention that z is along the insertion device, y is
%in the main magnetic field direction, and x is in the nominally field free
%direction.  xyz make a right handed coordinate system.
%
%The planar ID analysis must be run before this program can be run.
%
%Input -----
%
%The following structures are imported:
%
%param, structure containing required program parameters
%	input_file_dir      %Input file directory
%   input_file_name     %Input file name
%   input_file_type     %Input file type, gives file format
%   corr_required       %Logical variable, apply a correction to the measured fields, true or false
%   corr_bx_mult        %Multiplicative correction factor for Bx
%   corr_by_mult        %Multiplicative correction factor for By
%   corr_bx_add         %Additive constant correction for Bx (T)
%   corr_by_add         %Additive constant correction for By (T)
%   corr_bxy_add_file   %Correction file name including directory, additive for Bx and By, 'none' for no correction
%   corr_bxy_add_file_type  %Correction file type, gives format
%   gamma               %Lorentz factor
%   nom_lambda_u        %Nominal undulator period (m)
%   nom_k_value         %Nominal undulator K parameter value
%   nom_lambda_r        %Nominal radiation wavelength (m)
%   num_poles           %Number of poles in the undulator
%   num_end_poles       %Number of poles used to determine end effects
%   cell_length         %Cell length, undulator length plus drift length at each end
%   nom_phase_cell      %Nominal phase change through the cell (rad)
%   nom_phase_match     %Nominal phase from the cell boundary to the first pole after the end poles (rad)
%   save_as_final_result%Save output as a final result, true or false
%   result_file_dir     %Directory where final results are saved
%   result_file_name    %Name of file for final result
%   fig_close_on_exit   %Close figures when program exits, true or false
%   fig_vis             %Figures visible on screen, true or false
%
%header, cell array containing the header of the data file
%
%field, structure containing magnetic field information
%   zm                  %Z positions at which the field measurements are made (m)
%   z                   %Translated Z, with z=0 at undulator center (m)
%   bx                  %Measured horizontal field (T)
%   by                  %Measured vertical field (T)
%   z_peak              %Z positions of the By peak fields (m)
%   by_peak             %Fitted By peak values (T)
%   z_zero              %Z positions of the By zero points (m)
%   lambda_u            %Measured average undulator period (m)
%   int_bx_dz           %First integral of Bx (Tm)
%   int_by_dz           %First integral of By (Tm)
%   int_int_bx_dz_dz    %Second integral of Bx (Tm^2)
%   int_int_by_dz_dz    %Second integral of By (Tm^2)
%   bx_filt             %Filtered measured horizontal field (T)
%   by_filt             %Filtered measured vertical field (T)
%   int_bx_dz_filt      %Filtered first integral of Bx (Tm)
%   int_by_dz_filt      %Filtered first integral of By (Tm)
%   int_int_bx_dz_dz_filt  %Filtered second integral of Bx (Tm^2)
%   int_int_by_dz_dz_filt  %Filtered second integral of By (Tm^2)
%   temp                %Average undulator temperature (C)
%
%traj, structure containing trajectory information
%   z                   %Translated Z, with z=0 at undulator center (m)
%   x                   %Trajectory x position (m)
%   x_p                 %First derivative dx/dz
%   x_pp                %Second derivative d(dx/dz)/dz (m^-1)
%   y                   %Trajectory y position (m)
%   y_p                 %First derivative dy/dz
%   y_pp                %Second derivative d(dy/dz)/dz (m^-1)
%   x_filt              %Filtered trajectory x position (m)
%   x_p_filt            %Filtered first derivative dx/dz
%   x_pp_filt           %Filtered second derivative d(dx/dz)/dz (m^-1)
%   y_filt              %Filtered trajectory y position (m)
%   y_p_filt            %Filtered first derivative dy/dz
%   y_pp_filt           %Filtered second derivative d(dy/dz)/dz (m^-1)
%   x_slope_cor         %X trajectory minus linear fit
%   x_p_slope_cor       %X trajectory slope minus linear fit slope
%   y_slope_cor         %Y trajectory minus linear fit
%   y_p_slope_cor       %Y trajectory slope minus linear fit slope
%
%rad, structure containing radiation information
%	z                   %Translated Z, from traj structure (m)
%	z_peak              %z at the field peaks (m)
%	z_peak_no_ends      %z at the field peaks excluding the ends (m)
%   lambda_u            %Measured average undulator period (m)
%	slip                %Slippage, slip = 0 at z = 0 (m)
%	slip_peak           %Slippage at the field peaks (m)
%	slip_peak_no_ends	%Slippage at the field peaks excluding the ends (m)
%	slope               %Slope of the slip_peak vs z_peak (no ends) linear fit
%	slip_norm           %Normalized slippage, slip_norm = 0 at z = 0 (m)
%	slip_norm_peak      %Normalized slippage at the field peaks (m)
%	slip_norm_peak_no_ends	%Normalized slippage at the field peaks excluding the ends (m)
%	slope_norm          %Slope of the slip_norm_peak vs z_peak (no ends) linear fit
%	k_eff               %K value for undulator
%	b_eff               %Effective field strength in undulator (T)
%	lambda_r            %Radiation wavelength (m)
%	phase               %Phase, phase = 0 at cell boundary (rad)
%	phase_peak          %Phase at the field peaks (rad)
%	phase_peak_no_ends	%Phase at the field peaks excluding the ends (rad)
%	phase_error_peak_no_ends	%Phase errors, error at first pole after end defines zero error (rad)
%	phase_cell          %Total phase change between the light and the electrons in the cell (rad)
%	phase_nom           %Phase relative to nominal radiation wave, phase = 0 at cell boundary (rad)
%	phase_nom_peak      %Phase relative to nominal radiation wave at the field peaks (rad)
%	phase_nom_peak_no_ends  %Phase relative to nominal radiation wave at the field peaks excluding the ends (rad)
%	phase_nom_error_peak_no_ends  %Phase errors relative to nominal radiation wave, error at first pole after end defines zero error (rad)
%	phase_nom_cell      %Total phase change between the nominal radiation wave and the electrons in the cell (rad)
%
%Shim characteristics (dimensions, etc.) required to perform the shimming
%are input to the program.  Many quantities are determined experimentally.
%This information is put into the shim_param structure.
%
%shim_param, structure containing shim parameters
%	input_file_dir      %Input file directory
%   input_file_name     %Input file name
%   traj_num_seg        %Number of segments in the segmented trajectory
%   traj_shift_max      %Max trajectory shift when a shim is moved
%   traj_shift_accum_max  %Max trajectory shift accumulation before a shim is placed
%   x_traj_shim_par     %X trajectory shim parameters, determined experimentally
%   y_traj_shim_par     %Y trajectory shim parameters, determined experimentally
%   phaserr_num_seg     %Number of segments in the segmented phase error
%   phaserr_pos_delta_max  %Max positive phase error change before a shim is added
%   phaserr_neg_delta_max  %Max negative phase error change before a shim is added
%   phaserr_gap_shim_width %Effective width of a gap shim (m)
%   phaserr_gap_shim_nom_gap %Nominal undulator gap, used in shim calculations (m)
%   phaserr_gap_shim_corr_fact %Multiplicative correction to the gap change accounting for actual shape
%   phaserr_phase_shim_par   %Phase error phase shim parameters, determined experimentally
%   k_shim_cant_angle   %Undulator pole cant angle (rad)
%
%Computed quantities -----
%
%Set Gap Shims
%The program uses the phase relative to a reference wave to do the
%caluclations.  It computes the gap changes required to make the phase
%error go to zero.
%
%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
%
%Trajectory Shims
%The program makes a segmented approximation to the trajectory.  The
%following structure is used to contain the segment information.
%
%seg_traj, structure containing the segmented trajectory information
%   x_seg               %structure containing the x segmented trajectory
%   y_seg               %structure containing the y segmented trajectory
%x_seg, y_seg
%   traj_name           %'X' or 'Y'
%   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
%   traj_slope_orig     %Trajectory slope of the segment of the original trajectory
%   traj_start_orig     %Trajectory position at the start of the segment of the original trajectory
%   traj_end_orig       %Trajectory position at the end of the segment of the original trajectory
%   shim_slope          %Shim at each segment, effect on slope
%   shim_bl             %Shim at each segment, integrated field strength
%   traj_slope_shimmed  %Trajectory slope of the segment after shimming
%   traj_start_shimmed  %Trajectory position at the start of the segment after shimming
%   traj_end_shimmed    %Trajectory position at the end of the segment after shimming
%
%The program calculates shim strengths and positions.  This information is
%put into the traj_shim structure.
%
%traj_shim, structure containing the trajectory shim information
%   x_shim              %Structure containing the x trajectory shim information
%   y_shim              %Structure containing the y trajectory shim information
%x_shim, structure containing the x-trajectory shim information
%   num_shim            %Number of shims
%   pole_num            %Pole number to place the shim
%   pole_z_pos          %z position of the pole
%   pole_by_sign        %Sign of the field in the gap at the pole_num location
%   shim_slope          %Shim effect on trajectory slope
%   shim_bl             %Shim integrated field strength
%   shim_type           %Shim type (types given in parameter file)
%   shim_dim            %Shim physical dimension
%   shim_d_dim          %Shim physical dimension change for pre-existing shims
%y_shim, structure containing the y-trajectory shim information (The shim uses two poles.)
%   num_shim            %Number of shims
%   pole_1_num          %Pole number of upstream pole in shim
%   pole_2_num          %Pole number of downstream pole in shim
%   pole_1_z_pos        %Z position of upstream pole in shim
%   pole_2_z_pos        %Z position of downstream pole in shim
%   pole_1_by_sign      %Sign of the field at the upstream pole
%   pole_2_by_sign      %Sign of the field at the downstream pole
%   pole_1_loc          %Location of shim on upstream pole, +1 upper, -1 lower
%   pole_2_loc          %Location of shim on downstream pole, +1 upper, -1 lower
%   shim_slope          %Shim effect on trajectory slope
%   shim_bl             %Shim integrated field strength
%   shim_type           %Shim type
%   shim_dim            %Shim physical dimension
%   shim_d_dim          %Shim physical dimension change for pre-existing shims
%
%Phase Error Shims
%Shims are required to keep the light and the electrons in phase in the
%body of the undulator.  This is done with phase error shims.  The phase
%error is segmented as an aid in computing the shim values.
%
%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
%
%K Adjustment Shims
%Adjustments are needed to get the proper K value.  They are in the
%following structure.
%
%k_shim, structure containing shim information to get the proper K value
%   dbrel               %Required dB / B to get the proper K value
%   dgap                %Required gap change (m)
%   dxbeam              %Change in x of the beam required to give the proper K value
%
%Phase Matching Shims
%The phase of an existing light beam must be matched to the phase of the
%electron motion in the undulator.  This is done with phase matching shims.
%
%phasematch_shim, structure containing the phase matching shim information
%   expect_phase_poles  %expected phases on the poles based on the phase match phase
%   expect_phase_cell   %expected phase of the cell based on the pahse match phase
%   phase_err_enter     %phase errors on the poles entering the undulator (rad)
%   phase_err_exit      %phase errors on the poles leaving the undulator (rad)
%   des_phase_change_enter  %desired phase change from the shim at the entrance (rad)
%   des_phase_change_exit   %desired phase change from the shim at the exit (rad)
%   shim_dim_enter      %size of the shim required to give the phase change at the entrance (m)
%   shim_dim_exit       %size of the shim required to give the phase change at the exit (m)
%
%Zachary Wolf, 12/28/05, 11/2/06

function [] = pid_shim()

%Set up program parameters using the user interface
%Create the updated p_id_shim_param.m file which is run to set the parameter values
%pid_shim_ui;

%Clear the workspace
clear

%Initialize global physical constants used throughout the program
global Q_ELEC M_ELEC C_LIGHT;
Q_ELEC = -1.60217733e-19;    %Electron charge (C)
M_ELEC = 9.1093897e-31;      %Electron mass (kg)
C_LIGHT = 2.99792458e8;      %Speed of light (m/s)

%Get the shim program parameters
[shim_param] = pid_shim_get_param();

%Input the analysis results
anal_file = [shim_param.input_file_dir, shim_param.input_file_name];
load(anal_file, 'param', 'header', 'field', 'traj', 'rad');

%Open output files, write headers
[dat_file, plt_file] = pid_shim_init(param, shim_param, header);

%Perfrom the analysis to set the undulator gap
[setgap_shim] = pid_shim_setgap(dat_file, plt_file, param, shim_param, field, rad);

%Perform the trajectory shim analysis
[seg_traj, traj_shim] = pid_shim_traj(dat_file, plt_file, param, shim_param, field, traj);

%Model the shimmed trajectory
pid_shim_model_traj(plt_file, param, field, traj_shim);

%Perform the phase error shim analysis
[seg_phaserr, phaserr_shim] = pid_shim_phaserr(dat_file, plt_file, param, shim_param, field, traj, rad);

%Model the phase errors after shimming
pid_shim_model_phaserr(plt_file, param, field, phaserr_shim);

%Perform the K value shim analysis
[k_shim] = pid_shim_k(dat_file, plt_file, param, shim_param, field, traj, rad);

%Perform the phase matching shim analysis
[phasematch_shim] = pid_shim_phasematch(dat_file, plt_file, param, shim_param, field, traj, rad);

%Output the results to the measurement input file directory
mat_file = strcat(param.input_file_dir, 'pid_shim.mat');
save(mat_file, 'setgap_shim', 'seg_traj', 'traj_shim', 'seg_phaserr', 'phaserr_shim', 'k_shim', 'phasematch_shim');

%Remove all figures, if desired
if param.fig_vis == false
    close('all','hidden');
else
    if param.fig_close_on_exit == true
        close('all','hidden');
    end
end

%Done
