*/
package jalview.gui;
-import jalview.analysis.TreeBuilder;
-import jalview.analysis.scoremodels.ScoreModels;
-import jalview.analysis.scoremodels.SimilarityParams;
-import jalview.api.analysis.ScoreModelI;
-import jalview.api.analysis.SimilarityParamsI;
-import jalview.datamodel.SequenceGroup;
-import jalview.util.MessageManager;
-
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
+import jalview.analysis.AlignmentUtils;
+import jalview.analysis.TreeBuilder;
+import jalview.analysis.scoremodels.ScoreModels;
+import jalview.analysis.scoremodels.SimilarityParams;
+import jalview.api.analysis.ScoreModelI;
+import jalview.api.analysis.SimilarityParamsI;
+import jalview.bin.Cache;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.SequenceGroup;
+import jalview.util.MessageManager;
+
/**
* A dialog where a user can choose and action Tree or PCA calculation options
*/
private static final int MIN_TREE_SELECTION = 3;
private static final int MIN_PCA_SELECTION = 4;
+
+ private String secondaryStructureModelName;
+
+ private void getSecondaryStructureModelName() {
+
+ ScoreModels scoreModels = ScoreModels.getInstance();
+ for (ScoreModelI sm : scoreModels.getModels())
+ {
+ if (sm.isSecondaryStructure())
+ {
+ secondaryStructureModelName = sm.getName();
+ }
+ }
+
+ }
AlignFrame af;
JRadioButton averageDistance;
JComboBox<String> modelNames;
+
+ JComboBox<String> ssSourceDropdown;
JButton calculate;
final ComboBoxTooltipRenderer renderer = new ComboBoxTooltipRenderer();
- List<String> tips = new ArrayList<String>();
+ List<String> tips = new ArrayList<>();
/*
* the most recently opened PCA results panel
this.af = alignFrame;
init();
af.alignPanel.setCalculationDialog(this);
+
}
/**
*/
void init()
{
+ getSecondaryStructureModelName();
setLayout(new BorderLayout());
frame = new JInternalFrame();
+ frame.setFrameIcon(null);
frame.setContentPane(this);
this.setBackground(Color.white);
frame.addFocusListener(new FocusListener()
pca = new JRadioButton(
MessageManager.getString("label.principal_component_analysis"));
pca.setOpaque(false);
+
neighbourJoining = new JRadioButton(
MessageManager.getString("label.tree_calc_nj"));
neighbourJoining.setSelected(true);
+ neighbourJoining.setOpaque(false);
+
averageDistance = new JRadioButton(
MessageManager.getString("label.tree_calc_av"));
- neighbourJoining.setOpaque(false);
+ averageDistance.setOpaque(false);
JPanel calcChoicePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
calcChoicePanel.setOpaque(false);
JPanel treePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
treePanel.setOpaque(false);
- JvSwingUtils.createItalicTitledBorder(treePanel,
+ JvSwingUtils.createTitledBorder(treePanel,
MessageManager.getString("label.tree"), true);
// then copy the inset dimensions for the border-less PCA panel
pca.addActionListener(calcChanged);
neighbourJoining.addActionListener(calcChanged);
averageDistance.addActionListener(calcChanged);
+
+
+ //to do
+ ssSourceDropdown = buildSSSourcesOptionsList();
+ ssSourceDropdown.setVisible(false); // Initially hide the dropdown
/*
* 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);
+ }
+ }
+ });
+
JPanel scoreModelPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
scoreModelPanel.setOpaque(false);
scoreModelPanel.add(modelNames);
-
+ scoreModelPanel.add(ssSourceDropdown);
+
/*
* score model parameters
*/
paramsPanel.add(matchGaps);
paramsPanel.add(includeGappedColumns);
paramsPanel.add(shorterSequence);
-
+
/*
* OK / Cancel buttons
*/
}
this.add(actionPanel, BorderLayout.SOUTH);
- int width = 350;
+ int width = 365;
int height = includeParams ? 420 : 240;
setMinimumSize(new Dimension(325, height - 10));
String title = MessageManager.getString("label.choose_calculation");
- if (af.getViewport().viewName != null)
+ if (af.getViewport().getViewName() != null)
{
- title = title + " (" + af.getViewport().viewName + ")";
+ title = title + " (" + af.getViewport().getViewName() + ")";
}
Desktop.addInternalFrame(frame, title, width, height, false);
};
});
+ validateCalcTypes();
frame.setLayer(JLayeredPane.PALETTE_LAYER);
}
*/
protected JComboBox<String> buildModelOptionsList()
{
- final JComboBox<String> scoreModelsCombo = new JComboBox<String>();
+ final JComboBox<String> scoreModelsCombo = new JComboBox<>();
scoreModelsCombo.setRenderer(renderer);
/*
return scoreModelsCombo;
}
+
+
+ private JComboBox<String> buildSSSourcesOptionsList()
+ {
+ final JComboBox<String> comboBox = new JComboBox<>();
+ Object curSel = comboBox.getSelectedItem();
+ DefaultComboBoxModel<String> sourcesModel = new DefaultComboBoxModel<>();
+
+ List<String> ssSources = getApplicableSecondaryStructureSources();
+ boolean selectedIsPresent = false;
+ for (String source : ssSources)
+ {
+ if (curSel != null && source.equals(curSel))
+ {
+ selectedIsPresent = true;
+ curSel = source;
+ }
+ sourcesModel.addElement(source);
+
+ }
+
+ if (selectedIsPresent)
+ {
+ sourcesModel.setSelectedItem(curSel);
+ }
+ comboBox.setModel(sourcesModel);
+
+ return comboBox;
+ }
+
+
private void updateScoreModels(JComboBox<String> comboBox,
List<String> toolTips)
{
Object curSel = comboBox.getSelectedItem();
toolTips.clear();
- DefaultComboBoxModel<String> model = new DefaultComboBoxModel<String>();
+ DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>();
+
+ /*
+ * select the score models applicable to the alignment type
+ */
+ boolean nucleotide = af.getViewport().getAlignment().isNucleotide();
+ AlignmentAnnotation[] alignmentAnnotations = af.getViewport().getAlignment().getAlignmentAnnotation();
+
+ boolean ssPresent = AlignmentUtils.isSecondaryStructurePresent(alignmentAnnotations);
+
+ List<ScoreModelI> models = getApplicableScoreModels(nucleotide, pca.isSelected(),
+ ssPresent);
/*
* now we can actually add entries to the combobox,
* remembering their descriptions for tooltips
*/
- ScoreModels scoreModels = ScoreModels.getInstance();
boolean selectedIsPresent = false;
- for (ScoreModelI sm : scoreModels.getModels())
+ for (ScoreModelI sm : models)
{
- boolean nucleotide = af.getViewport().getAlignment().isNucleotide();
- if (sm.isDNA() && nucleotide || sm.isProtein() && !nucleotide)
+ if (curSel != null && sm.getName().equals(curSel))
{
- if (curSel != null && sm.getName().equals(curSel))
- {
- selectedIsPresent = true;
- curSel = sm.getName();
- }
- model.addElement(sm.getName());
-
- /*
- * tooltip is description if provided, else text lookup with
- * fallback on the model name
- */
- String tooltip = sm.getDescription();
- if (tooltip == null)
- {
- tooltip = MessageManager.getStringOrReturn("label.score_model_",
- sm.getName());
- }
- toolTips.add(tooltip);
+ selectedIsPresent = true;
+ curSel = sm.getName();
}
+ model.addElement(sm.getName());
+
+ /*
+ * tooltip is description if provided, else text lookup with
+ * fallback on the model name
+ */
+ String tooltip = sm.getDescription();
+ if (tooltip == null)
+ {
+ tooltip = MessageManager.getStringOrReturn("label.score_model_",
+ sm.getName());
+ }
+ toolTips.add(tooltip);
}
+
if (selectedIsPresent)
{
model.setSelectedItem(curSel);
}
// finally, update the model
comboBox.setModel(model);
+
}
/**
+ * Builds a list of score models which are applicable for the alignment and
+ * calculation type (peptide or generic models for protein, nucleotide or
+ * generic models for nucleotide).
+ * <p>
+ * As a special case, includes BLOSUM62 as an extra option for nucleotide PCA.
+ * This is for backwards compatibility with Jalview prior to 2.8 when BLOSUM62
+ * was the only score matrix supported. This is included if property
+ * BLOSUM62_PCA_FOR_NUCLEOTIDE is set to true in the Jalview properties file.
+ *
+ * @param nucleotide
+ * @param forPca
+ * @return
+ */
+ protected static List<ScoreModelI> getApplicableScoreModels(
+ boolean nucleotide, boolean forPca, boolean ssPresent)
+ {
+ List<ScoreModelI> filtered = new ArrayList<>();
+
+ ScoreModels scoreModels = ScoreModels.getInstance();
+ for (ScoreModelI sm : scoreModels.getModels())
+ {
+ if (!nucleotide && sm.isProtein() || nucleotide && sm.isDNA()
+ || ssPresent && sm.isSecondaryStructure())
+ {
+ filtered.add(sm);
+ }
+ }
+
+ /*
+ * special case: add BLOSUM62 as last option for nucleotide PCA,
+ * for backwards compatibility with Jalview < 2.8 (JAL-2962)
+ */
+ if (nucleotide && forPca
+ && Cache.getDefault("BLOSUM62_PCA_FOR_NUCLEOTIDE", false))
+ {
+ filtered.add(scoreModels.getBlosum62());
+ }
+
+ return filtered;
+ }
+
+
+ protected List<String> getApplicableSecondaryStructureSources()
+ {
+ AlignmentAnnotation[] annotations = af.getViewport().getAlignment().getAlignmentAnnotation();
+
+ List<String> ssSources = AlignmentUtils.getSecondaryStructureSources(annotations);
+ //List<String> ssSources = AlignmentUtils.extractSSSourceInAlignmentAnnotation(annotations);
+
+
+ return ssSources;
+ }
+
+ /**
* Open and calculate the selected tree or PCA on 'OK'
*/
protected void calculate_actionPerformed()
{
boolean doPCA = pca.isSelected();
String modelName = modelNames.getSelectedItem().toString();
- SimilarityParamsI params = getSimilarityParameters(doPCA);
-
+ String ssSource = "";
+ Object selectedItem = ssSourceDropdown.getSelectedItem();
+ if (selectedItem != null) {
+ ssSource = selectedItem.toString();
+ }
+ SimilarityParams params = getSimilarityParameters(doPCA);
+ if(ssSource.length()>0)
+ {
+ params.setSecondaryStructureSource(ssSource);
+ }
if (doPCA)
{
openPcaPanel(modelName, params);
JvOptionPane.WARNING_MESSAGE);
return;
}
+
+ /*
+ * construct the panel and kick off its calculation thread
+ */
pcaPanel = new PCAPanel(af.alignPanel, modelName, params);
+ new Thread(pcaPanel).start();
+
}
/**
* @param doPCA
* @return
*/
- protected SimilarityParamsI getSimilarityParameters(boolean doPCA)
+ protected SimilarityParams getSimilarityParameters(boolean doPCA)
{
// commented out: parameter choices read from gui widgets
// SimilarityParamsI params = new SimilarityParams(