%**************************************************************************
%This function finds the zero field positions.
%
%Input:
%z, position the field was measured at (m)
%b, measured field strength (T)
%
%Output:
%z_zero, fitted z position of each field zero (m)
%
%Zack Wolf  10/17/06, 11/3/10

function [z_zero] = halln_field_find_zeros(z, b)

%Local parameter
B_THRESH = .02;  %200 Gauss default
%B_THRESH = .1;  %1000 Gauss
NUM_MAX_CHECK_SIDE = 10;  %Default
%NUM_MAX_CHECK_SIDE = 50;
NUM_FIT_PTS_ONE_SIDE = 8;  %Default
%NUM_FIT_PTS_ONE_SIDE = 50;

%Print a warning if parameter values are changed
%warndlg('field_find_zeros: parameter values are changed');
  
%Check
if length(z) ~= length(b)
    msgbox('field_find_zeros: z and b have different lengths', 'Error');
    return;
end
if length(z) < 10 || length(b) < 10
    msgbox('field_find_zeros: problem with array sizes', 'Error');
    return;
end

%Initial if no zeros
z_zero = 0;
index_meas_peak(1) = 0;
    
%Loop through the measured field values looking for peaks
num_peaks = 0;
b_abs = abs(b);
for ii = NUM_MAX_CHECK_SIDE + 1 : 1 : length(b) - NUM_MAX_CHECK_SIDE
    if (b_abs(ii) > B_THRESH) ...
        & (b_abs(ii) >= max(b_abs(ii - NUM_MAX_CHECK_SIDE : ii - 1))) & (b_abs(ii) > max(b_abs(ii + 1 : ii + NUM_MAX_CHECK_SIDE))) 
            num_peaks = num_peaks + 1;
            index_meas_peak(num_peaks) = ii;
    end     
end

%Check
if index_meas_peak(1) == 0
    return;
end
    
%Loop through the measured field values looking for minima
num_min = 0;
b_abs = abs(b);
for ii=index_meas_peak(1) : 1 : index_meas_peak(end)
    if b_abs(ii) <= min(b_abs(ii - NUM_MAX_CHECK_SIDE : ii - 1)) & b_abs(ii) < min(b_abs(ii + 1 : ii + NUM_MAX_CHECK_SIDE))
            num_min = num_min + 1;
            index_meas_min(num_min) = ii;
    end     
end

%Turn off a warning
warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');
    
%Loop through the zeros
for ii=1:1:length(index_meas_min)
    
    %Fill arrays for fit
    index = 0;
    for jj = -NUM_FIT_PTS_ONE_SIDE:1:NUM_FIT_PTS_ONE_SIDE
        index = index + 1;
        z_for_fit(index) = z(index_meas_min(ii) + jj);
        b_for_fit(index) = b(index_meas_min(ii) + jj);
    end
    
    %Fit the points with a line
    p1 = polyfit(z_for_fit, b_for_fit, 1);
    
    %Find z_zero
    z_zero(ii) = - p1(2) / p1(1);
    
    %Check
    if z_zero(ii) <= z_for_fit(1) | z_zero(ii) >= z_for_fit(end)
        msgbox('idanal_find_field_zeros: problem with a zero', 'Error');
        %Debug
        plot(z_for_fit, b_for_fit, '-*');
        z_zero(ii) = z(index_meas_min(ii));
    end
end
   
%Done
