def pperp_outliers(hierarchy, chain): kin_out = "@vectorlist {ext} color= magenta master= {base-P perp}\n" rv = rna_validate.rna_puckers(pdb_hierarchy=hierarchy) outliers = rv.results params = rna_sugar_pucker_analysis.master_phil.extract() outlier_key_list = [] for outlier in outliers: outlier_key_list.append(outlier.id_str()) for conformer in chain.conformers(): for residue in conformer.residues(): if common_residue_names_get_class( residue.resname) != "common_rna_dna": continue ra1 = residue_analysis( residue_atoms=residue.atoms(), distance_tolerance=params.bond_detection_distance_tolerance) if (ra1.problems is not None): continue if (not ra1.is_rna): continue try: key = residue.find_atom_by(name=" C1'").pdb_label_columns()[4:] except Exception: continue if key in outlier_key_list: if rv.pucker_perp_xyz[key][0] is not None: perp_xyz = rv.pucker_perp_xyz[key][0] #p_perp_xyz else: perp_xyz = rv.pucker_perp_xyz[key][1] #o3p_perp_xyz if rv.pucker_dist[key][0] is not None: perp_dist = rv.pucker_dist[key][0] if perp_dist < 2.9: pucker_text = " 2'?" else: pucker_text = " 3'?" else: perp_dist = rv.pucker_dist[key][1] if perp_dist < 2.4: pucker_text = " 2'?" else: pucker_text = " 3'?" key = key[0:4].lower() + key[4:] key += pucker_text kin_out += kin_vec(key, perp_xyz[0], key, perp_xyz[1]) a = matrix.col(perp_xyz[1]) b = matrix.col(residue.find_atom_by(name=" C1'").xyz) c = (a - b).normalize() new = a - (c * .8) kin_out += kin_vec(key, perp_xyz[1], key, tuple(new), 4) new = a + (c * .4) kin_out += kin_vec(key, perp_xyz[1], key, tuple(new), 4) r_vec = matrix.col(perp_xyz[1]) - matrix.col(perp_xyz[0]) r = r_vec.axis_and_angle_as_r3_rotation_matrix(angle=90, deg=True) new = r * (new - a) + a kin_out += kin_vec(key, perp_xyz[1], key, tuple(new), 4) r = r_vec.axis_and_angle_as_r3_rotation_matrix(angle=180, deg=True) new = r * (new - a) + a kin_out += kin_vec(key, perp_xyz[1], key, tuple(new), 4) return kin_out
def pperp_outliers(hierarchy, chain): kin_out = "@vectorlist {ext} color= magenta master= {base-P perp}\n" rv = rna_validate.rna_puckers(pdb_hierarchy=hierarchy) outliers = rv.results params = rna_sugar_pucker_analysis.master_phil.extract() outlier_key_list = [] for outlier in outliers: outlier_key_list.append(outlier.id_str()) for conformer in chain.conformers(): for residue in conformer.residues(): if common_residue_names_get_class(residue.resname) != "common_rna_dna": continue ra1 = residue_analysis( residue_atoms=residue.atoms(), distance_tolerance=params.bond_detection_distance_tolerance) if (ra1.problems is not None): continue if (not ra1.is_rna): continue try: key = residue.find_atom_by(name=" C1'").pdb_label_columns()[4:] except Exception: continue if key in outlier_key_list: if rv.pucker_perp_xyz[key][0] is not None: perp_xyz = rv.pucker_perp_xyz[key][0] #p_perp_xyz else: perp_xyz = rv.pucker_perp_xyz[key][1] #o3p_perp_xyz if rv.pucker_dist[key][0] is not None: perp_dist = rv.pucker_dist[key][0] if perp_dist < 2.9: pucker_text = " 2'?" else: pucker_text = " 3'?" else: perp_dist = rv.pucker_dist[key][1] if perp_dist < 2.4: pucker_text = " 2'?" else: pucker_text = " 3'?" key = key[0:4].lower()+key[4:] key += pucker_text kin_out += kin_vec(key, perp_xyz[0], key, perp_xyz[1]) a = matrix.col(perp_xyz[1]) b = matrix.col(residue.find_atom_by(name=" C1'").xyz) c = (a-b).normalize() new = a-(c*.8) kin_out += kin_vec(key, perp_xyz[1], key, tuple(new), 4) new = a+(c*.4) kin_out += kin_vec(key, perp_xyz[1], key, tuple(new), 4) r_vec = matrix.col(perp_xyz[1]) - matrix.col(perp_xyz[0]) r = r_vec.axis_and_angle_as_r3_rotation_matrix(angle=90, deg=True) new = r*(new-a)+a kin_out += kin_vec(key, perp_xyz[1], key, tuple(new), 4) r = r_vec.axis_and_angle_as_r3_rotation_matrix(angle=180, deg=True) new = r*(new-a)+a kin_out += kin_vec(key, perp_xyz[1], key, tuple(new), 4) return kin_out
def bond_outlier_as_kinemage (self) : """ Represent the bond outlier as a kinemage spring. """ from mmtbx.kinemage import kin_vec from scitbx import matrix kin_text = "" bond_key = self.kinemage_key() num_sigmas = - self.delta / self.sigma if (num_sigmas < 0) : color = "blue" else: color = "red" sites = self.sites_cart() a = matrix.col(sites[0]) b = matrix.col(sites[1]) c = matrix.col( (1,0,0) ) normal = ((a-b).cross(c-b).normalize())*0.2 current = a+normal new = tuple(current) kin_text += \ "@vectorlist {%s %.3f sigma} color= %s width= 3 master= {length dev}\n"\ % (bond_key, num_sigmas, color) bond_key_long = "%s %.3f sigma" % (bond_key, num_sigmas) kin_text += kin_vec(bond_key_long,sites[0],bond_key_long,new) angle = 36 dev = num_sigmas if dev > 10.0: dev = 10.0 if dev < -10.0: dev = -10.0 if dev <= 0.0: angle += 1.5*abs(dev) elif dev > 0.0: angle -= 1.5*dev i = 0 n = 60 axis = b-a step = axis*(1.0/n) r = axis.axis_and_angle_as_r3_rotation_matrix(angle=angle, deg=True) while i < n: next = (r*(current-b) +b) next = next + step kin_text += kin_vec(bond_key_long,tuple(current),bond_key_long, tuple(next)) current = next i += 1 kin_text += kin_vec(bond_key_long,tuple(current),bond_key_long,sites[1]) return kin_text
def angle_outlier_as_kinemage(self): """ Represent the angle outlier as a kinemage 'fan'. """ from mmtbx.kinemage import kin_vec from scitbx import matrix kin_text = "" atom0 = self.atoms_info[0] angle_key = self.kinemage_key() num_sigmas = -self.delta / self.sigma angle_key_full = "%s %.3f sigma" % (angle_key, num_sigmas) if (num_sigmas < 0): color = "blue" else: color = "red" sites = self.sites_cart() delta = self.delta a = matrix.col(sites[0]) b = matrix.col(sites[1]) c = matrix.col(sites[2]) normal = (a - b).cross(c - b).normalize() r = normal.axis_and_angle_as_r3_rotation_matrix(angle=delta, deg=True) new_c = tuple((r * (c - b)) + b) kin_text += "@vectorlist {%s} color= %s width= 4 master= {angle dev}\n" \ % (angle_key_full, color) kin_text += kin_vec(angle_key_full, sites[0], angle_key_full, sites[1]) kin_text += kin_vec(angle_key_full, sites[1], angle_key_full, new_c) r = normal.axis_and_angle_as_r3_rotation_matrix(angle=(delta * .75), deg=True) new_c = tuple((r * (c - b)) + b) kin_text += "@vectorlist {%s} color= %s width= 3 master= {angle dev}\n" \ % (angle_key_full, color) kin_text += kin_vec(angle_key_full, sites[1], angle_key, new_c) r = normal.axis_and_angle_as_r3_rotation_matrix(angle=(delta * .5), deg=True) new_c = tuple((r * (c - b)) + b) kin_text += "@vectorlist {%s} color= %s width= 2 master= {angle dev}\n" \ % (angle_key_full, color) kin_text += kin_vec(angle_key_full, sites[1], angle_key, new_c) r = normal.axis_and_angle_as_r3_rotation_matrix(angle=(delta * .25), deg=True) new_c = tuple((r * (c - b)) + b) kin_text += "@vectorlist {%s} color= %s width= 1 master= {angle dev}\n" \ % (angle_key_full, color) kin_text += kin_vec(angle_key_full, sites[1], angle_key, new_c) return kin_text
def angle_outlier_as_kinemage (self) : """ Represent the angle outlier as a kinemage 'fan'. """ from mmtbx.kinemage import kin_vec from scitbx import matrix kin_text = "" atom0 = self.atoms_info[0] angle_key = self.kinemage_key() num_sigmas = - self.delta / self.sigma angle_key_full = "%s %.3f sigma" % (angle_key, num_sigmas) if (num_sigmas < 0) : color = "blue" else: color = "red" sites = self.sites_cart() delta = self.delta a = matrix.col(sites[0]) b = matrix.col(sites[1]) c = matrix.col(sites[2]) normal = (a-b).cross(c-b).normalize() r = normal.axis_and_angle_as_r3_rotation_matrix(angle=delta, deg=True) new_c = tuple( (r*(c-b)) +b) kin_text += "@vectorlist {%s} color= %s width= 4 master= {angle dev}\n" \ % (angle_key_full, color) kin_text += kin_vec(angle_key_full,sites[0],angle_key_full,sites[1]) kin_text += kin_vec(angle_key_full,sites[1],angle_key_full,new_c) r = normal.axis_and_angle_as_r3_rotation_matrix(angle=(delta*.75), deg=True) new_c = tuple( (r*(c-b)) +b) kin_text += "@vectorlist {%s} color= %s width= 3 master= {angle dev}\n" \ % (angle_key_full, color) kin_text += kin_vec(angle_key_full,sites[1],angle_key,new_c) r = normal.axis_and_angle_as_r3_rotation_matrix(angle=(delta*.5), deg=True) new_c = tuple( (r*(c-b)) +b) kin_text += "@vectorlist {%s} color= %s width= 2 master= {angle dev}\n" \ % (angle_key_full, color) kin_text += kin_vec(angle_key_full,sites[1],angle_key,new_c) r = normal.axis_and_angle_as_r3_rotation_matrix(angle=(delta*.25), deg=True) new_c = tuple( (r*(c-b)) +b) kin_text += "@vectorlist {%s} color= %s width= 1 master= {angle dev}\n" \ % (angle_key_full, color) kin_text += kin_vec(angle_key_full,sites[1],angle_key,new_c) return kin_text
def add_spring(sites, num_sigmas, bond_key): kin_text = "" if num_sigmas < 0: color = "blue" else: color = "red" a = matrix.col(sites[0]) b = matrix.col(sites[1]) c = matrix.col((1, 0, 0)) normal = ((a - b).cross(c - b).normalize()) * 0.2 current = a + normal new = tuple(current) kin_text += "@vectorlist {%s %.3f sigma} color= %s width= 3 master= {length dev}\n" \ % (bond_key, num_sigmas, color) bond_key_long = "%s %.3f sigma" % (bond_key, num_sigmas) kin_text += kin_vec(bond_key_long, sites[0], bond_key_long, new) angle = 36 dev = num_sigmas if dev > 10.0: dev = 10.0 if dev < -10.0: dev = -10.0 if dev <= 0.0: angle += 1.5 * abs(dev) elif dev > 0.0: angle -= 1.5 * dev i = 0 n = 60 axis = b - a step = axis * (1.0 / n) r = axis.axis_and_angle_as_r3_rotation_matrix(angle=angle, deg=True) while i < n: next = (r * (current - b) + b) next = next + step kin_text += kin_vec(bond_key_long, tuple(current), bond_key_long, tuple(next)) current = next i += 1 kin_text += kin_vec(bond_key_long, tuple(current), bond_key_long, sites[1]) return kin_text
def add_fan(sites, delta, num_sigmas, angle_key): kin_text = "" angle_key_full = "%s %.3f sigma" % (angle_key, num_sigmas) if num_sigmas < 0: color = "blue" else: color = "red" a = matrix.col(sites[0]) b = matrix.col(sites[1]) c = matrix.col(sites[2]) normal = (a - b).cross(c - b).normalize() r = normal.axis_and_angle_as_r3_rotation_matrix(angle=delta, deg=True) new_c = tuple((r * (c - b)) + b) kin_text += "@vectorlist {%s} color= %s width= 4 master= {angle dev}\n" \ % (angle_key_full, color) kin_text += kin_vec(angle_key_full, sites[0], angle_key_full, sites[1]) kin_text += kin_vec(angle_key_full, sites[1], angle_key_full, new_c) r = normal.axis_and_angle_as_r3_rotation_matrix(angle=(delta * .75), deg=True) new_c = tuple((r * (c - b)) + b) kin_text += "@vectorlist {%s} color= %s width= 3 master= {angle dev}\n" \ % (angle_key_full, color) kin_text += kin_vec(angle_key_full, sites[1], angle_key, new_c) r = normal.axis_and_angle_as_r3_rotation_matrix(angle=(delta * .5), deg=True) new_c = tuple((r * (c - b)) + b) kin_text += "@vectorlist {%s} color= %s width= 2 master= {angle dev}\n" \ % (angle_key_full, color) kin_text += kin_vec(angle_key_full, sites[1], angle_key, new_c) r = normal.axis_and_angle_as_r3_rotation_matrix(angle=(delta * .25), deg=True) new_c = tuple((r * (c - b)) + b) kin_text += "@vectorlist {%s} color= %s width= 1 master= {angle dev}\n" \ % (angle_key_full, color) kin_text += kin_vec(angle_key_full, sites[1], angle_key, new_c) return kin_text
def add_spring(sites, num_sigmas, bond_key): kin_text = "" if num_sigmas < 0: color = "blue" else: color = "red" a = matrix.col(sites[0]) b = matrix.col(sites[1]) c = matrix.col( (1,0,0) ) normal = ((a-b).cross(c-b).normalize())*0.2 current = a+normal new = tuple(current) kin_text += "@vectorlist {%s %.3f sigma} color= %s width= 3 master= {length dev}\n" \ % (bond_key, num_sigmas, color) bond_key_long = "%s %.3f sigma" % (bond_key, num_sigmas) kin_text += kin_vec(bond_key_long,sites[0],bond_key_long,new) angle = 36 dev = num_sigmas if dev > 10.0: dev = 10.0 if dev < -10.0: dev = -10.0 if dev <= 0.0: angle += 1.5*abs(dev) elif dev > 0.0: angle -= 1.5*dev i = 0 n = 60 axis = b-a step = axis*(1.0/n) r = axis.axis_and_angle_as_r3_rotation_matrix(angle=angle, deg=True) while i < n: next = (r*(current-b) +b) next = next + step kin_text += kin_vec(bond_key_long,tuple(current),bond_key_long,tuple(next)) current = next i += 1 kin_text += kin_vec(bond_key_long,tuple(current),bond_key_long,sites[1]) return kin_text
def add_fan(sites, delta, num_sigmas, angle_key): kin_text = "" angle_key_full = "%s %.3f sigma" % (angle_key, num_sigmas) if num_sigmas < 0: color = "blue" else: color = "red" a = matrix.col(sites[0]) b = matrix.col(sites[1]) c = matrix.col(sites[2]) normal = (a-b).cross(c-b).normalize() r = normal.axis_and_angle_as_r3_rotation_matrix(angle=delta, deg=True) new_c = tuple( (r*(c-b)) +b) kin_text += "@vectorlist {%s} color= %s width= 4 master= {angle dev}\n" \ % (angle_key_full, color) kin_text += kin_vec(angle_key_full,sites[0],angle_key_full,sites[1]) kin_text += kin_vec(angle_key_full,sites[1],angle_key_full,new_c) r = normal.axis_and_angle_as_r3_rotation_matrix(angle=(delta*.75), deg=True) new_c = tuple( (r*(c-b)) +b) kin_text += "@vectorlist {%s} color= %s width= 3 master= {angle dev}\n" \ % (angle_key_full, color) kin_text += kin_vec(angle_key_full,sites[1],angle_key,new_c) r = normal.axis_and_angle_as_r3_rotation_matrix(angle=(delta*.5), deg=True) new_c = tuple( (r*(c-b)) +b) kin_text += "@vectorlist {%s} color= %s width= 2 master= {angle dev}\n" \ % (angle_key_full, color) kin_text += kin_vec(angle_key_full,sites[1],angle_key,new_c) r = normal.axis_and_angle_as_r3_rotation_matrix(angle=(delta*.25), deg=True) new_c = tuple( (r*(c-b)) +b) kin_text += "@vectorlist {%s} color= %s width= 1 master= {angle dev}\n" \ % (angle_key_full, color) kin_text += kin_vec(angle_key_full,sites[1],angle_key,new_c) return kin_text
def rotamer_outliers(chain, pdbID, rot_outliers): mc_atoms = ["N", "C", "O", "OXT"] rot_out = "@subgroup {Rota outliers} dominant\n" rot_out += "@vectorlist {chain %s} color= gold master= {Rota outliers}\n" % chain.id outlier_list = [] for outlier in rot_outliers.results : if (not outlier.is_outlier()) : continue outlier_list.append(outlier.atom_group_id_str()) for residue_group in chain.residue_groups(): for atom_group in residue_group.atom_groups() : check_key = atom_group.id_str() if (check_key in outlier_list) : key_hash = {} xyz_hash = {} for atom in atom_group.atoms(): key = "%s %s %s%s B%.2f %s" % ( atom.name.lower(), atom_group.resname.lower(), chain.id, residue_group.resid(), atom.b, pdbID) key_hash[atom.name.strip()] = key xyz_hash[atom.name.strip()] = atom.xyz bonds = get_bond_pairs(code=atom_group.resname) for bond in bonds: if bond[0] in mc_atoms or bond[1] in mc_atoms: continue elif bond[0].startswith('H') or bond[1].startswith('H'): continue if (key_hash.get(bond[0]) == None or key_hash.get(bond[1]) == None or xyz_hash.get(bond[0]) == None or xyz_hash.get(bond[1]) == None): continue rot_out += kin_vec(key_hash[bond[0]], xyz_hash[bond[0]], key_hash[bond[1]], xyz_hash[bond[1]]) if len(rot_out.splitlines()) == 2: rot_out = "" return rot_out
def get_kin_lots(chain, bond_hash, i_seq_name_hash, pdbID=None, index=0, show_hydrogen=True): mc_atoms = ["N", "CA", "C", "O", "OXT", "P", "OP1", "OP2", "OP3", "O5'", "C5'", "C4'", "O4'", "C1'", "C3'", "O3'", "C2'", "O2'"] mc_veclist = "" sc_veclist = "" mc_h_veclist = "" sc_h_veclist = "" ca_trace = "" virtual_bb = "" water_list = "" ion_list = "" kin_out = "" color = get_chain_color(index) mc_veclist = "@vectorlist {mc} color= %s master= {mainchain}\n" % color sc_veclist = "@vectorlist {sc} color= cyan master= {sidechain}\n" ca_trace = "@vectorlist {Calphas} color= %s master= {Calphas}\n" % color virtual_bb = "@vectorlist {Virtual BB} color= %s off master= {Virtual BB}\n" % color water_list = "@balllist {water O} color= peachtint radius= 0.15 master= {water}\n" hets = "@vectorlist {het} color= pink master= {hets}\n" het_h = "@vectorlist {ht H} color= gray nobutton master= {hets} master= {H's}\n" if show_hydrogen: mc_h_veclist = \ "@vectorlist {mc H} color= gray nobutton master= {mainchain} master= {H's}\n" sc_h_veclist = \ "@vectorlist {sc H} color= gray nobutton master= {sidechain} master= {H's}\n" prev_resid = None cur_resid = None prev_C_xyz = {} prev_C_key = {} prev_CA_xyz = {} prev_CA_key = {} prev_O3_xyz = {} prev_O3_key = {} p_hash_key = {} p_hash_xyz = {} c1_hash_key = {} c1_hash_xyz = {} c4_hash_key = {} c4_hash_xyz = {} drawn_bonds = [] for residue_group in chain.residue_groups(): altloc_hash = {} iseq_altloc = {} cur_C_xyz = {} cur_C_key = {} cur_CA_xyz = {} cur_CA_key = {} cur_O3_xyz = {} cur_O3_key = {} for atom_group in residue_group.atom_groups(): altloc = atom_group.altloc for atom in atom_group.atoms(): if altloc_hash.get(atom.name.strip()) is None: altloc_hash[atom.name.strip()] = [] altloc_hash[atom.name.strip()].append(altloc) iseq_altloc[atom.i_seq] = altloc cur_resid = residue_group.resid() for conformer in residue_group.conformers(): for residue in conformer.residues(): cur_resid = residue.resid() key_hash = {} xyz_hash = {} het_hash = {} altloc = conformer.altloc if altloc == '': altloc = ' ' for atom in residue.atoms(): cur_altlocs = altloc_hash.get(atom.name.strip()) if cur_altlocs == ['']: cur_altloc = ' ' elif altloc in cur_altlocs: cur_altloc = altloc else: # TO_DO: handle branching from altlocs cur_altloc == ' ' key = "%s%s%s %s%s B%.2f %s" % ( atom.name.lower(), cur_altloc.lower(), residue.resname.lower(), chain.id, residue_group.resid(), atom.b, pdbID) key_hash[atom.name.strip()] = key xyz_hash[atom.name.strip()] = atom.xyz if(common_residue_names_get_class(residue.resname) == "common_amino_acid"): if atom.name == ' C ': cur_C_xyz[altloc] = atom.xyz cur_C_key[altloc] = key if atom.name == ' CA ': cur_CA_xyz[altloc] = atom.xyz cur_CA_key[altloc] = key if len(prev_CA_key) > 0 and len(prev_CA_xyz) > 0: if int(residue_group.resseq_as_int()) - int(prev_resid[0:4]) == 1: try: prev_key = prev_CA_key.get(altloc) prev_xyz = prev_CA_xyz.get(altloc) if prev_key is None: prev_key = prev_CA_key.get(' ') prev_xyz = prev_CA_xyz.get(' ') if prev_key is None: continue ca_trace += kin_vec(prev_key, prev_xyz, key, atom.xyz) except Exception: pass if atom.name == ' N ': if len(prev_C_key) > 0 and len(prev_C_xyz) > 0: if int(residue_group.resseq_as_int()) - int(prev_resid[0:4]) == 1: try: prev_key = prev_C_key.get(altloc) prev_xyz = prev_C_xyz.get(altloc) if prev_key is None: prev_key = prev_C_key.get(' ') prev_xyz = prev_C_xyz.get(' ') if prev_key is None: continue mc_veclist += kin_vec(prev_key, prev_xyz, key, atom.xyz) except Exception: pass elif(common_residue_names_get_class(residue.resname) == "common_rna_dna"): if atom.name == " O3'": cur_O3_xyz[altloc] = atom.xyz cur_O3_key[altloc] = key elif atom.name == ' P ': if len(prev_O3_key) > 0 and len(prev_O3_xyz) > 0: if int(residue_group.resseq_as_int()) - int(prev_resid[0:4]) == 1: try: prev_key = prev_O3_key.get(altloc) prev_xyz = prev_O3_xyz.get(altloc) if prev_key is None: prev_key = prev_O3_key.get(' ') prev_xyz = prev_O3_xyz.get(' ') if prev_key is None: continue mc_veclist += kin_vec(prev_key, prev_xyz, key, atom.xyz) except Exception: pass p_hash_key[residue_group.resseq_as_int()] = key p_hash_xyz[residue_group.resseq_as_int()] = atom.xyz elif atom.name == " C1'": c1_hash_key[residue_group.resseq_as_int()] = key c1_hash_xyz[residue_group.resseq_as_int()] = atom.xyz elif atom.name == " C4'": c4_hash_key[residue_group.resseq_as_int()] = key c4_hash_xyz[residue_group.resseq_as_int()] = atom.xyz elif(common_residue_names_get_class(residue.resname) == "common_element"): ion_list += "{%s} %.3f %.3f %.3f\n" % ( key, atom.xyz[0], atom.xyz[1], atom.xyz[2]) elif( (common_residue_names_get_class(residue.resname) == "other") and (len(residue.atoms())==1) ): ion_list += "{%s} %.3f %.3f %.3f\n" % ( key, atom.xyz[0], atom.xyz[1], atom.xyz[2]) elif residue.resname.lower() == 'hoh': if atom.name == ' O ': water_list += "{%s} P %.3f %.3f %.3f\n" % ( key, atom.xyz[0], atom.xyz[1], atom.xyz[2]) else: het_hash[atom.name.strip()] = [key, atom.xyz] if(common_residue_names_get_class(residue.resname) == "common_rna_dna"): try: virtual_bb += kin_vec(c4_hash_key[residue_group.resseq_as_int()-1], c4_hash_xyz[residue_group.resseq_as_int()-1], p_hash_key[residue_group.resseq_as_int()], p_hash_xyz[residue_group.resseq_as_int()]) except Exception: pass try: virtual_bb += kin_vec(p_hash_key[residue_group.resseq_as_int()], p_hash_xyz[residue_group.resseq_as_int()], c4_hash_key[residue_group.resseq_as_int()], c4_hash_xyz[residue_group.resseq_as_int()]) except Exception: pass try: virtual_bb += kin_vec(c4_hash_key[residue_group.resseq_as_int()], c4_hash_xyz[residue_group.resseq_as_int()], c1_hash_key[residue_group.resseq_as_int()], c1_hash_xyz[residue_group.resseq_as_int()]) except Exception: pass cur_i_seqs = [] for atom in residue.atoms(): cur_i_seqs.append(atom.i_seq) for atom in residue.atoms(): try: cur_bonds = bond_hash[atom.i_seq] except Exception: continue for bond in cur_bonds: atom_1 = i_seq_name_hash.get(atom.i_seq) if atom_1 is not None: atom_1 = atom_1[0:4].strip() atom_2 = i_seq_name_hash.get(bond) if atom_2 is not None: atom_2 = atom_2[0:4].strip() if atom_1 is None or atom_2 is None: continue # handle altlocs ######## if (key_hash.get(atom_1) == None) or \ (key_hash.get(atom_2) == None): continue drawn_key = key_hash[atom_1]+key_hash[atom_2] if drawn_key in drawn_bonds: continue altloc_2 = iseq_altloc.get(bond) if altloc_2 != altloc and altloc_2 != '': continue ######################### if (common_residue_names_get_class(residue.resname) == 'other' or \ common_residue_names_get_class(residue.resname) == 'common_small_molecule'): if atom_1.startswith('H') or atom_2.startswith('H') or \ atom_1.startswith('D') or atom_2.startswith('D'): if show_hydrogen: try: het_h += kin_vec(het_hash[atom_1][0], het_hash[atom_1][1], het_hash[atom_2][0], het_hash[atom_2][1]) except Exception: pass else: try: hets += kin_vec(het_hash[atom_1][0], het_hash[atom_1][1], het_hash[atom_2][0], het_hash[atom_2][1]) except Exception: pass elif common_residue_names_get_class(residue.resname) == "common_amino_acid" or \ common_residue_names_get_class(residue.resname) == "common_rna_dna": if atom_1 in mc_atoms and atom_2 in mc_atoms: try: if atom_1 == "C" and atom_2 == "N": pass elif atom_1 == "O3'" and atom_2 == "P": pass else: mc_veclist += kin_vec(key_hash[atom_1], xyz_hash[atom_1], key_hash[atom_2], xyz_hash[atom_2]) except Exception: pass elif atom_1.startswith('H') or atom_2.startswith('H') or \ atom_1.startswith('D') or atom_2.startswith('D'): if show_hydrogen: if (atom_1 in mc_atoms or atom_2 in mc_atoms): try: mc_h_veclist += kin_vec(key_hash[atom_1], xyz_hash[atom_1], key_hash[atom_2], xyz_hash[atom_2]) except Exception: pass else: try: sc_h_veclist += kin_vec(key_hash[atom_1], xyz_hash[atom_1], key_hash[atom_2], xyz_hash[atom_2]) except Exception: pass else: try: sc_veclist += kin_vec(key_hash[atom_1], xyz_hash[atom_1], key_hash[atom_2], xyz_hash[atom_2]) except Exception: pass drawn_bonds.append(drawn_key) prev_CA_xyz = cur_CA_xyz prev_CA_key = cur_CA_key prev_C_xyz = cur_C_xyz prev_C_key = cur_C_key prev_resid = cur_resid prev_O3_key = cur_O3_key prev_O3_xyz = cur_O3_xyz ion_kin = None if len(ion_list) > 1: ion_kin = get_ions(ion_list) #clean up empty lists: if len(mc_veclist.splitlines()) > 1: kin_out += mc_veclist if len(mc_h_veclist.splitlines()) > 1: kin_out += mc_h_veclist if len(ca_trace.splitlines()) > 1: kin_out += ca_trace if len(sc_veclist.splitlines()) > 1: kin_out += sc_veclist if len(sc_h_veclist.splitlines()) > 1: kin_out += sc_h_veclist if len(water_list.splitlines()) > 1: kin_out += water_list if len(virtual_bb.splitlines()) > 1: kin_out += virtual_bb if len(hets.splitlines()) > 1: kin_out += hets if ion_kin is not None: kin_out += ion_kin if len(het_h.splitlines()) > 1: kin_out += het_h return kin_out
def chiral_outlier_as_kinemage(self): """ Represent a chiral volume outlier in kinemage """ from mmtbx.kinemage import kin_vec outlier_type = self.outlier_type() atoms = self.atoms_info chiral_center = atoms[0] chiral_coords = matrix.rec((chiral_center.xyz[0], chiral_center.xyz[1], chiral_center.xyz[2]),(3,1)) legs = [None] #None fills the 0 index, this indexes the same as atoms_info for atom in atoms[1:]: legs.append(matrix.rec((atom.xyz[0], atom.xyz[1], atom.xyz[2]),(3,1))) #legs need to be shortened for visual/selection clarity leg_vs = [None] for leg in legs[1:]: leg_vs.append(leg - chiral_coords) leg_ends = [None,0,0,0] shorten_by = 0.3 leg_ends[1] = legs[1] - leg_vs[1].normalize()*shorten_by leg_ends[2] = legs[2] - leg_vs[2].normalize()*shorten_by leg_ends[3] = legs[3] - leg_vs[3].normalize()*shorten_by kin_text = "" #tetrahedron is drawn for all markups kin_text += "@vectorlist {%s %s} color= yellow width= 4\n" %(chiral_center.id_str(), "lines") #draw legs from chiral center kin_text += "{%s %s: %.3f sigma} P %.3f %.3f %.3f\n" % (chiral_center.id_str(),outlier_type,self.score,chiral_coords[0],chiral_coords[1],chiral_coords[2]) kin_text += "{%s %s: %.3f sigma} %.3f %.3f %.3f\n" % (atoms[1].id_str(),outlier_type,self.score,leg_ends[1][0],leg_ends[1][1],leg_ends[1][2]) kin_text += "{%s %s: %.3f sigma} %.3f %.3f %.3f\n" % (atoms[2].id_str(),outlier_type,self.score,leg_ends[2][0],leg_ends[2][1],leg_ends[2][2]) kin_text += "{%s %s: %.3f sigma} %.3f %.3f %.3f\n" % (atoms[3].id_str(),outlier_type,self.score,leg_ends[3][0],leg_ends[3][1],leg_ends[3][2]) kin_text += "{%s %s: %.3f sigma} %.3f %.3f %.3f\n" % (atoms[1].id_str(),outlier_type,self.score,leg_ends[1][0],leg_ends[1][1],leg_ends[1][2]) kin_text += "{%s %s: %.3f sigma} P %.3f %.3f %.3f\n" % (atoms[2].id_str(),outlier_type,self.score,leg_ends[2][0],leg_ends[2][1],leg_ends[2][2]) kin_text += "{%s %s: %.3f sigma} %.3f %.3f %.3f\n" % (chiral_center.id_str(),outlier_type,self.score,chiral_coords[0],chiral_coords[1],chiral_coords[2]) kin_text += "{%s %s: %.3f sigma} %.3f %.3f %.3f\n" % (atoms[3].id_str(),outlier_type,self.score,leg_ends[3][0],leg_ends[3][1],leg_ends[3][2]) if outlier_type == "Chiral handedness swap": #Also add an arrow to suggest mirror operation #create normal to plane of 3 legs, scale to suitable length #m = rec((1, 2, 3, 4), (2, 2)) v1 = matrix.rec((atoms[1].xyz[0]-atoms[2].xyz[0], atoms[1].xyz[1]-atoms[2].xyz[1], atoms[1].xyz[2]-atoms[2].xyz[2]), (3,1)) v2 = matrix.rec((atoms[1].xyz[0]-atoms[3].xyz[0], atoms[1].xyz[1]-atoms[3].xyz[1], atoms[1].xyz[2]-atoms[3].xyz[2]), (3,1)) norm = v1.cross(v2) norm = norm.normalize() p = matrix.rec((chiral_center.xyz[0]+norm[0], chiral_center.xyz[1]+norm[1], chiral_center.xyz[2]+norm[2]),(3,1)) arrow_text = "%s %s: %.3f sigma" % (chiral_center.id_str(), outlier_type, self.score) kin_text += kin_vec(chiral_center.id_str(), chiral_center.xyz, arrow_text, p) #Add arrowhead #Move back lone that some line and out along the atoms[1]-atoms[2] line arrow_width = 0.125 * v1.normalize() arrow_end_1 = p - 0.125*norm + arrow_width arrow_end_2 = p - 0.125*norm - arrow_width #draw second arrow rotated 90 degrees, so arrowheaad is visible from more orientations arrow_end_3 = matrix.rotate_point_around_axis( axis_point_1 = chiral_coords, axis_point_2 = p, point = arrow_end_1, angle = 90, deg = True) arrow_end_4 = matrix.rotate_point_around_axis( axis_point_1 = chiral_coords, axis_point_2 = p, point = arrow_end_2, angle = 90, deg = True) kin_text += kin_vec(arrow_text, p, outlier_type, arrow_end_1) kin_text += kin_vec(arrow_text, p, outlier_type, arrow_end_2) kin_text += kin_vec(arrow_text, p, outlier_type, arrow_end_3) kin_text += kin_vec(arrow_text, p, outlier_type, arrow_end_4) #draw balls onto atoms of greatest interest kin_text += "@balllist {%s %s} color= yellow radius= 0.15\n" %(chiral_center.id_str(), "balls") if outlier_type != 'Pseudochiral naming error': #"Chiral handedness swap" or "Tetrahedral geometry outlier" #error is located at chiral center, draw ball at chiral center of interest kin_text += "{%s %s: %.3f sigma} %.3f %.3f %.3f\n" % (chiral_center.id_str(),outlier_type,self.score,atoms[0].xyz[0],atoms[0].xyz[1],atoms[0].xyz[2]) else: #Pseudochiral naming error #error is probably in naming of the non-center atoms #draw balls on legs, add atomnames as labels to draw attention to naming i = 1 while i <= 3: kin_text += "{%s %s: %.3f sigma} %.3f %.3f %.3f\n" % (atoms[i].id_str(),outlier_type,self.score,leg_ends[i][0],leg_ends[i][1],leg_ends[i][2]) i+=1 kin_text += "@labellist {%s %s} color= white\n" % (chiral_center.id_str(), "labels") #needs to be a different color than balls for readability during overlap #atomnames go on atoms rather than balls to reduce overlap and increase clarity kin_text += "{ %s} %.3f %.3f %.3f\n" % (chiral_center.name.strip(),chiral_center.xyz[0],chiral_center.xyz[1],chiral_center.xyz[2]) i = 1 while i <= 3: kin_text += "{ %s} %.3f %.3f %.3f\n" % (atoms[i].name.strip(),atoms[i].xyz[0],atoms[i].xyz[1],atoms[i].xyz[2]) #leading spaces reduce overlap with the ball already drawn on labeled atom i+=1 return kin_text