function [] = initializeDisturbances(args)
% initializeDisturbances - Initialize the disturbances
%
% Syntax: [] = initializeDisturbances(args)
%
% Inputs:
%    - args -

arguments
    % Global parameter to enable or disable the disturbances
    args.enable logical {mustBeNumericOrLogical} = true
    % Ground Motion - X direction
    args.Dw_x logical {mustBeNumericOrLogical} = true
    % Ground Motion - Y direction
    args.Dw_y logical {mustBeNumericOrLogical} = true
    % Ground Motion - Z direction
    args.Dw_z logical {mustBeNumericOrLogical} = true
    % Translation Stage - X direction
    args.Fdy_x logical {mustBeNumericOrLogical} = true
    % Translation Stage - Z direction
    args.Fdy_z logical {mustBeNumericOrLogical} = true
    % Spindle - X direction
    args.Frz_x logical {mustBeNumericOrLogical} = true
    % Spindle - Y direction
    args.Frz_y logical {mustBeNumericOrLogical} = true
    % Spindle - Z direction
    args.Frz_z logical {mustBeNumericOrLogical} = true
end

% Initialization of random numbers
rng("shuffle");

%% Ground Motion
if args.enable
    % Load the PSD of disturbance
    load('ustation_disturbance_psd.mat', 'gm_dist')

    % Frequency Data
    Dw.f = gm_dist.f;
    Dw.psd_x = gm_dist.pxx_x;
    Dw.psd_y = gm_dist.pxx_y;
    Dw.psd_z = gm_dist.pxx_z;

    % Time data
    Fs = 2*Dw.f(end);      % Sampling Frequency of data is twice the maximum frequency of the PSD vector [Hz]
    N  = 2*length(Dw.f);   % Number of Samples match the one of the wanted PSD
    T0 = N/Fs;             % Signal Duration [s]
    Dw.t = linspace(0, T0, N+1)'; % Time Vector [s]

    % ASD representation of the ground motion
    C = zeros(N/2,1);
    for i = 1:N/2
        C(i) = sqrt(Dw.psd_x(i)/T0);
    end

    if args.Dw_x
        theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
        Cx = [0 ; C.*complex(cos(theta),sin(theta))];
        Cx = [Cx; flipud(conj(Cx(2:end)))];;
        Dw.x = N/sqrt(2)*ifft(Cx); % Ground Motion - x direction [m]
    else
        Dw.x = zeros(length(Dw.t), 1);
    end

    if args.Dw_y
        theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
        Cx = [0 ; C.*complex(cos(theta),sin(theta))];
        Cx = [Cx; flipud(conj(Cx(2:end)))];;
        Dw.y = N/sqrt(2)*ifft(Cx); % Ground Motion - y direction [m]
    else
        Dw.y = zeros(length(Dw.t), 1);
    end

    if args.Dw_y
        theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
        Cx = [0 ; C.*complex(cos(theta),sin(theta))];
        Cx = [Cx; flipud(conj(Cx(2:end)))];;
        Dw.z = N/sqrt(2)*ifft(Cx); % Ground Motion - z direction [m]
    else
        Dw.z = zeros(length(Dw.t), 1);
    end

else
    Dw.t = [0,1]; % Time Vector [s]
    Dw.x = [0,0]; % Ground Motion - X [m]
    Dw.y = [0,0]; % Ground Motion - Y [m]
    Dw.z = [0,0]; % Ground Motion - Z [m]
end

