예제 #1
0
def loadFF(file):

	if file == "":
		#nu.warn("Forcefield type is not specified. Using DREIDING 2 as default.")
		file = "/home/noische/ff/DREIDING2.21.ff"

	file = file.strip()

	lines = []
	try:
		ffFile = open(file)
		while 1:
			line = ffFile.readline()
			if line == "": break
			line = line.strip()
			line = line.rstrip('\n')
			line = re.split('\s*', line)
			lines.append(line)
	except IOError:
		nu.die("Force Field File " + file + " open failed")
	else:
		pass;
		#print("Force Field Dreiding loaded")

	start_index = lines.index(["VERSION"])
	stop_index = lines.index(["END"], start_index)
	temp = nu.flatten(lines[start_index + 1 : stop_index])

	for i in temp:
		if "CERIUS" in i:
			return lines

	nu.die("Forcefield file " + file + " is not a CERIUS2 type file.")
예제 #2
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)
예제 #3
0
파일: CNT.py 프로젝트: hopefulp/sandbox
    def set_coord(self, coord):
        if len(coord) != len(self.bgfmodel.a):
            nu.die("Number of coordinates != number of BGF atoms")

        for index, i in enumerate(coord):
            self.bgfmodel.a[index].x = i[0]
            self.bgfmodel.a[index].y = i[1]
            self.bgfmodel.a[index].z = i[2]
예제 #4
0
def dat2bgf(bgf_file, dat_file, out_file):

    # init
    mybgf = bgf.BgfFile(bgf_file)
    
    f_dat_file = open(dat_file)
    temp = f_dat_file.read().split('\n')
    f_dat_file.close()

    temp = [i.partition('#')[0].rstrip() for i in temp if i != ""]

    # PBC
    for i in temp:
        if 'xlo' in i:
            line = i.split()
            mybgf.CRYSTX[0] = float(line[1]) - float(line[0])
        if 'ylo' in i:
            line = i.split()
            mybgf.CRYSTX[1] = float(line[1]) - float(line[0])
        if 'zlo' in i:
            line = i.split()
            mybgf.CRYSTX[2] = float(line[1]) - float(line[0])

    # Coordinates
    dat_atom_start = temp.index('Atoms')
    dat_atom_end = temp.index('Bonds')
    if 'Velocities' in temp:
        dat_atom_end = temp.index('Velocities') # if data file is from write_restart command, Velocities are also written in the file.:w

    temp = temp[dat_atom_start + 1:dat_atom_end]

    n_dat_atoms = len(temp)
    n_bgf_atoms = len(mybgf.a)

    if n_dat_atoms != n_bgf_atoms:
        nu.die("Number of atoms mismatch between bgf and LAMMPS data file.")

    coords = [] # coords = id type molid charge x y z ix iy iz
    for i in temp:
        line = i.split()
        coords.append(line)

    for i in coords:
        id = int(i[0])
        atom = mybgf.a[mybgf.a2i[id]]   # getAtom
        atom.x = float(i[4])
        atom.y = float(i[5])
        atom.z = float(i[6])

    if out_file == "": out_file = bgf_file.split(".bgf")[0] + "_mod.bgf"
    mybgf.REMARK.append("Coordinates updated on %s" % time.asctime(time.gmtime()))
    mybgf.REMARK.append("Coordinates updated with data file %s" % os.path.abspath(dat_file))
    mybgf.saveBGF(out_file)


    print('Done. Check %s ' % out_file)
    return 1
예제 #5
0
    def computeLatticeParam(self, lv):
        if not len(lv) == 3: nu.die("Proper lattice vectors are not provided.")

        x = lv[0]
        y = lv[1]
        z = lv[2]
        A, B, C = [veclength(v) for v in lv]
        alpha = angle(y, z)
        beta = angle(x, z)
        gamma = angle(x, y)

        return [A, B, C, alpha, beta, gamma]
예제 #6
0
        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)!"
                )

            # find nearest neighbor from D atom

            # calculate hbonds
            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])
                    if 1e-5 < nu.pbc_dist(a, d, mytrj.pbc[t]) < d_crit:
                        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:
                                hbonds.append([
                                    d_atom.aNo, a_atom.aNo, d_atom.z, a_atom.z
                                ])
                                #donors.append(d_atom.aNo)
                                #acceptors.append(a_atom.aNo)
                                #hydrogens.append(h_atom.aNo)
                                #distances.append(dist)

            return hbonds
