From ca46aa1b45050ea001e08ded2e382b965f229ba1 Mon Sep 17 00:00:00 2001 From: Dawid Jagiela Date: Wed, 6 Feb 2013 14:56:22 +0100 Subject: [PATCH] added pymol/UNRESInpGen.py - generates inputs for MD --- source/pymol/UNRESInpGen.py | 843 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 843 insertions(+) create mode 100755 source/pymol/UNRESInpGen.py diff --git a/source/pymol/UNRESInpGen.py b/source/pymol/UNRESInpGen.py new file mode 100755 index 0000000..b3d77a7 --- /dev/null +++ b/source/pymol/UNRESInpGen.py @@ -0,0 +1,843 @@ +# -*- coding: utf-8 -*- +''' +------------------------------------------------------------------------------- + UNRESInpGen.py - UNRES graphical input generator v 1.0 +------------------------------------------------------------------------------- + + Written by Dawid Jagieła (lightnir@chem.univ.gda.pl) Oct 2012 + +''' + +from pymol import cmd,stored +from Tkinter import * +import tkFileDialog +import tkMessageBox +import Pmw +import string +import os + +UNRESInpGen_version="1.0" + +def __init__(self): + self.UNRESInpGenWindow = None + try: + self.menuBar.addcascademenu('Plugin', 'UNRESPlugins', 'UNRESPACK Plugins', label='UNRES Plugins') + except: + pass + + self.menuBar.addmenuitem('UNRESPlugins', 'command','UNRESInpGen', + label='UNRES Input Generator', + command = lambda s=self: createUNRESInpGen(s) ) + +def createUNRESInpGen(app): + if (app.UNRESInpGenWindow == None): + app.UNRESInpGenWindow = UNRESInpGenerator(app) + else: + app.UNRESInpGenWindow.myToggle() + +#================================================================= + + +class UNRESInpGenerator(Toplevel): + global UNRESInpGen_version + # Class variables + """ + cv = IntVar() + pp = IntVar() + cp = IntVar() + rv = IntVar() + colorize = IntVar() + """ + seq_letter = IntVar() + writeSSbrige = IntVar() + OM1Val = StringVar() + OM2Val = StringVar() + objects_list = ['Select object'] + seq_list=[] + seq_length=0 + + weights = ['WLONG','WSCC','WSCP','WELEC','WVDWPP','WEL_LOC','WCORR4','WCORR5','WCORR6','WTURN3','WTURN4','WTURN6','WSCCOR','WSTRAIN','WBOND','WTOR','WTORD','WANG','WSCLOC','SCAL14','SCALSCP','WCORRH','CUTOFF' ] + + force_fields = [ {'FF':'GAB', 'WLONG' :'1.35279', 'WSCP' :'1.59304', 'WELEC' :'0.71534', 'WBOND' :'1.00000', 'WANG' :'1.13873', 'WSCLOC':'0.16258', 'WTOR':'1.98599', 'WTORD':'1.57069', 'WCORRH':'0.42887', 'WCORR5':'0.00000', + 'WCORR6':'0.00000', 'WEL_LOC':'0.16036', 'WTURN3':'1.68722', 'WTURN4':'0.66230', 'WTURN6':'0.00000', 'WVDWPP':'0.11371', 'WHPB':'1.00000', 'WCORR4':'0.00000', 'CUTOFF':'7.00000'}, + {'FF':'E0G', 'WLONG':'1.70905', 'WSCP':'2.18310', 'WELEC':'1.06684', 'WBOND':'1.00000', 'WANG':'1.17536', 'WSCLOC':'0.22070', 'WTOR':'2.65798', 'WTORD':'2.00646', 'WCORRH':'0.23541', 'WCORR5':'0.00000', + 'WCORR6':'0.00000', 'WEL_LOC':'0.42789', 'WTURN3':'1.68126', 'WTURN4':'0.75080', 'WTURN6':'0.00000', 'WVDWPP':'0.27044', 'WHPB':'1.00000', 'WSCP14':'0.00000', 'CUTOFF':'7.00000', 'WCORR4':'0.00000'}, + {'FF':'1L2Y_1LE1', 'WLONG' :'1.00000', 'WSCP' :'1.23315', 'WELEC' : '0.84476', 'WBOND' :'1.00000', 'WANG' :'0.62954', 'WSCLOC': '0.10554', 'WTOR': '1.84316', 'WTORD' : '1.26571', 'WCORRH': '0.19212', 'WCORR5': '0.00000', + 'WCORR6':'0.00000', 'WEL_LOC':'0.37357', 'WTURN3':'1.40323', 'WTURN4':'0.64673', 'WTURN6':'0.00000', 'WVDWPP': '0.23173', 'WHPB': '1.00000', 'WSCCOR': '0.00000', 'CUTOFF': '7.00000', 'WCORR4': '0.00000'}, + {'FF':'4P', 'WSC':'1.00000', 'WSCP':'2.73684', 'WELEC':'0.06833', 'WANG':'4.15526', 'WSCLOC':'0.16761', 'WTOR':'2.99546', 'WTORD':'2.89720', 'WCORRH':'1.98989', 'WCORR5':'0.00000', 'WCORR6':'0.00000', 'WEL_LOC':'1.60072', + 'WTURN3':'2.36351', 'WTURN4':'1.34051', 'WTURN6':'0.00000', 'CUTOFF':'7.00000', 'WCORR4':'0.00000', 'WSCCOR':'0.00000'}, + {'FF':'3P', 'WSC':'1.00000', 'WSCP':'2.85111', 'WELEC':'0.36281', 'WANG':'3.95152', 'WSCLOC':'0.15244', 'WTOR':'3.00008', 'WTORD':'2.89863', 'WCORRH':'1.91423', 'WCORR5':'0.00000', 'WCORR6':'0.00000', 'WEL_LOC':'1.72128', + 'WTURN3':'2.99827', 'WTURN4':'0.59174', 'WTURN6':'0.00000', 'CUTOFF':'7.00000', 'WCORR4':'0.00000', 'WSCCOR':'0.00000'}, + {'FF':'CASP5', 'WSC':'1.00000', 'WSCP':'1.54864', 'WELEC':'0.20016', 'WANG': '1.00572', 'WSCLOC': '0.06764', 'WTOR':'1.70537', 'WTORD':'1.24442', 'WCORRH':'0.91583', 'WCORR5':'0.00607', 'WCORR6':'0.02316', 'WEL_LOC':'1.51083', + 'WTURN3':'2.00764', 'WTURN4':'0.05345', 'WTURN6':'0.05282', 'WSCCOR':'0.0', 'CUTOFF': '7.00000', 'WCORR4':'0.00000' }, + {'FF':'ALPHABETA', 'WSC':'1.00000', 'WSCP':'1.43178', 'WELEC':'0.41501', 'WANG':'0.37790', 'WSCLOC':'0.12880', 'WTOR':'1.98784', 'WCORRH':'2.50526', 'WCORR5':'0.23873', 'WCORR6':'0.76327', 'WEL_LOC':'2.97687', 'WTURN3':'0.09261', + 'WTURN4':'0.79171', 'WTURN6':'0.01074', 'CUTOFF':'7.00000', 'WCORR4':'0.00000', 'WSCCOR':'0.00000'}, + {'FF':'BETA', 'WSC':'1.00000', 'WSCP':'1.10684', 'WELEC':'0.70000', 'WANG':'0.80775', 'WSCLOC':'1.91939', 'WTOR':'3.36070', 'WCORRH':'2.50000', 'WCORR5':'0.99949', 'WCORR6':'0.46247', 'WEL_LOC':'2.50000', 'WTURN3':'1.80121', + 'WTURN4':'4.35377', 'WTURN6':'0.10000', 'CUTOFF':'7.00000', 'WCORR4':'0.00000', 'WSCCOR':'0.00000'}, + {'FF':'ALPHA', 'WSC':'1.00000', 'WSCP':'0.72364', 'WELEC':'1.10890', 'WANG':'0.68702', 'WSCLOC':'1.79888', 'WTOR':'0.30562', 'WCORRH':'1.09616', 'WCORR5':'0.17452', 'WCORR6':'0.36878', 'WEL_LOC':'0.19508', 'WTURN3':'0.00000', + 'WTURN4':'0.55588', 'WTURN6':'0.11539', 'CUTOFF':'7.00000', 'WCORR4':'0.0000', 'WTORD':'0.00000', 'WSCCOR':'0.00000'}, + {'FF':'CASP3', 'WELEC':'1.50000', 'WSTRAIN':'1.00000', 'WTOR':'0.08617', 'WANG':'0.10384', 'WSCLOC':'0.10384', 'WCORR':'1.50000', 'WTURN3':'0.00000', 'WTURN4':'0.00000', 'WTURN6':'0.00000', 'WEL_LOC':'0.00000', 'WCORR5':'0.00000', + 'WCORR6':'0.00000', 'SCAL14':'0.40000', 'SCALSCP':'1.00000', 'CUTOFF':'7.00000', 'WSCCOR':'0.00000'} + ] + + one_letter ={'VAL':'V', 'ILE':'I', 'LEU':'L', 'GLU':'E', 'GLN':'Q', 'ASP':'D', 'ASN':'N', 'HIS':'H', 'TRP':'W', 'PHE':'F', 'TYR':'Y', 'ARG':'R', 'LYS':'K', 'SER':'S', 'THR':'T', 'MET':'M', 'ALA':'A', 'GLY':'G', 'PRO':'P', 'CYS':'C'} + + + def __init__(self,parent): + # Create the GUI window + root = Toplevel.__init__(self) + self.config(width=400, height=300) # create a root window + self.title("UNRES Input Generator v"+UNRESInpGen_version) # Set window title + self.resizable(0, 0) # Disable window resize + self.geometry('-40+40') # Set window placement + + # Create the Balloon. + self.balloon = Pmw.Balloon(root) + + #================================ + # "Main Options" group + # + self.gr1 = Pmw.Group(self,tag_text = 'Main options') + self.gr1.grid(row=0, column=0,columnspan=4,sticky=W+E,padx=10, pady=5) + + # - Create title Entryfield & Label + #self.l1 = Label(self.gr1.interior(), text="Title:") + #self.l1.grid(row=0, column=0,sticky=E) + self.e1 = Pmw.EntryField(self.gr1.interior(), + labelpos='w', + label_text="Title:", + validate = {'max': 80 }, + # value ="(Place input information here)" + ) + self.e1.component('entry').config(width=80) + self.e1.grid(row=0, column=0,columnspan=4, sticky=E) + + # - Create "choose method" OptionMenu + self.OM1Val.set('MD') + self.optmenu1 = Pmw.OptionMenu(self.gr1.interior(), + labelpos = 'w', + label_text = 'Choose method:', + menubutton_textvariable = self.OM1Val, + items = ['MD', 'MREMD' ], + command = self.switch_options, + menubutton_width = 10 + ) + self.optmenu1.grid(row=1, column=0,columnspan=2, sticky=E) + + + # - Seed entryfield + self.gr1.e1 = Pmw.EntryField(self.gr1.interior(), + labelpos='w', + label_text="Seed", + validate = {'validator' : 'integer', 'min': -2147483648 , 'max' : 0 }, + value = "-1111333" + ) + self.gr1.e1.component('entry').config(width=8) + self.gr1.e1.grid(row=1, column=2, sticky=W) + + #================================== + # - MD options frame + # + self.gr1.md = Frame(self.gr1.interior()) + self.gr1.md.grid(row=2, column=0, columnspan=4,sticky=W+E) + + # -- nstep entryfield + self.gr1.md.e1 = Pmw.EntryField(self.gr1.md, + labelpos='w', + label_text="NSTEP", + validate = {'validator' : 'integer', 'min': 1 , 'max' : 1000000 }, + value = "500000" + ) + self.balloon.bind(self.gr1.md.e1,'Number of calculation steps') + self.gr1.md.e1.component('entry').config(width=8) + self.gr1.md.e1.grid(row=0, column=0, sticky=E) + + # -- ntwe entryfield + self.gr1.md.e2 = Pmw.EntryField(self.gr1.md, + labelpos='w', + label_text="NTWE", + validate = {'validator' : 'integer', 'min': 0 , 'max' : 1000000 }, + value = "100" + ) + self.balloon.bind(self.gr1.md.e2,'Frequency of energy output.\nNTWE=0 means no energy dump. ') + self.gr1.md.e2.component('entry').config(width=8) + self.gr1.md.e2.grid(row=0,column=1, sticky=E) + + # -- ntwx entryfield + self.gr1.md.e3 = Pmw.EntryField(self.gr1.md, + labelpos='w', + label_text="NTWX", + validate = {'validator' : 'integer', 'min': 1 , 'max' : 1000000 }, + value = "1000" + ) + self.balloon.bind(self.gr1.md.e3, "Frequency of coordinate output.") + self.gr1.md.e3.component('entry').config(width=8) + self.gr1.md.e3.grid(row=0,column=2, sticky=E) + + # -- dt entryfield + self.gr1.md.e4 = Pmw.EntryField(self.gr1.md, + labelpos='w', + label_text="DT", + validate = {'validator' : 'real', 'min': 0.001 , 'max' : 1000 }, + value = "0.1") + self.balloon.bind(self.gr1.md.e4, "Time step. \nThe unit is \"molecular time unit\" (mtu)\n 1 mtu = 48.9 fs") + self.gr1.md.e4.component('entry').config(width=8) + self.gr1.md.e4.grid(row=0,column=3, sticky=E) + + # -- damax entryfield + self.gr1.md.e5 = Pmw.EntryField(self.gr1.md, + labelpos='w', + label_text="DAMAX", + validate = {'validator' : 'real', 'min': 0.001 , 'max' : 1000 }, + value = "1.0") + self.balloon.bind(self.gr1.md.e5, "Maximum allowed change of acceleration during a single time step.\nThe time step gets scaled down, if this is exceeded.") + self.gr1.md.e5.component('entry').config(width=8) + self.gr1.md.e5.grid(row=1,column=0, sticky=E) + + # -- dvmax entryfield + self.gr1.md.e6 = Pmw.EntryField(self.gr1.md, + labelpos='w', + label_text="DVMAX", + validate = {'validator' : 'real', 'min': 0.001 , 'max' : 1000 }, + value = "20.0") + self.balloon.bind(self.gr1.md.e6, "Maximum allowed velocity (in A/mtu).") + self.gr1.md.e6.component('entry').config(width=8) + self.gr1.md.e6.grid(row=1,column=1, sticky=E) + + # -- restet_vel entryfield + self.gr1.md.e7 = Pmw.EntryField(self.gr1.md, + labelpos='w', + label_text="RESET_VEL", + validate = {'validator' : 'integer', 'min': 0 , 'max' : 10000000 }, + value = "1000") + self.balloon.bind(self.gr1.md.e7, "Frequency of resetting velocities to values from Gaussian distribution") + self.gr1.md.e7.component('entry').config(width=8) + self.gr1.md.e7.grid(row=1,column=2, sticky=E) + + + #================================= + # - thermostat frame + # + self.gr1.th = Frame(self.gr1.interior()) + self.gr1.th.grid(row=3, column=0, columnspan=5,sticky=W+E) + + # -- Thermostat optionmenu + self.gr1.th.optmenu1 = Pmw.OptionMenu(self.gr1.th, + labelpos = 'w', + label_text = 'thermostat', + items = ['Berendsen', 'Nose-Poincare 1999','Nose-Poincare 2001', 'Nose-Hoover', 'Langevin' ], + command=self.set_thermostat, + menubutton_width = 15 + ) + self.gr1.th.optmenu1.pack(side=LEFT)#grid(row=0, column=0, sticky=E) + + # -- t_bath entryfield + self.gr1.th.e1 = Pmw.EntryField(self.gr1.th, + labelpos='w', + label_text="T_BATH", + validate = {'validator' : 'real', 'min': 0.000001 , 'max' : 10000 }, + value = "300.0") + self.balloon.bind(self.gr1.th.e1, "Temperature (in K) of canonical simulation.") + self.gr1.th.e1.component('entry').config(width=8) + self.gr1.th.e1.pack(side=LEFT) + + # -- tau_bath entryfield + self.gr1.th.e2 = Pmw.EntryField(self.gr1.th, + labelpos='w', + label_text="TAU_BATH", + validate = {'validator' : 'real', 'min': 0.000001 , 'max' : 1000000 }, + value = "1.0") + self.balloon.bind(self.gr1.th.e2, "(units are mtus; 1mtu=48.9 fs) \nConstant of the coupling to the thermal bath") + self.gr1.th.e2.component('entry').config(width=8) + self.gr1.th.e2.pack(side=LEFT) + + # -- q_np entryfield + self.gr1.th.e3 = Pmw.EntryField(self.gr1.th, + labelpos='w', + label_text="Q_NP", + validate = {'validator' : 'real', 'min': 0.000001 , 'max' : 1000000 }, + value = "0.1") + self.balloon.bind(self.gr1.th.e3, "Mass of the fictitious particle in the calculations with the Nose-Poincare & Nose-Hoover thermostats.") + self.gr1.th.e3.component('entry').config(width=8) + #self.gr1.th.e2.pack(side=LEFT) + + + #================================= + # "Force field options" group + # + self.gr2 = Pmw.Group(self,tag_text = 'Force field options') + self.gr2.grid(row=2, column=0,columnspan=4,sticky=W+E,padx=10, pady=5) + + # - Create "force field parameters" Option menu + self.OM2Val.set('Custom') + self.optmenu2 = Pmw.OptionMenu(self.gr2.interior(), + label_text = 'Force field parameters:', + labelpos = 'w', + menubutton_textvariable = self.OM2Val, + items = ['Custom','GAB','E0G', '1L2Y_1LE1','4P','3P','CASP5','ALPHABETA','BETA','ALPHA','CASP3' ], + initialitem = 'Custom', + menubutton_width = 10, + command=self.set_force_field + ) + self.optmenu2.grid(row=0, column=0,columnspan=4,sticky=E) + + # Force field parameters Entry Fields + self.ef = [] + for i in range(0,len(self.weights)): + self.ef.append(Pmw.EntryField(self.gr2.interior(), + labelpos='n', + label_text=self.weights[i], + validate = {'validator' : 'real','min' : 0, 'max' : 10, 'minstrict' : 0}, + value = '1.00000')) + self.ef[i].component('entry').config(width=8) + self.ef[i].grid(row=1+(i//9), column=0+(i % 9)) + # "Sequence" group + self.gr3 = Pmw.Group(self,tag_text = 'Sequence') + self.gr3.grid(row=3, column=0,columnspan=4,sticky=W+E,padx=10, pady=5) + + self.gr3.f1 = Frame(self.gr3.interior()) + # Object List + self.cb2 = Pmw.ComboBox(self.gr3.f1, + labelpos = 'w', + #entry_relief = 'raised', + label_text = 'Selection/Object', + scrolledlist_items = self.objects_list + ) + self.cb2.pack(side=LEFT) + # refresh button + self.gr3.btn1 = Button(self.gr3.f1, text='Refresh', padx=0, pady=0 , command = self.refresh_list) + self.gr3.btn1.pack(side=LEFT) + # Get sequence button + self.gr3.btn2 = Button(self.gr3.f1, text='Get Sequence', padx=0, pady=0 , command = self.get_seq) + self.gr3.btn2.pack(side=LEFT) + + self.gr3.f1.pack(expand="yes",fill="both") + + # Disulfide brige checkbox + self.gr3.chk = Checkbutton(self.gr3.f1, text="Write disulfide bridges", variable=self.writeSSbrige) + self.gr3.chk.pack(side=LEFT) + + # Sequence text + self.gr3.t1 = Pmw.ScrolledText(self.gr3.interior(), + columnheader = 1, + columnheader_width = 3, + rowheader = 1, + rowheader_width = 4, + usehullsize=1, + hull_width=30, + hull_height=180, + text_padx = 4, + text_pady = 4, + Header_padx = 4, + rowheader_pady = 4, + ) + # Sequence text - create the header line + headerline = '' + for column in range(1,21): + headerline = headerline + ('%-4s' % str(column) ) + self.gr3.t1.component('columnheader').insert('0.0',headerline) + + self.gr3.t1.pack(expand="yes",fill="both") + + # Add some buttons + btn3=Button(self, text='Write Input', padx=0, pady=0, command = self.ok) + btn3.grid(row=10, column=0, columnspan=2,sticky=N+W+S+E) + btn4=Button(self, text='Close', padx=0, pady=0, command = self.myHide) + btn4.grid(row=10, column=2, columnspan=2,sticky=N+W+S+E) + + # create callback to prevent window kill + self.protocol("WM_DELETE_WINDOW", self.myHide) + + def ToggleColor(self): + if self.colorize.get()==1: + for i in range(0,len(self.res_states)): + UNRESInpGenWindow.ccb[i].config(state=ACTIVE, bg=self.res_states[i][1], activebackground=self.res_states[i][1], relief=RAISED, overrelief=RAISED) + else: + for i in range(0,len(self.res_states)): + UNRESInpGenWindow.ccb[i].config(state=DISABLED, bg=self.Default_Color , activebackground=self.Default_Color, relief=RAISED, overrelief=RAISED) + + def myShow(self): + self.deiconify() + + def myHide(self): + self.withdraw() + + def myToggle(self): + if self.state() == "normal": + self.myHide() + elif self.state() == "withdrawn": + self.myShow() + + def get_selections(self): + self.objects_list = [] + for item in cmd.get_names("all"): + if cmd.get_type(item)=="object:molecule": + self.objects_list.append(item) + if cmd.get_type(item)=="selection": + if item[0]<>"_": + self.objects_list.append(item) + + def get_nonstandard(self): + stored.list=[] + cmd.iterate("(all)","stored.list.append(resn)") + stored.list=list(Set(stored.list)) # remove duplicates + # Remove standard amino acids and water from list + for m in ['HIS','ASP','ARG','PHE','ALA','CYS','GLY','GLN','GLU','LYS','LEU','MET','ASN','SER','TYR','THR','ILE','TRP','PRO','VAL','HOH']: + try: + stored.list.remove(m) + except ValueError: + pass + UNRESInpGenWindow.cbcr1.setlist(stored.list) + + def refresh_list(self): + # Save old values + old = self.objects_list + try: + old_cb2=self.cb2.getvalue()[0] + except: + old_cb2='' + self.get_selections() + + # Update selectionlist if needed + if not(old==self.objects_list): + self.cb2.setlist(self.objects_list) + self.cb2.setlist(self.objects_list) + + if not(old_cb2 in self.objects_list): + # No - clear the combobox entry + self.cb2.component('entryfield').clear() + else: + # Yes - set the old value + self.cb2.selectitem(old_cb2,setentry=1) + + + def get_seq(self): + # Get the number of chains + try: + nchains=int(len(cmd.get_chains(self.cb2.getvalue()[0]))) + except: + nchains=0 + pass + + if (nchains>0): + self.seq_list=[] + offset=0 + seq_data='' + self.seq_length=0 + for chain in range(0,nchains): + # Get only amonoacids, N-terminus acyl and C-terminus amide + # example: (1uRC and chain F and (n. ca or (resn ACE and n. C) or (resn NH2 and n. N))) + # No chain information or only one chain + if nchains==1: + atomchain=cmd.get_model(str(self.cb2.getvalue()[0])+" & (n. ca|(resn ACE & n. C)|(resn NH2+NHH+NME & n. N))").atom + # Chain information is present + else: + atomchain=cmd.get_model(str(self.cb2.getvalue()[0])+" & chain "+cmd.get_chains(self.cb2.getvalue()[0])[chain]+" & (n. ca|(resn ACE & n. C)|(resn NH2+NHH+NME & n. N))").atom + # dodaj separator lancuchow + if chain>0: + self.seq_list.append("D ") + self.seq_length+=1 + + + # Zamiana chronionych + # ACE ALA ALA NH2 D ACE ALA ALA NH2 + # GLY ALA ALA GLY D GLY ALA ALA GLY + # Zamiana niechronionych + # ALA ALA D ALA ALA + # D ALA ALA D ALA ALA D + # + # j - licznik pozycji reszty + j=0 + for i in atomchain: + self.seq_length+=1 + if str(i.resn)=="NH2": + self.seq_list.append("GLY") + elif str(i.resn)=="NHH": + self.seq_list.append("GLY") + elif str(i.resn)=="NME": + self.seq_list.append("GLY") + elif str(i.resn)=="ACE": + self.seq_list.append("GLY") + elif str(i.resn)=="GLY": + self.seq_list.append("GLY") + else: + if j==0 and chain==0: + self.seq_list.append("D ") + self.seq_list.append(str(i.resn)) + self.seq_length+=1 + elif j==len(atomchain)-1 and chain==(nchains-1): + self.seq_list.append(str(i.resn)) + self.seq_list.append("D ") + self.seq_length+=1 + else: + self.seq_list.append(str(i.resn)) + j+=1 + rows=0 + #row_header='0' - old header + row_header='1' + # tag setup + self.gr3.t1.tag_configure('dummy', background = 'LightBlue1') + tagList=[] + self.gr3.t1.tag_configure('cysteine', background = 'LightGoldenrod1') + CysTagList=[] + + for i in range(len(self.seq_list)): + # Dummy tag + if self.seq_list[i]=="D ": + tag1 = '%d.%d' % (rows+1, ((len(seq_data)-rows)%80)) + tag2 = '%d.%d' % (rows+1, ((len(seq_data)-rows)%80)+3) + tagList.append(tag1) + tagList.append(tag2) + # Cysteine tag + if self.seq_list[i]=="CYS" or self.seq_list[i]=="CYX": + tag1 = '%d.%d' % (rows+1, ((len(seq_data)-rows)%80)) + tag2 = '%d.%d' % (rows+1, ((len(seq_data)-rows)%80)+3) + CysTagList.append(tag1) + CysTagList.append(tag2) + # + offset+=1 + seq_data=seq_data+self.seq_list[i]+" " + # Line Wrap + if offset>19: + offset=0 + seq_data=seq_data+'\n' + rows+=1 + #row_header=row_header+'\n'+str(rows*20) - old header + row_header=row_header+'\n'+str(rows+1) + + self.gr3.t1.clear() + self.gr3.t1.insert('end',seq_data) + # Apply tags + if len(tagList): + apply(self.gr3.t1.tag_add, ('dummy',) + tuple(tagList)) + if len(CysTagList): + apply(self.gr3.t1.tag_add, ('cysteine',) + tuple(CysTagList)) + + # Show row header + self.gr3.t1.component('rowheader').delete(1.0, END) + self.gr3.t1.component('rowheader').insert('end',row_header) + + + def switch_options(self,calctype): + ''' + Displays the options available to set depending on the currently + selected calculation type + ''' + # Hide all + self.gr1.th.grid_remove() + self.gr1.md.grid_remove() + if self.OM1Val.get()=="MD": + self.gr1.md.grid(row=2, column=0, columnspan=5, sticky=W+E) + self.gr1.th.grid(row=3, column=0, columnspan=5, sticky=W+E) + + + def set_force_field(self, pole): + ''' + Enables/disables entryfields for force field perameters depending + on the currently selected force field + ''' + for ff in self.force_fields: + if ff['FF']==pole: + #print ff + for i in range(0,len(self.weights)): + if ff.has_key(self.weights[i]): + self.ef[i].setvalue(ff.get(self.weights[i])) + self.ef[i].component('entry').config(state=NORMAL) + else: + self.ef[i].component('entry').config(state=DISABLED) + # Custom force field + elif pole=='Custom': + for i in range(0,len(self.weights)): + self.ef[i].component('entry').config(state=NORMAL) + + def set_thermostat(self,thermostat): + ''' + Display additional widget acording to selected thermostat + ''' + #print thermostat + self.gr1.th.e2.pack_forget() + self.gr1.th.e3.pack_forget() + if thermostat=='Berendsen': + self.gr1.th.e2.pack(side=LEFT) + elif thermostat=='Nose-Poincare 1999' or thermostat=='Nose-Poincare 2001' or thermostat=='Nose-Hoover': + self.gr1.th.e3.pack(side=LEFT) + + def fortran_format(self,s): + ''' + Formats string containing keywords to wrap over 80 columns + ''' + tmpstr='' + column=1 + for k in s.split(): + if column+len(k)+1<80: + tmpstr+=k+' ' + column+=len(k)+1 + else: + tmpstr+=" "*(80-column)+"&\n"+k+" " + column=len(k)+2 + tmpstr+='\n' + return tmpstr + + def get_weights(self): + ''' + Get the force field weights + ''' + s = '' + for i in range(0,len(self.weights)): + if self.ef[i].component('entry').cget("state")=="normal": + s+=self.weights[i]+"="+self.ef[i].getvalue()+" " + return s + + def get_md_opt(self): + s = "NSTEP="+self.gr1.md.e1.getvalue()+" NTWE="+self.gr1.md.e2.getvalue()+" " + s+= "NTWX="+self.gr1.md.e3.getvalue()+" DT="+self.gr1.md.e4.getvalue()+" " + s+= "DAMAX="+self.gr1.md.e5.getvalue()+" DVMAX="+self.gr1.md.e6.getvalue()+" " + s+= "RESET_VEL="+self.gr1.md.e7.getvalue()+" " + + # Thermostat options + term=self.gr1.th.optmenu1.getvalue() + #print term + if term=="Berendsen": + s+="TBF TAU_BATH="+self.gr1.th.e2.getvalue()+" " + elif term=="Nose-Poincare 1999": + s+="NOSEPOINCARE99 Q_NP="+self.gr1.th.e3.getvalue()+" " + elif term=="Nose-Poincare 2001": + s+="NOSEPOINCARE01 Q_NP="+self.gr1.th.e3.getvalue()+" " + elif term=="Nose-Hoover": + s+="NOSEHOOVER96 Q_NP="+self.gr1.th.e3.getvalue()+" " + elif term=="Langevin": + s+="LANG=1 " + + s+="T_BATH="+self.gr1.th.e1.getvalue()+" " + return s + + + def get_seq_data(self): + ''' + Dumps the sequence and disulfide bridge information + ''' + # write sequence length + s = str(self.seq_length)+"\n" + # + #try: + # nchains=int(len(cmd.get_chains(self.cb2.getvalue()[0]))) + #except: + # nchains=0 + #pass + + chains=cmd.get_chains(self.cb2.getvalue()[0]) + nchains=len(chains) + #print "chains : ",chains + #print "nchains : ",nchains + + # apply one space before each sequence line + seq=self.gr3.t1.get() + for line in seq.split('\n'): + s+=" "+line+"\n" + # remove last newline character + s = s[:-1] + + # disulfide bridges - get half-cysteines by selection: + # sele (bto. ((object) & r. CYS+CYX & n. SG) )& n. SG + ncys=cmd.get_model("(bto. (("+str(self.cb2.getvalue()[0])+") & r. CYS+CYX & n. SG)) & n. SG").atom + nSSbr=len(ncys)/2 + + + # Is "Write disulfide brige" checked? + # yes + if self.writeSSbrige.get(): + # write number of half-cysteines + s+=str(len(ncys))+"\n" + if len(ncys)==0: + # No half-cysteines, cys position = 0 + s+=" 0\n" + else: + # Write half-cysteine positions in sequence + # + # get first chain + first=cmd.get_model(str(self.cb2.getvalue()[0])+"& chain "+str(chains[0])+" & n. ca") + + # calculate base offset in first chain (if dummy atom present offset = 1 ) + if first.atom[0].resn=="GLY": + boff=0 + else: + boff=1 + + # create dictionary of PDB chain/resi to UNRES_index + unresidx={} + for c in ncys: + # calculate residue index offset from first residue in chain containing half-cysteine + fresinchain=cmd.get_model(str(self.cb2.getvalue()[0])+"& chain "+c.chain+" & n. ca").atom + roff=int(c.resi)-int(fresinchain[0].resi)+1 + + resb=0 + coff=0 + for r in chains: + if c.chain==r: + break + resb+=len(cmd.get_model(str(self.cb2.getvalue()[0])+"& chain "+r+" & n. ca").atom) + coff+=1 + # add key/value to dictionary + unresidx[c.chain+"/"+str(c.resi)]=boff+resb+coff+roff + s+=" "+str(boff+resb+coff+roff) + s+="\n" + + # Write the number of disulfide bridges + s+=" "+str(nSSbr)+"\n" + + lista_mostkow=[] + for c in ncys: + # get neibhoring Sulfur atom + opis=c.chain+str(c.resi) + lista_mostkow.append(opis) + nbr=cmd.get_model("(bto. ("+str(self.cb2.getvalue()[0])+" & resi "+str(c.resi)+"& n. SG & chain "+str(c.chain)+")) & n. SG").atom[0] + opis2=nbr.chain+str(nbr.resi) + if opis2 not in lista_mostkow: + # Write witch half-cysteines build the i-th disulfide bridge + s+=" "+str(unresidx[c.chain+"/"+str(c.resi)])+" "+str(unresidx[nbr.chain+"/"+str(nbr.resi)])+"\n" + #print c.chain, c.resn,c.resi,"-S-S-", nbr.chain, nbr.resn,nbr.resi + # Don't writeSSbrige + else: + s+="0\n 0\n" + + + return s + + + def write_cshell(self, cshname,prefix): + ''' + Writes the C-shell script needed to run UNRES calculations + ''' + s='#!/bin/csh -f\n#\n# C-shell script generated by UNRESInpGen.py\n#\n' + + # number of processors per energy + if self.OM1Val.get()=="MD": + s+='setenv FGPROCS 1\n' + + # Potential + if self.OM2Val.get()=="CASP3": + s+='setenv POT LJ\n' + else: + s+='setenv POT GB\n' + + # input file + s+='setenv PREFIX '+prefix+'\n' + + # Parallel stuff + s+='setenv OUT1FILE YES\n' + + # force filed parameters + s+='#---------------------------------------------------------------------\n' + s+='setenv DD $UNRES_ROOT/PARAM\n' + + if self.OM2Val.get()=="CASP3": + s+='setenv BONDPAR $DD/bond.parm\nsetenv THETPAR $DD/thetaml.5parm\nsetenv ROTPAR $DD/scgauss.parm\n' + s+='setenv TORPAR $DD/torsion_cryst.parm\nsetenv TORDPAR $DD/torsion_double_631Gdp.parm\nsetenv SIDEPAR $DD/scinter_LJ.parm\n' + s+='setenv ELEPAR $DD/electr.parm\nsetenv SCPPAR $DD/scp.parm\nsetenv FOURIER $DD/fourier_GAP.parm\n' + s+='setenv SCCORPAR $DD/rotcorr_AM1.parm\n' + elif self.OM2Val.get()=="ALPHA" or self.OM2Val.get()=="BETA" or self.OM2Val.get()=="ALPHABETA": + s+='setenv BONDPAR $DD/bond.parm\nsetenv THETPAR $DD/thetaml.5parm\nsetenv ROTPAR $DD/scgauss.parm\n' + s+='setenv TORPAR $DD/torsion_ecepp.parm\nsetenv TORDPAR $DD/torsion_double_631Gdp.parm\nsetenv SIDEPAR $DD/scinter_GB.parm\n' + s+='setenv ELEPAR $DD/electr.parm\nsetenv SCPPAR $DD/scp.parm\nsetenv FOURIER $DD/fourier_GAP.parm\nsetenv SCCORPAR $DD/rotcorr_AM1.parm\n' + elif self.OM2Val.get()=="CASP5": + s+='setenv BONDPAR $DD/bond.parm\nsetenv THETPAR $DD/thetaml.5parm\nsetenv ROTPAR $DD/scgauss.parm\n' + s+='setenv TORPAR $DD/torsion_631Gdp.parm\nsetenv TORDPAR $DD/torsion_double_631Gdp.parm\nsetenv SIDEPAR $DD/scinter_GB.parm\n' + s+='setenv ELEPAR $DD/electr_631Gdp.parm\nsetenv SCPPAR $DD/scp.parm\nsetenv FOURIER $DD/fourier_opt.parm.1igd_iter7n_c\nsetenv SCCORPAR $DD/rotcorr_AM1.parm\n' + elif self.OM2Val.get()=="3P": + s+='setenv BONDPAR $DD/bond.parm\nsetenv THETPAR $DD/thetaml.5parm\nsetenv ROTPAR $DD/scgauss.parm\n' + s+='setenv TORPAR $DD/torsion_631Gdp.parm\nsetenv TORDPAR $DD/torsion_double_631Gdp.parm\nsetenv SIDEPAR $DD/sc_GB_opt.3P7_iter81_1r\n' + s+='setenv ELEPAR $DD/electr_631Gdp.parm\nsetenv SCPPAR $DD/scp.parm\nsetenv FOURIER $DD/fourier_opt.parm.1igd_hc_iter3_3\nsetenv SCCORPAR $DD/rotcorr_AM1.parm\n' + elif self.OM2Val.get()=="4P": + s+='setenv BONDPAR $DD/bond.parm\nsetenv THETPAR $DD/thetaml.5parm\nsetenv ROTPAR $DD/scgauss.parm\n' + s+='setenv TORPAR $DD/torsion_631Gdp.parm\nsetenv TORDPAR $DD/torsion_double_631Gdp.parm\nsetenv SIDEPAR $DD/sc_GB_opt.4P5_iter33_3r\n' + s+='setenv ELEPAR $DD/electr_631Gdp.parm\nsetenv SCPPAR $DD/scp.parm\nsetenv FOURIER $DD/fourier_opt.parm.1igd_hc_iter3_3\nsetenv SCCORPAR $DD/rotcorr_AM1.parm\n' + elif self.OM2Val.get()=="GAB": + s+='setenv BONDPAR $DD/bond.parm\nsetenv THETPAR $DD/thetaml.5parm\nsetenv ROTPAR $DD/scgauss.parm\n' + s+='setenv TORPAR $DD/torsion_631Gdp.parm\nsetenv TORDPAR $DD/torsion_double_631Gdp.parm\nsetenv SIDEPAR $DD/sc_GB_opt.1gab_3S_qclass5no310-shan2-sc-16-10-8k\n' + s+='setenv ELEPAR $DD/electr_631Gdp.parm\nsetenv SCPPAR $DD/scp.parm\nsetenv FOURIER $DD/fourier_opt.parm.1igd_hc_iter3_3\nsetenv SCCORPAR $DD/rotcorr_AM1.parm\n' + elif self.OM2Val.get()=="E0G": + s+='setenv BONDPAR $DD/bond.parm\nsetenv THETPAR $DD/thetaml.5parm\nsetenv ROTPAR $DD/scgauss.parm\n' + s+='setenv TORPAR $DD/torsion_631Gdp.parm\nsetenv TORDPAR $DD/torsion_double_631Gdp.parm\nsetenv SIDEPAR $DD/sc_GB_opt.1e0g-52-17k-2k-newclass-shan1e9_gap8g-sc\n' + s+='setenv ELEPAR $DD/electr_631Gdp.parm\nsetenv SCPPAR $DD/scp.parm\nsetenv FOURIER $DD/fourier_opt.parm.1igd_hc_iter3_3\nsetenv SCCORPAR $DD/rotcorr_AM1.parm\n' + elif self.OM2Val.get()=="1L2Y_1LE1": + s+='setenv BONDPAR $DD/bond_AM1.parm\nsetenv THETPAR $DD/thetaml.5parm\nsetenv ROTPAR $DD/rotamers_AM1_aura.10022007.parm\n' + s+='setenv TORPAR $DD/torsion_631Gdp.parm\nsetenv TORDPAR $DD/torsion_double_631Gdp.parm\nsetenv SIDEPAR $DD/scinter_$POT.parm\n' + s+='setenv ELEPAR $DD/electr_631Gdp.parm\nsetenv SCPPAR $DD/scp.parm\nsetenv FOURIER $DD/fourier_opt.parm.1igd_hc_iter3_3\nsetenv SCCORPAR $DD/rotcorr_AM1.parm\n' + elif self.OM2Val.get()=="Custom": + s+='setenv BONDPAR $DD/.parm\nsetenv THETPAR $DD/.parm\nsetenv ROTPAR $DD/.parm\n' + s+='setenv TORPAR $DD/.parm\nsetenv TORDPAR $DD/.parm\nsetenv SIDEPAR $DD/.parm\n' + s+='setenv ELEPAR $DD/.parm\nsetenv SCPPAR $DD/.parm\nsetenv FOURIER $DD/.parm\nsetenv SCCORPAR $DD/.parm\n' + + + + s+='setenv PATTERN $DD/patterns.cart\n' + s+='#---------------------------------------------------------------------\n' + s+='$UNRES_BIN $*\n' + + f = open(cshname, 'w') + f.write(s) + f.close() + + + def setenv_info(self): + print '''IMPORTANT: Remember to set the following envirament variables for your shell before starting calculations: + UNRES_ROOT - the root directory where UNRES is installed on your system (should contain PARAM directory) + UNRES_BIN - the UNRES binary you want to execute + ''' + + + def ok(self): + ''' + Writes the actual input + ''' + myFormats = [ + ('Input files','*.inp'), + ('All files','*.*') + ] + # Write error handling for empty sequence + # + s=self.gr3.t1.getvalue() + if len(s.strip())==0: + tkMessageBox.showerror("NEED SEQUENCE DATA!", "NEED SEQUENCE DATA!\n\nYou have not loaded the sequence information. Please click \"Refresh\", choose an object from the list and click \"Get sequence\".") + else: + # Display dialog window + fout = tkFileDialog.asksaveasfile(parent=self,mode='w',filetypes=myFormats,title='Save input') + if fout: + print "Saving input file %s" % fout.name + # Get input header + text2save=self.fortran_format(self.e1.get()) + # Get main options + mainopt="SEED="+self.gr1.e1.get()+" " + if self.OM1Val.get()=="MD": + mainopt+="MD PDBREF EXTCONF" + elif self.OM1Val.get()=="MREMD": + mainopt+="RE " + text2save+=self.fortran_format(mainopt) + # Get aux options + + if self.OM1Val.get()=="MD": + text2save+=self.fortran_format(self.get_md_opt()) + + # Get force fields parameters + text2save+=self.fortran_format(self.get_weights()) + + # PDB reference + pdbreffn=str(self.cb2.getvalue()[0])+"_pdbref.pdb" + text2save+=pdbreffn+"\n" + print "Saving PDB reference structure %s" % (os.path.join(os.path.dirname(fout.name),pdbreffn)) + cmd.save(os.path.join(os.path.dirname(fout.name),pdbreffn), self.cb2.getvalue()[0]) + + # C-shell script + cshellfn=os.path.join(os.path.dirname(fout.name),"unres_"+os.path.basename(os.path.splitext(fout.name)[0])+".csh") + print "Writing C-shell script %s" % (cshellfn) + prefix=os.path.basename(os.path.splitext(fout.name)[0]) + self.write_cshell(cshellfn,prefix) + + # Get sequence data + text2save+=self.get_seq_data() + + fout.write(text2save) + fout.close() + + # ENV Varaiables info + self.setenv_info() -- 1.7.9.5