示例#1
0
def centerbgffileclass(myBGF, method="com_origin"):

    new_x, new_y, new_z = bgftools.getCom(myBGF, "")

    if len(myBGF.CRYSTX) > 2:
        boxcenter = [(i / 2.0) for i in myBGF.CRYSTX[0:3]]
    else:
        boxsize = bgf.getBGFSize(myBGF, 0)
        boxcenter = [(boxsize[1] - boxsize[0]) / 2,
                     (boxsize[3] - boxsize[2]) / 2,
                     (boxsize[5] - boxsize[4]) / 2]

    if method == "com_origin":
        bgf.moveBGF(myBGF, (-new_x), (-new_y), (-new_z))
    elif method == "com_center":
        dx = boxcenter[0] - new_x
        dy = boxcenter[1] - new_y
        dz = boxcenter[2] - new_z
        bgf.moveBGF(myBGF, dx, dy, dz)
    elif method == "box_origin":
        dx = boxcenter[0]
        dy = boxcenter[1]
        dz = boxcenter[2]
        bgf.moveBGF(myBGF, dx, dy, dz)
    else:
        bgf.moveBGF(myBGF, (-new_x), (-new_y), (-new_z))

    return myBGF
示例#2
0
def centerbgf(bgf_file, out_file, ff_file, method="com_origin", silent=False):
    if silent == 1:
        nu.shutup()

    boxcenter = []

    # open bgf
    if isinstance(bgf_file, bgf.BgfFile):
        myBGF = bgf_file
    else:
        if not silent: print("Reading " + bgf_file + " ..")
        myBGF = bgf.BgfFile(bgf_file)
        if not silent:
            print("Moving the origin of the coordinate in " + bgf_file +
                  " and saving to " + out_file + ".")

    if method != "box_origin":
        new_x, new_y, new_z = bgftools.getCom(myBGF, ff_file)

    if len(myBGF.CRYSTX) > 2:
        boxcenter = [(i / 2.0) for i in myBGF.CRYSTX[0:3]]
    else:
        boxsize = bgf.getBGFSize(myBGF, 0)  # [xlo, xhi, ylo, yhi, zlo, zhi]
        boxcenter = [(boxsize[1] - boxsize[0]) / 2,
                     (boxsize[3] - boxsize[2]) / 2,
                     (boxsize[5] - boxsize[4]) / 2]

    if method == "com_origin":
        bgf.moveBGF(myBGF, (-new_x), (-new_y), (-new_z))
    elif method == "com_center":
        dx = boxcenter[0] - new_x
        dy = boxcenter[1] - new_y
        dz = boxcenter[2] - new_z
        bgf.moveBGF(myBGF, dx, dy, dz)
    elif method == "box_origin":
        dx = boxcenter[0]
        dy = boxcenter[1]
        dz = boxcenter[2]
        bgf.moveBGF(myBGF, dx, dy, dz)
    else:
        bgf.moveBGF(myBGF, (-new_x), (-new_y), (-new_z))

    # save
    if isinstance(out_file, str):
        if not silent: print("Saving information to " + out_file + " ..")
        myBGF.saveBGF(out_file)
        return 1
    else:
        return myBGF
