| 1 | #
|
|---|
| 2 | # Change pseudobond colors based on the bond length. This is for showing distance constraints when
|
|---|
| 3 | # interactively moving one molecule relative to another.
|
|---|
| 4 | #
|
|---|
| 5 | # To color all distance pseudobonds, or selected pseudobonds, or stop coloring all or selected:
|
|---|
| 6 | #
|
|---|
| 7 | # runscript colordist.py 8.5 green red
|
|---|
| 8 | # runscript colordist.py 8.5 green red sel
|
|---|
| 9 | # runscript colordist.py
|
|---|
| 10 | # runscript colordist.py sel
|
|---|
| 11 | #
|
|---|
| 12 | class color_by_distance:
|
|---|
| 13 |
|
|---|
| 14 | def __init__(self):
|
|---|
| 15 | self.pseudobond_colors = {}
|
|---|
| 16 | self.tid = None
|
|---|
| 17 |
|
|---|
| 18 | def color_pseudobonds(self, pseudobonds, length, color_short, color_long):
|
|---|
| 19 |
|
|---|
| 20 | pbc = self.pseudobond_colors
|
|---|
| 21 | for pb in pseudobonds:
|
|---|
| 22 | pbc[pb] = (length, color_short, color_long)
|
|---|
| 23 |
|
|---|
| 24 | self.recolor()
|
|---|
| 25 |
|
|---|
| 26 | if self.tid is None:
|
|---|
| 27 | from chimera import triggers
|
|---|
| 28 | self.tid = triggers.addHandler('OpenState', self.moved_cb, None)
|
|---|
| 29 |
|
|---|
| 30 | def moved_cb(self, trigger_name, data, changes):
|
|---|
| 31 | if 'transformation change' in changes.reasons:
|
|---|
| 32 | self.recolor()
|
|---|
| 33 |
|
|---|
| 34 | def recolor(self):
|
|---|
| 35 | for pb, (length, color_short, color_long) in self.pseudobond_colors.items():
|
|---|
| 36 | pb.color = (color_long if pb.length() >= length else color_short)
|
|---|
| 37 |
|
|---|
| 38 | def stop_coloring(self, pseudobonds = None):
|
|---|
| 39 | pbc = self.pseudobond_colors
|
|---|
| 40 | if pseudobonds is None:
|
|---|
| 41 | pbc.clear()
|
|---|
| 42 | else:
|
|---|
| 43 | for pb in pseudobonds:
|
|---|
| 44 | if pb in pbc:
|
|---|
| 45 | pbc.pop(pb)
|
|---|
| 46 | if len(pbc) == 0 and not self.tid is None:
|
|---|
| 47 | from chimera import triggers
|
|---|
| 48 | triggers.deleteHandler('OpenState', self.tid)
|
|---|
| 49 | self.tid = None
|
|---|
| 50 |
|
|---|
| 51 | def parse_pseudobonds(pb_spec):
|
|---|
| 52 |
|
|---|
| 53 | from chimera import specifier
|
|---|
| 54 | sel = specifier.evalSpec(pb_spec)
|
|---|
| 55 | pblist = sel.pseudobonds()
|
|---|
| 56 | return pblist
|
|---|
| 57 |
|
|---|
| 58 | def all_pseudobonds():
|
|---|
| 59 |
|
|---|
| 60 | pblist = []
|
|---|
| 61 | from chimera import openModels, PseudoBondGroup
|
|---|
| 62 | for m in openModels.list(hidden = True, modelTypes = [PseudoBondGroup]):
|
|---|
| 63 | if m.category == 'distance monitor':
|
|---|
| 64 | pblist.extend(m.pseudoBonds)
|
|---|
| 65 | return pblist
|
|---|
| 66 |
|
|---|
| 67 | cbd = None
|
|---|
| 68 |
|
|---|
| 69 | def parse_command(args):
|
|---|
| 70 |
|
|---|
| 71 | if args is None or len(args) not in (0,1,3,4):
|
|---|
| 72 | from Commands import CommandError
|
|---|
| 73 | raise CommandError('Wrong number of arguments: runscript colorconstraints.py 8.5 green red sel')
|
|---|
| 74 |
|
|---|
| 75 | # Get color by distance updater.
|
|---|
| 76 | if hasattr(chimera, 'color_by_distance'):
|
|---|
| 77 | cbd = chimera.color_by_distance
|
|---|
| 78 | else:
|
|---|
| 79 | chimera.color_by_distance = cbd = color_by_distance()
|
|---|
| 80 |
|
|---|
| 81 | # Stop color updating if no arguments given.
|
|---|
| 82 | if len(args) == 0:
|
|---|
| 83 | cbd.stop_coloring()
|
|---|
| 84 | return
|
|---|
| 85 |
|
|---|
| 86 | # Uncolor pseudobonds if just one argument was given.
|
|---|
| 87 | if len(args) == 1:
|
|---|
| 88 | cbd.stop_coloring(parse_pseudobonds(args[0]))
|
|---|
| 89 | return
|
|---|
| 90 |
|
|---|
| 91 | # Get distance
|
|---|
| 92 | from Commands import float_arg
|
|---|
| 93 | length = float_arg(args[0])
|
|---|
| 94 |
|
|---|
| 95 | # Get colors
|
|---|
| 96 | color1, color2 = args[1:3]
|
|---|
| 97 | from Commands import color_arg
|
|---|
| 98 | srgba = color_arg(color1)
|
|---|
| 99 | lrgba = color_arg(color2)
|
|---|
| 100 | from chimera import specifier, MaterialColor
|
|---|
| 101 | short_color = MaterialColor(*srgba)
|
|---|
| 102 | long_color = MaterialColor(*lrgba)
|
|---|
| 103 |
|
|---|
| 104 | # Get pseudobonds
|
|---|
| 105 | pblist = parse_pseudobonds(args[3]) if len(args) == 4 else all_pseudobonds()
|
|---|
| 106 | if len(pblist) == 0:
|
|---|
| 107 | from Commands import CommandError
|
|---|
| 108 | raise CommandError('No pseudobonds to color')
|
|---|
| 109 |
|
|---|
| 110 | # Setup automatic coloring
|
|---|
| 111 | cbd.color_pseudobonds(pblist, length, short_color, long_color)
|
|---|
| 112 |
|
|---|
| 113 | parse_command(globals().get('arguments'))
|
|---|