Beispiel #1
0
    def delete_cluster_dialog(self, cluster_element):
        title = "Delete Cluster?"
        message = "Are you sure you want to delete %s?" % (
            cluster_element.my_header)
        remove_cluster_choice = askyesno_qt(message=message,
                                            title=title,
                                            parent=self.get_qt_parent())
        if not remove_cluster_choice:
            return None
        title = "Delete Sequences?"
        message = "Would you like to delete all the sequences contained in the %s cluster? By selecting 'No', you will only extract them from the cluster." % (
            cluster_element.my_header)
        remove_children_choice = askyesno_qt(message=message,
                                             title=title,
                                             parent=self.get_qt_parent())

        # Delete both the cluster and its children.
        if remove_children_choice:
            cluster_element.delete()
        # Delete only the cluster element and extract the child sequences.
        else:
            children = cluster_element.get_children()
            for c in reversed(children[:]):
                c.extract_to_upper_level()
            cluster_element.delete()

        self.main_window.gridder(update_menus=True)
Beispiel #2
0
    def auto_find_command(self, etry):
        """
        Automatically find the tool value and ask whether to set it in the GUI.
        """

        auto_find_results = self.guess_first_session_value()
        tool_param_text = "%s '%s'" % (self.parent_tool.full_name,
                                       self.full_name)
        if auto_find_results:
            message = (
                "%s was found in one of the system's directories (at: %s)."
                " Would you like to use this file and set its value in the PyMod"
                " Options window?" % (tool_param_text, auto_find_results))
            answer = askyesno_qt("File Automatically Found",
                                 message,
                                 parent=self.parent_tool.pymod.get_qt_parent())
            if answer:
                etry.setText(str(auto_find_results))
        else:
            message = (
                "%s was not found in any of the system's directories. Please"
                " manually specify its path in the PyMod Options window through"
                " the 'Browse' button." % (tool_param_text))
            self.parent_tool.pymod.main_window.show_info_message(
                "File Not Found", message)
Beispiel #3
0
 def ask_to_remove_indels(self):
     title = "Save File"
     message = "Would you like to remove indels from the sequence when saving it to a file?"
     remove_indels_choice = askyesno_qt(title,
                                        message,
                                        parent=self.get_qt_parent())
     return remove_indels_choice
 def start_new_session_from_main_menu(self):
     title = "Begin New Project?"
     message = ("Are you really sure you want to begin a new PyMod project? If"
                " you do not save your current project, its data will be"
                " permanently lost.")
     answer = askyesno_qt(title, message, parent=self.get_qt_parent())
     if not answer:
         return None
     self.start_new_session()
Beispiel #5
0
 def confirm_close(self, evnt=None):
     """
     Asks confirmation when the main window is closed by the user.
     """
     answer = askyesno_qt("Exit PyMod?",
                          "Are you really sure you want to exit PyMod?",
                          parent=self.pymod.get_qt_parent())
     if answer:
         self.pymod.inactivate_session()
         self.close()  # Closes the PyMod main window.
     else:
         if evnt is not None:
             evnt.ignore()
Beispiel #6
0
 def closeEvent(self, evnt):
     if evnt.spontaneous():
         title = "Exit PyMod?"
         message = "Are you really sure you want to exit PyMod?"
         answer = askyesno_qt(title,
                              message,
                              parent=self.pymod.get_qt_parent())
         if answer:
             self.close()  # Closes the dialog.
             self.main_window.close(
             )  # Close the main window if the user exits the dialog.
         else:
             evnt.ignore()
    def check_sequences_level(self):
        """
        This method is used to ask the user a confirmation before performing an alignment in certain
        situations (for example when building an alignment only with sequences belonging to the same
        cluster).
        """
        proceed_with_alignment = False
        self.clusters_are_involved = False
        self.rebuild_single_alignment_choice = False
        self.extract_siblings_choice = False

        # Only root sequences are involved.
        if len(self.involved_clusters_list) == 0 and len(
                self.selected_root_sequences_list) > 0:
            proceed_with_alignment = True

        # Only one cluster and not external sequences are involved.
        if len(self.involved_clusters_list) == 1 and len(
                self.selected_root_sequences_list) == 0:
            # If there is only one cluster selected with all its elements: the user might want to
            # rebuild an alignment with all its elements.
            if set(self.selected_clusters_list) == set(
                    self.involved_clusters_list):
                proceed_with_alignment = True
                self.rebuild_single_alignment_choice = proceed_with_alignment
            # Only a subset of all the elements in a clster are selected.
            else:
                title = "Extract children?"
                message = "Would you like to extract the selected children and build a new alignment?"
                proceed_with_alignment = askyesno_qt(
                    title, message, parent=self.pymod.get_qt_parent())
                self.extract_siblings_choice = proceed_with_alignment

        # Multiple clusters are involved.
        elif len(self.involved_clusters_list) > 0:
            self.clusters_are_involved = True
            proceed_with_alignment = True

        return proceed_with_alignment