%% Translation stage
if args.enable
    % Load the PSD of disturbance
    load('ustation_disturbance_psd.mat', 'dy_dist')

    % Frequency Data
    Dy.f = dy_dist.f;
    Dy.psd_x = dy_dist.pxx_fx;
    Dy.psd_z = dy_dist.pxx_fz;

    % Time data
    Fs = 2*Dy.f(end);      % Sampling Frequency of data is twice the maximum frequency of the PSD vector [Hz]
    N  = 2*length(Dy.f);   % Number of Samples match the one of the wanted PSD
    T0 = N/Fs;             % Signal Duration [s]
    Dy.t = linspace(0, T0, N+1)'; % Time Vector [s]

    % ASD representation of the disturbance voice
    C = zeros(N/2,1);
    for i = 1:N/2
        C(i) = sqrt(Dy.psd_x(i)/T0);
    end

    if args.Fdy_x
        theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
        Cx = [0 ; C.*complex(cos(theta),sin(theta))];
        Cx = [Cx; flipud(conj(Cx(2:end)))];;
        Dy.x = N/sqrt(2)*ifft(Cx); % Translation stage disturbances - X direction [N]
    else
        Dy.x = zeros(length(Dy.t), 1);
    end

    if args.Fdy_z
        theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
        Cx = [0 ; C.*complex(cos(theta),sin(theta))];
        Cx = [Cx; flipud(conj(Cx(2:end)))];;
        Dy.z = N/sqrt(2)*ifft(Cx); % Translation stage disturbances - Z direction [N]
    else
        Dy.z = zeros(length(Dy.t), 1);
    end

else
    Dy.t = [0,1]; % Time Vector [s]
    Dy.x = [0,0]; % Translation Stage disturbances - X [N]
    Dy.z = [0,0]; % Translation Stage disturbances - Z [N]
end

%% Spindle
if args.enable
    % Load the PSD of disturbance
    load('ustation_disturbance_psd.mat', 'rz_dist')

    % Frequency Data
    Rz.f = rz_dist.f;
    Rz.psd_x = rz_dist.pxx_fx;
    Rz.psd_y = rz_dist.pxx_fy;
    Rz.psd_z = rz_dist.pxx_fz;

    % Time data
    Fs = 2*Rz.f(end);      % Sampling Frequency of data is twice the maximum frequency of the PSD vector [Hz]
    N  = 2*length(Rz.f);   % Number of Samples match the one of the wanted PSD
    T0 = N/Fs;             % Signal Duration [s]
    Rz.t = linspace(0, T0, N+1)'; % Time Vector [s]

    % ASD representation of the disturbance voice
    C = zeros(N/2,1);
    for i = 1:N/2
        C(i) = sqrt(Rz.psd_x(i)/T0);
    end

    if args.Frz_x
        theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
        Cx = [0 ; C.*complex(cos(theta),sin(theta))];
        Cx = [Cx; flipud(conj(Cx(2:end)))];;
        Rz.x = N/sqrt(2)*ifft(Cx); % spindle disturbances - X direction [N]
    else
        Rz.x = zeros(length(Rz.t), 1);
    end

    if args.Frz_y
        theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
        Cx = [0 ; C.*complex(cos(theta),sin(theta))];
        Cx = [Cx; flipud(conj(Cx(2:end)))];;
        Rz.y = N/sqrt(2)*ifft(Cx); % spindle disturbances - Y direction [N]
    else
        Rz.y = zeros(length(Rz.t), 1);
    end

    if args.Frz_z
        theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
        Cx = [0 ; C.*complex(cos(theta),sin(theta))];
        Cx = [Cx; flipud(conj(Cx(2:end)))];;
        Rz.z = N/sqrt(2)*ifft(Cx); % spindle disturbances - Z direction [N]
    else
        Rz.z = zeros(length(Rz.t), 1);
    end

else
    Rz.t = [0,1]; % Time Vector [s]
    Rz.x = [0,0]; % Spindle disturbances - X [N]
    Rz.y = [0,0]; % Spindle disturbances - X [N]
    Rz.z = [0,0]; % Spindle disturbances - Z [N]
end

u = zeros(100, 6);
Fd = u;

Dw.x   = Dw.x   - Dw.x(1);
Dw.y   = Dw.y   - Dw.y(1);
Dw.z   = Dw.z   - Dw.z(1);

Dy.x   = Dy.x   - Dy.x(1);
Dy.z   = Dy.z   - Dy.z(1);

Rz.x   = Rz.x   - Rz.x(1);
Rz.y   = Rz.y   - Rz.y(1);
Rz.z   = Rz.z   - Rz.z(1);

if exist('./mat', 'dir')
    save('mat/nass_model_disturbances.mat', 'Dw', 'Dy', 'Rz', 'Fd', 'args');
elseif exist('./matlab', 'dir')
    save('matlab/mat/nass_model_disturbances.mat', 'Dw', 'Dy', 'Rz', 'Fd', 'args');
end
