# general modules import os import sys import thread import select import exceptions import Queue import Tkinter # chimera import chimera from chimera import elements from chimera.actions import colorAtomByElement from chimera.colorTable import getColorByName class Browser: def __init__( self ): # connection log # verbosity levels: # 0 ERROR # 1 connection IO # 2 method-calls # 3+ ... #self.log_dirname = "/var/log/browser" # dirname = os.path.dirname(os.path.abspath(__file__)) parent_dirname = os.path.dirname(dirname) # self.exec_filename = os.path.join( parent_dirname, "browser" ) self.log_filename = os.path.join( dirname, "log" ) self.log_verbosity = 2 self.log = open( self.log_filename, 'w' ) self.writelog( "INIT", 0 ) # gui polling self.polling_thread = chimera.tkgui.app self.polling_intervall = 100 self.polling_queuesize = 100 self.polling_queue=Queue.Queue( self.polling_queuesize ) # connecting to the browser self.is_connected = 0 self.connect() # current molecule self.molecule = None self.residue = None self.moleculeid_dict = {} self.nr_dict = {} def writelog( self, string, level = 3 ): if( level > self.log_verbosity ): return self.log.write( string+"\n" ) self.log.flush() def write_connection( self, string ): self.writelog( "> "+string, 1 ) self.cin.write( string+"\n" ) self.cin.flush() def connect( self ): self.writelog( "METHOD(connect)", 2 ) if( self.is_connected ): self.writelog( "ERROR(connect) connection exists", 0 ) return # start browser ( self.cin, self.cout ) = os.popen2( self.exec_filename ) # handshake self.write_connection("READY") timeout = 5 (input, output, exc)=select.select([self.cout],[],[], timeout) if( len(input) == 0 ): self.writelog( "ERROR(connect) timeout after %d seconds" %( timeout ), 0 ) return handshake = self.cout.readline() if( handshake != "READY\n" ): self.writelog( "ERROR(connect) connection not ready: \"%s\"" %( handshake ), 0 ) # start connection polling self.is_connected = 1 self.writelog( "CONNECTION estabished", 1 ) thread.start_new_thread( self.read_connection,()) # start gui polling self.writelog( "GUI-POLLING STARTED", 1 ) self.poll() def disconnect( self ): self.writelog( "METHOD(disconnect)", 2 ) if( not self.is_connected ): self.writelog( "ERROR(disconnect) no connection estabished", 0 ) return # sending exit request to browser self.write_connection("EXIT") def internal_disconnect( self ): self.writelog( "METHOD(internal_disconnect)", 2 ) # used by connection-polling thread only self.is_connected = 0 def read_connection( self ): try: while( 1 ): self.writelog( "METHOD(read_connection)", 2 ) # used by connection-polling thread only if( not self.is_connected ): return self.writelog( "x", 2 ) command = self.cout.readline() self.writelog( "y", 2 ) self.writelog( "COMMAND %s" % ( command ), 1 ) self.writelog( "z", 2 ) exec( command ) #self.read_connection() except Exception: self.writelog( "EXECPTION %s on COMMAND %s" % ( sys.exc_type, command ), 0 ) def poll( self ): #self.writelog( "METHOD(poll)", 2 ) while( not( self.polling_queue.empty())): molecule = self.polling_queue.get() chimera.openModels.add([molecule]) if( not self.is_connected ): self.writelog( "GUI-POLLING STOPED", 1 ) return self.polling_thread.after( self.polling_intervall, self.poll ) def put( self, molecule ): self.writelog( "METHOD(put)", 2 ) if( self.polling_queue.full()): self.writelog( "ERROR(put) polling queue is full", 0 ) else: self.polling_queue.put( molecule ) def show_molecule_callback( self ): self.writelog( "METHOD(show_molecule_callback)", 2 ) self.put( self.molecule ) def new_molecule( self, id, name, show_ballstick = 0 ): self.writelog( "METHOD(show_molecule_callback)", 2 ) self.show_ballstick = show_ballstick # self.writelog( "a", 2 ) self.molecule = chimera.Molecule() self.writelog( "b", 2 ) self.molecule.name = name self.writelog( "c", 2 ) # self.residue = self.molecule.newResidue('', chimera.MolResId( 1 )) self.writelog( "d", 2 ) # if( id > 0 ): self.moleculeid_dict[id] = self.molecule self.writelog( "e", 2 ) self.nr_dict = {} def new_atom( self, nr, name, symbol, radius, x, y, z ): self.writelog( "METHOD(new_atom)", 2 ) element = chimera.Element( elements.name.index( symbol )) atom = self.molecule.newAtom( name, element ) # COORDINATES xyz = chimera.Coord() xyz.x = x xyz.y = y xyz.z = z atom.setCoord( xyz ) # APPEARANCE atom.radius = radius if( self.show_ballstick ): atom.drawMode = chimera.Atom.Ball else: atom.drawMode = chimera.Atom.Dot colorAtomByElement( atom ) # self.residue.addAtom( atom ) self.nr_dict[nr] = atom #COMMAND self.new_atom(36,"H36: H","H",1.20,4.35,22.92,28.82) #COMMAND self.new_pseudoatom(0,"0: 0 3| 2 0| 0 0",3.32,0.23,15.73,29.05,0.01,0.99,1.00) def new_pseudoatom( self, nr, name, radius, x, y, z, red, green, blue ): self.writelog( "METHOD(new_pseudoatom)", 2 ) atom = self.molecule.newAtom( name, chimera.elements.H ) self.writelog( "Z", 2 ) # COORDINATES xyz = chimera.Coord() self.writelog( "A", 2 ) xyz.x = x xyz.y = y xyz.z = z self.writelog( "B", 2 ) atom.setCoord( xyz ) # APPEARANCE atom.radius = radius self.writelog( "C", 2 ) if( self.show_ballstick ): self.writelog( "1", 2 ) atom.drawMode = chimera.Atom.Ball else: self.writelog( "2", 2 ) atom.drawMode = chimera.Atom.Dot self.writelog( "3", 2 ) atom.color = chimera.MaterialColor( red, green, blue ) self.writelog( "D", 2 ) # self.residue.addAtom( atom ) self.writelog( "E", 2 ) self.nr_dict[nr] = atom self.writelog( "F", 2 ) def new_bond( self, nr, nr1, nr2 ): self.writelog( "METHOD(new_bond)", 2 ) bond = self.molecule.newBond( self.nr_dict[nr1], self.nr_dict[nr2]) # APPEARANCE if( self.show_ballstick ): bond.drawMode = chimera.Bond.Stick else: bond.drawMode = chimera.Bond.Wire