Beispiel #8
0
 def extend_selection_to_hidden_children(self):
     selected_elements = self.pymod.get_selected_sequences()
     extend_selection = None
     # Checks if in the selection there are some cluster leads of which mothers are not selected.
     if False in [
             e.mother.selected for e in selected_elements
             if self.pymod.main_window.is_lead_of_collapsed_cluster(e)
     ]:
         # Ask to include the hidden children of the collapsed clusters.
         title = "Selection Message"
         message = "Would you like to include in the alignment the hidden sequences of the collapsed clusters?"
         extend_selection = askyesno_qt(title,
                                        message,
                                        parent=self.pymod.get_qt_parent())
     else:
         extend_selection = False
     if not extend_selection:
         return None
     # Actually selects the hidden children.
     for e in selected_elements:
         if self.pymod.main_window.is_lead_of_collapsed_cluster(
                 e) and not e.mother.selected:
             e.mother.widget_group.select_collapsed_cluster_descendants()
Beispiel #9
0
    def launch_from_gui(self):
        """
        Launches the domain splitting procedure from the PyMod GUI.
        """

        # If the sequence has already some derived domains, ask the users whether to repeat the
        # splitting operation.
        if self.pymod_element.derived_domains_list:
            confirmation = askyesno_qt(
                "Confirm",
                "Do you want to overwrite the previous splitting operation?",
                parent=self.pymod.get_qt_parent())
            if not confirmation:
                return None

        # Show the options window.
        self.split_seq_offset_window = SplitSeqOffsetWindow_qt(
            self.pymod.main_window,
            protocol=self,
            title="Choose the Domain Offset",
            upper_frame_title=
            "Choose how many flanking residues\nto append to each domain",
            submit_command=self.split_seq_offset_window_state)
        self.split_seq_offset_window.show()
Beispiel #10
0
    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)
