Exemplo n.º 1
0
def test_basic_getset(file_3frames):

    m = molecule.load("pdb", file_3frames)
    sel = atomsel(selection="protein", molid=m, frame=1)

    assert sel.frame == 1
    assert sel.molid == m
    assert len(sel.bonds) == 10
    assert str(sel) == "protein"
    assert repr(sel) == "atomsel('protein', molid=%d, frame=%d)" % (m, 1)

    # Default selections
    molecule.set_frame(m, 2)
    molecule.set_top(m)
    sel = atomsel()
    assert repr(sel) == "atomsel('all', molid=%d, frame=-1)" % m

    # Set something without a setter
    with pytest.raises(AttributeError):
        sel.molid = m+1

    # Invalid selection text
    with pytest.raises(ValueError):
        atomsel(selection="cannot be parsed")

    molecule.delete(m)

    # Selection on deleted molecule
    with pytest.raises(ValueError):
        assert sel.frame == 1
    with pytest.raises(ValueError):
        assert sel.molid == m
    with pytest.raises(ValueError):
        assert sel.bonds == []
Exemplo n.º 2
0
def test_multiligand_building(tmpdir):
    """
    Solvates and membranes a system with multiple ligands """
    from vmd import atomsel, molecule
    from Dabble import DabbleBuilder

    # Build the system
    p = str(tmpdir.mkdir("multiligand_build"))
    b = DabbleBuilder(solute_filename=os.path.join(dir, "B2AR_10ALPs.mae"),
                      output_filename=os.path.join(p, "test.mae"),
                      xy_buf=10., wat_buffer=10., overwrite=True, tmp_dir=p)
    b.write()

    # Load the built system
    m2 = molecule.load("mae", os.path.join(p, "test.mae"))
    molecule.set_top(m2)

    # Check the system dimensions are correct
    solsel = atomsel("protein or resname ACE NMA ALP")
    prot_x = max(solsel.get("x")) - min(solsel.get("x"))
    prot_y = max(solsel.get("y")) - min(solsel.get("y"))
    prot_z = max(solsel.get("z")) - min(solsel.get("z"))
    assert(abs(molecule.get_periodic(m2)["a"] - prot_x - 20.0) < 0.1)
    assert(abs(molecule.get_periodic(m2)["b"] - prot_y - 20.0) < 0.1)
    assert(abs(molecule.get_periodic(m2)["c"] - prot_z - 20.0) < 0.1)

    # Check all the alprenolols are there
    assert(len(set(atomsel("resname ALP").get("resid"))) == 10)
Exemplo n.º 3
0
def test_absolute_box(tmpdir):
    """
    Tests the absolute box size for a system with ligands far from
    the box
    """
    from vmd import atomsel, molecule
    from dabble import DabbleBuilder

    # Build the system
    p = str(tmpdir)
    b = DabbleBuilder(solute_filename=os.path.join(dir, "dor_ligs.mae"),
                      output_filename=os.path.join(p, "test.mae"),
                      user_x=75.,
                      user_y=75.,
                      user_z=115.,
                      overwrite=True,
                      tmp_dir=p,
                      exclude_sel="same fragment as resname FRAG")
    b.write()

    # Load the built system
    m2 = molecule.load("mae", os.path.join(p, "test.mae"))
    molecule.set_top(m2)

    # Check all the ligands are there
    assert len(set(atomsel("resname FRAG").residue)) == 3
Exemplo n.º 4
0
def check_built_system(p):

    from vmd import atomsel, molecule

    # Load the built system for checking
    assert os.path.isfile(os.path.join(p, "test.prmtop"))

    # Use psf so we can check HMR was done correctly
    m3 = molecule.load("parm7", os.path.join(p, "test.prmtop"))

    # Check the protein is there with correct capping groups
    assert len(atomsel("protein", m3)) == 299
    assert len(set(atomsel("resname ACE NMA NME", m3).get("resid"))) == 2

    # Check for 3 phosphoserines and no regular serines
    molecule.set_top(m3)
    assert atomsel("resname SER SEP").get("name").count("P") == 3
    assert not atomsel("resname SER SEP and not same residue as name P")

    # Check for one phosphothreonine
    assert len(set(atomsel("resname THR TPO").get("resid"))) == 3
    assert len(atomsel("resname THR TPO and name P")) == 1

    # Check HMR was done correctly
    minmasspost = min(atomsel("all", m3).get("mass"))
    assert abs(minmasspost - 1.008) > 0.0001
Exemplo n.º 5
0
def test_amber_params(tmpdir):
    """
    Tests writing a ligand with amber parameters
    """
    from Dabble.param import AmberWriter

    # Parameterize with amber parameters
    p = str(tmpdir.mkdir("multiligand_rename"))
    molid = molecule.load("mae", os.path.join(dir, "07HT2B_WT.mae"))
    w = AmberWriter(molid, tmp_dir=p, forcefield="amber", hmr=False,
                    extra_topos=[os.path.join(dir,"lsd.lib")],
                    extra_params=[os.path.join(dir, "lsd.frcmod")],
                    override_defaults=False)
    w.write(os.path.join(p, "test"))

    # Check output is correct
    m2 = molecule.load("parm7", os.path.join(p, "test.prmtop"),
                       "rst7", os.path.join(p, "test.inpcrd"))
    molecule.set_top(m2)

    # Check the system is correctly built
    assert(len(set(atomsel("protein or resname ACE NMA").get("resid"))) == 298)
    assert(len(atomsel("water")) == 186)
    assert(len(atomsel("ion")) == 0)

    # Check the LSD and CHL (cholesterol) are present
    assert(len(atomsel("resname LSD")) == 50)
    assert(len(atomsel("resname CHL")) == 74)

    # Check the partial charges are set
    # Here the LSD library has partial charges of 0 except +0.6 on the N2
    assert(len(set(atomsel("resname LSD").get("charge"))) == 2)
    assert(abs(atomsel("resname LSD and name N2").get("charge")[0] - 0.6) < 0.01)
    assert(abs(set(atomsel("resname LSD and not name N2").get("charge")).pop()) < 0.01)
Exemplo n.º 6
0
def test_multiple_insertion_codes(tmpdir):
    from dabble.param import CharmmWriter

    # Generate the file
    p = str(tmpdir)
    molid = molecule.load("mae", os.path.join(dir, "3PTB_1lig_prepped.mae"))
    w = CharmmWriter(molid=molid,
                     tmp_dir=p,
                     forcefield="charmm",
                     hmr=False,
                     override_defaults=False)
    w.write(os.path.join(p, "test"))

    # Load the output file and start checking it
    m2 = molecule.load("psf", os.path.join(p, "test.psf"), "pdb",
                       os.path.join(p, "test.pdb"))
    molecule.set_top(m2)

    # Check the entire protein is there and connected
    assert len(atomsel("protein or resname ACE NMA NME")) == 3229
    assert len(set(atomsel("protein or resname ACE NMA NME").fragment)) == 1

    # Check the calcium ion is present
    assert atomsel("element Ca").resname == ["CAL"]

    # Check residues with insertion codes
    assert set(atomsel("resid 184").resname) == set(["GLY", "TYR"])
    assert set(atomsel("resid 188").resname) == set(["GLY", "LYS"])
    assert set(atomsel("resid 221").resname) == set(["ALA", "GLN"])
    assert set(atomsel("resid 245").resname) == set(["ASN", "NMA"])
    assert set(atomsel("all").insertion) == set([" ", "A"])

    # Check the ligand is there
    assert len(atomsel("resname BAMI")) == 18
Exemplo n.º 7
0
    def _write_ion_blocks(self):
        """
        Writes a PDB file containing correctly named ions for use by
        psfgen, and instructs psfgen to use it in TCL code.
        """

        # Put our molecule on top to simplify atom selection language
        old_top = molecule.get_top()
        molecule.set_top(self.molid)

        # Select all ions
        allions = []
        for resname in set(atomsel("numbonds 0").resname):
            allions.extend(self._rename_by_resname(resname, renumber=True))

        # Stop if no ions were found
        if not allions:
            return

        # Save ions as pdb
        allsel = atomsel("residue %s" % " ".join(str(_) for _ in allions))
        allsel.resid = range(len(allsel))
        allsel.user = 0.0
        _, temp = tempfile.mkstemp(suffix=".pdb",
                                   prefix="psf_ions_",
                                   dir=self.tmp_dir)
        os.close(_)
        allsel.write("pdb", temp)

        self.psfgen.add_segment(segid="I", pdbfile=temp)
        self.psfgen.read_coords(segid="I", filename=temp)

        molecule.set_top(old_top)
Exemplo n.º 8
0
def general_water(tmpdir, writerclass, forcefield, water_model):
    """
    Tests water generally
    """
    m = molecule.load("pdb", os.path.join(dir, "tip3.pdb"))
    p = str(tmpdir)

    w = writerclass(molid=m,
                    tmp_dir=p,
                    forcefield=forcefield,
                    water_model=water_model)
    w.write(os.path.join(p, "test"))

    if os.path.isfile(os.path.join(p, "test.prmtop")):
        tm = molecule.load("parm7", os.path.join(p, "test.prmtop"), "rst7",
                           os.path.join(p, "test.inpcrd"))
    else:
        tm = molecule.load("psf", os.path.join(p, "test.psf"), "pdb",
                           os.path.join(p, "test.pdb"))

    molecule.set_top(tm)
    watsel = "water or resname TIP3 TP4E TP4 SPC SPCE"
    assert len(set(atomsel(watsel).residue)) == 1
    assert len(set(atomsel(watsel).resid)) == 1

    if water_model == "tip4e":
        assert len(atomsel()) == 4
    else:  # SPC or TIP3
        assert len(atomsel()) == 3
def check_result(format, outdir, solvent=True, lipid=True):
    if format == "prmtop":
        m2 = molecule.load("parm7", os.path.join(outdir, "test.prmtop"),
                           "rst7", os.path.join(outdir, "test.inpcrd"))
    elif format == "psf":
        m2 = molecule.load("psf", os.path.join(outdir, "test.psf"), "pdb",
                           os.path.join(outdir, "test.pdb"))
    # Check by reading .top file, as VMD won't parse it and .gro doesn't
    # have bond information
    elif format == "gro":
        return check_gro(os.path.join(outdir, "test.top"), lipid=lipid)

    elif format == "lammps":
        return check_lammps(os.path.join(outdir, "test.dat"))

    molecule.set_top(m2)

    assert len(set(atomsel("protein").resid)) == 282
    assert len(set(atomsel("resname ACE NMA NME").resid)) == 4
    if solvent:
        assert len(atomsel("water")) == 32106
        assert len(atomsel("same fragment as lipid")) == 12194

    # Check for the corrrect number of alprenolols
    assert len(atomsel("resname ALP")) == 420
    assert len(set(atomsel("resname ALP").resid)) == 10
    assert any(_ in set(atomsel("resname ALP").name) for _ in ["O09", "OX"])
    assert "O1" not in set(atomsel("resname ALP").name)

    # Check coordinates are unique (not zero)
    assert len(atomsel("resname ALP")) == 420
    assert 0.0 not in atomsel("resname ALP").x

    molecule.delete(m2)
Exemplo n.º 10
0
def test_angles(file_3nob):
    with pytest.raises(ValueError):
        topology.angles(molid=0)

    m = molecule.load("mae", file_3nob)
    molecule.set_top(m)

    # No angles defined in a mae file
    x = topology.angles(molid=m, type=True)
    print(len(x))
    assert len(x) == 0
    assert topology.angletypes() == []

    # pass invalid molid
    with pytest.raises(ValueError):
        topology.addangle(0, 0, 0, molid=-1999)

    assert topology.addangle(i=0, j=1, k=2, molid=m) == 0
    assert topology.angles(m, True) == [(0, 1, 2, None)]

    x = topology.addangle(0, 0, 0, molid=m, type="angle2")
    assert topology.angles(m, True)[x] == (0, 0, 0, "angle2")

    assert topology.delangle(i=0, j=0, k=0, molid=m)
    assert topology.angles(m, True) == [(0, 1, 2, None)]

    assert not topology.delangle(1, 2, 3, molid=m)

    assert topology.delallangles(m) == 1
    assert topology.angletypes() == ["angle2"]

    molecule.delete(m)
Exemplo n.º 11
0
def test_multiligand_parameterizing(tmpdir):
    """
    Checks the parameterization of a system with multiple ligands
    """
    from vmd import atomsel, molecule
    from Dabble.param import CharmmWriter

    # Parameterize the multiple ligand system with charmm parameters
    p = str(tmpdir.mkdir("multiligand_parameterize"))
    molid = molecule.load("mae", os.path.join(dir, "test_multiligand_correct.mae"))
    w = CharmmWriter(tmp_dir=p, molid=molid, lipid_sel="lipid",
                     extra_topos=[os.path.join(dir, "alprenolol.rtf")])
    w.write(os.path.join(p, "test"))

    # Load the created file
    m2 = molecule.load("psf", os.path.join(p, "test.psf"))
    molecule.set_top(m2)

    # Check the system is intact
    assert(len(set(atomsel("protein").get("resid"))) == 282)
    assert(len(set(atomsel("resname ACE NMA").get("resid"))) == 4)
    assert(len(atomsel("water")) == 32106)
    assert(len(atomsel("lipid")) == 12194)

    # Check for the correct number of alprenolols
    assert(len(atomsel("resname ALP")) == 420)
    assert(set(atomsel("resname ALP").get("resid")) == set(range(1,11)))
Exemplo n.º 12
0
def test_basic_getset(file_3frames):

    m = molecule.load("pdb", file_3frames)
    sel = atomsel(selection="protein", molid=m, frame=1)

    assert sel.frame == 1
    assert sel.molid == m
    assert len(sel.bonds) == 10
    assert str(sel) == "protein"
    assert repr(sel) == "atomsel('protein', molid=%d, frame=%d)" % (m, 1)

    # Default selections
    molecule.set_frame(m, 2)
    molecule.set_top(m)
    sel = atomsel()
    assert repr(sel) == "atomsel('all', molid=%d, frame=-1)" % m

    # Set something without a setter
    with pytest.raises(AttributeError):
        sel.molid = m + 1

    # Invalid selection text
    with pytest.raises(ValueError):
        atomsel(selection="cannot be parsed")

    molecule.delete(m)

    # Selection on deleted molecule
    with pytest.raises(ValueError):
        assert sel.frame == 1
    with pytest.raises(ValueError):
        assert sel.molid == m
    with pytest.raises(ValueError):
        assert sel.bonds == []
Exemplo n.º 13
0
def test_water_box(tmpdir):
    """
    Tests building in a water box only
    """
    from Dabble import DabbleBuilder
    from Dabble import molutils
    from vmd import molecule

    # Build a system with well defined dimensions
    p = str(tmpdir.mkdir("po4_hmr"))
    filename = os.path.join(dir, "rho_test.mae")
    b = DabbleBuilder(solute_filename=filename,
                      output_filename=os.path.join(p, "test.mae"),
                      membrane_system="TIP3",
                      user_x=40.0,
                      user_y=35.0,
                      user_z=65.0,
                      tmp_dir=p)
    b.write()

    # Load the built system for checking
    m2 = molecule.load("mae", os.path.join(p, "test.mae"))
    molecule.set_top(m2)

    # Check the system dimensions
    assert molutils.get_system_dimensions(m2) == (40.0, 35.0, 65.0)
Exemplo n.º 14
0
def test_multiligand_building(tmpdir):
    """
    Solvates and membranes a system with multiple ligands """
    from dabble import DabbleBuilder
    p = str(tmpdir)

    # Build the system
    b = DabbleBuilder(solute_filename=os.path.join(dir, "B2AR_10ALPs.mae"),
                      output_filename=os.path.join(p, "test.mae"),
                      xy_buf=10.,
                      wat_buffer=10.,
                      overwrite=True,
                      tmp_dir=p)
    b.write()

    # Load the built system
    m2 = molecule.load("mae", os.path.join(p, "test.mae"))
    molecule.set_top(m2)

    # Check the system dimensions are correct
    solsel = atomsel("protein or resname ACE NMA ALP")
    prot_x = max(solsel.x) - min(solsel.x)
    prot_y = max(solsel.y) - min(solsel.y)
    prot_z = max(solsel.z) - min(solsel.z)
    assert abs(molecule.get_periodic(m2)["a"] - prot_x - 20.0) < 0.1
    assert abs(molecule.get_periodic(m2)["b"] - prot_y - 20.0) < 0.1
    assert abs(molecule.get_periodic(m2)["c"] - prot_z - 20.0) < 0.1

    # Check all the alprenolols are there
    assert len(set(atomsel("resname ALP").resid)) == 10
    assert len(atomsel("resname ALP")) == 420

    molecule.delete(m2)
Exemplo n.º 15
0
def test_covalent_ligand_patches(tmpdir):
    """
    Tests covalently bound ligand parameterization with the graph. One
    hydrogen atom should be renamed in the palmitoylcysteine.
    Also tests for detection of phosphorylations on amino acids.
    """
    from vmd import atomsel, molecule
    from Dabble.param import CharmmWriter

    # Parameterize with charmm parameters
    p = str(tmpdir.mkdir("multiligand_rename"))
    molid = molecule.load("mae", dir + "rho_arr_CYP_prepped_aligned_dowsered.mae")
    w = CharmmWriter(tmp_dir=p, molid=molid, lipid_sel="lipid",
                     extra_topos=[dir + "CYP_v1.str"])
    w.write(os.path.join(p, "test"))

    # Load the result
    m2 = molecule.load("psf", os.path.join(p, "test.psf"))
    molecule.set_top(m2)

    # Sanity check the system was built completely
    assert(len(set(atomsel("protein or resname ACE NMA").get("resid"))) == 699)
    assert(len(set(atomsel("resname ACE NMA").get("resid"))) == 4)
    assert(len(atomsel("water")) == 654)
    assert(len(set(atomsel("all").get("fragment"))) == 220)

    # Check for palmitoylation
    assert(len(atomsel("resname CYP")) == 116)
    assert(set(atomsel("resname CYP").get("resid")) == set([322, 323]))

    # Check for protonation on Asp83
    assert(len(atomsel("resid 83 and resname ASP")) == 13)
    assert(len(atomsel("resid 331 and resname ASP")) == 12)
    assert("OH1" in atomsel("resid 83 and resname ASP").get("type"))
    assert("OH1" not in atomsel("resid 331 and resname ASP").get("type"))

    # Check for protation on Glu134A
    assert(len(atomsel("resid 134 and resname GLU")) == 16)
    assert(len(atomsel("resid 247 and resname GLU")) == 15)
    assert("OB" in atomsel("resid 134 and resname GLU").get("type"))
    assert("OB" not in atomsel("resid 331 and resname GLU").get("type"))

    # Check that Ser98 is normal
    assert(len(atomsel("resid 98 and resname SER")) == 11)
    assert("P" not in atomsel("resid 98 and resname SER").get("type"))
    assert("OH1" in atomsel("resid 98 and resname SER").get("type"))

    # Check for phosphorylation on Ser334
    assert(len(atomsel("resid 334 and resname SER")) == 14)
    assert("P" in atomsel("resid 334 and resname SER").get("type"))
    assert("OH1" not in atomsel("resid 334 and resname SER").get("type"))

    # Check for phosphorylation on Ser338
    assert(len(atomsel("resid 338 and resname SER")) == 14)
    assert("P" in atomsel("resid 338 and resname SER").get("type"))
    assert("OH1" not in atomsel("resid 338 and resname SER").get("type"))
Exemplo n.º 16
0
    def _write_ion_blocks(self):
        """
        Writes a PDB file containing correctly named ions for use by
        psfgen, and instructs psfgen to use it in TCL code.
        """

        # Put our molecule on top to simplify atom selection language
        old_top = molecule.get_top()
        molecule.set_top(self.molid)

        # Get ion resids that aren't associated w other molecules
        # because some ligands have Na, Cl, K
        total = atomsel('element Na Cl K')
        if len(total):
            not_ions = atomsel("(same fragment as element Na Cl K)  and (not index %s)"
                               % " ".join([str(s) for s in set(total.get('index'))]))
            ions = set(total.get('residue')) - set(not_ions.get('residue'))
        else:
            ions = set(total.get('residue'))

        if not len(ions):
            return
        ionstr = "residue " + " ".join([str(s) for s in ions])

        # Fix the names
        atomsel('%s and name NA' % ionstr).set('name', 'SOD')
        atomsel('%s and name CL' % ionstr).set('name', 'CLA')
        atomsel('%s and name K' % ionstr).set('name', 'POT')
        atomsel('%s and name NA' % ionstr).set('resname', 'SOD')
        atomsel('%s and name CL' % ionstr).set('resname', 'CLA')
        atomsel('%s and name K' % ionstr).set('resname', 'POT')

        # Renumber the residues since some may be above 10k
        residues = atomsel('name SOD CLA POT').get('residue')
        batch = atomsel('residue %s' % ' '.join([str(s) for s in set(residues)]))
        batch.set('resid', [k for k in range(1, len(batch)+1)])

        # Save the temporary ions file
        temp = tempfile.mkstemp(suffix='.pdb', prefix='psf_ions_',
                                dir=self.tmp_dir)[1]
        atomsel('name SOD CLA POT').set('user', 0.0) # mark as saved
        atomsel('name SOD CLA POT').write('pdb', temp)

        string = '''
       set ionfile %s
       segment I {
          pdb $ionfile
          first none
          last none
       }
       coordpdb $ionfile I
        ''' % temp
        self.file.write(string)
        molecule.set_top(old_top)
Exemplo n.º 17
0
    def _set_cell_to_square_prism(self, molid):
        """
        Sets the periodic box to be a square prism of specified dimension

        Args:
          molid (int): VMD molecule ID to consider
        """
        old_top = molecule.get_top()
        molecule.set_top(molid)
        molecule.set_periodic(-1, -1, self.size[0], self.size[1], self.size[2],
                              90.0, 90.0, 90.0)
        molecule.set_top(old_top)
Exemplo n.º 18
0
def _write_ordered_pdb(filename, sel, molid):
    """
    Writes a pdb file in order of residues, renumbering the atoms
    accordingly, since psfgen wants each residue sequentially while
    VMD will write them in the same order as input, which from Maestro
    created files has some guessed atoms at the end.

    Args:
      filename (str): Name of the pdb file to write
      sel (str): VMD atomsel string for atoms that will be written
      molid (int): VMD molecule ID to write from
    """
    old_top = molecule.get_top()
    molecule.set_top(molid)

    fileh = open(filename, 'w')
    # Use resids since order can be wrong when sorting by residue
    # Then, use residue to pull out each one since it is much much
    # faster then trying to pull out residues
    resids = set(atomsel(sel).get('resid'))

    # Add additional residue constraint to selection since pulling out
    # by resid can match something in a different chain
    resstr = ' '.join([str(x) for x in set(atomsel(sel).get('residue'))])

    idx = 1
    # For renumbering capping groups
    for resid in sorted(resids):
        # Check for alternate locations
        residues = sorted(set(atomsel("resid '%s' and residue %s"
                                      % (resid, resstr)).get('residue')))
        for rid in residues:
            for i in atomsel('residue %d' % rid).get('index'):
                a = atomsel('index %d' % i) # pylint: disable=invalid-name
                ins = a.get("insertion")[0]
                entry = ('%-6s%5d %-5s%-4s%c%4d%c   %8.3f%8.3f%8.3f%6.2f%6.2f'
                         '     %-4s%2s\n' % ('ATOM', idx, a.get('name')[0],
                                             a.get('resname')[0],
                                             a.get('chain')[0],
                                             a.get('resid')[0],
                                             ins if len(ins) else " ",
                                             a.get('x')[0],
                                             a.get('y')[0],
                                             a.get('z')[0],
                                             0.0, 0.0, a.get('segname')[0],
                                             a.get('element')[0]))
                idx += 1
                fileh.write(entry)
    fileh.write('END\n')
    atomsel(sel).set('user', 0.0) # Mark as written
    fileh.close()
    molecule.set_top(old_top)
Exemplo n.º 19
0
    def _set_cell_to_square_prism(self, molid):
        """
        Sets the periodic box to be a square prism of specified dimension

        Args:
          molid (int): VMD molecule ID to consider
        """
        old_top = molecule.get_top()
        molecule.set_top(molid)
        molecule.set_periodic(-1, -1,
                              self.size[0], self.size[1], self.size[2],
                              90.0, 90.0, 90.0)
        molecule.set_top(old_top)
Exemplo n.º 20
0
    def _write_lipid_blocks(self):
        """
        Writes a temporary PDB file containing the lipids for later use by
        psfgen. Renumbers the lipid residues because some can have **** instead
        of an integer for resid in large systems, which will crash psfgen. Also
        sets atom names for some common lipids (currently POPC)

        Raises:
            NotImplementedError if more than 10,000 lipids are present since it
              doesn't support feeding multiple lipid blocks to psfgen currently
            NotImplementedError if lipid other than POPC,POPE,POPG is found
        """
        # Put current molecule on top to simplify atom selection
        old_top = molecule.get_top()
        molecule.set_top(self.molid)

        # Collect lipid residues up
        alll = atomsel('(%s) and user 1.0' % self.lipid_sel)
        residues = list(set(alll.residue))

        # Lipids not compatible with AMBER parameters, CHARMM format
        if alll and ("amber" in self.forcefield or "opls" in self.forcefield):
            raise ValueError(
                "AMBER or OPLS parameters not supported for lipids"
                " in CHARMM output format")

        # Sanity check for < 10k lipids
        if len(residues) >= 10000:
            raise NotImplementedError("More than 10k lipids found")

        # Loop through all residues and renumber and correctly name them
        lipress = []
        for resname in set(alll.resname):
            lipress.extend(self._rename_by_resname(resname, renumber=True))

        # Write temporary lipid pdb
        _, temp = tempfile.mkstemp(suffix='.pdb',
                                   prefix='psf_lipid_',
                                   dir=self.tmp_dir)
        os.close(_)

        saved_lips = atomsel("residue %s" % ' '.join(str(_) for _ in lipress))
        saved_lips.user = 0.0
        saved_lips.write('pdb', temp)

        # Generate lipid segment
        self.psfgen.add_segment(segid="L", pdbfile=temp)
        self.psfgen.read_coords(segid="L", filename=temp)

        # Put old top back
        molecule.set_top(old_top)
Exemplo n.º 21
0
    def _write_ion_blocks(self):
        """
        Writes a PDB file containing correctly named ions for use by
        psfgen, and instructs psfgen to use it in TCL code.
        """

        # Put our molecule on top to simplify atom selection language
        old_top = molecule.get_top()
        molecule.set_top(self.molid)

        # Get ion resids that aren't associated w other molecules
        # because some ligands have Na, Cl, K
        total = atomsel('element Na Cl K')
        not_ions = atomsel("(same fragment as element Na Cl K)  and (not index %s)"
                           % " ".join([str(s) for s in set(total.get('index'))]))
        ions = set(total.get('residue')) - set(not_ions.get('residue'))

        if not len(ions):
            return
        ionstr = "residue " + " ".join([str(s) for s in ions])

        # Fix the names
        atomsel('%s and name NA' % ionstr).set('name', 'SOD')
        atomsel('%s and name CL' % ionstr).set('name', 'CLA')
        atomsel('%s and name K' % ionstr).set('name', 'POT')
        atomsel('%s and name NA' % ionstr).set('resname', 'SOD')
        atomsel('%s and name CL' % ionstr).set('resname', 'CLA')
        atomsel('%s and name K' % ionstr).set('resname', 'POT')

        # Renumber the residues since some may be above 10k
        residues = atomsel('name SOD CLA POT').get('residue')
        batch = atomsel('residue %s' % ' '.join([str(s) for s in set(residues)]))
        batch.set('resid', [k for k in range(1, len(batch)+1)])

        # Save the temporary ions file
        temp = tempfile.mkstemp(suffix='.pdb', prefix='psf_ions_',
                                dir=self.tmp_dir)[1]
        atomsel('name SOD CLA POT').set('user', 0.0) # mark as saved
        atomsel('name SOD CLA POT').write('pdb', temp)

        string = '''
       set ionfile %s
       segment I {
          pdb $ionfile
          first none
          last none
       }
       coordpdb $ionfile I
        ''' % temp
        self.file.write(string)
        molecule.set_top(old_top)
Exemplo n.º 22
0
def test_mol_attrs(file_3nob):

    m1 = molecule.load("mae", file_3nob)
    m2 = molecule.load("mae", file_3nob)

    # Get/set top
    assert molecule.get_top() == m2
    molecule.set_top(molid=m1)
    assert molecule.get_top() == m1
    with pytest.raises(ValueError):
        molecule.set_top(m2+1)

    # Get/set visibility
    molecule.set_visible(m1, visible=False)
    assert molecule.get_visible() == False
    assert molecule.get_visible(molid=m2) == True

    with pytest.warns(DeprecationWarning):
        molecule.set_visible(m1, state=True)
    assert molecule.get_visible(molid=m1) == True

    with pytest.raises(ValueError):
        molecule.set_visible(m2+1, True)
    with pytest.raises(TypeError):
        molecule.set_visible(m2, 3)
    with pytest.raises(ValueError):
        molecule.get_visible(m2+1)

    # Get/set periodic
    assert molecule.get_periodic(m2) == {'a': 1.0, 'alpha': 90.0, 'b': 1.0,
                                         'beta': 90.0, 'c': 1.0, 'gamma':
                                         90.0}
    with pytest.raises(ValueError):
        molecule.get_periodic(molid=m1, frame=3000)

    with pytest.raises(ValueError):
        molecule.set_periodic(molid=m2+1, a=2.0)
    with pytest.raises(ValueError):
        molecule.set_periodic(m1, frame=3000, a=20.0)

    molecule.set_periodic(m2, frame=0, a=90.0, b=90.0, c=90.0,
                          alpha=90.0, beta=90.0, gamma=90.0)
    assert list(molecule.get_periodic(m2, frame=0).values()) == [pytest.approx(90.0)]*6
    assert set(molecule.get_periodic(m1, frame=0).values()) != [pytest.approx(90.0)]*6
    molecule.set_periodic(c=20.0)

    assert molecule.get_periodic()["c"] == pytest.approx(20.0)

    molecule.delete(m1)
    molecule.delete(m2)
Exemplo n.º 23
0
def _write_ordered_pdb(filename, sel, molid):
    """
    Writes a pdb file in order of residues, renumbering the atoms
    accordingly, since psfgen wants each residue sequentially while
    VMD will write them in the same order as input, which from Maestro
    created files has some guessed atoms at the end.

    Args:
      filename (str): Name of the pdb file to write
      sel (str): VMD atomsel string for atoms that will be written
      molid (int): VMD molecule ID to write from
    """
    old_top = molecule.get_top()
    molecule.set_top(molid)

    fileh = open(filename, 'w')
    # Use resids since order can be wrong when sorting by residue
    # Then, use residue to pull out each one since it is much much
    # faster then trying to pull out residues
    resids = set(atomsel(sel).get('resid'))

    # Add additional residue constraint to selection since pulling out
    # by resid can match something in a different chain
    resstr = ' '.join([str(x) for x in set(atomsel(sel).get('residue'))])

    idx = 1
    # For renumbering capping groups
    for resid in sorted(resids):
        rid = atomsel("resid '%s' and residue %s"
                      % (resid, resstr)).get('residue')[0]

        for i in atomsel('residue %d' % rid).get('index'):
            a = atomsel('index %d' % i) # pylint: disable=invalid-name
            entry = ('%-6s%5d %-5s%-4s%c%4d    %8.3f%8.3f%8.3f%6.2f%6.2f'
                     '     %-4s%2s\n' % ('ATOM', idx, a.get('name')[0],
                                         a.get('resname')[0],
                                         a.get('chain')[0],
                                         a.get('resid')[0],
                                         a.get('x')[0],
                                         a.get('y')[0],
                                         a.get('z')[0],
                                         0.0, 0.0, a.get('segname')[0],
                                         a.get('element')[0]))
            idx += 1
            fileh.write(entry)
    fileh.write('END\n')
    atomsel(sel).set('user', 0.0) # Mark as written
    fileh.close()
    molecule.set_top(old_top)
Exemplo n.º 24
0
    def write(self, filename):
        """
        Writes the parameter and topology files

        Args:
            filename (str): File name to write. File type suffix will be added.
        """
        self.outprefix = filename

        # Put our molecule on top
        old_top = molecule.get_top()
        molecule.set_top(self.molid)

        # Amber forcefield done with AmberWriter then conversion
        if "amber" in self.forcefield:
            # Avoid circular import by doing it here
            from dabble.param import AmberWriter
            prmtopgen = AmberWriter(molid=self.molid,
                                    tmp_dir=self.tmp_dir,
                                    forcefield=self.forcefield,
                                    water_model=self.water_model,
                                    hmr=self.hmr,
                                    lipid_sel=self.lipid_sel,
                                    extra_topos=self.extra_topos,
                                    extra_params=self.extra_params,
                                    override_defaults=self.override,
                                    debug_verbose=self.debug)
            prmtopgen.write(self.outprefix)
            self._prmtop_to_charmm()

        # Charmm forcefield
        elif "charmm" in self.forcefield:
            self._run_psfgen()

        # OPLS forcefield. Same as charmm but list separately for readability
        elif "opls" in self.forcefield:
            self._run_psfgen()

        else:
            raise DabbleError("Unsupported forcefield '%s' for CharmmWriter" %
                              self.forcefield)

        # Check output and finish up
        self._check_psf_output()

        # Reset top molecule
        molecule.set_top(old_top)
Exemplo n.º 25
0
def test_covalent_ligand_gromacs_charmm(tmpdir):
    from vmd import atomsel, molecule
    from dabble.param import GromacsWriter

    # Parameterize with charmm parameters
    p = str(tmpdir)
    molid = molecule.load(
        "mae", os.path.join(dir, "rho_arr_CYP_prepped_aligned_dowsered.mae"))

    w = GromacsWriter(tmp_dir=p,
                      molid=molid,
                      forcefield="charmm",
                      extra_topos=[os.path.join(dir, "CYP_v1.str")])
    w.write(os.path.join(p, "test"))

    # Load the result
    m2 = molecule.load("gro", os.path.join(p, "test.gro"))
    molecule.set_top(m2)

    # Sanity check the system was built completely
    assert len(set(atomsel("protein or resname ACE NMA").residue)) == 697
    assert len(atomsel("name N C O CA")) == 2784
    assert len(set(atomsel("resname ACE NMA").resid)) == 4
    assert len(atomsel("water")) == 654

    # Check for palmitoylation
    assert len(atomsel("resname CYP")) == 116
    assert set(atomsel("resname CYP").resid) == set([322, 323])

    # Check for protonation on Asp83
    assert len(atomsel("resid 83 and resname ASP")) == 13
    assert len(atomsel("resid 331 and resname ASP")) == 12

    # Check for protonation on Glu134A
    assert len(atomsel("resid 134 and resname GLU")) == 16
    assert len(atomsel("resid 247 and resname GLU")) == 15

    # Check that Ser98 is normal
    assert len(atomsel("resid 98 and resname SER")) == 11

    # Check for phosphorylation on Ser334
    assert len(atomsel("resid 334 and resname SER")) == 14

    # Check for phosphorylation on Ser338
    assert len(atomsel("resid 338 and resname SER")) == 14
Exemplo n.º 26
0
def test_amber_custom_residues(tmpdir):
    from Dabble.param import AmberWriter

    # Generate the file
    p = str(tmpdir.mkdir("3nob_custom"))
    molid = molecule.load("mae", os.path.join(dir, "prepped.mae"))
    w = AmberWriter(molid,
                    tmp_dir=p,
                    forcefield="amber",
                    hmr=False,
                    extra_topos=[
                        os.path.join(dir, "glx.off"),
                        os.path.join(dir, "lyx.off")
                    ],
                    extra_params=[
                        os.path.join(dir, "join.frcmod"),
                        os.path.join(dir, "analogies.frcmod")
                    ],
                    override_defaults=False)
    w.write(os.path.join(p, "test"))

    # Load the output file and start checking it
    m2 = molecule.load("parm7", os.path.join(p, "test.prmtop"), "rst7",
                       os.path.join(p, "test.inpcrd"))
    molecule.set_top(m2)

    # Check the two custom residues are present
    assert (len(atomsel("resname GLX")) == 7)
    assert (len(atomsel("resname LYX")) == 20)

    # Check the custom residues have gaff2 atom types
    assert ("n" in atomsel("resname LYX").get("type"))
    assert ("n2" in atomsel("resname GLX").get("type"))

    # Check the normal residues have ff14SB atom types
    assert ("N" in atomsel("resname LYS").get("type"))
    assert ("N" in atomsel("resname GLY").get("type"))

    # Check that the isopeptide bond is there
    lybonds = []
    for x in atomsel("resname LYX").bonds:
        lybonds.extend(x)
    assert (any(x in lybonds for x in atomsel("resname GLX").get("index")))
Exemplo n.º 27
0
def test_multiligand_amber(tmpdir):
    """
    Checks that multiple ligands work with AMBER.
    Should rename some atoms in matching
    """
    from vmd import atomsel, molecule
    from Dabble.param import AmberWriter

    # Parameterize the system. One atom name will be changed.
    p = str(tmpdir.mkdir("multiligand_amber"))
    molid = molecule.load("mae",
                          os.path.join(dir, "test_multiligand_correct.mae"))
    w = AmberWriter(tmp_dir=p,
                    molid=molid,
                    forcefield="amber",
                    extra_topos=[os.path.join(dir, "alp.off")],
                    extra_params=[os.path.join(dir, "alp.frcmod")])
    w.write(os.path.join(p, "test"))

    # Load the built system and see if it works
    m2 = molecule.load("parm7", os.path.join(p, "test.prmtop"), "rst7",
                       os.path.join(p, "test.inpcrd"))
    molecule.set_top(m2)

    # Check results
    assert len(set(atomsel("protein").get("resid"))) == 282
    assert len(set(atomsel("resname ACE NME").get("resid"))) == 4
    assert len(atomsel("water")) == 32106
    assert len(atomsel("same fragment as lipid")) == 12194

    # Check for the corrrect number of alprenolols
    assert len(atomsel("resname ALP")) == 420
    assert len(set(atomsel("resname ALP").get("resid"))) == 10
    assert "OX" in set(atomsel("resname ALP").get("name"))
    assert "O1" not in set(atomsel("resname ALP").get("name"))

    # Check coordinates are unique (not zero)
    # It's 419 because two of them have the same x
    assert len(atomsel("resname ALP")) == 420
    assert len(set(atomsel("resname ALP").get("x"))) == 419

    molecule.delete(m2)
Exemplo n.º 28
0
def _write_ordered_pdb(filename, sel, molid):
    """
    Writes a pdb file in order of residues, renumbering the atoms
    accordingly, since psfgen wants each residue sequentially while
    VMD will write them in the same order as input, which from Maestro
    created files has some guessed atoms at the end.

    Args:
      filename (str): Name of the pdb file to write
      sel (str): VMD atomsel string for atoms that will be written
      molid (int): VMD molecule ID to write from
    """
    old_top = molecule.get_top()
    molecule.set_top(molid)

    fileh = open(filename, 'w')
    # Use resids since order can be wrong when sorting by residue
    # Then, use residue to pull out each one since it is much much
    # faster then trying to pull out residues
    resids = set(atomsel(sel).resid)

    # Add additional residue constraint to selection since pulling out
    # by resid can match something in a different chain
    resstr = ' '.join([str(x) for x in set(atomsel(sel).residue)])

    idx = 1
    # For renumbering capping groups
    for resid in sorted(resids):
        # Check for alternate locations
        residues = sorted(
            set(
                atomsel("resid '%s' and residue %s" %
                        (resid, resstr)).residue))
        for rid in residues:
            for i in atomsel('residue %d' % rid).index:
                a = atomsel('index %d' % i)  # pylint: disable=invalid-name
                fileh.write(MoleculeWriter.get_pdb_line(a, idx, a.resid[0]))
                idx += 1
    fileh.write('END\n')
    atomsel(sel).user = 0.0
    fileh.close()
    molecule.set_top(old_top)
Exemplo n.º 29
0
def check_correctness(molid):
    """ Verifies molecule is sane """
    molecule.set_top(molid)

    # Check the protein is there with the correct capping groups
    assert len(atomsel("protein")) == 804
    assert len(set(atomsel("all").get("fragment"))) == 2
    assert len(set(atomsel("resname ACE NMA NME").get("residue"))) == 4

    # Check for 6 cysteines, 2 with same resid
    assert len(set(atomsel("resname CYS CYX").get("residue"))) == 6

    # Check connectivity between cysteines is correct
    for res in set(atomsel("resname CYS CYX").get("residue")):
        assert len(atomsel("residue %d" % res)) == 10
        assert len(atomsel("residue %d and name SG" % res)) == 1
        idxs = atomsel("residue %d and name SG" % res).bonds[0]
        assert set(atomsel("index %s"
                           % " ".join(str(i) for i in idxs)).get("name")) \
            == set(["CB", "SG"])
Exemplo n.º 30
0
def check_correctness(molid):
    """ Verifies molecule is sane """
    molecule.set_top(molid)

    # Check the protein is there with the correct capping groups
    assert len(atomsel("protein or resname ACE NMA NME")) == 828
    assert len(set(atomsel("all").fragment)) == 2
    assert len(set(atomsel("resname ACE NMA NME").residue)) == 4

    # Check for 6 cysteines, 2 with same resid
    assert len(set(atomsel("resname CYS CYX").residue)) == 6

    # Check connectivity between cysteines is correct
    for res in set(atomsel("resname CYS CYX").residue):
        assert len(atomsel("residue %d" % res)) == 10
        assert len(atomsel("residue %d and name SG" % res)) == 1
        idxs = atomsel("residue %d and name SG" % res).bonds[0]
        assert set(atomsel("index %s"
                           % " ".join(str(i) for i in idxs)).name) \
            == set(["CB", "SG"])
Exemplo n.º 31
0
def verify_amber(molid):

    molecule.set_top(molid)
    # Check the two custom residues are present
    assert len(atomsel("resname GLX")) == 7
    assert len(atomsel("resname LYX")) == 20

    # Check the custom residues have gaff2 atom types
    assert "n" in atomsel("resname LYX").type
    assert "n2" in atomsel("resname GLX").type

    # Check the normal residues have ff14SB atom types
    assert "N" in atomsel("resname LYS").type
    assert "N" in atomsel("resname GLY").type

    # Check that the isopeptide bond is there
    lybonds = []
    for x in atomsel("resname LYX").bonds:
        lybonds.extend(x)
    assert any(x in lybonds for x in atomsel("resname GLX").index)
Exemplo n.º 32
0
def test_gromacs_amber(tmpdir):
    from dabble.param import GromacsWriter

    p = str(tmpdir)
    molid = molecule.load("mae", os.path.join(dir, "prepped.mae"))
    w = GromacsWriter(molid,
                      tmp_dir=p,
                      forcefield="amber",
                      extra_topos=[
                          os.path.join(dir, "glx.off"),
                          os.path.join(dir, "lyx.off")
                      ],
                      extra_params=[
                          os.path.join(dir, "join.frcmod"),
                          os.path.join(dir, "analogies.frcmod")
                      ],
                      override_defaults=False)
    w.write(os.path.join(p, "test"))

    # Load and check the output file
    m2 = molecule.load("gro", os.path.join(p, "test.gro"))
    molecule.set_top(m2)

    # Check the two custom residues are present
    assert len(atomsel("resname GLX")) == 7
    assert len(atomsel("resname LYX")) == 20

    # Check that the isopeptide bond is there
    lybonds = []
    for x in atomsel("resname LYX").bonds:
        lybonds.extend(x)
    assert any(x in lybonds for x in atomsel("resname GLX").index)

    # Check the parameterized file with parmed API
    from parmed.formats.registry import load_file
    f = load_file(os.path.join(p, "test.top"))

    assert f.residues[153].name == "GLX"
    assert "n2" in [_.type for _ in f.residues[153].atoms]
    assert "n2" not in [_.type for _ in f.residues[152].atoms]
    assert "N" in [_.type for _ in f.residues[152].atoms]