示例#3
0
def addsolvent(bgf_file,
               solvent_bgf,
               size,
               margin,
               out_file,
               ff_file,
               silent=True):

    ### initialize
    water = False

    ### load the solute bgf file
    if not silent: print("Initializing..")
    myBGF = bgf.BgfFile(bgf_file)  # str

    #solventBGF = bgf.BgfFile("/home/noische/scripts/dat/WAT/f3c_box.bgf")	# F3C waterbox
    if not silent: print("Loading the solvent file " + solvent_bgf + " ..")
    solventBGF = bgf.BgfFile(solvent_bgf)

    ### Generate error when the solvent box is not periodic:
    if not solventBGF.PERIOD:
        nu.die(
            "addSolvent: The solvent file is not periodic. Use a box full of solvent."
        )

    ### Check the type of solvent
    if not silent:
        print("(the solvent box seems to be full of " +
              os.path.basename(solvent_file)[:-4] + " )")
    if "f3c" in solvent_bgf:
        water = True  # this flag is used to remove the bad contacts with the molecule.
    if "spc" in solvent_bgf:
        water = True  # this flag is used to remove the bad contacts with the molecule.
    if "tip" in solvent_bgf:
        water = True  # this flag is used to remove the bad contacts with the molecule.

    ### calculate the box size
    if not silent: print("Analyzing box information..")
    if len(myBGF.CRYSTX) > 2:
        strsize = [myBGF.CRYSTX[0], myBGF.CRYSTX[1], myBGF.CRYSTX[2]]
    else:
        box = bgf.getBGFSize(myBGF, 0)  # [xlo, xhi, ylo, yhi, zlo, zhi]
        strsize = [box[1] - box[0], box[3] - box[2], box[5] - box[4]]

    ###
    if size == "" and margin != "":
        strsize = [
            strsize[0] + 2 * margin[0], strsize[1] + 2 * margin[1],
            strsize[2] + 2 * margin[2]
        ]  # add margin on str size
    elif size != "" and margin == "":
        strsize = size

    waterboxsize = solventBGF.CRYSTX[:3]  # REMARK: This is a kind of constant.
    copyNumber = [0, 0, 0]
    for index, i in enumerate(copyNumber):
        copyNumber[index] = math.ceil(
            strsize[index] /
            waterboxsize[index])  # how many times to replicate the water box

    if not silent: print("Creating box information: " + str(strsize))

    ### replicate the solvent box
    bigboxBGF = bgftools.replicateCell(solventBGF, copyNumber, True)
    bigboxBGF.saveBGF("_replicate.bgf")
    if not silent:
        print("- Number of atoms in the created box: " + str(len(bigboxBGF.a)))

    ### trim the water box
    if water:
        if not silent:
            print("Generating water box.. Calculating water molecules")
        delatom = []
        delwater = []
        delwaterindex = []
        for atom in bigboxBGF.a:
            if atom.x > strsize[0] or atom.y > strsize[1] or atom.z > strsize[
                    2]:
                delatom.append(atom.aNo)
        for aNo in delatom:
            water_molecule = bgftools.is_water(bigboxBGF, aNo)
            if not water_molecule in delwater:
                delwater.append(water_molecule)
        delwater = nu.flatten(delwater)
        delwater = nu.removeRepeat(delwater)
        delwater.sort()
        delwater.reverse()
        for aNo in delwater:
            delwaterindex.append(bigboxBGF.getAtomIndex(aNo))
        del (delwater)
        if not silent: print("Generating water box.. Trimming")
        bigboxBGF.delAtoms(delwaterindex, False)
        bigboxBGF.renumber()
    elif not water:
        if not silent:
            print("Generating solvent box.. Extracting solvent molecules")
        delatom = []
        delsolvent = []
        delsolventindex = []
        for atom in bigboxBGF.a:
            if atom.x > strsize[0] or atom.y > strsize[1] or atom.z > strsize[
                    2]:
                delatom.append(atom.aNo)
        for aNo in delatom:
            molecule_list = []
            molecule = bgftools.getmolecule(bigboxBGF, bigboxBGF.getAtom(aNo),
                                            molecule_list)
            for number in molecule_list:
                if not number in delsolvent: delsolvent.append(number)
        delsolvent = nu.flatten(delsolvent)
        delsolvent = nu.removeRepeat(delsolvent)
        delsolvent.sort()
        delsolvent.reverse()
        for aNo in delsolvent:
            delsolventindex.append(bigboxBGF.getAtomIndex(aNo))
        if not silent: print("Generating solvent box.. Trimming")
        bigboxBGF.delAtoms(delsolventindex, False)
        bigboxBGF.renumber()

    ### merge two structure
    # REMARK: it is natural to have the periodic information of water box for the output BGF file.
    # REMARK: HETATOM should be located on the first of the BGF file. So use dummy for merging.
    if not silent: print("\nAdding trimmed solvent box to the structure..")
    bigboxcenter = [strsize[0] / 2, strsize[1] / 2, strsize[2] / 2]
    a, b, c = bgftools.getCom(myBGF, ff_file)
    bgf.moveBGF(myBGF, bigboxcenter[0] - a, bigboxcenter[1] - b,
                bigboxcenter[2] - c)

    ## remove bad contacts between solutes and solvents
    if not silent: print("Atom distance calculation for contacts..")
    delatom = []
    delsolvent = []
    delsolventindex = []
    for atom1 in myBGF.a:
        for atom2 in bigboxBGF.a:
            # if the distance between atom1 and atom2 is less than 2.8, add to a delete list
            dist_sq = (atom1.x - atom2.x)**2 + (atom1.y - atom2.y)**2 + (
                atom1.z - atom2.z)**2
            if dist_sq < 7.84:
                delatom.append(atom2.aNo)

    # delete bad atoms!
    if not silent: print("Removing bad contacts..")
    for aNo in delatom:
        molecule_list = []
        molecule = bgftools.getmolecule(bigboxBGF, bigboxBGF.getAtom(aNo),
                                        molecule_list)
        for number in molecule_list:
            if not number in delsolvent: delsolvent.append(number)
    delsolvent = nu.flatten(delsolvent)
    delsolvent = nu.removeRepeat(delsolvent)
    delsolvent.sort()
    delsolvent.reverse()
    for aNo in delsolvent:
        delsolventindex.append(bigboxBGF.getAtomIndex(aNo))
    bigboxBGF.delAtoms(delsolventindex, False)
    bigboxBGF.renumber()

    ## compute stats for adding solvents
    if not silent: print("\nComputing stats..")
    mol_list = bgftools.getMoleculeList(bigboxBGF)
    n_mol = len(mol_list)
    n_atom = len(nu.flatten(mol_list))
    if not silent:
        print(
            str(n_mol) + " molecules (" + str(n_atom) +
            " atoms) will be added.")

    ## merge
    bigboxBGF = myBGF.merge(bigboxBGF, True)
    if not silent: print("Total atoms in the file: " + str(len(bigboxBGF.a)))

    ## some paperworking for periodic box
    bigboxBGF.OTHER = solventBGF.OTHER
    bigboxBGF.PERIOD = solventBGF.PERIOD
    bigboxBGF.AXES = solventBGF.AXES
    bigboxBGF.SGNAME = solventBGF.SGNAME
    bigboxBGF.CRYSTX = solventBGF.CRYSTX
    bigboxBGF.CELLS = solventBGF.CELLS

    ## adjust the size of the box
    bigboxBGF.CRYSTX = [
        strsize[0], strsize[1], strsize[2], solventBGF.CRYSTX[3],
        solventBGF.CRYSTX[4], solventBGF.CRYSTX[5]
    ]
    """
	### remove bad contacts and save
	if water:
		if not silent: print("Removing bad contacts: distance criteria is 2.8 A")
		bigboxBGF = removebadcontacts(bigboxBGF, bigboxBGF, 2.8)

		### renumber residue numbers
		# RULE: all rNos for water molecules will be renumbered from 2. (for createLammpsInput.pl)
		if not silent: print("Renumbering water molecules..")
		max_rNo_in_hetatm = 0;
		oxygen_list = bgftools.listOxygenAtoms(bigboxBGF)
	
		### find the biggest rNo among HETATM
		for atom in bigboxBGF.a:
			if atom.aTag == 1:
				if max_rNo_in_hetatm < atom.rNo: max_rNo_in_hetatm = atom.rNo
	
		### update rNo in water molecules
		rNo_for_water = max_rNo_in_hetatm + 500;
		for aNo in oxygen_list:
			water_aNo = bgftools.is_water(bigboxBGF, aNo)	# get aNo in a water molecule by checking the oxygen atom
			if water_aNo != []:
				for atom_aNo in water_aNo:
					bigboxBGF.getAtom(atom_aNo).rNo = rNo_for_water
				rNo_for_water += 1
	"""

    ### record BGF remarks
    bigboxBGF.REMARK.insert(
        0, "Solvents added by " + os.path.basename(sys.argv[0]) + " by " +
        os.environ["USER"] + " on " + time.asctime(time.gmtime()))
    bigboxBGF.REMARK.insert(0, "Solvents: " + str(solvent_file))

    ### save BGF
    if not silent: print("Saving the file.. see " + str(out_file))
    bigboxBGF.saveBGF(out_file)

    return 1
