function DSGEModel = VerifyScenarioInformation(DSGEModel,DataStructure)
% VerifyScenarioInformation: Checks if there is valid information for running observed
%                            variables scenarios from the DataStructure structure.
%
% USAGE:
%
%       DSGEModel = VerifyScenarioInformation(DSGEModel,DataStructure)
%
% REQUIRED INPUT:  DSGEModel (structure) whose fields contain all required information
%                            about the model, such as input files, variable and sample
%                            data. Actual observations are not stored in this file.
%
%                  DataStrcuture (structure) where this function looks at the fields C.data
%                            C.names, C.C1, C.C2, CBar.data, C.transformation, C.export.
%
% REQUIRED OUTPUT: DSGEModel (structure) whose fields contain all required information
%                            about the model, such as input files, variable and sample
%                            data. Actual observations are not stored in this file.
%
%
%                       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: April 25, 2007.
%                        This version: February 10, 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:
%
% * 02-05-2007: Added the field "ScenarioParameters".
%
% * 28-09-2007: Made sure that field "ObsVariableScenarioFile" is reinitialized if the scenario information
%               is faulty. The fields "CData" and "CDataComment" are now taken into account.
%
% * 09-10-2007: The fields "CVariableNames", "C1", "C2", and "CBar" are now loaded from the "ObsVariableScenarioFile".
%               The fields "CDataOriginal", "CDataCommentOriginal", "CVariableNamesOriginal", "C1Original", "C2Original",
%               and "CBarOriginal" are now created.
%
% * 22-10-2007: The field "CTransformation" is now loaded from "ObsVariableScenarioFile".
%
% * 31-10-2007: The field "OVSComparisonFile" is now changed if there are missing data for the scenario.
%
% * 06-11-2007: Updated the documentation.
%
% * 09-01-2008: The field "CompData" is now supported.
%
% * 22-01-2008: Made sure that the field "CompData" can only take the comparison data from the data
%               construction file. The field "OVSComparisonFile" is no longer supported.
%
% * 31-01-2008: The function now also checks if "ScenarioVariables" and "ScenarioShocks" field exists in the
%               mat-file and if so uses them.
%
% * 28-03-2008: The fields "CExport" and "COrder" are now checked
%
% * 02-04-2008: The field "startperiod" is now checked.
%
% * 07-04-2008: The field "exportprepend" is now checked.
%
% * 23-05-2008: Updated the documentation.
%
% * 01-08-2008: The function now sets the "YData" field if it can be located in the scenario data
%               file.
%
% * 13-08-2008: The function now provides the field "CompCBar".
%
% * 20-08-2008: The function now provides the structure "CExportVariables".
%
% * 28-08-2008: The function now provides the structure "CCreateData".
%
% * 24-09-2008: Added the check for the field "createafterpartial".
%
% * 18-12-2008: Updated the documentation.
%
% * 09-02-2009: Fixed a bug where CompData was not properly set if either it was too
%               big or if it had fewer data points than what it could have.
%
% * 10-02-2009: Made sure that CompData is not checked too many times.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%

%
% initialize
%
DSGEModel.C = [];
DSGEModel.CData = [];
DSGEModel.CDataComment = '';
DSGEModel.CVariableNames = '';
DSGEModel.C1 = [];
DSGEModel.C2 = [];
DSGEModel.CBar = [];
DSGEModel.CTransformation = [];
DSGEModel.CompData = [];
DSGEModel.CompCBar = [];
DSGEModel.OrigScenarioVariables = DSGEModel.ScenarioVariables;
DSGEModel.OrigScenarioShocks = DSGEModel.ScenarioShocks;
DSGEModel.CExport = [];
DSGEModel.CExportVariables = [];
DSGEModel.CCreateData = [];
DSGEModel.COrder = [];
%
DSGEModel.CDataOriginal = [];
DSGEModel.CDataCommentOriginal = '';
DSGEModel.CVariableNamesOriginal = '';
DSGEModel.C1Original = [];
DSGEModel.C2Original = [];
DSGEModel.CBarOriginal = [];
DSGEModel.CTransformationOriginal = [];
%
if isfield(DSGEModel,'ScenarioShocks')==0;
   DSGEModel.ScenarioShocks = [];
end;
if isfield(DSGEModel,'ScenarioVariables')==0;
   DSGEModel.ScenarioVariables = [];
