Beispiel #1
0
def solvate(struct='top/protein.pdb', top='top/system.top',
            distance=0.9, boxtype='dodecahedron',
            concentration=0, cation='NA', anion='CL',
            water='spc', solvent_name='SOL', with_membrane=False,
            ndx = 'main.ndx', mainselection = '"Protein"',
            dirname='solvate',
            **kwargs):
    """Put protein into box, add water, add counter-ions.

    Currently this really only supports solutes in water. If you need
    to embedd a protein in a membrane then you will require more
    sophisticated approaches.

    However, you *can* supply a protein already inserted in a
    bilayer. In this case you will probably want to set *distance* =
    ``None`` and also enable *with_membrane* = ``True`` (using extra
    big vdw radii for typical lipids).

    .. Note:: The defaults are suitable for solvating a globular
       protein in a fairly tight (increase *distance*!) dodecahedral
       box.

    :Arguments:
      *struct* : filename
          pdb or gro input structure
      *top* : filename
          Gromacs topology
      *distance* : float
          When solvating with water, make the box big enough so that
          at least *distance* nm water are between the solute *struct*
          and the box boundary.
          Set *boxtype*  to ``None`` in order to use a box size in the input
          file (gro or pdb).
      *boxtype* or *bt*: string
          Any of the box types supported by :class:`~gromacs.tools.Editconf`
          (triclinic, cubic, dodecahedron, octahedron). Set the box dimensions
          either with *distance* or the *box* and *angle* keywords.

          If set to ``None`` it will ignore *distance* and use the box
          inside the *struct* file.

          *bt* overrides the value of *boxtype*.
      *box*
          List of three box lengths [A,B,C] that are used by :class:`~gromacs.tools.Editconf`
          in combination with *boxtype* (``bt`` in :program:`editconf`) and *angles*.
          Setting *box* overrides *distance*.
      *angles*
          List of three angles (only necessary for triclinic boxes).
      *concentration* : float
          Concentration of the free ions in mol/l. Note that counter
          ions are added in excess of this concentration.
      *cation* and *anion* : string
          Molecule names of the ions. This depends on the chosen force field.
      *water* : string
          Name of the water model; one of "spc", "spce", "tip3p",
          "tip4p". This should be appropriate for the chosen force
          field. If an alternative solvent is required, simply supply the path to a box
          with solvent molecules (used by :func:`~gromacs.genbox`'s  *cs* argument)
          and also supply the molecule name via *solvent_name*.
      *solvent_name*
          Name of the molecules that make up the solvent (as set in the itp/top).
          Typically needs to be changed when using non-standard/non-water solvents.
          ["SOL"]
      *with_membrane* : bool
           ``True``: use special ``vdwradii.dat`` with 0.1 nm-increased radii on
           lipids. Default is ``False``.
      *ndx* : filename
          How to name the index file that is produced by this function.
      *mainselection* : string
          A string that is fed to :class:`~gromacs.tools.Make_ndx` and
          which should select the solute.
      *dirname* : directory name
          Name of the directory in which all files for the solvation stage are stored.
      *includes*
          List of additional directories to add to the mdp include path
      *kwargs*
          Additional arguments are passed on to
          :class:`~gromacs.tools.Editconf` or are interpreted as parameters to be
          changed in the mdp file.

    """
    structure = realpath(struct)
    topology = realpath(top)

    # arguments for editconf that we honour
    editconf_keywords = ["box", "bt", "angles", "c", "center", "aligncenter",
                         "align", "translate", "rotate", "princ"]
    editconf_kwargs = dict((k,kwargs.pop(k,None)) for k in editconf_keywords)
    editconf_boxtypes = ["triclinic", "cubic", "dodecahedron", "octahedron", None]

    # needed for topology scrubbing
    scrubber_kwargs = {'marker': kwargs.pop('marker',None)}

    # sanity checks and argument dependencies
    bt = editconf_kwargs.pop('bt')
    boxtype = bt if bt else boxtype   # bt takes precedence over boxtype
    if not boxtype in editconf_boxtypes:
        msg = "Unsupported boxtype {boxtype!r}: Only {boxtypes!r} are possible.".format(**vars())
        logger.error(msg)
        raise ValueError(msg)
    if editconf_kwargs['box']:
        distance = None    # if box is set then user knows what she is doing...

    # handle additional include directories (kwargs are also modified!)
    mdp_kwargs = cbook.add_mdp_includes(topology, kwargs)

    if water.lower() in ('spc', 'spce'):
        water = 'spc216'
    elif water.lower() == 'tip3p':
        water = 'spc216'
        logger.warning("TIP3P water model selected: using SPC equilibrated box "
                       "for initial solvation because it is a reasonable starting point "
                       "for any 3-point model. EQUILIBRATE THOROUGHLY!")

    # By default, grompp should not choke on a few warnings because at
    # this stage the user cannot do much about it (can be set to any
    # value but is kept undocumented...)
    grompp_maxwarn = kwargs.pop('maxwarn',10)

    # clean topology (if user added the marker; the default marker is
    # ; Gromacs auto-generated entries follow:
    n_removed = cbook.remove_molecules_from_topology(topology, **scrubber_kwargs)

    with in_dir(dirname):
        logger.info("[{dirname!s}] Solvating with water {water!r}...".format(**vars()))
        if boxtype is None:
            hasBox = False
            ext = os.path.splitext(structure)[1]
            if ext == '.gro':
                hasBox = True
            elif ext == '.pdb':
                with open(structure) as struct:
                    for line in struct:
                        if line.startswith('CRYST'):
                            hasBox = True
                            break
            if not hasBox:
                msg = "No box data in the input structure {structure!r} and boxtype is set to None".format(**vars())
                logger.exception(msg)
                raise MissingDataError(msg)
            distance = boxtype = None   # ensures that editconf just converts
        editconf_kwargs.update({'f': structure, 'o': 'boxed.gro',
                                'bt': boxtype, 'd': distance})
        gromacs.editconf(**editconf_kwargs)

        if with_membrane:
            vdwradii_dat = get_lipid_vdwradii()  # need to clean up afterwards
            logger.info("Using special vdW radii for lipids {0!r}".format(vdw_lipid_resnames))

        try:
            gromacs.genbox(p=topology, cp='boxed.gro', cs=water, o='solvated.gro')
        except:
            if with_membrane:
                # remove so that it's not picked up accidentally
                utilities.unlink_f(vdwradii_dat)
            raise
        logger.info("Solvated system with %s", water)

        with open('none.mdp','w') as mdp:
            mdp.write('; empty mdp file\ninclude = {include!s}\nrcoulomb = 1\nrvdw = 1\nrlist = 1\n'.format(**mdp_kwargs))
        qtotgmx = cbook.grompp_qtot(f='none.mdp', o='topol.tpr', c='solvated.gro',
                                            p=topology, stdout=False, maxwarn=grompp_maxwarn)
        qtot = round(qtotgmx)
        logger.info("[{dirname!s}] After solvation: total charge qtot = {qtotgmx!r} = {qtot!r}".format(**vars()))

        if concentration != 0:
            logger.info("[{dirname!s}] Adding ions for c = {concentration:f} M...".format(**vars()))
            # target concentration of free ions c ==>
            #    N = N_water * c/c_water
            # add ions for concentration to the counter ions (counter ions are less free)
            #
            # get number of waters (count OW ... works for SPC*, TIP*P water models)
            rc,output,junk = gromacs.make_ndx(f='topol.tpr', o='ow.ndx',
                                              input=('keep 0', 'del 0', 'a OW*', 'name 0 OW', '', 'q'),
                                              stdout=False)
            groups = cbook.parse_ndxlist(output)
            gdict = {g['name']: g for g in groups}   # overkill...
            N_water = gdict['OW']['natoms']                  # ... but dict lookup is nice
            N_ions = int(N_water * concentration/CONC_WATER) # number of monovalents
        else:
            N_ions = 0

        # neutralize (or try -neutral switch of genion???)
        n_cation = n_anion = 0
        if qtot > 0:
            n_anion = int(abs(qtot))
        elif qtot < 0:
            n_cation = int(abs(qtot))

        n_cation += N_ions
        n_anion  += N_ions

        if n_cation != 0 or n_anion != 0:
            # sanity check:
            assert qtot + n_cation - n_anion < 1e-6
            logger.info("[{dirname!s}] Adding n_cation = {n_cation:d} and n_anion = {n_anion:d} ions...".format(**vars()))
            gromacs.genion(s='topol.tpr', o='ionized.gro', p=topology,
                           pname=cation, nname=anion, np=n_cation, nn=n_anion,
                           input=solvent_name)
        else:
            # fake ionized file ... makes it easier to continue without too much fuzz
            try:
                os.unlink('ionized.gro')
            except OSError, err:
                if err.errno != errno.ENOENT:
                    raise
            os.symlink('solvated.gro', 'ionized.gro')

        qtot = cbook.grompp_qtot(f='none.mdp', o='ionized.tpr', c='ionized.gro',
                                         p=topology, stdout=False, maxwarn=grompp_maxwarn)

        if abs(qtot) > 1e-4:
            wmsg = "System has non-zero total charge qtot = {qtot:g} e.".format(**vars())
            warnings.warn(wmsg, category=BadParameterWarning)
            logger.warn(wmsg)

        # make main index
        try:
            make_main_index('ionized.tpr', selection=mainselection, ndx=ndx)
        except GromacsError, err:
            # or should I rather fail here?
            wmsg = "Failed to make main index file %r ... maybe set mainselection='...'.\n"\
                   "The error message was:\n%s\n" % (ndx, str(err))
            logger.warn(wmsg)
            warnings.warn(wmsg, category=GromacsFailureWarning)
