Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ShowSelectedTracksAction: don't get stuck if there's a loop in the graph #229

Merged
merged 9 commits into from
May 31, 2023

Conversation

maarzt
Copy link
Contributor

@maarzt maarzt commented Mar 20, 2023

fixes #222

The "show track downward" action got stuck, whenever there's a loop in the
ModelGraph. This is because the "show track downward" action uses the
DepthFirstIteration class to iterate over the ModelGraph when searching
for the correct new roots.

The DepthFirstIteration class itself does not detect loops and hangs if
loops are present in the graph. The commit adds the required tests to
that keep track of visited nodes and breaks the loop during iteration.
@maarzt maarzt requested review from stefanhahmann and tinevez March 20, 2023 16:04
Copy link
Collaborator

@stefanhahmann stefanhahmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pull request fixes the described bug.

I would recommend to add the 2 new notes to the javadoc. It is a private method, but you added javadoc to it anyway already. The notes are very informative and the javadoc would benefit from it.

In general this method seems to be a very efficient way to get the root nodes of selected nodes (and now even avoiding to get stuck in case of loops).

It may even be worth to move this method as a public static method to a Utility class, since it solves a problem that may be used in different context. If you do so, it may be worth to write a unit test for it that shows that it does not fail on trees that have loops.

@maarzt
Copy link
Contributor Author

maarzt commented Mar 24, 2023

I extracted the filterRootNodes method into a utility class "TreeUtils" and wrote a unit test for it. I also renamed the method to findSelectedSubtreeRoot(...). I hope the new name gives a better impression of what the method does.

@maarzt maarzt requested a review from stefanhahmann March 24, 2023 14:01
@stefanhahmann
Copy link
Collaborator

I extracted the filterRootNodes method into a utility class "TreeUtils" and wrote a unit test for it. I also renamed the method to findSelectedSubtreeRoot(...). I hope the new name gives a better impression of what the method does.

This is very good. I noticed that in the class ShowSelectedTracksActions, the method getRealRoots() would also be a candidate that could be moved to TreeUtils(), since it could also be used in other contexts.

Copy link
Collaborator

@stefanhahmann stefanhahmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A code smell has been detected in the findSelectedSubtreeRoots() method.
Apart from this, the changes are perfect. The tests fit well to the intended purpose.

src/main/java/org/mastodon/util/TreeUtils.java Outdated Show resolved Hide resolved
Copy link
Contributor Author

@maarzt maarzt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say the PR is ready. What do you think?

@maarzt maarzt requested a review from stefanhahmann April 17, 2023 11:14
Copy link
Collaborator

@stefanhahmann stefanhahmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding findRealRoots() to TreeUtils. I am sure this method can be used elsewhere in the project.

I think the related unit test could be a bit extended. Also this method may deserve some javadoc. I made suggestions for both.

The method findSelectedSubtreeRoots() does not contains the detected code smell anymore and is well reabable.

final RefList< V > selectedSubtreeRoots = RefCollections.createRefList( graph.vertices() );
final RefSet< V > visitedNodes = RefCollections.createRefSet( graph.vertices() );

for ( final V realRoot : roots )
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a bit confused now about what a realRoot is. There is now also a method in this in this class called findRealRoots. In this function a realRoot seems to be something else than within this method. If I understood this correctly, I would think the variable here should be named root instead of realRoot.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are reasons to be confused. This PR changes code that works with roots of subtrees. Every node in a tree is at the same time the root of a subtree. So the borders between the terms node and root become blurry. I don't have a good way to resolve this confusion.

src/test/java/org/mastodon/util/TreeUtilsTest.java Outdated Show resolved Hide resolved
@maarzt maarzt requested a review from stefanhahmann May 3, 2023 08:00
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the mastodon-graph lib there is RootFinder:
https://github.com/mastodon-sc/mastodon-graph/blob/master/src/main/java/org/mastodon/graph/algorithm/RootFinder.java
Maybe we could merge these two?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what you would like to suggest. Would you like to have a method TreeUtils.getRoots(graph) that replaces new RootFinder(graph).get()?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes exactly. Do you think it is a good fit? One fewer class.... that would be nice.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would make sense organize the utility classes, but maybe not as a part of this PR.

There is already a ticket mastodon-sc/mastodon-tomancak#13, we should have a look at the RootFinder as part of this.

Rename the findRealRoots to findRootsOfTheGivenNodes.

Mastodon works with graphs not trees. The findRootsOfTheGivenNodes method
would under some conditions not return all roots of the graph. There is now
a unit test for this. And the method has been fixes.
src/main/java/org/mastodon/util/TreeUtils.java Outdated Show resolved Hide resolved
src/test/java/org/mastodon/util/TreeUtilsTest.java Outdated Show resolved Hide resolved
src/test/java/org/mastodon/util/TreeUtilsTest.java Outdated Show resolved Hide resolved
src/test/java/org/mastodon/util/TreeUtilsTest.java Outdated Show resolved Hide resolved
src/test/java/org/mastodon/util/TreeUtilsTest.java Outdated Show resolved Hide resolved
@stefanhahmann stefanhahmann self-requested a review May 24, 2023 12:56
Copy link
Collaborator

@stefanhahmann stefanhahmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I approve this PR

The method findRootsOfTheGivenNodes is used in the
ShowSelectedTracksAction. It's purpose is to find the root nodes of the
tracks that contain selected nodes. The new implementation gives better
results if the ModelGraph also contains merges.

The previous implementataion worked fine if the ModelGraph contained only
trees. But it did miss root nodes for more general graphs. In order to
get all roots it is necessary to do a depth first search that considers the
graph as undirected.

Example graph:
a   b
| \ |
c   d

If "c" is selected, the method now return both roots "a" and "b" of the
track.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants