示例#1
0
 def widget_msg(self, msg, options):
     #e improved timestamp?
     #e use html for color etc? [some callers put this directly in the msg, for now]
     _quote_html = options.pop(
         'quote_html', False
     )  #bruce 060126 new feature, improving on message_no_html interface ##k
     if _quote_html:
         msg = quote_html(msg)
     _color = options.pop('color', None)
     if _color:
         #bruce 060126 new feature; for now only permits 4 fixed color name strings;
         # should someday permit any color name (in any format) or object (of any kind) #e
         funcs = {
             'green': greenmsg,
             'orange': orangemsg,
             'red': redmsg,
             'gray': graymsg
         }
         func = funcs[
             _color]  # any colorname not in this dict is an exception (ok for now)
         msg = func(msg)
     _compact_stack = options.pop('compact_stack', "")  #bruce 060720
     if _compact_stack:
         msg += graymsg("; history.message() call stack: %s" %
                        quote_html(_compact_stack))
     # any unrecognized options are warned about below
     self._print_msg(msg)
     if options:
         msg2 = "fyi: bug: widget_msg got unsupported options: %r" % options
         print msg2  # too important to only print in the history file --
         # could indicate that not enough info is being saved there
         self._print_msg(msg2)
     return
示例#2
0
 def widget_msg(self, msg, options):
     #e improved timestamp?
     #e use html for color etc? [some callers put this directly in the msg, for now]
     _quote_html = options.pop('quote_html', False) #bruce 060126 new feature, improving on message_no_html interface ##k
     if _quote_html:
         msg = quote_html(msg)
     _color = options.pop('color', None)
     if _color:
         #bruce 060126 new feature; for now only permits 4 fixed color name strings;
         # should someday permit any color name (in any format) or object (of any kind) #e
         funcs = {'green':greenmsg, 'orange':orangemsg, 'red':redmsg, 'gray':graymsg}
         func = funcs[_color] # any colorname not in this dict is an exception (ok for now)
         msg = func(msg)
     _compact_stack = options.pop('compact_stack', "") #bruce 060720
     if _compact_stack:
         msg += graymsg("; history.message() call stack: %s" % quote_html(_compact_stack))
     # any unrecognized options are warned about below
     self._print_msg(msg)
     if options:
         msg2 = "fyi: bug: widget_msg got unsupported options: %r" % options
         print msg2 # too important to only print in the history file --
             # could indicate that not enough info is being saved there
         self._print_msg(msg2)
     return
示例#3
0
 def widget_html(self):  ###@@@ experimental. This sort of works...
     ###e also escape < > and & ? not appropriate when self.text contains html, as it sometimes does!
     # maybe it's best in the long run to just require the source messages to escape these if they need to.
     # if not, we'll need some sort of hueristic to escape them except when part of well-formatted tags.
     return graymsg(self.widget_text_header(
     )) + self.text  #e could remove graymsg when what's inside it is ""
示例#4
0
 def graymsg(self, msg, **kws):  #bruce 080201
     """
     Shorthand for self.message(graymsg(msg), <options>).
     """
     self.message(graymsg(msg), **kws)
     return
def _kill_Pl_and_rebond_neighbors_0(atom):

    # Note: we optimize for the common case (nothing wrong, conversion happens)

    ### NOTE: many of the following checks have probably also been done by
    # calling code before we get here. Optimize this sometime. [bruce 080408]

    bonds = atom.bonds

    # change these during the loop
    bad = False
    saw_plus = saw_minus = False
    num_bondpoints = 0
    neighbors = []
    direction = None # KLUGE: set this during loop, but use it afterwards too

    for bond in bonds:
        other = bond.other(atom)
        neighbors += [other]
        element = other.element
        direction = bond.bond_direction_from(atom)

        if direction == 1:
            saw_plus = True
        elif direction == -1:
            saw_minus = True

        if element is Singlet:
            num_bondpoints += 1
        elif element.symbol in ('Ss3', 'Ss5'):
            # [in the 080408 copy, will often be one of each!]
            pass
        else:
            bad = True
        continue

    if not (len(bonds) == 2 and saw_minus and saw_plus and num_bondpoints < 2):
        bad = True

    if bad:
        summary_format = \
            "Warning: dna updater left [N] Pl5 pseudoatom(s) unconverted"
        env.history.deferred_summary_message( redmsg(summary_format) ) # orange -> red [080408]
        return

    del saw_plus, saw_minus, num_bondpoints, bad

    # Now we know it is either Ss-Pl-Ss or X-Pl-Ss,
    # with fully set and consistent bond_directions.

    # But we'd better make sure the neighbors are not already bonded!
    #
    # (This is weird enough to get its own summary message, which is red.
    #  Mild bug: we're not also counting it in the above message.)
    #
    # (Note: there is potentially slow debug code in rebond which is
    #  redundant with this. It does a few other things too that we don't
    #  need, so if it shows up in a profile, just write a custom version
    #  for this use. ### OPTIM)

    n0, n1 = neighbors
    del neighbors

    b0, b1 = bonds
    del bonds # it might be mutable and we're changing it below,
        # so be sure not to use it again

    if find_bond(n0, n1):
        summary_format = \
            "Error: dna updater noticed [N] Pl5 pseudoatom(s) whose neighbors are directly bonded"
        env.history.deferred_summary_message( redmsg(summary_format) )
        return

    # Pull out the Pl5 and directly bond its neighbors,
    # reusing one of the bonds for efficiency.
    # (This doesn't preserve its bond_direction, so set that again.)

    # Kluge: the following code only works for n1 not a bondpoint
    # (since bond.bust on an open bond kills the bondpoint),
    # and fixing that would require inlining and modifying a
    # few Atom methods,
    # so to avoid this case, reverse everything if needed.
    if n1.element is Singlet:
        direction = - direction
        n0, n1 = n1, n0
        b0, b1 = b1, b0
        # Note: bonds.reverse() might modify atom.bonds itself,
        # so we shouldn't do it even if we didn't del bonds above.
        # (Even though no known harm comes from changing an atom's
        #  order of its bonds. It's not reviewed as a problematic
        #  change for an undo snapshot, though. Which is moot here
        #  since we're about to remove them all. But it still seems
        #  safer not to do it.)
        pass