Beispiel #2
0
def solvate(struct='top/protein.pdb',
            top='top/system.top',
            distance=0.9,
            boxtype='dodecahedron',
            concentration=0,
            cation='NA',
            anion='CL',
            water='spc',
            solvent_name='SOL',
            with_membrane=False,
            ndx='main.ndx',
            mainselection='"Protein"',
            dirname='solvate',
            **kwargs):
    """Put protein into box, add water, add counter-ions.

    Currently this really only supports solutes in water. If you need
    to embedd a protein in a membrane then you will require more
    sophisticated approaches.

    However, you *can* supply a protein already inserted in a
    bilayer. In this case you will probably want to set *distance* =
    ``None`` and also enable *with_membrane* = ``True`` (using extra
    big vdw radii for typical lipids).

    .. Note:: The defaults are suitable for solvating a globular
       protein in a fairly tight (increase *distance*!) dodecahedral
       box.

    :Arguments:
      *struct* : filename
          pdb or gro input structure
      *top* : filename
          Gromacs topology
      *distance* : float
          When solvating with water, make the box big enough so that
          at least *distance* nm water are between the solute *struct*
          and the box boundary.
          Set *boxtype*  to ``None`` in order to use a box size in the input
          file (gro or pdb).
      *boxtype* or *bt*: string
          Any of the box types supported by :class:`~gromacs.tools.Editconf`
          (triclinic, cubic, dodecahedron, octahedron). Set the box dimensions
          either with *distance* or the *box* and *angle* keywords.

          If set to ``None`` it will ignore *distance* and use the box
          inside the *struct* file.

          *bt* overrides the value of *boxtype*.
      *box*
          List of three box lengths [A,B,C] that are used by :class:`~gromacs.tools.Editconf`
          in combination with *boxtype* (``bt`` in :program:`editconf`) and *angles*.
          Setting *box* overrides *distance*.
      *angles*
          List of three angles (only necessary for triclinic boxes).
      *concentration* : float
          Concentration of the free ions in mol/l. Note that counter
          ions are added in excess of this concentration.
      *cation* and *anion* : string
          Molecule names of the ions. This depends on the chosen force field.
      *water* : string
          Name of the water model; one of "spc", "spce", "tip3p",
          "tip4p". This should be appropriate for the chosen force
          field. If an alternative solvent is required, simply supply the path to a box
          with solvent molecules (used by :func:`~gromacs.genbox`'s  *cs* argument)
          and also supply the molecule name via *solvent_name*.
      *solvent_name*
          Name of the molecules that make up the solvent (as set in the itp/top).
          Typically needs to be changed when using non-standard/non-water solvents.
          ["SOL"]
      *with_membrane* : bool
           ``True``: use special ``vdwradii.dat`` with 0.1 nm-increased radii on
           lipids. Default is ``False``.
      *ndx* : filename
          How to name the index file that is produced by this function.
      *mainselection* : string
          A string that is fed to :class:`~gromacs.tools.Make_ndx` and
          which should select the solute.
      *dirname* : directory name
          Name of the directory in which all files for the solvation stage are stored.
      *includes*
          List of additional directories to add to the mdp include path
      *kwargs*
          Additional arguments are passed on to
          :class:`~gromacs.tools.Editconf` or are interpreted as parameters to be
          changed in the mdp file.

    """
    structure = realpath(struct)
    topology = realpath(top)

    # arguments for editconf that we honour
    editconf_keywords = [
        "box", "bt", "angles", "c", "center", "aligncenter", "align",
        "translate", "rotate", "princ"
    ]
    editconf_kwargs = dict((k, kwargs.pop(k, None)) for k in editconf_keywords)
    editconf_boxtypes = [
        "triclinic", "cubic", "dodecahedron", "octahedron", None
    ]

    # needed for topology scrubbing
    scrubber_kwargs = {'marker': kwargs.pop('marker', None)}

    # sanity checks and argument dependencies
    bt = editconf_kwargs.pop('bt')
    boxtype = bt if bt else boxtype  # bt takes precedence over boxtype
    if not boxtype in editconf_boxtypes:
        msg = "Unsupported boxtype {boxtype!r}: Only {boxtypes!r} are possible.".format(
            **vars())
        logger.error(msg)
        raise ValueError(msg)
    if editconf_kwargs['box']:
        distance = None  # if box is set then user knows what she is doing...

    # handle additional include directories (kwargs are also modified!)
    mdp_kwargs = cbook.add_mdp_includes(topology, kwargs)

    if water.lower() in ('spc', 'spce'):
        water = 'spc216'
    elif water.lower() == 'tip3p':
        water = 'spc216'
        logger.warning(
            "TIP3P water model selected: using SPC equilibrated box "
            "for initial solvation because it is a reasonable starting point "
            "for any 3-point model. EQUILIBRATE THOROUGHLY!")

    # By default, grompp should not choke on a few warnings because at
    # this stage the user cannot do much about it (can be set to any
    # value but is kept undocumented...)
    grompp_maxwarn = kwargs.pop('maxwarn', 10)

    # clean topology (if user added the marker; the default marker is
    # ; Gromacs auto-generated entries follow:
    n_removed = cbook.remove_molecules_from_topology(topology,
                                                     **scrubber_kwargs)

    with in_dir(dirname):
        logger.info(
            "[{dirname!s}] Solvating with water {water!r}...".format(**vars()))
        if boxtype is None:
            hasBox = False
            ext = os.path.splitext(structure)[1]
            if ext == '.gro':
                hasBox = True
            elif ext == '.pdb':
                with open(structure) as struct:
                    for line in struct:
                        if line.startswith('CRYST'):
                            hasBox = True
                            break
            if not hasBox:
                msg = "No box data in the input structure {structure!r} and boxtype is set to None".format(
                    **vars())
                logger.exception(msg)
                raise MissingDataError(msg)
            distance = boxtype = None  # ensures that editconf just converts
        editconf_kwargs.update({
            'f': structure,
            'o': 'boxed.gro',
            'bt': boxtype,
            'd': distance
        })
        gromacs.editconf(**editconf_kwargs)

        if with_membrane:
            vdwradii_dat = get_lipid_vdwradii()  # need to clean up afterwards
            logger.info("Using special vdW radii for lipids {0!r}".format(
                vdw_lipid_resnames))

        try:
            gromacs.genbox(p=topology,
                           cp='boxed.gro',
                           cs=water,
                           o='solvated.gro')
        except:
            if with_membrane:
                # remove so that it's not picked up accidentally
                utilities.unlink_f(vdwradii_dat)
            raise
        logger.info("Solvated system with %s", water)

        with open('none.mdp', 'w') as mdp:
            mdp.write(
                '; empty mdp file\ninclude = {include!s}\nrcoulomb = 1\nrvdw = 1\nrlist = 1\n'
                .format(**mdp_kwargs))
        qtotgmx = cbook.grompp_qtot(f='none.mdp',
                                    o='topol.tpr',
                                    c='solvated.gro',
                                    p=topology,
                                    stdout=False,
                                    maxwarn=grompp_maxwarn)
        qtot = round(qtotgmx)
        logger.info(
            "[{dirname!s}] After solvation: total charge qtot = {qtotgmx!r} = {qtot!r}"
            .format(**vars()))

        if concentration != 0:
            logger.info(
                "[{dirname!s}] Adding ions for c = {concentration:f} M...".
                format(**vars()))
            # target concentration of free ions c ==>
            #    N = N_water * c/c_water
            # add ions for concentration to the counter ions (counter ions are less free)
            #
            # get number of waters (count OW ... works for SPC*, TIP*P water models)
            rc, output, junk = gromacs.make_ndx(f='topol.tpr',
                                                o='ow.ndx',
                                                input=('keep 0', 'del 0',
                                                       'a OW*', 'name 0 OW',
                                                       '', 'q'),
                                                stdout=False)
            groups = cbook.parse_ndxlist(output)
            gdict = {g['name']: g for g in groups}  # overkill...
            N_water = gdict['OW']['natoms']  # ... but dict lookup is nice
            N_ions = int(N_water * concentration /
                         CONC_WATER)  # number of monovalents
        else:
            N_ions = 0

        # neutralize (or try -neutral switch of genion???)
        n_cation = n_anion = 0
        if qtot > 0:
            n_anion = int(abs(qtot))
        elif qtot < 0:
            n_cation = int(abs(qtot))

        n_cation += N_ions
        n_anion += N_ions

        if n_cation != 0 or n_anion != 0:
            # sanity check:
            assert qtot + n_cation - n_anion < 1e-6
            logger.info(
                "[{dirname!s}] Adding n_cation = {n_cation:d} and n_anion = {n_anion:d} ions..."
                .format(**vars()))
            gromacs.genion(s='topol.tpr',
                           o='ionized.gro',
                           p=topology,
                           pname=cation,
                           nname=anion,
                           np=n_cation,
                           nn=n_anion,
                           input=solvent_name)
        else:
            # fake ionized file ... makes it easier to continue without too much fuzz
            try:
                os.unlink('ionized.gro')
            except OSError, err:
                if err.errno != errno.ENOENT:
                    raise
            os.symlink('solvated.gro', 'ionized.gro')

        qtot = cbook.grompp_qtot(f='none.mdp',
                                 o='ionized.tpr',
                                 c='ionized.gro',
                                 p=topology,
                                 stdout=False,
                                 maxwarn=grompp_maxwarn)

        if abs(qtot) > 1e-4:
            wmsg = "System has non-zero total charge qtot = {qtot:g} e.".format(
                **vars())
            warnings.warn(wmsg, category=BadParameterWarning)
            logger.warn(wmsg)

        # make main index
        try:
            make_main_index('ionized.tpr', selection=mainselection, ndx=ndx)
        except GromacsError, err:
            # or should I rather fail here?
            wmsg = "Failed to make main index file %r ... maybe set mainselection='...'.\n"\
                   "The error message was:\n%s\n" % (ndx, str(err))
            logger.warn(wmsg)
            warnings.warn(wmsg, category=GromacsFailureWarning)