Beispiel #11
0
    def __init__(self, app, pymod_plugin_name, pymod_version, pymod_revision,
                 parallel_modeller):
        """
        Startup of the plugin.
        """

        #---------------------
        # Initializes PyMod. -
        #---------------------

        self.pymod_plugin_name = pymod_plugin_name
        self.pymod_version = pymod_version
        self.pymod_revision = pymod_revision

        self.DEVELOP = False
        self.TEST = False

        self.app = app

        # Initialize PyMod elements and information about the analyses performed by the user.
        self.initialize_pymod_elements_information()

        # --------------------------------------------------------------------------------------
        # Prepare PyMod files and folders that will be created in the project main directory. -
        # --------------------------------------------------------------------------------------

        # PyMod directory. The main folder where all PyMod files (with the exception of the
        # configuration file) will be stored.
        self.pymod_directory_name = "pymod"
        self.pymod_temp_directory_name = "pymod_temp_directory"
        self.projects_directory_name = "projects"
        self.new_project_default_name = "new_pymod_project"
        self.external_tools_dirname = "external_tools"
        self.data_dirname = "data"
        self.temp_directory_name = "temp_dir"
        self.active_session_filename = ".active_session.txt"
        self.inactive_session_filename = ".inactive_session.txt"

        # Structures.
        self.structures_dirname = "structures"  # structures_dirpath

        # Alignments.
        self.alignments_dirname = "alignments"  # alignments_directory
        self.alignments_files_names = "alignment"

        # Images directory
        self.images_dirname = "images"  # images_directory

        # Models.
        self.models_dirname = "models"  # models_directory
        self.models_subdirectory = "modeling_session"

        # PSIPRED.
        self.psipred_dirname = "psipred"

        # BLAST.
        self.similarity_searches_dirname = "similarity_searches"
        self.use_blast_v5_databases = True

        # Domain analysis.
        self.domain_analysis_dirname = 'domain_analysis'

        # File names used in order to store the information of PyMod sessions.
        self.session_temp_dirname = "pymod_project_temp_dir"
        self.session_filename = "pymod_session"

        # Initializes the main paths for the plugin.
        self.initializes_main_paths()

        # -----------------------
        # Prepare PyMod tools. -
        # -----------------------

        self.pymod_tools = []

        # PyMod itself.
        self.pymod_plugin = pm_tool.Tool("pymod", self.pymod_plugin_name)
        self.pymod_plugin.initialize_parameters([
            pm_tool.Tool_directory("pymod_dir_path",
                                   "PyMod Directory",
                                   editable=False)
        ])
        self.pymod_tools.append(self.pymod_plugin)

        # ClustalW.
        self.clustalw = pm_tool.Executable_tool(
            "clustalw",
            "Clustal W",
        )
        self.clustalw.initialize_parameters([
            pm_tool.Tool_exec_file("exe_file_path",
                                   "Executable File",
                                   auto_find=True)
        ])
        self.pymod_tools.append(self.clustalw)

        # Clustal Omega.
        self.clustalo = pm_tool.Executable_tool("clustalo", "Clustal Omega")
        self.clustalo.initialize_parameters([
            pm_tool.Tool_exec_file("exe_file_path",
                                   "Executable File",
                                   auto_find=True)
        ])
        self.pymod_tools.append(self.clustalo)

        # MUSCLE.
        self.muscle = pm_tool.Executable_tool("muscle", "MUSCLE")
        self.muscle.initialize_parameters([
            pm_tool.Tool_exec_file("exe_file_path",
                                   "Executable File",
                                   auto_find=True)
        ])
        self.pymod_tools.append(self.muscle)

        # BLAST+ suite. Used to run PSI-BLAST and store BLAST sequence databases retrieved from
        # ftp://ftp.ncbi.nlm.nih.gov/blast/db/ .
        self.blast_plus = pm_tool.Executable_tool("blast_plus", "BLAST+ suite")
        self.blast_plus.initialize_parameters([
            pm_tool.Tool_exec_directory("exe_dir_path",
                                        "Executables Directory",
                                        auto_find=True),
            # A default directory where the database folders available for the
            # PSI-BLAST database selection are going to be located.
            pm_tool.Tool_directory("database_dir_path", "Database Directory")
        ])
        self.pymod_tools.append(self.blast_plus)

        # HMMER suite.
        self.hmmer_tool = pm_tool.Executable_tool("hmmer", "HMMER suite")
        self.hmmer_tool.initialize_parameters([
            pm_tool.Tool_exec_directory("exe_dir_path",
                                        "Executables Directory",
                                        auto_find=True),
            pm_tool.Tool_directory("database_dir_path",
                                   "HMMER Database Directory"),
            pm_tool.Tool_directory("hmmscan_db_dir_path",
                                   "HMMSCAN Database Directory")
        ])
        self.pymod_tools.append(self.hmmer_tool)

        # PSIPRED.
        self.psipred = pm_tool.Executable_tool("psipred", "PSIPRED")
        self.psipred.initialize_parameters([
            pm_tool.Tool_directory("exe_dir_path", "Executables Directory"),
            pm_tool.Tool_directory("data_dir_path", "Data Files Directory"),
            pm_tool.Tool_directory("database_dir_path",
                                   "BLAST Database Directory")
        ])
        self.pymod_tools.append(self.psipred)

        # KSDSSP.
        self.ksdssp = pm_tool.Executable_tool("ksdssp", "KSDSSP")
        self.ksdssp.initialize_parameters(
            [pm_tool.Tool_exec_file("exe_file_path", "Executable File")])
        self.pymod_tools.append(self.ksdssp)

        # MODELLER.
        self.modeller = pm_tool.Modeller_tool("modeller", "MODELLER")
        self.modeller.initialize_parameters([
            pm_tool.Use_importable_modeller("use_importable_modeller",
                                            "Internal MODELLER"),
        ])
        self.pymod_tools.append(self.modeller)
        self.parallel_modeller = parallel_modeller

        # Initializes tools.
        for tool in self.pymod_tools:
            tool.pymod = self

        # If set to 'True' the most time consuming protocols of PyMod will be run in a thread so
        # that the GUI is not freezed. When developing the code, it is better to set it to 'False',
        # in order to better track exceptions.
        if self.DEVELOP:
            self.use_protocol_threads = False
        else:
            self.use_protocol_threads = True

        # Initializes colors for PyMod and PyMOL.
        self.initialize_colors()

        #----------------------------------------
        # Builds the main window of the plugin. -
        #----------------------------------------

        self.main_window = PyMod_main_window_qt(self)

        #-----------------------
        # Starts up a new job. -
        #-----------------------

        # If it is not found, then treat this session as the first one and asks the user to input
        # the 'PyMod Directory' path before beginning the first PyMod job.
        if not os.path.isfile(self.cfg_file_path):
            self.show_first_time_usage_message()
            self.show_pymod_directory_selection_window()

        # The configuration file is found.
        else:

            # Start an usual PyMod session. Get values options for each PyMod tool and start a
            # new PyMod job.
            try:
                self.get_parameters_from_configuration_file()
                # Checks if the PyMod directory exists.
                if not os.path.isdir(
                        self.pymod_plugin["pymod_dir_path"].get_value()):
                    message = (
                        "The project directory specified in PyMod configuration"
                        " file ('%s') is missing. Please specify a new"
                        " one." %
                        self.pymod_plugin["pymod_dir_path"].get_value())
                    raise Exception(message)
                self.new_job_state()

            except Exception as e:
                if self.DEVELOP:
                    raise e
                self.show_configuration_file_error(e, "read")
                title = 'Configuration file repair'
                message = "Would you like to delete PyMod configuration file and build a new functional copy of it?"
                repair_choice = askyesno_qt(title, message,
                                            self.get_qt_parent())
                if repair_choice:
                    self.show_pymod_directory_selection_window()
                else:
                    self.main_window.destroy()
