Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
4f33a18
test commit and enter first TODO point.
raacampbell Apr 10, 2015
ce46f8e
Change concatenation during object creation so it works for arbitrary…
raacampbell Apr 11, 2015
58b6042
Fix incorrect treatment of non-numerics as numerics. Handle more abst…
raacampbell Apr 11, 2015
9c86fe4
obj.Node must be a column vector.
raacampbell Apr 11, 2015
8645b16
Minor correction in comments: camel case was wrong.
raacampbell Apr 11, 2015
012c09d
Allow plot and depthfirstiterator to handle data classes that aren't …
raacampbell Apr 11, 2015
243cb1c
replace "i" with "ii" in for loop
raacampbell Apr 11, 2015
fa620b5
Add example in comment. Replace "i" with "ii" in for loop.
raacampbell Apr 11, 2015
df73f8a
replace special character with an 'o' because my text editor wasn't h…
raacampbell Apr 11, 2015
f4d6373
missing semicolon
raacampbell Apr 11, 2015
1905273
silence the warning by default.
raacampbell Apr 11, 2015
2e9caef
incorporate faster method for finding path between root and node (sim…
raacampbell Apr 13, 2015
47daf40
Dump tree to a text and select node contents to string for exporting …
raacampbell Aug 3, 2015
32a4386
missing semi-colons.
raacampbell Aug 3, 2015
0532b51
add function that gets all the unique segments in the tree. Useful fo…
raacampbell Sep 22, 2015
32a86a8
Make node data public, so they can be edited. Leave the parent ID pri…
raacampbell Oct 14, 2015
ad4aed7
modify findleaves so it can optionally return only leaves that descen…
raacampbell Oct 14, 2015
9916361
Merge remote-tracking branch 'tinevez_github/master'
Nov 10, 2015
68f30dc
comment improvements to dumptree
Nov 17, 2015
a31b489
add method to remove a sub-tree
raacampbell Feb 12, 2016
ce0844e
add help text to the graft method
raacampbell Feb 12, 2016
c49cbca
add function to change a node's parent
raacampbell Feb 12, 2016
57b29ee
treefun supports variable # output arguments
ejrx Sep 23, 2016
5369682
varargout support for treefun2
ejrx Sep 23, 2016
11e166d
My removesubtree seems to be a reimplementation of chop, which alread…
raacampbell Jan 4, 2017
410c92a
Merge remote-tracking branch 'ejrx/ejrx/treefun-varargout' into dev
raacampbell Jan 4, 2017
b26de63
Merge branch 'master' into dev
raacampbell Jan 4, 2017
72d1822
chop works just fine.
raacampbell Jan 4, 2017
54e3d4b
Merge branch 'dev'
raacampbell Jan 4, 2017
2d1bb93
Bugfixes and safety features to changeparent.
raacampbell Jan 5, 2017
3d39d9a
Minor fix to documentation
raacampbell Jan 17, 2017
6675e52
minor
raacampbell Jan 19, 2017
a8582e0
minor
raacampbell Jan 29, 2017
493604a
simple way of printing tree contents
raacampbell Jan 29, 2017
127b8ba
Minor readme change
raacampbell Jan 29, 2017
208ee09
minor
raacampbell Nov 29, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions @tree/changeparent.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
function obj = changeparent(obj, selectedNode, newParent)
% Assign a given node to a new parent
%
% obj = changeparent(obj, selectedNode, newParent)
%
%
% EXAMPLE:
% move node 100 to a new parent (300)
%
% myTree = myTree.changeparent(100,300)
%
%
% Rob Campbell - 2016

% Do not proceed if newParent is a child of the selected node.
% Proceeding will cause this part of the tree to be deleted.
if any(obj.getchildren(selectedNode) == newParent)
disp('tree.changeparent -- newParent can not be a child of selectedNode')
return
end

%Get a subtree
subTree=obj.subtree(selectedNode);

%Graft the subtree to the new location
modifiedTree = obj.graft(newParent,subTree);

%Remove the sub-tree (must remove afterwards or sometimes the graft is to the wrong place)
modifiedTree = modifiedTree.chop(selectedNode);

% Do not return the tree if the number of nodes has changed.
% This can happen if the changeparent operation breaks the tree, since the broken part just gets deleted
if length(modifiedTree.Node) ~= length(obj.Node)
disp('tree.changeparent -- can not perform operation: it would change the number of nodes in the tree')
else
obj=modifiedTree;
end



end
11 changes: 8 additions & 3 deletions @tree/chop.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
function obj = chop(obj, node)
%% CHOP Remove the target node and all subnodes from the given tree.
%
%
% e.g.
% nodeIndex=34;
% myTree.chop(nodeIndex)

iterator = obj.depthfirstiterator(node);

Expand All @@ -8,12 +13,12 @@

% Remove unwanted nodes
np ( iterator ) = [];

% Shift parent value: if a parent were after some nodes we removed, we
% need to shift its value by an amount equal to the number of parent we
% removed, and that were BEFORE the target parent
for i = 1 : numel(np)
np(i) = np(i) - sum(np(i) > iterator);
for ii = 1 : numel(np)
np(ii) = np(ii) - sum(np(ii) > iterator);
end

obj.Parent = np;
Expand Down
28 changes: 19 additions & 9 deletions @tree/depthfirstiterator.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
% % Create a copy of the tree that holds the order of iteration
% lineage = tree.example;
% itOrder = tree(lineage, 'clear'); % Copy the tree structure only
% iterator = itOrder.depthFirstIterator;
% iterator = itOrder.depthfirstiterator;
% index = 1;
% for i = iterator
% itOrder = itOrder.set(i, index);
Expand All @@ -27,7 +27,7 @@
% EXAMPLE 2
% % List the content of a subtree of the tree
% lineage = tree.example;
% iterator = lineage.depthFirstIterator(19);
% iterator = lineage.depthfirstiterator(19);
% content = cell(numel(iterator), 1);
% index = 1;
% for i = iterator
Expand All @@ -46,7 +46,8 @@
IDs = recurse(startNode);

function val = recurse(node)

showWarning=0;

val = node;
if obj.isleaf(node)
return
Expand All @@ -57,15 +58,24 @@
if sorted && numel(children) > 1

contents = obj.Node(children);
[~, sorting_array] = sortrows(contents);
children = children(sorting_array);
try
[~, sorting_array] = sortrows(contents);
children = children(sorting_array);
catch
if showWarning
fprintf('%s: Failed to sort tree contents. Data type likely not sortable\n',mfilename)
end
children=children(1:length(contents));
end

end

cellval = cell(numel(children), 1);
for i = 1 : numel(children)
cellval{i} = recurse(children(i));


cellval = cell(numel(children), 1); %prealloacte a cell array
for ii = 1 : numel(children)
cellval{ii} = recurse(children(ii)); %recursive function call
end

val = [ val cellval{:} ] ;

end
Expand Down
40 changes: 40 additions & 0 deletions @tree/dumptree.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
function str = dumptree(obj, nodeFunc)
%% DUMPTREE Dump the contents of the tree to a string.
%
% Each line of the string (lines terminated by newline) is one node.
% Each line is in the format:
% node_index , node_parent , node_contents
%
% If the node_contents is a string then the it is simply printed.
% If node_contents is anything else, then the user must supply
% a function handle (nodeFunc) that tells dumptree how to handle
% the data.
%
% Examples
% myTree.dumptree(@(n) sprintf('%d,%d,%d',n.xVoxel,n.yVoxel,n.zVoxel))
% myTree.dumptree(@treeDumperFncInPathSomewhere)
% myTree.dumptree()
% dumpTree(myTree)
%
% Rob Campbell, Basel, 2015


if nargin<2
nodeFunc=[];
if ~isstr(obj.Node{1})
fprintf('Node data are not a string but nodeFunc was not defined.\nAborting\n\n')
return
end
end


str= '';
for ii=1:obj.nnodes
if isempty(nodeFunc)
nodeData = obj.Node{ii};
else
nodeData = nodeFunc(obj.Node{ii});
end

str = [str,sprintf('%d,%d,%s\n',ii,obj.Parent(ii),nodeData)];
end
11 changes: 11 additions & 0 deletions @tree/findpath.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,22 @@
% index = index + 1;
% end
% disp(pt.tostring)
%
%




if n1 == n2

path = n1;

elseif n2 == 1
path = obj.pathtoroot(n1);

elseif n1 == 1
path = fliplr(obj.pathtoroot(n2));

elseif any( n2 == obj.depthfirstiterator(n1) )
% n2 is in the children of n1
path = [ n1 descend(n1) ];
Expand Down
48 changes: 48 additions & 0 deletions @tree/getsegments.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
function segments = getsegments(obj, linkSegments, nodeID, segments)
%% GETSEGMENTS Return a cell array containing all unique segments of the tree
%
% segments = getsegments(obj, linkSegments)
%
% Options
% If linkSegments is 1, then the branch node is added to each returned segement. This makes
% it possible to plot the data without gaps appearing. This is the default.
% If linkSegments is 0, then the no duplicate points are returned.
%
% Examples
% segments = myTree.getsegments %for plotting a tree without repeats
% segments = myTree.getsegments(0) %for returning segments without redundant nodes
%
%
% Rob Campbell, Basel, 2015


if nargin<2
linkSegments=1;
end

if nargin<3
nodeID = 1;
segments = {};
end

if linkSegments & nodeID>1
thisPath = [obj.getparent(nodeID)];
else
thisPath = [];
end

while length(nodeID)==1 %Loop until we get to a branch point
thisPath = [thisPath,nodeID];
nodeID = obj.getchildren(nodeID);
end

%Store this segment
segments = [segments,thisPath];

%Go into the branches with a recursive function call
for ii=1:length(nodeID)
segments=obj.getsegments(linkSegments,nodeID(ii),segments);
end



22 changes: 16 additions & 6 deletions @tree/graft.m
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
function obj = graft(obj, ID, othertree)
%% GRAFT Graft another tree at the specified node of this tree.

% Graft another tree at the specified node of this tree.
%
% obj = graft(obj, node, othertree)
% Returns a new tree made of the current tree with the new tree (othertree) attached at node "ID".
%
%
% EXAMPLE:
% graft "differentTree" to "myTree" at node 200
%
% myTree = myTree.graft(200,differentTree)
%
%
% Jean-Yves Tinevez - 2013

nNodes = numel(obj.Parent);

otParents = othertree.Parent;
% Shift other parent indices
otParents = otParents + nNodes;
% Make the other root a child of the target node
otParents(1) = ID;

otParents = otParents + nNodes; % Shift other parent indices
otParents(1) = ID; % Make the other root a child of the target node

% Concatenate
newParents = [ obj.Parent ; otParents ];
Expand Down
30 changes: 30 additions & 0 deletions @tree/pathtoroot.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
function path = pathtoroot(obj, n)
%% PATHTOROOT Path from node "n" to the tree root.
%
% This is a special case of findpath(), which simply needs to follow a tree back
% by looking at node's parent. Since a node can only have one parent, this is
% trivial. It's about 50 times faster than calling findpath(1,myNode), since we don't need
% to exhaustively search the tree for the fastest path.
%



if n == 1

path = n;
return

else

p=obj.Parent(n);
path=[n,p];
while p ~= 1
p=obj.Parent(p);
path(end+1)=p; % For very large trees it might hekp to pre-allocate then prune back. But right now it doesn't seem worth it.
end



end


9 changes: 6 additions & 3 deletions @tree/plot.m
Original file line number Diff line number Diff line change
Expand Up @@ -295,10 +295,13 @@
% The label = content
content = obj.get(i);
if isempty(content)
content = '';
content = 'o';
end
if ~ischar(content)
content = num2str(content);

if isnumeric(content)
content = num2str(content)
else
content=class(content);
end

ht = text(x1, y2, contentfun(content), ... A hack to have text displayed above bars
Expand Down
10 changes: 8 additions & 2 deletions @tree/private/contentToString.m
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
% Nothing -> print the void symbol
str = '�';
elseif ~ischar(content)

if numel(content) == 1
% Scalar stuff we most probably be able to print
if islogical(content)
Expand All @@ -30,9 +31,14 @@
% Cell with one element -> append cell and print element
str = ['cell:' contentToString(content{1}) ];

else
% Scalar number -> print it
elseif isnumeric(content)

% number -> print it
str = num2str(content);

else
%unknown or a struct so print this instead
str = class(content);
end

else
Expand Down
1 change: 1 addition & 0 deletions @tree/removenode.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
function obj = removenode(obj , node)
% remove selected node and return tree with this node missing

if node <= 1
error('MATLAB:tree:removenode', ...
Expand Down
Loading