Beispiel #3
0
def solvate_sol(struct='top/protein.pdb', top='top/system.top',
                distance=0.9, boxtype='dodecahedron',
                water='tip4p', solvent_name='SOL', with_membrane=False,
                dirname='solvate',
                **kwargs):
    structure = realpath(struct)
    topology = realpath(top)

    # arguments for editconf that we honour
    editconf_keywords = ["box", "bt", "angles", "c", "center", "aligncenter",
                         "align", "translate", "rotate", "princ"]
    editconf_kwargs = dict((k,kwargs.pop(k,None)) for k in editconf_keywords)
    editconf_boxtypes = ["triclinic", "cubic", "dodecahedron", "octahedron", None]

    # needed for topology scrubbing
    scrubber_kwargs = {'marker': kwargs.pop('marker',None)}

    # sanity checks and argument dependencies
    bt = editconf_kwargs.pop('bt')
    boxtype = bt if bt else boxtype   # bt takes precedence over boxtype
    if not boxtype in editconf_boxtypes:
        msg = "Unsupported boxtype {boxtype!r}: Only {boxtypes!r} are possible.".format(**vars())
        logger.error(msg)
        raise ValueError(msg)
    if editconf_kwargs['box']:
        distance = None    # if box is set then user knows what she is doing...

    if water.lower() in ('spc', 'spce'):
        water = 'spc216'
    elif water.lower() == 'tip3p':
        water = 'spc216'
        logger.warning("TIP3P water model selected: using SPC equilibrated box "
                       "for initial solvation because it is a reasonable starting point "
                       "for any 3-point model. EQUILIBRATE THOROUGHLY!")

    # clean topology (if user added the marker; the default marker is
    # ; Gromacs auto-generated entries follow:
    n_removed = cbook.remove_molecules_from_topology(topology, **scrubber_kwargs)

    with in_dir(dirname):
        logger.info("[{dirname!s}] Solvating with water {water!r}...".format(**vars()))
        if boxtype is None:
            hasBox = False
            ext = os.path.splitext(structure)[1]
            if ext == '.gro':
                hasBox = True
            elif ext == '.pdb':
                with open(structure) as struct:
                    for line in struct:
                        if line.startswith('CRYST'):
                            hasBox = True
                            break
            if not hasBox:
                msg = "No box data in the input structure {structure!r} and boxtype is set to None".format(**vars())
                logger.exception(msg)
                raise MissingDataError(msg)
            distance = boxtype = None   # ensures that editconf just converts
        editconf_kwargs.update({'f': structure, 'o': 'boxed.gro',
                                'bt': boxtype, 'd': distance})
        gromacs.editconf(**editconf_kwargs)

        if with_membrane:
            vdwradii_dat = get_lipid_vdwradii()  # need to clean up afterwards
            logger.info("Using special vdW radii for lipids {0!r}".format(vdw_lipid_resnames))

        try:
            gromacs.genbox(p=topology, cp='boxed.gro', cs=water, o='solvated.gro')
        except:
            if with_membrane:
                # remove so that it's not picked up accidentally
                utilities.unlink_f(vdwradii_dat)
            raise
        logger.info("Solvated system with %s", water)
    return {'struct': realpath(dirname, 'solvated.gro'),}
