0001 function [ data ] = intFindFociCurve( data, CONST, channelID )
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 DEBUG_FLAG = false;
0044 fieldname = ['locus', num2str(channelID)];
0045 options = optimset('MaxIter', 1000, 'Display', 'off', 'TolX', 1/10);
0046
0047
0048 originalImage = double(data.(['fluor',num2str(channelID)]));
0049
0050
0051
0052 hg = fspecial( 'gaussian' , 210, 30 );
0053 highPassImage = originalImage - imfilter( originalImage, hg, 'replicate' );
0054 cytoplasmicFlourescenceSTD = std(double(highPassImage(data.mask_bg)));
0055 if isnan(cytoplasmicFlourescenceSTD)
0056 cytoplasmicFlourescenceSTD = 1;
0057 disp ('Possibly empty mask for image - foci may not be found');
0058 end
0059 normalizedImage = originalImage/cytoplasmicFlourescenceSTD;
0060
0061
0062 normalizedImage = normalizedImage - 1;
0063 normalizedImage(normalizedImage < 0) = 0;
0064
0065 filter_width = 1.5;
0066 [~,~,fluorFiltered] = curveFilter(normalizedImage,filter_width);
0067 data.(['fluor',num2str(channelID),'_filtered']) = fluorFiltered;
0068
0069 mask_mod = bwmorph (data.mask_bg, 'dilate', 1);
0070
0071 fociWatershed = watershed(-fluorFiltered);
0072 maskedFociWatershed = logical(double(fociWatershed).*double(mask_mod));
0073
0074 fociRegionLabels = bwlabel(maskedFociWatershed);
0075 props = regionprops( fociRegionLabels, {'BoundingBox'} );
0076 numFociRegions = numel(props);
0077 imsize = size(highPassImage);
0078
0079
0080 focusInit.r = [nan,nan];
0081 focusInit.score = nan;
0082 focusInit.intensity = nan;
0083 focusInit.normIntensity = nan;
0084 focusInit.shortaxis = nan;
0085 focusInit.longaxis = nan;
0086 focusInit.fitSigma = nan;
0087 focusInit.fitScore = nan;
0088
0089 fociData = [];
0090 cellIDs = [];
0091
0092 if DEBUG_FLAG
0093 figure(2);
0094 clf;
0095 end
0096
0097 for ii = 1:numFociRegions
0098 tempData = focusInit;
0099
0100 [xPad,yPad] = getBBpad( props(ii).BoundingBox, imsize, 3 );
0101 [meshX,meshY] = meshgrid(xPad, yPad);
0102
0103 maskToFit = (fociRegionLabels(yPad, xPad) == ii);
0104 imageToFit = fluorFiltered(yPad, xPad);
0105 imageToFit = imageToFit .* double(maskToFit);
0106
0107 [~, maxIndex] = max(imageToFit(maskToFit));
0108
0109 tempImage = imageToFit(maskToFit);
0110 tempData.intensity = tempImage(maxIndex);
0111
0112 tempImage = meshX(maskToFit);
0113 fociX = tempImage(maxIndex);
0114 tempData.r(1) = fociX;
0115
0116 tempImage = meshY(maskToFit);
0117 fociY = tempImage(maxIndex);
0118 tempData.r(2) = fociY;
0119
0120
0121 maskSize = [numel(yPad),numel(xPad)];
0122
0123
0124 cellsLabel = data.regs.regs_label(yPad,xPad);
0125 cellsMask = logical(cellsLabel);
0126 tempMask = zeros(maskSize);
0127
0128 tempMask(fociY - yPad(1)+1, fociX - xPad(1)+1 ) = 1;
0129 distanceToFoci = bwdist( tempMask );
0130
0131 cellIDList = cellsLabel(cellsMask);
0132 [~, minDistanceIndex] = min(distanceToFoci(cellsMask));
0133 bestCellID = cellIDList(minDistanceIndex);
0134
0135 if ~isempty( bestCellID )
0136 croppedImage = highPassImage(data.CellA{bestCellID}.yy, data.CellA{bestCellID}.xx);
0137 cellFlouresenseSTD = std(croppedImage(data.CellA{bestCellID}.mask));
0138
0139 if tempData.intensity >0
0140
0141 backgroundIntensity = 0;
0142 gaussianIntensity = fluorFiltered(fociY, fociX) - backgroundIntensity;
0143 sigmaValue = 1;
0144
0145 parameters(1) = fociX;
0146 parameters(2) = fociY;
0147 parameters(3) = gaussianIntensity;
0148 parameters(4) = sigmaValue;
0149
0150
0151 [parameters] = fminsearch( @doFit, parameters, options);
0152
0153 gaussianApproximation = makeGassianTestImage(meshX, meshY, parameters(1), parameters(2), parameters(3), backgroundIntensity, parameters(4));
0154
0155
0156 croppedImage = imageToFit;
0157 croppedImage(gaussianApproximation < 0.1 * max(max(gaussianApproximation))) = 0;
0158
0159 imageTotal = sqrt(sum(sum(croppedImage)));
0160 guassianTotal = sqrt(sum(sum(gaussianApproximation)));
0161
0162 fitScore = sum(sum(sqrt(croppedImage) .* sqrt(gaussianApproximation))) / (imageTotal * guassianTotal);
0163
0164 if DEBUG_FLAG
0165 figure(1);
0166 clf;
0167 subplot(2, 2, 1);
0168 imshow(imageToFit, []);
0169 subplot(2, 2, 2);
0170 imshow(croppedImage, []);
0171 subplot(2, 2, 3);
0172 imshow(gaussianApproximation, []);
0173 subplot(2, 2, 4);
0174 title(['Score: ', num2str(fitScore)]);
0175 keyboard;
0176 end
0177
0178 tempData.r(1) = parameters(1);
0179 tempData.r(2) = parameters(2);
0180 tempData.fitSigma = parameters(4);
0181 tempData.intensity = parameters(3);
0182 tempData.fitScore = fitScore;
0183
0184
0185 tempData.normIntensity = tempData.intensity;
0186 tempData.score = tempData.intensity / (sqrt(pi)*tempData.fitSigma) * tempData.fitScore;
0187 tempData.shortaxis = ...
0188 (tempData.r-data.CellA{bestCellID}.coord.rcm)*data.CellA{bestCellID}.coord.e2;
0189 tempData.longaxis = ...
0190 (tempData.r-data.CellA{bestCellID}.coord.rcm)*data.CellA{bestCellID}.coord.e1;
0191
0192
0193
0194 cellIDs(ii) = bestCellID;
0195 focusData(ii) = tempData;
0196 if DEBUG_FLAG
0197 figure(2);
0198 hold on;
0199 plot(fociX, fociY, '.r' );
0200 text(fociX, fociY, num2str( tempData.intensity, '%1.2g' ));
0201 end
0202 end
0203 end
0204 end
0205
0206
0207
0208 for ii = 1:data.regs.num_regs
0209
0210 fociIndex = find(cellIDs == ii);
0211 tempData = focusData(fociIndex);
0212
0213 [~, order] = sort( [tempData.intensity], 'descend' );
0214 sortedFoci = tempData(order);
0215
0216 focus = focusInit;
0217 if numel(sortedFoci) > 0
0218 maxIndex = find([sortedFoci.intensity] > 0.333 * sortedFoci(1).intensity);
0219 if numel(maxIndex) > CONST.trackLoci.numSpots(channelID)
0220 maxIndex = maxIndex(1:CONST.trackLoci.numSpots(channelID));
0221 end
0222
0223 numFoci = numel(maxIndex);
0224
0225 for jj = 1:numFoci
0226 focus(jj) = sortedFoci(jj);
0227 end
0228 end
0229
0230 scores = [focus(:).score];
0231 focus = focus(~isnan(scores));
0232 data.CellA{ii}.(fieldname) = focus;
0233
0234
0235 xPad = data.CellA{ii}.xx;
0236 yPad = data.CellA{ii}.yy;
0237 data.CellA{ii}.(['fluor',num2str(channelID),'_filtered'])=fluorFiltered( yPad, xPad );
0238 end
0239
0240 function error = doFit(parameters)
0241
0242
0243
0244
0245
0246
0247
0248
0249 gaussian = makeGassianTestImage(meshX, meshY, parameters(1), parameters(2), parameters(3), backgroundIntensity, parameters(4));
0250 tempImage = (double(imageToFit) - gaussian);
0251 error = sum(sum(tempImage.^2));
0252 end
0253
0254 function testImage = makeGassianTestImage(meshX, meshY, fociX, fociY, gaussianIntensity, backgroundIntensity, sigmaValue)
0255 testImage = backgroundIntensity + gaussianIntensity * exp( -((meshX - fociX).^2 + (meshY - fociY).^2)/(2 * sigmaValue^2) );
0256 end
0257
0258 end