JAL-2103 propagate inserts only used for reconstructing profile view, currently
[jalview.git] / examples / groovy / multipleFeatureAnnotations.groovy
1 import jalview.workers.AlignmentAnnotationFactory;
2 import jalview.workers.AnnotationProviderI;
3 import jalview.datamodel.AlignmentAnnotation;
4 import jalview.datamodel.Annotation;
5 import jalview.util.ColorUtils;
6 import jalview.util.Comparison;
7 import java.awt.Color;
8
9 /*
10  * Example script to compute two alignment annotations
11  * - count of Phosphorylation features
12  * - count of Turn features
13  * To try this, first load example file uniref50.fa and load on features file
14  * exampleFeatures.txt, before running this script
15  *
16  * The script only needs to be run once - it will be registered by Jalview
17  * and recalculated automatically when the alignment changes.
18  */
19
20 /*
21  * A closure that returns true if value includes "PHOSPHORYLATION"
22  */
23 def phosCounter = { type ->    type.contains("PHOSPHORYLATION") }
24
25 /*
26  * A closure that returns true if value includes "TURN"
27  */
28 def turnCounter = { type ->    type.contains("TURN") }
29
30 /*
31  * A closure that computes and returns an array of Annotation values,
32  * one for each column of the alignment
33  */
34 def getAnnotations(al, fr, counter) 
35 {
36     def width = al.width
37     def counts = new int[width] 
38     def max = 0
39     
40     /*
41      * count features in each column, record the maximum value
42      */
43     for (col = 0 ; col < width ; col++)
44     {
45         def count = 0
46         for (row = 0 ; row < al.height ; row++)
47         {
48             seq = al.getSequenceAt(row)
49             if (seq != null && col < seq.getLength())
50             {
51                 def res = seq.getCharAt(col)
52                 if (!Comparison.isGap(res))
53                 {
54                     pos = seq.findPosition(col)
55                     features = fr.findFeaturesAtRes(seq, pos)
56                     for (feature in features)
57                     {
58                         if (counter.call(feature.type))
59                         {
60                             count++
61                         }
62                     }
63                 }
64             }
65         }
66         counts[col] = count
67         if (count > max)
68         {
69             max = count
70         }
71     }
72     
73     /*
74      * make the Annotation objects, with a graduated colour scale 
75      * (from min value to max value) for the histogram bars 
76      */
77     def zero = '0' as char
78     def anns = new Annotation[width] 
79     for (col = 0 ; col < width ; col++)
80     {
81         def c = counts[col]
82         if (c > 0)
83         {
84             Color color = ColorUtils.getGraduatedColour(c, 0, Color.cyan,
85                 max, Color.blue)
86             anns[col] = AlignmentAnnotationFactory.newAnnotation(String.valueOf(c),
87                 String.valueOf(c), zero, c, color)
88         }
89     }
90     anns
91 }
92
93 /*
94  * Define the method that performs the calculations, and builds two
95  * AlignmentAnnotation objects
96  */
97 def annotator = 
98     [ calculateAnnotation: { al, fr ->
99         def phosAnns = getAnnotations(al, fr, phosCounter)
100         def ann1 = AlignmentAnnotationFactory.newAlignmentAnnotation("Phosphorylation", "Count of Phosphorylation features", phosAnns)
101         def turnAnns = getAnnotations(al, fr, turnCounter)
102         def ann2 = AlignmentAnnotationFactory.newAlignmentAnnotation("Turn", "Count of Turn features", turnAnns)
103         return [ann1, ann2]
104       } 
105     ] as AnnotationProviderI
106     
107 /*
108  * Register the annotation calculator with Jalview
109  */
110 AlignmentAnnotationFactory.newCalculator(annotator)