Exemple #1
0
    def run_command(self,
                    command,
                    script_name,
                    progress_update,
                    check_output=None):
        """
        Runs a script. Must provide script_name (e.g. "script.py") and progress_update (e.g.
        "BINARIZING DATABASE"). Optionally can provide list of output files whose existences are
        checked to make sure command was successfully ran. We ALWAYS cd into the MODELLER's
        directory before running a script, and we ALWAYS cd back into the original directory after
        running a script.
        """
        # first things first, we CD into MODELLER's directory
        os.chdir(self.directory)

        # run the command
        self.progress.update(progress_update)

        # try and execute the command
        process = subprocess.Popen(command,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
        output, error = process.communicate()

        # if MODELLER script gave a traceback, it is caught here and everything is stopped
        if process.returncode:
            self.progress.end()
            error = error.decode('utf-8').strip()

            error = "\n" + "\n".join(error.split('\n'))
            print(terminal.c(error, color='red'))
            self.out["structure_exists"] = False
            raise ModellerScriptError("The MODELLER script {} did not execute properly. Hopefully it is clear \
                                       from the above error message. No structure is going to be modelled."\
                                       .format(script_name))

        # If we made it this far, the MODELLER script ran to completion. Now check outputs exist
        if check_output:
            for output in check_output:
                utils.filesnpaths.is_file_exists(output)

        # MODELLER outputs a log that we rename right here, right now
        old_log_name = os.path.splitext(script_name)[0] + ".log"
        new_log_name = "gene_{}_{}".format(self.corresponding_gene_call,
                                           old_log_name)
        os.rename(old_log_name, new_log_name)

        # add to logs
        self.logs[script_name] = new_log_name

        self.run.info("Log of {}".format(script_name),
                      new_log_name,
                      progress=self.progress)

        # last things last, we CD back into the starting directory
        os.chdir(self.start_dir)
Exemple #2
0
    def is_executable_a_MODELLER_program(self):
        # temp_dir created because log file outputs to wherever fasta_to_pir.py is
        temp_dir = filesnpaths.get_temp_directory_path()
        self.copy_script_to_directory('fasta_to_pir.py',
                                      add_to_scripts_dict=False,
                                      directory=temp_dir)
        test_script = J(temp_dir, 'fasta_to_pir.py')
        test_input = os.path.abspath(
            J(os.path.dirname(anvio.__file__),
              '../tests/sandbox/mock_data_for_structure/proteins.fa'))
        test_output = J(temp_dir, 'test_out')

        command = [self.executable, test_script, test_input, test_output]

        # try and execute the command
        process = subprocess.Popen(command,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
        output, error = process.communicate()

        if process.returncode:
            # modeller has failed
            error = error.decode('utf-8').strip()

            is_licence_key_error = True if error.find(
                'Invalid license key') > -1 else False
            if is_licence_key_error:
                # its a valid modeller program with no license key
                license_target_file = error.split('\n')[-1]
                raise ConfigError(
                    "You're making progress and anvi'o is proud of you! You just need to validate your MODELLER\
                                   with a license key (it's free). Please go to https://salilab.org/modeller/registration.html\
                                   to register for a new license. After you receive an e-mail with your key, please open '%s'\
                                   and replace the characters XXXXX with your own key. Save the file and try again. "
                    % license_target_file)

            else:
                error = "\n" + "\n".join(error.split('\n'))
                print(terminal.c(error, color='red'))
                raise ConfigError(
                    "The executable you requested is called `%s`, but anvi'o doesn't agree with you that\
                                   it is a working MODELLER program. That was determined by running the command `%s`, which raised the\
                                   error seen above. If you want to specify a specific MODELLER program, you can specify it with\
                                   `--modeller-executable`." %
                    (self.executable, " ".join(command)))

        # no error was raised. now check if output file exists
        try:
            filesnpaths.is_file_exists(test_output)
        except FilesNPathsError:
            raise ConfigError(
                "The executable you requested is called `%s`, but anvi'o doesn't agree with you that\
                               it is a working MODELLER program. That was determined by running the command `%s`, which did not\
                               output the file expected. If you want to specify a specific MODELLER program, you can specify it with\
                               `--modeller-executable`." %
                (self.executable, " ".join(command)))
Exemple #3
0
    def run_command(self, command, script_name, progress_update, check_output=None):
        """
        Runs a script. Must provide script_name (e.g. "script.py") and progress_update (e.g.
        "BINARIZING DATABASE"). Optionally can provide list of output files whose existences are
        checked to make sure command was successfully ran. We ALWAYS cd into the MODELLER's
        directory before running a script, and we ALWAYS cd back into the original directory after
        running a script.
        """
        # first things first, we CD into MODELLER's directory
        os.chdir(self.directory)

        # run the command
        self.progress.update(progress_update)

        # try and execute the command
        process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        output, error = process.communicate()

        # if MODELLER script gave a traceback, it is caught here and everything is stopped
        if process.returncode: 
            self.progress.end()
            error = error.decode('utf-8').strip()

            error = "\n" + "\n".join(error.split('\n'))
            print(terminal.c(error, color='red'))
            self.out["structure_exists"] = False
            raise ModellerScriptError("The MODELLER script {} did not execute properly. Hopefully it is clear \
                                       from the above error message. No structure is going to be modelled."\
                                       .format(script_name))

        # If we made it this far, the MODELLER script ran to completion. Now check outputs exist
        if check_output:
            for output in check_output:
                utils.filesnpaths.is_file_exists(output)

        # MODELLER outputs a log that we rename right here, right now
        old_log_name = os.path.splitext(script_name)[0] + ".log"
        new_log_name = "gene_{}_{}".format(self.corresponding_gene_call, old_log_name)
        os.rename(old_log_name, new_log_name)

        # add to logs
        self.logs[script_name] = new_log_name

        self.run.info("Log of {}".format(script_name), new_log_name, progress=self.progress)

        # last things last, we CD back into the starting directory
        os.chdir(self.start_dir)
Exemple #4
0
    def is_executable_a_MODELLER_program(self):
        # temp_dir created because log file outputs to wherever fasta_to_pir.py is
        temp_dir = filesnpaths.get_temp_directory_path()
        self.copy_script_to_directory('fasta_to_pir.py', add_to_scripts_dict=False, directory=temp_dir)
        test_script = J(temp_dir, 'fasta_to_pir.py')
        test_input = os.path.abspath(J(os.path.dirname(anvio.__file__), '../tests/sandbox/mock_data_for_structure/proteins.fa'))
        test_output = J(temp_dir, 'test_out')

        command = [self.executable,
                   test_script,
                   test_input,
                   test_output]

        # try and execute the command
        process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        output, error = process.communicate()

        if process.returncode:
            # modeller has failed
            error = error.decode('utf-8').strip()

            is_licence_key_error = True if error.find('Invalid license key') > -1 else False
            if is_licence_key_error:
                # its a valid modeller program with no license key
                license_target_file = error.split('\n')[-1]
                raise ConfigError("You're making progress and anvi'o is proud of you! You just need to validate your MODELLER\
                                   with a license key (it's free). Please go to https://salilab.org/modeller/registration.html\
                                   to register for a new license. After you receive an e-mail with your key, please open '%s'\
                                   and replace the characters XXXXX with your own key. Save the file and try again. " % license_target_file)

            else:
                error = "\n" + "\n".join(error.split('\n'))
                print(terminal.c(error, color='red'))
                raise ConfigError("The executable you requested is called `%s`, but anvi'o doesn't agree with you that\
                                   it is a working MODELLER program. That was determined by running the command `%s`, which raised the\
                                   error seen above. If you want to specify a specific MODELLER program, you can specify it with\
                                   `--modeller-executable`."
                                       % (self.executable, " ".join(command)))

        # no error was raised. now check if output file exists
        try:
            filesnpaths.is_file_exists(test_output)
        except FilesNPathsError:
            raise ConfigError("The executable you requested is called `%s`, but anvi'o doesn't agree with you that\
                               it is a working MODELLER program. That was determined by running the command `%s`, which did not\
                               output the file expected. If you want to specify a specific MODELLER program, you can specify it with\
                               `--modeller-executable`." % (self.executable, " ".join(command)))
Exemple #5
0
def check_MODELLER(executable=None):
    """Test if MODELLER is going to work.

    Checks the executable exists, that a license exists, and can produce the expected output of a
    modeller executable. Exists outside of the class MODELLER so it does not have to be checked
    everytime the class is initialized. 

    Parameters
    ==========
    executable : str, None
        The string representation of a binary MODELLER program. E.g "mod9.21". If None,
        up_to_date_modeller_exec is chosen and tested.

    Returns
    =======
    executable : str
        Returns the executable that you _should_ use, which is not necessarily what is input
    """

    executable = executable if executable else up_to_date_modeller_exec

    scripts_folder = J(os.path.dirname(anvio.__file__),
                       'data/misc/MODELLER/scripts')
    if utils.filesnpaths.is_dir_empty(scripts_folder):
        raise ConfigError(
            "Anvi'o houses all its MODELLER scripts in %s, but your directory "
            "contains no scripts. Why you did dat?" % scripts_folder)

    try:
        utils.is_program_exists(executable)
    except ConfigError as e:
        *prefix, sub_version = up_to_date_modeller_exec.split('.')
        prefix, sub_version = ''.join(prefix), int(sub_version)
        for alternate_version in reversed(
                range(sub_version - 10, sub_version + 10)):
            alternate_program = prefix + '.' + str(alternate_version)
            if utils.is_program_exists(alternate_program, dont_raise=True):
                executable = alternate_program
                break
        else:
            raise ConfigError(
                "Anvi'o needs a MODELLER program to be installed on your system. You didn't specify one "
                "(which can be done with `--modeller-executable`), so anvi'o tried the most recent version "
                "it knows about: '%s'. If you are certain you have it on your system (for instance you can run it "
                "by typing '%s' in your terminal window), you may want to send a detailed bug report. If you "
                "don't have it on your system, check out these installation instructions on our website: "
                "http://merenlab.org/2016/06/18/installing-third-party-software/#modeller"
                % (executable, executable))

    temp_dir = filesnpaths.get_temp_directory_path()
    shutil.copy2(J(scripts_folder, 'fasta_to_pir.py'), temp_dir)

    test_script = J(temp_dir, 'fasta_to_pir.py')
    test_input = J(os.path.dirname(anvio.__file__),
                   'tests/sandbox/mock_data_for_structure/proteins.fa')
    test_output = J(temp_dir, 'test_out')

    command = [executable, test_script, test_input, test_output]

    # try and execute the command
    process = subprocess.Popen(command,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
    output, error = process.communicate()

    if process.returncode:
        # modeller has failed
        error = error.decode('utf-8').strip()

        is_licence_key_error = True if error.find(
            'Invalid license key') > -1 else False
        if is_licence_key_error:
            # its a valid modeller program with no license key
            license_target_file = error.split('\n')[-1]
            raise ConfigError(
                "You're making progress and anvi'o is proud of you! You just need to validate your MODELLER "
                "with a license key (it's free). Please go to https://salilab.org/modeller/registration.html "
                "to register for a new license. After you receive an e-mail with your key, please open '%s' "
                "and replace the characters XXXXX with your own key. Save the file and try again. "
                % license_target_file)

        else:
            error = "\n" + "\n".join(error.split('\n'))
            print(terminal.c(error, color='red'))
            raise ConfigError(
                "The executable you requested is called `%s`, but anvi'o doesn't agree with you that "
                "it is a working MODELLER program. That was determined by running the command `%s`, which raised the "
                "error seen above. If you want to specify a specific MODELLER program, you can specify it with "
                "`--modeller-executable`." % (executable, " ".join(command)))

    # no error was raised. now check if output file exists
    try:
        filesnpaths.is_file_exists(test_output)
    except FilesNPathsError:
        raise ConfigError(
            "The executable you requested is called `%s`, but anvi'o doesn't agree with you that "
            "it is a working MODELLER program. That was determined by running the command `%s`, which did not "
            "output the file expected. If you want to specify a specific MODELLER program, you can specify it with "
            "`--modeller-executable`." % (executable, " ".join(command)))

    return executable
Exemple #6
0
    def run_command(self,
                    command,
                    script_name,
                    check_output=None,
                    rename_log=True):
        """Base routine for running MODELLER scripts

        Parameters
        ==========
        command : list of strs
            E.g. ['mod921', 'test_script.py', 'input1', 'input2'] corresponds to the command line
            "mod9.21 test_script.py input1 input2"

        script_name : str
            E.g. 'test_script.py'

        check_output : list, None
            Verify that this list of filepaths exist after the command is ran

        rename_log : bool, True
            MODELLER outputs a log that is renamed to reflect the command and gene used
        """

        # first things first, we CD into MODELLER's directory
        os.chdir(self.directory)

        # try and execute the command
        process = subprocess.Popen(command,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
        output, error = process.communicate()

        # if MODELLER script gave a traceback, it is caught here and everything is stopped
        if process.returncode:
            error = error.decode('utf-8').strip()

            error = "\n" + "\n".join(error.split('\n'))
            print(terminal.c(error, color='red'))
            self.out["structure_exists"] = False
            raise ModellerScriptError("The MODELLER script {} did not execute properly. Hopefully it is clear "
                                      "from the above error message. No structure is going to be modelled."\
                                       .format(script_name))

        # If we made it this far, the MODELLER script ran to completion. Now check outputs exist
        if check_output:
            for output in check_output:
                utils.filesnpaths.is_file_exists(output)

        # MODELLER outputs a log that we rename right here, right now
        old_log_name = os.path.splitext(script_name)[0] + ".log"
        if rename_log:
            new_log_name = "gene_{}_{}".format(self.corresponding_gene_call,
                                               old_log_name)
            os.rename(old_log_name, new_log_name)
        else:
            new_log_name = old_log_name

        # add to logs
        self.logs[script_name] = new_log_name

        self.run.info("Log of {}".format(script_name), new_log_name)

        # last things last, we CD back into the starting directory
        os.chdir(self.start_dir)