Beispiel #4
0
def solvate_sol(struct='top/protein.pdb',
                top='top/system.top',
                distance=0.9,
                boxtype='dodecahedron',
                water='tip4p',
                solvent_name='SOL',
                with_membrane=False,
                dirname='solvate',
                **kwargs):
    structure = realpath(struct)
    topology = realpath(top)

    # arguments for editconf that we honour
    editconf_keywords = [
        "box", "bt", "angles", "c", "center", "aligncenter", "align",
        "translate", "rotate", "princ"
    ]
    editconf_kwargs = dict((k, kwargs.pop(k, None)) for k in editconf_keywords)
    editconf_boxtypes = [
        "triclinic", "cubic", "dodecahedron", "octahedron", None
    ]

    # needed for topology scrubbing
    scrubber_kwargs = {'marker': kwargs.pop('marker', None)}

    # sanity checks and argument dependencies
    bt = editconf_kwargs.pop('bt')
    boxtype = bt if bt else boxtype  # bt takes precedence over boxtype
    if not boxtype in editconf_boxtypes:
        msg = "Unsupported boxtype {boxtype!r}: Only {boxtypes!r} are possible.".format(
            **vars())
        logger.error(msg)
        raise ValueError(msg)
    if editconf_kwargs['box']:
        distance = None  # if box is set then user knows what she is doing...

    if water.lower() in ('spc', 'spce'):
        water = 'spc216'
    elif water.lower() == 'tip3p':
        water = 'spc216'
        logger.warning(
            "TIP3P water model selected: using SPC equilibrated box "
            "for initial solvation because it is a reasonable starting point "
            "for any 3-point model. EQUILIBRATE THOROUGHLY!")

    # clean topology (if user added the marker; the default marker is
    # ; Gromacs auto-generated entries follow:
    n_removed = cbook.remove_molecules_from_topology(topology,
                                                     **scrubber_kwargs)

    with in_dir(dirname):
        logger.info(
            "[{dirname!s}] Solvating with water {water!r}...".format(**vars()))
        if boxtype is None:
            hasBox = False
            ext = os.path.splitext(structure)[1]
            if ext == '.gro':
                hasBox = True
            elif ext == '.pdb':
                with open(structure) as struct:
                    for line in struct:
                        if line.startswith('CRYST'):
                            hasBox = True
                            break
            if not hasBox:
                msg = "No box data in the input structure {structure!r} and boxtype is set to None".format(
                    **vars())
                logger.exception(msg)
                raise MissingDataError(msg)
            distance = boxtype = None  # ensures that editconf just converts
        editconf_kwargs.update({
            'f': structure,
            'o': 'boxed.gro',
            'bt': boxtype,
            'd': distance
        })
        gromacs.editconf(**editconf_kwargs)

        if with_membrane:
            vdwradii_dat = get_lipid_vdwradii()  # need to clean up afterwards
            logger.info("Using special vdW radii for lipids {0!r}".format(
                vdw_lipid_resnames))

        try:
            gromacs.genbox(p=topology,
                           cp='boxed.gro',
                           cs=water,
                           o='solvated.gro')
        except:
            if with_membrane:
                # remove so that it's not picked up accidentally
                utilities.unlink_f(vdwradii_dat)
            raise
        logger.info("Solvated system with %s", water)
    return {
        'struct': realpath(dirname, 'solvated.gro'),
    }
