%**************************************************************************
%gen_bxvsz
%
%This function generates the small error field in an undulator.
%The convention is that the field is in the X direction, the beam is moving in
%the Z direction, and the trajectory is in the Y direction.
%The data is generated for the beam axis with X = 0 and Y = 0.
%The point Z = 0 is at the undulator midpoint.
%The output is written to a file.
%
%Zachary Wolf  7/31/03, 1/3/06, 2/19/07

%Clear the workspace
clear;

%Set the working directory
cd 'c:\Analysis\Insertion Device Analysis\Generate Fake Data\';

%Parameters
B0 = 1.249471;                  %Peak field strength on the midplane (T)
LAMBDA_U = .03;                 %Undulator period (m)
NUM_POLE = 226;                 %Number of poles per jaw, even (for these ends)
SAMPLE_SPACING = .000200;       %Distance between magnetic field samples
GAMMA = 26692.70;               %Electron Lorentz factor
DAT_FILE = 'c:\magdata\fake_data\fake_bxvsz.dat';    %Output data file
PAR_FILE = 'c:\magdata\fake_data\fake_bxvsz.par';    %Output parameter file

%Errors
B_ERR_SIN = 0;                  %Switch, sinusoidal field variation through the undulator
B_ERR_EARTH = 1;                %Switch, add constant field to all field values

%Error parameters
B_ERR_SIN_AMP = 0.0001;         %Amplitude of the sinusoidal field variation
B_ERR_SIN_HAR = 1;              %Harmonic number for the sinusoidal field variation
B_ERR_EARTH_VAL = 0.00002;      %Earth's field (T)

%Generate z positions in the undulator starting from the end
z = 0 : SAMPLE_SPACING : NUM_POLE * LAMBDA_U / 2.;

%Generate the ideal Bx
b = zeros(1, length(z));

%Generate a sinusoidal field for the undulator
if B_ERR_SIN ~= 0
    b = b + B_ERR_SIN_AMP * sin(B_ERR_SIN_HAR * pi * z / z(end));
end

%Generate 10 periods of zeros for the ends
z_end = 0 : SAMPLE_SPACING : (30 + 1) * LAMBDA_U / 2.;
b_end = zeros(1, length(z_end));

%Add the ends to the undulator field
z_gen = z_end;
z_gen = [z_gen, z_gen(end)+ SAMPLE_SPACING + z];
z_gen = [z_gen, z_gen(end)+ SAMPLE_SPACING + z_end];
b_gen = [b_end, b, b_end];

%Make z = 0 the center of the undulator
z_meas = z_gen - (z_gen(1) + z_gen(end)) / 2.;
b_meas = b_gen;

%Error, add the Earth's field to all samples
if B_ERR_EARTH ~= 0
    b_meas = b_meas + B_ERR_EARTH_VAL;
end

%Write the data to a file
fid = fopen(DAT_FILE, 'w');
fprintf(fid, 'SLAC Magnetic Measurements\r\n');
fprintf(fid, 'Date: mm-dd-yyyy\r\n');
fprintf(fid, 'Time: hh:mm:ss\r\n');
fprintf(fid, '\r\n');
fprintf(fid, 'Project: Test\r\n');
fprintf(fid, 'Magnet Type: Undulator\r\n');
fprintf(fid, 'Magnet Name: Test\r\n');
fprintf(fid, 'Serial Number:\r\n');
fprintf(fid, 'Run Number: 1\r\n');
fprintf(fid, 'Measurement Device: Hall probe\r\n');
fprintf(fid, 'Operator: zw\r\n');
fprintf(fid, 'Comment: Test\r\n');
fprintf(fid, '\r\n');
fprintf(fid, '     Z           Bx     \r\n');
fprintf(fid, '    (m)          (T)    \r\n');
fprintf(fid, '-----------  -----------\r\n');
fprintf(fid, '%11.6f  %11.6f\r\n', [z_meas; b_meas]);
fclose(fid);

%Write the parameters to a file
fid = fopen(PAR_FILE, 'w');
fprintf(fid, 'SLAC Magnetic Measurements\r\n');
fprintf(fid, 'Simulated data to test undulator analysis software.\r\n');
fprintf(fid, '\r\n');
fprintf(fid, 'Simulated Data Parameters:\r\n');
fprintf(fid, 'B0 = %10.5f T\r\n', B0);
fprintf(fid, 'GAMMA = %10.2f\r\n', GAMMA);
fprintf(fid, 'LAMBDA_U = %10.5f m\r\n', LAMBDA_U);
fprintf(fid, 'NUM_POLE = %5i\r\n', NUM_POLE);
fprintf(fid, 'SAMPLE_SPACING = %10.7f m\r\n', SAMPLE_SPACING);
fprintf(fid, 'N_SAMPLES = %7i\r\n', length(z_meas));
fprintf(fid, 'Magnetic Field Length = %10.6f m\r\n', z(end) - z(1));
fprintf(fid, 'Measurement Length = %10.6f m\r\n', z_meas(end) - z_meas(1));
fprintf(fid, '\r\n');
fprintf(fid, 'Errors:\r\n');
if B_ERR_SIN ~= 0
    fprintf(fid, 'B_ERR_SIN_HAR = %4i\r\n', B_ERR_SIN_HAR);
    fprintf(fid, 'B_ERR_SIN_AMP = %10.6f\r\n', B_ERR_SIN_AMP);
end
if B_ERR_EARTH ~= 0
    fprintf(fid, 'B_ERR_EARTH_VAL = %11.7f T\r\n', B_ERR_EARTH_VAL);
end
fprintf(fid, 'End of error list.\r\n');
fclose(fid);
    
%Done