예제 #7
0
def getCom(myBGF, ff_file='', aNo_list=[], silent=False):
    """
getCom(myBGF):
    Returns a (x, y, z) of the center of mass of the molecule.
    """

    # init
    mrx = 0
    mry = 0
    mrz = 0
    m = 0

    # if aNo_list not specified, CoM of whole molecule will be returned.
    if not aNo_list:
        for atom in myBGF.a:
            aNo_list.append(atom.aNo)

    # read atom mass from the dictionary
    for i in aNo_list:
        atom = myBGF.getAtom(i)
        fftype_key = atom.ffType.strip()
        if not fftype_key in atom_mass:
            parse = ff_file.split()
            update_mass(parse, silent=silent)

        if not fftype_key in atom_mass:
            nu.die(
                "No ffType %s found in the atom mass dictionary. You have to specify a ff_file to countinue."
                % fftype_key)

        mrx += (atom.x * float(atom_mass[fftype_key]))
        mry += (atom.y * float(atom_mass[fftype_key]))
        mrz += (atom.z * float(atom_mass[fftype_key]))
        m += float(atom_mass[fftype_key])

    try:
        x = mrx / m
        y = mry / m
        z = mrz / m
    except:
        nu.warn(
            "Total mass is zero for the molecule while calculating center of mass!"
        )
        x = 0
        y = 0
        z = 0

    return (x, y, z)
예제 #8
0
        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
예제 #9
0
def count_layer(bgf_file, trj_file, ff_file='', out_file=''):
    '''counts number of O atoms in each layer.
    '''
    # variables
    result = dict()

    # 1. Load BGF
    mybgf = bgf.BgfFile(bgf_file)
    N_BGF_ATOMS = len(mybgf.a)
    r_vdw_C = 3.38383824 / 2

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

    # 4. Update coordinates from the snapshot
    for t in tqdm.tqdm(timesteps,
                       ncols=120,
                       desc="Calculating graphene z positions"):
        mybgf = get_timestep(mybgf, trj_file, t)
        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
        result[t] = [avg_gra_z1, avg_gra_z2, dist, eff_dist]

    # 5. Analyze
    timesteps = sorted(result.keys())
    with open('z_position.test.dat', 'w') as f:
        output = ''
        for t in timesteps:
            output += "%d " % t
            output += "%8.3f %8.3f %8.3f %8.3f\n" % result[t]

        f.write(output)
예제 #10
0
def stress_cell(bgf_file, ratio, out_file=''):
    '''
    scales the cell to the ratio.
    '''

    # initialization
    if not isinstance(bgf_file, bgf.BgfFile):
        myBGF = bgf.BgfFile(bgf_file)
    else:
        myBGF = bgf_file

    if not myBGF.CRYSTX:
        nu.die("No pbc information to stress the cell.")

    xs = ys = zs = 1.0
    parse = ratio.split()

    if len(parse) == 1:
        xs = ys = zs = float(parse[0])
    elif len(parse) == 3:
        xs = float(parse[0])
        ys = float(parse[1])
        zs = float(parse[2])
    else:
        nu.die("Error on specifying cell inflation ratio %s: must be 1 or 3" %
               ratio)

    for atom in myBGF.a:
        atom.x *= xs
        atom.y *= ys
        atom.z *= zs

    myBGF.CRYSTX[0] *= xs
    myBGF.CRYSTX[1] *= ys
    myBGF.CRYSTX[2] *= zs

    # returns
    if not out_file:
        return myBGF
    else:
        myBGF.saveBGF(out_file)
        if not silent: print("File saved to %s" % out_file)
        return 1
예제 #11
0
        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
예제 #12
0
def dot(a, b):
    """
	Calculate dot product of a and b
	"""
    try:
        na = len(a)
        nb = len(b)
    except:
        nu.die("List required for dot product calculation.")

    na = len(a)
    nb = len(b)

    temp = [a[i] * b[i] for i in range(na)]
    temp2 = 0

    for i in temp:
        temp2 += i

    return temp2
예제 #13
0
def atoms_minmax(mybgf, attr, selection=''):
    min = 1e10
    max = -1e10

    # conditions
    if not attr:
        nu.die("You have to specify BgfAtom attribute to get minmax!")

    if not 'atom.' in attr:
        attr = "atom." + attr

    if not attr in possible_atom_attr:
        nu.die("Impossible to get minmax of %s!" % attr)

    if not "atom" in selection:
        nu.die("You have to specify a proper selection!")

    # get minmax
    for atom in mybgf.a:
        if selection:
            if eval(selection):
                if eval(attr) < min:
                    min = eval(attr)
                if eval(attr) > max:
                    max = eval(attr)
        else:
            if eval(attr) < min:
                min = eval(attr)
            if eval(attr) > max:
                max = eval(attr)

    return min, max