Beispiel #5
0
#!/usr/bin/env python

import sys
import os
import gromacs
import numpy as np

solute = sys.argv[1]
outname = solute.split(".")[0] + "_b" + ".gro"
gromacs.editconf(f=solute,
                 box=list((input("Enter the box size: ").split())),
                 o=outname)
# center=list(input("Enter the position for solute: ").split()),
#!/usr/bin/env python

import gromacs
import sys, os

grofile = sys.argv[1]

gromacs.editconf(f=grofile, translate=list(input("Enter the translate vector: ").split()), o="out.gro")
Beispiel #7
0
    def add_box_mutation(self):
        """
        Function to add the solvent and run a minimization of the local amino acid with the waters included
        
        Output:
        system.gro -- file containing the complete system minimized after the mutation
        """
        
        # Read the solvent
        os.system("grep ATOM {path}/solvent/solvent_{itera}.pdb | grep -v ENDMDL > {path}/solvent.pdb".format(path=self.path,itera=self.last_iteration))
        
        # Concatenate complex and system
        os.system("cat {path}/complex.pdb {path}/solvent.pdb > {path}/system.pdb".format(path=self.path))
        rc,sout,serr=gromacs.editconf(f=self.path+"/system.pdb", o=self.path+"/system_mod.pdb", stdout=False)
        os.system("mv {}/system_mod.pdb {}/system.pdb".format(self.path,self.path))

        # Make an index of the system
        rc,sout,serr=gromacs.make_ndx(f=self.path+"/system.pdb", o=self.path+"/index.ndx", stdout=False, input=('chain {} \n q'.format(self.pep_chain)))
        
        # Copy the topol files of the target chains, which are the same always
        if self.target=="protein":
            for ch in self.chain_join:
                os.system("cp {}/topol_Protein_chain_{}.itp {}/system_Protein_chain_{}.itp".format(self.path,ch,self.path,ch))
        if self.target=="drug":
            for ch in self.chain_join:
                os.system("cp {}/topol_Drug_chain_{}.itp {}/system_Drug_chain_{}.itp".format(self.path,ch,self.path,ch))
        
        # Copy the topol.top to system.top
        os.system("cp {}/topol.top {}/system.top".format(self.path,self.path))
        os.system("cp {}/complex_Protein_chain_{}.itp {}/system_Protein_chain_{}.itp".format(self.path,self.pep_chain,self.path,self.pep_chain))
        os.system("sed -i 's/topol_/system_/g' {}/system.top".format(self.path))
       
        # Select water and ions within 0.2 distance of the residue
        rc,sout,serr=gromacs.make_ndx(f=self.path+"/system.pdb", o=self.path+"/index.ndx", stdout=False, input=('chain {}'.format(self.pep_chain),'q'))
        rc,sout,serr=gromacs.select(f=self.path+"/system.pdb", n=self.path+"/index.ndx", s=self.path+"/system.pdb", on=self.path+"/index_sol.ndx", stdout=False, select="group Water_and_ions and same residue as within 0.2 of (group ch{} and resnr {})".format(self.pep_chain,self.pep_position))
        
        # Solve the issue with atoms overlapped with the selected residue
        values=[x.strip() for x in open(self.path+"/index_sol.ndx")]
        atomsSOL=[]
        for i,v in enumerate(values):
            if i!=0:
                info=v.split()
                atomsSOL=atomsSOL+info
        # List of the atoms that will be deleted
        atomsDelete=[]
         
        # Check the overlapped atoms
        for a in atomsSOL:
            # Obtain the list of atoms from the index file
            bash = "awk '$2 == '{}' {{print $6','$7','$8}}' {}/system.pdb".format(a,self.path)
            coordinates = subprocess.check_output(['bash','-c', bash])
            comp=coordinates.strip().split()
            comparison=[]
            for c in comp: comparison.append(float(c))
            ndComp=np.array(comparison)
            
            distancesSOL=[]
            
            # Read the structure in biopython
            parser = PDBParser()
            structure = parser.get_structure('PEP', self.path+"/system.pdb")
            model = structure[0]
            
            # Check the distances with all the atoms from the selected residue
            for residue in model[self.pep_chain]:
                resC=residue.get_resname()
                resNumber=residue.get_full_id()[3][1]
                if resNumber==self.pep_position:
                    for atom in residue:
                        idAtom = atom.get_id()
                        if idAtom[0].isdigit() == False:
                            if resC=="ILE" and idAtom=="CD": idAtom="CD1"
                            
                            diff = atom.coord - ndComp
                            diffValue=np.sqrt(np.sum(diff * diff))
                            distancesSOL.append(float(diffValue))
                            
            # Threshold to determine which atoms can be overlapped
            if min(distancesSOL)<1.0:
                if a not in atomsDelete: atomsDelete.append(a)
         
        # Selection of the final atoms that will be included in the index
        final_index=[]
        for element in atomsSOL:
            flag=0
            for delete in atomsDelete:
                if abs(int(element)-int(delete))<=2: flag=1
            if flag==0:
                final_index.append(element)
                
        # Update of the index sol file
        new_index=open(self.path+"/index_sol2.ndx","w")
        new_index.write("{}\n".format(values[0]))
        group=[]
        counter=1
        for ele in final_index:
            if counter <15:
                group.append(ele)
                counter+=1
            else:
                group.append(ele)
                new_index.write(" ".join(group)+" \n")
                counter=1
                group=[]
        new_index.write(" ".join(group)+" ")
        new_index.close()
        
        # Update the file
        os.system("mv {}/index_sol2.ndx {}/index_sol.ndx".format(self.path,self.path))
                
        ref_ndx = NDX()
        ref_ndx.read(self.path+"/index.ndx")
        bash="grep '\[' {}/index.ndx | wc -l".format(self.path)
        number_index = subprocess.check_output(['bash','-c', bash])
        index_ref=int(number_index)-1
        #index_ref=len(ref_ndx)-1
                                          
        # Create the side chain index in a template file
        os.system("echo 'name 0 overlap' > %s/template" %self.path)
        os.system("echo '\"SideChain\" & \"ch{}\" & r {}' >> {}/template".format(self.pep_chain,str(self.pep_position),self.path))
        os.system("echo '\"overlap\" | \"SideChain_&_ch{}_&_r_{}\"' >> {}/template".format(self.pep_chain,str(self.pep_position),self.path))
        os.system("echo '\"System\" &! \"overlap_SideChain_&_ch{}_&_r_{}\"' >> {}/template".format(self.pep_chain,str(self.pep_position),self.path))
        os.system("echo 'q' >> {}/template".format(self.path))
        
        # Create an index joining both created before
        os.system("gmx -quiet make_ndx -f {path}/system.pdb -n {path}/index_sol.ndx {path}/index.ndx -o {path}/total_index.ndx < {path}/template".format(path=self.path))
        os.system("sed -i 's/System_&_\!overlap_SideChain_&_ch{}_&_r_{}/to_block/g' {}/total_index.ndx".format(self.pep_chain,str(self.pep_position),self.path))
        
        # Generate the gro file
        rc,sout,serr=gromacs.editconf(f=self.path+"/system.pdb", o=self.path+"/system.gro", stdout=False)
        
        # Prepare the files for the minimization and run
        rc,sout,serr=gromacs.grompp(f=self.path+"/mdp/minim_overlap.mdp", o=self.path+"/systemNEW.tpr", p=self.path+"/system.top", n=self.path+"/total_index.ndx", c=self.path+"/system.gro", stdout=False)
        gromacs.utilities.unlink_gmx("mdout.mdp")
        print("Running second minimization ...")
        rc,sout,serr=gromacs.mdrun(deffnm=self.path+"/systemNEW", stdout=False)

        # Copy the system.gro file that will be used to run the last minimization
        os.system("cp {}/systemNEW.gro {}/system.gro".format(self.path,self.path))
        os.system("sed -i '$ d' {}/system.gro".format(self.path))
        os.system("tail -n1 {path}/npt-pbc.gro >> {path}/system.gro".format(path=self.path)) 
        
        # Delete temporal files
        os.system("rm {path}/complex.pdb {path}/solvent.pdb {path}/systemNEW* {path}/template {path}/index.ndx {path}/index_sol.ndx {path}/total_index.ndx *.itp".format(path=self.path))
