diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java index 9a87e92f88..2bbad10f1f 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java @@ -507,27 +507,24 @@ public boolean mergeStructure(SubunitCluster other, SubunitClustererParameters p } } - AFPChain afp = aligner.align(this.subunits.get(this.representative) - .getRepresentativeAtoms(), - other.subunits.get(other.representative) - .getRepresentativeAtoms()); + AFPChain afp = aligner.align(this.subunits.get(this.representative).getRepresentativeAtoms(), + other.subunits.get(other.representative).getRepresentativeAtoms()); + String pairName = this.subunits.get(this.representative).getName() + "-" + other.subunits.get(other.representative).getName(); if (afp.getOptLength() < 1) { // alignment failed (eg if chains were too short) throw new StructureException( - String.format("Subunits failed to align using %s", params.getSuperpositionAlgorithm())); + String.format("Subunits %s failed to align using %s", pairName, params.getSuperpositionAlgorithm())); } // Convert AFPChain to MultipleAlignment for convenience MultipleAlignment msa = new MultipleAlignmentEnsembleImpl( afp, this.subunits.get(this.representative).getRepresentativeAtoms(), - other.subunits.get(other.representative) - .getRepresentativeAtoms(), false) - .getMultipleAlignment(0); + other.subunits.get(other.representative).getRepresentativeAtoms(), + false).getMultipleAlignment(0); - double structureCoverage = Math.min(msa.getCoverages().get(0), msa - .getCoverages().get(1)); + double structureCoverage = Math.min(msa.getCoverages().get(0), msa.getCoverages().get(1)); if(params.isUseStructureCoverage() && structureCoverage < params.getStructureCoverageThreshold()) { return false; @@ -543,8 +540,7 @@ public boolean mergeStructure(SubunitCluster other, SubunitClustererParameters p return false; } - logger.info(String.format("SubunitClusters are structurally similar with " - + "%.2f RMSD %.2f coverage", rmsd, structureCoverage)); + logger.info("SubunitClusters {} are structurally similar with [ {} ] RMSD and [ {} ] coverage", pairName, String.format("%.2f", rmsd), String.format("%.2f", structureCoverage)); // Merge clusters List> alignedRes = msa.getBlock(0).getAlignRes(); @@ -565,13 +561,18 @@ public boolean mergeStructure(SubunitCluster other, SubunitClustererParameters p // Only consider residues that are part of the SubunitCluster if (this.subunitEQR.get(this.representative).contains(thisIndex) - && other.subunitEQR.get(other.representative).contains( - otherIndex)) { + && other.subunitEQR.get(other.representative).contains(otherIndex)) { thisAligned.add(thisIndex); otherAligned.add(otherIndex); } } + // this can happen in very rare cases, e.g. 9y9z when merging E_1 into the cluster D_1, OM_1, Y_1 + if (thisAligned.isEmpty() && otherAligned.isEmpty()) { + logger.warn("No equivalent aligned atoms found between SubunitClusters {} via structure alignment. Will not merge the second one into the first.", pairName); + return false; + } + updateEquivResidues(other, thisAligned, otherAligned); this.method = SubunitClustererMethod.STRUCTURE; @@ -602,18 +603,12 @@ private void updateEquivResidues(SubunitCluster other, List thisAligned Collections.sort(otherRemove); Collections.reverse(otherRemove); - for (int t = 0; t < thisRemove.size(); t++) { - for (List eqr : this.subunitEQR) { - int column = thisRemove.get(t); - eqr.remove(column); - } + for (int column : thisRemove) { + this.subunitEQR.forEach(eqr -> eqr.remove(column)); } - for (int t = 0; t < otherRemove.size(); t++) { - for (List eqr : other.subunitEQR) { - int column = otherRemove.get(t); - eqr.remove(column); - } + for (int column : otherRemove) { + other.subunitEQR.forEach(eqr -> eqr.remove(column)); } // The representative is the longest sequence diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClusterer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClusterer.java index 6295f8fdf0..70da0b56db 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClusterer.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClusterer.java @@ -83,8 +83,7 @@ public static Stoichiometry cluster(List subunits, SubunitClustererPara } } catch (CompoundNotFoundException e) { - logger.warn("Could not merge by Sequence. {}", - e.getMessage()); + logger.info("Could not merge by Sequence. {}", e.getMessage()); } } } @@ -100,7 +99,7 @@ public static Stoichiometry cluster(List subunits, SubunitClustererPara clusters.remove(c2); } } catch (StructureException e) { - logger.warn("Could not merge by Structure. {}", e.getMessage()); + logger.info("Could not merge by Structure. {}", e.getMessage()); } } } @@ -112,8 +111,7 @@ public static Stoichiometry cluster(List subunits, SubunitClustererPara try { clusters.get(c).divideInternally(params); } catch (StructureException e) { - logger.warn("Error analyzing internal symmetry. {}", - e.getMessage()); + logger.info("Error analyzing internal symmetry. {}", e.getMessage()); } } @@ -125,8 +123,7 @@ public static Stoichiometry cluster(List subunits, SubunitClustererPara if (clusters.get(c1).mergeStructure(clusters.get(c2), params)) clusters.remove(c2); } catch (StructureException e) { - logger.warn("Could not merge by Structure. {}", - e.getMessage()); + logger.info("Could not merge by Structure. {}", e.getMessage()); } } }