示例#4
0
def replicateCell(myBGF, multiplication, spaceFilling=True):
    """
replicateCell():
    Requires a BgfFile class.
    Returns a BgfFile class of the replicated structure of the given structure.

    Options:
    spaceFilling = True
        Just copy the cell (x, y, z) times to the (x, y, z) coordinateas. Negative multiplication indices are allowed.
        (1, 1, 1) with a cell gives 4 cells (i.e. replication to x, y, and z coordinates).

    spaceFilling = False
        Fill the space as a Cuboid form for a given times. Negative multiplication indices are NOT allowed.
        (2, 1, 3) with a cell gives the 6 cells (i.e. cubiod). (1, 1, 1) with a cell gives the identical structure (nothing happens).
    """

    copyTime = [
        int(multiplication[0]),
        int(multiplication[1]),
        int(multiplication[2])
    ]
    # the number of cells that will be copied
    myBGFx = bgf.BgfFile()
    myBGFy = bgf.BgfFile()
    myBGFz = bgf.BgfFile()
    boxsize = [0, 0, 0]

    if len(myBGF.CRYSTX) > 2:
        boxsize = [myBGF.CRYSTX[0], myBGF.CRYSTX[1], myBGF.CRYSTX[2]]
    else:
        box = bgf.getBGFSize(myBGF, 0)  # [xlo, xhi, ylo, yhi, zlo, zhi]
        boxsize = [box[1] - box[0], box[3] - box[2], box[5] - box[4]]

    if spaceFilling:
        if copyTime[0] != 0:
            myBGF2 = copy.deepcopy(myBGF)
            for n in range(0, copyTime[0] - 1):
                bgf.moveBGF(myBGF2, boxsize[0], 0, 0)
                myBGF = myBGF.merge(myBGF2, True)
        if copyTime[1] != 0:
            myBGF2 = copy.deepcopy(myBGF)
            for n in range(0, copyTime[1] - 1):
                bgf.moveBGF(myBGF2, 0, boxsize[1], 0)
                myBGF = myBGF.merge(myBGF2, True)
        if copyTime[2] != 0:
            myBGF2 = copy.deepcopy(myBGF)
            for n in range(0, copyTime[2] - 1):
                bgf.moveBGF(myBGF2, 0, 0, boxsize[2])
                myBGF = myBGF.merge(myBGF2, True)

        # update the CRYSTX information
        if len(myBGF.CRYSTX) > 2:
            for index, number in enumerate(copyTime):
                myBGF.CRYSTX[index] *= copyTime[index]

    else:
        # replication
        if copyTime[0] != 0:
            if copyTime[0] < 0: sign = -1
            else: sign = 1
            for n in range(0, abs(copyTime[0])):
                if copyTime[0] < 0: n -= 1
                myBGF2 = copy.deepcopy(myBGF)
                bgf.moveBGF(myBGF2, boxsize[0] * (n + 1) * sign, 0, 0)
                myBGFx = myBGFx.merge(myBGF2, True)
        if copyTime[1] != 0:
            if copyTime[0] < 0: sign = -1
            else: sign = 1
            for n in range(0, abs(copyTime[1])):
                if copyTime[0] < 0: n -= 1
                myBGF2 = copy.deepcopy(myBGF)
                bgf.moveBGF(myBGF2, 0, boxsize[1] * (n + 1) * sign, 0)
                myBGFy = myBGFy.merge(myBGF2, True)
        if copyTime[2] != 0:
            if copyTime[0] < 0: sign = -1
            else: sign = 1
            for n in range(0, abs(copyTime[2])):
                if copyTime[0] < 0: n -= 1
                myBGF2 = copy.deepcopy(myBGF)
                bgf.moveBGF(myBGF2, 0, 0, boxsize[2] * (n + 1) * sign)
                myBGFz = myBGFz.merge(myBGF2, True)

        myBGF = myBGF.merge(myBGFx, True)
        myBGF = myBGF.merge(myBGFy, True)
        myBGF = myBGF.merge(myBGFz, True)

        # update the CRYSTX information
        if len(myBGF.CRYSTX) > 2:
            for index, number in enumerate(copyTime):
                myBGF.CRYSTX[index] += myBGF.CRYSTX[index] * copyTime[index]

    return myBGF
