def bond_menu_section(bond, quat = Q(1,0,0,0)): """ Return a menu_spec subsection for displaying info about a highlighted bond, changing its bond_type, offering commands about it, etc. If given, use the quat describing the rotation used for displaying it to order the atoms in the bond left-to-right (e.g. in text strings). """ res = [] res.append(( bonded_atoms_summary(bond, quat = quat), noop, 'disabled' )) res.extend( _bond_type_menu_section(bond) ) if bond.is_directional(): ### REVIEW: Do we want to do this for open bonds, after mark's 071014 change # which allows them here? Or do we want "and not bond.is_open_bond()"? # (BTW, I'm not sure this gets called at all, for open bonds.) # Guess: open bonds would be safe here, so allow them, though I'm # not sure it's always a good idea. Caveat: if we treat them as non-directional # when the base atom has three or more directional bonds, we should probably # make that exception here too -- probably using a higher-level method in place # of is_directional, namely directional_bond_chain_status for both atoms in bond. # We'd want a new method on bond to call that for both atoms and look at the # results (perhaps there's already code like that elsewhere). Without this, # we may get a bug if a user can try to change direction on an open bond # that hits a strand but is not in it. But since I suspect the UI never allows # an open bond here, I won't bother to write that code just yet. [bruce 071016] submenu_contents = bond_direction_submenu_contents(bond, quat) left_atom = bond_left_atom(bond, quat) # same one that comes first in bonded_atoms_summary #e ideally, for mostly vertical bonds, we'd switch to an up/down distinction for the menu text about directions #e and whatever the direction names, maybe we should explore farther along the strand to see what they are... # unless it hairpins or crosses over... hmm. current_dir = bond.bond_direction_from(left_atom) current_dir_str = _BOND_DIR_TEXTS[current_dir] text = "strand direction (%s)" % current_dir_str item = (text, submenu_contents) res.append(item) return res
def bond_direction_submenu_contents(bond, quat): #bruce 070415 res = [] left_atom = bond_left_atom(bond, quat) direction = bond.bond_direction_from(left_atom) ## # order will be: if this bond has a dir: this dir, opp dir, unset; ## # or if not: unset, right, left. So current dir is always first. Not sure this is good! In fact, I'm sure it's not! ## if direction: ## dir_order = [direction, - direction, 0] ## else: ## dir_order = [0, 1, -1] dir_order = [1, -1, 0] for dir in dir_order: text = "make it %s" % _BOND_DIR_NAMES[dir] # how do we say concisely: # "make the bond dirs all one way along entire strand, # so they're going (eg) right, when they pass thru this bond"? if dir == direction: text += " (like this bond)" #e also use checkmark, or is that confusing since it's not a noop? for now, use it. command = (lambda _guard = None, bond = bond, left_atom = left_atom, dir = dir: bond.set_bond_direction_from(left_atom, dir, propogate = True)) checkmark = (dir == direction) and 'checked' or None item = (text, command, checkmark) res.append(item) res.append(('set to fit minor groove (not implemented)', noop, 'disabled')) return res
def bond_direction_submenu_contents(bond, quat): #bruce 070415 res = [] left_atom = bond_left_atom(bond, quat) direction = bond.bond_direction_from(left_atom) ## # order will be: if this bond has a dir: this dir, opp dir, unset; ## # or if not: unset, right, left. So current dir is always first. Not sure this is good! In fact, I'm sure it's not! ## if direction: ## dir_order = [direction, - direction, 0] ## else: ## dir_order = [0, 1, -1] dir_order = [1, -1, 0] for dir in dir_order: text = "make it %s" % _BOND_DIR_NAMES[dir] # how do we say concisely: # "make the bond dirs all one way along entire strand, # so they're going (eg) right, when they pass thru this bond"? if dir == direction: text += " (like this bond)" #e also use checkmark, or is that confusing since it's not a noop? for now, use it. command = ( lambda _guard=None, bond=bond, left_atom=left_atom, dir=dir: bond. set_bond_direction_from(left_atom, dir, propogate=True)) checkmark = (dir == direction) and 'checked' or None item = (text, command, checkmark) res.append(item) res.append(('set to fit minor groove (not implemented)', noop, 'disabled')) return res
def bond_menu_section(bond, quat=Q(1, 0, 0, 0)): """ Return a menu_spec subsection for displaying info about a highlighted bond, changing its bond_type, offering commands about it, etc. If given, use the quat describing the rotation used for displaying it to order the atoms in the bond left-to-right (e.g. in text strings). """ res = [] res.append((bonded_atoms_summary(bond, quat=quat), noop, 'disabled')) res.extend(_bond_type_menu_section(bond)) if bond.is_directional(): ### REVIEW: Do we want to do this for open bonds, after mark's 071014 change # which allows them here? Or do we want "and not bond.is_open_bond()"? # (BTW, I'm not sure this gets called at all, for open bonds.) # Guess: open bonds would be safe here, so allow them, though I'm # not sure it's always a good idea. Caveat: if we treat them as non-directional # when the base atom has three or more directional bonds, we should probably # make that exception here too -- probably using a higher-level method in place # of is_directional, namely directional_bond_chain_status for both atoms in bond. # We'd want a new method on bond to call that for both atoms and look at the # results (perhaps there's already code like that elsewhere). Without this, # we may get a bug if a user can try to change direction on an open bond # that hits a strand but is not in it. But since I suspect the UI never allows # an open bond here, I won't bother to write that code just yet. [bruce 071016] submenu_contents = bond_direction_submenu_contents(bond, quat) left_atom = bond_left_atom( bond, quat) # same one that comes first in bonded_atoms_summary #e ideally, for mostly vertical bonds, we'd switch to an up/down distinction for the menu text about directions #e and whatever the direction names, maybe we should explore farther along the strand to see what they are... # unless it hairpins or crosses over... hmm. current_dir = bond.bond_direction_from(left_atom) current_dir_str = _BOND_DIR_TEXTS[current_dir] text = "strand direction (%s)" % current_dir_str item = (text, submenu_contents) res.append(item) return res
def getToolTipInfoForBond(self, bond): """ Tooltip information when the cursor is over a strand bond. As of 2008-11-09, it gives the information in the following form: """ #Bond direction will always be atm1 --> atm2 #@see: Bond.bond_direction_from() atm1 = bond.atom1 atm2 = bond.atom2 strandInfo = "" if not (atm1 and atm2): strandInfo = self.getDefaultToolTipInfo() return strandInfo threePrimeEndAtom = self.get_three_prime_end_base_atom() fivePrimeEndAtom = self.get_five_prime_end_base_atom() allAtoms = self.get_strand_atoms_in_bond_direction(filterBondPoints = True) tooltipDirection = "3<--5" left_atom = bond_left_atom(bond, quat = self.assy.glpane.quat) right_atom = bond.other(left_atom) if bond.bond_direction_from(left_atom) == 1: tooltipDirection = "5-->3" else: tooltipDirection = "3<--5" left_atm_index = None try: left_atm_index = allAtoms.index(left_atom) except: print_compact_traceback("bug in getting strand info string "\ "atom %s not in list"%left_atom) if left_atm_index: #@BUG: The computation of numOfBases_next_crossover_5prime and #numOfBases_next_crossover_3prime is wrong in some cases. So, #that information is not displayed. numOfBases_next_crossover_5prime, numOfBases_next_crossover_3prime = \ self._number_of_atoms_before_next_crossover( left_atom, tooltipDirection = tooltipDirection) if threePrimeEndAtom and fivePrimeEndAtom: if tooltipDirection == "3<--5": numOfBasesDown_3PrimeDirection = len(allAtoms[left_atm_index:]) #Note: This does not include atm1 , which is intentional-- numOfBasesDown_5PrimeDirection = len(allAtoms[:left_atm_index]) ##strandInfo += " 3' < " + str(numOfBasesDown_3PrimeDirection) + "/" + str(numOfBases_next_crossover_3prime) strandInfo += " 3' < " + str(numOfBasesDown_3PrimeDirection) strandInfo += " --(%s)-- "%(len(allAtoms)) ##strandInfo += str(numOfBases_next_crossover_5prime) + "/" + str(numOfBasesDown_5PrimeDirection) + " < 5'" strandInfo += str(numOfBasesDown_5PrimeDirection) + " < 5'" else: numOfBasesDown_3PrimeDirection = len(allAtoms[left_atm_index + 1:]) #Note: This does not include atm1 , which is intentional-- numOfBasesDown_5PrimeDirection = len(allAtoms[:left_atm_index + 1]) ##strandInfo += " 5' > " + str(numOfBasesDown_5PrimeDirection) + "/" + str(numOfBases_next_crossover_5prime) strandInfo += " 5' > " + str(numOfBasesDown_5PrimeDirection) strandInfo += " --(%s)-- "%(len(allAtoms)) ##strandInfo += str(numOfBases_next_crossover_3prime) + "/" + str(numOfBasesDown_3PrimeDirection) + " > 3'" strandInfo += str(numOfBasesDown_3PrimeDirection) + " > 3'" #Make sure that symbol like > are converted to html strandInfo = quote_html(strandInfo) return strandInfo