예제 #1
0
def add_hydrogen(pdb_in, pdb_out, check_file_out=True, **reduce_options):
    """Add hydrogen to a pdb file using the ``reduce`` software:

    :param pdb_in: pdb input
    :type pdb_in: str

    :param pdb_out: pdb output
    :type pdb_out: str

    :param check_file_out: flag to check or not if file has already been
        created. If the file is present then the command break.
    :type check_file_out: bool, optional, default=True

    :param reduce_options: Optional arguments for ``reduce``


    :Example:

    >>> from pdb_manip_py import pdb_manip
    >>> pdb_manip.show_log()
    >>> TEST_OUT = getfixture('tmpdir')
    >>> add_hydrogen(pdb_in=TEST_PATH+'/phenol.pdb',\
    pdb_out=TEST_OUT+'/phenol_h.pdb') #doctest: +ELLIPSIS
    reduce -build -nuclear .../phenol.pdb
    >>> phenol_coor = pdb_manip.Coor(TEST_OUT+'/phenol_h.pdb')  \
#doctest: +ELLIPSIS
    Succeed to read file .../phenol_h.pdb ,  13 atoms found

    """
    # Check if output files exist:
    if check_file_out and os.path.isfile(pdb_out):
        logger.info("PDB files not created, {} already exist".format(pdb_out))
        return

    # Define reduce command:
    cmd_reduce = os_command.Command([REDUCE_BIN, "-build", "-nuclear", pdb_in],
                                    **reduce_options)

    cmd_reduce.display()
    return_code = cmd_reduce.run(display=False, out_data=True)

    filout = open(pdb_out, 'w')
    filout.write(return_code['stdout'])

    logger.info("Succeed to save file %s" % os.path.relpath(pdb_out))

    return
예제 #2
0
def acpype(pdb_in,
           out_folder,
           charge_model="bcc",
           atom_type="gaff",
           net_charge=None,
           check_file_out=True,
           **acpype_options):
    """Compute a molecule topologie using the ``antechamber`` software:

    :param pdb_in: pdb input
    :type pdb_in: str

    :param out_folder: output folder
    :type out_folder: str

    :param charge_model: charge model
    :type charge_model: str, default="bcc"

    :param atom_type: atom_type model
    :type atom_type: str, default="gaff"

    :param check_file_out: flag to check or not if file has already been
        created. If the file is present then the command break.
    :type check_file_out: bool, optional, default=True

    :param acpype_options: Optional arguments for ``acpype``


    :Example:

    >>> pdb_manip.show_log()
    >>> TEST_OUT = getfixture('tmpdir')
    >>> add_hydrogen(pdb_in=TEST_PATH+'/phenol.pdb',\
    pdb_out=TEST_OUT+'/phenol_h.pdb') #doctest: +ELLIPSIS
    reduce -build -nuclear .../phenol.pdb
    >>> phenol_coor = pdb_manip.Coor(TEST_OUT+'/phenol_h.pdb')  \
#doctest: +ELLIPSIS
    Succeed to read file .../phenol_h.pdb ,  13 atoms found

    """

    # Check if output files exist:
    if check_file_out and os.path.isfile(out_folder):
        logger.info(
            "MOL2 files not created, {} already exist".format(out_folder))
        return

    # Remove tha last char if == '/'
    if out_folder[-1] == '/':
        out_folder = out_folder[:-1]

    name = out_folder.split('/')[-1]

    cmd_list = [
        ACPYPE_BIN, "-i", pdb_in, "-b", out_folder, "-c", charge_model, "-a",
        atom_type, "-o", "gmx"
    ]

    if net_charge is not None:
        cmd_list += ["-n", str(net_charge)]

    # Define reduce command:
    cmd_acpype = os_command.Command(cmd_list, **acpype_options)

    cmd_acpype.display()
    cmd_acpype.run(display=False)

    logger.info("Succeed to create topologie in %s" %
                os.path.relpath(out_folder))

    # Split the itp file atom_type part:
    extract_itp_atomtypes(
        '{}.acpype/{}_GMX.itp'.format(out_folder, name),
        '{}.acpype/{}_GMX_atomtypes.itp'.format(out_folder, name))

    sys_top = gmx.TopSys('{}.acpype/{}_GMX.top'.format(out_folder, name))

    fullname = '{}_GMX_atomtypes.itp'.format(name)
    include = '{}_GMX_atomtypes'.format(name)
    path = '{}.acpype/{}_GMX_atomtypes.itp'.format(out_folder, name)

    atomtypes_itp = gmx.Itp(name=include, fullname=fullname, path=path)

    sys_top.itp_list = [atomtypes_itp] + sys_top.itp_list
    # Add position restraints
    # Get heavy atoms name:
    atom_list = []
    for key, value in sys_top.itp_list[-1].top_mol_list[0].atom_dict.items():
        if not value['atom_name'].startswith('H'):
            atom_list.append(value['atom_name'])

    sys_top.add_posre(posre_name="POSRES",
                      selec_dict={'atom_name': atom_list},
                      fc=[1000, 1000, 1000])
    sys_top.add_posre(posre_name="POSRES_LIG",
                      selec_dict={'atom_name': atom_list},
                      fc=[1000, 1000, 1000])

    sys_top.add_posre(posre_name="POSRES_CA",
                      selec_dict={'atom_name': atom_list},
                      fc=[1000, 1000, 1000])

    sys_top.add_posre(posre_name="POSRES_CA_LOW",
                      selec_dict={'atom_name': atom_list},
                      fc=[100, 100, 100])

    sys_top.write_file('{}.acpype/{}_GMX_split.top'.format(out_folder, name))

    molecule = gmx.GmxSys(
        name='mol',
        coor_file='{}.acpype/{}_GMX.gro'.format(out_folder, name),
        top_file='{}.acpype/{}_GMX_split.top'.format(out_folder, name))

    return molecule
