JAL-1919 set default structure file format to mmCIF, refactored some StructureImportS...
[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 counts residues with a Pfam feature annotation
49  * Parameters are
50  * - the name (label) for the alignment annotation
51  * - the description (tooltip) for the annotation
52  * - a closure (groovy function) that tests whether to include a residue
53  * - a closure that tests whether to increment count based on sequence features  
54  */
55 def getColumnCounter = { name, desc, acceptResidue, acceptFeatures ->
56     [
57      getName: { name }, 
58      getDescription: { desc },
59      getMinColour: { [0, 255, 255] }, // cyan
60      getMaxColour: { [0, 0, 255] }, // blue
61      count: 
62          { res, feats -> 
63             def c = 0
64             if (acceptResidue.call(res))
65             {
66                 if (acceptFeatures.call(feats))
67                 {
68                     c++
69                 }
70             }
71             c
72          }
73      ] as FeatureCounterI
74 }
75
76 /*
77  * Define an annotation that counts any residue with Pfam domain annotation
78  */
79 def pfamAnnotation = getColumnCounter("Pfam", "Count of residues with Pfam domain annotation", {true}, hasPfam)
80
81 /*
82  * Define an annotation that counts charged residues with Pfam domain annotation
83  */
84 def chargedPfamAnnotation = getColumnCounter("Pfam charged", "Count of charged residues with Pfam domain annotation", isCharged, hasPfam)
85
86 /*
87  * Register the annotations
88  */
89 AlignmentAnnotationFactory.newCalculator(pfamAnnotation) 
90 AlignmentAnnotationFactory.newCalculator(chargedPfamAnnotation)