def launch_from_gui(self): if len(self.target_sequences) == 0: self.pymod.main_window.show_error_message( "PSIPRED Error", "Please select at least one sequence to be analyzed with PSIPRED." ) return False if not self.check_psipred_parameters(): return False # Run psipred on all the selected sequences. self.predicted_sequences = [] if not self.pymod.use_protocol_threads: self.predict_all_sequences() else: label_text = ( "Running psipred on %s. Please wait for the process to" " complete..." % self.get_seq_text(self.target_sequences)) p_dialog = Protocol_exec_dialog( app=self.pymod.main_window, pymod=self.pymod, function=self.predict_all_sequences, args=(), title="Running psipred", label_text=label_text) p_dialog.exec_() # Colors the sequences by predicted secondary structure. for sequence in self.predicted_sequences: sequence.predicted_secondary_structure = True self.pymod.main_window.color_element_by_pred_sec_str( sequence, color_structure=True)
def run_ncbiblast(self): """ This function allows to contact the NCBI BLAST server using Biopython. """ # Actually connects to the server. query_seq = str(self.blast_query_element.my_sequence.replace("-", "")) args = { "query_seq": query_seq, "ncbiblast_database": self.ncbiblast_database, "hitlist_size": self.max_hsp_num, "expect": self.evalue_cutoff } if not self.pymod.use_protocol_threads: self.launch_qblast(**args) else: label_text = "Connecting to the BLAST NCBI server. Please wait for the process to complete..." p_dialog = Protocol_exec_dialog(app=self.pymod.main_window, pymod=self.pymod, function=self.launch_qblast, args=args, title="Running NCBI BLAST", label_text=label_text) p_dialog.exec_() # In this way the results window can be opened. return True
def fetch_pdb_files(self): """ This method will call other methods to tetch the PDB files and load the corresponding elements in PyMod. """ # List which will store information for each downloaded file. self.fetch_results_list = [] try: if not self.pymod.use_protocol_threads: self.download_all_pdb_files() else: label_text = ( "Connecting to the PDB to download %s. Please wait for" " completion..." % self.get_seq_text(self.structures_to_fetch, "PDB file")) p_dialog = Protocol_exec_dialog( app=self.pymod.main_window, pymod=self.pymod, function=self.download_all_pdb_files, args=(), title="Downloading PDB files", wait_start=0.15, wait_end=0.15, label_text=label_text) p_dialog.exec_() except PyModInterruptedProtocol: return None # Warns the user if some structure files could not be fetched. n_failures = len([r for r in self.fetch_results_list if r["failure"]]) if n_failures != 0: title = "Connection Error" message = ( "Can not access the PDB database to download %s structures out of %s." "\nPlease check your Internet connection or if the PDB ids of the" " structures are valid." % (n_failures, len(self.structures_to_fetch))) self.pymod.main_window.show_warning_message(title, message) if n_failures == 0: return None # Actually loads the elements in PyMod. for fetch_results in self.fetch_results_list: if not fetch_results["failure"]: try: self._load_structure(fetch_results) except Exception as e: title = "Associate Structure Failure" message = ( "The structure association for %s chain %s failed because" " of the following error: %s" % (fetch_results["pdb_code"], fetch_results["pdb_chain_id"], str(e))) self.pymod.main_window.show_error_message(title, message) self.pymod.main_window.gridder(clear_selection=True, update_elements=True, update_clusters=True)
def alignment_state(self): """ This method is called either by the "start_alignment()" method or when the 'SUBMIT' button in some alignment window is pressed. It will first define the alignment mode according to the choices made by the user. Then, depending on the alignment strategy and the alignment mode, it will execute all the steps necessary to perform the alignment. """ # Gets the parameters from the GUI in order to chose the kind of alignment to perform. self.define_alignment_mode() if not self.get_options_from_gui(): return None try: self.alignment_window.destroy() except: pass # This list is going to be used inside in other methods of this class needed to perform the # alignment. self.elements_to_align = [] self.elements_to_align_dict = {} self.protocol_output_file_name = None #----------------------------------- # Actually performs the alignment. - #----------------------------------- if not self.pymod.use_protocol_threads: self.perform_alignment_protocol() else: label_text = ("Running %s. Please wait for the process to" " complete..." % pymod_vars.algs_full_names_dict[self.protocol_name]) lock_dialog = self.protocol_name.startswith("salign") # A MODELLER thread can no be exited safely. p_dialog = Protocol_exec_dialog(app=self.pymod.main_window, pymod=self.pymod, function=self.perform_alignment_protocol, args=(), wait_start=0.4, wait_end=0.4, lock=lock_dialog, stdout_silence=lock_dialog, title="Running %s" % pymod_vars.algs_full_names_dict[self.protocol_name], label_text=label_text) p_dialog.exec_() #---------------------------------------------------------------------- # Updates the PyMod elements just aligned and completes the protocol. - #---------------------------------------------------------------------- self.create_alignment_element() self.update_aligned_elements() self.finish_alignment() self.show_additional_alignment_output()
def run_psiblast(self): """ Launches a standalone version of BLAST installed locally when using the BLAST option in the plugin main menu. """ # Builds a temporary file with the sequence of the query needed by psiblast. query_file_name = "query" self.pymod.build_sequence_file([self.blast_query_element], query_file_name, file_format="fasta", remove_indels=True, new_directory=self.output_directory) # Sets some parameters in needed to run PSI-BLAST. ncbi_dir = self.pymod.blast_plus["exe_dir_path"].get_value() args = { "ncbi_dir": ncbi_dir, "db_path": self.db_path, "query": os.path.join(self.output_directory, query_file_name + ".fasta"), "inclusion_ethresh": None, "outfmt": 5, "out": os.path.join(self.output_directory, self.xml_blast_output_file_name), "num_iterations": None, "evalue": self.evalue_cutoff, "max_target_seqs": self.max_hsp_num, "blast_version": "blastp" } if not self.pymod.use_protocol_threads: self.execute_psiblast(**args) else: label_text = "Running BLASTp. Please wait for the process to complete..." p_dialog = Protocol_exec_dialog(app=self.pymod.main_window, pymod=self.pymod, function=self.execute_psiblast, args=args, title="Running BLASTp", label_text=label_text) p_dialog.exec_() # If everything went ok, return 'True', so that the results window can be opened. return True
def contact_map_analysis_state(self): #------------------------------------ # Gets the parameters from the GUI. - #------------------------------------ input_error = self.validate_input() if input_error is not None: self.pymod.main_window.show_error_message("Input Error", input_error) return None self.contact_map_options_window.destroy() #------------------------------------- # Actually computes the contact map. - #------------------------------------- # Assign function to fill the target map. if self.feature_type == "contact": self.get_map_pixel = self._get_contact_val elif self.feature_type == "distance": self.get_map_pixel = self._get_distance_val elif self.feature_type == "distances_difference": self.get_map_pixel = self._get_distances_difference_val elif self.feature_type == "distances_mean": self.get_map_pixel = self._get_distances_mean elif self.feature_type == "distances_std": self.get_map_pixel = self._get_distances_std else: raise KeyError(self.feature_type) if not self.pymod.use_protocol_threads: self.compute_target_map() else: label_text = ( "Computing %s map on %s. Please wait for the process to" " complete..." % (self.feature_type_full_name, self.get_seq_text(self.target_sequences))) p_dialog = Protocol_exec_dialog(app=self.pymod.main_window, pymod=self.pymod, function=self.compute_target_map, args=(), lock=True, wait_start=0.25, wait_end=0.25, title="Computing %s map" % self.feature_type_full_name, label_text=label_text) p_dialog.exec_() #------------------------ # Show the contact map. - #------------------------ # Gets the title of the window. if self.feature_type in ("contact", "distance"): title = "%s %s Map." % (self.target_sequence.my_header, self.feature_type_full_name[0:-1]) elif self.feature_type == "distances_difference": title = "Distances Difference Map." elif self.feature_type == "distances_mean": title = "Distances Mean Map." elif self.feature_type == "distances_std": title = "Distances Std Map." # Initializes the contact/distance map window. cp = Contact_map_analysis_window_qt(self.pymod.main_window) cp.initialize_map(pymod=self.pymod, data_array=self.target_map, pymod_elements=self.target_sequences, ref_residues=self.ref_residues, ref_selectors=self.ref_selectors, title=title, pixel_size=self.pixel_size, feature_type=self.feature_type, threshold=self.dist_threshold, interaction_center=self.interaction_center) cp.show()
def import_results_in_pymod(self): """ Builds a list containing those hits that were selected by the user in the BLAST results window. """ if not check_network_connection("https://google.com", timeout=3): has_network = False else: has_network = True #------------------------------------------ # Get the templates selected by the user. - #------------------------------------------ self.imported_hsp_list = [] for hsp_counter, hsp in enumerate(self.hhr_results): if self.my_blast_map[hsp_counter]: template_id = hsp.template_id hsp_dict = { "hsp": hsp, "pdb_code": None, "chain_id": None, "hsp_num": str(hsp_counter + 1), "successful": False } if re.match("([a-zA-Z0-9]{4})_([A-Za-z])$", template_id): pdb_code, chain_id = template_id.split("_") hsp_dict["pdb_code"] = pdb_code hsp_dict["chain_id"] = chain_id self.imported_hsp_list.append(hsp_dict) # Check if the CIF files of the hits can be fetched from the PDB. pdb_hsp_list = [ h for h in self.imported_hsp_list if h["pdb_code"] is not None ] if len(pdb_hsp_list) == len(self.imported_hsp_list): if has_network: message = ("Would you like to fetch from the Internet the 3D" " structures of the templates that you selected?") fetch_cif_files = askyesno_qt( "Fetch 3D structures?", message, parent=self.pymod.get_qt_parent()) else: message = ( "No network connection. The template 3D structures can" " not be fetched now from the Internet.") self.pymod.main_window.show_warning_message( self.import_error_message, message) fetch_cif_files = False elif len(pdb_hsp_list) == 0: fetch_cif_files = False else: if has_network: n_pdb_missing = len(self.imported_hsp_list) - len(pdb_hsp_list) message = ( "You selected {} (out of {}) hit sequences which do not appear" " to be valid templates from the PDB. No 3D structure" " will be fetched now. You can fetch the PDB structures" " of each hit sequence having a valid PDB id later at any" " moment".format(n_pdb_missing, len(self.imported_hsp_list))) self.pymod.main_window.show_warning_message( self.import_error_message, message) fetch_cif_files = False #-------------------------------------- # Prepare the input and output files. - #-------------------------------------- # Prepare the templates input CIF directory. This will be needed by the # 'hhmakemodel.py' script. self.tem_in_dirpath = os.path.join(self.output_directory, "hhsuite_tem_input") if os.path.isdir(self.tem_in_dirpath): shutil.rmtree(self.tem_in_dirpath) os.mkdir(self.tem_in_dirpath) # Prepare the templates output CIF directory. This will be needed by the # 'hhmakemodel.py' script. self.tem_out_dirpath = os.path.join(self.output_directory, "hhsuite_tem_output") if os.path.isdir(self.tem_out_dirpath): shutil.rmtree(self.tem_out_dirpath) os.mkdir(self.tem_out_dirpath) # Set the path of the ouput PIR file generated by the 'hhmakemodel.py' script. self.pir_out_filepath = os.path.join(self.output_directory, "hhsuite_alignment.pir") #------------------------------------ # Actually downloads the CIF files. - #------------------------------------ if fetch_cif_files: try: if not self.pymod.use_protocol_threads: self.download_all_cif_files() else: label_text = ( "Connecting to the PDB to download %s. Please wait for" " completion..." % self.get_seq_text(self.imported_hsp_list, "CIF file")) p_dialog = Protocol_exec_dialog( app=self.pymod.main_window, pymod=self.pymod, function=self.download_all_cif_files, args=(), title="Downloading CIF files", wait_start=0.15, wait_end=0.15, label_text=label_text) p_dialog.exec_() except PyModInterruptedProtocol: return None # Check if there were some structures which could not be fetched. n_failures = len( [h for h in self.imported_hsp_list if not h["successful"]]) if n_failures != 0: title = "Download Error" message = ( "Can not access the PDB database to download %s structures out of %s." " These templates will not be imported in PyMod." "\nPlease check your Internet connection or if the PDB ids of the" " structures are valid." % (n_failures, len(self.imported_hsp_list))) self.pymod.main_window.show_warning_message(title, message) if n_failures == len(self.imported_hsp_list): self.pymod.main_window.show_warning_message( "Import HHsuite Results Error", "No templates could be fetched. Quitting.") return None self.selected_templates_nums = [ h["hsp_num"] for h in self.imported_hsp_list if h["successful"] ] else: self.selected_templates_nums = [ h["hsp_num"] for h in self.imported_hsp_list ] #------------------------------------ # Runs the 'hhmakemodel.py' script. - #------------------------------------ # Prepare the arguments for the hhsuite function. hhsuite_args = { "input": self.hhr_filepath, "cifs": self.tem_in_dirpath, "pir": self.pir_out_filepath, "output": self.tem_out_dirpath, "verbose": True, "m": self.selected_templates_nums, "e": None, "r": 0, # Do not use any filters. "c": True } # Run the hhsuite function. hhmakemodel_main(hhsuite_args) #---------------------------------------------------------- # Parse the output PIR file produced by the above script. - #---------------------------------------------------------- elements_to_load = [] ali_records = list(SeqIO.parse(self.pir_out_filepath, "pir")) for record_idx, record in enumerate(ali_records): if record_idx == 0: element_name = self.query_id else: if fetch_cif_files: element_name = "__temp_template_{}__".format(record_idx - 1) else: element_name = self.imported_hsp_list[record_idx - 1]["hsp"].template_id new_element = self.pymod.build_pymod_element_from_args( element_name, str(record.seq).replace("*", "-")) elements_to_load.append(new_element) self.pymod.add_element_to_pymod(new_element) # Add a new alignment object to PyMod in which contains the query sequence # and that of the selected templates. new_cluster = self.pymod.add_new_cluster_to_pymod( cluster_type="alignment", child_elements=elements_to_load, algorithm="imported") #----------------------------------------------- # Actually imports the final results in PyMod. - #----------------------------------------------- if fetch_cif_files: for record_idx, record in enumerate(ali_records): if record_idx == 0: continue chain = record.description.split(":")[3] modified_cif_filepath = os.path.join( self.tem_in_dirpath, "{}.cif".format(record.id)) modified_pdb_filepath = os.path.join( self.tem_in_dirpath, "{}.pdb".format(record.id)) tem_temp_name = "_hhsuite_template_{}".format(record_idx) cmd.load(modified_cif_filepath, tem_temp_name) cmd.save(modified_pdb_filepath, tem_temp_name) cmd.delete(tem_temp_name) try: a = Associate_structure(self.pymod, elements_to_load[record_idx]) a.associate(modified_pdb_filepath, chain) except Exception as e: title = "Associate Structure Failure" message = ( "The structure association for %s chain %s failed because" " of the following error: %s" % (record.id, chain, str(e))) self.pymod.main_window.show_error_message(title, message) #------------- # Cleans up. - #------------- if os.path.isdir(self.tem_in_dirpath): shutil.rmtree(self.tem_in_dirpath) if os.path.isdir(self.tem_out_dirpath): shutil.rmtree(self.tem_out_dirpath) if os.path.isfile(self.pir_out_filepath): os.remove(self.pir_out_filepath) self.pymod.main_window.gridder(update_clusters=True, update_menus=True, update_elements=True)
def domain_search_state(self): """ Launched when pressing the 'SUBMIT' button in the hmmscan option window. """ #---------------------------- # Get options from the GUI. - #---------------------------- try: self.get_options_from_gui() except Exception as e: self.pymod.main_window.show_error_message("Input Error", str(e)) return None self.hmmer_options_window.destroy() #---------------------------------------- # Actually runs the searching protocol. - #---------------------------------------- # Remote. if self.father_protocol.domain_search_mode == 'remote': self.search_protocol = Hmmscan_web_parsing_protocol( self.pymod, self.father_protocol) # Local. elif self.father_protocol.domain_search_mode == 'local': self.search_protocol = Hmmscan_local_parsing_protocol( self.pymod, self.father_protocol) self.hmmscan_db = os.path.join( self.pymod.hmmer_tool["hmmscan_db_dir_path"].get_value(), self.hmmscan_db_dict[self.hmmscan_db]) if not self.pymod.use_protocol_threads: self.run_search_protocol_scan() else: if self.father_protocol.domain_search_mode == 'remote': title = "Running EBI HMMSCAN" label_text = "Connecting to the HMMSCAN EBI server. Please wait for the process to complete..." elif self.father_protocol.domain_search_mode == 'local': title = "Running HMMSCAN" label_text = "Running HMMSCAN. Please wait for the process to complete..." p_dialog = Protocol_exec_dialog( app=self.pymod.main_window, pymod=self.pymod, function=self.run_search_protocol_scan, args=(), wait_start=1, title=title, label_text=label_text) p_dialog.exec_() #---------------------------------------------------------- # Parses the results and show them in the results window. - #---------------------------------------------------------- self.parsed_res = self.run_search_protocol_parse() if not self.parsed_res: self.pymod.main_window.show_warning_message( "Search completed", "No match found with enabled filters.") return None self.results_window = Hmmscan_results_window_qt( parent=self.pymod.main_window, protocol=self) self.results_window.show()
def run_hmmer(self): """ Launches a standalone version of PHMMER installed locally. """ # Builds a temporary file with the sequence of the query needed. query_file_name = "query" if self.protocol_name != "hmmsearch": # Saves a sequence file with only the query. self.pymod.build_sequence_file([self.blast_query_element], query_file_name, file_format="fasta", remove_indels=True, new_directory=self.output_directory) else: # Saves the entire query alignment. self.pymod.build_sequence_file( self.blast_query_element.get_children(), query_file_name, file_format="fasta", remove_indels=False, new_directory=self.output_directory) # Sets some parameters needed to run PHMMER. if self.protocol_name != "hmmsearch": # Get only one filepath. exe_filepath = self.get_similariry_search_exe_path()[0] else: # Get all filepaths. exe_filepath_dict = self.get_similariry_search_exe_path( return_dict=True) out_filepath = os.path.join(self.output_directory, "%s_out.txt" % self.protocol_name) self.result_filepath = out_filepath query_filepath = os.path.join(self.output_directory, "query.fasta") db_dirpath = self.pymod.hmmer_tool["database_dir_path"].get_value() db_filepath = os.path.join(db_dirpath, self.db_filename) args = { "query_filepath": query_filepath, "out_filepath": out_filepath, "db_filepath": db_filepath, "report_evalue": self.report_evalue } args.update(self.additional_params) if self.protocol_name != "hmmsearch": # Adds only one exec filepath. args["exe_filepath"] = exe_filepath else: # Adds two exec filepaths. args["exe_filepath"] = exe_filepath_dict[self.all_exe_filenames[1]] args["hmmbuild_exe_filepath"] = exe_filepath_dict[ self.all_exe_filenames[0]] # Actually runs phmmer. if not self.pymod.use_protocol_threads: self.execute_hmmer_program(**args) else: label_text = "Running %s. Please wait for the process to complete..." % self.blast_version_full_name p_dialog = Protocol_exec_dialog( app=self.pymod.main_window, pymod=self.pymod, function=self.execute_hmmer_program, args=args, title="Running %s" % self.blast_version_full_name, label_text=label_text) p_dialog.exec_() return True
def launch_from_gui(self): """ Called when users decide calculate DOPE of a structure loaded in PyMod. """ self.selected_sequences = self.pymod.get_selected_sequences( ) # self.get_pymod_elements(self.selected_sequences) #----------------------------------------------- # Checks if the DOPE profiles can be computed. - #----------------------------------------------- modeller_error = self.pymod.modeller.check_exception() if modeller_error is not None: message = "In order to compute DOPE scores of a structure, MODELLER must be installed and configured correctly. %s" % modeller_error self.pymod.main_window.show_error_message("MODELLER Error", message) return None if len(self.selected_sequences) == 0: self.pymod.main_window.show_error_message( "Selection Error", "Please select at least one structure to assess.") return None if any([ e.polymer_type == "nucleic_acid" for e in self.selected_sequences ]): self.pymod.main_window.show_error_message( "Selection Error", "Can not perform DOPE assessment on nucleci acids structures.") return None if not self.pymod.all_sequences_have_structure( self.selected_sequences): self.pymod.main_window.show_error_message( "Selection Error", "Please select only elements that have a 3D structure currently loaded in PyMOL." ) return None if len(self.selected_sequences) > 1: mothers_set = set([seq.mother for seq in self.selected_sequences]) if self.pymod.root_element in mothers_set or len(mothers_set) > 1: self.pymod.main_window.show_error_message( "Selection Error", "You can assess multiple structures DOPE only if they are aligned in the same cluster." ) return None # Ask users if they would like to color the sequences according to their DOPE values. title = "Color Option" message = "Would you like to color the selected sequences by their DOPE values, once they have been calculated?" color_by_dope_choice = askyesno_qt(message=message, title=title, parent=self.pymod.get_qt_parent()) #---------------------------------------- # Initializes the MODELLER environment. - #---------------------------------------- if self.run_modeller_internally: with open(os.devnull, "w") as n_fh: # Silence some MODELLER output. original_stdout = sys.stdout sys.stdout = n_fh env = self._initialize_env() sys.stdout = original_stdout else: env = None #------------------------------------------------------------------------------------ # Actually computes the DOPE scores of the polypeptide chains in the user selection - # and assigns to each residue of a corresponding color according to its DOPE. - #------------------------------------------------------------------------------------ if not self.pymod.use_protocol_threads: self.compute_all_dopes(env=env) self.assign_dope_items() else: label_text = ( "Computing DOPE of %s. Please wait for the process to" " complete..." % self.get_seq_text(self.selected_sequences, "structure")) p_dialog = Protocol_exec_dialog( app=self.pymod.main_window, pymod=self.pymod, function=self._launch_dope_thread, args=(None, ), wait_start=1.25, wait_end=0.25, title="Computing DOPE scores.", label_text=label_text, lock=True, # a thread with MODELLER can not exit safely. lock_title=self.pymod.modeller_lock_title, stdout_silence=True, lock_message=self.pymod.modeller_lock_message) p_dialog.exec_() #---------------------- # Color the elements. - #---------------------- if color_by_dope_choice: for element in self.selected_sequences: self.pymod.main_window.color_element_by_dope(element) #-------------------------------- # Shows the DOPE profiles plot. - #-------------------------------- if len(self.selected_sequences) == 1: dope_graph_mode = "single" elif len(self.selected_sequences) >= 2: dope_graph_mode = "multiple" # Prepares the data to show in the plot. self.dope_plot_data = self.prepare_dope_plot_data( self.selected_sequences, mode=dope_graph_mode) # Shows the plot. self.show_plot() #----------------------------- # Shows an assessment table. - #----------------------------- column_headers = ["Structure Name", "DOPE score"] data_array = list( zip([ e.get_pymol_selector() for e in self.assessed_structures_list ], self.global_dope_scores)) assessment_table_args = { "column_headers": column_headers, # "row_headers": [m["name"] for m in a.outputs], "data_array": data_array, "title": "Assessment of Selected Structures", "width": 850, "height": 420, "sortable": True, } self.pymod.show_table(**assessment_table_args)