From 79912985d2d21c7d456bbd2281ed84fdfe2e99e7 Mon Sep 17 00:00:00 2001 From: jprocter Date: Fri, 19 Dec 2008 15:39:12 +0000 Subject: [PATCH] experimental: sort by feature UI in feature settings and variable height rendering of features by score --- src/jalview/gui/FeatureRenderer.java | 121 ++++++++++++++++++++++++++- src/jalview/gui/FeatureSettings.java | 152 ++++++++++++++++++++++------------ 2 files changed, 218 insertions(+), 55 deletions(-) diff --git a/src/jalview/gui/FeatureRenderer.java b/src/jalview/gui/FeatureRenderer.java index 9eacb6c..b6806e7 100755 --- a/src/jalview/gui/FeatureRenderer.java +++ b/src/jalview/gui/FeatureRenderer.java @@ -43,7 +43,9 @@ public class FeatureRenderer AlignViewport av; Color resBoxColour; - + /** + * global transparency for feature + */ float transparency = 1.0f; FontMetrics fm; @@ -248,6 +250,11 @@ public class FeatureRenderer int sfSize, sfindex, spos, epos; + /** + * show scores as heights + */ + protected boolean varyHeight=false; + synchronized public void drawSequence(Graphics g, SequenceI seq, int start, int end, int y1) { @@ -366,6 +373,13 @@ public class FeatureRenderer } else + if (av.showSeqFeaturesHeight && sequenceFeatures[sfindex].score!=Float.NaN) + { + renderScoreFeature(g, seq, seq + .findIndex(sequenceFeatures[sfindex].begin) - 1, seq + .findIndex(sequenceFeatures[sfindex].end) - 1, + getColour(sequenceFeatures[sfindex].type), start, end, y1, normaliseScore(sequenceFeatures[sfindex])); + } else { renderFeature(g, seq, seq .findIndex(sequenceFeatures[sfindex].begin) - 1, seq @@ -384,6 +398,28 @@ public class FeatureRenderer 1.0f)); } } + Hashtable minmax = new Hashtable(); + /** + * normalise a score against the max/min bounds for the feature type. + * @param sequenceFeature + * @return byte[] { signed, normalised signed (-127 to 127) or unsigned (0-255) value. + */ + private final byte[] normaliseScore(SequenceFeature sequenceFeature) + { + float[] mm = (float[]) minmax.get(sequenceFeature.type); + final byte[] r=new byte[] { 0, (byte) 255}; + if (mm!=null) + { + if (r[0]!=0 || mm[0]<0.0) + { + r[0]=1; + r[1]=(byte) ((int) 128.0+127.0*(sequenceFeature.score/mm[1])); + } else { + r[1]=(byte) ((int) 255.0*(sequenceFeature.score/mm[1])); + } + } + return r; + } char s; @@ -432,6 +468,67 @@ public class FeatureRenderer } } } + void renderScoreFeature(Graphics g, SequenceI seq, int fstart, int fend, + Color featureColour, int start, int end, int y1, byte[] bs) + { + + if (((fstart <= end) && (fend >= start))) + { + if (fstart < start) + { // fix for if the feature we have starts before the sequence start, + fstart = start; // but the feature end is still valid!! + } + + if (fend >= end) + { + fend = end; + } + int pady = (y1 + av.charHeight) - av.charHeight / 5; + int ystrt = 0,yend=av.charHeight; + if (bs[0]!=0) + { + // signed - zero is always middle of residue line. + if (bs[1]<128) + { + yend = av.charHeight*(128-bs[1])/512; + ystrt = av.charHeight-yend/2; + } else { + ystrt = av.charHeight/2; + yend = av.charHeight*(bs[1]-128)/512; + } + } else { + yend = av.charHeight*bs[1]/255; + ystrt = av.charHeight-yend; + + } + for (i = fstart; i <= fend; i++) + { + s = seq.getCharAt(i); + + if (jalview.util.Comparison.isGap(s)) + { + continue; + } + + g.setColor(featureColour); + int x=(i-start)*av.charWidth; + g.drawRect(x, y1, av.charWidth, av.charHeight); + g.fillRect(x, y1+ystrt, av.charWidth, + yend); + + if (offscreenRender || !av.validCharWidth) + { + continue; + } + + g.setColor(Color.black); + charOffset = (av.charWidth - fm.charWidth(s)) / 2; + g.drawString(String.valueOf(s), charOffset + + (av.charWidth * (i - start)), pady); + + } + } + } boolean newFeatureAdded = false; @@ -503,6 +600,10 @@ public class FeatureRenderer } } } + if (minmax==null) + { + minmax = new Hashtable(); + } for (int i = 0; i < av.alignment.getHeight(); i++) { SequenceFeature[] features = av.alignment.getSequenceAt(i) @@ -552,6 +653,24 @@ public class FeatureRenderer { allfeatures.addElement(features[index].getType()); } + if (features[index].score!=Float.NaN) + { + float[] mm = (float[]) minmax.get(features[index].getType()); + if (mm==null) + { + mm = new float[] { features[index].score,features[index].score}; + minmax.put(features[index].getType(), mm); + } else { + if (mm[0]>features[index].score) + { + mm[0] = features[index].score; + } + if (mm[1] -1; ro--) @@ -617,8 +646,8 @@ public class FeatureSettings extends JPanel if (awidth[0] > 0) { width[i] = awidth[1] / awidth[0];// *awidth[0]*awidth[2]; - better - // weight - but have to make per - // sequence, too (awidth[2]) + // weight - but have to make per + // sequence, too (awidth[2]) // if (width[i]==1) // hack to distinguish single width sequences. num++; } @@ -714,7 +743,9 @@ public class FeatureSettings extends JPanel JButton cancelDAS = new JButton(); JButton optimizeOrder = new JButton(); + JButton sortByScore = new JButton(); + JButton sortByDens = new JButton(); JPanel transbuttons = new JPanel(new BorderLayout()); @@ -760,7 +791,8 @@ public class FeatureSettings extends JPanel { sortByDens(null); } - }); cancel.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11)); + }); + cancel.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11)); cancel.setText("Cancel"); cancel.addActionListener(new ActionListener() { @@ -861,48 +893,51 @@ public class FeatureSettings extends JPanel { sortBy(typ, "Sort by Density", AlignmentSorter.FEATURE_DENSITY); } - protected void sortBy(String[] typ, String methodText, final String method) { - if (typ==null) + + protected void sortBy(String[] typ, String methodText, final String method) + { + if (typ == null) { typ = getDisplayedFeatureTypes(); } - String gps[]=null; + String gps[] = null; gps = getDisplayedFeatureGroups(); - if (typ!=null) + if (typ != null) { - for (int i=0;i