def AngleFinder(Atom1,Atom2,Atom3): vector1 = Atom1.get_vector() vector2 = Atom2.get_vector() vector3 = Atom3.get_vector() angle = bp.calc_angle(vector1,vector2,vector3) return math.degrees(angle)
def w_pdb_1(segment1, segment2): '''Compute writhe contribution from two input line segments. Segments are pairs of vectors as returned by Biopython.''' # t1 = time.time() s1 = segment1 s2 = segment2 #form unit vectors at the segment extremes: v13 = s2[0] - s1[0] v23 = s2[0] - s1[1] v24 = s2[1] - s1[1] v14 = s2[1] - s1[0] v = [v13, v23, v24, v14, v13, v23] e = [] # l13 = np.sqrt(PDB.Vector.__mul__(v13,v13)) # l23 = np.sqrt(PDB.Vector.__mul__(v23,v23)) # l24 = np.sqrt(PDB.Vector.__mul__(v24,v24)) # l14 = np.sqrt(PDB.Vector.__mul__(v14,v14)) l13 = np.sqrt(v13 * v13) l23 = np.sqrt(v23 * v23) l24 = np.sqrt(v24 * v24) l14 = np.sqrt(v14 * v14) ls = [l13, l23, l24, l14] for l in ls: if l == 0.0: return 0 e13 = v13 / l13 e23 = v23 / l23 e24 = v24 / l24 e14 = v14 / l14 e = [e13, e23, e24, e14, e13, e23] ## n_vect = np.linalg.norm(vect) ## if n_vect == 0: #if one of the vectors is zero the two segments lie in a plane ## return 0 # else: # n_vect = np.linalg.norm(vect) # e.append(vect/n_vect) # t2 = time.time() #compute the angles s = 0 for i in range(1, len(e) - 1): a = e[i - 1] b = e[i] c = e[i + 1] theta = PDB.calc_angle(a, b, c) # print "angle is %f" % theta #APPARENTLY THIS ANGLE IS ALWAYS POSITIVE AND BETWEEN O AND PI; PROBABLY THE ANGLE BETWEEN SEGMENT AB, AC (WITHOUT SIGN) s = s + theta # print "s is %f " % s # t3 = time.time w = np.sign(s) * 2 * np.pi - s # t4 = time.time() # print "t2-t1:", 10*(t2-t1) # print "t3-t2:", 10*(t3-t2) # print "t4-t3:",10*(t4-t3) return w
def get_pose_constraints(Pose, MaxDist, MinPositionSeperation, SasaRadius, SasaScale, UpstreamGrep, DownstreamGrep, NeedHydrogen=True): ''' ''' # AlexsSasaCalculator is from Alex's interface_fragment_matching # thanks Alex! # # This is used to give buried polar contacts more weight. Thanks Alex Ford! try: from interface_fragment_matching.utility.analysis import AtomicSasaCalculator # make instace of Alex's sasa calculator AlexsSasaCalculator = AtomicSasaCalculator(probe_radius=SasaRadius) ResidueAtomSasa = AlexsSasaCalculator.calculate_per_atom_sasa(Pose) except ImportError: ' Error: SASA weighting of contacts requires interface_fragment_matching from Alex Ford ' # for making full atom kd tree ResAtmCoordLists = [] # for translating from kd tree index to ( residue, atom ) coord ResAtmRecordLists = [] # loop through all residue numbers for Res in range(1, Pose.n_residue() + 1): # remade for each residue AtmRecordList = [] AtmCoordList = [] # loop through residue's atom numbers for Atm in range(1, Pose.residue(Res).natoms() + 1): # add (residue, atom) coord to residue's list AtmRecordList.append((Res, Atm)) # add atom xyz coord to residue's list AtmCoordList.append( np.array(list(Pose.residue(Res).atom(Atm).xyz()))) # add residue's lists to respective global lists ResAtmCoordLists.extend(AtmCoordList) ResAtmRecordLists.extend(AtmRecordList) ResidueAtomArray = np.array(ResAtmCoordLists) ResidueAtomKDTree = spatial.KDTree(ResidueAtomArray) ResidueAtomNeighbors = ResidueAtomKDTree.query_ball_point( ResidueAtomArray, MaxDist) # ResidueAtomNearNeighbors = ResidueAtomKDTree.query_ball_point( ResidueAtomArray, 2.0 ) ResidueAtomHydrogens = ResidueAtomKDTree.query_ball_point( ResidueAtomArray, 1.1) # holds constraints before printing AllConstraints = [] # holds sorted cst AllBackboneBackboneCst = [] AllBackboneSidechainCst = [] AllSidechainSidechainCst = [] # All contacts are from upstream to downstream residues to avoid double counting Upstream = [] for UpIndex, UpXyzCoords in enumerate(ResAtmCoordLists): UpRes, UpAtm = ResAtmRecordLists[UpIndex] # # loop through residues storing info on oxygens # for UpRes in range( 1, Pose.n_residue() + 1 ): # # loop through atoms # for UpAtm in range( 1, Pose.residue(UpRes).natoms() + 1 ): UpName = Pose.residue(UpRes).atom_name(UpAtm).replace(' ', '') # skip virtual residues if Pose.residue(UpRes).is_virtual(UpAtm): continue # this guy # / # checks upstream name V if re.match(UpstreamGrep, UpName): # print '\n'*2 # print 'UpRes, UpName', UpRes, UpName # get neighbors of upstream residues NeighborsOfUpstream = ResidueAtomNeighbors[UpIndex] # prep for loop Downstreams = [] Constraints = [] BackboneBackboneCst = [] BackboneSidechainCst = [] SidechainSidechainCst = [] # ArbitrayOrderOfAtomNames = {} for DownIndex in NeighborsOfUpstream: # name presumes downstream, checks with if imediately below DownRes, DownAtm = ResAtmRecordLists[DownIndex] # checks that downstream residue is dowstream of upstream and passes min primary sequence spacing if DownRes - UpRes >= MinPositionSeperation: DownName = Pose.residue(DownRes).atom_name( DownAtm).replace(' ', '') # skip if same atom if UpRes == DownRes: if UpName == DownName: continue # skip virtual residues if Pose.residue(DownRes).is_virtual(DownAtm): continue # checks downstream name if re.match(DownstreamGrep, DownName): # print 'DownRes, DownName', DownRes, DownName PotentialUpstreamHydrogens = ResidueAtomHydrogens[ UpIndex] UpstreamHydrogens = [] # print 'PotentialUpstreamHydrogens', PotentialUpstreamHydrogens for UpH_I in PotentialUpstreamHydrogens: UpH_Res, UpH_Atm = ResAtmRecordLists[UpH_I] UpH_Name = Pose.residue(UpH_Res).atom_name( UpH_Atm).replace(' ', '') # print 'UpH_Name', UpH_Name if 'H' in UpH_Name: UpstreamHydrogens.append( (UpH_Res, UpH_Atm, UpH_Name)) # print 'UpstreamHydrogens', UpstreamHydrogens PotentialDownstreamHydrogens = ResidueAtomHydrogens[ DownIndex] DownstreamHydrogens = [] # print 'PotentialDownstreamHydrogens', PotentialDownstreamHydrogens for DownH_I in PotentialDownstreamHydrogens: DownH_Res, DownH_Atm = ResAtmRecordLists[DownH_I] DownH_Name = Pose.residue(DownH_Res).atom_name( DownH_Atm).replace(' ', '') # print 'DownH_Name', DownH_Name if 'H' in DownH_Name: DownstreamHydrogens.append( (DownH_Res, DownH_Atm, DownH_Name)) # print 'DownstreamHydrogens', DownstreamHydrogens # check their is at least one hydrogen in system before adding constraint if len(UpstreamHydrogens) or len( DownstreamHydrogens) or NeedHydrogen == False: # these trys / excepts seperate # backbone-backbone from # backbone-sidechain from # sidechain-sidechain interactions # # in future maybe sort into seperate lists, shouldn't rely on ResidueAtomSasa to know what is in backbone try: UpstreamSasa = ResidueAtomSasa[UpRes][UpName] DownstreamSasa = ResidueAtomSasa[DownRes][ DownName] AverageSasa = np.mean( [UpstreamSasa, DownstreamSasa]) BBBB = 1 BBSC = SCSC = 0 except KeyError: # These lines handle backbone to sidechain interactions # set weight equal to the most buried try: UpstreamSasa = ResidueAtomSasa[UpRes][ UpName] AverageSasa = SasaScale.FloorSasa BBSC = 1 BBBB = SCSC = 0 except KeyError: try: DownstreamSasa = ResidueAtomSasa[ DownRes][DownName] AverageSasa = SasaScale.FloorSasa BBSC = 1 BBBB = SCSC = 0 # set weight of side chain side chain equal to the most buried except KeyError: AverageSasa = SasaScale.CeilingSasa SCSC = 1 BBSC = BBBB = 0 # use instance of sasa_scale to calculate weight based on avg sasa of N and O SasaBasedWeight = SasaScale.weigh(AverageSasa) # print # print 'AverageSasa', AverageSasa # print 'SasaBasedWeight', SasaBasedWeight # print 'found downstream neighbor %s'%DownName DownXyzCoords = np.array( list( Pose.residue(DownRes).atom(DownAtm).xyz())) # print 'DownRes, DownName', DownRes, DownName # print 'DownXyzCoords', DownXyzCoords # ## Get neighbors for angles and torsions to use with AtomPairs SelectUpNeighbors = [] # iterates through upstream atom neighbors for references for angle for UpNeighborIndex in NeighborsOfUpstream: UpNeighborRes, UpNeighborAtm = ResAtmRecordLists[ UpNeighborIndex] UpNeighborName = Pose.residue( UpNeighborRes).atom_name( UpNeighborAtm).replace(' ', '') # keep looking if neighbor is hyrdogen if 'H' in UpNeighborName: continue # skip virtual residues if Pose.residue(UpNeighborRes).is_virtual( UpNeighborAtm): continue # keep looking if neighbor is self if UpNeighborName == UpName and UpNeighborRes == UpRes: continue # keep looking if neighbor is downstream residue again if UpNeighborName == DownName and UpNeighborRes == DownRes: continue UpNeighborCoords = ResAtmCoordLists[ UpNeighborIndex] DistanceToNeighbor = solenoid_tools.vector_magnitude( UpXyzCoords - UpNeighborCoords) SelectUpNeighbors.append( (DistanceToNeighbor, UpNeighborName, UpNeighborRes, UpNeighborCoords)) # sort by distance to atom, nearest first SelectUpNeighbors.sort() UpNeighbor1Tuple = SelectUpNeighbors[0] UpNeighbor2Tuple = SelectUpNeighbors[1] # print '\n'*2 # print 'UpRes, UpName', UpRes, UpName # print 'UpstreamHydrogens', UpstreamHydrogens # print 'SelectUpNeighbors', SelectUpNeighbors # get neighbors of upstream residues NeighborsOfDownstream = ResidueAtomNeighbors[ DownIndex] SelectDownNeighbors = [] # iterates through upstream atom neighbors for references for angle for DownNeighborIndex in NeighborsOfDownstream: DownNeighborRes, DownNeighborAtm = ResAtmRecordLists[ DownNeighborIndex] DownNeighborName = Pose.residue( DownNeighborRes).atom_name( DownNeighborAtm).replace(' ', '') # keep looking if neighbor is hyrdogen if 'H' in DownNeighborName: continue # skip virtual residues if Pose.residue(DownNeighborRes).is_virtual( DownNeighborAtm): continue # keep looking if neighbor is self if DownNeighborName == DownName and DownNeighborRes == DownRes: continue # keep looking if neighbor is upstream residue if DownNeighborName == UpName and DownNeighborRes == UpRes: continue DownNeighborCoords = ResAtmCoordLists[ DownNeighborIndex] DistanceToNeighbor = solenoid_tools.vector_magnitude( DownXyzCoords - DownNeighborCoords) SelectDownNeighbors.append( (DistanceToNeighbor, DownNeighborName, DownNeighborRes, DownNeighborCoords)) # sort by distance to atom, nearest first SelectDownNeighbors.sort() DownNeighbor1Tuple = SelectDownNeighbors[0] DownNeighbor2Tuple = SelectDownNeighbors[1] # print 'DownRes, DownName', DownRes, DownName # print 'DownstreamHydrogens', DownstreamHydrogens # print 'SelectDownNeighbors', SelectDownNeighbors Distance = solenoid_tools.vector_magnitude( DownXyzCoords - UpXyzCoords) DistanceCst = 'AtomPair %s %d %s %d SCALARWEIGHTEDFUNC %f HARMONIC %.2f 1.0' % ( UpName, UpRes, DownName, DownRes, SasaBasedWeight, Distance) # Use Biopython for angle and dihedral calculations # here 'Vec' means PDB.Vector of atom's xyz coord UpstreamVec = PDB.Vector(UpXyzCoords) DownstreamVec = PDB.Vector(DownXyzCoords) UpNeighbor1Vec = PDB.Vector(UpNeighbor1Tuple[3]) UpNeighbor2Vec = PDB.Vector(UpNeighbor2Tuple[3]) DownNeighbor1Vec = PDB.Vector( DownNeighbor1Tuple[3]) DownNeighbor2Vec = PDB.Vector( DownNeighbor2Tuple[3]) Angle1 = PDB.calc_angle(UpNeighbor1Vec, UpstreamVec, DownstreamVec) AngleCst1 = 'Angle %s %d %s %d %s %d SCALARWEIGHTEDFUNC %f CIRCULARHARMONIC %.2f 0.5' % ( UpNeighbor1Tuple[1], UpNeighbor1Tuple[2], UpName, UpRes, DownName, DownRes, SasaBasedWeight, Angle1) Angle2 = PDB.calc_angle(UpstreamVec, DownstreamVec, DownNeighbor1Vec) AngleCst2 = 'Angle %s %d %s %d %s %d SCALARWEIGHTEDFUNC %f CIRCULARHARMONIC %.2f 0.5' % ( UpName, UpRes, DownName, DownRes, DownNeighbor1Tuple[1], DownNeighbor1Tuple[2], SasaBasedWeight, Angle2) Torsion1 = PDB.calc_dihedral( UpNeighbor2Vec, UpNeighbor1Vec, UpstreamVec, DownstreamVec) TorsionCst1 = 'Dihedral %s %d %s %d %s %d %s %d SCALARWEIGHTEDFUNC %f CIRCULARHARMONIC %.2f 0.5' % ( UpNeighbor2Tuple[1], UpNeighbor2Tuple[2], UpNeighbor1Tuple[1], UpNeighbor1Tuple[2], UpName, UpRes, DownName, DownRes, SasaBasedWeight, Torsion1) Torsion2 = PDB.calc_dihedral( UpNeighbor1Vec, UpstreamVec, DownstreamVec, DownNeighbor1Vec) TorsionCst2 = 'Dihedral %s %d %s %d %s %d %s %d SCALARWEIGHTEDFUNC %f CIRCULARHARMONIC %.2f 0.5' % ( UpNeighbor1Tuple[1], UpNeighbor1Tuple[2], UpName, UpRes, DownName, DownRes, DownNeighbor1Tuple[1], DownNeighbor1Tuple[2], SasaBasedWeight, Torsion2) Torsion3 = PDB.calc_dihedral( UpstreamVec, DownstreamVec, DownNeighbor1Vec, DownNeighbor2Vec) TorsionCst3 = 'Dihedral %s %d %s %d %s %d %s %d SCALARWEIGHTEDFUNC %f CIRCULARHARMONIC %.2f 0.5' % ( UpName, UpRes, DownName, DownRes, DownNeighbor1Tuple[1], DownNeighbor1Tuple[2], DownNeighbor2Tuple[1], DownNeighbor2Tuple[2], SasaBasedWeight, Torsion3) # adds constraint to running lists of constraints Constraints.extend([ DistanceCst, AngleCst1, AngleCst2, TorsionCst1, TorsionCst2, TorsionCst3 ]) if BBBB: BackboneBackboneCst.extend([ DistanceCst, AngleCst1, AngleCst2, TorsionCst1, TorsionCst2, TorsionCst3 ]) if BBSC: BackboneSidechainCst.extend([ DistanceCst, AngleCst1, AngleCst2, TorsionCst1, TorsionCst2, TorsionCst3 ]) if SCSC: SidechainSidechainCst.extend([ DistanceCst, AngleCst1, AngleCst2, TorsionCst1, TorsionCst2, TorsionCst3 ]) # else: # print 'No hydrogen!' # sys.exit() AllConstraints.extend(Constraints) AllBackboneBackboneCst.extend(BackboneBackboneCst) AllBackboneSidechainCst.extend(BackboneSidechainCst) AllSidechainSidechainCst.extend(SidechainSidechainCst) SortedConstraints = (AllBackboneBackboneCst, AllBackboneSidechainCst, AllSidechainSidechainCst) return AllConstraints, SortedConstraints
def get_pose_constraints(Pose, MaxDist, MinPositionSeperation, SasaRadius, SasaScale, UpstreamGrep, DownstreamGrep, NeedHydrogen=True): ''' ''' # AlexsSasaCalculator is from Alex's interface_fragment_matching # thanks Alex! # # This is used to give buried polar contacts more weight. Thanks Alex Ford! try: from interface_fragment_matching.utility.analysis import AtomicSasaCalculator # make instace of Alex's sasa calculator AlexsSasaCalculator = AtomicSasaCalculator(probe_radius=SasaRadius) ResidueAtomSasa = AlexsSasaCalculator.calculate_per_atom_sasa(Pose) except ImportError: ' Error: SASA weighting of contacts requires interface_fragment_matching from Alex Ford ' # for making full atom kd tree ResAtmCoordLists = [] # for translating from kd tree index to ( residue, atom ) coord ResAtmRecordLists = [] # loop through all residue numbers for Res in range(1, Pose.n_residue() + 1): # remade for each residue AtmRecordList = [] AtmCoordList = [] # loop through residue's atom numbers for Atm in range(1, Pose.residue(Res).natoms() + 1): # add (residue, atom) coord to residue's list AtmRecordList.append((Res, Atm)) # add atom xyz coord to residue's list AtmCoordList.append( np.array(list(Pose.residue(Res).atom(Atm).xyz())) ) # add residue's lists to respective global lists ResAtmCoordLists.extend(AtmCoordList) ResAtmRecordLists.extend(AtmRecordList) ResidueAtomArray = np.array( ResAtmCoordLists ) ResidueAtomKDTree = spatial.KDTree( ResidueAtomArray ) ResidueAtomNeighbors = ResidueAtomKDTree.query_ball_point( ResidueAtomArray, MaxDist ) # ResidueAtomNearNeighbors = ResidueAtomKDTree.query_ball_point( ResidueAtomArray, 2.0 ) ResidueAtomHydrogens = ResidueAtomKDTree.query_ball_point( ResidueAtomArray, 1.1 ) # holds constraints before printing AllConstraints = [] # holds sorted cst AllBackboneBackboneCst = [] AllBackboneSidechainCst = [] AllSidechainSidechainCst = [] # All contacts are from upstream to downstream residues to avoid double counting Upstream = [] for UpIndex, UpXyzCoords in enumerate(ResAtmCoordLists): UpRes, UpAtm = ResAtmRecordLists[UpIndex] # # loop through residues storing info on oxygens # for UpRes in range( 1, Pose.n_residue() + 1 ): # # loop through atoms # for UpAtm in range( 1, Pose.residue(UpRes).natoms() + 1 ): UpName = Pose.residue(UpRes).atom_name(UpAtm).replace(' ', '') # skip virtual residues if Pose.residue(UpRes).is_virtual(UpAtm): continue # this guy # / # checks upstream name V if re.match(UpstreamGrep, UpName ): # print '\n'*2 # print 'UpRes, UpName', UpRes, UpName # get neighbors of upstream residues NeighborsOfUpstream = ResidueAtomNeighbors[UpIndex] # prep for loop Downstreams = [] Constraints = [] BackboneBackboneCst = [] BackboneSidechainCst = [] SidechainSidechainCst = [] # ArbitrayOrderOfAtomNames = {} for DownIndex in NeighborsOfUpstream: # name presumes downstream, checks with if imediately below DownRes, DownAtm = ResAtmRecordLists[DownIndex] # checks that downstream residue is dowstream of upstream and passes min primary sequence spacing if DownRes - UpRes >= MinPositionSeperation: DownName = Pose.residue(DownRes).atom_name(DownAtm).replace(' ', '') # skip if same atom if UpRes == DownRes: if UpName == DownName: continue # skip virtual residues if Pose.residue(DownRes).is_virtual(DownAtm): continue # checks downstream name if re.match( DownstreamGrep, DownName ): # print 'DownRes, DownName', DownRes, DownName PotentialUpstreamHydrogens = ResidueAtomHydrogens[UpIndex] UpstreamHydrogens = [] # print 'PotentialUpstreamHydrogens', PotentialUpstreamHydrogens for UpH_I in PotentialUpstreamHydrogens: UpH_Res, UpH_Atm = ResAtmRecordLists[UpH_I] UpH_Name = Pose.residue(UpH_Res).atom_name(UpH_Atm).replace(' ', '') # print 'UpH_Name', UpH_Name if 'H' in UpH_Name: UpstreamHydrogens.append((UpH_Res, UpH_Atm, UpH_Name)) # print 'UpstreamHydrogens', UpstreamHydrogens PotentialDownstreamHydrogens = ResidueAtomHydrogens[DownIndex] DownstreamHydrogens = [] # print 'PotentialDownstreamHydrogens', PotentialDownstreamHydrogens for DownH_I in PotentialDownstreamHydrogens: DownH_Res, DownH_Atm = ResAtmRecordLists[DownH_I] DownH_Name = Pose.residue(DownH_Res).atom_name(DownH_Atm).replace(' ', '') # print 'DownH_Name', DownH_Name if 'H' in DownH_Name: DownstreamHydrogens.append((DownH_Res, DownH_Atm, DownH_Name)) # print 'DownstreamHydrogens', DownstreamHydrogens # check their is at least one hydrogen in system before adding constraint if len(UpstreamHydrogens) or len(DownstreamHydrogens) or NeedHydrogen == False: # these trys / excepts seperate # backbone-backbone from # backbone-sidechain from # sidechain-sidechain interactions # # in future maybe sort into seperate lists, shouldn't rely on ResidueAtomSasa to know what is in backbone try: UpstreamSasa = ResidueAtomSasa[UpRes][UpName] DownstreamSasa = ResidueAtomSasa[DownRes][DownName] AverageSasa = np.mean([UpstreamSasa, DownstreamSasa]) BBBB = 1 BBSC = SCSC = 0 except KeyError: # These lines handle backbone to sidechain interactions # set weight equal to the most buried try: UpstreamSasa = ResidueAtomSasa[UpRes][UpName] AverageSasa = SasaScale.FloorSasa BBSC = 1 BBBB = SCSC = 0 except KeyError: try: DownstreamSasa = ResidueAtomSasa[DownRes][DownName] AverageSasa = SasaScale.FloorSasa BBSC = 1 BBBB = SCSC = 0 # set weight of side chain side chain equal to the most buried except KeyError: AverageSasa = SasaScale.CeilingSasa SCSC = 1 BBSC = BBBB = 0 # use instance of sasa_scale to calculate weight based on avg sasa of N and O SasaBasedWeight = SasaScale.weigh(AverageSasa) # print # print 'AverageSasa', AverageSasa # print 'SasaBasedWeight', SasaBasedWeight # print 'found downstream neighbor %s'%DownName DownXyzCoords = np.array( list(Pose.residue(DownRes).atom(DownAtm).xyz()) ) # print 'DownRes, DownName', DownRes, DownName # print 'DownXyzCoords', DownXyzCoords # ## Get neighbors for angles and torsions to use with AtomPairs SelectUpNeighbors = [] # iterates through upstream atom neighbors for references for angle for UpNeighborIndex in NeighborsOfUpstream: UpNeighborRes, UpNeighborAtm = ResAtmRecordLists[UpNeighborIndex] UpNeighborName = Pose.residue(UpNeighborRes).atom_name(UpNeighborAtm).replace(' ', '') # keep looking if neighbor is hyrdogen if 'H' in UpNeighborName: continue # skip virtual residues if Pose.residue(UpNeighborRes).is_virtual(UpNeighborAtm): continue # keep looking if neighbor is self if UpNeighborName == UpName and UpNeighborRes == UpRes: continue # keep looking if neighbor is downstream residue again if UpNeighborName == DownName and UpNeighborRes == DownRes: continue UpNeighborCoords = ResAtmCoordLists[UpNeighborIndex] DistanceToNeighbor = solenoid_tools.vector_magnitude( UpXyzCoords - UpNeighborCoords ) SelectUpNeighbors.append( (DistanceToNeighbor, UpNeighborName, UpNeighborRes, UpNeighborCoords) ) # sort by distance to atom, nearest first SelectUpNeighbors.sort() UpNeighbor1Tuple = SelectUpNeighbors[0] UpNeighbor2Tuple = SelectUpNeighbors[1] # print '\n'*2 # print 'UpRes, UpName', UpRes, UpName # print 'UpstreamHydrogens', UpstreamHydrogens # print 'SelectUpNeighbors', SelectUpNeighbors # get neighbors of upstream residues NeighborsOfDownstream = ResidueAtomNeighbors[DownIndex] SelectDownNeighbors = [] # iterates through upstream atom neighbors for references for angle for DownNeighborIndex in NeighborsOfDownstream: DownNeighborRes, DownNeighborAtm = ResAtmRecordLists[DownNeighborIndex] DownNeighborName = Pose.residue(DownNeighborRes).atom_name(DownNeighborAtm).replace(' ', '') # keep looking if neighbor is hyrdogen if 'H' in DownNeighborName: continue # skip virtual residues if Pose.residue(DownNeighborRes).is_virtual(DownNeighborAtm): continue # keep looking if neighbor is self if DownNeighborName == DownName and DownNeighborRes == DownRes: continue # keep looking if neighbor is upstream residue if DownNeighborName == UpName and DownNeighborRes == UpRes: continue DownNeighborCoords = ResAtmCoordLists[DownNeighborIndex] DistanceToNeighbor = solenoid_tools.vector_magnitude( DownXyzCoords - DownNeighborCoords ) SelectDownNeighbors.append( (DistanceToNeighbor, DownNeighborName, DownNeighborRes, DownNeighborCoords) ) # sort by distance to atom, nearest first SelectDownNeighbors.sort() DownNeighbor1Tuple = SelectDownNeighbors[0] DownNeighbor2Tuple = SelectDownNeighbors[1] # print 'DownRes, DownName', DownRes, DownName # print 'DownstreamHydrogens', DownstreamHydrogens # print 'SelectDownNeighbors', SelectDownNeighbors Distance = solenoid_tools.vector_magnitude(DownXyzCoords - UpXyzCoords) DistanceCst = 'AtomPair %s %d %s %d SCALARWEIGHTEDFUNC %f HARMONIC %.2f 1.0' %( UpName, UpRes, DownName, DownRes, SasaBasedWeight, Distance ) # Use Biopython for angle and dihedral calculations # here 'Vec' means PDB.Vector of atom's xyz coord UpstreamVec = PDB.Vector(UpXyzCoords) DownstreamVec = PDB.Vector(DownXyzCoords) UpNeighbor1Vec = PDB.Vector(UpNeighbor1Tuple[3]) UpNeighbor2Vec = PDB.Vector(UpNeighbor2Tuple[3]) DownNeighbor1Vec = PDB.Vector(DownNeighbor1Tuple[3]) DownNeighbor2Vec = PDB.Vector(DownNeighbor2Tuple[3]) Angle1 = PDB.calc_angle(UpNeighbor1Vec, UpstreamVec, DownstreamVec) AngleCst1 = 'Angle %s %d %s %d %s %d SCALARWEIGHTEDFUNC %f CIRCULARHARMONIC %.2f 0.5' %( UpNeighbor1Tuple[1], UpNeighbor1Tuple[2], UpName, UpRes, DownName, DownRes, SasaBasedWeight, Angle1 ) Angle2 = PDB.calc_angle(UpstreamVec, DownstreamVec, DownNeighbor1Vec) AngleCst2 = 'Angle %s %d %s %d %s %d SCALARWEIGHTEDFUNC %f CIRCULARHARMONIC %.2f 0.5' %( UpName, UpRes, DownName, DownRes, DownNeighbor1Tuple[1], DownNeighbor1Tuple[2], SasaBasedWeight, Angle2 ) Torsion1 = PDB.calc_dihedral(UpNeighbor2Vec, UpNeighbor1Vec, UpstreamVec, DownstreamVec) TorsionCst1 = 'Dihedral %s %d %s %d %s %d %s %d SCALARWEIGHTEDFUNC %f CIRCULARHARMONIC %.2f 0.5' %( UpNeighbor2Tuple[1], UpNeighbor2Tuple[2], UpNeighbor1Tuple[1], UpNeighbor1Tuple[2], UpName, UpRes, DownName, DownRes, SasaBasedWeight, Torsion1 ) Torsion2 = PDB.calc_dihedral(UpNeighbor1Vec, UpstreamVec, DownstreamVec, DownNeighbor1Vec) TorsionCst2 = 'Dihedral %s %d %s %d %s %d %s %d SCALARWEIGHTEDFUNC %f CIRCULARHARMONIC %.2f 0.5' %( UpNeighbor1Tuple[1], UpNeighbor1Tuple[2], UpName, UpRes, DownName, DownRes, DownNeighbor1Tuple[1], DownNeighbor1Tuple[2], SasaBasedWeight, Torsion2 ) Torsion3 = PDB.calc_dihedral(UpstreamVec, DownstreamVec, DownNeighbor1Vec, DownNeighbor2Vec) TorsionCst3 = 'Dihedral %s %d %s %d %s %d %s %d SCALARWEIGHTEDFUNC %f CIRCULARHARMONIC %.2f 0.5' %( UpName, UpRes, DownName, DownRes, DownNeighbor1Tuple[1], DownNeighbor1Tuple[2], DownNeighbor2Tuple[1], DownNeighbor2Tuple[2], SasaBasedWeight, Torsion3 ) # adds constraint to running lists of constraints Constraints.extend( [DistanceCst, AngleCst1, AngleCst2, TorsionCst1, TorsionCst2, TorsionCst3] ) if BBBB: BackboneBackboneCst.extend( [DistanceCst, AngleCst1, AngleCst2, TorsionCst1, TorsionCst2, TorsionCst3] ) if BBSC: BackboneSidechainCst.extend( [DistanceCst, AngleCst1, AngleCst2, TorsionCst1, TorsionCst2, TorsionCst3] ) if SCSC: SidechainSidechainCst.extend( [DistanceCst, AngleCst1, AngleCst2, TorsionCst1, TorsionCst2, TorsionCst3] ) # else: # print 'No hydrogen!' # sys.exit() AllConstraints.extend(Constraints) AllBackboneBackboneCst.extend(BackboneBackboneCst) AllBackboneSidechainCst.extend(BackboneSidechainCst) AllSidechainSidechainCst.extend(SidechainSidechainCst) SortedConstraints = (AllBackboneBackboneCst, AllBackboneSidechainCst, AllSidechainSidechainCst) return AllConstraints, SortedConstraints