off by one for sequence associated annotation
[jalview.git] / src / jalview / ws / jws2 / AADisorderClient.java
1 package jalview.ws.jws2;
2
3 import jalview.api.AlignCalcWorkerI;
4 import jalview.bin.Cache;
5 import jalview.datamodel.AlignmentAnnotation;
6
7 import jalview.datamodel.GraphLine;
8 import jalview.datamodel.SequenceFeature;
9 import jalview.datamodel.SequenceI;
10 import jalview.gui.AlignFrame;
11 import jalview.schemes.GraduatedColor;
12 import jalview.schemes.UserColourScheme;
13 import jalview.ws.jws2.jabaws2.Jws2Instance;
14 import jalview.ws.params.WsParamSetI;
15
16 import java.awt.Color;
17 import java.util.ArrayList;
18 import java.util.HashMap;
19 import java.util.Hashtable;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.Map;
23 import compbio.data.sequence.Range;
24 import compbio.data.sequence.Score;
25 import compbio.data.sequence.ScoreManager.ScoreHolder;
26 import compbio.metadata.Argument;
27 import compbio.ws.client.Services;
28
29 public class AADisorderClient extends JabawsAlignCalcWorker implements
30         AlignCalcWorkerI
31 {
32
33   private static final String THRESHOLD = "THRESHOLD";
34
35   String typeName;
36
37   String methodName;
38
39   String groupName;
40
41   AlignFrame af;
42
43   public AADisorderClient(Jws2Instance sh, AlignFrame alignFrame,
44           WsParamSetI preset, List<Argument> paramset)
45   {
46     super(sh, alignFrame, preset, paramset);
47     af = alignFrame;
48     typeName = sh.action;
49     methodName = sh.serviceType;
50
51     submitGaps = false;
52     alignedSeqs = false;
53     nucleotidesAllowed = false;
54     proteinAllowed = true;
55     bySequence = true;
56   }
57
58   @Override
59   public String getServiceActionText()
60   {
61     return "Submitting amino acid sequences for disorder prediction.";
62   }
63
64   private static Map<String, Map<String, String[]>> featureMap;
65
66   private static Map<String, Map<String, Map<String, Object>>> annotMap;
67
68   private static String DONTCOMBINE = "DONTCOMBINE";
69   private static String INVISIBLE = "INVISIBLE";
70   static
71   {
72     // TODO: turn this into some kind of configuration file that's a bit easier to edit
73     featureMap = new HashMap<String, Map<String, String[]>>();
74     Map<String, String[]> fmap;
75     featureMap.put(compbio.ws.client.Services.IUPredWS.toString(),
76             fmap = new HashMap<String, String[]>());
77     fmap.put("Glob", new String[]
78     { "Globular Domain", "Predicted globular domain" });
79     featureMap.put(compbio.ws.client.Services.JronnWS.toString(),
80             fmap = new HashMap<String, String[]>());
81     featureMap.put(compbio.ws.client.Services.DisemblWS.toString(),
82             fmap = new HashMap<String, String[]>());
83     fmap.put("REM465", new String[]
84     { "REM465", "Missing density" });
85     fmap.put("HOTLOOPS", new String[]
86     { "HOTLOOPS", "Flexible loops" });
87     fmap.put("COILS", new String[]
88     { "COILS", "Random coil" });
89     featureMap.put(compbio.ws.client.Services.GlobPlotWS.toString(),
90             fmap = new HashMap<String, String[]>());
91     fmap.put("GlobDoms", new String[]
92     { "Globular Domain", "Predicted globular domain" });
93     fmap.put("Disorder", new String[]
94     { "Protein Disorder", "Probable unstructured peptide region" });
95     Map<String, Map<String, Object>> amap;
96     annotMap = new HashMap<String, Map<String, Map<String, Object>>>();
97     annotMap.put(compbio.ws.client.Services.GlobPlotWS.toString(),
98             amap = new HashMap<String, Map<String, Object>>());
99     amap.put("Dydx", new HashMap<String, Object>());
100     amap.get("Dydx").put(DONTCOMBINE, DONTCOMBINE);
101     amap.get("Dydx").put(THRESHOLD, new double[] {1, 0});
102     amap.put("SmoothedScore", new HashMap<String, Object>());
103     amap.get("SmoothedScore").put(INVISIBLE,INVISIBLE);
104     amap.put("RawScore", new HashMap<String, Object>());
105     amap.get("RawScore").put(INVISIBLE,INVISIBLE);
106     annotMap.put(compbio.ws.client.Services.DisemblWS.toString(),
107             amap = new HashMap<String, Map<String, Object>>());
108     amap.put("COILS", new HashMap<String, Object>());
109     amap.put("HOTLOOPS", new HashMap<String, Object>());
110     amap.put("REM465", new HashMap<String, Object>());
111     amap.get("COILS").put(THRESHOLD, new double[] { 1, 0.516});
112     amap.get("HOTLOOPS").put(THRESHOLD, new double[] { 1, 0.6});
113     amap.get("REM465").put(THRESHOLD, new double[] { 1, 0.1204});
114     
115     annotMap.put(compbio.ws.client.Services.IUPredWS.toString(),
116             amap = new HashMap<String, Map<String, Object>>());
117     amap.put("Long", new HashMap<String, Object>());
118     amap.put("Short", new HashMap<String, Object>());
119     amap.get("Long").put(THRESHOLD, new double[] { 1, 0.5});
120     amap.get("Short").put(THRESHOLD, new double[] { 1, 0.5});
121     annotMap.put(compbio.ws.client.Services.JronnWS.toString(),
122             amap = new HashMap<String, Map<String, Object>>());
123     amap.put("JRonn", new HashMap<String, Object>());
124     amap.get("JRonn").put(THRESHOLD, new double[] { 1, 0.5});
125   }
126
127   @Override
128   public void updateResultAnnotation(boolean immediate)
129   {
130
131     if (immediate || !calcMan.isWorking(this) && scoremanager != null)
132     {
133       Map<String, String[]> featureTypeMap = featureMap
134               .get(service.serviceType);
135       Map<String, Map<String, Object>> annotTypeMap = annotMap
136               .get(service.serviceType);
137       boolean dispFeatures = false;
138       Map<String, Object> fc = new Hashtable<String, Object>();
139       List<AlignmentAnnotation> ourAnnot = new ArrayList<AlignmentAnnotation>();
140       /**
141        * grouping for any annotation rows created
142        */
143       int graphGroup = 1;
144       if (alignViewport.getAlignment().getAlignmentAnnotation() != null)
145       {
146         for (AlignmentAnnotation ala : alignViewport.getAlignment()
147                 .getAlignmentAnnotation())
148         {
149           if (ala.graphGroup > graphGroup)
150           {
151             graphGroup = ala.graphGroup;
152           }
153         }
154       }
155
156       for (String seqId : seqNames.keySet())
157       {
158         boolean sameGroup = false;
159         SequenceI dseq, aseq, seq = seqNames.get(seqId);
160         int base = seq.getStart() - 1;
161         aseq = seq;
162         while ((dseq = seq).getDatasetSequence() != null)
163         {
164           seq = seq.getDatasetSequence();
165         }
166         ;
167         ScoreHolder scores = scoremanager.getAnnotationForSequence(seqId);
168         float last = Float.NaN, val = Float.NaN;
169         int lastAnnot = ourAnnot.size();
170         for (Score scr : scores.scores)
171         {
172
173           if (scr.getRanges() != null && scr.getRanges().size() > 0)
174           {
175             Iterator<Float> vals = scr.getScores().iterator();
176             // make features on sequence
177             for (Range rn : scr.getRanges())
178             {
179
180               SequenceFeature sf;
181               String[] type = featureTypeMap.get(scr.getMethod());
182               if (type == null)
183               {
184                 // create a default type for this feature
185                 type = new String[]
186                 { typeName + " (" + scr.getMethod() + ")",
187                     service.getActionText() };
188               }
189               if (vals.hasNext())
190               {
191                 sf = new SequenceFeature(type[0], type[1], base + rn.from,
192                         base + rn.to, val = vals.next().floatValue(),
193                         methodName);
194               }
195               else
196               {
197                 sf = new SequenceFeature(type[0], type[1], null, base
198                         + rn.from, base + rn.to, methodName);
199               }
200               dseq.addSequenceFeature(sf);
201               if (last != val && last != Float.NaN)
202               {
203                 fc.put(sf.getType(), sf);
204               }
205               last = val;
206               dispFeatures = true;
207             }
208           }
209           else
210           {
211             if (scr.getScores().size()==0)
212             {
213               continue;
214             }
215             AlignmentAnnotation annot = createAnnotationRowsForScores(
216                     ourAnnot, service.serviceType + " (" + scr.getMethod()
217                             + ")", service.getServiceTypeURI()+"/"+ scr.getMethod(), aseq,
218                     base+1, scr);
219             annot.graph = AlignmentAnnotation.LINE_GRAPH;
220             annot.visible = (annotTypeMap==null || annotTypeMap.get(scr.getMethod())==null || annotTypeMap.get(scr.getMethod()).get(INVISIBLE) == null);
221             double[] thrsh=(annotTypeMap==null || annotTypeMap.get(scr.getMethod())==null) ? null : (double[]) annotTypeMap.get(scr.getMethod()).get(THRESHOLD);
222             if (annotTypeMap==null || annotTypeMap.get(scr.getMethod())==null || annotTypeMap.get(scr.getMethod()).get(DONTCOMBINE) == null)
223             {
224               {
225                 if (!sameGroup)
226                 {
227                   graphGroup++;
228                   sameGroup = true;
229                 }
230
231                 annot.graphGroup = graphGroup;
232               }
233             }
234             
235             annot.description = "<html>"+service.getActionText() + " - raw scores";
236             if (thrsh!=null)
237             {
238               String threshNote=(thrsh[0]>0 ? "Above " : "Below ")+thrsh[1]+" indicates disorder";
239               annot.threshold=new GraphLine((float) thrsh[1], threshNote, Color.red);
240               annot.description+="<br/>"+threshNote;
241             }
242             annot.description+="</html>";
243             Color col = new UserColourScheme(typeName)
244                     .createColourFromName(typeName + scr.getMethod());
245             for (int p = 0, ps = annot.annotations.length; p < ps; p++)
246             {
247               if (annot.annotations[p] != null)
248               {
249                 annot.annotations[p].colour = col;
250               }
251             }
252             annot._linecolour=col;
253           }
254         }
255         if (lastAnnot + 1 == ourAnnot.size())
256         {
257           // remove singleton alignment annotation row
258           ourAnnot.get(lastAnnot).graphGroup = -1;
259         }
260       }
261       {
262         if (dispFeatures)
263         {
264           jalview.gui.FeatureRenderer fr = ((jalview.gui.AlignmentPanel) ap)
265                   .cloneFeatureRenderer();
266           for (String ft : fc.keySet())
267           {
268             Object gc = fr.getFeatureStyle(ft);
269             if (gc instanceof Color)
270             {
271               // set graduated color as fading to white for minimum, and
272               // autoscaling to values on alignment
273               GraduatedColor ggc = new GraduatedColor(Color.white,
274                       (Color) gc, Float.MIN_VALUE, Float.MAX_VALUE);
275               ggc.setAutoScaled(true);
276               fr.setColour(ft, ggc);
277             }
278           }
279           // TODO: JAL-1150 - create sequence feature settings API for defining styles and enabling/disabling feature overlay on alignment panel
280           ((jalview.gui.AlignmentPanel) ap).updateFeatureRendererFrom(fr);
281           if (af.alignPanel==ap)
282           {
283             // only do this if the alignFrame is currently showing this view.
284             af.setShowSeqFeatures(true);
285           } 
286           ap.paintAlignment(true);
287         }
288         if (ourAnnot.size() > 0)
289         {
290           // Modify the visible annotation on the alignment viewport with the
291           // new alignment annotation rows created.
292           updateOurAnnots(ourAnnot);
293           ap.adjustAnnotationHeight();
294         }
295       }
296     }
297   }
298
299 }