Example #1
0
def do_energy_min(pdb, itpfn, outpdb="out.pdb"):
    # write the topology file
    with open("topol_em.top", "w") as fh_t:
        fh_t.write(HEAD_TOP_FILE)
        fh_t.write("#include " + '"' + itpfn + '"')
        fh_t.write(BOTTOM_TOP_FILE)
    # TODO function that checks if files are present
    gromacs.grompp(f="em.mdp",
                   c=pdb,
                   p="topol_em.top",
                   o="em.tpr",
                   maxwarn="99")
    gromacs.mdrun(s="em.tpr", c=outpdb)
Example #2
0
def mdrun(s, prefix):
    o = prefix + '.trr'
    rc, output, junk = gromacs.mdrun(v=True,
                                     s=s,
                                     o=o,
                                     stdout=False,
                                     stderr=False)
    assert rc == 0, "mdrun failed"
    return o
Example #3
0
def rerun_energy(s, o, prefix):
        e = prefix + '.edr'
        rc, output, junk = gromacs.mdrun(v=True, s=s, rerun=o, e=e, stdout=False, stderr=False)
        assert rc == 0, "mdrun failed"

        xvg = prefix + '.xvg'
        rc, output, junk = gromacs.g_energy(f=e, o=xvg,
                                            input=("Proper-Dih.", "Improper-Dih.", "CMAP-Dih.",
                                                   "LJ-14", "Coulomb-14", "LJ-(SR)", "Coulomb-(SR)",
                                                   "Coul.-recip.", "Potential"), stdout=False, stderr=False)
        assert rc == 0, "g_energy failed"

        return XVG(xvg).to_df()
Example #4
0
    def _run_mdrun(self, step_name: str, tpr: GenPath = None
                   ) -> pathlib.Path:
        """
        Run mdrun with the given step_name or explicitly given tpr file.

        :param step_name: The name of this step
        :param tpr: Path to the tpr file. If None, the tpr will be found
            from the dict :attr:`tprs` with the key being `step_name`
        :return: The Path to the output geometry
        """
        tpr = self.tprs[step_name] if tpr is None else tpr
        deffnm = '{}-{}-out'.format(self.name, step_name)
        p_deffnm = self._fp(deffnm)
        self.deffnms[step_name] = p_deffnm
        rc, output, junk = gromacs.mdrun(s=tpr, deffnm=deffnm, stdout=False)
        # Doesn't capture output if failed?
        self.outputs['run_{}'.format(step_name)] = output
        gro = p_deffnm.with_suffix('.gro')
        self.geometries[step_name] = gro
        return gro
Example #5
0
def rerun_energy(s, o, prefix):
    e = prefix + '.edr'
    rc, output, junk = gromacs.mdrun(v=True,
                                     s=s,
                                     rerun=o,
                                     e=e,
                                     stdout=False,
                                     stderr=False)
    assert rc == 0, "mdrun failed"

    xvg = prefix + '.xvg'
    rc, output, junk = gromacs.g_energy(
        f=e,
        o=xvg,
        input=("Proper-Dih.", "Improper-Dih.", "CMAP-Dih.", "LJ-14",
               "Coulomb-14", "LJ-(SR)", "Coulomb-(SR)", "Coul.-recip.",
               "Potential"),
        stdout=False,
        stderr=False)
    assert rc == 0, "g_energy failed"

    return XVG(xvg).to_df()
