5e355a780bd8b49e9ed52a562ac713b3466f5eb5
[unres.git] / source / pymol / UNRESInpGen.py
1 # -*- coding: utf-8 -*-
2 '''
3 -------------------------------------------------------------------------------
4  UNRESInpGen.py - UNRES graphical input generator v 1.0
5 -------------------------------------------------------------------------------
6
7  Written by Dawid JagieÅ‚a (lightnir@chem.univ.gda.pl)  Oct 2012 
8
9 '''
10
11 from pymol import cmd,stored
12 from Tkinter import *
13 import tkFileDialog
14 import tkMessageBox 
15 import Pmw
16 import string
17 import os
18
19 UNRESInpGen_version="1.0"
20
21 def __init__(self):
22         self.UNRESInpGenWindow = None 
23         try:
24                 self.menuBar.addcascademenu('Plugin', 'UNRESPlugins', 'UNRESPACK Plugins', label='UNRES Plugins')
25         except:
26                 pass
27
28         self.menuBar.addmenuitem('UNRESPlugins', 'command','UNRESInpGen',
29                 label='UNRES Input Generator',
30                 command = lambda s=self: createUNRESInpGen(s) )
31
32 def createUNRESInpGen(app):
33         if (app.UNRESInpGenWindow == None):
34                 app.UNRESInpGenWindow = UNRESInpGenerator(app)
35         else:
36                 app.UNRESInpGenWindow.myToggle()        
37
38 #=================================================================
39
40
41 class UNRESInpGenerator(Toplevel):
42         global UNRESInpGen_version
43         # Class variables
44         """
45         cv = IntVar()
46         pp = IntVar()
47         cp = IntVar()
48         rv = IntVar()
49         colorize = IntVar()
50         """
51         seq_letter = IntVar()
52         writeSSbrige = IntVar()
53         OM1Val = StringVar()
54         OM2Val = StringVar()
55         CART = IntVar()
56         OVERLAP = IntVar()
57         NOSEARCHSC = IntVar()
58         objects_list = ['Select object']    
59         seq_list=[]
60         seq_length=0
61
62         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' ]
63
64         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',
65                                         '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'},
66                     {'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',
67                                         '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'},
68                     {'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',
69                                         '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'},
70                     {'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',
71                                         'WTURN3':'2.36351', 'WTURN4':'1.34051', 'WTURN6':'0.00000', 'CUTOFF':'7.00000', 'WCORR4':'0.00000', 'WSCCOR':'0.00000'},
72                     {'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',
73                                         'WTURN3':'2.99827', 'WTURN4':'0.59174', 'WTURN6':'0.00000', 'CUTOFF':'7.00000', 'WCORR4':'0.00000', 'WSCCOR':'0.00000'},
74                         {'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',
75                                         'WTURN3':'2.00764', 'WTURN4':'0.05345', 'WTURN6':'0.05282', 'WSCCOR':'0.0', 'CUTOFF': '7.00000', 'WCORR4':'0.00000' },
76                         {'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',
77                                         'WTURN4':'0.79171', 'WTURN6':'0.01074', 'CUTOFF':'7.00000', 'WCORR4':'0.00000', 'WSCCOR':'0.00000'},
78                         {'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',
79                                         'WTURN4':'4.35377', 'WTURN6':'0.10000', 'CUTOFF':'7.00000', 'WCORR4':'0.00000', 'WSCCOR':'0.00000'},
80                         {'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',
81                                         'WTURN4':'0.55588', 'WTURN6':'0.11539', 'CUTOFF':'7.00000', 'WCORR4':'0.0000', 'WTORD':'0.00000', 'WSCCOR':'0.00000'},
82                         {'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',
83                                         'WCORR6':'0.00000', 'SCAL14':'0.40000', 'SCALSCP':'1.00000', 'CUTOFF':'7.00000', 'WSCCOR':'0.00000'}
84         ]
85
86         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'}
87
88
89         def __init__(self,parent):
90                 # Create the GUI window 
91                 root = Toplevel.__init__(self)
92                 self.config(width=400, height=300)              # create a root window
93                 self.title("UNRES Input Generator v"+UNRESInpGen_version)                 # Set window title
94                 self.resizable(0, 0)                                # Disable window resize
95                 self.geometry('-40+40')                             # Set window placement
96
97                 # Create the Balloon.
98                 self.balloon = Pmw.Balloon(root)
99
100                 #================================ 
101                 # "Main Options" group 
102                 #
103                 self.gr1 = Pmw.Group(self,tag_text = 'Main options')
104                 self.gr1.grid(row=0, column=0,columnspan=4,sticky=W+E,padx=10, pady=5)
105
106                 # - Create title Entryfield & Label
107                 #self.l1 = Label(self.gr1.interior(), text="Title:")
108                 #self.l1.grid(row=0, column=0,sticky=E)
109                 self.e1 = Pmw.EntryField(self.gr1.interior(),
110                         labelpos='w',
111                         label_text="Title:",
112                         validate = {'max': 80 },
113                 #       value ="(Place input information here)"
114                 )
115                 self.e1.component('entry').config(width=80)
116                 self.e1.grid(row=0, column=0,columnspan=4, sticky=E)
117
118                 # - Create "choose method" OptionMenu
119                 self.OM1Val.set('MD')
120                 self.optmenu1 =  Pmw.OptionMenu(self.gr1.interior(),
121                         labelpos = 'w',
122                         label_text = 'Choose method:',
123                         menubutton_textvariable = self.OM1Val,
124                         items = ['MD', 'MREMD', 'MINIMIZE' ],
125                         command = self.switch_options,
126                         menubutton_width = 10
127                 )
128                 self.optmenu1.grid(row=1, column=0,columnspan=2, sticky=E)
129         
130
131                 # - Seed entryfield
132                 self.gr1.e1 = Pmw.EntryField(self.gr1.interior(),
133                         labelpos='w',
134                         label_text="Seed",
135                         validate = {'validator' : 'integer', 'min': -2147483648 , 'max' : 0 },
136                         value = "-1111333"
137                 )
138                 self.gr1.e1.component('entry').config(width=8)
139                 self.gr1.e1.grid(row=1, column=2, sticky=W)
140  
141                 #==================================
142                 # - MD options frame
143                 #
144                 self.gr1.md = Frame(self.gr1.interior())
145                 self.gr1.md.grid(row=2, column=0, columnspan=4,sticky=W+E)
146                 
147                 # -- nstep entryfield
148                 self.gr1.md.e1 = Pmw.EntryField(self.gr1.md,
149                         labelpos='w',
150                         label_text="NSTEP",
151                         validate = {'validator' : 'integer', 'min': 1 , 'max' : 1000000 },
152                         value = "500000"
153                 )
154                 self.balloon.bind(self.gr1.md.e1,'Number of calculation steps')
155                 self.gr1.md.e1.component('entry').config(width=8)
156                 self.gr1.md.e1.grid(row=0, column=0, sticky=E)
157
158                 # -- ntwe entryfield
159                 self.gr1.md.e2 = Pmw.EntryField(self.gr1.md,
160                         labelpos='w',
161                         label_text="NTWE",
162                         validate = {'validator' : 'integer', 'min': 0 , 'max' : 1000000 },
163                         value = "100"
164                 )
165                 self.balloon.bind(self.gr1.md.e2,'Frequency of energy output.\nNTWE=0 means no energy dump. ')
166                 self.gr1.md.e2.component('entry').config(width=8)
167                 self.gr1.md.e2.grid(row=0,column=1, sticky=E)
168
169                 # -- ntwx entryfield
170                 self.gr1.md.e3 = Pmw.EntryField(self.gr1.md,
171                         labelpos='w',
172                         label_text="NTWX",
173                         validate = {'validator' : 'integer', 'min': 1 , 'max' : 1000000 },
174                         value = "1000"
175                 )
176                 self.balloon.bind(self.gr1.md.e3, "Frequency of coordinate output.")
177                 self.gr1.md.e3.component('entry').config(width=8)
178                 self.gr1.md.e3.grid(row=0,column=2, sticky=E)
179
180                 # -- dt entryfield
181                 self.gr1.md.e4 = Pmw.EntryField(self.gr1.md,
182                         labelpos='w',
183                         label_text="DT",
184                         validate = {'validator' : 'real', 'min': 0.001 , 'max' : 1000 },
185                         value = "0.1")
186                 self.balloon.bind(self.gr1.md.e4, "Time step. \nThe unit is \"molecular time unit\" (mtu)\n 1 mtu = 48.9 fs")
187                 self.gr1.md.e4.component('entry').config(width=8)
188                 self.gr1.md.e4.grid(row=0,column=3, sticky=E)
189
190                 # -- damax entryfield
191                 self.gr1.md.e5 = Pmw.EntryField(self.gr1.md,
192                         labelpos='w',
193                         label_text="DAMAX",
194                         validate = {'validator' : 'real', 'min': 0.001 , 'max' : 1000 },
195                         value = "1.0")
196                 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.")
197                 self.gr1.md.e5.component('entry').config(width=8)
198                 self.gr1.md.e5.grid(row=1,column=0, sticky=E)
199
200                 # -- dvmax entryfield
201                 self.gr1.md.e6 = Pmw.EntryField(self.gr1.md,
202                         labelpos='w',
203                         label_text="DVMAX",
204                         validate = {'validator' : 'real', 'min': 0.001 , 'max' : 1000 },
205                         value = "20.0")
206                 self.balloon.bind(self.gr1.md.e6, "Maximum allowed velocity (in A/mtu).")
207                 self.gr1.md.e6.component('entry').config(width=8)
208                 self.gr1.md.e6.grid(row=1,column=1, sticky=E)
209
210                 # -- restet_vel entryfield
211                 self.gr1.md.e7 = Pmw.EntryField(self.gr1.md,
212                         labelpos='w',
213                         label_text="RESET_VEL",
214                         validate = {'validator' : 'integer', 'min': 0 , 'max' : 10000000 },
215                         value = "1000")
216                 self.balloon.bind(self.gr1.md.e7, "Frequency of resetting velocities to values from Gaussian distribution")
217                 self.gr1.md.e7.component('entry').config(width=8)
218                 self.gr1.md.e7.grid(row=1,column=2, sticky=E)
219
220
221                 #=================================
222                 #  - thermostat frame
223                 #
224                 self.gr1.th = Frame(self.gr1.interior())
225                 self.gr1.th.grid(row=3, column=0, columnspan=5,sticky=W+E)
226
227                 # -- Thermostat optionmenu 
228                 self.gr1.th.optmenu1 =  Pmw.OptionMenu(self.gr1.th,
229                         labelpos = 'w',
230                         label_text = 'thermostat',
231                         items = ['Berendsen', 'Nose-Poincare 1999','Nose-Poincare 2001', 'Nose-Hoover', 'Langevin' ],
232                         command=self.set_thermostat,
233                         menubutton_width = 15
234                 )
235                 self.gr1.th.optmenu1.pack(side=LEFT)#grid(row=0, column=0, sticky=E)
236
237                 # -- t_bath entryfield
238                 self.gr1.th.e1 = Pmw.EntryField(self.gr1.th,
239                         labelpos='w',
240                         label_text="T_BATH",
241                         validate = {'validator' : 'real', 'min': 0.000001 , 'max' : 10000 },
242                         value = "300.0")
243                 self.balloon.bind(self.gr1.th.e1, "Temperature (in K) of canonical simulation.")
244                 self.gr1.th.e1.component('entry').config(width=8)
245                 self.gr1.th.e1.pack(side=LEFT)
246                 
247                 # -- tau_bath entryfield
248                 self.gr1.th.e2 = Pmw.EntryField(self.gr1.th,
249                         labelpos='w',
250                         label_text="TAU_BATH",
251                         validate = {'validator' : 'real', 'min': 0.000001 , 'max' : 1000000 },
252                         value = "1.0")
253                 self.balloon.bind(self.gr1.th.e2, "(units are mtus; 1mtu=48.9 fs) \nConstant of the coupling to the thermal bath")
254                 self.gr1.th.e2.component('entry').config(width=8)
255                 self.gr1.th.e2.pack(side=LEFT)
256                                  
257                 # -- q_np entryfield
258                 self.gr1.th.e3 = Pmw.EntryField(self.gr1.th,   
259                         labelpos='w',
260                         label_text="Q_NP",
261                         validate = {'validator' : 'real', 'min': 0.000001 , 'max' : 1000000 },
262                         value = "0.1")
263                 self.balloon.bind(self.gr1.th.e3, "Mass of the fictitious particle in the calculations with the Nose-Poincare & Nose-Hoover thermostats.")
264                 self.gr1.th.e3.component('entry').config(width=8)
265                 #self.gr1.th.e2.pack(side=LEFT)
266
267                 
268                 #================================= 
269                 # - Minimization frame
270                 self.gr1.mi = Frame(self.gr1.interior())
271                 #self.gr1.mi.grid(row=4, column=0, columnspan=5,sticky=W+E)
272
273                 self.gr1.mi.e1 = Pmw.EntryField(self.gr1.mi,
274                         labelpos='w',
275                         label_text="MAXMIN",
276                         validate = {'validator' : 'integer', 'min': 0 , 'max' : 1000000 },
277                         value = "2000" )
278                 self.balloon.bind(self.gr1.mi.e1,'Maximum number of iterations of the SUMSL minimizer.')
279                 self.gr1.mi.e1.component('entry').config(width=8)
280                 self.gr1.mi.e1.pack(side=LEFT)
281
282                 self.gr1.mi.e2 = Pmw.EntryField(self.gr1.mi,
283                         labelpos='w',
284                         label_text="MAXFUN",
285                         validate = {'validator' : 'integer', 'min': 0 , 'max' : 1000000 },
286                         value = "5000" )
287                 self.balloon.bind(self.gr1.mi.e2,'Maximum number of function evaluations in a single minimization.')
288                 self.gr1.mi.e2.component('entry').config(width=8)
289                 self.gr1.mi.e2.pack(side=LEFT)
290
291                 self.gr1.mi.c1 = Checkbutton(self.gr1.mi,
292                         text = "CART",
293                         variable = self.CART )
294                 self.balloon.bind(self.gr1.mi.c1,'Minimize in virtual-bond vectors instead of angles.')
295                 self.gr1.mi.c1.pack(side=LEFT)
296
297                 self.gr1.mi.c2 = Checkbutton(self.gr1.mi,
298                         text = "OVERLAP",
299                         variable = self.OVERLAP )
300                 self.balloon.bind(self.gr1.mi.c2,'Fix overlaping sidechains.')
301                 self.gr1.mi.c2.pack(side=LEFT)
302
303                 self.gr1.mi.c3 = Checkbutton(self.gr1.mi,
304                         text = "NOSEARCHSC",
305                         variable = self.NOSEARCHSC )
306                 #self.balloon.bind(self.gr1.mi.c3,'Minimize in virtual-bond vectors instead of angles.')
307                 self.gr1.mi.c3.pack(side=LEFT)
308
309
310
311                 #================================= 
312                 # "Force field options" group
313                 #     
314                 self.gr2 = Pmw.Group(self,tag_text = 'Force field options')
315                 self.gr2.grid(row=2, column=0,columnspan=4,sticky=W+E,padx=10, pady=5)
316
317                 # - Create "force field parameters" Option menu
318                 self.OM2Val.set('Custom')
319                 self.optmenu2 = Pmw.OptionMenu(self.gr2.interior(),
320                 label_text = 'Force field parameters:',
321                         labelpos = 'w',
322                         menubutton_textvariable = self.OM2Val,
323                         items = ['Custom','GAB','E0G', '1L2Y_1LE1','4P','3P','CASP5','ALPHABETA','BETA','ALPHA','CASP3' ],
324                         initialitem = 'Custom',
325                         menubutton_width = 10,
326                         command=self.set_force_field
327                 )
328                 self.optmenu2.grid(row=0, column=0,columnspan=4,sticky=E)
329
330                 # Force field parameters Entry Fields   
331                 self.ef = []
332                 for i in range(0,len(self.weights)):
333                         self.ef.append(Pmw.EntryField(self.gr2.interior(), 
334                         labelpos='n',
335                         label_text=self.weights[i],
336                         validate = {'validator' : 'real','min' : 0, 'max' : 10, 'minstrict' : 0},
337                         value = '1.00000'))
338                         self.ef[i].component('entry').config(width=8)
339                         self.ef[i].grid(row=1+(i//9), column=0+(i % 9))
340                 # "Sequence" group 
341                 self.gr3 = Pmw.Group(self,tag_text = 'Sequence')
342                 self.gr3.grid(row=3, column=0,columnspan=4,sticky=W+E,padx=10, pady=5)
343                                 
344                 self.gr3.f1 = Frame(self.gr3.interior())
345                 # Object List  
346                 self.cb2 = Pmw.ComboBox(self.gr3.f1,
347                         labelpos = 'w',
348                         #entry_relief = 'raised',
349                         label_text = 'Selection/Object',
350                         scrolledlist_items = self.objects_list
351                 )
352                 self.cb2.pack(side=LEFT)
353                 # refresh button
354                 self.gr3.btn1 = Button(self.gr3.f1, text='Refresh', padx=0, pady=0 , command = self.refresh_list)
355                 self.gr3.btn1.pack(side=LEFT)  
356                 # Get sequence button 
357                 self.gr3.btn2 = Button(self.gr3.f1, text='Get Sequence', padx=0, pady=0 , command = self.get_seq)
358                 self.gr3.btn2.pack(side=LEFT)  
359                         
360                 self.gr3.f1.pack(expand="yes",fill="both")
361
362                 # Disulfide brige checkbox
363                 self.gr3.chk = Checkbutton(self.gr3.f1, text="Write disulfide bridges", variable=self.writeSSbrige)
364                 self.gr3.chk.pack(side=LEFT)
365
366                 # Sequence text
367                 self.gr3.t1 = Pmw.ScrolledText(self.gr3.interior(),
368                         columnheader = 1,
369                         columnheader_width = 3,
370                         rowheader = 1,
371                         rowheader_width = 4,
372                         usehullsize=1,
373                         hull_width=30,
374                         hull_height=180,
375                         text_padx = 4,
376                         text_pady = 4,
377                         Header_padx = 4,
378                         rowheader_pady = 4,
379                 )
380                 # Sequence text - create the header line 
381                 headerline = ''
382                 for column in range(1,21):
383                         headerline = headerline + ('%-4s' % str(column) )
384                 self.gr3.t1.component('columnheader').insert('0.0',headerline)
385
386                 self.gr3.t1.pack(expand="yes",fill="both") 
387
388                 # Add some buttons
389                 btn3=Button(self, text='Write Input', padx=0, pady=0, command = self.ok)
390                 btn3.grid(row=10, column=0, columnspan=2,sticky=N+W+S+E)
391                 btn4=Button(self, text='Close', padx=0, pady=0, command = self.myHide)
392                 btn4.grid(row=10, column=2, columnspan=2,sticky=N+W+S+E)
393
394                 # create callback to prevent window kill
395                 self.protocol("WM_DELETE_WINDOW", self.myHide)
396
397         def ToggleColor(self):
398                 if self.colorize.get()==1:
399                         for i in range(0,len(self.res_states)):
400                                 UNRESInpGenWindow.ccb[i].config(state=ACTIVE, bg=self.res_states[i][1], activebackground=self.res_states[i][1], relief=RAISED, overrelief=RAISED)
401                 else:
402                         for i in range(0,len(self.res_states)):
403                                 UNRESInpGenWindow.ccb[i].config(state=DISABLED, bg=self.Default_Color , activebackground=self.Default_Color, relief=RAISED, overrelief=RAISED)
404
405         def myShow(self):
406                 self.deiconify()
407
408         def myHide(self):
409                 self.withdraw()
410
411         def myToggle(self):
412                 if self.state() == "normal":
413                         self.myHide()
414                 elif self.state() == "withdrawn":
415                         self.myShow()
416         
417         def get_selections(self):
418                 self.objects_list = []
419                 for item in cmd.get_names("all"):
420                         if cmd.get_type(item)=="object:molecule":
421                                 self.objects_list.append(item)
422                         if cmd.get_type(item)=="selection":
423                                 if item[0]<>"_":
424                                         self.objects_list.append(item)
425
426         def get_nonstandard(self):
427                 stored.list=[]
428                 cmd.iterate("(all)","stored.list.append(resn)")
429                 stored.list=list(Set(stored.list))  # remove duplicates
430                 # Remove standard amino acids and water from list
431                 for m in ['HIS','ASP','ARG','PHE','ALA','CYS','GLY','GLN','GLU','LYS','LEU','MET','ASN','SER','TYR','THR','ILE','TRP','PRO','VAL','HOH']:
432                         try:
433                                 stored.list.remove(m)
434                         except ValueError:
435                                 pass
436                 UNRESInpGenWindow.cbcr1.setlist(stored.list)
437
438         def refresh_list(self):
439                 # Save old values
440                 old = self.objects_list
441                 try:
442                         old_cb2=self.cb2.getvalue()[0]
443                 except:
444                         old_cb2=''
445                 self.get_selections()
446
447                 # Update selectionlist if needed
448                 if not(old==self.objects_list):
449                         self.cb2.setlist(self.objects_list)
450                         self.cb2.setlist(self.objects_list)
451
452                 if not(old_cb2 in self.objects_list):
453                         # No - clear the combobox entry
454                         self.cb2.component('entryfield').clear()
455                 else:
456                         # Yes - set the old value
457                         self.cb2.selectitem(old_cb2,setentry=1)
458         
459         
460         def get_seq(self):
461                 # Get the number of chains 
462                 try: 
463                         nchains=int(len(cmd.get_chains(self.cb2.getvalue()[0])))
464                 except:
465                         nchains=0
466                 pass
467                 
468                 if (nchains>0):
469                         self.seq_list=[]
470                 offset=0
471                 seq_data=''
472                 self.seq_length=0
473                 for chain in range(0,nchains):
474                         # Get only amonoacids, N-terminus acyl and C-terminus amide
475                         # example:      (1uRC and chain F and (n. ca or (resn ACE and n. C) or (resn NH2 and n. N)))
476                         # No chain information or only one chain
477                         if nchains==1:
478                                 atomchain=cmd.get_model(str(self.cb2.getvalue()[0])+" & (n. ca|(resn ACE & n. C)|(resn NH2+NHH+NME & n. N))").atom
479                         # Chain information is present
480                         else:
481                                 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
482                         # dodaj separator lancuchow
483                         if chain>0:
484                                 self.seq_list.append("D  ")
485                                 self.seq_length+=1
486                                 
487
488                         # Zamiana chronionych
489                         # ACE ALA ALA NH2 D   ACE ALA ALA NH2
490                         # GLY ALA ALA GLY D   GLY ALA ALA GLY
491                         # Zamiana niechronionych 
492                         #     ALA ALA     D       ALA ALA
493                         # D   ALA ALA     D       ALA ALA D
494                         #
495                         # j - licznik pozycji reszty
496                         j=0
497                         for i in atomchain:
498                                 self.seq_length+=1
499                                 if str(i.resn)=="NH2":
500                                         self.seq_list.append("GLY")
501                                 elif str(i.resn)=="NHH":
502                                         self.seq_list.append("GLY")
503                                 elif str(i.resn)=="NME":
504                                         self.seq_list.append("GLY")
505                                 elif str(i.resn)=="ACE":
506                                         self.seq_list.append("GLY")
507                                 elif str(i.resn)=="GLY":
508                                         self.seq_list.append("GLY")
509                                 else:
510                                         if j==0 and chain==0: 
511                                                 self.seq_list.append("D  ")     
512                                                 self.seq_list.append(str(i.resn))
513                                                 self.seq_length+=1
514                                         elif j==len(atomchain)-1 and chain==(nchains-1):
515                                                 self.seq_list.append(str(i.resn))
516                                                 self.seq_list.append("D  ")
517                                                 self.seq_length+=1
518                                         else:
519                                                 self.seq_list.append(str(i.resn))
520                                 j+=1
521                 rows=0
522                 #row_header='0'  - old header
523                 row_header='1'
524                 # tag setup 
525                 self.gr3.t1.tag_configure('dummy', background = 'LightBlue1')
526                 tagList=[]
527                 self.gr3.t1.tag_configure('cysteine', background = 'LightGoldenrod1')
528                 CysTagList=[]
529
530                 for i in range(len(self.seq_list)):
531                         # Dummy tag
532                         if self.seq_list[i]=="D  ":
533                                 tag1 = '%d.%d' % (rows+1, ((len(seq_data)-rows)%80))
534                                 tag2 = '%d.%d' % (rows+1, ((len(seq_data)-rows)%80)+3)
535                                 tagList.append(tag1)
536                                 tagList.append(tag2)
537                         # Cysteine tag  
538                         if self.seq_list[i]=="CYS" or self.seq_list[i]=="CYX":
539                                 tag1 = '%d.%d' % (rows+1, ((len(seq_data)-rows)%80))
540                                 tag2 = '%d.%d' % (rows+1, ((len(seq_data)-rows)%80)+3)
541                                 CysTagList.append(tag1)
542                                 CysTagList.append(tag2)
543                         #       
544                         offset+=1
545                         seq_data=seq_data+self.seq_list[i]+" "
546                         # Line Wrap
547                         if offset>19:
548                                 offset=0
549                                 seq_data=seq_data+'\n'
550                                 rows+=1
551                                 #row_header=row_header+'\n'+str(rows*20)    - old header
552                                 row_header=row_header+'\n'+str(rows+1)
553
554                 self.gr3.t1.clear()
555                 self.gr3.t1.insert('end',seq_data)
556                 # Apply tags
557                 if len(tagList): 
558                         apply(self.gr3.t1.tag_add, ('dummy',) + tuple(tagList))
559                 if len(CysTagList):
560                         apply(self.gr3.t1.tag_add, ('cysteine',) + tuple(CysTagList))
561
562                 # Show row header
563                 self.gr3.t1.component('rowheader').delete(1.0, END)
564                 self.gr3.t1.component('rowheader').insert('end',row_header)     
565
566     
567         def switch_options(self,calctype):
568                 '''
569                         Displays the options available to set depending on the currently 
570                         selected calculation type
571                 '''
572                 # Hide all
573                 self.gr1.th.grid_remove()
574                 self.gr1.md.grid_remove()
575                 self.gr1.mi.grid_remove()
576                 # Show MD stuff
577                 if  self.OM1Val.get()=="MD":
578                         self.gr1.md.grid(row=2, column=0, columnspan=5, sticky=W+E)
579                         self.gr1.th.grid(row=3, column=0, columnspan=5, sticky=W+E)
580                 elif self.OM1Val.get()=="MINIMIZE":
581                         self.gr1.mi.grid(row=4,column=0,columnspan=5, sticky=W+E)
582
583
584         def set_force_field(self, pole):
585                 '''
586                         Enables/disables entryfields for force field perameters depending
587                         on the currently selected force field 
588                 '''
589                 for ff in self.force_fields:
590                         if ff['FF']==pole: 
591                                 #print ff
592                                 for i in range(0,len(self.weights)):
593                                         if ff.has_key(self.weights[i]):
594                                                 self.ef[i].setvalue(ff.get(self.weights[i]))
595                                                 self.ef[i].component('entry').config(state=NORMAL)
596                                         else:
597                                                 self.ef[i].component('entry').config(state=DISABLED)
598                         # Custom force field
599                         elif pole=='Custom':
600                                 for i in range(0,len(self.weights)):
601                                         self.ef[i].component('entry').config(state=NORMAL)
602
603         def set_thermostat(self,thermostat):
604                 '''
605                         Display additional widget acording to selected thermostat
606                 '''
607                 #print thermostat
608                 self.gr1.th.e2.pack_forget()
609                 self.gr1.th.e3.pack_forget()
610                 if thermostat=='Berendsen':
611                         self.gr1.th.e2.pack(side=LEFT)
612                 elif thermostat=='Nose-Poincare 1999' or thermostat=='Nose-Poincare 2001' or thermostat=='Nose-Hoover':
613                         self.gr1.th.e3.pack(side=LEFT)
614
615         def fortran_format(self,s):
616                 '''
617                     Formats string containing keywords to wrap over 80 columns 
618                 '''
619                 tmpstr=''
620                 column=1
621                 for k in s.split():
622                         if column+len(k)+1<80:
623                                 tmpstr+=k+' '
624                                 column+=len(k)+1
625                         else:
626                                 tmpstr+=" "*(80-column)+"&\n"+k+" "
627                                 column=len(k)+2
628                 tmpstr+='\n'
629                 return tmpstr
630
631         def get_weights(self):
632                 '''
633                         Get the force field weights
634                 '''
635                 s = ''
636                 for i in range(0,len(self.weights)):
637                         if self.ef[i].component('entry').cget("state")=="normal":
638                                 s+=self.weights[i]+"="+self.ef[i].getvalue()+" "
639                 return s
640
641         def get_md_opt(self):
642                 s = "NSTEP="+self.gr1.md.e1.getvalue()+" NTWE="+self.gr1.md.e2.getvalue()+" "
643                 s+= "NTWX="+self.gr1.md.e3.getvalue()+" DT="+self.gr1.md.e4.getvalue()+" "
644                 s+= "DAMAX="+self.gr1.md.e5.getvalue()+" DVMAX="+self.gr1.md.e6.getvalue()+" " 
645                 s+= "RESET_VEL="+self.gr1.md.e7.getvalue()+" " 
646                 
647                 # Thermostat options
648                 term=self.gr1.th.optmenu1.getvalue()
649                 #print term
650                 if term=="Berendsen":
651                         s+="TBF TAU_BATH="+self.gr1.th.e2.getvalue()+" "
652                 elif term=="Nose-Poincare 1999":
653                         s+="NOSEPOINCARE99 Q_NP="+self.gr1.th.e3.getvalue()+" "
654                 elif term=="Nose-Poincare 2001":
655                         s+="NOSEPOINCARE01 Q_NP="+self.gr1.th.e3.getvalue()+" "
656                 elif term=="Nose-Hoover":
657                         s+="NOSEHOOVER96 Q_NP="+self.gr1.th.e3.getvalue()+" "
658                 elif term=="Langevin":
659                         s+="LANG=1 "
660
661                 s+="T_BATH="+self.gr1.th.e1.getvalue()+" "
662                 return s
663
664         def get_minim_opt(self):
665                 s = "MAXMIN="+self.gr1.mi.e1.getvalue()+" MAXFUN="+self.gr1.mi.e2.getvalue()
666                 return s
667
668
669         def get_seq_data(self):
670                 '''
671                         Dumps the sequence and disulfide bridge information
672                 '''
673                 # write sequence length 
674                 s = str(self.seq_length)+"\n"
675                 # 
676                 #try: 
677                 #       nchains=int(len(cmd.get_chains(self.cb2.getvalue()[0])))
678                 #except:
679                 #       nchains=0
680                 #pass
681
682                 chains=cmd.get_chains(self.cb2.getvalue()[0])
683                 nchains=len(chains)
684                 #print "chains  : ",chains
685                 #print "nchains : ",nchains
686
687                 # apply one space before each sequence line 
688                 seq=self.gr3.t1.get()
689                 for line in seq.split('\n'):
690                         s+=" "+line+"\n"
691                 # remove last newline character
692                 s = s[:-1]
693
694                 # disulfide bridges - get half-cysteines by selection:
695         # sele (bto. ((object) & r. CYS+CYX & n. SG) )& n. SG
696                 ncys=cmd.get_model("(bto. (("+str(self.cb2.getvalue()[0])+") & r. CYS+CYX & n. SG)) & n. SG").atom
697                 nSSbr=len(ncys)/2
698         
699                 
700                 # Is "Write disulfide brige" checked?
701                 # yes
702                 if self.writeSSbrige.get():
703                         # write number of half-cysteines
704                         s+=str(len(ncys))+"\n"
705                         if len(ncys)==0:
706                                 # No half-cysteines, cys position = 0  
707                                 s+=" 0\n"
708                         else:
709                                 # Write half-cysteine positions in sequence
710                                 #       
711                                 # get first chain
712                                 first=cmd.get_model(str(self.cb2.getvalue()[0])+"& chain "+str(chains[0])+" & n. ca")
713                         
714                                 # calculate base offset in first chain (if dummy atom present offset = 1 )      
715                                 if first.atom[0].resn=="GLY":
716                                         boff=0
717                                 else: 
718                                         boff=1 
719                         
720                                 # create dictionary of PDB chain/resi to UNRES_index
721                                 unresidx={}
722                                 for c in ncys:
723                                         # calculate residue index offset from first residue in chain containing half-cysteine
724                                         fresinchain=cmd.get_model(str(self.cb2.getvalue()[0])+"& chain "+c.chain+" & n. ca").atom
725                                         roff=int(c.resi)-int(fresinchain[0].resi)+1
726                                 
727                                         resb=0
728                                         coff=0
729                                         for r in chains:
730                                                 if c.chain==r:
731                                                         break
732                                                 resb+=len(cmd.get_model(str(self.cb2.getvalue()[0])+"& chain "+r+" & n. ca").atom)
733                                                 coff+=1
734                                         # add key/value to dictionary
735                                         unresidx[c.chain+"/"+str(c.resi)]=boff+resb+coff+roff   
736                                         s+=" "+str(boff+resb+coff+roff)
737                                 s+="\n"
738
739                                 # Write the number of disulfide bridges
740                                 s+=" "+str(nSSbr)+"\n"
741                         
742                                 lista_mostkow=[]
743                                 for c in ncys:
744                                         # get neibhoring Sulfur atom
745                                         opis=c.chain+str(c.resi)
746                                         lista_mostkow.append(opis)
747                                         nbr=cmd.get_model("(bto. ("+str(self.cb2.getvalue()[0])+" & resi "+str(c.resi)+"& n. SG & chain "+str(c.chain)+")) & n. SG").atom[0]
748                                         opis2=nbr.chain+str(nbr.resi)
749                                         if opis2 not in lista_mostkow:
750                                                 # Write witch half-cysteines build the i-th disulfide bridge
751                                                 s+=" "+str(unresidx[c.chain+"/"+str(c.resi)])+" "+str(unresidx[nbr.chain+"/"+str(nbr.resi)])+"\n"
752                                                 #print c.chain, c.resn,c.resi,"-S-S-", nbr.chain, nbr.resn,nbr.resi
753                 # Don't writeSSbrige    
754                 else:
755                         s+="0\n 0\n"
756                                 
757
758                 return s
759
760
761         def write_cshell(self, cshname,prefix):
762                 '''
763                         Writes the C-shell script needed to run UNRES calculations
764                 '''
765                 s='#!/bin/csh -f\n#\n# C-shell script generated by UNRESInpGen.py\n#\n'
766                 
767                 # number of processors per energy
768                 if self.OM1Val.get()=="MD":
769                         s+='setenv FGPROCS 1\n'
770
771                 # Potential
772                 if self.OM2Val.get()=="CASP3":
773                         s+='setenv POT LJ\n'
774                 else:
775                         s+='setenv POT GB\n'
776
777                 # input file
778                 s+='setenv PREFIX '+prefix+'\n'
779
780                 # Parallel stuff
781                 s+='setenv OUT1FILE YES\n'
782
783                 # force filed parameters
784                 s+='#---------------------------------------------------------------------\n'
785                 s+='setenv DD $UNRES_ROOT/PARAM\n'
786
787                 if self.OM2Val.get()=="CASP3":
788                         s+='setenv BONDPAR $DD/bond.parm\nsetenv THETPAR $DD/thetaml.5parm\nsetenv ROTPAR $DD/scgauss.parm\n'
789                         s+='setenv TORPAR $DD/torsion_cryst.parm\nsetenv TORDPAR $DD/torsion_double_631Gdp.parm\nsetenv SIDEPAR $DD/scinter_LJ.parm\n'
790                         s+='setenv ELEPAR $DD/electr.parm\nsetenv SCPPAR $DD/scp.parm\nsetenv FOURIER $DD/fourier_GAP.parm\n'
791                         s+='setenv SCCORPAR $DD/rotcorr_AM1.parm\n'
792                 elif self.OM2Val.get()=="ALPHA" or self.OM2Val.get()=="BETA" or self.OM2Val.get()=="ALPHABETA":
793                         s+='setenv BONDPAR $DD/bond.parm\nsetenv THETPAR $DD/thetaml.5parm\nsetenv ROTPAR $DD/scgauss.parm\n'
794                         s+='setenv TORPAR $DD/torsion_ecepp.parm\nsetenv TORDPAR $DD/torsion_double_631Gdp.parm\nsetenv SIDEPAR $DD/scinter_GB.parm\n'
795                         s+='setenv ELEPAR $DD/electr.parm\nsetenv SCPPAR $DD/scp.parm\nsetenv FOURIER $DD/fourier_GAP.parm\nsetenv SCCORPAR $DD/rotcorr_AM1.parm\n'
796                 elif self.OM2Val.get()=="CASP5":
797                         s+='setenv BONDPAR $DD/bond.parm\nsetenv THETPAR $DD/thetaml.5parm\nsetenv ROTPAR $DD/scgauss.parm\n'
798                         s+='setenv TORPAR $DD/torsion_631Gdp.parm\nsetenv TORDPAR $DD/torsion_double_631Gdp.parm\nsetenv SIDEPAR $DD/scinter_GB.parm\n'
799                         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'
800                 elif self.OM2Val.get()=="3P":
801                         s+='setenv BONDPAR $DD/bond.parm\nsetenv THETPAR $DD/thetaml.5parm\nsetenv ROTPAR $DD/scgauss.parm\n'
802                         s+='setenv TORPAR $DD/torsion_631Gdp.parm\nsetenv TORDPAR $DD/torsion_double_631Gdp.parm\nsetenv SIDEPAR $DD/sc_GB_opt.3P7_iter81_1r\n'
803                         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'
804                 elif self.OM2Val.get()=="4P":
805                         s+='setenv BONDPAR $DD/bond.parm\nsetenv THETPAR $DD/thetaml.5parm\nsetenv ROTPAR $DD/scgauss.parm\n'
806                         s+='setenv TORPAR $DD/torsion_631Gdp.parm\nsetenv TORDPAR $DD/torsion_double_631Gdp.parm\nsetenv SIDEPAR $DD/sc_GB_opt.4P5_iter33_3r\n'
807                         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'
808                 elif self.OM2Val.get()=="GAB":
809                         s+='setenv BONDPAR $DD/bond.parm\nsetenv THETPAR $DD/thetaml.5parm\nsetenv ROTPAR $DD/scgauss.parm\n'
810                         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'
811                         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'
812                 elif self.OM2Val.get()=="E0G":  
813                         s+='setenv BONDPAR $DD/bond.parm\nsetenv THETPAR $DD/thetaml.5parm\nsetenv ROTPAR $DD/scgauss.parm\n'
814                         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'
815                         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'
816                 elif self.OM2Val.get()=="1L2Y_1LE1":
817                         s+='setenv BONDPAR $DD/bond_AM1.parm\nsetenv THETPAR $DD/thetaml.5parm\nsetenv ROTPAR $DD/rotamers_AM1_aura.10022007.parm\n'
818                         s+='setenv TORPAR $DD/torsion_631Gdp.parm\nsetenv TORDPAR $DD/torsion_double_631Gdp.parm\nsetenv SIDEPAR $DD/scinter_$POT.parm\n'
819                         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'
820                 elif self.OM2Val.get()=="Custom":
821                         s+='setenv BONDPAR $DD/.parm\nsetenv THETPAR $DD/.parm\nsetenv ROTPAR $DD/.parm\n'
822                         s+='setenv TORPAR $DD/.parm\nsetenv TORDPAR $DD/.parm\nsetenv SIDEPAR $DD/.parm\n'
823                         s+='setenv ELEPAR $DD/.parm\nsetenv SCPPAR $DD/.parm\nsetenv FOURIER $DD/.parm\nsetenv SCCORPAR $DD/.parm\n'
824
825
826
827                 s+='setenv PATTERN $DD/patterns.cart\n'
828                 s+='#---------------------------------------------------------------------\n'
829                 s+='$UNRES_BIN $*\n'
830
831                 f = open(cshname, 'w')
832                 f.write(s)
833                 f.close()
834
835
836         def setenv_info(self):
837                 print '''IMPORTANT: Remember to set the following envirament variables for your shell before starting calculations:
838                   UNRES_ROOT - the root directory where UNRES is installed on your system (should contain PARAM directory)
839                   UNRES_BIN  - the UNRES binary you want to execute
840                 '''
841
842
843         def ok(self):
844                 '''
845                     Writes the actual input     
846                 '''
847                 myFormats = [
848                     ('Input files','*.inp'),
849                         ('All files','*.*')
850                 ]
851                 # Write error handling for empty sequence
852                 #
853                 s=self.gr3.t1.getvalue()
854                 if len(s.strip())==0:
855                         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\".")
856                 else:                           
857                         # Display dialog window
858                         fout = tkFileDialog.asksaveasfile(parent=self,mode='w',filetypes=myFormats,title='Save input')
859                         if fout:
860                                 print "Saving input file %s" % fout.name
861                                 # Get input header
862                                 text2save=self.fortran_format(self.e1.get())
863                                 # Get main options
864                                 mainopt="SEED="+self.gr1.e1.get()+" "
865                                 if self.OM1Val.get()=="MD":
866                                         mainopt+="MD PDBREF EXTCONF"
867                                 elif self.OM1Val.get()=="MREMD":
868                                         mainopt+="RE "
869                                 elif self.OM1Val.get()=="MINIMIZE":
870                                         mainopt+="PDBREF MINIMIZE RESCALE_MODE=0"
871                                         if self.CART.get():
872                                                 mainopt+=" CART"
873                                         if self.OVERLAP.get():
874                                                 mainopt+=" OVERLAP"
875                                         if self.NOSEARCHSC.get():
876                                                 mainopt+=" NOSERARCHSC"
877                                 text2save+=self.fortran_format(mainopt)
878                                 # Get aux options
879
880                                 if self.OM1Val.get()=="MD":
881                                         text2save+=self.fortran_format(self.get_md_opt())
882                                 elif self.OM1Val.get()=="MINIMIZE":
883                                         text2save+=self.fortran_format(self.get_minim_opt())
884
885                                 # Get force fields parameters
886                                 text2save+=self.fortran_format(self.get_weights())
887                 
888                                 # PDB reference
889                                 pdbreffn=str(self.cb2.getvalue()[0])+"_pdbref.pdb"
890                                 text2save+=pdbreffn+"\n"
891                                 print "Saving PDB reference structure %s" % (os.path.join(os.path.dirname(fout.name),pdbreffn))
892                                 cmd.save(os.path.join(os.path.dirname(fout.name),pdbreffn), self.cb2.getvalue()[0])
893
894                                 # C-shell script 
895                                 cshellfn=os.path.join(os.path.dirname(fout.name),"unres_"+os.path.basename(os.path.splitext(fout.name)[0])+".csh")
896                                 print "Writing C-shell script %s" % (cshellfn)
897                                 prefix=os.path.basename(os.path.splitext(fout.name)[0])
898                                 self.write_cshell(cshellfn,prefix)
899                                 
900                                 # Get sequence data
901                                 text2save+=self.get_seq_data()
902
903                                 fout.write(text2save)
904                                 fout.close()
905
906                                 # ENV Varaiables info
907                                 self.setenv_info()