JAL-1517 source formatting
[jalview.git] / src / jalview / ws / jws2 / AADisorderClient.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3  * Copyright (C) 2014 The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.ws.jws2;
22
23 import jalview.api.AlignCalcWorkerI;
24 import jalview.bin.Cache;
25 import jalview.datamodel.AlignmentAnnotation;
26 import jalview.datamodel.GraphLine;
27 import jalview.datamodel.SequenceFeature;
28 import jalview.datamodel.SequenceI;
29 import jalview.gui.AlignFrame;
30 import jalview.schemes.GraduatedColor;
31 import jalview.schemes.UserColourScheme;
32 import jalview.ws.jws2.jabaws2.Jws2Instance;
33 import jalview.ws.params.WsParamSetI;
34
35 import java.awt.Color;
36 import java.util.ArrayList;
37 import java.util.HashMap;
38 import java.util.Hashtable;
39 import java.util.Iterator;
40 import java.util.List;
41 import java.util.Map;
42
43 import compbio.data.sequence.Range;
44 import compbio.data.sequence.Score;
45 import compbio.data.sequence.ScoreManager.ScoreHolder;
46 import compbio.metadata.Argument;
47
48 public class AADisorderClient extends JabawsCalcWorker implements
49         AlignCalcWorkerI
50 {
51
52   private static final String THRESHOLD = "THRESHOLD";
53
54   private static final String RANGE = "RANGE";
55
56   String typeName;
57
58   String methodName;
59
60   String groupName;
61
62   AlignFrame af;
63
64   public AADisorderClient(Jws2Instance sh, AlignFrame alignFrame,
65           WsParamSetI preset, List<Argument> paramset)
66   {
67     super(sh, alignFrame, preset, paramset);
68     af = alignFrame;
69     typeName = sh.action;
70     methodName = sh.serviceType;
71
72     submitGaps = false;
73     alignedSeqs = false;
74     nucleotidesAllowed = false;
75     proteinAllowed = true;
76     bySequence = true;
77   }
78
79   @Override
80   public String getServiceActionText()
81   {
82     return "Submitting amino acid sequences for disorder prediction.";
83   }
84
85   private static Map<String, Map<String, String[]>> featureMap;
86
87   private static Map<String, Map<String, Map<String, Object>>> annotMap;
88
89   private static String DONTCOMBINE = "DONTCOMBINE";
90
91   private static String INVISIBLE = "INVISIBLE";
92   static
93   {
94     // TODO: turn this into some kind of configuration file that's a bit easier
95     // to edit
96     featureMap = new HashMap<String, Map<String, String[]>>();
97     Map<String, String[]> fmap;
98     featureMap.put(compbio.ws.client.Services.IUPredWS.toString(),
99             fmap = new HashMap<String, String[]>());
100     fmap.put("Glob", new String[]
101     { "Globular Domain", "Predicted globular domain" });
102     featureMap.put(compbio.ws.client.Services.JronnWS.toString(),
103             fmap = new HashMap<String, String[]>());
104     featureMap.put(compbio.ws.client.Services.DisemblWS.toString(),
105             fmap = new HashMap<String, String[]>());
106     fmap.put("REM465", new String[]
107     { "REM465", "Missing density" });
108     fmap.put("HOTLOOPS", new String[]
109     { "HOTLOOPS", "Flexible loops" });
110     fmap.put("COILS", new String[]
111     { "COILS", "Random coil" });
112     featureMap.put(compbio.ws.client.Services.GlobPlotWS.toString(),
113             fmap = new HashMap<String, String[]>());
114     fmap.put("GlobDoms", new String[]
115     { "Globular Domain", "Predicted globular domain" });
116     fmap.put("Disorder", new String[]
117     { "Protein Disorder", "Probable unstructured peptide region" });
118     Map<String, Map<String, Object>> amap;
119     annotMap = new HashMap<String, Map<String, Map<String, Object>>>();
120     annotMap.put(compbio.ws.client.Services.GlobPlotWS.toString(),
121             amap = new HashMap<String, Map<String, Object>>());
122     amap.put("Dydx", new HashMap<String, Object>());
123     amap.get("Dydx").put(DONTCOMBINE, DONTCOMBINE);
124     amap.get("Dydx").put(THRESHOLD, new double[]
125     { 1, 0 });
126     amap.get("Dydx").put(RANGE, new float[]
127     { -1, +1 });
128
129     amap.put("SmoothedScore", new HashMap<String, Object>());
130     amap.get("SmoothedScore").put(INVISIBLE, INVISIBLE);
131     amap.put("RawScore", new HashMap<String, Object>());
132     amap.get("RawScore").put(INVISIBLE, INVISIBLE);
133     annotMap.put(compbio.ws.client.Services.DisemblWS.toString(),
134             amap = new HashMap<String, Map<String, Object>>());
135     amap.put("COILS", new HashMap<String, Object>());
136     amap.put("HOTLOOPS", new HashMap<String, Object>());
137     amap.put("REM465", new HashMap<String, Object>());
138     amap.get("COILS").put(THRESHOLD, new double[]
139     { 1, 0.516 });
140     amap.get("COILS").put(RANGE, new float[]
141     { 0, 1 });
142
143     amap.get("HOTLOOPS").put(THRESHOLD, new double[]
144     { 1, 0.6 });
145     amap.get("HOTLOOPS").put(RANGE, new float[]
146     { 0, 1 });
147     amap.get("REM465").put(THRESHOLD, new double[]
148     { 1, 0.1204 });
149     amap.get("REM465").put(RANGE, new float[]
150     { 0, 1 });
151
152     annotMap.put(compbio.ws.client.Services.IUPredWS.toString(),
153             amap = new HashMap<String, Map<String, Object>>());
154     amap.put("Long", new HashMap<String, Object>());
155     amap.put("Short", new HashMap<String, Object>());
156     amap.get("Long").put(THRESHOLD, new double[]
157     { 1, 0.5 });
158     amap.get("Long").put(RANGE, new float[]
159     { 0, 1 });
160     amap.get("Short").put(THRESHOLD, new double[]
161     { 1, 0.5 });
162     amap.get("Short").put(RANGE, new float[]
163     { 0, 1 });
164     annotMap.put(compbio.ws.client.Services.JronnWS.toString(),
165             amap = new HashMap<String, Map<String, Object>>());
166     amap.put("JRonn", new HashMap<String, Object>());
167     amap.get("JRonn").put(THRESHOLD, new double[]
168     { 1, 0.5 });
169     amap.get("JRonn").put(RANGE, new float[]
170     { 0, 1 });
171   }
172
173   @Override
174   public void updateResultAnnotation(boolean immediate)
175   {
176
177     if (immediate || !calcMan.isWorking(this) && scoremanager != null)
178     {
179       Map<String, String[]> featureTypeMap = featureMap
180               .get(service.serviceType);
181       Map<String, Map<String, Object>> annotTypeMap = annotMap
182               .get(service.serviceType);
183       boolean dispFeatures = false;
184       Map<String, Object> fc = new Hashtable<String, Object>();
185       List<AlignmentAnnotation> ourAnnot = new ArrayList<AlignmentAnnotation>();
186       /**
187        * grouping for any annotation rows created
188        */
189       int graphGroup = 1;
190       if (alignViewport.getAlignment().getAlignmentAnnotation() != null)
191       {
192         for (AlignmentAnnotation ala : alignViewport.getAlignment()
193                 .getAlignmentAnnotation())
194         {
195           if (ala.graphGroup > graphGroup)
196           {
197             graphGroup = ala.graphGroup;
198           }
199         }
200       }
201
202       for (String seqId : seqNames.keySet())
203       {
204         boolean sameGroup = false;
205         SequenceI dseq, aseq, seq = seqNames.get(seqId);
206         int base = seq.findPosition(start) - 1;
207         aseq = seq;
208         while ((dseq = seq).getDatasetSequence() != null)
209         {
210           seq = seq.getDatasetSequence();
211         }
212         ScoreHolder scores = null;
213         try
214         {
215           scores = scoremanager.getAnnotationForSequence(seqId);
216         } catch (Exception q)
217         {
218           Cache.log
219                   .info("Couldn't recover disorder prediction for sequence "
220                           + seq.getName()
221                           + "(Prediction name was "
222                           + seqId
223                           + ")"
224                           + "\nSee http://issues.jalview.org/browse/JAL-1319 for one possible reason why disorder predictions might fail.");
225         }
226         float last = Float.NaN, val = Float.NaN;
227         int lastAnnot = ourAnnot.size();
228         if (scores != null && scores.scores != null)
229         {
230           for (Score scr : scores.scores)
231           {
232
233             if (scr.getRanges() != null && scr.getRanges().size() > 0)
234             {
235               Iterator<Float> vals = scr.getScores().iterator();
236               // make features on sequence
237               for (Range rn : scr.getRanges())
238               {
239
240                 SequenceFeature sf;
241                 String[] type = featureTypeMap.get(scr.getMethod());
242                 if (type == null)
243                 {
244                   // create a default type for this feature
245                   type = new String[]
246                   { typeName + " (" + scr.getMethod() + ")",
247                       service.getActionText() };
248                 }
249                 if (vals.hasNext())
250                 {
251                   sf = new SequenceFeature(type[0], type[1],
252                           base + rn.from, base + rn.to, val = vals.next()
253                                   .floatValue(), methodName);
254                 }
255                 else
256                 {
257                   sf = new SequenceFeature(type[0], type[1], null, base
258                           + rn.from, base + rn.to, methodName);
259                 }
260                 dseq.addSequenceFeature(sf);
261                 if (last != val && last != Float.NaN)
262                 {
263                   fc.put(sf.getType(), sf);
264                 }
265                 last = val;
266                 dispFeatures = true;
267               }
268             }
269             else
270             {
271               if (scr.getScores().size() == 0)
272               {
273                 continue;
274               }
275               AlignmentAnnotation annot = createAnnotationRowsForScores(
276                       ourAnnot,
277                       service.serviceType + " (" + scr.getMethod() + ")",
278                       service.getServiceTypeURI() + "/" + scr.getMethod(),
279                       aseq, base + 1, scr);
280               annot.graph = AlignmentAnnotation.LINE_GRAPH;
281
282               Map<String, Object> styleMap = (annotTypeMap == null) ? null
283                       : annotTypeMap.get(scr.getMethod());
284
285               annot.visible = (styleMap == null || styleMap.get(INVISIBLE) == null);
286               double[] thrsh = (styleMap == null) ? null
287                       : (double[]) styleMap.get(THRESHOLD);
288               float[] range = (styleMap == null) ? null
289                       : (float[]) styleMap.get(RANGE);
290               if (range != null)
291               {
292                 annot.graphMin = range[0];
293                 annot.graphMax = range[1];
294               }
295               if (styleMap == null || styleMap.get(DONTCOMBINE) == null)
296               {
297                 {
298                   if (!sameGroup)
299                   {
300                     graphGroup++;
301                     sameGroup = true;
302                   }
303
304                   annot.graphGroup = graphGroup;
305                 }
306               }
307
308               annot.description = "<html>" + service.getActionText()
309                       + " - raw scores";
310               if (thrsh != null)
311               {
312                 String threshNote = (thrsh[0] > 0 ? "Above " : "Below ")
313                         + thrsh[1] + " indicates disorder";
314                 annot.threshold = new GraphLine((float) thrsh[1],
315                         threshNote, Color.red);
316                 annot.description += "<br/>" + threshNote;
317               }
318               annot.description += "</html>";
319               Color col = new UserColourScheme(typeName)
320                       .createColourFromName(typeName + scr.getMethod());
321               for (int p = 0, ps = annot.annotations.length; p < ps; p++)
322               {
323                 if (annot.annotations[p] != null)
324                 {
325                   annot.annotations[p].colour = col;
326                 }
327               }
328               annot._linecolour = col;
329             }
330           }
331         }
332         if (lastAnnot + 1 == ourAnnot.size())
333         {
334           // remove singleton alignment annotation row
335           ourAnnot.get(lastAnnot).graphGroup = -1;
336         }
337       }
338       {
339         if (dispFeatures)
340         {
341           jalview.gui.FeatureRenderer fr = ((jalview.gui.AlignmentPanel) ap)
342                   .cloneFeatureRenderer();
343           for (String ft : fc.keySet())
344           {
345             Object gc = fr.getFeatureStyle(ft);
346             if (gc instanceof Color)
347             {
348               // set graduated color as fading to white for minimum, and
349               // autoscaling to values on alignment
350               GraduatedColor ggc = new GraduatedColor(Color.white,
351                       (Color) gc, Float.MIN_VALUE, Float.MAX_VALUE);
352               ggc.setAutoScaled(true);
353               fr.setColour(ft, ggc);
354             }
355           }
356           // TODO: JAL-1150 - create sequence feature settings API for defining
357           // styles and enabling/disabling feature overlay on alignment panel
358           ((jalview.gui.AlignmentPanel) ap).updateFeatureRendererFrom(fr);
359           if (af.alignPanel == ap)
360           {
361             // only do this if the alignFrame is currently showing this view.
362             af.setShowSeqFeatures(true);
363           }
364           ap.paintAlignment(true);
365         }
366         if (ourAnnot.size() > 0)
367         {
368           // Modify the visible annotation on the alignment viewport with the
369           // new alignment annotation rows created.
370           updateOurAnnots(ourAnnot);
371           ap.adjustAnnotationHeight();
372         }
373       }
374     }
375   }
376
377 }