Beispiel #8
0
    def run_minim_complex(self,run_minim=False):
        """
        Function to run a local minimization on the side chain that was mutated
        
        Arguments:
        run_minim -- boolean flag that will control if the minimization is run or not
        
        Output:
        complex.pdb -- new complex pdb with the minimization and the new itp files
        """
        
        # Get the chain with the peptide to generate a novel itp file
        os.system("python3 {}/src/scores/get_chains.py {}/complex.pdb {}".format(self.path_scores,self.path,self.path))
        rc,sout,serr=gromacs.pdb2gmx(f=self.path+"/complex_"+self.pep_chain+".pdb", p=self.path+"/binder.top", o=self.path+"/complex_"+self.pep_chain+".gro", stdout=False, input=('6','6'))
        os.system("sed -i '/forcefield/d' {}/binder.top".format(self.path))
        os.system("sed -i '/\[ system \]/,$d' {}/binder.top".format(self.path))
        os.system("mv {}/binder.top {}/complex_Protein_chain_{}.itp".format(self.path,self.path,self.pep_chain))
        rc,sout,serr=gromacs.editconf(f=self.path+"/complex_"+self.pep_chain+".gro", o=self.path+"/complex_"+self.pep_chain+".pdb", stdout=False)
        
        # Fix the amino acid nomenclature
        os.system("for i in ASP ARG HIS HIE HID HIP LYS GLU SER THR ASN GLN CYS CYX GLY PRO ALA VAL ILE LEU MET PHE TYR TRP; do sed -i s/\"$i  \"/\"$i {}\"/g {}/complex_{}.pdb; done".format(self.pep_chain,self.path,self.pep_chain))
        for i,ch in enumerate(self.chain_join):
            if i==0:            
                os.system("grep ATOM {}/complex_{}.pdb > {}/complex.pdb".format(self.path,ch,self.path))
                os.system("echo 'TER' >> {}/complex.pdb".format(self.path))
            else:
                os.system("grep ATOM {}/complex_{}.pdb >> {}/complex.pdb".format(self.path,ch,self.path))
                os.system("echo 'TER' >> {}/complex.pdb".format(self.path))
        
        # Get the new complex.pdb and the peptide chain itp file and delete temporal files
        os.system("grep ATOM {}/complex_{}.pdb >> {}/complex.pdb".format(self.path,self.pep_chain,self.path))
        os.system("echo 'TER' >> {}/complex.pdb".format(self.path))
        os.system("rm {}/complex_*.pdb".format(self.path))
        os.system("rm {}/complex_*.gro".format(self.path))
        os.system("rm {}/chains.seq".format(self.path))

        os.system("head -n -18 {}/complex_Protein_chain_{}.itp > {}/temp; mv {}/temp {}/complex_Protein_chain_{}.itp".format(self.path,self.pep_chain,self.path,self.path,self.path,self.pep_chain))
        
        # Copy the topol files of the target chains, which are the same always
        # Copy the topol files of the target chains, which are the same always
        if self.target=="protein":
            for ch in self.chain_join:
                os.system("cp {}/topol_Protein_chain_{}.itp {}/complex_Protein_chain_{}.itp".format(self.path,ch,self.path,ch))
        if self.target=="drug":
            for ch in self.chain_join:
                os.system("cp {}/topol_Drug_chain_{}.itp {}/complex_Drug_chain_{}.itp".format(self.path,ch,self.path,ch))
        
        # Copy the topol.top to complex.top and delete all the additional atoms
        os.system("cp {}/topol.top {}/complex.top".format(self.path,self.path))
        os.system("sed -i '/Ion/d' {}/complex.top".format(self.path))
        os.system("sed -i '/SOL/d' {}/complex.top".format(self.path))
        os.system("sed -i '/NA/d' {}/complex.top".format(self.path))
        os.system("sed -i '/CL/d' {}/complex.top".format(self.path))
        os.system("sed -i '/solvent/d' {}/complex.top".format(self.path))
        os.system("sed -i 's/topol_/complex_/g' {}/complex.top".format(self.path))
        
        # Get a pdb of the complex where an index will be created
        rc,sout,serr=gromacs.make_ndx(f=self.path+"/complex.pdb", o=self.path+"/reference.ndx", stdout=False, input=('q'))
        ref_ndx = NDX()
        ref_ndx.read(self.path+"/reference.ndx")
        #index_ref=len(ref_ndx)-1
        bash="grep '\[' {}/reference.ndx | wc -l".format(self.path)
        number_index = subprocess.check_output(['bash','-c', bash])
        index_ref=int(number_index)-1
        gromacs.utilities.unlink_gmx(self.path+"/reference.ndx")
        
        # Create the side chain index
        input_for_ndx=()
        counter=index_ref
        input_for_ndx+=('chain {}'.format(self.pep_chain),); counter+=1
        input_for_ndx+=('name {} binder'.format(counter),);
        input_for_ndx+=('"SideChain" & "binder"'+' &  r {}'.format(self.pep_position),); counter+=1
        input_for_ndx+=('"System" &! {}'.format(counter),); counter+=1
        input_for_ndx+=('name {} scmut'.format(counter),);
        sentence=""
        for i,ch in enumerate(self.chain_join):
            if i==0: sentence=sentence+"chain {}".format(ch)
            else: sentence=sentence+" | chain {}".format(ch)
        input_for_ndx+=(sentence,); counter+=1
        input_for_ndx+=('name {} target'.format(counter),)
        input_for_ndx+=('\"target\" | \"binder\"',); counter+=1
        input_for_ndx+=('name {} complex'.format(counter),)
        input_for_ndx+=('q',)
        
        # Generate the index file
        rc,sout,serr=gromacs.make_ndx(f=self.path+"/complex.pdb", o=self.path+"/scmut.ndx", stdout=False, input=input_for_ndx)
        
        # Generate the gro file
        rc,sout,serr=gromacs.editconf(f=self.path+"/complex.pdb", o=self.path+"/complex.gro", stdout=False)
        
        # Add a small box for the residues
        os.system("sed -i '$ d' {}/complex.gro".format(self.path))
        os.system('echo "   20.0   20.0   20.0" >> {path}/complex.gro'.format(path=self.path))
        
        # Prepare the files for the minimization
        rc,sout,serr=gromacs.grompp(f=self.path+"/mdp/minim_scmut.mdp", o=self.path+"/complex.tpr", p=self.path+"/complex.top", n=self.path+"/scmut.ndx", c=self.path+"/complex.gro", stdout=False)
        gromacs.utilities.unlink_gmx("mdout.mdp")
        
        # Run the minimization of the side chain alone and the residues around it
        if run_minim:
            # Run the minimization
            print("Running first minimization ...")
            rc,sout,serr=gromacs.mdrun(deffnm=self.path+"/complex", stdout=False)
            
            # Get the complex pdb file
            rc,sout,serr=gromacs.trjconv(f=self.path+"/complex.gro",s=self.path+"/complex.tpr", n=self.path+"/scmut.ndx", o=self.path+"/min_complex.pdb",stdout=False,input=("complex"))
            os.system("rm posre.itp {path}/complex.tpr {path}/complex.top; grep -v ENDMDL {path}/min_complex.pdb | grep -v MODEL > {path}/complex.pdb; rm {path}/min_complex.pdb {path}/complex.log {path}/complex.trr {path}/complex.edr {path}/scmut.ndx".format(path=self.path))
