function ImportData = checkdata(LoopData,ImportData)
%CHECKDATA  Check validity of imported data.

%   Author(s): P. Gahinet
%   Copyright 1986-2000 The MathWorks, Inc. 
%   $Revision: 1.3 $  $Date: 2000/06/14 20:18:25 $

% ImportData = {P,H,F,C}  (all structures with fields Name and Model)

Unchanged = cellfun('isempty',ImportData);
FirstImport = isempty(LoopData.Plant); % 1 if no data in yet

% Set defaults for empty inputs
if Unchanged(1) % P unchanged
    if FirstImport
        ImportData{1} = struct('Name','untitledP','Model',zpk(1));
    else
        ImportData{1} = struct('Name',LoopData.Plant.Name,'Model',LoopData.Plant.Model);
    end
end

if Unchanged(2) % H unchanged
    if FirstImport
        ImportData{2} = struct('Name','untitledH','Model',zpk(1));
    else
        ImportData{2} = struct('Name',LoopData.Sensor.Name,'Model',LoopData.Sensor.Model);
    end
end

if Unchanged(3) % F unchanged
    if FirstImport
        ImportData{3} = struct('Name','untitledF','Model',zpk(1));
    else
        ImportData{3} = struct('Name',LoopData.PreFilter.Name,'Model',LoopData.PreFilter.Model);
    end
end

if Unchanged(4) % C unchanged
    if FirstImport
        ImportData{4} = struct('Name','untitledC','Model',zpk(1));
    else
        ImportData{4} = struct('Name',LoopData.Compensator.Name,'Model',zpk(LoopData.Compensator));
    end
end


% Check validity of modified component
Description = {'plant','sensor','prefilter','compensator'};
for ct=find(~Unchanged)
    ImportData{ct} = LocalCheckModelData(ImportData{ct},Description{ct});
end

% Check sample time consistency
% RE: May affect "unchanged" components
[ImportData{:}] = LocalCheckSampleTime(ImportData{:},LoopData);  



%----------------- Local functions -----------------

%%%%%%%%%%%%%%%%%%%%%%%
% LocalCheckModelData %
%%%%%%%%%%%%%%%%%%%%%%%
function Data = LocalCheckModelData(Data,Component)
% Checks model data for plant, sensor, prefilter, and compensator.

% Check model class
if isa(Data.Model,'frd')
    error(sprintf('The %s must be a TF, ZPK, or SS model, or a scalar.',Component))
else
    % Double or LTI
    Data.Model = zpk(Data.Model);
end

% Check dimensions
[z,p,k,Ts] = zpkdata(Data.Model,'v');
sizes = size(k);
if ~k & ~strcmp(Component,'compensator'),
    error(sprintf('The SISO Tool does not accept %s models with zero gain.',Component))
elseif prod(sizes(1:2))~=1,
    error(sprintf('The %s model must be single input, single output.',Component))
elseif prod(sizes(3:end))~=1
    error('The SISO Tool cannot be used with arrays of models.')
end

% Check for delays
if hasdelay(Data.Model),
    if Ts,
        % Map delay times to poles at z=0 in discrete-time case
        Data.Model = delay2z(Data.Model);
    else
        line1 = sprintf('Cannot handle continuous-time %s models with delays.',Component);
        line2 = 'Use PADE to approximate the time delays.';
        error(sprintf('%s\n%s',line1,line2))
    end      
end


%%%%%%%%%%%%%%%%%%%%%%%%
% LocalCheckSampleTime %
%%%%%%%%%%%%%%%%%%%%%%%%
function [P,H,F,C] = LocalCheckSampleTime(P,H,F,C,LoopData)
% Checks sample time consistency

% Reconcile plant/sensor/prefilter/compensator sample times
% RE: The overall sample time is stored as LoopData.Compensator.Ts
AllTs = [get(P.Model,'Ts') ; get(H.Model,'Ts') ; get(F.Model,'Ts') ; get(C.Model,'Ts')];
Ts = abs(AllTs(4));

if any(AllTs~=Ts),
    % Sample time discrepancy
    StaticFlags = [isstatic(P.Model) ; isstatic(H.Model) ; isstatic(F.Model) ; isstatic(C.Model)];
    DefTs = AllTs(~StaticFlags);  % Unambiguous sample times
    
    if isempty(DefTs)
        % All models are static
        Ts = max(AllTs);
    elseif ~any(diff(DefTs,[],1))
        % Unambiguous sample times match
        Ts = DefTs(1);
    else
        % Resolve mismatch
        if any(~DefTs)
            % Mix continuous/discrete
            error('The feedback loop components F,C,P,H must be either all continuous or all discrete.')
        elseif any(diff(DefTs(DefTs>0,:),[],1))
            % Positive sample time mismatch
            error('The feedback loop components F,C,P,H must share the same sample time.')
        else
            Ts = max(DefTs);
        end
    end
    
    % Equalize sample times
    % RE: Make sure sample time is positive
    Ts = abs(Ts);
    P.Model.Ts = Ts;
    H.Model.Ts = Ts;
    F.Model.Ts = Ts;
    C.Model.Ts = Ts;
end




