From: Jim Procter Date: Tue, 3 Sep 2024 13:38:20 +0000 (+0100) Subject: Merge branch 'develop' into features/JAL-4366_foldseek_3di_viewing X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=c3551d9c3680ae6824dc5164e314cae10bb26b81;p=jalview.git Merge branch 'develop' into features/JAL-4366_foldseek_3di_viewing Conflicts: src/jalview/analysis/AlignSeq.java src/jalview/analysis/scoremodels/ScoreModels.java src/jalview/api/AlignViewportI.java src/jalview/gui/CalculationChooser.java src/jalview/gui/PairwiseAlignPanel.java test/jalview/gui/CalculationChooserTest.java --- c3551d9c3680ae6824dc5164e314cae10bb26b81 diff --cc src/jalview/analysis/AlignSeq.java index edf19ec,1a12681..6e35377 --- a/src/jalview/analysis/AlignSeq.java +++ b/src/jalview/analysis/AlignSeq.java @@@ -287,8 -334,10 +334,9 @@@ public class AlignSe s2.getDatasetSequence() == null ? s2 : s2.getDatasetSequence()); return alSeq2; } - /** * fraction of seq2 matched in the alignment + * * @return NaN or [0..1] */ public double getS2Coverage() @@@ -473,6 -533,141 +532,140 @@@ match++; } } + + /* + * we built the character strings backwards, so now + * reverse them to convert to sequence strings + */ + astr1 = sb1.reverse().toString(); + astr2 = sb2.reverse().toString(); + } + + /** + * DOCUMENT ME! + */ + public void traceAlignmentWithEndGaps() + { + // Find the maximum score along the rhs or bottom row + float max = -Float.MAX_VALUE; + + for (int i = 0; i < seq1.length; i++) + { + if (score[i][seq2.length - 1] > max) + { + max = score[i][seq2.length - 1]; + maxi = i; + maxj = seq2.length - 1; + } + } + + for (int j = 0; j < seq2.length; j++) + { + if (score[seq1.length - 1][j] > max) + { + max = score[seq1.length - 1][j]; + maxi = seq1.length - 1; + maxj = j; + } + } + + int i = maxi; + int j = maxj; + int trace; + maxscore = score[i][j] / 10f; + + // prepare trailing gaps + while ((i < seq1.length - 1) || (j < seq2.length - 1)) + { + i++; + j++; + } + seq1end = i + 1; + seq2end = j + 1; + + aseq1 = new int[seq1.length + seq2.length]; + aseq2 = new int[seq1.length + seq2.length]; + + StringBuilder sb1 = new StringBuilder(aseq1.length); + StringBuilder sb2 = new StringBuilder(aseq2.length); + + count = (seq1.length + seq2.length) - 1; + + // get trailing gaps + while ((i >= seq1.length) || (j >= seq2.length)) + { + if (i >= seq1.length) + { + aseq1[count] = GAP_INDEX; + sb1.append("-"); + aseq2[count] = seq2[j]; + sb2.append(s2str.charAt(j)); + } + else if (j >= seq2.length) + { + aseq1[count] = seq1[i]; + sb1.append(s1str.charAt(i)); + aseq2[count] = GAP_INDEX; + sb2.append("-"); + } + i--; + j--; + } + + while (i > 0 && j > 0) + { + aseq1[count] = seq1[i]; + sb1.append(s1str.charAt(i)); + aseq2[count] = seq2[j]; + sb2.append(s2str.charAt(j)); + + trace = findTrace(i, j); + + if (trace == 0) + { + i--; + j--; + } + else if (trace == 1) + { + j--; + aseq1[count] = GAP_INDEX; + sb1.replace(sb1.length() - 1, sb1.length(), "-"); + } + else if (trace == -1) + { + i--; + aseq2[count] = GAP_INDEX; + sb2.replace(sb2.length() - 1, sb2.length(), "-"); + } + + count--; + } + + seq1start = i + 1; + seq2start = j + 1; + + aseq1[count] = seq1[i]; + sb1.append(s1str.charAt(i)); + aseq2[count] = seq2[j]; + sb2.append(s2str.charAt(j)); + + // get initial gaps + while (j > 0 || i > 0) + { + if (j > 0) + { + j--; + sb1.append("-"); + sb2.append(s2str.charAt(j)); + } + else if (i > 0) + { + i--; + sb1.append(s1str.charAt(i)); + sb2.append("-"); + } + } - /* * we built the character strings backwards, so now * reverse them to convert to sequence strings diff --cc src/jalview/analysis/scoremodels/ScoreModels.java index 95e114e,490ec00..bdadacf --- a/src/jalview/analysis/scoremodels/ScoreModels.java +++ b/src/jalview/analysis/scoremodels/ScoreModels.java @@@ -41,8 -41,8 +41,10 @@@ public class ScoreModel private final ScoreMatrix DNA; + private final ScoreMatrix FOLDSEEK3DI; + + private final ScoreMatrix SECONDARYSTRUCTURE; + private static ScoreModels instance; private Map models; @@@ -70,7 -70,8 +72,9 @@@ *
  • PAM250
  • *
  • PID
  • *
  • DNA
  • - *
  • Sequence Feature Similarity
  • + *
  • Sequence Feature Similarity
  • * + *
  • Secondary Structure Similarity
  • ++ *
  • FOLDSEEK_3di
  • * */ private ScoreModels() @@@ -82,9 -83,12 +86,14 @@@ BLOSUM62 = loadScoreMatrix("scoreModel/blosum62.scm"); PAM250 = loadScoreMatrix("scoreModel/pam250.scm"); DNA = loadScoreMatrix("scoreModel/dna.scm"); + FOLDSEEK3DI = loadScoreMatrix("scoreModel/foldseek_mat3di.scm"); registerScoreModel(new PIDModel()); registerScoreModel(new FeatureDistanceModel()); + SECONDARYSTRUCTURE = loadScoreMatrix( + "scoreModel/secondarystructure.scm"); ++ // JBPNote - this overwrites previous + registerScoreModel(new SecondaryStructureDistanceModel()); + } /** @@@ -181,9 -189,9 +190,14 @@@ { return PAM250; } + + public ScoreMatrix getSecondaryStructureMatrix() + { + return SECONDARYSTRUCTURE; + } ++ + public ScoreMatrix getFOLDSEEK3DI() + { + return FOLDSEEK3DI; + } - } diff --cc src/jalview/api/AlignViewportI.java index 4e03e45,ef4a192..2c0afb7 --- a/src/jalview/api/AlignViewportI.java +++ b/src/jalview/api/AlignViewportI.java @@@ -566,9 -574,20 +574,22 @@@ public interface AlignViewportI extend */ Iterator getViewAsVisibleContigs(boolean selectedRegionOnly); + /** + * notify all concerned that the alignment data has changed and derived data + * needs to be recalculated + */ + public void notifyAlignmentChanged(); + + /** + * retrieve a matrix associated with the view's alignment's annotation + * + * @param alignmentAnnotation + * @return contact matrix or NULL + */ ContactMatrixI getContactMatrix(AlignmentAnnotation alignmentAnnotation); - + ProfilesI getSequenceSSConsensusHash(); + boolean is3di(); + + public AlignmentAnnotation getComparisonAnnotation(); } diff --cc src/jalview/gui/CalculationChooser.java index daab62b,8e5cc9e..c9e999a --- a/src/jalview/gui/CalculationChooser.java +++ b/src/jalview/gui/CalculationChooser.java @@@ -528,8 -700,21 +701,21 @@@ public class CalculationChooser extend protected void calculate_actionPerformed() { boolean doPCA = pca.isSelected(); - String modelName = modelNames.getSelectedItem().toString(); + boolean doPaSiMap = pasimap.isSelected(); + boolean doPairwise = pairwise.isSelected(); + String modelName = modelNames.getSelectedItem() == null ? "" + : modelNames.getSelectedItem().toString(); + String ssSource = ""; + Object selectedItem = ssSourceDropdown.getSelectedItem(); + if (selectedItem != null) + { + ssSource = selectedItem.toString(); + } - SimilarityParams params = getSimilarityParameters(doPCA); + SimilarityParamsI params = getSimilarityParameters(doPCA); + if (ssSource.length() > 0) + { + params.setSecondaryStructureSource(ssSource); + } if (doPCA) { diff --cc src/jalview/gui/PairwiseAlignPanel.java index 2c65bcc,90123f5..2fa28e8 --- a/src/jalview/gui/PairwiseAlignPanel.java +++ b/src/jalview/gui/PairwiseAlignPanel.java @@@ -113,14 -231,19 +233,22 @@@ public class PairwiseAlignPanel extend { continue; } - if (params!=null) - ++ if (sm!=null) + { - as.setScoreMatrix(params); ++ as.setScoreMatrix(sm); + } as.calcScoreMatrix(); - as.traceAlignment(); + if (endGaps) + { + as.traceAlignmentWithEndGaps(); + } + else + { + as.traceAlignment(); + } + as.scoreAlignment(); - if (!first) + if (!first && !quiet) { jalview.bin.Console.outPrintln(DASHES); textarea.append(DASHES); diff --cc src/jalview/viewmodel/AlignmentViewport.java index 22d863a,ce4473b..6cf7d86 --- a/src/jalview/viewmodel/AlignmentViewport.java +++ b/src/jalview/viewmodel/AlignmentViewport.java @@@ -75,9 -75,9 +76,10 @@@ import jalview.util.MappingUtils import jalview.util.MessageManager; import jalview.viewmodel.styles.ViewStyle; import jalview.workers.AlignCalcManager; +import jalview.workers.AlignmentComparisonThread; import jalview.workers.ComplementConsensusThread; import jalview.workers.ConsensusThread; + import jalview.workers.SecondaryStructureConsensusThread; import jalview.workers.StrucConsensusThread; /** @@@ -897,20 -921,26 +923,38 @@@ public abstract class AlignmentViewpor } } } + if (getCodingComplement() != null) + { + if (getCodingComplement().isNucleotide() == isNucleotide()) + { + if (calculator.getRegisteredWorkersOfClass( + AlignmentComparisonThread.class) == null) + { + initAlignmentComparison(ap); + ap.adjustAnnotationHeight(); + } + } + } } + /** + * trigger update of consensus annotation + */ + public void updateSecondaryStructureConsensus(final AlignmentViewPanel ap) + { + // see note in mantis : issue number 8585 + if (secondaryStructureConsensus == null || !autoCalculateConsensus) + { + return; + } + if (calculator.getRegisteredWorkersOfClass( + SecondaryStructureConsensusThread.class) == null) + { + calculator.registerWorker( + new SecondaryStructureConsensusThread(this, ap)); + } + } + // --------START Structure Conservation public void updateStrucConsensus(final AlignmentViewPanel ap) { diff --cc test/jalview/gui/CalculationChooserTest.java index ceda9ec,e6316f3..3ee12cf --- a/test/jalview/gui/CalculationChooserTest.java +++ b/test/jalview/gui/CalculationChooserTest.java @@@ -55,24 -55,28 +55,31 @@@ public class CalculationChooserTes * peptide models for PCA */ List filtered = CalculationChooser - .getApplicableScoreModels(false, true); - assertEquals(filtered.size(), 5); + .getApplicableScoreModels(false, true, true, false); - assertEquals(filtered.size(), 5); ++ assertEquals(filtered.size(), 6); assertSame(filtered.get(0), blosum62); assertSame(filtered.get(1), pam250); - assertEquals(filtered.get(2).getName(), "PID"); - assertEquals(filtered.get(3).getName(), "Sequence Feature Similarity"); - assertEquals(filtered.get(4).getName(), + assertEquals(filtered.get(2).getName(), "Mat3di"); + assertEquals(filtered.get(4).getName(), "Sequence Feature Similarity"); ++ assertEquals(filtered.get(5).getName(), + "Secondary Structure Similarity"); /* * peptide models for Tree are the same */ - filtered = CalculationChooser.getApplicableScoreModels(false, false); - assertEquals(filtered.size(), 5); + filtered = CalculationChooser.getApplicableScoreModels(false, false, + true, false); - assertEquals(filtered.size(), 5); ++ assertEquals(filtered.size(), 6); ++ assertSame(filtered.get(0), blosum62); assertSame(filtered.get(1), pam250); - assertEquals(filtered.get(2).getName(), "PID"); - assertEquals(filtered.get(3).getName(), "Sequence Feature Similarity"); + assertEquals(filtered.get(2).getName(), "Mat3di"); + assertEquals(filtered.get(3).getName(), "PID"); + assertEquals(filtered.get(4).getName(), "Sequence Feature Similarity"); + assertEquals(filtered.get(4).getName(), + "Secondary Structure Similarity"); + + /* * nucleotide models for PCA */ @@@ -100,8 -106,9 +109,9 @@@ /* * nucleotide models for Tree are unchanged */ - filtered = CalculationChooser.getApplicableScoreModels(true, false); + filtered = CalculationChooser.getApplicableScoreModels(true, false, + true, false); - assertEquals(filtered.size(), 4); + assertEquals(filtered.size(), 3); assertSame(filtered.get(0), dna); assertEquals(filtered.get(1).getName(), "PID"); assertEquals(filtered.get(2).getName(), "Sequence Feature Similarity");