Esempio n. 1
0
def run(mybgf, t, chunk, sel=""):
    """
    This function performs the calculation.
    Output:
        - int t: timestep
        - list result: found hbonds
        - bgf.BgfFile mybgf: BgfFile with update coordinates
        - string sel: a selection
    """

    mybgf = update_coord(chunk, mybgf, mytrj.pbc[t], scaled=yes_scale)
    mybgf = bt.periodicMoleculeSort(mybgf, mybgf.CRYSTX, fragments=atom_frags, ff_file=ff_file, silent=True)

    if not sel:
        sel = calculate_sel_kwac(mybgf)    # for Kwac's confined water molecules in MoS2 nanoslit
    elif sel == "all":
        sel = ""    # for water

    if sel:
        sel_O_atoms = [atom.aNo for atom in mybgf.a if eval(sel) and 'O' in atom.ffType]
    else:
        sel_O_atoms = [atom.aNo for atom in mybgf.a if 'O' in atom.ffType]

    result = hbonds(mybgf, selection=sel)

    if verbose:
        mybgf.saveBGF(str(t) + ".bgf")

    return t, sel_O_atoms, result
Esempio n. 2
0
def run_hb(mybgf, t, chunk):

    mybgf = update_coord(chunk, mybgf, mytrj.pbc[t], scaled=yes_scale)
    mybgf = bt.periodicMoleculeSort(mybgf,
                                    mybgf.CRYSTX,
                                    fragments=atom_frags,
                                    ff_file=ff_file,
                                    silent=True)
    '''
    #sel = "atom.chain == 'I'"  # for test
    # find inwater boundary for selection
    swr = 3.270615945/2
    gwr = 3.057430885/2
    margin = 5.0
    gwa_y = bt.atoms_average(mybgf, 'atom.y', selection="'GWA' in atom.rName")
    gwb_y = bt.atoms_average(mybgf, 'atom.y', selection="'GWB' in atom.rName")
    if type == "gra":
        avg_z1 = bt.atoms_average(mybgf, 'atom.z', selection="'C_R' in atom.ffType and 'GRA' in atom.rName")    # gra bottom
        avg_z2 = bt.atoms_average(mybgf, 'atom.z', selection="'C_R' in atom.ffType and 'GRB' in atom.rName")    # gra top
        actual_distance = avg_z2 - avg_z1
    elif type == "mos":
        avg_s3a_z2 = bt.atoms_average(mybgf, 'atom.z', selection="'S_3a' in atom.ffType and atom.rNo == 2")    # mos2 top
        avg_s3b_z1 = bt.atoms_average(mybgf, 'atom.z', selection="'S_3b' in atom.ffType and atom.rNo == 1")    # mos2 bottom
        actual_distance = avg_s3a_z2 - avg_s3b_z1
    inwater_x = mybgf.CRYSTX[0]
    inwater_y = gwb_y - gwa_y + 2 * gwr - 2 * margin
    inwater_z = actual_distance - 2 * swr

    sel = "atom.y > {gwa_y} + {margin} and atom.y < {gwb_y} - {margin}".format(**vars())
    '''
    sel = ""

    hb = calc_hbonds(mybgf, selection=sel)

    return t, hb
Esempio n. 3
0
def analyze(bgf_file, trj_file, ff_file='', out_file=''):
    '''analyze something within a timestep in a series of lammps trajectory.
    '''

    # variables

    # inner functions
    def get_line(file):
        with open(file, 'r') as f:
            for line in f:
                yield line

    # 1. Load BGF
    mybgf = bgf.BgfFile(bgf_file)
    N_BGF_ATOMS = len(mybgf.a)

    # 2. Read LAMMPS Trajectory
    #timesteps, N_HEADER, N_ATOMS = lt.getTrjInfo(trj_file)
    mytrj = lt.lammpstrj(trj_file)
    timesteps = mytrj.load()
    N_HEADER = mytrj.nheader
    N_ATOMS = mytrj.natoms[0]
    N_BUFFER = N_HEADER + N_ATOMS
    if N_BGF_ATOMS != N_ATOMS:
        nu.die(
            "Number of atoms in trajectory file does not match with BGF file.")

    # 3. Determine dump style
    dump_keywords = mytrj.dumpstyle
    yes_scale = False
    if 'xs' in dump_keywords:
        yes_scale = True

    # 4. Update coordinates from the snapshot
    dump = get_line(trj_file)
    for t in tqdm.tqdm(timesteps, ncols=120, desc="Analyzing"):
        chunk = [next(dump) for i in range(N_BUFFER)]

        t = int(chunk[1])
        mybgf.CRYSTX = mytrj.pbc[t] + [90.0, 90.0, 90.0]

        coords = chunk[9:]
        for c in coords:
            c = c.split(' ')
            atom = mybgf.getAtom(int(c[0]))

            if yes_scale:
                atom.x = float(c[2]) * pbc[0]
                atom.y = float(c[3]) * pbc[1]
                atom.z = float(c[4]) * pbc[2]
            else:
                atom.x = float(c[2])
                atom.y = float(c[3])
                atom.z = float(c[4])

        mybgf = bt.periodicMoleculeSort(mybgf,
                                        mybgf.CRYSTX,
                                        ff_file=ff_file,
                                        silent=True)
Esempio n. 4
0
def run(system, t, coords, sel=""):
    """
    This function performs the analysis.
    Input:
        - bgf.BgfFile mybgf
        - int t: a timestep written in LAMMPS trjectory
        - list chunk: list of atom coordinates in LAMMPS trajectory
        - str sel: a string to evaluate for selecting atoms
    Output:
        - int t: timestep
        - list result: found hbonds
    """
    assert isinstance(system, bgf.BgfFile), "Wrong object: should be an instance of bgf.BgfFile class."
    assert isinstance(t, int), "Timestep should be int."
    assert isinstance(coords, list), "coords should be a list."

    # update the coordinates from trj to the BGF object
    system = update_coord(coords, system, mytrj.pbc[t], scaled=yes_scale)

    # wrap the coordinates into the pbc cell
    system = bt.periodicMoleculeSort(system, system.CRYSTX, fragments=atom_frags, ff_file=ff_file, silent=True)

    selected_atoms = [atom for atom in system.a if eval(sel)]

    # do analysis here
    out = []  # list to save results
    # ...
    # something something something
    # ...
    #
    # blah blah blah
    # ...

    # save each trajectory as BGF file if verbose mode activated.
    if verbose:
        system.saveBGF(str(t) + ".bgf")

    return t, out
Esempio n. 5
0
def run(mybgf, t, chunk, sel=""):
    """
    This function performs the calculation.
    Output:
        - int t: timestep
        - list result: found hbonds
        - bgf.BgfFile mybgf: BgfFile with update coordinates
        - string sel: a selection
    """

    mybgf = update_coord(chunk, mybgf, mytrj.pbc[t], scaled=yes_scale)
    mybgf = bt.periodicMoleculeSort(mybgf,
                                    mybgf.CRYSTX,
                                    fragments=atom_frags,
                                    ff_file=ff_file,
                                    silent=True)

    result = hbonds(mybgf, selection=sel)

    if verbose:
        mybgf.saveBGF(str(t) + ".bgf")

    return t, result
Esempio n. 6
0
def countWaterCNT(bgf_file, trj_file, silent=False):

    # init
    timestep = 0
    l_timestep = []

    myBGF = bgf.BgfFile(bgf_file)
    myTRJ = open(trj_file)
    myDAT = open(bgf_file[:-4] + ".count.dat", "w")
    myDAT.write("Time\tHeight\tRadius\tNumber\n")

    # extract aNos of CNT in the BGF file
    aNo_CNT = []
    aNo_MtOH_C = []
    for atom in myBGF.a:
        # Carbons in CNT
        if "CNT" in atom.rName:
            aNo_CNT.append(atom.aNo)

        # Carbons in MeOH
        if "MET" in atom.rName and "C" in atom.aName:
            aNo_MtOH_C.append(atom.aNo)

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

    # for every shot in the trajectory file update BGF and manipulate
    myDUMP = dump.dump(trj_file, 0)  # sequential reading

    while 1:

        aNo_MtOH_C_in_CNT = copy.deepcopy(aNo_MtOH_C)

        # 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

        time = myDUMP.next()
        sys.stdout.write('\r' + "Reading timestep.. " + str(time))
        sys.stdout.flush()
        #print("Timestep: " + str(time))
        if time == -1:
            break

        nu.shutup()
        myDUMP.sort()
        nu.say()
        l_timestep = myDUMP.time()  # timesteps are 'appended' incrementally
        atoms = myDUMP.viz(len(l_timestep) - 1)[
            2]  # atom coordinate info: id,type,x,y,z for each atom as 2d array
        box = myDUMP.viz(len(l_timestep) -
                         1)[1]  # [xlo, ylo, zlo, xhi, yhi, zhi]
        box = [float(i) for i in box]
        boxsize = [box[3] - box[0], box[4] - box[1],
                   box[5] - box[1]]  # simbox size

        myBGF.CRYSTX = [
            boxsize[0], boxsize[1], boxsize[2], myBGF.CRYSTX[3],
            myBGF.CRYSTX[4], myBGF.CRYSTX[5]
        ]

        #print("l_atoms " + str(len(atoms)))

        # update the coordinates in the bgf file
        for atom in atoms:
            bgfatom = myBGF.getAtom(atom[0])
            bgfatom.x = float(atom[2])
            bgfatom.y = float(atom[3])
            bgfatom.z = float(atom[4])
        """
		# com of CNT
		for atom in myBGF.a:
			if "CNT" in atom.rName:
				Mx += atom.x / N_CNT
				My += atom.y / N_CNT
				Mz += atom.z / N_CNT
		"""

        myBGF = bgftools.periodicMoleculeSort(myBGF)

        #print(Mx, My, Mz)
        # transpose for "all atoms in BGF"
        for atom in myBGF.a:
            atom.x -= Mx
            atom.y -= My
            atom.z -= Mz

        # calculate the moment of inertia (MI) and the center of mass (COM) of CNT from "myBGF"
        for aNo in aNo_CNT:
            atom = myBGF.getAtom(aNo)
            Ixx += (atom.y**2 + atom.z**2) / N_CNT
            Iyy += (atom.x**2 + atom.z**2) / N_CNT
            Izz += (atom.x**2 + atom.y**2) / N_CNT
            Ixy -= (atom.x * atom.y) / N_CNT
            Ixz -= (atom.x * atom.z) / N_CNT
            Iyz -= (atom.y * atom.z) / N_CNT

        # the moment of inertia tensor
        I = numpy.array([[Ixx, Ixy, Ixz], [Ixy, Iyy, Iyz], [Ixz, Iyz, Izz]])

        # eigenvalue & eigenvector calculation
        eigval, eigvec = numpy.linalg.eig(
            I)  # eigval[0] is the minimum among the values.

        # rearrange the U vector
        U = numpy.matrix(eigvec)
        Ut = U.T

        # "myBGF" transform
        for atom in myBGF.a:
            v = numpy.matrix([atom.x, atom.y, atom.z]).T
            Uv = Ut * v
            atom.x = float(Uv[0])
            atom.y = float(Uv[1])
            atom.z = float(Uv[2])

        # com of CNT
        Mx = 0
        My = 0
        Mz = 0
        for atom in myBGF.a:
            if "CNT" in atom.rName:
                Mx += atom.x / N_CNT
                My += atom.y / N_CNT
                Mz += atom.z / N_CNT
        #print(Mx, My, Mz)

        # transpose for "all atoms in BGF"
        for atom in myBGF.a:
            atom.x -= Mx
            atom.y -= My
            atom.z -= Mz
        """ ### THIS PART (UPDATING LAMMPSTRJ) DOES NOT WORK ###

		myDUMP.aselect.all(time)	# all atoms should be selected to be changed
		myDUMP.tselect.one(time)
		coordx = []; coordy = []; coordz = []
		for atom in myBGF.a:
			coordx.append(atom.x)
			coordy.append(atom.y)
			coordz.append(atom.z)
		myDUMP.setv("xu", coordx)
		myDUMP.setv("yu", coordy)
		myDUMP.setv("zu", coordz)
		"""
        """	### CHECKING ORIGIN by adding an atom at (0, 0, 0) and is okay. 110914 inkim
		origin = bgf.BgfAtom()
		origin.aTag = 0
		origin.aName = "ORIG"
		origin.ffType = "Ar"
		origin.chain = "A"
		origin.x = 0.0
		origin.y = 0.0
		origin.z = 0.0
		origin.rName = "ORG"
		myBGF.addAtom(origin)
		"""

        # for CNT atoms, calculate some properties
        min_x_CNT = 0.0
        max_x_CNT = 0.0
        radius_CNT = 0.0
        height_CNT = 0.0

        for aNo in aNo_CNT:
            atom = myBGF.getAtom(aNo)
            # minimum and maximum x coord of CNT: this will be the height of CNT
            if atom.x < min_x_CNT:
                min_x_CNT = atom.x
            if atom.x > max_x_CNT:
                max_x_CNT = atom.x
            radius_CNT += math.sqrt(atom.y**2 +
                                    atom.z**2)  # average radius of CNT

        radius_CNT = radius_CNT / N_CNT
        height_CNT = max_x_CNT - min_x_CNT

        # determine whether C in MtOH is in the CNT Cylinder
        for aNo in aNo_MtOH_C:
            atom = myBGF.getAtom(aNo)
            dist = math.sqrt(atom.y**2 + atom.z**2)
            if atom.x > min_x_CNT \
             and atom.x < max_x_CNT \
             and dist < radius_CNT:
                pass
            else:
                aNo_MtOH_C_in_CNT.remove(aNo)

        #print("Height of CNT: " + str(height_CNT) + " " + str(min_x_CNT) +  " " + str(max_x_CNT))
        #print("Average radius of CNT: " + str(radius_CNT))
        #print("Average number of methanols in CNT: " + str(len(aNo_MtOH_C_in_CNT)))
        myDAT.write(str(time) + "\t")
        myDAT.write(str("{0:<8.3f}".format(height_CNT)))
        myDAT.write(str("{0:<8.3f}".format(radius_CNT)))
        myDAT.write(str(len(aNo_MtOH_C_in_CNT)) + "\n")

        # write output
        myBGF.saveBGF(bgf_file[:-4] + "." + str(time) + ".bgf")

    #myDUMP.write(trj_file.split(".")[0] + "_mod." + trj_file.split(".")[1])

    print('')
    return 1