예제 #3
0
def antechamber(pdb_in,
                mol2_out,
                charge_model="bcc",
                check_file_out=True,
                **antechamber_options):
    """Compute a molecule topologie using the ``antechamber`` software:

    :param pdb_in: pdb input
    :type pdb_in: str

    :param mol2_out: pdb output
    :type mol2_out: str

    :param charge_model: charge model
    :type charge_model: str, default="bcc"

    :param check_file_out: flag to check or not if file has already been
        created. If the file is present then the command break.
    :type check_file_out: bool, optional, default=True

    :param reduce_options: Optional arguments for ``reduce``

    Output files:

        - mol2_out
        - ANTECHAMBER_AM1BCC_PRE.AC
        - ANTECHAMBER_BOND_TYPE.AC
        - ANTECHAMBER_BOND_TYPE.AC0
        - ANTECHAMBER_AC.AC
        - ATOMTYPE.INF
        - ANTECHAMBER_AC.AC0
        - ANTECHAMBER_AM1BCC.AC

    :Example:

    >>> pdb_manip.show_log()
    >>> TEST_OUT = getfixture('tmpdir')
    >>> add_hydrogen(pdb_in=TEST_PATH+'/phenol.pdb',\
    pdb_out=TEST_OUT+'/phenol_h.pdb') #doctest: +ELLIPSIS
    reduce -build -nuclear .../phenol.pdb
    >>> phenol_coor = pdb_manip.Coor(TEST_OUT+'/phenol_h.pdb')  \
#doctest: +ELLIPSIS
    Succeed to read file .../phenol_h.pdb ,  13 atoms found
    >>> antechamber(pdb_in=TEST_OUT+'/phenol_h.pdb',\
    mol2_out=TEST_OUT+'/phenol_h.mol2') #doctest: +ELLIPSIS
    antechamber -i phenol_h.pdb -fi pdb -o phenol_h.mol2 -fo \
mol2 -c bcc

    """

    # Check if output files exist:
    if check_file_out and os.path.isfile(mol2_out):
        logger.info(
            "MOL2 files not created, {} already exist".format(mol2_out))
        return

    start_dir = os.path.abspath(".")
    # Create and go in out_folder:
    out_folder = os_command.get_directory(mol2_out)
    os_command.create_and_go_dir(out_folder)

    # Define reduce command:
    cmd_antechamber = os_command.Command([
        ANTECHAMBER_BIN, "-i", pdb_in, "-fi",
        str(pdb_in).split('.')[-1], "-o", mol2_out, "-fo", "mol2", "-c",
        charge_model
    ], **antechamber_options)

    cmd_antechamber.display()
    cmd_antechamber.run(display=False)

    logger.info("Succeed to save file %s" % os.path.relpath(mol2_out))

    # Get absolute path:
    os.chdir(start_dir)

    return
