def __init__(self, pdb_hierarchy, nontrans_only=False, out=sys.stdout, quiet=True): validation.__init__(self) self.residue_count = [0, 0] #[OMEGA_GENERAL, OMEGA_PRO] self.omega_count = [[0,0,0], [0,0,0]] #[OMEGA_GENERAL, OMEGA_PRO], then #[OMEGALYZE_TRANS, OMEGALYZE_CIS, OMEGALYZE_TWISTED] from mmtbx.validation import utils from scitbx.array_family import flex self._outlier_i_seqs = flex.size_t() pdb_atoms = pdb_hierarchy.atoms() all_i_seqs = pdb_atoms.extract_i_seq() if all_i_seqs.all_eq(0): pdb_atoms.reset_i_seq() use_segids = utils.use_segids_in_place_of_chainids( hierarchy=pdb_hierarchy) prev_rezes, next_rezes = None, None prev_resid = None cur_resseq = None next_resseq = None for model in pdb_hierarchy.models(): for chain in model.chains(): prev_rezes, next_rezes = None, None prev_resid = None cur_resseq = None next_resseq = None if use_segids: chain_id = utils.get_segid_as_chainid(chain=chain) else: chain_id = chain.id residues = list(chain.residue_groups()) for i, residue_group in enumerate(residues): # The reason I pass lists of atom_groups to get_phi and get_psi is to # deal with the particular issue where some residues have an A alt # conf that needs some atoms from a "" alt conf to get calculated # correctly. See 1jxt.pdb for examples. This way I can search both # the alt conf atoms and the "" atoms if necessary. prev_atom_list, next_atom_list, atom_list = None, None, None if cur_resseq is not None: prev_rezes = rezes prev_resseq = cur_resseq rezes = construct_residues(residues[i]) cur_resseq = residue_group.resseq_as_int() cur_icode = residue_group.icode.strip() if (i > 0): #check for insertion codes if (cur_resseq == residues[i-1].resseq_as_int()) : if (cur_icode == '') and (residues[i-1].icode.strip() == '') : continue elif (cur_resseq != (residues[i-1].resseq_as_int())+1): continue for atom_group in residue_group.atom_groups(): alt_conf = atom_group.altloc if rezes is not None: atom_list = rezes.get(alt_conf) if prev_rezes is not None: prev_atom_list = prev_rezes.get(alt_conf) if (prev_atom_list is None): prev_keys = sorted(prev_rezes.keys()) prev_atom_list = prev_rezes.get(prev_keys[0]) omega=get_omega(prev_atom_list, atom_list) highest_mc_b = get_highest_mc_b(prev_atom_list, atom_list) if omega is not None: resname = atom_group.resname[0:3] coords = get_center(atom_group) if resname == "PRO": res_type = OMEGA_PRO else: res_type = OMEGA_GENERAL self.residue_count[res_type] += 1 omega_type = find_omega_type(omega) is_nontrans = False if omega_type == OMEGALYZE_CIS or omega_type == OMEGALYZE_TWISTED: self.n_outliers += 1 is_nontrans = True self.omega_count[res_type][omega_type] += 1 markup_atoms = [None, None, None, None] #for kinemage markup if is_nontrans: for a in prev_atom_list: if a is None: continue a_ = atom(pdb_atom=a) if a.name.strip() == "CA": markup_atoms[0] = kin_atom( id_str=a_.atom_group_id_str(),xyz=a_.xyz) elif a.name.strip() == "C": markup_atoms[1] = kin_atom( id_str=a_.atom_group_id_str(),xyz=a_.xyz) for a in atom_list: if a is None: continue a_ = atom(pdb_atom=a) if a.name.strip() == "N": markup_atoms[2] = kin_atom( id_str=a_.atom_group_id_str(),xyz=a_.xyz) elif a.name.strip() == "CA": markup_atoms[3] = kin_atom( id_str=a_.atom_group_id_str(),xyz=a_.xyz) #------------ #prevres=residues[i-1] #find prev res identities for printing prev_alts = [] prev_resnames = {} for ag in residues[i-1].atom_groups(): prev_alts.append(ag.altloc) prev_resnames[ag.altloc] = ag.resname if alt_conf in prev_alts: prev_altloc = alt_conf else: if len(prev_alts) > 1: prev_altloc = prev_alts[1] else: prev_altloc = prev_alts[0] prev_resname = prev_resnames[prev_altloc] #done finding prev res identities result = omega_result( chain_id=chain_id, resseq=residue_group.resseq, icode=residue_group.icode, resname=atom_group.resname, altloc=atom_group.altloc, prev_resseq=residues[i-1].resseq, prev_icode=residues[i-1].icode, prev_resname=prev_resname, prev_altloc=prev_altloc, segid=None, omega=omega, omega_type=omega_type, res_type=res_type, is_nontrans=is_nontrans, outlier=is_nontrans, highest_mc_b=highest_mc_b, xyz=coords, markup_atoms=markup_atoms) if is_nontrans or not nontrans_only: #(not nontrans_only or is_nontrans) self.results.append(result) if is_nontrans: i_seqs = atom_group.atoms().extract_i_seq() assert (not i_seqs.all_eq(0)) #This assert copied from ramalyze self._outlier_i_seqs.extend(i_seqs)
def __init__ (self, pdb_hierarchy, outliers_only=False, show_errors=False, out=sys.stdout, quiet=False) : validation.__init__(self) self.n_allowed = 0 self.n_favored = 0 self.n_type = [ 0 ] * 6 from mmtbx.validation import utils import mmtbx.rotamer from mmtbx.rotamer import ramachandran_eval from scitbx.array_family import flex self._outlier_i_seqs = flex.size_t() pdb_atoms = pdb_hierarchy.atoms() all_i_seqs = pdb_atoms.extract_i_seq() if (all_i_seqs.all_eq(0)) : pdb_atoms.reset_i_seq() use_segids = utils.use_segids_in_place_of_chainids( hierarchy=pdb_hierarchy) analysis = "" output_list = [] r = ramachandran_eval.RamachandranEval() prev_rezes, next_rezes = None, None prev_resid = None cur_resseq = None next_resseq = None for model in pdb_hierarchy.models(): for chain in model.chains(): if use_segids: chain_id = utils.get_segid_as_chainid(chain=chain) else: chain_id = chain.id residues = list(chain.residue_groups()) for i, residue_group in enumerate(residues): # The reason I pass lists of atom_groups to get_phi and get_psi is to # deal with the particular issue where some residues have an A alt # conf that needs some atoms from a "" alt conf to get calculated # correctly. See 1jxt.pdb for examples. This way I can search both # the alt conf atoms and the "" atoms if necessary. prev_atom_list, next_atom_list, atom_list = None, None, None if cur_resseq is not None: prev_rezes = rezes prev_resseq = cur_resseq rezes = construct_complete_residues(residues[i]) cur_resseq = residue_group.resseq_as_int() cur_icode = residue_group.icode.strip() if (i > 0): #check for insertion codes if (cur_resseq == residues[i-1].resseq_as_int()) : if (cur_icode == '') and (residues[i-1].icode.strip() == '') : continue elif (cur_resseq != (residues[i-1].resseq_as_int())+1): continue if (i < len(residues)-1): #find next residue if residue_group.resseq_as_int() == \ residues[i+1].resseq_as_int(): if (cur_icode == '') and (residues[i+1].icode.strip() == '') : continue elif residue_group.resseq_as_int() != \ (residues[i+1].resseq_as_int())-1: continue next_rezes = construct_complete_residues(residues[i+1]) next_resid = residues[i+1].resseq_as_int() else: next_rezes = None next_resid = None for atom_group in residue_group.atom_groups(): alt_conf = atom_group.altloc if rezes is not None: atom_list = rezes.get(alt_conf) if prev_rezes is not None: prev_atom_list = prev_rezes.get(alt_conf) if (prev_atom_list is None): prev_keys = sorted(prev_rezes.keys()) prev_atom_list = prev_rezes.get(prev_keys[0]) if next_rezes is not None: next_atom_list = next_rezes.get(alt_conf) if (next_atom_list is None): next_keys = sorted(next_rezes.keys()) next_atom_list = next_rezes.get(next_keys[0]) phi = get_phi(prev_atom_list, atom_list) psi = get_psi(atom_list, next_atom_list) coords = get_center(atom_group) if (phi is not None and psi is not None): res_type = RAMA_GENERAL self.n_total += 1 if (atom_group.resname[0:3] == "GLY"): res_type = RAMA_GLYCINE elif (atom_group.resname[0:3] == "PRO"): is_cis = is_cis_peptide(prev_atom_list, atom_list) if is_cis: res_type = RAMA_CISPRO else: res_type = RAMA_TRANSPRO elif (isPrePro(residues, i)): res_type = RAMA_PREPRO elif (atom_group.resname[0:3] == "ILE" or \ atom_group.resname[0:3] == "VAL"): res_type = RAMA_ILE_VAL self.n_type[res_type] += 1 value = r.evaluate(res_types[res_type], [phi, psi]) ramaType = self.evaluateScore(res_type, value) is_outlier = ramaType == RAMALYZE_OUTLIER c_alphas = None # XXX only save kinemage data for outliers if is_outlier : c_alphas = [] for atoms in [prev_atom_list, atom_list, next_atom_list] : for a in atoms : if (a.name.strip() == "CA") : a_ = atom(pdb_atom=a) c_alphas.append(c_alpha( id_str=a_.atom_group_id_str(), xyz=a_.xyz)) assert (len(c_alphas) == 3) result = ramachandran( chain_id=chain_id, resseq=residue_group.resseq, icode=residue_group.icode, resname=atom_group.resname, altloc=atom_group.altloc, segid=None, # XXX ??? phi=phi, psi=psi, rama_type=ramaType, res_type=res_type, score=value*100, outlier=is_outlier, xyz=coords, c_alphas=c_alphas) if (not outliers_only or is_outlier) : self.results.append(result) if is_outlier : i_seqs = atom_group.atoms().extract_i_seq() assert (not i_seqs.all_eq(0)) self._outlier_i_seqs.extend(i_seqs) out_count, out_percent = self.get_outliers_count_and_fraction() fav_count, fav_percent = self.get_favored_count_and_fraction() self.out_percent = out_percent * 100.0 self.fav_percent = fav_percent * 100.0