Esempio n. 7
0
def getVelocity(bgf_file, trj_file, n_step, 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

    l_data = []
    # stores vz
    l_avg_radius_CNT = []

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

    ftemp = open("countWater42.profile", 'w')
    ftemp.write(str(sys.argv) + "\n")

    curr_dir = os.path.abspath(".")
    temp_dir = curr_dir + "/CountWAT42/"
    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 last " + str(n_step) +
          " timesteps.")

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

    for atom in myBGF.a:
        # Carbons in CNT or atoms in BNNT
        if "NT" in atom.rName:
            aNo_CNT.append(atom.aNo)

        # 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
        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(' ')

        ### update myBGF with trajectory information ###
        natom_bgf = len(myBGF.a)  # number of atoms in BGF file

        if not natom_bgf == natoms:
            nu.die(
                "Number of atoms in trajectory file does not match with BGF file."
            )

        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:]

        # modified for fast treatment
        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])
            atom.vx = float(atomcoord[5])
            atom.vy = float(atomcoord[6])
            atom.vz = float(atomcoord[7])

        if myBGF.CRYSTX != []:
            for i in range(0, 3):
                myBGF.CRYSTX[i] = boxsize[i]
        else:
            nu.warn("Crystal information error: is this file not periodic?")
            for i in range(0, 3):
                myBGF.CRYSTX.append(boxsize[i])

        ### myBGF update complete! ###

        ### align CNT to z axis
        # 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

        # set COM of CNT as origin
        Mx = 0
        My = 0
        Mz = 0
        # Center of mass of CNT
        for atom in myBGF.a:
            if "NT" in atom.rName:
                Mx += atom.x / N_CNT
                My += atom.y / N_CNT
                Mz += atom.z / N_CNT

        for atom in myBGF.a:
            atom.x -= Mx  # move
            atom.y -= My
            atom.z -= Mz

        # calculate the moment of inertia (MI) and the center of mass (COM) of CNT from "myBGF"
        for aNo in aNo_CNT:
            atom = myBGF.getAtom(aNo)
            Ixx += (atom.y**2 + atom.z**2) / N_CNT
            Iyy += (atom.x**2 + atom.z**2) / N_CNT
            Izz += (atom.x**2 + atom.y**2) / N_CNT
            Ixy -= (atom.x * atom.y) / N_CNT
            Ixz -= (atom.x * atom.z) / N_CNT
            Iyz -= (atom.y * atom.z) / N_CNT

        # the moment of inertia tensor
        I = np.array([[Ixx, Ixy, Ixz], [Ixy, Iyy, Iyz], [Ixz, Iyz, Izz]])

        # eigenvalue & eigenvector calculation
        eigval, eigvec = np.linalg.eig(
            I)  # eigval[0] is the minimum among the values.

        # rearrange the U vector
        U = np.matrix(eigvec)
        Ut = U.T

        # "myBGF" rotation
        for atom in myBGF.a:
            v = np.matrix([atom.x, atom.y, atom.z]).T
            Uv = Ut * v
            atom.x = float(Uv[2])
            atom.y = float(Uv[1])
            atom.z = float(Uv[0])
        #dimension = np.matrix(boxsize).T
        #boxsize_prime = np.array(np.dot(Ut, dimension).T)
        boxsize_prime = np.transpose(
            np.dot(Ut,
                   np.transpose(np.array(boxsize))))  # new pbc from jackjack5
        print(boxsize)
        print(boxsize_prime)

        # move atoms to box center
        for atom in myBGF.a:
            atom.x -= boxsize_prime[0] / 2
            atom.y -= boxsize_prime[1] / 2
            atom.z -= boxsize_prime[2] / 2

        myBGF.saveBGF(temp_dir + bgf_file.split(".bgf")[0] + "." +
                      str(timestep) + ".beforepbc.bgf")
        myBGF = bgftools.periodicMoleculeSort(myBGF, 0, myBGF.CRYSTX)
        myBGF.saveBGF(temp_dir + bgf_file.split(".bgf")[0] + "." +
                      str(timestep) + ".bgf")

        # for CNT atoms, calculate some properties
        min_x_CNT = 1000.0
        max_x_CNT = -1000.0
        radius_CNT = 0.0
        height_CNT = 0.0
        min_y_CNT = 1000.0
        max_y_CNT = -1000.0
        min_z_CNT = 1000.0
        max_z_CNT = -1000.0

        l_radius_CNT = []
        l_x_CNT = []
        l_y_CNT = []
        for aNo in aNo_CNT:
            atom = myBGF.getAtom(aNo)

            # center of CNT
            l_x_CNT.append(atom.x)
            l_y_CNT.append(atom.y)

            # height
            if atom.z < min_z_CNT:
                min_z_CNT = atom.z
            if atom.z > max_z_CNT:
                max_z_CNT = atom.z

        x_CNT, a = nu.meanstdv(l_x_CNT)
        y_CNT, a = nu.meanstdv(l_y_CNT)
        z_diff = max_z_CNT - min_z_CNT
        height_CNT = z_diff

        # radius of CNT
        for aNo in aNo_CNT:
            atom = myBGF.getAtom(aNo)
            l_radius_CNT.append(
                math.sqrt((atom.x - x_CNT)**2 + (atom.y - y_CNT)**2))

        radius_CNT, a = nu.meanstdv(l_radius_CNT)
        l_avg_radius_CNT.append(radius_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 < radius_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
        aNo_WAT_O_in_CNT = []
        for aNo in aNo_WAT_O:
            atom = myBGF.getAtom(aNo)
            dist_sq = (atom.x - x_CNT)**2 + (atom.y - y_CNT)**2
            if "WAT" in atom.rName and "O" in atom.ffType and min_z_CNT + margin <= atom.z and atom.z <= max_z_CNT - margin and dist_sq < radius_CNT**2:
                aNo_WAT_O_in_CNT.append(aNo)
            else:
                pass

        ### record number of water molecules in CNT
        #l_data.append([timestep, len(aNo_WAT_O_in_CNT), radius_CNT, z_diff])

        #output = str(timestep) + '\t' + str(len(aNo_WAT_O_in_CNT)) + '\t' + str(radius_CNT) + '\t' + str(z_diff) + '\n'
        output = str(timestep) + '\t' + str(
            len(aNo_WAT_O_in_CNT)) + '\t' + str(radius_CNT) + '\t' + str(
                min_z_CNT) + '\t' + str(max_z_CNT) + '\t' + str(
                    z_diff) + '\t' + str(height_CNT) + '\t' + str(
                        len(aNo_CNT)) + '\n'  # debug
        ftemp.write(output)

        #sys.stdout.write('Done                                                        ')
        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 countWater.profile ..Done.")

    return 1
Esempio n. 8
0
def densityProfile(bgf_file,
                   trj_file,
                   out_file,
                   interval,
                   avg_timestep,
                   direction='z',
                   ff_file='',
                   silent=False):

    nu.warn(
        "LAMMPS trajectory with NPT simulations will give you the wrong result."
    )

    ### init
    timestep = 0
    l_timestep = []
    line = []
    n_header = 0
    t1 = 0
    t2 = 0
    # clock
    vector = [0, 0, 1]
    # the axis of interest. in the acetone-water case, z direction.
    atominfo = bgftools.atom_mass  # atom data extracted from ff_file
    result = dict()
    axis = 0
    # 1: x-axis, 2: y-axis, 3: z-axis

    ### direction
    if "x" in direction:
        axis = 0
    elif "y" in direction:
        axis = 1
    elif "z" in direction:
        axis = 2
    else:
        nu.die("Error on reading direction.")

    ### open files
    myBGF = bgf.BgfFile(bgf_file)
    myTRJ = open(trj_file)
    myTRJ.seek(0)
    f_out_file = open(out_file + ".dat", 'w')
    f_avg_out_file = open(out_file + ".average.dat", 'w')
    f_pickle = open(out_file + ".pickle", 'w')
    f_avg_pickle = open(out_file + ".average.pickle", 'w')

    ### read residues from bgf_file:: residue is replaced by ffTypes
    residue = set()
    # kind of residues in BGF file
    dict_residue = dict()
    # stores residue numbers per each residue. RES1: [1, 2, ..], RES2: [6, 7, ..]
    for i in myBGF.a:
        rname = string.strip(i.ffType)
        residue.add(rname)
    output = ""
    for i in residue:
        output += i + " "

    if not silent:
        print("Found " + str(len(residue)) + " residues in BGF file: " +
              str(output))
    residue = list(residue)
    residue.append('TOTAL')

    for index, i in enumerate(residue):
        dict_residue[i] = index

    n_residue = len(residue)  # number of residues (including total)

    if ff_file:
        bgftools.update_mass(ff_file)

    ### read trajectory file
    # how many steps to go?
    #l_timestep = lt.getTrjInfo(trj_file)
    #mytrj = trj.lammpstrj(trj_file)
    mytrj = Trj(trj_file)
    l_timestep = mytrj.load()
    n_timestep = len(l_timestep)
    if not silent:
        print("\nThe trajectory contains %d timesteps." % n_timestep)

    # 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:
        try:
            chunk = [next(dumpatom) for i in range(natoms + n_header)]
        except StopIteration:
            break

        timestep = int(chunk[1])
        l_timestep.append(timestep)
        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(' ')

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

        processed_step += 1

        ### update myBGF with trajectory information ###
        natom_bgf = len(myBGF.a)  # number of atoms in BGF file

        if not natom_bgf == natoms:
            nu.die(
                "Number of atoms in trajectory file does not match with BGF file."
            )

        mode = ""
        if 'xs' in keywords or 'ys' in keywords or 'zs' in keywords:
            mode = 'scaled'
        elif 'x' in keywords or 'y' in keywords or 'z' in keywords:
            mode = 'normal'
        elif 'xu' in keywords or 'yu' in keywords or 'zu' in keywords:
            mode = 'unwrapped'

        # actual coordinate
        coordinfo = chunk[9:]

        # assume that coordinfo is similar to ['id', 'type', 'xs', 'ys', 'zs', 'ix', 'iy', 'iz']
        for atomline in coordinfo:
            atomcoord = atomline.split(' ')
            atom = myBGF.getAtom(int(atomcoord[0]))

            if mode == 'scaled':
                atom.x = float(atomcoord[2]) * boxsize[0]
                atom.y = float(atomcoord[3]) * boxsize[1]
                atom.z = float(atomcoord[4]) * boxsize[2]

            elif mode == 'unwrapped':
                atom.x = float(atomcoord[2])
                atom.y = float(atomcoord[3])
                atom.z = float(atomcoord[4])

            elif mode == 'normal':
                try:
                    ix_index = keywords.index('ix')
                    iy_index = keywords.index('iy')
                    iz_index = keywords.index('iz')
                except ValueError:
                    nu.warn(
                        "No image information no the trajectory file. Will be treated as unwrapped."
                    )
                    atom.x = float(atomcoord[2])
                    atom.y = float(atomcoord[3])
                    atom.z = float(atomcoord[4])
                else:
                    atom.x = (int(atomcoord[ix_index]) * boxsize[0]) + float(
                        atomcoord[2])
                    atom.y = (int(atomcoord[iy_index]) * boxsize[1]) + float(
                        atomcoord[3])
                    atom.z = (int(atomcoord[iz_index]) * boxsize[2]) + float(
                        atomcoord[4])

            try:
                for i in range(0, 3):
                    myBGF.CRYSTX[i] = boxsize[i]
            except:
                pass
                #nu.warn("Crystal information error: is this file not periodic?")

        # apply periodic condition
        myBGF = bgftools.periodicMoleculeSort(myBGF, myBGF.CRYSTX, silent=True)

        ### DONE for updating trj on BGF file ###
        ### Do whatever I want: density profile

        ### upper and lower bound
        min = -3.0
        max = boxsize[axis] + 3.0

        ### make a bin
        bin = np.arange(math.floor(min), math.ceil(max), interval)

        ### for every atoms, get atom coordinate and its type
        positions = []
        # atom positions. [ res1, res2, ..., total ]
        masses = []
        # used for a weight for histogram. [ res1, res2, ..., total ]
        hist = []
        bin_edges = []
        for i in range(n_residue):
            positions.append([])
            masses.append([])
            hist.append([])
            bin_edges.append([])

        for atom in myBGF.a:
            coord = [atom.x, atom.y, atom.z]
            # total
            positions[-1].append(coord[axis])
            masses[-1].append(atominfo[atom.ffType])
            # residues
            positions[dict_residue[atom.ffType.strip()]].append(coord[axis])
            masses[dict_residue[atom.ffType.strip()]].append(
                atominfo[atom.ffType])

        ### calculate volume
        area = 0
        if axis == 0:
            area = boxsize[1] * boxsize[2]
        elif axis == 1:
            area = boxsize[0] * boxsize[2]
        elif axis == 2:
            area = boxsize[0] * boxsize[1]
        vol = area * interval

        ### histogram
        for i in range(n_residue):
            hist[i], bin_edges[i] = np.histogram(positions[i],
                                                 bins=bin,
                                                 weights=masses[i])
            hist[i] = hist[i] / 6.022 / vol * 10  # density

        ### store
        temp = dict()
        for i in range(n_residue):
            temp2 = dict()
            temp2['HIST'] = hist[i]
            temp2['BIN_EDGES'] = bin_edges[i]
            temp[residue[i]] = temp2
        result[timestep] = temp

        ### end of loop: check elapsed time
        t2 = time.time()  # time mark
        elapsed_time = t2 - t1

    ### calculate average values
    if not silent: print("\nAveraging the last %d timesteps.." % avg_timestep)
    avg_timesteps = l_timestep[-avg_timestep:]
    avg_hist = []
    avg_bin_edges = []
    for i in range(n_residue):
        avg_hist.append(
            np.zeros(len(result[l_timestep[-avg_timestep]]['TOTAL']['HIST'])))
        #avg_bin_edges.append(np.zeros(len(result[-avg_timestep]['TOTAL']['BIN_EDGES'])));

    for t in avg_timesteps:
        for r in result[t]:
            avg_hist[dict_residue[r]] += result[t][r]['HIST']

    for i in range(n_residue):
        avg_hist[i] /= len(avg_timesteps)  # normalize

    temp_avg = dict()
    # residue --- HIST, BIN_EDGES
    for i in residue:
        temp2 = dict()
        temp2['HIST'] = avg_hist[dict_residue[i]]
        temp2['BIN_EDGES'] = bin_edges[0]
        temp_avg[i] = temp2

    ### write up a average data to file
    output = str(avg_timestep) + "\n"
    for r in temp_avg:
        output += str(r) + "\n"
        for index, i in enumerate(temp_avg[r]['HIST']):
            output += str(
                temp_avg[r]['BIN_EDGES'][index]) + "\t" + str(i) + "\n"
        output += "\n"
    f_avg_out_file.write(output)

    ### write up a whole data to file
    output = ""
    tkey = result.keys()
    tkey.sort()
    for t in tkey:
        output += str(t) + "\n"
        rkey = result[t].keys()
        rkey.sort()
        for r in rkey:
            output += str(r) + "\n"
            for index, i in enumerate(result[t][r]['HIST']):
                output += str(
                    result[t][r]['BIN_EDGES'][index]) + "\t" + str(i) + "\n"
            output += "\n"
        output += "\n"
    f_out_file.write(output)

    ### write up a pickle object
    if not silent: print("Writing pickle object..")
    pickle.dump(result, f_pickle)
    f_pickle.close()
    pickle.dump(temp, f_avg_pickle)
    f_avg_pickle.close()

    ### return

    print('')
    return 1
def myfunction(bgf_file, trj_file, n_step, out_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

    # environments
    myBGF = bgf.BgfFile(bgf_file)  # load BGF
    myTRJ = open(trj_file)  # load LAMMPS trj
    myTRJ.seek(0)

    out_file = "myfunction.dat"
    f_out_file = open(out_file, 'w')  # data will be recorded here
    f_out_file.write(str(sys.argv) + "\n")

    curr_dir = os.path.abspath(".")
    temp_dir = curr_dir + "/data/"
    if not os.path.isdir(temp_dir): os.makedirs(temp_dir)
    print("* Current directory: " + curr_dir)
    print("* Temp directory: " + temp_dir)

    # variables
    pass

    # scan LAMMPS trj to count how many shots in the file
    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 last " + str(n_step) +
          " timesteps.")

    # prepare something with BGF file
    for atom in myBGF.a:
        # do something
        pass

    ### Read trajectory file header
    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 ')

    # launch LAMMPS trj file
    dumpatom = get_line(trj_file)

    ### loop over trj and do the analysis
    processed_step = 0
    # counter
    t1 = t2 = 0
    elapsed_time = 0
    # timer: calculate ETA

    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()

        # stop analysis if requested n_step reached
        if processed_step == n_step:
            break

        # Read a shot from the trj 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(' ')

        ### update myBGF with trajectory information ###
        natom_bgf = len(myBGF.a)  # number of atoms in BGF file

        if not natom_bgf == natoms:
            nu.die(
                "Number of atoms in trajectory file does not match with BGF file."
            )

        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:]

        # modified for fast treatment
        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])
            atom.vx = float(atomcoord[5])
            atom.vy = float(atomcoord[6])
            atom.vz = float(atomcoord[7])

        if myBGF.CRYSTX != []:
            for i in range(0, 3):
                myBGF.CRYSTX[i] = boxsize[i]
        else:
            nu.warn("Crystal information error: is this file not periodic?")
            for i in range(0, 3):
                myBGF.CRYSTX.append(boxsize[i])

        # pbc wrap if required
        myBGF = bgftools.periodicMoleculeSort(myBGF, 0, myBGF.CRYSTX)

        ### do some analysis
        """
		asdflkjhasdlkfjadslkfjasdlkvjbaldskjfha;lsiefhja;lsejkfblnkdsjvb
		"""

        ### record data
        output = str(timestep) + '\t' + str(123) + '\n'
        f_out_file.write(output)

        ### update timer
        sys.stdout.flush()
        t2 = time.time()  # time mark
        elapsed_time = t2 - t1
        processed_step += 1

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

    return 1
