function [ModelStatus,DSGEModel] = VerifyDSGEModel(DSGEModel,ModelFile,OldDataConstructionFile,CurrINI);
% VerifyDSGEModel: Verifies the validity of the information read from a DSGE Model File. This means that any
%                  files being referenced to exist where they are claimed to exist.
%
% USAGE:
%
%       [ModelStatus,DSGEModel] = VerifyDSGEModel(DSGEModel,ModelFile,CurrINI);
%
% REQUIRED INPUTS:  DSGEModel (structure) with fields containing all the information about a DSGE Model for YADA.
%
%                   ModelFile (string vector), with full path and filename of the DSGE Model File whose data
%                             is summarized by DSGEModel.
%
%                   OldDataConstructionFile (string vector) with full path (and filename) of currently valid
%                             data construction file (may be a path)
%
%                   CurrINI (structure), with fields containing initialization information.
%
% REQUIRED OUTPUTS: ModelStatus (boolean), takes the value 1 if the ModelFile data are valid, otherwise it is 0
%
%                   DSGEModel (structure), with some new fields (if ModelStatus=1) and some fixed to defaults
%
%
%                       Written by: Anders Warne
%                                   New Area Wide Model Project
%                                   DG-R/EMO
%                                   European Central Bank (ECB)
%                                   Email: anders.warne@ecb.europa.eu
%                                   Copyright © 2006-2009 European Central Bank.
%
%                       First version: August 2, 2006.
%                        This version: March 9, 2009.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% LICENSE INFORMATION:
%
%      YADA is free software: you can redistribute it and/or modify
%      it under the terms of the GNU General Public License as published by
%      the Free Software Foundation, either version 3 of the License, or
%      (at your option) any later version.
%
%      This program is distributed in the hope that it will be useful,
%      but WITHOUT ANY WARRANTY; without even the implied warranty of
%      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%      GNU General Public License for more details.
%
%      You should have received a copy of the GNU General Public License
%      along with this program.  If not, see <http://www.gnu.org/licenses/>.
%
%      YADA is released under the GNU General Public License, Version 3,
%      29 June 2007 <http://www.gnu.org/licenses/>. The current release of
%      the program was last modified by the ECB on the "This version" date
%      above.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% CHANGELOG:
%
% * 07-08-2006: Added try, catch around eval statement.
%
% * 15-08-2006: Added a lower function around "DataStructure.frequency(1,1)" to allow for case invariance in the setup of
%               data frequency in the data construction file.
%
% * 04-12-2006: Added the fields "ShockGroupNames" and "ShockGroups".
%
% * 08-12-2006: The field DataStructure.Y.levels is now taken into account for setting up the vector DSGEModel.levels.
%
% * 12-01-2007: The fields DataStructure.Y.BVAR and DataStructure.X.BVAR are taken into account for setting up the
%               vectors DSGEModel.BVARY and DSGEModel.BVARX, respectively.
%
% * 22-01-2007: The field "DataStructure.Y.annual" is now taken into account.
%
% * 23-01-2007: Took the changes in the setup of "DataStructure.Y.annual" into account.
%
% * 25-01-2007: The field "DataStructure.Y.annualscale" is now taken into account.
%
% * 16-02-2007: The field "DataStructure.X.extradata" is now taken into account.
%
% * 20-02-2007: The field "percentiles" is now taken into account.
%
% * 08-03-2007: Made sure that "DSGEModel.Percentiles" is now rounded to integer number only. The fields "Z",
%               "ZVariableNames", "K1", "K2", and "U" are also taken into account.
%
% * 20-03-2007: Took the name change of the "isodd" function to "IsOdd" into account.
%
% * 25-04-2007: The fields "C", "CVariableNames", "C1", "C2", and "CBar" are now taken into account.
%
% * 28-09-2007: The fields "ObsVariableScenarioFile", "CData", and "CDataComment" are now taken into account.
%
% * 09-10-2007: The fields "CDataOriginal", "CVariableNamesOriginal", "CDataCommentOriginal", "C1Original",
%               "C2Original", and "CBarOriginal" are now taken into account.
%
% * 22-10-2007: The fields "YTransformation", "CTransformation", and "CTransformationOriginal" are taken into account.
%
% * 23-10-2007: The fields "ZTransformation" and "ZTransformationOriginal" are now taken into account.
%
% * 31-10-2007: The field "OVSComparisonFile" is now taken into account.
%
% * 06-11-2007: Updated the documentation and fixed an issue with "OVSComparisonFile".
%
% * 09-01-2008: The field "CompData" is now accounted for. Moreover, we now allow for the possibility that
%               the scenario data has selected the comparison scenario data.
%
% * 11-01-2008: The field "CompY" is now accounted for.
%
% * 22-01-2008: The field "OVSComparisonFile" is no longer supported.
%
% * 31-01-2008: The fields "ShockColorStart" and "ShockColorEnd" are now accounted for.
%
% * 28-03-2008: The fields "CExport" and "COrder" are now accounted for.
%
% * 30-04-2008: The field "T" is now set from the size function. Moreover, all fields that are missing from
%               the input "DSGEModel" relative to those provided through InitializeDSGEModel are now
%               set to the initial values.
%
% * 23-05-2008: Updated the documentation.
%
% * 01-08-2008: The fields "YData" and "YDataOriginal" are now specified.
%
% * 13-08-2008: Took the field "CompCBar" into account.
%
% * 20-08-2008: The field "CExportVariables" is now accounted for.
%
% * 28-08-2008: The field "CCreateData" is now accounted for.
%
% * 19-12-2008: Made it possible for the AiMFile to be missing as long as both the AiMDataFile
%               and the compute_aim_matrices.m files exist.
%
% * 09-03-2009: Added quotation marks around paths for the dos copy command.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%

