function [data500, data750, data999] = loadFilteredData(maxSphericity2, ...
    maxRelRoughness, minBrightFactor)

% load all data
% data was generated with rev443 and parameters:
% 'minConvexity', 0.9
% 'minDiameter', 100
% 'maxSphericity2', 0.97
% 'maxAngleGap', 2*pi/10
% maxRoundness = 0.7;

% "original"
% data500 = load('localData/exp246_500rpm_resultStruct.mat');
% data500 = load('localData/exp247_500rpm_resultStruct.mat');
% dataAAA = load('localData/exp243_1000rpm2_resultStruct.mat');

% "n2"
% data500 = load('localData/exp252_500rpm_n2_resultStruct.mat');
% data750 = load('localData/exp253_1000rpm_n2_resultStruct.mat');
% data999 = load('localData/exp251_1500rpm_n2_resultStruct.mat');


% "final"
data500 = load('localData/exp255_500rpm_f_resultStruct.mat');
data750 = load('localData/exp254_1800rpm_f_resultStruct.mat');
% data999 = load('localData/exp1800_1800rpm_f_resultStruct.mat');
data999 = load('localData/exp252_500rpm_n2_resultStruct.mat');


% transfer to new structure
data500 = handleDataSet(data500.timeResult, data500.timeGrid);
data750 = handleDataSet(data750.timeResult, data750.timeGrid);
data999 = handleDataSet(data999.timeResult, data999.timeGrid);
% dataAAA = handleDataSet(dataAAA.timeResult, dataAAA.timeGrid);

% filter data: note that the fitting algorithm already applied some of
%   these limits

filterVector = true(size(data500.time));
% filterVector = filterVector & (data500.sphericity2 < maxSphericity2);
filterVector = filterVector & (data500.relativeRoughness < maxRelRoughness);
filterVector = filterVector & (data500.width < 2000);
filterVector = filterVector & (data500.width >= 100);
% filterVector = filterVector & (data500.roundness <= maxRoundness | ...
%     (data500.brightFactorH > minBrightFactor & ...
%      data500.brightFactorM > minBrightFactor));
filterVector = filterVector & (...
    (data500.brightFactorH > minBrightFactor & ...
     data500.brightFactorM > minBrightFactor));
data500 = filterData(data500, filterVector);

filterVector = true(size(data750.time));
% filterVector = filterVector & (data750.sphericity2 < maxSphericity2);
filterVector = filterVector & (data750.relativeRoughness < maxRelRoughness);
filterVector = filterVector & (data750.width < 2000);
filterVector = filterVector & (data750.width >= 100);
% filterVector = filterVector & (data750.roundness <= maxRoundness | ...
%     (data750.brightFactorH >= minBrightFactor & ...
%      data750.brightFactorM >= minBrightFactor));
filterVector = filterVector & (...
    (data750.brightFactorH >= minBrightFactor & ...
     data750.brightFactorM >= minBrightFactor));
data750 = filterData(data750, filterVector);

filterVector = true(size(data999.time));
% filterVector = filterVector & (data999.sphericity2 < maxSphericity2);
filterVector = filterVector & (data999.relativeRoughness < maxRelRoughness);
filterVector = filterVector & (data999.width < 2000);
filterVector = filterVector & (data999.width >= 100);
% filterVector = filterVector & (data999.roundness <= maxRoundness | ...
%     (data999.brightFactorH >= minBrightFactor & ...
%      data999.brightFactorM >= minBrightFactor));
filterVector = filterVector & (...
    (data999.brightFactorH >= minBrightFactor & ...
     data999.brightFactorM >= minBrightFactor));
data999 = filterData(data999, filterVector);

% filterVector = true(size(dataAAA.time));
% filterVector = filterVector & (dataAAA.sphericity2 < maxSphericity2);
% filterVector = filterVector & (dataAAA.relativeRoughness < maxRelRoughness);
% filterVector = filterVector & (dataAAA.width < 2000);
% filterVector = filterVector & (dataAAA.width >= 100);
% filterVector = filterVector & (dataAAA.roundness <= maxRoundness | ...
%     (dataAAA.brightFactorH >= minBrightFactor & ...
%      dataAAA.brightFactorM >= minBrightFactor));
% dataAAA = filterData(dataAAA, filterVector);

end


function data = handleDataSet(timeResult, timeGrid)
data = struct('time', [], ...
    'width', [], 'lambda', [], 'lambdaH', [], 'lambdaM', [], ...
    'roughness', [], 'convexity', [], 'sphericity2', [], ...
    'brightFactorH', [], 'brightFactorM', []);

for iTime = 1:length(timeResult)
    nSample = length(timeResult(iTime).lambda);
    
    % data vectors
    data.time = [data.time ones(1, nSample)*timeGrid(iTime)];
    
    data.width = [data.width timeResult(iTime).meanWidth];
    data.lambda = [data.lambda timeResult(iTime).lambda];
    data.lambdaH = [data.lambdaH timeResult(iTime).lambdaH];
    data.lambdaM = [data.lambdaM timeResult(iTime).lambdaM];
    
    data.roundness = 2*data.lambda ./ data.width;
    
    data.roughness = [data.roughness timeResult(iTime).roughness];
    data.convexity = [data.convexity timeResult(iTime).convexity];
    data.sphericity2 = [data.sphericity2 timeResult(iTime).sphericity2];
    
    data.brightFactorH = [data.brightFactorH timeResult(iTime).brightFactorH];
    data.brightFactorM = [data.brightFactorM timeResult(iTime).brightFactorM];
end 

% some secondary data
data.relativeRoundness = (2*data.lambda ./ data.width);
% data.relativeRoundness = data.roundness ./ data.width;
data.relativeRoughness = data.roughness ./ data.width;

% check for relative roundness < 1 (sanity)
if any(data.relativeRoundness > 1.01)
    warning('input data is not sane: 2[lambda] > mean width');
end

end

function data = filterData(data, filterVector)

fieldNameList = fieldnames(data);
for iField = 1:length(fieldNameList)
    data.(fieldNameList{iField}) = data.(fieldNameList{iField})(filterVector);
end
end