Beispiel #9
0
#tr_vector= np.asarray([0, 0, u1.dimensions[2]/10])
#print(tr_vector)

###SET UP THE PROTEIN BOX
print("This stage is to setup protein box to combine to membrane box!!!")
#boxsize = input("enter the box size: ").split()
z_box = float(input("enter the box size along z: "))
x_box = u1.dimensions[0] / 10
y_box = u1.dimensions[1] / 10
boxsize = [x_box, y_box, z_box]
#print(boxsize)
#print(type(z_box))
center = [
    x_box / 2, y_box / 2,
    float(input("enter the coordinates you want to place protein along z: "))
]
filename = input("provide the file name of residue: ")
outname = filename.split(".")[0]
outname_b = outname + "_b" + ".gro"
gromacs.editconf(f=filename, o=outname_b, box=boxsize, center=center)
outname_bw = outname + "_bw" + ".gro"
gromacs.solvate(cp=outname_b, o="out.gro")
gromacs.editconf(f="out.gro", translate=tr_vector, o=outname_bw)
#
##
#### COMBINE MEMBRANE GRO FILE AND PEPTIDE GRO FILE
u2 = mda.Universe(outname_bw)
u12 = mda.Merge(u2.atoms, u1.atoms)

u12.atoms.write(str(sys.argv[1]).split(".")[0] + "_" + outname + ".gro")
Beispiel #10
0
                os.rename(
                    protein_name + '.D00000001', './inactives/incomplete/' +
                    protein_name + '_inactive_logFile')
                modelname = ('./inactives/incomplete/' + protein_name +
                             '_inactive.pdb')
                briefname = ('./inactives/incomplete/' + protein_name +
                             '_inactive')
                briefername = (protein_name + '_inactive')
                dir_name = ('./inactives/incomplete/')
                is_active = 0
        for filename in glob.glob("./" + protein_name + "*"):
            os.remove(filename)

        #mutate_model.py

        gromacs.editconf(f=modelname, resnr=first_res, o=modelname)

        if re.search('no_mutation', mutation) is not None:
            print 'No mutations here'
        else:
            print "Looks like we've got a mutation.  Let's check it out. \n"
            different_mutations = re.split('&', mutation)
            for mutant_res in range(0, len(different_mutations)):
                is_mutated = re.search(r"([a-z])([0-9]+)([a-z])",
                                       different_mutations[mutant_res], re.I)
                if is_mutated:
                    mutations_list = is_mutated.groups()
                    respos = mutations_list[1]
                    restyp = pdb.Polypeptide.one_to_three(
                        mutations_list[0])  #get three letter code
