package jalview.schemes;
import jalview.analysis.Conservation;
-import jalview.analysis.Profile;
+import jalview.datamodel.AlignmentI;
import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.ProfileI;
+import jalview.datamodel.ProfilesI;
import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceI;
+import jalview.util.ColorUtils;
import jalview.util.Comparison;
-import jalview.util.MessageManager;
import java.awt.Color;
import java.util.Map;
/**
- * DOCUMENT ME!
- *
- * @author $author$
- * @version $Revision$
+ * Base class for residue-based colour schemes
*/
-public class ResidueColourScheme implements ColourSchemeI
+public abstract class ResidueColourScheme implements ColourSchemeI
{
+ public static final String NONE = "None";
+
+ public static final String USER_DEFINED = "User Defined";
+
+ /*
+ * lookup up by character value e.g. 'G' to the colors array index
+ * e.g. if symbolIndex['K'] = 11 then colors[11] is the colour for K
+ */
final int[] symbolIndex;
boolean conservationColouring = false;
+ /*
+ * colour for residue characters as indexed by symbolIndex
+ */
Color[] colors = null;
int threshold = 0;
/*
* Consensus data indexed by column
*/
- Profile[] consensus;
+ ProfilesI consensus;
/*
* Conservation string as a char array
}
/**
+ * Returns the colour for symbol 'A'. Intended for use in a 'fixed colour'
+ * colour scheme (for example a feature colour).
+ */
+ @Override
+ public Color findColour()
+ {
+ // TODO delete this method in favour of ColorUtils.parseColourString()?
+ return findColour('A');
+ }
+
+ /**
* Find a colour without an index in a sequence
*/
@Override
residue -= ('a' - 'A');
}
- if (consensus == null || consensus.length < column
- || consensus[column] == null)
+ if (consensus == null)
{
return false;
}
+ ProfileI profile = consensus.get(column);
+
/*
* test whether this is the consensus (or joint consensus) residue
*/
- if (consensus[column].getModalResidue().contains(
- String.valueOf(residue)))
+ if (profile != null
+ && profile.getModalResidue().contains(String.valueOf(residue)))
{
- if (consensus[column].getPercentageIdentity(ignoreGaps) >= threshold)
+ if (profile.getPercentageIdentity(ignoreGaps) >= threshold)
{
return true;
}
* DOCUMENT ME!
*/
@Override
- public void setConsensus(Profile[] consensus)
+ public void setConsensus(ProfilesI consensus)
{
if (consensus == null)
{
float bleachFactor = (11 - (conservationScore - '0')) / 10f;
/*
- * scale this by the percentage slider / 20
+ * scale this up by 0-5 (percentage slider / 20)
+ * as a result, scores of: 0 1 2 3 4 5 6 7 8 9
+ * fade to white at slider value: 18 20 22 25 29 33 40 50 67 100%
*/
bleachFactor *= (inc / 20f);
- int red = currentColour.getRed();
- int green = currentColour.getGreen();
- int blue = currentColour.getBlue();
+ return ColorUtils.bleachColour(currentColour, bleachFactor);
+ }
+
+ @Override
+ public void alignmentChanged(AnnotatedCollectionI alignment,
+ Map<SequenceI, SequenceCollectionI> hiddenReps)
+ {
+ }
+
+ /**
+ * Answers false if the colour scheme is nucleotide or peptide specific, and
+ * the data does not match, else true. Override to modify or extend this test
+ * as required.
+ */
+ @Override
+ public boolean isApplicableTo(AnnotatedCollectionI ac)
+ {
+ if (!isPeptideSpecific() && !isNucleotideSpecific())
+ {
+ return true;
+ }
/*
- * bleach colours towards white (255, 255, 255),
- * depending on the consensus score and the conservation slider value
- * scores of: 0 1 2 3 4 5 6 7 8 9
- * fade to white at slider value: 18 20 22 25 29 33 40 50 67 100%
+ * inspect the data context (alignment) for residue type
*/
- red += (255 - red) * bleachFactor;
- green += (255 - green) * bleachFactor;
- blue += (255 - blue) * bleachFactor;
-
- if (red > 255 || green > 255 || blue > 255)
+ boolean nucleotide = false;
+ if (ac instanceof AlignmentI)
{
- currentColour = Color.white;
+ nucleotide = ((AlignmentI) ac).isNucleotide();
}
else
{
- currentColour = new Color(red, green, blue);
+ AnnotatedCollectionI context = ac.getContext();
+ if (context instanceof AlignmentI)
+ {
+ nucleotide = ((AlignmentI) context).isNucleotide();
+ }
+ else
+ {
+ // not sure what's going on, play safe
+ return true;
+ }
}
- return currentColour;
+
+ /*
+ * does data type match colour scheme type?
+ */
+ return (nucleotide && isNucleotideSpecific())
+ || (!nucleotide && isPeptideSpecific());
}
- @Override
- public void alignmentChanged(AnnotatedCollectionI alignment,
- Map<SequenceI, SequenceCollectionI> hiddenReps)
+ /**
+ * Answers true if the colour scheme is normally only for peptide data
+ *
+ * @return
+ */
+ public boolean isPeptideSpecific()
{
+ return false;
}
+ /**
+ * Answers true if the colour scheme is normally only for nucleotide data
+ *
+ * @return
+ */
+ public boolean isNucleotideSpecific()
+ {
+ return false;
+ }
+
+ /**
+ * Default method returns true. Override this to return false in colour
+ * schemes that are not determined solely by the sequence symbol.
+ */
@Override
- public ColourSchemeI applyTo(AnnotatedCollectionI sg,
- Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
+ public boolean isSimple()
{
- try
- {
- return getClass().newInstance();
- } catch (Exception q)
- {
- throw new Error(MessageManager.formatMessage(
- "error.implementation_error_cannot_duplicate_colour_scheme",
- new String[] { getClass().getName() }), q);
- }
+ return true;
}
}