##    # save atom_posn before modifying atom (not known to be needed), and
    # set atom.atomtype to avoid bugs in reguess_atomtype during atom.kill
    # (need to do that when it still has the right number of bonds, I think)
##    atom_posn = atom.posn()
    atom.atomtype # side effect: set atomtype

    old_nbonds_neighbor1 = len(n1.bonds) # for assert
    old_nbonds_neighbor0 = len(n0.bonds) # for assert

    b1.bust(make_bondpoints = False) # n1 is now missing one bond; so is atom
        # note: if n1 was a Singlet, this would kill it (causing bugs);
        # see comment above, where we swap n1 and n0 if needed to prevent that.
    b0.rebond(atom, n1) # now n1 has enough bonds again; atom is missing both bonds

    assert len(atom.bonds) == 0, "Pl %r should have no bonds but has %r" % (atom, atom.bonds)
    assert not atom.killed()

    assert len(n1.bonds) == old_nbonds_neighbor1
    assert len(n0.bonds) == old_nbonds_neighbor0

##    # KLUGE: we know direction is still set to the direction of b1 from atom
##    # (since b1 was processed last by the for loop above),
##    # which is the overall direction from n0 thru b0 to atom thru b1 to n1,
##    # so use this to optimize recording the Pl info below.
##    # (Of course we really ought to just rewrite this whole conversion in Pyrex.)
##
##    ## assert direction == b1.bond_direction_from(atom) # too slow to enable by default
##
##    # not needed, rebond preserves it:
##    ## b0.set_bond_direction_from(n0, direction)
##    ## assert b0.bond_direction_from(n0) == direction # too slow to enable by default
##
##    # now save the info we'll need later (this uses direction left over from for-loop)
##
##    if n0.element is not Singlet:
##        _save_Pl_info( n0, direction, atom_posn)
##
##    if n1.element is not Singlet:
##        _save_Pl_info( n1, - direction, atom_posn) # note the sign on direction

    # get the Pl atom out of the way

    atom.kill()
##        # (let's hope this happened before an Undo checkpoint ever saw it --
##        #  sometime verify that, and optimize if it's not true)

    if 0: # for now; bruce 080413 356pm
        # summarize our success -- we'll remove this when it becomes the default,
        # or condition it on a DEBUG_DNA_UPDATER flag ###

        debug_flags.DEBUG_DNA_UPDATER # for use later

        summary_format = \
            "Note: dna updater removed [N] Pl5 pseudoatom(s) while converting to PAM3+5"
        env.history.deferred_summary_message( graymsg(summary_format) )

    return