예제 #14
0
def atoms_average(mybgf, attr, selection=''):
    '''
    attr: e.g.) x, y, z or atom.x, atom.y, ...
    selection: e.g.) "'Mo' in atom.ffType"
    '''
    # init
    avg = 0.0
    n = 0

    # conditions
    if not attr:
        nu.die("You have to specify BgfAtom attribute to average!")

    if not 'atom.' in attr:
        attr = "atom." + attr

    if not attr in possible_atom_attr:
        nu.die("Impossible to get average of %s!" % attr)

    if not "atom" in selection:
        nu.die("You have to specify a proper selection!")

    # get average
    for atom in mybgf.a:
        if selection:
            if eval(selection):
                avg += eval(attr)
                n += 1
        else:
            avg += eval(attr)
            n += 1

    return avg / float(n)
예제 #15
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)
예제 #16
0
    def compile(self, filename="compile.bgf"):
        """
        generate random hyperbranched polymer structure according to the graph.
        returns a BgfFile object.
        """
        # LAMMPS preparation
        lammps_command = os.environ["EXEC"]
        curr_dir = os.path.abspath(".")
        temp_dir = curr_dir + ("/scratch/")
        if not os.path.isdir(temp_dir):
            os.makedirs(temp_dir)
        os.chdir(temp_dir)

        # REMARK: make sure self.Terminal/Linear/Dendron is properly assigned.
        if self.Terminal == "" or self.Linear == "" or self.Dendron == "":
            nu.die("BGF file for monomers are not properly set.")
            return False

        # for i in nodes:
        for i in self.nodes():
            ## introduce a monomer
            ### count a number of branches connected to a node
            n_branch = 0
            parent_monomer = 0
            for j in self[i]:
                if i < j:
                    n_branch += 1
                elif i > j:
                    parent_monomer = j
            if n_branch == 0:
                new_monomer = bgf.BgfFile(self.Terminal)
            elif n_branch == 1:
                new_monomer = bgf.BgfFile(self.Linear)
            elif n_branch == 2:
                new_monomer = bgf.BgfFile(self.Dendron)

            for atom in new_monomer.a:
                atom.rNo = i  # set the residue number to the node id

            ## connect the monomer to the body
            if i == 0:
                self.bgfmodel = self.bgfmodel.merge(new_monomer)
                self.bgfmodel.renumber()
                continue  ### for headnode, no connection is required.
            else:
                ### head: in monomer (C) // tail: in the body (N)
                for atom in self.bgfmodel.a:
                    if ("B" in atom.chain or "T"
                            in atom.chain) and atom.rNo == parent_monomer:
                        tail_atom_ano = atom.aNo
                for atom in new_monomer.a:
                    if "H" in atom.chain and atom.rNo == i:
                        head_atom_ano = atom.aNo

                head_atom = new_monomer.getAtom(head_atom_ano)
                tail_atom = self.bgfmodel.getAtom(tail_atom_ano)

                # choose a random H atom to detach from the tail (N)
                bonding_candidate_body = []
                for ano in tail_atom.CONECT:
                    atom = self.bgfmodel.getAtom(ano)
                    if "H" in atom.ffType and "H" in atom.aName:
                        bonding_candidate_body.append(ano)
                bonding_candidate_body = random.choice(bonding_candidate_body)
                bonding_candidate_body_atom = self.bgfmodel.getAtom(
                    bonding_candidate_body)

                # translate
                (x, y, z) = (bonding_candidate_body_atom.x,
                             bonding_candidate_body_atom.y,
                             bonding_candidate_body_atom.z)
                for atom in new_monomer.a:
                    atom.x += x
                    atom.y += y
                    atom.z += z

                # merge
                self.bgfmodel = self.bgfmodel.merge(new_monomer)
                self.bgfmodel.renumber()

                # choose a random H atom to detach from the head (C)
                bonding_candidate_monomer = []
                for ano in head_atom.CONECT:
                    atom = self.bgfmodel.getAtom(ano)
                    if "H" in atom.ffType and "H" in atom.aName:  # any H atoms are exposed to detachment
                        bonding_candidate_monomer.append(ano)
                bonding_candidate_monomer = random.choice(
                    bonding_candidate_monomer)
                bonding_candidate_monomer_atom = self.bgfmodel.getAtom(
                    bonding_candidate_monomer)

                # connect
                tail_atom.connect(head_atom)
                head_atom.connect(tail_atom)
                tail_atom.charge += bonding_candidate_body_atom.charge
                head_atom.charge += bonding_candidate_monomer_atom.charge
                delatoms = [
                    self.bgfmodel.a2i[bonding_candidate_body],
                    self.bgfmodel.a2i[bonding_candidate_monomer]
                ]
                self.bgfmodel.delAtoms(delatoms)
                self.bgfmodel.renumber()

                # translate
                _ = bgftools.getCom(self.bgfmodel, self.ff)
                for atom in self.bgfmodel.a:
                    atom.x -= _[0]
                    atom.y -= _[1]
                    atom.z -= _[2]

                # save
                temp_suffix = "_polymer_" + str(i)
                temp_file = temp_suffix + ".bgf"  # ex) _polymer_1.bgf
                self.bgfmodel.CRYSTX = [50.0, 50.0, 50.0, 90.0, 90.0, 90.0]
                self.bgfmodel.PERIOD = "111"
                self.bgfmodel.AXES = "ZYX"
                self.bgfmodel.SGNAME = "P 1                  1    1"
                self.bgfmodel.CELLS = [-1, 1, -1, 1, -1, 1]
                self.bgfmodel.saveBGF(temp_file)

                # Minimization on LAMMPS
                createLammpsInput = "~tpascal/scripts/createLammpsInput.pl" + " -b " + temp_file + " -f " + self.ff + " -s " + temp_suffix + " -o 'no shake' -t min " + " > /dev/null"
                os.system(createLammpsInput)
                in_file = "in." + temp_suffix
                data_file = "data." + temp_suffix

                # LAMMPS input patch
                #os.system("sed -i 's/' " + in_file)
                os.system("sed -i 's/dielectric      1/dielectric      72/' " +
                          in_file)
                os.system(
                    "sed -i 's/kspace_style    pppm 0.0001/kspace_style    none/' "
                    + in_file)
                os.system(
                    "sed -i 's/boundary        p p p/boundary        s s s/' "
                    + in_file)
                os.system(
                    "sed -i 's/lj\/charmm\/coul\/long\/opt 7.5 8.50000/lj\/cut\/coul\/debye 0.142 10/' "
                    + in_file)

                # LAMMPS data patch
                os.system(
                    "sed -i 's/0.000000  50.000000/-50.000000  50.000000/' " +
                    data_file)
                os.system("sed -i 's/0 # X/0 0 # X/' " + data_file)
                os.system("sed -i 's/Impropers//' " + data_file)

                t1 = time.time()
                runLammps = lammps_command + " -in in." + temp_suffix + " -log " + temp_suffix + ".log " + "-screen none"
                #print("Running " + runLammps)
                os.system(runLammps)
                t2 = time.time()
                #print("Elapsed time for minimization: " + str(t2 - t1) + " sec")

                # update coordinates
                trj_file = temp_suffix + ".min.lammpstrj"
                LAMMPS_trj2bgf.getLAMMPSTrajectory(temp_file, trj_file,
                                                   temp_file, -1, False, True)
                self.bgfmodel = bgf.BgfFile(temp_file)

        # compile success!
        self.bgfmodel.saveBGF(curr_dir + '/' + filename)