Beispiel #11
0
                dir_name = ('./inactives/complete/')
                is_active = 0
            else:
                os.rename(protein_name+'.B99990001.pdb', './inactives/incomplete/'+protein_name+'_inactive.pdb') 
                os.rename(protein_name+'.D00000001', './inactives/incomplete/'+protein_name+'_inactive_logFile')
                modelname = ('./inactives/incomplete/'+protein_name+'_inactive.pdb')
                briefname = ('./inactives/incomplete/'+protein_name+'_inactive')
                briefername = (protein_name+'_inactive')
                dir_name = ('./inactives/incomplete/')
                is_active = 0
        for filename in glob.glob("./"+protein_name+"*"):
            os.remove(filename)
         
        #mutate_model.py
     
        gromacs.editconf(f = modelname, resnr = first_res, o = modelname)
        

        if re.search('no_mutation', mutation) is not None:
            print 'No mutations here'
        else:
            print "Looks like we've got a mutation.  Let's check it out. \n"
            different_mutations = re.split('&', mutation)
            for mutant_res in range(0, len(different_mutations)):
                is_mutated = re.search(r"([a-z])([0-9]+)([a-z])", different_mutations[mutant_res], re.I)
                if is_mutated:
                    mutations_list = is_mutated.groups()
                    respos = mutations_list[1]
                    restyp = pdb.Polypeptide.one_to_three(mutations_list[0]) #get three letter code

                    #makes use of the optimize function in modeller