
function [ResultStruct] = HarmonicityFrequency(dataAccCut_filt,P,F, StrideFrequency,dF,LowFrequentPowerThresholds,N_Harm,FS,AccVectorLen,ResultStruct)

%LD 15-04-2021: Solve problem finding fundamental frequency in power
%spectral density STRIDE - VS STEP frequency. 

% Add sum of power spectra (as a rotation-invariant spectrum)
P = [P,sum(P,2)];
PS = sqrt(P);

% Calculate the measures for the power per separate dimension
for i=1:size(P,2);
    % Relative cumulative power and frequencies that correspond to these cumulative powers
    
    PCumRel = cumsum(P(:,i))/sum(P(:,i));
    PSCumRel = cumsum(PS(:,i))/sum(PS(:,i));
    FCumRel = F+0.5*dF;
    
    % Derive relative cumulative power for threshold frequencies
    Nfreqs = size(LowFrequentPowerThresholds,2);
    LowFrequentPercentage(i,1:Nfreqs) = interp1(FCumRel,PCumRel,LowFrequentPowerThresholds)*100;
    
    % Calculate relative power of first 10 harmonics, taking the power of each harmonic with a band of + and - 10% of the first
    % harmonic around it
    PHarm = zeros(N_Harm,1);
    PSHarm = zeros(N_Harm,1);
    for Harm = 1:N_Harm,
        FHarmRange = (Harm+[-0.1 0.1])*(StrideFrequency); % In  view  of  possible  drift, which  could  lead  to  missing  or  widening  peaks,  the power  spectral  density  of  each  peak  was  calculated within  the  frequency  bands  of +0.1  and −0.1  Hz  of the  peak  frequency  value. 
        PHarm(Harm) = diff(interp1(FCumRel,PCumRel,FHarmRange));
        PSHarm(Harm) = diff(interp1(FCumRel,PSCumRel,FHarmRange));
    end
    
    % Derive index of harmonicity; which is the spectral power of the basic harmonic divided by the sum of the power of first six harmonics
    if i == 2 % for ML we expect odd instead of even harmonics
        IndexHarmonicity(i) = PHarm(1)/sum(PHarm(1:2:12));
    elseif i == 4
        IndexHarmonicity(i) = sum(PHarm(1:2))/sum(PHarm(1:12));
    else
        IndexHarmonicity(i) = PHarm(2)/sum(PHarm(2:2:12));
    end
    
    % Calculate the phase speed fluctuations
    StrideFreqFluctuation = nan(N_Harm,1);
    StrSamples = round(FS/StrideFrequency);
    for h=1:N_Harm,
        CutOffs = [StrideFrequency*(h-(1/3)) , StrideFrequency*(h+(1/3))]/(FS/2);
        if all(CutOffs<1) % for Stride frequencies above FS/20/2, the highest harmonics are not represented in the power spectrum
            [b,a] = butter(2,CutOffs);
            if i==4 % Take the vector length as a rotation-invariant signal
                AccFilt = filtfilt(b,a,AccVectorLen);
            else
                AccFilt = filtfilt(b,a,dataAccCut_filt(:,i));
            end
            Phase = unwrap(angle(hilbert(AccFilt)));
            SmoothPhase = sgolayfilt(Phase,1,2*(floor(FS/StrideFrequency/2))+1); % This is in fact identical to a boxcar filter with linear extrapolation at the edges
            StrideFreqFluctuation(h) = std(Phase(1+StrSamples:end,1)-Phase(1:end-StrSamples,1));
        end
    end
    FrequencyVariability(i) = nansum(StrideFreqFluctuation./(1:N_Harm)'.*PHarm)/nansum(PHarm);
    
    if i<4,
        % Derive harmonic ratio (two variants) --> Ratio of the even and
        % odd harmonics!
        if i == 2 % for ML we expect odd instead of even harmonics
            HarmonicRatio(i) = sum(PSHarm(1:2:end-1))/sum(PSHarm(2:2:end)); % relative to summed 3d spectrum
            HarmonicRatioP(i) = sum(PHarm(1:2:end-1))/sum(PHarm(2:2:end)); % relative to own spectrum
        else
            HarmonicRatio(i) = sum(PSHarm(2:2:end))/sum(PSHarm(1:2:end-1));
            HarmonicRatioP(i) = sum(PHarm(2:2:end))/sum(PHarm(1:2:end-1));
        end
    end
    
end

    ResultStruct.IndexHarmonicity_V = IndexHarmonicity(1); % higher smoother more regular patter
    ResultStruct.IndexHarmonicity_ML = IndexHarmonicity(2); % higher smoother more regular patter
    ResultStruct.IndexHarmonicity_AP = IndexHarmonicity(3); % higher smoother more regular patter
    ResultStruct.HarmonicRatio_V = HarmonicRatio(1);
    ResultStruct.HarmonicRatio_AP = HarmonicRatio(3);
    ResultStruct.StrideFrequency = StrideFrequency;