Changeset 1407:19c39cf0f9d8 in orange-bioinformatics


Ignore:
Timestamp:
06/03/11 12:11:30 (3 years ago)
Author:
ales_erjavec <ales.erjavec@…>
Branch:
default
Convert:
01c077d82e066bc4a809ad9fd86e34dab07d0944
Message:

Using the LabelSelectionWidget from OWVulcanoPlot for target selection.
Removed Zoom/Select/Pan toolbox.
Changed method and variable names for underscore naming style.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • widgets/OWFeatureSelection.py

    r1360 r1407  
    1616from OWHist import OWInteractiveHist 
    1717from OWToolbars import ZoomSelectToolbar 
     18 
    1819from obiGEO import transpose 
    1920from collections import defaultdict 
    2021from functools import wraps 
     22from operator import add 
    2123import numpy as np 
    2224import numpy.ma as ma 
     
    2628class ExpressionSignificance_TTest_PValue(ExpressionSignificance_TTest): 
    2729    def __call__(self, *args, **kwargs): 
    28         return [(key, pval) for key, (t, pval) in ExpressionSignificance_TTest.__call__(self, *args, **kwargs)] 
     30        return [(key, pval) for key, (t, pval) in \ 
     31                ExpressionSignificance_TTest.__call__(self, *args, **kwargs)] 
    2932     
    3033class ExpressionSignificance_TTest_T(ExpressionSignificance_TTest): 
    3134    def __call__(self, *args, **kwargs): 
    32         return [(key, t) for key, (t, pval) in ExpressionSignificance_TTest.__call__(self, *args, **kwargs)] 
     35        return [(key, t) for key, (t, pval) in \ 
     36                ExpressionSignificance_TTest.__call__(self, *args, **kwargs)] 
    3337     
    3438class ExpressionSignificance_ANOVA_PValue(ExpressionSignificance_ANOVA): 
    3539    def __call__(self, *args, **kwargs): 
    36         return [(key, pval) for key, (t, pval) in ExpressionSignificance_ANOVA.__call__(self, *args, **kwargs)] 
     40        return [(key, pval) for key, (t, pval) in \ 
     41                ExpressionSignificance_ANOVA.__call__(self, *args, **kwargs)] 
    3742     
    3843class ExpressionSignificance_ANOVA_F(ExpressionSignificance_ANOVA): 
    3944    def __call__(self, *args, **kwargs): 
    40         return [(key, f) for key, (f, pval) in ExpressionSignificance_ANOVA.__call__(self, *args, **kwargs)] 
     45        return [(key, f) for key, (f, pval) in \ 
     46                ExpressionSignificance_ANOVA.__call__(self, *args, **kwargs)] 
    4147     
    4248class ExpressionSignificance_Log2FoldChange(ExpressionSignificance_FoldChange): 
    4349    def __call__(self, *args, **kwargs): 
    44         return [(key, math.log(fold, 2.0) if fold > 1e-300 and fold < 1e300 else 0.0) for key, fold in ExpressionSignificance_FoldChange.__call__(self, *args, **kwargs)] 
     50        return [(key, math.log(fold, 2.0) if fold > 1e-300 and fold < 1e300 else 0.0) \ 
     51                for key, fold in ExpressionSignificance_FoldChange.__call__(self, *args, **kwargs)] 
    4552     
    4653class ExpressionSignigicance_MannWhitneyu_U(ExpressionSignificance_MannWhitneyu): 
    4754    def __call__(self, *args, **kwargs): 
    48         return [(key, u) for key, (u, p_val) in ExpressionSignificance_MannWhitneyu.__call__(self, *args, **kwargs)]     
     55        return [(key, u) for key, (u, p_val) in \ 
     56                ExpressionSignificance_MannWhitneyu.__call__(self, *args, **kwargs)]     
    4957     
    5058class ScoreHist(OWInteractiveHist): 
     
    5765    def setBoundary(self, low, hi): 
    5866        OWInteractiveHist.setBoundary(self, low, hi) 
    59         self.master.UpdateSelectedInfoLabel(low, hi) 
    60         self.master.CommitIf() 
     67        self.master.update_selected_info_label(low, hi) 
     68        self.master.commit_if() 
    6169             
    6270def disable_controls(method): 
     
    7280            self.controlArea.setDisabled(False) 
    7381    return f 
    74          
     82 
     83from orngDataCaching import data_hints 
     84from OWGenotypeDistances import SetContextHandler 
     85from OWVulcanoPlot import LabelSelectionWidget 
     86 
    7587class OWFeatureSelection(OWWidget): 
    76     settingsList = ["methodIndex", "dataLabelIndex", "computeNullDistribution", "permutationsCount", "selectPValue", "autoCommit"] 
    77 ##    contextHandlers={"":DomainContextHandler("",[])} 
     88    settingsList = ["method_index", "dataLabelIndex", "compute_null", 
     89                    "permutations_count", "selectPValue", "auto_commit"] 
     90    contextHandlers={"Data": DomainContextHandler("Data", ["genes_in_columns"]), 
     91                     "TargetSelection": SetContextHandler("TargetSelection", 
     92                                                          findImperfect=False)} 
     93     
    7894    def __init__(self, parent=None, signalManager=None, name="Gene selection"): 
    7995        OWWidget.__init__(self, parent, signalManager, name, wantGraph=True, showSaveGraph=True) 
    80         self.inputs = [("Examples", ExampleTable, self.SetData)] 
     96        self.inputs = [("Examples", ExampleTable, self.set_data)] 
    8197        self.outputs = [("Example table with selected genes", ExampleTable), ("Example table with remaining genes", ExampleTable), ("Selected genes", ExampleTable)] 
    8298 
    83         self.methodIndex = 0 
    84         self.dataLabelIndex = 0 
    85         self.computeNullDistribution = False 
    86         self.permutationsCount = 10 
    87         self.autoCommit = False 
     99        self.method_index = 0 
     100#        self.dataLabelIndex = 0 
     101        self.genes_in_columns = False 
     102        self.compute_null = False 
     103        self.permutations_count = 10 
     104        self.auto_commit = False 
    88105        self.selectNBest = 20 
    89106        self.selectPValue = 0.01 
    90         self.dataChangedFlag = False 
    91         self.addScoresToOutput = True 
     107        self.data_changed_flag = False 
     108        self.add_scores_to_output = True 
    92109 
    93110        self.oneTailTestHi = oneTailTestHi = lambda array, low, hi: array >= hi 
     
    98115        self.histType = {oneTailTestHi:"hiTail", oneTailTestLow:"lowTail", twoTailTest:"twoTail", middleTest:"middle"} 
    99116 
    100         self.scoreMethods = [("fold change", ExpressionSignificance_FoldChange, twoTailTest), 
    101                              ("log2 fold change", ExpressionSignificance_Log2FoldChange, twoTailTest), 
    102                              ("t-test", ExpressionSignificance_TTest_T, twoTailTest), 
    103                              ("t-test p-value", ExpressionSignificance_TTest_PValue, oneTailTestLow), 
    104                              ("anova", ExpressionSignificance_ANOVA_F, oneTailTestHi), 
    105                              ("anova p-value", ExpressionSignificance_ANOVA_PValue, oneTailTestLow), 
    106                              ("signal to noise ratio", ExpressionSignificance_SignalToNoise, twoTailTest), 
    107                              ("info gain", ExpressionSignificance_Info, oneTailTestHi), 
    108                              ("chi-square", ExpressionSignificance_ChiSquare, oneTailTestHi), 
    109                              ("mann-whitney", ExpressionSignigicance_MannWhitneyu_U, oneTailTestLow)] 
     117        # [(name, func, tail test, two sample test), ...] 
     118        self.score_methods = [("fold change", ExpressionSignificance_FoldChange, twoTailTest, True), 
     119                             ("log2 fold change", ExpressionSignificance_Log2FoldChange, twoTailTest, True), 
     120                             ("t-test", ExpressionSignificance_TTest_T, twoTailTest, True), 
     121                             ("t-test p-value", ExpressionSignificance_TTest_PValue, oneTailTestLow, True), 
     122                             ("anova", ExpressionSignificance_ANOVA_F, oneTailTestHi, False), 
     123                             ("anova p-value", ExpressionSignificance_ANOVA_PValue, oneTailTestLow, False), 
     124                             ("signal to noise ratio", ExpressionSignificance_SignalToNoise, twoTailTest, True), 
     125                             ("info gain", ExpressionSignificance_Info, oneTailTestHi, True), 
     126                             ("chi-square", ExpressionSignificance_ChiSquare, oneTailTestHi, True), 
     127                             ("mann-whitney", ExpressionSignigicance_MannWhitneyu_U, oneTailTestLow, True)] 
    110128 
    111129        boxHistogram = OWGUI.widgetBox(self.mainArea) 
     
    116134        box = OWGUI.widgetBox(self.controlArea, "Info") 
    117135        self.dataInfoLabel = OWGUI.widgetLabel(box, "\n\n") 
     136        self.dataInfoLabel.setWordWrap(True) 
    118137        self.selectedInfoLabel = OWGUI.widgetLabel(box, "") 
    119138 
    120139        box1 = OWGUI.widgetBox(self.controlArea, "Scoring Method") 
    121         self.testRadioBox = OWGUI.comboBox(box1, self, "methodIndex", 
    122                                     items=[sm[0] for sm in self.scoreMethods], 
    123                                     callback=self.Update) 
    124          
    125         self.dataLabelComboBox = OWGUI.comboBox(box1, self, "dataLabelIndex", "Attribute labels", 
    126                                                 callback=self.Update, 
    127                                                 tooltip="Use attribute labels for score computation") 
    128      
    129         ZoomSelectToolbar(self, self.controlArea, self.histogram, 
    130                           buttons=[ZoomSelectToolbar.IconSelect, 
    131                                    ZoomSelectToolbar.IconZoom, 
    132                                    ZoomSelectToolbar.IconPan]) 
     140        self.testRadioBox = OWGUI.comboBox(box1, self, "method_index", 
     141                                    items=[sm[0] for sm in self.score_methods], 
     142                                    callback=[self.on_scoring_method_changed, self.update_scores]) 
     143         
     144        box = OWGUI.widgetBox(self.controlArea, "Target Labels") 
     145        self.label_selection_widget = LabelSelectionWidget(self) 
     146        self.label_selection_widget.setMaximumHeight(150) 
     147        box.layout().addWidget(self.label_selection_widget) 
     148        self.connect(self.label_selection_widget, 
     149                     SIGNAL("selection_changed()"), 
     150                     self.on_target_changed) 
     151         
     152        self.connect(self.label_selection_widget, 
     153                     SIGNAL("label_activated(int)"), 
     154                     self.on_label_activated) 
     155         
     156        self.genes_in_columns_check = OWGUI.checkBox(box, self, "genes_in_columns", 
     157                                                  "Genes in columns", 
     158                                                  callback=self.on_genes_in_columns_change) 
     159     
     160#        ZoomSelectToolbar(self, self.controlArea, self.histogram, 
     161#                          buttons=[ZoomSelectToolbar.IconSelect, 
     162#                                   ZoomSelectToolbar.IconZoom, 
     163#                                   ZoomSelectToolbar.IconPan]) 
    133164         
    134165        box = OWGUI.widgetBox(self.controlArea, "Selection") 
    135166        box.layout().setSpacing(0) 
    136         callback = self.SetBoundary 
     167        callback = self.update_boundary 
    137168        self.upperBoundarySpin = OWGUI.doubleSpin(box, self, "histogram.upperBoundary", 
    138169                                                  min=-1e6, max=1e6, step= 1e-6, 
     
    147178                                                  callbackOnReturn=True) 
    148179         
    149         check = OWGUI.checkBox(box, self, "computeNullDistribution", "Compute null distribution", 
    150                                callback=self.Update) 
    151  
    152         check.disables.append(OWGUI.spin(box, self, "permutationsCount", min=1, max=10,  
    153                                          label="Permutations:", callback=self.Update,  
     180        check = OWGUI.checkBox(box, self, "compute_null", "Compute null distribution", 
     181                               callback=self.update_scores) 
     182 
     183        check.disables.append(OWGUI.spin(box, self, "permutations_count", min=1, max=10,  
     184                                         label="Permutations:", callback=self.update_scores,  
    154185                                         callbackOnReturn=True)) 
    155186 
     
    158189                                               min=2e-7, max=1.0, step=1e-7,  
    159190                                               label="P-value:")) 
    160         check.disables.append(OWGUI.button(box1, self, "Select", callback=self.SelectPBest)) 
     191        check.disables.append(OWGUI.button(box1, self, "Select", callback=self.select_p_best)) 
    161192        check.makeConsistent() 
    162193 
    163194        box1 = OWGUI.widgetBox(box, orientation='horizontal') 
    164195        OWGUI.spin(box1, self, "selectNBest", 0, 10000, step=1, label="Best Ranked:") 
    165         OWGUI.button(box1, self, "Select", callback=self.SelectNBest) 
     196        OWGUI.button(box1, self, "Select", callback=self.select_n_best) 
    166197 
    167198        box = OWGUI.widgetBox(self.controlArea, "Output") 
    168         b = OWGUI.button(box, self, "&Commit", callback=self.Commit) 
    169         cb = OWGUI.checkBox(box, self, "autoCommit", "Commit on change") 
    170         OWGUI.setStopper(self, b, cb, "dataChangedFlag", self.Commit) 
    171         OWGUI.checkBox(box, self, "addScoresToOutput", "Add gene scores to output", 
    172                        callback=self.CommitIf)  
     199        b = OWGUI.button(box, self, "&Commit", callback=self.commit) 
     200        cb = OWGUI.checkBox(box, self, "auto_commit", "Commit on change") 
     201        OWGUI.setStopper(self, b, cb, "data_changed_flag", self.commit) 
     202        OWGUI.checkBox(box, self, "add_scores_to_output", "Add gene scores to output", 
     203                       callback=self.commit_if)  
    173204         
    174205        OWGUI.rubber(self.controlArea) 
     
    184215        self.cuts = {} 
    185216        self.discretizer = orange.EquiNDiscretization(numberOfIntervals=5) 
    186         self.transposedData = False 
    187         self.nullDistribution = [] 
     217        self.null_dist = [] 
    188218        self.targets = [] 
    189219        self.scores = {} 
    190  
     220        self.genes_in_columns = True 
     221        self.target_selections = None 
     222         
     223        self.on_scoring_method_changed() 
     224         
    191225        self.resize(800, 600) 
    192226         
    193     def SetData(self, data): 
    194         self.error(0) 
    195         self.error(1) 
    196         self.warning(0) 
     227    def clear(self): 
     228        """ Clear widget. 
     229        """ 
    197230        self.scoreCache = {} 
    198231        self.nullDistCache = {} 
    199232        self.discData = None 
     233        self.data = None 
     234        self.attribute_targets = [] 
     235        self.class_targets = [] 
     236        self.label_selection_widget.clear() 
     237        self.clear_plot() 
     238         
     239    def clear_plot(self): 
     240        """ Clear the histogram plot. 
     241        """ 
     242        self.histogram.removeDrawingCurves() 
     243        self.histogram.clear() 
     244        self.histogram.replot() 
     245         
     246    def init_from_data(self, data): 
     247        """ Init widget state from the data. 
     248        """ 
     249        if data: 
     250            items = [attr.attributes.items() for attr in data.domain.attributes] 
     251            items = reduce(add, items, []) 
     252             
     253            targets = defaultdict(set) 
     254            for label, value in items: 
     255                targets[label].add(value) 
     256                 
     257            targets = [(key, sorted(vals)) for key, vals in targets.items() \ 
     258                       if len(vals) >= 2] 
     259            self.attribute_targets = targets 
     260             
     261            class_var = data.domain.class_var 
     262            if class_var and isinstance(class_var, orange.EnumVariable): 
     263                targets = [(class_var.name, 
     264                            list(class_var.values))] 
     265                self.class_targets = targets 
     266            else: 
     267                self.class_targets = [] 
     268             
     269    def update_targets_widget(self): 
     270        """ Update the contents of the targets widget. 
     271        """ 
     272        if self.data: 
     273            if self.genes_in_columns: 
     274                targets = self.attribute_targets 
     275            elif self.data.domain.classVar: 
     276                targets = self.class_targets 
     277            else: 
     278                targets = [] 
     279        else: 
     280            targets = [] 
     281             
     282        self.label_selection_widget.clear() 
     283        self.label_selection_widget.set_labels(targets) 
     284        self.data_labels = targets 
     285         
     286    def set_data(self, data): 
     287        self.closeContext("Data") 
     288        self.closeContext("TargetSelection") 
     289        self.error([0, 1]) 
     290        self.warning(0) 
     291        self.clear() 
     292        self.genes_in_columns_check.setEnabled(True) 
    200293        self.data = data 
    201         self.transposedData = None 
    202         disabled = [] 
     294        self.init_from_data(data) 
     295         
    203296        if self.data: 
    204             self.dataLabels = reduce(lambda dict, tags: [dict[key].add(value) for key, value in tags.items()] and False or dict, 
    205                                        [attr.attributes for attr in self.data.domain.attributes], 
    206                                        defaultdict(set)) 
    207             self.dataLabels = [key for key, value in self.dataLabels.items() if len(value) > 1] 
    208         else: 
    209             self.dataLabels = [] 
    210         self.dataLabelComboBox.clear() 
    211         if self.data and data.domain.classVar and data.domain.classVar.varType == orange.VarTypes.Discrete: 
    212             self.dataLabels = ["(None)"] + self.dataLabels 
    213         self.dataLabelComboBox.addItems(self.dataLabels) 
    214          
    215         self.dataLabelComboBox.setDisabled(len(self.dataLabels) <= 1) 
    216         self.dataLabelIndex = max(min(self.dataLabelIndex, len(self.dataLabels) - 1), 0) 
    217          
    218         if self.data and not self.dataLabels: 
     297            self.genes_in_columns = not data_hints.get_hint(data, "genesinrows", False) 
     298            self.openContext("Data", data) 
     299             
     300            # If only attr. labels or only class values then disable the 'Genes in columns' control 
     301            if not self.attribute_targets or not self.class_targets: 
     302                self.genes_in_columns_check.setEnabled(False) 
     303                self.genes_in_columns = bool(self.attribute_targets) 
     304         
     305        self.update_targets_widget() 
     306         
     307        # If both attr. labels and classes are missing, show an error 
     308        if not (self.attribute_targets or self.class_targets): 
     309#        if self.data and not self.data_labels: 
    219310            self.error(1, "Cannot compute gene scores! Gene Selection widget requires a data-set with a discrete class variable or attribute labels!") 
    220311            self.data = None 
    221         self.Update() 
     312         
     313        if self.data: 
     314            # Load context selection 
     315            items = [(label, v) for label, values in self.data_labels for v in values] 
     316             
     317            self.target_selections = [values[:1] for _, values in self.data_labels] 
     318            label, values = self.data_labels[0] 
     319            self.current_target_selection = label, values[:1] # Default selections 
     320             
     321            self.openContext("TargetSelection", set(items)) # Load selections from context 
     322            self.label_selection_widget.set_selection(*self.current_target_selection) 
     323 
    222324        if not self.data: 
    223             self.UpdateDataInfoLabel() 
    224325            self.send("Example table with selected genes", None) 
    225326            self.send("Example table with remaining genes", None) 
    226327            self.send("Selected genes", None) 
    227      
    228     def ComputeScores(self, data, scoreFunc, useAttributeLabels, target=None, advance=lambda :None): 
    229         scoreFunc = scoreFunc(data, useAttributeLabels) 
     328             
     329    def set_targets(self, targets): 
     330        """ Set the target groups for score computation. 
     331        """ 
     332        self.targets = targets 
     333        self.update_scores() 
     334     
     335    def compute_scores(self, data, score_func, use_attribute_labels, 
     336                       target=None, advance=lambda: None): 
     337        score_func = score_func(data, use_attribute_labels) 
    230338        advance() 
    231         score = scoreFunc(target=target) 
     339        score = score_func(target=target) 
    232340        score = [(key, val) for key, val in score if val is not ma.masked] 
    233341        return score 
    234342     
    235     def ComputeNullDistribution(self, data, scoreFunc, useAttributes, target=None, permCount=10, advance=lambda: None): 
    236         scoreFunc = scoreFunc(data, useAttributes) 
    237         dist = scoreFunc.null_distribution(permCount, target, advance=advance) 
     343    def compute_null_distribution(self, data, score_func, use_attributes, 
     344                                  target=None, perm_count=10, advance=lambda: None): 
     345        score_func = score_func(data, use_attributes) 
     346        dist = score_func.null_distribution(perm_count, target, advance=advance) 
    238347        return [score for run in dist for k, score in run if score is not ma.masked] 
    239          
    240     def Update(self): 
    241         if not self.data: 
    242             self.histogram.removeDrawingCurves() 
    243             self.histogram.clear() 
    244             self.histogram.replot() 
    245         else: 
    246             self.UpdateScores() 
    247348             
    248349    @disable_controls 
    249     def UpdateScores(self): 
     350    def update_scores(self): 
    250351        """ Compute the scores and update the histogram. 
    251352        """ 
    252         targetLabel = self.dataLabels[self.dataLabelIndex] 
    253         if targetLabel == "(None)": 
    254             target = [self.data.domain.classVar(0), self.data.domain.classVar(1)] 
    255             self.targets = targets = list(self.data.domain.classVar.values) 
    256             self.genesInColumns = False 
    257         else: 
    258             self.targets = targets = list(set([attr.attributes.get(targetLabel) for attr in self.data.domain.attributes]) - set([None])) 
    259             target = [(targetLabel, targets[0]), (targetLabel, targets[1])] 
    260             self.genesInColumns = True 
    261         if self.methodIndex in [4, 5]: ## ANOVA 
    262             target = targets if targetLabel == "(None)" else [(targetLabel, t) for t in targets] 
    263         scoreFunc = self.scoreMethods[self.methodIndex][1]  
    264         pb = OWGUI.ProgressBar(self, 4 + self.permutationsCount if self.computeNullDistribution else 3) 
    265         self.scores = dict(self.ComputeScores(self.data, scoreFunc, self.genesInColumns, target, advance=pb.advance)) 
     353        self.clear_plot() 
     354        self.error(0) 
     355        if not self.data: 
     356            return 
     357        _, score_func, _, two_sample_test = self.score_methods[self.method_index] 
     358         
     359        target_label, target_values = self.current_target_selection 
     360        if two_sample_test: 
     361            target = self.targets 
     362            score_target = set(target) 
     363            ind1, ind2 = score_func(self.data, self.genes_in_columns).test_indices(score_target) 
     364            if not len(ind1) or not len(ind2): 
     365                self.error(0, "Target labels most exclude/include at least one value.") 
     366                return 
     367             
     368        else: # ANOVA should use all labels.  
     369            label, values = self.current_target_selection 
     370            target = dict(self.data_labels)[label] 
     371            if self.genes_in_columns: 
     372                target = [(label, t) for t in target] 
     373            score_target = target 
     374#            indices = score_func(self.data, self.genes_in_columns).test_indices(score_target) 
     375            # TODO: Check that each label has more than one measurement, raise warning otherwise. 
     376          
     377        pb = OWGUI.ProgressBar(self, 4 + self.permutations_count if self.compute_null else 3) 
     378        self.scores = dict(self.compute_scores(self.data, score_func, 
     379                    self.genes_in_columns, score_target, advance=pb.advance)) 
    266380        pb.advance() 
    267         if self.computeNullDistribution: 
    268             self.nullDistribution = self.ComputeNullDistribution(self.data, scoreFunc, self.genesInColumns, target, self.permutationsCount, advance=pb.advance) 
    269         else: 
    270             self.nullDistribution = [] 
     381        if self.compute_null: 
     382            self.null_dist = self.compute_null_distribution(self.data, 
     383                        score_func, self.genes_in_columns, score_target, 
     384                        self.permutations_count, advance=pb.advance) 
     385        else: 
     386            self.null_dist = [] 
    271387        pb.advance() 
    272         self.histogram.type = self.histType[self.scoreMethods[self.methodIndex][2]] 
     388        self.histogram.type = self.histType[self.score_methods[self.method_index][2]] 
    273389        if self.scores: 
    274390            self.histogram.setValues(self.scores.values()) 
    275 #        self.histogram.setBoundary(*self.cuts.get(None, (self.histogram.minx if self.histogram.type in ["lowTail", "twoTail"] else self.histogram.maxx, 
    276 #                                                                     self.histogram.maxx if self.histogram.type in ["hiTail", "twoTail"] else self.histogram.minx))) 
    277391            self.histogram.setBoundary(self.histogram.minx if self.histogram.type in ["lowTail", "twoTail"] else self.histogram.maxx, 
    278392                                       self.histogram.maxx if self.histogram.type in ["hiTail", "twoTail"] else self.histogram.minx) 
    279             if self.computeNullDistribution and self.nullDistribution: 
    280                 nullY, nullX = numpy.histogram(self.nullDistribution, bins=self.histogram.xData) 
    281                 self.histogram.nullCurve = self.histogram.addCurve("nullCurve", Qt.black, Qt.black, 6, symbol = QwtSymbol.NoSymbol, style = QwtPlotCurve.Steps, xData = nullX, yData = nullY/self.permutationsCount) 
     393            if self.compute_null and self.null_dist: 
     394                nullY, nullX = numpy.histogram(self.null_dist, bins=self.histogram.xData) 
     395                self.histogram.nullCurve = self.histogram.addCurve("nullCurve", 
     396                        Qt.black, Qt.black, 6, symbol=QwtSymbol.NoSymbol, 
     397                        style=QwtPlotCurve.Steps, xData = nullX, 
     398                        yData = nullY/self.permutations_count) 
    282399                 
    283400                minx = min(min(nullX), self.histogram.minx) 
    284401                maxx = max(max(nullX), self.histogram.maxx) 
    285                 miny = min(min(nullY/self.permutationsCount), self.histogram.miny) 
    286                 maxy = max(max(nullY/self.permutationsCount), self.histogram.maxy) 
     402                miny = min(min(nullY/self.permutations_count), self.histogram.miny) 
     403                maxy = max(max(nullY/self.permutations_count), self.histogram.maxy) 
    287404 
    288405                self.histogram.setAxisScale(QwtPlot.xBottom, minx - (0.05 * (maxx - minx)), maxx + (0.05 * (maxx - minx))) 
     
    292409                spin.setVisible(visible) 
    293410             
    294 ##            if self.methodIndex in [2, 3, 5, 6]: 
    295             if self.methodIndex in [0, 2, 6]: 
    296                 if self.methodIndex == 0: ## fold change is centered on 1.0 
     411            # If this is a two sample test add markers to the left and right 
     412            # plot indicating which target group is over-expressed in that 
     413            # part   
     414            if self.method_index in [0, 2, 6]: 
     415                if self.method_index == 0: ## fold change is centered on 1.0 
    297416                    x1, y1 = (self.histogram.minx + 1) / 2 , self.histogram.maxy 
    298417                    x2, y2 = (self.histogram.maxx + 1) / 2 , self.histogram.maxy 
     
    300419                    x1, y1 = (self.histogram.minx) / 2 , self.histogram.maxy 
    301420                    x2, y2 = (self.histogram.maxx) / 2 , self.histogram.maxy 
    302                 self.histogram.addMarker(self.targets[0], x1, y1) 
    303                 self.histogram.addMarker(self.targets[1], x2, y2) 
     421                if self.genes_in_columns: 
     422                    label = target[0][0] 
     423                    target_values = [t[1] for t in target] 
     424                    values = dict(self.data_labels)[label] 
     425                else: 
     426                    target_values = target 
     427                    values = self.data_labels[0][1] 
     428                     
     429                left = ", ".join(v for v in values if v not in target_values) 
     430                right = ", ".join(v for v in values if v in target_values) 
     431                     
     432                self.histogram.addMarker(left, x1, y1) 
     433                self.histogram.addMarker(right, x2, y2) 
    304434            self.warning(0) 
    305435        else: 
     
    308438        pb.advance() 
    309439        pb.finish() 
    310         self.UpdateDataInfoLabel() 
    311              
    312              
    313     def UpdateDataInfoLabel(self): 
     440        self.update_data_info_label() 
     441             
     442    def update_data_info_label(self): 
    314443        if self.data: 
    315444            samples, genes = len(self.data), len(self.data.domain.attributes) 
    316             if self.genesInColumns: 
     445            if self.genes_in_columns: 
    317446                samples, genes = genes, samples 
     447                target_labels = [t[1] for t in self.targets] 
     448            else: 
     449                target_labels = self.targets 
    318450            text = "%i samples, %i genes\n" % (samples, genes) 
    319             text += "Sample label: %s" % self.targets[0] 
     451            text += "Sample target: '%s'" % (",".join(target_labels)) 
    320452        else: 
    321453            text = "No data on input\n" 
    322454        self.dataInfoLabel.setText(text) 
    323455 
    324     def UpdateSelectedInfoLabel(self, cutOffLower=0, cutOffUpper=0): 
    325         self.cuts[self.methodIndex] = (cutOffLower, cutOffUpper) 
     456    def update_selected_info_label(self, cutOffLower=0, cutOffUpper=0): 
     457        self.cuts[self.method_index] = (cutOffLower, cutOffUpper) 
    326458        if self.data: 
    327459            scores = np.array(self.scores.values()) 
    328             test = self.scoreMethods[self.methodIndex][2] 
     460            test = self.score_methods[self.method_index][2] 
    329461            self.selectedInfoLabel.setText("%i selected genes" % len(np.nonzero(test(scores, cutOffLower, cutOffUpper))[0])) 
    330462        else: 
    331463            self.selectedInfoLabel.setText("0 selected genes") 
    332464 
    333     def SelectNBest(self): 
     465    def select_n_best(self): 
    334466        scores = self.scores.items() 
    335467        scores.sort(lambda a,b:cmp(a[1], b[1])) 
    336468        if not scores: 
    337469            return 
    338         if self.scoreMethods[self.methodIndex][2]==self.oneTailTestHi: 
     470        if self.score_methods[self.method_index][2]==self.oneTailTestHi: 
    339471            scores = scores[-max(self.selectNBest, 1):] 
    340472            self.histogram.setBoundary(scores[0][1], scores[0][1]) 
    341         elif self.scoreMethods[self.methodIndex][2]==self.oneTailTestLow: 
     473        elif self.score_methods[self.method_index][2]==self.oneTailTestLow: 
    342474            scores = scores[:max(self.selectNBest,1)] 
    343475            self.histogram.setBoundary(scores[-1][1], scores[-1][1]) 
     
    346478            scoresLo = scores[:max(min(self.selectNBest, len(scores)/2), 1)] 
    347479            scores = [(abs(score), 1) for attr, score in scoresHi] + [(abs(score), -1) for attr, score in scoresLo] 
    348             if self.scoreMethods[self.methodIndex][0]=="fold change": ## comparing fold change on a logaritmic scale 
     480            if self.score_methods[self.method_index][0]=="fold change": ## comparing fold change on a logaritmic scale 
    349481                scores =  [(abs(math.log(max(min(score, 1e300), 1e-300), 2.0)), sign) for score, sign in scores] 
    350482            scores.sort() 
     
    356488            self.histogram.setBoundary(cutLo, cutHi) 
    357489 
    358     def SetBoundary(self): 
     490    def update_boundary(self): 
    359491        if self.data != None and self.scores.items(): 
    360             if self.scoreMethods[self.methodIndex][2]==self.oneTailTestHi: 
     492            if self.score_methods[self.method_index][2]==self.oneTailTestHi: 
    361493                self.histogram.setBoundary(self.histogram.lowerBoundary, self.histogram.lowerBoundary) 
    362             elif self.scoreMethods[self.methodIndex][2]==self.oneTailTestLow: 
     494            elif self.score_methods[self.method_index][2]==self.oneTailTestLow: 
    363495                self.histogram.setBoundary(self.histogram.upperBoundary, self.histogram.upperBoundary) 
    364496            else: 
    365497                self.histogram.setBoundary(self.histogram.lowerBoundary, self.histogram.upperBoundary) 
    366498 
    367     def SelectPBest(self): 
    368         if not self.nullDistribution: 
     499    def select_p_best(self): 
     500        if not self.null_dist: 
    369501            return 
    370         nullDist = sorted(self.nullDistribution) 
    371         test = self.scoreMethods[self.methodIndex][2] 
     502        nullDist = sorted(self.null_dist) 
     503        test = self.score_methods[self.method_index][2] 
    372504        count = min(int(len(nullDist)*self.selectPValue), len(nullDist)) 
    373505        if test == self.oneTailTestHi: 
     
    381513            scoresLo = nullDist[:count] 
    382514            scores = [(abs(score), 1) for score in scoresHi] + [(abs(score), -1) for score in scoresLo] 
    383             if self.scoreMethods[self.methodIndex][0] == "fold change": ## fold change is on a logaritmic scale 
     515            if self.score_methods[self.method_index][0] == "fold change": ## fold change is on a logaritmic scale 
    384516                scores =  [(abs(math.log(max(min(score, 1e300), 1e-300), 2.0)), sign) for score, sign in scores] 
    385517            scores = sorted(scores)[-count:] 
     
    393525             
    394526 
    395     def CommitIf(self): 
    396         if self.autoCommit: 
    397             self.Commit() 
    398         else: 
    399             self.dataChangedFlag = True 
    400          
    401     def Commit(self): 
     527    def commit_if(self): 
     528        if self.auto_commit: 
     529            self.commit() 
     530        else: 
     531            self.data_changed_flag = True 
     532         
     533    def commit(self): 
    402534        if not self.data or not self.scores: 
    403535            return 
    404         test = self.scoreMethods[self.methodIndex][2] 
     536        test = self.score_methods[self.method_index][2] 
    405537         
    406538        cutOffUpper = self.histogram.upperBoundary 
     
    411543        selected = set([key for key, test in scores if test]) 
    412544        remaining = set([key for key, test in scores if not test]) 
    413         if self.data and self.genesInColumns: 
     545        if self.data and self.genes_in_columns: 
    414546            selected = sorted(selected) 
    415             newdata = orange.ExampleTable(orange.Domain(self.data.domain), [self.data[int(i)] for i in selected]) if selected else None 
    416             if self.addScoresToOutput: 
    417                 scoreAttr = orange.FloatVariable(self.scoreMethods[self.methodIndex][0]) 
     547            if selected: 
     548                newdata = orange.ExampleTable(orange.Domain(self.data.domain), 
     549                                        [self.data[int(i)] for i in selected]) 
     550            else: 
     551                newdata = None 
     552            if self.add_scores_to_output: 
     553                score_attr = orange.FloatVariable(self.score_methods[self.method_index][0]) 
    418554                mid = orange.newmetaid() 
    419555                 
    420             if self.addScoresToOutput and newdata is not None: 
    421                 newdata.domain.addmeta(mid, scoreAttr) 
     556            if self.add_scores_to_output and newdata is not None: 
     557                newdata.domain.addmeta(mid, score_attr) 
    422558                for ex, key in zip(newdata, selected): 
    423559                    ex[mid] = self.scores[key] 
     
    426562             
    427563            remaining = sorted(remaining) 
    428             newdata = orange.ExampleTable(orange.Domain(self.data.domain), [self.data[int(i)] for i in remaining]) if remaining else None 
    429              
    430             if self.addScoresToOutput and newdata is not None: 
    431                 newdata.domain.addmeta(mid, scoreAttr) 
     564            if remaining: 
     565                newdata = orange.ExampleTable(orange.Domain(self.data.domain), [self.data[int(i)] for i in remaining]) 
     566            else: 
     567                newdata = None 
     568             
     569            if self.add_scores_to_output and newdata is not None: 
     570                newdata.domain.addmeta(mid, score_attr) 
    432571                for ex, key in zip(newdata, remaining): 
    433572                    ex[mid] = self.scores[key] 
     
    435574            self.send("Example table with remaining genes", newdata) 
    436575             
    437         elif self.data and not self.genesInColumns: 
    438              
    439             selectedAttrs = [attr for attr in self.data.domain.attributes if attr in selected or attr.varType == orange.VarTypes.String] 
    440             newdomain = orange.Domain(selectedAttrs, self.data.domain.classVar) 
    441             if self.addScoresToOutput: 
     576        elif self.data and not self.genes_in_columns: 
     577             
     578            selected_attrs = [attr for attr in self.data.domain.attributes \ 
     579                             if attr in selected or \ 
     580                                attr.varType == orange.VarTypes.String] 
     581            newdomain = orange.Domain(selected_attrs, self.data.domain.classVar) 
     582            if self.add_scores_to_output: 
    442583                for attr in newdomain.attributes: 
    443                     attr.attributes[self.scoreMethods[self.methodIndex][0]] = str(self.scores[attr]) 
     584                    attr.attributes[self.score_methods[self.method_index][0]] = str(self.scores[attr]) 
    444585            newdomain.addmetas(self.data.domain.getmetas()) 
    445586            newdata = orange.ExampleTable(newdomain, self.data) 
    446587             
    447             self.send("Example table with selected genes", newdata if selectedAttrs else None) 
    448              
    449             remainingAttrs = [attr for attr in self.data.domain.attributes if attr in remaining] 
    450             newdomain = orange.Domain(remainingAttrs, self.data.domain.classVar) 
    451             if self.addScoresToOutput: 
     588            self.send("Example table with selected genes", newdata if selected_attrs else None) 
     589             
     590            remaining_attrs = [attr for attr in self.data.domain.attributes if attr in remaining] 
     591            newdomain = orange.Domain(remaining_attrs, self.data.domain.classVar) 
     592            if self.add_scores_to_output: 
    452593                for attr in newdomain.attributes: 
    453                     attr.attributes[self.scoreMethods[self.methodIndex][0]] = str(self.scores[attr]) 
     594                    attr.attributes[self.score_methods[self.method_index][0]] = str(self.scores[attr]) 
    454595            newdomain.addmetas(self.data.domain.getmetas()) 
    455596            newdata = orange.ExampleTable(newdomain, self.data) 
    456597             
    457             self.send("Example table with remaining genes", newdata if remainingAttrs else None) 
    458              
    459             domain = orange.Domain([orange.StringVariable("label"), orange.FloatVariable(self.scoreMethods[self.methodIndex][0])], False) 
    460             self.send("Selected genes", orange.ExampleTable([orange.Example(domain, [attr.name, self.scores.get(attr, 0)]) for attr in selectedAttrs]) if selectedAttrs else None) 
     598            self.send("Example table with remaining genes", newdata if remaining_attrs else None) 
     599             
     600            domain = orange.Domain([orange.StringVariable("label"), 
     601                                    orange.FloatVariable(self.score_methods[self.method_index][0])], 
     602                                    False) 
     603            if selected_attrs: 
     604                selected_genes = orange.ExampleTable(domain, 
     605                            [[attr.name, self.scores.get(attr, 0)] for attr in selected_attrs]) 
     606            else: 
     607                selected_genes = None 
     608            self.send("Selected genes",  selected_genes) 
    461609             
    462610        else: 
     
    464612            self.send("Example table with remaining genes", None) 
    465613            self.send("Selected genes", None) 
    466         self.dataChangedFlag = False 
    467  
     614        self.data_changed_flag = False 
     615         
     616    def on_target_changed(self): 
     617        label, values  = self.label_selection_widget.current_selection() 
     618        if self.genes_in_columns: 
     619            targets = [(label, t) for t in values] 
     620        else: 
     621            targets = values 
     622        self.targets = targets 
     623        self.current_target_selection = label, values 
     624        # Save target label selection 
     625        labels = [l for l, _ in self.data_labels] 
     626        if label in labels: 
     627            label_index = labels.index(label) 
     628            self.target_selections[label_index] = values 
     629        self.set_targets(targets)  
     630     
     631    def on_label_activated(self, index): 
     632        selection = self.target_selections[index] 
     633        if not selection: 
     634            selection = self.data_labels[index][1][:1] 
     635        self.label_selection_widget.set_selection(index, selection) 
     636 
     637    def on_genes_in_columns_change(self): 
     638        self.closeContext("TargetSelection") 
     639        self.update_targets_widget() 
     640        items = [(label, v) for label, values in self.data_labels \ 
     641                                for v in values] 
     642        if self.data_labels: 
     643            label, values = self.data_labels[0]  
     644            self.current_target_selection = label, values[:1] 
     645            self.target_selections = [values[1:] for _, values in self.data_labels] 
     646            self.openContext("TargetSelection", set(items)) 
     647            self.label_selection_widget.set_selection(*self.current_target_selection) 
     648         
     649    def on_scoring_method_changed(self): 
     650        two_sample = self.score_methods[self.method_index][3] 
     651        self.label_selection_widget.values_view.setDisabled(not two_sample) 
     652         
     653    def settingsFromWidgetCallbackTargetSelection(self, handler, context): 
     654        context.target_selections = self.target_selections 
     655        context.current_target_selection = self.current_target_selection 
     656         
     657    def settingsToWidgetCallbackTargetSelection(self, handler, context): 
     658        self.target_selections = getattr(context, "target_selections", self.target_selections) 
     659        self.current_target_selection = getattr(context, "current_target_selection", self.current_target_selection) 
     660     
    468661if __name__=="__main__": 
    469662    import sys 
    470663    app = QApplication(sys.argv) 
    471 #    data = orange.ExampleTable("E:\\out1.tab") 
    472664#    data = orange.ExampleTable("/home/marko/t2.tab") 
    473     data = orange.ExampleTable("../../../doc/datasets/brown-selected") 
     665#    data = orange.ExampleTable("../../../doc/datasets/brown-selected") 
     666    data = orange.ExampleTable(os.path.expanduser("~/Documents/GDS636")) 
    474667    w = OWFeatureSelection() 
    475668    w.show() 
    476     w.SetData(data) 
     669    w.set_data(data) 
     670#    w.set_data(None) 
     671#    w.set_data(data) 
    477672    app.exec_() 
    478673    w.saveSettings() 
Note: See TracChangeset for help on using the changeset viewer.