Source code for schrodinger.application.bioluminate.workspacelabeler

"""
A module containing a class for labeling atoms in the workspace.

Copyright Schrodinger, LLC. All rights reserved.

"""

from schrodinger.structutils import analyze

try:
    from schrodinger.maestro import maestro
except ImportError:
    maestro = None

SAVE_FMT_PROP = 's_bioluminate_saved_label_format'
DEFAULT_OPTIONS = {
    '1charge': 'FALSE',
    '1chargeformatstring': '%C1.3',
    '2charge': 'FALSE',
    '2chargeformatstring': '%C2.3',
    'acolor': 'TRUE',
    'anum': 'FALSE',
    'anumformatstring': '%NU',
    'atomicnumber': 'FALSE',
    'atomname': 'FALSE',
    'atomnameformatstring': '%AT',
    'atype': 'FALSE',
    'atypeformatstring': '%TY',
    'chain': 'FALSE',
    'chainformatstring': '%CH',
    'chirality': 'FALSE',
    'chiralityformatstring': '%CY',
    'cindex': '2',
    'compositionfields': '',
    'dmsopka': 'FALSE',
    'dmsopkaformatstring': '%DP',
    'element': 'FALSE',
    'elementformatstring': '%EL',
    'entryname': 'FALSE',
    'entrynameformatstring': '%EN',
    'entrypropertynames': '',
    'font': '',
    'font_size': '14',
    'font_style': 'bold',
    'formalcharge': 'FALSE',
    'formalchargeformatstring': '%FC',
    'growname': 'FALSE',
    'grownameformatstring': '%GN',
    'h2opka': 'FALSE',
    'h2opkaformatstring': '%HP',
    'headings': 'FALSE',
    'isotopenumber': 'FALSE',
    'isotopenumformatstring': '%IN',
    'keeplabels': 'on_top',
    'mode': 'replace',
    'molnum': 'FALSE',
    'molnumentry': 'FALSE',
    'molnumentryformatstring': '%ME',
    'numentry': 'FALSE',
    'numentryformatstring': '%NE',
    'nummol': 'FALSE',
    'nummolformatstring': '%NM',
    'occupancy': 'FALSE',
    'occupancyformatstring': '%OC',
    'oneletter': 'FALSE',
    'pdbname': 'FALSE',
    'pdbnameformatstring': '%PA',
    'reapply': 'FALSE',
    'reapplylabels': 'FALSE',
    'resname': 'FALSE',
    'resnameformatstring': '%RT',
    'resnum': 'FALSE',
    'resnumformatstring': '%RN',
    'separator': '',
    'showhisotopes': 'TRUE',
    'showlabel': 'FALSE',
    'stereochemistry': 'FALSE',
    'stereochemistryformatstring': '%ST',
    'title': 'FALSE',
    'titleformatstring': '%ET',
    'user': 'FALSE',
    'useratompropertyformatstring': '%UA',
    'utext': '',
    'xoffset': '0.05',
    'xyz': 'FALSE',
    'xyzformatstring': '%XY',
    'yoffset': '-0.15'
}


