source: orange-bioinformatics/obiGeneSetSig.py @ 1592:c39f563cc473

Revision 1592:c39f563cc473, 6.5 KB checked in by markotoplak, 2 years ago (diff)

Added Mean and Median to the new gene set signatures module.

Line 
1import Orange
2import obiAssess
3import Orange.misc
4import obiGeneSets
5import obiGene
6import numpy
7from collections import defaultdict
8import stats
9import obiGsea
10
11def setSig_example_geneset(ex, data):
12    """ Gets learning data and example with the same domain, both
13    containing only genes from the gene set. """
14
15    distances = [ [], [] ]   
16
17    def pearsonr(v1, v2):
18        return numpy.corrcoef([v1, v2])[0,1]
19
20    def pearson(ex1, ex2):
21        #leaves undefined elements out
22
23        attrs = range(len(ex1.domain.attributes))
24        vals1 = [ ex1[i].value for i in attrs ]
25        vals2 = [ ex2[i].value for i in attrs ]
26
27        common = [ True if v1 != "?" and v2 != "?" else False \
28            for v1,v2 in zip(vals1,vals2) ]
29        vals1 = [ v for v,c in zip(vals1, common) if c ]
30        vals2 = [ v for v,c in zip(vals2, common) if c ]
31
32        return numpy.corrcoef([vals1, vals2])[0,1]
33
34    def ttest(ex1, ex2):
35        try:
36            return stats.lttest_ind(ex1, ex2)[0]
37        except:
38            return 0.0
39   
40    #maps class value to its index
41    classValueMap = dict( [ (val,i) for i,val in enumerate(data.domain.class_var.values) ])
42 
43    #create distances to all learning data - save or other class
44    for c in data:
45        distances[classValueMap[c[-1].value]].append(pearson(c, ex))
46
47    return ttest(distances[0], distances[1])
48
49def mat_ni(data, matcher):
50    nm = matcher([at.name for at in data.domain.attributes])
51    name_ind = dict((n.name,i) for i,n in enumerate(data.domain.attributes))
52    return nm, name_ind
53
54def select_genesets(nm, gene_sets, min_size=3, max_size=1000, min_part=0.1):
55    """ Returns a list of gene sets that have sizes in limits """
56
57    def ok_sizes(gs):
58        """compares sizes of genesets to limitations"""
59        transl = filter(lambda x: x != None, [ nm.umatch(gene) for gene in gs.genes ])
60        if len(transl) >= min_size \
61            and len(transl) <= max_size \
62            and float(len(transl))/len(gs.genes) >= min_part:
63            return True
64        return False
65
66    return filter(ok_sizes, gene_sets) 
67
68class GeneSetTrans(object):
69
70    __new__ = Orange.misc._orange__new__(object)
71
72    def _mat_ni(self, data):
73        """ With cached gene matchers. """
74        if data.domain not in self._cache:
75            self._cache[data.domain] = mat_ni(data, self.matcher)
76        return self._cache[data.domain]
77
78    def __init__(self, matcher=None, gene_sets=None, min_size=3, max_size=1000, min_part=0.1, class_values=None):
79        self.matcher = matcher
80        self.gene_sets = gene_sets
81        self.min_size = min_size
82        self.max_size = max_size
83        self.min_part = min_part
84        self.class_values = class_values
85        self._cache = {}
86
87    def __call__(self, data, weight_id=None):
88
89        #selection of classes and gene sets
90        data = obiGsea.takeClasses(data, classValues=self.class_values)
91        nm,_ =  self._mat_ni(data)
92        gene_sets = select_genesets(nm, self.gene_sets, self.min_size, self.max_size, self.min_part)
93
94        #build a new domain
95        newfeatures = self.build_features(data, gene_sets)
96        newdomain = Orange.data.Domain(newfeatures, data.domain.class_var)
97        return Orange.data.Table(newdomain, data)
98
99def vou(ex, gn, indices):
100    """ returns the value or "?" for the given gene name gn"""
101    if gn not in indices:
102        return "?"
103    else:
104        return ex[indices[gn]].value
105
106class SetSig(GeneSetTrans):
107
108    def build_features(self, data, gene_sets):
109
110        attributes = []
111
112        for gs in gene_sets:
113            at = Orange.feature.Continuous(name=str(gs))
114
115            def t(ex, w, gs=gs, data=data): #copy od the data
116                geneset = list(gs.genes)
117
118                nm, name_ind = self._mat_ni(data)
119                nm2, name_ind2 = self._mat_ni(ex)
120
121                genes = [ nm.umatch(gene) for gene in geneset ]
122                genes2 = [ nm2.umatch(gene) for gene in geneset ]
123
124                genes, genes2 = zip(*[ (g,g2) for g,g2 in zip(genes, genes2) if g != None])
125
126                domain = Orange.data.Domain([data.domain.attributes[name_ind[gene]] for gene in genes], data.domain.class_var)
127                datao = Orange.data.Table(domain, data)
128               
129                #convert the example to the same domain
130                exvalues = [ vou(ex, gn, name_ind2) for gn in genes2 ] + [ "?" ]
131                example = Orange.data.Instance(domain, exvalues)
132
133                return setSig_example_geneset(example, datao) #only this one is setsig specific
134         
135            at.get_value_from = t
136            attributes.append(at)
137
138        return attributes
139
140class SimpleFun(GeneSetTrans):
141
142    def build_features(self, data, gene_sets):
143
144        attributes = []
145
146        for gs in gene_sets:
147            at = Orange.feature.Continuous(name=str(gs))
148
149            def t(ex, w, gs=gs):
150                geneset = list(gs.genes)
151                nm2, name_ind2 = self._mat_ni(ex)
152                genes2 = [ nm2.umatch(gene) for gene in geneset ]
153               
154                exvalues = [ vou(ex, gn, name_ind2) for gn in genes2 ] + [ "?" ]
155                exvalues = filter(lambda x: x != "?", exvalues)
156
157                return self.fn(exvalues)
158         
159            at.get_value_from = t
160            attributes.append(at)
161
162        return attributes
163
164class Mean(SimpleFun):
165
166    def __init__(self, **kwargs):
167       self.fn = numpy.mean
168       super(Mean, self).__init__(**kwargs)
169
170class Median(SimpleFun):
171
172    def __init__(self, **kwargs):
173       self.fn = numpy.median
174       super(Median, self).__init__(**kwargs)
175
176if __name__ == "__main__":
177
178    data = Orange.data.Table("iris")
179    gsets = obiGeneSets.collections({
180        "ALL": ['sepal length', 'sepal width', 'petal length', 'petal width'],
181        "f3": ['sepal length', 'sepal width', 'petal length'],
182        "l3": ['sepal width', 'petal length', 'petal width'],
183        })
184    matcher = obiGene.matcher([])
185    choosen_cv = ["Iris-setosa", "Iris-versicolor"]
186
187    """
188    data = Orange.data.Table("DLBCL_200a")
189    gsets = obiGeneSets.collections((("KEGG",),"9606"))
190    matcher = obiGene.matcher([obiGene.GMKEGG("hsa")])
191    choosen_cv = None
192    """
193
194    def to_old_dic(d, data):
195        ar = defaultdict(list)
196        for ex1 in data:
197            ex = d(ex1)
198            for a,x in zip(d.attributes, ex):
199                ar[a.name].append(x.value)
200        return ar
201
202    def pp2(ar):
203        ol =  sorted(ar.items())
204        print '\n'.join([ a + ": " +str(b) for a,b in ol])
205
206    ass = Median(data, matcher=matcher, gene_sets=gsets, class_values=choosen_cv, min_part=0.0)
207    ar = to_old_dic(ass.domain, data[:5])
208    pp2(ar)
Note: See TracBrowser for help on using the repository browser.