function [yel,ye,ROC,Model] = GetShapeBasedROCPerformance(Root,Template,variablename, objidx, options,savename);
%function [yel,ye,ROC,Model] = GetShapeBasedROCPerformance(Root,Template,variablename, objidx, options,savename);
%
%computes performance on the shape based object data.
%will randomly pick features if there are over 8000 features!


HelpTextInfo = 'GetPerformance';
AppRoot = '/cbcl/scratch01/bileschi/PrecomputedFeatures/StreetScenes/AppearanceDetector/';

d.bRandsplit = 0; %0 means that we will take the first 2/3 for training
d.TrainingPart = 2/3;
d.sPARAMS.Nrounds = 200;
d.sPARAMS.R = 0;
d.sPARAMS.T = 0;
d.sPARAMS.C = 1;
d.sPARAMS.KERNEL = 0;
d.nMaxFeatures = 4500;
d.ClassifierName = 'gentleBoost';
d.bNormalizeDataSamples = 1;
d.caNormalizationRegions = [];
d.NormalizationRelativeStrengths = [1];
d.bAbsVal = 0;
d.featuresubset = [];
d.bOverwrite = 1;
d.bAlternateDecimationScheme = 0;
d.bPCAReduceSize = 0;

seedrand;
d.RandSeed = floor(rand*99999);

options = ResolveMissingOptions(options,d);

sPARAMS = options.sPARAMS;

objname{1} = 'car';
objname{2} = 'pedestrian';
objname{3} = 'bicycle';