示例#6
0
def _convert_Pl5(atom):
    """
    If atom's neighbors have the necessary structure
    (Ss-Pl-Ss or X-Pl-Ss, with fully set and consistent bond_directions),
    save atom's coordinates on its Ss neighbors,
    arrange for them to postprocess that info later,
    and then kill atom, replacing its bonds with a direct bond
    between its neighbors (same bond_direction).

    Summarize results (ok or error) to history.
    """

    ### NOTE: the code starting from here has been copied and modified
    #### into a new function in pam3plus5_ops.py by bruce 080408.
    
    assert atom.element is Pl5 # remove when works

    # could also assert no dna updater error

    # Note: we optimize for the common case (nothing wrong, conversion happens)

    bonds = atom.bonds
    
    # change these during the loop
    bad = False
    saw_plus = saw_minus = False
    num_bondpoints = 0
    neighbors = []
    direction = None # KLUGE: set this during loop, but use it afterwards too

    for bond in bonds:
        other = bond.other(atom)
        neighbors += [other]
        element = other.element
        direction = bond.bond_direction_from(atom)
        
        if direction == 1:
            saw_plus = True
        elif direction == -1:
            saw_minus = True
        
        if element is Singlet:
            num_bondpoints += 1
        elif element.symbol in ('Ss3', 'Ss5'):
            pass
        else:
            bad = True
        continue

    if not (len(bonds) == 2 and saw_minus and saw_plus and num_bondpoints < 2):
        bad = True

    if bad:
        summary_format = \
            "Warning: dna updater left [N] Pl5 pseudoatom(s) unconverted"
        env.history.deferred_summary_message( orangemsg(summary_format) )
        return

    del saw_plus, saw_minus, num_bondpoints, bad    

    # Now we know it is either Ss-Pl-Ss or X-Pl-Ss,
    # with fully set and consistent bond_directions.
    
    # But we'd better make sure the neighbors are not already bonded!
    #
    # (This is weird enough to get its own summary message, which is red.
    #  Mild bug: we're not also counting it in the above message.)
    #
    # (Note: there is potentially slow debug code in rebond which is
    #  redundant with this. It does a few other things too that we don't
    #  need, so if it shows up in a profile, just write a custom version
    #  for this use. ### OPTIM)

    n0, n1 = neighbors
    del neighbors

    b0, b1 = bonds
    del bonds # it might be mutable and we're changing it below,
        # so be sure not to use it again
    
    if find_bond(n0, n1):
        summary_format = \
            "Error: dna updater noticed [N] Pl5 pseudoatom(s) whose neighbors are directly bonded"
        env.history.deferred_summary_message( redmsg(summary_format) )
        return
        
    # Pull out the Pl5 and directly bond its neighbors,
    # reusing one of the bonds for efficiency.
    # (This doesn't preserve its bond_direction, so set that again.)

    # Kluge: the following code only works for n1 not a bondpoint
    # (since bond.bust on an open bond kills the bondpoint),
    # and fixing that would require inlining and modifying a
    # few Atom methods,
    # so to avoid this case, reverse everything if needed.    
    if n1.element is Singlet:
        direction = - direction
        n0, n1 = n1, n0
        b0, b1 = b1, b0
        # Note: bonds.reverse() might modify atom.bonds itself,
        # so we shouldn't do it even if we didn't del bonds above.
        # (Even though no known harm comes from changing an atom's
        #  order of its bonds. It's not reviewed as a problematic
        #  change for an undo snapshot, though. Which is moot here
        #  since we're about to remove them all. But it still seems
        #  safer not to do it.)
        pass

    # save atom_posn before modifying atom (not known to be needed),
    # and set atom.atomtype to avoid bugs in reguess_atomtype during atom.kill
    # (need to do that when it still has the right number of bonds, I think)
    atom_posn = atom.posn()
    atom.atomtype # side effect: set atomtype

    old_nbonds_neighbor1 = len(n1.bonds) # for assert
    old_nbonds_neighbor0 = len(n0.bonds) # for assert
    
    b1.bust(make_bondpoints = False) # n1 is now missing one bond; so is atom
    b0.rebond(atom, n1) # now n1 has enough bonds again; atom is missing both bonds

    assert len(atom.bonds) == 0, "Pl %r should have no bonds but has %r" % (atom, atom.bonds)
    assert not atom.killed()

    assert len(n1.bonds) == old_nbonds_neighbor1
    assert len(n0.bonds) == old_nbonds_neighbor0

    # KLUGE: we know direction is still set to the direction of b1 from atom
    # (since b1 was processed last by the for loop above),
    # which is the overall direction from n0 thru b0 to atom thru b1 to n1,
    # so use this to optimize recording the Pl info below.
    # (Of course we really ought to just rewrite this whole conversion in Pyrex.)
    
    ## assert direction == b1.bond_direction_from(atom) # too slow to enable by default

    # not needed, rebond preserves it:
    ## b0.set_bond_direction_from(n0, direction)
    ## assert b0.bond_direction_from(n0) == direction # too slow to enable by default
        
    # now save the info we'll need later (this uses direction left over from for-loop)

    if n0.element is not Singlet:
        _save_Pl_info( n0, direction, atom_posn)
    
    if n1.element is not Singlet:
        _save_Pl_info( n1, - direction, atom_posn) # note the sign on direction

    # get the Pl atom out of the way

    atom.kill()
        # (let's hope this happened before an Undo checkpoint ever saw it --
        #  sometime verify that, and optimize if it's not true)
    
    # summarize our success -- we'll remove this when it becomes the default,
    # or condition it on a DEBUG_DNA_UPDATER flag ###

    debug_flags.DEBUG_DNA_UPDATER # for use later
    
    summary_format = \
        "Note: dna updater converted [N] Pl5 pseudoatom(s)"
    env.history.deferred_summary_message( graymsg(summary_format) )
    
    return
示例#7
0
 def widget_html(self): ###@@@ experimental. This sort of works... 
     ###e also escape < > and & ? not appropriate when self.text contains html, as it sometimes does!
     # maybe it's best in the long run to just require the source messages to escape these if they need to.
     # if not, we'll need some sort of hueristic to escape them except when part of well-formatted tags.
     return graymsg(self.widget_text_header()) + self.text #e could remove graymsg when what's inside it is ""
示例#8
0
 def graymsg(self, msg, **kws): #bruce 080201
     """
     Shorthand for self.message(graymsg(msg), <options>).
     """
     self.message(graymsg(msg), **kws)
     return