Skip to content

Commit 08150f5

Browse files
author
Dmytro Guzenko
committed
NCS-aware CrystalBuilder object
1 parent 5a1068d commit 08150f5

File tree

4 files changed

+360
-76
lines changed

4 files changed

+360
-76
lines changed

biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/xtal/TestCrystalBuilder.java

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@
2828
import org.biojava.nbio.structure.xtal.CrystalBuilder;
2929
import org.junit.Test;
3030

31+
import javax.vecmath.Matrix4d;
3132
import java.io.IOException;
33+
import java.util.HashMap;
34+
import java.util.Map;
3235

3336
import static org.junit.Assert.*;
3437

@@ -48,7 +51,7 @@ public void test1NMR() throws IOException, StructureException {
4851

4952
CrystalBuilder cb = new CrystalBuilder(s1);
5053
StructureInterfaceList interfaces = cb.getUniqueInterfaces(5.5);
51-
assertTrue(interfaces.size()==0);
54+
assertEquals(0,interfaces.size());
5255

5356
}
5457

@@ -65,7 +68,7 @@ public void test1B8G() throws IOException, StructureException {
6568
Structure s1 = StructureIO.getStructure("1B8G");
6669
CrystalBuilder cb = new CrystalBuilder(s1);
6770
StructureInterfaceList interfaces = cb.getUniqueInterfaces(5.5);
68-
assertTrue(interfaces.size()>1);
71+
assertEquals(8,interfaces.size());
6972

7073

7174
}
@@ -83,7 +86,7 @@ public void test2MFZ() throws IOException, StructureException {
8386
Structure s1 = StructureIO.getStructure("2MFZ");
8487
CrystalBuilder cb = new CrystalBuilder(s1);
8588
StructureInterfaceList interfaces = cb.getUniqueInterfaces(5.5);
86-
assertTrue(interfaces.size()==1);
89+
assertEquals(1,interfaces.size());
8790

8891
}
8992

@@ -100,10 +103,55 @@ public void test4MF8() throws IOException, StructureException {
100103
Structure s1 = StructureIO.getStructure("4MF8");
101104
CrystalBuilder cb = new CrystalBuilder(s1);
102105
StructureInterfaceList interfaces = cb.getUniqueInterfaces(5.5);
103-
assertTrue(interfaces.size()>3);
106+
assertEquals(17,interfaces.size());
104107

105108
}
106109

