Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
AADisorderClient | 49 | 144 | 38 |
1 | /* | |
2 | * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) | |
3 | * Copyright (C) $$Year-Rel$$ 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.FeatureColourI; | |
24 | import jalview.bin.Console; | |
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.FeatureColour; | |
31 | import jalview.util.ColorUtils; | |
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.FastaSequence; | |
44 | import compbio.data.sequence.Range; | |
45 | import compbio.data.sequence.Score; | |
46 | import compbio.data.sequence.ScoreManager.ScoreHolder; | |
47 | import compbio.metadata.Argument; | |
48 | ||
49 | public class AADisorderClient extends JabawsCalcWorker | |
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 | 0 | public AADisorderClient(Jws2Instance sh, AlignFrame alignFrame, |
65 | WsParamSetI thePreset, List<Argument> paramset) | |
66 | { | |
67 | 0 | super(sh, alignFrame, thePreset, paramset); |
68 | 0 | af = alignFrame; |
69 | 0 | typeName = sh.action; |
70 | 0 | methodName = sh.serviceType; |
71 | ||
72 | 0 | submitGaps = false; |
73 | 0 | alignedSeqs = false; |
74 | 0 | nucleotidesAllowed = false; |
75 | 0 | proteinAllowed = true; |
76 | 0 | bySequence = true; |
77 | } | |
78 | ||
79 | 0 | @Override |
80 | public String getServiceActionText() | |
81 | { | |
82 | 0 | return "Submitting amino acid sequences for disorder prediction."; |
83 | } | |
84 | ||
85 | 0 | @Override |
86 | boolean checkValidInputSeqs(boolean dynamic, List<FastaSequence> seqs) | |
87 | { | |
88 | 0 | return (seqs.size() > 0); |
89 | } | |
90 | ||
91 | private static Map<String, Map<String, String[]>> featureMap; | |
92 | ||
93 | private static Map<String, Map<String, Map<String, Object>>> annotMap; | |
94 | ||
95 | private static String DONTCOMBINE = "DONTCOMBINE"; | |
96 | ||
97 | private static String INVISIBLE = "INVISIBLE"; | |
98 | 0 | static |
99 | { | |
100 | // TODO: turn this into some kind of configuration file that's a bit easier | |
101 | // to edit | |
102 | 0 | featureMap = new HashMap<>(); |
103 | 0 | Map<String, String[]> fmap; |
104 | 0 | featureMap.put(compbio.ws.client.Services.IUPredWS.toString(), |
105 | fmap = new HashMap<>()); | |
106 | 0 | fmap.put("Glob", |
107 | new String[] | |
108 | { "Globular Domain", "Predicted globular domain" }); | |
109 | 0 | featureMap.put(compbio.ws.client.Services.JronnWS.toString(), |
110 | fmap = new HashMap<>()); | |
111 | 0 | featureMap.put(compbio.ws.client.Services.DisemblWS.toString(), |
112 | fmap = new HashMap<>()); | |
113 | 0 | fmap.put("REM465", new String[] { "REM465", "Missing density" }); |
114 | 0 | fmap.put("HOTLOOPS", new String[] { "HOTLOOPS", "Flexible loops" }); |
115 | 0 | fmap.put("COILS", new String[] { "COILS", "Random coil" }); |
116 | 0 | featureMap.put(compbio.ws.client.Services.GlobPlotWS.toString(), |
117 | fmap = new HashMap<>()); | |
118 | 0 | fmap.put("GlobDoms", |
119 | new String[] | |
120 | { "Globular Domain", "Predicted globular domain" }); | |
121 | 0 | fmap.put("Disorder", |
122 | new String[] | |
123 | { "Protein Disorder", "Probable unstructured peptide region" }); | |
124 | 0 | Map<String, Map<String, Object>> amap; |
125 | 0 | annotMap = new HashMap<>(); |
126 | 0 | annotMap.put(compbio.ws.client.Services.GlobPlotWS.toString(), |
127 | amap = new HashMap<>()); | |
128 | 0 | amap.put("Dydx", new HashMap<String, Object>()); |
129 | 0 | amap.get("Dydx").put(DONTCOMBINE, DONTCOMBINE); |
130 | 0 | amap.get("Dydx").put(THRESHOLD, new double[] { 1, 0 }); |
131 | 0 | amap.get("Dydx").put(RANGE, new float[] { -1, +1 }); |
132 | ||
133 | 0 | amap.put("SmoothedScore", new HashMap<String, Object>()); |
134 | 0 | amap.get("SmoothedScore").put(INVISIBLE, INVISIBLE); |
135 | 0 | amap.put("RawScore", new HashMap<String, Object>()); |
136 | 0 | amap.get("RawScore").put(INVISIBLE, INVISIBLE); |
137 | 0 | annotMap.put(compbio.ws.client.Services.DisemblWS.toString(), |
138 | amap = new HashMap<>()); | |
139 | 0 | amap.put("COILS", new HashMap<String, Object>()); |
140 | 0 | amap.put("HOTLOOPS", new HashMap<String, Object>()); |
141 | 0 | amap.put("REM465", new HashMap<String, Object>()); |
142 | 0 | amap.get("COILS").put(THRESHOLD, new double[] { 1, 0.516 }); |
143 | 0 | amap.get("COILS").put(RANGE, new float[] { 0, 1 }); |
144 | ||
145 | 0 | amap.get("HOTLOOPS").put(THRESHOLD, new double[] { 1, 0.6 }); |
146 | 0 | amap.get("HOTLOOPS").put(RANGE, new float[] { 0, 1 }); |
147 | 0 | amap.get("REM465").put(THRESHOLD, new double[] { 1, 0.1204 }); |
148 | 0 | amap.get("REM465").put(RANGE, new float[] { 0, 1 }); |
149 | ||
150 | 0 | annotMap.put(compbio.ws.client.Services.IUPredWS.toString(), |
151 | amap = new HashMap<>()); | |
152 | 0 | amap.put("Long", new HashMap<String, Object>()); |
153 | 0 | amap.put("Short", new HashMap<String, Object>()); |
154 | 0 | amap.get("Long").put(THRESHOLD, new double[] { 1, 0.5 }); |
155 | 0 | amap.get("Long").put(RANGE, new float[] { 0, 1 }); |
156 | 0 | amap.get("Short").put(THRESHOLD, new double[] { 1, 0.5 }); |
157 | 0 | amap.get("Short").put(RANGE, new float[] { 0, 1 }); |
158 | 0 | annotMap.put(compbio.ws.client.Services.JronnWS.toString(), |
159 | amap = new HashMap<>()); | |
160 | 0 | amap.put("JRonn", new HashMap<String, Object>()); |
161 | 0 | amap.get("JRonn").put(THRESHOLD, new double[] { 1, 0.5 }); |
162 | 0 | amap.get("JRonn").put(RANGE, new float[] { 0, 1 }); |
163 | } | |
164 | ||
165 | 0 | @Override |
166 | public void updateResultAnnotation(boolean immediate) | |
167 | { | |
168 | ||
169 | 0 | if (immediate || !calcMan.isWorking(this) && scoremanager != null) |
170 | { | |
171 | 0 | Map<String, String[]> featureTypeMap = featureMap |
172 | .get(service.serviceType); | |
173 | 0 | Map<String, Map<String, Object>> annotTypeMap = annotMap |
174 | .get(service.serviceType); | |
175 | 0 | boolean dispFeatures = false; |
176 | 0 | Map<String, Object> fc = new Hashtable<>(); |
177 | 0 | List<AlignmentAnnotation> ourAnnot = new ArrayList<>(); |
178 | /** | |
179 | * grouping for any annotation rows created | |
180 | */ | |
181 | 0 | int graphGroup = 1; |
182 | 0 | if (alignViewport.getAlignment().getAlignmentAnnotation() != null) |
183 | { | |
184 | 0 | for (AlignmentAnnotation ala : alignViewport.getAlignment() |
185 | .getAlignmentAnnotation()) | |
186 | { | |
187 | 0 | if (ala.graphGroup > graphGroup) |
188 | { | |
189 | 0 | graphGroup = ala.graphGroup; |
190 | } | |
191 | } | |
192 | } | |
193 | ||
194 | 0 | for (String seqId : seqNames.keySet()) |
195 | { | |
196 | 0 | boolean sameGroup = false; |
197 | 0 | SequenceI dseq, aseq, seq = seqNames.get(seqId); |
198 | 0 | int base = seq.findPosition(start) - 1; |
199 | 0 | aseq = seq; |
200 | 0 | while ((dseq = seq).getDatasetSequence() != null) |
201 | { | |
202 | 0 | seq = seq.getDatasetSequence(); |
203 | } | |
204 | 0 | ScoreHolder scores = null; |
205 | 0 | try |
206 | { | |
207 | 0 | scores = scoremanager.getAnnotationForSequence(seqId); |
208 | } catch (Exception q) | |
209 | { | |
210 | 0 | Console.info("Couldn't recover disorder prediction for sequence " |
211 | + seq.getName() + "(Prediction name was " + seqId + ")" | |
212 | + "\nSee http://issues.jalview.org/browse/JAL-1319 for one possible reason why disorder predictions might fail."); | |
213 | } | |
214 | 0 | float last = Float.NaN, val = Float.NaN; |
215 | 0 | int lastAnnot = ourAnnot.size(); |
216 | 0 | if (scores != null && scores.scores != null) |
217 | { | |
218 | 0 | for (Score scr : scores.scores) |
219 | { | |
220 | ||
221 | 0 | if (scr.getRanges() != null && scr.getRanges().size() > 0) |
222 | { | |
223 | 0 | Iterator<Float> vals = scr.getScores().iterator(); |
224 | // make features on sequence | |
225 | 0 | for (Range rn : scr.getRanges()) |
226 | { | |
227 | ||
228 | 0 | SequenceFeature sf; |
229 | 0 | String[] type = featureTypeMap.get(scr.getMethod()); |
230 | 0 | if (type == null) |
231 | { | |
232 | // create a default type for this feature | |
233 | 0 | type = new String[] { |
234 | typeName + " (" + scr.getMethod() + ")", | |
235 | service.getActionText() }; | |
236 | } | |
237 | 0 | if (vals.hasNext()) |
238 | { | |
239 | 0 | val = vals.next().floatValue(); |
240 | 0 | sf = new SequenceFeature(type[0], type[1], base + rn.from, |
241 | base + rn.to, val, methodName); | |
242 | } | |
243 | else | |
244 | { | |
245 | 0 | sf = new SequenceFeature(type[0], type[1], base + rn.from, |
246 | base + rn.to, methodName); | |
247 | } | |
248 | 0 | dseq.addSequenceFeature(sf); |
249 | 0 | if (last != val && !Float.isNaN(last)) |
250 | { | |
251 | 0 | fc.put(sf.getType(), sf); |
252 | } | |
253 | 0 | last = val; |
254 | 0 | dispFeatures = true; |
255 | } | |
256 | } | |
257 | else | |
258 | { | |
259 | 0 | if (scr.getScores().size() == 0) |
260 | { | |
261 | 0 | continue; |
262 | } | |
263 | 0 | String typename, calcName; |
264 | 0 | AlignmentAnnotation annot = createAnnotationRowsForScores( |
265 | ourAnnot, | |
266 | typename = service.serviceType + " (" | |
267 | + scr.getMethod() + ")", | |
268 | calcName = service.getServiceTypeURI() + "/" | |
269 | + scr.getMethod(), | |
270 | aseq, base + 1, scr); | |
271 | 0 | annot.graph = AlignmentAnnotation.LINE_GRAPH; |
272 | ||
273 | 0 | Map<String, Object> styleMap = (annotTypeMap == null) ? null |
274 | : annotTypeMap.get(scr.getMethod()); | |
275 | ||
276 | 0 | annot.visible = (styleMap == null |
277 | || styleMap.get(INVISIBLE) == null); | |
278 | 0 | double[] thrsh = (styleMap == null) ? null |
279 | : (double[]) styleMap.get(THRESHOLD); | |
280 | 0 | float[] range = (styleMap == null) ? null |
281 | : (float[]) styleMap.get(RANGE); | |
282 | 0 | if (range != null) |
283 | { | |
284 | 0 | annot.graphMin = range[0]; |
285 | 0 | annot.graphMax = range[1]; |
286 | } | |
287 | 0 | if (styleMap == null || styleMap.get(DONTCOMBINE) == null) |
288 | { | |
289 | { | |
290 | 0 | if (!sameGroup) |
291 | { | |
292 | 0 | graphGroup++; |
293 | 0 | sameGroup = true; |
294 | } | |
295 | ||
296 | 0 | annot.graphGroup = graphGroup; |
297 | } | |
298 | } | |
299 | ||
300 | 0 | annot.description = "<html>" + service.getActionText() |
301 | + " - raw scores"; | |
302 | 0 | if (thrsh != null) |
303 | { | |
304 | 0 | String threshNote = (thrsh[0] > 0 ? "Above " : "Below ") |
305 | + thrsh[1] + " indicates disorder"; | |
306 | 0 | annot.threshold = new GraphLine((float) thrsh[1], |
307 | threshNote, Color.red); | |
308 | 0 | annot.description += "<br/>" + threshNote; |
309 | } | |
310 | 0 | annot.description += "</html>"; |
311 | 0 | Color col = ColorUtils |
312 | .createColourFromName(typeName + scr.getMethod()); | |
313 | 0 | for (int p = 0, ps = annot.annotations.length; p < ps; p++) |
314 | { | |
315 | 0 | if (annot.annotations[p] != null) |
316 | { | |
317 | 0 | annot.annotations[p].colour = col; |
318 | } | |
319 | } | |
320 | 0 | annot._linecolour = col; |
321 | // finally, update any dataset annotation | |
322 | 0 | replaceAnnotationOnAlignmentWith(annot, typename, calcName, |
323 | aseq); | |
324 | } | |
325 | } | |
326 | } | |
327 | 0 | if (lastAnnot + 1 == ourAnnot.size()) |
328 | { | |
329 | // remove singleton alignment annotation row | |
330 | 0 | ourAnnot.get(lastAnnot).graphGroup = -1; |
331 | } | |
332 | } | |
333 | { | |
334 | 0 | if (dispFeatures) |
335 | { | |
336 | 0 | jalview.api.FeatureRenderer fr = ((jalview.gui.AlignmentPanel) ap) |
337 | .cloneFeatureRenderer(); | |
338 | 0 | for (String ft : fc.keySet()) |
339 | { | |
340 | 0 | FeatureColourI gc = fr.getFeatureStyle(ft); |
341 | 0 | if (gc.isSimpleColour()) |
342 | { | |
343 | // set graduated color as fading to white for minimum, and | |
344 | // autoscaling to values on alignment | |
345 | 0 | FeatureColourI ggc = new FeatureColour(gc.getColour(), |
346 | Color.white, gc.getColour(), Color.white, | |
347 | Float.MIN_VALUE, Float.MAX_VALUE); | |
348 | 0 | ggc.setAutoScaled(true); |
349 | 0 | fr.setColour(ft, ggc); |
350 | } | |
351 | } | |
352 | // TODO: JAL-1150 - create sequence feature settings API for defining | |
353 | // styles and enabling/disabling feature overlay on alignment panel | |
354 | 0 | ((jalview.gui.AlignmentPanel) ap).updateFeatureRendererFrom(fr); |
355 | 0 | if (af.alignPanel == ap) |
356 | { | |
357 | // only do this if the alignFrame is currently showing this view. | |
358 | 0 | af.setShowSeqFeatures(true); |
359 | } | |
360 | } | |
361 | 0 | if (ourAnnot.size() > 0) |
362 | { | |
363 | // Modify the visible annotation on the alignment viewport with the | |
364 | // new alignment annotation rows created. | |
365 | 0 | updateOurAnnots(ourAnnot); |
366 | 0 | ap.adjustAnnotationHeight(); |
367 | 0 | ap.paintAlignment(true, true); |
368 | } | |
369 | } | |
370 | } | |
371 | } | |
372 | ||
373 | 0 | @Override |
374 | public String getCalcId() | |
375 | { | |
376 | // Disorder predictions are not dynamically updated so we return null | |
377 | 0 | return null; |
378 | } | |
379 | ||
380 | } |