diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d2229ed
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,10 @@
+emove autosaves generated by the Matlab editor
+## We have git for backups!
+##---------------------------------------------------
+
+# Windows default autosave extension
+*.asv
+
+# OSX / *nix default autosave extension
+*.m~
+
diff --git a/batch/BatchSuperSeggerOpti.m~ b/batch/BatchSuperSeggerOpti.m~
deleted file mode 100644
index dbc396f..0000000
--- a/batch/BatchSuperSeggerOpti.m~
+++ /dev/null
@@ -1,347 +0,0 @@
-function BatchSuperSeggerOpti(dirname_,skip,clean_flag,res,startEnd,showWarnings)
-% BatchSuperSeggerOpti : runs everything from start to finish,
-% including alignment, building the directory structure,
-%single image segmentation, error resolution, cell linking,
-% fluorescence analysis, and cell files.
-%
-% Processes a raw data set by
-% (1) Aligning and cropping time series
-% (2) Organizing files into directories
-% xy points are put in their own dir's
-% phase, fluor files put in their own dir's
-% makes seg and cell directories
-% (3) Segmenting the frames into cell regions
-% (4) Linking the regions between time steps
-% (5) finding loci and calculating fluor statistics
-% (6) Putting complete cells into the cell dir.
-%
-% INPUT :
-% dirname_ : dir containing raw tif files
-% skip : The segmentation is performed every skip files
-% : this skip is very useful for high frequency timelapse where
-% : cells would switch back and forth between one and two
-% : segments leading to errors that are difficult to resolve.
-% : This segments every skip files, then copies the segments into
-% : the intermediate frames.
-% clean_flag : Set this to be true to start from scratch and reseg all the
-% : files regardless of whether any seg files exist. If this
-% : flag is false, use existing segments, if they exist and
-% : new segs if they don't yet exist.
-% res : is a string that is passed to loadConstants(Mine).m to load
-% : the right constants for processing.
-% SEGMENT_FLAG : to segment cells
-% ONLY_SEG : if true it does not run trackOpti (does only the segmentation)
-% showWarnings : Set to 0 to mute warnings
-% startEnd : array of two values to indicate where to start and where to
-% stop the program. 1, alignment, 2, segmentation, 3, stripping, 4 linking,
-% 5, cell marker, 6, cellA structrues, 7, clist, 8 cell files.
-%
-% Copyright (C) 2016 Wiggins Lab
-% Written by Paul Wiggins & Stella Stylianidou.
-% 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 .
-
-% Init
-
-if (nargin < 1) || isempty( dirname_ ) || strcmp(dirname_ ,'.')
- dirname_ = pwd;
-end
-dirname_ = fixDir(dirname_);
-
-if nargin < 2 || isempty( skip )
- skip = 1; % default : don't skip frames
-end
-
-if nargin < 3 || isempty( clean_flag )
- clean_flag = 0; % default : don't resegment frames if segmented.
-end
-
-if nargin < 4 || isempty( res )
- res = [];
-end
-
-
-if ~exist( 'startEnd', 'var' ) || isempty( startEnd )
- startEnd = [NaN NaN];
-end
-
-if ~exist( 'showWarnings', 'var' ) || isempty( showWarnings )
- showWarnings = 1;
-end
-
-%if you pass a res value, write over CONST values. If it isn't passed,
-% use existing values, if they exist. If not, load the default values.
-if isstruct(res)
- CONST = res;
-else
- disp (['BatchSuperSeggerOpti : Loading constants file ', res]);
- if exist('loadConstantsMine','file');
- CONST = loadConstantsMine(res);
- else
- CONST = loadConstants(res,0);
- end
-end
-
-
-if clean_flag && SEGMENT_FLAG && showWarnings
- try
- disp ('Clean flag is set to true.')
- answer=input('Do you want to continue, Y/N [Y]:','s');
- if lower(answer) ~='y'
- disp ('Exiting BatchSuperSegger. Reset clean flag and rerun');
- return
- end
- catch
- % can not use input - in eval mode
- end
-end
-
-% align frames
-if exist( dirname_, 'dir' ) && startEnd(1) <=1
- if exist( [dirname_,filesep,'raw_im'] ,'dir') && ...
- (numel(dir ([dirname_,filesep,'raw_im',filesep,'*.tif'])) || ...
- exist([dirname_,filesep,'raw_im',filesep,'cropbox.mat'],'file'))
- disp('BatchSuperSeggerOpti : images already aligned');
- if exist([dirname_,filesep,'raw_im',filesep,'cropbox.mat'],'file')
- tmp = load( [dirname_,filesep,'raw_im',filesep,'cropbox.mat'] );
- crop_box_array = tmp.crop_box_array;
- else
- crop_box_array = cell(1,10000);
- end
- elseif numel(dir ([dirname_,filesep,'*.tif']))
- % check naming convention
- if ~isRightNameFormat(dirname_)
- disp('Images in incorrect naming format. Using convertImageNames to convert names.')
- convertImageNames(dirname_)
- end
-
- mkdir( [dirname_,filesep,'raw_im'] );
- if CONST.align.ALIGN_FLAG
- crop_box_array = trackOptiAlignPad( dirname_,...
- CONST.parallel.parallel_pool_num, CONST);
- movefile( [dirname_,filesep,'*.tif'], [dirname_,filesep,'raw_im'] ) % moves images to raw_im
- movefile( [dirname_,'align',filesep,'*.tif'], [dirname_,filesep]); % moves aligned back to main folder
- rmdir( [dirname_,'align'] ); % removes _align directory
- else
- crop_box_array = cell(1,10000);
- end
- else
- error('No images found');
- end
-else
- error(['BatchSuperSeggerOpti : Can''t find directory ''',dirname_,'''. Exiting.'] );
-end
-
-
-% setups the dir structure for analysis.
-trackOptiPD(dirname_, CONST);
-save( [dirname_,'CONST.mat'],'-STRUCT', 'CONST' ); % Saves CONST set you used.
-save( [dirname_,'raw_im',filesep,'cropbox.mat'], 'crop_box_array' );
-
-% Loop through xy directories
-% Reset n values in case directories have already been made.
-% setup nxy values
-contents = dir([dirname_,'xy*']);
-
-if isempty(contents)
- disp('BSSO: No xy directories were found.');
-else
- num_dir_tmp = numel(contents);
- nxy = [];
- num_xy = 0;
-
- for i = 1:num_dir_tmp
- if (contents(i).isdir) && (numel(contents(i).name) > 2)
- num_xy = num_xy+1;
- nxy = [nxy, str2num(contents(i).name(3:end))];
- dirname_list{i} = [dirname_,contents(i).name,filesep];
- end
- end
-
- % set values for nc (array of channels (phase and fluorescent))
- contents = dir([dirname_list{1},'fluor*']);
- num_dir_tmp = numel(contents);
- nc = 1;
- num_c = 1;
-
- for i = 1:num_dir_tmp
- if (contents(i).isdir) && (numel(contents(i).name) > numel('fluor'))
- num_c = num_c+1;
- nc = [nc, str2num(contents(i).name(numel('fluor')+1:end))+1];
- end
- end
-
-
- % Set up parallel loop for each xy point if more than one xy position
- % exists. If not more than one xy, we will parallelize inner loops
- if (num_xy>1) && (CONST.parallel.parallel_pool_num>0)
- workers = CONST.parallel.parallel_pool_num;
- CONST.parallel.parallel_pool_num = 0;
- else
- workers=0;
- end
-
- if workers || ~CONST.parallel.show_status
- h = [];
- else
- h = waitbar( 0, ['Data segmentation xy: 0/',num2str(num_xy)] );
- cleanup = onCleanup( @()( delete( h ) ) );
- end
-
- parfor(j = 1:num_xy,workers)
- %for j = 1:num_xy
-
- dirname_xy = dirname_list{j};
- intProcessXY( dirname_xy, skip, nc, num_c, clean_flag, ...
- CONST, startEnd, crop_box_array{j})
-
- if workers || ~CONST.parallel.show_status
- disp( ['BatchSuperSeggerOpti: No status bar. xy ',num2str(j), ...
- ' of ', num2str(num_xy),'.']);
- else
- if isvalid(h)
- waitbar( j/num_xy,h,...
- ['Data segmentation xy: ',num2str(j),...
- '/',num2str(num_xy)]);
- end
- end
- end
-
- if workers % shutting down parallel pool
- poolobj = gcp('nocreate');
- delete(poolobj);
- end
-
-
- if ~workers
- close(h);
- end
-
-end
-
-% done!
-end
-
-function intProcessXY( dirname_xy, skip, nc, num_c, clean_flag, ...
- CONST, startEnd, crop_box)
-% intProcessXY : the details of running the code in parallel.
-% Essentially for parallel processing to work, you have to hand each
-% processor all the information it needs to process the images.
-
-% Initialization
-file_filter = '*.tif';
-verbose = CONST.parallel.verbose;
-
-% get header to show xy position
-tmp1 = strfind( dirname_xy, 'xy');
-tmp2 = strfind( dirname_xy,[filesep]);
-
-if ~isempty(tmp1) && ~isempty(tmp2)
- header = [dirname_xy(tmp1(end):(tmp2(end)-1)),': '];
-else
- header = [dirname_xy];
-end
-
-% reset nz values
-contents=dir([dirname_xy,'phase',filesep,file_filter]);
-num_im = numel(contents);
-
-nz = []; % array of numbers of z frames
-nt = []; % array of frame numbers
-
-for i = 1:num_im;
- nameInfo = ReadFileName( contents(i).name );
- nt = [nt, nameInfo.npos(1,1)];
- nz = [nz, nameInfo.npos(4,1)];
-end
-
-nt = sort(unique(nt));
-nz = sort(unique(nz));
-
-num_t = numel(nt);
-num_z = numel(nz);
-
-if isempty(nz) || nz(1)==-1 % no z frames
- nz = 1;
-end
-
-
-disp([header 'BatchSuperSeggerOpti : Segmenting Cells']);
-
-if (CONST.parallel.parallel_pool_num>0)
- workers = CONST.parallel.parallel_pool_num; % number of workers
-else
- workers=0;
-end
-
-if ~CONST.parallel.show_status
- h = [];
-else
- h = waitbar( 0, ['BatchSuperSeggerOpti : Frame 0/',num2str(num_t)] );
- cleanup = onCleanup( @()( delete( h ) ) );
-end
-
-stamp_name = [dirname_xy,'seg',filesep,'.doSegFull'];
-
-if clean_flag
- if exist(stamp_name,'file')
- delete(stamp_name)
- end
- delete([dirname_xy,'seg',filesep,'*seg.mat*']);
-end
-
-
-% does the segmentations for all the frames in parallel
-if startEnd(1) <= 2 && ~exist( stamp_name, 'file' )
- parfor(i=1:num_t,workers) % through all frames
- %for i = 1:num_t
-
- if isempty( crop_box )
- crop_box_tmp = [];
- else
- crop_box_tmp = crop_box(i,:);
- end
-
- doSeg(i, nameInfo, nc, nz, nt, num_z, num_c, dirname_xy, ...
- skip, CONST, [header,'t',num2str(i),': '], crop_box_tmp);
-
- if ~CONST.parallel.show_status
- if verbose
- disp( [header, 'BatchSuperSeggerOpti : Segment. Frame ',num2str(i), ...
- ' of ', num2str(num_t),'.']);
- end
- else
- waitbar( i/num_t, h,...
- ['Data segmentation t: ',num2str(i),'/',num2str(num_t)]);
- end
- end
- time_stamp = clock; %#ok saved below
- save( stamp_name, 'time_stamp'); % saves that xydir was full segmented
-end
-if CONST.parallel.show_status
- if isvalid(h)
- close(h);
- end
-end
-
-% trackOpti has all the rest of things : Linking, Cell files, Fluorescence calculation etc
-if ~ONLY_SEG
- trackOpti(dirname_xy,skip,CONST, clean_flag, header);
-else
- disp ('Only segmentation was set to true - Linking and cell files were not made');
-end
-end
-
diff --git a/batch/processExp.m~ b/batch/processExp.m~
deleted file mode 100644
index c833edf..0000000
--- a/batch/processExp.m~
+++ /dev/null
@@ -1,117 +0,0 @@
-function processExp( dirname )
-% processExp : main function for running the segmentation software.
-% Used to choose the appropriate settings, and converting the images
-% filenames before running BatchSuperSeggerOpti.
-% Images need to have the NIS-Elements Format, or they can be converted
-% using convertImageNames.
-%
-% the naming convention of the image files must be of the following format
-% time, xy-positions, fluorescence channel, where c1 is bright field
-% and c2,c3 etc are different fluorescent channels
-% Example of two time points, two xy positions and one fluorescent channel
-% filename_t001xy1c1.tif
-% filename_t001xy1c2.tif
-% filename_t001xy2c1.tif
-% filename_t001xy2c2.tif
-% filename_t002xy1c1.tif
-% filename_t002xy1c2.tif
-% filename_t002xy2c1.tif
-% filename_t002xy2c2.tif
-%
-% INPUT :
-% dirname : folder that contains .tif images in NIS elements format.
-%
-%
-% Copyright (C) 2016 Wiggins Lab
-% Written by Paul Wiggins, Nathan Kuwada, Stella Stylianidou.
-% 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 .
-
-%% Converting other microscopes files
-% For example if you are using MicroManager and the file format is the
-% followin : date-strain_00000000t_BF.tif, date-strain_00000000t_GFP.tif,
-% you can run convertImageNames(dirname, 'whatever_name_you_want', '', 't',
-% '','', {'BF','GFP'} )
-
-basename = 'date-strain';
-timeFilterBefore ='t';
-timeFilterAfter = '_' ;
-xyFilterBefore='_x';
-xyFilterAfter='_';
-channelNames = {'BF','GFP'};
-
-convertImageNames(dirname, basename, timeFilterBefore, ...
- timeFilterAfter, xyFilterBefore,xyFilterAfter, channelNames )
-
-%% Set the segmentations constants for your bacteria and micrscope resolution
-% Using correct resolution ensures correct pixel size and segmentation constants
-% if you do not know which constants to use you can run
-% tryDifferentConstants(dirname) with a phase image to choose.
-
-% for E. coli we mainly use :
-% '60XEc' : loadConstants 60X Ecoli
-% '100XEc': loadConstants 100X Ecoli
-
-% other possible constants are :
-% '100XPa' : 100X Pseudemonas
-% '60XPa' : 60X Pseudemonas
-%' 60XA' : 60X E.coli Aska
-% '60XEcLB' : E.coli LB
-% '60XPaM','60XPaM2' : for 60X, Pseudomonas Minimal
-% '60XBthai' : 60X Thailandensis
-
-res = '60XEcLB';
-
-%% Paralell Processing Mode
-% to run code in parallel mode must have the parallel processing toolbox,
-% for convenience default is false (non-parallel)
-
-parallel_flag = true;
-
-%% Load Constants
-CONST = loadConstants(res,parallel_flag) ;
-
-%% Calculation Options
-% after you load the constants you can modify them according to your needs
-% for more options, looks at the loadConstants file.
-
-CONST.trackLoci.numSpots = [0 0]; % Max number of foci to fit in each fluorescence channel (default = [0 0])
-CONST.trackLoci.fluorFlag = false ; % compute integrated fluorescence (default = true)
-CONST.trackOpti.NEIGHBOR_FLAG = false; % calculate number of neighbors (default = false)
-CONST.imAlign.AlignChannel = 1; % change this if you want the images to be aligned to fluorescence channel
-
-
-%% Skip Frames for Segmentation
-% For fast time-lapse or slow growth you can skip phase image frames
-% during segmentation to increase processing speed. Fluorescence images
-% will not be skipped.
-
-skip = 1; % segment every frame
-%skip = 5; % segment every fifth phase image
-
-%% Clean previous segmented data
-% If set to true, will begin processing on aligned images; if false, will
-% try to restart processing at last successful function (default = false)
-
-cleanflag = false;
-
-
-%% Start running segmentation
-
-BatchSuperSeggerOpti( dirname, skip, cleanflag, CONST);
-
-
-end
diff --git a/batch/superSeggerGui.fig b/batch/superSeggerGui.fig
index dacc5f1..5d546c5 100644
Binary files a/batch/superSeggerGui.fig and b/batch/superSeggerGui.fig differ
diff --git a/batch/superSeggerGui.m b/batch/superSeggerGui.m
index 5e61d2d..53fde85 100644
--- a/batch/superSeggerGui.m
+++ b/batch/superSeggerGui.m
@@ -59,6 +59,31 @@ function load_listbox(handles)
function imageFolder_ClickedCallback(hObject, eventdata, handles)
handles.directory.String = uigetdir;
+
+
+function help_ClickedCallback(hObject, eventdata, handles)
+msgbox('Examples for image conversion : ')
+
+function convert_names_help_Callback(hObject, eventdata, handles)
+
+Opt.Interpreter = 'tex';
+Opt.WindowStyle = 'normal';
+msgbox({'NAMING CONVERSION:',
+ '',
+ 'Our naming convention is : basename_t001xy1c1.tif, where t is the prefix for time, xy the prefix for position number and c the prefix for channel number.',
+ '',
+ 'The convert script accepts the prefix and suffix characters you use to indicate the frame and position numbers.' ,
+ '',
+ 'For example if your naming convetion is \bfname-pos1-p-t001.tif\rm, you can use for channel names : \bf-p-\rm, position prefix : \bfpos\rm, time suffix : \bf.tif\rm.',
+'If your naming convetion is \bfname{\_}00000000t{\_}BF.tif\rm and \bfname{\_}00000000t{\_}GFP.tif\rm, you can use for channel names : \bfBF,GFP\rm, time prefix : \bf{\_}\rm and time suffix : \bft{\_}\rm.'
+}, 'Title','none',Opt);
+
+
+function convert_names_help_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
function directory_Callback(hObject, eventdata, handles)
function directory_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
@@ -200,4 +225,4 @@ function constants_list_Callback(hObject, eventdata, handles)
function constants_list_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
-end
\ No newline at end of file
+end
diff --git a/frameLink/errorRez.m~ b/frameLink/errorRez.m~
deleted file mode 100644
index e4e8095..0000000
--- a/frameLink/errorRez.m~
+++ /dev/null
@@ -1,465 +0,0 @@
-function [data_c, data_r, cell_count,resetRegions] = errorRez (time, ...
- data_c, data_r, data_f, CONST, cell_count, header, ignoreError, debug_flag)
-% errorRez : links cells from the frame before to the current and attempts to
-% resolve segmentation errors if the linking is inconsistent.
-%
-% INPUT :
-% time : current frame number
-% data_c : current time frame data (seg/err) file.
-% data_r : reverse time frame data (seg/err) file.
-% data_f : forward time frame data (seg/err) file.
-% CONST : segmentation parameters.
-% cell_count : last cell id used.
-% header : last cell id used.
-% debug_flag : 1 to display figures for debugging
-%
-% OUTPUT :
-% data_c : updated current time frame data (seg/err) file.
-% data_r : updated reverse time frame data (seg/err) file.
-% cell_count : last cell id used.
-% resetRegions : if true, regions were modified and this frame needs to
-% be relinked.
-%
-%
-% Copyright (C) 2016 Wiggins Lab
-% Written by Stella Stylianidou
-% 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 .
-
-
-global REMOVE_STRAY
-global header_string
-global regToDelete
-header_string = header;
-verbose = CONST.parallel.verbose;
-MIN_LENGTH = 10;
-REMOVE_STRAY = CONST.trackOpti.REMOVE_STRAY;
-DA_MIN = CONST.trackOpti.DA_MIN;
-DA_MAX = CONST.trackOpti.DA_MAX;
-regToDelete = [];
-resetRegions = false;
-minAreaToMerge = 55;
-
-
-% set all ids to 0
-cArea = [data_c.regs.props.Area];
-data_c.regs.ID = zeros(1,data_c.regs.num_regs);
-modRegions = [];
-for regNum = 1 : data_c.regs.num_regs;
-
-
- if regNum == 34
- keyboard;
- end
-
- if data_c.regs.ID(regNum) ~= 0
- disp ([header, 'ErRes: Frame: ', num2str(time), ' already has an id ',num2str(regNum)]);
- elseif ismember (regNum,modRegions)
- disp ([header, 'ErRes: Frame: ', num2str(time), ' already modified ',num2str(regNum)]);
- else
- rCellsFromC = data_c.regs.map.r{regNum}; % where regNum maps in reverse
-
- if ~isempty(rCellsFromC)
- cCellsFromR = data_r.regs.map.f{rCellsFromC};
- cCellsTransp = data_c.regs.revmap.r{rCellsFromC};
- else
- cCellsFromR = [];
- cCellsTransp = [];
- end
-
-
- %%% maps to 0
- if numel(rCellsFromC) == 0 % maps to 0 in the previous frame - stray
-
- % think whether this is useful : numel(mapRC) == 0
- if (time ~= 1) && (hasNoFwMapping(data_c,regNum) && REMOVE_STRAY)
- % deletes the regions not appearing at time = 1 that do not map to anything
- % or if remove_stray flag is set to true.
- data_c.regs.error.label{regNum} = ['Frame: ', num2str(time), ...
- ', reg: ', num2str(regNum), '. is a stray region - Deleted.'];
- if verbose
- disp([header, 'ErRes: ',data_c.regs.error.label{regNum}] );
- end
- regToDelete = [regToDelete;regNum];
- resetRegions = true;
- else % maps to a region in the next frame, or time is 1
- if time~=1
- data_c.regs.error.label{regNum} = ['Frame: ', num2str(time), ...
- ', reg: ', num2str(regNum), '. is a stray region.'];
- if verbose
- disp([header, 'ErRes: ',data_c.regs.error.label{regNum}] );
- end
- end
- [data_c,cell_count] = createNewCell (data_c, regNum, time, cell_count);
- end
-
- elseif numel(rCellsFromC) == 1 && numel (cCellsTransp) == 1 && all(cCellsFromR == regNum)
- % MAPS TO ONE AND AGREES
- % sets cell ID from mapped reg, updates death in data_r
- errorStat = (data_c.regs.error.r(regNum)>0);
- [data_c, data_r] = continueCellLine( data_c, regNum, data_r, rCellsFromC, time, errorStat);
-
- elseif numel(rCellsFromC) == 1 && numel (cCellsTransp) == 1 && ~all(cCellsFromR == regNum)
- % MAPS TO ONE AND DISAGREES
- % map with an error flag...
- errorStat = (data_c.regs.error.r(regNum)>0);
- [data_c, data_r] = continueCellLine( data_c, regNum, data_r, rCellsFromC, time, errorStat);
-
-
-
- elseif numel(rCellsFromC) == 1 && numel(cCellsFromR) == 1 && numel (cCellsTransp) == 2
- % regNum and another cell map to one in reverse
- % but one in reverse only maps to one forward
-
- sister1 = regNum;
- sister2 = cCellsTransp (cCellsTransp~=regNum);
- mapRC = cCellsTransp;
- mother = rCellsFromC;
-
- if debug_flag
- % red in c maps to blue in r, blue in r maps to green in c
- imshow(cat(3,0.5*ag(data_c.phase) + 0.5*ag(data_c.regs.regs_label==sister1),...
- ag(data_r.regs.regs_label == mother),ag(data_c.regs.regs_label==sister2)));
- end
-
- totAreaC = data_c.regs.props(sister1).Area + data_c.regs.props(sister2).Area;
- totAreaR = data_r.regs.props(mother).Area;
- AreaChange = (totAreaC-totAreaR)/totAreaC;
- goodAreaChange = (AreaChange > DA_MIN && AreaChange < DA_MAX);
- haveNoMatch = (isempty(data_c.regs.map.f{sister1}) || isempty(data_c.regs.map.f{sister2}));
- matchToTheSame = ~haveNoMatch && all(ismember(data_c.regs.map.f{sister1}, data_c.regs.map.f{sister2}));
- oneIsSmall = (cArea(sister1) < minAreaToMerge) || (cArea(sister2) < minAreaToMerge);
- if goodAreaChange && ~ignoreError && ~isempty(data_f) && (haveNoMatch || matchToTheSame || oneIsSmall)
- % r: one has no forward mapping, or both map to the same in fw, or one small
- % wrong division merge cells
- [data_c,mergeReset] = merge2Regions (data_c, [sister1, sister2], CONST);
- modRegions = [modRegions;sister1;sister2];
- resetRegions = (resetRegions || mergeReset);
- elseif goodAreaChange
- [data_c, data_r, cell_count] = createDivision (data_c,data_r,mother,sister1,sister2, cell_count, time,header, verbose);
- modRegions = [modRegions;sister1;sister2];
- else
- % map to best, remove mapping from second
- [data_c,data_r,cell_count,reset_tmp,modids_tmp] = mapBestOfTwo (data_c, mapRC, data_r, rCellsFromC, time, verbose, cell_count,header);
- resetRegions = or(reset_tmp,resetRegions);
- modRegions = [modRegions;modids_tmp];
- end
-
- elseif numel(rCellsFromC) == 1 && numel(cCellsFromR) == 2
- % the 1 in reverse maps to two in current : possible splitting event
- mother = rCellsFromC;
- sister1 = regNum;
- mapRC = data_r.regs.map.f{mother};
- sister2 = mapRC (mapRC~=regNum);
- sister2Mapping = data_c.regs.map.r{sister2};
-
- if numel(sister2) == 1 && any(mapRC==regNum) && ~isempty(sister2Mapping) && all(sister2Mapping == mother)
-
-
-
- totAreaC = data_c.regs.props(sister1).Area + data_c.regs.props(sister2).Area;
- totAreaR = data_r.regs.props(mother).Area;
- AreaChange = (totAreaC-totAreaR)/totAreaC;
- goodAreaChange = (AreaChange > DA_MIN && AreaChange < DA_MAX);
- haveNoMatch = (isempty(data_c.regs.map.f{sister1}) || isempty(data_c.regs.map.f{sister2}));
- matchToTheSame = ~haveNoMatch && all(ismember(data_c.regs.map.f{sister1}, data_c.regs.map.f{sister2}));
- oneIsSmall = (cArea(sister1) < minAreaToMerge) || (cArea(sister2) < minAreaToMerge);
- if goodAreaChange && ~ignoreError && (haveNoMatch || matchToTheSame || oneIsSmall)
-
-
-
- % wrong division merge cells
- if ~ignoreError
- [data_c,reset_tmp] = merge2Regions (data_c, [sister1, sister2], CONST);
- modRegions = [modRegions;sister1;sister2];
- else
- [data_c,data_r,cell_count,reset_tmp,modids_tmp] = mapBestOfTwo (data_c, mapRC, data_r, rCellsFromC, time, verbose, cell_count,header);
- modRegions = [modRegions;modids_tmp];
- end
- resetRegions = or(reset_tmp,resetRegions);
- else
- [data_c, data_r, cell_count] = createDivision (data_c,data_r,mother,sister1,sister2, cell_count, time,header, verbose);
- modRegions = [modRegions;sister1;sister2];
- end
- elseif numel(sister2) == 1 && any(mapRC==regNum) && any(data_c.regs.map.r{sister2} ~= mother)
- % map the one-to-one to mother
- errorStat = (data_c.regs.error.r(regNum)>0);
- [data_c, data_r] = continueCellLine( data_c, regNum, data_r, rCellsFromC, time, errorStat);
-
- elseif ~any(mapRC==regNum)
- % ERROR NOT FIXED : mapCR maps to mother. but mother maps to
- % two other cells..
- % OTHER POSSIBLE RESOLUTIONS.. :
- % 1 : merging missing, cell divided but piece fell out - check
- % if all three should be mapped
- % 2 : get the best two couples of the three
-
- % force mapping
- sister1 = regNum;
- sister2 = mapRC(1);
- sister3 = mapRC(2);
-
- % make a new cell for regNum with error...
- [data_c,cell_count] = createNewCell (data_c, regNum, time, cell_count);
- data_c.regs.error.r(regNum) = 1;
- data_c.regs.error.label{regNum} = ['Frame: ', num2str(time),...
- ', reg: ', num2str(regNum),'. Incorrect Mapping 1 to 2 - making a new cell'];
-
- if verbose
- disp([header, 'ErRes: ', data_c.regs.error.label{regNum}]);
- end
- % red : regNum, green : ones mother maps to, blue : mother
- if debug_flag
- imshow(cat(3,0.5*ag(data_c.phase) + 0.5*ag(data_c.regs.regs_label==regNum), ...
- ag((data_c.regs.regs_label == mapRC(1)) + ...
- (data_c.regs.regs_label==mapRC(2))),ag(data_r.regs.regs_label==mother)));
- end
- else
- data_c.regs.error.label{regNum} = ['Frame: ', num2str(time),...
- ', reg: ', num2str(regNum),'. Error not fixed - two to 1 but don''t know what to do.'];
-
- if verbose
- disp([header, 'ErRes: ', data_c.regs.error.label{regNum}]);
- end
-
- end
- elseif numel(rCellsFromC) > 1
- % 1 in current maps to two in reverse
- % try to find a segment that should be turned on in current
- % frame, exit regNum loop, make time - 1 and relink
-
- % The two in reverse map to regNum only
- % twoInRMapToCOnly = numel(data_r.regs.map.f{rCellsFromC(1)}) == 1 && data_r.regs.map.f{rCellsFromC(1)}==regNum && ...
- % numel(data_r.regs.map.f{rCellsFromC(2)}) == 1 && data_r.regs.map.f{rCellsFromC(2)}==regNum;
-
- if debug_flag
- imshow(cat(3,0.5*ag(data_c.phase), 0.7*ag(data_c.regs.regs_label==regNum),...
- ag((data_r.regs.regs_label==rCellsFromC(1)) + (data_r.regs.regs_label==rCellsFromC(2)))));
- end
-
-
- if ~ignoreError %& twoInRMapToCOnly
- [data_c,success] = missingSeg2to1 (data_c,regNum,data_r,rCellsFromC,CONST);
- else
- success = false;
- end
-
- if success % segment found
- data_c.regs.error.r(regNum) = 0;
- data_c.regs.error.label{regNum} = ['Frame: ', num2str(time),...
- ', reg: ', num2str(regNum),'. Segment added to fix 2 to 1 error'];
-
- if verbose
- disp([header, 'ErRes: ', data_c.regs.error.label{regNum}]);
- end
- if debug_flag
- imshow(cat(3,ag(data_c.regs.regs_label == regNum)+0.5*ag(data_c.phase),...
- ag(data_r.regs.regs_label == rCellsFromC(1)),...
- ag(data_r.regs.regs_label == rCellsFromC(2))));
- end
- resetRegions = true;
- else
- % ERROR NOT FIXED : link to the one with the best score
- [data_c,data_r] = mapToBestOfTwo (data_c, regNum, data_r, rCellsFromC, time, verbose,header);
- end
-
-
- elseif numel(rCellsFromC) == 1 && numel(cCellsFromR) > 2
-
- haveNoMatch = any(isempty({data_c.regs.map.f{cCellsFromR}}));
- forwMap = [data_c.regs.map.f{cCellsFromR}];
- forwardMap = unique(forwMap);
- occur = histc(forwMap,forwardMap);
- matchToTheSame = ~haveNoMatch && numel(forwardMap)==1;
- someMatchToSame = ~haveNoMatch && any(occur>1);
- % r: one has no forward mapping, or both map to the same in fw
- if ~isempty(data_f) && (haveNoMatch || matchToTheSame)
- % wrong division merge cells
- if ~ignoreError
- [data_c,reset_tmp] = merge2Regions (data_c, cCellsFromR, CONST);
- modRegions = [modRegions;cCellsFromR'];
- else
- [data_c,data_r,cell_count,reset_tmp,modids_tmp] = mapBestOfTwo (data_c, cCellsTransp, data_r, rCellsFromC, time, verbose, cell_count,header);
- modRegions = [modRegions;modids_tmp];
- end
- resetRegions = or(reset_tmp,resetRegions);
- elseif ~isempty(data_f) && (someMatchToSame)
- indFwMap = find(occur>1);
- valueFw = forwardMap(indFwMap);
- cellsToMerge = [];
- for i = 1 : numel(cCellsFromR)
- cur_cell = cCellsFromR(i);
- if any(data_c.regs.map.f{cur_cell} == valueFw)
- cellsToMerge = [cellsToMerge ;cur_cell];
- end
-
- end
- [data_c,reset_tmp] = merge2Regions (data_c, cellsToMerge, CONST);
- modRegions = [modRegions;cellsToMerge];
- end
- else
-
- data_c.regs.error.label{regNum} = ['Frame: ', num2str(time),...
- ', reg: ', num2str(regNum),'. Error not fixed'];
-
- if verbose
- disp([header, 'ErRes: ', data_c.regs.error.label{regNum}]);
- end
- if debug_flag
- intDisplay (data_r,rCellsFromC,data_c,regNum);
-
- end
-
- end
-
- end
-end
-%intDisplay (data_c,regToDelete,data_f,[]);
-[data_c] = deleteRegions( data_c,regToDelete);
-
-end
-
-
-
-function intDisplay (data_c,regC,data_f,regF)
-% intDisplay : displays linking
-% reg : maskF
-% green : maskC
-% blue : all cell masks in c
-
-
-maskC = data_c.regs.regs_label*0;
-for c = 1 : numel(regC)
- if ~isnan(regC(c))
- maskC = maskC + (data_c.regs.regs_label == regC(c))>0;
- end
-end
-
-if ~isempty (data_f)
- maskF = data_f.regs.regs_label*0;
- if isempty(regF)
- disp('nothing')
- imshow (cat(3,0*ag(maskF),ag(maskC),ag(data_c.mask_cell)));
- else
- for f = 1 : numel(regF)
- if ~isnan(regF(f))
- maskF = maskF + (data_f.regs.regs_label == regF(f))>0;
- end
- end
- imshow (cat(3,ag(maskF),ag(maskC),ag(data_c.mask_cell)));
- end
-end
-end
-
-
-
-
-function [ data_c, data_r, cell_count ] = createDivision (data_c,data_r,mother,sister1,sister2, cell_count, time, header, verbose)
-
-data_c.regs.error.label{sister1} = (['Frame: ', num2str(time),...
- ', reg: ', num2str(sister1),' and ', num2str(sister2),' . cell division from mother reg', num2str(mother),'. [L1,L2,Sc] = [',...
- num2str(data_c.regs.L1(sister1),2),', ',num2str(data_c.regs.L2(sister1),2),...
- ', ',num2str(data_c.regs.scoreRaw(sister1),2),'].']);
-if verbose
- disp([header, 'ErRes: ', data_c.regs.error.label{sister1}] );
-end
-data_r.regs.error.r(mother) = 0;
-data_c.regs.error.r(sister1) = 0;
-data_c.regs.error.r(sister2) = 0;
-[data_c, data_r, cell_count] = markDivisionEvent( ...
- data_c, sister1, data_r, mother, time, 0, sister2, cell_count);
-
-end
-
-
-function result = hasNoFwMapping (data_c,regNum)
-result = isempty(data_c.regs.map.f{regNum});
-end
-
-
-function [data_c,data_r] = mapToBestOfTwo (data_c, regNum, data_r, mapCR, time, verbose,header)
-% maps to best from two forward
-
-
-flaggerC = (data_c.regs.idsC.r(1,:) == regNum) & isnan(data_c.regs.idsC.r(2,:));
-flaggerR1 = (data_c.regs.idsR.r(1,:) == mapCR(1)) & isnan(data_c.regs.idsR.r(2,:));
-flaggerR2 = (data_c.regs.idsR.r(1,:) == mapCR(2)) & isnan(data_c.regs.idsR.r(2,:));
-
-loc1 = find(flaggerC&flaggerR1);
-loc2 = find(flaggerC&flaggerR2);
-cost1 = data_c.regs.cost.r(loc1);
-cost2 = data_c.regs.cost.r(loc2);
-
-if isempty(cost2) || cost10);
-[data_c, data_r] = continueCellLine( data_c, keeper, data_r, mapCR, time, errorStat);
-data_c.regs.revmap.r{mapCR} = keeper;
-
-
-data_c.regs.error.r(remove) = 1;
-idsOfModRegions = [remove;keeper];
-if REMOVE_STRAY && hasNoFwMapping(data_c,remove)
- data_c.regs.error.label{remove} = (['Frame: ', num2str(time),...
- ', reg: ', num2str(remove),' was not the best match for ', num2str(mapCR),' and was deleted.' num2str(keeper) , ' was.']);
- if verbose
- disp([header, 'ErRes: ', data_c.regs.error.label{remove}] );
- end
- regToDelete = [regToDelete;remove];
- resetRegions = true;
-else
- [data_c,cell_count] = createNewCell (data_c, remove, time, cell_count);
- data_c.regs.error.label{remove} = (['Frame: ', num2str(time),...
- ', reg: ', num2str(remove),' was not the best match for ', num2str(mapCR),' made into a new cell.']);
- if verbose
- disp([header, 'ErRes: ', data_c.regs.error.label{remove}] );
- end
-end
-end
\ No newline at end of file
diff --git a/frameLink/trackOptiStripSmall.m~ b/frameLink/trackOptiStripSmall.m~
deleted file mode 100644
index 156c944..0000000
--- a/frameLink/trackOptiStripSmall.m~
+++ /dev/null
@@ -1,136 +0,0 @@
-function trackOptiStripSmall(dirname, CONST, disp_flag)
-% trackOptiStripSmall : removes small regions and fills holes in the regions.
-% It removes regions anything with area below CONST.trackOpti.MIN_AREA
-% that are probably not real, typically bubbles, dust, or minicells.
-% It then creates a new cell mask and new region fields and resaves the seg
-% file.
-%
-% INPUT :
-% dirname : seg folder eg. maindirectory/xy1/seg
-% CONST : Constants file
-%
-% Copyright (C) 2016 Wiggins Lab
-% Written by Stella Stylianidou & 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 .
-
-
-VERY_SMALL_AREA = CONST.trackOpti.MIN_AREA; % smaller that this is stripped
-MIN_AREA = CONST.trackOpti.MIN_AREA; % smaller that this is stripped if no neighbors
-dirname = fixDir(dirname);
-contents=dir([dirname '*_seg.mat']);
-num_im = length(contents);
-
-if ~exist('disp_flag','var') || isempty(disp_flag)
- disp_flag = 0;
-end
-
-
-if CONST.parallel.show_status
- h = waitbar( 0, 'Strip small cells.');
- cleanup = onCleanup( @()( delete( h ) ) );
-else
- h = [];
-end
-SE = strel('disk',3);
-
-for i = 1:num_im;
-
- if CONST.parallel.show_status
- waitbar((num_im-i)/num_im,h,['Strip small cells--Frame: ',num2str(i),'/',num2str(num_im)]);
- end
-
- data_c = loaderInternal([dirname,contents(i).name]); % load data
-
- % remove small area regions
- regs_label = bwlabel(data_c.mask_cell);
- props = regionprops( regs_label, 'Area' );
- area_props = [props(:).Area];
- small = find(area_props<=MIN_AREA);
-
- small_new = [];
- % only if they can not connect to other cells
- for j = 1 : numel(small)
- id = small(j);
- mask = imdilate(regs_label == id,SE);
- neighbors = unique(regs_label(mask));
- neighbors = neighbors(neighbors~=id);
- neighbors = neighbors(neighbors~=0);
- if isempty(neighbors) || (area_props(id) < VERY_SMALL_AREA)
- small_new = [small_new,id];
- end
- end
-
-
- % remove the small from the mask
- cellmask_small= ismember( regs_label,small_new );
- cellmask_nosmall = data_c.mask_cell ;
- cellmask_nosmall (cellmask_small) = 0;
-
- data_c.mask_bg (cellmask_small) =0;
-
- % remove segments in small regions
- dilatedMask = imdilate(cellmask_nosmall, strel('square',4));
- data_c.segs.segs_3n(~dilatedMask) = 0;
- data_c.segs.segs_good(~dilatedMask) = 0;
- data_c.segs.segs_bad(~dilatedMask) = 0;
-
-
- % filling the holes in each region separetely
- ss = size( data_c.phase );
- regs_label = bwlabel( cellmask_nosmall );
- props = regionprops( regs_label, {'Area','BoundingBox'} );
- num_props = numel(props);
- mask_new = false(ss);
-
- for ii = 1:num_props
- [xx,yy] = getBBpad(props(ii).BoundingBox, ss,1);
- mask = (regs_label(yy,xx)==ii);
- mask__ = bwmorph(bwmorph( mask, 'dilate'), 'erode' );
- mask__ = imfill(mask__,'holes');
- mask_tmp = mask_new(yy,xx);
- mask_tmp(mask__) = true;
- mask_new(yy,xx) = mask_tmp;
- end
-
-
- if disp_flag
- imshow(cat(3,ag( data_c.mask_cell),ag(mask_new),ag(mask_new)));
- pause;
- end
-
- data_c.mask_cell = mask_new;
-
- % remake the regions
- data_c = intMakeRegs( data_c, CONST);
-
- % save the updated *seg.mat file
- dataname=[dirname,contents(i).name];
- save(dataname,'-STRUCT','data_c');
-
-
-end
-
-if CONST.parallel.show_status
- close(h);
-end
-
-end
-
-
-function data = loaderInternal( filename )
-data = load( filename );
-end
\ No newline at end of file
diff --git a/settings/loadConstants.m b/settings/loadConstants.m
index 2516564..fe24951 100644
--- a/settings/loadConstants.m
+++ b/settings/loadConstants.m
@@ -34,8 +34,13 @@
% You should have received a copy of the GNU General Public License
% along with SuperSegger. If not, see .
+% gets the list of all possible constants in the settings folder
+[possibleConstants, list, filepath] = getConstantsList();
+
+CONST = [];
if nargin < 1 || isempty( res )
- disp ('No constant chosen');
+ disp ('No constant chosen. Possible constants are : ');
+ disp(list');
return;
end
@@ -47,8 +52,7 @@
dispText = true;
end
-% gets the list of all possible constants in the settings folder
-[possibleConstants, ~, filepath] = getConstantsList();
+
% default values for numbers
resFlag = [];
@@ -186,7 +190,10 @@
ConstLoaded = load(res);
CONST.ResFlag = res;
else
- errordlg('loadConstants: Constants not loaded : no match found. Aborting.');
+ errordlg('loadConstants: Constants not loaded : no match found. Aborting. ');
+ disp(['Possible constants']);
+ disp(list');
+ CONST = [];
return;
end
diff --git a/viz/superSeggerViewerGui.fig b/viz/superSeggerViewerGui.fig
index 0ba4add..4da48f3 100644
Binary files a/viz/superSeggerViewerGui.fig and b/viz/superSeggerViewerGui.fig differ
diff --git a/viz/superSeggerViewerGui.m b/viz/superSeggerViewerGui.m
index 1ea3648..d1b12fa 100644
--- a/viz/superSeggerViewerGui.m
+++ b/viz/superSeggerViewerGui.m
@@ -337,12 +337,7 @@ function initImage(hObject, handles) % Not updated
showSeggerImage(handles.data_c, handles.data_r, handles.data_f, forcedFlags, handles.clist, handles.CONST, handles.axes1);
try
save(handles.filename_flags, 'FLAGS', 'nn', 'dirnum' );
- clist = handles.clist;
- if ~isempty(clist)
- save( [handles.dirname0,handles.contents_xy(handles.dirnum).name,filesep,'clist.mat'],'-STRUCT','clist');
- end
catch
- disp('Error saving.' );
end
end
@@ -1501,3 +1496,18 @@ function cell_no_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
+
+
+% --- Executes on button press in save_clist.
+function save_clist_Callback(hObject, eventdata, handles)
+% hObject handle to save_clist (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+try
+ clist = handles.clist;
+ if ~isempty(clist)
+ save( [handles.dirname0,handles.contents_xy(handles.dirnum).name,filesep,'clist.mat'],'-STRUCT','clist');
+ end
+catch
+ disp('Error saving.' );
+end