[docs]def removeBadOptions(): """ Test each option in DEFAULT_OPTIONS and remove any bad or deprecated ones. """ badoptions = set() for option in DEFAULT_OPTIONS: try: maestro.get_command_option('labelatom', option) except KeyError: #If an option has been deprecated or removed badoptions.add(option) for option in badoptions: del DEFAULT_OPTIONS[option]
if maestro: removeBadOptions()
[docs]class WorkspaceLabeler(object): """ Class with methods for manipulating workspace atom labels. """
[docs] def __init__(self): self.saved_options = {}
[docs] def resetLabelOptions(self): """ Resets Maestro's internally persistent label options to ensure consistent behavior of the labeler regardless of intervening calls to the Maestro command 'labelatom' that might change label options. It is generally not necessary to use this command; however it could be useful when invoking custom 'labelatom' commands. """ maestro.command('labelatomfieldsnone')
[docs] def saveLabelOptions(self, options=None): """ Saves the state of all of Maestro's 'labelatom' options, generally for the purpose of changing the label options by the WorkspaceLabeler class or by other Python scripts and then changing them back to their original state. :type options: dict :param options: dictionary containing a set of options and values Default: saved_options """ if not options: options = self.saved_options for option in DEFAULT_OPTIONS: options[option] = maestro.get_command_option('labelatom', option)
[docs] def restoreLabelOptions(self, options=None): """ Restores the state of all of Maestro's 'labelatom' options from a dictionary, generally for the purpose of restoring them to their original state. :type options: dict :param options: dictionary containing a set of options and values Default: saved_options """ if not options: options = self.saved_options option_string = '' for option, value in options.items(): option_string += option + '="' + value + '" ' maestro.command('labelatom ' + option_string)
[docs] def labelAtoms(self, asl, options='atomname=TRUE'): """ Labels the specified atoms. By default labelAtoms will label with atomname, but the label content can be customized with the options parameter. :type asl: str :param asl: ASL string specifying atoms to label :type options: str :param options: An options string that will be passed to the Maestro command 'labelatom' to specify the labeling behavior. See the Maestro Command Reference for full documentation. Default: 'atomname=TRUE' """ self.saveLabelOptions() #Save persistent option state self.resetLabelOptions() asl = '(' + asl + ')' #Doesn't hurt and simplifies testing commandstring = ' '.join(('labelatom', options, asl)) maestro.command(commandstring) self.restoreLabelOptions() #Restore persistent option state
[docs] def clearLabels(self, asl): """ Deletes all labels from the specified atoms. :type asl: str :param asl: ASL string specifying atoms to remove labels from """ asl = '(' + asl + ')' #Doesn't hurt and simplifies testing maestro.command('labelclear ' + asl)
[docs] def labelResidues(self, asl, options='resname=TRUE resnum=TRUE'): """ Labels the alpha carbon of every residue that has at least one atom in the specified ASL. This means that labels may be added to atoms that are outside the ASL. By default labelAtoms will label each CA with the 3-letter residue code and residue number, but the label content can be customized with the options parameter. :type asl: str :param asl: ASL string specifying atoms that are in residues to label :type options: str :param options: An options string that will be passed to the Maestro command 'labelatom' to specify the labeling behavior. See the Maestro Command Reference for full documentation. Default: 'resname=TRUE resnum=TRUE' """ ca_asl = 'fillres(' + asl + ') AND atom. CA' self.labelAtoms(ca_asl, options)
[docs] def labelChains(self, asl, options='chain=TRUE'): """ Labels the first and last alpha carbon within the specified ASL of each chain that has at least one atom specified by the ASL. First and last CA are determined by residue numbering. By default, labelChains will label each of the two CA's with the chain name, but the label content can be customized with the options paramter. :type asl: str :param asl: ASL string specifying atoms that are in residues to label :type options: str :param options: An options string that will be passed to the Maestro command 'labelatom' to specify the labeling behavior. See the Maestro Command Reference for full documentation. Default: 'chain=TRUE' """ workspace = maestro.workspace_get() asl = '(' + asl + ') AND not water' # Don't want to label water atoms = analyze.get_atoms_from_asl(workspace, asl) firstatoms = { } # Dictionaries keyed by (entryid, chain.name) containing lastatoms = {} # (res, index), where res is (resnum, inscode) # Store the index of the highest- and lowest-index atom from each chain for atom in atoms: chainkey = (atom.entry_id, atom.chain) res = (atom.resnum, atom.inscode) try: if res < firstatoms[chainkey][0]: # First element is res-tuple firstatoms[chainkey] = (res, atom.index) except KeyError: firstatoms[chainkey] = (res, atom.index) try: if res > lastatoms[chainkey][0]: # First element is res-tuple lastatoms[chainkey] = (res, atom.index) except KeyError: lastatoms[chainkey] = (res, atom.index) # Two loops to collect all the atom indices for labeling labelatoms = set() for val in firstatoms.values(): labelatoms.add(str(val[1])) # Second element is atom index for val in lastatoms.values(): labelatoms.add(str(val[1])) # Second element is atom index self.labelResidues('atom.n ' + ' '.join(labelatoms), 'chain=TRUE')
[docs] def hideLabels(self, asl): """ Hides the labels on the specified atoms. The difference between hideLabels() and clearLabels() is that labels that have been hidden can be unhidden. Any time a hidden label is replaced or updated, the new label is visible, as in PyMol. Hidden labels can also be cleared; they do not then reappear on showLabels(). :type asl: str :param asl: ASL string specifying atoms to hide labels on """ workspace = maestro.workspace_get() atoms = analyze.evaluate_asl(workspace, asl) for atom in atoms: fmt = workspace.atom[atom].label_format # Save label_format for each atom if not fmt == '%HIDDEN': # Don't double-hide workspace.atom[atom].property[SAVE_FMT_PROP] = fmt # Maestro ignores meaningless label_format '%HIDDEN'. This is non- # standard behavior which is not guaranteed to work workspace.atom[atom].label_format = '%HIDDEN' maestro.command('labelclear ' + asl) maestro.workspace_set(workspace) # Must come after labelclear
[docs] def showLabels(self, asl): """ Unhides previously hidden labels on the specified atoms. :type asl: str :param asl: ASL string specifying atoms to unhide labels on """ workspace = maestro.workspace_get() atoms = analyze.evaluate_asl(workspace, asl) for atom in atoms: try: # Recall saved label_format fmt = workspace.atom[atom].property[SAVE_FMT_PROP] except KeyError: # Unhiding a label that has never been hidden pass # Only untouched hidden labels will retain the '%HIDDEN' format if workspace.atom[atom].label_format == '%HIDDEN': workspace.atom[atom].label_format = fmt maestro.workspace_set(workspace)