示例#5
0
def poresize(bgf_file, out_file, grid=0.25, thresh=0.25, silent=False):
    """
def poresize():
	Calculates pore sizes in the BGF molecule

Function Parameters:
	bgf_file	A string which contains a PEI information in a BGF format. 
			(e.g. "file1.bgf file2.bgf file3.bgf ...")
	"""

    # initialize
    xyz = []
    rvdw = dict()
    ubound = 10
    lbound = 0

    # open bgf
    myBGF = bgf.BgfFile(bgf_file)

    # read van der waals radii
    rvdw['H'] = 1.2
    rvdw['C'] = 1.7
    rvdw['N'] = 1.55
    rvdw['O'] = 1.52

    # copy positions: [ x y z vdw ]
    for atom in myBGF.a:
        atomtype = atom.ffType[:-1].strip("_")
        xyz.append(
            [float(atom.x),
             float(atom.y),
             float(atom.z), rvdw[atomtype]])

    xyz = np.array(xyz)

    # get bgf size
    size = np.array(bgf.getBGFSize(myBGF))
    np.around(size, decimals=1)

    # make grid
    grid_x = np.arange(size[0], size[1], grid)
    grid_y = np.arange(size[2], size[3], grid)
    grid_z = np.arange(size[4], size[5], grid)
    len_grid_x = len(grid_x)
    len_grid_y = len(grid_y)
    len_grid_z = len(grid_z)
    poresize = np.zeros((len_grid_x, len_grid_y, len_grid_z))

    ix = 0
    iy = 0
    iz = 0
    t1 = 0
    t2 = 0

    # for each grid
    for ix, x in enumerate(grid_x):
        t1 = time.time()

        for iy, y in enumerate(grid_y):

            for iz, z in enumerate(grid_z):

                ubound = 10
                lbound = 0
                minubound = 10

                while ubound - lbound > thresh:

                    test_r = random.uniform(lbound, ubound)

                    flag = True
                    for atom in xyz:
                        value = (x - atom[0])**2 + (y - atom[1])**2 + (
                            z - atom[2])**2 - atom[3]**2 - test_r**2
                        if value < 0:
                            flag = False
                            if minubound > test_r: minubound = test_r

                    if flag:
                        lbound = test_r
                    else:
                        ubound = minubound

                    poresize[ix, iy, iz] = test_r

        t2 = time.time()
        print(
            str(ix) + " out of " + str(len_grid_x) +
            "( elapsed time for the step: " + str(t2 - t1) + " sec)")

    # store them as a matrix
    scipy.io.savemat(out_file, {'m': poresize})
