Example #1
0
    def adjust_interior_water(self, n_water):

        if not self._water_position_determined:
            nu.warn("You have to run determine_water_position() first.")
            return

        if not n_water:
            nu.warn(
                "You must specify the number of water molecules inside the Nanotube."
            )
            return

        self.bgfmodel = bgftools.renumberMolecules(self.bgfmodel, 0, False)

        waters = set()
        for atom in self.bgfmodel.a:
            if atom.chain == 'I':
                waters.add(atom.rNo)
        waters = list(waters)
        print("\tFound %d interior water molecules." % len(waters))
        if len(waters) < n_water:
            nu.warn("Too few solvent molecules to choose %d molecules." %
                    n_water)
            return

        rNos = random.sample(waters, n_water)
        print("%d water molecules are randomly chosen. Others are removed." %
              n_water)
        delist = []
        for atom in self.bgfmodel.a:
            if atom.chain == 'I' and not atom.rNo in rNos:
                delist.append(self.bgfmodel.a2i[atom.aNo])
        delist.sort()
        self.bgfmodel.delAtoms(delist, False)
        self.bgfmodel.renumber()
        self.bgfmodel = bgftools.renumberMolecules(self.bgfmodel, 0, False)
        self.update()
Example #2
0
    def determine_water_position(self, *args):
        print("Marking water molecules whether internal or external..")
        if self.isRadiusCalc == False:
            nu.warn("Nanotube radius not calculated.")
            return 0

        tempBGF = bgf.BgfFile()
        tempBGF = bgftools.make_periodic(tempBGF, self.pbc)
        self.make_pbc(self.pbc, self.bgfmodel.CRYSTX)

        # copy Nanotube atoms
        for atom in self.NTatoms + self.otheratoms:
            atom2 = copy.deepcopy(atom)
            tempBGF.addAtom(atom2)
        tempBGF.renumber()

        # mark rNames to Oxygen atoms
        n_oxygen_inside = 0
        n_oxygen_outside = 0

        for atom in self.WATatoms:
            if "H" in atom.ffType:
                continue

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

            if r < self.radius:
                # inside O
                atom.chain = "I"
                n_oxygen_inside += 1
            else:
                # outside O
                atom.chain = "O"
                n_oxygen_outside += 1

        print("Interior oxygens: " + str(n_oxygen_inside) +
              ", exterior oxygens: " + str(n_oxygen_outside))

        self.n_inside_water = n_oxygen_inside
        self.n_outside_water = n_oxygen_outside

        # write water molecules
        chain = ["I", "O"]
        for cname in chain:
            print("Passing " + cname)
            for atom in self.WATatoms:
                if cname in atom.chain and "O" in atom.ffType:
                    tempBGF.addAtom(atom)  #
                    l_Hatoms = atom.CONECT
                    for index, ano in enumerate(l_Hatoms):
                        atom2 = self.bgfmodel.getAtom(ano)
                        atom2.chain = cname
                        tempBGF.addAtom(atom2)  #
        self.bgfmodel = tempBGF
        self.bgfmodel.renumber()
        self.bgfmodel = bgftools.renumberMolecules(self.bgfmodel, 0, False)
        self.update()
        print(
            "Water molecules are identified into interior(I) and exterior(O).")

        if len(args) == 0:
            nu.warn(
                "Residue name and coords for water molecules are modified.")
        elif len(args) == 1:
            print("Modified BGF file is saved to " + str(args[0]))
            self.bgfmodel.saveBGF(args[0])

        self._water_position_determined = True
Example #3
0
def renumberResNum(bgf_file, out_file, silent=True):

    bgftools.renumberMolecules(bgf_file, out_file, False)
Example #4
0
if len(sys.argv) < 3:
    print(usage)
    sys.exit(0)

mybgf = bgf.BgfFile(sys.argv[1])
out_file = sys.argv[2]
selection = sys.argv[3]
n_del = int(sys.argv[4])