Beispiel #12
0
    def new_job_state(self, overwrite=False):
        """
        This is called when the SUBMIT button on the "New Job" window is pressed.
        """

        # Checks if the name is valid.
        new_dir_name = self.new_project_default_name  # self.new_dir_window.main_entry.get()
        if bool(re.search('[^A-z0-9-_]',
                          new_dir_name)) or "\\" in new_dir_name:
            self.main_window.show_error_message(
                'Name Error',
                'Only a-z, 0-9, "-" and "_" are allowed in the project name.')
            return None

        # Writes the directory.
        try:

            # Composes the name of the new projects directory.
            pymod_projects_dir_path = os.path.join(
                self.pymod_plugin["pymod_dir_path"].get_value(),
                self.projects_directory_name)
            if not os.path.isdir(pymod_projects_dir_path):
                os.mkdir(pymod_projects_dir_path)

            new_project_dir_path = os.path.join(pymod_projects_dir_path,
                                                new_dir_name)

            # Decide whether to build a new directory or overwrite the content
            # of the previous one.
            if os.path.isdir(new_project_dir_path):

                if overwrite:
                    # Just overwrite the previous directory.
                    active_session = False
                else:
                    # Look for a file signaling an active sessions in the project
                    # directory.
                    active_session = self.check_exisisting_session_tempfile(
                        new_project_dir_path)

                if not active_session:
                    # Remove the content of the previous folder.
                    self.remove_previous_project_files(new_project_dir_path)

                else:
                    # Let the user decide whether to remove the content of the
                    # previous directory.
                    title = "Overwrite an existing project?"
                    message = (
                        "An non-finished PyMod project was found in the"
                        " 'projects' folder of your PyMod Directory. This"
                        " either means that PyMod has shut down unexpectedly last"
                        " time or that another PyMod instance is already running"
                        " on your system.\nWould you like to overwrite the"
                        " existing project folder? If another PyMod instance"
                        " is running, its data will be lost (only one PyMod"
                        " instance can be run at any time). If you are not"
                        " running any other PyMod instances, you can safely"
                        " overwrite the old project.")
                    buttons_text = ("Overwrite and continue", "Skip and quit")

                    if self.DEVELOP or self.TEST:
                        overwrite_choice = True
                    else:
                        overwrite_choice = askyesno_qt(
                            title,
                            message,
                            self.get_qt_parent(),
                            buttons_text=buttons_text)

                    if overwrite_choice:
                        # Remove the content of the old directory.
                        self.remove_previous_project_files(
                            new_project_dir_path)
                    else:
                        # Quit PyMod.
                        self.main_window.close()
                        return None

            # Simply builds the new directory.
            else:
                os.mkdir(new_project_dir_path)

            # Start the new project.
            self.initialize_session(new_dir_name)

        except Exception as e:
            if self.DEVELOP:
                raise e
            message = "Unable to write directory '%s' because of the following error: %s." % (
                new_dir_name, e)
            self.main_window.show_error_message("Initialization error",
                                                message)
            try:  # This raises an exception if the PyMod project has not been initialized.
                self.inactivate_session()
            except:
                pass
            self.main_window.close()
            return None