Example #6
0
def energy_minimize(dirname='em', mdp=config.templates['em.mdp'],
                    struct='solvate/ionized.pdb', top='top/system.top',
                    output='em.pdb', deffnm="em",
                    mdrunner=None, **kwargs):
    """Energy minimize the system.

    This sets up the system (creates run input files) and also runs
    ``mdrun_d``. Thus it can take a while.

    Additional itp files should be in the same directory as the top file.

    Many of the keyword arguments below already have sensible values.

    :Keywords:
       *dirname*
          set up under directory dirname [em]
       *struct*
          input structure (gro, pdb, ...) [solvate/ionized.pdb]
       *output*
          output structure (will be put under dirname) [em.pdb]
       *deffnm*
          default name for mdrun-related files [em]
       *top*
          topology file [top/system.top]
       *mdp*
          mdp file (or use the template) [templates/em.mdp]
       *includes*
          additional directories to search for itp files
       *mdrunner*
          :class:`gromacs.run.MDrunner` class; by defauly we
          just try :func:`gromacs.mdrun_d` and :func:`gromacs.mdrun` but a
          MDrunner class gives the user the ability to run mpi jobs
          etc. [None]
       *kwargs*
          remaining key/value pairs that should be changed in the
          template mdp file, eg ``nstxtcout=250, nstfout=250``.

    .. note:: If :func:`~gromacs.mdrun_d` is not found, the function
              falls back to :func:`~gromacs.mdrun` instead.
    """

    structure = realpath(struct)
    topology = realpath(top)
    mdp_template = config.get_template(mdp)
    deffnm = deffnm.strip()

    # write the processed topology to the default output
    kwargs.setdefault('pp', 'processed.top')

    # filter some kwargs that might come through when feeding output
    # from previous stages such as solvate(); necessary because *all*
    # **kwargs must be *either* substitutions in the mdp file *or* valid
    # command line parameters for ``grompp``.
    kwargs.pop('ndx', None)
    # mainselection is not used but only passed through; right now we
    # set it to the default that is being used in all argument lists
    # but that is not pretty. TODO.
    mainselection = kwargs.pop('mainselection', '"Protein"')
    # only interesting when passed from solvate()
    qtot = kwargs.pop('qtot', 0)

    mdp = deffnm+'.mdp'
    tpr = deffnm+'.tpr'

    logger.info("[%(dirname)s] Energy minimization of struct=%(struct)r, top=%(top)r, mdp=%(mdp)r ..." % vars())

    add_mdp_includes(topology, kwargs)

    if qtot != 0:
        # At the moment this is purely user-reported and really only here because
        # it might get fed into the function when using the keyword-expansion pipeline
        # usage paradigm.
        wmsg = "Total charge was reported as qtot = %(qtot)g <> 0; probably a problem." % vars()
        logger.warn(wmsg)
        warnings.warn(wmsg, category=BadParameterWarning)

    with in_dir(dirname):
        unprocessed = gromacs.cbook.edit_mdp(mdp_template, new_mdp=mdp, **kwargs)
        check_mdpargs(unprocessed)
        gromacs.grompp(f=mdp, o=tpr, c=structure, p=topology, **unprocessed)
        mdrun_args = dict(v=True, stepout=10, deffnm=deffnm, c=output)
        if mdrunner is None:
            try:
                gromacs.mdrun_d(**mdrun_args)
            except (AttributeError, OSError):
                # fall back to mdrun if no double precision binary
                wmsg = "No 'mdrun_d' binary found so trying 'mdrun' instead.\n"\
                    "(Note that energy minimization runs better with mdrun_d.)"
                logger.warn(wmsg)
                warnings.warn(wmsg, category=AutoCorrectionWarning)
                gromacs.mdrun(**mdrun_args)
        else:
            # user wants full control and provides simulation.MDrunner **class**
            # NO CHECKING --- in principle user can supply any callback they like
            mdrun = mdrunner(**mdrun_args)
            mdrun.run()

        # em.gro --> gives 'Bad box in file em.gro' warning --- why??
        # --> use em.pdb instead.
        if not os.path.exists(output):
            errmsg = "Energy minimized system NOT produced."
            logger.error(errmsg)
            raise GromacsError(errmsg)
        final_struct = realpath(output)

    logger.info("[%(dirname)s] energy minimized structure %(final_struct)r" % vars())
    return {'struct': final_struct,
            'top': topology,
            'mainselection': mainselection,
            }
Example #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))
Example #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))
Example #9
0
def mdrun(s, prefix):
        o = prefix + '.trr'
        rc, output, junk = gromacs.mdrun(v=True, s=s, o=o, stdout=False, stderr=False)
        assert rc == 0, "mdrun failed"
        return o