110+
@Test
111+
public void test1AUY() throws IOException, StructureException {
112+
// a virus with NCS operators
113+
AtomCache cache = new AtomCache();
114+
StructureIO.setAtomCache(cache);
115+
cache.setUseMmCif(true);
116+
Structure s1 = StructureIO.getStructure("1AUY");
117+
118+
Map<String,Matrix4d> chainNcsOps = new HashMap<>();
119+
Map<String,String> chainOrigNames = new HashMap<>();
120+
121+
CrystalBuilder.expandNcsOps(s1,chainOrigNames,chainNcsOps);
122+
123+
CrystalBuilder cb = new CrystalBuilder(s1,chainOrigNames,chainNcsOps);
124+
StructureInterfaceList interfaces = cb.getUniqueInterfaces(5.5);
125+
assertEquals(186,interfaces.size());
126+
assertEquals(24,interfaces.getClustersNcs().size());
127+
128+
// kill the cell info to simulate incorrect and/or missing
129+
s1.getCrystallographicInfo().setCrystalCell(null);
130+
cb = new CrystalBuilder(s1,chainOrigNames,chainNcsOps);
131+
interfaces = cb.getUniqueInterfaces(5.5);
132+
//only interfaces within AU
133+
assertEquals(132,interfaces.size());
134+
assertEquals(12,interfaces.getClustersNcs().size());
135+
}
136+
137+
@Test
138+
public void test1A37() throws IOException, StructureException {
139+
// a smaller structure with NCS operators
140+
AtomCache cache = new AtomCache();
141+
StructureIO.setAtomCache(cache);
142+
cache.setUseMmCif(true);
143+
Structure s1 = StructureIO.getStructure("1A37");
144+
145+
Map<String,Matrix4d> chainNcsOps = new HashMap<>();
146+
Map<String,String> chainOrigNames = new HashMap<>();
147+
CrystalBuilder.expandNcsOps(s1,chainOrigNames,chainNcsOps);
148+
149+
CrystalBuilder cb = new CrystalBuilder(s1,chainOrigNames,chainNcsOps);
150+
StructureInterfaceList interfaces = cb.getUniqueInterfaces(5.5);
151+
assertEquals(17,interfaces.size());
152+
assertEquals(14,interfaces.getClustersNcs().size());
153+
}
154+
107155
@Test
108156
public void test2H2Z() throws IOException, StructureException {
109157

@@ -120,7 +168,7 @@ public void test2H2Z() throws IOException, StructureException {
120168
Structure s1 = StructureIO.getStructure("2H2Z");
121169
CrystalBuilder cb = new CrystalBuilder(s1);
122170
StructureInterfaceList interfaces = cb.getUniqueInterfaces(5.5);
123-
assertTrue(interfaces.size()>=3);
171+
assertEquals(3,interfaces.size());
124172

125173
}
126174

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2019,7 +2019,9 @@ public static void cleanUpAltLocs(Structure structure) {
20192019
* Expands the NCS operators in the given Structure adding new chains as needed.
20202020
* The new chains are assigned ids of the form: original_chain_id+ncs_operator_index+"n"
20212021
* @param structure
2022+
* @deprecated use {@link org.biojava.nbio.structure.xtal.CrystalBuilder#expandNcsOps(Structure, Map, Map)} instead.
20222023
*/
2024+
@Deprecated
20232025
public static void expandNcsOps(Structure structure) {
20242026
PDBCrystallographicInfo xtalInfo = structure.getCrystallographicInfo();
20252027
if (xtalInfo ==null) return;
@@ -2051,7 +2053,7 @@ public static void expandNcsOps(Structure structure) {
20512053

20522054
/**
20532055
* Auxiliary method to reset chain ids of residue numbers in a chain.
2054-
* Used when cloning chains and resetting their ids: one needs to take care of
2056+
* Used when cloning chains and resetting their ids: one needs to take care of
20552057
* resetting the ids within residue numbers too.
20562058
* @param c
20572059
* @param newChainName

biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterfaceList.java

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,7 @@
2121
package org.biojava.nbio.structure.contact;
2222

2323
import java.io.Serializable;
24-
import java.util.ArrayList;
25-
import java.util.Collections;
26-
import java.util.Comparator;
27-
import java.util.Iterator;
28-
import java.util.List;
29-
import java.util.Map;
30-
import java.util.Set;
31-
import java.util.TreeMap;
24+
import java.util.*;
3225

3326
import org.biojava.nbio.core.util.SingleLinkageClusterer;
3427
import org.biojava.nbio.structure.Atom;
@@ -76,11 +69,11 @@ public class StructureInterfaceList implements Serializable, Iterable<StructureI
7669

7770
private List<StructureInterface> list;
7871

79-
private List<StructureInterfaceCluster> clusters;
80-
72+
private List<StructureInterfaceCluster> clusters = null;
73+
private List<StructureInterfaceCluster> clustersNcs = null;
8174

8275
public StructureInterfaceList() {
83-
this.list = new ArrayList<StructureInterface>();
76+
this.list = new ArrayList<>();
8477
}
8578

8679
public void add(StructureInterface interf) {
@@ -196,6 +189,62 @@ public void sort() {
196189
}
197190
}
198191

192+
/**
193+
* Get the interface clusters for this StructureInterfaceList grouped by NCS-equivalence.
194+
* This means that for any two interfaces in the same cluster:
195+
* 1. The chains forming the first interface are NCS-copies of the chains forming the second interface, in any order.
196+
* 2. Relative orientation of the chains is preserved, i.e. the contacts are identical.
197+
* @return list of {@link StructureInterfaceCluster} objects.
198+
*/
199+
public List<StructureInterfaceCluster> getClustersNcs() {
200+
return clustersNcs;
201+
}
202+
203+
/**
204+
* Add an interface to the list, possibly defining it as NCS-equivalent to an interface already in the list.
205+
* Used to build up the NCS clustering.
206+
* @param interfaceNew
207+
* an interface to be added to the list.
208+
* @param interfaceRef
209+
* interfaceNew will be added to the cluster which contains interfaceRef.
210+
* If interfaceRef is null, new cluster will be created for interfaceNew.
211+
*/
212+
213+
public void addNcsEquivalent(StructureInterface interfaceNew, StructureInterface interfaceRef) {
214+
215+
this.add(interfaceNew);
216+
if (clustersNcs == null) {
217+
clustersNcs = new ArrayList<>();
218+
}
219+
220+
if (interfaceRef == null) {
221+
222+
StructureInterfaceCluster newCluster = new StructureInterfaceCluster();
223+
newCluster.addMember(interfaceNew);
224+
clustersNcs.add(newCluster);
225+
return;
226+
}
227+
228+
Optional<StructureInterfaceCluster> clusterRef =
229+
clustersNcs.stream().
230+
filter(r->r.getMembers().stream().
231+
anyMatch(c -> c.equals(interfaceRef))).
232+
findFirst();
233+
234+
if (clusterRef.isPresent()) {
235+
clusterRef.get().addMember(interfaceNew);
236+
return;
237+
}
238+
239+
logger.warn("The specified reference interface, if not null, should have been added to this set previously. " +
240+
"Creating new cluster and adding both interfaces. This is likely a bug.");
241+
this.add(interfaceRef);
242+
StructureInterfaceCluster newCluster = new StructureInterfaceCluster();
243+
newCluster.addMember(interfaceRef);
244+
newCluster.addMember(interfaceNew);
245+
clustersNcs.add(newCluster);
246+
}
247+
199248
/**
200249
* Removes from this interface list all interfaces with areas
201250
* below the default cutoff area

0 commit comments

Comments
 (0)