diff --git a/functions/clusterSpots.m b/functions/clusterSpots.m index 6e72380..ac0800a 100644 --- a/functions/clusterSpots.m +++ b/functions/clusterSpots.m @@ -1,182 +1,185 @@ function clusterSpots() global X; % Get the kind of clustering we will be doing is_do_manual = getFromTag('is_do_manual'); is_do_brute = getFromTag('is_do_brute'); is_do_kmeans = getFromTag('is_do_kmeans'); % Check if we remove empty clusters is_remove_empty = getFromTag('is_no_empty_clusters'); % Grab the Spot Object in the Scene nS = X.GetNumberOf('Spots'); if nS > 1 [~, nS] = X.SelectDialog('Spots'); end spots = X.GetObject('Type', 'Spots', 'Number', nS); % Grab the channels we will be using chanIdx = getChannelIndexes(); % Grab the stats we need, namely Intensity Mean spotsData = X.GetSelectedStatistics(spots, 'Intensity Mean'); % To cluster, we need an nx2 array with % col1: spotID % col2: Value of selected statistic % Get the indices of the chosen statistic % Build what we need selectedIds = spotsData.ids+1; selectedChannels = cell2mat(spotsData.factors(:,2)); selectedValues = spotsData.values; +%ID FIX from imaris 8 onwards, they might not be continuous, so instead of +%bothering with them, try to create our own IDs. (For each channel) +id_idx = unique(selectedIds); % for all the Ids and all Channels, will fill all values from the chosen statistic for i = 1:length(selectedValues) - fullSpotsDataForCluster(selectedIds(i),str2num(selectedChannels(i))) = selectedValues(i); + fullSpotsDataForCluster(find(id_idx == selectedIds(i)),str2num(selectedChannels(i))) = selectedValues(i); end % Finished data for clustering spotsClusterData = fullSpotsDataForCluster(:,chanIdx); % Clear some memory fullSpotsDataForCluster = []; %Spot Grouping spotGrouping = getFromTag('txt_grouping_distance', 'Number'); % Z compensation zComp = getFromTag('txt_z_compensation_factor', 'Number'); % Grouping Distance for after clustering minDist = getFromTag('txt_grouping_distance', 'Number'); if is_do_manual % Just grab all the channels and all the values and then use the % equivalent of the brute-force to get the results % How many categories per channel nCat = getFromTag('txt_manual_cat_num', 'Number'); % Make an array of edges for each channel edges = zeros(numel(chanIdx), nCat+2); % +2 to include 0 and Infinity edges(:,end) = Inf; % Everything in double loop, first channels for c=1:numel(chanIdx) %get BG edges(c,2) = getFromTag(sprintf('txt_manual_bg_ch_%d',chanIdx(c)), 'Number'); % Now for each category for n=1:(nCat-1) edges(c,2+n) = getFromTag(sprintf('txt_manual_cat_%d_ch_%d',n,chanIdx(c)), 'Number'); end end [edges, clusterIndexes ] = sortManual(spotsClusterData, edges); % create a Parent folder with the Cluster Number manualFolder = X.CreateGroup(sprintf('Manual Clustering %d categories per channel, Z Compensation [%d]', nCat, zComp )); X.AddToScene(manualFolder); clusterDistances(spotsData, clusterIndexes, zComp, minDist, manualFolder); disp('Manual Clustering DONE'); edges end if is_do_brute % Here we use a very simple method to cluster them : % Check on each channel for the intensities and categorise them. a % binning into N categories for each channel. nCat = getFromTag('txt_brute_cat_num', 'Number'); max = getFromTag('txt_brute_max', 'Number'); bg = getFromTag('txt_brute_bg', 'Number'); [centroids, clusterIndexes ] = sortBrute(spotsClusterData, nCat, max, bg); if (is_remove_empty) [centroids, clusterIndexes ] = removeEmptyClusters(centroids, clusterIndexes); end % create a Parent folder with the Cluster Number bruteFolder = X.CreateGroup(sprintf('Brute Force Clustering %d categories per channel, Z Compensation [%d]', nCat, zComp )); X.AddToScene(bruteFolder); clusterDistances(spotsData, clusterIndexes, zComp, minDist, bruteFolder); disp('Brute Force Clustering DONE'); centroids end if is_do_kmeans % Use separate clusterings per channel? is_sep_kmeans = getFromTag('is_sep_kmeans'); if is_sep_kmeans nClusterPerChannel = getFromTag('txt_kmeans_sep_cluster_num', 'Number'); opts = statset('Display','final'); str = ''; for i=1:numel(chanIdx) [clusterIndexes(:,i), centroids(:,i)] = kmeans(spotsClusterData(:,i),nClusterPerChannel,... 'start','plus',... 'replicates',50,... 'emptyaction','drop',... 'Options',opts); str = [str '%d']; end [C ia ic] = unique(clusterIndexes, 'rows'); % for the indexes, make a new array from 1 to to numger of unique % rows newIdx = 1:size(C,1); % Get the centroids cent = []; for c=1:numel(chanIdx) cent = [cent centroids(C(:,c),c)]; end newIdx = newIdx(ic); centroids = cent; if (is_remove_empty) [centroids, newIdx ] = removeEmptyClusters(centroids, newIdx); end % create a Parent folder with the Cluster Number sepkMeansFolder = X.CreateGroup(sprintf('Separate K-Means With %d Clusters per Channel, Z Compensation [%d]', nClusterPerChannel, zComp )); X.AddToScene(sepkMeansFolder); clusterDistances(spotsData, newIdx, zComp, minDist, sepkMeansFolder); else nClusters = getFromTag('txt_kmeans_cluster_num', 'Number'); opts = statset('Display','final'); [clusterIndexes, centroids] = kmeans(spotsClusterData,nClusters,... 'start','plus',... 'replicates',50,... 'emptyaction','drop',... 'Options',opts); % create a Parent folder with the Cluster Number kMeansFolder = X.CreateGroup(sprintf('K-Means With %d Clusters, Z Compensation [%d]', nClusters, zComp )); X.AddToScene(kMeansFolder); if (is_remove_empty) [centroids, clusterIndexes ] = removeEmptyClusters(centroids, newIdx); end clusterDistances(spotsData, clusterIndexes, zComp, minDist, kMeansFolder); disp('K-Means Clustering DONE'); end centroids end end