def create_alignments(algorithm: alignment_algorithms.Algorithm, component: Optional[List[Component]] = None) -> EChanges: """ Aligns the component. If no component is specified, aligns all components. Requisites: `create_minor` and FASTA data. :param algorithm: Algorithm to use. See `algorithm_help`. :param component: Component to align, or `None` for all. """ model = global_view.current_model() if not all(x.site_array for x in model.genes): raise ValueError( "Refusing to make alignments because there is no site data. Did you mean to load the site data (FASTA) first?" ) to_do = cli_view_utils.get_component_list(component) before = sum(x.alignment is not None for x in model.components) for component_ in pr.pr_iterate(to_do, "Aligning"): fasta = component_.get_unaligned_legacy_fasta() component_.alignment = external_runner.run_in_temporary( algorithm, component_.model, fasta) after = sum(x.alignment is not None for x in model.components) pr.printx( "<verbose>{} components aligned. {} of {} components have an alignment ({}).</verbose>" .format(len(to_do), after, len(model.components), string_helper.as_delta(after - before))) return EChanges.COMP_DATA
def file_save( file_name: isOptional[isFilename[EFileMode.WRITE, constants.EXT_MODEL]] = None ) -> EChanges: """ Saves the model :param file_name: Filename. File to load. Either specify a complete path, or the name of the file in the `sessions` folder. If not specified the current filename is used. :return: """ model = global_view.current_model() if file_name: file_name = __fix_path(file_name) else: file_name = model.file_name if not file_name: raise ValueError( "Cannot save because a filename has not been specified.") config.remember_file(file_name) sys.setrecursionlimit(10000) with pr.pr_action("Saving file to «{}»".format(file_name)): model.file_name = file_name io_helper.save_binary(file_name, model) model.file_name = file_name pr.printx("<verbose>Saved model to <file>{}</file></verbose>", file_name) return EChanges.FILE_NAME
def create_fusions() -> EChanges: """ Finds the fusion points in the model. i.e. Given the events (see `find_events`), find the exact points at which the fusion(s) occur. Requisites: `create_trees` """ model = global_view.current_model() model.get_status(constants.STAGES.FUSIONS_9).assert_create() r: List[Fusion] = [] for event in __find_fusion_events(model): __LOG("Processing fusion event: {}", event) event.points = [] for component in model.components: __find_fusion_points(event, component) r.append(event) model.fusions = FusionCollection(r) n = len(model.fusions) pr.printx("<verbose>{} {} detected</verbose>".format( n, "fusion" if n == 1 else "fusions")) return EChanges.MODEL_DATA
def on_convert_from_text(self, text: str) -> object: model = global_view.current_model() for graph in model.iter_graphs(): if graph.name == text: return graph return None
def on_executed(self, args: intermake.Result): super().on_executed(args) from groot import global_view model = global_view.current_model() if model: model.command_history.append("{}".format(args))
def print_genes(find: Optional[str] = None, targets: Optional[List[IHasFasta]] = None) -> EChanges: """ List sequences or presents their FASTA data. If no parameters are specified the accessions of all current sequences are listed. :param targets: Object(s) to present. If specified FASTA data for these objects are listed. :param find: Regular expression. If specified sequences with matching accessions will be listed. """ if find is None and targets is None: find = ".*" if find is not None: model = global_view.current_model() genes = [] rx = re.compile(find, re.IGNORECASE) for s in model.genes: if rx.search(s.accession): genes.append(s) if not genes: print("No matching genes.") else: for gene in genes: print(gene) print("Found {} genes.".format(len(genes))) return EChanges.INFORMATION elif targets is not None: for target in targets: if isinstance(target, IHasFasta): print( cli_view_utils.colour_fasta_ansi( target.to_fasta(), global_view.current_model().site_type)) else: warnings.warn( "Target «{}» does not have FASTA data.".format(target), UserWarning) return EChanges.INFORMATION
def update_buttons( self ): if self.data_warn: status = global_view.current_model().get_status( constants.STAGES.SEQ_AND_SIM_ps ) for button in self.__controls: button.setEnabled( status.is_none ) self.ui.BTN_BROWSE.setEnabled( status.is_none ) self.ui.LBL_HAS_DATA_WARNING.setVisible( status.is_partial )
def drop_checked(): """ Removes the check-NRFG report from the model. """ model = global_view.current_model() model.get_status(constants.STAGES.CHECKED_17).assert_drop() model.report = None return EChanges.MODEL_DATA
def drop_cleaned(): """ Removes data from the model. """ model = global_view.current_model() model.get_status(STAGES.CLEAN_16).assert_drop() model.fusion_graph_clean = None return EChanges.MODEL_DATA
def print_outgroups(): """ Prints the outgroups. """ model = global_view.current_model() for gene in model.genes: if gene.position != EPosition.NONE: print( str( gene ) )
def drop_genes(genes: List[Gene]) -> EChanges: """ Removes one or more sequences from the model. It is safe to use this function up to and including the `create_major` stage. References to this gene(s) will be removed from any extant edges or components. :param genes: One or more genes to drop. """ # Get the model model = global_view.current_model() # Delete the previous MAJOR components has_major = model.get_status(STAGES.MAJOR_4) if has_major: from . import s040_major old_comps: List[Set[Gene]] = list( set(component.major_genes) for component in model.components) s040_major.drop_major(None) # = drop all! else: old_comps = None # Drop the edges to_drop = set() for edge in model.edges: if edge.left.gene in genes or edge.right.gene in genes: to_drop.add(edge) from . import s030_similarity s030_similarity.drop_similarities(list(to_drop)) # Assert the drop (this should pass now we have removed the components and edges!) model.get_status(STAGES.SEQUENCES_2).assert_drop() # Drop the genes for gene in genes: assert isinstance(gene, Gene), gene gene.display_name = "DROPPED" gene.model.genes.remove(gene) # Create new components if has_major: for comp in old_comps: for gene in genes: if gene in comp: comp.remove(gene) if comp: from . import s040_major s040_major.set_major(list(comp)) return EChanges.MODEL_ENTITIES
def drop_subsets(): """ Removes data from the model. """ model = global_view.current_model() model.get_status( STAGES.SUBSETS_12 ).assert_drop() model.subsets = frozenset() return EChanges.COMP_DATA
def drop_consensus(): """ Removes data from the model. """ model = global_view.current_model() model.get_status(STAGES.CONSENSUS_11).assert_drop() model.consensus = frozenset() return EChanges.COMP_DATA
def __init__( self ) -> None: """ CONSTRUCTOR """ # QT stuff FrmMain.INSTANCE = self QCoreApplication.setAttribute( Qt.AA_DontUseNativeMenuBar ) QMainWindow.__init__( self ) self.ui = frm_main_designer.Ui_MainWindow() self.ui.setupUi( self ) self.setWindowTitle( "Lego Model Creator" ) controller : intermake_qt.GuiController = cast(intermake_qt.GuiController, Controller.ACTIVE) self.mdi: Dict[str, FrmBase] = { } self.COLOUR_EMPTY = QColor( controller.style_sheet_parsed.get( 'QMdiArea[style="empty"].background', "#E0E0E0" ) ) self.COLOUR_NOT_EMPTY = QColor( controller.style_sheet_parsed.get( 'QMdiArea.background', "#E0E0E0" ) ) self.ui.MDI_AREA.setBackground( self.COLOUR_EMPTY ) self.showMaximized() global_options = groot.data.config.options() self.mdi_mode = global_options.window_mode != EWindowMode.BASIC self.ui.FRA_FILE.setVisible( global_options.tool_file ) self.ui.FRA_VISUALISERS.setVisible( global_options.tool_visualisers ) self.ui.FRA_WORKFLOW.setVisible( global_options.tool_workflow ) if global_options.window_mode == EWindowMode.TDI: self.ui.MDI_AREA.setViewMode( QMdiArea.TabbedView ) self.ui.MDI_AREA.setDocumentMode( True ) from groot_gui.utilities.gui_menu import GuiMenu self.menu_handler = GuiMenu( self ) self.actions = self.menu_handler.gui_actions view = groot.data.config.options().startup_mode if global_view.current_model().get_status( constants.STAGES.SEQ_AND_SIM_ps ).is_none: if view == EStartupMode.STARTUP: handlers().VIEW_STARTUP.execute( self, EIntent.DIRECT, None ) elif view == EStartupMode.WORKFLOW: handlers().VIEW_WORKFLOW.execute( self, EIntent.DIRECT, None ) elif view == EStartupMode.SAMPLES: handlers().VIEW_OPEN_FILE.execute( self, EIntent.DIRECT, None ) elif view == EStartupMode.NOTHING: pass else: raise mh.SwitchError( "view", view ) self.completed_changes = None self.completed_plugin = None self.update_title() self.menu_handler.update_buttons()
def print_domains(algorithm: domain_algorithms.Algorithm) -> EChanges: """ Prints the genes (highlighting components). Note: Use :func:`print_fasta` or :func:`print_alignments` to show the actual sites. :param algorithm: How to break up the sequences. See `algorithm_help`. """ assert isinstance(algorithm, domain_algorithms.Algorithm), algorithm model = global_view.current_model() longest = max(x.length for x in model.genes) r = [] for sequence in model.genes: minor_components = model.components.find_components_for_minor_gene( sequence) if not minor_components: minor_components = [None] for component_index, component in enumerate(minor_components): if component_index == 0: r.append(sequence.accession.ljust(20)) else: r.append("".ljust(20)) if component: r.append(cli_view_utils.component_to_ansi(component) + " ") else: r.append("Ø ") subsequences = __list_userdomains(sequence, algorithm) for subsequence in subsequences: components = model.components.find_components_for_minor_domain( subsequence) if component in components: colour = cli_view_utils.component_to_ansi_back(component) else: colour = ansi.BACK_LIGHT_BLACK size = max(1, int((subsequence.length / longest) * 80)) name = "{}-{}".format(subsequence.start, subsequence.end) r.append(colour + ansi.DIM + ansi.FORE_BLACK + "▏" + ansi.NORMAL + string_helper.centre_align(name, size)) r.append("\n") r.append("\n") print("".join(r)) return EChanges.INFORMATION
def print_subsets() -> EChanges: """ Prints NRFG subsets. """ model = global_view.current_model() for x in sorted( model.subsets, key = cast( Any, str ) ): assert isinstance( x, Subset ) print( "{} - {} elements: {}".format( x, len( x ), string_helper.format_array( x.contents, sort = True, autorange = True ) ) ) return EChanges.INFORMATION
def get_component_list(component: Optional[List[Component]]): if component is not None: to_do = component else: to_do = global_view.current_model().components if not to_do: raise ValueError( "No components available, consider running `create_major`.") return to_do
def drop_minor() -> EChanges: """ Drops minor component information from model. """ model = global_view.current_model() model.get_status(STAGES.MINOR_5).assert_drop() for comp in model.components: comp.minor_domains = None return EChanges.COMPONENTS
def export_json( file_name: isFilename[EFileMode.WRITE, constants.EXT_JSON]) -> EChanges: """ Exports the entirety of the current model into a JSON file for reading by external programs. :param file_name: Name of file to export to. """ model = global_view.current_model() io_helper.save_json(file_name, model) return EChanges.NONE
def name(self) -> str: from groot.data import global_view if self is not global_view.current_model(): return "Not the current model" if self.file_name: return FileHelper.get_filename_without_extension(self.file_name) elif self.genes: return "Unsaved model" else: return "Empty model"
def print_consensus() -> EChanges: """ Prints NRFG viable splits. """ model = global_view.current_model() for x in model.consensus: print(str(x)) return EChanges.INFORMATION
def drop_supertrees() -> EChanges: """ Removes data from the model. """ model = global_view.current_model() model.get_status(STAGES.SUPERTREES_14).assert_drop() model.subgraphs = tuple() model.subgraphs_destinations = tuple() model.subgraphs_sources = tuple() return EChanges.MODEL_DATA
def create_comparison(left: INamedGraph, right: INamedGraph) -> EChanges: """ Compares two graphs. The resulting report is added to the current model's user reports. :param left: First graph. The calculated or "new" data. :param right: Second graph. The original or "existing" data. """ model = global_view.current_model() model.user_reports.append(compare_graphs(left, right)) return EChanges.INFORMATION
def __fn6_make_trees(self): with self.__start_line(STAGES.TREES_8): model = global_view.current_model() ogs = [model.genes[x] for x in self.outgroups] self.__result |= workflow.s055_outgroups.set_outgroups(ogs) algo = workflow.s080_tree.tree_algorithms.get_algorithm(self.tree) self.__result |= workflow.s080_tree.create_trees(algo) if STAGES.TREES_8 in self.pauses: self.__pause(STAGES.TREES_8, (workflow.s080_tree.print_trees, ))
def drop_pregraphs(): """ Removes data from the model. """ model = global_view.current_model() model.get_status(STAGES.PREGRAPHS_13).assert_drop() for subset in model.subsets: assert isinstance(subset, Subset) subset.pregraphs = None return EChanges.COMP_DATA
def set_similarity(left: Domain, right: Domain) -> EChanges: """ Adds a new edge to the model. :param left: Subsequence to create the edge from :param right: Subsequence to create the edge to """ model: Model = global_view.current_model() model.get_status(STAGES.SIMILARITIES_3).assert_set() edge = Edge(left, right) left.gene.model.edges.add(edge) return EChanges.MODEL_ENTITIES
def drop_graph(graph: INamedGraph): """ Removes a graph created with `import_graph`. :param graph: Graph to remove. See `format_help`. """ model = global_view.current_model() if not isinstance(graph, FixedUserGraph): raise ValueError( "The specified graph is not a user-graph and cannot be removed. Please specify an _existing_ user-graph." ) model.user_graphs.remove(graph)
def create_supertrees(algorithm: supertree_algorithms.Algorithm) -> None: """ Creates the supertrees/subgraphs for the model. Requisites: `create_pregraphs` :param algorithm: Algorithm to use, see `algorithm_help`. :return: Nothing is returned, the state is saved into the model. """ # Check we're ready to go model = global_view.current_model() model.get_status(STAGES.SUPERTREES_14).assert_create() # Create the subgraphs subgraphs = [] for subset in model.subsets: subgraph = __create_supertree(algorithm, subset) subgraphs.append((subset, subgraph)) # Collect the sources and destinations destinations = set() sources = set() for subset, subgraph in subgraphs: sequences = lego_graph.get_sequence_data(subgraph) ffn = lego_graph.get_fusion_formation_nodes(subgraph) if not ffn: raise ValueError( "The subgraph («{}») of the subset «{}» («{}») doesn't appear to have any fusion point nodes. Refusing to continue because this means the subgraph's position in the NRFG is unavailable." .format(string_helper.format_array(subgraph.nodes), subset, string_helper.format_array(subset.contents))) for node in ffn: # type:MNode formation: Formation = node.data if any(x in sequences for x in formation.pertinent_inner): destinations.add(node.uid) else: sources.add(node.uid) model.subgraphs_destinations = tuple(destinations) model.subgraphs_sources = tuple(sources) model.subgraphs = tuple( Subgraph(subgraph, subset, repr(algorithm)) for subset, subgraph in subgraphs) return EChanges.MODEL_DATA
def drop_splits(): """ Removes data from the model. """ model: Model = global_view.current_model() model.get_status(STAGES.SPLITS_10).assert_drop() model.splits = frozenset() for component in model.components: component.splits = None component.leaves = None return EChanges.COMP_DATA
def print_pregraphs() -> EChanges: """ Prints the names of the NRFG subgraphs. Note: you'll need to use `print_trees` to print the actual trees. """ model = global_view.current_model() for subgraph in model.iter_pregraphs(): print("{} = {}".format(str(subgraph), lego_graph.export_newick(subgraph.graph))) else: print("The current model has no subgraphs.") return EChanges.INFORMATION