예제 #17
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
예제 #18
0
def calc_hbonds(mybgf, selection=""):
    # 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
예제 #19
0
        elif option in ('-r', '--ratio'):
            r = [float(i) for i in str.split(value)]
        elif option in ('-m', '--mw'):
            M = float(value)
        elif option in ('-o', '--output'):
            out_file = value
        elif option in ('-f', '--ff'):
            ff = str(value)
        elif option in ('-n', '--n'):
            n = int(value)
        elif option in ('-a', '--force'):
            isForce = True
        elif option in (''):
            print usage
            sys.exit(0)

    # check ratio
    if np.array(r).sum() == 100:
        r = [float(i / 100) for i in r]
    elif np.array(r).sum() != 1:
        nu.die("Ratio sum should be 1 (fraction) or 100 (percentage)")

    # defaults
    if ff == "":
        ff = "/home/noische/ff/DREIDING2.21.ff"
    if n == 0:
        n = 1

    # main run
    main(T, L, D, r, M, out_file, ff, n, isForce, silent)
예제 #20
0
def getLogData(log_file, out_file, requested_key, silent=True):
    """
getLogData: GET thermodynamic data from a LAMMPS log file
	If getLogData is called from the main function, then getLogData will write the parsed data into keyword.log.parsed
	Otherwise, the list of [step, value(keyword)] will be returned.
	"""

    # initialization
    n_count = 0
    TICK = 10000

    # parse section and extract all thermodynamic data
    #pat1 = re.compile(r"Step\s*(\S*)\s-+")	# (old)
    pat1 = re.compile(
        r"Step[-= ]*(\d*)"
    )  # step. modified in case with /qcfs/dongshin/lis/test/reaxff/trial01/reaxtest/reaxtest.log
    pat2 = re.compile(r"([A-z]+)\s+=\s*-*\d+\.\d+")  # keywords
    pat3 = re.compile(r"[A-z]+\s+=\s*(-*\d+\.\d+)")  # numbers

    # log file loading
    myLOG = open(log_file)
    myLOG_output = []

    # preprocessing
    if not silent: print("\n== Step 1. Preprocessing the LAMMPS log file")
    wc_log_file = os.popen("wc -l " + log_file).read()  # file newline counts
    log_file_length = int(wc_log_file.split()[0])
    str_log_file_length = str(log_file_length)
    t1 = time.time()
    t2 = 0
    while 1:
        try:
            line = myLOG.readline()

            if not line:
                break

            line = line.replace("\n", "")

            n_count += 1
            if not silent:
                if n_count % TICK == 0 or n_count == log_file_length:
                    # estimated time calculation
                    t2 = time.time()
                    elapsed = t2 - t1
                    estimated = elapsed * ((log_file_length - n_count) // TICK)

                    # string conversion
                    str_n_count = str(n_count)
                    str_estimated = "{0:4.1f}".format(estimated)
                    sys.stdout.write("\rPreprocessing.. " + str_n_count +
                                     " / " + str_log_file_length + ".. " +
                                     "(" + str_estimated + " sec remain)")
                    sys.stdout.flush()

                    # reassigning time
                    t1 = t2

            # keyword checking
            """	### ORIGINAL version
			if "angle_coeff" in line or "angle_style" in line or "atom_modify" in line or "atom_style" in line or \
				"bond_coeff" in line or "bond_style" in line or "boundary" in line or "change_box" in line or \
				"variable" in line or "data" in line or "group" in line or "dump" in line or \
				"clear" in line or "communicate" in line or "compute" in line or "compute_modify" in line or \
				"create_atoms" in line or "create_box" in line or "delete_atoms" in line or "delete_bonds" in line or \
				"dielectric" in line or "dihedral_coeff" in line or "dihedral_style" in line or "dimension" in line or \
				"displace_atoms" in line or "displace_box" in line or "dump" in line or "dump" in line or "image" in line or \
				"dump_modify" in line or "echo" in line or "fix" in line or "fix_modify" in line or \
				"group" in line or "if" in line or "improper_coeff" in line or "improper_style" in line or \
				"include" in line or "jump" in line or "kspace_modify" in line or "kspace_style" in line or \
				"label" in line or "lattice" in line or "log" in line or "mass" in line or \
				"minimize" in line or "min_modify" in line or "min_style" in line or "neb" in line or \
				"neigh_modify" in line or "neighbor" in line or "newton" in line or "next" in line or \
				"package" in line or "pair_coeff" in line or "pair_modify" in line or "pair_style" in line or \
				"pair_write" in line or "partition" in line or "prd" in line or "print" in line or \
				"processors" in line or "read_data" in line or "read_restart" in line or "region" in line or \
				"replicate" in line or "reset_timestep" in line or "restart" in line or "run" in line or \
				"run_style" in line or "set" in line or "shell" in line or "special_bonds" in line or \
				"suffix" in line or "tad" in line or "temper" in line or "thermo" in line or \
				"thermo_modify" in line or "thermo_style" in line or "timestep" in line or "uncompute" in line or \
				"undump" in line or "unfix" in line or "units" in line or "variable" in line or \
				"velocity" in line or "write_restart" in line:
				pass;
			"""

            ### 2nd version
            if "coeff" in line or "modify" in line or "style" in line or \
             "boundary" in line or "change_box" in line or \
             "variable" in line or "data" in line or "group" in line or "dump" in line or \
             "clear" in line or "communicate" in line or "compute" in line or \
             "create" in line or "delete" in line or \
             "dielectric" in line or "dimension" in line or \
             "displace_atoms" in line or "displace_box" in line or "image" in line or \
             "echo" in line or "fix" in line or \
             "group" in line or "if" in line or \
             "include" in line or "jump" in line or \
             "label" in line or "lattice" in line or "log" in line or "mass" in line or \
             "minimize" in line or "neb" in line or \
             "neighbor" in line or "newton" in line or "next" in line or \
             "package" in line or \
             "write" in line or "partition" in line or "prd" in line or "print" in line or \
             "processors" in line or "read" in line or "region" in line or \
             "replicate" in line or "time" in line or "restart" in line or "run" in line or \
             "set" in line or "shell" in line or "special_bonds" in line or \
             "tad" in line or "temper" in line or "thermo" in line or \
             "uncompute" in line or \
             "units" in line or "variable" in line or \
             "velocity" in line:
                pass

            elif "Step" in line or "TotEng" in line or "PotEng" in line or "E_dihed" in line or "E_coul" in line or \
             "Temp" in line or "Volume" in line:
                myLOG_output.append(line)

            elif "KinEng" in line or "E_bond" in line or "E_impro" in line or "E_long" in line or \
             "E_angle" in line or "E_vdwl" in line or "Press" in line or  \
             "v_" in line or "c_" in line:
                myLOG_output.append(line)

        except KeyboardInterrupt:
            nu.die("Keyboard Break.. Exiting.")

    #print(myLOG_output)	# Preprocessed data

    # find the number of last step
    templist = copy.deepcopy(myLOG_output)
    laststep = ""
    while 1:
        l = templist.pop()
        if "Step" in l:
            laststep = l
            break
    laststep = int(re.search(pat1, laststep).group(1))  # last step
    str_laststep = str(laststep)

    if not silent: sys.stdout.write("\nDone.\n")

    if not silent: print("\n== Step 2. Getting Thermodynamic Properties")

    if out_file != "":
        myLOG_parse = open(out_file, "w")  # output file

    section = ""
    thermo_data = []
    line = ""

    # first line: pass!!
    section = myLOG_output[0]
    myLOG_output = myLOG_output[1:]

    t1 = time.time()
    t2 = 0
    try:
        for line in myLOG_output:

            section_full = False

            if "Step" in line:
                section_full = True

            # for ONE step
            if section_full == True:
                step = int(re.search(pat1, section).group(1))  # steps
                keyword = re.findall(pat2, section)  # keywords
                value = re.findall(pat3, section)  # numbers

                # display step progress
                if not silent:
                    if step % TICK == 0 or step == laststep:
                        # estimated time calculation
                        t2 = time.time()
                        elapsed = t2 - t1
                        estimated = elapsed * ((laststep - step) // TICK)

                        str_step = str(step)
                        str_estimated = "{0:4.1f}".format(estimated)
                        sys.stdout.write("\rParsing the Step " + str_step +
                                         " / " + str_laststep + ".. " + "(" +
                                         str_estimated + " sec remain)")
                        sys.stdout.flush()

                        # reassign time
                        t1 = t2

                if len(keyword) != len(value):
                    nu.warn("Suspicious parsing at " + str(step) +
                            ".. Exiting.")
                    break

                # check if keyword is a filename
                if out_file != "":
                    # Write thermodynamic data to a new file for further use
                    output_myLOG_parse = "Step\t" + str(step) + "\t"
                    for asdf in range(0, len(keyword)):
                        output_myLOG_parse += keyword[asdf] + "\t" + str(
                            value[asdf]) + "\t"
                    output_myLOG_parse += "\n"
                    myLOG_parse.write(output_myLOG_parse)

                # keyword check
                if requested_key == "":
                    # no option: return the whole data [keyword value keyword value ...]
                    temp = []
                    temp.append("Step")
                    temp.append(step)
                    for i in range(0, len(keyword)):
                        temp.append(keyword[i])
                        temp.append(value[i])
                    thermo_data.append(temp)
                else:
                    # with keyword: append to the result list
                    try:
                        temp = keyword.index(requested_key)
                    except:
                        #nu.warn("Keyword " + str(keyword) + " is not found in the log file.. Exiting.")
                        pass
                    else:
                        thermo_data.append([step, value[temp]])

                # empty bin
                section = line
                section_full = False

            else:
                section += line

    except KeyboardInterrupt:
        nu.die("Keyboard Break.. Exiting.")

    if out_file != "":
        if not silent:
            print("\nParsed thermodynamic data is saved on " + out_file +
                  " ..")
        myLOG_parse.close()

    if not silent: sys.stdout.write("Done.\n")

    return thermo_data
예제 #21
0
def countWater(bgf_file, trj_file, n_step, watercopy, ff_file, silent=False):

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    t1 = t2 = 0
    elapsed_time = 0

    while 1:

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

        if processed_step == n_step:
            break

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

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

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

        # actual coordinate
        coordinfo = chunk[9:]

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

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

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

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

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

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

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

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

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

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

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

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

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

        margin = 5.0

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    return 1
예제 #22
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
예제 #23
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
예제 #24
0
def getBestShot(bgf_file,
                dat_file,
                trj_file,
                log_file,
                ff_file,
                keyword,
                saveBgfFlag,
                n_sample,
                silent=False):

    ### init
    timestep = 0
    l_timestep = []
    line = []
    n_header = 0
    yes_velocity = False
    yes_image = False
    mode = ""
    t1 = 0
    t2 = 0
    # clock

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

    ### LAMMPS Trajectory
    # how many steps to go?
    if not silent: print("** Loading LAMMPS Trajectory **\n")
    if not os.path.exists(trj_file):
        nu.die("Please check the LAMMPS trajectory file.")
    l_timestep = lt.getTrjInfo(trj_file)
    n_timestep = len(l_timestep)
    if not silent:
        print("\nThe 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 ')

    # Find modes
    if 'vx' in keywords:
        if not silent:
            print("Found velocities information from the trajectory.")
        yes_velocity = True

    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'

    if 'ix' in keywords or 'iy' in keywords or 'iz' in keywords:
        yes_image = True

    # scan trajectory to get timesteps
    dumpatom = get_line(trj_file)

    # get working path
    workingpath = os.getcwd()

    if not silent:
        print(
            '\n** Analyzing LAMMPS Log to find the timestep closest to the average "'
            + keyword + '" **\n')

    # read keywords from log file
    logdata = LAMMPS_getLogData.getLogData(log_file, "", keyword, silent=False)

    logdata2 = []
    for i in logdata:
        if i[0] in l_timestep:
            logdata2.append(i)

    logdata2.sort(key=sortkey)

    # truncate
    if not silent:
        print("Only the last " + str(n_sample) +
              " snapshots will be used to calculate the average.")
    logdata2 = logdata2[-n_sample:]

    # average
    temp_avg = 0
    for i in logdata2:
        temp_avg += float(i[1])
    temp_avg /= len(logdata2)

    # deviation
    dev = []
    for i in logdata2:
        dev.append([i[0], abs(float(i[1]) - temp_avg)])

    dev.sort(key=sortkeymin)
    if not silent:
        print("Found the timestep " + str(dev[0][0]) +
              " has the value closest to the average " + keyword +
              " (value: " + str(temp_avg) + ", deviation: " + str(dev[0][1]) +
              ")")

    ### REMARK: dev[0] has the smallest deviation from the average

    # get trajectory
    myTRJ.seek(0)
    dumpatom = get_line(trj_file)

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

        # only treat the designated timestep
        timestep = int(chunk[1])
        if timestep != int(dev[0][0]):
            continue

        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."
            )

        # actual coordinate
        coordinfo = chunk[9:]
        info = hash()

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

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

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

            elif mode == 'normal':
                # images
                if yes_image:
                    ix_index = keywords.index('ix')
                    iy_index = keywords.index('iy')
                    iz_index = keywords.index('iz')
                    info[atomNo]['x'] = (int(atomcoord[ix_index]) *
                                         boxsize[0]) + float(atomcoord[2])
                    info[atomNo]['y'] = (int(atomcoord[iy_index]) *
                                         boxsize[1]) + float(atomcoord[3])
                    info[atomNo]['z'] = (int(atomcoord[iz_index]) *
                                         boxsize[2]) + float(atomcoord[4])
                else:
                    info[atomNo]['x'] = float(atomcoord[2])
                    info[atomNo]['y'] = float(atomcoord[3])
                    info[atomNo]['z'] = float(atomcoord[4])

                # velocities
                if yes_velocity:
                    vx_index = keywords.index('vx')
                    vy_index = keywords.index('vy')
                    vz_index = keywords.index('vz')
                    info[atomNo]['vx'] = float(atomcoord[vx_index])
                    info[atomNo]['vy'] = float(atomcoord[vy_index])
                    info[atomNo]['vz'] = float(atomcoord[vz_index])

        print("")
        if not silent:
            print("** New system size: %12.6f %12.6f %12.6f" %
                  (boxsize[0], boxsize[1], boxsize[2]))
        for i in range(0, 3):
            myBGF.CRYSTX[i] = boxsize[i]

        if saveBgfFlag:
            myBGF.REMARK.append("From the " + str(timestep) + " of " +
                                trj_file + " in " + workingpath + " and " +
                                bgf_file + " by " + str(sys.argv[0]))
            myBGF.REMARK.append(
                "n_samples: %d / %s average: %8.3f / stdev of the snapshot: %8.3f"
                % (n_sample, keyword, temp_avg, dev[0][1]))
            new_bgf_filename = bgf_file[:-4] + "." + str(timestep) + ".bgf"
            for atom in myBGF.a:
                atom.x = info[atom.aNo]['x']
                atom.y = info[atom.aNo]['y']
                atom.z = info[atom.aNo]['z']

            #myBGF = bgftools.periodicMoleculeSort(myBGF, 0, [], ff_file=ff_file, silent=True)  # pbc wrap
            myBGF.saveBGF(new_bgf_filename)
            if not silent:
                print("The snapshot is saved in BGF file " + new_bgf_filename)

        if dat_file:
            ### LAMMPS Data
            dat_atoms = []
            if not silent: print("** Loading LAMMPS Data **\n")

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

            ### update LAMMPS data file ###
            myDAT = open(dat_file)
            new_dat_filename = dat_file + "." + keyword + "." + str(timestep)
            myNewDAT = open(new_dat_filename, '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:10.5f} {8:10.5f} {9:10.5f}".format(
                                atom.aNo, atom.rNo, atomTypeNo, atom.charge,
                                atom.x, atom.y, atom.z, float(parse[7]),
                                float(parse[8]), float(parse[9])) + "\n"
                        myNewDAT.write(output)

                    # Write velocities
                    if yes_velocity:
                        myNewDAT.write("\n\nVelocities\n\n")
                        for i in dat_atoms:
                            if len(i) == 0:
                                continue
                            parse = i.split()
                            atomNo = int(parse[0])
                            output = "{0:>8} {1:12.8f} {2:12.8f} {3:12.8f}\n".format(
                                atomNo, info[atomNo]['vx'], info[atomNo]['vy'],
                                info[atomNo]['vz'])
                            myNewDAT.write(output)

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

                    myNewDAT.write("\n")

            if not silent:
                print("The snapshot is saved in LAMMPS data file " +
                      new_dat_filename)
    print('')
    return 1
예제 #25
0
            dat_file = value
        elif option in ('-t', '--trj'):
            trj_file = value
        elif option in ('-l', '--log'):
            log_file = value
        elif option in ('-f', '--ff'):
            ff_file = value
        elif option in ('-k', '--keyword'):
            keyword = value
        elif option in ('-s', '--save'):
            saveBgfFlag = True
        elif option in ('-n', '--sample'):
            n_sample = int(value)
        elif option == NULL:
            print(usage)
            sys.exit(0)

    ### default options
    if not bgf_file:
        nu.die("No BGF file specified.")
    if not trj_file:
        nu.die("No LAMMPS trajectory file specified.")
    if not log_file:
        nu.die("No LAMMPS log file specified.")
    if not keyword:
        keyword = "Volume"

    # main call
    getBestShot(bgf_file, dat_file, trj_file, log_file, ff_file, keyword,
                saveBgfFlag, n_sample)
예제 #26
0
        elif option in ('-d', '--direction'):
            direction = value
        elif option in ('-i', '--interval'):
            interval = float(value)
        elif option in ('-a', '--average'):
            avg_timestep = int(value)
        elif option == NULL:
            print(usage)
            sys.exit(0)

    direction = string.split(direction)

    if len(direction) == 1:
        if "x" in direction or "y" in direction or "z" in direction:
            pass
        else:
            nu.die("Please specify the direction to see the density profile.")
    else:
        nu.die("Please specify the correct direction.")

    if out_file == "":
        out_file = bgf_file[:-4] + ".densityProfile"

    # main call
    densityProfile(bgf_file,
                   trj_file,
                   out_file,
                   interval,
                   avg_timestep,
                   direction=direction)
예제 #27
0
    N_BGF_ATOMS = len(mybgf.a)
    atom_frags = bt.getMoleculeList(mybgf)
    type = "gra"
    for atom in mybgf.a:
        if "Mo" in atom.ffType:
            type = "mos"

    # 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)
    chunks = dict()
    for t in tqdm.tqdm(timesteps, ncols=120, desc="Updating coordinates"):
        chunk = [next(dump) for i in range(N_BUFFER)]
        chunks[t] = chunk
    ''' single processor usage
    for t in tqdm.tqdm(chunks, ncols=120):
예제 #28
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 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
예제 #30
0
파일: WAT_AOP.py 프로젝트: hopefulp/sandbox
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