Streamline Variability Calculation

Transforms a given streamline with PCA into a another space. This streamline points in this space are sampled and the statistical parameters of each cluster (median, variance) are transformed back into the original space.

Contents

Parameter

pYMin = 1;
pYMax = (size(streamlines, 1) / 2);
pXMin  = pYMax + 1;
pXMax = size(streamlines, 1);
colors = 'rbgycm';

streamlines = connections';

if(exist('numClusters', 'var')~=1)
    numClusters = 3;
end

if(exist('highNumberSamples', 'var')~=1)
    highNumberSamples = 0;
end

if(exist('numBasis', 'var')~=1)
    numBasis = 3;
end

if(exist('convInter', 'var')~=1)
    convInter = 0.9;
end

if(exist('numSamples', 'var')~=1)
    numSamples = 30000;
end

sampleOffset = 2;

meanVector = mean(streamlines, 2);

streamlines = streamlines - repmat(meanVector, 1, size(streamlines, 2));

Calculate PCA Basis

if ~highNumberSamples
	[eigenvectors, eigenvalues] = eig(streamlines' * streamlines, 'vector');
else
    [eigenvectors, eigenvalues] = eig(streamlines * streamlines', 'vector');
end
[eigenvectors, eigenvalues] = eigsort(eigenvectors, eigenvalues);

Reduce Streamlines

if ~highNumberSamples
	basis = determineBasis(streamlines, eigenvectors);
else
    basis = eigenvectors;
end
reducedStreamlines = reduceData(basis, numBasis, streamlines);

Cluster Reduced Streamlines with k-Means

lineIDs = kmeans(reducedStreamlines', numClusters);

Calculate the Median Streamline for each Cluster

centerLines = zeros(numClusters, numBasis);

for i = 1:numClusters
    centerLines(i, :) = median(reducedStreamlines(:, lineIDs==i), 2)';

end

reconStreamlines = reconstructData(basis, numBasis, reducedStreamlines, meanVector);
reconCenterLines = reconstructData(basis, numBasis, centerLines', meanVector);

Uniformly Sample each Cluster's Convidence Lobe

The region around all clusters is sampled using the Monte-Carlo Method. The points in a rectengular region are randomly chosen and only those who lie with in the bounds of the convidence elipsoid get chosen. To check if a point lies with the multidimensional elipsoid its Mahalanobis distance is calculated and compared against a threshold.

threshold = sqrt(chi2inv(convInter, numBasis));

for i = 1:numClusters
    gridStreamlines = reducedStreamlines(:,lineIDs == i);
    minStreamlines = min(gridStreamlines, [], 2) - repmat(sampleOffset, numBasis, 1);
    maxStreamlines = max(gridStreamlines, [], 2) + repmat(sampleOffset, numBasis, 1);
    samples = rand(numBasis, numSamples) .* repmat((maxStreamlines - minStreamlines), 1, numSamples) + repmat(minStreamlines, 1, numSamples);
    samples = samples';
    if size(gridStreamlines, 2) > size(gridStreamlines, 1)
        mahalDist = mahal(samples, gridStreamlines');

        samplesInside = samples(mahalDist <= threshold, :)';
        eval(strcat('sampleStreamlines', int2str(i), '=reconstructData(basis, numBasis, samplesInside, meanVector);'));
        if ~highNumberSamples
            samplesInside = samplesInside';
        end
    else
        eval(strcat('sampleStreamlines', int2str(i), '=reconCenterLines(:,',int2str(i),');'));
    end
end

percentCluster = zeros(numClusters, 1);
countClusterTotal = size(lineIDs, 1);
for i = 1:numClusters
    eval(strcat('sampleStreamlines', int2str(i), '=', 'sampleStreamlines', int2str(i), '''', ';'));
    eval(strcat('percentCluster(', int2str(i), ')=sum(lineIDs == ', int2str(i), ') / countClusterTotal;'));
end
reconCenterLines = reconCenterLines';

Calculate Boundary Region for the Sampled Lobes

% for i = 1:numClusters
%     I = zeros(1000, 1000, 'uint8');
%     eval(strcat('sampleStreamlines=sampleStreamlines', int2str(i), ';'));
%     for r = sampleStreamlines'
%         for c = 1:((size(r) / 2) - 1)
%             x = [r(c) r(c + 1)] * 2.5 + 250;
%             y = [r(pXMin + c - 1) r(pXMin + c)] * 2.5+250;
%             nPoints = max(abs(diff(x)), abs(diff(y)))+1;
%             rIndex = round(linspace(y(1), y(2), nPoints));
%             cIndex = round(linspace(x(1), x(2), nPoints));
%             index = sub2ind(size(I), rIndex, cIndex);
%             I(index) = 255;
%         end
%     end
%     se = strel('square',2);
%     I = imdilate(I, se);
%     [x, y] = find(I);
%     k = boundary(x, y, 0.2);
%     x = x(k);
%     y = y(k);
%     eval(strcat('boundary', int2str(i), '=[x, y];'));
% end