end;
if isfield(DSGEModel,'ScenarioParameters')==0;
   DSGEModel.ScenarioParameters = [];
end;
if isfield(DataStructure,'C')==0;
   DSGEModel.ScenarioShocks = [];
   DSGEModel.ScenarioVariables = [];
   DSGEModel.ScenarioParameters = [];
   DSGEModel.ObsVariableScenarioFile = '';
   return;
end;
if isfield(DataStructure.C,'data')==0;
   DSGEModel.ScenarioShocks = [];
   DSGEModel.ScenarioVariables = [];
   DSGEModel.ScenarioParameters = [];
   DSGEModel.ObsVariableScenarioFile = '';
   return;
end;
if isfield(DataStructure.C,'names')==0;
   DSGEModel.ScenarioShocks = [];
   DSGEModel.ScenarioVariables = [];
   DSGEModel.ScenarioParameters = [];
   DSGEModel.ObsVariableScenarioFile = '';
   return;
end;
if isfield(DataStructure.C,'C1')==0;
   DSGEModel.ScenarioShocks = [];
   DSGEModel.ScenarioVariables = [];
   DSGEModel.ScenarioParameters = [];
   DSGEModel.ObsVariableScenarioFile = '';
   return;
end;
if isfield(DataStructure.C,'C2')==0;
   DSGEModel.ScenarioShocks = [];
   DSGEModel.ScenarioVariables = [];
   DSGEModel.ScenarioParameters = [];
   DSGEModel.ObsVariableScenarioFile = '';
   return;
end;
if isfield(DataStructure,'CBar')==0;
   DSGEModel.ScenarioShocks = [];
   DSGEModel.ScenarioVariables = [];
   DSGEModel.ScenarioParameters = [];
   DSGEModel.ObsVariableScenarioFile = '';
   return;
end;
if isfield(DataStructure.CBar,'data')==0;
   DSGEModel.ScenarioShocks = [];
   DSGEModel.ScenarioVariables = [];
   DSGEModel.ScenarioParameters = [];
   DSGEModel.ObsVariableScenarioFile = '';
   return;
end;
%
% all fields are available.
%
% 1. check if dimensions match for C, CVariableNames, and C1
%
C1 = DataStructure.C.C1;
C = DataStructure.C.data;
if isfield(DataStructure.C,'comparisondata')==1;
   CompData = DataStructure.C.comparisondata;
else;
   CompData = [];
end;
if isfield(DataStructure.CBar,'comparisondata')==1;
   CompCBar = DataStructure.CBar.comparisondata;
else;
   CompCBar = [];
end;
CVariableNames = DataStructure.C.names;
C2 = DataStructure.C.C2;
CBar = DataStructure.CBar.data;
[n c] = size(C1);
if size(C,1)>size(C,2);
   C = C';
end;
Tc = size(C,2);
if (Tc==0)|(c==0)|(c~=size(C,1))|(c~=length(CVariableNames))|(c~=rank(C1));
   DSGEModel.ScenarioShocks = [];
   DSGEModel.ScenarioVariables = [];
   DSGEModel.ScenarioParameters = [];
   DSGEModel.ObsVariableScenarioFile = '';
   return;
end;
%
% allow for empty inputs for C2 and CBar
%
if isempty(C2)==1;
   C2 = zeros(n,c);
end;
if isempty(CBar)==1;
   CBar = zeros(c,Tc);
end;
%
% deal with the comparison data
%
if isempty(CompData)==0;
   if size(CompData,1)>size(CompData,2);
      CompData = CompData';
   end;
   if size(CompData,2)>Tc;
      CompData = CompData(:,1:Tc);
   elseif size(CompData,2)<Tc;
      CompData = [CompData NaN*ones(size(CompData,1),Tc-size(CompData,2))];
   end;
   if size(CompData,1)>=c;
      CompData = CompData(1:c,:);
   else;
      CompData = [];
   end;
end;
if (isempty(CompCBar)==1)&(isempty(CompData)==0);
   CompCBar = zeros(size(CompData));
end;
if isempty(CompData)==1;
   CompCBar = [];
