label.group_consensus = Group Consensus
label.group_conservation = Group Conservation
label.show_consensus_histogram = Show Consensus Histogram
+label.show_ssconsensus_histogram = Show SS Consensus Histogram
label.show_consensus_logo = Show Consensus Logo
+label.show_ssconsensus_logo = Show SS Consensus Logo
label.norm_consensus_logo = Normalise Consensus Logo
label.apply_all_groups = Apply to all groups
label.autocalculated_annotation = Autocalculated Annotation
label.quality_descr = Alignment Quality based on Blosum62 scores
label.conservation_descr = Conservation of total alignment less than {0}% gaps
label.consensus_descr = PID
+label.ssconsensus_descr = SS Consensus
label.complement_consensus_descr = PID for cDNA
label.strucconsensus_descr = PID for base pairs
label.occupancy_descr = Number of aligned positions
import jalview.datamodel.ProfilesI;
import jalview.datamodel.ResidueCount;
import jalview.datamodel.ResidueCount.SymbolCounts;
+import jalview.datamodel.SecondaryStructureCount;
import jalview.datamodel.SequenceI;
import jalview.ext.android.SparseIntArray;
import jalview.util.Comparison;
public class AAFrequency
{
public static final String PROFILE = "P";
+ private static final String SS_ANNOTATION_LABEL = "Secondary Structure";
+ private static final char COIL = 'C';
/*
* Quick look-up of String value of char 'A' to 'Z'
// jalview.bin.Console.outPrintln(elapsed);
}
+
+ public static final ProfilesI calculateSS(List<SequenceI> list, int start,
+ int end)
+ {
+ return calculateSS(list, start, end, false);
+ }
+
+ public static final ProfilesI calculateSS(List<SequenceI> sequences,
+ int start, int end, boolean profile)
+ {
+ SequenceI[] seqs = new SequenceI[sequences.size()];
+ int width = 0;
+ synchronized (sequences)
+ {
+ for (int i = 0; i < sequences.size(); i++)
+ {
+ seqs[i] = sequences.get(i);
+ int length = seqs[i].getLength();
+ if (length > width)
+ {
+ width = length;
+ }
+ }
+
+ if (end >= width)
+ {
+ end = width;
+ }
+
+ ProfilesI reply = calculateSS(seqs, width, start, end, profile);
+ return reply;
+ }
+ }
+
+ public static final ProfilesI calculateSS(final SequenceI[] sequences,
+ int width, int start, int end, boolean saveFullProfile)
+ {
+ // long now = System.currentTimeMillis();
+ int seqCount = sequences.length;
+
+ ProfileI[] result = new ProfileI[width];
+
+ for (int column = start; column < end; column++)
+ {
+ /*
+ * Apply a heuristic to detect nucleotide data (which can
+ * be counted in more compact arrays); here we test for
+ * more than 90% nucleotide; recheck every 10 columns in case
+ * of misleading data e.g. highly conserved Alanine in peptide!
+ * Mistakenly guessing nucleotide has a small performance cost,
+ * as it will result in counting in sparse arrays.
+ * Mistakenly guessing peptide has a small space cost,
+ * as it will use a larger than necessary array to hold counts.
+ */
+
+ int ssCount = 0;
+
+ SecondaryStructureCount ssCounts = new SecondaryStructureCount();
+
+ for (int row = 0; row < seqCount; row++)
+ {
+ if (sequences[row] == null)
+ {
+ jalview.bin.Console.errPrintln(
+ "WARNING: Consensus skipping null sequence - possible race condition.");
+ continue;
+ }
+
+ char c = sequences[row].getCharAt(column);
+
+ if (sequences[row].getLength() > column && !Comparison.isGap(c))
+ {
+
+ AlignmentAnnotation[] aa = sequences[row].getAnnotation(SS_ANNOTATION_LABEL);
+ if(aa == null) {
+ continue;
+ }
+ int seqPosition = sequences[row].findPosition(column);
+ char ss;
+ if (aa[0].getAnnotationForPosition(seqPosition) != null) {
+ ss = aa[0].getAnnotationForPosition(seqPosition).secondaryStructure;
+
+ //There is no representation for coil and it can be either ' ' or null.
+ if (ss == ' ') {
+ ss = COIL;
+ }
+ }
+ else {
+ ss = COIL;
+ }
+
+ //secondaryStructures[row][column] = ss;
+
+ ssCounts.add(ss);
+ ssCount++;
+
+ }
+ else
+ {
+ /*
+ * count a gap if the sequence doesn't reach this column
+ */
+ ssCounts.addGap();
+ }
+ }
+
+ int maxSSCount = ssCounts.getModalCount();
+ String maxSS = ssCounts.getSSForCount(maxSSCount);
+ int gapCount = ssCounts.getGapCount();
+ ProfileI profile = new Profile(maxSS, ssCount, gapCount,
+ maxSSCount);
+
+ if (saveFullProfile)
+ {
+ profile.setSSCounts(ssCounts);
+ }
+
+ result[column] = profile;
+ }
+ return new Profiles(result);
+ // long elapsed = System.currentTimeMillis() - now;
+ // jalview.bin.Console.outPrintln(elapsed);
+ }
+
/**
* Make an estimate of the profile size we are going to compute i.e. how many
* different characters may be present in it. Overestimating has a cost of
// long elapsed = System.currentTimeMillis() - now;
// jalview.bin.Console.outPrintln(-elapsed);
}
+
+
+ public static void completeSSConsensus(AlignmentAnnotation ssConsensus,
+ ProfilesI profiles, int startCol, int endCol, boolean ignoreGaps,
+ boolean showSequenceLogo, long nseq)
+ {
+ // long now = System.currentTimeMillis();
+ if (ssConsensus == null || ssConsensus.annotations == null
+ || ssConsensus.annotations.length < endCol)
+ {
+ /*
+ * called with a bad alignment annotation row
+ * wait for it to be initialised properly
+ */
+ return;
+ }
+
+ for (int i = startCol; i < endCol; i++)
+ {
+ ProfileI profile = profiles.get(i);
+ if (profile == null)
+ {
+ /*
+ * happens if sequences calculated over were
+ * shorter than alignment width
+ */
+ ssConsensus.annotations[i] = null;
+ return;
+ }
+
+ final int dp = getPercentageDp(nseq);
+
+ float value = profile.getSSPercentageIdentity(ignoreGaps);
+
+ String description = getSSTooltip(profile, value, showSequenceLogo,
+ ignoreGaps, dp);
+
+ String modalSS = profile.getModalSS();
+ if ("".equals(modalSS))
+ {
+ modalSS = "-";
+ }
+ else if (modalSS.length() > 1)
+ {
+ modalSS = "+";
+ }
+ ssConsensus.annotations[i] = new Annotation(modalSS, description,
+ ' ', value);
+ }
+ // long elapsed = System.currentTimeMillis() - now;
+ // jalview.bin.Console.outPrintln(-elapsed);
+ }
/**
* Derive the gap count annotation row.
}
return description;
}
+
+ static String getSSTooltip(ProfileI profile, float pid,
+ boolean showSequenceLogo, boolean ignoreGaps, int dp)
+ {
+ SecondaryStructureCount counts = profile.getSSCounts();
+
+ String description = null;
+ if (counts != null && showSequenceLogo)
+ {
+ int normaliseBy = ignoreGaps ? profile.getNonGapped()
+ : profile.getHeight();
+ description = counts.getTooltip(normaliseBy, dp);
+ }
+ else
+ {
+ StringBuilder sb = new StringBuilder(64);
+ String maxSS = profile.getModalSS();
+ if (maxSS.length() > 1)
+ {
+ sb.append("[").append(maxSS).append("]");
+ }
+ else
+ {
+ sb.append(maxSS);
+ }
+ if (maxSS.length() > 0)
+ {
+ sb.append(" ");
+ Format.appendPercentage(sb, pid, dp);
+ sb.append("%");
+ }
+ description = sb.toString();
+ }
+ return description;
+ }
/**
* Returns the sorted profile for the given consensus data. The returned array
*/
public static int[] extractProfile(ProfileI profile, boolean ignoreGaps)
{
- ResidueCount counts = profile.getCounts();
- if (counts == null)
+ char[] symbols;
+ int[] values;
+
+ if (profile.getCounts() != null)
{
+ ResidueCount counts = profile.getCounts();
+ SymbolCounts symbolCounts = counts.getSymbolCounts();
+ symbols = symbolCounts.symbols;
+ values = symbolCounts.values;
+
+ }
+ else if(profile.getSSCounts() != null)
+ {
+ SecondaryStructureCount counts = profile.getSSCounts();
+ // to do
+ SecondaryStructureCount.SymbolCounts symbolCounts = counts.getSymbolCounts();
+ symbols = symbolCounts.symbols;
+ values = symbolCounts.values;
+ }
+ else {
return null;
}
+
- SymbolCounts symbolCounts = counts.getSymbolCounts();
- char[] symbols = symbolCounts.symbols;
- int[] values = symbolCounts.values;
QuickSort.sort(values, symbols);
int totalPercentage = 0;
final int divisor = ignoreGaps ? profile.getNonGapped()
import java.util.SortedMap;
import java.util.TreeMap;
+import jalview.api.AlignCalcWorkerI;
import jalview.bin.Console;
import jalview.commands.RemoveGapColCommand;
import jalview.datamodel.AlignedCodon;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
import jalview.datamodel.features.SequenceFeatures;
+import jalview.gui.AlignmentPanel;
import jalview.io.gff.SequenceOntologyI;
import jalview.schemes.ResidueProperties;
import jalview.util.Comparison;
import jalview.util.IntRangeComparator;
import jalview.util.MapList;
import jalview.util.MappingUtils;
+import jalview.workers.SecondaryStructureConsensusThread;
/**
* grab bag of useful alignment manipulation operations Expect these to be
{
private static final int CODON_LENGTH = 3;
- private static final String SEQUENCE_VARIANT = "sequence_variant:";
+ private static final String SEQUENCE_VARIANT = "sequence_variant:";
+
+ private static final String SS_ANNOTATION_LABEL = "Secondary Structure";
/*
* the 'id' attribute is provided for variant features fetched from
}
}
}
+
+
+ public static boolean isSSAnnotationPresent( Map<SequenceI, List<AlignmentAnnotation>> annotations) {
+
+ for (SequenceI seq : annotations.keySet())
+ {
+ for (AlignmentAnnotation ann : annotations.get(seq))
+ {
+ if(ann.getDescription(false).startsWith(SS_ANNOTATION_LABEL)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
/**
* Make a copy of a reference annotation {@code ann} and add it to an
boolean isValidCharWidth();
boolean isShowConsensusHistogram();
+
+ boolean isShowSSConsensusHistogram();
boolean isShowSequenceLogo();
+
+ boolean isShowSequenceSSLogo();
boolean isNormaliseSequenceLogo();
* @return
*/
AlignmentAnnotation getAlignmentConsensusAnnotation();
+
+ AlignmentAnnotation getAlignmentSecondaryStructureConsensusAnnotation();
+
/**
* get the container for alignment gap annotation
* @param hconsensus
*/
void setSequenceConsensusHash(ProfilesI hconsensus);
+
+ void setSequenceSSConsensusHash(ProfilesI hSSConsensus);
+
/**
* Set the cDNA complement consensus for the viewport
Iterator<int[]> getViewAsVisibleContigs(boolean selectedRegionOnly);
ContactMatrixI getContactMatrix(AlignmentAnnotation alignmentAnnotation);
+
+ ProfilesI getSequenceSSConsensusHash();
+
}
* in the alignment.</li>
* <li>SHOW_CONSENSUS_HISTOGRAM (false) Show consensus annotation row's
* histogram.</li>
+ * <li>SHOW_SSCONSENSUS_HISTOGRAM (false) Show secondary structure consensus annotation row's
+ * histogram.</li>
* <li>SHOW_CONSENSUS_LOGO (false) Show consensus annotation row's sequence
* logo.</li>
* <li>NORMALISE_CONSENSUS_LOGO (false) Show consensus annotation row's sequence
* an object holding counts of symbols in the profile
*/
private ResidueCount counts;
+
+ private SecondaryStructureCount ssCounts;
/*
* the number of sequences (gapped or not) in the profile
* the highest count for any residue in the profile
*/
private int maxCount;
+ private int maxSSCount;
+
/*
* the residue (e.g. K) or residues (e.g. KQW) with the
* highest count in the profile
*/
private String modalResidue;
+
+ private String modalSS;
/**
* Constructor which allows derived data to be stored without having to store
this.maxCount = max;
this.modalResidue = modalRes;
}
+
+ public Profile(String modalSS, int ssCount, int gaps, int maxSSCount)
+ {
+ this.height = ssCount;
+ this.gapped = gaps;
+ this.maxSSCount = maxSSCount;
+ this.modalSS = modalSS;
+ }
/* (non-Javadoc)
* @see jalview.datamodel.ProfileI#setCounts(jalview.datamodel.ResidueCount)
{
this.counts = residueCounts;
}
+
+ @Override
+ public void setSSCounts(SecondaryStructureCount secondaryStructureCount)
+ {
+ this.ssCounts = secondaryStructureCount;
+ }
/* (non-Javadoc)
* @see jalview.datamodel.ProfileI#getPercentageIdentity(boolean)
}
return pid;
}
+
+ @Override
+ public float getSSPercentageIdentity(boolean ignoreGaps)
+ {
+ if (height == 0)
+ {
+ return 0f;
+ }
+ float ssPid = 0f;
+ if (ignoreGaps && gapped < height)
+ {
+ ssPid = (maxSSCount * 100f) / (height - gapped);
+ }
+ else
+ {
+ ssPid = (maxSSCount * 100f) / height;
+ }
+ return ssPid;
+ }
/* (non-Javadoc)
* @see jalview.datamodel.ProfileI#getCounts()
{
return counts;
}
+
+ @Override
+ public SecondaryStructureCount getSSCounts()
+ {
+ return ssCounts;
+ }
/* (non-Javadoc)
* @see jalview.datamodel.ProfileI#getHeight()
{
return maxCount;
}
+
+ @Override
+ public int getMaxSSCount()
+ {
+ return maxSSCount;
+ }
/* (non-Javadoc)
* @see jalview.datamodel.ProfileI#getModalResidue()
{
return modalResidue;
}
+
+ @Override
+ public String getModalSS()
+ {
+ return modalSS;
+ }
/* (non-Javadoc)
* @see jalview.datamodel.ProfileI#getNonGapped()
* @param residueCounts
*/
public abstract void setCounts(ResidueCount residueCounts);
+ public abstract void setSSCounts(SecondaryStructureCount secondaryStructureCount);
+
/**
* Returns the percentage identity of the profile, i.e. the highest proportion
* @return
*/
public abstract float getPercentageIdentity(boolean ignoreGaps);
+
+ public abstract float getSSPercentageIdentity(boolean ignoreGaps);
/**
* Returns the full symbol counts for this profile
* @return
*/
public abstract int getMaxCount();
+ public abstract int getMaxSSCount();
/**
* Returns the symbol (or concatenated symbols) which have the highest count
* @return
*/
public abstract String getModalResidue();
+ public abstract String getModalSS();
/**
* Answers the number of non-gapped sequences in the profile
* @return
*/
public abstract int getNonGapped();
+ SecondaryStructureCount getSSCounts();
}
\ No newline at end of file
* consensus calculation property
*/
private boolean showSequenceLogo = false;
+
+
+ private boolean showSequenceSSLogo = false;
/**
* flag indicating if logo should be rendered normalised
private boolean hidecols = false;
AlignmentAnnotation consensus = null;
+
+
+ AlignmentAnnotation ssConsensus = null;
AlignmentAnnotation conservation = null;
private boolean showConsensusHistogram;
+
+ private boolean showSSConsensusHistogram;
private AnnotatedCollectionI context;
showSequenceLogo = seqsel.showSequenceLogo;
normaliseSequenceLogo = seqsel.normaliseSequenceLogo;
showConsensusHistogram = seqsel.showConsensusHistogram;
+ showSSConsensusHistogram = seqsel.showSSConsensusHistogram;
idColour = seqsel.idColour;
outlineColour = seqsel.outlineColour;
seqrep = seqsel.seqrep;
cs.setConsensus(cnsns);
upd = true;
}
+
+
+ ProfilesI ssCnsns = AAFrequency.calculateSS(sequences, startRes,
+ endRes + 1, showSequenceLogo);
+ if (ssConsensus != null)
+ {
+ _updateSSConsensusRow(ssCnsns, sequences.size());
+ upd = true;
+ }
+ if (cs != null)
+ {
+ cs.setSsConsensus(ssCnsns);
+ upd = true;
+ }
+
if ((conservation != null)
|| (cs != null && cs.conservationApplied()))
// for
// ignoreGapsInConsensusCalculation);
}
+
+ public ProfilesI ssConsensusData = null;
+
+ private void _updateSSConsensusRow(ProfilesI ssCnsns, long nseq)
+ {
+ if (ssConsensus == null)
+ {
+ getSSConsensus();
+ }
+ 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
+
+ AAFrequency.completeSSConsensus(ssConsensus, ssCnsns, startRes, endRes + 1,
+ ignoreGapsInConsensus, showSequenceLogo, nseq); // TODO: setting
+ // container
+ // for
+ // ignoreGapsInConsensusCalculation);
+ }
/**
* @param s
}
return consensus;
}
+
+ public AlignmentAnnotation getSSConsensus()
+ {
+ // TODO get or calculate and get consensus annotation row for this group
+ int aWidth = this.getWidth();
+ // pointer
+ // possibility
+ // here.
+ if (aWidth < 0)
+ {
+ return null;
+ }
+ 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";
+ }
+ return ssConsensus;
+ }
/**
* set this alignmentAnnotation object as the one used to render consensus
}
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;
+ }
/**
*
}
this.showConsensusHistogram = showConsHist;
}
+
+ public void setShowSSConsensusHistogram(boolean showSSConsHist)
+ {
+
+ if (showSSConsensusHistogram != showSSConsHist && consensus != null)
+ {
+ this.showSSConsensusHistogram = showSSConsHist;
+ recalcConservation();
+ }
+ this.showSSConsensusHistogram = showSSConsHist;
+ }
/**
* @return the showConsensusHistogram
}
ap.av.updateConservation(ap);
ap.av.updateConsensus(ap);
+ ap.av.updateSecondaryStructureConsensus(ap);
ap.av.updateStrucConsensus(ap);
}
}
viewport.setShowConsensusHistogram(showConsensusHistogram.getState());
alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
}
+
+ @Override
+ protected void showSSConsensusHistogram_actionPerformed(ActionEvent e)
+ {
+ viewport.setShowSSConsensusHistogram(showSSConsensusHistogram.getState());
+ alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
+ }
/*
* (non-Javadoc)
}
showConsensusHistogram = Cache.getDefault("SHOW_CONSENSUS_HISTOGRAM",
true);
- showSequenceLogo = Cache.getDefault("SHOW_CONSENSUS_LOGO", false);
+ showSSConsensusHistogram = Cache.getDefault("SHOW_SSCONSENSUS_HISTOGRAM",
+ true);
+ showSequenceLogo = Cache.getDefault("SHOW_CONSENSUS_LOGO", true);
normaliseSequenceLogo = Cache.getDefault("NORMALISE_CONSENSUS_LOGO",
false);
showGroupConsensus = Cache.getDefault("SHOW_GROUP_CONSENSUS", false);
if (residueShading != null)
{
residueShading.setConsensus(hconsensus);
+ residueShading.setSsConsensus(hSSConsensus);
}
setColourAppliesToAllGroups(true);
}
import jalview.analysis.AlignmentAnnotationUtils;
import jalview.analysis.AlignmentUtils;
import jalview.analysis.Conservation;
+import jalview.api.AlignCalcWorkerI;
import jalview.api.AlignViewportI;
import jalview.bin.Console;
import jalview.commands.ChangeCaseCommand;
import jalview.util.StringUtils;
import jalview.util.UrlLink;
import jalview.viewmodel.seqfeatures.FeatureRendererModel;
+import jalview.workers.SecondaryStructureConsensusThread;
/**
* The popup menu that is displayed on right-click on a sequence id, or in the
{
final AlignmentI alignment = this.ap.getAlignment();
AlignmentUtils.addReferenceAnnotations(candidates, alignment, null);
+
+ if(AlignmentUtils.isSSAnnotationPresent(candidates)) {
+ restartSSConsensusWorker();
+ }
+
refresh();
}
+
+
+ private void restartSSConsensusWorker() {
+
+ List<AlignCalcWorkerI> workers = ap.alignFrame.getViewport().getCalcManager()
+ .getRegisteredWorkersOfClass(SecondaryStructureConsensusThread.class);
+ if (!workers.isEmpty()) {
+
+ ap.alignFrame.getViewport().getCalcManager().startWorker(workers.remove(0));
+
+ }
+
+ }
+
+
protected void makeReferenceSeq_actionPerformed(ActionEvent actionEvent)
{
protected JCheckBoxMenuItem showGroupConservation = new JCheckBoxMenuItem();
- protected JCheckBoxMenuItem showConsensusHistogram = new JCheckBoxMenuItem();
+ protected JCheckBoxMenuItem showConsensusHistogram = new JCheckBoxMenuItem();
+
+ protected JCheckBoxMenuItem showSSConsensusHistogram = new JCheckBoxMenuItem();
protected JCheckBoxMenuItem showSequenceLogo = new JCheckBoxMenuItem();
showConsensusHistogram_actionPerformed(e);
}
+ });
+ showSSConsensusHistogram.setText(
+ MessageManager.getString("label.show_ssconsensus_histogram"));
+ showSSConsensusHistogram.addActionListener(new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ showConsensusHistogram_actionPerformed(e);
+ }
+
});
showSequenceLogo
.setText(MessageManager.getString("label.show_consensus_logo"));
autoAnnMenu.addSeparator();
autoAnnMenu.add(applyAutoAnnotationSettings);
autoAnnMenu.add(showConsensusHistogram);
+ autoAnnMenu.add(showSSConsensusHistogram);
autoAnnMenu.add(showSequenceLogo);
autoAnnMenu.add(normaliseSequenceLogo);
autoAnnMenu.addSeparator();
// TODO Auto-generated method stub
}
+
+ protected void showSSConsensusHistogram_actionPerformed(ActionEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
protected void showSequenceLogo_actionPerformed(ActionEvent e)
{
view.isIgnoreGapsinConsensus());
viewport.getResidueShading()
.setConsensus(viewport.getSequenceConsensusHash());
+ viewport.getResidueShading()
+ .setSsConsensus(viewport.getSequenceSSConsensusHash());
if (safeBoolean(view.isConservationSelected()) && cs != null)
{
viewport.getResidueShading()
private HiddenColumns hiddenColumns;
private ProfilesI hconsensus;
+
+ private ProfilesI hSSconsensus;
private Hashtable<String, Object>[] complementConsensus;
{
hiddenColumns = null;
hconsensus = null;
+ hSSconsensus = null;
complementConsensus = null;
hStrucConsensus = null;
fadedImage = null;
columnSelection = av.getColumnSelection();
hiddenColumns = av.getAlignment().getHiddenColumns();
hconsensus = av.getSequenceConsensusHash();
+ hSSconsensus = av.getSequenceSSConsensusHash();
complementConsensus = av.getComplementConsensusHash();
hStrucConsensus = av.getRnaStructureConsensusHash();
av_ignoreGapsConsensus = av.isIgnoreGapsConsensus();
}
}
}
+
+ else if(aa.autoCalculated && aa.label.startsWith("SecondaryStructureConsensus"))
+ {
+ return AAFrequency.extractProfile(
+ hSSconsensus.get(column),
+ av_ignoreGapsConsensus);
+
+ }
+
else
{
if (aa.autoCalculated && aa.label.startsWith("StrucConsensus"))
.getAlignmentStrucConsensusAnnotation();
final AlignmentAnnotation complementConsensusAnnot = av
.getComplementConsensusAnnotation();
+ final AlignmentAnnotation ssConsensusAnnot = av
+ .getAlignmentSecondaryStructureConsensusAnnotation();
BitSet graphGroupDrawn = new BitSet();
int charOffset = 0; // offset for a label
normaliseProfile = row.groupRef.isNormaliseSequenceLogo();
}
else if (row == consensusAnnot || row == structConsensusAnnot
- || row == complementConsensusAnnot)
+ || row == complementConsensusAnnot || row == ssConsensusAnnot)
{
renderHistogram = av_renderHistogram;
renderProfile = av_renderProfile;
* {profile type, #values, total count, char1, pct1, char2, pct2...}
*/
int profl[] = getProfileFor(_aa, column);
+
+
// just try to draw the logo if profl is not null
if (profl != null && profl[2] != 0)
}
else
{
+
colour = profcolour.findColour(dc[0], column, null);
+
}
g.setColor(colour == Color.white ? Color.lightGray : colour);
* the consensus data for each column
*/
private ProfilesI consensus;
+
+ /*
+ * the consensus data for each column
+ */
+ private ProfilesI ssConsensus;
+
+
+ public ProfilesI getSsConsensus()
+ {
+ return ssConsensus;
+ }
+
+ public void setSsConsensus(ProfilesI ssConsensus)
+ {
+ this.ssConsensus = ssConsensus;
+ }
/*
* if true, apply shading of colour by conservation
this.conservationIncrement = rs.conservationIncrement;
this.ignoreGaps = rs.ignoreGaps;
this.pidThreshold = rs.pidThreshold;
+ this.ssConsensus = rs.ssConsensus;
}
/**
public void setConsensus(ProfilesI cons)
{
consensus = cons;
+
}
/**
return colour;
}
+
+ @Override
+ public Color findSSColour(char symbol, int position, SequenceI seq)
+ {
+ if (colourScheme == null)
+ {
+ return Color.white; // Colour is 'None'
+ }
+
+ /*
+ * get 'base' colour
+ */
+ ProfileI profile = ssConsensus == null ? null : ssConsensus.get(position);
+ String modalSS = profile == null ? null
+ : profile.getModalSS();
+ float pid = profile == null ? 0f
+ : profile.getSSPercentageIdentity(ignoreGaps);
+ Color colour = colourScheme.findColour(symbol, position, seq,
+ modalSS, pid);
+
+ /*
+ * apply PID threshold and consensus fading if in force
+ */
+ if (!Comparison.isGap(symbol))
+ {
+ colour = adjustColour(symbol, position, colour);
+ }
+
+ return colour;
+ }
/**
* Adjusts colour by applying thresholding or conservation shading, if in
{
public abstract void setConsensus(ProfilesI cons);
+
+ public abstract void setSsConsensus(ProfilesI cons);
public abstract boolean conservationApplied();
public abstract void setColourScheme(ColourSchemeI cs);
+ Color findSSColour(char symbol, int position, SequenceI seq);
+
}
\ No newline at end of file
import jalview.workers.AlignCalcManager;
import jalview.workers.ComplementConsensusThread;
import jalview.workers.ConsensusThread;
+import jalview.workers.SecondaryStructureConsensusThread;
import jalview.workers.StrucConsensusThread;
/**
}
protected AlignmentAnnotation consensus;
+
+ protected AlignmentAnnotation secondaryStructureConsensus;
protected AlignmentAnnotation complementConsensus;
protected AlignmentAnnotation quality;
protected AlignmentAnnotation[] groupConsensus;
+
+ protected AlignmentAnnotation[] groupSSConsensus;
protected AlignmentAnnotation[] groupConservation;
* results of alignment consensus analysis for visible portion of view
*/
protected ProfilesI hconsensus = null;
+
+ protected ProfilesI hSSConsensus = null;
+
+
/**
* results of cDNA complement consensus visible portion of view
{
this.hconsensus = hconsensus;
}
-
+
+ @Override
+ public void setSequenceSSConsensusHash(ProfilesI hSSConsensus)
+ {
+ this.hSSConsensus = hSSConsensus;
+ }
+
@Override
public void setComplementConsensusHash(
Hashtable<String, Object>[] hconsensus)
{
return hconsensus;
}
+
+ @Override
+ public ProfilesI getSequenceSSConsensusHash()
+ {
+ return hSSConsensus;
+ }
@Override
public Hashtable<String, Object>[] getComplementConsensusHash()
return consensus;
}
+
+ @Override
+ public AlignmentAnnotation getAlignmentSecondaryStructureConsensusAnnotation()
+ {
+ return secondaryStructureConsensus;
+ }
+
+
@Override
public AlignmentAnnotation getAlignmentGapAnnotation()
{
}
}
}
+
+
+
+
+ /**
+ * trigger update of consensus annotation
+ */
+ public void updateSecondaryStructureConsensus(final AlignmentViewPanel ap)
+ {
+ // see note in mantis : issue number 8585
+ if (secondaryStructureConsensus == null || !autoCalculateConsensus)
+ {
+ return;
+ }
+ if (calculator
+ .getRegisteredWorkersOfClass(SecondaryStructureConsensusThread.class) == null)
+ {
+ calculator.registerWorker(new SecondaryStructureConsensusThread(this, ap));
+ }
+ }
// --------START Structure Conservation
public void updateStrucConsensus(final AlignmentViewPanel ap)
consensus = null;
complementConsensus = null;
strucConsensus = null;
+ secondaryStructureConsensus = null;
conservation = null;
quality = null;
groupConsensus = null;
* should consensus profile be rendered by default
*/
protected boolean showSequenceLogo = false;
+
+ protected boolean showSequenceSSLogo = false;
/**
* should consensus profile be rendered normalised to row height
* should consensus histograms be rendered by default
*/
protected boolean showConsensusHistogram = true;
+
+ protected boolean showSSConsensusHistogram = true;
+
+ public void setShowSSConsensusHistogram(boolean showSSConsensusHistogram)
+ {
+ this.showSSConsensusHistogram = showSSConsensusHistogram;
+ }
/**
* @return the showConsensusProfile
{
return showSequenceLogo;
}
+
+ @Override
+ public boolean isShowSequenceSSLogo()
+ {
+ return showSequenceSSLogo;
+ }
/**
* @param showSequenceLogo
}
this.showSequenceLogo = showSequenceLogo;
}
+
+ public void setShowSequenceSSLogo(boolean showSequenceSSLogo)
+ {
+ if (showSequenceSSLogo != this.showSequenceSSLogo)
+ {
+ // TODO: decouple settings setting from calculation when refactoring
+ // annotation update method from alignframe to viewport
+ this.showSequenceSSLogo = showSequenceSSLogo;
+ calculator.updateAnnotationFor(SecondaryStructureConsensusThread.class);
+ }
+ this.showSequenceSSLogo = showSequenceSSLogo;
+ }
/**
* @param showConsensusHistogram
{
return this.showConsensusHistogram;
}
+
+ @Override
+ public boolean isShowSSConsensusHistogram()
+ {
+ return this.showSSConsensusHistogram;
+ }
/**
* when set, updateAlignment will always ensure sequences are of equal length
if (ap != null)
{
updateConsensus(ap);
+ updateSecondaryStructureConsensus(ap);
if (residueShading != null)
{
residueShading.setThreshold(residueShading.getThreshold(),
if (autoCalculateConsensus)
{
updateConsensus(ap);
+ updateSecondaryStructureConsensus(ap);
}
if (hconsensus != null && autoCalculateConsensus)
{
consensus = new AlignmentAnnotation("Consensus",
MessageManager.getString("label.consensus_descr"),
new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
+
+ secondaryStructureConsensus = new AlignmentAnnotation("SecondaryStructureConsensus",
+ MessageManager.getString("label.ssconsensus_descr"),
+ new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
+
initConsensus(consensus);
+ initSSConsensus(secondaryStructureConsensus);
initGapCounts();
-
initComplementConsensus();
}
}
+
/**
* If this is a protein alignment and there are mappings to cDNA, adds the
* cDNA consensus annotation and returns true, else returns false.
alignment.addAnnotation(aa);
}
}
+
+ private void initSSConsensus(AlignmentAnnotation aa)
+ {
+ aa.hasText = true;
+ aa.autoCalculated = true;
+
+ if (showConsensus)
+ {
+ alignment.addAnnotation(aa);
+ }
+ }
// these should be extracted from the view model - style and settings for
// derived annotation
boolean conv = isShowGroupConservation();
boolean cons = isShowGroupConsensus();
boolean showprf = isShowSequenceLogo();
+ boolean showSSprf = isShowSequenceSSLogo();
boolean showConsHist = isShowConsensusHistogram();
+ boolean showSSConsHist = isShowSSConsensusHistogram();
boolean normLogo = isNormaliseSequenceLogo();
/**
{
// set defaults for this group's conservation/consensus
sg.setshowSequenceLogo(showprf);
+ sg.setshowSequenceSSLogo(showSSprf);
sg.setShowConsensusHistogram(showConsHist);
+ sg.setShowSSConsensusHistogram(showSSConsHist);
sg.setNormaliseSequenceLogo(normLogo);
}
if (conv)
{
updateCalcs = true;
alignment.addAnnotation(sg.getConsensus(), 0);
+ alignment.addAnnotation(sg.getSSConsensus(), 0);
}
// refresh the annotation rows
if (updateCalcs)
+ ((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
return sq;
}
+
+ public SequenceI getSSConsensusSeq()
+ {
+ if (secondaryStructureConsensus == null)
+ {
+ updateSecondaryStructureConsensus(null);
+ }
+ 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);
+ }
+ }
+ }
+
+ SequenceI sq = new Sequence("Sec Str Consensus", seqs.toString());
+ sq.setDescription("Percentage Identity Sec Str Consensus "
+ + ((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
+ return sq;
+ }
@Override
public void setCurrentTree(TreeModel tree)
*/
package jalview.workers;
-import jalview.api.AlignCalcManagerI;
-import jalview.api.AlignCalcWorkerI;
-import jalview.datamodel.AlignmentAnnotation;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
+import jalview.api.AlignCalcManagerI;
+import jalview.api.AlignCalcWorkerI;
+import jalview.datamodel.AlignmentAnnotation;
+
public class AlignCalcManager implements AlignCalcManagerI
{
/*