Skip to content

Commit bb2ccaf

Browse files
author
Dmytro Guzenko
committed
Refactoring of clustering/symmetry detection methods to work with stoichiometry objects.
1 parent a69aa4c commit bb2ccaf

8 files changed

Lines changed: 431 additions & 93 deletions

File tree

‎biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/cluster/TestSubunitClustererExamples.java‎

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.biojava.nbio.structure.cluster.SubunitClusterer;
3333
import org.biojava.nbio.structure.cluster.SubunitClustererMethod;
3434
import org.biojava.nbio.structure.cluster.SubunitClustererParameters;
35+
import org.biojava.nbio.structure.symmetry.core.Stoichiometry;
3536
import org.junit.Test;
3637

3738
/**
@@ -53,13 +54,60 @@ public void testPTMs() throws StructureException, IOException {
5354
SubunitClustererParameters params = new SubunitClustererParameters();
5455
params.setClustererMethod(SubunitClustererMethod.SEQUENCE);
5556

56-
List<SubunitCluster> clusters = SubunitClusterer.cluster(s, params);
57+
List<SubunitCluster> clusters = SubunitClusterer.cluster(s, params).getClusters();
5758

5859
// We expect a single cluster with length 99
5960
assertEquals(clusters.size(), 1);
6061
assertEquals(clusters.get(0).length(), 99);
6162
}
6263

64+
65+
/**
66+
* A couple of structures with large number of subunits
67+
*
68+
* @throws IOException
69+
* @throws StructureException
70+
*/
71+
72+
@Test
73+
public void testStoichiometry() throws IOException, StructureException {
74+
75+
SubunitClustererParameters clusterParams = new SubunitClustererParameters(true);
76+
clusterParams.setClustererMethod(SubunitClustererMethod.SEQUENCE);
77+
clusterParams.setSequenceIdentityThreshold(0.75);
78+
79+
Structure structure = StructureIO.getStructure("BIO:5WVK:1");
80+
81+
Stoichiometry composition = SubunitClusterer.cluster(structure,clusterParams);
82+
// default alphabet and strategy
83+
assertEquals("A2B2C2D2E2F2G2H2I2J2K2L2M2N2OPQRSTUVWXYZabcdef",composition.toString());
84+
// nothing should change
85+
composition.setStrategy(Stoichiometry.StringOverflowStrategy.DOUBLE);
86+
assertEquals("A2B2C2D2E2F2G2H2I2J2K2L2M2N2OPQRSTUVWXYZabcdef",composition.toString());
87+
// nothing should change
88+
composition.setStrategy(Stoichiometry.StringOverflowStrategy.QUESTIONMARK);
89+
assertEquals("A2B2C2D2E2F2G2H2I2J2K2L2M2N2OPQRSTUVWXYZabcdef",composition.toString());
90+
91+
// now make the alphabet shorter to force changes in representation
92+
composition.setAlphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
93+
94+
composition.setStrategy(Stoichiometry.StringOverflowStrategy.DOUBLE);
95+
assertEquals("AA2AB2AC2AD2AE2AF2AG2AH2AI2AJ2AK2AL2AM2AN2AO1AP1AQ1AR1AS1AT1AU1AV1AW1AX1AY1AZ1" +
96+
"BA1BB1BC1BD1BE1BF1",
97+
composition.toString());
98+
99+
composition.setStrategy(Stoichiometry.StringOverflowStrategy.QUESTIONMARK);
100+
assertEquals("A2B2C2D2E2F2G2H2I2J2K2L2M2N2OPQRSTUVWXYZ??????",
101+
composition.toString());
102+
103+
// back to default
104+
composition.setStrategy(Stoichiometry.StringOverflowStrategy.CYCLE);
105+
assertEquals("A2B2C2D2E2F2G2H2I2J2K2L2M2N2OPQRSTUVWXYZABCDEF",
106+
composition.toString());
107+
108+
}
109+
110+
63111
/**
64112
* Test pseudostoichiometry: 4HHB
65113
*/
@@ -72,7 +120,7 @@ public void testPseudostoichiometry() throws StructureException,
72120
params.setClustererMethod(SubunitClustererMethod.SEQUENCE);
73121
params.setSequenceIdentityThreshold(0.95);
74122