end;
%
% check to make sure that CompCBar and CompData have the same dimensions
%
if isempty(CompCBar)==0;
   if size(CompCBar,1)>size(CompCBar,2);
      CompCBar = CompCBar';
   end;
   if size(CompCBar,2)>Tc;
      CompCBar = CompCBar(:,1:Tc);
   elseif size(CompCBar,2)<Tc;
      CompCBar = [CompCBar zeros(size(CompCBar,1),Tc-size(CompCBar,2))];
   end;
   if size(CompCBar,1)>=c;
      CompCBar = CompCBar(1:c,:);
   else;
      CompCBar = [];
   end;
end;
%
% make sure that C1 and C2 have same dimensions
%
if (size(C2,1)~=n)|(size(C2,2)~=c);
   DSGEModel.ScenarioShocks = [];
   DSGEModel.ScenarioVariables = [];
   DSGEModel.ScenarioParameters = [];
   DSGEModel.ObsVariableScenarioFile = '';
   return;
end;
if size(CBar,1)>size(CBar,2);
   CBar = CBar';
end;
Tcbar = size(CBar,2);
%
% make sure that Cbar has the c rows and Tc columns
%
if (c~=size(CBar,1))|(Tcbar<Tc);
   DSGEModel.ScenarioShocks = [];
   DSGEModel.ScenarioVariables = [];
   DSGEModel.ScenarioParameters = [];
   DSGEModel.ObsVariableScenarioFile = '';
   return;
elseif Tcbar>Tc;
   CBar = CBar(:,1:Tc);
end;
%
% Everything looks OK. we can now let the DSGEModel structure hold
% these data
%
DSGEModel.C = C;
DSGEModel.CData = C;
DSGEModel.CompData = CompData;
DSGEModel.CDataComment = 'Original observed variable scenario data.';
DSGEModel.CVariableNames = char(CVariableNames);
DSGEModel.C1 = C1;
DSGEModel.C2 = C2;
DSGEModel.CBar = CBar;
DSGEModel.CompCBar = CompCBar;
if isfield(DataStructure.C,'transformation')==1;
   DSGEModel.CTransformation = DataStructure.C.transformation;
end;
if isfield(DataStructure.C,'summaryorder')==1;
   TestSummaryOrder = round(abs(DataStructure.C.summaryorder));
   if (length(TestSummaryOrder)==c)&(min(TestSummaryOrder)==1)&(max(TestSummaryOrder)==c);
      DSGEModel.COrder = TestSummaryOrder;
   else;
      DSGEModel.COrder = (1:c);
   end;
else;
   DSGEModel.COrder = (1:c);
end;
%
% check if there is any data to prepend to the scenario data when exporting
%
PrependData = [];
if isfield(DataStructure.C,'exportprepend')==1;
   if size(DataStructure.C.exportprepend,1)==c;
      PrependData = DataStructure.C.exportprepend;
   elseif (size(DataStructure.C.exportprepend,2)==c)&(size(DataStructure.C.exportprepend,1)~=c);
      PrependData = DataStructure.C.exportprepend';
   end;
end;
Td = size(PrependData,2);
DSGEModel.CExport.prependdata = PrependData;
%
% check if there is export data and names
%
if isfield(DataStructure.C,'export')==1;
   if isfield(DataStructure.C.export,'data')==1;
      if size(DataStructure.C.export.data,2)==(Tc+Td);
         ExportData = DataStructure.C.export.data;
      elseif size(DataStructure.C.export.data,1)==(Tc+Td);
         ExportData = DataStructure.C.export.data';
      else;
         ExportData = [];
      end;
      if isempty(ExportData)==0;
         DSGEModel.CExport.data = ExportData;
         if (isfield(DataStructure.C.export,'names')==1)&(size(DataStructure.C.export.names)==[2 size(ExportData,1)])&(iscellstr(DataStructure.C.export.names)==1);
            %
            % check if all elements are char's
            %
            IsCharStr = 1;
            for i=1:2;
               for j=1:size(ExportData,1);
                  if ischar(DataStructure.C.export.names{i,j})==0;
                     IsCharStr = 0;
                     break;
                  end;
                  if IsCharStr==0;
                     break;
                  end;
               end;
            end;
            if IsCharStr==1;
               DSGEModel.CExport.names = DataStructure.C.export.names;
            else;
               DSGEModel.CExport.names = '';
            end;
         else;
            DSGEModel.CExport.names = '';
         end;
         if isempty(DSGEModel.CExport.names)==1;
            for i=1:2;
               for j=1:size(ExportData,1);
                  DSGEModel.CExport.names{i,j} = '';
               end;
            end;
         end;
      end;
   end;
