def SC_mapping(prop_vec,nres,nsymop,resid): from cctbx_sgtbx_ext import rt_mx xnres=prop_vec[2]*prop_vec[1]*nres*nsymop ynres=prop_vec[2]*nres*nsymop znres=nres*nsymop (xmoves,resid)=divmod(resid-1,xnres) (ymoves,resid)=divmod(resid,ynres) (zmoves,resid)=divmod(resid,znres) (sym_op,resid)=divmod(resid, nres) tr_op=rt_mx('x+%d,y+%d,z+%d' %(xmoves,ymoves,zmoves)) return tr_op, sym_op, resid+1
def get_symm(sg): from cctbx_sgtbx_ext import rt_mx if sg == 'P212121': rot0 = rt_mx("x,y,z") rot1 = rt_mx("-x+1/2,-y,z+1/2") rot2 = rt_mx("-x,y+1/2,-z+1/2") rot3 = rt_mx("x+1/2,-y+1/2,-z") rt_mx_matrices = (rot0, rot1, rot2, rot3) elif sg == 'P1211': rot0 = rt_mx("x,y,z") rot1 = rt_mx("-x,y+1/2,-z") rt_mx_matrices = (rot0, rot1) elif sg == 'P121': rot0 = rt_mx("x,y,z") rot1 = rt_mx("-x,y,-z") rt_mx_matrices = (rot0, rot1) elif sg == 'P222': rot0 = rt_mx("x,y,z") rot1 = rt_mx("-x,-y,z") rot2 = rt_mx("-x,y,-z") rot3 = rt_mx("x,-y,-z") rt_mx_matrices = (rot0, rot1, rot2, rot3) elif sg == 'C121': rot0 = rt_mx("x,y,z") rot1 = rt_mx("-x,y,-z") rot2 = rt_mx("x+1/2,y+1/2,z") rot3 = rt_mx("-x+1/2,y+1/2,-z") rt_mx_matrices = (rot0, rot1, rot2, rot3) else: print "%s not found\n" % sg sys.exit() return rt_mx_matrices
def get_symm(sg): from cctbx_sgtbx_ext import rt_mx if sg == 'P212121': rot0=rt_mx("x,y,z") rot1=rt_mx("-x+1/2,-y,z+1/2") rot2=rt_mx("-x,y+1/2,-z+1/2") rot3=rt_mx("x+1/2,-y+1/2,-z") rt_mx_matrices=(rot0,rot1,rot2,rot3) elif sg == 'P1211': rot0=rt_mx("x,y,z") rot1=rt_mx("-x,y+1/2,-z") rt_mx_matrices=(rot0,rot1) elif sg == 'P121': rot0=rt_mx("x,y,z") rot1=rt_mx("-x,y,-z") rt_mx_matrices=(rot0,rot1) elif sg == 'P222': rot0=rt_mx("x,y,z") rot1=rt_mx("-x,-y,z") rot2=rt_mx("-x,y,-z") rot3=rt_mx("x,-y,-z") rt_mx_matrices=(rot0,rot1,rot2,rot3) else: print "%s not found\n" %sg sys.exit() return rt_mx_matrices
def find_supercell_contacts_by_residue(residue_contacts, atoms, prop_vec, nres, nsymop, rt_mx_matrices, ignore_waters=True): supercell_contacts={} #skip all solvent ions added that does not belong to any asymmetric unit #by calculating maxresidue and skipping residues above that maxres=nres*prop_vec[0]*prop_vec[1]*prop_vec[2]*nsymop #loop over each residue in residue_contacts for (residue,contacts) in residue_contacts: i_resid=int(residue[2]) i_resname=residue[1] if (ignore_waters and i_resname in ["HOH","WAT"]): continue if i_resid >= maxres: continue # residue_contacts may have multiple entries between two residues due to # different atoms of the same residues. Duplicate_test{} is used # to filter this so that only one contact between each pair of residues # is returned with the shortest atom to atom distance reported. # sc_sym_op is the translation that relates the original supercell to # the supercell where residue_j resides when the contact occurs (remember # that the supercell is being treated as a P1 'unit cell' duplicate_test={} for contact in contacts: sc_sym_op=contact[1] j_seq=contact[0] j_resid = int(atoms[j_seq].fetch_labels().resid()) j_resname = atoms[j_seq].fetch_labels().resname dist=contact[2] if j_resid > maxres: continue # unit_mx sc_sym_op means the contact is in the original supercell # if same asu in same supercell, it's an "intra_asu" contact so # ignore if is_same_asu(nres,i_resid,j_resid): if sc_sym_op.is_unit_mx() : continue if (ignore_waters and j_resname in ["HOH","WAT"]): continue # populate duplicate_test{} with only one instance of a given # residue pair, keeping the shortest distance value if (j_resid, j_resname,sc_sym_op) in duplicate_test.keys(): if dist < duplicate_test[(j_resid,j_resname,sc_sym_op)]: duplicate_test[(j_resid,j_resname,sc_sym_op)]=dist else: duplicate_test[(j_resid,j_resname,sc_sym_op)]=dist # for contact residue pair, get residue's number in original asu, # symop number to arrive at the residue's asu (this is the ordinal number # of the symop from the rt_mx_matrices object (SYMM cards in PDB file) # applied to the resiude in the original ASU to bring it to it's current # ASU), and the translation operation to bring it to its current unit cell for (j_resid, j_resname,sc_sym_op) in duplicate_test.keys(): dist=duplicate_test[(j_resid, j_resname,sc_sym_op)] i_transop, symop1, i_asymresid = SC_mapping(prop_vec, nres, nsymop,i_resid) j_transop, symop2, j_asymresid = SC_mapping(prop_vec, nres, nsymop,j_resid) # both residues within the original supercell, so get the translation # that relates j's unit_cell to i's unit_cell if sc_sym_op.is_unit_mx() : ij_transop=j_transop.multiply(i_transop.inverse()) #res_j outside the original supercell else: # get the translation operation of the supercell where the contact # residue would reside relative to the original supercell t=sc_sym_op.t().as_double() # augment by the translations inherent in the supercell itself t=[t[0]*prop_vec[0],t[1]*prop_vec[1],t[2]*prop_vec[2]] # convert back to rt_mx t=[int(i) for i in t] from cctbx_sgtbx_ext import rt_mx,tr_vec # t is the translation vector to go from an asu in the original # supercell to an asu in the supercell where the # contact would occur # j_transop is the translation from the original unit cell to the # unit cell in the supercell where resid_j is located # to get the translation necessary to go from resid_i unit cell to # resid_j supercell we do: # # t+j_transop - i_transop # t=rt_mx(tr_vec(t,tr_den=1)) j_transop=j_transop.multiply(t) ij_transop=j_transop.multiply(i_transop.inverse()) ####THIS SHOULD WORK BUT DOESNT ## get the symmetry operation that relates the asu of resid_j to ## the asu of resid_i: ## ## Rij*Ri=Rj ## Rij=Rj*Ri^-1 ## #i_r=rt_mx_matrices[symop1] #j_r=rt_mx_matrices[symop2] #ij_r=j_r.multiply(i_r.inverse()) ## now add the translation that relates unit cell of resiude_j to ## unit cell of residue_i: ## ## sym_op=Rij+transop ## #sym_op=ij_transop.multiply(ij_r) ## this symop is relative to the asu of residue_i. Apply the inverse ## of the symmetry operation that creates residue_i's asu to obtain ## the symop relative to the original asu. #transop=i_r.inverse().multiply(sym_op) ####THIS SHOULD WORK BUT DOESNT ###THIS WORKS ON MANY SPACEGROUPS BUT NOT P212121 # The transop translation is relative to the asu of resid_i. Rotate # it by the inverse of the rotation part of the rot/trans matrix # used to create the asu of resid_i to obtain the translation relative # to the original asu. rot=rt_mx_matrices[symop1] transop=rot.inverse().r().multiply(ij_transop.t()) transop=rt_mx(transop) # Obtain the rot/trans matrix that relates the the asu of resid_j to # the asu of resid_i. i_r=rt_mx_matrices[symop1] j_r=rt_mx_matrices[symop2] ij_r=j_r.multiply(i_r.inverse()) # Theoretically this rotation should now be rotated by the inverse of # the rotation used to get to asu of resid_i to get the rotation # relative to the original ASU. But this does not work; works without # it. Don't know why. #TEST #~ ij_r=i_r.inverse().multiply(ij_r) # Add the translation relative to the original ASU to the symmetry op # relative to the original ASU transop=transop.multiply(ij_r) ###THIS WORKS ON MANY SPACEGROUPS BUT NOT P212121 #populate supercell_contacts{}. To avoid duplicates chose by highest #x trans op, then y then z if transop.as_xyz()==transop.inverse().as_xyz(): if i_asymresid <= j_asymresid: i_key=(i_asymresid, i_resname, j_asymresid, j_resname,transop.as_xyz()) else: i_key=(j_asymresid, j_resname, i_asymresid, i_resname,transop.as_xyz()) elif transop.t().as_double()[0] > transop.inverse().t().as_double()[0]: i_key=(i_asymresid, i_resname, j_asymresid, j_resname,transop.as_xyz()) elif transop.t().as_double()[0] < transop.inverse().t().as_double()[0]: i_key=(j_asymresid, j_resname, i_asymresid, i_resname,transop.inverse().as_xyz()) else: if transop.t().as_double()[1] > transop.inverse().t().as_double()[1]: i_key=(i_asymresid, i_resname, j_asymresid, j_resname,transop.as_xyz()) elif transop.t().as_double()[1] < transop.inverse().t().as_double()[1]: i_key=(j_asymresid, j_resname, i_asymresid, i_resname,transop.inverse().as_xyz()) else: if transop.t().as_double()[2] > transop.inverse().t().as_double()[2]: i_key=(i_asymresid, i_resname, j_asymresid, j_resname,transop.as_xyz()) elif transop.t().as_double()[2] < transop.inverse().t().as_double()[2]: i_key=(j_asymresid, j_resname, i_asymresid, i_resname,transop.inverse().as_xyz()) else: print "Warning: maybe something is wrong. Transop is: " print transop.as_xyz() import code; code.interact(local=locals()) sys.exit() #~ print i_resid, j_resid, i_asymresid, j_asymresid, transop # The residue numbers, names and symmetry operation uniquely identify # each contact. Populate supercell_contacts dictionary object. Keys # are the cotnact identified. Values are list of distances. if i_key in supercell_contacts.keys(): supercell_contacts[i_key].append(dist) else: supercell_contacts[i_key]=[dist] return supercell_contacts
def find_supercell_contacts_by_residue(residue_contacts, atoms, prop_vec, nres, nsymop, ignore_waters=True): supercell_contacts = {} # skip all solvent ions added that does not belong to any asymmetric unit # by calculating maxresidue and skipping residues above that maxres = nres * prop_vec[0] * prop_vec[1] * prop_vec[2] * nsymop for (residue, contacts) in residue_contacts: debug = False i_resid = int(residue[2]) i_resname = residue[1] if ignore_waters and i_resname in ["HOH", "WAT"]: continue if i_resid >= maxres: continue # residue_contacts may have multiple entries for contacts between # different atoms of the same residues. Duplicate_test{} is used # to filter this so that only one contact is returned with the # shortest atom to atom distance reported. duplicate_test = {} for contact in contacts: sym_op = contact[1] j_seq = contact[0] j_resid = int(atoms[j_seq].fetch_labels().resid()) j_resname = atoms[j_seq].fetch_labels().resname dist = contact[2] if j_resid >= maxres: continue # ~ if i_resname in ["Na+"] and j_resname in ["ASN"]: # ~ print i_resname, i_resid # ~ print j_resname, j_resid # ~ print sym_op # ~ debug=True # ~ elif i_resname in ["ASN"] and j_resname in ["Na+"]: # ~ print i_resname, i_resid # ~ print j_resname, j_resid # ~ print sym_op # ~ debug=True # unit_mx sym_op means the contact is in the original supercell # if same asu in same supercell, it's an "intra_asu" contact so # ignore if is_same_asu(nres, i_resid, j_resid): print i_resid, j_resid, sym_op if sym_op.is_unit_mx(): continue if ignore_waters and j_resname in ["HOH", "WAT"]: continue # populate duplicate_test{} with only one instance of a given # residue pair, keeping the shortest distance value if (j_resid, j_resname, sym_op) in duplicate_test.keys(): if dist < duplicate_test[(j_resid, j_resname, sym_op)]: duplicate_test[(j_resid, j_resname, sym_op)] = dist else: duplicate_test[(j_resid, j_resname, sym_op)] = dist # ~ if i_resname=="ASN" and i_resid==324: # ~ print duplicate_test # ~ for key in duplicate_test.keys(): # ~ print key[2] # ~ debug=True # for contact residue pair, get residue's number in original asu # and symmetry operation relating res_j to res_i for (j_resid, j_resname, sym_op) in duplicate_test.keys(): dist = duplicate_test[(j_resid, j_resname, sym_op)] i_transop, symop1, i_asymresid = SC_mapping(prop_vec, nres, nsymop, i_resid) j_transop, symop2, j_asymresid = SC_mapping(prop_vec, nres, nsymop, j_resid) if debug: print i_transop, symop1, i_asymresid print j_transop, symop2, j_asymresid # both residues within the original supercell if sym_op.is_unit_mx(): transop = j_transop.multiply(i_transop.inverse()) # res_j outside the original supercell else: t = sym_op.t().as_double() t = [t[0] * prop_vec[0], t[1] * prop_vec[1], t[2] * prop_vec[2]] t = [int(i) for i in t] from cctbx_sgtbx_ext import rt_mx, tr_vec t = rt_mx(tr_vec(t, tr_den=1)) j_transop, symop2, j_asymresid = SC_mapping(prop_vec, nres, nsymop, j_resid) j_transop = j_transop.multiply(t) transop = j_transop.multiply(i_transop.inverse()) ################################################################## ###TO DO and TEST!: for multiple asyms in unit cell # transop=j.transop.multiply(symop2).multiply(symop1.inverse()) # where symop1 and symop2 must be turned into an rt_mx first... ################################################################# # populate supercell_contacts{}. To avoid duplicates chose by highest # x trans op, then y then z if transop.t().as_double()[0] > transop.inverse().t().as_double()[0]: i_key = (i_asymresid, i_resname, j_asymresid, j_resname, transop.as_xyz()) elif transop.t().as_double()[0] < transop.inverse().t().as_double()[0]: i_key = (j_asymresid, j_resname, i_asymresid, i_resname, transop.inverse().as_xyz()) else: if transop.t().as_double()[1] > transop.inverse().t().as_double()[1]: i_key = (i_asymresid, i_resname, j_asymresid, j_resname, transop.as_xyz()) elif transop.t().as_double()[1] < transop.inverse().t().as_double()[1]: i_key = (j_asymresid, j_resname, i_asymresid, i_resname, transop.inverse().as_xyz()) else: if transop.t().as_double()[2] > transop.inverse().t().as_double()[2]: i_key = (i_asymresid, i_resname, j_asymresid, j_resname, transop.as_xyz()) elif transop.t().as_double()[2] < transop.inverse().t().as_double()[2]: i_key = (j_asymresid, j_resname, i_asymresid, i_resname, transop.inverse().as_xyz()) else: print "something is wrong. Transop is: " print transop.as_xyz() import code code.interact(local=locals()) # This was the old way. It would avoid duplicates in the same frame but # not between frames (eg. would have (x+1,y,z) iface in one frame # and (x-1,y,z) contacts in another. # ~ if transop.inverse().as_xyz() in [i[4] for i in supercell_contacts.keys()]: # ~ i_key=(j_asymresid, j_resname, i_asymresid, i_resname,transop.inverse().as_xyz()) # ~ else: # ~ i_key=(i_asymresid, i_resname, j_asymresid, j_resname,transop.as_xyz()) if i_key in supercell_contacts.keys(): supercell_contacts[i_key].append(dist) else: supercell_contacts[i_key] = [dist] return supercell_contacts