JAL-2068 clarify comments
[jalview.git] / examples / groovy / featureCounter.groovy
1 import jalview.workers.FeatureCounterI;
2 import jalview.workers.AlignmentAnnotationFactory;
3
4 /*
5  * Example script that registers two alignment annotation calculators
6  * - one that counts residues in a column with Pfam annotation
7  * - one that counts only charged residues with Pfam annotation
8  * To try this, first load uniref50.fa from the examples folder, then load features
9  * from examples/exampleFeatures.txt, before running this script from the Groovy console.
10  
11  * Modify this example as required to count by column any desired value that can be 
12  * derived from the residue and sequence features at each position of an alignment.
13  */
14
15 /*
16  * A closure that returns true for any Charged residue
17  */
18 def isCharged = { residue ->
19     switch(residue) {
20         case ['D', 'd', 'E', 'e', 'H', 'h', 'K', 'k', 'R', 'r']:
21             return true
22     }
23     false
24
25
26 /*
27  * A closure that returns 1 if sequence features include type 'Pfam', else 0
28  * Argument should be a list of SequenceFeature 
29  */
30 def hasPfam = { features -> 
31     for (sf in features)
32     {
33         /*
34          * Here we inspect the type of the sequence feature.
35          * You can also test sf.description, sf.score, sf.featureGroup,
36          * sf.strand, sf.phase, sf.begin, sf.end
37          * or sf.getValue(attributeName) for GFF 'column 9' properties
38          */
39         if ("Pfam".equals(sf.type))
40         {
41             return true
42         }
43     }
44     false
45 }
46
47 /*
48  * Closure that computes an annotation based on 
49  * presence of particular residues and features
50  * Parameters are
51  * - the name (label) for the alignment annotation
52  * - the description (tooltip) for the annotation
53  * - a closure (groovy function) that tests whether to include a residue
54  * - a closure that tests whether to increment count based on sequence features  
55  */
56 def getColumnCounter = { name, desc, acceptResidue, acceptFeatures ->
57     [
58      getName: { name }, 
59      getDescription: { desc },
60      getMinColour: { [0, 255, 255] }, // cyan
61      getMaxColour: { [0, 0, 255] }, // blue
62      count: 
63          { res, feats -> 
64             def c = 0
65             if (acceptResidue.call(res))
66             {
67                 if (acceptFeatures.call(feats))
68                 {
69                     c++
70                 }
71             }
72             c
73          }
74      ] as FeatureCounterI
75 }
76
77 /*
78  * Define an annotation row that counts any residue with Pfam domain annotation
79  */
80 def pfamAnnotation = getColumnCounter("Pfam", "Count of residues with Pfam domain annotation", {true}, hasPfam)
81
82 /*
83  * Define an annotation row that counts charged residues with Pfam domain annotation
84  */
85 def chargedPfamAnnotation = getColumnCounter("Pfam charged", "Count of charged residues with Pfam domain annotation", isCharged, hasPfam)
86
87 /*
88  * Register the annotations
89  */
90 AlignmentAnnotationFactory.newCalculator(pfamAnnotation) 
91 AlignmentAnnotationFactory.newCalculator(chargedPfamAnnotation)