resid = set()
for atom in mybgf.a:
    if eval(selection):
        resid.add(atom.rNo)

resid = list(resid)
if len(resid) < n_del:
    nu.die("Not enough molecules to choose %d molecules to delete." % n_del)

rnos = random.sample(resid, n_del)

delist = []
for atom in mybgf.a:
    if atom.rNo in rnos:
        delist.append(mybgf.a2i[atom.aNo])

mybgf.delAtoms(delist)
mybgf.renumber()
mybgf.saveBGF(out_file)
bt.renumberMolecules(out_file, out_file)
for atom in newBGF.a:
    atom.aTag = 0  # change into ATOM
    atom.rName = "WAT"

    if "O" in atom.ffType:
        atom.aName = "O"
        atom.ffType = water_O_ffType

        l_Hatoms = atom.CONECT
        for index, ano2 in enumerate(l_Hatoms):
            atom2 = newBGF.getAtom(ano2)
            atom2.aName = "H" + str(index + 1)
            atom2.ffType = water_H_ffType

# merge myBGF and newBGF
myBGF = myBGF.merge(newBGF, True)
myBGF.renumber()

# save
myBGF = bgftools.renumberMolecules(myBGF, 0)
myBGF.renumber()

try:
    bgf_file = sys.argv[2]
except:
    myBGF.saveBGF(sys.argv[1].split(".bgf")[0] + "_mod.bgf")
else:
    myBGF.saveBGF(bgf_file)

### end
    mybgf, 'atom.z', selection="'S_3a' in atom.ffType and atom.rNo == 2")
avg_s3b_z2 = bt.atoms_average(
    mybgf, 'atom.z', selection="'S_3b' in atom.ffType and atom.rNo == 2")

# prepare water box
solvent = bgf.BgfFile('/home/noische/scripts/dat/WAT/spc_box.bgf')
solvent = bt.stress_cell(solvent, str(1 / math.pow(1.7, 0.3333)))
solvent.saveBGF('_solvent.bgf')

addsolv_reg_cmd = "/qcfs/noische/scripts/BGF_addSolvent_region.py -b _temp.bgf -f %s -o _temp.bgf -m '0 0 %f' -M '%f %f %f' -n %d -t _solvent.bgf -v I" % (
    ff_file, avg_s3a_z1 + 1.5, result.CRYSTX[0], result.CRYSTX[1],
    avg_s3b_z2 - 1.0, n_wat)
print("** Adding confined water..")
print(addsolv_reg_cmd)
os.system(addsolv_reg_cmd)
bt.renumberMolecules('_temp.bgf', '_temp.bgf')

if len(sys.argv) == 8:
    os.system("mv _temp.bgf %s" % out_file)
    sys.exit(0)

# add water outside mos2: bottom
addsolv_reg_cmd = "/qcfs/noische/scripts/BGF_addSolvent_region.py -b _temp.bgf -f %s -o _temp.bgf -M '%f %f %f' -v O" % (
    ff_file, result.CRYSTX[0], result.CRYSTX[1], avg_s3b_z1 - 0.5)
print("** Adding bottom water..")
print(addsolv_reg_cmd)
os.system(addsolv_reg_cmd)
bt.renumberMolecules('_temp.bgf', '_temp.bgf')