示例#6
0
def poresize(bgf_file, out_file, grid=0.25, thresh=0.25, silent=False):
    """
def poresize():
	Calculates pore sizes in the BGF molecule

Function Parameters:
	bgf_file	A string which contains a PEI information in a BGF format. 
			(e.g. "file1.bgf file2.bgf file3.bgf ...")
	"""

    # initialize
    xyz = []
    rvdw = dict()
    ubound = 10
    lbound = 0

    # open bgf
    myBGF = bgf.BgfFile(bgf_file)

    # read van der waals radii
    rvdw['H'] = 1.2
    rvdw['C'] = 1.7
    rvdw['N'] = 1.55
    rvdw['O'] = 1.52

    # copy positions: [ x y z vdw ]
    for atom in myBGF.a:
        atomtype = atom.ffType[:-1].strip("_")
        xyz.append(
            [float(atom.x),
             float(atom.y),
             float(atom.z), rvdw[atomtype]])

    xyz = np.array(xyz)

    # get bgf size
    size = np.array(bgf.getBGFSize(myBGF))
    np.around(size, decimals=1)

    # make grid
    grid_x = np.arange(size[0], size[1], grid)
    grid_y = np.arange(size[2], size[3], grid)
    grid_z = np.arange(size[4], size[5], grid)
    len_grid_x = len(grid_x)
    len_grid_y = len(grid_y)
    len_grid_z = len(grid_z)
    poresize = np.zeros((len_grid_x, len_grid_y, len_grid_z))

    # for each grid
    for ix, x in enumerate(grid_x):
        print(str(ix) + " out of " + str(len_grid_x))
        for iy, y in enumerate(grid_y):
            for iz, z in enumerate(grid_z):
                ubound = 10
                lbound = 0
                minubound = 10

                while ubound - lbound > thresh:

                    test_r = random.uniform(lbound, ubound)

                    ### check the distance
                    flag = True
                    for atom in xyz:
                        value = (x - atom[0])**2 + (y - atom[1])**2 + (
                            z - atom[2])**2 - atom[3]**2 - test_r**2
                        if value < 0:
                            flag = False
                            if minubound > test_r: minubound = test_r

                    if flag:
                        lbound = test_r
                    else:
                        ubound = minubound

                    poresize[ix, iy, iz] = test_r

    # store them as a matrix
    with file(out_file, 'w') as outfile:
        for data in poresize:
            outfile.write("# new shot\n")
            np.savetxt(outfile, data, fmt='%8.2f')