Skip to content
This repository has been archived by the owner on Mar 29, 2024. It is now read-only.

GetNodesEqualsTo do not always return the proper nodes #165

Open
renoust opened this issue Jan 22, 2020 · 5 comments
Open

GetNodesEqualsTo do not always return the proper nodes #165

renoust opened this issue Jan 22, 2020 · 5 comments

Comments

@renoust
Copy link

renoust commented Jan 22, 2020

Hi,

I am scouting through subgraphs and using getNodesEqualTo of a string property as follows:

def linkViews(self, graph):
    for sg in graph.getSubGraphs():
      for t, values in self.type2nodes.items():
        for n in sg['node_type'].getNodesEqualTo(t):
          if sg['viewLabel'][n] in values:
             sg['viewSelection'][n] = True 

If I follow this logic, each node returned by sg['node_type'].getNodesEqualTo(t) should belong to sg a subgraph of graph. Unfortunately I obtained a message telling the contrary.

    if ssg['viewLabel'][n] in values:
Exception: Node with id 87749 does not belong to graph "gender" (id 10)

I have further ploted the number of match in comparison to the number of nodes of my subgraph:

for sg in graph.getSubGraphs():
      print ('subgraph: ',sg.getName(), sg.numberOfNodes())
      for t, values in self.type2nodes.items():
        nlist = [n for n in sg['node_type'].getNodesEqualTo(t)]
        print ('    ', t,  '--> matching ', len(nlist))

Which gives me:

subgraph:  gender 29
    : patient --> matching  689

Which can be read as:
in a subgraph titled gender which contains 29 nodes,
I am trying to match a value patient,
689 nodes are matching this condition.
Same if I use getStringProperty instead of brackets.

I believe the 689 nodes to match the parent graph or the root graph.

Now this behavior can be worked around by adding the subgraph as a parameter:
sg['node_type'].getNodesEqualTo(t, sg) (all the numbers are then correct).

But is this the expected behavior? There is a subtlety I understood while writing this post that the sg['node_type'] (or sg.getXXXProperty(YYY)) gives you the scope in which the property was intially created. But this is conterintuitive considering that we call the accessor within the graph and not from the tlp scope.

@bpinaud
Copy link
Contributor

bpinaud commented Jan 22, 2020

Hello,
I read quickly but this is normal Tulip behavior. A property can be local to a subgraph or inherited. sg['node_type'].getNodesEqualTo(t) will return all nodes from the graph where the property belongs, i.e., where it is local.
It is not conterintuitive. This gives you much more freedom. I, for instance, often iterate on the nodes of a subgraph to get the value of a property of the parent graph.

@renoust
Copy link
Author

renoust commented Jan 22, 2020

When you ask for getProperty, you expect to get the values of the inherited value if inherited that is no problem, as opposed to the values of local.

I also often iterate on the nodes of a subgraph to get the values of the parent, this is one major advantage of Tulip. My point is different.
What is counter intuitive it that the subset of nodes is not the one of which the getProperty is called, but the one of the property's creation. Because we call it some sg, and some nodes of graph which do not belong to sg. These issues are especially hard to identify.

I understand the point on an object model perspective (returns the same pointer), I'm more talking on a code semantic one.
Do you see the subtlety? basically, we expect that the node iterator is placed from within the scope in which we would access the property.

Imagine you have sg and ssg very different subgraphs of graph, I am not sure many people would expect to see that:
sg[`someProp`] == ssg[`someProp`] == graph[`someProp`]
would return the exact same object, hence the exact same iterator when using getNodesEqualTo.

@anlambert
Copy link
Contributor

I agree with @bpinaud, this is Tulip normal behavior and not a design flaw. The Python brackets notation is just syntactic sugar to write shorter code. But you still get a pointer to a property and it is up to the caller to filter the nodes to process when calling getNodesEqualTo.

@renoust
Copy link
Author

renoust commented Jan 23, 2020 via email

@anlambert
Copy link
Contributor

As I told earlier, it is not about the bracket, but about the getProperty
too. I understand the pointer logic, but the semantic is confusing. At
least we may raise this warning in the doc.

Indeed, the Tulip semantics are quite particular for a Python programmer. I agree that the documentation could be improved to clarify that behavior.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants