Ejemplo n.º 1
0
def xyz2bgf(xyz_file, bgf_file, silent=False):
    """
	Converts xyz to bgf
	"""

    ### open xyz
    f_xyz = open(xyz_file, 'r')

    ### create bgf
    myBGF = bgf.BgfFile()
    myBGF.BIOGRF = '200'
    myBGF.DESCRP = xyz_file

    ### read and create atoms for bgf file
    while 1:
        line = f_xyz.readline()

        if not line: break

        words = string.split(line)

        if not words: break

        natoms = int(words[0])
        myBGF.REMARK = [cleansym(f_xyz.readline())]

        for i in range(natoms):
            line = f_xyz.readline()
            words = string.split(line)
            sym = words[0]
            sym = cleansym(sym)
            x, y, z = float(words[1]), float(words[2]), float(words[3])

            ### add atoms
            atom = bgf.BgfAtom()
            atom.x = x
            atom.y = y
            atom.z = z
            atom.ffType = sym
            atom.aNo = i
            atom.aName = sym + str(i)
            atom.rNo = 1
            atom.chain = "A"
            atom.rName = "RES"
            myBGF.addAtom(atom)

    ### save bgf
    myBGF.OTHER = []
    myBGF.saveBGF(bgf_file)
Ejemplo n.º 2
0
    def convertBGF(self):
        myBGF = bgf.BgfFile()
        natom = 0

        for index, i in enumerate(self._atom_numbers):
            name = self._atom_types[index]
            name = raw_input("- assign the force field type for " + name +
                             " (default: " + name +
                             ") ?? ") or self._atom_types[index]

            for j in xrange(i):
                atom = bgf.BgfAtom()
                atom.x = self._coords[natom][0]
                atom.y = self._coords[natom][1]
                atom.z = self._coords[natom][2]
                atom.aTag = 1
                atom.aNo = natom + 1
                atom.aName = self._atom_types[index] + str(j + 1)
                atom.rName = "RES"
                atom.rNo = 100
                atom.chain = "A"
                atom.ffType = name
                myBGF.addAtom(atom)

                natom += 1

        # assign remarks
        myBGF.BIOGRF = 200
        myBGF.DESCRP = "From " + self._filename + " at " + time.asctime(
            time.gmtime(
            )) + " on " + os.environ["HOSTNAME"] + " by " + os.environ["USER"]
        myBGF.PERIOD = "111"
        myBGF.AXES = "ZYX"
        myBGF.SGNAME = "P 1                  1    1"
        myBGF.CELLS = [-1, 1, -1, 1, -1, 1]
        myBGF.CRYSTX = self._latticeParams

        self._bgf = myBGF
Ejemplo n.º 3
0
    def add_ions_inside_nanotube(self, n_ion):
        """
        Add Na+ and Cl- ions inside nanotube.
        """
        if not self.isRadiusCalc == True:
            nu.warn("Nanotube radius not defined. Exiting.")
            return 0

        ### find the last atom before resname WAT
        aNo_lastatom = 0
        for i in self.bgfmodel.a:
            aNo = i.aNo
            if not "WAT" in i.rName:
                if aNo > aNo_lastatom:
                    aNo_lastatom = aNo

        ### add
        n_add = 0
        while n_add < n_ion:
            x = random.uniform(0, self.pbc[0])
            y = random.uniform(0, self.pbc[1])
            z = random.uniform(0, self.pbc[2])

            xyz = np.array([x, y, z])
            r = np.sqrt(
                ((xyz * self.axis - self.center * self.axis)**2).sum(axis=-1))
            h = (xyz * self.axismask).sum()

            if r < self.radius and self.zlo < h < self.zhi:

                # Na+ ion
                atom_Na = bgf.BgfAtom()
                atom_Na.x = x
                atom_Na.y = y
                atom_Na.z = z
                atom_Na.aTag = 1  # HETATM
                atom_Na.ffType = "Na"
                atom_Na.rName = "ION"
                atom_Na.aName = "Na"
                atom_Na.charge = 1.00
                atom_Na.rNo = 0
                atom_Na.chain = "X"

                # Cl- ion
                atom_Cl = bgf.BgfAtom()
                atom_Cl.x = x + 2
                atom_Cl.y = y + 2
                atom_Cl.z = z + 2
                atom_Cl.aTag = 1  # HETATM
                atom_Cl.ffType = "Cl"
                atom_Cl.rName = "ION"
                atom_Cl.aName = "Cl"
                atom_Cl.charge = -1.00
                atom_Cl.rNo = 0
                atom_Cl.chain = "X"

                self.bgfmodel.addAtom(atom_Na,
                                      self.bgfmodel.a2i[aNo_lastatom + 1])
                self.bgfmodel.addAtom(atom_Cl,
                                      self.bgfmodel.a2i[aNo_lastatom + 2])

                n_add += 1

        self.bgfmodel.renumber()
        print("%d atoms added to the nanotube." % n_add)
Ejemplo n.º 4
0
def countWater(bgf_file, trj_file, n_step, watercopy, ff_file, silent=False):

    ### const
    PI = math.pi
    vdw_r_C = 1.7

    ### init
    timestep = 0
    l_timestep = []
    line = []
    n_header = 0
    t1 = 0
    t2 = 0
    # clock

    myBGF = bgf.BgfFile(bgf_file)
    myTRJ = open(trj_file)
    myTRJ.seek(0)

    global out_file
    if out_file == "": out_file = "countWater5.profile"
    print("The result will be recorded to the file " + out_file + " ...")
    ftemp = open(out_file, 'w')
    ftemp.write(str(sys.argv) + "\n")
    ftemp.write("t" + '\t' + "n_O" + '\t' + "r_CNT" + '\t' + "std_r" + '\t' +
                "min_x" + '\t' + "max_x" + '\t' + "min_y" + '\t' + "max_y" +
                '\t' + "min_z" + '\t' + "max_z" + '\t' + "l_NT" + '\t' +
                "replNum" + '\t' + "copyNum" + '\t' + "n_WAT" + '\t' +
                "remark" + '\n')

    curr_dir = os.path.abspath(".")
    temp_dir = curr_dir + "/countWAT5/"
    print(temp_dir)
    if not os.path.isdir(temp_dir): os.makedirs(temp_dir)

    ### how many steps to go?
    n_timestep = len(lt.getTrjInfo(trj_file))
    if n_step == 0:
        n_step = n_timestep

    print(" ..The trajectory contains " + str(n_timestep) + " timesteps.")
    print("The script will proceed for the first " + str(n_step) +
          " timesteps.")

    ### read mass from ff_file
    atominfo = dict()
    try:
        parse = ff_file.split(" ")
    except:
        nu.die(
            "Error occurred when reading the force field file.. Check your " +
            str(ff_file))
    else:
        if not silent:
            print("Found " + str(len(parse)) + " Cerius2 Force Fields.")

    for i in parse:
        FF = dreiding.loadFF(i)
        temp_atominfo = dreiding.loadAtomTypes(FF)
        atominfo.update(temp_atominfo)

    ### extract aNos of CNT in the BGF file
    aNo_CNT = []
    aNo_WAT_O = []
    aNo_WAT_all = []
    mass_CNT = []

    for atom in myBGF.a:
        # Carbons in CNT or atoms in BNNT
        if "NT" in atom.rName:
            aNo_CNT.append(atom.aNo)
            ffType = string.strip(atom.ffType)
            try:
                aMass = atominfo[ffType]['MASS']
            except:
                nu.die("Cannot read the atom type " + str(atom.ffType) +
                       " in the data file.")
            mass_CNT.append(aMass)

        # Oxygen in water
        if "WAT" in atom.rName and "O" in atom.aName:
            aNo_WAT_O.append(atom.aNo)

    N_CNT = len(aNo_CNT)  # the number of CNT atoms

    ### check if there exists water properly
    if len(aNo_WAT_O) == 0:
        nu.die("No water molecules in the BGF file.")
    if len(aNo_CNT) == 0:
        nu.die("No CNT molecules in the BGF file.")

    ### Find header of the trajectory file
    while 1:
        templine = myTRJ.readline()
        line.append(templine.strip('\n').strip('ITEM: '))
        n_header += 1
        if "ITEM: ATOMS" in templine:
            break

    ### INITIAL trajectory information
    timestep = int(line[1])
    natoms = int(line[3])
    boxsize = [
        line[5].split(' ')[0], line[5].split(' ')[1], line[6].split(' ')[0],
        line[6].split(' ')[1], line[7].split(' ')[0], line[7].split(' ')[1]
    ]
    boxsize = [float(i) for i in boxsize]
    keywords = line[8].strip('ATOMS ')

    # for every shot in the trajectory file update BGF and manipulate
    dumpatom = get_line(trj_file)
    processed_step = 0

    t1 = t2 = 0
    elapsed_time = 0

    while 1:

        ### Show progress
        t1 = time.time()
        remaining_time = elapsed_time * (n_step - processed_step)
        sys.stdout.write('\r' + "Reading timestep.. " + str(timestep) +
                         " (Remaining time: " +
                         "{0:4.1f}".format(remaining_time) + " seconds, " +
                         "{0:4.1f} minutes".format(remaining_time / 60) + ")")
        sys.stdout.flush()

        if processed_step == n_step:
            break

        ### Read
        myBGF = bgf.BgfFile(bgf_file)
        try:
            chunk = [next(dumpatom) for i in range(natoms + n_header)]
        except StopIteration:
            break

        timestep = int(chunk[1])
        natoms = int(chunk[3])
        boxsize = [
            chunk[5].split(' ')[0], chunk[5].split(' ')[1],
            chunk[6].split(' ')[0], chunk[6].split(' ')[1],
            chunk[7].split(' ')[0], chunk[7].split(' ')[1]
        ]
        boxsize = [float(i) for i in boxsize]
        boxsize = [(boxsize[1] - boxsize[0]), (boxsize[3] - boxsize[2]),
                   (boxsize[5] - boxsize[4])]
        keywords = chunk[8].split('ATOMS ')[1].strip('\n').split(' ')

        mode = 'unwrapped'  # assume that "dump            1 all custom 100 ${sname}${rtemp}K.nvt.lammps id type xu yu zu vx vy vz" in lammps input

        # actual coordinate
        coordinfo = chunk[9:]

        # load atom coordinates from chunk
        for atomline in coordinfo:
            atomcoord = atomline.split(' ')
            atom = myBGF.getAtom(int(atomcoord[0]))

            atom.x = float(atomcoord[2])
            atom.y = float(atomcoord[3])
            atom.z = float(atomcoord[4])

        ### convert atom coordinates to lists
        CNT = []
        WATER = []
        for atom in myBGF.a:
            if "NT" in atom.rName:
                CNT.append([atom.x, atom.y, atom.z])
            if "WAT" in atom.rName and "O" in atom.ffType:
                WATER.append([atom.x, atom.y, atom.z])

        CNT = np.array(CNT)
        n_CNT = len(CNT)  # CNT coordinates
        WATER = np.array(WATER)  # Water coordinates
        WATERONLY = np.copy(WATER)
        boxsize = np.array(boxsize)

        ### initialize for the moment of inertia and the center of mass calculation
        U = 0
        Ut = 0
        Uv = 0
        Ixx = 0
        Ixy = 0
        Ixz = 0
        Iyx = 0
        Iyy = 0
        Iyz = 0
        Izx = 0
        Izy = 0
        Izz = 0
        Mx = 0
        My = 0
        Mz = 0

        ### transpose "all atoms in BGF": move COM of CNT as origin
        Mx, My, Mz = np.average(CNT, axis=0, weights=mass_CNT)  # CoM of CNT
        COM = np.array([[Mx, My, Mz]])

        CNT = CNT - COM + boxsize / 2.0  # move
        WATER = WATER - COM + boxsize / 2.0

        ### apply PBC
        WATER = np.mod(WATER, boxsize)

        ### save coordinates to BGF before rotation
        myBGF2 = bgf.BgfFile()
        for index, i in enumerate(CNT):
            newatom = bgf.BgfAtom()
            newatom.x, newatom.y, newatom.z = i
            newatom.aNo = index
            newatom.aName = 'C' + str(index)
            newatom.rName = 'CNT'
            newatom.ffType = 'C_'
            newatom.chain = 'A'
            newatom.rNo = 1
            myBGF2.addAtom(newatom)

        for index, i in enumerate(WATER):
            newatom = bgf.BgfAtom()
            newatom.x, newatom.y, newatom.z = i
            newatom.aNo = index + n_CNT
            newatom.aName = 'O'
            newatom.rName = 'WAT'
            newatom.ffType = 'OW'
            newatom.chain = 'O'
            newatom.rNo = 100
            myBGF2.addAtom(newatom)

        myBGF2.REMARK.append('TIMESTEP ' + str(timestep))
        myBGF2.PERIOD = "111"
        myBGF2.AXES = "ZYX"
        myBGF2.SGNAME = "P 1                  1    1"
        myBGF2.CELLS = [-1, 1, -1, 1, -1, 1]
        myBGF2.CRYSTX = [boxsize[0], boxsize[1], boxsize[2], 90.0, 90.0, 90.0]
        myBGF2.saveBGF(temp_dir + bgf_file.split(".bgf")[0] + "." +
                       str(timestep) + ".bgf")

        ### move CM of CNT to origin
        CNT = CNT - boxsize / 2.0
        WATER = WATER - boxsize / 2.0

        ### how the CNT is lying across the periodic box?
        for atom in CNT:
            min_x_CNT, min_y_CNT, min_z_CNT = CNT.min(axis=0)
            max_x_CNT, max_y_CNT, max_z_CNT = CNT.max(axis=0)

        margin = 5.0

        ### copy water molecules
        max_x_axis = int(round((max_x_CNT + margin) / boxsize[0]))
        min_x_axis = int(round((min_x_CNT - margin) / boxsize[0]))
        max_y_axis = int(round((max_y_CNT + margin) / boxsize[1]))
        min_y_axis = int(round((min_y_CNT - margin) / boxsize[1]))
        max_z_axis = int(round((max_z_CNT + margin) / boxsize[2]))
        min_z_axis = int(round((min_z_CNT - margin) / boxsize[2]))

        replNum = (min_x_axis, max_x_axis, min_y_axis, max_y_axis, min_z_axis,
                   max_z_axis)
        copyNum = 0

        remark = ""
        if watercopy:
            for x in range(min_x_axis, max_x_axis + 1):
                remark += "x: "
                if x != 0:
                    WATER2 = np.copy(WATERONLY)
                    dx = np.array([[boxsize[0] * x, 0, 0]])
                    WATER2 = WATER2 + dx
                    WATER = np.concatenate((WATER, WATER2))
                    copyNum += 1
                    remark += str(x) + " "

            for y in range(min_y_axis, max_y_axis + 1):
                remark += "y: "
                if y != 0:
                    WATER2 = np.copy(WATERONLY)
                    dy = np.array([[0, boxsize[1] * y, 0]])
                    WATER2 = WATER2 + dy
                    WATER = np.concatenate((WATER, WATER2))
                    copyNum += 1
                    remark += str(y) + " "

            for z in range(min_z_axis, max_z_axis + 1):
                remark += "z: "
                if z != 0:
                    WATER2 = np.copy(WATERONLY)
                    dz = np.array([[0, 0, boxsize[2] * z]])
                    WATER2 = WATER2 + dz
                    WATER = np.concatenate((WATER, WATER2))
                    copyNum += 1
                    remark += str(z) + " "
        '''
		### WATER distribution check
		x_axis = np.linspace(WATER[:,0].min(), WATER[:,0].max(), 10)
		y_axis = np.linspace(WATER[:,1].min(), WATER[:,1].max(), 10)
		z_axis = np.linspace(WATER[:,2].min(), WATER[:,2].max(), 10)
		x_hist, _ = np.histogram(WATER[:,0], x_axis, normed=True)
		y_hist, _ = np.histogram(WATER[:,1], y_axis, normed=True)
		z_hist, _ = np.histogram(WATER[:,2], z_axis, normed=True)
		remark += " xdist: "
		for i in x_hist:
			remark += "{0:6.3f}".format(i)
		remark += " ydist: "
		for i in y_hist:
			remark += "{0:6.3f}".format(i)
		remark += " zdist: "
		for i in z_hist:
			remark += "{0:6.3f}".format(i)
		'''

        ### MI of CNT calculation
        for atom in CNT:
            Ixx += (atom[1]**2 + atom[2]**2) / N_CNT
            Iyy += (atom[0]**2 + atom[2]**2) / N_CNT
            Izz += (atom[0]**2 + atom[1]**2) / N_CNT
            Ixy -= (atom[0] * atom[1]) / N_CNT
            Ixz -= (atom[0] * atom[2]) / N_CNT
            Iyz -= (atom[1] * atom[2]) / N_CNT

        I = np.array([[Ixx, Ixy, Ixz], [Ixy, Iyy, Iyz],
                      [Ixz, Iyz, Izz]])  # the moment of inertia tensor
        eigval, eigvec = np.linalg.eig(
            I)  # eigval[0] is the minimum among the values.
        U = np.matrix(eigvec)
        Ut = U.T

        ### box rotation
        for atom in CNT:
            v = np.matrix([atom[0], atom[1], atom[2]]).T
            Uv = Ut * v
            atom[0] = float(Uv[2])
            atom[1] = float(Uv[1])
            atom[2] = float(Uv[0])  # CNT rotation

        for atom in WATER:
            v = np.matrix([atom[0], atom[1], atom[2]]).T
            Uv = Ut * v
            atom[0] = float(Uv[2])
            atom[1] = float(Uv[1])
            atom[2] = float(Uv[0])  # water rotation

        ### save coordinates to BGF after rotation
        myBGF2 = bgf.BgfFile()
        for index, i in enumerate(CNT):
            newatom = bgf.BgfAtom()
            newatom.x, newatom.y, newatom.z = i
            newatom.aNo = index
            newatom.aName = 'C' + str(index)
            newatom.rName = 'CNT'
            newatom.ffType = 'C_'
            newatom.chain = 'A'
            newatom.rNo = 1
            myBGF2.addAtom(newatom)

        for index, i in enumerate(WATER):
            newatom = bgf.BgfAtom()
            newatom.x, newatom.y, newatom.z = i
            newatom.aNo = index + n_CNT
            newatom.aName = 'O'
            newatom.rName = 'WAT'
            newatom.ffType = 'OW'
            newatom.chain = 'O'
            newatom.rNo = 100
            myBGF2.addAtom(newatom)

        myBGF2.REMARK.append('TIMESTEP ' + str(timestep))
        myBGF2.PERIOD = "111"
        myBGF2.AXES = "ZYX"
        myBGF2.SGNAME = "P 1                  1    1"
        myBGF2.CELLS = [-1, 1, -1, 1, -1, 1]
        myBGF2.CRYSTX = [boxsize[0], boxsize[1], boxsize[2], 90.0, 90.0, 90.0]
        myBGF2.saveBGF(temp_dir + bgf_file.split(".bgf")[0] + "." +
                       str(timestep) + ".rot.bgf")

        ### CNT height
        _, _, min_z_CNT = CNT.min(axis=0)
        _, _, max_z_CNT = CNT.max(axis=0)
        height_CNT = max_z_CNT - min_z_CNT

        ### CNT radius
        x_CNT, y_CNT, z_CNT = np.mean(CNT, axis=0)
        x_std_CNT, y_std_CNT, z_std_CNT = np.std(CNT, axis=0)
        if x_std_CNT > 1.0 or y_std_CNT > 1.0:
            remark += ""

        ### radius of CNT
        l_r_CNT = []
        for atom in CNT:
            l_r_CNT.append(
                math.sqrt((atom[0] - x_CNT)**2 + (atom[1] - y_CNT)**2))

        r_CNT = np.mean(l_r_CNT)
        std_r_CNT = np.std(l_r_CNT)

        ### get water molecules in CNT
        # inside the CNT := min_z_CNT <= z <= max_z_CNT and (x - (x_diff/2))**2 + (y - (y_diff/2))**2 < r_CNT**2
        # aNo_WAT_O_atoms: molecules which O atom is within CNT
        # we don't need to calculate H atoms. Let's consider only O atoms
        #####
        margin = 0.0
        # water molecules far from the margin will be only considered
        WAT_in_CNT = []
        for atom in WATER:
            dist_sq = (atom[0] - x_CNT)**2 + (atom[1] - y_CNT)**2
            if min_z_CNT + margin <= atom[2] and atom[
                    2] <= max_z_CNT - margin and dist_sq < r_CNT**2:
                WAT_in_CNT.append(atom)

        n_WAT_in_CNT = len(WAT_in_CNT)
        '''
		### WATER bad contact check: copy-failure-proof: NEED CORRECTION
		WAT1 = []; WAT2 = [];
		for index1, i in enumerate(WAT_in_CNT):
			for j in WATER[index1:]:
				WAT1.append(i); WAT2.append(j);
		WAT1 = np.array(WAT1); WAT2 = np.array(WAT2)

		min_dists = np.min(np.dstack(((WAT1 - WAT2) % boxsize, (WAT2 - WAT1) % boxsize)), axis = 2)
		dists = np.sqrt(np.sum(min_dists ** 2, axis = 1))
		for d in dists:
			if d > 0 and d < 1.0:
				remark += "Bad contacts" + str(d)
				continue;
		'''

        d = "{0:8.3f}"
        e = "{0:6.1f}"
        output = "{0:<10}".format(timestep) + str(
            n_WAT_in_CNT
        ) + ' | ' + d.format(r_CNT) + d.format(std_r_CNT) + ' | ' + e.format(
            boxsize[0]
        ) + e.format(boxsize[1]) + e.format(boxsize[2]) + ' | ' + e.format(
            min_x_CNT) + e.format(max_x_CNT) + e.format(min_y_CNT) + e.format(
                max_y_CNT) + e.format(min_z_CNT) + e.format(
                    max_z_CNT) + ' | ' + e.format(height_CNT) + ' | ' + str(
                        replNum) + '\t' + str(copyNum) + '\t' + str(
                            len(WATER)) + '\t' + str(remark) + '\n'
        ftemp.write(output)
        sys.stdout.flush()

        t2 = time.time()  # time mark
        elapsed_time = t2 - t1
        processed_step += 1

    print('')
    ftemp.close()
    print("Numbers of water molecules are written in " + out_file + " ..Done.")

    return 1
Ejemplo n.º 5
0
def main():

    if len(sys.argv) < 2:
        print usage
        sys.exit(0)

    head = bgf.BgfFile(sys.argv[1])
    head_mon = bgf.BgfFile(sys.argv[2])
    monomer = bgf.BgfFile(sys.argv[3])
    tail_mon = bgf.BgfFile(sys.argv[4])
    tail = bgf.BgfFile(sys.argv[5])
    target_mw = float(sys.argv[6])
    ff_file = sys.argv[7]

    # number of required monomers to make a PEGDE chain
    mw_head = bgftools.getMoleculeMass(head, ff_file)
    print("** Mw of Molecule head: " + "{0:5.3f}".format(mw_head))

    mw_tail = bgftools.getMoleculeMass(tail, ff_file)
    print("** Mw of Molecule tail: " + "{0:5.3f}".format(mw_tail))

    mw_monomer = bgftools.getMoleculeMass(monomer, ff_file)
    print("** Mw of Molecule monomer: " + "{0:5.3f}".format(mw_monomer))

    print("** Requested Mw: " + str(target_mw))

    # number of required monomers
    n_monomers = round((target_mw - mw_head - mw_tail) / mw_monomer)
    print("** Required number of monomers: " + str(int(n_monomers)))

    actual_mw = mw_head + mw_tail + mw_monomer * n_monomers
    print("** Actual Mw: " + "{0:5.3f}".format(actual_mw))

    ### overall structure
    ### head -- head_mon -- monomer -- tail_mon -- tail

    ### connect blocks
    m1 = copy.deepcopy(
        head_mon)  # start adding monomers from the head_near monomer
    for atom in m1.a:
        atom.rNo = 1
        atom.rName = 'MON'

    print("* attaching head_monomer")
    n_monomers = int(n_monomers)

    ### monomer - monomer: 1H_T -- 2H_H
    for i in range(n_monomers - 1):

        # if the last monomer, attach tail_monomer
        # else prepare monomer 2
        if i == n_monomers - 2:
            print("* attaching tail_monomer")
            m2 = copy.deepcopy(tail_mon)
        else:
            print("* attaching monomer " + str(i))
            m2 = copy.deepcopy(monomer)

        # renumber residue numbers
        for atom in m2.a:
            atom.rNo = i + 2
            atom.rName = 'MON'

        # move H_H of m2 to H_T of m1 position
        h_t = 0
        h_h = 0
        for atom in m1.a:
            if atom.ffType == "H_T" and atom.rNo == i + 1:
                h_t = atom

        for atom in m2.a:
            if atom.ffType == "H_H" and atom.rNo == i + 2:
                h_h = atom

        for atom in m2.a:
            atom.x += h_t.x
            atom.y += h_t.y
            atom.z += h_t.z

        # delete H_T in monomer
        m1.delAtom(m1.a2i[h_t.aNo])
        m1.renumber()

        # delete H_H in monomer2
        m2.delAtom(m2.a2i[h_h.aNo])
        m2.renumber()

        # merge
        m1 = m1.merge(m2, True)
        m1.renumber()

        # find tag in the merged molecule
        atomH = bgf.BgfAtom()
        atomT = bgf.BgfAtom()
        for atom in m1.a:
            if 'T' in atom.chain and atom.rNo == i + 1:
                atomT = atom
            if 'H' in atom.chain and atom.rNo == i + 2:
                atomH = atom

        # update chain
        atomT.chain = "A"
        atomH.chain = "A"

        # connect
        m1.connect(m1.a2i[atomH.aNo], m1.a2i[atomT.aNo])

    #m1.saveBGF('temp_monomer.bgf')

    ### head - monomer: H_EG -- H_H
    # head
    h1 = copy.deepcopy(head)
    for atom in h1.a:
        atom.rNo = 100
        atom.rName = 'HED'

    h_eg = 0
    h_h = 0
    for atom in h1.a:
        if atom.ffType == "H_EG":
            h_eg = atom

    for atom in m1.a:
        if atom.ffType == "H_H":
            h_h = atom

    for atom in m1.a:
        atom.x += h_eg.x
        atom.y += h_eg.y
        atom.z += h_eg.z

    h1.delAtom(h1.a2i[h_eg.aNo])
    h1.renumber()

    m1.delAtom(m1.a2i[h_h.aNo])
    m1.renumber()

    h1 = h1.merge(m1, True)
    h1.renumber()

    atomH = bgf.BgfAtom()
    atomT = bgf.BgfAtom()
    for atom in h1.a:
        if 'T' in atom.chain and 'HED' in atom.rName:
            atomT = atom
        if 'H' in atom.chain and 'MON' in atom.rName:
            atomH = atom

    h1.connect(h1.a2i[atomT.aNo], h1.a2i[atomH.aNo])

    #h1.saveBGF('temp_h-m.bgf')

    # monomer - tail: H_T -- H_EG
    t1 = copy.deepcopy(tail)
    for atom in t1.a:
        atom.rNo = 200
        atom.rName = 'TAL'

    h_t = 0
    h_eg = 0
    for atom in h1.a:
        if atom.ffType == "H_T":
            h_t = atom

    for atom in t1.a:
        if atom.ffType == "H_EG":
            h_eg = atom

    for atom in t1.a:
        atom.x += h_t.x
        atom.y += h_t.y
        atom.z += h_t.z

    h1.delAtom(h1.a2i[h_t.aNo])
    h1.renumber()

    t1.delAtom(t1.a2i[h_eg.aNo])
    t1.renumber()

    h1 = h1.merge(t1, True)
    h1.renumber()

    atomH = bgf.BgfAtom()
    atomT = bgf.BgfAtom()
    for atom in h1.a:
        if 'T' in atom.chain and 'MON' in atom.rName:
            atomT = atom
        if 'H' in atom.chain and 'TAL' in atom.rName:
            atomH = atom

    h1.connect(h1.a2i[atomT.aNo], h1.a2i[atomH.aNo])

    # adding remarks
    h1.REMARK.append("Polymer Generated at " +
                     str(time.asctime(time.gmtime())))
    h1.REMARK.append("head: " + sys.argv[1] + ", head_mon: " + sys.argv[2] +
                     ", monomer: " + sys.argv[3] + ", tail_mon: " +
                     sys.argv[4] + ", tail: " + sys.argv[5])
    h1.REMARK.append("Target Mw: " + str(sys.argv[6]) + ", Actual Mw: " +
                     "{0:5.3f}".format(actual_mw))
    h1.REMARK.append("Number of monomers: " + str(n_monomers))
    h1.REMARK.append("ff: " + sys.argv[7])
    h1.saveBGF('generated_charge.bgf')
Ejemplo n.º 6
0
def addIons(bgf_file, out_file, region, number, silent=False):
    """
def addIons():
    Write what this function does.

Function Parameters:
    -b bgf_file    A string of filename or BgfFile class.
    -o out_file    A string of filename or BgfFile class.
    -n number
    -r region: "xlo xhi ylo yhi zlo zhi"
    """
    # open BGF
    if isinstance(bgf_file, bgf.BgfFile):
        myBGF = bgf_file
    else:
        if not silent: print("opening bgf file.. " + str(bgf_file))
        myBGF = bgf.BgfFile(bgf_file)

    boxsize = [myBGF.CRYSTX[0], myBGF.CRYSTX[1], myBGF.CRYSTX[2]]

    ### find the last HETATM
    aNo_lastHETAtom = 0
    for i in myBGF.a:
        aNo = i.aNo
        if i.aTag == 1:
            if aNo > aNo_lastHETAtom:
                aNo_lastHETAtom = aNo

    for i in range(number):
        """
        randx = random.uniform(0, boxsize[0])
        randy = random.uniform(0, boxsize[1])
        randz = random.uniform(0, boxsize[2])
        """
        randx = random.uniform(region[0], region[1])
        randy = random.uniform(region[2], region[3])
        randz = random.uniform(region[4], region[5])

        # Na+ ion
        atom_Na = bgf.BgfAtom()
        atom_Na.x = randx
        atom_Na.y = randy
        atom_Na.z = randz
        atom_Na.aTag = 1  # HETATM
        atom_Na.ffType = "Na"
        atom_Na.rName = "ION"
        atom_Na.aName = "Na"
        atom_Na.charge = 1.00
        atom_Na.rNo = 0
        atom_Na.chain = "X"

        # Cl- ion
        atom_Cl = bgf.BgfAtom()
        atom_Cl.x = randx + 2
        atom_Cl.y = randy + 2
        atom_Cl.z = randz + 2
        atom_Cl.aTag = 1  # HETATM
        atom_Cl.ffType = "Cl"
        atom_Cl.rName = "ION"
        atom_Cl.aName = "Cl"
        atom_Cl.charge = -1.00
        atom_Cl.rNo = 0
        atom_Cl.chain = "X"

        myBGF.addAtom(atom_Na, myBGF.a2i[aNo_lastHETAtom + 1])
        myBGF.addAtom(atom_Cl, myBGF.a2i[aNo_lastHETAtom + 2])

    myBGF.renumber()

    # save BGF
    if isinstance(out_file, str):
        if not silent: print("Saving information to " + out_file + " ..")
        myBGF.saveBGF(out_file)
        return 1
    else:
        return myBGF
Ejemplo n.º 7
0
def protonate(bgf_file, out_file, log_file, silent=False):
    """
protonate(bgf_file, out_file, log_file, silent=False):
	Protonate (performs alkylation of primary amines) the given bgf file.

	To-do:
	"""

    # initialization

    # open bgffile
    myBGF = bgf.BgfFile(bgf_file)

    # find all inserted hydrogen
    N_index = []
    for atom in myBGF.a:
        if "H+" in atom.aName:
            N_index.append(atom.aNo)

    N_number = len(N_index)
    # the number of all inserted hydrogen atoms
    if not silent: print(str(N_number) + " protonated sites are found.")

    # find the last HETATM (insertion position)
    last_hetatm_aNo = 0
    for atom in myBGF.a:
        if atom.aTag != 1:
            last_hetatm_aNo = atom.aNo
            break

    # add Cl atoms
    if len(N_index) > 0:
        for index, aNo in enumerate(N_index):
            if not silent:
                print("*** Protonated Hydrogen " + str(aNo) + " ***")

            atom_H = myBGF.getAtom(aNo)

            # new Cl atom near atom_H
            atom_Cl = bgf.BgfAtom()
            atom_Cl.x = atom_H.x + 3
            atom_Cl.y = atom_H.y + 3
            atom_Cl.z = atom_H.z + 3
            atom_Cl.aName = "Cl"
            atom_Cl.rName = "ION"
            atom_Cl.chain = "A"
            atom_Cl.aTag = 1
            atom_Cl.rNo = 0
            atom_Cl.ffType = "Cl"
            atom_Cl.aNo = last_hetatm_aNo
            atom_Cl.charge = -1.0000

            myBGF.addAtom(atom_Cl, last_hetatm_aNo - 1)

        if not silent: print("Total charge: " + " : " + str(myBGF.charge()))

        # renumber
        myBGF.renumber()

        # save
        myBGF.REMARK.insert(
            0, "Ion added by " + os.path.basename(sys.argv[0]) + " by " +
            os.environ["USER"] + " on " + time.asctime(time.gmtime()))
        myBGF.saveBGF(out_file)
        if not silent: print("saving file " + out_file)

    else:
        if not silent:
            print("No amine groups to be counter-ionized")
            sys.exit(0)

    if not silent: print("Done.")
Ejemplo n.º 8
0
def protonate(bgf_file,
              ff_file,
              probability,
              out_file,
              log_file,
              silent=False):
    """
protonate(bgf_file, ff_file, suffix, nodes, criteria, t, out_file):
	Protonate (performs alkylation of primary amines) the given bgf file.

	To-do:
		clean temp file management
		display appropriate messages
		server environments
	"""

    # initialization

    # open bgffile
    myBGF = bgf.BgfFile(bgf_file)

    # find all tertiary amines
    N_index = []
    last_hetatm_aNo = 0
    for atom in myBGF.a:
        if string.strip(atom.ffType) == "N_3":
            if "PRI" in atom.rName:
                N_index.append(atom.aNo)

    N_number = len(N_index)
    # the number of all tertiary amines
    if not silent: print(str(N_number) + " primary amines are found.")

    # find the last HETATM (insertion position)
    for atom in myBGF.a:
        if atom.aTag != 1:
            last_hetatm_aNo = atom.aNo
            break
    print(last_hetatm_aNo)

    # choose the primary amines randomly according to the probability
    if not probability == 1.0:
        N_choose = int(N_number * probability)
        N_index = random.sample(N_index, N_choose)

    if not silent:
        print(str(len(N_index)) + " primary amines will be protonated.")

    # add an hydrogen
    if len(N_index) > 0:
        for index, aNo in enumerate(N_index):

            if not silent: print("*** Primary amine " + str(aNo) + " ***")
            atom_Npri = myBGF.getAtom(aNo)  # N from the N_index list

            # new proton on primary amine
            proton = bgf.BgfAtom()
            proton.x = atom_Npri.x + 1
            proton.y = atom_Npri.y + 1
            proton.z = atom_Npri.z + 1
            proton.aName = "H+_" + str(index)
            proton.rName = "PRI"
            proton.chain = "A"
            proton.aTag = 1
            proton.rNo = atom_Npri.rNo
            proton.ffType = "H_"
            proton.aNo = last_hetatm_aNo

            myBGF.addAtom(proton, last_hetatm_aNo - 1)
            proton = myBGF.getAtom(
                last_hetatm_aNo)  # since (proton) != (proton add in myBGF)
            #proton.aName = "H++"
            myBGF.connect(myBGF.a2i[atom_Npri.aNo],
                          myBGF.a2i[proton.aNo])  # connect

            # charge change: NH3 - CH2 - CH2 - .....
            # 1. NH3 part
            N_CONECT_aNo = atom_Npri.CONECT
            N_CONECT_C_aNo = []
            N_CONECT_H_aNo = []
            for ano in N_CONECT_aNo:
                atom = myBGF.getAtom(ano)
                if "C" in atom.ffType:
                    N_CONECT_C_aNo.append(atom.aNo)
                elif "H" in atom.ffType:
                    N_CONECT_H_aNo.append(atom.aNo)
                else:
                    nu.die(str(atom))

            if len(N_CONECT_C_aNo) != 1:
                nu.die("Number of C atoms connected with primary amine " +
                       str(atom_Npri.aNo) + " mismatch!")
            if len(N_CONECT_H_aNo) != 3:
                nu.die("Number of H atoms connected with primary amine " +
                       str(atom_Npri.aNo) + " mismatch!")

            atom_C2 = myBGF.getAtom(N_CONECT_C_aNo[0])
            atom_HN1 = myBGF.getAtom(N_CONECT_H_aNo[0])
            atom_HN2 = myBGF.getAtom(N_CONECT_H_aNo[1])
            atom_HN3 = myBGF.getAtom(N_CONECT_H_aNo[2])

            # update charges
            old_NH3_charge = atom_Npri.charge + atom_HN1.charge + atom_HN2.charge + atom_HN3.charge

            atom_Npri.charge = -0.72540
            atom_HN1.charge = 0.43330
            atom_HN2.charge = 0.43330
            atom_HN3.charge = 0.43330
            new_NH3_charge = atom_Npri.charge + atom_HN1.charge + atom_HN2.charge + atom_HN3.charge
            NH3_charge_change = new_NH3_charge - old_NH3_charge
            if not silent:
                print("NH3 site charge change: " + str(atom_Npri.aNo) + " : " +
                      str(NH3_charge_change))

            # 2. first CH2 part
            C2_CONECT_aNo = atom_C2.CONECT
            C2_CONECT_C_aNo = []
            C2_CONECT_H_aNo = []
            for ano in C2_CONECT_aNo:
                atom = myBGF.getAtom(ano)
                if "H" in atom.ffType:
                    C2_CONECT_H_aNo.append(atom.aNo)
                elif "C" in atom.ffType and ano != atom_C2.aNo:
                    C2_CONECT_C_aNo.append(atom.aNo)

            if len(C2_CONECT_H_aNo) != 2:
                nu.die("Number of H atoms connected with primary amine " +
                       str(atom_C2.aNo) + " mismatch!")
            if len(C2_CONECT_C_aNo) != 1:
                nu.die("Number of C atoms connected with primary amine " +
                       str(atom_C2.aNo) + " mismatch!")

            atom_C3 = myBGF.getAtom(C2_CONECT_C_aNo[0])
            atom_HC21 = myBGF.getAtom(C2_CONECT_H_aNo[0])
            atom_HC22 = myBGF.getAtom(C2_CONECT_H_aNo[1])

            old_CH2_charge = atom_C2.charge + atom_HC21.charge + atom_HC22.charge
            #if not silent: print((atom_C2.charge, atom_HC21.charge, atom_HC22.charge))
            #if not silent: print("old CH2 site charge change: " + str(atom_Npri.aNo) + " : " + str(old_CH2_charge))

            atom_C2.charge = -0.20790
            atom_HC21.charge = 0.24090
            atom_HC22.charge = 0.24090
            new_CH2_charge = atom_C2.charge + atom_HC21.charge + atom_HC22.charge
            #if not silent: print("new CH2 site charge change: " + str(atom_Npri.aNo) + " : " + str(new_CH2_charge))
            CH2_charge_change = new_CH2_charge - old_CH2_charge
            if not silent:
                print("CH2 site charge change: " + str(atom_Npri.aNo) + " : " +
                      str(CH2_charge_change))

            delta_charge = NH3_charge_change + CH2_charge_change
            if not silent:
                print("Primary amine site charge change: " +
                      str(atom_Npri.aNo) + " : " + str(delta_charge))

            # 3. second CH2 part
            old_C3_charge = atom_C3.charge
            if not silent: print("Old C3 charge: " + str(atom_C3.charge))
            atom_C3.charge = atom_C3.charge + (1 - delta_charge)
            if not silent: print("New C3 charge: " + str(atom_C3.charge))
            if not silent:
                print("Total charge: " + " : " + str(myBGF.charge()))

        # renumber
        myBGF.renumber()

        # save
        myBGF.REMARK.insert(
            0, "Protonated by " + os.path.basename(sys.argv[0]) + " by " +
            os.environ["USER"] + " on " + time.asctime(time.gmtime()))
        myBGF.saveBGF(bgf_file[:-4] + "_protonated.bgf")
        if not silent:
            print("saving file " + bgf_file[:-4] + "_protonated.bgf")

    else:
        if not silent:
            print("No amine groups to be protonated")
            sys.exit(0)

    if not silent: print("Done.")