1/*
2 * Jalview - A Sequence Alignment Editor and Viewer (2.11.1.4)
3 * Copyright (C) 2021 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 */
21import jalview.bin.Jalview
22import jalview.workers.FeatureSetCounterI
23import jalview.workers.AlignmentAnnotationFactory
24
25/*
26 * Demonstration of FeatureSetCounterI
27 * compute annotation tracks counting number of displayed
28 * features of each type in each column
29 */
30
31/*
32 * discover features on the current view
33 */
34
35def featuresDisp=Jalview.currentAlignFrame.currentView.featuresDisplayed
36if (featuresDisp == null) {
37    print 'Need at least one feature visible on alignment'
38}
39def visibleFeatures=featuresDisp.visibleFeatures.toList()
40assert 'java.util.ArrayList' == visibleFeatures.class.name
41
42/*
43 * A closure that returns an array of features present
44 * for each feature type in visibleFeatures
45 * Argument 'features' will be a list of SequenceFeature
46 */
47def getCounts =
48    { features ->
49        int[] obs = new int[visibleFeatures.size]
50        for (sf in features)
51        {
52            /*
53             * Here we inspect the type of the sequence feature.
54             * You can also test sf.description, sf.score, sf.featureGroup,
55             * sf.strand, sf.phase, sf.begin, sf.end
56             * or sf.getValue(attributeName) for GFF 'column 9' properties
57             */
58            int pos = 0
59            for (type in visibleFeatures)
60            {
61              if (type.equals(sf.type))
62              {
63                  obs[pos]++
64              }
65              pos++
66            }
67        }
68        obs
69}
70
71/*
72 * Define something that counts each visible feature type
73 */
74def columnSetCounter =
75    [
76     getNames: { visibleFeatures as String[] },
77     getDescriptions:  { visibleFeatures as String[] },
78     getMinColour: { [0, 255, 255] as int[] }, // cyan
79     getMaxColour: { [0, 0, 255] as int[] }, // blue
80     count:
81         { res, feats ->
82             getCounts.call(feats)
83         }
84     ] as FeatureSetCounterI
85
86/*
87 * and register the counter
88 */
89AlignmentAnnotationFactory.newCalculator(columnSetCounter)
90