0001 function [data_c, data_r, cell_count,resetRegions] = errorRez (time, ...
0002 data_c, data_r, data_f, CONST, cell_count, header, ignoreError, debug_flag)
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 global REMOVE_STRAY
0043 global header_string
0044 global regToDelete
0045
0046 header_string = header;
0047 verbose = CONST.parallel.verbose;
0048 MIN_LENGTH = 10;
0049 REMOVE_STRAY = CONST.trackOpti.REMOVE_STRAY;
0050 DA_MIN = CONST.trackOpti.DA_MIN;
0051 DA_MAX = CONST.trackOpti.DA_MAX;
0052 regToDelete = [];
0053 resetRegions = false;
0054 minAreaToMerge = CONST.trackOpti.SMALL_AREA_MERGE;
0055
0056
0057 cArea = [data_c.regs.props.Area];
0058 data_c.regs.ID = zeros(1,data_c.regs.num_regs);
0059 modRegions = [];
0060
0061 for regNum = 1 : data_c.regs.num_regs;
0062
0063 if data_c.regs.ID(regNum) ~= 0
0064 disp ([header, 'ErRes: Frame: ', num2str(time), ' already has an id ',num2str(regNum)]);
0065 elseif ismember (regNum,modRegions)
0066 disp ([header, 'ErRes: Frame: ', num2str(time), ' already modified ',num2str(regNum)]);
0067 else
0068
0069 rCellsFromC = data_c.regs.map.r{regNum};
0070
0071 if ~isempty(rCellsFromC)
0072 cCellsFromR = data_r.regs.map.f{rCellsFromC};
0073 cCellsTransp = data_c.regs.revmap.r{rCellsFromC};
0074 else
0075 cCellsFromR = [];
0076 cCellsTransp = [];
0077 end
0078
0079
0080 if numel(rCellsFromC) == 0
0081
0082
0083 if (time ~= 1) && (hasNoFwMapping(data_c,regNum) && REMOVE_STRAY)
0084
0085
0086 data_c.regs.error.label{regNum} = ['Frame: ', num2str(time), ...
0087 ', reg: ', num2str(regNum), '. is a stray region - Deleted.'];
0088 if verbose
0089 disp([header, 'ErRes: ',data_c.regs.error.label{regNum}] );
0090 end
0091 regToDelete = [regToDelete;regNum];
0092 resetRegions = true;
0093 else
0094 if time~=1
0095 data_c.regs.error.label{regNum} = ['Frame: ', num2str(time), ...
0096 ', reg: ', num2str(regNum), '. is a stray region.'];
0097 if verbose
0098 disp([header, 'ErRes: ',data_c.regs.error.label{regNum}] );
0099 end
0100 end
0101 [data_c,cell_count] = createNewCell (data_c, regNum, time, cell_count);
0102 end
0103
0104 elseif numel(rCellsFromC) == 1 && numel (cCellsTransp) == 1 && all(cCellsFromR == regNum)
0105
0106
0107 errorStat = (data_c.regs.error.r(regNum)>0);
0108 [data_c, data_r] = continueCellLine( data_c, regNum, data_r, rCellsFromC, time, errorStat);
0109
0110 elseif numel(rCellsFromC) == 1 && numel (cCellsTransp) == 1 && ~all(cCellsFromR == regNum)
0111
0112
0113 errorStat = (data_c.regs.error.r(regNum)>0);
0114 [data_c, data_r] = continueCellLine( data_c, regNum, data_r, rCellsFromC, time, errorStat);
0115
0116 elseif numel(rCellsFromC) == 1 && numel(cCellsFromR) == 1 && numel (cCellsTransp) == 2
0117
0118
0119
0120 sister1 = regNum;
0121 sister2 = cCellsTransp (cCellsTransp~=regNum);
0122 mapRC = cCellsTransp;
0123 mother = rCellsFromC;
0124
0125 if debug_flag
0126
0127 imshow(cat(3,0.5*ag(data_c.phase) + 0.5*ag(data_c.regs.regs_label==sister1),...
0128 ag(data_r.regs.regs_label == mother),ag(data_c.regs.regs_label==sister2)));
0129 end
0130
0131 totAreaC = data_c.regs.props(sister1).Area + data_c.regs.props(sister2).Area;
0132 totAreaR = data_r.regs.props(mother).Area;
0133 AreaChange = (totAreaC-totAreaR)/totAreaC;
0134 goodAreaChange = (AreaChange > DA_MIN && AreaChange < DA_MAX);
0135 haveNoMatch = (isempty(data_c.regs.map.f{sister1}) || isempty(data_c.regs.map.f{sister2}));
0136 matchToTheSame = ~haveNoMatch && all(ismember(data_c.regs.map.f{sister1}, data_c.regs.map.f{sister2}));
0137 oneIsSmall = (cArea(sister1) < minAreaToMerge) || (cArea(sister2) < minAreaToMerge);
0138 if goodAreaChange && ~ignoreError && ~isempty(data_f) && (haveNoMatch || matchToTheSame || oneIsSmall)
0139
0140
0141 [data_c,mergeReset] = merge2Regions (data_c, [sister1, sister2], CONST);
0142 modRegions = [modRegions;col(cCellsTransp)];
0143 resetRegions = (resetRegions || mergeReset);
0144 elseif goodAreaChange
0145 [data_c, data_r, cell_count] = createDivision (data_c,data_r,mother,sister1,sister2, cell_count, time,header, verbose);
0146 modRegions = [modRegions;col(cCellsTransp)];
0147 else
0148
0149 [data_c,data_r,cell_count,reset_tmp,modids_tmp] = mapBestOfTwo (data_c, mapRC, data_r, rCellsFromC, time, verbose, cell_count,header,data_f);
0150 resetRegions = or(reset_tmp,resetRegions);
0151 modRegions = [modRegions;col(modids_tmp)];
0152 end
0153
0154 elseif numel(rCellsFromC) == 1 && numel(cCellsFromR) == 2
0155
0156 mother = rCellsFromC;
0157 sister1 = regNum;
0158 mapRC = data_r.regs.map.f{mother};
0159 sister2 = mapRC (mapRC~=regNum);
0160 sister2Mapping = data_c.regs.map.r{sister2};
0161
0162 if numel(sister2) == 1 && any(mapRC==regNum) && ~isempty(sister2Mapping) && all(sister2Mapping == mother)
0163
0164 totAreaC = data_c.regs.props(sister1).Area + data_c.regs.props(sister2).Area;
0165 totAreaR = data_r.regs.props(mother).Area;
0166 AreaChange = (totAreaC-totAreaR)/totAreaC;
0167 goodAreaChange = (AreaChange > DA_MIN && AreaChange < DA_MAX);
0168 haveNoMatch = ~isempty(data_f) && (isempty(data_c.regs.map.f{sister1}) || isempty(data_c.regs.map.f{sister2}));
0169 matchToTheSame = ~isempty(data_f) && ~haveNoMatch && all(ismember(data_c.regs.map.f{sister1}, data_c.regs.map.f{sister2}));
0170 oneIsSmall = (cArea(sister1) < minAreaToMerge) || (cArea(sister2) < minAreaToMerge);
0171
0172 if goodAreaChange && ~ignoreError && (haveNoMatch || matchToTheSame || oneIsSmall)
0173
0174 if ~ignoreError
0175 [data_c,reset_tmp] = merge2Regions (data_c, [sister1, sister2], CONST);
0176 modRegions = [modRegions;col(mapRC) ];
0177 else
0178 [data_c,data_r,cell_count,reset_tmp,modids_tmp] = mapBestOfTwo (data_c, mapRC, data_r, rCellsFromC, time, verbose, cell_count,header,data_f);
0179 modRegions = [modRegions;col(modids_tmp)];
0180 end
0181 resetRegions = or(reset_tmp,resetRegions);
0182 else
0183 [data_c, data_r, cell_count] = createDivision (data_c,data_r,mother,sister1,sister2, cell_count, time,header, verbose);
0184 modRegions = [modRegions;col(mapRC) ];
0185 end
0186 elseif numel(sister2) == 1 && any(mapRC==regNum) && any(data_c.regs.map.r{sister2} ~= mother)
0187
0188 errorStat = (data_c.regs.error.r(regNum)>0);
0189 [data_c, data_r] = continueCellLine( data_c, regNum, data_r, rCellsFromC, time, errorStat);
0190
0191 elseif ~any(mapRC==regNum)
0192
0193
0194
0195
0196
0197
0198
0199
0200 sister1 = regNum;
0201 sister2 = mapRC(1);
0202 sister3 = mapRC(2);
0203
0204
0205 [data_c,cell_count] = createNewCell (data_c, regNum, time, cell_count);
0206 data_c.regs.error.r(regNum) = 1;
0207 data_c.regs.error.label{regNum} = ['Frame: ', num2str(time),...
0208 ', reg: ', num2str(regNum),'. Incorrect Mapping 1 to 2 - making a new cell'];
0209
0210 if verbose
0211 disp([header, 'ErRes: ', data_c.regs.error.label{regNum}]);
0212 end
0213
0214 if debug_flag
0215 imshow(cat(3,0.5*ag(data_c.phase) + 0.5*ag(data_c.regs.regs_label==regNum), ...
0216 ag((data_c.regs.regs_label == mapRC(1)) + ...
0217 (data_c.regs.regs_label==mapRC(2))),ag(data_r.regs.regs_label==mother)));
0218 end
0219 else
0220 data_c.regs.error.label{regNum} = ['Frame: ', num2str(time),...
0221 ', reg: ', num2str(regNum),'. Error not fixed - two to 1 but don''t know what to do.'];
0222
0223 if verbose
0224 disp([header, 'ErRes: ', data_c.regs.error.label{regNum}]);
0225 end
0226
0227 end
0228 elseif numel(rCellsFromC) > 1
0229
0230
0231
0232
0233
0234
0235
0236
0237 if debug_flag
0238 imshow(cat(3,0.5*ag(data_c.phase), 0.7*ag(data_c.regs.regs_label==regNum),...
0239 ag((data_r.regs.regs_label==rCellsFromC(1)) + (data_r.regs.regs_label==rCellsFromC(2)))));
0240 end
0241
0242
0243 if ~ignoreError
0244 [data_c,success] = missingSeg2to1 (data_c,regNum,data_r,rCellsFromC,CONST);
0245 else
0246 success = false;
0247 end
0248
0249 if success
0250 data_c.regs.error.r(regNum) = 0;
0251 data_c.regs.error.label{regNum} = ['Frame: ', num2str(time),...
0252 ', reg: ', num2str(regNum),'. Segment added to fix 2 to 1 error'];
0253
0254 if verbose
0255 disp([header, 'ErRes: ', data_c.regs.error.label{regNum}]);
0256 end
0257 if debug_flag
0258 imshow(cat(3,ag(data_c.regs.regs_label == regNum)+0.5*ag(data_c.phase),...
0259 ag(data_r.regs.regs_label == rCellsFromC(1)),...
0260 ag(data_r.regs.regs_label == rCellsFromC(2))));
0261 end
0262 resetRegions = true;
0263 else
0264
0265 [data_c,data_r] = mapToBestOfTwo (data_c, regNum, data_r, rCellsFromC, time, verbose,header);
0266 end
0267
0268
0269 elseif numel(rCellsFromC) == 1 && numel(cCellsFromR) > 2
0270
0271 haveNoMatch = any(isempty({data_c.regs.map.f{cCellsFromR}}));
0272 forwMap = [data_c.regs.map.f{cCellsFromR}];
0273 forwardMap = unique(forwMap);
0274 occur = histc(forwMap,forwardMap);
0275 matchToTheSame = ~haveNoMatch && numel(forwardMap)==1;
0276 someMatchToSame = ~haveNoMatch && any(occur>1);
0277
0278 if ~isempty(data_f) && (haveNoMatch || matchToTheSame)
0279
0280 if ~ignoreError
0281 [data_c,reset_tmp] = merge2Regions (data_c, cCellsFromR, CONST);
0282 modRegions = [modRegions;col(cCellsFromR)];
0283
0284
0285
0286 end
0287 resetRegions = or(reset_tmp,resetRegions);
0288 elseif ~isempty(data_f) && (someMatchToSame)
0289 indFwMap = find(occur>1);
0290 valueFw = forwardMap(indFwMap);
0291 cellsToMerge = [];
0292 for i = 1 : numel(cCellsFromR)
0293 cur_cell = cCellsFromR(i);
0294 if any(data_c.regs.map.f{cur_cell} == valueFw)
0295 cellsToMerge = [cellsToMerge ;cur_cell];
0296 end
0297
0298 end
0299 [data_c,reset_tmp] = merge2Regions (data_c, cellsToMerge, CONST);
0300 modRegions = [modRegions;col(cellsToMerge)];
0301 resetRegions = or(reset_tmp,resetRegions);
0302 end
0303 else
0304
0305 data_c.regs.error.label{regNum} = ['Frame: ', num2str(time),...
0306 ', reg: ', num2str(regNum),'. Error not fixed'];
0307
0308 if verbose
0309 disp([header, 'ErRes: ', data_c.regs.error.label{regNum}]);
0310 end
0311 if debug_flag
0312 intDisplay (data_r,rCellsFromC,data_c,regNum);
0313
0314 end
0315
0316 end
0317
0318 end
0319 end
0320
0321 [data_c] = deleteRegions( data_c,regToDelete);
0322
0323 end
0324
0325
0326
0327 function intDisplay (data_c,regC,data_f,regF)
0328
0329
0330
0331
0332
0333
0334 maskC = data_c.regs.regs_label*0;
0335 for c = 1 : numel(regC)
0336 if ~isnan(regC(c))
0337 maskC = maskC + (data_c.regs.regs_label == regC(c))>0;
0338 end
0339 end
0340
0341 if ~isempty (data_f)
0342 maskF = data_f.regs.regs_label*0;
0343 if isempty(regF)
0344 disp('nothing')
0345 imshow (cat(3,0*ag(maskF),ag(maskC),ag(data_c.mask_cell)));
0346 else
0347 for f = 1 : numel(regF)
0348 if ~isnan(regF(f))
0349 maskF = maskF + (data_f.regs.regs_label == regF(f))>0;
0350 end
0351 end
0352 imshow (cat(3,ag(maskF),ag(maskC),ag(data_c.mask_cell)));
0353 end
0354 end
0355 end
0356
0357
0358
0359
0360 function [ data_c, data_r, cell_count ] = createDivision (data_c,data_r,mother,sister1,sister2, cell_count, time, header, verbose)
0361
0362 data_c.regs.error.label{sister1} = (['Frame: ', num2str(time),...
0363 ', reg: ', num2str(sister1),' and ', num2str(sister2),' . cell division from mother reg', num2str(mother),'. [L1,L2,Sc] = [',...
0364 num2str(data_c.regs.L1(sister1),2),', ',num2str(data_c.regs.L2(sister1),2),...
0365 ', ',num2str(data_c.regs.scoreRaw(sister1),2),'].']);
0366 if verbose
0367 disp([header, 'ErRes: ', data_c.regs.error.label{sister1}] );
0368 end
0369 data_r.regs.error.r(mother) = 0;
0370 data_c.regs.error.r(sister1) = 0;
0371 data_c.regs.error.r(sister2) = 0;
0372 [data_c, data_r, cell_count] = markDivisionEvent( ...
0373 data_c, sister1, data_r, mother, time, 0, sister2, cell_count);
0374
0375 end
0376
0377
0378 function result = hasNoFwMapping (data_c,regNum)
0379 result = isempty(data_c.regs.map.f{regNum});
0380 end
0381
0382
0383 function [data_c,data_r] = mapToBestOfTwo (data_c, regNum, data_r, mapCR, time, verbose,header)
0384
0385
0386
0387 flaggerC = (data_c.regs.idsC.r(1,:) == regNum) & isnan(data_c.regs.idsC.r(2,:));
0388 flaggerR1 = (data_c.regs.idsR.r(1,:) == mapCR(1)) & isnan(data_c.regs.idsR.r(2,:));
0389 flaggerR2 = (data_c.regs.idsR.r(1,:) == mapCR(2)) & isnan(data_c.regs.idsR.r(2,:));
0390
0391 loc1 = find(flaggerC&flaggerR1);
0392 loc2 = find(flaggerC&flaggerR2);
0393 cost1 = data_c.regs.cost.r(loc1);
0394 cost2 = data_c.regs.cost.r(loc2);
0395
0396 if isempty(cost2) || cost1<cost2 || isnan(cost2)
0397 data_c.regs.error.r(regNum) = 2;
0398 errorStat = 1;
0399 data_c.regs.error.label{regNum} = ['Frame: ', num2str(time),...
0400 ', reg: ', num2str(regNum),'. Map to minimum cost'];
0401
0402 if verbose
0403 disp([header, 'ErRes: ', data_c.regs.error.label{regNum}]);
0404 end
0405 [data_c, data_r] = continueCellLine(data_c, regNum, data_r, mapCR(1), time, errorStat);
0406
0407 else
0408 errorStat = 1;
0409 data_c.regs.error.r(regNum) = 2;
0410 data_c.regs.error.label{regNum} = ['Frame: ', num2str(time),...
0411 ', reg: ', num2str(regNum),'. Map to minimum cost'];
0412
0413 if verbose
0414 disp([header, 'ErRes: ', data_c.regs.error.label{regNum}]);
0415 end
0416
0417 [data_c, data_r] = continueCellLine(data_c, regNum, data_r, mapCR(2), time, errorStat);
0418
0419 end
0420 end
0421
0422
0423 function [data_c,data_r,cell_count,resetRegions,idsOfModRegions] = mapBestOfTwo ...
0424 (data_c, mapRC, data_r, mapCR, time, verbose, cell_count,header,data_f)
0425
0426 global regToDelete
0427 global REMOVE_STRAY
0428 resetRegions = 0;
0429 [~,minInd] = min (data_c.regs.dA.r(mapRC));
0430 keeper = mapRC(minInd);
0431 remove = mapRC(mapRC~=keeper);
0432 errorStat = (data_c.regs.error.r(keeper)>0);
0433 [data_c, data_r] = continueCellLine( data_c, keeper, data_r, mapCR, time, errorStat);
0434 data_c.regs.revmap.r{mapCR} = keeper;
0435 data_c.regs.error.r(remove) = 1;
0436
0437 idsOfModRegions = [col(remove);col(keeper)];
0438
0439 if REMOVE_STRAY && ~isempty(data_f) && hasNoFwMapping(data_c,remove)
0440 data_c.regs.error.label{remove} = (['Frame: ', num2str(time),...
0441 ', reg: ', num2str(remove),' was not the best match for ', num2str(mapCR),' and was deleted.' num2str(keeper) , ' was.']);
0442 if verbose
0443 disp([header, 'ErRes: ', data_c.regs.error.label{remove}] );
0444 end
0445 regToDelete = [regToDelete;remove];
0446 resetRegions = true;
0447 else
0448 [data_c,cell_count] = createNewCell (data_c, remove, time, cell_count);
0449 data_c.regs.error.label{remove} = (['Frame: ', num2str(time),...
0450 ', reg: ', num2str(remove),' was not the best match for ', num2str(mapCR),' made into a new cell.']);
0451 if verbose
0452 disp([header, 'ErRes: ', data_c.regs.error.label{remove}] );
0453 end
0454 end
0455 end