trackOptiCellMarker : puts together a list of complete cell cycles. It goes through the dirname/*err.mat files and determines which cells go through complete cell cycles (i.e. cells in which both birth and division are observed) Clist contains information about complete cell cycles (see information in clist_def). Note that the complete clist is made later by trackOptiClist.m this to get the pole information. Since this is set by the next step in the process. INPUT : dirname: seg folder eg. maindirectory/xy1/seg CONST: the segmentation constants. header : string displayed with information OUTPUT : clist : list of all cells found with non time dependent information about them. clist_def : definitions of the fields in clist set. Copyright (C) 2016 Wiggins Lab Written by Paul Wiggins. University of Washington, 2016 This file is part of SuperSegger. SuperSegger is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. SuperSegger is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with SuperSegger. If not, see <http://www.gnu.org/licenses/>.
0001 function [clist, clist_def] = trackOptiCellMarker(dirname, CONST, header) 0002 % trackOptiCellMarker : puts together a list of complete cell cycles. 0003 % It goes through the dirname/*err.mat files and determines which 0004 % cells go through complete cell cycles (i.e. cells in which both birth and 0005 % division are observed) Clist contains information about complete cell cycles 0006 % (see information in clist_def). Note that the complete clist is made later 0007 % by trackOptiClist.m this to get the pole information. Since this is set 0008 % by the next step in the process. 0009 % 0010 % 0011 % INPUT : 0012 % dirname: seg folder eg. maindirectory/xy1/seg 0013 % CONST: the segmentation constants. 0014 % header : string displayed with information 0015 % OUTPUT : 0016 % clist : list of all cells found with non time dependent information about them. 0017 % clist_def : definitions of the fields in clist set. 0018 % 0019 % 0020 % Copyright (C) 2016 Wiggins Lab 0021 % Written by Paul Wiggins. 0022 % University of Washington, 2016 0023 % This file is part of SuperSegger. 0024 % 0025 % SuperSegger is free software: you can redistribute it and/or modify 0026 % it under the terms of the GNU General Public License as published by 0027 % the Free Software Foundation, either version 3 of the License, or 0028 % (at your option) any later version. 0029 % 0030 % SuperSegger is distributed in the hope that it will be useful, 0031 % but WITHOUT ANY WARRANTY; without even the implied warranty of 0032 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0033 % GNU General Public License for more details. 0034 % 0035 % You should have received a copy of the GNU General Public License 0036 % along with SuperSegger. If not, see <http://www.gnu.org/licenses/>. 0037 0038 if ~exist('header', 'var') 0039 header = []; 0040 end 0041 0042 dirname = fixDir(dirname); 0043 0044 MIN_CELL_AGE = CONST.trackOpti.MIN_CELL_AGE; 0045 verbose = CONST.parallel.verbose; 0046 0047 % this variable contains the label for every set in the clist variable. 0048 clist_def = { 'Cell ID', ... 0049 'Region Num Birth', ... 0050 'Region Num Divide', ... 0051 'Cell Birth Time', ... 0052 'Cell Division Time', ... 0053 'Cell Age', ... 0054 'Cell Dist to edge', ... 0055 'Old Pole Age--must be run after Batch to get this right', ... 0056 'Long Axis Birth', ... 0057 'Long Axis Divide'}; 0058 0059 0060 0061 contents=dir([dirname '*_err.mat']); 0062 num_im = length(contents); 0063 clist = []; 0064 0065 if CONST.parallel.show_status 0066 h = waitbar( 0, 'Marking complete cell cycles.'); 0067 cleanup = onCleanup( @()( delete( h ) ) ); 0068 else 0069 h = []; 0070 end 0071 0072 % Work barkwards starting at the last frame. 0073 for i = (num_im-1):-1:2; 0074 0075 0076 if CONST.parallel.show_status 0077 waitbar((num_im-i)/num_im,h,['Marking complete cell cycles--Frame: ',num2str(i),'/',num2str(num_im)]); 0078 end 0079 % load data 0080 data_c = loaderInternal([dirname,contents(i).name]); 0081 0082 % calculate distance from the edge of the colony 0083 data_c.dist_mask = makeColonyDist( data_c.mask_bg ); 0084 0085 0086 % loop through regions looking for cells that divide successfully in 0087 % this frame. 0088 for ii = 1:data_c.regs.num_regs 0089 0090 % get the regions that the current region maps to in the next frame 0091 list_f = data_c.regs.map.f{ii}; 0092 0093 0094 % if the cell divides in this frame and the stat0 is true (meaning 0095 % that it resulted itself from a good division) and the error 0096 % history hasn't been set, the cell is tracked for a complete cell 0097 % cycles. 0098 if data_c.regs.divide(ii) && ... 0099 data_c.regs.stat0(ii) && ... 0100 (~data_c.regs.ehist(ii) && ... 0101 (i-data_c.regs.birth(ii)) >= MIN_CELL_AGE ) 0102 0103 if verbose 0104 disp([header, 'CellMarker: Complete Cell Cycle! Frame:', num2str(i),' reg: ', num2str(ii)]); 0105 end 0106 0107 % get the distance of the cell from the edge of the colony and 0108 % put that distance (in pixels) in cell_dist 0109 mask_cell = (data_c.regs.regs_label==ii); 0110 cell_dist = min(data_c.dist_mask(mask_cell)); 0111 0112 % Check to make sure that the cell has been assigned an ID 0113 % number 0114 if isfield(data_c.regs,'ID') 0115 0116 % The first time this function is called on a data set, the 0117 % CellA field doesn't exist yet. So.. if it doesn't exist, 0118 % record a NaN as the pole age 0119 if isfield( data_c, 'CellA' ) 0120 pole_age = data_c.CellA{ii}.pole.op_age; 0121 else 0122 pole_age = NaN; 0123 end 0124 0125 % store data in clist to set stat0 == 2 (good division) 0126 clist = [clist; data_c.regs.ID(ii), ii, ii, data_c.regs.birth(ii), i, i-data_c.regs.birth(ii), cell_dist, pole_age, data_c.regs.L1(ii), data_c.regs.L1(ii)]; 0127 0128 % clist_def = { 'Cell ID', ... 0129 % 'Region Num Birth', ... 0130 % 'Region Num Divide', ... 0131 % 'Cell Birth Time', ... 0132 % 'Cell Division Time', ... 0133 % 'Cell Age', ... 0134 % 'Cell Dist to edge', ... 0135 % 'Old Pole Age--must be run after Batch to get this right', ... 0136 % 'Long Axis Birth', ... 0137 % 'Long Axis Divide'}; 0138 0139 % field 2 will be updated when the code moves to the previous frame. 0140 0141 else 0142 %clist = [clist; data_c.regs.birth(ii), i, ii, ii]; 0143 disp( [header, 'CellMarker Error']); 0144 end 0145 elseif data_c.regs.divide(ii) && ... 0146 data_c.regs.stat0(ii) && ... 0147 (~data_c.regs.ehist(ii)) 0148 0149 data_c.regs.error.label{ii} = [data_c.regs.error.label{ii},... 0150 'Frame: ',num2str(i),', reg: ', num2str(ii), ... 0151 '. Division Failed: Cell age ', ... 0152 num2str(i-data_c.regs.birth(ii)), ... 0153 '< min age ' , num2str(MIN_CELL_AGE), '.']; 0154 0155 if verbose 0156 disp([header, 'CellMarker: ', data_c.regs.error.label{ii}] ); 0157 end 0158 end 0159 0160 end 0161 0162 % loop through clist to set the stat0 flag to 2 for cells that are 0163 % observed for complete cell cycles 0164 ss = size(clist); 0165 0166 for ii = 1:ss(1); 0167 0168 % get the current region number for entry ii of the clist. 0169 jj = clist(ii,2); 0170 0171 % check the birth date of the cell and skip it if it is born after 0172 % the current frame number. 0173 if i >= clist(ii,4); 0174 try 0175 0176 % This cell is active, therefore update the region number 0177 % for the next frame 0178 clist(ii,2) = data_c.regs.map.r{jj}(1); 0179 0180 % And also update the length of the cell since we want the 0181 % length @ birth. 0182 clist(ii,9) = data_c.regs.L1(jj); 0183 0184 % set the stat0 to 2 meaning the the cell is observed for 0185 % an entire cell cycle. 0186 data_c.regs.stat0(jj) = 2; 0187 0188 catch 0189 disp([header, 'Error is trackOptiCellMarker.']); 0190 end 0191 end 0192 end 0193 0194 % resave the updated *err.mat file and move on to the previous frame. 0195 dataname=[dirname,contents(i).name]; 0196 save(dataname,'-STRUCT','data_c'); 0197 0198 0199 end 0200 0201 if CONST.parallel.show_status 0202 close(h); 0203 end 0204 % Resort the list of cells so it is listed by cell ID number. 0205 if ~isempty(clist) 0206 try 0207 [tmp,ind_order] = sort( clist(:,1) ); 0208 clist = clist(ind_order,:); 0209 catch 0210 disp([header, 'Error is trackOptiCellMarker.']); 0211 end 0212 end 0213 0214 end 0215 0216 0217 0218 function data = loaderInternal( filename ) 0219 data = load( filename ); 0220 end