label.neighbour_blosum62 = Neighbour Joining Using BLOSUM62
label.show_annotations = Show annotations
label.hide_annotations = Hide annotations
+label.group_show_auto_calculated_annotations = Show auto calculated annotations
+label.group_hide_auto_calculated_annotations = Hide auto calculated annotations
label.show_all_seq_annotations = Show sequence related
label.hide_all_seq_annotations = Hide sequence related
label.show_all_al_annotations = Show alignment related
package jalview.analysis;
import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
import jalview.renderer.AnnotationRenderer;
+import jalview.util.Constants;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
public class AlignmentAnnotationUtils
{
}
/**
+ * Updates the lists of shown and hidden secondary structure types based on
+ * the selected sequence group.
+ *
+ * @param shownTypes
+ * A list that will be populated with the providers of secondary
+ * structures that are shown.
+ * @param hiddenTypes
+ * A list that will be populated with the providers of secondary
+ * structures that are hidden.
+ * @param annotations
+ * A list of AlignmentAnnotation objects.
+ * @param selectedSequenceGroup
+ * The sequence group selected by the user.
+ */
+ public static void getShownHiddenSecondaryStructureProvidersForGroup(
+ List<String> shownTypes, List<String> hiddenTypes,
+ List<AlignmentAnnotation> annotations,
+ SequenceGroup selectedSequenceGroup)
+ {
+ // Return if the selected sequence group or annotations are null
+ if (selectedSequenceGroup == null || annotations == null)
+ {
+ return;
+ }
+
+ // Get the secondary structure sources of the selected sequence group
+ List<String> ssSourcesForSelectedGroup = selectedSequenceGroup
+ .getSecondaryStructureSources();
+
+ // Return if there are no secondary structure sources for the selected group
+ if (ssSourcesForSelectedGroup == null
+ || ssSourcesForSelectedGroup.isEmpty())
+ {
+ return;
+ }
+
+ // Iterate through each annotation
+ for (AlignmentAnnotation aa : annotations)
+ {
+ /* Skip to the next annotation if the annotation, the annotation's group
+ * reference is null, or the annotation's group reference does not match
+ * the selected group
+ */
+ if (aa.annotations == null || aa.groupRef == null
+ || selectedSequenceGroup != aa.groupRef
+ || !aa.label.startsWith(
+ Constants.SECONDARY_STRUCTURE_CONSENSUS_LABEL))
+ {
+ continue;
+ }
+
+ /* Find a provider from the secondary structure sources that matches
+ * the annotation's label. This is to exclude secondary structure
+ * providers which has no secondary structure data for the selected group.
+ */
+ Optional<String> provider = ssSourcesForSelectedGroup.stream()
+ .filter(aa.label::contains).findFirst()
+ .map(substring -> aa.label.substring(0,
+ aa.label.indexOf(substring) + substring.length()));
+
+ // If a matching provider is found and the annotation is visible, add
+ // the provider to the shown types list (if not already in shownTypes).
+ // If the annotation is not visible, add it to hiddenTypes list.
+ provider.ifPresent(p -> {
+ if (aa.visible && !shownTypes.contains(p))
+ {
+ shownTypes.add(p);
+ }
+ else if (!aa.visible && !shownTypes.contains(p))
+ {
+ hiddenTypes.add(p);
+ }
+ });
+ }
+ }
+
+
+ /**
* Returns a BitSet (possibly empty) of those graphGroups for line graph
* annotations, which have at least one member annotation row marked visible.
* <p/>
}
}
}
+
+ /**
+ * Shows or hides auto calculated annotations for a sequence group.
+ *
+ * @param al
+ * The alignment object with the annotations.
+ * @param type
+ * The type of annotation to show or hide.
+ * @param selectedGroup
+ * The sequence group for which the annotations should be shown or
+ * hidden.
+ * @param anyType
+ * If true, all types of annotations will be shown/hidden.
+ * @param doShow
+ * If true, the annotations will be shown; if false, annotations will
+ * be hidden.
+ */
+ public static void showOrHideAutoCalculatedAnnotationsForGroup(
+ AlignmentI al, String type, SequenceGroup selectedGroup,
+ boolean anyType, boolean doShow)
+ {
+ // Get all alignment annotations
+ AlignmentAnnotation[] anns = al.getAlignmentAnnotation();
+ if (anns != null)
+ {
+ for (AlignmentAnnotation aa : anns)
+ {
+ // Check if anyType is true or if the annotation's label contains the
+ // specified type (currently for secondary structure consensus)
+ if ((anyType && aa.label
+ .startsWith(Constants.SECONDARY_STRUCTURE_CONSENSUS_LABEL))
+ || aa.label.startsWith(type))
+ {
+ // If the annotation's group reference is not null and matches the
+ // selected group, update its visibility.
+ if (aa.groupRef != null && selectedGroup == aa.groupRef)
+ {
+ aa.visible = doShow;
+ }
+ }
+ }
+ }
+ }
+
+
public static AlignmentAnnotation getFirstSequenceAnnotationOfType(
AlignmentI al, int graphType)
{
}
return true;
}
-
-
- 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;
- }
-
+
public static boolean isSecondaryStructurePresent(AlignmentAnnotation[] annotations)
{
boolean ssPresent = false;
}
// For JPred
- if (aa.label.equals(Constants.SS_ANNOTATION_FROM_JPRED_LABEL))
+ if (Constants.SS_ANNOTATION_FROM_JPRED_LABEL.equals(aa.label))
{
return (Constants.SECONDARY_STRUCTURE_LABELS.get(aa.label));
}
// For input with secondary structure
- if (aa.label.equals(Constants.SS_ANNOTATION_LABEL)
- && aa.description != null && aa.description.equals(Constants.SS_ANNOTATION_LABEL))
+ if (Constants.SS_ANNOTATION_LABEL.equals(aa.label)
+ && aa.description != null && Constants.SS_ANNOTATION_LABEL.equals(aa.description))
{
return (Constants.SECONDARY_STRUCTURE_LABELS.get(aa.label));
if (aa != null)
{
- if (ssSource.equals(Constants.SS_ALL_PROVIDERS))
+ if (Constants.SS_ALL_PROVIDERS.equals(ssSource))
{
ssAnnots.addAll(Arrays.asList(aa));
continue;
if (label.equals(aa.label))
{
- if (selectedSSSource.equals(Constants.SS_ALL_PROVIDERS))
+ if (Constants.SS_ALL_PROVIDERS.equals(selectedSSSource))
{
ssAlignmentAnnotationForSequences
.computeIfAbsent(aa.sequenceRef.getDatasetSequence(),
import jalview.renderer.ResidueShaderI;
import jalview.schemes.ColourSchemeI;
import jalview.util.Constants;
-import jalview.util.MessageManager;
/**
* Collects a set contiguous ranges on a set of sequences
private boolean showSequenceLogo = false;
- private boolean showSequenceSSLogo = false;
-
/**
* flag indicating if logo should be rendered normalised
*/
List<AlignmentAnnotation> ssConsensus = null;
+
+ List<String> secondaryStructureSources = null;
AlignmentAnnotation conservation = null;
private boolean showConsensusHistogram;
- private boolean showSSConsensusHistogram;
-
private AnnotatedCollectionI context;
public Map<String, ProfilesI> hSSConsensusProfileMap;
showSequenceLogo = seqsel.showSequenceLogo;
normaliseSequenceLogo = seqsel.normaliseSequenceLogo;
showConsensusHistogram = seqsel.showConsensusHistogram;
- showSSConsensusHistogram = seqsel.showSSConsensusHistogram;
idColour = seqsel.idColour;
outlineColour = seqsel.outlineColour;
seqrep = seqsel.seqrep;
}
return tmp.toArray(new SequenceI[tmp.size()]);
}
+
+ public List<String> getSecondaryStructureSources()
+ {
+ return secondaryStructureSources;
+ }
+
+ public void setSecondaryStructureSources(
+ List<String> secondaryStructureSources)
+ {
+ this.secondaryStructureSources = secondaryStructureSources;
+ }
/**
* DOCUMENT ME!
// ignoreGapsInConsensusCalculation);
}
- public ProfilesI ssConsensusData = null;
-
+
+ /**
+ * Updates the secondary structure consensus row based on the provided profiles map and the number of sequences.
+ *
+ * @param hSSConsensusProfileMap A map containing secondary structure consensus profiles for each providers.
+ * @param nseq The number of sequences.
+ */
private void _updateSSConsensusRow(Map<String, ProfilesI> hSSConsensusProfileMap, long nseq)
{
+ // Get a list of secondary structure sources from the profile map keys
List<String> ssSources = new ArrayList<>(hSSConsensusProfileMap.keySet());
+ secondaryStructureSources = new ArrayList<String>();
+ // Sort the secondary structure sources alphabetically
Collections.sort(ssSources);
+
+ // Initialize ssConsensus if it is null
if (ssConsensus == null)
{
getSSConsensus(ssSources);
}
+
+ // Iterate through each alignment annotation in the ssConsensus list
for (AlignmentAnnotation aa : ssConsensus) {
ProfilesI profile = null;
String ssSource = null;
+
+ // Find the matching profile for the current annotation based on its description
for(String source : ssSources) {
if(aa.description.startsWith(source)) {
profile = hSSConsensusProfileMap.get(source);
ssSource = source;
}
}
+
+ // If no matching profile is found, continue to the next annotation
if(profile == null) {
continue;
}
+ // Update the label and description of the annotation with the source/provider
aa.label = Constants.SECONDARY_STRUCTURE_CONSENSUS_LABEL + " " + ssSource + " " + getName();
aa.description = ssSource + Constants.SECONDARY_STRUCTURE_CONSENSUS_LABEL +" for " + getName();
- ssConsensusData = profile;
- // preserve width if already set
+
+ // Get the width of the annotations array
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
+ aa.annotations = new Annotation[aWidth];
- AAFrequency.completeSSConsensus(aa, profile, startRes, endRes + 1,
- ignoreGapsInConsensus, showSequenceLogo, nseq); // TODO: setting
- // container
+ // Complete the secondary structure consensus
+ AAFrequency.completeSSConsensus(aa, profile, startRes, endRes + 1,
+ ignoreGapsInConsensus, showSequenceLogo, nseq);
+
+ //Add the provider to the list if the no of sequences
+ //contributed to the secondary structure consensus is
+ //more than 0.
+ if(aa.getNoOfSequencesIncluded()>0 && !Constants.SS_ALL_PROVIDERS.equals(ssSource))
+ {
+ // Remove "All" from the hidden types list{
+ secondaryStructureSources.add(ssSource);
+ }
}
- // for
- // ignoreGapsInConsensusCalculation);
}
/**
for(String ssSource : ssSources) {
AlignmentAnnotation aa = new AlignmentAnnotation("", "", new Annotation[1], 0f,
100f, AlignmentAnnotation.BAR_GRAPH);
+ // Setting the annotation visibility to true of the provider is "All"
+ // and false otherwise.
+ aa.visible = Constants.SS_ALL_PROVIDERS.equals(ssSource);
aa.hasText = true;
aa.autoCalculated = true;
aa.groupRef = this;
this.showSequenceLogo = showSequenceLogo;
}
-
- public void setshowSequenceSSLogo(boolean showSequenceSSLogo)
- {
- // TODO: decouple calculation from settings update
- if (this.showSequenceSSLogo != showSequenceSSLogo && ssConsensus != null)
- {
- this.showSequenceSSLogo = showSequenceSSLogo;
- recalcConservation();
- }
- this.showSequenceSSLogo = showSequenceSSLogo;
- }
-
/**
*
* @param showConsHist
}
this.showConsensusHistogram = showConsHist;
}
-
- public void setShowSSConsensusHistogram(boolean showSSConsHist)
- {
-
- if (showSSConsensusHistogram != showSSConsHist && consensus != null)
- {
- this.showSSConsensusHistogram = showSSConsHist;
- recalcConservation();
- }
- this.showSSConsensusHistogram = showSSConsHist;
- }
/**
* @return the showConsensusHistogram
for (AlignmentAnnotation aa: annotations) {
+ if(aa.groupRef!=null) {
+ continue;
+ }
+
boolean isSSConsensus = aa.label.startsWith(MessageManager.getString("label.ssconsensus_label"));
boolean matchesSSSourceSelection = aa.description.startsWith(ssSourceSelection);
JMenuItem textColour = new JMenuItem();
- JMenu editGroupMenu = new JMenu();
+ JMenu editGroupMenu = new JMenu();
+
+ JMenu groupShowAutoCalculatedAnnotations = new JMenu();
+
+ JMenu groupHideAutoCalculatedAnnotations = new JMenu();
JMenuItem chooseStructure = new JMenuItem();
final List<SequenceI> selectedGroup = (alignPanel.av
.getSelectionGroup() == null
? Collections.<SequenceI> emptyList()
- : alignPanel.av.getSelectionGroup().getSequences());
+ : alignPanel.av.getSelectionGroup().getSequences());
buildAnnotationTypesMenus(groupShowAnnotationsMenu,
groupHideAnnotationsMenu, selectedGroup);
configureReferenceAnnotationsMenu(groupAddReferenceAnnotations,
selectedGroup);
+
+ //If a sequence group is selected, build show/hide auto calculated annotations menu
+ SequenceGroup selectedSequenceGroup = alignPanel.av.getSelectionGroup();
+ if(selectedSequenceGroup != null) {
+ buildAutoCalculatedAnnotationsMenu(groupShowAutoCalculatedAnnotations,
+ groupHideAutoCalculatedAnnotations, selectedSequenceGroup);
+ }
try
{
unGroupMenuItem.setVisible(false);
editGroupMenu
.setText(MessageManager.getString("action.edit_new_group"));
+
+ // Hide show/hide auto calculated annotations menus for group if a sequence
+ // group is not defined.
+ groupShowAutoCalculatedAnnotations.setVisible(false);
+ groupHideAutoCalculatedAnnotations.setVisible(false);
}
else
{
createGroupMenuItem.setVisible(false);
unGroupMenuItem.setVisible(true);
editGroupMenu.setText(MessageManager.getString("action.edit_group"));
+
+ // Show show/hide auto calculated annotations menus for group if a sequence
+ // group is defined and showGroupSSConsensus is true. Hide the menus otherwise.
+ if(alignPanel.av.isShowGroupSSConsensus()) {
+ groupShowAutoCalculatedAnnotations.setVisible(true);
+ groupHideAutoCalculatedAnnotations.setVisible(true);
+ }
+ else {
+ groupShowAutoCalculatedAnnotations.setVisible(false);
+ groupHideAutoCalculatedAnnotations.setVisible(false);
+ }
}
if (!forIdPanel)
// grey out 'hide annotations' if none are shown
hideMenu.setEnabled(!shownTypes.isEmpty());
}
+
+ /**
+ * Builds the menu for showing and hiding auto calculated annotations for a
+ * selected sequence group. It clears existing menu items and adds menu items
+ * for showing/hiding annotations. The menu is populated based on the current
+ * visible status.
+ *
+ * @param groupShowAutoCalculatedAnnotations
+ * The menu for showing auto calculated annotations.
+ * @param groupHideAutoCalculatedAnnotations
+ * The menu for hiding auto calculated annotations.
+ * @param selectedSequenceGroup
+ * The sequence group selected by the user.
+ */
+ protected void buildAutoCalculatedAnnotationsMenu(
+ JMenu groupShowAutoCalculatedAnnotations,
+ JMenu groupHideAutoCalculatedAnnotations,
+ SequenceGroup selectedSequenceGroup)
+ {
+
+ // Clear all existing items from the menus
+ groupShowAutoCalculatedAnnotations.removeAll();
+ groupHideAutoCalculatedAnnotations.removeAll();
+
+ // Add "All" menu item to both show and hide menus.
+ final String all = MessageManager.getString("label.all");
+ addAutoCalculatedAnnotationTypeToShowHide(
+ groupShowAutoCalculatedAnnotations, selectedSequenceGroup, all,
+ true, true);
+ addAutoCalculatedAnnotationTypeToShowHide(
+ groupHideAutoCalculatedAnnotations, selectedSequenceGroup, all,
+ true, false);
+
+ // Add separators after "All"
+ groupShowAutoCalculatedAnnotations.addSeparator();
+ groupHideAutoCalculatedAnnotations.addSeparator();
+
+ // Get the alignment annotations
+ final AlignmentAnnotation[] annotations = ap.getAlignment()
+ .getAlignmentAnnotation();
+
+ // Lists to hold shown and hidden annotation types
+ List<String> shownTypes = new ArrayList<>();
+ List<String> hiddenTypes = new ArrayList<>();
+
+ // Populate the lists of shown and hidden annotation types based on the
+ // current visible status for the selected sequence group
+ AlignmentAnnotationUtils
+ .getShownHiddenSecondaryStructureProvidersForGroup(shownTypes,
+ hiddenTypes,
+ AlignmentAnnotationUtils.asList(annotations),
+ selectedSequenceGroup);
+
+ // Add code if additional auto calculated annotation types (like residue consensus,
+ // conservation, etc.) are needed for a selected group
+
+ // Add currently hidden types to the show menu
+ for (String shownType : shownTypes)
+ {
+ addAutoCalculatedAnnotationTypeToShowHide(
+ groupHideAutoCalculatedAnnotations, selectedSequenceGroup,
+ shownType, false, false);
+ }
+
+ // Add currently shown types to the hide menu
+ for (String hiddenType : hiddenTypes)
+ {
+ addAutoCalculatedAnnotationTypeToShowHide(
+ groupShowAutoCalculatedAnnotations, selectedSequenceGroup,
+ hiddenType, false, true);
+ }
+
+ // Enable or disable the menus based on whether there are any hidden
+ // or shown types
+ groupShowAutoCalculatedAnnotations.setEnabled(!hiddenTypes.isEmpty());
+ groupHideAutoCalculatedAnnotations.setEnabled(!shownTypes.isEmpty());
+ }
+
+
+ /**
+ * Adds a menu item to the provided menu for showing or hiding a specific type
+ * of auto calculated annotation
+ *
+ * @param showOrHideAutoCalculatedAnnotationsMenu
+ * The menu to which the item should be added.
+ * @param selectedSequenceGroup
+ * The selected sequence group for which the action will be
+ * performed.
+ * @param type
+ * The type of annotation to show or hide.
+ * @param allTypes
+ * Indicates if the action should apply to all annotation types.
+ * True if user selects "All".
+ * @param actionIsShow
+ * Indicates if the item is for showing (true) or hiding (false) the
+ * annotation type.
+ */
+ protected void addAutoCalculatedAnnotationTypeToShowHide(
+ JMenu showOrHideAutoCalculatedAnnotationsMenu,
+ final SequenceGroup selectedSequenceGroup, final String type,
+ final boolean allTypes, final boolean actionIsShow)
+ {
+
+ // Create a new menu item with the type
+ final JMenuItem item = new JMenuItem(type);
+
+ // Add an action listener to the menu item
+ item.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ // Show or hide the auto calculated annotations for the selected group
+ AlignmentUtils.showOrHideAutoCalculatedAnnotationsForGroup(
+ ap.getAlignment(), type, selectedSequenceGroup, allTypes,
+ actionIsShow);
+
+ refresh();
+ }
+ });
+
+ // Add the menu item to the menu
+ showOrHideAutoCalculatedAnnotationsMenu.add(item);
+ }
+
+
/**
* Returns a list of sequences - either the current selection group (if there
.setText(MessageManager.getString("label.show_annotations"));
groupHideAnnotationsMenu
.setText(MessageManager.getString("label.hide_annotations"));
+ groupShowAutoCalculatedAnnotations
+ .setText(MessageManager.getString("label.group_show_auto_calculated_annotations"));
+ groupHideAutoCalculatedAnnotations
+ .setText(MessageManager.getString("label.group_hide_auto_calculated_annotations"));
JMenuItem sequenceFeature = new JMenuItem(
MessageManager.getString("label.create_sequence_feature"));
sequenceFeature.addActionListener(new ActionListener()
groupMenu.add(groupShowAnnotationsMenu);
groupMenu.add(groupHideAnnotationsMenu);
groupMenu.add(groupAddReferenceAnnotations);
+ groupMenu.add(groupShowAutoCalculatedAnnotations);
+ groupMenu.add(groupHideAutoCalculatedAnnotations);
groupMenu.add(editMenu);
groupMenu.add(outputMenu);
groupMenu.add(sequenceFeature);
List<AlignmentAnnotation> ssAa = sg.getSSConsensus(secondaryStructureSources);
if(ssAa != null) {
for(AlignmentAnnotation aa : ssAa) {
+ // Setting annotation visibility to true for the secondary
+ // structure consensus for all providers
+ if (aa.label.contains(Constants.SS_ALL_PROVIDERS))
+ {
+ aa.visible = true;
+ }
alignment.addAnnotation(aa, 0);
}
}