Exemplo n.º 33
0
def test_multiligand_chamber(tmpdir):
    """
    Checks that multiple ligands work with AMBER.
    Should rename some atoms in matching
    """
    from vmd import atomsel, molecule
    from Dabble.param import AmberWriter

    # Parameterize the system. One atom name will be changed.
    p = str(tmpdir.mkdir("multiligand_amber"))
    molid = molecule.load("mae",
                          os.path.join(dir, "test_multiligand_correct.mae"))
    w = AmberWriter(tmp_dir=p,
                    molid=molid,
                    forcefield="charmm",
                    extra_topos=[os.path.join(dir, "alprenolol.rtf")],
                    extra_params=[os.path.join(dir, "alprenolol.prm")])
    w.write(os.path.join(p, "test"))

    # Load result
    m2 = molecule.load("psf", os.path.join(p, "test.psf"), "pdb",
                       os.path.join(p, "test.pdb"))
    molecule.set_top(m2)

    # Check results
    assert len(set(atomsel("protein").get("resid"))) == 282
    assert len(set(atomsel("resname ACE NMA").get("resid"))) == 4
    assert len(atomsel("water")) == 32106
    assert len(atomsel("same fragment as lipid")) == 12194

    # Check for the corrrect number of alprenolols
    assert len(atomsel("resname ALP")) == 420
    assert len(set(atomsel("resname ALP").get("resid"))) == 10
    assert "O1" in set(atomsel("resname ALP").get("name"))
    assert "OX" not in set(atomsel("resname ALP").get("name"))

    # Check coordinates are unique (not zero)
    # Two atoms have the same X but that is okay
    assert len(set(atomsel("resname ALP").get("x"))) == 419

    molecule.delete(m2)
Exemplo n.º 34
0
def test_hmr_param(tmpdir):
    """
    Tests phosphorylations on Ser
    Also checks HMR
    """
    from Dabble.param import AmberWriter
    from vmd import atomsel, molecule

    # Build the system with HMR
    p = str(tmpdir.mkdir("hmr_param"))
    molid = molecule.load("mae", os.path.join(dir, "rho_test.mae"))
    w = AmberWriter(tmp_dir=p, molid=molid, hmr=True,
                    extra_topos=[], extra_params=[])
    w.write(os.path.join(p, "test"))

    # Load the built system for checking
    # Use psf so we can check HMR was done correctly
    m2 = molecule.load("psf", os.path.join(p, "test.psf"))
    m3 = molecule.load("parm7", os.path.join(p, "test.prmtop"))

    # Check the protein is there with correct capping groups
    assert len(atomsel("protein", m2)) == 299
    assert len(atomsel("protein", m3)) == 299
    assert len(set(atomsel("resname ACE NMA", m2).get("resid"))) == 2
    assert len(set(atomsel("resname ACE NMA", m3).get("resid"))) == 2

    # Check for 3 phosphoserines and no regular serines
    molecule.set_top(m2)
    assert atomsel("resname SER").get("name").count("P") == 3
    assert not atomsel("resname SER and not same residue as name P")

    # Check for one phosphothreonine
    assert len(set(atomsel("resname THR").get("resid"))) == 3
    assert len(atomsel("resname THR and name P")) == 1

    # Check HMR was done correctly
    minmasspre = min(atomsel("all", m2).get("mass"))
    minmasspost = min(atomsel("all", m3).get("mass"))
    assert abs(minmasspre - 1.008) < 0.0001
    assert abs(minmasspost - 1.008) > 0.0001
Exemplo n.º 35
0
def test_multiligand_parameterizing(tmpdir):
    """
    Checks the parameterization of a system with multiple ligands
    """
    from vmd import atomsel, molecule
    from Dabble.param import CharmmWriter

    # Parameterize the multiple ligand system with charmm parameters
    p = str(tmpdir.mkdir("multiligand_parameterize"))
    molid = molecule.load("mae",
                          os.path.join(dir, "test_multiligand_correct.mae"))
    w = CharmmWriter(tmp_dir=p,
                     molid=molid,
                     lipid_sel="lipid",
                     extra_topos=[os.path.join(dir, "alprenolol.rtf")])
    w.write(os.path.join(p, "test"))

    # Load the created file
    m2 = molecule.load("psf", os.path.join(p, "test.psf"), "pdb",
                       os.path.join(p, "test.pdb"))
    molecule.set_top(m2)

    # Check the system is intact
    assert len(set(atomsel("protein").get("resid"))) == 282
    assert len(set(atomsel("resname ACE NMA").get("resid"))) == 4
    assert len(atomsel("water")) == 32106
    assert len(atomsel("lipid")) == 12194

    # Check for the correct number of alprenolols
    assert len(atomsel("resname ALP")) == 420
    assert set(atomsel("resname ALP").get("resid")) == set(range(1, 11))

    # Check coordinates are unique (not zero)
    # It's 419 because two of them have the same x
    assert len(atomsel("resname ALP")) == 420
    assert len(set(atomsel("resname ALP").get("x"))) == 419

    molecule.delete(m2)
Exemplo n.º 36
0
def combine_molecules(input_ids, tmp_dir):
    """
    Combines input molecules, closes them and returns the molecule id
    of the new molecule that combines them, putting it on top.

    Args:
      input_ids (list of int): Molecule IDs to combine, will be closed
      tmp_dir (str): Directory to put combined molecule into

    Returns:
      (int) molid of combined system
    """

    output_filename = tempfile.mkstemp(suffix='.mae',
                                       prefix='dabble_combine',
                                       dir=tmp_dir)[1]
    concatenate_mae_files(output_filename, input_ids=input_ids)
    output_id = molecule.load('mae', output_filename)
    molecule.set_top(output_id)
    for i in input_ids:
        molecule.delete(i)
    atomsel('all', molid=output_id).beta = 1
    return output_id
Exemplo n.º 37
0
def combine_molecules(input_ids, tmp_dir):
    """
    Combines input molecules, closes them and returns the molecule id
    of the new molecule that combines them, putting it on top.

    Args:
      input_ids (list of int): Molecule IDs to combine, will be closed
      tmp_dir (str): Directory to put combined molecule into

    Returns:
      (int) molid of combined system
    """

    output_filename = tempfile.mkstemp(suffix='.mae',
                                       prefix='dabble_combine',
                                       dir=tmp_dir)[1]
    fileutils.concatenate_mae_files(output_filename, input_ids=input_ids)
    output_id = molecule.load('mae', output_filename)
    molecule.set_top(output_id)
    for i in input_ids:
        molecule.delete(i)
    atomsel('all', molid=output_id).set('beta', 1)
    return output_id
Exemplo n.º 38
0
def test_amber_custom_residues(tmpdir):
    from Dabble.param import AmberWriter

    # Generate the file
    p = str(tmpdir.mkdir("3nob_custom"))
    molid = molecule.load("mae", os.path.join(dir, "prepped.mae"))
    w = AmberWriter(molid, tmp_dir=p, forcefield="amber", hmr=False,
                    extra_topos=[os.path.join(dir, "glx.off"),
                                 os.path.join(dir, "lyx.off")],
                    extra_params=[os.path.join(dir, "join.frcmod"),
                                  os.path.join(dir, "analogies.frcmod")],
                    override_defaults=False)
    w.write(os.path.join(p, "test"))

    # Load the output file and start checking it
    m2 = molecule.load("parm7", os.path.join(p, "test.prmtop"),
                       "rst7", os.path.join(p, "test.inpcrd"))
    molecule.set_top(m2)

    # Check the two custom residues are present
    assert(len(atomsel("resname GLX")) == 7)
    assert(len(atomsel("resname LYX")) == 20)

    # Check the custom residues have gaff2 atom types
    assert("n" in atomsel("resname LYX").get("type"))
    assert("n2" in atomsel("resname GLX").get("type"))

    # Check the normal residues have ff14SB atom types
    assert("N" in atomsel("resname LYS").get("type"))
    assert("N" in atomsel("resname GLY").get("type"))

    # Check that the isopeptide bond is there
    lybonds = []
    for x in atomsel("resname LYX").bonds:
        lybonds.extend(x)
    assert(any(x in lybonds for x in atomsel("resname GLX").get("index")))
Exemplo n.º 39
0
    def _write_generic_block(self, residues):
        """
        Matches ligands to available topology file, renames atoms, and then
        writes temporary files for the ligands

        Args:
          residues (list of int): Residue numbers to be written. Will all
            be written to one segment.

        Returns:
          True if successful
        """
        # Put our molecule on top to simplify atom selection language
        old_top = molecule.get_top()
        molecule.set_top(self.molid)

        alig = atomsel('user 1.0 and residue %s' % " ".join([str(x) for x in residues]))

        # Write temporary file containg the residues and update tcl commands
        temp = tempfile.mkstemp(suffix='.pdb', prefix='psf_block_',
                                dir=self.tmp_dir)[1]
        string = '''
       set blockfile %s
       segment B%s {
         pdb $blockfile
         first none
         last none
       }
       coordpdb $blockfile B%s
        ''' % (temp, residues[0], residues[0])
        alig.write('pdb', temp)
        alig.set('user', 0.0)
        self.file.write(string)
        if old_top != -1:
            molecule.set_top(old_top)
        return True
Exemplo n.º 40
0
def test_water_box(tmpdir):
    """
    Tests building in a water box only
    """
    from Dabble import DabbleBuilder
    from Dabble import molutils
    from vmd import molecule

    # Build a system with well defined dimensions
    p = str(tmpdir.mkdir("po4_hmr"))
    filename = os.path.join(dir, "rho_test.mae")
    b = DabbleBuilder(solute_filename=filename,
                      output_filename=os.path.join(p, "test.mae"),
                      membrane_system="TIP3",
                      user_x=40.0, user_y=35.0, user_z = 65.0,
                      tmp_dir=p)
    b.write()

    # Load the built system for checking
    m2 = molecule.load("mae", os.path.join(p, "test.mae"))
    molecule.set_top(m2)

    # Check the system dimensions
    assert molutils.get_system_dimensions(m2) == (40.0, 35.0, 65.0)
Exemplo n.º 41
0
    def _write_generic_block(self, residues):
        """
        Matches ligands to available topology file, renames atoms, and then
        writes temporary files for the ligands

        Args:
          residues (list of int): Residue numbers to be written. Will all
            be written to one segment.

        Returns:
          True if successful
        """
        # Put our molecule on top to simplify atom selection language
        old_top = molecule.get_top()
        molecule.set_top(self.molid)

        alig = atomsel('user 1.0 and residue %s' %
                       " ".join([str(x) for x in residues]))

        # Write temporary file containg the residues and update tcl commands
        _, temp = tempfile.mkstemp(suffix='.pdb',
                                   prefix='psf_block_',
                                   dir=self.tmp_dir)
        os.close(_)
        alig.write('pdb', temp)
        alig.user = 0.0

        # Get next available segment name
        segname = "B%d" % self.segint
        self.segint += 1
        self.psfgen.add_segment(segid=segname, pdbfile=temp)
        self.psfgen.read_coords(segid=segname, filename=temp)

        if old_top != -1:
            molecule.set_top(old_top)
        return True
Exemplo n.º 42
0
    def _write_generic_block(self, residues):
        """
        Matches ligands to available topology file, renames atoms, and then
        writes temporary files for the ligands

        Args:
          residues (list of int): Residue numbers to be written. Will all
            be written to one segment.

        Returns:
          True if successful
        """
        # Put our molecule on top to simplify atom selection language
        old_top = molecule.get_top()
        molecule.set_top(self.molid)

        alig = atomsel('user 1.0 and residue %s' % " ".join([str(x) for x in residues]))

        # Write temporary file containg the residues and update tcl commands
        temp = tempfile.mkstemp(suffix='.pdb', prefix='psf_block_',
                                dir=self.tmp_dir)[1]
        string = '''
       set blockfile %s
       segment B%s {
         pdb $blockfile
         first none
         last none
       }
       coordpdb $blockfile B%s
        ''' % (temp, residues[0], residues[0])
        alig.write('pdb', temp)
        alig.set('user', 0.0)
        self.file.write(string)
        if old_top != -1:
            molecule.set_top(old_top)
        return True