예제 #4
0
def compute_pdb2pqr(pdb_in,
                    pdb_out,
                    ff="CHARMM",
                    method='propka',
                    ph=7.0,
                    check_file_out=True):
    """
    Use pdb2pqr to define protonation state of each residue of a protein.

    :param pdb_in: path of input pdb file
    :type pdb_in: str

    :param pdb_out: path of output pdb file
    :type pdb_out: str

    :param ff: forcefield nomenclature for atom names
    :type ff: str, optional, default="CHARMM"

    :param method:  Method used to calculate ph values (propka or pdb2pka).
    :type method: str, optional, default="propka"

    :param ph: pH value to define AA residue
    :type ph: float, optional, default=7.0

    :param check_file_out: flag to check or not if file has already
        been created. If the file is present then the command break.
    :type check_file_out: bool, optional, default=True


    :Example:

    >>> pdb_manip.show_log()
    >>> TEST_OUT = str(getfixture('tmpdir'))
    >>> # Compute protonation with pdb2pqr:
    >>> compute_pdb2pqr(os.path.join(TEST_PATH,'4n1m.pdb'),
    ... os.path.join(TEST_OUT, '4n1m.pqr')) #doctest: +ELLIPSIS
    Succeed to read file ...4n1m.pdb ,  2530 atoms found
    Succeed to save file ...tmp_pdb2pqr.pdb
    pdb2pqr30... --ff CHARMM --ffout CHARMM --keep-chain \
--titration-state-method=propka --with-ph=7.00 \
...tmp_pdb2pqr.pdb ...4n1m.pqr
    0
    >>> prot_coor = pdb_manip.Coor()
    >>> prot_coor.read_pdb(os.path.join(TEST_OUT, '4n1m.pqr'), \
pqr_format = True) #doctest: +ELLIPSIS
    Succeed to read file ...4n1m.pqr ,  2549 atoms found
    >>> HSD_index = prot_coor.get_index_selection({'res_name' : ['HSD'],
    ... 'name':['CA']})
    >>> print(len(HSD_index))
    4
    >>> HSE_index = prot_coor.get_index_selection({'res_name' : ['HSE'],
    ... 'name':['CA']})
    >>> print(len(HSE_index))
    0
    >>> HSP_index = prot_coor.get_index_selection({'res_name' : ['HSP'],
    ... 'name':['CA']})
    >>> print(len(HSP_index))
    1

    .. note::
        Idealy I would need a pdb file with 3 different histidine protonation.
        I couldn't find one.

    """

    # print("Compute pdb2pqr on",pdb_in)

    # Check if output files exist and create directory:
    if check_file_out and os_command.check_file_and_create_path(pdb_out):
        logger.info("pdb2pqr not launched %s already exist" % pdb_out)
        return pdb_out

    out_folder = os_command.get_directory(pdb_out)
    # print("out_folder", out_folder)

    # WARING :
    # Many bugs are due to the REMARK field in pdb2pqr
    # The 2 following steps remove the REMARK field of the pdb

    tmp_coor = pdb_manip.Coor()
    tmp_coor.read_pdb(pdb_in)

    # Remove Nucleic acids:
    # WARNING, that part might be removed, as pdb2pqr could compute
    # protonation on nucleic acid in a near future
    na_index = tmp_coor.get_index_selection({'res_name': pdb_manip.NA_DICT})
    tmp_coor.del_atom_index(index_list=na_index)

    # Remove HETATM
    no_hetatm_pdb = tmp_coor.select_part_dict({'field': 'ATOM'})
    if no_hetatm_pdb.num == 0:
        logger.warning('No amino acids present in pdb file'
                       ', no PD2PQR calculation')
        tmp_coor = pdb_manip.Coor()
        tmp_coor.read_pdb(pdb_in)
        # To be coherent with the pdb2pqr calc., remove HETATOM :
        no_hetatm_pdb = tmp_coor.select_part_dict({'field': 'ATOM'})
        no_hetatm_pdb.write_pqr(pdb_out)
        return

    no_hetatm_pdb.write_pdb(os.path.join(out_folder + "/tmp_pdb2pqr.pdb"))

    cmd_pdb2pqr = os_command.Command([
        PDB2PQR_BIN, "--ff", ff, "--ffout", ff, "--keep-chain",
        "--titration-state-method={}".format(method),
        "--with-ph={:.2f}".format(ph),
        os.path.join(out_folder + "/tmp_pdb2pqr.pdb"), pdb_out
    ])

    cmd_pdb2pqr.display()
    out_data = cmd_pdb2pqr.run()
    os_command.delete_file(os.path.join(out_folder + "/tmp_pdb2pqr.pdb"))

    return out_data