import jalview.analysis.AlignmentUtils;
import jalview.analysis.SequenceIdMatcher;
import jalview.api.AlignViewportI;
+import jalview.api.FeatureColourI;
import jalview.api.FeaturesSourceI;
import jalview.datamodel.AlignedCodonFrame;
import jalview.datamodel.Alignment;
import jalview.io.gff.GffHelperBase;
import jalview.io.gff.GffHelperFactory;
import jalview.io.gff.GffHelperI;
-import jalview.schemes.AnnotationColourGradient;
-import jalview.schemes.GraduatedColor;
+import jalview.schemes.FeatureColour;
import jalview.schemes.UserColourScheme;
import jalview.util.Format;
import jalview.util.MapList;
import jalview.util.ParseHtmlBodyAndLinks;
import jalview.util.StringUtils;
-import java.awt.Color;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
* - process html strings into plain text
* @return true if features were added
*/
- public boolean parse(AlignmentI align, Map<String, Object> colours,
+ public boolean parse(AlignmentI align,
+ Map<String, FeatureColourI> colours,
boolean removeHTML)
{
return parse(align, colours, removeHTML, false);
* - when true, ID matches to compound sequence IDs are allowed
* @return true if features were added
*/
- public boolean parse(AlignmentI align, Map<String, Object> colours,
+ public boolean parse(AlignmentI align,
+ Map<String, FeatureColourI> colours,
boolean removeHTML, boolean relaxedIdmatching)
{
Map<String, String> gffProps = new HashMap<String, String>();
* @param featureGroup
*/
protected boolean parseJalviewFeature(String line, String[] gffColumns,
- AlignmentI alignment, Map<String, Object> featureColours,
+ AlignmentI alignment, Map<String, FeatureColourI> featureColours,
boolean removeHTML, boolean relaxedIdMatching, String featureGroup)
{
/*
* synthesize a colour from the feature type
*/
UserColourScheme ucs = new UserColourScheme(ft);
- featureColours.put(ft, ucs.findColour('A'));
+ featureColours.put(ft, new FeatureColour(ucs.findColour('A')));
}
SequenceFeature sf = new SequenceFeature(ft, desc, "", startPos,
endPos, featureGroup);
* map to which to add derived colour specification
*/
protected void parseFeatureColour(String line, String featureType,
- String[] gffColumns, Map<String, Object> colours)
+ String[] gffColumns, Map<String, FeatureColourI> colours)
{
- Object colour = null;
+ FeatureColourI colour = null;
String colscheme = gffColumns[1];
if (colscheme.indexOf("|") > -1
|| colscheme.trim().equalsIgnoreCase("label"))
else
{
UserColourScheme ucs = new UserColourScheme(colscheme);
- colour = ucs.findColour('A');
+ colour = new FeatureColour(ucs.findColour('A'));
}
if (colour != null)
{
* @param colourDescriptor
* @return
*/
- protected GraduatedColor parseGraduatedColourScheme(String line,
+ protected FeatureColourI parseGraduatedColourScheme(String line,
String colourDescriptor)
{
// Parse '|' separated graduated colourscheme fields:
maxcol = "000000";
}
- GraduatedColor colour = null;
+ FeatureColourI colour = null;
try
{
- colour = new GraduatedColor(
+ colour = new FeatureColour(
new UserColourScheme(mincol).findColour('A'),
new UserColourScheme(maxcol).findColour('A'), min, max);
} catch (Exception e)
colour.setAutoScaled(abso == null);
// add in any additional parameters
String ttype = null, tval = null;
+ boolean hasThreshold = false;
if (gcol.hasMoreTokens())
{
// threshold type and possibly a threshold value
ttype = gcol.nextToken();
if (ttype.toLowerCase().startsWith("below"))
{
- colour.setThreshType(AnnotationColourGradient.BELOW_THRESHOLD);
+ colour.setBelowThreshold(true);
+ hasThreshold = true;
}
else if (ttype.toLowerCase().startsWith("above"))
{
- colour.setThreshType(AnnotationColourGradient.ABOVE_THRESHOLD);
+ colour.setAboveThreshold(true);
+ hasThreshold = true;
}
else
{
- colour.setThreshType(AnnotationColourGradient.NO_THRESHOLD);
if (!ttype.toLowerCase().startsWith("no"))
{
System.err.println("Ignoring unrecognised threshold type : "
}
}
}
- if (colour.getThreshType() != AnnotationColourGradient.NO_THRESHOLD)
+ if (hasThreshold)
{
try
{
gcol.nextToken();
tval = gcol.nextToken();
- colour.setThresh(new Float(tval).floatValue());
+ colour.setThreshold(new Float(tval).floatValue());
} catch (Exception e)
{
System.err.println("Couldn't parse threshold value as a float: ("
* @return features file contents
*/
public String printJalviewFormat(SequenceI[] sequences,
- Map<String, Object> visible)
+ Map<String, FeatureColourI> visible)
{
return printJalviewFormat(sequences, visible, true, true);
}
*
* @param sequences
* source of features
- * @param visible
+ * @param featureColours
* hash of Colours for each feature type
* @param visOnly
* when true only feature types in 'visible' will be output
* @return features file contents
*/
public String printJalviewFormat(SequenceI[] sequences,
- Map<String, Object> visible, boolean visOnly, boolean nonpos)
+ Map<String, FeatureColourI> featureColours, boolean visOnly,
+ boolean nonpos)
{
StringBuilder out = new StringBuilder(256);
boolean featuresGen = false;
- if (visOnly && !nonpos && (visible == null || visible.size() < 1))
+ if (visOnly && !nonpos
+ && (featureColours == null || featureColours.size() < 1))
{
// no point continuing.
return "No Features Visible";
}
- if (visible != null && visOnly)
+ if (featureColours != null && visOnly)
{
// write feature colours only if we're given them and we are generating
// viewed features
// TODO: decide if feature links should also be written here ?
- Iterator<String> en = visible.keySet().iterator();
+ Iterator<String> en = featureColours.keySet().iterator();
String featureType, color;
while (en.hasNext())
{
- featureType = en.next().toString();
-
- if (visible.get(featureType) instanceof GraduatedColor)
+ featureType = en.next();
+ FeatureColourI fc = featureColours.get(featureType);
+ if (fc.isSimpleColour())
{
- GraduatedColor gc = (GraduatedColor) visible.get(featureType);
- color = (gc.isColourByLabel() ? "label|" : "")
- + Format.getHexString(gc.getMinColor()) + "|"
- + Format.getHexString(gc.getMaxColor())
- + (gc.isAutoScale() ? "|" : "|abso|") + gc.getMin() + "|"
- + gc.getMax() + "|";
- if (gc.getThreshType() != AnnotationColourGradient.NO_THRESHOLD)
- {
- if (gc.getThreshType() == AnnotationColourGradient.BELOW_THRESHOLD)
+ color = Format.getHexString(fc.getColour());
+ }
+ else
+ {
+ color = (fc.isColourByLabel() ? "label|" : "")
+ + Format.getHexString(fc.getMinColour()) + "|"
+ + Format.getHexString(fc.getMaxColour())
+ + (fc.isAutoScaled() ? "|" : "|abso|") + fc.getMin() + "|"
+ + fc.getMax() + "|";
+ if (fc.isBelowThreshold())
{
color += "below";
}
- else
+ else if (fc.isAboveThreshold())
{
- if (gc.getThreshType() != AnnotationColourGradient.ABOVE_THRESHOLD)
- {
- System.err.println("WARNING: Unsupported threshold type ("
- + gc.getThreshType() + ") : Assuming 'above'");
- }
color += "above";
}
// add the value
- color += "|" + gc.getThresh();
+ color += "|" + fc.getThreshold();
}
- else
- {
- color += "none";
- }
- }
- else if (visible.get(featureType) instanceof Color)
- {
- color = Format.getHexString((Color) visible.get(featureType));
- }
- else
- {
- // legacy support for integer objects containing colour triplet values
- color = Format.getHexString(new Color(Integer.parseInt(visible
- .get(featureType).toString())));
- }
+// else
+// {
+// color += "none";
+// }
+ // else
+ // {
+ // // legacy support for integer objects containing colour triplet
+ // values
+ // color = Format.getHexString(new Color(Integer
+ // .parseInt(fc.toString())));
+ // }
out.append(featureType);
out.append(TAB);
out.append(color);
{
isnonpos = features[j].begin == 0 && features[j].end == 0;
if ((!nonpos && isnonpos)
- || (!isnonpos && visOnly && !visible
+ || (!isnonpos && visOnly && !featureColours
.containsKey(features[j].type)))
{
continue;
{
isnonpos = features[j].begin == 0 && features[j].end == 0;
if ((!nonpos && isnonpos)
- || (!isnonpos && visOnly && !visible
+ || (!isnonpos && visOnly && !featureColours
.containsKey(features[j].type)))
{
// skip if feature is nonpos and we ignore them or if we only
* @return
*/
public String printGffFormat(SequenceI[] sequences,
- Map<String, Object> visible)
+ Map<String, FeatureColourI> visible)
{
return printGffFormat(sequences, visible, true, true);
}
*
* @param sequences
* the sequences whose features are to be output
- * @param visible
+ * @param featureColours
* a map whose keys are the type names of visible features
* @param outputVisibleOnly
* @param includeNonPositionalFeatures
* @return
*/
public String printGffFormat(SequenceI[] sequences,
- Map<String, Object> visible, boolean outputVisibleOnly,
+ Map<String, FeatureColourI> featureColours,
+ boolean outputVisibleOnly,
boolean includeNonPositionalFeatures)
{
StringBuilder out = new StringBuilder(256);
// TODO why the test !isnonpos here?
// what about not visible non-positional features?
if (!isnonpos && outputVisibleOnly
- && !visible.containsKey(sf.type))
+ && !featureColours.containsKey(sf.type))
{
/*
* ignore not visible features if not wanted