Exemplo n.º 43
0
    def _find_single_residue_names(self, resname, molid):
        """
        Uses graph matcher and available topologies to match up
        ligand names automatically. Tries to use graphs, and if there's an
        uneven number of atoms tries to match manually to suggest which atoms
        are most likely missing.

        Args:
          resname (str): Residue name of the ligand that will be written.
            All ligands will be checked separately against the graphs.
          molid (int): VMD molecule ID to consider

        Returns:
          (list of ints): Residue numbers (not resid) of all input ligands
            that were successfully matched. Need to do it this way since
            residue names can be changed in here to different things.

        Raises:
          ValueError if number of resids does not match number of residues as
            interpreted by VMD
          NotImplementedError if a residue could not be matched to a graph.
        """
        # Put our molecule on top
        old_top = molecule.get_top()
        molecule.set_top(molid)

        # Sanity check that there is no discrepancy between defined resids and
        # residues as interpreted by VMD.
        for chain in set(atomsel("user 1.0 and resname '%s'" % resname).get('chain')):
            residues = list(set(atomsel("user 1.0 and resname '%s' and chain %s"
                                        % (resname, chain)).get('residue')))
            resids = list(set(atomsel("user 1.0 and resname '%s' and chain %s"
                                      % (resname, chain)).get('resid')))
            if len(residues) != len(resids):
                raise ValueError("VMD found %d residues for resname '%s', but there "
                                 "are %d resids! Check input." % (len(residues), resname,
                                                                  len(resids)))

        for residue in residues:
            sel = atomsel("residue %s and resname '%s' and user 1.0" % (residue, resname))
            (newname, atomnames) = self.matcher.get_names(sel, print_warning=True)
            if not newname:
                (resname, patch, atomnames) = self.matcher.get_patches(sel)
                if not newname:
                    print("ERROR: Could not find a residue definition for %s:%s"
                          % (resname, residue))
                    raise NotImplementedError("No residue definition for %s:%s"
                                              % (resname, residue))
                print("\tApplying patch %s to ligand %s" % (patch, newname))

            # Do the renaming
            for idx, name in atomnames.items():
                atom = atomsel('index %s' % idx)
                if atom.get('name')[0] != name and "+" not in name and \
                   "-" not in name:
                    print("Renaming %s:%s: %s -> %s" % (resname, residue,
                                                        atom.get('name')[0],
                                                        name))
                    atom.set('name', name)
            sel.set('resname', newname)

        #logger.info("Renamed %d atoms for all resname %s->%s" % (num_renamed, resname, name))
        molecule.set_top(old_top)

        return residues
Exemplo n.º 44
0
def test_bonds(file_3nob):
    with pytest.raises(ValueError):
        topology.bonds(molid=0)

    m = molecule.load("mae", file_3nob)
    molecule.set_top(m)

    with pytest.raises(ValueError):
        topology.bonds(molid=m, type=3, order=True)

    with pytest.warns(DeprecationWarning):
        x = topology.bonds(molid=m, type=3)
        assert len(x) == 2493
        assert x[0] == (0, 1, None, 1.0)

    with pytest.warns(DeprecationWarning):
        x = topology.bonds(molid=m, type=2)
        assert len(x) == 2493
        assert x[0] == (0, 1, 1.0)

    with pytest.warns(DeprecationWarning):
        x = topology.bonds(molid=m, type=1)
        assert len(x) == 2493
        assert x[0] == (0, 1, None)

    x = topology.bonds(molid=m, type=True)
    assert len(x) == 2493
    assert x[0] == (0, 1, None)

    x = topology.bonds(molid=m, type=False, order=True)
    assert len(x) == 2493
    assert x[0] == (0, 1, 1.0)

    x = topology.bonds(molid=m, type=True, order=True)
    assert len(x) == 2493
    assert x[0] == (0, 1, None, 1.0)

    x = topology.bonds(molid=m)
    assert len(x) == 2493
    assert len(x[0]) == 2
    assert (0, 1) in x

    # Test adding a bond
    assert (0, 2) not in x
    topology.addbond(i=0, j=2, molid=-1)
    assert (0, 2, None, 1.0) in topology.bonds(molid=m, order=True, type=True)

    assert (2, 3) not in x
    assert topology.bondtypes(m) == []
    topology.addbond(i=2, j=3, molid=m, order=2.0, type="test")
    assert (2, 3, "test", 2.0) in topology.bonds(molid=m, order=True, type=True)
    assert topology.bondtypes(m) == ["test"]

    # Test deleting a bond
    assert topology.delbond(i=2, j=0, molid=m)
    assert (0, 2) not in topology.bonds(molid=m)

    assert not topology.delbond(0, 0, molid=m)
    assert topology.delbond(i=2, j=3)
    assert topology.bondtypes(m) == ["test"] # bond type not deleted

    with pytest.raises(ValueError):
        topology.delbond(i=-1, j=5, molid=m)

    with pytest.raises(ValueError):
        topology.delbond(i=0, j=1, molid=-5)

    with pytest.raises(ValueError):
        topology.delallbonds(molid=2389182)

    assert topology.delallbonds(m) == 2493
    assert len(topology.bonds(m)) == 0
    assert topology.delallbonds(m) == 0

    molecule.delete(m)
Exemplo n.º 45
0
    def _write_protein_blocks(self, molid, frag):
        """
        Writes a protein fragment to a pdb file for input to psfgen
        Automatically assigns amino acid names

        Args:
            molid (int): VMD molecule ID of renumbered protein
            frag (str): Fragment to write

        Returns:
            (list of str): Patches to add to the psfgen input file
                after all proteins have been loaded
       """

        print("Setting protein atom names")

        # Put our molecule on top to simplify atom selection language
        old_top = molecule.get_top()
        molecule.set_top(molid)
        patches = set()
        extpatches = set()
        seg = "P%s" % frag

        residues = list(set(atomsel("fragment '%s'" % frag).get('residue')))
        for residue in residues:
            sel = atomsel('residue %s' % residue)
            resid = sel.get('resid')[0]
            # Only try to match single amino acid if there are 1 or 2 bonds
            if len(self.matcher.get_extraresidue_atoms(sel)) < 3:
                (newname, atomnames) = self.matcher.get_names(sel,
                                                              print_warning=False)

            # See if it's a disulfide bond participant
            else:
                (newname, patchline, atomnames) = \
                        self.matcher.get_disulfide("residue %d" % residue,
                                                   frag, molid)
                if newname:
                    extpatches.add(patchline)

            # Couldn't find a match. See if it's a patched residue
            if not newname:
                (newname, patch, atomnames) = self.matcher.get_patches(sel)
                if newname:
                    patches.add("patch %s %s:%d\n" % (patch, seg, resid))

            # Fall through to error condition
            if not newname:
                raise ValueError("Couldn't find a patch for %s:%s"
                                 % (sel.get('resname')[0], resid))

            # Do the renaming
            for idx, name in atomnames.items():
                atom = atomsel('index %s' % idx)
                if atom.get('name')[0] != name and "+" not in name and \
                   "-" not in name:
                    atom.set('name', name)
            sel.set('resname', newname)

        # Save protein chain in the correct order
        filename = self.tmp_dir + '/psf_protein_%s.pdb' % seg
        _write_ordered_pdb(filename, "fragment '%s'" % frag, molid)
        print("\tWrote %d atoms to the protein segment %s"
              % (len(atomsel("fragment %s" % frag)), seg))

        # Now write to psfgen input file
        string = '''
        set protnam %s
        segment %s {
          first none
          last none
          pdb $protnam
        }
        ''' % (filename, seg)
        self.file.write(string)

        print("Applying the following single-residue patches to P%s:\n" % frag)
        print("\t%s" % "\t".join(patches))
        self.file.write(''.join(patches))
        self.file.write("\n")

        self.file.write("coordpdb $protnam %s\n" % seg)

        if old_top != -1:
            molecule.set_top(old_top)

        return extpatches
Exemplo n.º 46
0
    def _renumber_protein_chains(self, molid):
        """
        Pulls all protein fragments and renumbers the residues
        so that ACE and NMA caps appear to be different residues to VMD.
        This is necessary so that they don't appear as patches. Proteins with
        non standard capping groups will have the patches applied.

        Args:
            molid (int): VMD molecule ID of entire system
        Returns:
            (int): Molid of loaded fragment
        """
        # Put our molecule on top and grab selection
        old_top = molecule.get_top()
        molecule.set_top(molid)

        for frag in set(atomsel("protein or resname ACE NMA").get("fragment")):
            fragment = atomsel('fragment %s' % frag, molid=molid)

            print("Checking capping groups resids on protein fragment %d" % frag)
            for resid in sorted(set(fragment.get("resid"))):
                # Handle bug where capping groups in same residue as the
                # neighboring amino acid Maestro writes it this way for some
                # reason but it causes problems down the line when psfgen doesn't
                # understand the weird combined residue
                rid = atomsel("fragment '%s' and resid '%d'"
                              % (frag, resid)).get('residue')[0]
                names = set(atomsel('residue %d'% rid).get('resname'))
                assert len(names) < 3, ("More than 2 residues with same number... "
                                        "currently unhandled. Report a bug")

                if len(names) > 1:
                    if 'ACE' in names and 'NMA' in names:
                        print("ERROR: Both ACE and NMA were given the same resid"
                              "Check your input structure")
                        quit(1)

                    if 'ACE' in names:
                        # Set ACE residue number as one less
                        resid = atomsel('residue %d and not resname ACE' % rid).get('resid')[0]
                        if len(atomsel("fragment '%s' and resid %d" % (frag, resid-1))):
                            raise ValueError('ACE resid collision number %d' % (resid-1))
                        atomsel('residue %d and resname ACE'
                                % rid).set('resid', resid-1)
                        print("\tACE %d -> %d" % (resid, resid-1))

                    elif 'NMA' in names:
                        # Set NMA residue number as one more
                        resid = int(atomsel('residue %d and not resname NMA' % rid).get('resid')[0])
                        if len(atomsel("fragment '%s' and resid %d" % (frag, resid+1))):
                            raise ValueError("NMA resid collision number %d" % (resid+1))

                        atomsel('residue %d and resname NMA'
                                % rid).set('resid', resid+1)
                        print("\tNMA %d -> %d" % (resid, resid+1))

        # Have to save and reload so residues are parsed correctly by VMD
        temp = tempfile.mkstemp(suffix='_renum.mae',
                                prefix='psf_prot_', dir=self.tmp_dir)[1]
        atomsel("same fragment as protein or resname ACE NMA").write('mae', temp)
        prot_molid = molecule.load('mae', temp)

        # Put things back the way they were
        if old_top != -1:
            molecule.set_top(old_top)
        return prot_molid
