diff --git a/src/MATLAB/AddHashedCell.m b/src/MATLAB/AddHashedCell.m index a0260fd928c5fe297bc978558d7f9f6216064eb5..d0d3065de4f274c7d4aff2bccaadf9eb8220a4c2 100644 --- a/src/MATLAB/AddHashedCell.m +++ b/src/MATLAB/AddHashedCell.m @@ -14,9 +14,13 @@ else HashedCells{t}(1).trackID = cellTrackID; else %if the hullID exists update it, otherwise create the entry - index = find([HashedCells{t}(:).hullID] == cellHullID); - if(isempty(index)) - index = length(HashedCells{t}) + 1; + if(t>length(HashedCells) || isempty(HashedCells{t})) + index = 1; + else + index = find([HashedCells{t}(:).hullID] == cellHullID); + if(isempty(index)) + index = length(HashedCells{t}) + 1; + end end HashedCells{t}(index).hullID = cellHullID; HashedCells{t}(index).trackID = cellTrackID; diff --git a/src/MATLAB/CombineTrackWithParent.m b/src/MATLAB/CombineTrackWithParent.m index b55598dfff7ae4be0b025c25c49754c9d0a13ad0..6d1e60707a4eed08f2063825813320520e8da01d 100644 --- a/src/MATLAB/CombineTrackWithParent.m +++ b/src/MATLAB/CombineTrackWithParent.m @@ -30,6 +30,9 @@ end %inherit grandchildren CellTracks(parentID).childrenTracks = CellTracks(trackID).childrenTracks; +for i=1:length(CellTracks(parentID).childrenTracks) + CellTracks(CellTracks(parentID).childrenTracks(i)).parentTrack = parentID; +end %update the endTime of the parent CellTracks(parentID).endTime = CellTracks(trackID).endTime; diff --git a/src/MATLAB/ContextChangeLabel.m b/src/MATLAB/ContextChangeLabel.m index 5ce3f1451cc29b296ed0aa1347f188cebc60bf96..8af1d7d45dcb0531292e6039aaa22297a2906951 100644 --- a/src/MATLAB/ContextChangeLabel.m +++ b/src/MATLAB/ContextChangeLabel.m @@ -9,8 +9,25 @@ newTrackID = inputdlg('Enter New Label','New Label',1,{num2str(trackID)}); if(isempty(newTrackID)),return,end; newTrackID = str2double(newTrackID(1)); -if(newTrackID>length(CellTracks) || isempty(CellTracks(newTrackID).hulls)) - choice = questdlg('New label does not exist. Do you want this cell and its children dropped from its tree?','Drop Cell?','Yes','Cancel','Cancel'); +%error checking +if(0>=newTrackID) + msgbox(['New label of ' num2str(newTrackID) ' is not a valid number'],'Change Label','warn'); + return +elseif(length(CellTracks)<newTrackID || isempty(CellTracks(newTrackID).hulls)) + choice = questdlg(['Changing ' num2str(trackID) ' to ' num2str(newTrackID) ' will have the same effect as Remove From Tree'],... + 'Remove From Tree?','Continue','Cancel','Cancel'); + switch choice + case 'Continue' + newLabel = length(CellTracks) + 1; + ContextRemoveFromTree(time,trackID); + msgbox(['The new cell label is ' num2str(newLabel)],'Remove From Tree','help'); + return + case 'Cancel' + return + end +elseif(newTrackID>length(CellTracks) || isempty(CellTracks(newTrackID).hulls)) + choice = questdlg('New label does not exist. Do you want this cell and its children dropped from its tree?',... + 'Drop Cell?','Yes','Cancel','Cancel'); switch choice case 'Yes' oldFamily = CellTracks(trackID).familyID; @@ -21,13 +38,15 @@ if(newTrackID>length(CellTracks) || isempty(CellTracks(newTrackID).hulls)) return end elseif(~isempty(find([HashedCells{time}.trackID]==newTrackID,1))) - choice = questdlg(['Label ' num2str(newTrackID) ' exist on this frame. Would you like these labels to swap from here forward?'],... - 'Swap Labels?','Yes','Cancel','Cancel'); + choice = questdlg(['Label ' num2str(newTrackID) ' exist on this frame. Would you like these labels to swap from here forward or just this frame?'],... + 'Swap Labels?','Forward','This Frame','Cancel','Cancel'); switch choice - case 'Yes' + case 'Forward' SwapTrackLabels(time,trackID,newTrackID); History('Push'); LogAction('Swapped Labels',trackID,newTrackID); + case 'This Frame' + SwapHulls(time,trackID,newTrackID); case 'Cancel' return end diff --git a/src/MATLAB/ContextChangeParent.m b/src/MATLAB/ContextChangeParent.m index 2172cf5f96957ffc1045a9db0dfd3fc2a94a8e61..6eaf77b9b08d73067947a1b06fdebdb0a8911855 100644 --- a/src/MATLAB/ContextChangeParent.m +++ b/src/MATLAB/ContextChangeParent.m @@ -9,6 +9,11 @@ newParentID = inputdlg('Enter New Parent','New Parent',1,{num2str(CellTracks(tra if(isempty(newParentID)),return,end; newParentID = str2double(newParentID(1)); +%error checking +if(0>=newParentID || length(CellTracks)<newParentID || isempty(CellTracks(newParentID).hulls)) + msgbox(['Parent ' num2str(newParentID) ' is not a valid cell'],'Parent Change','warn'); + return +end if(CellTracks(newParentID).startTime > time) msgbox(['Parent ' num2str(newParentID) ' comes after ' num2str(trackID) ' consider a different edit.'],'Parent Change','warn'); return diff --git a/src/MATLAB/ConvertTrackingData.m b/src/MATLAB/ConvertTrackingData.m index bad774e2072d58db887b1df21f56c50c646ab35d..6ec6b58e3f8161ce8c4b46853be7257f4603511d 100644 --- a/src/MATLAB/ConvertTrackingData.m +++ b/src/MATLAB/ConvertTrackingData.m @@ -15,7 +15,7 @@ CONSTANTS.minParentHistoryTimeFrame = 5; CONSTANTS.minParentFuture = 5; CONSTANTS.minFamilyTimeFrame = 5; CONSTANTS.maxFrameDifference = 5; -CONSTANTS.historySize = 5; +CONSTANTS.historySize = 50; CONSTANTS.clickMargin = 500; Costs = gConnect; @@ -36,19 +36,48 @@ end %loop through the data for i=2:length(objHulls) - CellHulls(i).time = objHulls(i).t; - CellHulls(i).points = objHulls(i).pts; - CellHulls(i).centerOfMass = objHulls(i).COM; - CellHulls(i).indexPixels = objHulls(i).indPixels; - CellHulls(i).deleted = 0; - - if objHulls(i).inID == 0 - NewCellFamily(i,objHulls(i).t); - else - AddHullToTrack(i,[],objHulls(i).inID); + if(i<=length(CellHulls)+1 || ~isempty(CellHulls(i).time)) + addHull(i); end +% CellHulls(i).time = objHulls(i).t; +% CellHulls(i).points = objHulls(i).pts; +% CellHulls(i).centerOfMass = objHulls(i).COM; +% CellHulls(i).indexPixels = objHulls(i).indPixels; +% CellHulls(i).deleted = 0; +% +% if objHulls(i).inID == 0 +% NewCellFamily(i,objHulls(i).t); +% else +% AddHullToTrack(i,[],objHulls(i).inID); +% end end %create the family trees ProcessNewborns(1:length(CellFamilies)); + + function addHull(num) + CellHulls(num).time = objHulls(num).t; + CellHulls(num).points = objHulls(num).pts; + CellHulls(num).centerOfMass = objHulls(num).COM; + CellHulls(num).indexPixels = objHulls(num).indPixels; + CellHulls(num).deleted = 0; + + if objHulls(num).inID > length(CellHulls)+1 + if objHulls(objHulls(num).inID).inID == 0 + NewCellFamily(num,objHulls(objHulls(num).inID).t); + else + addHull(objHulls(num).inID); + end + end + + if objHulls(num).inID == 0 + NewCellFamily(num,objHulls(num).t); + else + AddHullToTrack(num,[],objHulls(num).inID); + end + + if objHulls(num).outID > length(CellHulls)+1 + addHull(objHulls(num).outID); + end + end end diff --git a/src/MATLAB/CreateContextMenuCells.m b/src/MATLAB/CreateContextMenuCells.m index 544d213a0434f257c27f8f9a32f4e7cd93161a24..2be7ab2dabf4bfeb38c3cd94d937a1dc39c236b5 100644 --- a/src/MATLAB/CreateContextMenuCells.m +++ b/src/MATLAB/CreateContextMenuCells.m @@ -9,9 +9,23 @@ global Figures figure(Figures.cells.handle); Figures.cells.contextMenuHandle = uicontextmenu; +% Figures.cells.contextMenuLabelHandle = uimenu(Figures.cells.contextMenuHandle,... +% 'Label', 'Click to Show Which Cell Is Selected',... +% 'CallBack', @cellSelected); + +Figures.cells.removeMenu = uimenu(Figures.cells.contextMenuHandle,... + 'Label', 'Remove Mitosis',... + 'CallBack', @removeMitosis,... + 'Visible', 'off'); + +uimenu(Figures.cells.contextMenuHandle,... + 'Label', 'Add Mitosis',... + 'CallBack', @addMitosis); + uimenu(Figures.cells.contextMenuHandle,... 'Label', 'Change Label',... - 'CallBack', @changeLabel); + 'CallBack', @changeLabel,... + 'Separator', 'on'); uimenu(Figures.cells.contextMenuHandle,... 'Label', 'Change Parent',... @@ -66,6 +80,80 @@ uimenu(Figures.cells.contextMenuHandle,... end %% Callback functions +% function cellSelected(src,evnt) +% %doesn't work, closes context menu +% global Figures +% [hullID trackID] = getClosestCell(); +% +% if(isempty(trackID)) +% set(Figures.cells.contextMenuLabelHandle,'Label','No Cell Selected, Click Closer'); +% else +% set(Figures.cells.contextMenuLabelHandle,'Label',['Cell: ' num2str(trackID)]); +% end +% end + +function removeMitosis(src,evnt) +global CellTracks Figures +object = get(gco); + +if(~strcmp(object.Tag,'SiblingRelationship')) + msgbox('Please click on a Relationship line to remove','Not on line','warn'); + return +end + +choice = questdlg('Which Side to Keep?','Merge With Parent',object.UserData,... + num2str(CellTracks(object.UserData).siblingTrack),'Cancel','Cancel'); +switch choice + case num2str(object.UserData) + remove = CellTracks(object.UserData).siblingTrack; + newTree = RemoveFromTree(CellTracks(CellTracks(object.UserData).siblingTrack).startTime,... + CellTracks(object.UserData).siblingTrack,'yes'); + case num2str(CellTracks(object.UserData).siblingTrack) + remove = object.UserData; + newTree = RemoveFromTree(CellTracks(object.UserData).startTime,object.UserData,'yes'); + otherwise + return +end +History('Push'); +LogAction(['Removed ' num2str(remove) ' from tree'],Figures.tree.familyID,newTree); +DrawTree(Figures.tree.familyID); +DrawCells(); +end + +function addMitosis(src,evnt) +global CellTracks Figures + +[hullID trackID] = getClosestCell(); +if(isempty(trackID)),return,end + +answer = inputdlg({'Enter Time of Mitosis',['Enter new sibling of ' num2str(trackID)]},... + 'Add Mitosis',1,{num2str(Figures.time),''}); + +if(isempty(answer)),return,end + +time = str2double(answer(1)); +siblingTrack = str2double(answer(2)); + +if(isempty(CellTracks(siblingTrack).hulls)) + msgbox([answer(2) ' is not a valid cell'],'Not a valid cell','error'); + return +end +if(CellTracks(trackID).startTime>time) + msgbox([num2str(trackID) ' exists after ' answer(1)],'Not a valid child','error'); + return +end + +oldParent = CellTracks(siblingTrack).parentTrack; + +ChangeTrackParent(trackID,time,siblingTrack); + +History('Push'); +LogAction(['Changed parent of ' num2str(siblingTrack)],oldParent,trackID); + +DrawTree(CellTracks(trackID).familyID); +DrawCells(); +end + function changeLabel(src,evnt) global Figures @@ -107,7 +195,7 @@ addHull(num); end function removeHull(src,evnt) -global Figures +global Figures CellFamilies [hullID trackID] = getClosestCell(); if(isempty(trackID)),return,end @@ -115,6 +203,22 @@ if(isempty(trackID)),return,end RemoveHull(hullID); History('Push'); LogAction(['Removed hull from track ' num2str(trackID)],hullID,[]); + +%if the whole family disapears with this change, pick a diffrent family to +%display +if(isempty(CellFamilies(Figures.tree.familyID).tracks)) + for i=1:length(CellFamilies) + if(~isempty(CellFamilies(i).tracks)) + Figures.tree.familyID = i; + break + end + end + DrawTree(Figures.tree.familyID); + DrawCells(); + msgbox(['By removing this hull, the complete tree is no more. Displaying tree rooted at ' num2str(CellFamilies(i).rootTrackID) ' instead'],'Displaying Tree','help'); + return +end + DrawTree(Figures.tree.familyID); DrawCells(); end diff --git a/src/MATLAB/CreateContextMenuTree.m b/src/MATLAB/CreateContextMenuTree.m index ac1a048c7cc3b43540572c7ad109517a5e35f018..079861618dd11a0875a8dad4729c8cb58e6a1b12 100644 --- a/src/MATLAB/CreateContextMenuTree.m +++ b/src/MATLAB/CreateContextMenuTree.m @@ -9,9 +9,18 @@ global Figures figure(Figures.tree.handle); Figures.tree.contextMenuHandle = uicontextmenu; +uimenu(Figures.tree.contextMenuHandle,... + 'Label', 'Remove Mitosis',... + 'CallBack', @removeMitosis); + +uimenu(Figures.tree.contextMenuHandle,... + 'Label', 'Add Mitosis',... + 'CallBack', @addMitosis); + uimenu(Figures.tree.contextMenuHandle,... 'Label', 'Change Label',... - 'CallBack', @changeLabel); + 'CallBack', @changeLabel,... + 'Separator', 'on'); uimenu(Figures.tree.contextMenuHandle,... 'Label', 'Change Parent',... @@ -28,6 +37,86 @@ uimenu(Figures.tree.contextMenuHandle,... end %% Callback functions +function removeMitosis(src,evnt) +global CellTracks Figures +object = get(gco); +if(strcmp(object.Type,'text') || strcmp(object.Marker,'o')) + %clicked on a node + if(isempty(CellTracks(object.UserData).parentTrack)) + msgbox('No Mitosis to Remove','Unable to Remove Mitosis','error'); + return + end + choice = questdlg('Which Side to Keep?','Merge With Parent',object.UserData,... + num2str(CellTracks(object.UserData).siblingTrack),'Cancel','Cancel'); +elseif(object.YData(1)==object.YData(2)) + %clicked on a horizontal line + choice = questdlg('Which Side to Keep?','Merge With Parent',... + num2str(CellTracks(object.UserData).childrenTracks(1)),... + num2str(CellTracks(object.UserData).childrenTracks(2)),'Cancel','Cancel'); +else + %clicked on a vertical line + msgbox('Please Click on the Node or the Vertical Edge to Remove Mitosis','Unable to Remove Mitosis','warn'); + return +end +switch choice + case num2str(object.UserData) + remove = CellTracks(object.UserData).siblingTrack; + newTree = RemoveFromTree(CellTracks(CellTracks(object.UserData).siblingTrack).startTime,... + CellTracks(object.UserData).siblingTrack,'yes'); + case num2str(CellTracks(object.UserData).siblingTrack) + remove = object.UserData; + newTree = RemoveFromTree(CellTracks(object.UserData).startTime,object.UserData,'yes'); + case num2str(CellTracks(object.UserData).childrenTracks(1)) + remove = CellTracks(object.UserData).childrenTracks(2); + newTree = RemoveFromTree(CellTracks(CellTracks(object.UserData).childrenTracks(2)).startTime,... + CellTracks(object.UserData).childrenTracks(2),'yes'); + case num2str(CellTracks(object.UserData).childrenTracks(2)) + remove = CellTracks(object.UserData).childrenTracks(1); + newTree = RemoveFromTree(CellTracks(CellTracks(object.UserData).childrenTracks(1)).startTime,... + CellTracks(object.UserData).childrenTracks(1),'yes'); + otherwise + return +end +History('Push'); +LogAction(['Removed ' num2str(remove) ' from tree'],Figures.tree.familyID,newTree); +DrawTree(Figures.tree.familyID); +DrawCells(); +end + +function addMitosis(src,evnt) +global CellTracks +trackID = get(gco,'UserData'); +time = get(gca,'CurrentPoint'); +time = round(time(1,2)); + +answer = inputdlg({'Enter Time of Mitosis',['Enter new sibling of ' num2str(trackID)]},... + 'Add Mitosis',1,{num2str(time),''}); + +if(isempty(answer)),return,end + +time = str2double(answer(1)); +siblingTrack = str2double(answer(2)); + +if(isempty(CellTracks(siblingTrack).hulls)) + msgbox([answer(2) ' is not a valid cell'],'Not a valid cell','error'); + return +end +if(CellTracks(trackID).startTime>time) + msgbox([num2str(trackID) ' exists after ' answer(1)],'Not a valid child','error'); + return +end + +oldParent = CellTracks(siblingTrack).parentTrack; + +ChangeTrackParent(trackID,time,siblingTrack); + +History('Push'); +LogAction(['Changed parent of ' num2str(siblingTrack)],oldParent,trackID); + +DrawTree(CellTracks(trackID).familyID); +DrawCells(); +end + function changeLabel(src,evnt) global CellTracks trackID = get(gco,'UserData'); diff --git a/src/MATLAB/CreateMenuBar.m b/src/MATLAB/CreateMenuBar.m index 2f456f0582f3b6d10150d56aa380561d2810b6ad..4e0e9cd071a28e88baa2de3474a40c70b96295fe 100644 --- a/src/MATLAB/CreateMenuBar.m +++ b/src/MATLAB/CreateMenuBar.m @@ -85,6 +85,14 @@ labelsMenu = uimenu(... 'Checked', 'on',... 'Accelerator', 'l'); +siblingsMenu = uimenu(... + 'Parent', viewMenu,... + 'Label', 'Show Sibling Relationships',... + 'HandleVisibility', 'callback',... + 'Callback', @toggleSiblings,... + 'Checked', 'off',... + 'Accelerator', 'b'); + playMenu = uimenu(... 'Parent', viewMenu,... 'Label', 'Play',... @@ -107,6 +115,11 @@ uimenu(... 'Callback', @largestTree,... 'Separator', 'on'); +uimenu(... + 'Parent', viewMenu,... + 'Label', 'Display Tree...',... + 'HandleVisibility', 'callback',... + 'Callback', @displayTree); if(strcmp(get(handle,'Tag'),'cells')) Figures.cells.menuHandles.saveMenu = saveMenu; @@ -114,12 +127,14 @@ if(strcmp(get(handle,'Tag'),'cells')) Figures.cells.menuHandles.redoMenu = redoMenu; Figures.cells.menuHandles.labelsMenu = labelsMenu; Figures.cells.menuHandles.playMenu = playMenu; + Figures.cells.menuHandles.siblingsMenu = siblingsMenu; else Figures.tree.menuHandles.saveMenu = saveMenu; Figures.tree.menuHandles.undoMenu = undoMenu; Figures.tree.menuHandles.redoMenu = redoMenu; Figures.tree.menuHandles.labelsMenu = labelsMenu; Figures.tree.menuHandles.playMenu = playMenu; + Figures.tree.menuHandles.siblingsMenu = siblingsMenu; end end @@ -166,6 +181,19 @@ else end end +function toggleSiblings(src,evnt) +global Figures +if(strcmp(get(Figures.cells.menuHandles.siblingsMenu, 'Checked'), 'on')) + set(Figures.cells.menuHandles.siblingsMenu, 'Checked', 'off'); + set(Figures.tree.menuHandles.siblingsMenu, 'Checked', 'off'); + DrawCells(); +else + set(Figures.cells.menuHandles.siblingsMenu, 'Checked', 'on'); + set(Figures.tree.menuHandles.siblingsMenu, 'Checked', 'on'); + DrawCells(); +end +end + function timeJump(src,evnt) global Figures HashedCells answer = inputdlg('Enter Frame Number:','Jump to Time...',1,{num2str(Figures.time)}); @@ -199,3 +227,15 @@ Figures.tree.familyID = maxID; DrawTree(maxID); DrawCells(); end + +function displayTree(src,evnt) +global CellTracks +answer = inputdlg('Enter Tree Containing Cell:','Display Tree',1); +answer = str2double(answer); + +if(0>=answer || isempty(CellTracks(answer).hulls)) + msgbox([num2str(answer) ' is not a valid cell'],'Not Valid','error'); + return +end +DrawTree(CellTracks(answer).familyID); +end diff --git a/src/MATLAB/DrawCells.m b/src/MATLAB/DrawCells.m index 301da85cb7b20c10398b88bd9ca4ee204d7dc5aa..cf6d15005757822fcb75df6c6ae1368ac1db6d32 100644 --- a/src/MATLAB/DrawCells.m +++ b/src/MATLAB/DrawCells.m @@ -33,6 +33,7 @@ end colormap(gray); hold all; +siblingsAlreadyDrawn = []; %draw labels if turned on if(strcmp(get(Figures.cells.menuHandles.labelsMenu, 'Checked'),'on')) @@ -79,6 +80,14 @@ if(strcmp(get(Figures.cells.menuHandles.labelsMenu, 'Checked'),'on')) textColor = 'r'; end + %draw connection to sibling + if(strcmp(get(Figures.cells.menuHandles.siblingsMenu, 'Checked'),'on')) + %if the cell is on the current tree or already drawn + if(Figures.tree.familyID == CellTracks(curTrackID).familyID && isempty(find(siblingsAlreadyDrawn==curTrackID, 1))) + siblingsAlreadyDrawn = [siblingsAlreadyDrawn drawSiblingsLine(curTrackID,curHullID)]; + end + end + %draw outline plot(CellHulls(curHullID).points(:,1),... CellHulls(curHullID).points(:,2),... @@ -104,5 +113,42 @@ if(strcmp(get(Figures.cells.menuHandles.labelsMenu, 'Checked'),'on')) 'UserData', curTrackID,... 'uicontextmenu', Figures.cells.contextMenuHandle); end +elseif(strcmp(get(Figures.cells.menuHandles.siblingsMenu, 'Checked'),'on')) + %just draw sibling lines + for i=1:length(HashedCells{Figures.time}) + curHullID = HashedCells{Figures.time}(i).hullID; + curTrackID = HashedCells{Figures.time}(i).trackID; + + %if the cell is on the current tree or already drawn + if(Figures.tree.familyID == CellTracks(curTrackID).familyID && isempty(find(siblingsAlreadyDrawn==curTrackID, 1))) + siblingsAlreadyDrawn = [siblingsAlreadyDrawn drawSiblingsLine(curTrackID,curHullID)]; + end + end +end end + +function tracksDrawn = drawSiblingsLine(trackID,hullID) +global Figures CellTracks CellHulls HashedCells + +tracksDrawn = []; +siblingID = CellTracks(trackID).siblingTrack; +parentID = CellTracks(trackID).parentTrack; + +if(isempty(siblingID)),return,end + +tracksDrawn = [trackID siblingID]; + +siblingHullID = [HashedCells{Figures.time}.trackID] == siblingID; +siblingHullID = [HashedCells{Figures.time}(siblingHullID).hullID]; + +if(isempty(siblingHullID)),return,end + +plot([CellHulls(hullID).centerOfMass(2) CellHulls(siblingHullID).centerOfMass(2)],... + [CellHulls(hullID).centerOfMass(1) CellHulls(siblingHullID).centerOfMass(1)],... + 'Color', CellTracks(parentID).color.background,... + 'UserData', trackID,... + 'uicontextmenu', Figures.cells.contextMenuHandle,... + 'Tag', 'SiblingRelationship'); + +set(Figures.cells.removeMenu,'Visible','on'); end diff --git a/src/MATLAB/DrawTree.m b/src/MATLAB/DrawTree.m index 9afd693de35fa164300d2bb552b28683d12af661..a05b13cb4d320bf6002025c8152268c9c160f859 100644 --- a/src/MATLAB/DrawTree.m +++ b/src/MATLAB/DrawTree.m @@ -5,7 +5,7 @@ function DrawTree(familyID) global CellFamilies HashedCells Figures -if(isempty(CellFamilies(familyID).tracks)),return,end +if(isempty(CellFamilies(familyID).tracks) || (isvarname('Figures.tree.familyID') && familyID==Figures.tree.familyID)),return,end %let the user know that this might take a while set(Figures.tree.handle,'Pointer','watch'); diff --git a/src/MATLAB/History.m b/src/MATLAB/History.m index ed2d84e58f2f1edf1950ad1b25e2fb4890da49a1..1582660cc7daaefc64935c06d91bdb18182e6c18 100644 --- a/src/MATLAB/History.m +++ b/src/MATLAB/History.m @@ -163,8 +163,13 @@ end else set(Figures.cells.menuHandles.redoMenu,'Enable','off'); set(Figures.tree.menuHandles.redoMenu,'Enable','off'); - set(Figures.cells.menuHandles.undoMenu,'Enable','off'); - set(Figures.tree.menuHandles.undoMenu,'Enable','off'); + if(~full) + set(Figures.cells.menuHandles.undoMenu,'Enable','off'); + set(Figures.tree.menuHandles.undoMenu,'Enable','off'); + else + set(Figures.cells.menuHandles.undoMenu,'Enable','on'); + set(Figures.tree.menuHandles.undoMenu,'Enable','on'); + end end else diff --git a/src/MATLAB/RehashCellTracks.m b/src/MATLAB/RehashCellTracks.m index 4e6ef60805c4354dc455ca1529e88de6dbe7f1b1..82c460326094b8bc18cdcb36a77581e9c1e1c4d1 100644 --- a/src/MATLAB/RehashCellTracks.m +++ b/src/MATLAB/RehashCellTracks.m @@ -42,4 +42,6 @@ if(indexOfLastHull~=length(CellTracks(trackID).hulls)) end CellTracks(trackID).startTime = newStartTime; + +%check to see if this effects the family end diff --git a/src/MATLAB/RemoveHull.m b/src/MATLAB/RemoveHull.m index 91d039c4fb51b8573194e9aca0ce742846f7b29e..78550a63e77e5934694b5654f1530da6018f6f45 100644 --- a/src/MATLAB/RemoveHull.m +++ b/src/MATLAB/RemoveHull.m @@ -14,7 +14,29 @@ index = find(CellTracks(trackID).hulls==hullID); CellTracks(trackID).hulls(index) = 0; if(1==index) index = find(CellTracks(trackID).hulls,1,'first'); - RehashCellTracks(trackID,CellHulls(CellTracks(trackID).hulls(index)).time); + if(~isempty(index)) + RehashCellTracks(trackID,CellHulls(CellTracks(trackID).hulls(index)).time); + else + if(~isempty(CellTracks(trackID).parentTrack)) + CombineTrackWithParent(CellTracks(trackID).siblingTrack); + end + if(~isempty(CellTracks(trackID).childrenTracks)) + for i=1:length(CellTracks(trackID).childrenTracks) + RemoveFromTree(CellTracks(trackID).childrenTracks(i)) + end + end + RemoveTrackFromFamily(trackID); + CellTracks(trackID).familyID = []; + CellTracks(trackID).parentTrack = []; + CellTracks(trackID).siblingTrack = []; + CellTracks(trackID).childrenTracks = []; + CellTracks(trackID).hulls = []; + CellTracks(trackID).starTime = []; + CellTracks(trackID).endTime = []; + CellTracks(trackID).hulls = []; + CellTracks(trackID).timeOfDeath = []; + CellTracks(trackID).color = []; + end elseif(index==length(CellTracks(trackID).hulls)) RehashCellTracks(trackID,CellTracks(trackID).startTime); end diff --git a/src/MATLAB/RemoveTrackFromFamily.m b/src/MATLAB/RemoveTrackFromFamily.m index cf564045eed8a1ab5fe0e28e18801a2915bfd147..6f2853a9f4de31087c8550412091d956c1e32d51 100644 --- a/src/MATLAB/RemoveTrackFromFamily.m +++ b/src/MATLAB/RemoveTrackFromFamily.m @@ -25,4 +25,7 @@ CellFamilies(familyID).endTime = max([CellTracks(CellFamilies(familyID).tracks). if(CellFamilies(familyID).rootTrackID == trackID) CellFamilies(familyID).rootTrackID = CellFamilies(familyID).tracks(index); end +if(isempty(index)) + CellFamilies(familyID).tracks = []; +end end diff --git a/src/MATLAB/ResegmentHull.m b/src/MATLAB/ResegmentHull.m index dc58f94af6c03eecc22ed1f6d719862fea894dcd..9f829ac53bdb372f600856fc3817e96b4a2cf806 100644 --- a/src/MATLAB/ResegmentHull.m +++ b/src/MATLAB/ResegmentHull.m @@ -31,7 +31,7 @@ for i=1:k end nh.indexPixels = hull.indexPixels(bIdxPix); - nh.centerOfMass = mean([hx hy]); + nh.centerOfMass = mean([hy hx]); nh.time = hull.time; try diff --git a/src/MATLAB/SwapHulls.m b/src/MATLAB/SwapHulls.m new file mode 100644 index 0000000000000000000000000000000000000000..4ba2d49f727c17464923af61d24adb5362d92e11 --- /dev/null +++ b/src/MATLAB/SwapHulls.m @@ -0,0 +1,24 @@ +function SwapHulls(time,track1,track2) +% SwapHulls(time,track1,track2) will swap the hulls at the given time in +% the given tracks + +global CellTracks HashedCells + +track1Hash = time - CellTracks(track1).startTime + 1; +track2Hash = time - CellTracks(track2).startTime + 1; + +if(0>=track1Hash || 0>=track2Hash || ... + track1Hash>length(CellTracks(track1).hulls) || track2Hash>length(CellTracks(track2).hulls)) + return +end + +hull1 = CellTracks(track1).hulls(track1Hash); +hull2 = CellTracks(track2).hulls(track2Hash); +CellTracks(track1).hulls(track1Hash) = hull2; +CellTracks(track2).hulls(track2Hash) = hull1; + +index = [HashedCells{time}.hullID]==hull1; +HashedCells{time}(index).trackID = track2; +index = [HashedCells{time}.hullID]==hull2; +HashedCells{time}(index).trackID = track1; +end diff --git a/src/MATLAB/SwapTrackLabels.m b/src/MATLAB/SwapTrackLabels.m index 63fa5fbe3753e9be0bde3704a8390f47bc2b2900..74a1c42682a071f68bba6905928f4a17d7bfc7b3 100644 --- a/src/MATLAB/SwapTrackLabels.m +++ b/src/MATLAB/SwapTrackLabels.m @@ -22,6 +22,13 @@ CellTracks(trackID1).hulls = [CellTracks(trackID1).hulls track2Hulls]; CellTracks(trackID2).hulls = [CellTracks(trackID2).hulls track1Hulls]; %update times +% index = find(CellTracks(trackID1).hulls,1,'first'); +% startTime1 = CellHulls(CellTracks(trackID1).hulls(index)).time; +% index = find(CellTracks(trackID2).hulls,1,'first'); +% startTime2 = CellHulls(CellTracks(trackID2).hulls(index)).time; +% RehashCellTracks(trackID1,startTime1); +% RehashCellTracks(trackID2,startTime2); + CellTracks(trackID1).startTime = CellHulls(CellTracks(trackID1).hulls(1)).time; CellTracks(trackID2).startTime = CellHulls(CellTracks(trackID2).hulls(1)).time; CellTracks(trackID1).endTime = CellHulls(CellTracks(trackID1).hulls(find([CellTracks(trackID1).hulls]~=0,1,'last'))).time; @@ -36,10 +43,18 @@ tempChildrenTracks = CellTracks(trackID1).childrenTracks; CellTracks(trackID1).childrenTracks = CellTracks(trackID2).childrenTracks; CellTracks(trackID2).childrenTracks = tempChildrenTracks; +for i=1:length(CellTracks(trackID1).childrenTracks) + CellTracks(CellTracks(trackID1).childrenTracks(i)).parentTrack = trackID1; +end +for i=1:length(CellTracks(trackID2).childrenTracks) + CellTracks(CellTracks(trackID2).childrenTracks(i)).parentTrack = trackID2; +end + + %check to see if the children have moved to a new family if(CellTracks(trackID1).familyID ~= CellTracks(trackID2).familyID) for i=1:length(CellTracks(trackID1).childrenTracks) - ChangeTrackAndChildrensFamily(CellTracks(trackID2).familyID,CellTracks(trackID1).familyID,CellTracks(trackID1).childrenTracks(i)); + ChangeTrackAndChildrensFamily(CellTracks(trackID2).familyID,CellTracks(trackID1).familyID,CellTracks(trackID1).childrenTracks(1)); end for i=1:length(CellTracks(trackID2).childrenTracks) ChangeTrackAndChildrensFamily(CellTracks(trackID1).familyID,CellTracks(trackID2).familyID,CellTracks(trackID2).childrenTracks(i));