75-
List<SubunitCluster> clusters = SubunitClusterer.cluster(s, params);
123+
List<SubunitCluster> clusters = SubunitClusterer.cluster(s, params).getClusters();
76124

77125
// We expect two SEQUENCE clusters with length 141 and 146
78126
assertEquals(clusters.size(), 2);
@@ -86,7 +134,7 @@ public void testPseudostoichiometry() throws StructureException,
86134
params.setClustererMethod(SubunitClustererMethod.SEQUENCE_STRUCTURE);
87135
params.setRMSDThreshold(3.0);
88136

89-
clusters = SubunitClusterer.cluster(s, params);
137+
clusters = SubunitClusterer.cluster(s, params).getClusters();
90138

91139
// We expect a single STRUCTURE cluster with length 140
92140
assertEquals(clusters.size(), 1);
@@ -107,7 +155,7 @@ public void testInternalSymmetry() throws StructureException, IOException {
107155
params.setClustererMethod(SubunitClustererMethod.SEQUENCE);
108156
params.setSequenceCoverageThreshold(0.8);
109157

110-
List<SubunitCluster> clusters = SubunitClusterer.cluster(s, params);
158+
List<SubunitCluster> clusters = SubunitClusterer.cluster(s, params).getClusters();
111159

112160
// We expect one SEQUENCE cluster with 3 Subunits of length 351
113161
assertEquals(clusters.size(), 1);
@@ -121,7 +169,7 @@ public void testInternalSymmetry() throws StructureException, IOException {
121169
params.setInternalSymmetry(true);
122170
params.setRMSDThreshold(3.0);
123171

124-
clusters = SubunitClusterer.cluster(s, params);
172+
clusters = SubunitClusterer.cluster(s, params).getClusters();
125173

126174
// We expect a single INTERNAL_SYMMETRY cluster with 6 Subunits
127175
assertEquals(clusters.size(), 1);

‎biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java‎

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@
2828
import org.biojava.nbio.structure.Structure;
2929
import org.biojava.nbio.structure.StructureException;
3030
import org.biojava.nbio.structure.StructureIO;
31-
import org.biojava.nbio.structure.cluster.SubunitCluster;
3231
import org.biojava.nbio.structure.cluster.SubunitClusterer;
3332
import org.biojava.nbio.structure.cluster.SubunitClustererMethod;
3433
import org.biojava.nbio.structure.cluster.SubunitClustererParameters;
3534
import org.biojava.nbio.structure.symmetry.core.QuatSymmetryDetector;
3635
import org.biojava.nbio.structure.symmetry.core.QuatSymmetryParameters;
3736
import org.biojava.nbio.structure.symmetry.core.QuatSymmetryResults;
37+
import org.biojava.nbio.structure.symmetry.core.Stoichiometry;
3838
import org.junit.Test;
3939

4040
/**
@@ -66,7 +66,7 @@ public void testNMR() throws IOException, StructureException {
6666

6767
// C2 symmetry non pseudosymmetric
6868
assertEquals("C2", symmetry.getSymmetry());
69-
assertEquals("A2", symmetry.getStoichiometry());
69+
assertEquals("A2", symmetry.getStoichiometry().toString());
7070
assertFalse(symmetry.isPseudoStoichiometric());
7171

7272
}
@@ -87,7 +87,7 @@ public void testDihedral() throws IOException, StructureException {
8787

8888
// D3 symmetry non pseudosymmetric
8989
assertEquals("D3", symmetry.getSymmetry());
90-
assertEquals("A6B6", symmetry.getStoichiometry());
90+
assertEquals("A6B6", symmetry.getStoichiometry().toString());
9191
assertFalse(symmetry.isPseudoStoichiometric());
9292

9393

@@ -113,7 +113,7 @@ public void testPseudosymmetry() throws IOException, StructureException {
113113

114114
// C2 symmetry
115115
assertEquals("C2", symmetry.getSymmetry());
116-
assertEquals("A2B2", symmetry.getStoichiometry());
116+
assertEquals("A2B2", symmetry.getStoichiometry().toString());
117117

118118
// Use pseudosymmetry (structural clustering)
119119
clusterParams.setClustererMethod(SubunitClustererMethod.STRUCTURE);
@@ -122,7 +122,7 @@ public void testPseudosymmetry() throws IOException, StructureException {
122122

123123
// D2 pseudo-symmetry
124124
assertEquals("D2", symmetry.getSymmetry());
125-
assertEquals("A4", symmetry.getStoichiometry());
125+
assertEquals("A4", symmetry.getStoichiometry().toString());
126126
assertTrue(symmetry.isPseudoStoichiometric());
127127
}
128128

@@ -238,19 +238,19 @@ public void testLocal() throws IOException, StructureException {
238238

239239
for(int iTest = 0; iTest<testIds.size();iTest++) {
240240
Structure pdb = StructureIO.getStructure(testIds.get(iTest));
241-
List<SubunitCluster> clusters = SubunitClusterer.cluster(pdb,clusterParams);
241+
Stoichiometry composition = SubunitClusterer.cluster(pdb,clusterParams);
242242

243243
// no global symmetry
244-
QuatSymmetryResults globalSymmetry = QuatSymmetryDetector.calcGlobalSymmetry(clusters,symmParams);
244+
QuatSymmetryResults globalSymmetry = QuatSymmetryDetector.calcGlobalSymmetry(composition,symmParams);
245245
assertEquals("C1", globalSymmetry.getSymmetry());
246-
assertEquals(testStoichiometries.get(iTest), globalSymmetry.getStoichiometry());
246+
assertEquals(testStoichiometries.get(iTest), globalSymmetry.getStoichiometry().toString());
247247

248-
List<QuatSymmetryResults> foundLocal = QuatSymmetryDetector.calcLocalSymmetries(clusters, symmParams);
248+
List<QuatSymmetryResults> foundLocal = QuatSymmetryDetector.calcLocalSymmetries(composition, symmParams);
249249
Map<String,String> refLocal = testLocalSymmetries.get(iTest);
250250

251251
for (QuatSymmetryResults local:foundLocal) {
252-
assertTrue(refLocal.keySet().contains(local.getStoichiometry()));
253-
assertEquals(refLocal.get(local.getStoichiometry()),local.getSymmetry());
252+
assertTrue(refLocal.keySet().contains(local.getStoichiometry().toString()));
253+
assertEquals(refLocal.get(local.getStoichiometry().toString()),local.getSymmetry());
254254
}
255255
}
256256
}
@@ -278,7 +278,7 @@ public void testInternalSymmetry() throws IOException, StructureException {
278278

279279
// D2 combined internal and quaternary symmetry
280280
assertEquals("D3", symmetry.getSymmetry());
281-
assertEquals("A6", symmetry.getStoichiometry());
281+
assertEquals("A6", symmetry.getStoichiometry().toString());
282282

283283
}
284284

@@ -300,7 +300,7 @@ public void testHelical() throws IOException, StructureException {
300300

301301
// H symmetry A3 stoichiometry
302302
assertEquals("H", symmetry.getSymmetry());
303-
assertEquals("A3", symmetry.getStoichiometry());
303+
assertEquals("A3", symmetry.getStoichiometry().toString());
304304

305305
}
306306

@@ -322,7 +322,7 @@ public void testHelicalLocal() throws IOException, StructureException {
322322

323323
// H symmetry A5 stoichiometry
324324
assertEquals("H", results.get(0).getSymmetry());
325-
assertEquals("A5", results.get(0).getStoichiometry());
325+
assertEquals("A5", results.get(0).getStoichiometry().toString());
326326

327327
}
328328

@@ -345,7 +345,7 @@ public void testPseudoIdentity95() throws IOException, StructureException {
345345
pdb, symmParams, cp);
346346

347347
assertEquals("C2", symmetry.getSymmetry());
348-
assertEquals("A2", symmetry.getStoichiometry());
348+
assertEquals("A2", symmetry.getStoichiometry().toString());
349349
assertFalse(symmetry.isPseudoStoichiometric());
350350
assertEquals(SubunitClustererMethod.SEQUENCE, symmetry.getSubunitClusters().get(0).getClustererMethod());
351351

‎biojava-structure/src/main/java/org/biojava/nbio/structure/align/quaternary/QsAlign.java‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,9 @@ public static QsAlignResult align(List<Subunit> s1, List<Subunit> s2,
6969
QsAlignResult result = new QsAlignResult(s1, s2);
7070

7171
// SETP 1: cluster each group of subunits O(N^2*L^2) - intra
72-
List<SubunitCluster> c1 = SubunitClusterer.cluster(s1, cParams);
73-
List<SubunitCluster> c2 = SubunitClusterer.cluster(s2, cParams);
72+
73+
List<SubunitCluster> c1 = SubunitClusterer.cluster(s1, cParams).getClusters();
74+
List<SubunitCluster> c2 = SubunitClusterer.cluster(s2, cParams).getClusters();
7475

7576
// STEP 2: match each subunit cluster between groups O(N^2*L^2) - inter
7677
Map<Integer, Integer> clusterMap = new HashMap<Integer, Integer>();

‎biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClusterUtils.java‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
*
1212
* @author Aleix Lafita
1313
* @since 5.0.0
14-
*
14+
* @deprecated Use {@link org.biojava.nbio.structure.symmetry.core.Stoichiometry} instead.
1515
*/
16+
@Deprecated
1617
public class SubunitClusterUtils {
1718

1819
/** Prevent instantiation **/
@@ -93,7 +94,7 @@ public static List<SubunitCluster> orderByStoichiometry(List<SubunitCluster> clu
9394
* A pseudostoichiometric {@link SubunitCluster} was obtained using the
9495
* {@link SubunitClustererMethod#STRUCTURE} similarity,
9596
* or {@link SubunitClustererMethod#SEQUENCE} similarity with low scores.
96-
*
97+
*
9798
* @param clusters
9899
* @return true if any of the clusters is pseudostoichiometric, false
99100
* otherwise

‎biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClusterer.java‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.biojava.nbio.core.exceptions.CompoundNotFoundException;
2727
import org.biojava.nbio.structure.Structure;
2828
import org.biojava.nbio.structure.StructureException;
29+
import org.biojava.nbio.structure.symmetry.core.Stoichiometry;
2930
import org.slf4j.Logger;
3031
import org.slf4j.LoggerFactory;
3132

@@ -46,7 +47,7 @@ public class SubunitClusterer {
4647
private SubunitClusterer() {
4748
}
4849

49-
public static List<SubunitCluster> cluster(Structure structure,
50+
public static Stoichiometry cluster(Structure structure,
5051
SubunitClustererParameters params) {
5152
List<Subunit> subunits = SubunitExtractor.extractSubunits(structure,
5253
params.getAbsoluteMinimumSequenceLength(),
@@ -55,14 +56,14 @@ public static List<SubunitCluster> cluster(Structure structure,
5556
return cluster(subunits, params);
5657
}
5758

58-
public static List<SubunitCluster> cluster(List<Subunit> subunits,
59+
public static Stoichiometry cluster(List<Subunit> subunits,
5960
SubunitClustererParameters params) {
6061

6162
// The collection of clusters to return
6263
List<SubunitCluster> clusters = new ArrayList<SubunitCluster>();
6364

6465
if (subunits.size() == 0)
65-
return clusters;
66+
return new Stoichiometry(clusters);
6667

6768
// First generate a new cluster for each Subunit
6869
for (Subunit s : subunits)
@@ -128,6 +129,6 @@ public static List<SubunitCluster> cluster(List<Subunit> subunits,
128129
}
129130
}
130131

131-
return SubunitClusterUtils.orderByStoichiometry(clusters);
132+
return new Stoichiometry(clusters);
132133
}
133134
}

0 commit comments

Comments
 (0)