end;
if isfield(DataStructure.C,'exportvariables')==1;
   if (isfield(DataStructure.C.exportvariables,'names')==1)&(isfield(DataStructure.C.exportvariables,'titles')==1)&(iscellstr(DataStructure.C.exportvariables.names)==1)&(iscellstr(DataStructure.C.exportvariables.titles)==1)&(length(DataStructure.C.exportvariables.names)>0)&(length(DataStructure.C.exportvariables.names)==length(DataStructure.C.exportvariables.titles));
      %
      % now we check each variable field
      %
      NumChecks = 0;
      for j=1:length(DataStructure.C.exportvariables.names);
         CurrVariable = DataStructure.C.exportvariables.names{j};
         if isfield(DataStructure.C.exportvariables,CurrVariable)==1;
            CurrField = getfield(DataStructure.C.exportvariables,CurrVariable);
            if (isfield(CurrField,'fcn')==1)&(isfield(CurrField,'x')==1)&(isfield(CurrField,'y')==1)&(isfield(CurrField,'subsample')==1)&(isfield(CurrField,'priordata')==1);
               if (isempty(CurrField.fcn)==0)&(ischar(CurrField.fcn)==1)&(isempty(CurrField.subsample)==0)&(length(CurrField.subsample)==2)&(isnumeric(CurrField.x)==1)&(isnumeric(CurrField.priordata)==1);
                  NumChecks = NumChecks+1;
               else;
                  break;
               end;
            else;
               break;
            end;
         else;
            break;
         end;
      end;
      if NumChecks==length(DataStructure.C.exportvariables.names);
         DSGEModel.CExportVariables = DataStructure.C.exportvariables;
      end;
   end;
end;
% 
if isfield(DataStructure.C,'createdata')==1;
   NumChecks = 0;
   if (isfield(DataStructure.C.createdata,'names')==1)&(iscellstr(DataStructure.C.createdata.names)==1);
      for j=1:length(DataStructure.C.createdata.names);
         CurrVariable = DataStructure.C.createdata.names{j};
         if isfield(DataStructure.C.createdata,CurrVariable)==1;
            CurrField = getfield(DataStructure.C.createdata,CurrVariable);
            if (isfield(CurrField,'createbeforefcn')==1)&(isfield(CurrField,'createafterfcn')==1)&(isfield(CurrField,'createafterpartial')==1)&(isfield(CurrField,'createx')==1)&(isfield(CurrField,'createcompx')==1)&(isfield(CurrField,'createy')==1)&(isfield(CurrField,'before')==1)&(isempty(CurrField.createbeforefcn)==0)&(isempty(CurrField.createafterfcn)==0)&(ischar(CurrField.createbeforefcn)==1)&(ischar(CurrField.createafterfcn)==1)&(iscellstr(CurrField.createafterpartial)==1)&(iscellstr(CurrField.createy)==1)&(isnumeric(CurrField.before)==1)&((CurrField.before==1)|(CurrField.before==0))&(isnumeric(CurrField.createx)==1)&(isnumeric(CurrField.createcompx)==1);
               if CurrField.before==1;
                  if (isfield(CurrField,'fcn')==1)&(isfield(CurrField,'partial')==1)&(isfield(CurrField,'annualizefcn')==1)&(isfield(CurrField,'annualizepartial')==1)&(isfield(CurrField,'initial')==1)&(isfield(CurrField,'x')==1)&(isfield(CurrField,'compinitial')==1)&(isfield(CurrField,'compx')==1)&(isempty(CurrField.fcn)==0)&(ischar(CurrField.fcn)==1)&(isempty(CurrField.partial)==0)&(ischar(CurrField.partial)==1)&(isempty(CurrField.annualizefcn)==0)&(ischar(CurrField.annualizefcn)==1)&(isempty(CurrField.annualizepartial)==0)&(ischar(CurrField.annualizepartial)==1)&(isnumeric(CurrField.initial)==1)&(isnumeric(CurrField.x)==1)&(isnumeric(CurrField.compinitial)==1)&(isnumeric(CurrField.compx)==1);
                     NumChecks = NumChecks+1;
                  else;
                     break;
                  end;
               else;
                  NumChecks = NumChecks+1;
               end;
            else;
               break;
            end;
         else;
            break;
         end;
      end;
      if NumChecks==length(DataStructure.C.createdata.names);
         DSGEModel.CCreateData = DataStructure.C.createdata;
      end;
   end;