# add water outside mos2: top
addsolv_reg_cmd = "/qcfs/noische/scripts/BGF_addSolvent_region.py -b _temp.bgf -f %s -m '0 0 %f' -o %s -v O" % (
def addsolvent(bgf_file,
               solvent_bgf,
               min,
               max,
               n_solvent,
               out_file,
               ff_file,
               margin,
               mark,
               silent=True):

    ### initialize
    water = False
    default_margin = 1.0
    x_margin = 0.0
    y_margin = 0.0
    z_margin = 0.0
    if "x" in margin.lower():
        x_margin = default_margin
    if "y" in margin.lower():
        y_margin = default_margin
    if "z" in margin.lower():
        z_margin = default_margin

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

    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 not min:
        min = [0.0, 0.0, 0.0]
    if not max:
        max = myBGF.CRYSTX[:3]

    strsize = [
        max[0] - min[0] - x_margin, max[1] - min[1] - y_margin,
        max[2] - min[2] - z_margin
    ]

    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
    if not silent: print("Creating box.. this may take some time.")
    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)))
    delatom = []
    delsolvent = []
    delsolventindex = []
    delwater = []
    delwaterindex = []

    bigboxBGF = bgf.BgfFile("_replicate.bgf")
    bigboxBGF.renumber()

    ### trim the water box
    if water:
        if not silent:
            print("Generating water box.. Calculating water molecules")
        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)
        for aNo in delwater:
            delwaterindex.append(bigboxBGF.a2i[aNo])
        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")
        for atom in tqdm.tqdm(bigboxBGF.a, desc='Iterating', ncols=120):
            if atom.x > strsize[0] or atom.y > strsize[1] or atom.z > strsize[
                    2]:
                delatom.append(atom.aNo)

        molecule = bgftools.getMoleculeList(bigboxBGF)
        for aNo in tqdm.tqdm(delatom,
                             desc='Appending atoms to remove',
                             ncols=120):
            for i in molecule:
                if aNo in i:
                    delsolvent += i
                    break
        delsolvent = list(set(delsolvent))
        for aNo in delsolvent:
            delsolventindex.append(bigboxBGF.a2i[aNo])
        if not silent: print("Generating solvent box.. Trimming")
        delsolventindex.sort()
        #delsolventindex.reverse()
        bigboxBGF.delAtoms(delsolventindex, False)
        bigboxBGF.renumber()

    bigboxBGF.saveBGF("_temp.bgf")  ## debug

    ### remain n molecules and delete residues
    bigboxBGF = bgftools.renumberMolecules(bigboxBGF, 0, False)  # renumber rNo

    if n_solvent:
        residues = set()
        for atom in bigboxBGF.a:
            residues.add(atom.rNo)  # scan molecule rNo
        residues = list(residues)
        if not silent: print("Found %d water molecules." % len(residues))
        if len(residues) < n_solvent:
            nu.die("Too few solvent molecules to choose %d molecules." %
                   n_solvent)

        rNos = random.sample(residues, n_solvent)  # select n molecules
        if not silent: print("%d water molecules are chosen." % n_solvent)

        # delete molecules
        delist = []
        for atom in bigboxBGF.a:
            if not atom.rNo in rNos:
                delist.append(bigboxBGF.a2i[atom.aNo])  # if not chosen, delete
        delist.sort()
        bigboxBGF.delAtoms(delist, False)
        bigboxBGF.renumber()

        bigboxBGF = bgftools.renumberMolecules(bigboxBGF, 0, False)

    ### move the water box to min position
    for atom in bigboxBGF.a:
        atom.x += min[0] + x_margin / 2
        atom.y += min[1] + y_margin / 2
        atom.z += min[2] + z_margin / 2

    ### add mark to the solvents
    if mark:
        for atom in bigboxBGF.a:
            atom.chain = mark

    bigboxBGF.saveBGF('_temp.bgf')

    # 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.
    ## 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)
    myBGF = bgf.BgfFile(bgf_file)
    bigboxBGF = bgf.BgfFile("_temp.bgf")
    bigboxBGF2 = myBGF.merge(bigboxBGF)
    if not silent: print("Total atoms in the file: " + str(len(bigboxBGF.a)))

    ## some paperworking for periodic box
    bigboxBGF2.OTHER = myBGF.OTHER
    bigboxBGF2.PERIOD = myBGF.PERIOD
    bigboxBGF2.AXES = myBGF.AXES
    bigboxBGF2.SGNAME = myBGF.SGNAME
    bigboxBGF2.CRYSTX = myBGF.CRYSTX
    bigboxBGF2.CELLS = myBGF.CELLS

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

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

    return 1