preserveOrder true
useDefaultListeners=true
}
- timeout = Duration.ofMinutes(10)
+ timeout = Duration.ofMinutes(15)
}
/* separated tests */
one of the sequences (the shorter) is discarded. Press the
"Apply" button to remove redundant sequences. The
"Undo" button will undo the last redundancy deletion.</em></li>
+ <li><strong>Left Justify</strong> and <strong>Right
+ Justify<br>
+ </strong> <em>Moves all gaps to either right or left of the sequences in
+ the alignment or the currently selected region.</em></li>
<li><strong>Pad Gaps<br>
</strong><em>When selected, the alignment will be kept at minimal width
(so there are no empty columns before or after the first or last
---
version: 2.11.3.3
-date: 2024-01-24
+date: 2024-05-16
channel: "release"
---
## New Features
+- <!-- JAL-518 --> Left/Right justify the alignment or current selection (with Undo)
- <!-- JAL-4192 --> Minimum versions of Jalview's build toolchain are explicitly specified in doc/building.md
+### development and deployment
+
+- <!-- JAL-4413 --> timeout for test tasks to prevent hanging builds
+
## Issues Resolved
+- <!-- JAL-4407 --> Secondary structure not available after dragging a 3D structure onto a sequence to associate it when 'Process secondary structure' flag is true in preferences
- <!-- JAL-840 --> Clustal colourscheme documentation not consistent with implementation
- <!-- JAL-4367 --> Handles to adjust ID panel width or annotation panel height can be dragged out of the Alignment window
- <!-- JAL-2934 --> Trackpad scrolling not proportional to gesture velocity
- <!-- JAL-4369 --> Uniprot record retrieval not working in JalviewJS (affects all versions)
- <!-- JAL-4243 --> bio.tools record version number updated
- <!-- JAL-4217 --> Miscellaneous patches to fix hangs in 2.11.3 test suite
+
+### New Known Issues
+
+- <!-- JAL-3124 --> Protein structure derived annotation tracks not available as reference annotation unless 'add to alignment' preference is enabled
+- <!-- JAL-4415 --> Enabling just "Add Secondary Structure" Structure preference when importing structure via CLI results in temperature factor being shown in alignment
+
-The 2.11.3.3 release features minor updates to documentation, and addresses bugs affecting export of multiple images for structure views.
+The 2.11.3.3 release features minor updates to documentation, and addresses bugs affecting export of multiple images for structure views, trackpad scrolling, sequence ID margin width, and extraction of secondary structure for imported models. It also includes two new alignment editing operations - Left and Right justify, which can be applied to the whole alignment or current selection.
action.remove_right = Remove right
action.remove_empty_columns = Remove Empty Columns
action.remove_all_gaps = Remove All Gaps
-action.left_justify_alignment = Left Justify Alignment
-action.right_justify_alignment = Right Justify Alignment
+tooltip.left_justify = Left justify whole alignment or selected region
+tooltip.right_justify = Right justify whole alignment or selected region
+action.left_justify = Left Justify
+action.right_justify = Right Justify
action.boxes = Boxes
action.text = Text
action.by_pairwise_id = By Pairwise Identity
label.conservation_descr = Conservation of total alignment less than {0}% gaps
label.consensus_descr = PID
label.ssconsensus_label = Secondary Structure Consensus
-label.ssconsensus_descr = SS Consensus
+label.ssconsensus_descr = Secondary Structure Consensus
+option.ss_providers_all = All
+option.ss_providers_none = None
label.complement_consensus_descr = PID for cDNA
label.strucconsensus_descr = PID for base pairs
label.occupancy_descr = Number of aligned positions
public static final ProfilesI calculateSS(List<SequenceI> list, int start,
- int end)
+ int end, String source)
{
- return calculateSS(list, start, end, false);
+ return calculateSS(list, start, end, false, source);
}
public static final ProfilesI calculateSS(List<SequenceI> sequences,
- int start, int end, boolean profile)
+ int start, int end, boolean profile, String source)
{
SequenceI[] seqs = new SequenceI[sequences.size()];
int width = 0;
{
end = width;
}
+
- ProfilesI reply = calculateSS(seqs, width, start, end, profile);
+ ProfilesI reply = calculateSS(seqs, width, start, end, profile, source);
return reply;
}
}
public static final ProfilesI calculateSS(final SequenceI[] sequences,
- int width, int start, int end, boolean saveFullProfile)
+ int width, int start, int end, boolean saveFullProfile, String source)
{
int seqCount = sequences.length;
}
char c = sequences[row].getCharAt(column);
- AlignmentAnnotation aa = AlignmentUtils.getDisplayedAlignmentAnnotation(sequences[row]);
- if(aa!=null) {
- ssCount++;
- }
-
- if (sequences[row].getLength() > column && !Comparison.isGap(c) && aa !=null)
- {
-
- int seqPosition = sequences[row].findPosition(column);
+ List<AlignmentAnnotation> annots = AlignmentUtils.getAlignmentAnnotationForSource(sequences[row], source);
+ if(annots!=null) {
+ for(AlignmentAnnotation aa:annots) {
+ if(aa!=null) {
+ ssCount++;
+ }
- char ss = AlignmentUtils.findSSAnnotationForGivenSeqposition(
- aa, seqPosition);
- if(ss == '*') {
- continue;
- }
- ssCounts.add(ss);
- }
- else if(Comparison.isGap(c) && aa!=null) {
- ssCounts.addGap();
+ if (sequences[row].getLength() > column && !Comparison.isGap(c) && aa !=null)
+ {
+
+ int seqPosition = sequences[row].findPosition(column);
+
+ char ss = AlignmentUtils.findSSAnnotationForGivenSeqposition(
+ aa, seqPosition);
+ if(ss == '*') {
+ continue;
+ }
+ ssCounts.add(ss);
+ }
+ else if(Comparison.isGap(c) && aa!=null) {
+ ssCounts.addGap();
+ }
}
}
+ }
int maxSSCount = ssCounts.getModalCount();
String maxSS = ssCounts.getSSForCount(maxSSCount);
import jalview.util.IntRangeComparator;
import jalview.util.MapList;
import jalview.util.MappingUtils;
+import jalview.util.MessageManager;
import jalview.workers.SecondaryStructureConsensusThread;
/**
}
- public static List<String> getSecondaryStructureSources(AlignmentAnnotation[] annotations) {
-
- List<String> ssSources = new ArrayList<>();
- Set<String> addedLabels = new HashSet<>(); // to keep track of added labels
-
- for (AlignmentAnnotation annotation : annotations) {
- String label = annotation.label;
- if (Constants.SECONDARY_STRUCTURE_LABELS.containsKey(label) && !addedLabels.contains(label)) {
- ssSources.add(Constants.SECONDARY_STRUCTURE_LABELS.get(label));
- addedLabels.add(label); // Add the label to the set
- }
+ public static List<String> getSecondaryStructureSources(
+ AlignmentAnnotation[] annotations)
+ {
+
+ List<String> ssSources = new ArrayList<>();
+ Set<String> addedLabels = new HashSet<>(); // to keep track of added labels
+
+ for (AlignmentAnnotation annotation : annotations)
+ {
+ String label = annotation.label;
+ if (Constants.SECONDARY_STRUCTURE_LABELS.containsKey(label)
+ && !addedLabels.contains(label))
+ {
+ ssSources.add(Constants.SECONDARY_STRUCTURE_LABELS.get(label));
+ addedLabels.add(label); // Add the label to the set
}
+ }
- return ssSources;
+ return ssSources;
}
public static boolean isSecondaryStructurePresent(AlignmentAnnotation[] annotations)
{
boolean ssPresent = false;
-
+
for (AlignmentAnnotation aa : annotations)
{
- if(ssPresent) {
+ if (ssPresent)
+ {
break;
- }
+ }
- if (Constants.SECONDARY_STRUCTURE_LABELS.containsKey(aa.label)) {
- ssPresent = true;
- break;
+ if (Constants.SECONDARY_STRUCTURE_LABELS.containsKey(aa.label))
+ {
+ ssPresent = true;
+ break;
}
}
-
+
return ssPresent;
-
+
}
- public static Color getSecondaryStructureAnnotationColour(char symbol){
-
- if (symbol== Constants.COIL) {
+ public static Color getSecondaryStructureAnnotationColour(char symbol)
+ {
+
+ if (symbol == Constants.COIL)
+ {
return Color.gray;
}
- if (symbol== Constants.SHEET) {
+ if (symbol == Constants.SHEET)
+ {
return Color.green;
}
- if (symbol== Constants.HELIX) {
+ if (symbol == Constants.HELIX)
+ {
return Color.red;
}
-
+
return Color.gray;
}
public static char findSSAnnotationForGivenSeqposition(AlignmentAnnotation aa,
int seqPosition)
{
- char ss = '*';
-
- if (aa != null) {
- if (aa.getAnnotationForPosition(seqPosition) != null) {
+ char ss = '*';
+
+ if (aa != null)
+ {
+ if (aa.getAnnotationForPosition(seqPosition) != null)
+ {
Annotation a = aa.getAnnotationForPosition(seqPosition);
ss = a.secondaryStructure;
-
- //There is no representation for coil and it can be either ' ' or null.
- if (ss == ' ' || ss == '-') {
- ss = Constants.COIL;
+
+ // There is no representation for coil and it can be either ' ' or null.
+ if (ss == ' ' || ss == '-')
+ {
+ ss = Constants.COIL;
}
}
- else {
+ else
+ {
ss = Constants.COIL;
- }
+ }
}
-
- return ss;
+
+ return ss;
}
- public static List<String> extractSSSourceInAlignmentAnnotation(AlignmentAnnotation[] annotations) {
-
+ public static List<String> extractSSSourceInAlignmentAnnotation(
+ AlignmentAnnotation[] annotations)
+ {
+
List<String> ssSources = new ArrayList<>();
- Set<String> addedSources = new HashSet<>(); // to keep track of added sources
+ Set<String> addedSources = new HashSet<>(); // to keep track of added
+ // sources
+
+ if (annotations == null)
+ {
+ return ssSources;
+ }
+
+ for (AlignmentAnnotation aa : annotations)
+ {
-
- for (AlignmentAnnotation aa: annotations) {
-
String ssSource = extractSSSourceFromAnnotationDescription(aa);
-
- if (ssSource!= null && !addedSources.contains(ssSource)) {
- ssSources.add(ssSource);
- addedSources.add(ssSource);
+
+ if (ssSource != null && !addedSources.contains(ssSource))
+ {
+ ssSources.add(ssSource);
+ addedSources.add(ssSource);
}
-
- }
+
+ }
Collections.sort(ssSources);
-
+
return ssSources;
-
+
}
- public static String extractSSSourceFromAnnotationDescription(AlignmentAnnotation aa) {
-
-
- for (String label : Constants.SECONDARY_STRUCTURE_LABELS.keySet()) {
-
- if (label.equals(aa.label)) {
-
- //For JPred
- if(aa.label.equals(Constants.SS_ANNOTATION_FROM_JPRED_LABEL)){
-
+ public static String extractSSSourceFromAnnotationDescription(
+ AlignmentAnnotation aa)
+ {
+
+ for (String label : Constants.SECONDARY_STRUCTURE_LABELS.keySet())
+ {
+
+ if (label.equals(aa.label))
+ {
+
+ // For JPred
+ if (aa.label.equals(Constants.SS_ANNOTATION_FROM_JPRED_LABEL))
+ {
+
return (Constants.SECONDARY_STRUCTURE_LABELS.get(aa.label));
-
- }
-
- //For input with secondary structure
- if(aa.label.equals(Constants.SS_ANNOTATION_LABEL)
- && aa.description.equals(Constants.SS_ANNOTATION_LABEL)){
-
+
+ }
+
+ // For input with secondary structure
+ if (aa.label.equals(Constants.SS_ANNOTATION_LABEL)
+ && aa.description != null && aa.description.equals(Constants.SS_ANNOTATION_LABEL))
+ {
+
return (Constants.SECONDARY_STRUCTURE_LABELS.get(aa.label));
-
- }
-
- //For other sources
- if(aa.sequenceRef==null) {
+
+ }
+
+ // For other sources
+ if (aa.sequenceRef == null)
+ {
return null;
}
- else if(aa.sequenceRef.getDatasetSequence()==null) {
+ else if (aa.sequenceRef.getDatasetSequence() == null)
+ {
return null;
}
- Vector<PDBEntry> pdbEntries = aa.sequenceRef.getDatasetSequence().getAllPDBEntries();
-
- for (PDBEntry entry : pdbEntries){
-
- String entryProvider = entry.getProvider();
- if(entryProvider == null) {
- entryProvider = "PDB";
- }
-
- // Trim the string from first occurrence of colon
- String entryID = entry.getId();
- int index = entryID.indexOf(':');
-
- // Check if colon exists
- if (index != -1) {
-
- // Trim the string from first occurrence of colon
- entryID = entryID.substring(0, index);
-
- }
-
- if(entryProvider == "PDB" && aa.description.toLowerCase().contains
- ("secondary structure for " + entryID.toLowerCase())){
-
- return entryProvider;
-
- }
-
- else if (entryProvider != "PDB" && aa.description.toLowerCase().contains(entryID.toLowerCase())){
-
- return entryProvider;
-
- }
-
+ Vector<PDBEntry> pdbEntries = aa.sequenceRef.getDatasetSequence()
+ .getAllPDBEntries();
+
+ for (PDBEntry entry : pdbEntries)
+ {
+
+ String entryProvider = entry.getProvider();
+ if (entryProvider == null)
+ {
+ entryProvider = "PDB";
+ }
+
+ // Trim the string from first occurrence of colon
+ String entryID = entry.getId();
+ int index = entryID.indexOf(':');
+
+ // Check if colon exists
+ if (index != -1)
+ {
+
+ // Trim the string from first occurrence of colon
+ entryID = entryID.substring(0, index);
+
+ }
+
+ if (entryProvider == "PDB" && aa.description.toLowerCase()
+ .contains("secondary structure for "
+ + entryID.toLowerCase()))
+ {
+
+ return entryProvider;
+
+ }
+
+ else if (entryProvider != "PDB" && aa.description.toLowerCase()
+ .contains(entryID.toLowerCase()))
+ {
+
+ return entryProvider;
+
}
-
- }
+
+ }
}
-
+ }
+
return null;
-
+
}
//to do set priority for labels
- public static AlignmentAnnotation getDisplayedAlignmentAnnotation(SequenceI seq){
-
- for(String ssLabel : Constants.SECONDARY_STRUCTURE_LABELS.keySet()) {
-
- AlignmentAnnotation[] aa = seq.getAnnotation(ssLabel);
- if(aa!=null) {
-
- for (AlignmentAnnotation annot: aa) {
- if(annot.visible) {
- return annot;
+ public static List<AlignmentAnnotation> getAlignmentAnnotationForSource(
+ SequenceI seq, String ssSource)
+ {
+
+ List<AlignmentAnnotation> ssAnnots = new ArrayList<AlignmentAnnotation>();
+ for (String ssLabel : Constants.SECONDARY_STRUCTURE_LABELS.keySet())
+ {
+
+ AlignmentAnnotation[] aa = seq.getAnnotation(ssLabel);
+ if (aa != null)
+ {
+
+ if (ssSource.equals(MessageManager.getString("option.ss_providers_all")))
+ {
+ ssAnnots.addAll(Arrays.asList(aa));
+ continue;
+ }
+
+ for (AlignmentAnnotation annot : aa)
+ {
+
+ if (ssSource
+ .equals(extractSSSourceFromAnnotationDescription(annot)))
+ {
+ ssAnnots.add(annot);
+ }
}
}
- }
}
-
+ if (ssAnnots.size() > 0)
+ {
+ return ssAnnots;
+ }
+
return null;
-
+
+ }
+
+ public static Map<SequenceI, ArrayList<AlignmentAnnotation>> getSequenceAssociatedAlignmentAnnotations(
+ AlignmentAnnotation[] alignAnnotList, String selectedSSSource)
+ {
+
+ Map<SequenceI, ArrayList<AlignmentAnnotation>> ssAlignmentAnnotationForSequences
+ = new HashMap<SequenceI, ArrayList<AlignmentAnnotation>>();
+ if (alignAnnotList == null || alignAnnotList.length == 0)
+ {
+ return ssAlignmentAnnotationForSequences;
+ }
+
+ for (AlignmentAnnotation aa : alignAnnotList)
+ {
+ if (aa.sequenceRef == null)
+ {
+ continue;
+ }
+
+ for (String label : Constants.SECONDARY_STRUCTURE_LABELS.keySet())
+ {
+
+ if (label.equals(aa.label))
+ {
+
+ if (selectedSSSource.equals(MessageManager.getString("option.ss_providers_all")))
+ {
+ ssAlignmentAnnotationForSequences
+ .computeIfAbsent(aa.sequenceRef.getDatasetSequence(),
+ k -> new ArrayList<>())
+ .add(aa);
+ break;
+ }
+
+ String ssSource = AlignmentUtils
+ .extractSSSourceFromAnnotationDescription(aa);
+ if (ssSource.equals(selectedSSSource))
+ {
+
+ ssAlignmentAnnotationForSequences
+ .computeIfAbsent(aa.sequenceRef.getDatasetSequence(),
+ k -> new ArrayList<>())
+ .add(aa);
+ break;
+ }
+ }
+ }
+ }
+
+ return ssAlignmentAnnotationForSequences;
+
}
}
import jalview.api.analysis.SimilarityParamsI;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentView;
-import jalview.datamodel.Annotation;
import jalview.datamodel.SeqCigar;
+import jalview.datamodel.SequenceI;
import jalview.math.Matrix;
import jalview.math.MatrixI;
-import jalview.util.Constants;
-import jalview.util.SetUtils;
+import jalview.util.MessageManager;
-import java.util.HashMap;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
SeqCigar[] seqs = seqData.getSequences();
int noseqs = seqs.length; //no of sequences
- int cpwidth = 0; // = seqData.getWidth();
+ int cpwidth = 0;
double[][] similarities = new double[noseqs][noseqs]; //matrix to store similarity score
//secondary structure source parameter selected by the user from the drop down.
String ssSource = params.getSecondaryStructureSource();
- ssRateMatrix = ScoreModels.getInstance().getSecondaryStructureMatrix();
-
- //defining the default value for secondary structure source as 3d structures
- //or JPred if user selected JPred
- String selectedSSSource = Constants.SS_ANNOTATION_LABEL;
- if(ssSource.equals(Constants.SECONDARY_STRUCTURE_LABELS.get(Constants.SS_ANNOTATION_FROM_JPRED_LABEL)))
- {
- selectedSSSource = Constants.SS_ANNOTATION_FROM_JPRED_LABEL;
+ if(ssSource == null || ssSource == "") {
+ ssSource = MessageManager.getString("option.ss_providers_all");
}
+ ssRateMatrix = ScoreModels.getInstance().getSecondaryStructureMatrix();
// need to get real position for view position
int[] viscont = seqData.getVisibleContigs();
- /*
- * Add secondary structure annotations that are added to the annotation track
- * to the map
- */
- Map<String, HashSet<String>> ssAlignmentAnnotationForSequences
- = new HashMap<String,HashSet<String>>();
AlignmentAnnotation[] alignAnnotList = fr.getViewport().getAlignment()
.getAlignmentAnnotation();
- if(alignAnnotList.length > 0) {
- for (AlignmentAnnotation aa: alignAnnotList) {
- if (selectedSSSource.equals(aa.label)) {
- ssAlignmentAnnotationForSequences.computeIfAbsent(
- aa.sequenceRef.getName(), k -> new HashSet<>())
- .add(aa.description);
- }
- }
- }
-
+
/*
- * Get the set of sequences which are not considered for the calculation.
- * Following sequences are added:
- * 1. Sequences without a defined secondary structure from the selected
- * source.
- * 2. Sequences whose secondary structure annotations are not added to
- * the annotation track
+ * Add secondary structure annotations that are added to the annotation track
+ * to the map
*/
- Set<SeqCigar> seqsWithUndefinedSS
- = findSeqsWithUndefinedSS(seqs, ssAlignmentAnnotationForSequences);
+ Map<SequenceI, ArrayList<AlignmentAnnotation>> ssAlignmentAnnotationForSequences
+ = AlignmentUtils.getSequenceAssociatedAlignmentAnnotations(alignAnnotList, ssSource);
/*
* scan each column, compute and add to each similarity[i, j]
//Iterates for each sequences
for (int j = i + 1; j < noseqs; j++)
{
- SeqCigar sc1 = seqs[i];
- SeqCigar sc2 = seqs[j];
-
//check if ss is defined
- boolean undefinedSS1 = seqsWithUndefinedSS.contains(sc1);
- boolean undefinedSS2 = seqsWithUndefinedSS.contains(sc2);
+ boolean undefinedSS1 = ssAlignmentAnnotationForSequences.get(seqs[i].getRefSeq()) == null;
+ boolean undefinedSS2 = ssAlignmentAnnotationForSequences.get(seqs[j].getRefSeq()) == null;
// Set similarity to max score if both SS are not defined
if (undefinedSS1 && undefinedSS2) {
}
//check if the sequence contains gap in the current column
- boolean gap1 = !seqsWithoutGapAtCol.contains(sc1);
- boolean gap2 = !seqsWithoutGapAtCol.contains(sc2);
+ boolean gap1 = !seqsWithoutGapAtCol.contains(seqs[i]);
+ boolean gap2 = !seqsWithoutGapAtCol.contains(seqs[j]);
//Variable to store secondary structure at the current column
char ss1 = '*';
//corresponding secondary structure annotation
//TO DO - consider based on priority and displayed
int seqPosition = seqs[i].findPosition(cpos);
- AlignmentAnnotation[] aa = seqs[i].getRefSeq().getAnnotation(selectedSSSource);
+ AlignmentAnnotation aa = ssAlignmentAnnotationForSequences.get(seqs[i].getRefSeq()).get(0);
if(aa!=null)
ss1 =
- AlignmentUtils.findSSAnnotationForGivenSeqposition(aa[0], seqPosition);
+ AlignmentUtils.findSSAnnotationForGivenSeqposition(aa, seqPosition);
}
if(!gap2 && !undefinedSS2) {
int seqPosition = seqs[j].findPosition(cpos);
- AlignmentAnnotation[] aa = seqs[j].getRefSeq().getAnnotation(selectedSSSource);
+ AlignmentAnnotation aa = ssAlignmentAnnotationForSequences.get(seqs[j].getRefSeq()).get(0);
if(aa!=null)
ss2 =
- AlignmentUtils.findSSAnnotationForGivenSeqposition(aa[0], seqPosition);
+ AlignmentUtils.findSSAnnotationForGivenSeqposition(aa, seqPosition);
}
if ((!gap1 && !gap2) || params.includeGaps())
return seqsWithoutGapAtCol;
}
-
- /**
- * Builds and returns a set containing sequences (SeqCigar) which
- * are not considered for the similarity calculation.
- * Following sequences are added:
- * 1. Sequences without a defined secondary structure from the selected
- * source.
- * 2. Sequences whose secondary structure annotations are not added to
- * the annotation track
- * @param seqs
- * @param ssAlignmentAnnotationForSequences
- * @return
- */
- private Set<SeqCigar> findSeqsWithUndefinedSS(SeqCigar[] seqs,
- Map<String, HashSet<String>> ssAlignmentAnnotationForSequences) {
- Set<SeqCigar> seqsWithUndefinedSS = new HashSet<>();
- for (SeqCigar seq : seqs) {
- if (isSSUndefinedOrNotAdded(seq, ssAlignmentAnnotationForSequences)) {
- seqsWithUndefinedSS.add(seq);
- }
- }
- return seqsWithUndefinedSS;
- }
-
-
- /**
- * Returns true if a sequence (SeqCigar) should not be
- * considered for the similarity calculation.
- * Following conditions are checked:
- * 1. Sequence without a defined secondary structure from the selected
- * source.
- * 2. Sequences whose secondary structure annotations are not added to
- * the annotation track
- * @param seq
- * @param ssAlignmentAnnotationForSequences
- * @return
- */
- private boolean isSSUndefinedOrNotAdded(SeqCigar seq,
- Map<String, HashSet<String>> ssAlignmentAnnotationForSequences) {
- for (String label : Constants.SECONDARY_STRUCTURE_LABELS.keySet()) {
- AlignmentAnnotation[] annotations = seq.getRefSeq().getAnnotation(label);
- if (annotations != null) {
- for (AlignmentAnnotation annotation : annotations) {
- HashSet<String> descriptionSet = ssAlignmentAnnotationForSequences
- .get(annotation.sequenceRef.getName());
- if (descriptionSet != null)
- {
- if (descriptionSet.contains(annotation.description)) {
- // Secondary structure annotation is present and
- //added to the track, no need to add seq
- return false;
- }
- }
- }
- }
- }
- // Either annotations are undefined or not added to the track
- return true;
- }
@Override
public String getName()
*/
boolean copyHighlightedRegionsToClipboard();
+ /**
+ * Justify alignment or currently selected region left or right
+ * @param left - true - means justify left
+ * @return
+ */
+ boolean justify_Region(boolean left);
}
*/
package jalview.api;
+import java.awt.Color;
+import java.awt.Font;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
import jalview.analysis.Conservation;
import jalview.analysis.TreeModel;
import jalview.datamodel.AlignmentAnnotation;
import jalview.schemes.ColourSchemeI;
import jalview.viewmodel.ViewportRanges;
-import java.awt.Color;
-import java.awt.Font;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
/**
* @author jimp
*
*/
AlignmentAnnotation getAlignmentConsensusAnnotation();
- AlignmentAnnotation getAlignmentSecondaryStructureConsensusAnnotation();
+ List<AlignmentAnnotation> getAlignmentSecondaryStructureConsensusAnnotation();
/**
*/
void setSequenceConsensusHash(ProfilesI hconsensus);
- void setSequenceSSConsensusHash(ProfilesI hSSConsensus);
+ void setSequenceSSConsensusHash(Map<String, ProfilesI> hSSConsesnusProfileMap);
/**
* @return
*/
Iterator<int[]> 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();
+ Map<String, ProfilesI> getSequenceSSConsensusHash();
+
+ List<String> getSecondaryStructureSources();
+
+ void setSecondaryStructureSources(List<String> secondaryStructureSources);
}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.commands;
+
+import java.util.List;
+
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.ContiguousI;
+import jalview.datamodel.SequenceI;
+import jalview.util.Comparison;
+
+public class JustifyLeftOrRightCommand extends EditCommand
+{
+ /**
+ * Constructs and performs a trim alignment command
+ *
+ * @param description
+ * (to show in Undo/Redo menu)
+ * @param justifyLeft
+ * if true left justify, otherwise right
+ * @param seqs
+ * the sequences to justify
+ * @param start
+ * - leftmost column (base 0) to justify
+ *
+ * @param end
+ * - rightmost column (base 0) to justify
+ *
+ * @param al
+ */
+ public JustifyLeftOrRightCommand(String description, boolean left,
+ List<SequenceI> seqs, int from, int to, AlignmentI al)
+ {
+ this.description = description;
+
+ for (SequenceI seq : seqs)
+ {
+ ContiguousI cont = seq.findPositions(from + 1, to + 1);
+ if (cont == null)
+ {
+ continue;
+ }
+ char[] range = seq.getSequence(from, to+1);
+ if (range==null || range.length==0)
+ {
+ continue;
+ }
+ int dsstart = seq.getDatasetSequence().getStart();
+ char[] sqchar = seq.getDatasetSequence().getSequence(
+ -dsstart + cont.getBegin(), -dsstart + cont.getEnd() + 1);
+ // debug
+ // println sqchar;
+ char[] alseq = new char[to - from + 1];
+ int sqstart = left ? 0 : alseq.length - sqchar.length;
+ int gaps = alseq.length - sqchar.length;
+ int gapstart = left ? sqchar.length : 0;
+ char gc = al.getGapCharacter();
+ for (int gp = 0; gp < gaps; gp++)
+ {
+ alseq[gapstart + gp] = gc;
+ }
+
+ for (int sqp = 0,insp=0; sqp<alseq.length; sqp++)
+ {
+ if (sqp < range.length && !Comparison.isGap(range[sqp]))
+ {
+ alseq[insp++ + sqstart] = range[sqp];
+ }
+ }
+ SequenceI[] sqa = new SequenceI[1];
+ sqa[0] = seq;
+
+ addEdit(new jalview.commands.EditCommand.Edit(
+ jalview.commands.EditCommand.Action.REPLACE, sqa, from,
+ to + 1, al, new String(alseq)));
+ }
+
+ performEdit(0, null);
+ }
+}
// Technically we should return false, since view has not changed
return false;
}
+
+ @Override
+ public boolean justify_Region(boolean left)
+ {
+ AlignmentI al = viewport.getAlignment();
+ SequenceGroup reg = viewport.getSelectionGroup();
+ int from, to;
+ List<SequenceI> seqs;
+
+ from = 0;
+ to = al.getWidth() - 1;
+ seqs = al.getSequences();
+ if (reg != null)
+ {
+ seqs = reg.getSequences();
+ from = reg.getStartRes();
+ to = reg.getEndRes();
+ }
+
+ if ((to - from) < 1)
+ {
+ return false;
+ }
+
+ al.padGaps();
+ jalview.commands.JustifyLeftOrRightCommand finalEdit = new jalview.commands.JustifyLeftOrRightCommand(
+ "Justify " + (left ? "Left" : "Right"), left, seqs, from, to,
+ al);
+ avcg.addHistoryItem(finalEdit);
+ viewport.notifyAlignmentChanged();
+ return true;
+ }
}
public Hashtable alignmentProperties;
private List<AlignedCodonFrame> codonFrameList;
+
+ private List<String> secondaryStructureSources;
private void initAlignment(SequenceI[] seqs)
{
nucleotide = Comparison.isNucleotide(seqs);
sequences = Collections.synchronizedList(new ArrayList<SequenceI>());
+
for (int i = 0; i < seqs.length; i++)
{
sequences.add(seqs[i]);
}
-
+
}
/**
cmholder.addContactListFor(annotation, cm);
}
+
+ public List<String> getSecondaryStructureSources()
+ {
+ return secondaryStructureSources;
+ }
+
+ public void setSecondaryStructureSources(
+ List<String> secondaryStructureSources)
+ {
+ this.secondaryStructureSources = secondaryStructureSources;
+ }
+
}
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import jalview.renderer.ResidueShader;
import jalview.renderer.ResidueShaderI;
import jalview.schemes.ColourSchemeI;
+import jalview.util.MessageManager;
/**
* Collects a set contiguous ranges on a set of sequences
AlignmentAnnotation consensus = null;
- AlignmentAnnotation ssConsensus = null;
+ List<AlignmentAnnotation> ssConsensus = null;
AlignmentAnnotation conservation = null;
cs.setConsensus(cnsns);
upd = true;
}
+
+ Map<String, ProfilesI> hSSConsensusProfileMap = new HashMap<String, ProfilesI>();
+ List <String> ssSources = new ArrayList<String>();
-
- ProfilesI ssCnsns = AAFrequency.calculateSS(sequences, startRes,
- endRes + 1, showSequenceLogo);
+ //ssSources = AlignmentUtils.extractSSSourceInAlignmentAnnotation(ssConsensus.toArray());
+ if(ssSources != null) {
+ ssSources.add(MessageManager.getString("option.ss_providers_all"));
+
+ for(String ssSource : ssSources) {
+ ProfilesI hSSConsensus = AAFrequency.calculateSS(sequences, startRes, endRes + 1, showSequenceLogo,
+ ssSource);
+ hSSConsensusProfileMap.put(ssSource, hSSConsensus);
+ }
+ }
+
+
if (ssConsensus != null)
{
- _updateSSConsensusRow(ssCnsns, sequences.size());
+ _updateSSConsensusRow(hSSConsensusProfileMap, sequences.size());
upd = true;
}
+
if (cs != null)
{
- cs.setSsConsensus(ssCnsns);
+ cs.setSSConsensusProfileMap(hSSConsensusProfileMap);
upd = true;
}
public ProfilesI ssConsensusData = null;
- private void _updateSSConsensusRow(ProfilesI ssCnsns, long nseq)
+ private void _updateSSConsensusRow(Map<String, ProfilesI> hSSConsensusProfileMap, long nseq)
{
+ List<String> ssSources = new ArrayList<>(hSSConsensusProfileMap.keySet());
+
+ Collections.sort(ssSources);
if (ssConsensus == null)
{
- getSSConsensus();
+ getSSConsensus(ssSources);
}
- ssConsensus.label = "Sec Str Consensus for " + getName();
- ssConsensus.description = "Percent Identity";
- ssConsensusData = ssCnsns;
- // preserve width if already set
- int aWidth = (ssConsensus.annotations != null)
- ? (endRes < ssConsensus.annotations.length
- ? ssConsensus.annotations.length
- : endRes + 1)
- : endRes + 1;
- ssConsensus.annotations = null;
- ssConsensus.annotations = new Annotation[aWidth]; // should be alignment width
+ for (AlignmentAnnotation aa : ssConsensus) {
+ ProfilesI profile = null;
+ String ssSource = null;
+ for(String source : ssSources) {
+ if(aa.description.startsWith(source)) {
+ profile = hSSConsensusProfileMap.get(source);
+ ssSource = source;
+ }
+ }
+ if(profile == null) {
+ continue;
+ }
- AAFrequency.completeSSConsensus(ssConsensus, ssCnsns, startRes, endRes + 1,
+ aa.label = MessageManager.getString("label.ssconsensus_label") + " " + ssSource + " " + getName();
+ aa.description = ssSource + MessageManager.getString("label.ssconsensus_label") +" for " + getName();
+ ssConsensusData = profile;
+ // preserve width if already set
+ int aWidth = (aa.annotations != null)
+ ? (endRes < aa.annotations.length
+ ? aa.annotations.length
+ : endRes + 1)
+ : endRes + 1;
+ aa.annotations = null;
+ aa.annotations = new Annotation[aWidth]; // should be alignment width
+
+ AAFrequency.completeSSConsensus(aa, profile, startRes, endRes + 1,
ignoreGapsInConsensus, showSequenceLogo, nseq); // TODO: setting
// container
+ }
// for
// ignoreGapsInConsensusCalculation);
}
return consensus;
}
- public AlignmentAnnotation getSSConsensus()
+ public List<AlignmentAnnotation> getSSConsensus(List<String> ssSources)
{
// TODO get or calculate and get consensus annotation row for this group
int aWidth = this.getWidth();
}
if (ssConsensus == null)
{
- ssConsensus = new AlignmentAnnotation("", "", new Annotation[1], 0f,
- 100f, AlignmentAnnotation.BAR_GRAPH);
- ssConsensus.hasText = true;
- ssConsensus.autoCalculated = true;
- ssConsensus.groupRef = this;
- ssConsensus.label = "Sec Str Consensus for " + getName();
- ssConsensus.description = "Percent Identity";
+ ssConsensus = new ArrayList<AlignmentAnnotation>();
+
+ for(String ssSource : ssSources) {
+ AlignmentAnnotation aa = new AlignmentAnnotation("", "", new Annotation[1], 0f,
+ 100f, AlignmentAnnotation.BAR_GRAPH);
+ aa.hasText = true;
+ aa.autoCalculated = true;
+ aa.groupRef = this;
+
+ aa.label = MessageManager.getString("label.ssconsensus_label") + " " + ssSource + " " + getName();
+ aa.description = ssSource + MessageManager.getString("label.ssconsensus_label") +" for " + getName();
+ ssConsensus.add(aa);
+ }
+
}
return ssConsensus;
}
import java.util.Arrays;
import java.util.Deque;
import java.util.Enumeration;
+import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.Vector;
-import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;
-import javax.swing.ButtonModel;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JEditorPane;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
-import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import jalview.analysis.GeneticCodeI;
import jalview.analysis.ParseProperties;
import jalview.analysis.SequenceIdMatcher;
-import jalview.api.AlignCalcWorkerI;
import jalview.api.AlignExportSettingsI;
import jalview.api.AlignViewControllerGuiI;
import jalview.api.AlignViewControllerI;
import jalview.util.imagemaker.BitmapImageSizing;
import jalview.viewmodel.AlignmentViewport;
import jalview.viewmodel.ViewportRanges;
-import jalview.workers.SecondaryStructureConsensusThread;
import jalview.ws.DBRefFetcher;
import jalview.ws.DBRefFetcher.FetchFinishedListenerI;
import jalview.ws.jws1.Discoverer;
@Override
protected void justifyLeftMenuItem_actionPerformed(ActionEvent e)
{
- AlignmentI al = viewport.getAlignment();
- al.justify(false);
- viewport.firePropertyChange("alignment", null, al);
+ avc.justify_Region(true);
}
/**
@Override
protected void justifyRightMenuItem_actionPerformed(ActionEvent e)
{
- AlignmentI al = viewport.getAlignment();
- al.justify(true);
- viewport.firePropertyChange("alignment", null, al);
+ avc.justify_Region(false);
}
@Override
}
@Override
- protected void updateShowSSRadioButtons(JMenu showSS, ButtonGroup ssButtonGroup){
+ protected void updateShowSecondaryStructureMenu(JMenu showSS, ButtonGroup ssButtonGroup){
List<String> ssSources = new ArrayList<String>();
AlignmentAnnotation[] anns = alignPanel.getAlignment()
.getAlignmentAnnotation();
+ Map<String, JCheckBoxMenuItem> checkboxMap = getCheckboxesInMenu(showSS);
ssSources = AlignmentUtils.extractSSSourceInAlignmentAnnotation(anns);
- // Get the currently selected radio button
- String selectedButtonModelName = getSelectedRadioButtonDisplayString(ssButtonGroup);
- boolean selectedButtonModel = false;
+ List<String> selectedCheckBoxes = getSelectedOptions(checkboxMap);
- // Clear existing radio buttons
- showSS.removeAll();
- JRadioButtonMenuItem radioButtonAllSS = new JRadioButtonMenuItem("All");
- radioButtonAllSS.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- showSS_actionPerformed("All");
- }
- });
- ssButtonGroup.add(radioButtonAllSS);
- showSS.add(radioButtonAllSS);
-
- JRadioButtonMenuItem radioButtonNoneSS = new JRadioButtonMenuItem("None");
- radioButtonNoneSS.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- showSS_actionPerformed("None");
+ // Add checkboxes for categories
+ for (String ssSource : ssSources) {
+
+ if(checkboxMap.get(ssSource)== null) {
+ JCheckBoxMenuItem checkBox = new JCheckBoxMenuItem(ssSource);
+ checkBox.setSelected(false);
+
+ checkBox.addItemListener(e -> {
+ if (e.getStateChange() == ItemEvent.SELECTED) {
+
+ showOrHideSecondaryStructureForSource(ssSource, true);
+
+ } else {
+
+ showOrHideSecondaryStructureForSource(ssSource, false);
+
+ }
+ });
+ showSS.add(checkBox);
}
- });
- ssButtonGroup.add(radioButtonNoneSS);
- showSS.add(radioButtonNoneSS);
- showSS.addSeparator();
+ }
+ // Iterate over the keys of checkboxMap
+ for (String key : checkboxMap.keySet()) {
+ // Check if the key is not in ssSources
+ if (!ssSources.contains(key)) {
+ showSS.remove(checkboxMap.get(key));
+ checkboxMap.remove(key);
+ selectedCheckBoxes.remove(key);
+ }
+ if(selectedCheckBoxes.contains(key)){
+ checkboxMap.get(key).setSelected(true);
+ }
+ else {
+ checkboxMap.get(key).setSelected(false);
+ }
- for(String ssSource : ssSources) {
-
- JRadioButtonMenuItem radioButton = new JRadioButtonMenuItem(ssSource);
- radioButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- showSS_actionPerformed(ssSource);
- }
- });
- ssButtonGroup.add(radioButton);
- showSS.add(radioButton);
-
- // Check if this radio button's name matches the selected radio button's name
- if (ssSource.equals(selectedButtonModelName)) {
- radioButton.setSelected(true); // Select this radio button
- selectedButtonModel = true;
+ ssButtonGroup.clearSelection();
+ }
+
+ }
+
+ private List<String> getSelectedOptions(Map<String, JCheckBoxMenuItem> checkboxMap) {
+ List<String> selectedOptions = new ArrayList<>();
+ for (String key : checkboxMap.keySet()) {
+ JCheckBoxMenuItem checkbox = checkboxMap.get(key);
+ if (checkbox.isSelected()) {
+ selectedOptions.add(key);
}
-
- }
-
- if (selectedButtonModelName == "None") {
- // If no radio button was previously selected, select "All"
- ssButtonGroup.setSelected(radioButtonNoneSS.getModel(), true);
- selectedButtonModel = true;
- }
- if (!selectedButtonModel) {
- // If no radio button was previously selected, select "All"
- ssButtonGroup.setSelected(radioButtonAllSS.getModel(), true);
- }
+ }
+ return selectedOptions;
}
+ private Map<String, JCheckBoxMenuItem> getCheckboxesInMenu(JMenu menu) {
+ Map<String, JCheckBoxMenuItem> checkboxMap = new HashMap<>();
+ for (Component component : menu.getMenuComponents()) {
+ if (component instanceof JCheckBoxMenuItem) {
+ JCheckBoxMenuItem checkbox = (JCheckBoxMenuItem) component;
+ checkboxMap.put(checkbox.getText(), checkbox);
+ }
+ }
+ return checkboxMap;
+}
+
@Override
- protected void showSS_actionPerformed(String ssSourceSelection){
+ protected void showOrHideSecondaryStructureForSource(String ssSourceSelection, boolean visible){
+
+ String noneOption = MessageManager.getString("option.ss_providers_none");
+ String allOption = MessageManager.getString("option.ss_providers_all");
-
AlignmentAnnotation[] annotations = alignPanel.getAlignment()
.getAlignmentAnnotation();
for (AlignmentAnnotation aa: annotations) {
+ boolean isSSConsensus = aa.label.startsWith(MessageManager.getString("label.ssconsensus_label"));
+ boolean matchesSSSourceSelection = aa.description.startsWith(ssSourceSelection);
+
+ if(isSSConsensus && (matchesSSSourceSelection || ssSourceSelection.equals(noneOption))) {
+
+ if (ssSourceSelection.equals(allOption)) {
+ aa.visible = true;
+ break;
+ }
+
+ if(!aa.description.startsWith(allOption))
+ aa.visible = visible;
+
+ }
+
for (String label : Constants.SECONDARY_STRUCTURE_LABELS.keySet()) {
if (label.equals(aa.label)) {
-
- aa.visible = false;
-
- if(ssSourceSelection == "All") {
- aa.visible = true;
- }
-
- else {
+
String ssSource = AlignmentUtils.extractSSSourceFromAnnotationDescription(aa);
- if(ssSource.equals(ssSourceSelection)) {
- aa.visible = true;
- }
-
-
- }
+ if(ssSource.equals(ssSourceSelection) || ssSourceSelection.equals(noneOption)) {
+ aa.visible = visible;
+ }
}
}
}
-
- List<AlignCalcWorkerI> workers = viewport.getCalcManager()
- .getRegisteredWorkersOfClass(SecondaryStructureConsensusThread.class);
- if (!workers.isEmpty()) {
-
- viewport.getCalcManager().startWorker(workers.remove(0));
-
- }
-
PaintRefresher.Refresh(this, viewport.getSequenceSetId());
alignPanel.updateAnnotation();
alignPanel.paintAlignment(true, true);
-
-
}
-
- protected String getSelectedRadioButtonDisplayString(ButtonGroup ssButtonGroup) {
- Enumeration<AbstractButton> buttons = ssButtonGroup.getElements();
- while (buttons.hasMoreElements()) {
- AbstractButton button = buttons.nextElement();
- if (button.isSelected()) {
- return button.getText();
- }
- }
- return null; // No radio button is selected
-}
+
/*
* (non-Javadoc)
if (residueShading != null)
{
residueShading.setConsensus(hconsensus);
- residueShading.setSsConsensus(hSSConsensus);
+ residueShading.setSSConsensusProfileMap(hSSConsensusProfileMap);
}
setColourAppliesToAllGroups(true);
}
}
this.add(actionPanel, BorderLayout.SOUTH);
- int width = 365;
+ int width = 375;
int height = includeParams ? 420 : 240;
setMinimumSize(new Dimension(325, height - 10));
final JComboBox<String> comboBox = new JComboBox<>();
Object curSel = comboBox.getSelectedItem();
DefaultComboBoxModel<String> sourcesModel = new DefaultComboBoxModel<>();
-
+
List<String> ssSources = getApplicableSecondaryStructureSources();
+
+ if(ssSources == null) {
+ return comboBox;
+ }
+ ssSources.add(0, MessageManager.getString("option.ss_providers_all"));
boolean selectedIsPresent = false;
for (String source : ssSources)
{
AlignmentAnnotation[] annotations = af.getViewport().getAlignment().getAlignmentAnnotation();
- List<String> ssSources = AlignmentUtils.getSecondaryStructureSources(annotations);
- //List<String> ssSources = AlignmentUtils.extractSSSourceInAlignmentAnnotation(annotations);
+ //List<String> ssSources = AlignmentUtils.getSecondaryStructureSources(annotations);
+ List<String> ssSources = AlignmentUtils.extractSSSourceInAlignmentAnnotation(annotations);
return ssSources;
{
boolean doPCA = pca.isSelected();
String modelName = modelNames.getSelectedItem().toString();
- String ssSource = "";
- Object selectedItem = ssSourceDropdown.getSelectedItem();
- if (selectedItem != null) {
- ssSource = selectedItem.toString();
+
+ String ssSource = null;
+
+ if (modelName.equals(secondaryStructureModelName)) {
+ Object selectedItem = ssSourceDropdown.getSelectedItem();
+ if (selectedItem != null) {
+ ssSource = selectedItem.toString();
+ }
}
SimilarityParams params = getSimilarityParameters(doPCA);
- if(ssSource.length()>0)
- {
- params.setSecondaryStructureSource(ssSource);
- }
+ params.setSecondaryStructureSource(ssSource);
+
if (doPCA)
{
openPcaPanel(modelName, params);
import java.awt.print.PrinterJob;
import javax.swing.ButtonGroup;
+import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JRadioButtonMenuItem;
+import javax.swing.SwingConstants;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
PaintRefresher.Register(this, av.getSequenceSetId());
setRotatableCanvas(new RotatableCanvas(alignPanel));
+
+ if(params.getSecondaryStructureSource()!=null ) {
+ // Initialize and set subtitle text
+ JLabel subtitleLabel = new JLabel(" Secondary Structure Provider : "
+ + params.getSecondaryStructureSource(), SwingConstants.LEFT);
+ this.getContentPane().add(subtitleLabel, BorderLayout.NORTH);
+
+ }
this.getContentPane().add(getRotatableCanvas(), BorderLayout.CENTER);
addKeyListener(getRotatableCanvas());
cut_actionPerformed();
}
});
+ JMenuItem justifyLeftMenuItem = new JMenuItem(
+ MessageManager.getString("action.left_justify"));
+ justifyLeftMenuItem.addActionListener(new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ ap.alignFrame.avc.justify_Region(true);
+ }
+ });
+ JMenuItem justifyRightMenuItem = new JMenuItem(
+ MessageManager.getString("action.right_justify"));
+ justifyRightMenuItem.addActionListener(new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ ap.alignFrame.avc.justify_Region(false);
+ }
+ });
+
upperCase.setText(MessageManager.getString("label.to_upper_case"));
upperCase.addActionListener(new ActionListener()
{
editMenu.add(copy);
editMenu.add(cut);
+ editMenu.add(justifyLeftMenuItem);
+ editMenu.add(justifyRightMenuItem);
editMenu.add(editSequence);
editMenu.add(upperCase);
editMenu.add(lowerCase);
AlignmentUtils.addReferenceAnnotations(candidates, alignment, null);
if(AlignmentUtils.isSSAnnotationPresent(candidates)) {
+
restartSSConsensusWorker();
+ ap.validateAnnotationDimensions(true);
+ ap.fontChanged();
+ ap.av.alignmentChanged(ap);
+ ap.adjustAnnotationHeight();
+ restartSSConsensusWorker();
+ //ap.alignFrame.getViewport().getCalcManager().restartWorkers();
}
- refresh();
}
selectedSequence = userSelectedSeq;
}
String pdbFilename = selectedPdbFileName;
-
+ // TODO - tidy up this ugly hack so we call launchStructureViewer too
StructureChooser.openStructureFileForSequence(ssm, sc, ap,
- selectedSequence, true, pdbFilename, tft, paeFilename,
- true);
+ selectedSequence, true, pdbFilename, tft, paeFilename,false,
+ true,false,getTargetedStructureViewer(ssm).getViewerType());
}
SwingUtilities.invokeLater(new Runnable()
{
paeFilename, false, true, doXferSettings, null);
}
+ /**
+ *
+ * @param ssm
+ * @param sc
+ * @param ap
+ * @param seq
+ * @param prompt
+ * @param sFilename
+ * @param tft
+ * @param paeFilename
+ * @param forceHeadless
+ * @param showRefAnnotations
+ * @param doXferSettings
+ * @param viewerType - when not null means the viewer will be opened, providing forceHeadless/headless is not true
+ * @return
+ */
public static StructureViewer openStructureFileForSequence(
StructureSelectionManager ssm, StructureChooser sc,
AlignmentPanel ap, SequenceI seq, boolean prompt,
ssm = ap.getStructureSelectionManager();
StructureSelectionManager.doConfigureStructurePrefs(ssm);
}
-
+
PDBEntry fileEntry = new AssociatePdbFileWithSeq().associatePdbWithSeq(
sFilename, DataSourceType.FILE, seq, prompt, Desktop.instance,
tft, paeFilename, doXferSettings);
sv = sc.launchStructureViewer(ssm, new PDBEntry[] { fileEntry }, ap,
new SequenceI[]
{ seq }, viewerType);
+ // foo
+ sv.getJalviewStructureDisplay().raiseViewer();
}
sc.mainFrame.dispose();
+ // TODO should honor preferences - only show reference annotation that is requested - JAL-4415 JAL-3124
if (showRefAnnotations)
{
showReferenceAnnotationsForSequence(ap.alignFrame, seq);
*/
package jalview.gui;
+import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.util.Locale;
import javax.swing.ButtonGroup;
+import javax.swing.JLabel;
import javax.swing.JMenuItem;
+import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
+import javax.swing.SwingConstants;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
TreeModel tree;
private AlignViewport av;
+
+
+ // New JLabel for subtitle
+ private JLabel subtitleLabel;
/**
* Creates a new TreePanel object.
treeCanvas = new TreeCanvas(this, ap, scrollPane);
scrollPane.setViewportView(treeCanvas);
+
+ if(this.similarityParams!=null)
+ if(this.similarityParams.getSecondaryStructureSource()!=null ) {
+
+ subtitleLabel = new JLabel(" Secondary Structure Provider : "
+ + this.similarityParams.getSecondaryStructureSource(), SwingConstants.LEFT);
+
+ JPanel panel = new JPanel(new BorderLayout());
+ panel.add(subtitleLabel, BorderLayout.NORTH);
+ panel.add(scrollPane, BorderLayout.CENTER);
+
+ this.add(panel);
+ }
if (columnWise)
{
import java.awt.BorderLayout;
import java.awt.Color;
+import java.awt.Component;
import java.awt.GridLayout;
-import java.awt.Menu;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import jalview.analysis.GeneticCodes;
import jalview.api.SplitContainerI;
import jalview.bin.Cache;
-import jalview.bin.Console;
import jalview.gui.JvSwingUtils;
import jalview.gui.Preferences;
import jalview.io.FileFormats;
-import jalview.log.JLoggerLog4j;
import jalview.schemes.ResidueColourScheme;
-import jalview.util.Log4j;
import jalview.util.MessageManager;
import jalview.util.Platform;
protected JMenuItem expandViews = new JMenuItem();
- protected JCheckBoxMenuItem threeDStructure = new JCheckBoxMenuItem();
-
- protected JCheckBoxMenuItem jPred = new JCheckBoxMenuItem();
-
protected JCheckBoxMenuItem showGroupConsensus = new JCheckBoxMenuItem();
protected JCheckBoxMenuItem showGroupConservation = new JCheckBoxMenuItem();
addMenuActionAndAccelerator(keyStroke, removeAllGapsMenuItem, al);
JMenuItem justifyLeftMenuItem = new JMenuItem(
- MessageManager.getString("action.left_justify_alignment"));
+ MessageManager.getString("action.left_justify"));
+ justifyLeftMenuItem.setToolTipText(
+ MessageManager.getString("tooltip.left_justify"));
justifyLeftMenuItem.addActionListener(new ActionListener()
{
@Override
}
});
JMenuItem justifyRightMenuItem = new JMenuItem(
- MessageManager.getString("action.right_justify_alignment"));
+ MessageManager.getString("action.right_justify"));
+ justifyRightMenuItem.setToolTipText(
+ MessageManager.getString("action.left_justify"));
+
justifyRightMenuItem.addActionListener(new ActionListener()
{
@Override
};
addMenuActionAndAccelerator(keyStroke, copyHighlighted, al);
copyHighlighted.addActionListener(al);
-
-
- ButtonGroup ssButtonGroup = new ButtonGroup();
- final JRadioButtonMenuItem showAll = new JRadioButtonMenuItem(
- MessageManager.getString("label.show_first"));
- final JRadioButtonMenuItem showjPred = new JRadioButtonMenuItem(
- MessageManager.getString("label.show_last"));
- final JRadioButtonMenuItem show3DSS = new JRadioButtonMenuItem(
- MessageManager.getString("label.show_last"));
- ssButtonGroup.add(showAll);
- ssButtonGroup.add(showjPred);
- ssButtonGroup.add(show3DSS);
- final boolean autoFirst1 = Cache
- .getDefault(Preferences.SHOW_AUTOCALC_ABOVE, false);
- showAll.setSelected(autoFirst1);
- setShowAutoCalculatedAbove(autoFirst);
- showAutoFirst.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- setShowAutoCalculatedAbove(showAutoFirst.isSelected());
- sortAnnotations_actionPerformed();
- }
- });
- showAutoLast.setSelected(!showAutoFirst.isSelected());
- showAutoLast.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- setShowAutoCalculatedAbove(!showAutoLast.isSelected());
- sortAnnotations_actionPerformed();
- }
- });
+ ButtonGroup ssButtonGroup = new ButtonGroup();
JMenu tooltipSettingsMenu = new JMenu(
MessageManager.getString("label.sequence_id_tooltip"));
JMenu showSS = new JMenu(
MessageManager.getString("label.show_secondary_structure"));
- showSS.addMouseListener(new MouseAdapter() {
+ JRadioButtonMenuItem radioButtonAllSS = new JRadioButtonMenuItem(MessageManager.getString("option.ss_providers_all"));
+ radioButtonAllSS.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ showOrHideSecondaryStructureForSource(MessageManager.getString("option.ss_providers_all"), true);
+ // Select all checkboxes if "All" is selected
+ Component[] components = showSS.getMenuComponents();
+ for (Component component : components) {
+ if (component instanceof JCheckBoxMenuItem) {
+ ((JCheckBoxMenuItem) component).setSelected(true);
+ }
+ }
+ }
+ });
+ ssButtonGroup.add(radioButtonAllSS);
+ showSS.add(radioButtonAllSS);
+
+ JRadioButtonMenuItem radioButtonNoneSS = new JRadioButtonMenuItem(MessageManager.getString("option.ss_providers_none"));
+ radioButtonNoneSS.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ showOrHideSecondaryStructureForSource(MessageManager.getString("option.ss_providers_none"), false);
+ // Remove selection of all checkboxes if "None" is selected
+ Component[] components = showSS.getMenuComponents();
+ for (Component component : components) {
+ if (component instanceof JCheckBoxMenuItem) {
+ ((JCheckBoxMenuItem) component).setSelected(false);
+ }
+ }
+ }
+ });
+ ssButtonGroup.add(radioButtonNoneSS);
+ showSS.add(radioButtonNoneSS);
+ showSS.addSeparator();
+
+ annotationsMenu.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
- updateShowSSRadioButtons(showSS, ssButtonGroup); // Update radio buttons every time the menu is clicked
+ updateShowSecondaryStructureMenu(showSS, ssButtonGroup); // Update radio buttons every time the menu is clicked
}
});
editMenu.add(removeAllGapsMenuItem);
editMenu.add(removeRedundancyMenuItem);
editMenu.addSeparator();
- // dont add these yet in the CVS build - they cannot be undone!
- // Excluded from Jalview 2.5 release - undo needs to be implemented.
- // editMenu.add(justifyLeftMenuItem);
- // editMenu.add(justifyRightMenuItem);
- // editMenu.addSeparator();
+
+ editMenu.add(justifyLeftMenuItem);
+ editMenu.add(justifyRightMenuItem);
+
+ editMenu.addSeparator();
editMenu.add(padGapsMenuitem);
showMenu.add(showAllColumns);
}
- protected void jpred_actionPerformed(ActionEvent e)
- {
- }
-
protected void scaleAbove_actionPerformed(ActionEvent e)
{
}
return null;
}
- protected void updateShowSSRadioButtons(JMenu showSS,
- ButtonGroup ssButtonGroup)
+ protected void showOrHideSecondaryStructureForSource(String ssSourceSelection, boolean visible)
{
// TODO Auto-generated method stub
+
}
- protected void showSS_actionPerformed(String ssSourceSelection)
+ protected void updateShowSecondaryStructureMenu(JMenu showSS,
+ ButtonGroup ssButtonGroup)
{
// TODO Auto-generated method stub
viewport.getResidueShading()
.setConsensus(viewport.getSequenceConsensusHash());
viewport.getResidueShading()
- .setSsConsensus(viewport.getSequenceSSConsensusHash());
+ .setSSConsensusProfileMap(viewport.getSequenceSSConsensusHash());
if (safeBoolean(view.isConservationSelected()) && cs != null)
{
viewport.getResidueShading()
import java.awt.image.ImageObserver;
import java.util.BitSet;
import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
import org.jfree.graphics2d.svg.SVGGraphics2D;
import org.jibble.epsgraphics.EpsGraphics2D;
private ProfilesI hconsensus;
- private ProfilesI hSSconsensus;
+ private Map<String, ProfilesI> hSSconsensus;
private Hashtable<String, Object>[] complementConsensus;
}
}
- else if(aa.autoCalculated && aa.label.startsWith(MessageManager.getString("label.ssconsensus_label")))
+ if(aa.autoCalculated && aa.label.startsWith(MessageManager.getString("label.ssconsensus_label")))
{
- return AAFrequency.extractProfile(
- hSSconsensus.get(column),
- av_ignoreGapsConsensus);
+ if(hSSconsensus!=null) {
+ for (String source : hSSconsensus.keySet()) {
+ if(aa.description.startsWith(source)) {
+
+ return AAFrequency.extractProfile(
+ hSSconsensus.get(source).get(column),
+ av_ignoreGapsConsensus);
+ }
+ }
+ }
}
- else
- {
if (aa.autoCalculated && aa.label.startsWith("StrucConsensus"))
{
// TODO implement group structure consensus
av_ignoreGapsConsensus);
}
}
- }
+
return null;
}
.getAlignmentStrucConsensusAnnotation();
final AlignmentAnnotation complementConsensusAnnot = av
.getComplementConsensusAnnotation();
- final AlignmentAnnotation ssConsensusAnnot = av
+ final List<AlignmentAnnotation> ssConsensusAnnot = av
.getAlignmentSecondaryStructureConsensusAnnotation();
BitSet graphGroupDrawn = new BitSet();
normaliseProfile = row.groupRef.isNormaliseSequenceLogo();
}
else if (row == consensusAnnot || row == structConsensusAnnot
- || row == complementConsensusAnnot || row == ssConsensusAnnot)
+ || row == complementConsensusAnnot || (ssConsensusAnnot!=null && ssConsensusAnnot.contains(row)))
{
renderHistogram = av_renderHistogram;
renderProfile = av_renderProfile;
colour = profcolour.findColour(codonTranslation.charAt(0),
column, null);
}
- if(_aa.label == MessageManager.getString("label.ssconsensus_label")) {
+ if(_aa.label.startsWith(MessageManager.getString("label.ssconsensus_label"))) {
colour = AlignmentUtils.getSecondaryStructureAnnotationColour(dc[0]);
}
else
private ProfilesI consensus;
/*
- * the consensus data for each column
+ * the ss consensus data for each column for each source
*/
- private ProfilesI ssConsensus;
-
- public ProfilesI getSsConsensus()
- {
- return ssConsensus;
- }
-
- public void setSsConsensus(ProfilesI ssConsensus)
- {
- this.ssConsensus = ssConsensus;
- }
+ private Map<String, ProfilesI> ssConsensusProfileMap;
/*
* if true, apply shading of colour by conservation
this.conservationIncrement = rs.conservationIncrement;
this.ignoreGaps = rs.ignoreGaps;
this.pidThreshold = rs.pidThreshold;
- this.ssConsensus = rs.ssConsensus;
+ this.ssConsensusProfileMap = rs.ssConsensusProfileMap;
}
/**
}
@Override
- public Color findSSColour(char symbol, int position, SequenceI seq)
+ public Color findSSColour(char symbol, int position, SequenceI seq, String source)
{
if (colourScheme == null)
{
/*
* get 'base' colour
*/
- ProfileI profile = ssConsensus == null ? null : ssConsensus.get(position);
+ ProfileI profile = ssConsensusProfileMap.get(source) == null ? null : ssConsensusProfileMap.get(source).get(position);
String modalSS = profile == null ? null
: profile.getModalSS();
float pid = profile == null ? 0f
{
colourScheme = cs;
}
+
+ public Map<String, ProfilesI> getSSConsensusProfileMap()
+ {
+ return ssConsensusProfileMap;
+ }
+
+ public void setSSConsensusProfileMap(Map<String, ProfilesI> ssConsensusProfileMap)
+ {
+ this.ssConsensusProfileMap = ssConsensusProfileMap;
+ }
}
public abstract void setConsensus(ProfilesI cons);
- public abstract void setSsConsensus(ProfilesI cons);
+ public abstract void setSSConsensusProfileMap(Map<String, ProfilesI> ssConsensusProfileMap);
public abstract boolean conservationApplied();
public abstract void setColourScheme(ColourSchemeI cs);
- Color findSSColour(char symbol, int position, SequenceI seq);
+ Color findSSColour(char symbol, int position, SequenceI seq,
+ String source);
}
\ No newline at end of file
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.BitSet;
+import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
+import jalview.analysis.AlignmentUtils;
import jalview.analysis.Conservation;
import jalview.analysis.TreeModel;
import jalview.api.AlignCalcManagerI;
protected AlignmentAnnotation consensus;
- protected AlignmentAnnotation secondaryStructureConsensus;
+ protected List<AlignmentAnnotation> secondaryStructureConsensus;
+
+ protected List<String> secondaryStructureSources;
protected AlignmentAnnotation complementConsensus;
*/
protected ProfilesI hconsensus = null;
- protected ProfilesI hSSConsensus = null;
+ protected Map<String, ProfilesI> hSSConsensusProfileMap = null;
{
hconservation = cons;
}
+
+ @Override
+ public List<String> getSecondaryStructureSources()
+ {
+ return secondaryStructureSources;
+ }
+
+ @Override
+ public void setSecondaryStructureSources(
+ List<String> secondaryStructureSources)
+ {
+ this.secondaryStructureSources = secondaryStructureSources;
+ }
+
+ protected void setSecondaryStructureSources(AlignmentAnnotation[] aa)
+ {
+ List<String> sources = null;
+
+ if(aa!=null) {
+ sources = AlignmentUtils.extractSSSourceInAlignmentAnnotation(aa);
+ if(sources != null) {
+ sources.add(0,MessageManager.getString("option.ss_providers_all"));
+ setSecondaryStructureSources(sources);
+ }
+ }
+ }
/**
* percentage gaps allowed in a column before all amino acid properties should
}
@Override
- public void setSequenceSSConsensusHash(ProfilesI hSSConsensus)
+ public void setSequenceSSConsensusHash(Map<String, ProfilesI> hSSConsensusProfileMap)
{
- this.hSSConsensus = hSSConsensus;
+ this.hSSConsensusProfileMap = hSSConsensusProfileMap;
}
-
+
@Override
public void setComplementConsensusHash(
Hashtable<String, Object>[] hconsensus)
{
return hconsensus;
}
-
+
@Override
- public ProfilesI getSequenceSSConsensusHash()
+ public Map<String, ProfilesI> getSequenceSSConsensusHash()
{
- return hSSConsensus;
+ return hSSConsensusProfileMap;
}
+
@Override
public Hashtable<String, Object>[] getComplementConsensusHash()
@Override
- public AlignmentAnnotation getAlignmentSecondaryStructureConsensusAnnotation()
+ public List<AlignmentAnnotation> getAlignmentSecondaryStructureConsensusAnnotation()
{
return secondaryStructureConsensus;
}
/**
- * trigger update of consensus annotation
+ * trigger update of Secondary Structure consensus annotation
*/
public void updateSecondaryStructureConsensus(final AlignmentViewPanel ap)
{
{
return;
}
+ if (secondaryStructureConsensus.size() != secondaryStructureSources.size()) {
+
+ for(String source : secondaryStructureSources) {
+ boolean ssConsensusForSourcePresent = false;
+ for(AlignmentAnnotation aa : secondaryStructureConsensus) {
+ if(aa.description.startsWith(source)) {
+ ssConsensusForSourcePresent = true;
+ break;
+ }
+ }
+
+ if(!ssConsensusForSourcePresent) {
+ AlignmentAnnotation ssConsensus = new AlignmentAnnotation(MessageManager.getString("label.ssconsensus_label") + " "+source,
+ source + MessageManager.getString("label.ssconsensus_descr"),
+ new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
+
+ ssConsensus.hasText = true;
+ ssConsensus.autoCalculated = true;
+ secondaryStructureConsensus.add(ssConsensus);
+ if (showSSConsensus)
+ {
+ ssConsensus.visible = true;
+ alignment.addAnnotation(ssConsensus);
+
+ }
+ }
+ }
+ }
if (calculator
.getRegisteredWorkersOfClass(SecondaryStructureConsensusThread.class) == null)
{
calculator.registerWorker(new SecondaryStructureConsensusThread(this, ap));
}
+ ap.adjustAnnotationHeight();
+
+
}
// --------START Structure Conservation
changeSupport.firePropertyChange(prop, oldvalue, newvalue);
}
+ @Override
+ public void notifyAlignmentChanged()
+ {
+ firePropertyChange("alignment", null, alignment);
+ }
+
// common hide/show column stuff
public void hideSelectedColumns()
consensus = new AlignmentAnnotation("Consensus",
MessageManager.getString("label.consensus_descr"),
new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
-
- secondaryStructureConsensus = new AlignmentAnnotation(MessageManager.getString("label.ssconsensus_label"),
- MessageManager.getString("label.ssconsensus_descr"),
- new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
+ setSecondaryStructureSources(alignment.getAlignmentAnnotation());
+ List<String> secondaryStructureSources = getSecondaryStructureSources();
+
+ if(secondaryStructureSources!=null) {
+
+ secondaryStructureConsensus = new ArrayList<AlignmentAnnotation>();
+ for (String ssSource : secondaryStructureSources) {
+
+ AlignmentAnnotation ssConsensus = new AlignmentAnnotation(MessageManager.getString("label.ssconsensus_label") + " "+ssSource,
+ ssSource + MessageManager.getString("label.ssconsensus_descr"),
+ new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
+ secondaryStructureConsensus.add(ssConsensus);
+ }
+
+ }
initConsensus(consensus);
initSSConsensus(secondaryStructureConsensus);
}
}
- private void initSSConsensus(AlignmentAnnotation aa)
+ private void initSSConsensus(List<AlignmentAnnotation> secondaryStructureConsensuses)
{
- aa.hasText = true;
- aa.autoCalculated = true;
-
- if (showSSConsensus)
- {
- alignment.addAnnotation(aa);
+ if(secondaryStructureConsensuses == null) {
+ return;
+ }
+ for(AlignmentAnnotation aa : secondaryStructureConsensuses) {
+ aa.hasText = true;
+ aa.autoCalculated = true;
+
+ if (showSSConsensus)
+ {
+ alignment.addAnnotation(aa);
+ }
+
}
}
{
updateCalcs = true;
alignment.addAnnotation(sg.getConsensus(), 0);
- alignment.addAnnotation(sg.getSSConsensus(), 0);
+
+ List<String> secondaryStructureSources = getSecondaryStructureSources();
+ if(secondaryStructureSources !=null) {
+ List<AlignmentAnnotation> ssAa = sg.getSSConsensus(secondaryStructureSources);
+ if(ssAa != null) {
+ for(AlignmentAnnotation aa : ssAa) {
+ alignment.addAnnotation(aa, 0);
+ }
+ }
+ }
}
// refresh the annotation rows
if (updateCalcs)
return sq;
}
+ //to do jal-4386
public SequenceI getSSConsensusSeq()
{
if (secondaryStructureConsensus == null)
return null;
}
StringBuffer seqs = new StringBuffer();
- for (int i = 0; i < secondaryStructureConsensus.annotations.length; i++)
- {
- Annotation annotation = secondaryStructureConsensus.annotations[i];
- if (annotation != null)
- {
- String description = annotation.description;
- if (description != null && description.startsWith("["))
- {
- // consensus is a tie - just pick the first one
- seqs.append(description.charAt(1));
- }
- else
- {
- seqs.append(annotation.displayCharacter);
- }
- }
- }
+// for (int i = 0; i < secondaryStructureConsensus.annotations.length; i++)
+// {
+// Annotation annotation = secondaryStructureConsensus.annotations[i];
+// if (annotation != null)
+// {
+// String description = annotation.description;
+// if (description != null && description.startsWith("["))
+// {
+// // consensus is a tie - just pick the first one
+// seqs.append(description.charAt(1));
+// }
+// else
+// {
+// seqs.append(annotation.displayCharacter);
+// }
+// }
+// }
SequenceI sq = new Sequence("Sec Str Consensus", seqs.toString());
sq.setDescription("Percentage Identity Sec Str Consensus "
*/
package jalview.workers;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
import jalview.analysis.AAFrequency;
+import jalview.analysis.AlignmentUtils;
import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.ProfilesI;
import jalview.datamodel.SequenceI;
import jalview.renderer.ResidueShaderI;
+import jalview.util.MessageManager;
public class SecondaryStructureConsensusThread extends AlignCalcWorker
{
// long started = System.currentTimeMillis();
try
{
- AlignmentAnnotation ssConsensus = getSSConsensusAnnotation();
+ List<AlignmentAnnotation> ssConsensus = getSSConsensusAnnotation();
AlignmentAnnotation gap = getGapAnnotation();
if ((ssConsensus == null && gap == null) || calcMan.isPending(this))
{
calcMan.workerComplete(this);
return;
}
-
+
+ setSecondaryStructureSources();
eraseSSConsensus(aWidth);
computeSSConsensus(alignment);
updateResultAnnotation(true);
*/
protected void eraseSSConsensus(int aWidth)
{
- AlignmentAnnotation ssConsensus = getSSConsensusAnnotation();
- if (ssConsensus != null)
- {
- ssConsensus.annotations = new Annotation[aWidth];
+ List<AlignmentAnnotation> ssConsensuses = getSSConsensusAnnotation();
+ for(AlignmentAnnotation ssConsensus : ssConsensuses) {
+ if (ssConsensus != null)
+ {
+ ssConsensus.annotations = new Annotation[aWidth];
+ }
}
AlignmentAnnotation gap = getGapAnnotation();
if (gap != null)
SequenceI[] aseqs = getSequences();
int width = alignment.getWidth();
- ProfilesI hSSConsensus = AAFrequency.calculateSS(aseqs, width, 0, width,
- true);
+ Map<String, ProfilesI> hSSConsensusProfileMap = new HashMap<String, ProfilesI>();
+ List <String> ssSources = getSecondaryStructureSources();
+ for(String ssSource : ssSources) {
+ ProfilesI hSSConsensus = AAFrequency.calculateSS(aseqs, width, 0, width,
+ true, ssSource);
+ hSSConsensusProfileMap.put(ssSource, hSSConsensus);
+ }
+
- alignViewport.setSequenceSSConsensusHash(hSSConsensus);
- setColourSchemeConsensus(hSSConsensus);
+ alignViewport.setSequenceSSConsensusHash(hSSConsensusProfileMap);
+ setColourSchemeConsensus(hSSConsensusProfileMap);
}
/**
/**
* @param hconsensus
*/
- protected void setColourSchemeConsensus(ProfilesI hSSconsensus)
+ protected void setColourSchemeConsensus(Map<String, ProfilesI> ssConsensusProfileMap)
{
ResidueShaderI cs = alignViewport.getResidueShading();
if (cs != null)
{
- cs.setSsConsensus(hSSconsensus);
+ cs.setSSConsensusProfileMap(ssConsensusProfileMap);
}
}
*
* @return
*/
- protected AlignmentAnnotation getSSConsensusAnnotation()
+ protected List<AlignmentAnnotation> getSSConsensusAnnotation()
{
return alignViewport.getAlignmentSecondaryStructureConsensusAnnotation();
}
+
+ /**
+ * Get the Consensus annotation for the alignment
+ *
+ * @return
+ */
+ protected void setSecondaryStructureSources()
+ {
+ List<String> sources = null;
+ AlignmentAnnotation[] aa = alignViewport.getAlignment().getAlignmentAnnotation();
+ if(aa!=null) {
+ sources = AlignmentUtils.extractSSSourceInAlignmentAnnotation(aa);
+ if(sources != null) {
+ sources.add(0, MessageManager.getString("option.ss_providers_all"));
+ alignViewport.setSecondaryStructureSources(sources);
+ }
+ }
+ }
+
+ protected List<String> getSecondaryStructureSources()
+ {
+ return alignViewport.getSecondaryStructureSources();
+ }
/**
* Get the Gap annotation for the alignment
public void updateResultAnnotation(boolean immediate)
{
- AlignmentAnnotation ssConsensus = getSSConsensusAnnotation();
- ProfilesI hSSConsensus = (ProfilesI) getViewportSSConsensus();
+ List<AlignmentAnnotation> ssConsensuses = getSSConsensusAnnotation();
+ Map<String, ProfilesI> ssConsensusProfileMap = getViewportSSConsensus();
+ for(AlignmentAnnotation ssConsensus : ssConsensuses) {
+ ProfilesI ssConsensusProfile = null;
+ for(String source: ssConsensusProfileMap.keySet()) {
+ if(ssConsensus.description.startsWith(source)) {
+ ssConsensusProfile = ssConsensusProfileMap.get(source);
+ break;
+ }
+ }
+ if(ssConsensusProfile==null) {
+ continue;
+ }
if (immediate || !calcMan.isWorking(this) && ssConsensus != null
- && hSSConsensus != null)
+ && ssConsensusProfile != null)
{
- deriveSSConsensus(ssConsensus, hSSConsensus);
+ deriveSSConsensus(ssConsensus, ssConsensusProfile);
AlignmentAnnotation gap = getGapAnnotation();
if (gap != null)
{
- deriveGap(gap, hSSConsensus);
+ deriveGap(gap, ssConsensusProfile);
}
}
+ }
}
/**
* @param hconsensus
* the computed consensus data
*/
- protected void deriveSSConsensus(AlignmentAnnotation ssConsensusAnnotation,
+ protected void deriveSSConsensus(AlignmentAnnotation ssConsensus,
ProfilesI hSSConsensus)
{
long nseq = getSequences().length;
- AAFrequency.completeSSConsensus(ssConsensusAnnotation, hSSConsensus,
+ AAFrequency.completeSSConsensus(ssConsensus, hSSConsensus,
hSSConsensus.getStartColumn(), hSSConsensus.getEndColumn() + 1,
alignViewport.isIgnoreGapsConsensus(),
alignViewport.isShowSequenceLogo(), nseq);
*
* @return
*/
- protected Object getViewportSSConsensus()
+ protected Map<String, ProfilesI> getViewportSSConsensus()
{
// TODO convert ComplementConsensusThread to use Profile
return alignViewport.getSequenceSSConsensusHash();
import jalview.datamodel.features.SequenceFeatures;
import jalview.gui.JvOptionPane;
+import java.nio.charset.Charset;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
+import java.util.spi.LocaleServiceProvider;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
assertEquals(10, sf.getBegin());
assertEquals(11, sf.getEnd());
}
+ private SequenceI mkDs(SequenceI as)
+ {
+ SequenceI ds = as.createDatasetSequence();
+ ds.setSequence(ds.getSequenceAsString().toUpperCase(Locale.ROOT));
+ return ds;
+ }
+ /**
+ * Test that mimics 'remove all gapped columns' action. This generates a
+ * series Delete Gap edits that each act on all sequences that share a gapped
+ * column region.
+ */
+ @Test(groups = { "Functional" })
+ public void testLeftRight_Justify_and_preserves_gaps()
+ {
+ EditCommand command = new EditCommand();
+ String original1 = "--ABc--DEF";
+ String original2 = "-G-Hi--J";
+ String original3 = "-M-No--PQ";
+
+ /*
+ * Set up the sequence array for operations
+ */
+ SequenceI seq1 = new Sequence("sq1", original1);
+ SequenceI ds1 = mkDs(seq1);
+ /*
+ * and check we are preserving data - if the calls below fail, something has broken the Jalview dataset derivation process
+ */
+ assertEquals("ABCDEF", seq1.getDatasetSequence().getSequenceAsString());
+ assertEquals(original1,seq1.getSequenceAsString());
+ SequenceI seq2 = new Sequence("sq2",original2);
+ SequenceI ds2 = mkDs(seq2);
+ SequenceI seq3 = new Sequence("sq3", original3);
+ SequenceI ds3 = mkDs(seq3);
+ List<SequenceI> sqs = Arrays.asList( seq1, seq2, seq3 );
+ Alignment al = new Alignment(sqs.toArray(new SequenceI[0]));
+ EditCommand lefj = new JustifyLeftOrRightCommand("Left J", true, sqs, 1, 7, al);
+ String exp = "-ABcD---EF";
+ // check without case conservation
+ assertEquals(exp.toUpperCase(Locale.ROOT),seq1.getSequenceAsString().toUpperCase(Locale.ROOT));
+ // check case
+ assertEquals(exp,seq1.getSequenceAsString());
+ // and other seqs
+ assertEquals("-GHiJ---",seq2.getSequenceAsString());
+ assertEquals("-MNoP---Q",seq3.getSequenceAsString());
+ lefj.undoCommand(new AlignmentI[] { al});
+ assertEquals(original3,seq3.getSequenceAsString());
+ assertEquals(original1,seq1.getSequenceAsString());
+ assertEquals(original2,seq2.getSequenceAsString());
+
+ EditCommand righj = new JustifyLeftOrRightCommand("Right J", false, sqs, 2, 7, al);
+ assertEquals("----ABcDEF",seq1.getSequenceAsString());
+ assertEquals("-G---HiJ",seq2.getSequenceAsString());
+ assertEquals("-M---NoPQ",seq3.getSequenceAsString());
+ righj.undoCommand(new AlignmentI[] { al});
+ assertEquals(original3,seq3.getSequenceAsString());
+ assertEquals(original1,seq1.getSequenceAsString());
+ assertEquals(original2,seq2.getSequenceAsString());
+
+ }
}