objs2do = objidx;
for i = objs2do
  on = objname{i};
  if(not(options.bOverwrite))
    if(exist('savename'))
    if(exist(savename))
      fprintf('File exists, continuing\n');
      Model= [];, ye = [];, ROC = [];, yel = [];
      continue;
    end
    end
  end;
  [yfull, NewDataX] = GetNewDataX(Template, variablename, on,Root,options);
  if(size(NewDataX,1) > options.nMaxFeatures), 
    rand('state',options.RandSeed);
    p = randperm(size(NewDataX,1));
    NewDataX = NewDataX(p(1:options.nMaxFeatures),:);
    fprintf('TOO MANY FEATURES: Randomly sampling features');
  end
  L = length(yfull);
  if(options.bRandsplit)
    nTrain = round(options.TrainingPart * L);
    nTest = L - nTrain;
    rand('state',options.RandSeed);
    p = randperm(L);
    Test = p(1:nTest);
    Train = p((nTest+1):end);
  else
    Test = 1:(floor(L * (1-options.TrainingPart)));
    Train = (floor(L * (1-options.TrainingPart))+1):L;
  end
  DXtest = NewDataX(:,Test);
  ytest = yfull(:,Test);
  DXtrain = NewDataX(:,Train);
  ytrain = yfull(:,Train);
  [DXtrain, FeatureSubsample] = SubSampleFeatures(DXtrain, options);
  [DXtrain,NormalizationParams] = InternalNormalize(DXtrain, options);
  DXtest = SubSampleFeatures(DXtest, options, FeatureSubsample);
  DXtest = InternalNormalize(DXtest,options,NormalizationParams);
  if(options.bPCAReduceSize) 
     [U,S,V] = svd(DXtrain,0);
     DXtrain = U'*DXtrain;
     DXtest = U'*DXtest;
  end
  cmd = sprintf('Model = CLS%s(DXtrain,ytrain'',options.sPARAMS);',options.ClassifierName);
  eval(cmd);
  % [yel,ye] = CLSgentleBoostC(DXtest,Model);
  cmd = sprintf('[yel, ye] = CLS%sC(DXtest,Model);',options.ClassifierName);
  eval(cmd)
  ROC = ROCetc2(ye' ,ytest);
  if(exist('savename'))
    save(savename,'HelpTextInfo','yel','ye','ROC','Root','Template','variablename','objidx','Model','options');
  end
end



function [yfull, NewDataX] = GetNewDataX(Template, variablename,on,Root,options)
NewDataX = [];
yfull = [];
if(not(iscell(Template)))
  d = dir(fullfile(Root,sprintf('AppearanceData_128x128_%s*.mat',on)));
  d2 = dir(fullfile(Root,sprintf(Template,on)));
  for iFl = 1:min(length(d),4);
    load(fullfile(Root,d(iFl).name));%-->grayX,toyotaX,y;
    D = load(fullfile(Root,d2(iFl).name));%-->eval(variablename);
    Part = getfield(D,variablename);
    if(isfield(options,'featuresubset'))
         if(not(isempty(options.featuresubset)))
  	   Part = Part(options.featuresubset,:);
	 end
    end
    NewDataX = [NewDataX,Part];
    yfull = [yfull,y]; 
  end
else
  % In order to save memory here, we are going to have to estimate the full
  % size of the matrix to load, and decimate as we build.
  
  
  
  
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%BEFORE EDIT%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  sn = 1;
  d = dir(fullfile(Root,sprintf('AppearanceData_128x128_%s*.mat',on)));
  for iGroup = 1:length(Template)
    d2 = dir(fullfile(Root,sprintf(Template{iGroup},on)));
    sq = 1;
    for iFl = 1:min(length(d),4);
      D = load(fullfile(Root,d2(iFl).name));%-->eval(variablename);
      [n,q] = size(getfield(D,variablename{iGroup}));
      Part = getfield(D,variablename{iGroup});
      if(isfield(options,'featuresubset'))
         if(not(isempty(options.featuresubset)))
  	   Part = Part(options.featuresubset,:);
	 end
      end
      NewDataX(sn:(n+sn-1),sq:(sq+q-1)) = Part;
      sq = sq + q;
      if(iGroup == 1)
        load(fullfile(Root,d(iFl).name),'y');%-->grayX,gradX,toyotaX,y;
        yfull = [yfull,y];
      end 
    end %loop over breaks in data on disk
    sn = size(NewDataX,1) + 1;
    PartSizes(iGroup) = size(Part,1);
  end %loop over data types
  nParts = length(Template);
  [newPartSizes,p] = ComputeNewPartSizes(PartSizes,options.nMaxFeatures);
  if(options.bAlternateDecimationScheme)
    NewDataX = NewDataX(p,:);
  end
end


function [X,NormalizationParams] = InternalNormalize(X,options,NormalizationParams)
if(nargin < 3)
  NormalizationParams = [];
end
if(options.bNormalizeDataSamples > 0)
  if(isempty(options.caNormalizationRegions))
    caNR{1} = 1:size(X,1);
  else
    caNR = options.caNormalizationRegions;
  end
  [X,NormalizationParams] = normalizeByIndex(X, caNR, options.bNormalizeDataSamples,NormalizationParams,options);
end
     

function [XTrainFull, SelectedFeatures] = SubSampleFeatures(XTrainFull, options, SelectedFeatures);
if(nargin < 3)
  SelectedFeatures = 1:size(XTrainFull,1);
  if(size(XTrainFull,1) > options.nMaxFeatures), 
    seedrand(options.RandSeed);
    p = randperm(size(XTrainFull,1));
    XTrainFull = XTrainFull(p(1:options.nMaxFeatures),:);
    SelectedFeatures = p(1:options.nMaxFeatures);
    fprintf('TOO MANY FEATURES: Randomly sampling %d features\n', options.nMaxFeatures);
  end
else
  XTrainFull = XTrainFull(SelectedFeatures,:);
end  

function [newPartSizes,p] = ComputeNewPartSizes(PartSizes,nMaxFeatures);
%if each part is larger than nMaxFeatures / length(PartSizes)
%make each part equally big. Otherwise take all parts wich are less than this limit,
%add the extra to the bin and recurse.
nParts = length(PartSizes);
newPartSizes = zeros(nParts,1);
bPartRepresented = zeros(nParts,1);
done = 0;
while(not(done))
  maxTake = floor(nMaxFeatures / sum(not(bPartRepresented)));
  v = intersect(find(PartSizes < maxTake), find(not(bPartRepresented)));
  newPartSizes(v) = PartSizes(v);
  nMaxFeatures = nMaxFeatures - sum(PartSizes(v));
  bPartRepresented(v) = 1;
  if(not(any(v)))
    v = find(not(bPartRepresented));
    newPartSizes(v) = maxTake;
    bPartRepresented(v) = 1;
  end
  if(all(bPartRepresented))
    done = 1;
  end
end  
s = [0,cumsum(PartSizes)];
p = [];
for i = 1:nParts
  p_i = randperm(PartSizes(i));
  p_i = p_i(1:newPartSizes(i));
  p = [p,s(i)+p_i];
end    


