środa, maja 21, 2008

E211

Lately I've been showing Phosphoros, a friend of mine, some Pymol features especially the basics of structure modification. I thought I know almost everything about it since there's no much to learn about it, but then he asked me a question I had no answer for.
- How do you make this aromatic rings look so like in this indigo molecule you've showed me earlier?

The point is that some chemical file formats save the information about the delocalized bonds (like MDL Molfile) and some not (PDB for example). If you load a molecule with delocalized bonds into Pymol the program displays them as dashed lines/sticks. Don't know why this feature was not implemented into the internal builder, but since Pymol can represent these bonds you could probably also convert single and double bonds to delocalized. Following this idea I wrote a small wizard for changing the bond order.

resonance.py(Toggle Plain Text)

# -*- coding: utf-8 -*-

# -----------------------------------------------------------------------
# resonance.py - delocalized bonds wizard for Pymol version 1.0
# -----------------------------------------------------------------------

# Copyright (C) 2008 by Lightnir - lightnir@gmail.com

# This script is free software; you can redistribute it and#or modify
# it under the terms of the GNU Library General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.

# This script is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU Library General Public
# License along with this program; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.


from pymol.wizard import Wizard
from pymol import cmd
import pymol
import types
import string
import traceback

class Resonanse(Wizard):

    def __init__(self):
 cmd.unpick();
        Wizard.__init__(self)
 
        # some attributes to do with picking
 self.error = None
        self.pick_count = 0
        self.object_prefix = "res"

        self.selection_mode = cmd.get_setting_legacy("mouse_selection_mode")
        cmd.set("mouse_selection_mode",0) # set selection mode to atomic
        cmd.deselect()
  
# generic set routines

    def get_prompt(self):
        self.prompt = None
        if self.pick_count==0:
     self.prompt = [ 'Pick first atom...']
        elif self.pick_count==1:
            self.prompt = [ 'Pick second atom...' ]
        if self.error!=None:
            self.prompt.append(self.error)
        return self.prompt

    def get_panel(self):
        return [
            [ 1, 'Delocalized bonds', '' ],
            [ 2, 'Done', 'cmd.set_wizard()' ]
            ]

    def cleanup(self):
        self.clear()
 cmd.set("mouse_selection_mode",self.selection_mode) # restore selection mode

    def clear(self):
        cmd.delete(self.object_prefix+"*")

    def do_select(self, name):
        # "edit" only this atom, and not others with the object prefix
        try:
            cmd.edit("%s and not %s*" % (name, self.object_prefix))
            self.do_pick(0)
        except pymol.CmdException, pmce:
            print pmce

    def pickNextAtom(self, atom_name):
        cmd.select(atom_name, "(pk1)")
        cmd.unpick()
        self.pick_count += 1
        self.error = None
        cmd.refresh_wizard()

    def do_pick(self, picked_bond):
 
        # this shouldn't actually happen if going through the "do_select"
        if picked_bond:
            self.error = "Error: please select bonds, not atoms"
            print self.error
            return
 
        atom_name = self.object_prefix + str(self.pick_count)
        if self.pick_count < 1:
            self.pickNextAtom(atom_name)
        else:
     self.pickNextAtom(atom_name)
     cmd.unbond(self.object_prefix+"0",self.object_prefix+"1")
     cmd.bond(self.object_prefix+"0",self.object_prefix+"1",4)
     self.clear
     cmd.delete(self.object_prefix+"*")
     self.pick_count = 0
     cmd.unpick()
 cmd.refresh_wizard()

Just place the script in the wizrads directory (pymol_install_directory/modules/pymol/wizard). You can call it now by typing in the pymol command line:
wizard resonance If you are as lazy as I am you can go further and add yourself a menu shortcut for this. Open the file pymol_install_directory/modules/pmg_tk/skins/normal/__init__.py (make a backup first) and locate these lines:
self.menuBar.addmenuitem('Wizard', 'command', 'Pair Fitting',
                                 label='Pair Fitting',
                                 command = lambda s=self: s.cmd.do("_ wizard pair_fit"))
and add this code after:
self.menuBar.addmenuitem('Wizard', 'command', 'Resonance',
                                 label='Resonance',
                                 command = lambda s=self: s.cmd.do("_ wizard resonance"))
After Pymol restart a new option called "Resonance" in the wizard menu should be available. The image at the beginning of this post shows sodium benzoate, a common food preservative (E211). The whole molecule was entirely build in Pymol. First using the internal builder and then using the resonance wizard for changing bond order of the aromatic ring and the carboxylic group.
The wizard works, however I've found a bug. If you pick an atom, then click somewhere in the main window(for example the builder button) and than want to pick the second atom Pymol rises an exception. Let me know if you know the reason of this - I'm biting my fingers on it and can't find a solution for this.

Brak komentarzy: