Skip to content

Commit 3747377

Browse files
committed
Initial implementation and tests
1 parent 5840f24 commit 3747377

4 files changed

Lines changed: 232 additions & 7 deletions

File tree

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package org.biojava.nbio.structure.test.contact;
2+
3+
import org.biojava.nbio.structure.Structure;
4+
import org.biojava.nbio.structure.StructureException;
5+
import org.biojava.nbio.structure.StructureIO;
6+
import org.biojava.nbio.structure.contact.AtomContact;
7+
import org.biojava.nbio.structure.contact.AtomContactSet;
8+
import org.biojava.nbio.structure.contact.InterfaceFinder;
9+
import org.biojava.nbio.structure.contact.Pair;
10+
import org.biojava.nbio.structure.contact.StructureInterface;
11+
import org.biojava.nbio.structure.contact.StructureInterfaceList;
12+
import org.junit.Test;
13+
14+
import java.io.IOException;
15+
import java.util.HashSet;
16+
import java.util.Set;
17+
18+
import static org.junit.Assert.assertEquals;
19+
20+
public class TestInterfaceFinder {
21+
22+
@Test
23+
public void testGetAllInterfaces() throws StructureException, IOException {
24+
Structure s = StructureIO.getStructure("3hbx");
25+
InterfaceFinder finder = new InterfaceFinder(s);
26+
27+
StructureInterfaceList list = finder.getAllInterfaces();
28+
29+
assertEquals(12, list.size());
30+
31+
Set<Pair<String>> unique = new HashSet<>();
32+
33+
for (StructureInterface interf : list) {
34+
System.out.println("Interface " + interf.getMoleculeIds());
35+
AtomContactSet set = interf.getContacts();
36+
System.out.println("Number of contacts: " + set.size());
37+
38+
unique.add(interf.getMoleculeIds());
39+
40+
}
41+
assertEquals(12, unique.size());
42+
}
43+
}

biojava-structure/src/main/java/org/biojava/nbio/structure/StructureTools.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ public static List<Group> getUnalignedGroups(Atom[] ca) {
474474
* @see StructureTools#DEFAULT_LIGAND_PROXIMITY_CUTOFF
475475
*/
476476
public static List<Group> getLigandsByProximity(Collection<Group> target, Atom[] query, double cutoff) {
477-
// Geometric hashing of the reduced structure
477+
// Spatial hashing of the reduced structure
478478
Grid grid = new Grid(cutoff);
479479
grid.addAtoms(query);
480480

@@ -1387,7 +1387,7 @@ public static final Group getGroupByPDBResidueNumber(Structure struc,
13871387

13881388
/**
13891389
* Returns the set of intra-chain contacts for the given chain for given
1390-
* atom names, i.e. the contact map. Uses a geometric hashing algorithm that
1390+
* atom names, i.e. the contact map. Uses a spatial hashing algorithm that
13911391
* speeds up the calculation without need of full distance matrix. The
13921392
* parsing mode {@link FileParsingParameters#setAlignSeqRes(boolean)} needs
13931393
* to be set to true for this to work.
@@ -1422,7 +1422,7 @@ public static AtomContactSet getAtomsInContact(Chain chain,
14221422

14231423
/**
14241424
* Returns the set of intra-chain contacts for the given chain for all non-H
1425-
* atoms of non-hetatoms, i.e. the contact map. Uses a geometric hashing
1425+
* atoms of non-hetatoms, i.e. the contact map. Uses a spatial hashing
14261426
* algorithm that speeds up the calculation without need of full distance
14271427
* matrix. The parsing mode
14281428
* {@link FileParsingParameters#setAlignSeqRes(boolean)} needs to be set to
@@ -1439,7 +1439,7 @@ public static AtomContactSet getAtomsInContact(Chain chain, double cutoff) {
14391439
/**
14401440
* Returns the set of intra-chain contacts for the given chain for C-alpha
14411441
* atoms (including non-standard aminoacids appearing as HETATM groups),
1442-
* i.e. the contact map. Uses a geometric hashing algorithm that speeds up
1442+
* i.e. the contact map. Uses a spatial hashing algorithm that speeds up
14431443
* the calculation without need of full distance matrix. The parsing mode
14441444
* {@link FileParsingParameters#setAlignSeqRes(boolean)} needs to be set to
14451445
* true for this to work.
@@ -1462,7 +1462,7 @@ public static AtomContactSet getAtomsCAInContact(Chain chain, double cutoff) {
14621462
/**
14631463
* Returns the set of intra-chain contacts for the given chain for C-alpha
14641464
* or C3' atoms (including non-standard aminoacids appearing as HETATM
1465-
* groups), i.e. the contact map. Uses a geometric hashing algorithm that
1465+
* groups), i.e. the contact map. Uses a spatial hashing algorithm that
14661466
* speeds up the calculation without need of full distance matrix.
14671467
*
14681468
* @param chain
@@ -1483,7 +1483,7 @@ public static AtomContactSet getRepresentativeAtomsInContact(Chain chain,
14831483

14841484
/**
14851485
* Returns the set of inter-chain contacts between the two given chains for
1486-
* the given atom names. Uses a geometric hashing algorithm that speeds up
1486+
* the given atom names. Uses a spatial hashing algorithm that speeds up
14871487
* the calculation without need of full distance matrix. The parsing mode
14881488
* {@link FileParsingParameters#setAlignSeqRes(boolean)} needs to be set to
14891489
* true for this to work.
@@ -1518,7 +1518,7 @@ public static AtomContactSet getAtomsInContact(Chain chain1, Chain chain2,
15181518

15191519
/**
15201520
* Returns the set of inter-chain contacts between the two given chains for
1521-
* all non-H atoms. Uses a geometric hashing algorithm that speeds up the
1521+
* all non-H atoms. Uses a spatial hashing algorithm that speeds up the
15221522
* calculation without need of full distance matrix. The parsing mode
15231523
* {@link FileParsingParameters#setAlignSeqRes(boolean)} needs to be set to
15241524
* true for this to work.
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package org.biojava.nbio.structure.contact;
2+
3+
import org.biojava.nbio.structure.Chain;
4+
import org.biojava.nbio.structure.Structure;
5+
import org.biojava.nbio.structure.StructureTools;
6+
import org.biojava.nbio.structure.xtal.CrystalTransform;
7+
import org.biojava.nbio.structure.xtal.SpaceGroup;
8+
9+
import java.util.List;
10+
11+
public class InterfaceFinder {
12+
13+
public static final double DEFAULT_CONTACT_CUTOFF = 6;
14+
15+
private static final CrystalTransform IDENTITY_TRANSFORM = new CrystalTransform(SpaceGroup.parseSpaceGroup("P1"));
16+
private static final boolean INCLUDE_HETATOMS = true;
17+
18+
private Structure structure;
19+
private double cutoff;
20+
21+
public InterfaceFinder(Structure structure) {
22+
this.structure = structure;
23+
this.cutoff = DEFAULT_CONTACT_CUTOFF;
24+
}
25+
26+
public void setCutoff(double cutoff) {
27+
this.cutoff = cutoff;
28+
}
29+
30+
public StructureInterfaceList getAllInterfaces() {
31+
StructureInterfaceList list = new StructureInterfaceList();
32+
33+
List<Chain> polyChains = structure.getPolyChains();
34+
for (int i = 0; i<polyChains.size(); i++) {
35+
for (int j = i + 1; j<polyChains.size(); j++) {
36+
StructureInterface interf = calcInterface(polyChains.get(i), polyChains.get(j));
37+
if (interf!=null) {
38+
list.add(interf);
39+
}
40+
}
41+
}
42+
return list;
43+
}
44+
45+
private StructureInterface calcInterface(Chain chain1, Chain chain2) {
46+
AtomContactSet graph = StructureTools.getAtomsInContact(chain1, chain2, cutoff, INCLUDE_HETATOMS);
47+
48+
StructureInterface interf = null;
49+
if (graph.size()>0) {
50+
interf = new StructureInterface(
51+
StructureTools.getAllAtomArray(chain1), StructureTools.getAllAtomArray(chain2),
52+
chain1.getName(), chain2.getName(),
53+
graph,
54+
IDENTITY_TRANSFORM, IDENTITY_TRANSFORM);
55+
}
56+
57+
return interf;
58+
}
59+
}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package org.biojava.nbio.structure.contact;
2+
3+
import org.biojava.nbio.structure.AminoAcidImpl;
4+
import org.biojava.nbio.structure.Atom;
5+
import org.biojava.nbio.structure.AtomImpl;
6+
import org.biojava.nbio.structure.Chain;
7+
import org.biojava.nbio.structure.ChainImpl;
8+
import org.biojava.nbio.structure.EntityInfo;
9+
import org.biojava.nbio.structure.Group;
10+
import org.biojava.nbio.structure.ResidueNumber;
11+
import org.biojava.nbio.structure.Structure;
12+
import org.biojava.nbio.structure.StructureImpl;
13+
import org.biojava.nbio.structure.StructureTools;
14+
import org.junit.Test;
15+
import static org.junit.Assert.*;
16+
17+
import javax.vecmath.Point3d;
18+
import java.util.ArrayList;
19+
import java.util.HashSet;
20+
import java.util.List;
21+
import java.util.Set;
22+
23+
public class TestInterfaceFinder {
24+
25+
@Test
26+
public void testGetAllInterfaces() {
27+
Structure s = mockStructure();
28+
InterfaceFinder finder = new InterfaceFinder(s);
29+
30+
StructureInterfaceList list = finder.getAllInterfaces();
31+
32+
assertEquals(3, list.size());
33+
34+
Set<Pair<String>> unique = new HashSet<>();
35+
36+
for (StructureInterface interf : list) {
37+
System.out.println("Interface " + interf.getMoleculeIds());
38+
AtomContactSet set = interf.getContacts();
39+
for (AtomContact c : set)
40+
System.out.println(c.getPair() +" - " + c.getDistance());
41+
42+
unique.add(interf.getMoleculeIds());
43+
44+
}
45+
assertEquals(3, unique.size());
46+
}
47+
48+
/**
49+
* Create a mock structure with 2 entities 1 (chains A, B) and 2 (chain C).
50+
* @return a structure
51+
*/
52+
private Structure mockStructure() {
53+
Structure structure = new StructureImpl();
54+
EntityInfo entity1 = new EntityInfo();
55+
entity1.setMolId(1);
56+
EntityInfo entity2 = new EntityInfo();
57+
entity2.setMolId(2);
58+
structure.addEntityInfo(entity1);
59+
structure.addEntityInfo(entity2);
60+
61+
Chain chainA = new ChainImpl();
62+
chainA.setId("A");
63+
chainA.setName("A");
64+
Chain chainB = new ChainImpl();
65+
chainB.setId("B");
66+
chainB.setName("B");
67+
entity1.addChain(chainA);
68+
entity1.addChain(chainB);
69+
Chain chainC = new ChainImpl();
70+
chainC.setId("C");
71+
chainC.setName("C");
72+
entity2.addChain(chainC);
73+
74+
structure.addChain(chainA);
75+
structure.addChain(chainB);
76+
structure.addChain(chainC);
77+
78+
// entity 1: chain A 10 observed residues, chain B 9 observed residues (first unobserved)
79+
List<Group> aGroups = getGroupList(10, "ALA", chainA, new Point3d(0,0,0));
80+
chainA.setAtomGroups(new ArrayList<>(aGroups));
81+
chainA.setSeqResGroups(aGroups);
82+
chainA.setEntityInfo(entity1);
83+
84+
List<Group> bGroups = getGroupList(10, "ALA", chainB, new Point3d(4, 0, 0));
85+
chainB.setAtomGroups(new ArrayList<>(bGroups.subList(1,10)));
86+
chainB.setSeqResGroups(bGroups);
87+
chainB.setEntityInfo(entity1);
88+
89+
List<Group> cGroups = getGroupList(20, "GLY", chainC, new Point3d(0, 4, 0));
90+
chainC.setAtomGroups(new ArrayList<>(cGroups));
91+
chainC.setSeqResGroups(cGroups);
92+
chainC.setEntityInfo(entity2);
93+
94+
return structure;
95+
}
96+
97+
private List<Group> getGroupList(int size, String type, Chain chain, Point3d center) {
98+
List<Group> list = new ArrayList<>();
99+
double offsetx = 0;
100+
double offsety = 0;
101+
double offsetz = 0;
102+
for (int i=0;i<size;i++) {
103+
Group g = new AminoAcidImpl();
104+
g.setPDBName(type);
105+
g.setResidueNumber(new ResidueNumber(chain.getId(), i+1, null));
106+
chain.addGroup(g);
107+
Atom a = new AtomImpl();
108+
a.setName(StructureTools.CA_ATOM_NAME);
109+
a.setX(center.x + offsetx);
110+
a.setY(center.y + offsety);
111+
a.setZ(center.z + offsetz);
112+
g.addAtom(a);
113+
list.add(g);
114+
115+
if (i%3 == 0) offsetx += 1;
116+
if (i%3 == 1) offsety += 1;
117+
if (i%3 == 2) offsetz += 1;
118+
}
119+
120+
return list;
121+
}
122+
123+
}

0 commit comments

Comments
 (0)