poniedziałek, maja 26, 2008

Slow motion realms

Ostatnio zapragnąłem znów obejrzeć sobie Teslę. Kocham to słonecznikowe demo za świetne połączenie wizualizacji z ambientową muzyką. Anyway, to właśnie muzyka autorstwa Radixa i Lluvii sprawiła, że jakoś dziwnym trafem wylądowałem na stronie kompilacji demoscenowej muzyki pt. Demovibes. Jeśli ktoś tak jak ja gustuje w muzyce gatunku elektro, ambient, chillout, alternative to polecam składankę. Szczególnie podczas nocnego programowania w pythonie. Ponieważ album jest w formie jednego wielkiego pliku mp3 + plik cue (podział na tracki) polecam tą wtyczkę do Winampa. Szkoda tylko, że Amarok jeszcze nie ma takiej funkcjonalności :-(

środa, maja 21, 2008


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
# 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):
        # 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
# 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:
        return self.prompt

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

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

    def clear(self):

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

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

    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
        atom_name = self.object_prefix + str(self.pick_count)
        if self.pick_count < 1:
     self.pick_count = 0

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',
                                 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.

niedziela, maja 18, 2008

In the shadow of the molecule

If you do a lot molecule visualization in Pymol like I do, then after a while you'll probably ask yourself how to cut your working time. For this I wrote myself some scripts for batched molecule rendering. But today I had another idea. The most common animation I do is rotating a molecule along the Y axis. It doesn't matter if it's done by Pymols intern commands or by using the movie.py or emovie.py scripts - every time the molecule gets rotated all the coordinates (atoms, surface & mesh points) have to get recalculated. And that's CPU expensive if you have a slower machine or just a lot of coordinates. If you look at the ray commands API , then you'll notice the angle parameter. It can be used to render a stereo pair of images both looked at a different angle. But why just to render two images, when you can render a sequence of images of a full rotation along the Y axis? To test how does it look like a wrote myself this little script:

rsd.py(Toggle Plain Text)

from pymol import *
from time import *

# Variables

width    = 500
height   = 375
step     = 5
angle    = 360
molecule = 'morphine.mol'

# Main settings

logfile = open("rsd.log","w")
logfile.write('Script started '+strftime("%Y-%m-%d %H:%M:%S"+"\n"))

cmd.load(molecule,"molecule")       # Load molecule
cmd.hide("everything","molecule")   # Hide everything
cmd.show("surface"   ,"molecule")   # Show surface
cmd.set("surface_quality",3)        # Set a high surface resolution
util.ray_shadows('heavy')           # Set heavy shadows drop
cmd.zoom("all",1)                   # Zoom out
util.cba(29,"molecule")             # Apply color scheme

# Rendering A (rotating the camera)

logfile = open("rsd.log","a")
logfile.write('Starting rendering A => '+strftime("%Y-%m-%d %H:%M:%S",gmtime(t))+"\n")


while i<angle:
    name = "%s%.4d" % ("molecule_A_",i)

logfile = open("rsd.log","a")
logfile.write('Stoping  rendering A => '+strftime("%Y-%m-%d %H:%M:%S",gmtime(t2))+"\n")
logfile.write('Summary: '+strftime("%H hours, %M minutes, ",gmtime(diff))+str(diff % 60)+' seconds taken to render '+str(angle/step)+' frames'+"\n")


# Rendering B (rotating the model)

logfile = open("rsd.log","a")
logfile.write('Starting rendering B => '+strftime("%Y-%m-%d %H:%M:%S",gmtime(t))+"\n")

while i<angle:
    name = "%s%.4d" % ("molecule_B_",i)

logfile = open("rsd.log","a")
logfile.write('Stoping  rendering B => '+strftime("%Y-%m-%d %H:%M:%S",gmtime(t2))+"\n")
logfile.write('Summary: '+strftime("%H hours, %M minutes, ",gmtime(diff))+str(diff % 60)+' seconds taken to render '+str(angle/step)+' frames'+"\n")

# End log

logfile = open("rsd.log","a")
logfile.write('Script stoped '+strftime("%Y-%m-%d %H:%M:%S")+"\n")
And then run it with Pymol as a background tread like this:
pymol -qcr rsd.py
Note that the morphine.mol file used in this script have to be in the same directory as the script. What exactly does the script? First it renders a full-angle rotation of the "camera" along the Y axis using a five degree step. Second it renders a full-angle rotation of the molecule (morphine in my case) along the Y axis also using a five degree step. The output is dumped into a log file and the rendered images are saved in the current directory. The final result looks like this:
(Download video)
Here's the output of my log file(rsd.log):
Script started 2008-05-18 15:27:04
Starting rendering A => 2008-05-18 13:27:04
Stoping  rendering A => 2008-05-18 13:34:18
Summary: 00 hours, 07 minutes, 14.7353949547 seconds taken to render 72 frames
Starting rendering B => 2008-05-18 13:34:18
Stoping  rendering B => 2008-05-18 14:04:11
Summary: 00 hours, 29 minutes, 52.1074898243 seconds taken to render 72 frames
Script stoped 2008-05-18 16:04:11
I was amazed by myself when i looked at this. Not only I created an interesting animation effect, but also cut down the rendering time by four. For small molecules the difference in time taken to render is not so visible, but if you use a bigger model like a protein or increase the quality of displayed model (in my case more detailed surface) you'll better take a longer coffee break or go for a longer walk. Sure, the two renders looks different, but only because I'd set Pymol to render heavy dropped shadows. By default you don't see a difference or a slightly one. I think I'll add this method of rendering to my batch rendering scripts. ]:)

