def setBioMartConfiguration(self, configuration): assert QThread.currentThread() is self.thread() self.setEnabled(True) # parse the xml in the main thread (a long time ago this step was # done in a thread but would frequently cause `expat` to segfault. doc = biomart.parseXML(io.BytesIO(configuration)) config = list(doc.elements("DatasetConfig"))[0] configuration = biomart.DatasetConfig(self.registry, config.tag, config.attributes, config.children) self.clearConfiguration() self.configuration = configuration def hidden(tree): return getattr(tree, "hidden", "false") != "false" or getattr(tree, "hideDisplay", "false") != "false" self.attributePagesTabWidget = tabs = gui.tabWidget(self.attributesConfigurationBox) for page in configuration.elements("AttributePage"): if not hidden(page): page_widget = PageWidget(page, self.dataset, self) gui.createTabPage(tabs, getattr(page, "displayName", ""), widgetToAdd=page_widget, canScroll=True) if self.SHOW_FILTERS: self.filterPagesTabWidget = tabs = gui.tabWidget(self.filtersConfigurationBox) for page in configuration.elements("FilterPage"): if not hidden(page): page_widget = PageWidget(page, self.dataset, self) gui.createTabPage(tabs, getattr(page, "displayName", ""), widgetToAdd=page_widget, canScroll=True) self.afterInit() self.commitButton.setEnabled(True)
def __init__(self): super().__init__() self.graph = None self.items = None # items set by Items signal self.items_graph = None # items set by graph.items by Network signal self.items_analysis = None # items to output and merge with analysis result self.known = {} self.running_jobs = {} # Indicates that node level statistics have changed or are pending to self._nodelevel_invalidated = False self.controlArea = QWidget(self.controlArea) self.layout().addWidget(self.controlArea) layout = QGridLayout() self.controlArea.setLayout(layout) layout.setContentsMargins(4, 4, 4, 4) tabs = gui.tabWidget(self.controlArea) tabs.setMinimumWidth(450) graph_indices = gui.createTabPage(tabs, "Graph-level indices", orientation=Qt.Horizontal) node_indices = gui.createTabPage(tabs, "Node-level indices", orientation=Qt.Horizontal) graph_methods = gui.vBox(graph_indices) gui.rubber(graph_indices) graph_labels = gui.vBox(graph_indices) node_methods = gui.vBox(node_indices) gui.rubber(node_indices) node_labels = gui.vBox(node_indices) graph_labels.layout().setAlignment(Qt.AlignRight) self.method_cbs = {} for method in METHODS.values(): if method.level == INTERNAL: continue setattr(self, method.name, method.name in self.enabled_methods) setattr(self, "lbl_" + method.name, "") methods = node_methods if method.level == NODELEVEL else graph_methods labels = node_labels if method.level == NODELEVEL else graph_labels cb = gui.checkBox( methods, self, method.name, method.label, callback=lambda attr=method.name: self.method_clicked(attr)) self.method_cbs[method.name] = cb lbl = gui.label(labels, self, f"%(lbl_{method.name})s") labels.layout().setAlignment(lbl, Qt.AlignRight) setattr(self, "tool_" + method.name, lbl) # todo: is this accessible through controls? graph_indices.layout().addStretch(1) node_indices.layout().addStretch(1)
def clearConfiguration(self): self.mainTab.deleteLater() self.mainTab = QTabWidget() self.mainWidget.layout().addWidget(self.mainTab) self.mainWidget.layout().setCurrentWidget(self.mainTab) self.attributesConfigurationBox = gui.createTabPage(self.mainTab, "Attributes") if self.SHOW_FILTERS: self.filtersConfigurationBox = gui.createTabPage(self.mainTab, "Filters")
def create_control_panel(self): self.control_tabs = gui.tabWidget(self.controlArea) self.general_tab = gui.createTabPage(self.control_tabs, "Main") self.settings_tab = gui.createTabPage(self.control_tabs, "Settings") self.add_attribute_selection_area(self.general_tab) self.add_zoom_select_toolbar(self.general_tab) self.add_visual_settings(self.settings_tab) self.add_annotation_settings(self.settings_tab) self.add_color_settings(self.settings_tab) self.settings_tab.layout().addStretch(100) self.icons = attributeIconDict
def setBioMartConfiguration(self, configuration): assert (QThread.currentThread() is self.thread()) self.setEnabled(True) # parse the xml in the main thread (a long time ago this step was # done in a thread but would frequently cause `expat` to segfault. doc = biomart.parseXML(io.BytesIO(configuration)) config = list(doc.elements("DatasetConfig"))[0] configuration = biomart.DatasetConfig(self.registry, config.tag, config.attributes, config.children) self.clearConfiguration() self.configuration = configuration def hidden(tree): return getattr(tree, "hidden", "false") != "false" or \ getattr(tree, "hideDisplay", "false") != "false" self.attributePagesTabWidget = tabs = gui.tabWidget( self.attributesConfigurationBox) for page in configuration.elements("AttributePage"): if not hidden(page): page_widget = PageWidget(page, self.dataset, self) gui.createTabPage(tabs, getattr(page, "displayName", ""), widgetToAdd=page_widget, canScroll=True) if self.SHOW_FILTERS: self.filterPagesTabWidget = tabs = gui.tabWidget( self.filtersConfigurationBox) for page in configuration.elements("FilterPage"): if not hidden(page): page_widget = PageWidget(page, self.dataset, self) gui.createTabPage(tabs, getattr(page, "displayName", ""), widgetToAdd=page_widget, canScroll=True) self.afterInit() self.commitButton.setEnabled(True)
def __init__(self): super().__init__() self.graph = None self.items = None # items set by Items signal self.items_graph = None # items set by graph.items by Network signal self.items_analysis = None # items to output and merge with analysis result self.known = {} self.running_jobs = {} self.controlArea = QWidget(self.controlArea) self.layout().addWidget(self.controlArea) layout = QGridLayout() self.controlArea.setLayout(layout) layout.setContentsMargins(4, 4, 4, 4) tabs = gui.tabWidget(self.controlArea) tabs.setMinimumWidth(450) graph_indices = gui.createTabPage(tabs, "Graph-level indices") node_indices = gui.createTabPage(tabs, "Node-level indices") self.method_cbs = {} for method in METHODS.values(): if method.level == INTERNAL: continue setattr(self, method.name, method.name in self.enabled_methods) setattr(self, "lbl_" + method.name, "") box = gui.hBox(node_indices if method.level == NODELEVEL else graph_indices) cb = gui.checkBox( box, self, method.name, method.label, callback=lambda attr=method.name: self.method_clicked(attr)) self.method_cbs[method.name] = cb box.layout().addStretch(1) lbl = gui.label(box, self, f"%(lbl_{method.name})s") setattr(self, "tool_" + method.name, lbl) # todo: is this accessible through controls? graph_indices.layout().addStretch(1) node_indices.layout().addStretch(1)
def initializeTabs(self): size = len(self.tab) indexes = range(0, size) for index in indexes: self.tabs.removeTab(size-1-index) self.tab = [gui.createTabPage(self.tabs, "X,Z"), gui.createTabPage(self.tabs, "X',Z'"), gui.createTabPage(self.tabs, "X,X'"), gui.createTabPage(self.tabs, "Z,Z'"), gui.createTabPage(self.tabs, "Energy")] for tab in self.tab: tab.setFixedHeight(self.IMAGE_HEIGHT) tab.setFixedWidth(self.IMAGE_WIDTH) self.plot_canvas = [None, None, None, None, None] self.plot_upper_canvas = [None, None, None, None, None] self.plot_right_canvas = [None, None, None, None, None]
def createTabPage(cls, tabWidget, name, widgetToAdd=None, canScroll=False, height=None, width=None): tab = gui.createTabPage(tabWidget, name, widgetToAdd, canScroll) tab.layout().setAlignment(Qt.AlignTop) if not height is None: tab.setFixedHeight(height) if not width is None: tab.setFixedWidth(width) return tab
def createTabPage(cls, tabWidget, name, widgetToAdd=None, canScroll=False, height=None, width=None, isImage=False): tab = orange_gui.createTabPage(tabWidget, name, widgetToAdd, canScroll) tab.layout().setAlignment(Qt.AlignTop) if not height is None: tab.setFixedHeight(height) if not width is None: tab.setFixedWidth(width) if isImage: tab.setStyleSheet("background-color: #FFFFFF;") return tab
def __init__(self, parent=None): super().__init__(self, parent) self.clusterDataset = None self.referenceDataset = None self.ontology = None self.annotations = None self.loadedAnnotationCode = "---" self.treeStructRootKey = None self.probFunctions = [stats.Binomial(), stats.Hypergeometric()] self.selectedTerms = [] self.selectionChanging = 0 self.__state = OWGOEnrichmentAnalysis.Initializing self.annotationCodes = [] ############# ## GUI ############# self.tabs = gui.tabWidget(self.controlArea) ## Input tab self.inputTab = gui.createTabPage(self.tabs, "Input") box = gui.widgetBox(self.inputTab, "Info") self.infoLabel = gui.widgetLabel(box, "No data on input\n") gui.button(box, self, "Ontology/Annotation Info", callback=self.ShowInfo, tooltip="Show information on loaded ontology and annotations") box = gui.widgetBox(self.inputTab, "Organism") self.annotationComboBox = gui.comboBox( box, self, "annotationIndex", items=self.annotationCodes, callback=self._updateEnrichment, tooltip="Select organism") genebox = gui.widgetBox(self.inputTab, "Gene Names") self.geneAttrIndexCombo = gui.comboBox( genebox, self, "geneAttrIndex", callback=self._updateEnrichment, tooltip="Use this attribute to extract gene names from input data") self.geneAttrIndexCombo.setDisabled(self.useAttrNames) cb = gui.checkBox(genebox, self, "useAttrNames", "Use column names", tooltip="Use column names for gene names", callback=self._updateEnrichment) cb.toggled[bool].connect(self.geneAttrIndexCombo.setDisabled) gui.button(genebox, self, "Gene matcher settings", callback=self.UpdateGeneMatcher, tooltip="Open gene matching settings dialog") self.referenceRadioBox = gui.radioButtonsInBox( self.inputTab, self, "useReferenceDataset", ["Entire genome", "Reference set (input)"], tooltips=["Use entire genome for reference", "Use genes from Referece Examples input signal as reference"], box="Reference", callback=self._updateEnrichment) self.referenceRadioBox.buttons[1].setDisabled(True) gui.radioButtonsInBox( self.inputTab, self, "aspectIndex", ["Biological process", "Cellular component", "Molecular function"], box="Aspect", callback=self._updateEnrichment) ## Filter tab self.filterTab = gui.createTabPage(self.tabs, "Filter") box = gui.widgetBox(self.filterTab, "Filter GO Term Nodes") gui.checkBox(box, self, "filterByNumOfInstances", "Genes", callback=self.FilterAndDisplayGraph, tooltip="Filter by number of input genes mapped to a term") ibox = gui.indentedBox(box) gui.spin(ibox, self, 'minNumOfInstances', 1, 100, step=1, label='#:', labelWidth=15, callback=self.FilterAndDisplayGraph, callbackOnReturn=True, tooltip="Min. number of input genes mapped to a term") gui.checkBox(box, self, "filterByPValue_nofdr", "p-value", callback=self.FilterAndDisplayGraph, tooltip="Filter by term p-value") gui.doubleSpin(gui.indentedBox(box), self, 'maxPValue_nofdr', 1e-8, 1, step=1e-8, label='p:', labelWidth=15, callback=self.FilterAndDisplayGraph, callbackOnReturn=True, tooltip="Max term p-value") #use filterByPValue for FDR, as it was the default in prior versions gui.checkBox(box, self, "filterByPValue", "FDR", callback=self.FilterAndDisplayGraph, tooltip="Filter by term FDR") gui.doubleSpin(gui.indentedBox(box), self, 'maxPValue', 1e-8, 1, step=1e-8, label='p:', labelWidth=15, callback=self.FilterAndDisplayGraph, callbackOnReturn=True, tooltip="Max term p-value") box = gui.widgetBox(box, "Significance test") gui.radioButtonsInBox(box, self, "probFunc", ["Binomial", "Hypergeometric"], tooltips=["Use binomial distribution test", "Use hypergeometric distribution test"], callback=self._updateEnrichment) box = gui.widgetBox(self.filterTab, "Evidence codes in annotation", addSpace=True) self.evidenceCheckBoxDict = {} for etype in go.evidenceTypesOrdered: ecb = QCheckBox( etype, toolTip=go.evidenceTypes[etype], checked=self.useEvidenceType[etype]) ecb.toggled.connect(self.__on_evidenceChanged) box.layout().addWidget(ecb) self.evidenceCheckBoxDict[etype] = ecb ## Select tab self.selectTab = gui.createTabPage(self.tabs, "Select") box = gui.radioButtonsInBox( self.selectTab, self, "selectionDirectAnnotation", ["Directly or Indirectly", "Directly"], box="Annotated genes", callback=self.ExampleSelection) box = gui.widgetBox(self.selectTab, "Output", addSpace=True) gui.radioButtonsInBox( box, self, "selectionDisjoint", btnLabels=["All selected genes", "Term-specific genes", "Common term genes"], tooltips=["Outputs genes annotated to all selected GO terms", "Outputs genes that appear in only one of selected GO terms", "Outputs genes common to all selected GO terms"], callback=[self.ExampleSelection, self.UpdateAddClassButton]) self.addClassCB = gui.checkBox( box, self, "selectionAddTermAsClass", "Add GO Term as class", callback=self.ExampleSelection) # ListView for DAG, and table for significant GOIDs self.DAGcolumns = ['GO term', 'Cluster', 'Reference', 'p-value', 'FDR', 'Genes', 'Enrichment'] self.splitter = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(self.splitter) # list view self.listView = GOTreeWidget(self.splitter) self.listView.setSelectionMode(QTreeView.ExtendedSelection) self.listView.setAllColumnsShowFocus(1) self.listView.setColumnCount(len(self.DAGcolumns)) self.listView.setHeaderLabels(self.DAGcolumns) self.listView.header().setSectionsClickable(True) self.listView.header().setSortIndicatorShown(True) self.listView.setSortingEnabled(True) self.listView.setItemDelegateForColumn( 6, EnrichmentColumnItemDelegate(self)) self.listView.setRootIsDecorated(True) self.listView.itemSelectionChanged.connect(self.ViewSelectionChanged) # table of significant GO terms self.sigTerms = QTreeWidget(self.splitter) self.sigTerms.setColumnCount(len(self.DAGcolumns)) self.sigTerms.setHeaderLabels(self.DAGcolumns) self.sigTerms.setSortingEnabled(True) self.sigTerms.setSelectionMode(QTreeView.ExtendedSelection) self.sigTerms.setItemDelegateForColumn( 6, EnrichmentColumnItemDelegate(self)) self.sigTerms.itemSelectionChanged.connect(self.TableSelectionChanged) self.sigTableTermsSorted = [] self.graph = {} self.inputTab.layout().addStretch(1) self.filterTab.layout().addStretch(1) self.selectTab.layout().addStretch(1) self.setBlocking(True) self._executor = ThreadExecutor() self._init = EnsureDownloaded( [(taxonomy.Taxonomy.DOMAIN, taxonomy.Taxonomy.FILENAME), ("GO", "taxonomy.pickle")] ) self._init.finished.connect(self.__initialize_finish) self._executor.submit(self._init)
def __init__(self): super().__init__() self.output_corpus = None self.pubmed_api = None self.progress = None self.email_is_valid = False self.record_count = 0 self.download_running = False # To hold all the controls. Makes access easier. self.pubmed_controls = [] h_box = gui.hBox(self.controlArea) label = gui.label(h_box, self, 'Email:') label.setMaximumSize(label.sizeHint()) # Drop-down for recent emails. self.email_combo = QComboBox(h_box) self.email_combo.setMinimumWidth(150) self.email_combo.setEditable(True) self.email_combo.lineEdit().textChanged.connect(self.sync_email) h_box.layout().addWidget(self.email_combo) self.email_combo.activated[int].connect(self.select_email) # RECORD SEARCH self.search_tabs = gui.tabWidget(self.controlArea) # --- Regular search --- regular_search_box = gui.widgetBox(self.controlArea, addSpace=True) # Author self.author_input = gui.lineEdit(regular_search_box, self, 'author', 'Author:', orientation=Qt.Horizontal) self.pubmed_controls.append(self.author_input) h_box = gui.hBox(regular_search_box) year_box = gui.widgetBox(h_box, orientation=Qt.Horizontal) min_date = QDate.fromString( self.MIN_DATE.strftime(self.PY_DATE_FORMAT), self.QT_DATE_FORMAT) if not self.pub_date_from: self.pub_date_from = self.MIN_DATE.strftime(self.PY_DATE_FORMAT) if not self.pub_date_to: self.pub_date_to = date.today().strftime(self.PY_DATE_FORMAT) self.date_from = QDateEdit(QDate.fromString(self.pub_date_from, self.QT_DATE_FORMAT), displayFormat=self.QT_DATE_FORMAT, minimumDate=min_date, calendarPopup=True) self.date_to = QDateEdit(QDate.fromString(self.pub_date_to, self.QT_DATE_FORMAT), displayFormat=self.QT_DATE_FORMAT, minimumDate=min_date, calendarPopup=True) self.date_from.dateChanged.connect(lambda date: setattr( self, 'pub_date_from', date.toString(self.QT_DATE_FORMAT))) self.date_to.dateChanged.connect(lambda date: setattr( self, 'pub_date_to', date.toString(self.QT_DATE_FORMAT))) self.pubmed_controls.append(self.date_from) self.pubmed_controls.append(self.date_to) gui.label(year_box, self, 'From:') year_box.layout().addWidget(self.date_from) gui.label(year_box, self, 'to:') year_box.layout().addWidget(self.date_to) # Keywords. h_box = gui.hBox(regular_search_box) label = gui.label(h_box, self, 'Query:') label.setMaximumSize(label.sizeHint()) self.keyword_combo = QComboBox(h_box) self.keyword_combo.setMinimumWidth(150) self.keyword_combo.setEditable(True) h_box.layout().addWidget(self.keyword_combo) self.keyword_combo.activated[int].connect(self.select_keywords) self.pubmed_controls.append(self.keyword_combo) tab_height = regular_search_box.sizeHint() regular_search_box.setMaximumSize(tab_height) # --- Advanced search --- advanced_search_box = gui.widgetBox(self.controlArea, addSpace=True) # Advanced search query. h_box = gui.hBox(advanced_search_box) self.advanced_query_input = QTextEdit(h_box) h_box.layout().addWidget(self.advanced_query_input) self.advanced_query_input.setMaximumSize(tab_height) self.pubmed_controls.append(self.advanced_query_input) gui.createTabPage(self.search_tabs, 'Regular search', regular_search_box) gui.createTabPage(self.search_tabs, 'Advanced search', advanced_search_box) # Search info label. self.search_info_label = gui.label(self.controlArea, self, 'Number of records found: /') # Search for records button. self.run_search_button = gui.button( self.controlArea, self, 'Find records', callback=self.run_search, tooltip='Performs a search for articles that fit the ' 'specified parameters.') self.pubmed_controls.append(self.run_search_button) h_line = QFrame() h_line.setFrameShape(QFrame.HLine) h_line.setFrameShadow(QFrame.Sunken) self.controlArea.layout().addWidget(h_line) # RECORD RETRIEVAL # Text includes box. text_includes_box = gui.widgetBox(self.controlArea, 'Text includes', addSpace=True) self.authors_checkbox = gui.checkBox(text_includes_box, self, 'includes_authors', 'Authors') self.title_checkbox = gui.checkBox(text_includes_box, self, 'includes_title', 'Article title') self.mesh_checkbox = gui.checkBox(text_includes_box, self, 'includes_mesh', 'Mesh headings') self.abstract_checkbox = gui.checkBox(text_includes_box, self, 'includes_abstract', 'Abstract') self.url_checkbox = gui.checkBox(text_includes_box, self, 'includes_url', 'URL') self.pubmed_controls.append(self.authors_checkbox) self.pubmed_controls.append(self.title_checkbox) self.pubmed_controls.append(self.mesh_checkbox) self.pubmed_controls.append(self.abstract_checkbox) self.pubmed_controls.append(self.url_checkbox) # Num. records. h_box = gui.hBox(self.controlArea) label = gui.label(h_box, self, 'Retrieve') label.setMaximumSize(label.sizeHint()) self.num_records_input = gui.spin(h_box, self, 'num_records', minv=1, maxv=10000) self.max_records_label = gui.label(h_box, self, 'records from /.') self.max_records_label.setMaximumSize( self.max_records_label.sizeHint()) self.pubmed_controls.append(self.num_records_input) # Download articles. # Search for records button. self.retrieve_records_button = gui.button( self.controlArea, self, 'Retrieve records', callback=self.retrieve_records, tooltip='Retrieves the specified documents.') self.pubmed_controls.append(self.retrieve_records_button) # Num. retrieved records info label. self.retrieval_info_label = gui.label( self.controlArea, self, 'Number of records retrieved: /') # Load the most recent emails. self.set_email_list() # Load the most recent queries. self.set_keyword_list() # Check the email and enable controls accordingly. if self.recent_emails: email = self.recent_emails[0] self.email_is_valid = validate_email(email) self.enable_controls()
def __init__(self): super().__init__() self.controlArea = QWidget(self.controlArea) self.layout().addWidget(self.controlArea) layout = QGridLayout() self.controlArea.setLayout(layout) layout.setContentsMargins(4, 4, 4, 4) self.methods = [method for method in METHODS if method[-1] is not None] self.tab_index = 0 self.mutex = QMutex() self.graph = None self.items = None # items set by Items signal self.items_graph = None # items set by graph.items by Network signal self.items_analysis = None # items to output and merge with analysis result self.job_queue = [] self.job_working = [] self.analfeatures = [] self.analdata = {} for method in self.methods: setattr(self, method[0], method[0] in self.enabled_methods) setattr(self, "lbl_" + method[0], "") self.tabs = gui.tabWidget(self.controlArea) self.tabs.setMinimumWidth(450) self.graphIndices = gui.createTabPage(self.tabs, "Graph-level indices") self.nodeIndices = gui.createTabPage(self.tabs, "Node-level indices") self.tabs.setCurrentIndex(self.tab_index) self.tabs.currentChanged.connect( lambda index: setattr(self, 'tab_index', index)) a = {NODELEVEL: self.nodeIndices, GRAPHLEVEL: self.graphIndices} for name, _, label, type, algorithm in self.methods: box = gui.widgetBox(a[type], orientation="horizontal") gui.checkBox(box, self, name, label=label, callback=lambda n=name: self.method_clicked(n)) box.layout().addStretch(1) lbl = gui.label(box, self, "%(lbl_" + name + ")s") setattr(self, "tool_" + name, lbl) self.graphIndices.layout().addStretch(1) self.nodeIndices.layout().addStretch(1) autobox = gui.auto_commit(None, self, "auto_commit", "Commit", commit=self.analyze) layout.addWidget(autobox, 3, 0, 1, 1) cancel = gui.button(None, self, "Cancel", callback=lambda: self.stop_job(current=False)) autobox.layout().insertWidget(3, cancel) autobox.layout().insertSpacing(2, 10) cancel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
def __init__(self): super().__init__() self.methods = [ ("number_of_nodes", True, "Number of nodes", GRAPHLEVEL, lambda G: G.number_of_nodes()), ("number_of_edges", True, "Number of edges", GRAPHLEVEL, lambda G: G.number_of_edges()), ("average_degree", True, "Average degree", GRAPHLEVEL, lambda G: np.average(list(G.degree().values()))), ("diameter", False, "Diameter", GRAPHLEVEL, nx.diameter), ("radius", False, "Radius", GRAPHLEVEL, nx.radius), ("average_shortest_path_length", False, "Average shortest path length", GRAPHLEVEL, nx.average_shortest_path_length), ("density", True, "Density", GRAPHLEVEL, nx.density), ("degree_assortativity_coefficient", False, \ "Degree assortativity coefficient", GRAPHLEVEL, \ nx.degree_assortativity_coefficient if \ hasattr(nx, "degree_assortativity_coefficient") else None), # additional attr needed #("attribute_assortativity_coefficient", False, "Attribute assortativity coefficient", GRAPHLEVEL, nx.attribute_assortativity_coefficient), #("numeric_assortativity_coefficient", False, "Numeric assortativity coefficient", GRAPHLEVEL, nx.numeric_assortativity_coefficient), ("degree_pearson_correlation_coefficient", False, \ "Degree pearson correlation coefficient", GRAPHLEVEL, \ nx.degree_pearson_correlation_coefficient if\ hasattr(nx, "degree_pearson_correlation_coefficient") else None), ("estrada_index", False, "Estrada index", GRAPHLEVEL, \ nx.estrada_index if hasattr(nx, "estrada_index") else None), ("graph_clique_number", False, "Graph clique number", GRAPHLEVEL, nx.graph_clique_number), ("graph_number_of_cliques", False, "Graph number of cliques", GRAPHLEVEL, nx.graph_number_of_cliques), ("transitivity", False, "Graph transitivity", GRAPHLEVEL, nx.transitivity), ("average_clustering", False, "Average clustering coefficient", GRAPHLEVEL, nx.average_clustering), ("number_connected_components", False, "Number of connected components", GRAPHLEVEL, nx.number_connected_components), ("number_strongly_connected_components", False, "Number of strongly connected components", GRAPHLEVEL, nx.number_strongly_connected_components), ("number_weakly_connected_components", False, "Number of weakly connected components", GRAPHLEVEL, nx.number_weakly_connected_components), ("number_attracting_components", False, "Number of attracting components", GRAPHLEVEL, nx.number_attracting_components), # TODO: input parameters #("max_flow", False, "Maximum flow", GRAPHLEVEL, nx.max_flow), #("min_cut", False, "Minimum cut", GRAPHLEVEL, nx.min_cut), #("ford_fulkerson", False, "Maximum single-commodity flow (Ford-Fulkerson)", GRAPHLEVEL, nx.ford_fulkerson), #("min_cost_flow_cost", False, "min_cost_flow_cost", GRAPHLEVEL, nx.min_cost_flow_cost), # returns dict of dict #("shortest_path_length", False, "Shortest path length", GRAPHLEVEL, nx.shortest_path_length), ("degree", False, "Degree", NODELEVEL, nx.degree), ("in_degree", False, "In-degree", NODELEVEL, lambda G: G.in_degree()), ("out_degree", False, "Out-degree", NODELEVEL, lambda G: G.out_degree()), ("average_neighbor_degree", False, "Average neighbor degree", NODELEVEL, nx.average_neighbor_degree), ("clustering", False, "Clustering coefficient", NODELEVEL, nx.clustering), ("triangles", False, "Number of triangles", NODELEVEL, nx.triangles), ("square_clustering", False, "Squares clustering coefficient", NODELEVEL, nx.square_clustering), ("number_of_cliques", False, "Number of cliques", NODELEVEL, nx.number_of_cliques), ("degree_centrality", False, "Degree centrality", NODELEVEL, nx.degree_centrality), ("in_degree_centrality", False, "In-egree centrality", NODELEVEL, nx.in_degree_centrality), ("out_degree_centrality", False, "Out-degree centrality", NODELEVEL, nx.out_degree_centrality), ("closeness_centrality", False, "Closeness centrality", NODELEVEL, nx.closeness_centrality), ("betweenness_centrality", False, "Betweenness centrality", NODELEVEL, nx.betweenness_centrality), ("current_flow_closeness_centrality", False, "Information centrality", NODELEVEL, nx.current_flow_closeness_centrality), ("current_flow_betweenness_centrality", False, "Random-walk betweenness centrality", NODELEVEL, nx.current_flow_betweenness_centrality), ("approximate_current_flow_betweenness_centrality", False, \ "Approx. random-walk betweenness centrality", NODELEVEL, \ nx.approximate_current_flow_betweenness_centrality if \ hasattr(nx, "approximate_current_flow_betweenness_centrality") \ else None), ("eigenvector_centrality", False, "Eigenvector centrality", NODELEVEL, nx.eigenvector_centrality), ("eigenvector_centrality_numpy", False, "Eigenvector centrality (NumPy)", NODELEVEL, nx.eigenvector_centrality_numpy), ("load_centrality", False, "Load centrality", NODELEVEL, nx.load_centrality), ("core_number", False, "Core number", NODELEVEL, nx.core_number), ("eccentricity", False, "Eccentricity", NODELEVEL, nx.eccentricity), ("closeness_vitality", False, "Closeness vitality", NODELEVEL, nx.closeness_vitality), ] """ TODO: add average-degree_connectivity is_bipartite is_chordal katz_centrality katz_centrality_numpy communicability communicability_exp communicability_centrality communicability_centrality_exp communicability_betweenness_centrality average_node_connectivity is_directed_acyclic_graph center ?? """ self.methods = [method for method in self.methods if method[-1] is not None] self.auto_commit = False self.tab_index = 0 self.mutex = QtCore.QMutex() self.graph = None self.items = None # items set by Items signal self.items_graph = None # items set by graph.items by Network signal self.items_analysis = None # items to output and merge with analysis result self.job_queue = [] self.job_working = [] self.analfeatures = [] self.analdata = {} for method in self.methods: setattr(self, method[0], method[1]) setattr(self, "lbl_" + method[0], "") self.tabs = gui.tabWidget(self.controlArea) self.tabs.setMinimumWidth(450) self.graphIndices = gui.createTabPage(self.tabs, "Graph-level indices") self.nodeIndices = gui.createTabPage(self.tabs, "Node-level indices") self.tabs.setCurrentIndex(self.tab_index) self.tabs.currentChanged.connect(lambda index: setattr(self, 'tab_index', index)) for name, default, label, type, algorithm in self.methods: if type == NODELEVEL: box = gui.widgetBox(self.nodeIndices, orientation="horizontal") elif type == GRAPHLEVEL: box = gui.widgetBox(self.graphIndices, orientation="horizontal") gui.checkBox(box, self, name, label=label, callback=lambda n=name: self.method_clicked(n)) box.layout().addStretch(1) lbl = gui.label(box, self, "%(lbl_" + name + ")s") setattr(self, "tool_" + name, lbl) self.graphIndices.layout().addStretch(1) self.nodeIndices.layout().addStretch(1) gui.checkBox(self.controlArea, self, "auto_commit", label="Commit automatically") hb = gui.widgetBox(self.controlArea, None, orientation='horizontal') self.btnCommit = gui.button(hb, self, "Commit", callback=self.analyze, toggleButton=1) self.btnStopA = gui.button(hb, self, "Cancel", callback=lambda: self.stop_job(current=False)) self.btnStopA.setEnabled(False)
def __init__(self, parent=None): super().__init__(self, parent) self.clusterDataset = None self.referenceDataset = None self.ontology = None self.annotations = None self.loadedAnnotationCode = "---" self.treeStructRootKey = None self.probFunctions = [stats.Binomial(), stats.Hypergeometric()] self.selectedTerms = [] self.selectionChanging = 0 self.__state = OWGOEnrichmentAnalysis.Initializing self.annotationCodes = [] ############# ## GUI ############# self.tabs = gui.tabWidget(self.controlArea) ## Input tab self.inputTab = gui.createTabPage(self.tabs, "Input") box = gui.widgetBox(self.inputTab, "Info") self.infoLabel = gui.widgetLabel(box, "No data on input\n") gui.button( box, self, "Ontology/Annotation Info", callback=self.ShowInfo, tooltip="Show information on loaded ontology and annotations") box = gui.widgetBox(self.inputTab, "Organism") self.annotationComboBox = gui.comboBox(box, self, "annotationIndex", items=self.annotationCodes, callback=self._updateEnrichment, tooltip="Select organism") genebox = gui.widgetBox(self.inputTab, "Gene Names") self.geneAttrIndexCombo = gui.comboBox( genebox, self, "geneAttrIndex", callback=self._updateEnrichment, tooltip="Use this attribute to extract gene names from input data") self.geneAttrIndexCombo.setDisabled(self.useAttrNames) cb = gui.checkBox(genebox, self, "useAttrNames", "Use column names", tooltip="Use column names for gene names", callback=self._updateEnrichment) cb.toggled[bool].connect(self.geneAttrIndexCombo.setDisabled) gui.button(genebox, self, "Gene matcher settings", callback=self.UpdateGeneMatcher, tooltip="Open gene matching settings dialog") self.referenceRadioBox = gui.radioButtonsInBox( self.inputTab, self, "useReferenceDataset", ["Entire genome", "Reference set (input)"], tooltips=[ "Use entire genome for reference", "Use genes from Referece Examples input signal as reference" ], box="Reference", callback=self._updateEnrichment) self.referenceRadioBox.buttons[1].setDisabled(True) gui.radioButtonsInBox( self.inputTab, self, "aspectIndex", ["Biological process", "Cellular component", "Molecular function"], box="Aspect", callback=self._updateEnrichment) ## Filter tab self.filterTab = gui.createTabPage(self.tabs, "Filter") box = gui.widgetBox(self.filterTab, "Filter GO Term Nodes") gui.checkBox( box, self, "filterByNumOfInstances", "Genes", callback=self.FilterAndDisplayGraph, tooltip="Filter by number of input genes mapped to a term") ibox = gui.indentedBox(box) gui.spin(ibox, self, 'minNumOfInstances', 1, 100, step=1, label='#:', labelWidth=15, callback=self.FilterAndDisplayGraph, callbackOnReturn=True, tooltip="Min. number of input genes mapped to a term") gui.checkBox(box, self, "filterByPValue_nofdr", "p-value", callback=self.FilterAndDisplayGraph, tooltip="Filter by term p-value") gui.doubleSpin(gui.indentedBox(box), self, 'maxPValue_nofdr', 1e-8, 1, step=1e-8, label='p:', labelWidth=15, callback=self.FilterAndDisplayGraph, callbackOnReturn=True, tooltip="Max term p-value") #use filterByPValue for FDR, as it was the default in prior versions gui.checkBox(box, self, "filterByPValue", "FDR", callback=self.FilterAndDisplayGraph, tooltip="Filter by term FDR") gui.doubleSpin(gui.indentedBox(box), self, 'maxPValue', 1e-8, 1, step=1e-8, label='p:', labelWidth=15, callback=self.FilterAndDisplayGraph, callbackOnReturn=True, tooltip="Max term p-value") box = gui.widgetBox(box, "Significance test") gui.radioButtonsInBox(box, self, "probFunc", ["Binomial", "Hypergeometric"], tooltips=[ "Use binomial distribution test", "Use hypergeometric distribution test" ], callback=self._updateEnrichment) box = gui.widgetBox(self.filterTab, "Evidence codes in annotation", addSpace=True) self.evidenceCheckBoxDict = {} for etype in go.evidenceTypesOrdered: ecb = QCheckBox(etype, toolTip=go.evidenceTypes[etype], checked=self.useEvidenceType[etype]) ecb.toggled.connect(self.__on_evidenceChanged) box.layout().addWidget(ecb) self.evidenceCheckBoxDict[etype] = ecb ## Select tab self.selectTab = gui.createTabPage(self.tabs, "Select") box = gui.radioButtonsInBox(self.selectTab, self, "selectionDirectAnnotation", ["Directly or Indirectly", "Directly"], box="Annotated genes", callback=self.ExampleSelection) box = gui.widgetBox(self.selectTab, "Output", addSpace=True) gui.radioButtonsInBox( box, self, "selectionDisjoint", btnLabels=[ "All selected genes", "Term-specific genes", "Common term genes" ], tooltips=[ "Outputs genes annotated to all selected GO terms", "Outputs genes that appear in only one of selected GO terms", "Outputs genes common to all selected GO terms" ], callback=[self.ExampleSelection, self.UpdateAddClassButton]) self.addClassCB = gui.checkBox(box, self, "selectionAddTermAsClass", "Add GO Term as class", callback=self.ExampleSelection) # ListView for DAG, and table for significant GOIDs self.DAGcolumns = [ 'GO term', 'Cluster', 'Reference', 'p-value', 'FDR', 'Genes', 'Enrichment' ] self.splitter = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(self.splitter) # list view self.listView = GOTreeWidget(self.splitter) self.listView.setSelectionMode(QTreeView.ExtendedSelection) self.listView.setAllColumnsShowFocus(1) self.listView.setColumnCount(len(self.DAGcolumns)) self.listView.setHeaderLabels(self.DAGcolumns) self.listView.header().setSectionsClickable(True) self.listView.header().setSortIndicatorShown(True) self.listView.setSortingEnabled(True) self.listView.setItemDelegateForColumn( 6, EnrichmentColumnItemDelegate(self)) self.listView.setRootIsDecorated(True) self.listView.itemSelectionChanged.connect(self.ViewSelectionChanged) # table of significant GO terms self.sigTerms = QTreeWidget(self.splitter) self.sigTerms.setColumnCount(len(self.DAGcolumns)) self.sigTerms.setHeaderLabels(self.DAGcolumns) self.sigTerms.setSortingEnabled(True) self.sigTerms.setSelectionMode(QTreeView.ExtendedSelection) self.sigTerms.setItemDelegateForColumn( 6, EnrichmentColumnItemDelegate(self)) self.sigTerms.itemSelectionChanged.connect(self.TableSelectionChanged) self.sigTableTermsSorted = [] self.graph = {} self.inputTab.layout().addStretch(1) self.filterTab.layout().addStretch(1) self.selectTab.layout().addStretch(1) self.setBlocking(True) self._executor = ThreadExecutor() self._init = EnsureDownloaded([(taxonomy.Taxonomy.DOMAIN, taxonomy.Taxonomy.FILENAME), ("GO", "taxonomy.pickle")]) self._init.finished.connect(self.__initialize_finish) self._executor.submit(self._init)
def __init__(self): super().__init__() #self.contextHandlers = {"": DomainContextHandler("", [ContextField("attributes", selected="node_label_attrs"), ContextField("attributes", selected="tooltipAttributes"), "color"])} self.view = GraphView(self) self.mainArea.layout().addWidget(self.view) self.graph_attrs = [] self.acceptingEnterKeypress = False self.node_label_attrs = [] self.tooltipAttributes = [] self.searchStringTimer = QTimer(self) self.markInputItems = None self.node_color_attr = 0 self.node_size_attr = 0 self.nHighlighted = 0 self.nSelected = 0 self.verticesPerEdge = 0 self.edgesPerVertex = 0 self.lastVertexSizeColumn = '' self.lastColorColumn = '' self.lastLabelColumns = set() self.lastTooltipColumns = set() self.items_matrix = None self.number_of_nodes_label = 0 self.number_of_edges_label = 0 self.graph = None self.setMinimumWidth(600) self.tabs = gui.tabWidget(self.controlArea) self.displayTab = gui.createTabPage(self.tabs, "Display") self.markTab = gui.createTabPage(self.tabs, "Marking") def on_tab_changed(index): self.tabIndex = index self.set_selection_mode() self.tabs.currentChanged.connect(on_tab_changed) self.tabs.setCurrentIndex(self.tabIndex) ib = gui.widgetBox(self.displayTab, "Info") gui.label( ib, self, "Nodes: %(number_of_nodes_label)i (%(verticesPerEdge).2f per edge)" ) gui.label( ib, self, "Edges: %(number_of_edges_label)i (%(edgesPerVertex).2f per node)") box = gui.widgetBox(self.displayTab, "Nodes") self.relayout_button = gui.button(box, self, 'Re-layout', callback=self.relayout, autoDefault=False) self.view.positionsChanged.connect( lambda _: self.progressbar.advance()) def animationFinished(): self.relayout_button.setEnabled(True) self.progressbar.finish() self.view.animationFinished.connect(animationFinished) self.colorCombo = gui.comboBox(box, self, "node_color_attr", label='Color:', orientation='horizontal', callback=self.set_node_colors) self.invertNodeSizeCheck = self.maxNodeSizeSpin = QWidget( ) # Forward declaration self.nodeSizeCombo = gui.comboBox(box, self, "node_size_attr", label='Size:', orientation='horizontal', callback=self.set_node_sizes) hb = gui.widgetBox(box, orientation="horizontal") hb.layout().addStretch(1) self.minNodeSizeSpin = gui.spin(hb, self, "minNodeSize", 1, 50, step=1, label="Min:", callback=self.set_node_sizes) self.minNodeSizeSpin.setValue(8) gui.separator(hb) self.maxNodeSizeSpin = gui.spin(hb, self, "maxNodeSize", 10, 200, step=5, label="Max:", callback=self.set_node_sizes) self.maxNodeSizeSpin.setValue(50) gui.separator(hb) self.invertNodeSizeCheck = gui.checkBox(hb, self, "invertNodeSize", "Invert", callback=self.set_node_sizes) hb = gui.widgetBox(self.displayTab, box="Node labels | tooltips", orientation="horizontal", addSpace=False) self.attListBox = gui.listBox( hb, self, "node_label_attrs", "graph_attrs", selectionMode=QListWidget.MultiSelection, sizeHint=QSize(100, 100), callback=self._on_node_label_attrs_changed) self.tooltipListBox = gui.listBox( hb, self, "tooltipAttributes", "graph_attrs", selectionMode=QListWidget.MultiSelection, sizeHint=QSize(100, 100), callback=self._clicked_tooltip_lstbox) eb = gui.widgetBox(self.displayTab, "Edges", orientation="vertical") self.checkbox_relative_edges = gui.checkBox( eb, self, 'relativeEdgeWidths', 'Relative edge widths', callback=self.set_edge_sizes) self.checkbox_show_weights = gui.checkBox( eb, self, 'showEdgeWeights', 'Show edge weights', callback=self.set_edge_labels) ib = gui.widgetBox(self.markTab, "Info", orientation="vertical") gui.label(ib, self, "Nodes: %(number_of_nodes_label)i") gui.label(ib, self, "Selected: %(nSelected)i") gui.label(ib, self, "Highlighted: %(nHighlighted)i") def on_selection_change(): self.nSelected = len(self.view.getSelected()) self.nHighlighted = len(self.view.getHighlighted()) self.set_selection_mode() self.commit() self.view.selectionChanged.connect(on_selection_change) ib = gui.widgetBox(self.markTab, "Highlight nodes ...") ribg = gui.radioButtonsInBox(ib, self, "selectionMode", callback=self.set_selection_mode) gui.appendRadioButton(ribg, "None") gui.appendRadioButton(ribg, "... whose attributes contain:") self.ctrlMarkSearchString = gui.lineEdit( gui.indentedBox(ribg), self, "markSearchString", callback=self._set_search_string_timer, callbackOnType=True) self.searchStringTimer.timeout.connect(self.set_selection_mode) gui.appendRadioButton(ribg, "... neighbours of selected, ≤ N hops away") ib = gui.indentedBox(ribg, orientation=0) self.ctrlMarkDistance = gui.spin( ib, self, "markDistance", 1, 100, 1, label="Hops:", callback=lambda: self.set_selection_mode(SelectionMode.NEIGHBORS)) ib.layout().addStretch(1) gui.appendRadioButton(ribg, "... with at least N connections") gui.appendRadioButton(ribg, "... with at most N connections") ib = gui.indentedBox(ribg, orientation=0) self.ctrlMarkNConnections = gui.spin( ib, self, "markNConnections", 0, 1000000, 1, label="Connections:", callback=lambda: self.set_selection_mode( SelectionMode.AT_MOST_N if self.selectionMode == SelectionMode. AT_MOST_N else SelectionMode.AT_LEAST_N)) ib.layout().addStretch(1) gui.appendRadioButton(ribg, "... with more connections than any neighbor") gui.appendRadioButton( ribg, "... with more connections than average neighbor") gui.appendRadioButton(ribg, "... with most connections") ib = gui.indentedBox(ribg, orientation=0) self.ctrlMarkNumber = gui.spin( ib, self, "markNBest", 1, 1000000, 1, label="Number of nodes:", callback=lambda: self.set_selection_mode(SelectionMode.MOST_CONN)) ib.layout().addStretch(1) self.markInputRadioButton = gui.appendRadioButton( ribg, "... from Node Subset input signal") self.markInputRadioButton.setEnabled(True) gui.auto_commit(ribg, self, 'do_auto_commit', 'Output changes') self.markTab.layout().addStretch(1) self.set_graph(None) self.set_selection_mode()
def __init__(self, parent=None): super().__init__(self, parent) self.input_data = None self.ref_data = None self.ontology = None self.annotations = None self.loaded_annotation_code = None self.treeStructRootKey = None self.probFunctions = [statistics.Binomial(), statistics.Hypergeometric()] self.selectedTerms = [] self.selectionChanging = 0 self.__state = State.Ready self.__scheduletimer = QTimer(self, singleShot=True) self.__scheduletimer.timeout.connect(self.__update) ############# # GUI ############# self.tabs = gui.tabWidget(self.controlArea) # Input tab self.inputTab = gui.createTabPage(self.tabs, "Input") box = gui.widgetBox(self.inputTab, "Info") self.infoLabel = gui.widgetLabel(box, "No data on input\n") gui.button(box, self, "Ontology/Annotation Info", callback=self.ShowInfo, tooltip="Show information on loaded ontology and annotations") self.referenceRadioBox = gui.radioButtonsInBox( self.inputTab, self, "useReferenceDataset", ["Entire genome", "Reference set (input)"], tooltips=["Use entire genome for reference", "Use genes from Referece Examples input signal as reference"], box="Reference", callback=self.__invalidate) self.referenceRadioBox.buttons[1].setDisabled(True) gui.radioButtonsInBox( self.inputTab, self, "aspectIndex", ["Biological process", "Cellular component", "Molecular function"], box="Aspect", callback=self.__invalidate) # Filter tab self.filterTab = gui.createTabPage(self.tabs, "Filter") box = gui.widgetBox(self.filterTab, "Filter GO Term Nodes") gui.checkBox(box, self, "filterByNumOfInstances", "Genes", callback=self.FilterAndDisplayGraph, tooltip="Filter by number of input genes mapped to a term") ibox = gui.indentedBox(box) gui.spin(ibox, self, 'minNumOfInstances', 1, 100, step=1, label='#:', labelWidth=15, callback=self.FilterAndDisplayGraph, callbackOnReturn=True, tooltip="Min. number of input genes mapped to a term") gui.checkBox(box, self, "filterByPValue_nofdr", "p-value", callback=self.FilterAndDisplayGraph, tooltip="Filter by term p-value") gui.doubleSpin(gui.indentedBox(box), self, 'maxPValue_nofdr', 1e-8, 1, step=1e-8, label='p:', labelWidth=15, callback=self.FilterAndDisplayGraph, callbackOnReturn=True, tooltip="Max term p-value") # use filterByPValue for FDR, as it was the default in prior versions gui.checkBox(box, self, "filterByPValue", "FDR", callback=self.FilterAndDisplayGraph, tooltip="Filter by term FDR") gui.doubleSpin(gui.indentedBox(box), self, 'maxPValue', 1e-8, 1, step=1e-8, label='p:', labelWidth=15, callback=self.FilterAndDisplayGraph, callbackOnReturn=True, tooltip="Max term p-value") box = gui.widgetBox(box, "Significance test") gui.radioButtonsInBox(box, self, "probFunc", ["Binomial", "Hypergeometric"], tooltips=["Use binomial distribution test", "Use hypergeometric distribution test"], callback=self.__invalidate) # TODO: only update the p values box = gui.widgetBox(self.filterTab, "Evidence codes in annotation", addSpace=True) self.evidenceCheckBoxDict = {} for etype in go.evidenceTypesOrdered: ecb = QCheckBox( etype, toolTip=go.evidenceTypes[etype], checked=self.useEvidenceType[etype]) ecb.toggled.connect(self.__on_evidenceChanged) box.layout().addWidget(ecb) self.evidenceCheckBoxDict[etype] = ecb # Select tab self.selectTab = gui.createTabPage(self.tabs, "Select") box = gui.radioButtonsInBox( self.selectTab, self, "selectionDirectAnnotation", ["Directly or Indirectly", "Directly"], box="Annotated genes", callback=self.ExampleSelection) box = gui.widgetBox(self.selectTab, "Output", addSpace=True) gui.radioButtonsInBox( box, self, "selectionDisjoint", btnLabels=["All selected genes", "Term-specific genes", "Common term genes"], tooltips=["Outputs genes annotated to all selected GO terms", "Outputs genes that appear in only one of selected GO terms", "Outputs genes common to all selected GO terms"], callback=self.ExampleSelection) # ListView for DAG, and table for significant GOIDs self.DAGcolumns = ['GO term', 'Cluster', 'Reference', 'p-value', 'FDR', 'Genes', 'Enrichment'] self.splitter = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(self.splitter) # list view self.listView = GOTreeWidget(self.splitter) self.listView.setSelectionMode(QTreeView.ExtendedSelection) self.listView.setAllColumnsShowFocus(1) self.listView.setColumnCount(len(self.DAGcolumns)) self.listView.setHeaderLabels(self.DAGcolumns) self.listView.header().setSectionsClickable(True) self.listView.header().setSortIndicatorShown(True) self.listView.header().setSortIndicator(self.DAGcolumns.index('p-value'), Qt.AscendingOrder) self.listView.setSortingEnabled(True) self.listView.setItemDelegateForColumn( 6, EnrichmentColumnItemDelegate(self)) self.listView.setRootIsDecorated(True) self.listView.itemSelectionChanged.connect(self.ViewSelectionChanged) # table of significant GO terms self.sigTerms = QTreeWidget(self.splitter) self.sigTerms.setColumnCount(len(self.DAGcolumns)) self.sigTerms.setHeaderLabels(self.DAGcolumns) self.sigTerms.setSortingEnabled(True) self.sigTerms.setSelectionMode(QTreeView.ExtendedSelection) self.sigTerms.header().setSortIndicator(self.DAGcolumns.index('p-value'), Qt.AscendingOrder) self.sigTerms.setItemDelegateForColumn( 6, EnrichmentColumnItemDelegate(self)) self.sigTerms.itemSelectionChanged.connect(self.TableSelectionChanged) self.sigTableTermsSorted = [] self.graph = {} self.originalGraph = None self.inputTab.layout().addStretch(1) self.filterTab.layout().addStretch(1) self.selectTab.layout().addStretch(1) class AnnotationSlot(SimpleNamespace): taxid = ... # type: str name = ... # type: str filename = ... # type:str @staticmethod def parse_tax_id(f_name): return f_name.split('.')[1] try: remote_files = serverfiles.ServerFiles().listfiles(DOMAIN) except (ConnectTimeout, RequestException, ConnectionError): # TODO: Warn user about failed connection to the remote server remote_files = [] self.available_annotations = [ AnnotationSlot( taxid=AnnotationSlot.parse_tax_id(annotation_file), name=taxonomy.common_taxid_to_name(AnnotationSlot.parse_tax_id(annotation_file)), filename=FILENAME_ANNOTATION.format(AnnotationSlot.parse_tax_id(annotation_file)) ) for _, annotation_file in set(remote_files + serverfiles.listfiles(DOMAIN)) if annotation_file != FILENAME_ONTOLOGY ] self._executor = ThreadExecutor()
def __init__(self): super().__init__() self.methods = [ ("number_of_nodes", True, "Number of nodes", GRAPHLEVEL, lambda G: G.number_of_nodes()), ("number_of_edges", True, "Number of edges", GRAPHLEVEL, lambda G: G.number_of_edges()), ("average_degree", True, "Average degree", GRAPHLEVEL, lambda G: np.average(list(G.degree().values()))), ("diameter", False, "Diameter", GRAPHLEVEL, nx.diameter), ("radius", False, "Radius", GRAPHLEVEL, nx.radius), ("average_shortest_path_length", False, "Average shortest path length", GRAPHLEVEL, nx.average_shortest_path_length), ("density", True, "Density", GRAPHLEVEL, nx.density), ("degree_assortativity_coefficient", False, \ "Degree assortativity coefficient", GRAPHLEVEL, \ nx.degree_assortativity_coefficient if \ hasattr(nx, "degree_assortativity_coefficient") else None), # additional attr needed #("attribute_assortativity_coefficient", False, "Attribute assortativity coefficient", GRAPHLEVEL, nx.attribute_assortativity_coefficient), #("numeric_assortativity_coefficient", False, "Numeric assortativity coefficient", GRAPHLEVEL, nx.numeric_assortativity_coefficient), ("degree_pearson_correlation_coefficient", False, \ "Degree pearson correlation coefficient", GRAPHLEVEL, \ nx.degree_pearson_correlation_coefficient if\ hasattr(nx, "degree_pearson_correlation_coefficient") else None), ("estrada_index", False, "Estrada index", GRAPHLEVEL, \ nx.estrada_index if hasattr(nx, "estrada_index") else None), ("graph_clique_number", False, "Graph clique number", GRAPHLEVEL, nx.graph_clique_number), ("graph_number_of_cliques", False, "Graph number of cliques", GRAPHLEVEL, nx.graph_number_of_cliques), ("transitivity", False, "Graph transitivity", GRAPHLEVEL, nx.transitivity), ("average_clustering", False, "Average clustering coefficient", GRAPHLEVEL, nx.average_clustering), ("number_connected_components", False, "Number of connected components", GRAPHLEVEL, nx.number_connected_components), ("number_strongly_connected_components", False, "Number of strongly connected components", GRAPHLEVEL, nx.number_strongly_connected_components), ("number_weakly_connected_components", False, "Number of weakly connected components", GRAPHLEVEL, nx.number_weakly_connected_components), ("number_attracting_components", False, "Number of attracting components", GRAPHLEVEL, nx.number_attracting_components), # TODO: input parameters #("max_flow", False, "Maximum flow", GRAPHLEVEL, nx.max_flow), #("min_cut", False, "Minimum cut", GRAPHLEVEL, nx.min_cut), #("ford_fulkerson", False, "Maximum single-commodity flow (Ford-Fulkerson)", GRAPHLEVEL, nx.ford_fulkerson), #("min_cost_flow_cost", False, "min_cost_flow_cost", GRAPHLEVEL, nx.min_cost_flow_cost), # returns dict of dict #("shortest_path_length", False, "Shortest path length", GRAPHLEVEL, nx.shortest_path_length), ("degree", False, "Degree", NODELEVEL, nx.degree), ("in_degree", False, "In-degree", NODELEVEL, lambda G: G.in_degree()), ("out_degree", False, "Out-degree", NODELEVEL, lambda G: G.out_degree()), ("average_neighbor_degree", False, "Average neighbor degree", NODELEVEL, nx.average_neighbor_degree), ("clustering", False, "Clustering coefficient", NODELEVEL, nx.clustering), ("triangles", False, "Number of triangles", NODELEVEL, nx.triangles), ("square_clustering", False, "Squares clustering coefficient", NODELEVEL, nx.square_clustering), ("number_of_cliques", False, "Number of cliques", NODELEVEL, nx.number_of_cliques), ("degree_centrality", False, "Degree centrality", NODELEVEL, nx.degree_centrality), ("in_degree_centrality", False, "In-egree centrality", NODELEVEL, nx.in_degree_centrality), ("out_degree_centrality", False, "Out-degree centrality", NODELEVEL, nx.out_degree_centrality), ("closeness_centrality", False, "Closeness centrality", NODELEVEL, nx.closeness_centrality), ("betweenness_centrality", False, "Betweenness centrality", NODELEVEL, nx.betweenness_centrality), ("current_flow_closeness_centrality", False, "Information centrality", NODELEVEL, nx.current_flow_closeness_centrality), ("current_flow_betweenness_centrality", False, "Random-walk betweenness centrality", NODELEVEL, nx.current_flow_betweenness_centrality), ("approximate_current_flow_betweenness_centrality", False, \ "Approx. random-walk betweenness centrality", NODELEVEL, \ nx.approximate_current_flow_betweenness_centrality if \ hasattr(nx, "approximate_current_flow_betweenness_centrality") \ else None), ("eigenvector_centrality", False, "Eigenvector centrality", NODELEVEL, nx.eigenvector_centrality), ("eigenvector_centrality_numpy", False, "Eigenvector centrality (NumPy)", NODELEVEL, nx.eigenvector_centrality_numpy), ("load_centrality", False, "Load centrality", NODELEVEL, nx.load_centrality), ("core_number", False, "Core number", NODELEVEL, nx.core_number), ("eccentricity", False, "Eccentricity", NODELEVEL, nx.eccentricity), ("closeness_vitality", False, "Closeness vitality", NODELEVEL, nx.closeness_vitality), ] """ TODO: add average-degree_connectivity is_bipartite is_chordal katz_centrality katz_centrality_numpy communicability communicability_exp communicability_centrality communicability_centrality_exp communicability_betweenness_centrality average_node_connectivity is_directed_acyclic_graph center ?? """ self.methods = [ method for method in self.methods if method[-1] is not None ] self.auto_commit = False self.tab_index = 0 self.mutex = QtCore.QMutex() self.graph = None self.items = None # items set by Items signal self.items_graph = None # items set by graph.items by Network signal self.items_analysis = None # items to output and merge with analysis result self.job_queue = [] self.job_working = [] self.analfeatures = [] self.analdata = {} for method in self.methods: setattr(self, method[0], method[1]) setattr(self, "lbl_" + method[0], "") self.tabs = gui.tabWidget(self.controlArea) self.tabs.setMinimumWidth(450) self.graphIndices = gui.createTabPage(self.tabs, "Graph-level indices") self.nodeIndices = gui.createTabPage(self.tabs, "Node-level indices") self.tabs.setCurrentIndex(self.tab_index) self.tabs.currentChanged.connect( lambda index: setattr(self, 'tab_index', index)) for name, default, label, type, algorithm in self.methods: if type == NODELEVEL: box = gui.widgetBox(self.nodeIndices, orientation="horizontal") elif type == GRAPHLEVEL: box = gui.widgetBox(self.graphIndices, orientation="horizontal") gui.checkBox(box, self, name, label=label, callback=lambda n=name: self.method_clicked(n)) box.layout().addStretch(1) lbl = gui.label(box, self, "%(lbl_" + name + ")s") setattr(self, "tool_" + name, lbl) self.graphIndices.layout().addStretch(1) self.nodeIndices.layout().addStretch(1) gui.checkBox(self.controlArea, self, "auto_commit", label="Commit automatically") hb = gui.widgetBox(self.controlArea, None, orientation='horizontal') self.btnCommit = gui.button(hb, self, "Commit", callback=self.analyze, toggleButton=1) self.btnStopA = gui.button( hb, self, "Cancel", callback=lambda: self.stop_job(current=False)) self.btnStopA.setEnabled(False)
def __init__(self): super().__init__() self.output_corpus = None self.pubmed_api = None self.progress = None self.email_is_valid = False self.record_count = 0 self.download_running = False # To hold all the controls. Makes access easier. self.pubmed_controls = [] h_box = gui.hBox(self.controlArea) label = gui.label(h_box, self, 'Email:') label.setMaximumSize(label.sizeHint()) # Drop-down for recent emails. self.email_combo = QComboBox(h_box) self.email_combo.setMinimumWidth(150) self.email_combo.setEditable(True) self.email_combo.lineEdit().textChanged.connect(self.sync_email) h_box.layout().addWidget(self.email_combo) self.email_combo.activated[int].connect(self.select_email) # RECORD SEARCH self.search_tabs = gui.tabWidget(self.controlArea) # --- Regular search --- regular_search_box = gui.widgetBox(self.controlArea, addSpace=True) # Author self.author_input = gui.lineEdit(regular_search_box, self, 'author', 'Author:', orientation=Qt.Horizontal) self.pubmed_controls.append(self.author_input) h_box = gui.hBox(regular_search_box) year_box = gui.widgetBox(h_box, orientation=Qt.Horizontal) min_date = QDate.fromString( self.MIN_DATE.strftime(self.PY_DATE_FORMAT), self.QT_DATE_FORMAT ) if not self.pub_date_from: self.pub_date_from = self.MIN_DATE.strftime(self.PY_DATE_FORMAT) if not self.pub_date_to: self.pub_date_to = date.today().strftime(self.PY_DATE_FORMAT) self.date_from = QDateEdit( QDate.fromString(self.pub_date_from, self.QT_DATE_FORMAT), displayFormat=self.QT_DATE_FORMAT, minimumDate=min_date, calendarPopup=True ) self.date_to = QDateEdit( QDate.fromString(self.pub_date_to, self.QT_DATE_FORMAT), displayFormat=self.QT_DATE_FORMAT, minimumDate=min_date, calendarPopup=True ) self.date_from.dateChanged.connect( lambda date: setattr(self, 'pub_date_from', date.toString(self.QT_DATE_FORMAT))) self.date_to.dateChanged.connect( lambda date: setattr(self, 'pub_date_to', date.toString(self.QT_DATE_FORMAT))) self.pubmed_controls.append(self.date_from) self.pubmed_controls.append(self.date_to) gui.label(year_box, self, 'From:') year_box.layout().addWidget(self.date_from) gui.label(year_box, self, 'to:') year_box.layout().addWidget(self.date_to) # Keywords. h_box = gui.hBox(regular_search_box) label = gui.label(h_box, self, 'Query:') label.setMaximumSize(label.sizeHint()) self.keyword_combo = QComboBox(h_box) self.keyword_combo.setMinimumWidth(150) self.keyword_combo.setEditable(True) h_box.layout().addWidget(self.keyword_combo) self.keyword_combo.activated[int].connect(self.select_keywords) self.pubmed_controls.append(self.keyword_combo) tab_height = regular_search_box.sizeHint() regular_search_box.setMaximumSize(tab_height) # --- Advanced search --- advanced_search_box = gui.widgetBox(self.controlArea, addSpace=True) # Advanced search query. h_box = gui.hBox(advanced_search_box) self.advanced_query_input = QTextEdit(h_box) h_box.layout().addWidget(self.advanced_query_input) self.advanced_query_input.setMaximumSize(tab_height) self.pubmed_controls.append(self.advanced_query_input) gui.createTabPage(self.search_tabs, 'Regular search', regular_search_box) gui.createTabPage(self.search_tabs, 'Advanced search', advanced_search_box) # Search info label. self.search_info_label = gui.label( self.controlArea, self, 'Number of records found: /') # Search for records button. self.run_search_button = gui.button( self.controlArea, self, 'Find records', callback=self.run_search, tooltip='Performs a search for articles that fit the ' 'specified parameters.') self.pubmed_controls.append(self.run_search_button) h_line = QFrame() h_line.setFrameShape(QFrame.HLine) h_line.setFrameShadow(QFrame.Sunken) self.controlArea.layout().addWidget(h_line) # RECORD RETRIEVAL # Text includes box. text_includes_box = gui.widgetBox(self.controlArea, 'Text includes', addSpace=True) self.authors_checkbox = gui.checkBox(text_includes_box, self, 'includes_authors', 'Authors') self.title_checkbox = gui.checkBox(text_includes_box, self, 'includes_title', 'Article title') self.mesh_checkbox = gui.checkBox(text_includes_box, self, 'includes_mesh', 'Mesh headings') self.abstract_checkbox = gui.checkBox(text_includes_box, self, 'includes_abstract', 'Abstract') self.url_checkbox = gui.checkBox(text_includes_box, self, 'includes_url', 'URL') self.pubmed_controls.append(self.authors_checkbox) self.pubmed_controls.append(self.title_checkbox) self.pubmed_controls.append(self.mesh_checkbox) self.pubmed_controls.append(self.abstract_checkbox) self.pubmed_controls.append(self.url_checkbox) # Num. records. h_box = gui.hBox(self.controlArea) label = gui.label(h_box, self, 'Retrieve') label.setMaximumSize(label.sizeHint()) self.num_records_input = gui.spin(h_box, self, 'num_records', minv=1, maxv=100000) self.max_records_label = gui.label(h_box, self, 'records from /.') self.max_records_label.setMaximumSize(self.max_records_label .sizeHint()) self.pubmed_controls.append(self.num_records_input) # Download articles. # Search for records button. self.retrieve_records_button = gui.button( self.controlArea, self, 'Retrieve records', callback=self.retrieve_records, tooltip='Retrieves the specified documents.') self.pubmed_controls.append(self.retrieve_records_button) # Num. retrieved records info label. self.retrieval_info_label = gui.label( self.controlArea, self, 'Number of records retrieved: /') # Load the most recent emails. self.set_email_list() # Load the most recent queries. self.set_keyword_list() # Check the email and enable controls accordingly. if self.recent_emails: email = self.recent_emails[0] self.email_is_valid = validate_email(email) self.enable_controls()
def __init__(self): super().__init__() #self.contextHandlers = {"": DomainContextHandler("", [ContextField("attributes", selected="node_label_attrs"), ContextField("attributes", selected="tooltipAttributes"), "color"])} self.view = GraphView(self) self.mainArea.layout().addWidget(self.view) self.graph_attrs = [] self.acceptingEnterKeypress = False self.node_label_attrs = [] self.tooltipAttributes = [] self.searchStringTimer = QTimer(self) self.markInputItems = None self.node_color_attr = 0 self.node_size_attr = 0 self.nHighlighted = 0 self.nSelected = 0 self.verticesPerEdge = 0 self.edgesPerVertex = 0 self.lastVertexSizeColumn = '' self.lastColorColumn = '' self.lastLabelColumns = set() self.lastTooltipColumns = set() self.items_matrix = None self.number_of_nodes_label = 0 self.number_of_edges_label = 0 self.graph = None self.setMinimumWidth(600) self.tabs = gui.tabWidget(self.controlArea) self.displayTab = gui.createTabPage(self.tabs, "Display") self.markTab = gui.createTabPage(self.tabs, "Marking") def on_tab_changed(index): self.tabIndex = index self.set_selection_mode() self.tabs.currentChanged.connect(on_tab_changed) self.tabs.setCurrentIndex(self.tabIndex) ib = gui.widgetBox(self.displayTab, "Info") gui.label(ib, self, "Nodes: %(number_of_nodes_label)i (%(verticesPerEdge).2f per edge)") gui.label(ib, self, "Edges: %(number_of_edges_label)i (%(edgesPerVertex).2f per node)") box = gui.widgetBox(self.displayTab, "Nodes") self.relayout_button = gui.button(box, self, 'Re-layout', callback=self.relayout, autoDefault=False) self.view.positionsChanged.connect(lambda _: self.progressbar.advance()) def animationFinished(): self.relayout_button.setEnabled(True) self.progressbar.finish() self.view.animationFinished.connect(animationFinished) self.colorCombo = gui.comboBox( box, self, "node_color_attr", label='Color:', orientation='horizontal', callback=self.set_node_colors) self.invertNodeSizeCheck = self.maxNodeSizeSpin = QWidget() # Forward declaration self.nodeSizeCombo = gui.comboBox( box, self, "node_size_attr", label='Size:', orientation='horizontal', callback=self.set_node_sizes) hb = gui.widgetBox(box, orientation="horizontal") hb.layout().addStretch(1) self.minNodeSizeSpin = gui.spin( hb, self, "minNodeSize", 1, 50, step=1, label="Min:", callback=self.set_node_sizes) self.minNodeSizeSpin.setValue(8) gui.separator(hb) self.maxNodeSizeSpin = gui.spin( hb, self, "maxNodeSize", 10, 200, step=5, label="Max:", callback=self.set_node_sizes) self.maxNodeSizeSpin.setValue(50) gui.separator(hb) self.invertNodeSizeCheck = gui.checkBox( hb, self, "invertNodeSize", "Invert", callback=self.set_node_sizes) hb = gui.widgetBox(self.displayTab, box="Node labels | tooltips", orientation="horizontal", addSpace=False) self.attListBox = gui.listBox( hb, self, "node_label_attrs", "graph_attrs", selectionMode=QListWidget.MultiSelection, sizeHint=QSize(100, 100), callback=self._on_node_label_attrs_changed) self.tooltipListBox = gui.listBox( hb, self, "tooltipAttributes", "graph_attrs", selectionMode=QListWidget.MultiSelection, sizeHint=QSize(100, 100), callback=self._clicked_tooltip_lstbox) eb = gui.widgetBox(self.displayTab, "Edges", orientation="vertical") self.checkbox_relative_edges = gui.checkBox( eb, self, 'relativeEdgeWidths', 'Relative edge widths', callback=self.set_edge_sizes) self.checkbox_show_weights = gui.checkBox( eb, self, 'showEdgeWeights', 'Show edge weights', callback=self.set_edge_labels) ib = gui.widgetBox(self.markTab, "Info", orientation="vertical") gui.label(ib, self, "Nodes: %(number_of_nodes_label)i") gui.label(ib, self, "Selected: %(nSelected)i") gui.label(ib, self, "Highlighted: %(nHighlighted)i") def on_selection_change(): self.nSelected = len(self.view.getSelected()) self.nHighlighted = len(self.view.getHighlighted()) self.set_selection_mode() self.commit() self.view.selectionChanged.connect(on_selection_change) ib = gui.widgetBox(self.markTab, "Highlight nodes ...") ribg = gui.radioButtonsInBox(ib, self, "selectionMode", callback=self.set_selection_mode) gui.appendRadioButton(ribg, "None") gui.appendRadioButton(ribg, "... whose attributes contain:") self.ctrlMarkSearchString = gui.lineEdit(gui.indentedBox(ribg), self, "markSearchString", callback=self._set_search_string_timer, callbackOnType=True) self.searchStringTimer.timeout.connect(self.set_selection_mode) gui.appendRadioButton(ribg, "... neighbours of selected, ≤ N hops away") ib = gui.indentedBox(ribg, orientation=0) self.ctrlMarkDistance = gui.spin(ib, self, "markDistance", 1, 100, 1, label="Hops:", callback=lambda: self.set_selection_mode(SelectionMode.NEIGHBORS)) ib.layout().addStretch(1) gui.appendRadioButton(ribg, "... with at least N connections") gui.appendRadioButton(ribg, "... with at most N connections") ib = gui.indentedBox(ribg, orientation=0) self.ctrlMarkNConnections = gui.spin(ib, self, "markNConnections", 0, 1000000, 1, label="Connections:", callback=lambda: self.set_selection_mode(SelectionMode.AT_MOST_N if self.selectionMode == SelectionMode.AT_MOST_N else SelectionMode.AT_LEAST_N)) ib.layout().addStretch(1) gui.appendRadioButton(ribg, "... with more connections than any neighbor") gui.appendRadioButton(ribg, "... with more connections than average neighbor") gui.appendRadioButton(ribg, "... with most connections") ib = gui.indentedBox(ribg, orientation=0) self.ctrlMarkNumber = gui.spin(ib, self, "markNBest", 1, 1000000, 1, label="Number of nodes:", callback=lambda: self.set_selection_mode(SelectionMode.MOST_CONN)) ib.layout().addStretch(1) self.markInputRadioButton = gui.appendRadioButton(ribg, "... given in the ItemSubset input signal") self.markInput = 0 ib = gui.indentedBox(ribg) self.markInputCombo = gui.comboBox(ib, self, 'markInput', callback=lambda: self.set_selection_mode(SelectionMode.FROM_INPUT)) self.markInputRadioButton.setEnabled(False) gui.auto_commit(ribg, self, 'do_auto_commit', 'Output changes') self.markTab.layout().addStretch(1) self.set_graph(None) self.set_selection_mode()
def __init__(self, parent=None): super().__init__(parent) self.selectedDatabase = 0 self.uniqueRows = True gui.button(gui.widgetBox(self.controlArea, "Cache", addSpace=True), self, "Clear cache", tooltip="Clear saved query results", callback=self.clearCache) self.serviceindex = 0 self.serviceCombo = gui.comboBox( self.controlArea, self, "serviceindex", "Mart Service", callback=self._setServiceUrl ) for name, url in MartServices: self.serviceCombo.addItem(name, userData=url) idx = self.serviceCombo.findData(self.selectedService, Qt.UserRole) self.serviceCombo.setCurrentIndex(idx) # self.selectedService = self.serviceCombo.itemData(self.serviceCombo.currentItem()) self.martsCombo = gui.comboBox( self.controlArea, self, "selectedDatabase", "Database", callback=self.setSelectedMart, addSpace=True) self.martsCombo.setMaximumWidth(250) self.datasetsCombo = gui.comboBox( self.controlArea, self, "selectedDataset", "Dataset", callback=self.setSelectedDataset, addSpace=True) self.datasetsCombo.setMaximumWidth(250) gui.rubber(self.controlArea) box = gui.widgetBox(self.controlArea, "Results") gui.checkBox( box, self, "uniqueRows", "Unique results only", tooltip="Return unique results only.",) self.commitButton = gui.button( box, self, "Get Results", callback=self.commit, tooltip="Query the BioMart server and output the results", autoDefault=True) self.commitButton.setEnabled(False) self.mainWidget = gui.widgetBox( self.mainArea, orientation=QStackedLayout()) self.mainTab = QTabWidget() self.mainWidget.layout().addWidget(self.mainTab) self.attributesConfigurationBox = gui.createTabPage(self.mainTab, "Attributes") if self.SHOW_FILTERS: # ?? self.filtersConfigurationBox = gui.createTabPage(self.mainTab, "Filters") self.error(0) self.setEnabled(False) self._task = None self._executor = concurrent.ThreadExecutor( threadPool=QThreadPool(maxThreadCount=2) ) service = self.selectedService self._task = task = concurrent.Task( function=partial(self._get_registry, url=service)) task.resultReady.connect(self.setBioMartRegistry) task.exceptionReady.connect(self._handleException) self._executor.submit(task) self._setServiceUrl() self._afterInitQueue = [] try: from Bio import SeqIO self.hasBiopython = True except ImportError: self.warning(100, "Biopython package not found.\nTo retrieve FASTA sequence data from BioMart install Biopython.") self.hasBiopython = False
def __init__(self, parent=None): super().__init__(parent) self.selectedDatabase = 0 self.idAttr = 0 self.useAttrNames = False self.uniqueRows = True gui.button( gui.widgetBox(self.controlArea, "Cache", addSpace=True), self, "Clear cache", tooltip="Clear saved query results", callback=self.clearCache, ) self.martsCombo = gui.comboBox( self.controlArea, self, "selectedDatabase", "Database", callback=self.setSelectedMart, addSpace=True ) self.martsCombo.setMaximumWidth(250) self.datasetsCombo = gui.comboBox( self.controlArea, self, "selectedDataset", "Dataset", callback=self.setSelectedDataset, addSpace=True ) self.datasetsCombo.setMaximumWidth(250) box = gui.widgetBox(self.controlArea, "Input Ids") cb = gui.checkBox( box, self, "useAttrNames", "Use attribute names", tooltip="Use attribute names for ids", callback=self.updateInputIds, ) self.idAttrCB = gui.comboBox( box, self, "idAttr", tooltip="Use attribute values from ...", callback=self.updateInputIds ) cb.disables = [(-1, self.idAttrCB)] cb.makeConsistent() self.idText = QPlainTextEdit() self.idText.setReadOnly(True) box.layout().addWidget(self.idText) gui.rubber(self.controlArea) box = gui.widgetBox(self.controlArea, "Results") gui.checkBox(box, self, "uniqueRows", "Unique results only", tooltip="Return unique results only.") self.commitButton = gui.button( box, self, "Get Results", callback=self.commit, tooltip="Query the BioMart server and output the results", autoDefault=True, ) self.commitButton.setEnabled(False) self.mainWidget = gui.widgetBox(self.mainArea, orientation=QStackedLayout()) self.mainTab = QTabWidget() self.mainWidget.layout().addWidget(self.mainTab) self.attributesConfigurationBox = gui.createTabPage(self.mainTab, "Attributes") if self.SHOW_FILTERS: # ?? self.filtersConfigurationBox = gui.createTabPage(self.mainTab, "Filters") self.error(0) self.setEnabled(False) self._executor = concurrent.ThreadExecutor(threadPool=QThreadPool(maxThreadCount=2)) self._task = task = concurrent.Task(function=self._get_registry) task.resultReady.connect(self.setBioMartRegistry) task.exceptionReady.connect(self._handleException) self._executor.submit(task) self.candidateIdAttrs = [] self._afterInitQueue = [] self.data = None try: from Bio import SeqIO self.hasBiopython = True except ImportError: self.warning( 100, "Biopython package not found.\nTo retrieve FASTA sequence data from BioMart install Biopython." ) self.hasBiopython = False
def __init__(self): super().__init__() #self.contextHandlers = {"": DomainContextHandler("", [ContextField("attributes", selected="node_label_attrs"), ContextField("attributes", selected="tooltipAttributes"), "color"])} self.networkCanvas = networkCanvas = OWNxCanvas(self) self.graph_attrs = [] self.edges_attrs = [] self.node_label_attrs = [] self.tooltipAttributes = [] self.edgeLabelAttributes = [] self.autoSendSelection = False self.graphShowGrid = 1 # show gridlines in the graph self.markNConnections = 2 self.markNumber = 0 self.markProportion = 0 self.markSearchString = "" self.markDistance = 2 self.frSteps = 1 self.hubs = 0 self.node_color_attr = 0 self.edgeColor = 0 self.node_size_attr = 0 self.nShown = self.nHidden = self.nHighlighted = self.nSelected = self.verticesPerEdge = self.edgesPerVertex = 0 self.optimizeWhat = 1 self.maxNodeSize = 50 self.labelsOnMarkedOnly = 0 self.invertNodeSize = 0 self.optMethod = 0 self.lastVertexSizeColumn = '' self.lastColorColumn = '' self.lastLabelColumns = set() self.lastTooltipColumns = set() self.showWeights = 0 self.selectedEdgeSchemaIndex = 0 self.items_matrix = None self.showDistances = 0 self.showMissingValues = 0 self.fontSize = 12 self.fontWeight = 1 self.mdsTorgerson = 0 self.mdsAvgLinkage = 1 self.mdsSteps = 10000 self.mdsRefresh = 50 self.mdsStressDelta = 0.0000001 self.showTextMiningInfo = 0 self.toolbarSelection = 0 self.minComponentEdgeWidth = 10 self.maxComponentEdgeWidth = 70 self.mdsFromCurrentPos = 0 self.tabIndex = 0 self.number_of_nodes_label = -1 self.number_of_edges_label = -1 self.opt_from_curr = False self.checkSendMarkedNodes = True self.checkSendSelectedNodes = True self.marked_nodes = [] self._network_view = None self.graph = None self.graph_base = None self.networkCanvas.showMissingValues = self.showMissingValues class ViewBox(pg.ViewBox): def __init__(self): super().__init__() def mouseDragEvent(self, ev): if not ev.isFinish(): return super().mouseDragEvent(ev) if self.state['mouseMode'] != self.RectMode: return # Tap into pg.ViewBox's rbScaleBox ... it'll be fine. self.rbScaleBox.hide() ax = QRectF(pg.Point(ev.buttonDownPos(ev.button())), pg.Point(ev.pos())) ax = self.childGroup.mapRectFromParent(ax) networkCanvas.selectNodesInRect(ax) self.setMouseMode(self.PanMode) ev.accept() def mouseClickEvent(self, ev): if ev.button() == Qt.LeftButton: if networkCanvas.is_animating: networkCanvas.is_animating = False ev.accept() else: networkCanvas.mouseClickEvent(ev) super().mouseClickEvent(ev) class PlotItem(pg.PlotItem): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) for axis in ('bottom', 'left'): self.hideAxis(axis) def _path(filename): return os.path.join(os.path.dirname(__file__), 'icons', filename + '.png') self.rectBtn = pg.ButtonItem(_path('button_rect'), parentItem=self) self.rectBtn.clicked.connect(self.rectBtnClicked) self._qtBaseClass.setParentItem(self.autoBtn, None) self.autoBtn.hide() self.autoBtn = pg.ButtonItem(_path('button_autoscale'), parentItem=self) self.autoBtn.mode = 'auto' self.autoBtn.clicked.connect(self.autoBtnClicked) self.textEnterToSelect = pg.TextItem( html='<div style="background-color:#f0f0f0; padding:5px;">' '<font color="#444444"><b>Press <tt>Enter</tt> to add ' '<i><font color="{}">highlighted</font></i> nodes to ' '<i><font color="{}">selection</font></i> ...</font></b></div>' .format(NodePenColor.HIGHLIGHTED, NodePenColor.SELECTED)) self.textEnterToSelect.setParentItem(self) self.textEnterToSelect.hide() def rectBtnClicked(self, ev): self.vb.setMouseMode(self.vb.RectMode) def updateButtons(self): self.autoBtn.show() def resizeEvent(self, ev): super().resizeEvent(ev) btnRect = self.mapRectFromItem(self.rectBtn, self.rectBtn.boundingRect()) LEFT_OFFSET, BOTTOM_OFFSET = 3, 5 y = self.size().height() - btnRect.height() - BOTTOM_OFFSET self.autoBtn.setPos(LEFT_OFFSET, y) self.rectBtn.setPos(2*LEFT_OFFSET + btnRect.width(), y) self.textEnterToSelect.setPos(LEFT_OFFSET, BOTTOM_OFFSET) class PlotWidget(pg.PlotWidget): def __init__(self, *args, **kwargs): pg.GraphicsView.__init__(self, *args, **kwargs) plot = PlotWidget(self, background='w') plot.plotItem = PlotItem(enableAutoRange=True, viewBox=ViewBox()) plot.setCentralItem(plot.plotItem) # Required, copied from pg.PlotWidget constructor for m in ['addItem', 'removeItem', 'autoRange', 'clear', 'setXRange', 'setYRange', 'setRange', 'setAspectLocked', 'setMouseEnabled', 'setXLink', 'setYLink', 'enableAutoRange', 'disableAutoRange', 'setLimits', 'register', 'unregister', 'viewRect']: setattr(plot, m, getattr(plot.plotItem, m)) plot.plotItem.sigRangeChanged.connect(plot.viewRangeChanged) self.textEnterToSelect = plot.plotItem.textEnterToSelect plot.setFrameStyle(QFrame.StyledPanel) plot.setMinimumSize(500, 500) plot.setAspectLocked(True) plot.addItem(self.networkCanvas) self.mainArea.layout().addWidget(plot) self.tabs = gui.tabWidget(self.controlArea) self.displayTab = gui.createTabPage(self.tabs, "Display") self.markTab = gui.createTabPage(self.tabs, "Marking") def showTextOnMarkingTab(index): if self.tabs.widget(index) == self.markTab: self.set_mark_mode() else: self.acceptingEnterKeypress = False self.tabs.currentChanged.connect(showTextOnMarkingTab) self.tabs.setCurrentIndex(self.tabIndex) self.connect(self.tabs, SIGNAL("currentChanged(int)"), lambda index: setattr(self, 'tabIndex', index)) ib = gui.widgetBox(self.displayTab, "Info") gui.label(ib, self, "Nodes: %(number_of_nodes_label)i (%(verticesPerEdge).2f per edge)") gui.label(ib, self, "Edges: %(number_of_edges_label)i (%(edgesPerVertex).2f per node)") box = gui.widgetBox(self.displayTab, "Nodes") self.optCombo = gui.comboBox( box, self, "optMethod", label='Layout:', orientation='horizontal', callback=self.graph_layout_method) for layout in Layout.all: self.optCombo.addItem(layout) self.optMethod = Layout.all.index(Layout.FHR) self.optCombo.setCurrentIndex(self.optMethod) self.colorCombo = gui.comboBox( box, self, "node_color_attr", label='Color by:', orientation='horizontal', callback=self.set_node_colors) hb = gui.widgetBox(box, orientation="horizontal", addSpace=False) hb.layout().addWidget(QLabel('Size by:', hb)) self.nodeSizeCombo = gui.comboBox( hb, self, "node_size_attr", callback=self.set_node_sizes) self.maxNodeSizeSpin = gui.spin( hb, self, "maxNodeSize", 5, 200, step=10, label="Max:", callback=self.set_node_sizes) self.maxNodeSizeSpin.setValue(50) self.invertNodeSizeCheck = gui.checkBox( hb, self, "invertNodeSize", "Invert", callback=self.set_node_sizes) lb = gui.widgetBox(box, "Node labels | tooltips", orientation="vertical", addSpace=False) hb = gui.widgetBox(lb, orientation="horizontal", addSpace=False) self.attListBox = gui.listBox( hb, self, "node_label_attrs", "graph_attrs", selectionMode=QListWidget.MultiSelection, callback=self._on_node_label_attrs_changed) self.tooltipListBox = gui.listBox( hb, self, "tooltipAttributes", "graph_attrs", selectionMode=QListWidget.MultiSelection, callback=self._clicked_tooltip_lstbox) eb = gui.widgetBox(self.displayTab, "Edges", orientation="vertical") self.checkbox_relative_edges = gui.checkBox( eb, self, 'networkCanvas.relative_edge_widths', 'Relative edge widths', callback=self.networkCanvas.set_edge_sizes) self.checkbox_show_weights = gui.checkBox( eb, self, 'networkCanvas.show_edge_weights', 'Show edge weights', callback=self.networkCanvas.set_edge_labels) self.edgeColorCombo = gui.comboBox( eb, self, "edgeColor", label='Color by:', orientation='horizontal', callback=self.set_edge_colors) elb = gui.widgetBox(eb, "Edge labels", addSpace=False) self.edgeLabelListBox = gui.listBox( elb, self, "edgeLabelAttributes", "edges_attrs", selectionMode=QListWidget.MultiSelection, callback=self._clicked_edge_label_listbox) elb.setEnabled(False) ib = gui.widgetBox(self.markTab, "Info", orientation="vertical") gui.label(ib, self, "Nodes: %(number_of_nodes_label)i") gui.label(ib, self, "Selected: %(nSelected)i") gui.label(ib, self, "Highlighted: %(nHighlighted)i") ib = gui.widgetBox(self.markTab, "Highlight nodes ...") ribg = gui.radioButtonsInBox(ib, self, "hubs", [], "Mark", callback=self.set_mark_mode) gui.appendRadioButton(ribg, "None") gui.appendRadioButton(ribg, "... whose attributes contain:") self.ctrlMarkSearchString = gui.lineEdit(gui.indentedBox(ribg), self, "markSearchString", callback=self._set_search_string_timer, callbackOnType=True) self.searchStringTimer = QTimer(self) self.connect(self.searchStringTimer, SIGNAL("timeout()"), self.set_mark_mode) gui.appendRadioButton(ribg, "... neighbours of selected, ≤ N hops away") ib = gui.indentedBox(ribg, orientation=0) self.ctrlMarkDistance = gui.spin(ib, self, "markDistance", 1, 100, 1, label="Distance:", callback=lambda: self.set_mark_mode(SelectionMode.NEIGHBORS)) #self.ctrlMarkFreeze = gui.button(ib, self, "&Freeze", value="graph.freezeNeighbours", toggleButton = True) gui.appendRadioButton(ribg, "... with at least N connections") gui.appendRadioButton(ribg, "... with at most N connections") self.ctrlMarkNConnections = gui.spin(gui.indentedBox(ribg), self, "markNConnections", 0, 1000000, 1, label="N:", callback=lambda: self.set_mark_mode(SelectionMode.AT_MOST_N if self.hubs == SelectionMode.AT_MOST_N else SelectionMode.AT_LEAST_N)) gui.appendRadioButton(ribg, "... with more connections than any neighbor") gui.appendRadioButton(ribg, "... with more connections than average neighbor") gui.appendRadioButton(ribg, "... with most connections") ib = gui.indentedBox(ribg) #~ self.ctrlMarkNumber = gui.spin(ib, self, "markNumber", 1, 1000000, 1, label="Number of nodes:", callback=(lambda h=7: self.set_mark_mode(h))) self.ctrlMarkNumber = gui.spin(ib, self, "markNumber", 1, 1000000, 1, label="Number of nodes:", callback=lambda: self.set_mark_mode(SelectionMode.MOST_CONN)) gui.auto_commit(ribg, self, 'do_auto_commit', 'Output changes') #ib = gui.widgetBox(self.markTab, "General", orientation="vertical") #self.checkSendMarkedNodes = True self.toolbar = gui.widgetBox(self.controlArea, orientation='horizontal') #~ G = self.networkCanvas.gui #~ self.zoomSelectToolbar = G.zoom_select_toolbar(self.toolbar, nomargin=True, buttons= #~ G.default_zoom_select_buttons + #~ [ #~ G.Spacing, #~ ("buttonM2S", "Marked to selection", None, None, "marked_to_selected", 'Dlg_Mark2Sel'), #~ ("buttonS2M", "Selection to marked", None, None, "selected_to_marked", 'Dlg_Sel2Mark'), #~ ("buttonHSEL", "Hide selection", None, None, "hide_selection", 'Dlg_HideSelection'), #~ ("buttonSSEL", "Show all nodes", None, None, "show_selection", 'Dlg_ShowSelection'), #~ #("buttonUN", "Hide unselected", None, None, "hideUnSelectedVertices", 'Dlg_SelectedNodes'), #~ #("buttonSW", "Show all nodes", None, None, "showAllVertices", 'Dlg_clear'), #~ ]) #~ self.zoomSelectToolbar.buttons[G.SendSelection].clicked.connect(self.send_data) #~ self.zoomSelectToolbar.buttons[G.SendSelection].clicked.connect(self.send_marked_nodes) #~ self.zoomSelectToolbar.buttons[("buttonHSEL", "Hide selection", None, None, "hide_selection", 'Dlg_HideSelection')].clicked.connect(self.hide_selection) #~ self.zoomSelectToolbar.buttons[("buttonSSEL", "Show all nodes", None, None, "show_selection", 'Dlg_ShowSelection')].clicked.connect(self.show_selection) #self.zoomSelectToolbar.buttons[G.SendSelection].hide() self.set_mark_mode() self.displayTab.layout().addStretch(1) self.markTab.layout().addStretch(1) self.graph_layout_method() self.set_graph(None) self.setMinimumWidth(900)