ModelStatus = 1;
%
% make sure that all fields are initialized
%
InitialDSGEModel = InitializeDSGEModel;
DSGENames = fieldnames(InitialDSGEModel);
for j=1:length(DSGENames);
   if isfield(DSGEModel,DSGENames{j})==0;
      DSGEModel = setfield(DSGEModel,DSGENames{j},getfield(InitialDSGEModel,DSGENames{j}));
   end;
end;
%
% There are fields of the DSGEModel structure that may need to be updated.
% These are: k, n, T, X, Y, VariabelNames, and XVariableNames
%
if FileExist(DSGEModel.DataConstructionFile)==1;
   %
   % run the file to check it out
   %
   [f_path,f_name,f_ext] = fileparts(DSGEModel.DataConstructionFile);
   if strcmp(lower(f_path),lower([pwd '\tmp']))==0;
      [stat,msg] = dos(['copy /Y "' DSGEModel.DataConstructionFile '" "' pwd '\tmp"']);
      file = [pwd '\tmp\' f_name f_ext];
   end;
   %
   % check the file to see if we can retrieve the necessary information
   %
   if FileExist(file)==1;
      ErrorStr = '';
      try;
         eval(['DataStructure = ' f_name ';']);
      catch;
         ErrorStr = ['Error found in data construction file "' f_name '". The error message caught is: ' lasterr];
      end;
      if isempty(ErrorStr)==1;
         %
         % now we check if DataStructure is valid
         %
         stat = CheckObservedDataFile(DataStructure,[],OldDataConstructionFile,[f_name f_ext],CurrINI);
         if stat>=1;
            DSGEModel.T = size(DataStructure.Y.data,2);
            DSGEModel.n = length(DataStructure.Y.names);
            DSGEModel.k = length(DataStructure.X.names);
            DSGEModel.Y = DataStructure.Y.data;
            if isfield(DataStructure.Y,'comparisondata')==1;
               DSGEModel.CompY = DataStructure.Y.comparisondata;
            else;
               DSGEModel.CompY = [];
            end;
            DSGEModel.DataFrequency = lower(DataStructure.frequency(1,1));
            if (isfield(DataStructure.Y,'BVAR')==1)&(length(DataStructure.Y.BVAR)<=DSGEModel.n);
               DSGEModel.BVARY = VerifyVector(DataStructure.Y.BVAR,DSGEModel.n);
            else;
               DSGEModel.BVARY = (1:DSGEModel.n);
            end;
            if (isfield(DataStructure.X,'BVAR')==1)&(length(DataStructure.X.BVAR)<=DSGEModel.k);
               DSGEModel.BVARX = VerifyVector(DataStructure.X.BVAR,DSGEModel.k);
            else;
               DSGEModel.BVARX = (1:DSGEModel.k);
            end;
            if isfield(DataStructure.X,'extradata')==1;
               %
               % we need to test if this data is valid
               %
               if size(DataStructure.X.extradata,1)==DSGEModel.k;
                  DSGEModel.PredictedX = DataStructure.X.extradata;
               else;
                  DSGEModel.PredictedX = [];
               end;
            else;
               DSGEModel.PredictedX = [];
            end;
            if isfield(DataStructure,'percentiles')==1;
               Ptiles = unique(DataStructure.percentiles);
               %
               % make sure that all entries are greater than 0, less than a 100, and integers
               %
               Ptiles = Ptiles(Ptiles>0);
               Ptiles = Ptiles(Ptiles<100);
               if length(Ptiles)>1;
                  if IsOdd(length(Ptiles))==1;
                     Pmiddle = Ptiles(ceil(length(Ptiles)/2));
                     Ptiles = Ptiles(Ptiles~=Pmiddle);
                  end;
                  DSGEModel.Percentiles = Ptiles;
               else;
                  DSGEModel.Percentiles = [5 15 85 95];
               end;
            else;
               DSGEModel.Percentiles = [5 15 85 95];
            end;
            if stat==1;
               DSGEModel.levels = DataStructure.Y.levels;
               if (isfield(DataStructure.Y,'annual')==1)&(length(DataStructure.Y.annual)==DSGEModel.n);
                  if strcmp(DSGEModel.DataFrequency,'q')==1;
                     SampleFreq = 4;
                  elseif strcmp(DSGEModel.DataFrequency,'m')==1;
                     SampleFreq = 12;
                  else;
                     SampleFreq = 1;
                  end;
                  DSGEModel.annual = ((DataStructure.Y.annual)*(SampleFreq-1))+ones(1,DSGEModel.n);
               else;
                  DSGEModel.annual = ones(1,DSGEModel.n);
               end;
               if (isfield(DataStructure.Y,'annualscale')==1)&(length(DataStructure.Y.annualscale)==DSGEModel.n);
                  DSGEModel.annualscale = ReplaceData(DataStructure.Y.annualscale,0,1);
               else;
                  DSGEModel.annualscale = ones(1,DSGEModel.n);
               end;
            elseif stat==2;
               DSGEModel.levels = ones(1,DSGEModel.n);
               DSGEModel.annual = ones(1,DSGEModel.n);
               DSGEModel.annualscale = ones(1,DSGEModel.n);
            end;
            if size(DSGEModel.Y,1)>size(DSGEModel.Y,2);
               DSGEModel.Y = DSGEModel.Y';
            end;
            if size(DSGEModel.CompY,1)>size(DSGEModel.CompY,2);
               DSGEModel.CompY = DSGEModel.CompY';
            end;
            if size(DSGEModel.Y)~=size(DSGEModel.CompY);
               DSGEModel.CompY = [];
            end;
            DSGEModel.X = DataStructure.X.data;
            if size(DSGEModel.X,1)>size(DSGEModel.X,2);
               DSGEModel.X = DSGEModel.X';
            end;
            DSGEModel.YData = DSGEModel.Y;
            DSGEModel.YDataOriginal = DSGEModel.Y;
            DSGEModel.BeginYear = num2str(floor(DataStructure.sample(1)));
            DSGEModel.BeginPeriod = num2str(floor(DataStructure.sample(2)));
            DSGEModel.EndYear = num2str(floor(DataStructure.sample(3)));
            DSGEModel.EndPeriod = num2str(floor(DataStructure.sample(4)));
            %
            % check if we need to fix the sub-sample information
            %
            if str2num(DSGEModel.SubBeginYear)<floor(DataStructure.sample(1));
               DSGEModel.SubBeginYear = num2str(floor(DataStructure.sample(1)));
               DSGEModel.SubBeginPeriod = num2str(floor(DataStructure.sample(2)));
            elseif (str2num(DSGEModel.SubBeginYear)==floor(DataStructure.sample(1)))&(str2num(DSGEModel.SubBeginPeriod)<floor(DataStructure.sample(2)));
               DSGEModel.SubBeginPeriod = num2str(floor(DataStructure.sample(2)));
            end;
            if str2num(DSGEModel.SubEndYear)>floor(DataStructure.sample(3));
               DSGEModel.SubEndYear = num2str(floor(DataStructure.sample(3)));
               DSGEModel.SubEndPeriod = num2str(floor(DataStructure.sample(4)));
            elseif (str2num(DSGEModel.SubEndYear)==floor(DataStructure.sample(3)))&(str2num(DSGEModel.SubEndPeriod)>floor(DataStructure.sample(4)));
               DSGEModel.SubEndPeriod = num2str(floor(DataStructure.sample(4)));
            end;
            %
            DSGEModel.VariableNames = '';
            for i=1:DSGEModel.n;
               DSGEModel.VariableNames = strvcat(DSGEModel.VariableNames,DataStructure.Y.names{i});
            end;
            DSGEModel.XVariableNames = '';
            for i=1:DSGEModel.k;
               DSGEModel.XVariableNames = strvcat(DSGEModel.XVariableNames,DataStructure.X.names{i});
            end;
            if isfield(DataStructure.Y,'transformation')==1;
               DSGEModel.YTransformation = DataStructure.Y.transformation;
            else;
               DSGEModel.YTransformation = [];
            end;
            %
            % check if there is conditioning information
            %
            DSGEModel = VerifyConditioningInformation(DSGEModel,DataStructure);
            %
            % check if there is observed variable scenario information
            %
            DSGEModel = VerifyScenarioInformation(DSGEModel,DataStructure);
            %
            if (isempty(DSGEModel.ObsVariableScenarioFile)==0)&(FileExist([DSGEModel.OutputDirectory '\ovsdata\' DSGEModel.ObsVariableScenarioFile '.mat'])==0);
               DSGEModel.ObsVariableScenarioFile = '';
            end;
         else;
            ModelStatus = 0;
            return;
         end;
      else;
         About(ErrorStr,'error',['Error - ' f_name],140,500,CurrINI);
         ModelStatus = 0;
         return;
      end;
   end;
elseif strcmp(lower(GetExt(DSGEModel.DataConstructionFile)),'.m')==1;
   txt = ['The DSGE Model file "' GetFilename(ModelFile) '" references a data construction file "' GetFilename(DSGEModel.DataConstructionFile) '" that doesn''t exist in the specified location (' GetPath(DSGEModel.DataConstructionFile) '). YADA is therefore unable to open the DSGE Model.'];
   About(txt,'information','Bad DSGE Model File',140,500,CurrINI);
   ModelStatus = 0;
   return;
else;
   %
   % Assume that the data construction field is pwd and reset all relevant fields
   %
   DSGEModel.DataConstructionFile = pwd;
   DSGEModel.T = 0;
   DSGEModel.n = 0;
   DSGEModel.k = 0;
   DSGEModel.Y = [];
   DSGEModel.YData = [];
   DSGEModel.YDataOriginal = [];
   DSGEModel.CompY = [];
   DSGEModel.levels = [];
   DSGEModel.annual = [];
   DSGEModel.annualscale = [];
   DSGEModel.X = [];
   DSGEModel.PredictedX = [];
   DSGEModel.Percentiles = [5 15 85 95];
   DSGEModel.BVARY = [];
   DSGEModel.BVARX = [];
   DSGEModel.DataFrequency = '';
   DSGEModel.BeginYear = '';
   DSGEModel.BeginPeriod = '';
   DSGEModel.EndYear = '';
   DSGEModel.EndPeriod = '';
   DSGEModel.SubBeginYear = '';
   DSGEModel.SubBeginPeriod = '';
   DSGEModel.SubEndYear = '';
   DSGEModel.SubEndPeriod = '';
   DSGEModel.VariableNames = '';
   DSGEModel.XVariableNames = '';
   DSGEModel.ConfidenceBandBaseColor = [1 1 1];
   DSGEModel.Z = [];
   DSGEModel.ZVariableNames = '';
   DSGEModel.K1 = [];
   DSGEModel.K2 = [];
   DSGEModel.U = [];
   DSGEModel.C = [];
   DSGEModel.CData = [];
   DSGEModel.CompData = [];
   DSGEModel.CDataComment = '';
   DSGEModel.CVariableNames = '';
   DSGEModel.ObsVariableScenarioFile = '';
   DSGEModel.C1 = [];
   DSGEModel.C2 = [];
   DSGEModel.CBar = [];
   DSGEModel.CompCBar = [];
   DSGEModel.CDataOriginal = [];
   DSGEModel.CDataCommentOriginal = '';
   DSGEModel.CVariableNamesOriginal = '';
   DSGEModel.C1Original = [];
   DSGEModel.C2Original = [];
   DSGEModel.CBarOriginal = [];
   DSGEModel.CTransformation = [];
   DSGEModel.YTransformation = [];
   DSGEModel.CTransformationOriginal = [];
   DSGEModel.ZTransformation = [];
   DSGEModel.ZTransformationOriginal = [];
   DSGEModel.CExport = [];
   DSGEModel.CExportVariables = [];
   DSGEModel.CCreateData = [];
   DSGEModel.COrder = [];
end;
%
% check the measurement equation file
%
if FileExist(DSGEModel.MeasurementEquationFile)==0;
   DSGEModel.MeasurementEquationFile = pwd;
end;
%
% check the prior file
%
if FileExist(DSGEModel.PriorFile)==0;
   DSGEModel.PriorFile = pwd;
   DSGEModel.PriorFileSheet = 'None';
end;
%
% check the update parameters file
%
if FileExist(DSGEModel.UpdateParameterFile)==0;
   DSGEModel.UpdateParameterFile = pwd;
end;
%
% check the initialize parameters file
%
if FileExist(DSGEModel.InitializeParameterFile)==0;
   DSGEModel.InitializeParameterFile = pwd;
   DSGEModel.RunInitializeFirst = 0;
end;
%
% check the AiM Model file
%
if FileExist(DSGEModel.AIMFile)==0;
   DSGEModel.AIMFile = pwd;
   if (FileExist(DSGEModel.AIMDataFile)==0)|(FileExist([GetPath(DSGEModel.AIMDataFile) 'compute_aim_matrices.m'])==0);
      DSGEModel.AIMDataFile = pwd;
      DSGEModel.NameOfModel = '';
      DSGEModel.StateShockNames = '';
      DSGEModel.StateShockPositions = [];
      DSGEModel.StateVariableNames = '';
      DSGEModel.StateVariablePositions = [];
      DSGEModel.ShockGroupNames = '';
      DSGEModel.ShockGroups = [];
      DSGEModel.ShockGroupColors = [];
      DSGEModel.ShockColorStart = [];
      DSGEModel.ShockColorEnd = [];
   end;
else;
   %
   % check the AiM data file
   %
   if (FileExist(DSGEModel.AIMDataFile)==0)|(FileExist([GetPath(DSGEModel.AIMDataFile) 'compute_aim_matrices.m'])==0);
      DSGEModel.AIMDataFile = pwd;
      DSGEModel.StateShockNames = '';
      DSGEModel.StateShockPositions = [];
      DSGEModel.StateVariableNames = '';
      DSGEModel.StateVariablePositions = [];
      DSGEModel.ShockGroupNames = '';
      DSGEModel.ShockGroups = [];
      DSGEModel.ShockGroupColors = [];
      DSGEModel.ShockColorStart = [];
      DSGEModel.ShockColorEnd = [];
   end;
end;
%
% check the output directory
%
if DirExist(DSGEModel.OutputDirectory)==0;
   DSGEModel.OutputDirectory = GetPath(ModelFile);
   if strcmp(DSGEModel.OutputDirectory(1,length(DSGEModel.OutputDirectory)),'\')==1;
      DSGEModel.OutputDirectory = DSGEModel.OutputDirectory(1,1:length(DSGEModel.OutputDirectory)-1);
   end;
end;

%
% end of VerifyDSGEModel.m
%
