def __init__(self, host, rootfolder): self.host = host self.rootfolder = rootfolder self.host_folder = path.join(rootfolder, host) self.na_folder = path.join(self.host_folder, self.type_na) self.input_folder = path.join(self.na_folder, 'input') self.spring_obj = Spring(self.rootfolder, self.host, self.type_na, self.n_bp) self.df_all_k = self.spring_obj.read_k_b0_pairtype_df_given_cutoff(self.cutoff) self.crd = path.join(self.input_folder, '{0}.nohydrogen.avg.crd'.format(self.type_na)) self.npt4_crd = path.join(self.input_folder, '{0}.nohydrogen.crd'.format(self.type_na)) self.u = MDAnalysis.Universe(self.crd, self.crd) self.map, self.inverse_map, self.residues_map, self.atomid_map,\ self.atomid_map_inverse, self.atomname_map, self.strandid_map,\ self.resid_map, self.mass_map = self.__build_map() self.node_list = None self.d_idx = None self.n_node = None self.adjacency_mat = None self.degree_mat = None self.laplacian_mat = None self.w = None # Eigenvalue array self.v = None # Eigenvector matrix, the i-th column is the i-th eigenvector self.strand1_array = list() # 0: STRAND1, 1: STRAND2 self.strand2_array = list() # self.strand1_benchmark = None self.strand2_benchmark = None
def __initialize_df(self): d_temp = dict() for host in self.hosts: spring_obj = Spring(self.rootfolder, host, self.type_na, self.n_bp) df0 = spring_obj.read_k_b0_pairtype_df_given_cutoff(self.cutoff) d_temp[host] = k_b0_util.get_central_bps_df(df0) return d_temp
def __read_df_st(self): criteria = 1e-3 spring_obj = Spring(self.rootfolder, self.host, self.type_na, self.n_bp) df = spring_obj.read_k_b0_pairtype_df_given_cutoff(self.cutoff) df1 = get_df_by_filter_st(df, 'st') mask = df1['k'] > criteria return df1[mask]
class GraphAgent: type_na = 'bdna+bdna' n_bp = 21 cutoff = 4.7 def __init__(self, host, rootfolder): self.host = host self.rootfolder = rootfolder self.host_folder = path.join(rootfolder, host) self.na_folder = path.join(self.host_folder, self.type_na) self.input_folder = path.join(self.na_folder, 'input') self.spring_obj = Spring(self.rootfolder, self.host, self.type_na, self.n_bp) self.df_all_k = self.spring_obj.read_k_b0_pairtype_df_given_cutoff( self.cutoff) self.crd = path.join(self.input_folder, '{0}.nohydrogen.avg.crd'.format(self.type_na)) self.npt4_crd = path.join(self.input_folder, '{0}.nohydrogen.crd'.format(self.type_na)) self.u = MDAnalysis.Universe(self.crd, self.crd) self.map, self.inverse_map, self.residues_map, self.atomid_map,\ self.atomid_map_inverse, self.atomname_map, self.strandid_map,\ self.resid_map, self.mass_map = self.__build_map() self.node_list = None self.d_idx = None self.n_node = None self.adjacency_mat = None self.degree_mat = None self.laplacian_mat = None self.w = None # Eigenvalue array self.v = None # Eigenvector matrix, the i-th column is the i-th eigenvector self.strand1_array = list() # 0: STRAND1, 1: STRAND2 self.strand2_array = list() # self.strand1_benchmark = None self.strand2_benchmark = None self.d_seq = { 'STRAND1': sequences[host]['guide'], 'STRAND2': sequences[host]['target'] } def build_node_list(self): node_list = list() d_idx = dict() idx = 0 for cgname, atomname in self.atomname_map.items(): atom_type = pairtype.d_atomcgtype[atomname] if atom_type == 'B': node_list.append(cgname) d_idx[cgname] = idx idx += 1 self.node_list = node_list self.d_idx = d_idx self.n_node = len(self.node_list) print(f"Thare are {self.n_node} nodes.") def initialize_three_mat(self): self.adjacency_mat = np.zeros((self.n_node, self.n_node)) self.degree_mat = np.zeros((self.n_node, self.n_node)) self.laplacian_mat = np.zeros((self.n_node, self.n_node)) print('Initialize adjacency, degree and Laplacian matrices... Done.') def build_degree_from_adjacency(self): for idx in range(self.n_node): self.degree_mat[idx, idx] = self.adjacency_mat[idx, :].sum() def build_laplacian_by_adjacency_degree(self): self.laplacian_mat = self.degree_mat + self.adjacency_mat print("Finish the setup for Laplaican matrix.") def get_networkx_graph(self, df, key='k'): # key: 'k', 'b0' node1_list = df['Atomid_i'].tolist() node2_list = df['Atomid_j'].tolist() weight_list = df[key].tolist() edges_list = [(node1, node2, { 'weight': weight }) for node1, node2, weight in zip(node1_list, node2_list, weight_list) ] G = nx.Graph() G.add_nodes_from(self.get_node_list_by_id()) G.add_edges_from(edges_list) return G def get_node_list_by_id(self): return [self.atomid_map[name] for name in self.node_list] def get_networkx_d_pos(self, radius, dist_bw_base, dist_bw_strand): d_atcg = { 'A': { 'STRAND1': ADE_Base, 'STRAND2': ADE_Right_Base }, 'T': { 'STRAND1': THY_Base, 'STRAND2': THY_Right_Base }, 'C': { 'STRAND1': CYT_Base, 'STRAND2': CYT_Right_Base }, 'G': { 'STRAND1': GUA_Base, 'STRAND2': GUA_Right_Base } } d_strandid_resid = self.get_d_strandid_resid() d_pos = dict() x_move = 0 y_move = 0 for strand_id in ['STRAND1', 'STRAND2']: for resid in range(1, self.n_bp + 1): resname = self.d_seq[strand_id][resid - 1] nucleobase = d_atcg[resname][strand_id](radius) nucleobase.translate_xy(x_move, y_move) for name in d_strandid_resid[strand_id][resid]: atomid = self.atomid_map[name] atomname = self.atomname_map[name] d_pos[atomid] = nucleobase.d_nodes[atomname] if strand_id == 'STRAND1' and (resid != self.n_bp): y_move += dist_bw_base elif (strand_id == 'STRAND1') and (resid == self.n_bp): y_move -= 0 else: y_move -= dist_bw_base x_move -= dist_bw_strand return d_pos def get_d_strandid_resid(self): d_strandid_resid = self.initialize_d_strandid_resid() for name in self.node_list: strandid = self.strandid_map[name] resid = self.resid_map[name] d_strandid_resid[strandid][resid].append(name) return d_strandid_resid def initialize_d_strandid_resid(self): d_strandid_resid = dict() for strand_id in ['STRAND1', 'STRAND2']: d_strandid_resid[strand_id] = dict() for resid in range(1, self.n_bp + 1): d_strandid_resid[strand_id][resid] = list() return d_strandid_resid def get_D_by_atomname_strandid(self, sele_name, sele_strandid): sele_resid_list = list(range(4, 19)) sele_idx_list = list() for idx, name in enumerate(self.node_list): if (self.atomname_map[name] == sele_name) and ( self.strandid_map[name] == sele_strandid) and (self.resid_map[name] in sele_resid_list): sele_idx_list.append(idx) sele_D = np.zeros((self.n_node, self.n_node)) for idx in sele_idx_list: sele_D[idx, idx] = self.degree_mat[idx, idx] return sele_D def get_D_by_atomname_strandid_resname(self, sele_name, sele_strandid, sele_resname): sele_resid_list = self.get_sele_resid_list_by_resname( sele_resname, sele_strandid) sele_idx_list = list() for idx, name in enumerate(self.node_list): if (self.atomname_map[name] == sele_name) and ( self.strandid_map[name] == sele_strandid) and (self.resid_map[name] in sele_resid_list): sele_idx_list.append(idx) sele_D = np.zeros((self.n_node, self.n_node)) for idx in sele_idx_list: sele_D[idx, idx] = self.degree_mat[idx, idx] return sele_D def get_sele_resid_list_by_resname(self, resname, strandid): sele_resid_list = list() central_resids = list(range(4, 19)) #central_resids = list(range(1, 22)) for idx, nt_name in enumerate(self.d_seq[strandid]): resid = idx + 1 if (resid in central_resids) and (nt_name == resname): sele_resid_list.append(resid) return sele_resid_list def get_A_by_atomname1_atomname2(self, atomname_i, atomname_j, sele_strandid): sele_idx_list = list() for resid_i in range(4, 18): resid_j = resid_i + 1 idx_i = self.d_idx[self.map[ self.get_key_by_atomname_resid_strandid( atomname_i, resid_i, sele_strandid)]] idx_j = self.d_idx[self.map[ self.get_key_by_atomname_resid_strandid( atomname_j, resid_j, sele_strandid)]] sele_idx_list.append((idx_i, idx_j)) sele_A = np.zeros((self.n_node, self.n_node)) for idx_i, idx_j in sele_idx_list: sele_A[idx_i, idx_j] = self.adjacency_mat[idx_i, idx_j] i_lower = np.tril_indices(self.n_node, -1) sele_A[i_lower] = sele_A.transpose()[ i_lower] # make the matrix symmetric return sele_A def get_A_by_atomname1_atomname2_by_resnames(self, atomname_i, atomname_j, resname_i, resname_j, sele_strandid): sele_idx_list = list() resid_i_list, resid_j_list = self.get_resid_i_resid_j_list( resname_i, resname_j, sele_strandid) for resid_i, resid_j in zip(resid_i_list, resid_j_list): idx_i = self.d_idx[self.map[ self.get_key_by_atomname_resid_strandid( atomname_i, resid_i, sele_strandid)]] idx_j = self.d_idx[self.map[ self.get_key_by_atomname_resid_strandid( atomname_j, resid_j, sele_strandid)]] sele_idx_list.append((idx_i, idx_j)) sele_A = np.zeros((self.n_node, self.n_node)) for idx_i, idx_j in sele_idx_list: sele_A[idx_i, idx_j] = self.adjacency_mat[idx_i, idx_j] i_lower = np.tril_indices(self.n_node, -1) sele_A[i_lower] = sele_A.transpose()[ i_lower] # make the matrix symmetric return sele_A def get_resid_i_resid_j_list(self, resname_i, resname_j, sele_strandid): seq = self.d_seq[sele_strandid] central_resids = range(4, 19) resid_i_list = list() resid_j_list = list() for resid in central_resids: if (seq[resid - 1] == resname_i) and (seq[resid] == resname_j): resid_i_list.append(resid) resid_j_list.append(resid + 1) return resid_i_list, resid_j_list def get_atomidpairs_atomname1_atomname2(self, atomname_i, atomname_j, sele_strandid): atomidpairs = list() for resid_i in range(4, 18): resid_j = resid_i + 1 idx_i = self.atomid_map[self.map[ self.get_key_by_atomname_resid_strandid( atomname_i, resid_i, sele_strandid)]] idx_j = self.atomid_map[self.map[ self.get_key_by_atomname_resid_strandid( atomname_j, resid_j, sele_strandid)]] atomidpairs.append((idx_i, idx_j)) return atomidpairs def get_key_by_atomname_resid_strandid(self, atomname, resid, strandid): return f'segid {strandid} and resid {resid} and name {atomname}' def get_filter_by_atomname_strandid(self, sele_name, sele_strandid): sele_resid_list = list(range(4, 19)) sele_idx_list = list() for idx, name in enumerate(self.node_list): if (self.atomname_map[name] == sele_name) and ( self.strandid_map[name] == sele_strandid) and (self.resid_map[name] in sele_resid_list): sele_idx_list.append(idx) y = np.zeros(self.n_node) y[sele_idx_list] = 1 return y / np.linalg.norm(y) def get_filter_by_atomname_for_YR(self, sele_name, sele_resname, sele_strandid): sele_resid_list = list(range(4, 19)) sele_idx_list = list() for idx, name in enumerate(self.node_list): resid = self.resid_map[name] if resid not in sele_resid_list: continue strandid = self.strandid_map[name] if strandid != sele_strandid: continue resname = self.d_seq[strandid][resid - 1] if resname != sele_resname: continue if self.atomname_map[name] == sele_name: sele_idx_list.append(idx) y = np.zeros(self.n_node) y[sele_idx_list] = 1 return y / np.linalg.norm(y) def eigen_decompose(self): w, v = np.linalg.eig(self.laplacian_mat) idx = w.argsort()[::-1] # sort from big to small self.w = w[idx] self.v = v[:, idx] def get_eigenvalue_by_id(self, sele_id): return self.w[sele_id - 1] def get_eigenvector_by_id(self, sele_id): return self.v[:, sele_id - 1] def get_qtAq(self, sele_id): eigvector_sele = self.get_eigenvector_by_id(sele_id) return np.dot(eigvector_sele.T, np.dot(self.adjacency_mat, eigvector_sele)) def get_qtDq(self, sele_id): eigvector_sele = self.get_eigenvector_by_id(sele_id) return np.dot(eigvector_sele.T, np.dot(self.degree_mat, eigvector_sele)) def get_qtMq(self, sele_id, M): ### M is customized matrix eigvector_sele = self.get_eigenvector_by_id(sele_id) return np.dot(eigvector_sele.T, np.dot(M, eigvector_sele)) def vmd_show_crd(self): print(f'vmd -cor {self.npt4_crd}') def copy_nohydrogen_crd(self): allsys_root = '/home/yizaochen/codes/dna_rna/all_systems' srt = path.join(allsys_root, self.host, self.type_na, 'input', 'heavyatoms', f'{self.type_na}.nohydrogen.crd') dst = self.npt4_crd copyfile(srt, dst) print(f'cp {srt} {dst}') def decide_eigenvector_strand(self, eigv_id): eigv = self.get_eigenvector_by_id(eigv_id) dot_product = np.dot(eigv, self.strand1_benchmark) if np.isclose(dot_product, 0.): return True #'STRAND2' else: return False #'STRAND1' def set_strand_array(self): for eigv_id in range(1, self.n_node + 1): if self.decide_eigenvector_strand(eigv_id): self.strand2_array.append(eigv_id) else: self.strand1_array.append(eigv_id) print(f'Total number of nodes: {self.n_node}') print( f'There are {len(self.strand1_array)} eigenvectors belonging to STRAND1.' ) print( f'There are {len(self.strand2_array)} eigenvectors belonging to STRAND2.' ) print( f'Sum of two strands: {len(self.strand1_array)+len(self.strand2_array)}' ) def get_lambda_by_strand(self, strandid): if strandid == 'STRAND1': return [ self.get_eigenvalue_by_id(eigv_id) for eigv_id in self.strand1_array ] else: return [ self.get_eigenvalue_by_id(eigv_id) for eigv_id in self.strand2_array ] def get_eigvector_by_strand(self, strandid, sele_id): if strandid == 'STRAND1': real_eigv_id = self.strand1_array[sele_id] else: real_eigv_id = self.strand2_array[sele_id] return self.get_eigenvector_by_id( real_eigv_id), self.get_eigenvalue_by_id(real_eigv_id) def set_adjacency_by_df(self, df_sele): idx_i_list = self.__get_idx_list(df_sele['Atomid_i']) idx_j_list = self.__get_idx_list(df_sele['Atomid_j']) k_list = df_sele['k'].tolist() for idx_i, idx_j, k in zip(idx_i_list, idx_j_list, k_list): self.adjacency_mat[idx_i, idx_j] = k def set_adjacency_by_d(self, d_sele): idx_i_list = self.__get_idx_list(d_sele['Atomid_i']) idx_j_list = self.__get_idx_list(d_sele['Atomid_j']) k_list = d_sele['k'] for idx_i, idx_j, k in zip(idx_i_list, idx_j_list, k_list): self.adjacency_mat[idx_i, idx_j] = k def make_adjacency_symmetry(self): i_lower = np.tril_indices(self.n_node, -1) self.adjacency_mat[i_lower] = self.adjacency_mat.transpose()[ i_lower] # make the matrix symmetric def write_show_nodes_tcl(self, tcl_out, colorid=0, vdw_radius=1.0): serials_str = self.__get_serial_nodes() f = open(tcl_out, 'w') f.write('display resize 362 954\n\n') f.write('mol color ColorID 6\n') f.write('mol representation Lines 3.000\n') f.write('mol selection all\n') f.write('mol material Opaque\n') f.write('mol addrep 0\n') f.write(f'mol color ColorID {colorid}\n') f.write(f'mol representation VDW {vdw_radius:.3f} 12.000\n') f.write(f'mol selection serial {serials_str}\n') f.write('mol material Opaque\n') f.write('mol addrep 0\n') f.write(f'mol color ColorID 7\n') f.write(f'mol representation VDW 0.300 12.000\n') f.write(f'mol selection serial 6 7 8 9\n') f.write('mol material Opaque\n') f.write('mol addrep 0\n') f.close() print(f'Write tcl to {tcl_out}') print(f'source {tcl_out}') def process_lines_for_edges_tcl(self, lines, df_sele, radius=0.05): u_npt4 = MDAnalysis.Universe(self.npt4_crd, self.npt4_crd) for atomid1, atomid2 in zip(df_sele['Atomid_i'], df_sele['Atomid_j']): line = self.__get_draw_edge_line(u_npt4.atoms.positions, atomid1 - 1, atomid2 - 1, radius) lines.append(line) return lines def write_lines_to_tcl_out(self, lines, tcl_out): f = open(tcl_out, 'w') for line in lines: f.write(line) f.close() print(f'Write tcl to {tcl_out}') print(f'source {tcl_out}') def __get_idx_list(self, df_column): cgname_list = [self.atomid_map_inverse[atomid] for atomid in df_column] return [self.d_idx[cgname] for cgname in cgname_list] def __get_serial_nodes(self): serials_list = [ str(self.atomid_map[cgname]) for cgname in self.d_idx.keys() ] return ' '.join(serials_list) def __get_draw_edge_line(self, positions, atomid1, atomid2, radius): str_0 = 'graphics 0 cylinder {' str_1 = f'{positions[atomid1,0]:.3f} {positions[atomid1,1]:.3f} {positions[atomid1,2]:.3f}' str_2 = '} {' str_3 = f'{positions[atomid2,0]:.3f} {positions[atomid2,1]:.3f} {positions[atomid2,2]:.3f}' str_4 = '} ' str_5 = f'radius {radius:.2f}\n' return str_0 + str_1 + str_2 + str_3 + str_4 + str_5 def __build_map(self): d1 = dict() # key: selction, value: cgname d2 = dict() # key: cgname, value: selection d3 = dict() d4 = dict() # key: cgname, value: atomid d5 = dict() # key: atomid, value: cgname d6 = dict() # key: cgname, value: atomname d7 = dict() # key: cgname, value: strand_id d8 = dict() # key: cgname, value: resid d9 = dict() # key: cgname, value: mass atomid = 1 segid1 = self.u.select_atoms("segid STRAND1") d3['STRAND1'] = dict() for i, atom in enumerate(segid1): cgname = 'A{0}'.format(i + 1) selection = self.__get_selection(atom) d1[selection] = cgname d2[cgname] = selection if atom.resid not in d3['STRAND1']: d3['STRAND1'][atom.resid] = list() d3['STRAND1'][atom.resid].append(cgname) d4[cgname] = atomid d5[atomid] = cgname d6[cgname] = atom.name d7[cgname] = 'STRAND1' d8[cgname] = atom.resid d9[cgname] = atom.mass atomid += 1 segid2 = self.u.select_atoms("segid STRAND2") d3['STRAND2'] = dict() for i, atom in enumerate(segid2): cgname = 'B{0}'.format(i + 1) selection = self.__get_selection(atom) d1[selection] = cgname d2[cgname] = selection if atom.resid not in d3['STRAND2']: d3['STRAND2'][atom.resid] = list() d3['STRAND2'][atom.resid].append(cgname) d4[cgname] = atomid d5[atomid] = cgname d6[cgname] = atom.name d7[cgname] = 'STRAND2' d8[cgname] = atom.resid d9[cgname] = atom.mass atomid += 1 return d1, d2, d3, d4, d5, d6, d7, d8, d9 def __get_selection(self, atom): return 'segid {0} and resid {1} and name {2}'.format( atom.segid, atom.resid, atom.name)
class GraphAgent: type_na = 'bdna+bdna' n_bp = 21 cutoff = 4.7 def __init__(self, host, rootfolder): self.host = host self.rootfolder = rootfolder self.host_folder = path.join(rootfolder, host) self.na_folder = path.join(self.host_folder, self.type_na) self.input_folder = path.join(self.na_folder, 'input') self.spring_obj = Spring(self.rootfolder, self.host, self.type_na, self.n_bp) self.df_all_k = self.spring_obj.read_k_b0_pairtype_df_given_cutoff(self.cutoff) self.crd = path.join(self.input_folder, '{0}.nohydrogen.avg.crd'.format(self.type_na)) self.npt4_crd = path.join(self.input_folder, '{0}.nohydrogen.crd'.format(self.type_na)) self.u = MDAnalysis.Universe(self.crd, self.crd) self.map, self.inverse_map, self.residues_map, self.atomid_map,\ self.atomid_map_inverse, self.atomname_map, self.strandid_map,\ self.resid_map, self.mass_map = self.__build_map() self.node_list = None self.d_idx = None self.n_node = None self.adjacency_mat = None self.degree_mat = None self.laplacian_mat = None self.w = None # Eigenvalue array self.v = None # Eigenvector matrix, the i-th column is the i-th eigenvector self.strand1_array = list() # 0: STRAND1, 1: STRAND2 self.strand2_array = list() # self.strand1_benchmark = None self.strand2_benchmark = None def build_node_list(self): node_list = list() d_idx = dict() idx = 0 for cgname, atomname in self.atomname_map.items(): atom_type = pairtype.d_atomcgtype[atomname] if atom_type == 'B': node_list.append(cgname) d_idx[cgname] = idx idx += 1 self.node_list = node_list self.d_idx = d_idx self.n_node = len(self.node_list) print(f"Thare are {self.n_node} nodes.") def initialize_three_mat(self): self.adjacency_mat = np.zeros((self.n_node, self.n_node)) self.degree_mat = np.zeros((self.n_node, self.n_node)) self.laplacian_mat = np.zeros((self.n_node, self.n_node)) print('Initialize adjacency, degree and Laplacian matrices... Done.') def build_degree_from_adjacency(self): for idx in range(self.n_node): self.degree_mat[idx, idx] = self.adjacency_mat[idx, :].sum() def build_laplacian_by_adjacency_degree(self): self.laplacian_mat = self.degree_mat + self.adjacency_mat print("Finish the setup for Laplaican matrix.") def eigen_decompose(self): w, v = np.linalg.eig(self.laplacian_mat) idx = w.argsort()[::-1] # sort from big to small self.w = w[idx] self.v = v[:, idx] def get_eigenvalue_by_id(self, sele_id): return self.w[sele_id-1] def get_eigenvector_by_id(self, sele_id): return self.v[:,sele_id-1] def vmd_show_crd(self): print(f'vmd -cor {self.npt4_crd}') def copy_nohydrogen_crd(self): allsys_root = '/home/yizaochen/codes/dna_rna/all_systems' srt = path.join(allsys_root, self.host, self.type_na, 'input', 'heavyatoms', f'{self.type_na}.nohydrogen.crd') dst = self.npt4_crd copyfile(srt, dst) print(f'cp {srt} {dst}') def decide_eigenvector_strand(self, eigv_id): eigv = self.get_eigenvector_by_id(eigv_id) dot_product = np.dot(eigv, self.strand1_benchmark) if np.isclose(dot_product, 0.): return True #'STRAND2' else: return False #'STRAND1' def set_strand_array(self): for eigv_id in range(1, self.n_node+1): if self.decide_eigenvector_strand(eigv_id): self.strand2_array.append(eigv_id) else: self.strand1_array.append(eigv_id) print(f'Total number of nodes: {self.n_node}') print(f'There are {len(self.strand1_array)} eigenvectors belonging to STRAND1.') print(f'There are {len(self.strand2_array)} eigenvectors belonging to STRAND2.') print(f'Sum of two strands: {len(self.strand1_array)+len(self.strand2_array)}') def get_lambda_by_strand(self, strandid): if strandid == 'STRAND1': return [self.get_eigenvalue_by_id(eigv_id) for eigv_id in self.strand1_array] else: return [self.get_eigenvalue_by_id(eigv_id) for eigv_id in self.strand2_array] def get_eigvector_by_strand(self, strandid, sele_id): if strandid == 'STRAND1': real_eigv_id = self.strand1_array[sele_id] else: real_eigv_id = self.strand2_array[sele_id] return self.get_eigenvector_by_id(real_eigv_id), self.get_eigenvalue_by_id(real_eigv_id) def set_adjacency_by_df(self, df_sele): idx_i_list = self.__get_idx_list(df_sele['Atomid_i']) idx_j_list = self.__get_idx_list(df_sele['Atomid_j']) k_list = df_sele['k'].tolist() for idx_i, idx_j, k in zip(idx_i_list, idx_j_list, k_list): self.adjacency_mat[idx_i, idx_j] = k def set_adjacency_by_d(self, d_sele): idx_i_list = self.__get_idx_list(d_sele['Atomid_i']) idx_j_list = self.__get_idx_list(d_sele['Atomid_j']) k_list = d_sele['k'] for idx_i, idx_j, k in zip(idx_i_list, idx_j_list, k_list): self.adjacency_mat[idx_i, idx_j] = k def make_adjacency_symmetry(self): i_lower = np.tril_indices(self.n_node, -1) self.adjacency_mat[i_lower] = self.adjacency_mat.transpose()[i_lower] # make the matrix symmetric def write_show_nodes_tcl(self, tcl_out, colorid=0, vdw_radius=1.0): serials_str = self.__get_serial_nodes() f = open(tcl_out, 'w') f.write('display resize 362 954\n\n') f.write('mol color ColorID 6\n') f.write('mol representation Lines 3.000\n') f.write('mol selection all\n') f.write('mol material Opaque\n') f.write('mol addrep 0\n') f.write(f'mol color ColorID {colorid}\n') f.write(f'mol representation VDW {vdw_radius:.3f} 12.000\n') f.write(f'mol selection serial {serials_str}\n') f.write('mol material Opaque\n') f.write('mol addrep 0\n') f.write(f'mol color ColorID 7\n') f.write(f'mol representation VDW 0.300 12.000\n') f.write(f'mol selection serial 6 7 8 9\n') f.write('mol material Opaque\n') f.write('mol addrep 0\n') f.close() print(f'Write tcl to {tcl_out}') print(f'source {tcl_out}') def process_lines_for_edges_tcl(self, lines, df_sele, radius=0.05): u_npt4 = MDAnalysis.Universe(self.npt4_crd, self.npt4_crd) for atomid1, atomid2 in zip(df_sele['Atomid_i'], df_sele['Atomid_j']): line = self.__get_draw_edge_line(u_npt4.atoms.positions, atomid1-1, atomid2-1, radius) lines.append(line) return lines def write_lines_to_tcl_out(self, lines, tcl_out): f = open(tcl_out, 'w') for line in lines: f.write(line) f.close() print(f'Write tcl to {tcl_out}') print(f'source {tcl_out}') def __get_idx_list(self, df_column): cgname_list = [self.atomid_map_inverse[atomid] for atomid in df_column] return [self.d_idx[cgname] for cgname in cgname_list] def __get_serial_nodes(self): serials_list = [str(self.atomid_map[cgname]) for cgname in self.d_idx.keys()] return ' '.join(serials_list) def __get_draw_edge_line(self, positions, atomid1, atomid2, radius): str_0 = 'graphics 0 cylinder {' str_1 = f'{positions[atomid1,0]:.3f} {positions[atomid1,1]:.3f} {positions[atomid1,2]:.3f}' str_2 = '} {' str_3 = f'{positions[atomid2,0]:.3f} {positions[atomid2,1]:.3f} {positions[atomid2,2]:.3f}' str_4 = '} ' str_5 = f'radius {radius:.2f}\n' return str_0 + str_1 + str_2 + str_3 + str_4 + str_5 def __build_map(self): d1 = dict() # key: selction, value: cgname d2 = dict() # key: cgname, value: selection d3 = dict() d4 = dict() # key: cgname, value: atomid d5 = dict() # key: atomid, value: cgname d6 = dict() # key: cgname, value: atomname d7 = dict() # key: cgname, value: strand_id d8 = dict() # key: cgname, value: resid d9 = dict() # key: cgname, value: mass atomid = 1 segid1 = self.u.select_atoms("segid STRAND1") d3['STRAND1'] = dict() for i, atom in enumerate(segid1): cgname = 'A{0}'.format(i+1) selection = self.__get_selection(atom) d1[selection] = cgname d2[cgname] = selection if atom.resid not in d3['STRAND1']: d3['STRAND1'][atom.resid] = list() d3['STRAND1'][atom.resid].append(cgname) d4[cgname] = atomid d5[atomid] = cgname d6[cgname] = atom.name d7[cgname] = 'STRAND1' d8[cgname] = atom.resid d9[cgname] = atom.mass atomid += 1 segid2 = self.u.select_atoms("segid STRAND2") d3['STRAND2'] = dict() for i, atom in enumerate(segid2): cgname = 'B{0}'.format(i+1) selection = self.__get_selection(atom) d1[selection] = cgname d2[cgname] = selection if atom.resid not in d3['STRAND2']: d3['STRAND2'][atom.resid] = list() d3['STRAND2'][atom.resid].append(cgname) d4[cgname] = atomid d5[atomid] = cgname d6[cgname] = atom.name d7[cgname] = 'STRAND2' d8[cgname] = atom.resid d9[cgname] = atom.mass atomid += 1 return d1, d2, d3, d4, d5, d6, d7, d8, d9 def __get_selection(self, atom): return 'segid {0} and resid {1} and name {2}'.format(atom.segid, atom.resid, atom.name)