środa, maja 14, 2008

Elevator music

Mam dość specyficzne poczucie humoru - czarne. Przykład? A proszę - dyskusja w windzie po dzisiejszym seminarium magisterskim:
- Wiesz czego nam w tej windzie instytutowej brakuje?
- Nie, czego?
- Muzyki takiej jak mają te windy hotelowe. Wciskasz piątkę i jadąc na organikę z głośnika leci "Im on the highway to hell... highway to hell". ]:D
- ...
Tak po namyśle to stwierdzam, że jeszcze lepsza byłaby wersja z wyświetlaczem gdzie leciałby ten filmik.

niedziela, maja 11, 2008


And you can't fight the tears that ain't coming
Or the moment of truth in your lies
When everything seems like the movies
Yeah you bleed just to know your alive

And I don't want the world to see me
Cause I don't think that they'd understand
When everything's made to be broken
I just want you to know who I am

~Iris by The Goo Goo Dolls

Zazdroszczę kotu, że może zwinąć się w kłębek kiedy tylko chce i zapomnieć o świecie...

poniedziałek, maja 05, 2008


Bycie cieniem ma swoje uroki. Najszybszemu biegaczowi cień nie ustąpi na krok. Cień jest niestrudzony, nie zna głodu, ni zmęczenia. Zawsze jest w centrum rozmowy przysłuchując się najskrytszym sekretom, a jednak nikt nie zwraca na niego uwagi. Po prostu milczy i obserwuje...

Przez ten długi weekend majowy byłem jak taki właśnie cień - milczący i obserwujący. Miałem sporo czasu na refleksje nad osobami z którymi utrzymuje kontakty. Spojrzałem na znajomych nieco bardziej z dystansu i oczyma innych ludzi. Tak po prostu. Nie komentując. Bez wyrobionego zdania. Patrząc neutralnie z każdej możliwej tylko strony. Muszę przyznać, że zaskoczyło mnie to co zobaczyłem. Prawdziwych przyjaciół poznaje się podobno w biedzie. Ja myślę, że to prawdziwe oblicze ludzi poznaje się dopiero wtedy jak spojrzymy na nich obiektywnie i z dystansu. Zadziwiające jak przez takie spojrzenie bliscy stają się tylko znajomymi, znajomi obcymi, a obcy znajomymi. Nic nie trwa wiecznie. Pozostaje prawda, którą trzeba przyjąć taką jaka jest.
Staff Leopold


Miałem wielkie pogody i chmurne niewczasy,
Krok mój, zdobywczy niegdyś, zmienia się w obrończy,
Nie wróżą mi zwycięstwa me z czasem zapasy,
Zostaje prosta prawda, że wszystko się kończy.

Lecz chociaż zgasło lato i jesień wnet minie,
Zmierzch mi się nie uśmiecha w rozdźwięku udręce,
W sobie zestrajam sprzeczny ten świat, Apollinie,
Boś chyba po to dał mi lutnię w ręce.

piątek, maja 02, 2008

The cat, the wet & the wound

W końcu nie wytrzymałem tego warczenia Hildy(wiem, że ciężko sobie to wyobrazić jak kot warczy, ale to najbliższe określenie jakie mi przychodzi do głowy kiedy słyszę odgłosy jakie z siebie wydaje) przy szukaniu sobie kąta po pokoju. Dziś zabrałem ją do weterynarza. Jak się okazało ma krwiak oraz kontuzję u nasady ogona, w związku z czym nie ma nad nim kontroli. Kamień z serca mi spadł jak się okazało, że ma spore szanse z tego wyjść. Jeśli jednak nie(odpukać!) to trzeba będzie usunąć ogon. Żal mi futrzaka, bo wychodzi na to że jeszcze sobie trochę poleży zanim wrócą mu siły. Przy okazji się okazało, że ma świerzb uszny oraz warto by podać coś na odrobaczenie. I tu zaczął się cyrk. Po raz kolejny mój kot udowodnił, że jej imię jest jak najbardziej adekwatne:
- Ten drugi zastrzyk ją zaboli, więc mamy dwie opcje. Jeśli pobiegnie po zastrzyku to pozwolimy jej na to albo Pan ją złapie i uspokoi, bo czasem to kotom pomaga. Gotowi? Uwaga! No maleńka, to cię teraz trochę poszczypie... O! Chyba chce iść do Pana. Niech pan ją weźmie.
- Arrrrr!! Grrrr!! Sssss...

No i takim oto sposobem dostałem od weterynarza coś na dezynfekcję rany oraz Altacet do okładów...