Go2Color.init_goid2color()   D
last analyzed

Complexity

Conditions 12

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 12
dl 0
loc 29
rs 4.8
c 1
b 0
f 0

How to fix   Complexity   

Complexity

Complex classes like Go2Color.init_goid2color() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
"""Manages GO Term fill colors and bordercolors."""
2
3
__copyright__ = "Copyright (C) 2016-2018, DV Klopfenstein, H Tang, All rights reserved."
4
__author__ = "DV Klopfenstein"
5
6
import collections as cx
7
from goatools.gosubdag.utils import get_kwargs
8
9
10
class Go2Color(object):
11
    """Manages GO Term fill colors and bordercolors."""
12
13
    kws_dct = set(['go2color', 'go2bordercolor', 'dflt_bordercolor', 'key2col'])
14
15
    alpha2col = cx.OrderedDict([
16
        # GOEA GO terms that are significant
17
        (0.005, 'mistyrose'),
18
        (0.010, 'moccasin'),
19
        (0.050, 'lemonchiffon1'),
20
        # GOEA GO terms that are not significant
21
        (1.000, 'grey95'),
22
    ])
23
24
    key2col = {
25
        'level_01': '#f1fbfd', # Very light blue
26
        'go_sources': '#ffffe4', # xkcd off white
27
        'go_leafchild': '#eae8e8', # 'Grey palette' http://www.color-hex.com/color-palette/45491
28
    }
29
30
31
    def __init__(self, gosubdag, objgoea=None, **kws):
32
        # kws: go2color go2bordercolor dflt_bordercolor
33
        self.kws = get_kwargs(kws, self.kws_dct, None)
34
        # Use default key coloring if user does not specify to turn it off (key2col=False)
35
        if 'key2col' not in kws or kws['key2col']:
36
            self.kws['key2col'] = self.key2col
37
        self.gosubdag = gosubdag  # GoSubDag
38
        self.objgoea = objgoea    # GoeaResults
39
        self.dflt_bordercolor = kws.get('dflt_bordercolor', 'mediumseagreen')
40
        self.go2color = self.init_goid2color()
41
        self.go2bordercolor = kws.get('go2bordercolor', {})
42
        self._init_equiv()
43
44
    def get_bordercolor(self, goid):
45
        """Return GO Term border color."""
46
        return self.go2bordercolor.get(goid, self.dflt_bordercolor)
47
48
    def init_goid2color(self):
49
        """Set colors of GO terms."""
50
        goid2color = {}
51
        # 1. User-specified colors for each GO term
52
        if 'go2color' in self.kws:
53
            for goid, color in self.kws['go2color'].items():
54
                goid2color[goid] = color
55
        # 2. colors based on p-value override colors based on source GO
56
        if self.objgoea is not None:
57
            self.objgoea.set_goid2color_pval(goid2color)
58
        key2color = self.kws.get('key2col')
59
        if key2color is not None:
60
            # 3. Default GO source color
61
            if 'go_sources' in key2color:
62
                color = key2color['go_sources']
63
                go2obj = self.gosubdag.go2obj
64
                for goid in self.gosubdag.go_sources:
65
                    if goid not in goid2color:
66
                        goobj = go2obj[goid]
67
                        goid2color[goobj.id] = color
68
                        goid2color[goid] = color
69
            # 4. Level-01 GO color
70
            if 'level_01' in key2color:
71
                color = key2color['level_01']
72
                for goid, goobj in self.gosubdag.go2obj.items():
73
                    if goobj.level == 1:
74
                        if goid not in goid2color:
75
                            goid2color[goid] = color
76
        return goid2color
77
78
    def _init_equiv(self):
79
        """Add equivalent GO IDs to go2color, if necessary."""
80
        gocolored_all = set(self.go2color)
81
        go2obj_usr = self.gosubdag.go2obj
82
        go2color_add = {}
83
        for gocolored_cur, color in self.go2color.items():
84
            # Ignore GOs in go2color that are not in the user set
85
            if gocolored_cur in go2obj_usr:
86
                goobj = go2obj_usr[gocolored_cur]
87
                goids_equiv = goobj.alt_ids.union([goobj.id])
88
                # mrk_alt = "*" if gocolored_cur != goobj.id else ""
89
                # print("COLORED({}) KEY({}){:1} ALL({})".format(
90
                #     gocolored_cur, goobj.id, mrk_alt, goids_equiv))
91
                # Loop through GO IDs which are not colored, but are equivalent to colored GO IDs.
92
                for goid_add in goids_equiv.difference(gocolored_all):
93
                    if goid_add in go2color_add:
94
                        print('**TBD: TWO DIFFERENT COLORS FOR EQUIV GO ID') # pylint: disable=superfluous-parens
95
                    go2color_add[goid_add] = color
96
        # print("ADDING {N} GO IDs TO go2color".format(N=len(go2color_add)))
97
        for goid, color in go2color_add.items():
98
            self.go2color[goid] = color
99
100
101
# Copyright (C) 2016-2018, DV Klopfenstein, H Tang, All rights reserved.
102