| 1 | # When one selected pseudobond crosses another in the current camera view
|
|---|
| 2 | # remove the longer one.
|
|---|
| 3 |
|
|---|
| 4 | # Keep every pseudobond that is not crossed by a shorter one
|
|---|
| 5 | # as viewed along z axis.
|
|---|
| 6 | def crossing_pbonds(pbonds):
|
|---|
| 7 | spbonds = list(pbonds)
|
|---|
| 8 | spbonds.sort(key = lambda b: b.length())
|
|---|
| 9 | pb_cross = []
|
|---|
| 10 | segments = [] # Segments not crossed by shorter one.
|
|---|
| 11 | for pb in spbonds:
|
|---|
| 12 | a1,a2 = pb.atoms
|
|---|
| 13 | xy1 = a1.xformCoord().data()[:2]
|
|---|
| 14 | xy2 = a2.xformCoord().data()[:2]
|
|---|
| 15 | segment = (xy1,xy2)
|
|---|
| 16 | if any_cross(segment, segments):
|
|---|
| 17 | pb_cross.append(pb)
|
|---|
| 18 | else:
|
|---|
| 19 | segments.append(segment)
|
|---|
| 20 | return pb_cross
|
|---|
| 21 |
|
|---|
| 22 | def any_cross(segment, segments):
|
|---|
| 23 | for seg2 in segments:
|
|---|
| 24 | if crossing(seg2, segment):
|
|---|
| 25 | return True
|
|---|
| 26 | return False
|
|---|
| 27 |
|
|---|
| 28 | def crossing(segment1, segment2):
|
|---|
| 29 | (p1,p2),(p3,p4) = segment1,segment2
|
|---|
| 30 | if p1 == p3 or p1 == p4 or p2 == p3 or p2 == p4:
|
|---|
| 31 | return False # Endpoints match, no crossing
|
|---|
| 32 | return opposite_sides(p1, p2, segment2) and opposite_sides(p3, p4, segment1)
|
|---|
| 33 |
|
|---|
| 34 | # Are two points on opposite sides of a line.
|
|---|
| 35 | def opposite_sides(p1, p2, segment):
|
|---|
| 36 | x1,y1 = p1
|
|---|
| 37 | x2,y2 = p2
|
|---|
| 38 | (x3,y3),(x4,y4) = segment
|
|---|
| 39 | dx,dy = (x4-x3, y4-y3)
|
|---|
| 40 | nx,ny = (-dy,dx) # Normal vector to segment
|
|---|
| 41 | side1 = nx*(x1-x3) + ny*(y1-y3)
|
|---|
| 42 | side2 = nx*(x2-x3) + ny*(y2-y3)
|
|---|
| 43 | return (side1 < 0 and side2 > 0) or (side1 > 0 and side2 < 0)
|
|---|
| 44 |
|
|---|
| 45 |
|
|---|
| 46 | # Use currently selected pseudobonds
|
|---|
| 47 | from chimera import selection
|
|---|
| 48 | pbonds = selection.currentPseudobonds()
|
|---|
| 49 |
|
|---|
| 50 | # Delete longer crossing pseudobonds
|
|---|
| 51 | cpbonds = crossing_pbonds(pbonds)
|
|---|
| 52 | for pb in cpbonds:
|
|---|
| 53 | pb.pseudoBondGroup.deletePseudoBond(pb)
|
|---|
| 54 |
|
|---|
| 55 | print ('%d of %d pseudobonds deleted' % (len(cpbonds), len(pbonds)))
|
|---|