end;
%
% check if there's information about the scenario start value
%
if (DSGEModel.ScenarioValue==1)&(isfield(DataStructure.C,'startperiod')==1)&(length(DataStructure.C.startperiod)==2)&(isnumeric(DataStructure.C.startperiod)==1);
   %
   % check if we have a valid entry
   %
   DateVector = MakeDateVector(DSGEModel.SubBeginYear,DSGEModel.SubBeginPeriod,DSGEModel.SubEndYear,DSGEModel.SubEndPeriod,DSGEModel.DataFrequency);
   DateVector = DateVector(DSGEModel.KalmanFirstObservation:length(DateVector));
   if strcmp(lower(DSGEModel.DataFrequency),'q')==1;
      StartValue = DataStructure.C.startperiod(1)+(((2*DataStructure.C.startperiod(2))-1)/8);
   elseif strcmp(lower(DSGEModel.DataFrequency),'m')==1;
      StartValue = DataStructure.C.startperiod(1)+(((2*DataStructure.C.startperiod(2))-1)/24);
   else;
      StartValue = DataStructure.C.startperiod(1);
   end;
   StartPos = (DateVector==StartValue)*(1:length(DateVector))';
   if StartPos>0;
      DSGEModel.ScenarioValue = length(DateVector)-StartPos+1;
      if DSGEModel.AnnScenarioValue==1;
         DSGEModel.AnnScenarioValue = DSGEModel.ScenarioValue;
      end;
   end;
end;
%
% The original data must be stored first
%
DSGEModel.CDataOriginal = DSGEModel.CData;
DSGEModel.CDataCommentOriginal = DSGEModel.CDataComment;
DSGEModel.CVariableNamesOriginal = DSGEModel.CVariableNames;
DSGEModel.C1Original = DSGEModel.C1;
DSGEModel.C2Original = DSGEModel.C2;
DSGEModel.CBarOriginal = DSGEModel.CBar;
DSGEModel.CTransformationOriginal = DSGEModel.CTransformation;
%
if (isempty(DSGEModel.ScenarioVariables)==1)|(max(DSGEModel.ScenarioVariables)>c);
   DSGEModel.ScenarioVariables = (1:c);
end;
if (isempty(DSGEModel.ScenarioShocks)==1)|(max(DSGEModel.ScenarioShocks)>length(DSGEModel.StateShockPositions));
   DSGEModel.ScenarioShocks = (1:c);
end;
SDataFile = [DSGEModel.OutputDirectory '\ovsdata\' DSGEModel.ObsVariableScenarioFile '.mat'];
if FileExist(SDataFile)==1;
   SD = load(SDataFile);
   if isfield(SD,'CData')==1;
      DSGEModel.CData = SD.CData;
      DSGEModel.CDataComment = SD.CDataComment;
      DSGEModel.CVariableNames = SD.CVariableNames;
      DSGEModel.C1 = SD.C1;
      DSGEModel.C2 = SD.C2;
      DSGEModel.CBar = SD.CBar;
      if isfield(SD,'CTransformation')==1;
         DSGEModel.CTransformation = SD.CTransformation;
      else;
         DSGEModel.CTransformation = [];
      end;
      if isfield(SD,'ScenarioVariables')==1;
         DSGEModel.ScenarioVariables = SD.ScenarioVariables;
         DSGEModel.ScenarioShocks = SD.ScenarioShocks;
      end;
      if isfield(SD,'CExport')==1;
         DSGEModel.CExport = SD.CExport;
      else;
         DSGEModel.CExport = [];
      end;
      if isfield(SD,'YData')==1;
         DSGEModel.YData = SD.YData;
      end;
      if isfield(SD,'CExportVariables')==1;
         DSGEModel.CExportVariables = SD.CExportVariables;
      else;
         DSGEModel.CExportVariables = [];
      end;
      if isfield(SD,'CCreateData')==1;
         DSGEModel.CCreateData = SD.CCreateData;
      else;
         DSGEModel.CCreateData = [];
      end;
   end;
end;

%
% end of VerifyScenarioInformation.m
%
