function this = processInitializationData(this)
% Set this.QueuedX to be a set of points to evaluate first.
%

%   Copyright 2016-2024 The MathWorks, Inc.

if this.NumObjectiveEvaluations > 0
    % Only process initialization data if not resuming.
    return;
end
Opts = this.PrivOptions;
if isempty(Opts.InitialX)
    % No initial points passed. Choose initial points.
    if isequal(Opts.AcquisitionFunctionName, 'grid')
        % Random grid points
        [X, this] = gridXFeasiblePoint(this);
        XPoints = X;
        while ~isempty(X) && size(XPoints,1) < Opts.NumSeedPoints
            [X, this] = gridXFeasiblePoint(this);
            if ~isempty(X)
                XPoints(end+1, :) = X;
            end
        end
        this.QueuedX = XPoints;
    elseif isequal(Opts.AcquisitionFunctionName, 'asha')
        % Random asha points
        this.QueuedX = randomASHAFeasiblePoints(this, this.PrivOptions.NumSeedPoints);
    elseif ~isempty(Opts.MultiModelSplitVariableName) && ...
            any(strcmp(Opts.ModelType, {'MultiTreeBagger','MultiGaussianProcess'})) && ...
            Opts.NumSeedPoints > 0 && ...
            ~isequal(Opts.AcquisitionFunctionName, 'asha')
        %             any(strcmp(Opts.ModelType, {'MultiTreeBagger','GaussianProcess','MultiGaussianProcess'})) && ...
        % Choose NumSeedPoints random points for each level of the
        % designated categorical variable.
        [tf,catIndex] = ismember(Opts.MultiModelSplitVariableName, this.PrivOptions.VarSpec.Names);
        assert(tf);
        XPoints     = randomXFeasiblePointsForEachCategoricalLevel(this, Opts.NumSeedPoints, catIndex);
        XTable      = untransformPoints(this, XPoints, true);
        idx = randperm(size(XTable,1));
        XTable = XTable(idx,:);
        this.QueuedX = transformPoints(this, XTable);
    else
        % Random initial points
        this.QueuedX = initialXFeasiblePoints(this, this.PrivOptions.NumSeedPoints);
    end
else
    % InitialX was passed.
    anyOOB = any(isPointOutOfBounds(this, this.PrivOptions.InitialX));
    % Check asha points are in bounds
    if isequal(Opts.AcquisitionFunctionName, 'asha') && anyOOB
        bayesoptim.err('ASHA_InitialX_OOB');
    end
    if anyOOB
        bayesoptim.warn('InitialX_OOB')
    end
    if isempty(Opts.InitialObjective)
        % Initial X passed only. Recall that it is a table.
        this.QueuedX = transformPoints(this, Opts.InitialX);
    else
        % Initial evaluated points passed. use them directly.
        XTbl = canonicalizePoints(this, Opts.InitialX);
        this.XTrain = transformPoints(this, XTbl);
        this.FTrain = Opts.InitialObjective(:)';
        this.ObjectiveEvaluationTimeTrain = Opts.InitialObjectiveEvaluationTimes(:)';
        this.PrivIndexOfMinimumTrace(1:this.NumObjectiveEvaluations,1) = NaN;
        this.PrivFMinTrace(1:this.NumObjectiveEvaluations,1) = NaN;
        this.PrivFMinEstimatedTrace(1:this.NumObjectiveEvaluations,1) = NaN;
        this.PrivIterationTimeTrace = Opts.InitialIterationTimes;
        this = fillTotalElapsedTimeTrace(this);
        this.PrivUserDataTrace = Opts.InitialUserData;
        this.ConstraintTrain = Opts.InitialConstraintViolations;
        this.ErrorTrain = Opts.InitialErrorValues;
        % If ASHA, augment X variables, set rung=1, set promoted=false
        if isequal(this.PrivOptions.AcquisitionFunctionName, 'asha')
            XTbl.ASHARungNum = ones(1,this.NumObjectiveEvaluations);
            XTbl.ASHAIsPromoted = false(1,this.NumObjectiveEvaluations);
            this.XTrain = transformPoints(this, XTbl);
            this.ASHAIsPromoted(1:this.NumObjectiveEvaluations) = false;
        end
    end
end
end