Esempio n. 10
0
def getVelocity(bgf_file, trj_file, n_step, 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
	interval = 0.1;

	l_data = [];	# stores vz
	l_avg_radius_CNT = [];

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

	# how many steps to go?
	wc_trj_file = popen("grep TIMESTEP " + trj_file + " | wc -l ").read()
	n_timestep = int(wc_trj_file.split()[0]);

	print("The trajectory contains " + str(n_timestep) + " timesteps.")

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

	for atom in myBGF.a:
		# Carbons in CNT
		if "CNT" in atom.rName:
			aNo_CNT.append(atom.aNo)

		# 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
		sys.stdout.write('\r' + "Reading timestep.. " + str(timestep) )
		sys.stdout.flush()

		### Read
		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(' ')

		if timestep != n_step:
			continue;

		### update myBGF with trajectory information ###
		natom_bgf = len(myBGF.a)	# number of atoms in BGF file
	
		if not natom_bgf == natoms:
			nu.die("Number of atoms in trajectory file does not match with BGF file.")
	
		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:]
	
		# modified for fast treatment
		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])
			atom.vx = float(atomcoord[5])
			atom.vy = float(atomcoord[6])
			atom.vz = float(atomcoord[7])

			try:
				for i in range(0, 3):
					myBGF.CRYSTX[i] = boxsize[i]
			except:
				pass;
				#nu.warn("Crystal information error: is this file not periodic?")
				
		# apply periodic condition
		myBGF = bgftools.periodicMoleculeSort(myBGF, 0, True)

		### myBGF update complete! ###

		#aNo_WAT_O_in_CNT = copy.deepcopy(aNo_WAT_O)


		### align CNT to z axis
		# 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 for "all atoms in BGF": move COM of CNT as origin
		# com of CNT
		Mx = 0; My = 0; Mz = 0;
		for atom in myBGF.a:
			if "CNT" in atom.rName:
				Mx += atom.x / N_CNT
				My += atom.y / N_CNT
				Mz += atom.z / N_CNT

		# move
		for atom in myBGF.a:
			atom.x -= Mx
			atom.y -= My
			atom.z -= Mz

		# calculate the moment of inertia (MI) and the center of mass (COM) of CNT from "myBGF"
		for aNo in aNo_CNT:
			atom = myBGF.getAtom(aNo)
			Ixx += (atom.y**2 + atom.z**2) / N_CNT
			Iyy += (atom.x**2 + atom.z**2) / N_CNT
			Izz += (atom.x**2 + atom.y**2) / N_CNT
			Ixy -= (atom.x * atom.y) / N_CNT
			Ixz -= (atom.x * atom.z) / N_CNT
			Iyz -= (atom.y * atom.z) / N_CNT
			
		# the moment of inertia tensor
		I = np.array([[Ixx, Ixy, Ixz], [Ixy, Iyy, Iyz], [Ixz, Iyz, Izz]])

		# eigenvalue & eigenvector calculation
		eigval, eigvec = np.linalg.eig(I)	# eigval[0] is the minimum among the values.
	
		# rearrange the U vector
		U = np.matrix(eigvec)
		Ut = U.T

		# "myBGF" rotation
		for atom in myBGF.a:
			v = np.matrix([atom.x, atom.y, atom.z]).T
			Uv = Ut * v
			atom.x = float(Uv[1])
			atom.y = float(Uv[2])
			atom.z = float(Uv[0])


		# for CNT atoms, calculate some properties
		min_x_CNT = 1000.0; max_x_CNT = -1000.0; radius_CNT = 0.0; height_CNT = 0.0; temp = [];
		min_y_CNT = 1000.0; max_y_CNT = -1000.0;
		min_z_CNT = 1000.0; max_z_CNT = -1000.0;
		CNT_orientation = "";

		l_radius_CNT = [];
		l_x_CNT = [];
		l_y_CNT = [];
		for aNo in aNo_CNT:
			atom = myBGF.getAtom(aNo)

			# center of CNT
			l_x_CNT.append(atom.x)
			l_y_CNT.append(atom.y)

			# height
			if atom.z < min_z_CNT:
				min_z_CNT = atom.z
			if atom.z > max_z_CNT:
				max_z_CNT = atom.z
	
		x_CNT, a = nu.meanstdv(l_x_CNT)
		y_CNT, a = nu.meanstdv(l_y_CNT)
		z_diff = max_z_CNT - min_z_CNT

		# radius of CNT
		for aNo in aNo_CNT:
			atom = myBGF.getAtom(aNo)
			l_radius_CNT.append( math.sqrt( (atom.x - x_CNT)**2 + (atom.y - y_CNT)**2 ))

		radius_CNT, a = nu.meanstdv(l_radius_CNT)
		l_avg_radius_CNT.append(radius_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 < radius_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
		aNo_WAT_O_in_CNT = []
		aNo_WAT_O_not_in_CNT = []
		myBGF2 = copy.deepcopy(myBGF)

		# delete graphenes
		for atom in myBGF2.a:
			if "GRA" in atom.rName:
				aNo_WAT_O_not_in_CNT.append(myBGF.a2i[atom.aNo])

		# delete water molecules
		for aNo in aNo_WAT_O:
			atom = myBGF.getAtom(aNo)
			dist_sq = (atom.x - x_CNT)**2 + (atom.y - y_CNT)**2
			if "WAT" in atom.rName and "O" in atom.ffType and min_z_CNT + margin <= atom.z and atom.z <= max_z_CNT - margin and dist_sq < radius_CNT**2:
				aNo_WAT_O_in_CNT.append(aNo)
			else:
				delete_list = [];
				dummy = bgftools.getmolecule(myBGF, myBGF.getAtom(aNo), delete_list)
				for i in delete_list:
					aNo_WAT_O_not_in_CNT.append(myBGF.a2i[i])

		myBGF2.delAtoms(aNo_WAT_O_not_in_CNT)
		myBGF2.renumber()
		myBGF2.saveBGF(bgf_file[:-4] + "." + str(timestep) + "." + str(len(aNo_WAT_O_in_CNT)) + ".bgf")

		sys.stdout.write('Done                                                        ')
		sys.stdout.flush()

		print(len(aNo_WAT_O_in_CNT))

		processed_step += 1;


	print('')

	return 1
Esempio n. 11
0
def getHBond(bgf_file, trj_file, selection='', silent=False):

    # init
    timestep = 0
    l_timestep = []
    line = []
    n_header = 0
    t1 = 0
    t2 = 0
    # clock
    hbond_dat = dict()
    d_crit = 3.5
    a_crit = 30.0

    myBGF = bgf.BgfFile(bgf_file)
    myTRJ = open(trj_file)
    myTRJ.seek(0)
    myPickle_file = bgf_file[:-4] + ".hbond.pickle"
    myDAT = open(bgf_file[:-4] + ".hbond.count.dat", "w")
    myDAT.write(str(sys.argv) + "\n")

    # how many steps to go?
    wc_trj_file = popen("grep TIMESTEP " + trj_file + " | wc -l ").read()
    n_timestep = int(wc_trj_file.split()[0])

    print("The trajectory contains " + str(n_timestep) + " timesteps.")

    # 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_timestep - 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()

        ### Read
        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(' ')

        ### update myBGF with trajectory information ###
        natom_bgf = len(myBGF.a)  # number of atoms in BGF file

        if not natom_bgf == natoms:
            nu.die(
                "Number of atoms in trajectory file does not match with BGF file."
            )

        mode = ""
        if 'xs' in keywords or 'ys' in keywords or 'zs' in keywords:
            mode = 'scaled'
        elif 'x' in keywords or 'y' in keywords or 'z' in keywords:
            mode = 'normal'
        elif 'xu' in keywords or 'yu' in keywords or 'zu' in keywords:
            mode = 'unwrapped'

        # actual coordinate
        coordinfo = chunk[9:]

        # assume that coordinfo is similar to ['id', 'type', 'xs', 'ys', 'zs', 'ix', 'iy', 'iz']
        for atomline in coordinfo:
            atomcoord = atomline.split(' ')
            atom = myBGF.getAtom(int(atomcoord[0]))

            if mode == 'scaled':
                atom.x = float(atomcoord[2]) * boxsize[0]
                atom.y = float(atomcoord[3]) * boxsize[1]
                atom.z = float(atomcoord[4]) * boxsize[2]

            elif mode == 'unwrapped':
                atom.x = float(atomcoord[2])
                atom.y = float(atomcoord[3])
                atom.z = float(atomcoord[4])

            elif mode == 'normal':
                try:
                    ix_index = keywords.index('ix')
                    iy_index = keywords.index('iy')
                    iz_index = keywords.index('iz')
                except ValueError:
                    nu.warn(
                        "No image information no the trajectory file. Will be treated as unwrapped."
                    )
                    atom.x = float(atomcoord[2])
                    atom.y = float(atomcoord[3])
                    atom.z = float(atomcoord[4])
                else:
                    atom.x = (int(atomcoord[ix_index]) * boxsize[0]) + float(
                        atomcoord[2])
                    atom.y = (int(atomcoord[iy_index]) * boxsize[1]) + float(
                        atomcoord[3])
                    atom.z = (int(atomcoord[iz_index]) * boxsize[2]) + float(
                        atomcoord[4])

            try:
                for i in range(0, 3):
                    myBGF.CRYSTX[i] = boxsize[i]
            except:
                pass
                #nu.warn("Crystal information error: is this file not periodic?")

        pbc = myBGF.CRYSTX[:3]

        # apply periodic condition
        myBGF = bgftools.periodicMoleculeSort(myBGF, myBGF.CRYSTX, silent=True)

        ### myBGF update complete! ###

        # get donor and acceptor
        # donors: O in ACT
        A = []
        D = []
        for atom in myBGF.a:
            if selection:
                if "O" in atom.ffType and eval(selection):
                    A.append(atom)
                if "O" in atom.ffType and eval(selection):
                    D.append(atom)
            else:
                if "O" in atom.ffType:
                    A.append(atom)
                if "O" in atom.ffType:
                    D.append(atom)

        if not len(A) or not len(D):
            nu.die(
                "There are no atoms which can make H_bond (especially O atoms)!"
            )

        ### find hydrogen bonds
        # for all pairs of OC-HW
        sys.stdout.write('Hbonds.. ')
        sys.stdout.flush()

        hbonds = []
        donors = []
        acceptors = []
        hydrogens = []
        angles = []
        distances = []

        for d_atom in D:
            d = np.array([d_atom.x, d_atom.y, d_atom.z])
            for a_atom in A:
                a = np.array([a_atom.x, a_atom.y, a_atom.z])
                dist = nu.dist(d, a)
                #dist = bgf.distance(d_atom, a_atom)
                if 0.001 < dist < d_crit:
                    # check H angle
                    for ano in d_atom.CONECT:
                        h_atom = myBGF.getAtom(ano)
                        h = np.array([h_atom.x, h_atom.y, h_atom.z])
                        u = h - d
                        v = a - d
                        theta = np.dot(u, v) / norm(u) / norm(v)
                        theta = np.degrees(arccos(theta))
                        #theta = bgf.angle(h_atom, d_atom, a_atom, radians=False)
                        if theta < a_crit:
                            hbonds.append([d_atom.aNo, a_atom.aNo])
                            donors.append(d_atom.aNo)
                            acceptors.append(a_atom.aNo)
                            hydrogens.append(h_atom.aNo)
                            distances.append(dist)
                            angles.append(theta)
                            #n_hbond += 1
                            #print("%s %s" % (d_atom.rNo, a_atom.rNo))

        hbond_dat[timestep] = hbonds
        sys.stdout.write(
            'Done                                                        ')
        sys.stdout.flush()

        print("")
        for i in zip(donors, acceptors, hydrogens, distances, angles):
            print i
        sys.exit(0)

        myDAT.write("%d %d\n" % (timestep, len(hbonds)))

        # write output
        #myBGF.saveBGF(bgf_file[:-4] + "." + str(timestep) + ".bgf")
        #myBGF2.saveBGF(bgf_file[:-4] + "." + str(timestep) + ".bgf")

        t2 = time.time()  # time mark
        elapsed_time = t2 - t1

    pickle_f = open(myPickle_file, 'w')
    pickle.dump(hbond_dat, pickle_f)
    print('')

    myDAT.close()

    return 1
Esempio n. 12
0
def getHbond(bgf_file, trj_file, ff_file='', selection='', out_file=''):
    '''analyze something within a timestep in a series of lammps trajectory.
    '''
    # variables
    result = dict()

    # inner functions
    def get_line(file):
        with open(file, 'r') as f:
            for line in f:
                yield line

    # 1. Load BGF
    mybgf = bgf.BgfFile(bgf_file)
    N_BGF_ATOMS = len(mybgf.a)
    atom_frags = bt.getMoleculeList(mybgf)

    # 2. Read LAMMPS Trajectory
    mytrj = lt.lammpstrj(trj_file)
    mytrj.load()
    timesteps = sorted(mytrj.timesteps)
    N_HEADER = mytrj.nheader
    N_ATOMS = mytrj.natoms[timesteps[0]]
    N_BUFFER = N_HEADER + N_ATOMS
    if N_BGF_ATOMS != N_ATOMS:
        nu.die(
            "Number of atoms in trajectory file does not match with BGF file.")

    # 3. Determine dump style
    dump_keywords = mytrj._dump_style
    yes_scale = False
    if 'xs' in dump_keywords:
        yes_scale = True

    # 4. Update coordinates from the snapshot
    dump = get_line(trj_file)
    for t in tqdm.tqdm(timesteps, ncols=120, desc="Analyzing HBonds"):
        chunk = [next(dump) for i in range(N_BUFFER)]

        mybgf = update_coord(chunk, mybgf, mytrj.pbc[t], scaled=yes_scale)
        mybgf = bt.periodicMoleculeSort(mybgf,
                                        mybgf.CRYSTX,
                                        fragments=atom_frags,
                                        ff_file=ff_file,
                                        silent=True)

        ### collect data
        def calc_hbonds():
            # variables
            A = []
            D = []
            hbonds = []
            d_crit = 3.5
            a_crit = 30.0

            for atom in mybgf.a:
                if selection:
                    if "O" in atom.ffType and eval(selection):
                        A.append(atom)
                    if "O" in atom.ffType and eval(selection):
                        D.append(atom)
                else:
                    if "O" in atom.ffType:
                        A.append(atom)
                    if "O" in atom.ffType:
                        D.append(atom)
            if not len(A) or not len(D):
                nu.die(
                    "There are no atoms which can make H_bond (O atoms so far)!"
                )

            # calculate hbonds
            for d_atom in D:
                d = np.array([d_atom.x, d_atom.y, d_atom.z])  # donor coord
                neigh_anos = bt.get_neighbors_aNo(A,
                                                  d,
                                                  r=d_crit,
                                                  pbc=mytrj.pbc[t],
                                                  k=6)
                donors = [d_atom.aNo] + d_atom.CONECT

                for ano in neigh_anos:
                    a_atom = mybgf.getAtom(ano)
                    a = np.array([a_atom.x, a_atom.y,
                                  a_atom.z])  # acceptor coord
                    acceptors = [a_atom.aNo] + a_atom.CONECT

                    for ano in d_atom.CONECT:
                        h_atom = mybgf.getAtom(ano)
                        h = np.array([h_atom.x, h_atom.y, h_atom.z])
                        u = h - d
                        v = a - d
                        theta = np.dot(u, v) / norm(u) / norm(v)
                        theta = np.degrees(arccos(theta))
                        if theta < a_crit:  # HBond exists
                            dist = nu.pbc_dist(a, d, mytrj.pbc[t])
                            dist_ah = nu.pbc_dist(d, h, mytrj.pbc[t])

                            # E_vdw
                            sigma_r = O_sigma / dist
                            sigma_r_6 = sigma_r**6
                            sigma_r_12 = sigma_r**12
                            E_vdw = 4.0 * O_epsilon * (sigma_r_12 - sigma_r_6)
                            # E_vdw in kcal/mol

                            # E_coul
                            E_coul = 0.0
                            for i, j in itertools.product(donors, acceptors):
                                atom1 = mybgf.getAtom(i)
                                atom2 = mybgf.getAtom(j)
                                a1 = [atom1.x, atom1.y, atom1.z]
                                a2 = [atom2.x, atom2.y, atom2.z]
                                dist_ij = nu.pbc_dist(a1, a2, mytrj.pbc[t])
                                E_coul += 332.06371 * atom1.charge * atom2.charge / dist_ij  # E_coul in kcal/mol

                            # E_hbond
                            E_hbond = E_coul + E_vdw  # E_hbond = E_vdw + E_coul

                            # update for v4
                            # angle between H-O-H plane and O..O vector
                            H1 = mybgf.getAtom(d_atom.CONECT[0])
                            h1 = [H1.x, H1.y, H1.z]  # H1
                            H2 = mybgf.getAtom(d_atom.CONECT[1])
                            h2 = [H2.x, H2.y, H2.z]  # H2
                            p = d - h1
                            q = d - h2
                            n = np.cross(
                                p, q)  # normal vector of the H1-O-H2 plane
                            m = a - d
                            # O..O vector
                            alpha = np.dot(n, m) / norm(n) / norm(m)
                            alpha = np.degrees(
                                arcsin(alpha)
                            )  # angle between H-O-H plane and O..O vector

                            #hbonds.append([d_atom.aNo, a_atom.aNo, d, a, dist, theta, [E_coul, E_vdw, E_hbond]])  # v2
                            #hbonds.append([d_atom.aNo, a_atom.aNo, d, a, dist, theta, [E_coul, E_vdw, E_hbond], dist_ah])   # v3
                            hbonds.append([
                                d_atom.aNo, a_atom.aNo, d, a, dist, theta,
                                [E_coul, E_vdw, E_hbond], dist_ah, alpha
                            ])  # v4

            return hbonds

        hbonds = calc_hbonds()
        result[t] = hbonds

        #break; # tester

    # 5. Analyze
    if not out_file:
        out_file = trj_file + ".hbonds.v4"
    pickle_file = out_file + ".pickle"
    with open(pickle_file, 'wb') as f:
        pickle.dump(result, f, protocol=pickle.HIGHEST_PROTOCOL)
        print("Success to save the result to a pickle file %s" % pickle_file)
Esempio n. 13
0
def trj2data(dat_file, trj_file, step, skipVelocity, silent=False):

    # 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)

    ### LAMMPS Data
    dat_atoms = []
    if not silent: print("== Step 1. Loading LAMMPS Data")

    if not os.path.exists(dat_file):
        nu.die("Please check the LAMMPS data file.")

    f_dat_file = open(dat_file)
    temp = f_dat_file.read().split('\n')
    dat_atom_start = temp.index('Atoms')
    dat_atom_end = temp.index('Bonds')
    dat_atoms = temp[dat_atom_start + 1:dat_atom_end]
    f_dat_file.close()

    ### LAMMPS Trajectory
    # how many steps to go?
    if not silent: print("== Step 2. Loading LAMMPS Trajectory")
    n_timestep = len(lt.getTrjInfo(trj_file))
    print("The trajectory contains " + str(n_timestep) + " timesteps.")

    # 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

    if not silent: print("== Step 3. Reading LAMMPS Trajectory")
    while 1:
        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(' ')

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

        processed_step += 1

        ### if step is specified, then save only for that step.
        if step != "":
            if timestep == step:
                pass
            else:
                continue
        else:
            pass

        ### update myBGF with trajectory information ###
        natom_bgf = len(myBGF.a)  # number of atoms in BGF file

        if not natom_bgf == natoms:
            nu.die(
                "Number of atoms in trajectory file does not match with BGF file."
            )

        mode = ""
        if 'xs' in keywords or 'ys' in keywords or 'zs' in keywords:
            mode = 'scaled'
        elif 'x' in keywords or 'y' in keywords or 'z' in keywords:
            mode = 'normal'
        elif 'xu' in keywords or 'yu' in keywords or 'zu' in keywords:
            mode = 'unwrapped'

        flagVelocity = False
        if 'vx' in keywords or 'vy' in keywords or 'vz' in keywords:
            flagVelocity = True

        # actual coordinate
        coordinfo = chunk[9:]

        # assume that coordinfo is similar to ['id', 'type', 'xs', 'ys', 'zs', 'ix', 'iy', 'iz']
        for atomline in coordinfo:
            atomcoord = atomline.split(' ')
            atom = myBGF.getAtom(int(atomcoord[0]))

            if mode == 'scaled':
                atom.x = float(atomcoord[2]) * boxsize[0]
                atom.y = float(atomcoord[3]) * boxsize[1]
                atom.z = float(atomcoord[4]) * boxsize[2]

            elif mode == 'unwrapped':
                atom.x = float(atomcoord[2])
                atom.y = float(atomcoord[3])
                atom.z = float(atomcoord[4])

            elif mode == 'normal':
                try:
                    ix_index = keywords.index('ix')
                    iy_index = keywords.index('iy')
                    iz_index = keywords.index('iz')
                except ValueError:
                    nu.warn(
                        "No image information no the trajectory file. Will be treated as unwrapped."
                    )
                    atom.x = float(atomcoord[2])
                    atom.y = float(atomcoord[3])
                    atom.z = float(atomcoord[4])
                else:
                    atom.x = (int(atomcoord[ix_index]) * boxsize[0]) + float(
                        atomcoord[2])
                    atom.y = (int(atomcoord[iy_index]) * boxsize[1]) + float(
                        atomcoord[3])
                    atom.z = (int(atomcoord[iz_index]) * boxsize[2]) + float(
                        atomcoord[4])

            if not skipVelocity:
                if flagVelocity == True:
                    atom.vx = float(atomcoord[5])
                    atom.vy = float(atomcoord[6])
                    atom.vz = float(atomcoord[7])

            try:
                for i in range(0, 3):
                    myBGF.CRYSTX[i] = boxsize[i]
            except:
                pass
                #nu.warn("Crystal information error: is this file not periodic?")

        # apply periodic condition
        myBGF = bgftools.periodicMoleculeSort(myBGF, 0)

        #myBGF.saveBGF(bgf_file[:-4] + "." + str(timestep) + ".trjupdated.bgf")
        ### myBGF update complete! ###

        ### update LAMMPS data file ###
        myDAT = open(dat_file)
        myNewDAT = open(dat_file + "." + str(timestep), 'w')
        linecount = 0

        while 1:
            line = myDAT.readline()

            if not line:
                break

            if linecount == 0:
                output = line.strip(
                    "\n") + " and updated with timestep " + str(
                        timestep) + " in " + trj_file + "\n"
                linecount += 1
                myNewDAT.write(output)
                continue

            if "xlo " in line:
                output = "\t" + " {0:>10.6f} {1:>10.6f}".format(
                    0.0, boxsize[0]) + " xlo xhi\n"
                myNewDAT.write(output)
                continue
            elif "ylo " in line:
                output = "\t" + " {0:>10.6f} {1:>10.6f}".format(
                    0.0, boxsize[1]) + " ylo yhi\n"
                myNewDAT.write(output)
                continue
            elif "zlo " in line:
                output = "\t" + " {0:>10.6f} {1:>10.6f}".format(
                    0.0, boxsize[2]) + " zlo zhi\n"
                myNewDAT.write(output)
                continue

            if not "Atoms" in line:
                myNewDAT.write(line)

            else:
                myNewDAT.write("Atoms\n\n")

                for i in dat_atoms:
                    if len(i) == 0:
                        continue

                    parse = i.split()
                    atomNo = int(parse[0])
                    molNo = int(parse[1])
                    atomTypeNo = int(parse[2])

                    atom = myBGF.getAtom(atomNo)
                    if atom.aNo != atomNo or atom.rNo != molNo:
                        nu.die(
                            "BGF and data file mismatch. Please check both files."
                        )
                    else:
                        output = "{0:>8} {1:>8} {2:>8}  {3:10.5f} {4:10.5f} {5:10.5f} {6:10.5f} {7:12.8f} {8:12.8f} {9:12.8f}".format(
                            atom.aNo, atom.rNo, atomTypeNo, atom.charge,
                            atom.x, atom.y, atom.z, atom.vx, atom.vy,
                            atom.vz) + "\n"
                    myNewDAT.write(output)

                # consume
                for i in range(len(dat_atoms)):
                    line = myDAT.readline()

                myNewDAT.write("\n")

        t2 = time.time()  # time mark
        elapsed_time = t2 - t1

    print('')
    return 1
Esempio n. 14
0
def countWaterCNT(bgf_file, trj_file, fixed, silent):

	# init
	timestep = 0; l_timestep = []; line = []; n_header = 0; output = ""; radius_CNTs = [];
	t1 = 0; t2 = 0; # clock
	radius_CNT = 0.0; 

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

	# how many steps to go?
	#wc_trj_file = popen("grep TIMESTEP " + trj_file + " | wc -l ").read()
	#n_timestep = int(wc_trj_file.split()[0]);
	n_timestep = len(lt.getTrjInfo(trj_file))
	print("The trajectory contains " + str(n_timestep) + " timesteps.")

	# extract aNos of CNT in the BGF file
	aNo_CNT = []
	for atom in myBGF.a:
		# Carbons in CNT
		if "CNT" in atom.rName:
			aNo_CNT.append(atom.aNo)

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

	# 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:
		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(' ')

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

		processed_step += 1;

		### if step is specified, then save only for that step.
		if step != 0:
			if timestep == step:
				pass;
			else:
				continue;
		else:
			pass;

		### update myBGF with trajectory information ###
		natom_bgf = len(myBGF.a)	# number of atoms in BGF file
	
		if not natom_bgf == natoms:
			nu.die("Number of atoms in trajectory file does not match with BGF file.")
	
		mode = ""
		if 'xs' in keywords or 'ys' in keywords or 'zs' in keywords:
			mode = 'scaled'
		elif 'x' in keywords or 'y' in keywords or 'z' in keywords:
			mode = 'normal'
		elif 'xu' in keywords or 'yu' in keywords or 'zu' in keywords:
			mode = 'unwrapped'
	
		# actual coordinate
		coordinfo = chunk[9:]
	
		# assume that coordinfo is similar to ['id', 'type', 'xs', 'ys', 'zs', 'ix', 'iy', 'iz']
		for atomline in coordinfo:
			atomcoord = atomline.split(' ')
			atom = myBGF.getAtom(int(atomcoord[0]))
	
			if mode == 'scaled':
				atom.x = float(atomcoord[2]) * boxsize[0]
				atom.y = float(atomcoord[3]) * boxsize[1]
				atom.z = float(atomcoord[4]) * boxsize[2]
	
			elif mode == 'unwrapped':
				atom.x = float(atomcoord[2])
				atom.y = float(atomcoord[3])
				atom.z = float(atomcoord[4])
	
			elif mode == 'normal':
				try:
					ix_index = keywords.index('ix')
					iy_index = keywords.index('iy')
					iz_index = keywords.index('iz')
				except ValueError:
					nu.warn("No image information no the trajectory file. Will be treated as unwrapped.")
					atom.x = float(atomcoord[2])
					atom.y = float(atomcoord[3])
					atom.z = float(atomcoord[4])
				else:
					atom.x = (int(atomcoord[ix_index]) * boxsize[0]) + float(atomcoord[2]) 
					atom.y = (int(atomcoord[iy_index]) * boxsize[1]) + float(atomcoord[3]) 
					atom.z = (int(atomcoord[iz_index]) * boxsize[2]) + float(atomcoord[4]) 
	
			try:
				for i in range(0, 3):
					myBGF.CRYSTX[i] = boxsize[i]
			except:
				pass;
				#nu.warn("Crystal information error: is this file not periodic?")
				
		# apply periodic condition
		myBGF = bgftools.periodicMoleculeSort(myBGF, 0)

		#myBGF.saveBGF(bgf_file[:-4] + "." + str(timestep) + ".trjupdated.bgf")
		### myBGF update complete! ###

		if not fixed:
			### rotate cnt to x axis
			# 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 for "all atoms in BGF": move COM of CNT as origin
			# com of CNT
			Mx = 0; My = 0; Mz = 0;
			for atom in myBGF.a:
				if "CNT" in atom.rName:
					Mx += atom.x / N_CNT
					My += atom.y / N_CNT
					Mz += atom.z / N_CNT

			# move
			for atom in myBGF.a:
				atom.x -= Mx
				atom.y -= My
				atom.z -= Mz

			# calculate the moment of inertia (MI) and the center of mass (COM) of CNT from "myBGF"
			for aNo in aNo_CNT:
				atom = myBGF.getAtom(aNo)
				Ixx += (atom.y**2 + atom.z**2) / N_CNT
				Iyy += (atom.x**2 + atom.z**2) / N_CNT
				Izz += (atom.x**2 + atom.y**2) / N_CNT
				Ixy -= (atom.x * atom.y) / N_CNT
				Ixz -= (atom.x * atom.z) / N_CNT
				Iyz -= (atom.y * atom.z) / N_CNT
				
			# the moment of inertia tensor
			I = numpy.array([[Ixx, Ixy, Ixz], [Ixy, Iyy, Iyz], [Ixz, Iyz, Izz]])

			# eigenvalue & eigenvector calculation
			eigval, eigvec = numpy.linalg.eig(I)	# eigval[0] is the minimum among the values.
		
			# rearrange the U vector
			U = numpy.matrix(eigvec)
			Ut = U.T

			# "myBGF" rotation
			for atom in myBGF.a:
				v = numpy.matrix([atom.x, atom.y, atom.z]).T
				Uv = Ut * v
				atom.x = float(Uv[0])
				atom.y = float(Uv[1])
				atom.z = float(Uv[2])


		# for CNT atoms, calculate some properties
		min_x_CNT = 0.0; max_x_CNT = 0.0; height_CNT = 0.0; aNo_MtOH_C_not_in_CNT = []; temp = [];
		min_y_CNT = 0.0; max_y_CNT = 0.0;
		min_z_CNT = 0.0; max_z_CNT = 0.0;
		CNT_orientation = "";

		# check the orientation of CNT
		for aNo in aNo_CNT:
			atom = myBGF.getAtom(aNo)
			# minimum and maximum x coord of CNT: this will be the height of CNT
			if atom.x < min_x_CNT:
				min_x_CNT = atom.x
			if atom.x > max_x_CNT:
				max_x_CNT = atom.x
			if atom.y < min_y_CNT:
				min_y_CNT = atom.y
			if atom.y > max_y_CNT:
				max_y_CNT = atom.y
			if atom.z < min_z_CNT:
				min_z_CNT = atom.z
			if atom.z > max_z_CNT:
				max_z_CNT = atom.z
	
		x_diff = max_x_CNT - min_x_CNT
		y_diff = max_y_CNT - min_y_CNT
		z_diff = max_z_CNT - min_z_CNT

		if x_diff > y_diff and x_diff > z_diff:
			# CNT is aligned along x axis
			height_CNT = x_diff
			CNT_orientation = "x"
		elif y_diff > x_diff and y_diff > z_diff:
			# CNT is aligned along y axis
			height_CNT = y_diff
			CNT_orientation = "y"
		elif z_diff > x_diff and z_diff > y_diff:
			# CNT is aligned along z axis
			height_CNT = z_diff
			CNT_orientation = "z"

		if CNT_orientation == "x":
			for aNo in aNo_CNT:
				atom = myBGF.getAtom(aNo)
				radius_CNT += math.sqrt(atom.y**2 + atom.z**2)	# average radius of CNT
		elif CNT_orientation == "y":
			for aNo in aNo_CNT:
				atom = myBGF.getAtom(aNo)
				radius_CNT += math.sqrt(atom.x**2 + atom.z**2)	# average radius of CNT
		elif CNT_orientation == "z":
			for aNo in aNo_CNT:
				atom = myBGF.getAtom(aNo)
				radius_CNT += math.sqrt(atom.x**2 + atom.y**2)	# average radius of CNT

		radius_CNT = radius_CNT / N_CNT
		radius_CNTs.append(radius_CNT)

		output += str(timestep) + '\t' + str(radius_CNT) + '\n'
		#if not silent: print(str(timestep) + '\t' + str(radius_CNT) + '\n')
		# write output
		#myBGF.saveBGF(bgf_file[:-4] + "." + str(timestep) + ".bgf")
		#myBGF2.saveBGF(bgf_file[:-4] + "." + str(timestep) + ".bgf")

		t2 = time.time()	# time mark
		elapsed_time = t2 - t1;

	#print(output)
	m, s = nu.meanstdv(radius_CNTs)
	output += "average: " + '\t' + str(m) + '\t' + str(s) + '\n'
	print('')
	print(output)
	return 1
def getSlipLength(bgf_file,
                  trj_file,
                  ff_file,
                  n_step,
                  n_avg_step,
                  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

    l_data = []
    # stores [r vz]
    l_F_N = []
    l_F_N_inner = []
    l_F_N_outer = []
    # stores sum of friction force
    l_result = []
    l_avg_radius_CNT = []

    n_avg_count = 0
    n_avg_count_step = 0

    myBGF = bgf.BgfFile(bgf_file)
    myTRJ = open(trj_file)
    myTRJ.seek(0)
    myPkl = open(trj_file + ".method2.pickle", 'w')
    myOut = open(trj_file + ".method2.avg_vz.out", 'w')
    myOut.write(str(n_avg_step) + " steps are averaged.\n")
    myOut.write("AVG_STARTING_STEP\tAVG_vz\tF_N\tF_N_outer\tF_N_inner\n")

    # how many steps to go?
    if not silent: print("== Step 1. Loading LAMMPS Trajectory")
    wc_trj_file = popen("grep TIMESTEP " + trj_file + " | wc -l ").read()
    n_timestep = int(wc_trj_file.split()[0])
    if n_step == 0:
        n_step = n_timestep

    print("The trajectory contains " + str(n_timestep) + " timesteps.")

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

    for atom in myBGF.a:
        # Carbons in CNT
        if "CNT" in atom.rName:
            aNo_CNT.append(atom.aNo)

        # 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 ')  # assume ATOMS id type xu yu zu vx vy vz fx fy fz

    # 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
        try:
            chunk = [next(dumpatom) for i in range(natoms + n_header)]
        except StopIteration:
            break

        timestep = int(chunk[1])
        l_timestep.append(timestep)
        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(' ')

        ### update myBGF with trajectory information ###
        natom_bgf = len(myBGF.a)  # number of atoms in BGF file

        if not natom_bgf == natoms:
            nu.die(
                "Number of atoms in trajectory file does not match with BGF file."
            )

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

        # actual coordinate
        coordinfo = chunk[9:]

        # modified for fast treatment
        for atomline in coordinfo:
            atomcoord = atomline.split(' ')
            atom = myBGF.getAtom(int(atomcoord[0]))

            atom.x = float(atomcoord[2])  # coord
            atom.y = float(atomcoord[3])
            atom.z = float(atomcoord[4])
            atom.vx = float(atomcoord[5])  # vel
            atom.vy = float(atomcoord[6])
            atom.vz = float(atomcoord[7])
            if 'fx' in keywords:
                atom.fx = float(atomcoord[8])  # force
                atom.fy = float(atomcoord[9])
                atom.fz = float(atomcoord[10])

            try:
                for i in range(0, 3):
                    myBGF.CRYSTX[i] = boxsize[i]
            except:
                pass
                #nu.warn("Crystal information error: is this file not periodic?")

        # apply periodic condition
        myBGF = bgftools.periodicMoleculeSort(myBGF, 0, True)

        ### myBGF update complete! ###

        # for CNT atoms, calculate some properties on CNT
        min_x_CNT = 0.0
        max_x_CNT = 0.0
        radius_CNT = 0.0
        height_CNT = 0.0
        aNo_WAT_O_not_in_CNT = []
        temp = []
        min_y_CNT = 0.0
        max_y_CNT = 0.0
        min_z_CNT = 0.0
        max_z_CNT = 0.0
        CNT_orientation = ""

        l_radius_CNT = []
        l_x_CNT = []
        l_y_CNT = []
        for aNo in aNo_CNT:
            atom = myBGF.getAtom(aNo)

            # center of CNT
            l_x_CNT.append(atom.x)
            l_y_CNT.append(atom.y)

            # height
            if atom.z < min_z_CNT:
                min_z_CNT = atom.z
            if atom.z > max_z_CNT:
                max_z_CNT = atom.z

        # center of CNT
        x_CNT, a = nu.meanstdv(l_x_CNT)
        y_CNT, a = nu.meanstdv(l_y_CNT)
        z_diff = max_z_CNT - min_z_CNT

        # radius of CNT
        for aNo in aNo_CNT:
            atom = myBGF.getAtom(aNo)
            l_radius_CNT.append(
                math.sqrt((atom.x - x_CNT)**2 + (atom.y - y_CNT)**2))

        radius_CNT, a = nu.meanstdv(l_radius_CNT)
        l_avg_radius_CNT.append(radius_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 < radius_CNT**2
        margin = 0
        # water molecules far from the margin will be only considered
        aNo_WAT_O_in_CNT = []
        for aNo in aNo_WAT_O:
            atom = myBGF.getAtom(aNo)
            dist_sq = (atom.x - x_CNT)**2 + (atom.y - y_CNT)**2
            if "WAT" in atom.rName and min_z_CNT + margin <= atom.z and atom.z <= max_z_CNT - margin and dist_sq < radius_CNT**2:
                aNo_WAT_O_in_CNT.append(aNo)
            else:
                pass

        ### find outer water layer and collect data
        aNo_WAT_outer = []
        for aNo in aNo_WAT_O_in_CNT:
            atom = myBGF.getAtom(aNo)
            r = math.sqrt((atom.x - x_CNT)**2 + (atom.y - y_CNT)**2)

            # separate inner and outer water molecules	# for (12, 12) outer is r >= 3
            #if r >= 3: 	# 5 = 2 (depletion area) + 3 (outer shell)
            if radius_CNT - r <= 5:
                aNo_WAT_outer.append(aNo)
                #l_data.append(atom.vz*10**5)	# outer water velocity = v_slip, original velocity unit: A/fs = 10^5 m/s

        # calculate z-directional velocity of water molecules		vcm = sum vi mi / sum mi
        atom = myBGF.getAtom(aNo_WAT_outer[0])
        mass_O = bgftools.getMass(myBGF, [aNo_WAT_outer[0]], ff_file)
        atom = myBGF.getAtom(atom.CONECT[0])
        mass_H = bgftools.getMass(myBGF, [atom.aNo], ff_file)
        mass_H2O = mass_O + 2 * mass_H  # H2O mass

        for aNo in aNo_WAT_outer:
            atom = myBGF.getAtom(aNo)  # oxygen
            #vcmx = atom.vx * mass_O
            #vcmy = atom.vy * mass_O
            vcmz = atom.vz * mass_O

            for ano in atom.CONECT:
                atom2 = myBGF.getAtom(ano)
                #vcmx += atom.vx * mass_O
                #vcmy += atom.vy * mass_O
                vcmz += atom.vz * mass_H

            #vcmx /= mass_H2O
            #vcmy /= mass_H2O
            vcmz /= mass_H2O

            l_data.append(vcmz * 10**5)

        # calculate sum of forces on carbon atoms of CNT
        F_N = 0.0
        F_N_outer = 0.0
        F_N_inner = 0.0
        for aNo in aNo_CNT:
            atom = myBGF.getAtom(aNo)
            x, y = (atom.x - x_CNT, atom.y - y_CNT)
            theta = 0
            if y >= 0:
                theta = math.acos(x / (math.sqrt(x**2 + y**2)))
            else:
                theta = -math.acos(x / (math.sqrt(x**2 + y**2)))
            F_N += atom.fy * math.cos(theta) + atom.fx * math.sin(theta)
            #F_N += abs(atom.fx * math.cos(theta) + atom.fy * math.sin(theta))

        l_F_N.append(F_N)

        # timestep mark for starting average
        if n_avg_count == 0:
            n_avg_count_step = timestep

        n_avg_count += 1  # "Job's Done" counter

        # if the time comes.. average!
        if n_avg_count == n_avg_step:
            a = analyzeData(l_data)  # average vz
            l_result.append(
                [timestep, a]
            )  # note the the timestep here is not the timestep that the average started.

            t, s = nu.meanstdv(l_F_N)  # average force on CNT

            myOut.write(
                str(n_avg_count_step) + "\t" + str(a) + "\t" + str(t) + "\n")

            # reset
            l_data = []
            n_avg_count = 0
            l_F_N = []

        sys.stdout.write(
            'Done                                                        ')
        sys.stdout.flush()

        # ending for timestep treatment
        t2 = time.time()  # time mark
        elapsed_time = t2 - t1
        processed_step += 1

    # write output
    pkl.dump(l_result, myPkl)

    print('')
    return 1
Esempio n. 16
0
def getHbond(bgf_file, trj_file, ff_file='', selection='', out_file=''):
    '''analyze something within a timestep in a series of lammps trajectory.
    '''
    # variables
    result = dict()

    # inner functions
    def get_line(file):
        with open(file, 'r') as f:
            for line in f:
                yield line

    # 1. Load BGF
    mybgf = bgf.BgfFile(bgf_file)
    N_BGF_ATOMS = len(mybgf.a)

    # 2. Read LAMMPS Trajectory
    #timesteps, N_HEADER, N_ATOMS = lt.getTrjInfo(trj_file)
    mytrj = lt.lammpstrj(trj_file)
    timesteps = mytrj.load()
    N_HEADER = mytrj.nheader
    N_ATOMS = mytrj.natoms[timesteps[0]]
    N_BUFFER = N_HEADER + N_ATOMS
    if N_BGF_ATOMS != N_ATOMS:
        nu.die(
            "Number of atoms in trajectory file does not match with BGF file.")

    # 3. Determine dump style
    dump_keywords = mytrj.dumpstyle
    yes_scale = False
    if 'xs' in dump_keywords:
        yes_scale = True

    # 4. Update coordinates from the snapshot
    dump = get_line(trj_file)
    for t in tqdm.tqdm(timesteps, ncols=120, desc="Analyzing HBonds"):
        chunk = [next(dump) for i in range(N_BUFFER)]

        mybgf.CRYSTX = mytrj.pbc[t] + [90.0, 90.0, 90.0]

        coords = chunk[9:]
        for c in coords:
            c = c.split(' ')
            atom = mybgf.getAtom(int(c[0]))

            if yes_scale:
                atom.x = float(c[2]) * pbc[0]
                atom.y = float(c[3]) * pbc[1]
                atom.z = float(c[4]) * pbc[2]
            else:
                atom.x = float(c[2])
                atom.y = float(c[3])
                atom.z = float(c[4])

        mybgf = bt.periodicMoleculeSort(mybgf,
                                        mybgf.CRYSTX,
                                        ff_file=ff_file,
                                        silent=True)

        ### collect data
        def calc_hbonds():
            # variables
            A = []
            D = []
            hbonds = []
            d_crit = 3.5
            a_crit = 30.0

            for atom in mybgf.a:
                if selection:
                    if "O" in atom.ffType and eval(selection):
                        A.append(atom)
                    if "O" in atom.ffType and eval(selection):
                        D.append(atom)
                else:
                    if "O" in atom.ffType:
                        A.append(atom)
                    if "O" in atom.ffType:
                        D.append(atom)
            if not len(A) or not len(D):
                nu.die(
                    "There are no atoms which can make H_bond (O atoms so far)!"
                )

            # calculate hbonds
            for d_atom in D:
                d = np.array([d_atom.x, d_atom.y, d_atom.z])  # donor coord
                neigh_anos = bt.get_neighbors_aNo(A,
                                                  d,
                                                  r=d_crit,
                                                  pbc=mytrj.pbc[t],
                                                  k=6)
                donors = [d_atom.aNo] + d_atom.CONECT

                for ano in neigh_anos:
                    a_atom = mybgf.getAtom(ano)
                    a = np.array([a_atom.x, a_atom.y,
                                  a_atom.z])  # acceptor coord
                    acceptors = [a_atom.aNo] + a_atom.CONECT

                    for ano in d_atom.CONECT:
                        h_atom = mybgf.getAtom(ano)
                        h = np.array([h_atom.x, h_atom.y, h_atom.z])
                        u = h - d
                        v = a - d
                        theta = np.dot(u, v) / norm(u) / norm(v)
                        theta = np.degrees(arccos(theta))
                        if theta < a_crit:
                            dist = nu.pbc_dist(a, d, mytrj.pbc[t])
                            dist_dh = nu.pbc_dist(d, h, mytrj.pbc[t])
                            # E_vdw
                            sigma_r = O_sigma / dist
                            sigma_r_6 = sigma_r**6
                            sigma_r_12 = sigma_r**12
                            E_vdw = 4.0 * O_epsilon * (sigma_r_12 - sigma_r_6)
                            # Evdw in kcal/mol

                            # E_coul
                            E_coul = 0.0
                            for i, j in itertools.product(donors, acceptors):
                                atom1 = mybgf.getAtom(i)
                                atom2 = mybgf.getAtom(j)
                                a1 = [atom1.x, atom1.y, atom1.z]
                                a2 = [atom2.x, atom2.y, atom2.z]
                                dist_ij = nu.pbc_dist(a1, a2, mytrj.pbc[t])
                                E_coul += 332.06371 * atom1.charge * atom2.charge / dist_ij
                            #E_coul /= 2.0
                            E_hbond = E_coul + E_vdw  # E_hbond = E_vdw + E_coul
                            #print("e_coul: %f, e_coul2: %f, E_coul: %f, E_vdw: %f, E_hbond: %f, O-O dist: %f, O-H dist: %f" % (e_coul, e_coul2, E_coul, E_vdw, E_hbond, dist, dist_a_dh))
                            #print("E_coul: %f, E_vdw: %f, E_hbond: %f, O-O dist: %f" % (E_coul, E_vdw, E_hbond, dist))

                            #hbonds.append([d_atom.aNo, a_atom.aNo, d, a, dist, theta, [E_coul, E_vdw, E_hbond]])
                            hbonds.append([
                                d_atom.aNo, a_atom.aNo, d, a, dist, theta,
                                [E_coul, E_vdw, E_hbond], dist_dh
                            ])

            return hbonds

        hbonds = calc_hbonds()
        result[t] = hbonds

        #break; # tester

    # 5. Analyze
    if not out_file:
        out_file = trj_file + ".hbonds.v2"
    pickle_file = out_file + ".pickle"
    with open(pickle_file, 'wb') as f:
        pickle.dump(result, f, protocol=pickle.HIGHEST_PROTOCOL)
        print("Success to save the result to a pickle file %s" % pickle_file)
    '''
Esempio n. 17
0
def getHbond(bgf_file,
             trj_file,
             ff_file='',
             selection='',
             out_file='',
             nsamples=0):
    '''analyze something within a timestep in a series of lammps trajectory.
    '''
    # variables
    result = dict()

    # inner functions
    def get_line(file):
        with open(file, 'r') as f:
            for line in f:
                yield line

    # 1. Load BGF
    mybgf = bgf.BgfFile(bgf_file)
    N_BGF_ATOMS = len(mybgf.a)

    # 2. Read LAMMPS Trajectory
    #timesteps, N_HEADER, N_ATOMS = lt.getTrjInfo(trj_file)
    mytrj = lt.lammpstrj(trj_file)
    timesteps = mytrj.load()
    if nsamples:
        requested_timesteps = timesteps[-nsamples:]
    else:
        requested_timesteps = timesteps
    N_HEADER = mytrj.nheader
    N_ATOMS = mytrj.natoms[timesteps[0]]
    N_BUFFER = N_HEADER + N_ATOMS
    if N_BGF_ATOMS != N_ATOMS:
        nu.die(
            "Number of atoms in trajectory file does not match with BGF file.")

    A = []
    D = []
    if not selection:
        for atom in mybgf.a:
            if "O" in atom.ffType:
                A.append(atom)
            if "O" in atom.ffType:
                D.append(atom)

    # 3. Determine dump style
    dump_keywords = mytrj.dumpstyle

    # 4. Update coordinates from the snapshot
    dump = get_line(trj_file)
    for t in tqdm.tqdm(timesteps, ncols=120, desc="Analyzing HBonds"):
        chunk = [next(dump) for i in range(N_BUFFER)]

        t = int(chunk[1])
        if not t in requested_timesteps:
            continue

        mybgf.CRYSTX = mytrj.pbc[t] + [90.0, 90.0, 90.0]

        coords = chunk[9:]
        for c in coords:
            c = c.split(' ')
            atom = mybgf.getAtom(int(c[0]))

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

        mybgf = bt.periodicMoleculeSort(mybgf,
                                        mybgf.CRYSTX,
                                        ff_file=ff_file,
                                        silent=True)

        ### collect data
        def calc_hbonds():
            hbonds = []
            d_crit = 3.6

            if selection:
                for atom in mybgf.a:
                    if "O" in atom.ffType and eval(selection):
                        A.append(atom)
                    if "O" in atom.ffType and eval(selection):
                        D.append(atom)

            # calculate hbonds
            for d_atom in D:
                d = np.array([d_atom.x, d_atom.y, d_atom.z])  # donor coord
                neigh_anos = bt.get_neighbors_aNo(A,
                                                  d,
                                                  r=d_crit,
                                                  pbc=mytrj.pbc[t],
                                                  k=6)

                for ano in neigh_anos:
                    a_atom = mybgf.getAtom(ano)
                    a = np.array([a_atom.x, a_atom.y,
                                  a_atom.z])  # acceptor coord
                    dist = nu.pbc_dist(a, d, mytrj.pbc[t])
                    if dist > 2.0:
                        for ano in d_atom.CONECT:
                            h_atom = mybgf.getAtom(ano)
                            h = np.array([h_atom.x, h_atom.y, h_atom.z])
                            u = h - d
                            v = a - d
                            theta = np.dot(u, v) / norm(u) / norm(v)
                            #theta = np.degrees(arccos(theta))
                            if -0.17364817766693034885171662676931 < theta < 1.0:
                                hbonds.append([dist, np.degrees(theta)])

            return hbonds

        hbonds = calc_hbonds()
        result[t] = hbonds

        #break; # tester

    # 5. Analyze
    if not out_file:
        out_file = trj_file + ".hbonds_pmf"
    pickle_file = out_file + ".pickle"
    with open(pickle_file, 'wb') as f:
        pickle.dump(result, f, protocol=pickle.HIGHEST_PROTOCOL)
        print("Success to save the result to a pickle file %s" % pickle_file)
Esempio n. 18
0
def count_layer(bgf_file, trj_file, ff_file='', out_file='', prefix=''):
    '''measures confined density of graphene interlayer
    '''
    # variables
    result = dict()
    r_vdw_C = 3.38383824 / 2

    # inner functions
    def get_line(file):
        with open(file, 'r') as f:
            for line in f:
                yield line

    # 1. Load BGF
    mybgf = bgf.BgfFile(bgf_file)
    N_BGF_ATOMS = len(mybgf.a)

    # 2. Read LAMMPS Trajectory
    mytrj = lt.lammpstrj(trj_file)
    timesteps = mytrj.load()
    N_HEADER = mytrj.nheader
    N_ATOMS = mytrj.natoms[0]
    N_BUFFER = N_HEADER + N_ATOMS
    if N_BGF_ATOMS != N_ATOMS:
        nu.die(
            "Number of atoms in trajectory file does not match with BGF file.")

    # 3. Determine dump style
    dump_keywords = mytrj.dumpstyle
    yes_scale = False
    if 'xs' in dump_keywords:
        yes_scale = True

    # Mass
    wat_ano = []
    for atom in mybgf.a:
        if atom.chain == "I":
            wat_ano.append(atom.aNo)

    mass = bt.getMass(mybgf, wat_ano, ff_file=ff_file)

    # 4. Update coordinates from the snapshot
    dump = get_line(trj_file)
    for t in tqdm.tqdm(timesteps, ncols=120, desc="Counting Atoms"):
        chunk = [next(dump) for i in range(N_BUFFER)]

        t = int(chunk[1])
        mybgf.CRYSTX = mytrj.pbc[t] + [90.0, 90.0, 90.0]

        coords = chunk[9:]
        for c in coords:
            c = c.split(' ')
            atom = mybgf.getAtom(int(c[0]))

            if yes_scale:
                atom.x = float(c[2]) * pbc[0]
                atom.y = float(c[3]) * pbc[1]
                atom.z = float(c[4]) * pbc[2]
            else:
                atom.x = float(c[2])
                atom.y = float(c[3])
                atom.z = float(c[4])

        mybgf = bt.periodicMoleculeSort(mybgf,
                                        mybgf.CRYSTX,
                                        ff_file=ff_file,
                                        silent=True)

        ### collect data
        def density():
            # variables
            density = dict()

            # height
            avg_gra_z1 = bt.atoms_average(
                mybgf,
                'atom.z',
                selection="'C_2G' in atom.ffType and atom.rNo == 1")
            avg_gra_z2 = bt.atoms_average(
                mybgf,
                'atom.z',
                selection="'C_2G' in atom.ffType and atom.rNo == 2")
            dist = avg_gra_z2 - avg_gra_z1
            eff_dist = avg_gra_z2 - avg_gra_z1 - 2 * r_vdw_C

            # volume
            x = mytrj.pbc[t][0]
            y = mytrj.pbc[t][1]
            volume = x * y * dist
            eff_volume = x * y * eff_dist

            # density
            density = mass / 6.022 / volume * 10
            eff_density = mass / 6.022 / eff_volume * 10

            return [
                x, y, dist, mass, volume, eff_volume, eff_dist, density,
                eff_density
            ]

        density = density()
        result[t] = density

    # 5. Analyze
    timesteps = sorted(result.keys())
    with open(prefix + '.trj.density.dat', 'w') as f:
        output = "#x\ty\tdist\tmass\tvolume\teff_volume\teff_dist\tdensity\teff_density\n"
        for t in timesteps:
            output += "%d " % t
            output += " ".join("%8.3f" % float(i) for i in result[t])

        f.write(output)
Esempio n. 19
0
        def hard_work(mybgf, chunk):
            mybgf = update_coord(chunk, mybgf, mytrj.pbc[t], scaled=yes_scale)
            mybgf = bt.periodicMoleculeSort(mybgf,
                                            mybgf.CRYSTX,
                                            fragments=atom_frags,
                                            ff_file=ff_file,
                                            silent=True)
            '''
            # find inwater boundary
            swr = 3.270615945/2
            gwr = 3.057430885/2
            margin = 5.0
            gwa_y = bt.atoms_average(mybgf, 'atom.y', selection="'GWA' in atom.rName")
            gwb_y = bt.atoms_average(mybgf, 'atom.y', selection="'GWB' in atom.rName")
            if type == "gra":
                avg_z1 = bt.atoms_average(mybgf, 'atom.z', selection="'C_R' in atom.ffType and 'GRA' in atom.rName")    # gra bottom
                avg_z2 = bt.atoms_average(mybgf, 'atom.z', selection="'C_R' in atom.ffType and 'GRB' in atom.rName")    # gra top
                actual_distance = avg_z2 - avg_z1
            elif type == "mos":
                avg_s3a_z2 = bt.atoms_average(mybgf, 'atom.z', selection="'S_3a' in atom.ffType and atom.rNo == 2")    # mos2 top
                avg_s3b_z1 = bt.atoms_average(mybgf, 'atom.z', selection="'S_3b' in atom.ffType and atom.rNo == 1")    # mos2 bottom
                actual_distance = avg_s3a_z2 - avg_s3b_z1
            inwater_x = pbc[0]
            inwater_y = gwb_y - gwa_y + 2 * gwr - 2 * margin
            inwater_z = actual_distance - 2 * swr
            selection = "atom.y > {gwa_y} + {margin} and atom.y < {gwb_y} - {margin}".format(**vars())
            '''

            ### collect data
            def calc_hbonds():
                # variables
                A = []
                D = []
                hbonds = []
                d_crit = 3.5
                a_crit = 30.0

                for atom in mybgf.a:
                    if selection:
                        if "O" in atom.ffType and eval(selection):
                            A.append(atom)
                        if "O" in atom.ffType and eval(selection):
                            D.append(atom)
                    else:
                        if "O" in atom.ffType:
                            A.append(atom)
                        if "O" in atom.ffType:
                            D.append(atom)
                if not len(A) or not len(D):
                    nu.die(
                        "There are no atoms which can make H_bond (O atoms so far)!"
                    )

                # calculate hbonds
                for d_atom in D:
                    d = np.array([d_atom.x, d_atom.y, d_atom.z])  # donor coord
                    neigh_anos = bt.get_neighbors_aNo(A,
                                                      d,
                                                      r=d_crit,
                                                      pbc=mytrj.pbc[t],
                                                      k=6)
                    donors = [d_atom.aNo] + d_atom.CONECT

                    for ano in neigh_anos:
                        a_atom = mybgf.getAtom(ano)
                        a = np.array([a_atom.x, a_atom.y,
                                      a_atom.z])  # acceptor coord
                        acceptors = [a_atom.aNo] + a_atom.CONECT

                        for ano in d_atom.CONECT:
                            h_atom = mybgf.getAtom(ano)
                            h = np.array([h_atom.x, h_atom.y, h_atom.z])
                            u = h - d
                            v = a - d
                            theta = np.dot(u, v) / norm(u) / norm(v)
                            theta = np.degrees(arccos(theta))
                            if theta < a_crit:  # HBond exists
                                dist = nu.pbc_dist(a, d, mytrj.pbc[t])
                                dist_ah = nu.pbc_dist(d, h, mytrj.pbc[t])

                                # E_vdw
                                sigma_r = O_sigma / dist
                                sigma_r_6 = sigma_r**6
                                sigma_r_12 = sigma_r**12
                                E_vdw = 4.0 * O_epsilon * (sigma_r_12 -
                                                           sigma_r_6)
                                # E_vdw in kcal/mol

                                # E_coul
                                E_coul = 0.0
                                for i, j in itertools.product(
                                        donors, acceptors):
                                    atom1 = mybgf.getAtom(i)
                                    atom2 = mybgf.getAtom(j)
                                    a1 = [atom1.x, atom1.y, atom1.z]
                                    a2 = [atom2.x, atom2.y, atom2.z]
                                    dist_ij = nu.pbc_dist(a1, a2, mytrj.pbc[t])
                                    E_coul += 332.06371 * atom1.charge * atom2.charge / dist_ij  # E_coul in kcal/mol

                                # E_hbond
                                E_hbond = E_coul + E_vdw  # E_hbond = E_vdw + E_coul

                                # update for v4
                                # angle between H-O-H plane and O..O vector
                                H1 = mybgf.getAtom(d_atom.CONECT[0])
                                h1 = [H1.x, H1.y, H1.z]  # H1
                                H2 = mybgf.getAtom(d_atom.CONECT[1])
                                h2 = [H2.x, H2.y, H2.z]  # H2
                                p = d - h1
                                q = d - h2
                                n = np.cross(
                                    p, q)  # normal vector of the H1-O-H2 plane
                                m = a - d
                                # O..O vector
                                alpha = np.dot(n, m) / norm(n) / norm(m)
                                alpha = np.degrees(
                                    arcsin(alpha)
                                )  # angle between H-O-H plane and O..O vector

                                hbonds.append([
                                    d_atom.aNo, a_atom.aNo, d, a, dist, theta,
                                    [E_coul, E_vdw, E_hbond], dist_ah, alpha
                                ])  # v4

                return hbonds

            hb = calc_hbonds()
            return hb
def densityProfile(bgf_file,
                   trj_file,
                   ff_file,
                   out_file,
                   direction,
                   cnt_direction,
                   interval,
                   avg_timestep,
                   silent=False):

    nu.warn(
        "LAMMPS trajectory with NPT simulations will give you the wrong result."
    )

    ### init
    timestep = 0
    l_timestep = []
    line = []
    n_header = 0
    t1 = 0
    t2 = 0
    # clock
    vector = [0, 0, 1]
    # the axis of interest. in the acetone-water case, z direction.
    atominfo = dict()
    # atom data extracted from ff_file
    result = dict()
    axis = 0
    # 1: x-axis, 2: y-axis, 3: z-axis

    ### direction
    if "x" in direction:
        axis = 0
    elif "y" in direction:
        axis = 1
    elif "z" in direction:
        axis = 2
    else:
        nu.die("Error on reading direction.")

    ### CNT direction
    if "x" in cnt_direction:
        cnt_direction = 0
    elif "y" in cnt_direction:
        cnt_direction = 1
    elif "z" in cnt_direction:
        cnt_direction = 2
    else:
        nu.die("Error on reading CNT direction.")

    ### open files
    myBGF = bgf.BgfFile(bgf_file)
    myTRJ = open(trj_file)
    myTRJ.seek(0)
    f_out_file = open(out_file + ".dat", 'w')
    f_avg_out_file = open(out_file + ".average.dat", 'w')
    f_pickle = open(out_file + ".pickle", 'w')
    f_avg_pickle = open(out_file + ".average.pickle", 'w')

    ### read residues from bgf_file
    residue = set()
    # kind of residues in BGF file
    dict_residue = dict()
    # stores residue numbers per each residue. RES1: [1, 2, ..], RES2: [6, 7, ..]
    for i in myBGF.a:
        rname = string.strip(i.rName)
        residue.add(rname)
    output = ""
    for i in residue:
        output += i + " "

    if not silent:
        print("Found " + str(len(residue)) + " residues in BGF file: " +
              str(output))
    residue = list(residue)
    residue.append('TOTAL')

    for index, i in enumerate(residue):
        dict_residue[i] = index

    n_residue = len(residue)  # number of residues (including total)

    ### if no CNT the die
    if "CNT" not in residue:
        nu.die(
            "It seems that the BGF file does not contain any CNT atoms. Exiting."
        )

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

    for atom in myBGF.a:
        # Carbons in CNT
        if "CNT" in atom.rName:
            aNo_CNT.append(atom.aNo)

    ### read mass from ff_file
    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)

    ### read trajectory file
    # how many steps to go?
    n_timestep = len(lt.getTrjInfo(trj_file))
    if not silent:
        print("The trajectory contains " + str(n_timestep) + " timesteps.")

    # 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]
    boxsize = [(boxsize[1] - boxsize[0]), (boxsize[3] - boxsize[2]),
               (boxsize[5] - boxsize[4])]
    keywords = line[8].strip('ATOMS ')

    initial_boxsize = copy.deepcopy(boxsize)

    # 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:
        try:
            chunk = [next(dumpatom) for i in range(natoms + n_header)]
        except StopIteration:
            break

        timestep = int(chunk[1])
        l_timestep.append(timestep)
        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(' ')

        ### if the box size changes, then stop (only takes NVT trajectory)
        for i in range(3):
            if abs(initial_boxsize[i] - boxsize[i]) > 0.1:
                nu.die(
                    "Simulation box change detected in the trajectory file. NVT trajectory is required to continue."
                )

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

        processed_step += 1

        ### update myBGF with trajectory information ###
        natom_bgf = len(myBGF.a)  # number of atoms in BGF file

        if not natom_bgf == natoms:
            nu.die(
                "Number of atoms in trajectory file does not match with BGF file."
            )

        mode = ""
        if 'xs' in keywords or 'ys' in keywords or 'zs' in keywords:
            mode = 'scaled'
        elif 'x' in keywords or 'y' in keywords or 'z' in keywords:
            mode = 'normal'
        elif 'xu' in keywords or 'yu' in keywords or 'zu' in keywords:
            mode = 'unwrapped'

        # actual coordinate
        coordinfo = chunk[9:]

        # assume that coordinfo is similar to ['id', 'type', 'xs', 'ys', 'zs', 'ix', 'iy', 'iz']
        for atomline in coordinfo:
            atomcoord = atomline.split(' ')
            atom = myBGF.getAtom(int(atomcoord[0]))

            if mode == 'scaled':
                atom.x = float(atomcoord[2]) * boxsize[0]
                atom.y = float(atomcoord[3]) * boxsize[1]
                atom.z = float(atomcoord[4]) * boxsize[2]

            elif mode == 'unwrapped':
                atom.x = float(atomcoord[2])
                atom.y = float(atomcoord[3])
                atom.z = float(atomcoord[4])

            elif mode == 'normal':
                try:
                    ix_index = keywords.index('ix')
                    iy_index = keywords.index('iy')
                    iz_index = keywords.index('iz')
                except ValueError:
                    nu.warn(
                        "No image information no the trajectory file. Will be treated as unwrapped."
                    )
                    atom.x = float(atomcoord[2])
                    atom.y = float(atomcoord[3])
                    atom.z = float(atomcoord[4])
                else:
                    atom.x = (int(atomcoord[ix_index]) * boxsize[0]) + float(
                        atomcoord[2])
                    atom.y = (int(atomcoord[iy_index]) * boxsize[1]) + float(
                        atomcoord[3])
                    atom.z = (int(atomcoord[iz_index]) * boxsize[2]) + float(
                        atomcoord[4])

            try:
                for i in range(0, 3):
                    myBGF.CRYSTX[i] = boxsize[i]
            except:
                pass
                #nu.warn("Crystal information error: is this file not periodic?")

        # apply periodic condition
        myBGF = bgftools.periodicMoleculeSort(myBGF, 0)

        ### DONE for updating trj on BGF file ###
        ### Do whatever I want: density profile

        ### find the CNT center
        radius_CNT = 0
        cntx = cnty = cntz = 0
        natoms_CNT = len(aNo_CNT)
        for aNo in aNo_CNT:
            atom = myBGF.getAtom(aNo)
            cntx += atom.x
            cnty += atom.y
            cntz += atom.z
        cntx /= natoms_CNT
        cnty /= natoms_CNT
        cntz = natoms_CNT

        ### make a bin
        diagonal_length = 0.0
        box_height = boxsize[cnt_direction]
        radial_bin_length = 0.0
        x_length = boxsize[0] / 2
        y_length = boxsize[1] / 2
        z_length = boxsize[2] / 2

        if cnt_direction == 0:
            diagonal_length = math.sqrt(boxsize[1]**2 + boxsize[2]**2) / 2
            radial_bin_length = min(diagonal_length, y_length, z_length)
        elif cnt_direction == 1:
            diagonal_length = math.sqrt(boxsize[0]**2 + boxsize[2]**2) / 2
            radial_bin_length = min(diagonal_length, x_length, z_length)
        elif cnt_direction == 2:
            diagonal_length = math.sqrt(boxsize[0]**2 + boxsize[1]**2) / 2
            radial_bin_length = min(diagonal_length, y_length, z_length)

        # choose the shortest length among diagonal and half size of the box length
        #radial_bin_length = min(diagonal_length, boxsize[0]/2, boxsize[1]/2, boxsize[2]/2)
        bin = np.arange(0.0, math.ceil(radial_bin_length), interval)

        ### for every atoms, get atom coordinate and its type
        positions = []
        # atom positions. [ res1, res2, ..., total ]
        masses = []
        # used for a weight for histogram. [ res1, res2, ..., total ]
        hist = []
        bin_edges = []
        for i in range(n_residue):
            positions.append([])
            masses.append([])
            hist.append([])
            bin_edges.append([])

        for atom in myBGF.a:
            coord = [atom.x, atom.y, atom.z]
            dist = 0
            # calculate radial distance from CNT center to atom
            if cnt_direction == 0:
                dist = math.sqrt((atom.y - cnty)**2 + (atom.z - cntz)**2)
            elif cnt_direction == 1:
                dist = math.sqrt((atom.x - cntx)**2 + (atom.z - cntz)**2)
            elif cnt_direction == 2:
                dist = math.sqrt((atom.x - cntx)**2 + (atom.y - cnty)**2)

            # total
            positions[-1].append(dist)
            masses[-1].append(atominfo[atom.ffType]['MASS'])

            # residues
            positions[dict_residue[atom.rName.strip()]].append(dist)
            masses[dict_residue[atom.rName.strip()]].append(
                atominfo[atom.ffType]['MASS'])

        ### histogram
        for i in range(n_residue):
            hist[i], bin_edges[i] = np.histogram(positions[i],
                                                 bins=bin,
                                                 weights=masses[i])

        ### divide by volume for density
        vol = []
        for j in range(len(hist[0])):
            vol.append(math.pi *
                       (bin_edges[0][j + 1]**2 - bin_edges[0][j]**2) *
                       box_height)

        for i in range(n_residue):
            hist[i] = hist[i] / 6.022 / vol * 10.0  # density

        ### store
        temp = dict()
        for i in range(n_residue):
            temp2 = dict()
            temp2['HIST'] = hist[i]
            temp2['BIN_EDGES'] = bin_edges[i]
            temp[residue[i]] = temp2
        result[timestep] = temp

        ### end of loop: check elapsed time
        t2 = time.time()  # time mark
        elapsed_time = t2 - t1

    ### calculate average values
    if not silent:
        print("\nAveraging the last " + str(avg_timestep) + " timesteps..")
    avg_timesteps = l_timestep[-avg_timestep:]
    avg_hist = []
    avg_bin_edges = []
    for i in range(n_residue):
        avg_hist.append(
            np.zeros(len(result[l_timestep[-avg_timestep]]['TOTAL']['HIST'])))
        #avg_bin_edges.append(np.zeros(len(result[-avg_timestep]['TOTAL']['BIN_EDGES'])));

    for t in avg_timesteps:
        for r in result[t]:
            avg_hist[dict_residue[r]] += result[t][r]['HIST']

    for i in range(n_residue):
        avg_hist[i] /= len(avg_timesteps)  # normalize

    temp_avg = dict()
    # residue --- HIST, BIN_EDGES
    for i in residue:
        temp2 = dict()
        temp2['HIST'] = avg_hist[dict_residue[i]]
        temp2['BIN_EDGES'] = bin_edges[0]
        temp_avg[i] = temp2

    ### write up a average data to file
    output = str(avg_timestep) + "\n"
    for r in temp_avg:
        output += str(r) + "\n"
        for index, i in enumerate(temp_avg[r]['HIST']):
            output += str(
                temp_avg[r]['BIN_EDGES'][index]) + "\t" + str(i) + "\n"
        output += "\n"
    f_avg_out_file.write(output)

    ### write up a whole data to file
    output = ""
    tkey = result.keys()
    tkey.sort()
    for t in tkey:
        output += str(t) + "\n"
        rkey = result[t].keys()
        rkey.sort()
        for r in rkey:
            output += str(r) + "\n"
            for index, i in enumerate(result[t][r]['HIST']):
                output += str(
                    result[t][r]['BIN_EDGES'][index]) + "\t" + str(i) + "\n"
            output += "\n"
        output += "\n"
    f_out_file.write(output)

    ### write up a pickle object
    if not silent: print("Writing pickle object..")
    pickle.dump(result, f_pickle)
    f_pickle.close()
    pickle.dump(temp, f_avg_pickle)
    f_avg_pickle.close()

    ### return

    print('')
    return 1
Esempio n. 21
0
def getVelocity(bgf_file, trj_file, n_step, 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

    l_data = []
    # stores vz
    l_avg_radius_CNT = []

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

    # 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 last " + str(n_step) +
          " timesteps.")

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

    for atom in myBGF.a:
        # Carbons in CNT
        if "CNT" in atom.rName:
            aNo_CNT.append(atom.aNo)

        # 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
        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(' ')

        ### update myBGF with trajectory information ###
        natom_bgf = len(myBGF.a)  # number of atoms in BGF file

        if not natom_bgf == natoms:
            nu.die(
                "Number of atoms in trajectory file does not match with BGF file."
            )

        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:]

        del (chunk)

        # modified for fast treatment
        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])
            atom.vx = float(atomcoord[5])
            atom.vy = float(atomcoord[6])
            atom.vz = float(atomcoord[7])

            try:
                for i in range(0, 3):
                    myBGF.CRYSTX[i] = boxsize[i]
            except:
                pass
                #nu.warn("Crystal information error: is this file not periodic?")

        # apply periodic condition
        myBGF = bgftools.periodicMoleculeSort(myBGF, 0, True)

        ### myBGF update complete! ###

        #aNo_WAT_O_in_CNT = copy.deepcopy(aNo_WAT_O)

        # for CNT atoms, calculate some properties
        min_x_CNT = 1000.0
        max_x_CNT = -1000.0
        radius_CNT = 0.0
        height_CNT = 0.0
        temp = []
        min_y_CNT = 1000.0
        max_y_CNT = -1000.0
        min_z_CNT = 1000.0
        max_z_CNT = -1000.0
        CNT_orientation = ""

        l_radius_CNT = []
        l_x_CNT = []
        l_y_CNT = []
        for aNo in aNo_CNT:
            atom = myBGF.getAtom(aNo)

            # center of CNT
            l_x_CNT.append(atom.x)
            l_y_CNT.append(atom.y)

            # height
            if atom.z < min_z_CNT:
                min_z_CNT = atom.z
            if atom.z > max_z_CNT:
                max_z_CNT = atom.z

        x_CNT, a = nu.meanstdv(l_x_CNT)
        y_CNT, a = nu.meanstdv(l_y_CNT)
        z_diff = max_z_CNT - min_z_CNT

        # radius of CNT
        for aNo in aNo_CNT:
            atom = myBGF.getAtom(aNo)
            l_radius_CNT.append(
                math.sqrt((atom.x - x_CNT)**2 + (atom.y - y_CNT)**2))

        radius_CNT, a = nu.meanstdv(l_radius_CNT)
        l_avg_radius_CNT.append(radius_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 < radius_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
        aNo_WAT_O_in_CNT = []
        for aNo in aNo_WAT_O:
            atom = myBGF.getAtom(aNo)
            dist_sq = (atom.x - x_CNT)**2 + (atom.y - y_CNT)**2
            if "WAT" in atom.rName and "O" in atom.ffType and min_z_CNT + margin <= atom.z and atom.z <= max_z_CNT - margin and dist_sq < radius_CNT**2:
                aNo_WAT_O_in_CNT.append(aNo)
            else:
                pass

        ### record number of water molecules in CNT
        l_data.append([timestep, len(aNo_WAT_O_in_CNT), radius_CNT, z_diff])

        #sys.stdout.write('Done                                                        ')
        #sys.stdout.flush()

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

    print('')

    ftemp = open("countWater.profile", 'w')
    ftemp.write(str(sys.argv))
    for i in l_data:
        output = str(i[0]) + '\t' + str(i[1]) + '\t' + str(i[2]) + '\t' + str(
            i[3]) + '\n'
        ftemp.write(output)
    ftemp.close()
    print(
        "numbers of water molecules are written in countWater.profile ..Done.")

    return 1
Esempio n. 22
0
def countWaterCNT(bgf_file, trj_file, ff_file, n_step, do_hbonds, 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)
	myDAT = open(bgf_file[:-4] + ".calcDensity.count.dat", "w")
	myDAT2 = open(bgf_file[:-4] + ".calcDensity.hbond.dat", "w")
	myDAT3 = open(bgf_file[:-4] + ".calcDensity.configuration.dat", "w")
	myDAT.write(str(sys.argv) + "\n")
	myDAT.write("Time\tmin_X\tmax_X\tHeight\tRadius\tNumber\tVolume\tEff_volume\tExact_mass\tMass\tExact_den\tMtOH_den\tExact_eff_den\tMtOH_eff_den\tn_hbond\n")

	# how many steps to go?
	wc_trj_file = popen("grep TIMESTEP " + trj_file + " | wc -l ").read()
	n_timestep = int(wc_trj_file.split()[0]);
	if n_step == 0:
		n_step = n_timestep;

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

	# extract aNos of CNT in the BGF file
	aNo_CNT = []
	aNo_MtOH_C = []
	aNo_MtOH_all = []

	for atom in myBGF.a:
		# Carbons in CNT
		if "CNT" in atom.rName:
			aNo_CNT.append(atom.aNo)

		# Carbons in MeOH
		if "MET" in atom.rName and "C" in atom.aName:
			aNo_MtOH_C.append(atom.aNo)

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

	# check if there exists MtOH properly
	if len(aNo_MtOH_C) == 0:
		nu.die("No MtOH 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()

		processed_step += 1;
		if processed_step == n_step:
			break;

		aNo_MtOH_C_atoms = []
		aNo_atoms_in_CNT = []


		### Read
		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(' ')


		### update myBGF with trajectory information ###
		natom_bgf = len(myBGF.a)	# number of atoms in BGF file
	
		if not natom_bgf == natoms:
			nu.die("Number of atoms in trajectory file does not match with BGF file.")
	
		mode = ""
		if 'xs' in keywords or 'ys' in keywords or 'zs' in keywords:
			mode = 'scaled'
		elif 'x' in keywords or 'y' in keywords or 'z' in keywords:
			mode = 'normal'
		elif 'xu' in keywords or 'yu' in keywords or 'zu' in keywords:
			mode = 'unwrapped'
	
		# actual coordinate
		coordinfo = chunk[9:]
	
		# assume that coordinfo is similar to ['id', 'type', 'xs', 'ys', 'zs', 'ix', 'iy', 'iz']
		for atomline in coordinfo:
			atomcoord = atomline.split(' ')
			atom = myBGF.getAtom(int(atomcoord[0]))
	
			if mode == 'scaled':
				atom.x = float(atomcoord[2]) * boxsize[0]
				atom.y = float(atomcoord[3]) * boxsize[1]
				atom.z = float(atomcoord[4]) * boxsize[2]
	
			elif mode == 'unwrapped':
				atom.x = float(atomcoord[2])
				atom.y = float(atomcoord[3])
				atom.z = float(atomcoord[4])
	
			elif mode == 'normal':
				try:
					ix_index = keywords.index('ix')
					iy_index = keywords.index('iy')
					iz_index = keywords.index('iz')
				except ValueError:
					nu.warn("No image information no the trajectory file. Will be treated as unwrapped.")
					atom.x = float(atomcoord[2])
					atom.y = float(atomcoord[3])
					atom.z = float(atomcoord[4])
				else:
					atom.x = (int(atomcoord[ix_index]) * boxsize[0]) + float(atomcoord[2]) 
					atom.y = (int(atomcoord[iy_index]) * boxsize[1]) + float(atomcoord[3]) 
					atom.z = (int(atomcoord[iz_index]) * boxsize[2]) + float(atomcoord[4]) 
	
			try:
				for i in range(0, 3):
					myBGF.CRYSTX[i] = boxsize[i]
			except:
				pass;
				#nu.warn("Crystal information error: is this file not periodic?")
				
		# apply periodic condition
		myBGF = bgftools.periodicMoleculeSort(myBGF, 0, True)

		### myBGF update complete! ###

		aNo_MtOH_C_in_CNT = copy.deepcopy(aNo_MtOH_C)

		### Realign whole system to x axis
		sys.stdout.write(' Realigning.. ')
		sys.stdout.flush()
		# 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 for "all atoms in BGF": move COM of CNT as origin
		# com of CNT
		Mx = 0; My = 0; Mz = 0;
		for atom in myBGF.a:
			if "CNT" in atom.rName:
				Mx += atom.x / N_CNT
				My += atom.y / N_CNT
				Mz += atom.z / N_CNT

		# move
		for atom in myBGF.a:
			atom.x -= Mx
			atom.y -= My
			atom.z -= Mz

		# calculate the moment of inertia (MI) and the center of mass (COM) of CNT from "myBGF"
		for aNo in aNo_CNT:
			atom = myBGF.getAtom(aNo)
			Ixx += (atom.y**2 + atom.z**2) / N_CNT
			Iyy += (atom.x**2 + atom.z**2) / N_CNT
			Izz += (atom.x**2 + atom.y**2) / N_CNT
			Ixy -= (atom.x * atom.y) / N_CNT
			Ixz -= (atom.x * atom.z) / N_CNT
			Iyz -= (atom.y * atom.z) / N_CNT
			
		# the moment of inertia tensor
		I = numpy.array([[Ixx, Ixy, Ixz], [Ixy, Iyy, Iyz], [Ixz, Iyz, Izz]])

		# eigenvalue & eigenvector calculation
		eigval, eigvec = numpy.linalg.eig(I)	# eigval[0] is the minimum among the values.
	
		# rearrange the U vector
		U = numpy.matrix(eigvec)
		Ut = U.T

		# "myBGF" rotation
		for atom in myBGF.a:
			v = numpy.matrix([atom.x, atom.y, atom.z]).T
			Uv = Ut * v
			atom.x = float(Uv[0])
			atom.y = float(Uv[1])
			atom.z = float(Uv[2])

		# for CNT atoms, calculate some properties
		min_x_CNT = 0.0; max_x_CNT = 0.0; radius_CNT = 0.0; height_CNT = 0.0; aNo_MtOH_C_not_in_CNT = []; temp = [];
		min_y_CNT = 0.0; max_y_CNT = 0.0;
		min_z_CNT = 0.0; max_z_CNT = 0.0;
		CNT_orientation = "";

		# check the orientation of CNT
		for aNo in aNo_CNT:
			atom = myBGF.getAtom(aNo)
			# minimum and maximum x coord of CNT: this will be the height of CNT
			if atom.x < min_x_CNT:
				min_x_CNT = atom.x
			if atom.x > max_x_CNT:
				max_x_CNT = atom.x
			if atom.y < min_y_CNT:
				min_y_CNT = atom.y
			if atom.y > max_y_CNT:
				max_y_CNT = atom.y
			if atom.z < min_z_CNT:
				min_z_CNT = atom.z
			if atom.z > max_z_CNT:
				max_z_CNT = atom.z
	
		x_diff = max_x_CNT - min_x_CNT
		y_diff = max_y_CNT - min_y_CNT
		z_diff = max_z_CNT - min_z_CNT

		if x_diff > y_diff and x_diff > z_diff:
			# CNT is aligned along x axis
			height_CNT = x_diff
			CNT_orientation = "x"
		elif y_diff > x_diff and y_diff > z_diff:
			# CNT is aligned along y axis
			height_CNT = y_diff
			CNT_orientation = "y"
		elif z_diff > x_diff and z_diff > y_diff:
			# CNT is aligned along z axis
			height_CNT = z_diff
			CNT_orientation = "z"

		if CNT_orientation == "x":
			for aNo in aNo_CNT:
				atom = myBGF.getAtom(aNo)
				radius_CNT += math.sqrt(atom.y**2 + atom.z**2)	# average radius of CNT
		elif CNT_orientation == "y":
			for aNo in aNo_CNT:
				atom = myBGF.getAtom(aNo)
				radius_CNT += math.sqrt(atom.x**2 + atom.z**2)	# average radius of CNT
		elif CNT_orientation == "z":
			for aNo in aNo_CNT:
				atom = myBGF.getAtom(aNo)
				radius_CNT += math.sqrt(atom.x**2 + atom.y**2)	# average radius of CNT

		radius_CNT = radius_CNT / N_CNT

		### Rotate y or z to x axis
		Tyx = numpy.array([[0, -1, 0], [1, 0, 0], [0, 0, 1]])
		Tzx = numpy.array([[0, 0, -1], [0, 1, 0], [1, 0, 0]])
	
		if CNT_orientation == "y":
			for atom in myBGF.a:
				u = numpy.matrix([atom.x, atom.y, atom.z]).T
				Tu = Tyx*u
				atom.x = float(Tu[0])
				atom.y = float(Tu[1])
				atom.z = float(Tu[2])
				min_x_CNT = min_y_CNT;
				max_x_CNT = max_y_CNT;
	
		elif CNT_orientation == "z":
			for atom in myBGF.a:
				u = numpy.matrix([atom.x, atom.y, atom.z]).T
				Tu = Tzx*u
				atom.x = float(Tu[0])
				atom.y = float(Tu[1])
				atom.z = float(Tu[2])
				min_x_CNT = min_z_CNT;
				max_x_CNT = max_z_CNT;
	
		### get MtOHs in CNT
		sys.stdout.write('Density.. ')
		sys.stdout.flush()
		# 1. aNo_atoms_in_CNT: exact atoms within CNT
		for atom in myBGF.a:
			ano = atom.aNo
			dist = math.sqrt(atom.y**2 + atom.z**2)
			if not "CNT" in atom.rName and atom.x > min_x_CNT and atom.x < max_x_CNT and dist < radius_CNT:
				# inside
				aNo_atoms_in_CNT.append(ano)
			else:
				# outside
				pass;

		# 2. aNo_MtOH_C_atoms: molecules which C atom is within CNT
		for aNo in aNo_MtOH_C:
			atom = myBGF.getAtom(aNo)
			dist = math.sqrt(atom.y**2 + atom.z**2)
			if atom.x > min_x_CNT and atom.x < max_x_CNT and dist < radius_CNT:
				# inside of the CNT
				pass;
			else:
				"""
				# delete atoms
				delete_list = [];
				dummy = bgftools.getmolecule(myBGF, myBGF.getAtom(aNo), delete_list)
				for i in delete_list:
					aNo_MtOH_C_not_in_CNT.append(myBGF.a2i[i])
				"""
				# outside of the CNT
				aNo_MtOH_C_in_CNT.remove(aNo)

		for aNo in aNo_MtOH_C_in_CNT:
			anos = [];
			dummy = bgftools.getmolecule(myBGF, myBGF.getAtom(aNo), anos)
			for i in anos:
				aNo_MtOH_C_atoms.append(i)

		# calculate volume of CNT
		# radius: average radius - can't be applied in bent CNTs
		# height: maximum height of CNT
		# volume: radius**2 + height
		volume = (radius_CNT**2) * height_CNT * PI
		eff_volume = (radius_CNT - vdw_r_C)**2 * height_CNT * PI

		# calculate mass in CNT
		MtOH_exact_mass = bgftools.getMass(myBGF, aNo_atoms_in_CNT, ff_file)
		MtOH_MtOH_C_mass = bgftools.getMass(myBGF, aNo_MtOH_C_atoms, ff_file)

		# calculate density: mass / 6.022 / vol * 10
		vol_exact_density = MtOH_exact_mass / 6.022 / volume * 10;
		vol_MtOH_density = MtOH_MtOH_C_mass / 6.022 / volume * 10;

		# calculate effective density ( radius - r_vdw )
		eff_vol_exact_density = MtOH_exact_mass / 6.022 / eff_volume * 10;
		eff_vol_MtOH_density = MtOH_MtOH_C_mass / 6.022 / eff_volume * 10;

		### Check MET status
		output = "";
		MeOH_align = [];

		# find O in MET: MeOH_align = [C.x, O.x]
		for ano in aNo_MtOH_C_in_CNT:
			atom = myBGF.getAtom(ano)
			for i in atom.CONECT:
				atom2 = myBGF.getAtom(i)
				if "O" in atom2.ffType:
					MeOH_align.append([atom.x, atom2.x])
	
		MeOH_align.sort(key=sortkey)

		# print MET align status
		for i in MeOH_align:
			if i[0] > i[1]:
				# C-O: 1
				output += "1 "
			else:
				# O-C: 0
				output += "0 "

		# n_hbond
		n_hbond = 0;
		"""
		# how many 10 or 01 (hydrogen bonds) in output?
		count += output.count("1 0")
		count += output.count("0 1")
		"""

		hbond_C_pairs = "";
		hbond_OH_pairs = [];
		if do_hbonds:
			### find hydrogen bonds
			### criteria: r(O..O) <= 3.5, r(O..HO) <= 2.6, A(HO-O..O) <= 30' (ref: Haughney et al., JPC 1987)
			###                       acceptor donor       donor   acceptor
			# for all pairs of MtOH molecules
			sys.stdout.write('Hbonds.. ')
			sys.stdout.flush()

			C_pairs = itertools.permutations(aNo_MtOH_C_in_CNT, 2)
			# count how many iterations on the permutations:
			#c_perm = 0;
			#for i in C_pairs:
			#	c_perm += 1;

			#print(str(len(aNo_MtOH_C_in_CNT)) + " " + str(c_perm))

			for p in C_pairs:
				(ano1, ano2) = p

				# Donor part
				# get C1
				C1 = myBGF.getAtom(ano1)
				# get O1
				for i in C1.CONECT:
					temp_atom = myBGF.getAtom(i)
					if "O" in temp_atom.ffType[0]:
						O1 = temp_atom
				# get H1
				for i in O1.CONECT:
					temp_atom = myBGF.getAtom(i)
					if "H" in temp_atom.ffType[0]:
						H1 = temp_atom

				# Acceptor part
				# get C2
				C2 = myBGF.getAtom(ano2)
				# get O2
				for i in C2.CONECT:
					temp_atom = myBGF.getAtom(i)
					if "O" in temp_atom.ffType[0]:
						O2 = temp_atom
				# get H2
				for i in O2.CONECT:
					temp_atom = myBGF.getAtom(i)
					if "H" in temp_atom.ffType[0]:
						H2 = temp_atom

				"""
				# H1 and O2 should be inside the CNT
				dist = math.sqrt(H1.y**2 + H1.z**2)
				if H1.x > min_x_CNT and H1.x < max_x_CNT and dist < radius_CNT:
					continue;

				dist = math.sqrt(O2.y**2 + O2.z**2)
				if O2.x > min_x_CNT and O2.x < max_x_CNT and dist < radius_CNT:
					continue;
				"""

				## determine hbond
				# calculate r(O1..O2)
				crit_1 = bgf.distance(O1, O2);
				# calculate r(O1..H2)
				crit_2 = bgf.distance(O2, H1);
				# calculate A(O1-H2..O2)
				crit_3 = bgf.angle(H1, O1, O2);

				#if crit_1 <= 3.5 and crit_2 <= 2.6 and crit_3 <= 30:
				if crit_1 <= 3.5 and crit_3 <= 30:
					# Hbond!!
					n_hbond += 1;
					OH_pair = [O2.aNo, H1.aNo];
					hbond_OH_pairs.append(OH_pair)
					#hbond_C_pairs += str(ano1) + "-" + str(ano2) + "\t"
				else:
					continue;

		hbond_pairs = hbond_OH_pairs
		#temp = nu.removeRepeat(hbond_OH_pairs)
		#hbond_pairs = nu.removeReverse(temp)

		sys.stdout.write('Done                                                        ')
		sys.stdout.flush()

		myDAT.write(str(timestep) + "\t")
		myDAT.write(str("{0:<8.3f}".format(min_x_CNT)) + "\t")
		myDAT.write(str("{0:<8.3f}".format(max_x_CNT)) + "\t")
		myDAT.write(str("{0:<8.3f}".format(height_CNT)) + "\t")
		myDAT.write(str("{0:<8.3f}".format(radius_CNT)) + "\t")
		myDAT.write(str(len(aNo_MtOH_C_in_CNT)) + "\t")
		myDAT.write(str("{0:<8.3f}".format(volume)) + "\t")
		myDAT.write(str("{0:<8.3f}".format(eff_volume)) + "\t")
		myDAT.write(str("{0:<8.3f}".format(MtOH_exact_mass)) + "\t")
		myDAT.write(str("{0:<8.3f}".format(MtOH_MtOH_C_mass)) + "\t")
		myDAT.write(str("{0:<8.3f}".format(vol_exact_density)) + "\t")
		myDAT.write(str("{0:<8.3f}".format(vol_MtOH_density)) + "\t")
		myDAT.write(str("{0:<8.3f}".format(eff_vol_exact_density)) + "\t")
		myDAT.write(str("{0:<8.3f}".format(eff_vol_MtOH_density) + "\t"))
		myDAT.write(str(len(hbond_pairs)) + "\n")
		myDAT2.write(str(hbond_pairs) + "\n")
		myDAT3.write(str(output) + "\n")
		#myDAT.write(str(aNo_MtOH_C_in_CNT) + "\n")

		# write output
		#myBGF.saveBGF(bgf_file[:-4] + "." + str(timestep) + ".bgf")
		#myBGF2.saveBGF(bgf_file[:-4] + "." + str(timestep) + ".bgf")

		t2 = time.time()	# time mark
		elapsed_time = t2 - t1;

	print('')

	myDAT.close()
	myDAT2.close()

	return 1
Esempio n. 23
0
def countWaterCNT(bgf_file,
                  trj_file,
                  d_crit=3.5,
                  selection='',
                  nsample=0,
                  silent=False):

    ### init
    # constants
    deg_109p47 = math.radians(109.47)

    # variables
    timestep = 0
    l_timestep = []
    line = []
    n_header = 0
    avg_angles = []
    avg_diheds = []
    bin = np.arange(0.0, 181.0, 1.0)
    t1 = 0
    t2 = 0
    # clock

    myBGF = bgf.BgfFile(bgf_file)
    myTRJ = open(trj_file)
    myTRJ.seek(0)
    myDAT = open(bgf_file[:-4] + ".AOP.dat", "w")
    myDAT.write("#timestep\tAOP\tF4\n")

    # how many steps to go?
    #mytrj = lt.lammpstrj(trj_file)
    mytrj = Trj(trj_file)
    l_timestep = mytrj.load()
    n_timestep = len(l_timestep)
    l_timestep.sort()
    requested_timesteps = l_timestep[-nsample:]

    print(
        "Using neighboring water distance criteria %4.1f A (should be consistent with the coordination number)"
        % d_crit)
    print("The trajectory contains " + str(n_timestep) + " timesteps.")

    # 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 * (len(requested_timesteps) -
                                         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()

        ### Read
        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(' ')

        if not timestep in requested_timesteps:
            continue

        ### update myBGF with trajectory information ###
        natom_bgf = len(myBGF.a)  # number of atoms in BGF file

        if not natom_bgf == natoms:
            nu.die(
                "Number of atoms in trajectory file does not match with BGF file."
            )

        mode = ""
        if 'xs' in keywords or 'ys' in keywords or 'zs' in keywords:
            mode = 'scaled'
        elif 'x' in keywords or 'y' in keywords or 'z' in keywords:
            mode = 'normal'
        elif 'xu' in keywords or 'yu' in keywords or 'zu' in keywords:
            mode = 'unwrapped'

        # actual coordinate
        coordinfo = chunk[9:]

        # assume that coordinfo is similar to ['id', 'type', 'xs', 'ys', 'zs', 'ix', 'iy', 'iz']
        for atomline in coordinfo:
            atomcoord = atomline.split(' ')

            atom = myBGF.getAtom(int(atomcoord[0]))

            if mode == 'scaled':
                atom.x = float(atomcoord[2]) * boxsize[0]
                atom.y = float(atomcoord[3]) * boxsize[1]
                atom.z = float(atomcoord[4]) * boxsize[2]

            elif mode == 'unwrapped':
                atom.x = float(atomcoord[2])
                atom.y = float(atomcoord[3])
                atom.z = float(atomcoord[4])

            elif mode == 'normal':
                try:
                    ix_index = keywords.index('ix')
                    iy_index = keywords.index('iy')
                    iz_index = keywords.index('iz')
                except ValueError:
                    nu.warn(
                        "No image information no the trajectory file. Will be treated as unwrapped."
                    )
                    atom.x = float(atomcoord[2])
                    atom.y = float(atomcoord[3])
                    atom.z = float(atomcoord[4])
                else:
                    atom.x = (int(atomcoord[ix_index]) * boxsize[0]) + float(
                        atomcoord[2])
                    atom.y = (int(atomcoord[iy_index]) * boxsize[1]) + float(
                        atomcoord[3])
                    atom.z = (int(atomcoord[iz_index]) * boxsize[2]) + float(
                        atomcoord[4])

            try:
                for i in range(0, 3):
                    myBGF.CRYSTX[i] = boxsize[i]
            except:
                pass

        # apply periodic condition
        myBGF = bgftools.periodicMoleculeSort(myBGF, myBGF.CRYSTX, silent=True)

        ### myBGF update complete! ###

        # get water OW
        O = []
        anos_O = []
        for atom in myBGF.a:
            if selection:
                if "O" in atom.ffType and eval(selection):
                    O.append(atom)
                    anos_O.append(atom.aNo)
            else:
                if "O" in atom.ffType:
                    O.append(atom)
                    anos_O.append(atom.aNo)

        if not len(O):
            nu.die("There are no O atoms which satisfies %s!" % selection)

        ### calculate AOP and F4
        sys.stdout.write('AOP..... ')
        sys.stdout.flush()

        coords = []
        anos = []
        for atom in O:
            coords.append([atom.x, atom.y, atom.z])
            anos.append(atom.aNo)

        pbc = np.array(myBGF.CRYSTX[:3])
        coords = np.array(coords)
        tree = pkdtree.PeriodicKDTree(
            pbc, coords)  # KDtree for distance calculation

        # analyze local water structures for a timestep
        n_neighbors = []
        angles = []
        diheds = []
        for atom in O:
            # local variables

            # find neighbors
            neighbors = []
            # list of O atoms near centerO
            centerO = np.array([atom.x, atom.y, atom.z])
            d, ndx = tree.query(centerO, k=6)
            index = np.where((d >= 1e-4) & (d <= d_crit))  # discard self
            for i in ndx[index]:
                neighbors.append(myBGF.getAtom(anos[i]))

            # calculate O1-O-O2 angle
            for i, j in itertools.combinations(neighbors, 2):
                if not "O" in i.ffType or not "O" in j.ffType:
                    nu.die("Wrong atom found.")
                x = [i.x, i.y, i.z]
                y = [j.x, j.y, j.z]
                pbc_dist = nu.pbc_dist(x, y, pbc)
                dist = nu.dist(x, y)
                if abs(pbc_dist - dist) > 0.1:
                    continue
                    # discard atoms over pbc boundaries

                # angle
                angle = nu.angle(x, centerO, y, radians=False)
                angles.append(angle)

            n_neighbors.append(
                len(neighbors))  # number of neighboring water molecules

            # calculate dihedral
            for i in neighbors:
                # find aNos of H located farthest among all combinations
                hO_anos = atom.CONECT
                hi_anos = i.CONECT
                max_dist_pair = []
                max_dist = 0.0
                for k, l in itertools.product(hO_anos, hi_anos):
                    h1 = myBGF.getAtom(k)  # H atom connected with atom
                    h2 = myBGF.getAtom(l)  # H atom connected with i
                    dist = bgf.distance(h1, h2)
                    if dist > max_dist:
                        max_dist = dist
                        max_dist_pair = [
                            h1, h2
                        ]  # now we have two H atoms in maximum distance connected with atom and i

                # dihedral angle
                phi = bgf.dihedral(max_dist_pair[0],
                                   atom,
                                   i,
                                   max_dist_pair[1],
                                   radians=False)
                diheds.append(phi)

        hist_angle, _ = np.histogram(angles, bins=bin, normed=True)
        hist_dihed, _ = np.histogram(diheds, bins=bin, normed=True)
        avg_angles.append(hist_angle)
        avg_diheds.append(hist_dihed)

        sys.stdout.write(
            'Done                                                        ')
        sys.stdout.flush()

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

    avg_angles = np.mean(np.array(avg_angles), axis=0)
    avg_diheds = np.mean(np.array(avg_diheds), axis=0)

    #print(avg_diheds)

    myDAT.write("#angles population\n")
    for index, i in enumerate(avg_angles):
        myDAT.write("%8.2f %8.5f\n" % (_[index], avg_angles[index]))
    myDAT.write("\n\n")
    myDAT.write("#diheds population\n")
    for index, i in enumerate(avg_diheds):
        myDAT.write("%8.2f %8.5f\n" % (_[index], avg_diheds[index]))

    myDAT.close()
    print('')

    return 1
Esempio n. 24
0
def dipole(bgf_file, trj_file, ff_file, out_file, avg_timestep, silent=False):

    ### init
    timestep = 0
    l_timestep = []
    line = []
    n_header = 0
    t1 = 0
    t2 = 0
    # clock
    vector = [0, 0, 1]
    # the axis of interest. in the acetone-water case, z direction.
    atominfo = dict()
    # atom data extracted from ff_file
    result = dict()
    axis = 2
    # for orientational distribution of dipole moments. 1: x-axis, 2: y-axis, 3: z-axis

    ### unit conversion for debye
    elementary_q = 1.602176487e-19  # elementary charge in C
    debye_conv = 3.33564e-30  # 1 Debye in C*m
    k = elementary_q * 1e-10 / debye_conv

    ### open files
    myBGF = bgf.BgfFile(bgf_file)
    myTRJ = open(trj_file)
    myTRJ.seek(0)
    myOUT = open(out_file + ".dat", 'w')
    #myOUT2 = open(out_file + ".angle.dat", 'w')
    myRESULT = open(out_file + ".pickle", 'w')
    myRESULT2 = open(out_file + ".histo.pickle", 'w')

    ### read residues from bgf_file
    residueNames = set()
    # kind of residues in BGF file
    residueNumbers = set()
    dict_residue = dict()
    # stores residue numbers per each residue. RES1: [1, 2, ..], RES2: [6, 7, ..]
    for i in myBGF.a:
        rname = string.strip(i.rName)
        residueNames.add(rname)

        rno = i.rNo
        residueNumbers.add(rno)

    temp = ""
    for i in residueNames:
        temp += i + " "
        dict_residue[i] = []

    if not silent:
        print("Found " + str(len(residueNames)) + " residues in BGF file: " +
              str(temp))

    ### bookkeep residue numbers for each residue
    molecules = bgftools.getMoleculeList(myBGF)
    for molecule in molecules:
        # get an atom
        atom = myBGF.getAtom(molecule[0])
        atomresname = string.strip(atom.rName)
        atomresno = atom.rNo

        # check if all molecule has same residue name and numbers
        for ano in molecule:
            atom2 = myBGF.getAtom(ano)
            temp_rno = atom2.rNo
            temp_rname = string.strip(atom2.rName)
            if temp_rno != atomresno or temp_rname != atomresname:
                nu.die(
                    "Different residue name or residue number in a same molecule: "
                    + str(atom2.aNo))

        # record resid for resnames
        dict_residue[atomresname].append(atom.rNo)

    ### read mass from ff_file
    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)

    ### read trajectory file
    # how many steps to go?
    wc_trj_file = popen("grep -A 1 TIMESTEP " + trj_file).read()
    wc_trj_file = wc_trj_file.split()
    l_timestep = []

    for i in wc_trj_file:
        if "ITEM" in i or "TIME" in i or "--" in i:
            pass
        else:
            l_timestep.append(i)

    l_timestep = [int(i) for i in l_timestep]
    l_timestep.sort()

    n_timestep = len(l_timestep)
    if not silent:
        print("The trajectory contains " + str(n_timestep) + " timesteps.")

    l_requested_timesteps = l_timestep[-avg_timestep:]  # requested timesteps
    if not silent:
        print("Only requested the last " + str(avg_timestep) + " timesteps. ")

    # 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:
        try:
            chunk = [next(dumpatom) for i in range(natoms + n_header)]
        except StopIteration:
            break

        timestep = int(chunk[1])

        if not timestep in l_requested_timesteps:
            continue

        #l_timestep.append(timestep)
        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(' ')

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

        processed_step += 1

        ### update myBGF with trajectory information ###
        natom_bgf = len(myBGF.a)  # number of atoms in BGF file

        if not natom_bgf == natoms:
            nu.die(
                "Number of atoms in trajectory file does not match with BGF file."
            )

        mode = ""
        if 'xs' in keywords or 'ys' in keywords or 'zs' in keywords:
            mode = 'scaled'
        elif 'x' in keywords or 'y' in keywords or 'z' in keywords:
            mode = 'normal'
        elif 'xu' in keywords or 'yu' in keywords or 'zu' in keywords:
            mode = 'unwrapped'

        # actual coordinate
        coordinfo = chunk[9:]

        # assume that coordinfo is similar to ['id', 'type', 'xs', 'ys', 'zs', 'ix', 'iy', 'iz']
        for atomline in coordinfo:
            atomcoord = atomline.split(' ')
            atom = myBGF.getAtom(int(atomcoord[0]))

            if mode == 'scaled':
                atom.x = float(atomcoord[2]) * boxsize[0]
                atom.y = float(atomcoord[3]) * boxsize[1]
                atom.z = float(atomcoord[4]) * boxsize[2]

            elif mode == 'unwrapped':
                atom.x = float(atomcoord[2])
                atom.y = float(atomcoord[3])
                atom.z = float(atomcoord[4])

            elif mode == 'normal':
                try:
                    ix_index = keywords.index('ix')
                    iy_index = keywords.index('iy')
                    iz_index = keywords.index('iz')
                except ValueError:
                    nu.warn(
                        "No image information no the trajectory file. Will be treated as unwrapped."
                    )
                    atom.x = float(atomcoord[2])
                    atom.y = float(atomcoord[3])
                    atom.z = float(atomcoord[4])
                else:
                    atom.x = (int(atomcoord[ix_index]) * boxsize[0]) + float(
                        atomcoord[2])
                    atom.y = (int(atomcoord[iy_index]) * boxsize[1]) + float(
                        atomcoord[3])
                    atom.z = (int(atomcoord[iz_index]) * boxsize[2]) + float(
                        atomcoord[4])

            try:
                for i in range(0, 3):
                    myBGF.CRYSTX[i] = boxsize[i]
            except:
                pass
                #nu.warn("Crystal information error: is this file not periodic?")

        # apply periodic condition
        myBGF = bgftools.periodicMoleculeSort(myBGF, 0)

        ### DONE for updating trj on BGF file ###

        ### Now Dipole Moment Calculation
        # list of all molecules in BGF
        dipole_moments = dict()
        abs_dipole_moments = dict()
        angles = dict()
        temp_dict = dict()
        output_dipole = str(timestep) + "\t"
        output_abs_dipole = str(timestep) + "\t"
        output_angle = str(timestep) + "\t"

        ### find bin for orientational distribution of dipole moment
        min = 100000
        max = -100000
        for atom in myBGF.a:
            coord = [atom.x, atom.y, atom.z]
            if coord[axis] < min:
                min = coord[axis]
            if coord[axis] > max:
                max = coord[axis]

        if boxsize[axis] > max:
            max = boxsize[axis]
        if 0 < min:
            min = 0

        bins = np.arange(math.floor(min), math.ceil(max), 1.0)
        binned_rNo = dict()
        for r in residueNames:
            binned_rNo[r] = [[] for b in bins]
            # space for binned residue numbers (= molecules)
        binned_mu = copy.deepcopy(binned_rNo)

        ### For every molecule
        for molecule in molecules:
            n_atom = len(molecule)  # number of atoms in the molecule
            residue_no = myBGF.getAtom(molecule[0]).rNo
            # residue number of the molecule
            residue_name = myBGF.getAtom(molecule[0]).rName
            # residue name of the molecule
            m = bgftools.getMass(myBGF, molecule, ff_file)
            # molecule mass
            cm = [0, 0, 0]
            # center of mass
            mu = [0, 0, 0]
            # dipole moment
            coord = [0, 0, 0]
            # atom x, y, z

            for aNo in molecule:
                atom = myBGF.getAtom(aNo)
                coord = [atom.x, atom.y, atom.z]

                # error if residue numbers are different
                if atom.rNo != residue_no:
                    nu.die(
                        "Residue numbers in a same molecule are not consistent. Please check your BGF file."
                    )

                # error if mass is unreadable
                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.")

                # calculate CM
                for index, i in enumerate(coord):
                    cm[index] += i * aMass

            cm = [i / m for i in cm]
            # center of mass
            #print(str(residue_no) + '\t' + str(cm))

            # REMARK: it seems to be okay without this process.
            """
			# translate the molecule to CM
			for aNo in molecule:
				atom = myBGF.getAtom(aNo)
				atom.x -= cm[0]
				atom.y -= cm[1]
				atom.z -= cm[2]
			"""

            # calculate dipole moment sum(qi * di)
            mu_i = []
            for aNo in molecule:
                atom = myBGF.getAtom(aNo)
                coord = [atom.x, atom.y, atom.z]
                mu_i.append([i * atom.charge * k for i in coord])

            # sum up
            mu = [0, 0, 0]
            for i in mu_i:
                mu[0] += i[0]
                mu[1] += i[1]
                mu[2] += i[2]

            # for acetone case
            #len_mu = math.sqrt(dot(mu, mu))
            #len_vector = math.sqrt(dot(vector, vector))
            len_mu = math.sqrt(dot(mu, mu))
            len_vector = 1.0

            #angle = dot(mu, vector) / ( len_mu * len_vector )
            angle = mu[2] / (len_mu * len_vector)  # for ACETONE case

            # results
            dipole_moments[residue_no] = mu
            abs_dipole_moments[residue_no] = len_mu
            angles[residue_no] = angle

            ### Orientational distribution of dipole moments
            # binning according to molecule's CM and store to binned_rNo
            for index, bin in enumerate(bins):
                try:
                    if bin < cm[axis] and bins[index + 1] > cm[axis]:
                        binned_rNo[residue_name][index].append(residue_no)
                except:
                    continue
            # binning is perfect so far!

        residueNumbers = list(residueNumbers)
        residueNames = list(residueNames)
        residueNumbers.sort()

        temp_dict = dict()
        temp_dict2 = dict()
        temp_dict2['MU'] = dipole_moments
        temp_dict2['ABSMU'] = abs_dipole_moments
        temp_dict2['ANGLES'] = angles
        temp_dict['TOTAL'] = temp_dict2

        ### paperworks per residue
        for resname in residueNames:
            temp_dict2 = dict()
            res_dipole_moments = dict()
            res_abs_dipole_moments = dict()
            res_angles = dict()

            # load residue numbers per residue type
            resnumbers = dict_residue[resname]
            for rno in resnumbers:
                res_dipole_moments[rno] = dipole_moments[rno]
                res_abs_dipole_moments[rno] = abs_dipole_moments[rno]
                res_angles[rno] = angles[rno]

            temp_dict2['MU'] = res_dipole_moments
            temp_dict2['ABSMU'] = res_abs_dipole_moments
            temp_dict2['ANGLES'] = res_angles
            temp_dict2['BIN'] = bins

            # for analyze
            #temp_dict2['RNO_DISTR'] = binned_rNo[resname]
            temp_dict2['DISTR_ANGLES'] = binned_mu[resname]
            temp_dict2['DISTR_ABSMU'] = binned_mu[resname]

            # write dipole moments
            for index, item in enumerate(binned_rNo[resname]):
                if len(item) == 0:
                    continue
                for i in item:
                    temp_dict2['DISTR_ANGLES'][index].append(
                        temp_dict2['ANGLES'][i])
                    #temp_dict2['DISTR_ABSMU'][index].append(temp_dict2['ABSMU'][i])

            temp_dict[resname] = temp_dict2

        # result: timestep - residue - MU, ANGLES, NATOMS
        result[timestep] = temp_dict

        t2 = time.time()  # time mark
        elapsed_time = t2 - t1

    ### Averaging orientational distribution of dipole moments over timesteps
    #del temp_dict1
    del temp_dict2
    temp_dict1 = dict()
    # angles with keys: bin
    temp_dict2 = dict()
    # |mu| with keys: bin

    # append
    for r in residueNames:
        temp_dict1[r] = dict()
        temp_dict2[r] = dict()

        for t in l_requested_timesteps:
            for index, b in enumerate(result[t][r]['BIN']):
                if not temp_dict1[r].has_key(b):
                    temp_dict1[r][b] = []
                if not temp_dict2[r].has_key(b):
                    temp_dict2[r][b] = []

                # append averaged values
                avg, std = meanstdv(result[t][r]['DISTR_ANGLES'][index])
                temp_dict1[r][b].append(avg)

                for i in result[t][r]['DISTR_ANGLES'][index]:
                    temp_dict2[r][b].append(i)

                #for i in result[t][r]['DISTR_ABSMU'][index]:
                #	temp_dict2[b].append(i)

    # average
    avg_angles = dict()
    avg_absmu = dict()
    avg_angles_stdev = dict()
    avg_absmu_stdev = dict()

    for r in residueNames:
        avg_angles[r] = dict()
        avg_absmu[r] = dict()
        avg_angles_stdev[r] = dict()
        avg_absmu_stdev[r] = dict()
        temp = temp_dict1[r].keys()
        temp.sort()
        for i in temp:
            avg_angles[r][i], avg_angles_stdev[r][i] = meanstdv(
                temp_dict1[r][i])
            avg_absmu[r][i], avg_absmu_stdev[r][i] = meanstdv(temp_dict2[r][i])

    # print for average
    print("")
    print("Averaged " + str(avg_timestep) + " timesteps out of " +
          str(n_timestep))
    for r in residueNames:
        print(r)
        for i in temp:
            #print(str(i) + '\t' + str(temp_dict1[i]))
            print(
                str(i) + '\t' + str(avg_angles[r][i]) + '\t' +
                str(avg_angles_stdev[r][i]))
        print("")

    # save for debug
    output = ""
    for r in residueNames:
        for i in temp:
            output += str(i) + '\t' + str(temp_dict1[r][i]) + '\n'

    myOUT.write(output)
    myOUT.close()

    # save the pickle object
    pkl.dump(result, myRESULT)
    myRESULT.close()

    pkl.dump(temp_dict2, myRESULT2)
    myRESULT2.close()

    print('')
    return 1
Esempio n. 25
0
def getHbond(bgf_file, trj_file, ff_file='', selection='', out_file='', n=0):
    '''analyze something within a timestep in a series of lammps trajectory.
    '''
    # variables
    result = dict()

    # inner functions
    def get_line(file):
        with open(file, 'r') as f:
            for line in f:
                yield line

    # 1. Load BGF
    mybgf = bgf.BgfFile(bgf_file)
    N_BGF_ATOMS = len(mybgf.a)
    atom_frags = bt.getMoleculeList(mybgf)

    # 2. Read LAMMPS Trajectory
    mytrj = lt.lammpstrj(trj_file)
    timesteps = mytrj.load()
    N_HEADER = mytrj.nheader
    N_ATOMS = mytrj.natoms[timesteps[0]]
    N_BUFFER = N_HEADER + N_ATOMS
    if N_BGF_ATOMS != N_ATOMS:
        nu.die(
            "Number of atoms in trajectory file does not match with BGF file.")

    # 3. Determine dump style
    dump_keywords = mytrj.dumpstyle
    yes_scale = False
    if 'xs' in dump_keywords:
        yes_scale = True

    # 4. Update coordinates from the snapshot
    dump = get_line(trj_file)
    requested_t = sorted(timesteps)[-n:]
    for t in tqdm.tqdm(timesteps,
                       ncols=120,
                       desc="Analyzing HBonds",
                       miniters=1):
        chunk = [next(dump) for i in range(N_BUFFER)]
        if not t in requested_t:
            continue

        mybgf = update_coord(chunk, mybgf, mytrj.pbc[t], scaled=yes_scale)
        mybgf = bt.periodicMoleculeSort(mybgf,
                                        mybgf.CRYSTX,
                                        fragments=atom_frags,
                                        ff_file=ff_file,
                                        silent=True)

        ### collect data
        def calc_hbonds():
            # variables
            A = []
            D = []
            hbond_angles = []
            d_crit = 3.5
            a_crit = 30.0

            for atom in mybgf.a:
                if selection:
                    if "O" in atom.ffType and eval(selection):
                        A.append(atom)
                    if "O" in atom.ffType and eval(selection):
                        D.append(atom)
                else:
                    if "O" in atom.ffType:
                        A.append(atom)
                    if "O" in atom.ffType:
                        D.append(atom)
            if not len(A) or not len(D):
                nu.die(
                    "There are no atoms which can make H_bond (O atoms so far)!"
                )

            # calculate hbonds
            for d_atom in D:
                d = np.array([d_atom.x, d_atom.y, d_atom.z])  # donor coord
                neigh_anos = bt.get_neighbors_aNo(A, d, r=d_crit, k=6)
                neigh_hbonded_coord = []

                for ano in neigh_anos:
                    a_atom = mybgf.getAtom(ano)
                    a = np.array([a_atom.x, a_atom.y,
                                  a_atom.z])  # acceptor coord
                    if bt.is_hbonded(mybgf, d_atom, a_atom):
                        neigh_hbonded_coord.append(a)

                for i, j in itertools.combinations(neigh_hbonded_coord, 2):
                    angle = nu.angle(i, d, j, radians=False)
                    hbond_angles.append(angle)

            return hbond_angles

        hbonds = calc_hbonds()
        result[t] = hbonds

        #break; # tester

    # 5. Analyze
    if not out_file:
        out_file = trj_file + ".hbonds.angles."
    pickle_file = out_file + ".pickle"
    with open(pickle_file, 'wb') as f:
        pickle.dump(result, f, protocol=pickle.HIGHEST_PROTOCOL)
        print("Success to save the result to a pickle file %s" % pickle_file)
Esempio n. 26
0
def getHbond(bgf_file, trj_file, ff_file='', selection='', out_file=''):
    '''analyze something within a timestep in a series of lammps trajectory.
    '''
    # variables
    result = dict()

    # inner functions
    def get_line(file):
        with open(file, 'r') as f:
            for line in f:
                yield line

    # 1. Load BGF
    mybgf = bgf.BgfFile(bgf_file)
    N_BGF_ATOMS = len(mybgf.a)

    # 2. Read LAMMPS Trajectory
    #timesteps, N_HEADER, N_ATOMS = lt.getTrjInfo(trj_file)
    mytrj = lt.lammpstrj(trj_file)
    timesteps = mytrj.load()
    N_HEADER = mytrj.nheader
    N_ATOMS = mytrj.natoms[timesteps[0]]
    N_BUFFER = N_HEADER + N_ATOMS
    if N_BGF_ATOMS != N_ATOMS:
        nu.die(
            "Number of atoms in trajectory file does not match with BGF file.")

    # 3. Determine dump style
    dump_keywords = mytrj.dumpstyle
    yes_scale = False
    if 'xs' in dump_keywords:
        yes_scale = True

    # 4. Update coordinates from the snapshot
    dump = get_line(trj_file)
    for t in tqdm.tqdm(timesteps, ncols=120, desc="Analyzing HBonds"):
        chunk = [next(dump) for i in range(N_BUFFER)]

        t = int(chunk[1])
        mybgf.CRYSTX = mytrj.pbc[t] + [90.0, 90.0, 90.0]

        coords = chunk[9:]
        for c in coords:
            c = c.split(' ')
            atom = mybgf.getAtom(int(c[0]))

            if yes_scale:
                atom.x = float(c[2]) * pbc[0]
                atom.y = float(c[3]) * pbc[1]
                atom.z = float(c[4]) * pbc[2]
            else:
                atom.x = float(c[2])
                atom.y = float(c[3])
                atom.z = float(c[4])

        mybgf = bt.periodicMoleculeSort(mybgf,
                                        mybgf.CRYSTX,
                                        ff_file=ff_file,
                                        silent=True)

        ### collect data
        def calc_hbonds():
            # variables
            A = []
            D = []
            hbonds = []
            d_crit = 3.5
            a_crit = 30.0

            for atom in mybgf.a:
                if selection:
                    if "O" in atom.ffType and eval(selection):
                        A.append(atom)
                    if "O" in atom.ffType and eval(selection):
                        D.append(atom)
                else:
                    if "O" in atom.ffType:
                        A.append(atom)
                    if "O" in atom.ffType:
                        D.append(atom)
            if not len(A) or not len(D):
                nu.die(
                    "There are no atoms which can make H_bond (O atoms so far)!"
                )

            # calculate hbonds
            for d_atom in D:
                d = np.array([d_atom.x, d_atom.y, d_atom.z])
                neigh_anos = bt.get_neighbors_aNo(A,
                                                  d,
                                                  r=d_crit,
                                                  pbc=mytrj.pbc[t])
                for ano in neigh_anos:
                    a_atom = mybgf.getAtom(ano)
                    h = bt.is_hbonded2(mybgf, d_atom,
                                       a_atom)  # returns hbonded H coord
                    if len(h) != 0:
                        a = np.array([a_atom.x, a_atom.y, a_atom.z])
                        dist = nu.pbc_dist(a, d, mytrj.pbc[t])
                        u = h - d
                        v = a - d
                        theta = np.dot(u, v) / norm(u) / norm(v)
                        theta = np.degrees(arccos(theta))
                        hbonds.append(
                            [d_atom.aNo, a_atom.aNo, d, a, dist, theta])

            return hbonds

        hbonds = calc_hbonds()
        result[t] = hbonds

        #break; # tester

    # 5. Analyze
    if not out_file:
        out_file = trj_file + ".hbonds.new2"
    pickle_file = out_file + ".pickle"
    with open(pickle_file, 'wb') as f:
        pickle.dump(result, f, protocol=pickle.HIGHEST_PROTOCOL)
        print("Success to save the result to a pickle file %s" % pickle_file)
Esempio n. 27
0
def countWaterCNT(bgf_file, trj_file, step, doSave, silent=False):

    # 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)
    myDAT = open(bgf_file[:-4] + ".count.dat", "w")
    myDAT.write("Time\tmin_X\tmax_X\tHeight\tRadius\tNumber\n")

    # how many steps to go?
    wc_trj_file = popen("grep TIMESTEP " + trj_file + " | wc -l ").read()
    n_timestep = int(wc_trj_file.split()[0])
    print("The trajectory contains " + str(n_timestep) + " timesteps.")

    # extract aNos of CNT in the BGF file
    aNo_CNT = []
    aNo_MtOH_C = []
    for atom in myBGF.a:
        # Carbons in CNT
        if "CNT" in atom.rName:
            aNo_CNT.append(atom.aNo)

        # Carbons in MeOH
        if "MET" in atom.rName and "C" in atom.aName:
            aNo_MtOH_C.append(atom.aNo)

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

    # 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:
        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(' ')

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

        processed_step += 1

        ### if step is specified, then save only for that step.
        if step != 0:
            if timestep == step:
                pass
            else:
                continue
        else:
            pass

        ### update myBGF with trajectory information ###
        natom_bgf = len(myBGF.a)  # number of atoms in BGF file

        if not natom_bgf == natoms:
            nu.die(
                "Number of atoms in trajectory file does not match with BGF file."
            )

        mode = ""
        if 'xs' in keywords or 'ys' in keywords or 'zs' in keywords:
            mode = 'scaled'
        elif 'x' in keywords or 'y' in keywords or 'z' in keywords:
            mode = 'normal'
        elif 'xu' in keywords or 'yu' in keywords or 'zu' in keywords:
            mode = 'unwrapped'

        # actual coordinate
        coordinfo = chunk[9:]

        # assume that coordinfo is similar to ['id', 'type', 'xs', 'ys', 'zs', 'ix', 'iy', 'iz']
        for atomline in coordinfo:
            atomcoord = atomline.split(' ')
            atom = myBGF.getAtom(int(atomcoord[0]))

            if mode == 'scaled':
                atom.x = float(atomcoord[2]) * boxsize[0]
                atom.y = float(atomcoord[3]) * boxsize[1]
                atom.z = float(atomcoord[4]) * boxsize[2]

            elif mode == 'unwrapped':
                atom.x = float(atomcoord[2])
                atom.y = float(atomcoord[3])
                atom.z = float(atomcoord[4])

            elif mode == 'normal':
                try:
                    ix_index = keywords.index('ix')
                    iy_index = keywords.index('iy')
                    iz_index = keywords.index('iz')
                except ValueError:
                    nu.warn(
                        "No image information no the trajectory file. Will be treated as unwrapped."
                    )
                    atom.x = float(atomcoord[2])
                    atom.y = float(atomcoord[3])
                    atom.z = float(atomcoord[4])
                else:
                    atom.x = (int(atomcoord[ix_index]) * boxsize[0]) + float(
                        atomcoord[2])
                    atom.y = (int(atomcoord[iy_index]) * boxsize[1]) + float(
                        atomcoord[3])
                    atom.z = (int(atomcoord[iz_index]) * boxsize[2]) + float(
                        atomcoord[4])

            try:
                for i in range(0, 3):
                    myBGF.CRYSTX[i] = boxsize[i]
            except:
                pass
                #nu.warn("Crystal information error: is this file not periodic?")

        # apply periodic condition
        myBGF = bgftools.periodicMoleculeSort(myBGF, 0)

        #myBGF.saveBGF(bgf_file[:-4] + "." + str(timestep) + ".trjupdated.bgf")
        ### myBGF update complete! ###

        aNo_MtOH_C_in_CNT = copy.deepcopy(aNo_MtOH_C)

        # 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 for "all atoms in BGF": move COM of CNT as origin
        # com of CNT
        Mx = 0
        My = 0
        Mz = 0
        for atom in myBGF.a:
            if "CNT" in atom.rName:
                Mx += atom.x / N_CNT
                My += atom.y / N_CNT
                Mz += atom.z / N_CNT

        # move
        for atom in myBGF.a:
            atom.x -= Mx
            atom.y -= My
            atom.z -= Mz

        # calculate the moment of inertia (MI) and the center of mass (COM) of CNT from "myBGF"
        for aNo in aNo_CNT:
            atom = myBGF.getAtom(aNo)
            Ixx += (atom.y**2 + atom.z**2) / N_CNT
            Iyy += (atom.x**2 + atom.z**2) / N_CNT
            Izz += (atom.x**2 + atom.y**2) / N_CNT
            Ixy -= (atom.x * atom.y) / N_CNT
            Ixz -= (atom.x * atom.z) / N_CNT
            Iyz -= (atom.y * atom.z) / N_CNT

        # the moment of inertia tensor
        I = numpy.array([[Ixx, Ixy, Ixz], [Ixy, Iyy, Iyz], [Ixz, Iyz, Izz]])

        # eigenvalue & eigenvector calculation
        eigval, eigvec = numpy.linalg.eig(
            I)  # eigval[0] is the minimum among the values.

        # rearrange the U vector
        U = numpy.matrix(eigvec)
        Ut = U.T

        # "myBGF" rotation
        for atom in myBGF.a:
            v = numpy.matrix([atom.x, atom.y, atom.z]).T
            Uv = Ut * v
            atom.x = float(Uv[0])
            atom.y = float(Uv[1])
            atom.z = float(Uv[2])
        """
		# com of CNT
		Mx = 0; My = 0; Mz = 0;
		for atom in myBGF.a:
			if "CNT" in atom.rName:
				Mx += atom.x / N_CNT
				My += atom.y / N_CNT
				Mz += atom.z / N_CNT

		# transpose for "all atoms in BGF": move COM of CNT as origin
		for atom in myBGF.a:
			atom.x -= Mx
			atom.y -= My
			atom.z -= Mz
		"""

        # for CNT atoms, calculate some properties
        min_x_CNT = 0.0
        max_x_CNT = 0.0
        radius_CNT = 0.0
        height_CNT = 0.0
        aNo_MtOH_C_not_in_CNT = []
        temp = []
        min_y_CNT = 0.0
        max_y_CNT = 0.0
        min_z_CNT = 0.0
        max_z_CNT = 0.0
        CNT_orientation = ""

        # check the orientation of CNT
        for aNo in aNo_CNT:
            atom = myBGF.getAtom(aNo)
            # minimum and maximum x coord of CNT: this will be the height of CNT
            if atom.x < min_x_CNT:
                min_x_CNT = atom.x
            if atom.x > max_x_CNT:
                max_x_CNT = atom.x
            if atom.y < min_y_CNT:
                min_y_CNT = atom.y
            if atom.y > max_y_CNT:
                max_y_CNT = atom.y
            if atom.z < min_z_CNT:
                min_z_CNT = atom.z
            if atom.z > max_z_CNT:
                max_z_CNT = atom.z

        x_diff = max_x_CNT - min_x_CNT
        y_diff = max_y_CNT - min_y_CNT
        z_diff = max_z_CNT - min_z_CNT

        if x_diff > y_diff and x_diff > z_diff:
            # CNT is aligned along x axis
            height_CNT = x_diff
            CNT_orientation = "x"
        elif y_diff > x_diff and y_diff > z_diff:
            # CNT is aligned along y axis
            height_CNT = y_diff
            CNT_orientation = "y"
        elif z_diff > x_diff and z_diff > y_diff:
            # CNT is aligned along z axis
            height_CNT = z_diff
            CNT_orientation = "z"

        if CNT_orientation == "x":
            for aNo in aNo_CNT:
                atom = myBGF.getAtom(aNo)
                radius_CNT += math.sqrt(atom.y**2 +
                                        atom.z**2)  # average radius of CNT
        elif CNT_orientation == "y":
            for aNo in aNo_CNT:
                atom = myBGF.getAtom(aNo)
                radius_CNT += math.sqrt(atom.x**2 +
                                        atom.z**2)  # average radius of CNT
        elif CNT_orientation == "z":
            for aNo in aNo_CNT:
                atom = myBGF.getAtom(aNo)
                radius_CNT += math.sqrt(atom.x**2 +
                                        atom.y**2)  # average radius of CNT

        radius_CNT = radius_CNT / N_CNT

        # determine whether C in MtOH is in the CNT Cylinder
        if doSave:
            myBGF2 = copy.deepcopy(myBGF)
            for aNo in aNo_MtOH_C:
                atom = myBGF.getAtom(aNo)
                if CNT_orientation == "x":
                    dist = math.sqrt(atom.y**2 + atom.z**2)
                    if atom.x > min_x_CNT and atom.x < max_x_CNT and dist < radius_CNT:
                        # inside of the CNT
                        pass
                    else:
                        # delete atoms
                        delete_list = []
                        dummy = bgftools.getmolecule(myBGF, myBGF.getAtom(aNo),
                                                     delete_list)
                        for i in delete_list:
                            aNo_MtOH_C_not_in_CNT.append(myBGF.a2i[i])
                        # outside of the CNT
                        aNo_MtOH_C_in_CNT.remove(aNo)
                elif CNT_orientation == "y":
                    dist = math.sqrt(atom.x**2 + atom.z**2)
                    if atom.y > min_y_CNT and atom.y < max_y_CNT and dist < radius_CNT:
                        pass
                    else:
                        # delete atoms
                        delete_list = []
                        dummy = bgftools.getmolecule(myBGF, myBGF.getAtom(aNo),
                                                     delete_list)
                        for i in delete_list:
                            aNo_MtOH_C_not_in_CNT.append(myBGF.a2i[i])
                        # outside of the CNT
                        aNo_MtOH_C_in_CNT.remove(aNo)
                elif CNT_orientation == "z":
                    dist = math.sqrt(atom.x**2 + atom.y**2)
                    if atom.z > min_z_CNT and atom.z < max_z_CNT and dist < radius_CNT:
                        pass
                    else:
                        # delete atoms
                        delete_list = []
                        dummy = bgftools.getmolecule(myBGF, myBGF.getAtom(aNo),
                                                     delete_list)
                        for i in delete_list:
                            aNo_MtOH_C_not_in_CNT.append(myBGF.a2i[i])
                        # outside of the CNT
                        aNo_MtOH_C_in_CNT.remove(aNo)

            myBGF2.delAtoms(aNo_MtOH_C_not_in_CNT)
            myBGF2.renumber()

        myDAT.write(str(timestep) + "\t")
        myDAT.write(str("{0:<8.3f}".format(min_x_CNT)))
        myDAT.write(str("{0:<8.3f}".format(max_x_CNT)))
        myDAT.write(str("{0:<8.3f}".format(min_y_CNT)))
        myDAT.write(str("{0:<8.3f}".format(max_y_CNT)))
        myDAT.write(str("{0:<8.3f}".format(min_z_CNT)))
        myDAT.write(str("{0:<8.3f}".format(max_z_CNT)))
        myDAT.write(str("{0:<8.3f}".format(height_CNT)))
        myDAT.write(str("{0:<8.3f}".format(radius_CNT)))
        myDAT.write(str(len(aNo_MtOH_C_in_CNT)) + "\n")
        #myDAT.write(str(aNo_MtOH_C_in_CNT) + "\n")

        # write output
        if doSave:
            myBGF2.saveBGF(bgf_file[:-4] + "." + str(timestep) + ".bgf")

        t2 = time.time()  # time mark
        elapsed_time = t2 - t1

    print('')
    return 1
Esempio n. 28
0
def countWaterCNT(bgf_file, trj_file, out_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)
    myNewTRJ = open(out_file, 'w')

    # how many steps to go?
    wc_trj_file = popen("grep TIMESTEP " + trj_file + " | wc -l ").read()
    n_timestep = int(wc_trj_file.split()[0])

    print("The trajectory contains " + str(n_timestep) + " timesteps.")

    # extract aNos of CNT in the BGF file
    aNo_CNT = []
    aNo_MtOH_all = []

    for atom in myBGF.a:
        # Carbons in CNT
        if "CNT" in atom.rName:
            aNo_CNT.append(atom.aNo)

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

    # check if there exists MtOH properly
    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

    d_atomtype = dict()
    # dict for writing atom types

    # check flag for atom informations: the first shot will be treated, and will be skipped after.
    firsttimeFlag = 0

    while 1:
        ### Show progress
        t1 = time.time()
        remaining_time = elapsed_time * (n_timestep - 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()

        processed_step += 1

        ### Read
        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(' ')

        ### update myBGF with trajectory information ###
        natom_bgf = len(myBGF.a)  # number of atoms in BGF file

        if not natom_bgf == natoms:
            nu.die(
                "Number of atoms in trajectory file does not match with BGF file."
            )

        mode = ""
        if 'xs' in keywords or 'ys' in keywords or 'zs' in keywords:
            mode = 'scaled'
        elif 'x' in keywords or 'y' in keywords or 'z' in keywords:
            mode = 'normal'
        elif 'xu' in keywords or 'yu' in keywords or 'zu' in keywords:
            mode = 'unwrapped'

        # actual coordinate
        coordinfo = chunk[9:]

        # assume that coordinfo is similar to ['id', 'type', 'xs', 'ys', 'zs', 'ix', 'iy', 'iz']
        for atomline in coordinfo:
            atomcoord = atomline.split(' ')
            atom = myBGF.getAtom(int(atomcoord[0]))

            if mode == 'scaled':
                atom.x = float(atomcoord[2]) * boxsize[0]
                atom.y = float(atomcoord[3]) * boxsize[1]
                atom.z = float(atomcoord[4]) * boxsize[2]

            elif mode == 'unwrapped':
                atom.x = float(atomcoord[2])
                atom.y = float(atomcoord[3])
                atom.z = float(atomcoord[4])

            elif mode == 'normal':
                try:
                    ix_index = keywords.index('ix')
                    iy_index = keywords.index('iy')
                    iz_index = keywords.index('iz')
                except ValueError:
                    nu.warn(
                        "No image information no the trajectory file. Will be treated as unwrapped."
                    )
                    atom.x = float(atomcoord[2])
                    atom.y = float(atomcoord[3])
                    atom.z = float(atomcoord[4])
                else:
                    atom.x = (int(atomcoord[ix_index]) * boxsize[0]) + float(
                        atomcoord[2])
                    atom.y = (int(atomcoord[iy_index]) * boxsize[1]) + float(
                        atomcoord[3])
                    atom.z = (int(atomcoord[iz_index]) * boxsize[2]) + float(
                        atomcoord[4])

            try:
                for i in range(0, 3):
                    myBGF.CRYSTX[i] = boxsize[i]
            except:
                pass
                #nu.warn("Crystal information error: is this file not periodic?")

            ### for the first shot, record atom types
            if firsttimeFlag == 0:
                d_atomtype[int(atomcoord[0])] = atomcoord[1]

        ### myBGF update complete! ###

        ### Realign whole system to x axis
        sys.stdout.write(' Realigning.. ')
        sys.stdout.flush()

        # 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 for "all atoms in BGF": move COM of CNT as origin
        # com of CNT
        Mx = 0
        My = 0
        Mz = 0
        for atom in myBGF.a:
            if "CNT" in atom.rName:
                Mx += atom.x / N_CNT
                My += atom.y / N_CNT
                Mz += atom.z / N_CNT

        # move
        for atom in myBGF.a:
            atom.x += Mx
            atom.y += My
            atom.z += Mz

        # calculate the moment of inertia (MI) and the center of mass (COM) of CNT from "myBGF"
        for aNo in aNo_CNT:
            atom = myBGF.getAtom(aNo)
            Ixx += (atom.y**2 + atom.z**2) / N_CNT
            Iyy += (atom.x**2 + atom.z**2) / N_CNT
            Izz += (atom.x**2 + atom.y**2) / N_CNT
            Ixy -= (atom.x * atom.y) / N_CNT
            Ixz -= (atom.x * atom.z) / N_CNT
            Iyz -= (atom.y * atom.z) / N_CNT

        # the moment of inertia tensor
        I = numpy.array([[Ixx, Ixy, Ixz], [Ixy, Iyy, Iyz], [Ixz, Iyz, Izz]])

        # eigenvalue & eigenvector calculation
        eigval, eigvec = numpy.linalg.eig(
            I)  # eigval[0] is the minimum among the values.

        # rearrange the U vector
        U = numpy.matrix(eigvec)
        Ut = U.T

        # "myBGF" rotation
        for atom in myBGF.a:
            v = numpy.matrix([atom.x, atom.y, atom.z]).T
            Uv = Ut * v
            atom.x = float(Uv[0])
            atom.y = float(Uv[1])
            atom.z = float(Uv[2])

        ### update crystx information: note that CNT is along x-axis.	# is this right?? 20130619
        if boxsize[0] > boxsize[1] and boxsize[0] > boxsize[2]:
            boxsize = [boxsize[0], boxsize[1], boxsize[2]]
        elif boxsize[1] > boxsize[0] and boxsize[1] > boxsize[2]:
            boxsize = [boxsize[1], boxsize[0], boxsize[2]]
        elif boxsize[2] > boxsize[0] and boxsize[2] > boxsize[1]:
            boxsize = [boxsize[2], boxsize[0], boxsize[1]]

        for i in range(0, 3):
            myBGF.CRYSTX[i] = boxsize[i]

        # transpose to the center of box
        for atom in myBGF.a:
            atom.x += (boxsize[0] / 2)
            atom.y += (boxsize[1] / 2)
            atom.z += (boxsize[2] / 2)

        # apply periodic condition
        myBGF = bgftools.periodicMoleculeSort(myBGF, 0)

        ### Write LAMMPS trjectory
        output = "ITEM: TIMESTEP\n"
        output += str(timestep) + "\n"
        output += "ITEM: NUMBER OF ATOMS\n"
        output += str(natom_bgf) + "\n"
        output += "ITEM: BOX BOUNDS pp pp pp\n"
        output += "0 " + str(boxsize[0]) + "\n"
        output += "0 " + str(boxsize[1]) + "\n"
        output += "0 " + str(boxsize[2]) + "\n"
        output += "ITEM: ATOMS id type xu yu zu\n"
        for atom in myBGF.a:
            output += str(atom.aNo) + " " + d_atomtype[atom.aNo] + " " + str(
                atom.x) + " " + str(atom.y) + " " + str(atom.z) + "\n"

        myNewTRJ.write(output)

        t2 = time.time()  # time mark
        elapsed_time = t2 - t1

    myNewTRJ.close()
    print('')

    return 1
def getSlipLength(bgf_file,
                  trj_file,
                  ff_file,
                  interval,
                  n_step,
                  n_avg_step,
                  silent=False):
    """
	This calculates the profile of averaged velocity according to r. 
	NOTE: This is different from averaged velocity profile according to r.
	"""

    # const
    PI = math.pi
    vdw_r_C = 1.7

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

    myBGF = bgf.BgfFile(bgf_file)
    myTRJ = open(trj_file)
    myTRJ.seek(0)
    myPkl = open(
        trj_file + ".profile.r_ave_vel-s" + str(n_step) + "k" + str(n_skip) +
        ".pickle", 'w')
    #f_dump = open(trj_file + ".profile.r_ave_vel.dump", 'w')
    #dump = "";

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

    if not silent:
        print("The trajectory contains " + str(n_timestep) + " timesteps.")

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

    for atom in myBGF.a:
        # Carbons in CNT
        if "CNT" in atom.rName:
            aNo_CNT.append(atom.aNo)

        # 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

    # calculate radius_CNT
    avg_radius_CNT = 0.0
    x_CNT = 0.0
    y_CNT = 0.0
    if not silent:
        print(
            "Calculating the average radius of CNT throughout the averaging steps"
        )
    while 1:

        ### Show progress
        t1 = time.time()
        remaining_time = elapsed_time * (n_step - processed_step)

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

        # skip if necessary
        if processed_step <= n_skip:
            processed_step += 1
            continue

        timestep = int(chunk[1])
        l_timestep.append(timestep)
        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(' ')
        sys.stdout.write('\r' + "Fetched timestep: " + str(timestep) +
                         " (Remaining time: " +
                         "{0:4.1f}".format(remaining_time) + " seconds, " +
                         "{0:4.1f} minutes".format(remaining_time / 60) + ")")
        sys.stdout.flush()

        ### update myBGF with trajectory information ###
        natom_bgf = len(myBGF.a)  # number of atoms in BGF file

        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:]

        # modified for fast treatment
        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])

            try:
                for i in range(0, 3):
                    myBGF.CRYSTX[i] = boxsize[i]
            except:
                pass

        # apply periodic condition
        #myBGF = bgftools.periodicMoleculeSort(myBGF, 0, True)

        ### myBGF update complete! ###

        # for CNT atoms, calculate some properties
        min_x_CNT = 0.0
        max_x_CNT = 0.0
        radius_CNT = 0.0
        height_CNT = 0.0
        aNo_WAT_O_not_in_CNT = []
        temp = []
        min_y_CNT = 0.0
        max_y_CNT = 0.0
        min_z_CNT = 0.0
        max_z_CNT = 0.0
        CNT_orientation = ""

        l_radius_CNT = []
        l_x_CNT = []
        l_y_CNT = []

        for aNo in aNo_CNT:
            atom = myBGF.getAtom(aNo)

            # center of CNT
            l_x_CNT.append(atom.x)
            l_y_CNT.append(atom.y)

            # height
            if atom.z < min_z_CNT:
                min_z_CNT = atom.z
            if atom.z > max_z_CNT:
                max_z_CNT = atom.z

        x_CNT, a = nu.meanstdv(l_x_CNT)
        y_CNT, a = nu.meanstdv(l_y_CNT)
        z_diff = max_z_CNT - min_z_CNT

        # radius of CNT
        for aNo in aNo_CNT:
            atom = myBGF.getAtom(aNo)
            l_radius_CNT.append(
                math.sqrt((atom.x - x_CNT)**2 + (atom.y - y_CNT)**2))

        radius_CNT, a = nu.meanstdv(l_radius_CNT)
        l_avg_radius_CNT.append(radius_CNT)

        if processed_step > 3:
            break

    avg_radius_CNT, s = nu.meanstdv(l_avg_radius_CNT)
    bins = np.arange(0.0, math.ceil(radius_CNT), interval)
    l_radial_vz_profile = np.zeros(len(bins) - 1)

    if not silent:
        print("\nAveraged CNT radius: " + str(avg_radius_CNT) + " A")
    if not silent: print("CNT center: " + str([x_CNT, y_CNT]))

    # calculate properties
    myTRJ.close()
    myTRJ = open(trj_file)
    myTRJ.seek(0)
    dumpatom = get_line(trj_file)
    processed_step = 0
    r = []
    vz = []
    # data container
    while 1:
        data = dict()
        # stores [r vz] for a timestep

        ### Show progress
        t1 = time.time()
        remaining_time = elapsed_time * (n_step - processed_step)

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

        if processed_step <= n_skip:
            processed_step += 1
            continue

        timestep = int(chunk[1])
        l_timestep.append(timestep)
        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(' ')
        sys.stdout.write('\r' + "Fetched timestep: " + str(timestep) +
                         " (Remaining time: " +
                         "{0:4.1f}".format(remaining_time) + " seconds, " +
                         "{0:4.1f} minutes".format(remaining_time / 60) + ")")
        sys.stdout.flush()

        ### update myBGF with trajectory information ###
        natom_bgf = len(myBGF.a)  # number of atoms in BGF file

        if not natom_bgf == natoms:
            nu.die(
                "Number of atoms in trajectory file does not match with BGF file."
            )

        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:]

        # modified for fast treatment
        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])
            atom.vx = float(atomcoord[5])
            atom.vy = float(atomcoord[6])
            atom.vz = float(atomcoord[7])

            try:
                for i in range(0, 3):
                    myBGF.CRYSTX[i] = boxsize[i]
            except:
                pass
                #nu.warn("Crystal information error: is this file not periodic?")

        # apply periodic condition
        myBGF = bgftools.periodicMoleculeSort(myBGF, 0, True)

        ### myBGF update complete! ###

        # calculate z-directional velocity of water molecules wrt r		vcm = sum vi mi / sum mi
        atom = myBGF.getAtom(aNo_WAT_O[0])
        mass_O = bgftools.getMass(myBGF, [aNo_WAT_O[0]], ff_file)
        atom = myBGF.getAtom(atom.CONECT[0])
        mass_H = bgftools.getMass(myBGF, [atom.aNo], ff_file)
        mass_H2O = mass_O + 2 * mass_H  # H2O mass

        for ano in aNo_WAT_O:
            atom = myBGF.getAtom(ano)  # oxygen

            # com & velocity calculation
            cmx = atom.x * mass_O
            cmy = atom.y * mass_O
            vcmz = atom.vz * mass_O

            for ano2 in atom.CONECT:
                atom2 = myBGF.getAtom(ano2)
                cmx += atom2.x * mass_H
                cmy += atom2.y * mass_H
                vcmz += atom2.vz * mass_H

            cmx /= mass_H2O
            cmy /= mass_H2O
            vcmz /= mass_H2O

            dist = math.sqrt((x_CNT - cmx)**2 + (y_CNT - cmy)**2)
            r.append(dist)
            vz.append(vcmz * 10**5)  # LAMMPS real unit conversion for velocity

        # timestep mark for starting average
        if l_avg_count == []:
            n_avg_count_step = timestep

        l_avg_count.append(timestep)

        # if the time has come.. average!
        if len(l_avg_count) == n_avg_step or processed_step == n_timestep - 1:
            if not silent:
                print(" Averaging invoked at timestep " + str(timestep) +
                      " (" + str(len(l_avg_count)) + " points)")

            # binning
            vz = np.array(vz)
            sum_vz = np.ma.array(np.histogram(r, bins, weights=vz)[0])
            sum_vz2 = np.ma.array(np.histogram(r, bins, weights=vz * vz)[0])
            n_vz = np.ma.array(np.histogram(r, bins)[0])
            #mask_n = ma.masked_values(n_vz, 0)

            mean = sum_vz / n_vz
            std = np.sqrt(sum_vz2 / n_vz - mean * mean)

            mean = np.ma.fix_invalid(mean, fill_value=0.0).data
            std = np.ma.fix_invalid(std, fill_value=0.0).data
            n_vz = np.ma.fix_invalid(n_vz, fill_value=0).data

            if len(mean) != len(bins) - 1 or len(std) != len(bins) - 1:
                nu.die("on numpy masked_array calculation!")

            l_result.append([l_avg_count, bins, n_vz, mean, std])

            # reset
            r = []
            vz = []
            l_radial_vz_profile = np.zeros(len(bins) - 1)
            l_avg_count = []

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

    #f_dump.write(dump)
    pkl.dump(l_result, myPkl)

    print('')
    return 1
Esempio n. 30
0
def getHBond(bgf_file,
             trj_file,
             out_file,
             direction,
             interval,
             avg_timestep,
             silent=False):

    nu.warn(
        "LAMMPS trajectory with NPT simulations will give you the wrong result."
    )

    ### init
    timestep = 0
    l_timestep = []
    line = []
    n_header = 0
    t1 = 0
    t2 = 0
    # clock
    vector = [0, 0, 1]
    # the axis of interest. in the acetone-water case, z direction.
    atominfo = dict()
    # atom data extracted from ff_file
    result = dict()
    axis = 0
    # 1: x-axis, 2: y-axis, 3: z-axis

    ### direction
    if "x" in direction:
        axis = 0
    elif "y" in direction:
        axis = 1
    elif "z" in direction:
        axis = 2
    else:
        nu.die("Error on reading direction.")

    ### open files
    myBGF = bgf.BgfFile(bgf_file)
    myTRJ = open(trj_file)
    myTRJ.seek(0)
    f_out_file = open(out_file + ".dat", 'w')
    f_avg_out_file = open(out_file + ".average.dat", 'w')
    f_pickle = open(out_file + ".pickle", 'w')
    f_avg_pickle = open(out_file + ".average.pickle", 'w')

    ### read residues from bgf_file
    residue = set()
    # kind of residues in BGF file
    dict_residue = dict()
    # stores residue numbers per each residue. RES1: [1, 2, ..], RES2: [6, 7, ..]
    for i in myBGF.a:
        rname = string.strip(i.rName)
        residue.add(rname)
    output = ""
    for i in residue:
        output += i + " "

    if not silent:
        print("Found " + str(len(residue)) + " residues in BGF file: " +
              str(output))
    residue = list(residue)
    residue.append('TOTAL')

    for index, i in enumerate(residue):
        dict_residue[i] = index

    n_residue = len(residue)  # number of residues (including total)

    ### read trajectory file
    # how many steps to go?
    wc_trj_file = popen("grep TIMESTEP " + trj_file + " | wc -l ").read()
    n_timestep = int(wc_trj_file.split()[0])
    print("The trajectory contains " + str(n_timestep) + " timesteps.")

    # 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:
        try:
            chunk = [next(dumpatom) for i in range(natoms + n_header)]
        except StopIteration:
            break

        timestep = int(chunk[1])
        l_timestep.append(timestep)
        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(' ')

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

        processed_step += 1

        ### update myBGF with trajectory information ###
        natom_bgf = len(myBGF.a)  # number of atoms in BGF file

        if not natom_bgf == natoms:
            nu.die(
                "Number of atoms in trajectory file does not match with BGF file."
            )

        mode = ""
        if 'xs' in keywords or 'ys' in keywords or 'zs' in keywords:
            mode = 'scaled'
        elif 'x' in keywords or 'y' in keywords or 'z' in keywords:
            mode = 'normal'
        elif 'xu' in keywords or 'yu' in keywords or 'zu' in keywords:
            mode = 'unwrapped'

        # actual coordinate
        coordinfo = chunk[9:]

        # assume that coordinfo is similar to ['id', 'type', 'xs', 'ys', 'zs', 'ix', 'iy', 'iz']
        for atomline in coordinfo:
            atomcoord = atomline.split(' ')
            atom = myBGF.getAtom(int(atomcoord[0]))

            if mode == 'scaled':
                atom.x = float(atomcoord[2]) * boxsize[0]
                atom.y = float(atomcoord[3]) * boxsize[1]
                atom.z = float(atomcoord[4]) * boxsize[2]

            elif mode == 'unwrapped':
                atom.x = float(atomcoord[2])
                atom.y = float(atomcoord[3])
                atom.z = float(atomcoord[4])

            elif mode == 'normal':
                try:
                    ix_index = keywords.index('ix')
                    iy_index = keywords.index('iy')
                    iz_index = keywords.index('iz')
                except ValueError:
                    nu.warn(
                        "No image information no the trajectory file. Will be treated as unwrapped."
                    )
                    atom.x = float(atomcoord[2])
                    atom.y = float(atomcoord[3])
                    atom.z = float(atomcoord[4])
                else:
                    atom.x = (int(atomcoord[ix_index]) * boxsize[0]) + float(
                        atomcoord[2])
                    atom.y = (int(atomcoord[iy_index]) * boxsize[1]) + float(
                        atomcoord[3])
                    atom.z = (int(atomcoord[iz_index]) * boxsize[2]) + float(
                        atomcoord[4])

            try:
                for i in range(0, 3):
                    myBGF.CRYSTX[i] = boxsize[i]
            except:
                pass
                #nu.warn("Crystal information error: is this file not periodic?")

        # apply periodic condition
        myBGF = bgftools.periodicMoleculeSort(myBGF, 0)

        ### DONE for updating trj on BGF file ###
        ### Do whatever I want: density profile

        ### list up O in ACT

        ### list up H in WAT

        ### for every pair, get hbond dist

        ### if it's less than 2.4A, then count++

    ### return

    print('')
    return 1