def commit(self): if self.currentGds: self.error(0) sample_type = None self.progressBarInit(processEvents=None) _, groups = self.selectedSamples() if len(groups) == 1 and self.outputRows: sample_type = groups[0] self.setEnabled(False) self.setBlocking(True) progress = methodinvoke(self, "progressCompleted", (int, int)) def get_data(gds_id, report_genes, transpose, sample_type, title): gds_ensure_downloaded(gds_id, progress) gds = GDS(gds_id) data = gds.get_data(report_genes=report_genes, transpose=transpose, sample_type=sample_type) data.name = title return data get_data = partial(get_data, self.currentGds["dataset_id"], report_genes=self.mergeSpots, transpose=self.outputRows, sample_type=sample_type, title=self.datasetName or self.currentGds["title"]) self._datatask = Task(function=get_data) self._datatask.finished.connect(self._on_dataready) self._executor.submit(self._datatask)
def updateInfoItems(self): self.warning(0) if self.data is None: return if self.useAttr: genes = [attr.name for attr in self.data.domain.attributes] elif self.attributes: attr = self.attributes[self.gene_attr] genes = [ str(ex[attr]) for ex in self.data if not math.isnan(ex[attr]) ] else: genes = [] if not genes: self.warning(0, "Could not extract genes from input dataset.") self.warning(1) org = self.organisms[min(self.organism_index, len(self.organisms) - 1)] source_name, info_getter = ("NCBI Info", ncbi_info) self.error(0) self.progressBarInit() self.setBlocking(True) self.setEnabled(False) self.infoLabel.setText("Retrieving info records.\n") self.genes = genes task = Task(function=partial( info_getter, org, genes, advance=methodinvoke(self, "advance", ( )))) self.itemsfuture = self.executor.submit(task) task.finished.connect(self._onItemsCompleted)
def commit(self): include_neighborhood = self.include_neighborhood query_genes = self.query_genes() source = SOURCES[self.network_source] if source.score_filter: min_score = self.min_score assert source.name == "STRING" min_score = min_score * 1000 else: min_score = None taxid = self.taxid progress = methodinvoke(self, "advance") if self.geneinfo is None: self.geneinfo = self.executor.submit(fetch_ncbi_geneinfo, taxid, progress) geneinfo_f = self.geneinfo taxmap = source.tax_mapping db_taxid = taxmap.get(taxid, taxid) if db_taxid is None: raise ValueError("invalid taxid for this network") def fetch_network(): geneinfo = geneinfo_f.result() ppidb = fetch_ppidb(source, db_taxid, progress) return get_gene_network(ppidb, geneinfo, db_taxid, query_genes, include_neighborhood=include_neighborhood, min_score=min_score, progress=methodinvoke( self, "set_progress", (float, ))) self.nettask = Task(function=fetch_network) self.nettask.finished.connect(self._on_result_ready) self.executor.submit(self.nettask) self.setBlocking(True) self.setEnabled(False) self.progressBarInit() self._invalidated = False self._update_info()
def RetrieveFilesList(self): self.retryButton.hide() self.warning(0) self.progress.setRange(0, 3) task = Task(function=partial(retrieveFilesList, methodinvoke(self.progress, "advance"))) task.resultReady.connect(self.SetFilesList) task.exceptionReady.connect(self.HandleError) self.executor.submit(task) self.setEnabled(False)
def commit(self): include_neighborhood = self.include_neighborhood query_genes = self.query_genes() source = SOURCES[self.network_source] if source.score_filter: min_score = self.min_score assert source.name == "STRING" min_score = min_score * 1000 else: min_score = None taxid = self.taxid progress = methodinvoke(self, "advance") if self.geneinfo is None: self.geneinfo = self.executor.submit( fetch_ncbi_geneinfo, taxid, progress ) geneinfo_f = self.geneinfo taxmap = source.tax_mapping db_taxid = taxmap.get(taxid, taxid) if db_taxid is None: raise ValueError("invalid taxid for this network") def fetch_network(): geneinfo = geneinfo_f.result() ppidb = fetch_ppidb(source, db_taxid, progress) return get_gene_network(ppidb, geneinfo, db_taxid, query_genes, include_neighborhood=include_neighborhood, min_score=min_score, progress=methodinvoke(self, "set_progress", (float,))) self.nettask = Task(function=fetch_network) self.nettask.finished.connect(self._on_result_ready) self.executor.submit(self.nettask) self.setBlocking(True) self.setEnabled(False) self.progressBarInit() self._invalidated = False self._update_info()
def test_executor(self): executor = ThreadExecutor() f = executor.submit(QThread.currentThread) self.assertIsNot(f.result(3), QThread.currentThread()) f = executor.submit(lambda: 1 / 0) with self.assertRaises(ZeroDivisionError): f.result() results = [] task = Task(function=QThread.currentThread) task.resultReady.connect(results.append, Qt.DirectConnection) f = executor.submit_task(task) self.assertIsNot(f.result(3), QThread.currentThread()) executor.shutdown()
def test_task(self): results = [] task = Task(function=QThread.currentThread) task.resultReady.connect(results.append) task.start() self.app.processEvents() self.assertSequenceEqual(results, [QThread.currentThread()]) thread = QThread() thread.start() try: task = Task(function=QThread.currentThread) task.moveToThread(thread) self.assertIsNot(task.thread(), QThread.currentThread()) self.assertIs(task.thread(), thread) results = Future() def record(value): # record the result value and the calling thread results.set_result((QThread.currentThread(), value)) task.resultReady.connect(record, Qt.DirectConnection) task.start() f = task.future() emit_thread, thread_ = results.result(3) self.assertIs(f.result(3), thread) self.assertIs(emit_thread, thread) self.assertIs(thread_, thread) finally: thread.quit() thread.wait()
def __init__(self, files_list, parent=None): Task.__init__(self, parent) self.files_list = files_list
def __init__( self, parent=None, ): super().__init__(self, parent) self.selectionChangedFlag = False self.__initialized = False self.initfuture = None self.itemsfuture = None self.infoLabel = gui.widgetLabel( gui.widgetBox(self.controlArea, "Info", addSpace=True), "Initializing\n") self.organisms = None self.organismBox = gui.widgetBox(self.controlArea, "Organism", addSpace=True) self.organismComboBox = gui.comboBox( self.organismBox, self, "organism_index", callback=self._onSelectedOrganismChanged) # For now only support one alt source, with a checkbox # In the future this can be extended to multiple selections self.altSourceCheck = gui.checkBox(self.organismBox, self, "useAltSource", "Show information from dictyBase", callback=self.onAltSourceChange) self.altSourceCheck.hide() box = gui.widgetBox(self.controlArea, "Gene names", addSpace=True) self.geneAttrComboBox = gui.comboBox(box, self, "gene_attr", "Gene attribute", callback=self.updateInfoItems) self.geneAttrComboBox.setEnabled(not self.useAttr) cb = gui.checkBox(box, self, "useAttr", "Use attribute names", callback=self.updateInfoItems) cb.toggled[bool].connect(self.geneAttrComboBox.setDisabled) gui.auto_commit(self.controlArea, self, "auto_commit", "Commit") # A label for dictyExpress link (Why oh god why???) self.dictyExpressBox = gui.widgetBox(self.controlArea, "Dicty Express") self.linkLabel = gui.widgetLabel(self.dictyExpressBox, "") self.linkLabel.setOpenExternalLinks(False) self.linkLabel.linkActivated.connect(self.onDictyExpressLink) self.dictyExpressBox.hide() gui.rubber(self.controlArea) gui.lineEdit(self.mainArea, self, "search_string", "Filter", callbackOnType=True, callback=self.searchUpdate) self.treeWidget = QTreeView(self.mainArea, selectionMode=QTreeView.ExtendedSelection, rootIsDecorated=False, uniformRowHeights=True, sortingEnabled=True) self.treeWidget.setItemDelegate( gui.LinkStyledItemDelegate(self.treeWidget)) self.treeWidget.viewport().setMouseTracking(True) self.mainArea.layout().addWidget(self.treeWidget) box = gui.widgetBox(self.mainArea, "", orientation="horizontal") gui.button(box, self, "Select Filtered", callback=self.selectFiltered) gui.button(box, self, "Clear Selection", callback=self.treeWidget.clearSelection) self.geneinfo = [] self.cells = [] self.row2geneinfo = {} self.data = None # : (# input genes, # matches genes) self.matchedInfo = 0, 0 self.setBlocking(True) self.executor = ThreadExecutor(self) self.progressBarInit() task = Task( function=partial(taxonomy.ensure_downloaded, callback=methodinvoke(self, "advance", ()))) task.resultReady.connect(self.initialize) task.exceptionReady.connect(self._onInitializeError) self.initfuture = self.executor.submit(task)
def __init__( self, parent=None, ): super().__init__(self, parent) self.selectionChangedFlag = False self.__initialized = False self.initfuture = None self.itemsfuture = None self.map_input_to_ensembl = None self.infoLabel = gui.widgetLabel( gui.widgetBox(self.controlArea, "Info", addSpace=True), "Initializing\n") self.organisms = None self.organismBox = gui.widgetBox(self.controlArea, "Organism", addSpace=True) self.organismComboBox = gui.comboBox( self.organismBox, self, "organism_index", callback=self._onSelectedOrganismChanged) box = gui.widgetBox(self.controlArea, "Gene names", addSpace=True) self.geneAttrComboBox = gui.comboBox(box, self, "gene_attr", "Gene attribute", callback=self.updateInfoItems) self.geneAttrComboBox.setEnabled(not self.useAttr) self.geneAttrCheckbox = gui.checkBox(box, self, "useAttr", "Use column names", callback=self.updateInfoItems) self.geneAttrCheckbox.toggled[bool].connect( self.geneAttrComboBox.setDisabled) gui.auto_commit(self.controlArea, self, "auto_commit", "Commit") gui.rubber(self.controlArea) gui.lineEdit(self.mainArea, self, "search_string", "Filter", callbackOnType=True, callback=self.searchUpdate) self.treeWidget = QTreeView(self.mainArea) self.treeWidget.setAlternatingRowColors(True) self.treeWidget.setSortingEnabled(True) self.treeWidget.setSelectionMode(QTreeView.ExtendedSelection) self.treeWidget.setUniformRowHeights(True) self.treeWidget.setRootIsDecorated(False) self.treeWidget.setItemDelegateForColumn( HEADER_SCHEMA['NCBI ID'], gui.LinkStyledItemDelegate(self.treeWidget)) self.treeWidget.setItemDelegateForColumn( HEADER_SCHEMA['Ensembl ID'], gui.LinkStyledItemDelegate(self.treeWidget)) self.treeWidget.viewport().setMouseTracking(True) self.mainArea.layout().addWidget(self.treeWidget) box = gui.widgetBox(self.mainArea, "", orientation="horizontal") gui.button(box, self, "Select Filtered", callback=self.selectFiltered) gui.button(box, self, "Clear Selection", callback=self.treeWidget.clearSelection) self.geneinfo = [] self.cells = [] self.row2geneinfo = {} self.data = None # : (# input genes, # matches genes) self.matchedInfo = 0, 0 self.setBlocking(True) self.executor = ThreadExecutor(self) self.progressBarInit() task = Task( function=partial(taxonomy.ensure_downloaded, callback=methodinvoke(self, "advance", ()))) task.resultReady.connect(self.initialize) task.exceptionReady.connect(self._onInitializeError) self.initfuture = self.executor.submit(task)
def __init__(self, domain, filename, serverfiles, parent=None): Task.__init__(self, parent) self.filename = filename self.domain = domain self.serverfiles = serverfiles self._interrupt = False
class OWGeneNetwork(widget.OWWidget): name = "Gene Network" description = "Extract a gene network for a set of genes." icon = "../widgets/icons/GeneNetwork.svg" inputs = [("Data", Orange.data.Table, "set_data")] outputs = [("Network", network.Graph)] settingsHandler = settings.DomainContextHandler() taxid = settings.Setting("9606") gene_var_index = settings.ContextSetting(-1) use_attr_names = settings.ContextSetting(False) network_source = settings.Setting(1) include_neighborhood = settings.Setting(True) min_score = settings.Setting(0.9) want_main_area = False def __init__(self, parent=None): super().__init__(parent) self.taxids = taxonomy.common_taxids() self.current_taxid_index = self.taxids.index(self.taxid) self.data = None self.geneinfo = None self.nettask = None self._invalidated = False box = gui.widgetBox(self.controlArea, "Info") self.info = gui.widgetLabel(box, "No data on input\n") box = gui.widgetBox(self.controlArea, "Organism") self.organism_cb = gui.comboBox( box, self, "current_taxid_index", items=map(taxonomy.name, self.taxids), callback=self._update_organism ) box = gui.widgetBox(self.controlArea, "Genes") self.genes_cb = gui.comboBox( box, self, "gene_var_index", callback=self._update_query_genes ) self.varmodel = itemmodels.VariableListModel() self.genes_cb.setModel(self.varmodel) gui.checkBox( box, self, "use_attr_names", "Use attribute names", callback=self._update_query_genes ) box = gui.widgetBox(self.controlArea, "Network") gui.comboBox( box, self, "network_source", items=[s.name for s in SOURCES], callback=self._on_source_db_changed ) gui.checkBox( box, self, "include_neighborhood", "Include immediate gene neighbors", callback=self.invalidate ) self.score_spin = gui.doubleSpin( box, self, "min_score", 0.0, 1.0, step=0.001, label="Minimal edge score", callback=self.invalidate ) self.score_spin.setEnabled(SOURCES[self.network_source].score_filter) box = gui.widgetBox(self.controlArea, "Commit") gui.button(box, self, "Retrieve", callback=self.commit, default=True) self.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) self.layout().setSizeConstraint(QtGui.QLayout.SetFixedSize) self.executor = ThreadExecutor() def set_data(self, data): self.closeContext() self.data = data if data is not None: self.varmodel[:] = string_variables(data.domain) taxid = data_hints.get_hint(data, "taxid", default=self.taxid) if taxid in self.taxids: self.set_organism(self.taxids.index(taxid)) self.use_attr_names = data_hints.get_hint( data, "genesinrows", default=self.use_attr_names ) if not (0 <= self.gene_var_index < len(self.varmodel)): self.gene_var_index = len(self.varmodel) - 1 self.openContext(data) self.invalidate() self.commit() else: self.varmodel[:] = [] self.send("Network", None) def set_source_db(self, dbindex): self.network_source = dbindex self.invalidate() def set_organism(self, index): self.current_taxid_index = index self.taxid = self.taxids[index] self.invalidate() def set_gene_var(self, index): self.gene_var_index = index self.invalidate() def query_genes(self): if self.use_attr_names: if self.data is not None: return [var.name for var in self.data.domain.attributes] else: return [] elif self.gene_var_index >= 0: var = self.varmodel[self.gene_var_index] genes = [str(inst[var]) for inst in self.data if not compat.isunknown(inst[var])] return list(unique(genes)) else: return [] def invalidate(self): self._invalidated = True if self.nettask is not None: self.nettask.finished.disconnect(self._on_result_ready) self.nettask.future().cancel() self.nettask = None @Slot() def advance(self): self.progressBarValue = (self.progressBarValue + 1) % 100 @Slot(float) def set_progress(self, value): self.progressBarSet(value, processEvents=None) def commit(self): include_neighborhood = self.include_neighborhood query_genes = self.query_genes() source = SOURCES[self.network_source] if source.score_filter: min_score = self.min_score assert source.name == "STRING" min_score = min_score * 1000 else: min_score = None taxid = self.taxid progress = methodinvoke(self, "advance") if self.geneinfo is None: self.geneinfo = self.executor.submit( fetch_ncbi_geneinfo, taxid, progress ) geneinfo_f = self.geneinfo taxmap = source.tax_mapping db_taxid = taxmap.get(taxid, taxid) if db_taxid is None: raise ValueError("invalid taxid for this network") def fetch_network(): geneinfo = geneinfo_f.result() ppidb = fetch_ppidb(source, db_taxid, progress) return get_gene_network(ppidb, geneinfo, db_taxid, query_genes, include_neighborhood=include_neighborhood, min_score=min_score, progress=methodinvoke(self, "set_progress", (float,))) self.nettask = Task(function=fetch_network) self.nettask.finished.connect(self._on_result_ready) self.executor.submit(self.nettask) self.setBlocking(True) self.setEnabled(False) self.progressBarInit() self._invalidated = False self._update_info() @Slot(object) def _on_result_ready(self,): self.progressBarFinished() self.setBlocking(False) self.setEnabled(True) net = self.nettask.result() self._update_info() self.send("Network", net) def _on_source_db_changed(self): source = SOURCES[self.network_source] self.score_spin.setEnabled(source.score_filter) self.invalidate() def _update_organism(self): self.taxid = self.taxids[self.current_taxid_index] if self.geneinfo is not None: self.geneinfo.cancel() self.geneinfo = None self.invalidate() def _update_query_genes(self): self.invalidate() def _update_info(self): if self.data is None: self.info.setText("No data on input\n") else: names = self.query_genes() lines = ["%i unique genes on input" % len(set(names))] if self.nettask is not None: if not self.nettask.future().done(): lines.append("Retrieving ...") else: net = self.nettask.result() lines.append("%i nodes %i edges" % (len(net.nodes()), len(net.edges()))) else: lines.append("") self.info.setText("\n".join(lines))
def __init__(self, parent=None, signalManager=None, name="Databases update"): OWWidget.__init__(self, parent, signalManager, name, wantMainArea=False) self.searchString = "" fbox = gui.widgetBox(self.controlArea, "Filter") self.completer = TokenListCompleter( self, caseSensitivity=Qt.CaseInsensitive) self.lineEditFilter = QLineEdit(textChanged=self.SearchUpdate) self.lineEditFilter.setCompleter(self.completer) fbox.layout().addWidget(self.lineEditFilter) box = gui.widgetBox(self.controlArea, "Files") self.filesView = QTreeWidget(self) self.filesView.setHeaderLabels( ["", "Data Source", "Update", "Last Updated", "Size"]) self.filesView.setRootIsDecorated(False) self.filesView.setUniformRowHeights(True) self.filesView.setSelectionMode(QAbstractItemView.NoSelection) self.filesView.setSortingEnabled(True) self.filesView.sortItems(1, Qt.AscendingOrder) self.filesView.setItemDelegateForColumn( 0, UpdateOptionsItemDelegate(self.filesView)) self.filesView.model().layoutChanged.connect(self.SearchUpdate) box.layout().addWidget(self.filesView) box = gui.widgetBox(self.controlArea, orientation="horizontal") self.updateButton = gui.button( box, self, "Update all", callback=self.UpdateAll, tooltip="Update all updatable files", ) self.downloadButton = gui.button( box, self, "Download all", callback=self.DownloadFiltered, tooltip="Download all filtered files shown" ) self.cancelButton = gui.button( box, self, "Cancel", callback=self.Cancel, tooltip="Cancel scheduled downloads/updates." ) self.retryButton = gui.button( box, self, "Reconnect", callback=self.RetrieveFilesList ) self.retryButton.hide() gui.rubber(box) self.warning(0) box = gui.widgetBox(self.controlArea, orientation="horizontal") gui.rubber(box) self.infoLabel = QLabel() self.infoLabel.setAlignment(Qt.AlignCenter) self.controlArea.layout().addWidget(self.infoLabel) self.infoLabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.updateItems = [] self.resize(800, 600) self.progress = ProgressState(self, maximum=3) self.progress.valueChanged.connect(self._updateProgress) self.progress.rangeChanged.connect(self._updateProgress) self.executor = ThreadExecutor( threadPool=QThreadPool(maxThreadCount=2) ) task = Task(self, function=self.RetrieveFilesList) task.exceptionReady.connect(self.HandleError) task.start() self._tasks = [] self._haveProgress = False
class OWGeneNetwork(widget.OWWidget): name = "Gene Network" description = "Extract a gene network for a set of genes." icon = "../widgets/icons/GeneNetwork.svg" inputs = [("Data", Orange.data.Table, "set_data")] outputs = [("Network", network.Graph)] settingsHandler = settings.DomainContextHandler() taxid = settings.Setting("9606") gene_var_index = settings.ContextSetting(-1) use_attr_names = settings.ContextSetting(False) network_source = settings.Setting(1) include_neighborhood = settings.Setting(True) min_score = settings.Setting(0.9) want_main_area = False def __init__(self, parent=None): super().__init__(parent) self.taxids = taxonomy.common_taxids() self.current_taxid_index = self.taxids.index(self.taxid) self.data = None self.geneinfo = None self.nettask = None self._invalidated = False box = gui.widgetBox(self.controlArea, "Info") self.info = gui.widgetLabel(box, "No data on input\n") box = gui.widgetBox(self.controlArea, "Organism") self.organism_cb = gui.comboBox(box, self, "current_taxid_index", items=map(taxonomy.name, self.taxids), callback=self._update_organism) box = gui.widgetBox(self.controlArea, "Genes") self.genes_cb = gui.comboBox(box, self, "gene_var_index", callback=self._update_query_genes) self.varmodel = itemmodels.VariableListModel() self.genes_cb.setModel(self.varmodel) gui.checkBox(box, self, "use_attr_names", "Use attribute names", callback=self._update_query_genes) box = gui.widgetBox(self.controlArea, "Network") gui.comboBox(box, self, "network_source", items=[s.name for s in SOURCES], callback=self._on_source_db_changed) gui.checkBox(box, self, "include_neighborhood", "Include immediate gene neighbors", callback=self.invalidate) self.score_spin = gui.doubleSpin(box, self, "min_score", 0.0, 1.0, step=0.001, label="Minimal edge score", callback=self.invalidate) self.score_spin.setEnabled(SOURCES[self.network_source].score_filter) box = gui.widgetBox(self.controlArea, "Commit") gui.button(box, self, "Retrieve", callback=self.commit, default=True) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.layout().setSizeConstraint(QLayout.SetFixedSize) self.executor = ThreadExecutor() def set_data(self, data): self.closeContext() self.data = data if data is not None: self.varmodel[:] = string_variables(data.domain) taxid = data_hints.get_hint(data, "taxid", default=self.taxid) if taxid in self.taxids: self.set_organism(self.taxids.index(taxid)) self.use_attr_names = data_hints.get_hint( data, "genesinrows", default=self.use_attr_names) if not (0 <= self.gene_var_index < len(self.varmodel)): self.gene_var_index = len(self.varmodel) - 1 self.openContext(data) self.invalidate() self.commit() else: self.varmodel[:] = [] self.send("Network", None) def set_source_db(self, dbindex): self.network_source = dbindex self.invalidate() def set_organism(self, index): self.current_taxid_index = index self.taxid = self.taxids[index] self.invalidate() def set_gene_var(self, index): self.gene_var_index = index self.invalidate() def query_genes(self): if self.use_attr_names: if self.data is not None: return [var.name for var in self.data.domain.attributes] else: return [] elif self.gene_var_index >= 0: var = self.varmodel[self.gene_var_index] genes = [ str(inst[var]) for inst in self.data if not compat.isunknown(inst[var]) ] return list(unique(genes)) else: return [] def invalidate(self): self._invalidated = True if self.nettask is not None: self.nettask.finished.disconnect(self._on_result_ready) self.nettask.future().cancel() self.nettask = None @Slot() def advance(self): self.progressBarValue = (self.progressBarValue + 1) % 100 @Slot(float) def set_progress(self, value): self.progressBarSet(value, processEvents=None) def commit(self): include_neighborhood = self.include_neighborhood query_genes = self.query_genes() source = SOURCES[self.network_source] if source.score_filter: min_score = self.min_score assert source.name == "STRING" min_score = min_score * 1000 else: min_score = None taxid = self.taxid progress = methodinvoke(self, "advance") if self.geneinfo is None: self.geneinfo = self.executor.submit(fetch_ncbi_geneinfo, taxid, progress) geneinfo_f = self.geneinfo taxmap = source.tax_mapping db_taxid = taxmap.get(taxid, taxid) if db_taxid is None: raise ValueError("invalid taxid for this network") def fetch_network(): geneinfo = geneinfo_f.result() ppidb = fetch_ppidb(source, db_taxid, progress) return get_gene_network(ppidb, geneinfo, db_taxid, query_genes, include_neighborhood=include_neighborhood, min_score=min_score, progress=methodinvoke( self, "set_progress", (float, ))) self.nettask = Task(function=fetch_network) self.nettask.finished.connect(self._on_result_ready) self.executor.submit(self.nettask) self.setBlocking(True) self.setEnabled(False) self.progressBarInit() self._invalidated = False self._update_info() @Slot() def _on_result_ready(self, ): self.progressBarFinished() self.setBlocking(False) self.setEnabled(True) net = self.nettask.result() self._update_info() self.send("Network", net) def _on_source_db_changed(self): source = SOURCES[self.network_source] self.score_spin.setEnabled(source.score_filter) self.invalidate() def _update_organism(self): self.taxid = self.taxids[self.current_taxid_index] if self.geneinfo is not None: self.geneinfo.cancel() self.geneinfo = None self.invalidate() def _update_query_genes(self): self.invalidate() def _update_info(self): if self.data is None: self.info.setText("No data on input\n") else: names = self.query_genes() lines = ["%i unique genes on input" % len(set(names))] if self.nettask is not None: if not self.nettask.future().done(): lines.append("Retrieving ...") else: net = self.nettask.result() lines.append("%i nodes %i edges" % (len(net.nodes()), len(net.edges()))) else: lines.append("") self.info.setText("\n".join(lines))
def updateAnnotations(self): if self.data is None: return assert not self.__state & OWSetEnrichment.Initializing self._cancelPending() self._clearView() self.information(0) self.warning(0) self.error(0) if not self.genesinrows and len(self.geneAttrs) == 0: self.error(0, "Input data contains no columns with gene names") return self.__state = OWSetEnrichment.RunningEnrichment taxid = self.taxid_list[self.speciesIndex] self.taxid = taxid categories = self.selectedCategories() clusterGenes = self.genesFromTable(self.data) if self.referenceData is not None and self.useReferenceData: referenceGenes = self.genesFromTable(self.referenceData) else: referenceGenes = None self.currentAnnotatedCategories = categories genematcher = self._genematcher() self.progressBarInit() ## Load collections in a worker thread # TODO: Use cached collections if already loaded and # use ensure_genesetsdownloaded with progress report (OWSelectGenes) collections = self._executor.submit(geneset.collections, *categories) def refset_null(): """Return the default background reference set""" col = collections.result() return reduce(operator.ior, (set(g.genes) for g in col), set()) def refset_ncbi(): """Return all NCBI gene names""" geneinfo = gene.NCBIGeneInfo(taxid) return set(geneinfo.keys()) def namematcher(): matcher = genematcher.result() match = matcher.set_targets(ref_set.result()) match.umatch = memoize(match.umatch) return match def map_unames(): matcher = namematcher.result() query = list(filter(None, map(matcher.umatch, querynames))) reference = list( filter(None, map(matcher.umatch, ref_set.result()))) return query, reference if self._nogenematching(): if referenceGenes is None: ref_set = self._executor.submit(refset_null) else: ref_set = fulfill(referenceGenes) else: if referenceGenes == None: ref_set = self._executor.submit(refset_ncbi) else: ref_set = fulfill(referenceGenes) namematcher = self._executor.submit(namematcher) querynames = clusterGenes state = types.SimpleNamespace() state.query_set = clusterGenes state.reference_set = referenceGenes state.namematcher = namematcher state.query_count = len(set(clusterGenes)) state.reference_count = (len(set(referenceGenes)) if referenceGenes is not None else None) state.cancelled = False progress = methodinvoke(self, "_setProgress", (float, )) info = methodinvoke(self, "_setRunInfo", (str, )) @withtraceback def run(): info("Loading data") match = namematcher.result() query, reference = map_unames() gscollections = collections.result() results = [] info("Running enrichment") p = 0 for i, gset in enumerate(gscollections): genes = set(filter(None, map(match.umatch, gset.genes))) enr = set_enrichment(genes, reference, query) results.append((gset, enr)) if state.cancelled: raise UserInteruptException pnew = int(100 * i / len(gscollections)) if pnew != p: progress(pnew) p = pnew progress(100) info("") return query, reference, results task = Task(function=run) task.resultReady.connect(self.__on_enrichment_finished) task.exceptionReady.connect(self.__on_enrichment_failed) result = self._executor.submit(task) state.results = result self.state = state self._updatesummary()
class OWGEODatasets(OWWidget): name = "GEO Data Sets" description = "Access to Gene Expression Omnibus data sets." icon = "icons/OWGEODatasets.svg" priority = 2 inputs = [] outputs = [("Expression Data", Table)] settingsList = [ "outputRows", "mergeSpots", "gdsSelectionStates", "splitterSettings", "currentGds", "autoCommit", "datasetNames" ] outputRows = Setting(True) mergeSpots = Setting(True) gdsSelectionStates = Setting({}) currentGds = Setting(None) datasetNames = Setting({}) splitterSettings = Setting(( b'\x00\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x01\xea\x00\x00\x00\xd7\x01\x00\x00\x00\x07\x01\x00\x00\x00\x02', b'\x00\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x01\xb5\x00\x00\x02\x10\x01\x00\x00\x00\x07\x01\x00\x00\x00\x01' )) autoCommit = Setting(False) def __init__(self, parent=None, signalManager=None, name=" GEO Data Sets"): OWWidget.__init__(self, parent, signalManager, name) self.selectionChanged = False self.filterString = "" self.datasetName = "" ## GUI box = gui.widgetBox(self.controlArea, "Info", addSpace=True) self.infoBox = gui.widgetLabel(box, "Initializing\n\n") box = gui.widgetBox(self.controlArea, "Output", addSpace=True) gui.radioButtonsInBox(box, self, "outputRows", ["Genes in rows", "Samples in rows"], "Rows", callback=self.commitIf) gui.checkBox(box, self, "mergeSpots", "Merge spots of same gene", callback=self.commitIf) gui.separator(box) self.nameEdit = gui.lineEdit( box, self, "datasetName", "Data set name", tooltip="Override the default output data set name", callback=self.onNameEdited) self.nameEdit.setPlaceholderText("") if sys.version_info < (3, ): box = gui.widgetBox(self.controlArea, "Commit", addSpace=True) self.commitButton = gui.button(box, self, "Commit", callback=self.commit) cb = gui.checkBox(box, self, "autoCommit", "Commit on any change") gui.setStopper(self, self.commitButton, cb, "selectionChanged", self.commit) else: gui.auto_commit(self.controlArea, self, "autoCommit", "Commit", box="Commit") self.commitIf = self.commit gui.rubber(self.controlArea) gui.widgetLabel(self.mainArea, "Filter") self.filterLineEdit = QLineEdit(textChanged=self.filter) self.completer = TokenListCompleter(self, caseSensitivity=Qt.CaseInsensitive) self.filterLineEdit.setCompleter(self.completer) self.mainArea.layout().addWidget(self.filterLineEdit) splitter = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(splitter) self.treeWidget = QTreeView(splitter) self.treeWidget.setSelectionMode(QTreeView.SingleSelection) self.treeWidget.setRootIsDecorated(False) self.treeWidget.setSortingEnabled(True) self.treeWidget.setAlternatingRowColors(True) self.treeWidget.setUniformRowHeights(True) self.treeWidget.setEditTriggers(QTreeView.NoEditTriggers) linkdelegate = gui.LinkStyledItemDelegate(self.treeWidget) self.treeWidget.setItemDelegateForColumn(1, linkdelegate) self.treeWidget.setItemDelegateForColumn(8, linkdelegate) self.treeWidget.setItemDelegateForColumn( 0, gui.IndicatorItemDelegate(self.treeWidget, role=Qt.DisplayRole)) proxyModel = MySortFilterProxyModel(self.treeWidget) self.treeWidget.setModel(proxyModel) self.treeWidget.selectionModel().selectionChanged.connect( self.updateSelection) self.treeWidget.viewport().setMouseTracking(True) splitterH = QSplitter(Qt.Horizontal, splitter) box = gui.widgetBox(splitterH, "Description") self.infoGDS = gui.widgetLabel(box, "") self.infoGDS.setWordWrap(True) gui.rubber(box) box = gui.widgetBox(splitterH, "Sample Annotations") self.annotationsTree = QTreeWidget(box) self.annotationsTree.setHeaderLabels( ["Type (Sample annotations)", "Sample count"]) self.annotationsTree.setRootIsDecorated(True) box.layout().addWidget(self.annotationsTree) self.annotationsTree.itemChanged.connect( self.annotationSelectionChanged) self._annotationsUpdating = False self.splitters = splitter, splitterH for sp, setting in zip(self.splitters, self.splitterSettings): sp.splitterMoved.connect(self.splitterMoved) sp.restoreState(setting) self.searchKeys = [ "dataset_id", "title", "platform_organism", "description" ] self.gds = [] self.gds_info = None self.resize(1000, 600) self.setBlocking(True) self.setEnabled(False) self.progressBarInit() self._executor = ThreadExecutor() func = partial(get_gds_model, methodinvoke(self, "_setProgress", (float, ))) self._inittask = Task(function=func) self._inittask.finished.connect(self._initializemodel) self._executor.submit(self._inittask) self._datatask = None @Slot(float) def _setProgress(self, value): self.progressBarValue = value def _initializemodel(self): assert self.thread() is QThread.currentThread() model, self.gds_info, self.gds = self._inittask.result() model.setParent(self) proxy = self.treeWidget.model() proxy.setFilterKeyColumn(0) proxy.setFilterRole(TextFilterRole) proxy.setFilterCaseSensitivity(False) proxy.setFilterFixedString(self.filterString) proxy.setSourceModel(model) proxy.sort(0, Qt.DescendingOrder) self.progressBarFinished() self.setBlocking(False) self.setEnabled(True) filter_items = " ".join(gds[key] for gds in self.gds for key in self.searchKeys) tr_chars = ",.:;!?(){}[]_-+\\|/%#@$^&*<>~`" tr_table = str.maketrans(tr_chars, " " * len(tr_chars)) filter_items = filter_items.translate(tr_table) filter_items = sorted(set(filter_items.split(" "))) filter_items = [item for item in filter_items if len(item) > 3] self.completer.setTokenList(filter_items) if self.currentGds: current_id = self.currentGds["dataset_id"] gdss = [(i, proxy.data(proxy.index(i, 1), Qt.DisplayRole)) for i in range(proxy.rowCount())] current = [i for i, data in gdss if data and data == current_id] if current: current_index = proxy.index(current[0], 0) self.treeWidget.selectionModel().select( current_index, QItemSelectionModel.Select | QItemSelectionModel.Rows) self.treeWidget.scrollTo(current_index, QTreeView.PositionAtCenter) for i in range(8): self.treeWidget.resizeColumnToContents(i) self.treeWidget.setColumnWidth( 1, min(self.treeWidget.columnWidth(1), 300)) self.treeWidget.setColumnWidth( 2, min(self.treeWidget.columnWidth(2), 200)) self.updateInfo() def updateInfo(self): gds_info = self.gds_info text = ("%i datasets\n%i datasets cached\n" % (len(gds_info), len(glob.glob(serverfiles.localpath("GEO") + "/GDS*")))) filtered = self.treeWidget.model().rowCount() if len(self.gds) != filtered: text += ("%i after filtering") % filtered self.infoBox.setText(text) def updateSelection(self, *args): current = self.treeWidget.selectedIndexes() mapToSource = self.treeWidget.model().mapToSource current = [mapToSource(index).row() for index in current] if current: self.currentGds = self.gds[current[0]] self.setAnnotations(self.currentGds) self.infoGDS.setText(self.currentGds.get("description", "")) self.nameEdit.setPlaceholderText(self.currentGds["title"]) self.datasetName = \ self.datasetNames.get(self.currentGds["dataset_id"], "") else: self.currentGds = None self.nameEdit.setPlaceholderText("") self.datasetName = "" self.commitIf() def setAnnotations(self, gds): self._annotationsUpdating = True self.annotationsTree.clear() annotations = defaultdict(set) subsetscount = {} for desc in gds["subsets"]: annotations[desc["type"]].add(desc["description"]) subsetscount[desc["description"]] = str(len(desc["sample_id"])) for type, subsets in annotations.items(): key = (gds["dataset_id"], type) subsetItem = QTreeWidgetItem(self.annotationsTree, [type]) subsetItem.setFlags(subsetItem.flags() | Qt.ItemIsUserCheckable | Qt.ItemIsTristate) subsetItem.setCheckState( 0, self.gdsSelectionStates.get(key, Qt.Checked)) subsetItem.key = key for subset in subsets: key = (gds["dataset_id"], type, subset) item = QTreeWidgetItem( subsetItem, [subset, subsetscount.get(subset, "")]) item.setFlags(item.flags() | Qt.ItemIsUserCheckable) item.setCheckState( 0, self.gdsSelectionStates.get(key, Qt.Checked)) item.key = key self._annotationsUpdating = False self.annotationsTree.expandAll() for i in range(self.annotationsTree.columnCount()): self.annotationsTree.resizeColumnToContents(i) def annotationSelectionChanged(self, item, column): if self._annotationsUpdating: return for i in range(self.annotationsTree.topLevelItemCount()): item = self.annotationsTree.topLevelItem(i) self.gdsSelectionStates[item.key] = item.checkState(0) for j in range(item.childCount()): child = item.child(j) self.gdsSelectionStates[child.key] = child.checkState(0) def filter(self): filter_string = self.filterLineEdit.text() proxyModel = self.treeWidget.model() if proxyModel: strings = filter_string.lower().strip().split() proxyModel.setFilterFixedStrings(strings) self.updateInfo() def selectedSamples(self): """ Return the currently selected sample annotations. The return value is a list of selected (sample type, sample value) tuples. .. note:: if some Sample annotation type has no selected values. this method will return all values for it. """ samples = [] unused_types = [] used_types = [] for stype in childiter(self.annotationsTree.invisibleRootItem()): selected_values = [] all_values = [] for sval in childiter(stype): value = (str(stype.text(0)), str(sval.text(0))) if self.gdsSelectionStates.get(sval.key, True): selected_values.append(value) all_values.append(value) if selected_values: samples.extend(selected_values) used_types.append(str(stype.text(0))) else: # If no sample of sample type is selected we don't filter # on it. samples.extend(all_values) unused_types.append(str(stype.text(0))) return samples, used_types def commitIf(self): if self.autoCommit: self.commit() else: self.selectionChanged = True @Slot(int, int) def progressCompleted(self, value, total): if total > 0: self.progressBarSet(100. * value / total, processEvents=False) else: pass # TODO: report 'indeterminate progress' def commit(self): if self.currentGds: self.error(0) sample_type = None self.progressBarInit(processEvents=None) _, groups = self.selectedSamples() if len(groups) == 1 and self.outputRows: sample_type = groups[0] self.setEnabled(False) self.setBlocking(True) progress = methodinvoke(self, "progressCompleted", (int, int)) def get_data(gds_id, report_genes, transpose, sample_type, title): gds_ensure_downloaded(gds_id, progress) gds = GDS(gds_id) data = gds.get_data(report_genes=report_genes, transpose=transpose, sample_type=sample_type) data.name = title return data get_data = partial(get_data, self.currentGds["dataset_id"], report_genes=self.mergeSpots, transpose=self.outputRows, sample_type=sample_type, title=self.datasetName or self.currentGds["title"]) self._datatask = Task(function=get_data) self._datatask.finished.connect(self._on_dataready) self._executor.submit(self._datatask) def _on_dataready(self): self.setEnabled(True) self.setBlocking(False) self.progressBarFinished(processEvents=False) try: data = self._datatask.result() except urlrequest.URLError as error: self.error(0, ("Error while connecting to the NCBI ftp server! " "'%s'" % error)) sys.excepthook(type(error), error, getattr(error, "__traceback__")) return finally: self._datatask = None data_name = data.name samples, _ = self.selectedSamples() self.warning(0) message = None if self.outputRows: def samplesinst(ex): out = [] for meta in data.domain.metas: out.append((meta.name, ex[meta].value)) if data.domain.class_var.name != 'class': out.append((data.domain.class_var.name, ex[data.domain.class_var].value)) return out samples = set(samples) mask = [samples.issuperset(samplesinst(ex)) for ex in data] data = data[numpy.array(mask, dtype=bool)] if len(data) == 0: message = "No samples with selected sample annotations." else: samples = set(samples) domain = Domain([ attr for attr in data.domain.attributes if samples.issuperset(attr.attributes.items()) ], data.domain.class_var, data.domain.metas) # domain.addmetas(data.domain.getmetas()) if len(domain.attributes) == 0: message = "No samples with selected sample annotations." stypes = set(s[0] for s in samples) for attr in domain.attributes: attr.attributes = dict( (key, value) for key, value in attr.attributes.items() if key in stypes) data = Table(domain, data) if message is not None: self.warning(0, message) data_hints.set_hint(data, TAX_ID, self.currentGds.get("taxid", "")) data_hints.set_hint(data, GENE_NAME, bool(self.outputRows)) data.name = data_name self.send("Expression Data", data) model = self.treeWidget.model().sourceModel() row = self.gds.index(self.currentGds) model.setData(model.index(row, 0), " ", Qt.DisplayRole) self.updateInfo() self.selectionChanged = False def splitterMoved(self, *args): self.splitterSettings = [ bytes(sp.saveState()) for sp in self.splitters ] def send_report(self): self.report_items("GEO Dataset", [("ID", self.currentGds['dataset_id']), ("Title", self.currentGds['title']), ("Organism", self.currentGds['sample_organism'])]) self.report_items("Data", [("Samples", self.currentGds['sample_count']), ("Features", self.currentGds['feature_count']), ("Genes", self.currentGds['gene_count'])]) self.report_name("Sample annotations") subsets = defaultdict(list) for subset in self.currentGds['subsets']: subsets[subset['type']].append( (subset['description'], len(subset['sample_id']))) self.report_html += "<ul>" for type in subsets: self.report_html += "<b>" + type + ":</b></br>" for desc, count in subsets[type]: self.report_html += 9 * " " + "<b>{}:</b> {}</br>".format( desc, count) self.report_html += "</ul>" def onDeleteWidget(self): if self._inittask: self._inittask.future().cancel() self._inittask.finished.disconnect(self._initializemodel) if self._datatask: self._datatask.future().cancel() self._datatask.finished.disconnect(self._on_dataready) self._executor.shutdown(wait=False) super(OWGEODatasets, self).onDeleteWidget() def onNameEdited(self): if self.currentGds: gds_id = self.currentGds["dataset_id"] self.datasetNames[gds_id] = self.nameEdit.text() self.commitIf()
def __init__(self, parent=None, signalManager=None, name=" GEO Data Sets"): OWWidget.__init__(self, parent, signalManager, name) self.selectionChanged = False self.filterString = "" self.datasetName = "" ## GUI box = gui.widgetBox(self.controlArea, "Info", addSpace=True) self.infoBox = gui.widgetLabel(box, "Initializing\n\n") box = gui.widgetBox(self.controlArea, "Output", addSpace=True) gui.radioButtonsInBox(box, self, "outputRows", ["Genes in rows", "Samples in rows"], "Rows", callback=self.commitIf) gui.checkBox(box, self, "mergeSpots", "Merge spots of same gene", callback=self.commitIf) gui.separator(box) self.nameEdit = gui.lineEdit( box, self, "datasetName", "Data set name", tooltip="Override the default output data set name", callback=self.onNameEdited) self.nameEdit.setPlaceholderText("") if sys.version_info < (3, ): box = gui.widgetBox(self.controlArea, "Commit", addSpace=True) self.commitButton = gui.button(box, self, "Commit", callback=self.commit) cb = gui.checkBox(box, self, "autoCommit", "Commit on any change") gui.setStopper(self, self.commitButton, cb, "selectionChanged", self.commit) else: gui.auto_commit(self.controlArea, self, "autoCommit", "Commit", box="Commit") self.commitIf = self.commit gui.rubber(self.controlArea) gui.widgetLabel(self.mainArea, "Filter") self.filterLineEdit = QLineEdit(textChanged=self.filter) self.completer = TokenListCompleter(self, caseSensitivity=Qt.CaseInsensitive) self.filterLineEdit.setCompleter(self.completer) self.mainArea.layout().addWidget(self.filterLineEdit) splitter = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(splitter) self.treeWidget = QTreeView(splitter) self.treeWidget.setSelectionMode(QTreeView.SingleSelection) self.treeWidget.setRootIsDecorated(False) self.treeWidget.setSortingEnabled(True) self.treeWidget.setAlternatingRowColors(True) self.treeWidget.setUniformRowHeights(True) self.treeWidget.setEditTriggers(QTreeView.NoEditTriggers) linkdelegate = gui.LinkStyledItemDelegate(self.treeWidget) self.treeWidget.setItemDelegateForColumn(1, linkdelegate) self.treeWidget.setItemDelegateForColumn(8, linkdelegate) self.treeWidget.setItemDelegateForColumn( 0, gui.IndicatorItemDelegate(self.treeWidget, role=Qt.DisplayRole)) proxyModel = MySortFilterProxyModel(self.treeWidget) self.treeWidget.setModel(proxyModel) self.treeWidget.selectionModel().selectionChanged.connect( self.updateSelection) self.treeWidget.viewport().setMouseTracking(True) splitterH = QSplitter(Qt.Horizontal, splitter) box = gui.widgetBox(splitterH, "Description") self.infoGDS = gui.widgetLabel(box, "") self.infoGDS.setWordWrap(True) gui.rubber(box) box = gui.widgetBox(splitterH, "Sample Annotations") self.annotationsTree = QTreeWidget(box) self.annotationsTree.setHeaderLabels( ["Type (Sample annotations)", "Sample count"]) self.annotationsTree.setRootIsDecorated(True) box.layout().addWidget(self.annotationsTree) self.annotationsTree.itemChanged.connect( self.annotationSelectionChanged) self._annotationsUpdating = False self.splitters = splitter, splitterH for sp, setting in zip(self.splitters, self.splitterSettings): sp.splitterMoved.connect(self.splitterMoved) sp.restoreState(setting) self.searchKeys = [ "dataset_id", "title", "platform_organism", "description" ] self.gds = [] self.gds_info = None self.resize(1000, 600) self.setBlocking(True) self.setEnabled(False) self.progressBarInit() self._executor = ThreadExecutor() func = partial(get_gds_model, methodinvoke(self, "_setProgress", (float, ))) self._inittask = Task(function=func) self._inittask.finished.connect(self._initializemodel) self._executor.submit(self._inittask) self._datatask = None