From 72660f8e5c90ec6aba386714784cfd2bd137fbe5 Mon Sep 17 00:00:00 2001 From: Jim Procter Date: Fri, 24 May 2024 15:25:07 +0100 Subject: [PATCH] JAL-4257 JAL-4159 JAL-789 tidy up passing of score model to pairwise alignment directly/via pasimap and threading off the direct pairwise alignment calculation --- src/jalview/analysis/PaSiMap.java | 7 +- src/jalview/gui/AlignFrame.java | 9 +- src/jalview/gui/CalculationChooser.java | 239 ++++++++++++++++++------------- src/jalview/gui/PaSiMapPanel.java | 23 ++- src/jalview/gui/PairwiseAlignPanel.java | 43 +++--- 5 files changed, 195 insertions(+), 126 deletions(-) diff --git a/src/jalview/analysis/PaSiMap.java b/src/jalview/analysis/PaSiMap.java index fd20465..48ec899 100755 --- a/src/jalview/analysis/PaSiMap.java +++ b/src/jalview/analysis/PaSiMap.java @@ -76,12 +76,9 @@ public class PaSiMap implements Runnable { this.seqs = sequences; - //convert ScoreModel name into score matrix, use default if not Blosum or Pam - if (sm.getName().equals("BLOSUM62")) + if (sm!=null && sm instanceof ScoreMatrix) { - this.scoreMatrix = ScoreModels.getInstance().getBlosum62(); - } else if (sm.getName().equals("PAM250")) { - this.scoreMatrix = ScoreModels.getInstance().getPam250(); + this.scoreMatrix = ((ScoreMatrix) sm); } else { this.scoreMatrix = null; } diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index 7116cf3..8336626 100644 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -3862,12 +3862,19 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } else { - JInternalFrame frame = new JInternalFrame(); + new Thread(new Runnable() { + @Override + public void run() + { + JInternalFrame frame = new JInternalFrame(); frame.setFrameIcon(null); frame.setContentPane(new PairwiseAlignPanel(viewport)); Desktop.addInternalFrame(frame, MessageManager.getString("action.pairwise_alignment"), 600, 500); + } + }).start(); + } } diff --git a/src/jalview/gui/CalculationChooser.java b/src/jalview/gui/CalculationChooser.java index bf67a44..f8986b6 100644 --- a/src/jalview/gui/CalculationChooser.java +++ b/src/jalview/gui/CalculationChooser.java @@ -88,17 +88,17 @@ public class CalculationChooser extends JPanel private static final Font VERDANA_11PT = new Font("Verdana", 0, 11); - private static final int MIN_PAIRWISE_SELECTION = 2; private static final int MIN_TREE_SELECTION = 3; private static final int MIN_PCA_SELECTION = 4; - + private String secondaryStructureModelName; - - private void getSecondaryStructureModelName() { - + + private void getSecondaryStructureModelName() + { + ScoreModels scoreModels = ScoreModels.getInstance(); for (ScoreModelI sm : scoreModels.getModels()) { @@ -107,13 +107,14 @@ public class CalculationChooser extends JPanel secondaryStructureModelName = sm.getName(); } } - + } /** - * minimum number of sequences needed for PASIMAP is 9 (so each has 8 connections) + * minimum number of sequences needed for PASIMAP is 9 (so each has 8 + * connections) */ - private static final int MIN_PASIMAP_SELECTION = 9; + private static final int MIN_PASIMAP_SELECTION = 9; AlignFrame af; @@ -121,14 +122,14 @@ public class CalculationChooser extends JPanel JRadioButton pca; - JRadioButton pasimap; + JRadioButton pasimap; JRadioButton neighbourJoining; JRadioButton averageDistance; JComboBox modelNames; - + JComboBox ssSourceDropdown; JButton calculate; @@ -164,7 +165,7 @@ public class CalculationChooser extends JPanel this.af = alignFrame; init(); af.alignPanel.setCalculationDialog(this); - + } /** @@ -203,8 +204,9 @@ public class CalculationChooser extends JPanel MessageManager.getString("label.principal_component_analysis")); pca.setOpaque(false); - pasimap = new JRadioButton( // create the JRadioButton for pasimap with label.pasimap as its text - MessageManager.getString("label.pasimap")); + pasimap = new JRadioButton( // create the JRadioButton for pasimap with + // label.pasimap as its text + MessageManager.getString("label.pasimap")); pasimap.setOpaque(false); neighbourJoining = new JRadioButton( @@ -215,8 +217,9 @@ public class CalculationChooser extends JPanel averageDistance = new JRadioButton( MessageManager.getString("label.tree_calc_av")); averageDistance.setOpaque(false); - - pairwise = new JRadioButton(MessageManager.getString("label.pairwise_alignment")); + + pairwise = new JRadioButton( + MessageManager.getString("action.pairwise_alignment")); pairwise.setOpaque(false); JPanel calcChoicePanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); @@ -240,18 +243,36 @@ public class CalculationChooser extends JPanel calcChoicePanel.add(pcaBorderless, FlowLayout.LEFT); // create pasimap panel - JPanel pasimapBorderless = new JPanel(new FlowLayout(FlowLayout.LEFT)); // create new JPanel (button) for pasimap + JPanel pasimapBorderless = new JPanel(new FlowLayout(FlowLayout.LEFT)); // create + // new + // JPanel + // (button) + // for + // pasimap pasimapBorderless.setBorder( - BorderFactory.createEmptyBorder(2, b.left, 2, b.right)); // set border (margin) for button (same as treePanel and pca) - pasimapBorderless.setOpaque(false); // false -> stops every pixel inside border from being painted - pasimapBorderless.add(pasimap, FlowLayout.LEFT); // add pasimap button to the JPanel - calcChoicePanel.add(pasimapBorderless, FlowLayout.LEFT); // add button with border and everything to the overall ChoicePanel + BorderFactory.createEmptyBorder(2, b.left, 2, b.right)); // set + // border + // (margin) + // for + // button + // (same as + // treePanel + // and pca) + pasimapBorderless.setOpaque(false); // false -> stops every pixel inside + // border from being painted + pasimapBorderless.add(pasimap, FlowLayout.LEFT); // add pasimap button to + // the JPanel + calcChoicePanel.add(pasimapBorderless, FlowLayout.LEFT); // add button with + // border and + // everything to + // the overall + // ChoicePanel treePanel.add(neighbourJoining); treePanel.add(averageDistance); calcChoicePanel.add(treePanel); - calcChoicePanel.add(pairwise,FlowLayout.CENTER); + calcChoicePanel.add(pairwise, FlowLayout.CENTER); ButtonGroup calcTypes = new ButtonGroup(); calcTypes.add(pca); @@ -269,12 +290,13 @@ public class CalculationChooser extends JPanel } }; pca.addActionListener(calcChanged); - pasimap.addActionListener(calcChanged); // add the calcChanged ActionListener to pasimap --> <++> idk + pasimap.addActionListener(calcChanged); // add the calcChanged + // ActionListener to pasimap --> + // <++> idk neighbourJoining.addActionListener(calcChanged); averageDistance.addActionListener(calcChanged); - - - //to do + + // to do ssSourceDropdown = buildSSSourcesOptionsList(); ssSourceDropdown.setVisible(false); // Initially hide the dropdown pairwise.addActionListener(calcChanged); @@ -282,27 +304,31 @@ public class CalculationChooser extends JPanel * score models drop-down - with added tooltips! */ modelNames = buildModelOptionsList(); - + // Step 3: Show or Hide Dropdown Based on Selection - modelNames.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - String selectedModel = modelNames.getSelectedItem().toString(); - - if (selectedModel.equals(secondaryStructureModelName)) { - ssSourceDropdown.setVisible(true); - } else { - ssSourceDropdown.setVisible(false); - } + modelNames.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + String selectedModel = modelNames.getSelectedItem().toString(); + + if (selectedModel.equals(secondaryStructureModelName)) + { + ssSourceDropdown.setVisible(true); } + else + { + ssSourceDropdown.setVisible(false); + } + } }); - JPanel scoreModelPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); scoreModelPanel.setOpaque(false); scoreModelPanel.add(modelNames); scoreModelPanel.add(ssSourceDropdown); - + /* * score model parameters */ @@ -317,7 +343,7 @@ public class CalculationChooser extends JPanel paramsPanel.add(matchGaps); paramsPanel.add(includeGappedColumns); paramsPanel.add(shorterSequence); - + /* * OK / Cancel buttons */ @@ -400,7 +426,9 @@ public class CalculationChooser extends JPanel * return value of true means enabled and selected */ boolean checkPca = checkEnabled(pca, size, MIN_PCA_SELECTION); - boolean checkPasimap = checkEnabled(pasimap, size, MIN_PASIMAP_SELECTION); // check if pasimap is enabled and min_size is fulfilled + boolean checkPasimap = checkEnabled(pasimap, size, + MIN_PASIMAP_SELECTION); // check if pasimap is enabled and min_size + // is fulfilled boolean checkNeighbourJoining = checkEnabled(neighbourJoining, size, MIN_TREE_SELECTION); boolean checkAverageDistance = checkEnabled(averageDistance, size, @@ -408,7 +436,8 @@ public class CalculationChooser extends JPanel boolean checkPairwise = checkEnabled(pairwise, size, MIN_PAIRWISE_SELECTION); - if (checkPca || checkPasimap || checkPca || checkNeighbourJoining || checkAverageDistance || checkPairwise) + if (checkPca || checkPasimap || checkPca || checkNeighbourJoining + || checkAverageDistance || checkPairwise) { calculate.setToolTipText(null); calculate.setEnabled(true); @@ -506,7 +535,6 @@ public class CalculationChooser extends JPanel return scoreModelsCombo; } - private JComboBox buildSSSourcesOptionsList() { @@ -525,7 +553,7 @@ public class CalculationChooser extends JPanel curSel = source; } sourcesModel.addElement(source); - + } if (selectedIsPresent) @@ -533,11 +561,10 @@ public class CalculationChooser extends JPanel sourcesModel.setSelectedItem(curSel); } comboBox.setModel(sourcesModel); - + return comboBox; } - - + private void updateScoreModels(JComboBox comboBox, List toolTips) { @@ -549,12 +576,14 @@ public class CalculationChooser extends JPanel * select the score models applicable to the alignment type */ boolean nucleotide = af.getViewport().getAlignment().isNucleotide(); - AlignmentAnnotation[] alignmentAnnotations = af.getViewport().getAlignment().getAlignmentAnnotation(); + AlignmentAnnotation[] alignmentAnnotations = af.getViewport() + .getAlignment().getAlignmentAnnotation(); - boolean ssPresent = AlignmentUtils.isSecondaryStructurePresent(alignmentAnnotations); + boolean ssPresent = AlignmentUtils + .isSecondaryStructurePresent(alignmentAnnotations); - List models = getApplicableScoreModels(nucleotide, pca.isSelected(), - ssPresent, pasimap.isSelected()); + List models = getApplicableScoreModels(nucleotide, + pca.isSelected(), ssPresent, pasimap.isSelected()); /* * now we can actually add entries to the combobox, @@ -589,8 +618,8 @@ public class CalculationChooser extends JPanel } // finally, update the model comboBox.setModel(model); - comboBox.setEnabled(model.getSize()>0); - + comboBox.setEnabled(model.getSize() > 0); + } /** @@ -605,32 +634,27 @@ public class CalculationChooser extends JPanel * * @param nucleotide * @param forPca + * @param ssPresent - include secondary structure similarity model + * @param forPasimap - limit to ScoreMatrix based models - allows use of AlignSeq * @return */ protected static List getApplicableScoreModels( - boolean nucleotide, boolean forPca, boolean ssPresent, boolean forPasimap) + boolean nucleotide, boolean forPca, boolean ssPresent, + boolean forPasimap) { List filtered = new ArrayList<>(); ScoreModels scoreModels = ScoreModels.getInstance(); for (ScoreModelI sm : scoreModels.getModels()) { - if (!forPasimap && (!nucleotide && sm.isProtein() || nucleotide && sm.isDNA() - || sm.isSecondaryStructure() && ssPresent)) - + if ((!forPasimap || sm instanceof ScoreMatrix) + && (!nucleotide && sm.isProtein() || nucleotide && sm.isDNA() + || sm.isSecondaryStructure() && ssPresent)) + { filtered.add(sm); } } - - /* - * make PaSiMap only use Blosum62 and Pam250 - */ - if (forPasimap && !nucleotide && !forPca) - { - filtered.add(scoreModels.getBlosum62()); - filtered.add(scoreModels.getPam250()); - } /* * special case: add BLOSUM62 as last option for nucleotide PCA, @@ -641,22 +665,23 @@ public class CalculationChooser extends JPanel { filtered.add(scoreModels.getBlosum62()); } - + return filtered; } - protected List getApplicableSecondaryStructureSources() { - AlignmentAnnotation[] annotations = af.getViewport().getAlignment().getAlignmentAnnotation(); - - List ssSources = AlignmentUtils.getSecondaryStructureSources(annotations); - //List ssSources = AlignmentUtils.extractSSSourceInAlignmentAnnotation(annotations); - - + AlignmentAnnotation[] annotations = af.getViewport().getAlignment() + .getAlignmentAnnotation(); + + List ssSources = AlignmentUtils + .getSecondaryStructureSources(annotations); + // List ssSources = + // AlignmentUtils.extractSSSourceInAlignmentAnnotation(annotations); + return ssSources; } - + /** * Open and calculate the selected tree or PCA on 'OK' */ @@ -664,15 +689,17 @@ public class CalculationChooser extends JPanel { boolean doPCA = pca.isSelected(); boolean doPaSiMap = pasimap.isSelected(); - boolean doPairwise= pairwise.isSelected(); - String modelName = modelNames.getSelectedItem() == null ? "" : modelNames.getSelectedItem().toString(); + boolean doPairwise = pairwise.isSelected(); + String modelName = modelNames.getSelectedItem() == null ? "" + : modelNames.getSelectedItem().toString(); String ssSource = ""; Object selectedItem = ssSourceDropdown.getSelectedItem(); - if (selectedItem != null) { - ssSource = selectedItem.toString(); + if (selectedItem != null) + { + ssSource = selectedItem.toString(); } SimilarityParams params = getSimilarityParameters(doPCA); - if(ssSource.length()>0) + if (ssSource.length() > 0) { params.setSecondaryStructureSource(ssSource); } @@ -680,30 +707,45 @@ public class CalculationChooser extends JPanel if (doPCA) { openPcaPanel(modelName, params); - } else if (doPaSiMap) { - openPasimapPanel(modelName, params); - } else if (doPairwise) { - openPairwisePanel(modelName, params); - } else { - openTreePanel(modelName, params); - } + } + else if (doPaSiMap) + { + openPasimapPanel(modelName, params); + } + else if (doPairwise) + { + openPairwisePanel(modelName, params); + } + else + { + openTreePanel(modelName, params); + } closeFrame(); } private void openPairwisePanel(String modelName, SimilarityParamsI params) { - ScoreModelI sm = ScoreModels.getInstance().getScoreModel(modelName, af.alignPanel); - if (sm==null || !(sm instanceof ScoreMatrix)) + ScoreModelI sm = ScoreModels.getInstance().getScoreModel(modelName, + af.alignPanel); + if (sm == null || !(sm instanceof ScoreMatrix)) { return; } - JInternalFrame frame = new JInternalFrame(); - frame.setFrameIcon(null); - frame.setContentPane(new PairwiseAlignPanel(af.getViewport(),(ScoreMatrix)sm)); - Desktop.addInternalFrame(frame, - MessageManager.getString("action.pairwise_alignment"), 600, - 500); + new Thread(new Runnable() + { + @Override + public void run() + { + JInternalFrame frame = new JInternalFrame(); + frame.setFrameIcon(null); + frame.setContentPane( + new PairwiseAlignPanel(af.getViewport(), (ScoreMatrix) sm)); + Desktop.addInternalFrame(frame, + MessageManager.getString("action.pairwise_alignment"), 600, + 500); + } + }).start(); } /** @@ -780,7 +822,8 @@ public class CalculationChooser extends JPanel * @param modelName * @param params */ - protected void openPasimapPanel(String modelName, SimilarityParamsI params) + protected void openPasimapPanel(String modelName, + SimilarityParamsI params) { AlignViewport viewport = af.getViewport(); @@ -789,9 +832,11 @@ public class CalculationChooser extends JPanel * this check in in case this method gets exposed programmatically in future */ if (((viewport.getSelectionGroup() != null) - && (viewport.getSelectionGroup().getSize() < MIN_PASIMAP_SELECTION) + && (viewport.getSelectionGroup() + .getSize() < MIN_PASIMAP_SELECTION) && (viewport.getSelectionGroup().getSize() > 0)) - || (viewport.getAlignment().getHeight() < MIN_PASIMAP_SELECTION)) + || (viewport.getAlignment() + .getHeight() < MIN_PASIMAP_SELECTION)) { JvOptionPane.showInternalMessageDialog(this, MessageManager.formatMessage( diff --git a/src/jalview/gui/PaSiMapPanel.java b/src/jalview/gui/PaSiMapPanel.java index 3bf731d..702c4f4 100644 --- a/src/jalview/gui/PaSiMapPanel.java +++ b/src/jalview/gui/PaSiMapPanel.java @@ -213,6 +213,9 @@ public class PaSiMapPanel extends GPaSiMapPanel PairwiseAlignPanel pap = new PairwiseAlignPanel(av, selGroup, true, GAP_OPEN_COST, GAP_EXTEND_COST, false, null); + pap.setDiscardAlignments(true); + pap.setQuiet(true); + System.out.println(pap != null); setPairwiseAlignPanel(pap); getPasimapModel().calculate(pap); @@ -702,7 +705,11 @@ public class PaSiMapPanel extends GPaSiMapPanel pBar.repaint(); } - //&! + /** + * adds a listener for a pairwise alignment panel's progress + * TODO: generalise for anything that can report progress ? + * @param pap + */ public void setPairwiseAlignPanel(PairwiseAlignPanel pap) { pap.addPropertyChangeListener(new PropertyChangeListener() @@ -710,12 +717,14 @@ public class PaSiMapPanel extends GPaSiMapPanel @Override public void propertyChange(PropertyChangeEvent pcEvent) { - if (PairwiseAlignPanel.PROGRESS.equals(pcEvent.getPropertyName())) - { - updateProgressBar((int) pcEvent.getNewValue()); - } else if (PairwiseAlignPanel.TOTAL.equals(pcEvent.getPropertyName())) { - updateProgressBar((int) pcEvent.getNewValue(), 0); - } + if (PairwiseAlignPanel.PROGRESS.equals(pcEvent.getPropertyName())) + { + updateProgressBar((int) pcEvent.getNewValue()); + } + else if (PairwiseAlignPanel.TOTAL.equals(pcEvent.getPropertyName())) + { + updateProgressBar((int) pcEvent.getNewValue(), 0); + } } }); } diff --git a/src/jalview/gui/PairwiseAlignPanel.java b/src/jalview/gui/PairwiseAlignPanel.java index e8b130e..3e8fb02 100755 --- a/src/jalview/gui/PairwiseAlignPanel.java +++ b/src/jalview/gui/PairwiseAlignPanel.java @@ -22,8 +22,6 @@ package jalview.gui; import jalview.analysis.AlignSeq; import jalview.analysis.scoremodels.ScoreMatrix; -import jalview.api.analysis.ScoreModelI; -import jalview.api.analysis.SimilarityParamsI; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentView; import jalview.datamodel.SequenceGroup; @@ -33,10 +31,8 @@ import jalview.util.MessageManager; import jalview.viewmodel.AlignmentViewport; import jalview.math.MiscMath; -import java.beans.PropertyChangeListener; import java.awt.event.ActionEvent; import java.util.Vector; -import javax.swing.event.SwingPropertyChangeSupport; /** * DOCUMENT ME! @@ -63,7 +59,7 @@ public class PairwiseAlignPanel extends GPairwiseAlignPanel private String alignmentOutput; - private boolean suppressTextbox; + private boolean quiet; private boolean discardAlignments; @@ -77,13 +73,15 @@ public class PairwiseAlignPanel extends GPairwiseAlignPanel private int total; private int progress; - + private SequenceGroup selection; /** * input sequences */ private SequenceI[] seqs=null; + private ScoreMatrix scoreMatrix; + /** * Creates a new PairwiseAlignPanel object. * @@ -124,17 +122,15 @@ public class PairwiseAlignPanel extends GPairwiseAlignPanel this.endGaps = endGaps; this.selection = selection; this.total = MiscMath.combinations(av.getAlignment().getHeight(), 2); - + this.scoreMatrix = scoreMatrix; if (run) { - calculate(scoreMatrix); + calculate(); } - - System.out.println("Creating pap"); } public void calculate() { - calculate(null); + calculate(scoreMatrix); } public void calculate (ScoreMatrix sm) { @@ -181,8 +177,7 @@ public class PairwiseAlignPanel extends GPairwiseAlignPanel float[][] alignmentScores = new float[seqs.length][seqs.length]; double totscore = 0D; int count = seqs.length; - suppressTextbox = count>10; - discardAlignments = count>15; + boolean first = true; progress = 0; @@ -217,7 +212,7 @@ public class PairwiseAlignPanel extends GPairwiseAlignPanel } as.scoreAlignment(); - if (!first && !suppressTextbox) + if (!first && !quiet) { jalview.bin.Console.outPrintln(DASHES); textarea.append(DASHES); @@ -230,7 +225,7 @@ public class PairwiseAlignPanel extends GPairwiseAlignPanel scores[i][j] = as.getMaxScore() / as.getASeq1().length; alignmentScores[i][j] = as.getAlignmentScore(); totscore = totscore + scores[i][j]; - if (!suppressTextbox) + if (!quiet) { textarea.append(as.getOutput()); sb.append(as.getOutput()); @@ -248,7 +243,7 @@ public class PairwiseAlignPanel extends GPairwiseAlignPanel this.scores = scores; this.alignmentScores = alignmentScores; - if (count > 2) + if (count > 2 && !quiet) { printScoreMatrix(seqs, scores, totscore); } @@ -353,4 +348,20 @@ public class PairwiseAlignPanel extends GPairwiseAlignPanel { return seqs; } + /** + * Set to true to suppress output of progress to Console.stdout or GUI + * @param quiet + */ + public void setQuiet(boolean quiet) + { + this.quiet=quiet; + } + /** + * set this if you are only interested in final alignment scores + * @param discard + */ + public void setDiscardAlignments(boolean discard) + { + discardAlignments=discard; + } } -- 1.7.10.2