Exemplo n.º 47
0
    def get_cell_size(self,
                      mem_buf, wat_buf,
                      molid=None,
                      filename=None,
                      zh_mem_full=_MEMBRANE_FULL_THICKNESS / 2.0,
                      zh_mem_hyd=_MEMBRANE_HYDROPHOBIC_THICKNESS / 2.0):
        """
        Gets the cell size of the final system given initial system and
        buffers. Detects whether or not a membrane is present. Sets the
        size of the system.

        Args:
          mem_buf (float) : Membrane (xy) buffer amount
          wat_buf (float) : Water (z) buffer amount
          molid (int) : VMD molecule ID to consider (can't use with filename)
          filename (str) : Filename of system to consider (can't use w molid)
          zh_mem_full (float) : Membrane thickness
          zh_mem_hyd (float) : Membrane hydrophobic region thickness

        Returns:
        return dx_sol, dy_sol, dx_tm, dy_tm, dz_full
          (float tuple): x solute dimension, y solute dimension,
            TM x solute dimension, TM y solute dimension, solute z dimension

        Raises:
          ValueError: if filename and molid are both specified
        """

        # Sanity check
        if filename is not None and molid is not None:
            raise ValueError("Specified molid and filename to get_cell_size")

        if filename is not None:
            top = molecule.get_top()
            molid = molecule.read(-1, 'mae', filename)
        elif molid is None:
            molid = molecule.get_top()

        # Some options different for water-only systems (no lipid)
        if self.water_only:
            solute_z = atomsel(self.solute_sel, molid=molid).get('z')
            dx_tm = 0.0
            dy_tm = 0.0
            sol_solute = atomsel(self.solute_sel, molid)
        else:
            solute_z = atomsel(self.solute_sel, molid=molid).get('z')
            tm_solute = atomsel('(%s) and z > %f and z < %f' % (self.solute_sel,
                                                                -zh_mem_hyd,
                                                                zh_mem_hyd), molid)
            if len(tm_solute):
                dx_tm = max(tm_solute.get('x')) - min(tm_solute.get('x'))
                dy_tm = max(tm_solute.get('y')) - min(tm_solute.get('y'))
            else:
                dx_tm = dy_tm = 0

            sol_solute = atomsel('(%s) and (z < %f or z > %f)' % (self.solute_sel,
                                                                  -zh_mem_hyd,
                                                                  zh_mem_hyd), molid)

        # Solvent invariant options
        dx_sol = max(sol_solute.get('x')) - min(sol_solute.get('x'))
        dy_sol = max(sol_solute.get('y')) - min(sol_solute.get('y'))

        if self.opts.get('user_x'):
            self.size[0] = self.opts['user_x']
        else:
            self.size[0] = max(dx_tm + 2.*mem_buf, dx_sol + 2.*wat_buf)
        if self.opts.get('user_y'):
            self.size[1] = self.opts['user_y']
        else:
            self.size[1] = max(dy_tm + 2.*mem_buf, dy_sol + 2.*wat_buf)

        # Z dimension. If there's a membrane, need to account for asymmetry
        # in the Z dimension where the protein could be uneven in the membrane
        # or even peripheral
        if self.opts.get('user_z'):
            self.size[2] = self.opts['user_z']
            buf = (self.opts['user_z'] - max(solute_z) + min(solute_z))/2
            self._zmax = max(solute_z) + buf
            self._zmin = min(solute_z) - buf
            if zh_mem_full > self._zmax or -zh_mem_full < self._zmin:
                raise ValueError("Specified user z of %f is too small to "
                                 "accomodate protein and membrane!"
                                 % self.opts['user_z'])
        else:
            if self.water_only:
                self._zmax = max(solute_z) + wat_buf
                self._zmin = min(solute_z) - wat_buf
            else:
                self._zmax = max(max(solute_z)+wat_buf, zh_mem_full)
                self._zmin = min(min(solute_z)-wat_buf, -zh_mem_full)
            self.size[2] = self._zmax - self._zmin

        # Cleanup temporary file, if read in
        if filename is not None:
            molecule.delete(molid)
            if top != -1:
                molecule.set_top(top)

        return dx_sol, dy_sol, dx_tm, dy_tm, max(solute_z)-min(solute_z)
Exemplo n.º 48
0
    def get_cell_size(self,
                      mem_buf,
                      wat_buf,
                      molid=None,
                      filename=None,
                      zh_mem_full=_MEMBRANE_FULL_THICKNESS / 2.0,
                      zh_mem_hyd=_MEMBRANE_HYDROPHOBIC_THICKNESS / 2.0):
        """
        Gets the cell size of the final system given initial system and
        buffers. Detects whether or not a membrane is present. Sets the
        size of the system.

        Args:
          mem_buf (float) : Membrane (xy) buffer amount
          wat_buf (float) : Water (z) buffer amount
          molid (int) : VMD molecule ID to consider (can't use with filename)
          filename (str) : Filename of system to consider (can't use w molid)
          zh_mem_full (float) : Membrane thickness
          zh_mem_hyd (float) : Membrane hydrophobic region thickness

        Returns:
        return dx_sol, dy_sol, dx_tm, dy_tm, dz_full
          (float tuple): x solute dimension, y solute dimension,
            TM x solute dimension, TM y solute dimension, solute z dimension

        Raises:
          ValueError: if filename and molid are both specified
        """

        # Sanity check
        if filename is not None and molid is not None:
            raise ValueError("Specified molid and filename to get_cell_size")

        if filename is not None:
            top = molecule.get_top()
            molid = molecule.read(-1, 'mae', filename)
        elif molid is None:
            molid = molecule.get_top()

        # Some options different for water-only systems (no lipid)
        if self.water_only:
            solute_z = atomsel(self.solute_sel, molid=molid).get('z')
            dx_tm = 0.0
            dy_tm = 0.0
            sol_solute = atomsel(self.solute_sel, molid)
        else:
            solute_z = atomsel(self.solute_sel, molid=molid).get('z')
            tm_solute = atomsel(
                '(%s) and z > %f and z < %f' %
                (self.solute_sel, -zh_mem_hyd, zh_mem_hyd), molid)
            if len(tm_solute):
                dx_tm = max(tm_solute.get('x')) - min(tm_solute.get('x'))
                dy_tm = max(tm_solute.get('y')) - min(tm_solute.get('y'))
            else:
                dx_tm = dy_tm = 0

            sol_solute = atomsel(
                '(%s) and (z < %f or z > %f)' %
                (self.solute_sel, -zh_mem_hyd, zh_mem_hyd), molid)

        # Solvent invariant options
        dx_sol = max(sol_solute.get('x')) - min(sol_solute.get('x'))
        dy_sol = max(sol_solute.get('y')) - min(sol_solute.get('y'))

        if self.opts.get('user_x'):
            self.size[0] = self.opts['user_x']
        else:
            self.size[0] = max(dx_tm + 2. * mem_buf, dx_sol + 2. * wat_buf)
        if self.opts.get('user_y'):
            self.size[1] = self.opts['user_y']
        else:
            self.size[1] = max(dy_tm + 2. * mem_buf, dy_sol + 2. * wat_buf)

        # Z dimension. If there's a membrane, need to account for asymmetry
        # in the Z dimension where the protein could be uneven in the membrane
        # or even peripheral
        if self.opts.get('user_z'):
            self.size[2] = self.opts['user_z']
            buf = (self.opts['user_z'] - max(solute_z) + min(solute_z)) / 2
            self._zmax = max(solute_z) + buf
            self._zmin = min(solute_z) - buf
            if zh_mem_full > self._zmax or -zh_mem_full < self._zmin:
                raise DabbleError("Specified user z of %f is too small to "
                                  "accomodate protein and membrane!" %
                                  self.opts['user_z'])
        else:
            if self.water_only:
                self._zmax = max(solute_z) + wat_buf
                self._zmin = min(solute_z) - wat_buf
            else:
                self._zmax = max(max(solute_z) + wat_buf, zh_mem_full)
                self._zmin = min(min(solute_z) - wat_buf, -zh_mem_full)
            self.size[2] = self._zmax - self._zmin

        # Cleanup temporary file, if read in
        if filename is not None:
            molecule.delete(molid)
            if top != -1:
                molecule.set_top(top)

        return dx_sol, dy_sol, dx_tm, dy_tm, max(solute_z) - min(solute_z)
Exemplo n.º 49
0
    def _write_lipids(self):
        """
        Splits lipids into modular tail, head, tail that Lipid14 specifies.
        Closes the old molecule and loads the new renumbered molecule.
        Does name matching for lipids. Writes the pdb file with TER cards
        in between each lipid.

        Returns:
            (str): File name of PDB file written

        Raises:
            ValueError if an invalid lipid is found
        """
        lipid_res = set(atomsel(self.lipid_sel).get('residue'))
        n_lips = len(lipid_res)
        if not n_lips:
            return None

        molecule.set_top(self.molid)
        temp = tempfile.mkstemp(suffix='.pdb',
                                prefix='amber_lipids_',
                                dir=self.tmp_dir)[1]
        fileh = open(temp, 'w')

        # Check if it's a normal residue first in case cholesterol etc in
        # the selection
        resid = 1
        idx = 1
        while lipid_res:
            residue = lipid_res.pop()
            if len(lipid_res) % 1 == 0:
                sys.stdout.write(
                    "Writing lipids.... %.0f%%  \r" %
                    (100. - 100. * len(lipid_res) / float(n_lips)))
                sys.stdout.flush()

            sel = atomsel('residue %s' % residue)
            headres, headnam, minusidx = self.matcher.get_lipid_head(sel)

            # If it's not a lipid head, check if it's a normal residue
            if not headres:
                resnames, atomnames = self.matcher.get_names(
                    sel, print_warning=False)
                if not resnames:
                    raise DabbleError(
                        "Residue %s:%s not a valid lipid" %
                        (sel.get('resname')[0], sel.get('resid')[0]))
                self._apply_naming_dictionary(resnames, atomnames)
                sel.set('resid', resid)
                resid += 1
                continue
            else:
                # Apply the name to the heads
                self._apply_naming_dictionary(headres, headnam)

                # Pull out the tail resnames and indices
                taildicts = self.matcher.get_lipid_tails(sel, headnam.keys())
                for (resnames, atomnames) in taildicts:
                    self._apply_naming_dictionary(resnames, atomnames)

                # Renumber the first tail, head, then second tail and write
                # them separately. Needs to be done this way to guarantee order.
                # An atom index that's in the minus tail is given by get_lipid_head.

                # First tail
                firstdict = [_ for _ in taildicts if minusidx in _[0].keys()]
                if len(firstdict) != 1:
                    raise DabbleError(
                        "Error finding tails for lipid %s:%s" %
                        (sel.get('resname')[0], sel.get('resid')[0]))
                firstdict = firstdict[0]

                lsel = atomsel('index %s' % ' '.join([str(x) for x in \
                               firstdict[0].keys()]))
                lsel.set('resid', resid)
                lsel.set('user', 0.0)
                idx = self._write_residue(lsel, fileh, idx)
                taildicts.remove(firstdict)

                # Head
                lsel = atomsel('index %s' % ' '.join([str(x) for x in \
                               headnam.keys()]))
                lsel.set('resid', resid + 1)
                lsel.set('user', 0.0)
                idx = self._write_residue(lsel, fileh, idx)

                # Second tail
                lsel = atomsel('index %s' % ' '.join([str(x) for x in \
                               taildicts[0][0].keys()]))
                lsel.set('resid', resid + 2)
                lsel.set('user', 0.0)
                idx = self._write_residue(lsel, fileh, idx)
                resid += 3
                fileh.write("TER\n")  # TER card between lipid residues

        fileh.write("END\n")
        fileh.close()
        sys.stdout.write("\n")
        return temp