Beispiel #13
0
    def pymod_directory_selection_state(self):
        """
        This is called when the SUBMIT button on the "PyMod project" window is pressed.
        """
        try:

            # Check if the parent folder of the new PyMod directory exists.
            new_pymod_directory_parent = self.pymod_dir_window.main_entry.text(
            )
            if not os.path.isdir(new_pymod_directory_parent):
                title = 'PyMod directory Error'
                message = "The directory inside which you would like to create your 'PyMod Directory' ('%s') does not exist on your system. Please select an existing path." % (
                    new_pymod_directory_parent)
                self.main_window.show_error_message(title, message)
                return None

            # Check if a PyMod directory already exists in the parent folder.
            new_pymod_dirpath = os.path.join(new_pymod_directory_parent,
                                             self.pymod_directory_name)
            if os.path.exists(new_pymod_dirpath):
                title = 'PyMod directory Warning'
                message = "A folder named '%s' already exists on your system. Would you like to overwrite it and all its contents to build a new 'PyMod Directory'?" % (
                    new_pymod_dirpath)
                overwrite = askyesno_qt(title,
                                        message,
                                        parent=self.get_qt_parent())
                if overwrite:
                    if os.path.isfile(new_pymod_dirpath):
                        os.remove(new_pymod_dirpath)
                    if os.path.isdir(new_pymod_dirpath):
                        shutil.rmtree(new_pymod_dirpath)
                else:
                    return None

            # Check if the configuration file directory exist. If it does not exist, build it.
            if not os.path.exists(self.cfg_directory_path):
                os.mkdir(self.cfg_directory_path)

            # Builds the new PyMod directory with its projects folder.
            os.mkdir(new_pymod_dirpath)
            os.mkdir(
                os.path.join(new_pymod_dirpath, self.projects_directory_name))

            # Builds empty external tools and data directories.
            os.mkdir(
                os.path.join(new_pymod_dirpath, self.external_tools_dirname))
            os.mkdir(os.path.join(new_pymod_dirpath, self.data_dirname))

            # Writes the configuration file.
            cfgfile = open(self.cfg_file_path, 'w')
            pymod_config = {}

            # Initializes the parameters for each tool.
            for tool in self.pymod_tools:
                new_tool_parameters = {}
                for parameter in tool.parameters:
                    # new_tool_parameters.update({parameter.name: parameter.get_starting_value()})
                    new_tool_parameters.update({parameter.name: ""})
                pymod_config.update({tool.name: new_tool_parameters})
            pymod_config["pymod"]["pymod_dir_path"] = new_pymod_dirpath
            pymod_config["modeller"]["use_importable_modeller"] = True

            # Define the default database paths for the BLAST and HMMER suites. Users may later change
            # these through the Options window.
            for tool_name, param_name, dirname in [
                ("blast_plus", "database_dir_path", blast_databases_dirname),
                ("hmmer", "database_dir_path", hmmer_databases_dirname),
                ("hmmer", "hmmscan_db_dir_path", hmmscan_databases_dirname)
            ]:
                database_dirpath = os.path.join(new_pymod_dirpath,
                                                self.data_dirname, dirname)
                pymod_config[tool_name][param_name] = database_dirpath
                if not os.path.isdir(database_dirpath):
                    os.mkdir(database_dirpath)

            cfgfile.write(json.dumps(pymod_config))
            cfgfile.close()

        except Exception as e:
            if self.DEVELOP:
                raise e
            title = "PyMod Directory Error"
            message = "Unable to write the PyMod configuration directory '%s' because of the following error: %s." % (
                self.cfg_directory_path, e)
            self.main_window.show_error_message(title, message)
            return None

        # Begin a new PyMod job.
        self.pymod_dir_window.close()
        self.get_parameters_from_configuration_file()
        # tkMessageBox.showinfo("PyMod first run", "You are about to begin your first PyMod session.", parent=self.get_qt_parent())
        self.new_job_state()
Beispiel #14
0
    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)