1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
|
|
15 |
|
|
16 |
|
|
17 |
|
|
18 |
|
|
19 |
|
|
20 |
|
|
21 |
|
package jalview.io; |
22 |
|
|
23 |
|
import jalview.api.FeatureColourI; |
24 |
|
import jalview.datamodel.DBRefEntry; |
25 |
|
import jalview.datamodel.DBRefSource; |
26 |
|
import jalview.datamodel.SequenceFeature; |
27 |
|
import jalview.datamodel.SequenceI; |
28 |
|
import jalview.util.MessageManager; |
29 |
|
import jalview.util.StringUtils; |
30 |
|
import jalview.util.UrlLink; |
31 |
|
import jalview.viewmodel.seqfeatures.FeatureRendererModel; |
32 |
|
|
33 |
|
import java.util.Arrays; |
34 |
|
import java.util.Collection; |
35 |
|
import java.util.Comparator; |
36 |
|
import java.util.LinkedHashMap; |
37 |
|
import java.util.List; |
38 |
|
import java.util.Map; |
39 |
|
|
40 |
|
|
41 |
|
|
42 |
|
|
43 |
|
@author |
44 |
|
|
|
|
| 80.5% |
Uncovered Elements: 50 (257) |
Complexity: 72 |
Complexity Density: 0.47 |
|
45 |
|
public class SequenceAnnotationReport |
46 |
|
{ |
47 |
|
private static final String COMMA = ","; |
48 |
|
|
49 |
|
private static final String ELLIPSIS = "..."; |
50 |
|
|
51 |
|
private static final int MAX_REFS_PER_SOURCE = 4; |
52 |
|
|
53 |
|
private static final int MAX_SOURCES = 40; |
54 |
|
|
55 |
|
private static final String[][] PRIMARY_SOURCES = new String[][] { |
56 |
|
DBRefSource.CODINGDBS, DBRefSource.DNACODINGDBS, |
57 |
|
DBRefSource.PROTEINDBS }; |
58 |
|
|
59 |
|
final String linkImageURL; |
60 |
|
|
61 |
|
|
62 |
|
|
63 |
|
|
64 |
|
|
65 |
|
private static Comparator<DBRefEntry> comparator = new Comparator<DBRefEntry>() |
66 |
|
{ |
67 |
|
|
|
|
| 77.8% |
Uncovered Elements: 8 (36) |
Complexity: 12 |
Complexity Density: 0.67 |
|
68 |
145 |
@Override... |
69 |
|
public int compare(DBRefEntry ref1, DBRefEntry ref2) |
70 |
|
{ |
71 |
145 |
if (ref1.isChromosome()) |
72 |
|
{ |
73 |
0 |
return -1; |
74 |
|
} |
75 |
145 |
if (ref2.isChromosome()) |
76 |
|
{ |
77 |
0 |
return 1; |
78 |
|
} |
79 |
145 |
String s1 = ref1.getSource(); |
80 |
145 |
String s2 = ref2.getSource(); |
81 |
145 |
boolean s1Primary = isPrimarySource(s1); |
82 |
145 |
boolean s2Primary = isPrimarySource(s2); |
83 |
145 |
if (s1Primary && !s2Primary) |
84 |
|
{ |
85 |
26 |
return -1; |
86 |
|
} |
87 |
119 |
if (!s1Primary && s2Primary) |
88 |
|
{ |
89 |
1 |
return 1; |
90 |
|
} |
91 |
118 |
int comp = s1 == null ? -1 : (s2 == null ? 1 : s1 |
92 |
|
.compareToIgnoreCase(s2)); |
93 |
118 |
if (comp == 0) |
94 |
|
{ |
95 |
5 |
String a1 = ref1.getAccessionId(); |
96 |
5 |
String a2 = ref2.getAccessionId(); |
97 |
5 |
comp = a1 == null ? -1 : (a2 == null ? 1 : a1 |
98 |
|
.compareToIgnoreCase(a2)); |
99 |
|
} |
100 |
118 |
return comp; |
101 |
|
} |
102 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (7) |
Complexity: 2 |
Complexity Density: 0.4 |
|
103 |
290 |
private boolean isPrimarySource(String source)... |
104 |
|
{ |
105 |
290 |
for (String[] primary : PRIMARY_SOURCES) |
106 |
|
{ |
107 |
870 |
for (String s : primary) |
108 |
|
{ |
109 |
3369 |
if (source.equals(s)) |
110 |
|
{ |
111 |
37 |
return true; |
112 |
|
} |
113 |
|
} |
114 |
|
} |
115 |
253 |
return false; |
116 |
|
} |
117 |
|
}; |
118 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
119 |
444 |
public SequenceAnnotationReport(String linkURL)... |
120 |
|
{ |
121 |
444 |
this.linkImageURL = linkURL; |
122 |
|
} |
123 |
|
|
124 |
|
|
125 |
|
|
126 |
|
|
127 |
|
@param |
128 |
|
@param |
129 |
|
@param |
130 |
|
@param |
131 |
|
|
|
|
| 0% |
Uncovered Elements: 5 (5) |
Complexity: 2 |
Complexity Density: 0.67 |
|
132 |
0 |
public void appendFeatures(final StringBuilder sb, int rpos,... |
133 |
|
List<SequenceFeature> features, FeatureRendererModel fr) |
134 |
|
{ |
135 |
0 |
if (features != null) |
136 |
|
{ |
137 |
0 |
for (SequenceFeature feature : features) |
138 |
|
{ |
139 |
0 |
appendFeature(sb, rpos, fr, feature); |
140 |
|
} |
141 |
|
} |
142 |
|
} |
143 |
|
|
144 |
|
|
145 |
|
|
146 |
|
|
147 |
|
@param |
148 |
|
@param |
149 |
|
@param |
150 |
|
@param |
151 |
|
|
|
|
| 98.2% |
Uncovered Elements: 1 (57) |
Complexity: 18 |
Complexity Density: 0.58 |
|
152 |
30 |
void appendFeature(final StringBuilder sb, int rpos,... |
153 |
|
FeatureRendererModel fr, SequenceFeature feature) |
154 |
|
{ |
155 |
30 |
if (feature.isContactFeature()) |
156 |
|
{ |
157 |
3 |
if (feature.getBegin() == rpos || feature.getEnd() == rpos) |
158 |
|
{ |
159 |
2 |
if (sb.length() > 6) |
160 |
|
{ |
161 |
1 |
sb.append("<br>"); |
162 |
|
} |
163 |
2 |
sb.append(feature.getType()).append(" ").append(feature.getBegin()) |
164 |
|
.append(":").append(feature.getEnd()); |
165 |
|
} |
166 |
3 |
return; |
167 |
|
} |
168 |
|
|
169 |
27 |
if (sb.length() > 6) |
170 |
|
{ |
171 |
15 |
sb.append("<br>"); |
172 |
|
} |
173 |
|
|
174 |
27 |
boolean linkOnly = feature.getValue("linkonly") != null; |
175 |
27 |
if (!linkOnly) |
176 |
|
{ |
177 |
27 |
sb.append(feature.getType()).append(" "); |
178 |
27 |
if (rpos != 0) |
179 |
|
{ |
180 |
|
|
181 |
13 |
sb.append(feature.begin); |
182 |
|
} |
183 |
27 |
if (feature.begin != feature.end) |
184 |
|
{ |
185 |
13 |
sb.append(" ").append(feature.end); |
186 |
|
} |
187 |
|
|
188 |
27 |
String description = feature.getDescription(); |
189 |
27 |
if (description != null && !description.equals(feature.getType())) |
190 |
|
{ |
191 |
26 |
description = StringUtils.stripHtmlTags(description); |
192 |
26 |
sb.append("; ").append(description); |
193 |
|
} |
194 |
|
|
195 |
27 |
if (showScore(feature, fr)) |
196 |
|
{ |
197 |
3 |
sb.append(" Score=").append(String.valueOf(feature.getScore())); |
198 |
|
} |
199 |
27 |
String status = (String) feature.getValue("status"); |
200 |
27 |
if (status != null && status.length() > 0) |
201 |
|
{ |
202 |
2 |
sb.append("; (").append(status).append(")"); |
203 |
|
} |
204 |
|
|
205 |
|
|
206 |
|
|
207 |
|
|
208 |
27 |
if (fr != null) |
209 |
|
{ |
210 |
20 |
FeatureColourI fc = fr.getFeatureColours().get(feature.getType()); |
211 |
20 |
if (fc != null && fc.isColourByAttribute()) |
212 |
|
{ |
213 |
4 |
String[] attName = fc.getAttributeName(); |
214 |
4 |
String attVal = feature.getValueAsString(attName); |
215 |
4 |
if (attVal != null) |
216 |
|
{ |
217 |
3 |
sb.append("; ").append(String.join(":", attName)).append("=") |
218 |
|
.append(attVal); |
219 |
|
} |
220 |
|
} |
221 |
|
} |
222 |
|
} |
223 |
|
} |
224 |
|
|
225 |
|
|
226 |
|
|
227 |
|
|
228 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (14) |
Complexity: 6 |
Complexity Density: 0.75 |
|
229 |
27 |
boolean showScore(SequenceFeature feature, FeatureRendererModel fr)... |
230 |
|
{ |
231 |
27 |
if (Float.isNaN(feature.getScore())) |
232 |
|
{ |
233 |
9 |
return false; |
234 |
|
} |
235 |
18 |
if (fr == null) |
236 |
|
{ |
237 |
1 |
return true; |
238 |
|
} |
239 |
17 |
float[][] minMax = fr.getMinMax().get(feature.getType()); |
240 |
|
|
241 |
|
|
242 |
|
|
243 |
|
|
244 |
17 |
if (minMax == null || minMax[0] == null || minMax[0][0] == minMax[0][1]) |
245 |
|
{ |
246 |
15 |
return false; |
247 |
|
} |
248 |
2 |
return true; |
249 |
|
} |
250 |
|
|
251 |
|
|
252 |
|
|
253 |
|
|
254 |
|
|
255 |
|
@param |
256 |
|
@param |
257 |
|
|
|
|
| 0% |
Uncovered Elements: 15 (15) |
Complexity: 5 |
Complexity Density: 0.56 |
|
258 |
0 |
void appendLinks(final StringBuffer sb, SequenceFeature feature)... |
259 |
|
{ |
260 |
0 |
if (feature.links != null) |
261 |
|
{ |
262 |
0 |
if (linkImageURL != null) |
263 |
|
{ |
264 |
0 |
sb.append(" <img src=\"" + linkImageURL + "\">"); |
265 |
|
} |
266 |
|
else |
267 |
|
{ |
268 |
0 |
for (String urlstring : feature.links) |
269 |
|
{ |
270 |
0 |
try |
271 |
|
{ |
272 |
0 |
for (List<String> urllink : createLinksFrom(null, urlstring)) |
273 |
|
{ |
274 |
0 |
sb.append("<br/> <a href=\"" |
275 |
|
+ urllink.get(3) |
276 |
|
+ "\" target=\"" |
277 |
|
+ urllink.get(0) |
278 |
|
+ "\">" |
279 |
0 |
+ (urllink.get(0).toLowerCase() |
280 |
|
.equals(urllink.get(1).toLowerCase()) ? urllink |
281 |
|
.get(0) : (urllink.get(0) + ":" + urllink |
282 |
|
.get(1))) + "</a></br>"); |
283 |
|
} |
284 |
|
} catch (Exception x) |
285 |
|
{ |
286 |
0 |
System.err.println("problem when creating links from " |
287 |
|
+ urlstring); |
288 |
0 |
x.printStackTrace(); |
289 |
|
} |
290 |
|
} |
291 |
|
} |
292 |
|
|
293 |
|
} |
294 |
|
} |
295 |
|
|
296 |
|
|
297 |
|
|
298 |
|
@param |
299 |
|
@param |
300 |
|
@return |
301 |
|
|
302 |
|
|
|
|
| 0% |
Uncovered Elements: 9 (9) |
Complexity: 2 |
Complexity Density: 0.29 |
|
303 |
0 |
Collection<List<String>> createLinksFrom(SequenceI seq, String link)... |
304 |
|
{ |
305 |
0 |
Map<String, List<String>> urlSets = new LinkedHashMap<>(); |
306 |
0 |
UrlLink urlLink = new UrlLink(link); |
307 |
0 |
if (!urlLink.isValid()) |
308 |
|
{ |
309 |
0 |
System.err.println(urlLink.getInvalidMessage()); |
310 |
0 |
return null; |
311 |
|
} |
312 |
|
|
313 |
0 |
urlLink.createLinksFromSeq(seq, urlSets); |
314 |
|
|
315 |
0 |
return urlSets.values(); |
316 |
|
} |
317 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
318 |
9 |
public void createSequenceAnnotationReport(final StringBuilder tip,... |
319 |
|
SequenceI sequence, boolean showDbRefs, boolean showNpFeats, |
320 |
|
FeatureRendererModel fr) |
321 |
|
{ |
322 |
9 |
createSequenceAnnotationReport(tip, sequence, showDbRefs, showNpFeats, |
323 |
|
fr, false); |
324 |
|
} |
325 |
|
|
326 |
|
|
327 |
|
|
328 |
|
|
329 |
|
|
330 |
|
@param |
331 |
|
|
332 |
|
@param |
333 |
|
|
334 |
|
@param |
335 |
|
|
336 |
|
@param |
337 |
|
|
338 |
|
@param |
339 |
|
@param |
340 |
|
@return |
341 |
|
|
|
|
| 92.9% |
Uncovered Elements: 2 (28) |
Complexity: 5 |
Complexity Density: 0.25 |
|
342 |
10 |
int createSequenceAnnotationReport(final StringBuilder sb,... |
343 |
|
SequenceI sequence, boolean showDbRefs, boolean showNpFeats, |
344 |
|
FeatureRendererModel fr, boolean summary) |
345 |
|
{ |
346 |
10 |
String tmp; |
347 |
10 |
sb.append("<i>"); |
348 |
|
|
349 |
10 |
int maxWidth = 0; |
350 |
10 |
if (sequence.getDescription() != null) |
351 |
|
{ |
352 |
9 |
tmp = sequence.getDescription(); |
353 |
9 |
sb.append("<br>").append(tmp); |
354 |
9 |
maxWidth = Math.max(maxWidth, tmp.length()); |
355 |
|
} |
356 |
10 |
SequenceI ds = sequence; |
357 |
10 |
while (ds.getDatasetSequence() != null) |
358 |
|
{ |
359 |
0 |
ds = ds.getDatasetSequence(); |
360 |
|
} |
361 |
|
|
362 |
10 |
if (showDbRefs) |
363 |
|
{ |
364 |
9 |
maxWidth = Math.max(maxWidth, appendDbRefs(sb, ds, summary)); |
365 |
|
} |
366 |
|
|
367 |
|
|
368 |
|
|
369 |
|
|
370 |
10 |
if (showNpFeats) |
371 |
|
{ |
372 |
8 |
for (SequenceFeature sf : sequence.getFeatures() |
373 |
|
.getNonPositionalFeatures()) |
374 |
|
{ |
375 |
14 |
int sz = -sb.length(); |
376 |
14 |
appendFeature(sb, 0, fr, sf); |
377 |
14 |
sz += sb.length(); |
378 |
14 |
maxWidth = Math.max(maxWidth, sz); |
379 |
|
} |
380 |
|
} |
381 |
10 |
sb.append("</i>"); |
382 |
10 |
return maxWidth; |
383 |
|
} |
384 |
|
|
385 |
|
|
386 |
|
|
387 |
|
|
388 |
|
|
389 |
|
@param |
390 |
|
@param |
391 |
|
@param |
392 |
|
@return |
393 |
|
|
|
|
| 97.1% |
Uncovered Elements: 2 (68) |
Complexity: 16 |
Complexity Density: 0.33 |
|
394 |
9 |
protected int appendDbRefs(final StringBuilder sb, SequenceI ds,... |
395 |
|
boolean summary) |
396 |
|
{ |
397 |
9 |
DBRefEntry[] dbrefs = ds.getDBRefs(); |
398 |
9 |
if (dbrefs == null) |
399 |
|
{ |
400 |
6 |
return 0; |
401 |
|
} |
402 |
|
|
403 |
|
|
404 |
3 |
Arrays.sort(dbrefs, comparator); |
405 |
3 |
boolean ellipsis = false; |
406 |
3 |
String source = null; |
407 |
3 |
String lastSource = null; |
408 |
3 |
int countForSource = 0; |
409 |
3 |
int sourceCount = 0; |
410 |
3 |
boolean moreSources = false; |
411 |
3 |
int maxLineLength = 0; |
412 |
3 |
int lineLength = 0; |
413 |
|
|
414 |
3 |
for (DBRefEntry ref : dbrefs) |
415 |
|
{ |
416 |
49 |
source = ref.getSource(); |
417 |
49 |
if (source == null) |
418 |
|
{ |
419 |
|
|
420 |
0 |
continue; |
421 |
|
} |
422 |
49 |
boolean sourceChanged = !source.equals(lastSource); |
423 |
49 |
if (sourceChanged) |
424 |
|
{ |
425 |
45 |
lineLength = 0; |
426 |
45 |
countForSource = 0; |
427 |
45 |
sourceCount++; |
428 |
|
} |
429 |
49 |
if (sourceCount > MAX_SOURCES && summary) |
430 |
|
{ |
431 |
1 |
ellipsis = true; |
432 |
1 |
moreSources = true; |
433 |
1 |
break; |
434 |
|
} |
435 |
48 |
lastSource = source; |
436 |
48 |
countForSource++; |
437 |
48 |
if (countForSource == 1 || !summary) |
438 |
|
{ |
439 |
44 |
sb.append("<br>"); |
440 |
|
} |
441 |
48 |
if (countForSource <= MAX_REFS_PER_SOURCE || !summary) |
442 |
|
{ |
443 |
47 |
String accessionId = ref.getAccessionId(); |
444 |
47 |
lineLength += accessionId.length() + 1; |
445 |
47 |
if (countForSource > 1 && summary) |
446 |
|
{ |
447 |
3 |
sb.append(", ").append(accessionId); |
448 |
3 |
lineLength++; |
449 |
|
} |
450 |
|
else |
451 |
|
{ |
452 |
44 |
sb.append(source).append(" ").append(accessionId); |
453 |
44 |
lineLength += source.length(); |
454 |
|
} |
455 |
47 |
maxLineLength = Math.max(maxLineLength, lineLength); |
456 |
|
} |
457 |
48 |
if (countForSource == MAX_REFS_PER_SOURCE && summary) |
458 |
|
{ |
459 |
1 |
sb.append(COMMA).append(ELLIPSIS); |
460 |
1 |
ellipsis = true; |
461 |
|
} |
462 |
|
} |
463 |
3 |
if (moreSources) |
464 |
|
{ |
465 |
1 |
sb.append("<br>").append(source).append(COMMA).append(ELLIPSIS); |
466 |
|
} |
467 |
3 |
if (ellipsis) |
468 |
|
{ |
469 |
1 |
sb.append("<br>("); |
470 |
1 |
sb.append(MessageManager.getString("label.output_seq_details")); |
471 |
1 |
sb.append(")"); |
472 |
|
} |
473 |
|
|
474 |
3 |
return maxLineLength; |
475 |
|
} |
476 |
|
|
|
|
| 0% |
Uncovered Elements: 4 (4) |
Complexity: 2 |
Complexity Density: 1 |
|
477 |
0 |
public void createTooltipAnnotationReport(final StringBuilder tip,... |
478 |
|
SequenceI sequence, boolean showDbRefs, boolean showNpFeats, |
479 |
|
FeatureRendererModel fr) |
480 |
|
{ |
481 |
0 |
int maxWidth = createSequenceAnnotationReport(tip, sequence, |
482 |
|
showDbRefs, showNpFeats, fr, true); |
483 |
|
|
484 |
0 |
if (maxWidth > 60) |
485 |
|
{ |
486 |
|
|
487 |
|
|
488 |
|
|
489 |
|
} |
490 |
|
} |
491 |
|
} |