Skip to content

Commit

Permalink
Fixing bug in heteromeric graph contraction, enumeration is now corre…
Browse files Browse the repository at this point in the history
…ct for cases like 2ian, see #197
  • Loading branch information
josemduarte committed Oct 11, 2017
1 parent 42e3286 commit 73fac5c
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 31 deletions.
29 changes: 0 additions & 29 deletions eppic-cli/src/main/java/eppic/assembly/GraphContractor.java
Original file line number Diff line number Diff line change
Expand Up @@ -456,33 +456,4 @@ private static <V extends ChainVertexInterface, E extends InterfaceEdgeInterface
return counts;
}

public static <V extends ChainVertexInterface, E extends InterfaceEdgeInterface> boolean checkInterfClusterIsAutomorphicForEntities(
UndirectedGraph<V, E> g, int interfClusterId) {
int sourceEntityId = -1;
int targetEntityId = -1;
for (E e : g.edgeSet()) {
if (e.getClusterId() == interfClusterId) {
V s = g.getEdgeSource(e);
V t = g.getEdgeTarget(e);
sourceEntityId = s.getEntityId();
targetEntityId = t.getEntityId();
break;
}
}
if (sourceEntityId!=-1) {
if (!GraphUtils.isAutomorphicForEntityAndEdgeType(g, sourceEntityId, interfClusterId)) {
logger.warn("Graph is not automorphic with respect to entity id {} and interface cluster id {}", sourceEntityId, interfClusterId);
return false;
}
}
if (targetEntityId!=-1) {
if (!GraphUtils.isAutomorphicForEntityAndEdgeType(g, targetEntityId, interfClusterId)) {
logger.warn("Graph is not automorphic with respect to entity id {} and interface cluster id {}", targetEntityId, interfClusterId);
return false;
}
}

return true;

}
}
85 changes: 83 additions & 2 deletions eppic-cli/src/main/java/eppic/assembly/GraphUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
Expand Down Expand Up @@ -233,7 +234,8 @@ public static <V extends ChainVertexInterface, E extends InterfaceEdgeInterface>
}

/**
* Get the interface cluster id corresponding to the largest interface cluster present in given graph
* Get the interface cluster id corresponding to the largest interface cluster present in given graph,
* skipping those interface clusters that are not isomorphic throughout graph with respect to its endpoint entities.
* @param g
* @return the largest heteromeric interface cluster id, or -1 if none found
*/
Expand All @@ -242,7 +244,20 @@ public static <V extends ChainVertexInterface,E extends InterfaceEdgeInterface>

if (clusterIds.isEmpty()) return -1;

return clusterIds.first();
int interfClusterId = -1;
Iterator<Integer> it = clusterIds.iterator();
while (it.hasNext()) {
interfClusterId = it.next();
if (!isInterfClusterIsomorphicForEntities(g, interfClusterId)) {
logger.info("Interface cluster id {} is not isomorphic with respect to the 2 entities it connects. "
+ "Won't select it for contraction", interfClusterId );
continue;
} else {
break;
}
}

return interfClusterId;
}

/**
Expand Down Expand Up @@ -311,6 +326,72 @@ public static <V extends ChainVertexInterface,E extends InterfaceEdgeInterface>
return true;
}

/**
* Finds out whether the given graph is isomorphic for the given entity (entityId) and interface type (interfClusterId),
* i.e. if all nodes with the given entityId have an edge of the given interfClusterId
* @param g
* @param entityId
* @param interfClusterId
* @return
*/
public static <V extends ChainVertexInterface,E extends InterfaceEdgeInterface> boolean isIsomorphicForEntityAndEdgeType(
UndirectedGraph<V, E> g, int entityId, int interfClusterId) {
for (V v : g.vertexSet()) {
if (v.getEntityId() == entityId) {
boolean hasEdgeWithGivenInterfClusterId = false;
for (E e : g.edgesOf(v)) {
if (e.getClusterId() == interfClusterId) {
hasEdgeWithGivenInterfClusterId = true;
break;
}
}
if (!hasEdgeWithGivenInterfClusterId) {
// one vertex doesn't have an edge of the required type: the entity isn't isomorphic with
// respect to that interfClusterId
return false;
}
}
}
// all vertices of the given entityId have an edge of the given interfClusterId, the entity is isomorphic
// with respect to the given interfClusterId
return true;
}

/**
* Checks if given interface cluster is isomorphic throughout the graph with respect to the
* 2 entities it joins, i.e. if every node of the 2 entities has such an edge.
* @param g
* @param interfClusterId
* @return
*/
public static <V extends ChainVertexInterface, E extends InterfaceEdgeInterface> boolean isInterfClusterIsomorphicForEntities(
UndirectedGraph<V, E> g, int interfClusterId) {
int sourceEntityId = -1;
int targetEntityId = -1;
for (E e : g.edgeSet()) {
if (e.getClusterId() == interfClusterId) {
V s = g.getEdgeSource(e);
V t = g.getEdgeTarget(e);
sourceEntityId = s.getEntityId();
targetEntityId = t.getEntityId();
break;
}
}
if (sourceEntityId!=-1) {
if (!GraphUtils.isIsomorphicForEntityAndEdgeType(g, sourceEntityId, interfClusterId)) {
return false;
}
}
if (targetEntityId!=-1) {
if (!GraphUtils.isIsomorphicForEntityAndEdgeType(g, targetEntityId, interfClusterId)) {
return false;
}
}

return true;

}

private static <V extends ChainVertexInterface,E extends InterfaceEdgeInterface> Map<Integer,Integer> getInterfaceClusterIdsForVertex(UndirectedGraph<V, E> g, V v) {
Map<Integer,Integer> set = new HashMap<>();
for (InterfaceEdgeInterface e:g.edgesOf(v)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,5 +242,37 @@ public void testIssue148_3() throws IOException, StructureException {
assertTrue(gotTrimerAssembly);


}

/**
* See issue #197. 2ian wasn't enumerated correctly with contraction
* because some non-isomorphic heteromeric edges were chosen for contraction.
*/
@Test
public void test2ian() throws Exception {
Structure s = TestLatticeGraph.getStructure("2ian");

StructureInterfaceList interfaces = TestLatticeGraph.getAllInterfaces(s);

CrystalAssemblies crystalAssembliesC = new CrystalAssemblies(s, interfaces, true);


System.out.printf("%d assemblies found using contracted graph: \n", crystalAssembliesC.size());

for (Assembly a : crystalAssembliesC) {
System.out.println("assembly "+a.toString());

}

// we've got 2 assemblies
assertEquals(2, crystalAssembliesC.getAllAssemblies().size());
assertEquals(2, crystalAssembliesC.getUniqueAssemblies().size());

assertEquals("C1", crystalAssembliesC.getUniqueAssemblies().get(0).getDescription().iterator().next().getSymmetry());
assertEquals("C1", crystalAssembliesC.getUniqueAssemblies().get(1).getDescription().iterator().next().getSymmetry());

assertEquals(5, crystalAssembliesC.getUniqueAssemblies().get(1).getDescription().iterator().next().getSize());


}
}

0 comments on commit 73fac5c

Please sign in to comment.