Exemplo n.º 50
0
    def _write_lipid_blocks(self):
        """
        Writes a temporary PDB file containing the lipids for later use by
        psfgen. Renumbers the lipid residues because some can have **** instead
        of an integer for resid in large systems, which will crash psfgen. Also
        sets atom names for some common lipids (currently POPC)

        Raises:
            NotImplementedError if more than 10,000 lipids are present since it
              doesn't support feeding multiple lipid blocks to psfgen currently
            NotImplementedError if lipid other than POPC,POPE,POPG is found
        """
        # Put current molecule on top to simplify atom selection
        old_top = molecule.get_top()
        molecule.set_top(self.molid)

        # Collect lipid residues up
        alll = atomsel('(%s) and user 1.0' % self.lipid_sel)
        residues = list(set(alll.get('residue')))
        residues.sort()

        # Sanity check for < 10k lipids
        if len(residues) >= 10000:
            raise NotImplementedError("More than 10k lipids found")

        # Rename lipid residues by resname
        # This assumes all lipids with the same resname are the same
        # If that's not the case, the system is really broken in some way
#        for resname in set(alll.get('resname')):
#            ressel = atomsel("(%s) and user 1.0 and resname '%s'"
#                             % (self.lipid_sel, resname))
#
#            # Get naming dictionary for one representative residue
#            repsel = atomsel('residue %s' % ressel.get('residue')[0])
#            (newname, atomnames) = self.matcher.get_names(sel)
#
#            # Apply naming dictionary to all of these residues
#            for idx, name in atomnames.items():
#                oldname = atomsel('index %s' % idx).get('name')
#                if oldname != name:

        # Loop through all residues and renumber and correctly name them
        counter = 1
        for res in residues:
            # Renumber residue
            sel = atomsel('residue %s' % res)
            sel.set('resid', counter)
            counter = counter + 1

            # Rename residue
#            (newname, atomnames) = self.matcher.get_names(sel,
#                                                          print_warning=False)
#
#            for idx, name in atomnames.items():
#                atom = atomsel('index %s' % idx)
#                if atom.get('name')[0] != name:
#                    print("Renaming %s:%s: %s -> %s" % (sel.get('resname')[0],
#                                                        sel.get('resid')[0],
#                                                        atom.get('name')[0],
#                                                        name))
#                    atom.set('name', name)
#            sel.set('resname', newname)

        # Write temporary lipid pdb
        temp = tempfile.mkstemp(suffix='.pdb', prefix='psf_lipid_',
                                dir=self.tmp_dir)[1]
        alll.set('user', 0.0)
        alll.write('pdb', temp)

        # Write to file
        string = '''
       set lipidfile %s
       set mid [mol new $lipidfile]
       segment L {
          first none
          last none
          pdb $lipidfile
       }
       coordpdb $lipidfile L
       mol delete $mid
        ''' % temp
        self.file.write(string)

        # Put old top back
        molecule.set_top(old_top)
Exemplo n.º 51
0
def test_mol_attrs(file_3nob):

    m1 = molecule.load("mae", file_3nob)
    m2 = molecule.load("mae", file_3nob)

    # Get/set top
    assert molecule.get_top() == m2
    molecule.set_top(molid=m1)
    assert molecule.get_top() == m1
    with pytest.raises(ValueError):
        molecule.set_top(m2 + 1)

    # Get/set visibility
    molecule.set_visible(m1, visible=False)
    assert molecule.get_visible() == False
    assert molecule.get_visible(molid=m2) == True

    with pytest.warns(DeprecationWarning):
        molecule.set_visible(m1, state=True)
    assert molecule.get_visible(molid=m1) == True

    with pytest.raises(ValueError):
        molecule.set_visible(m2 + 1, True)
    with pytest.raises(TypeError):
        molecule.set_visible(m2, 3)
    with pytest.raises(ValueError):
        molecule.get_visible(m2 + 1)

    # Get/set periodic
    assert molecule.get_periodic(m2) == {
        'a': 1.0,
        'alpha': 90.0,
        'b': 1.0,
        'beta': 90.0,
        'c': 1.0,
        'gamma': 90.0
    }
    with pytest.raises(ValueError):
        molecule.get_periodic(molid=m1, frame=3000)

    with pytest.raises(ValueError):
        molecule.set_periodic(molid=m2 + 1, a=2.0)
    with pytest.raises(ValueError):
        molecule.set_periodic(m1, frame=3000, a=20.0)

    molecule.set_periodic(m2,
                          frame=0,
                          a=90.0,
                          b=90.0,
                          c=90.0,
                          alpha=90.0,
                          beta=90.0,
                          gamma=90.0)
    assert list(molecule.get_periodic(
        m2, frame=0).values()) == [pytest.approx(90.0)] * 6
    assert set(molecule.get_periodic(
        m1, frame=0).values()) != [pytest.approx(90.0)] * 6
    molecule.set_periodic(c=20.0)

    assert molecule.get_periodic()["c"] == pytest.approx(20.0)

    molecule.delete(m1)
    molecule.delete(m2)
Exemplo n.º 52
0
    def write(self, psf_name):
        """
        Writes the pdb/psf file.

        Args:
          psf_name (str): Prefix for the pdb/psf output files, extension
            will be appended

        Returns:
          topologies (list of str): Topology files that were used in creating
              the psf
        """
        # Clean up all temp files from previous runs if present
        # An earlier check will exit if it's not okay to overwrite here
        self.psf_name = psf_name
        try:
            os.remove('%s.pdb'% self.psf_name)
            os.remove('%s.psf'% self.psf_name)
        except OSError:
            pass

        #  Finds the psfgen package and sets the output file name
        string = '''
        set dir [file join $env(VMDDIR) plugins [vmdinfo arch] tcl psfgen1.6]
        package ifneeded psfgen 1.6 [list load [file join $dir libpsfgen.so]]
        package require psfgen
        set output "%s"
        resetpsf
        ''' % self.psf_name
        self.file.write(string)

        # Put our molecule on top
        old_top = molecule.get_top()
        molecule.set_top(self.molid)

        # Print out topology files
        self.file.write('\n')
        print("Using the following topologies:")
        for top in self.topologies:
            print("  - %s" % top.split("/")[-1])
            self.file.write('   topology %s\n' % top)

        # Mark all atoms as unsaved with the user field
        atomsel('all', molid=self.molid).set('user', 1.0)
        check_atom_names(molid=self.molid)

        # Now ions if present, changing the atom names
        if len(atomsel('element Na Cl K', molid=self.molid)) > 0:
            self._write_ion_blocks()

        # Save water 10k molecules at a time
        if len(atomsel('water', molid=self.molid)):
            self._write_water_blocks()

        # Now lipid
        if len(atomsel(self.lipid_sel)):
            self._write_lipid_blocks()

        if not len(atomsel("resname %s" % _acids, molid=self.molid)):
            print("\tDidn't find any protein.\n")

        # Now handle the protein
        # Save and reload the protein so residue looping is correct
        prot_molid = self._renumber_protein_chains(molid=self.molid)
        extpatches = set()
        for frag in sorted(set(atomsel("resname %s" % _acids,
                                molid=prot_molid).get('fragment'))):
            extpatches.update(self._write_protein_blocks(prot_molid, frag))
        atomsel("same fragment as resname %s" % _acids,
                molid=self.molid).set("user", 0.0)

        # List all patches applied to the protein
        print("Applying the following patches:\n")
        print("\t%s" % "\t".join(extpatches))
        self.file.write(''.join(extpatches))
        self.file.write("\n")

        # Regenerate angles and dihedrals after applying patches
        # Angles must be regenerated FIRST!
        # See http://www.ks.uiuc.edu/Research/namd/mailing_list/namd-l.2009-2010/4137.html
        self.file.write("regenerate angles\nregenerate dihedrals\n")

        # Check if there is anything else and let the user know about it
        leftovers = atomsel('user 1.0', molid=self.molid)
        for lig in set(leftovers.get('resname')):
            residues = self._find_single_residue_names(resname=lig, molid=self.molid)
            self._write_generic_block(residues)

        # Write the output files and run
        string = '''
        writepsf x-plor cmap ${output}.psf
        writepdb ${output}.pdb'''
        self.file.write(string)
        self.file.close()

        evaltcl('play %s' % self.filename)
        self._check_psf_output()

        # Reset top molecule
        molecule.set_top(old_top)

        return self.topologies
Exemplo n.º 53
0
    def _write_water_blocks(self):
        """
        Writes a lot of temporary files with 10000 waters each, to bypass
        psfgen being stupid with files containing more than 10000 of a residue.
        """
        # Put current molecule on top to simplify atom selection language
        old_top = molecule.get_top()
        molecule.set_top(self.molid)

        # Set consistent residue and atom names, crystal waters
        # can be named HOH, etc
        atomsel('water').set('resname', 'TIP3')
        atomsel('resname TIP3').set('chain', 'W')
        atomsel('resname TIP3 and element O').set('name', 'OH2')

        # Dowser can name water hydrogens strangely
        atomsel('resname TIP3 and name HW1').set('name', 'H1')
        atomsel('resname TIP3 and name HW2').set('name', 'H2')

        # Select all the waters. We'll use the user field to track which
        # ones have been written
        allw = atomsel('water and user 1.0')
        print("Found %d water residues" % len(set(atomsel('water and user 1.0').get('residue'))))

        # Find the problem waters with unordered indices
        problems = []
        for r in set(allw.get('residue')):
            widx = atomsel('residue %s' % r).get("index")
            if max(widx) - min(widx) != 2:
                problems.append(r)
                atomsel('residue %s' % r).set("user", 0.0) # get it out of allw

        allw.update()
        num_written = int(len(allw)/(9999*3))+1
        print("Going to write %d files for %d water atoms"
              % (num_written, len(allw)))

        # Pull out and write 10k waters at a time if we have normal waters
        if allw:
            for i in range(num_written):
                temp = tempfile.mkstemp(suffix='_%d.pdb' % i, prefix='psf_wat_',
                                        dir=self.tmp_dir)[1]
                residues = list(set(allw.get('residue')))[:9999]

                batch = atomsel('residue %s' % ' '.join([str(x) for x in residues]))
                try:
                    batch.set('resid', [k for k in range(1, int(len(batch)/3)+1)
                                        for _ in range(3)])
                except ValueError:
                    print("\nERROR! You have some waters missing hydrogens!\n"
                          "Found %d water residues, but %d water atoms. Check "
                          " your crystallographic waters in the input structure."
                          % (len(residues), len(batch)))
                    quit(1)
                batch.set('user', 0.0)
                batch.write('pdb', temp)
                allw.update()

        # Now write the problem waters
        self._write_unorderedindex_waters(problems, self.molid)

        string = '''
        set waterfiles [glob -directory %s psf_wat_*.pdb]
        set i 0
        foreach watnam $waterfiles {
           segment W${i} {
              auto none
              first none
              last none
              pdb $watnam
           }
           coordpdb $watnam W${i}
           incr i
        }
          ''' % self.tmp_dir
        self.file.write(string)
        molecule.set_top(old_top)

        return num_written