def vector_and_center_pbc_trim(point1, point2, box, method=1): """ Calculate the vector coordinates and the position of its center in the master cell """ if method == 1: x = point2.x - point1.x xcenter = (point2.x + point1.x) / 2. x_trimmed = np.remainder(x + box.x / 2., box.x) - box.x / 2. xcenter_trimmed = xcenter + (x_trimmed - x) / 2. y = point2.y - point1.y ycenter = (point2.y + point1.y) / 2. y_trimmed = np.remainder(y + box.y / 2., box.y) - box.y / 2. ycenter_trimmed = ycenter + (y_trimmed - y) / 2. z = point2.z - point1.z zcenter = (point2.z + point1.z) / 2. z_trimmed = np.remainder(z + box.z / 2., box.z) - box.z / 2. zcenter_trimmed = zcenter + (z_trimmed - z) / 2. elif method == 2: x1, y1, z1 = point1.x, point1.y, point1.z x2, y2, z2 = point2.x, point2.y, point2.z x = x2 - x1 y = y2 - y1 z = z2 - z1 xcenter = (x2 + x1) / 2. ycenter = (y2 + y1) / 2. zcenter = (z2 + z1) / 2. if box.x > 0: x_trimmed = x - box.x * int(round(x / box.x)) xcenter_trimmed = xcenter - 0.5 * box.x * int(round(x / box.x)) xcenter_trimmed = xcenter_trimmed - box.x * int( round(xcenter_trimmed / box.x)) else: x_trimmed = x xcenter_trimmed = xcenter xcenter_trimmed = xcenter_trimmed - box.x * int( round(xcenter_trimmed / box.x)) if box.y > 0: y_trimmed = y - box.y * int(round(y / box.y)) ycenter_trimmed = ycenter - 0.5 * box.y * int(round(y / box.y)) ycenter_trimmed = ycenter_trimmed - box.y * int( round(ycenter_trimmed / box.y)) else: y_trimmed = y ycenter_trimmed = ycenter ycenter_trimmed = ycenter_trimmed - box.y * int( round(ycenter_trimmed / box.y)) if box.z > 0: z_trimmed = z - box.z * int(round(z / box.z)) zcenter_trimmed = zcenter - 0.5 * box.z * int(round(z / box.z)) zcenter_trimmed = zcenter_trimmed - box.z * int( round(zcenter_trimmed / box.z)) else: z_trimmed = z zcenter_trimmed = zcenter zcenter_trimmed = zcenter_trimmed - box.z * int( round(zcenter_trimmed / box.z)) _vector = vector3d.Vector3d() _vector.set(x_trimmed, y_trimmed, z_trimmed) _center_vector = vector3d.Vector3d() _center_vector.set(xcenter_trimmed, ycenter_trimmed, zcenter_trimmed) return _vector, _center_vector
def exclude_sphere(self, pos, r): r_sq = r * r low = vector3d.Vector3d(pos.x - r, pos.y - r, pos.z - r) high = vector3d.Vector3d(pos.x + r, pos.y + r, pos.z + r) low_i, low_j, low_k = self.indices(low) high_i, high_j, high_k = self.indices(high) for i in self.int_range(low_i, high_i): for j in self.int_range(low_j, high_j): for k in self.int_range(low_k, high_k): if not self.is_excluded(i, j, k): if self.is_grid_point_near_sphere(i, j, k, pos, r_sq): self.set_excluded(i, j, k, True)
def __init__(self): self._atoms = [] self._bonds = [] self._angles = [] self._dihedrals = [] self._molecules = [] self._box = vector3d.Vector3d() self._box_center = vector3d.Vector3d() self.title = "" self._atoms_by_num = {} self._atoms_by_id = {} self._bonds_by_num = {}
def exclude_sphere(self, pos, r): low = vector3d.Vector3d(pos.x - r, pos.y - r, pos.z - r) low_i, low_j, low_k = self.indices(low) high = vector3d.Vector3d(pos.x + r, pos.y + r, pos.z + r) high_i, high_j, high_k = self.indices(high) r_sq = r * r for i in self.int_range(low_i, high_i): for j in self.int_range(low_j, high_j): for k in self.int_range(low_k, high_k): l = i * self.n_sq + j * self.n + k if self.array[l] == 0: if self.is_grid_point_near_sphere(i, j, k, pos, r_sq): self.array[l] = 1
def __init__(self): self.is_hetatm = False self.pos = vector3d.Vector3d() self.vel = vector3d.Vector3d() self.mass = 0.0 self.type = "" self.element = "" self.chain_id = " " self.res_type = "" self.res_num = "" self.res_insert = "" self.bfactor = 0.0 self.occupancy = 0.0 self.num = 0
def __init__(self, grid_spacing, width, center): self.width = float(width) half_width = self.width / 2.0 self.center = center.copy() self.spacing = float(grid_spacing) self.inv_spacing = 1.0 / self.spacing self.n = 1 cover = 0 self.low = vector3d.Vector3d() while cover < half_width: self.n += 1 half_n_point = int(self.n / 2) self.low.x = self.center.x - half_n_point * self.spacing self.low.y = self.center.y - half_n_point * self.spacing self.low.z = self.center.z - half_n_point * self.spacing width_1 = abs(self.center.x - self.low.x) high_x = self.low.x + self.n * self.spacing width_2 = abs(high_x - self.center.x) cover = min(width_1, width_2) self.actual_width = self.n * self.spacing self.total_volume = self.actual_width**3 self.total_point = self.n**3 self.array = array.array('b') for i in xrange(self.total_point): self.array.append(0) self.n_sq = self.n**2 self.x = [self.low.x + i * self.spacing for i in xrange(self.n)] self.y = [self.low.y + j * self.spacing for j in xrange(self.n)] self.z = [self.low.z + k * self.spacing for k in xrange(self.n)]
def BoxFromPdbLine(line): _box = vector3d.Vector3d() linesplit = line.split() _box.x = float(linesplit[1]) _box.y = float(linesplit[2]) _box.z = float(linesplit[3]) return _box
def exclude_surface(grid, atoms, probe): test_point = vector3d.Vector3d() sphere_points = asa.generate_sphere_points(960) for i, atom_i in enumerate(atoms): is_interior_atom = "asa" in atom_i.__dict__ and atom_i.asa < 9 if not is_interior_atom: neighbor_indices = asa.find_neighbor_indices(atoms, probe, i) n_neighbor = len(neighbor_indices) j_closest_neighbor = 0 radius = probe + atom_i.radius for point in sphere_points: is_point_accessible = True test_point.x = point[0] * radius + atom_i.pos.x test_point.y = point[1] * radius + atom_i.pos.y test_point.z = point[2] * radius + atom_i.pos.z cycled_indices = range(j_closest_neighbor, n_neighbor) cycled_indices.extend(range(j_closest_neighbor)) for j in cycled_indices: atom_j = atoms[neighbor_indices[j]] r = atom_j.radius + probe d_x = test_point.x - atom_j.pos.x d_y = test_point.y - atom_j.pos.y d_z = test_point.z - atom_j.pos.z if d_x * d_x + d_y * d_y + d_z * d_z < r * r: j_closest_neighbor = j is_point_accessible = False break if is_point_accessible: grid.exclude_sphere(test_point, probe)
def vector_pbc_trim( vector, box ): #Calculate the values of the vector between the nearest replicas taking into account the periodic boundary conditions x = vector.x - box.x * int(round(vector.x / box.x)) y = vector.y - box.y * int(round(vector.y / box.y)) z = vector.z - box.z * int(round(vector.z / box.z)) _vector_pbc_trim = vector3d.Vector3d() _vector_pbc_trim.set( x, y, z ) return _vector_pbc_trim
def __init__(self): self.is_hetatm = False self.pos = vector3d.Vector3d() self.vel = vector3d.Vector3d() self.mass = 0.0 self.type = "" self.element = "" self.id = "" self.mol_id = "" self.res_type = "" self.res_num = 0 self.res_insert = "" self.bfactor = 0.0 self.occupancy = 0.0 self.num = 0 self.pbc = vector3d.Vector3d(0, 0, 0) self.neighbors = [] self.inum = 0 #Internal number within a frame
def read_gro(self, fname): self.clear() f = open(fname, 'r') self.title = f.readline().strip() natoms = int(f.readline()) for i in range(natoms): atom = AtomFromGroLine(f.readline()) self.insert_atom(atom) box_array = map(float, f.readline().split()) _box = vector3d.Vector3d(box_array[0], box_array[1], box_array[2]) self.set_box(_box) f.close()
def com(self): com = vector3d.Vector3d(0., 0., 0.) atoms_with_mass = len( list([atom.mass for atom in self._atoms if atom.mass > 0.])) if atoms_with_mass > 0: use_masses = True denominator = atoms_with_mass else: use_masses = False denominator = self.n_atom() for atom in self._atoms: if use_masses: mass = atom.mass else: mass = 1.0 com += atom.pos.scaled_vec(mass) com.scale(1. / float(denominator)) return com
def calculate_asa(atoms, probe, n_sphere_point=960): """ Returns list of accessible surface areas of the atoms, using the probe and atom radius to define the surface. """ sphere_points = generate_sphere_points(n_sphere_point) const = 4.0 * math.pi / len(sphere_points) test_point = vector3d.Vector3d() areas = [] for i, atom_i in enumerate(atoms): neighbor_indices = find_neighbor_indices(atoms, probe, i) n_neighbor = len(neighbor_indices) j_closest_neighbor = 0 radius = probe + atom_i.radius n_accessible_point = 0 for point in sphere_points: is_accessible = True test_point.x = point[0]*radius + atom_i.pos.x test_point.y = point[1]*radius + atom_i.pos.y test_point.z = point[2]*radius + atom_i.pos.z cycled_indices = range(j_closest_neighbor, n_neighbor) cycled_indices.extend(range(j_closest_neighbor)) for j in cycled_indices: atom_j = atoms[neighbor_indices[j]] r = atom_j.radius + probe diff_sq = vector3d.pos_distance_sq(atom_j.pos, test_point) if diff_sq < r*r: j_closest_neighbor = j is_accessible = False break if is_accessible: n_accessible_point += 1 area = const*n_accessible_point*radius*radius areas.append(area) return areas
def get_vector3d(self, index): return vector3d.Vector3d(self.xs[index], self.ys[index], self.zs[index])
def get_center(atoms): center = vector3d.Vector3d(0, 0, 0) for atom in atoms: center += atom.pos center.scale(1.0 / float(len(atoms))) return center
def __init__(self,Coordinates): self.pos = vector3d.Vector3d() self.radius=0.0 self.Coordinates=Coordinates self.Element=''
def NpArray2Vector3d(array): return vector3d.Vector3d(array[0], array[1], array[2])
def getUnitStructure(config, unitType, atomNumOffset = 0): #Determine variables: keyAtom = "C3" #Determine set of required atom types lists = { "SLS" : ["O1", "C2", "C3", "O4", "H5", "H10", "C6", "H7", "H8", "H9"], \ "SLM" : ["O1", "C2", "C3", "O4", "H5", "C6", "H7", "H8", "H9"], \ "SLE" : ["O1", "C2", "C3", "O4", "H5", "O10", "H11", "C6", "H7", "H8", "H9"] } A_lists = { "SLS" : {"O1_next":15.9994, "O1":15.9994, "C2":12.011, "C3":12.011, "O4":15.9994, "H5":1.008, "H10":1.008}, \ "SLM" : {"O1_next":15.9994, "C2":12.011, "C3":12.011, "O4":15.9994, "H5":1.008}, \ "SLE" : {"C2":12.011, "C3":12.011, "O4":15.9994, "H5":1.008, "O10":15.9994, "H11":1.008} } B_lists = { "SLS" : {"C6":12.011, "H7":1.008, "H8":1.008, "H9":1.008}, \ "SLM" : {"C6":12.011, "H7":1.008, "H8":1.008, "H9":1.008}, \ "SLE" : {"C6":12.011, "H7":1.008, "H8":1.008, "H9":1.008} } #Sort configuration atoms by number config.trim() #Available atom identifiers: #Monomer unit number (1, 2, 3), "res_num"; monomer unit type (SLS, SLM, SLE) "res_type"; atom type (O1...H9), "type"; atom number (enumeration across all molecules), "num" template_counter = 0 maxAtomNum = 0 for i in range(len(config.atoms())): atom = config.atoms()[i] if atom.num >= atomNumOffset: resNum = atom.res_num if atom.res_type == unitType and atom.type == lists[unitType][0]: template = {} for requiredType in lists[unitType]: #Adding all of the atoms of the atomistic structure template[requiredType] = findAtom(config, requiredType, resNum, i, "forward") if unitType != "SLE": #Adding O1 atom of the next monomer unit (to determine position of A bead) template["O1_next"] = findAtom(config, "O1", resNum + 1, i, "forward") if unitType != "SLS": #Adding C3 atom of the previous monomer unit (required for the template) template["C3_prev"] = findAtom(config, "C3", resNum - 1, i, "backward") template2 = copy.deepcopy(template) for key in template: template2[key].pos, _ = config.interatom_vector(template[keyAtom].num, template[key].num) template = template2 A_pos = vector3d.Vector3d() A_mass = 0. for key in A_lists[unitType]: dA = copy.deepcopy(template[key].pos) dA.scale(A_lists[unitType][key]) A_pos += dA A_mass += A_lists[unitType][key] A_pos.scale(1./A_mass) A = Atom() A.pos = A_pos A.type = "A" template["A"] = A B_pos = vector3d.Vector3d() B_mass = 0. for key in B_lists[unitType]: dB = copy.deepcopy(template[key].pos) dB.scale(B_lists[unitType][key]) B_pos += dB B_mass += B_lists[unitType][key] B_pos.scale(1./B_mass) B = Atom() B.pos = B_pos B.type = "B" template["B"] = B if unitType != "SLS": C3_prev_pos = template["C3_prev"].pos unitVector = A_pos - C3_prev_pos else: C3_pos = template["C3"].pos unitVector = C3_pos - A_pos _, unitVector2, __ = getUnitStructure(config, "SLM", atomNumOffset) unitVector += unitVector2 A_next_pos = A_pos + unitVector A_next = Atom() A_next.pos = A_next_pos template["A_next"] = A_next template_counter += 1 for key in template: if key != "O1_next": atomNum = template[key].num if atomNum != None and atomNum > maxAtomNum: maxAtomNum = atomNum return template, unitVector, maxAtomNum
def CalculateCrystallinityParameter(config, bondtypes, reference_vector=vector3d.Vector3d( 0., 0., 0.), storeAsAtomtypes=False, mode='average', smin=-0.5, smax=1.0, sbins=75): if mode == 'histo': s_hist = createHistogram(smin, smax, sbins) s_hist_norm_total = 0. for i in range(sbins): sleft, sright = smin + i * s_hist["step"], smin + ( i + 1) * s_hist["step"] costhetaleft, costhetaright = (2. / 3. * (sleft + 0.5))**0.5, ( 2. / 3. * (sright + 0.5))**0.5 s_hist["norm"][i] = 1. / (costhetaleft + costhetaright) progress = 0 bondlist = [] if storeAsAtomtypes: atomOrderingList = [] for bond in config.bonds(): if (bondtypes is None) or (bond.type in bondtypes): bondlist.append(bond.num) if reference_vector.length_sq() == 0.: ave_b = vector3d.Vector3d() i_b = 0 for i in range(len(bondlist)): b1, r1 = config.bond_vector_by_num(bondlist[i]) ave_b = ave_b + b1 i_b += 1 if i_b > 0: ave_b.scale(1. / float(i_b)) else: ave_b = reference_vector if mode == 'average': npBonds = createNumpyBondsArrayFromConfig(config, allowedBondTypes=bondtypes) refBond = Bond() refBond.atom1, refBond.atom2 = Atom(), Atom() refBond.atom1.pos = vector3d.Vector3d(0., 0., 0.) refBond.atom2.pos = ave_b cosSq = calculateAveCosSqForReference(config, refBond, npBonds, -1.) return 1.5 * cosSq - 0.5 elif mode == 'histo': for i in range(len(bondlist)): b1, r1 = config.bond_vector_by_num(bondlist[i]) s_value = 1.5 * (b1.x * ave_b.x + b1.y * ave_b.y + b1.z * ave_b.z )**2 / b1.length_sq() / ave_b.length_sq() - 0.5 if storeAsAtomtypes: bondAtomNums = [ config.bond_by_num(bondlist[i]).atom1.num, config.bond_by_num(bondlist[i]).atom2.num ] for atomNum in bondAtomNums: try: atomOrderingList[[ x["num"] for x in atomOrderingList ].index(atomNum)]["values"].append(s_value) except ValueError: atomOrderingList.append({ "num": atomNum, "values": [s_value] }) updateHistogram(s_value, s_hist) if storeAsAtomtypes: for atomCryst in atomOrderingList: atom = config.atom_by_num(atomCryst["num"]) atomCrystallinity = np.mean(atomCryst["values"]) if atomCrystallinity >= 0.: atom.type = "C" + "%02d" % int(atomCrystallinity * 100) else: atom.type = "Cm" + "%02d" % int(atomCrystallinity * -100) normHistogram(s_hist, normInternalNorm=True) return s_hist
def pos(self, i, j, k): return vector3d.Vector3d(self.x[i], self.y[j], self.z[k])