1 # -*- coding: utf-8 -*-
3 -------------------------------------------------------------------------------
4 UNRESInpGen.py - UNRES graphical input generator v 1.0
5 -------------------------------------------------------------------------------
7 Written by Dawid Jagieła (lightnir@chem.univ.gda.pl) Oct 2012
11 from pymol import cmd,stored
19 UNRESInpGen_version="1.0"
22 self.UNRESInpGenWindow = None
24 self.menuBar.addcascademenu('Plugin', 'UNRESPlugins', 'UNRESPACK Plugins', label='UNRES Plugins')
28 self.menuBar.addmenuitem('UNRESPlugins', 'command','UNRESInpGen',
29 label='UNRES Input Generator',
30 command = lambda s=self: createUNRESInpGen(s) )
32 def createUNRESInpGen(app):
33 if (app.UNRESInpGenWindow == None):
34 app.UNRESInpGenWindow = UNRESInpGenerator(app)
36 app.UNRESInpGenWindow.myToggle()
38 #=================================================================
41 class UNRESInpGenerator(Toplevel):
42 global UNRESInpGen_version
52 writeSSbrige = IntVar()
58 objects_list = ['Select object']
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' ]
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'}
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'}
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
98 self.balloon = Pmw.Balloon(root)
100 #================================
101 # "Main Options" group
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)
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(),
112 validate = {'max': 80 },
113 # value ="(Place input information here)"
115 self.e1.component('entry').config(width=80)
116 self.e1.grid(row=0, column=0,columnspan=4, sticky=E)
118 # - Create "choose method" OptionMenu
119 self.OM1Val.set('MD')
120 self.optmenu1 = Pmw.OptionMenu(self.gr1.interior(),
122 label_text = 'Choose method:',
123 menubutton_textvariable = self.OM1Val,
124 items = ['MD', 'REMD/MREMD', 'MINIMIZE' ],
125 command = self.switch_options,
126 menubutton_width = 10
128 self.optmenu1.grid(row=1, column=0,columnspan=2, sticky=E)
132 self.gr1.e1 = Pmw.EntryField(self.gr1.interior(),
135 validate = {'validator' : 'integer', 'min': -2147483648 , 'max' : 0 },
138 self.gr1.e1.component('entry').config(width=8)
139 self.gr1.e1.grid(row=1, column=2, sticky=W)
141 #==================================
144 self.gr1.md = Frame(self.gr1.interior())
145 self.gr1.md.grid(row=2, column=0, columnspan=4,sticky=W+E)
147 # -- nstep entryfield
148 self.gr1.md.e1 = Pmw.EntryField(self.gr1.md,
151 validate = {'validator' : 'integer', 'min': 1 , 'max' : 1000000 },
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)
159 self.gr1.md.e2 = Pmw.EntryField(self.gr1.md,
162 validate = {'validator' : 'integer', 'min': 0 , 'max' : 1000000 },
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)
170 self.gr1.md.e3 = Pmw.EntryField(self.gr1.md,
173 validate = {'validator' : 'integer', 'min': 1 , 'max' : 1000000 },
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)
181 self.gr1.md.e4 = Pmw.EntryField(self.gr1.md,
184 validate = {'validator' : 'real', 'min': 0.001 , 'max' : 1000 },
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)
190 # -- damax entryfield
191 self.gr1.md.e5 = Pmw.EntryField(self.gr1.md,
194 validate = {'validator' : 'real', 'min': 0.001 , 'max' : 1000 },
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)
200 # -- dvmax entryfield
201 self.gr1.md.e6 = Pmw.EntryField(self.gr1.md,
204 validate = {'validator' : 'real', 'min': 0.001 , 'max' : 1000 },
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)
210 # -- restet_vel entryfield
211 self.gr1.md.e7 = Pmw.EntryField(self.gr1.md,
213 label_text="RESET_VEL",
214 validate = {'validator' : 'integer', 'min': 0 , 'max' : 10000000 },
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)
220 # -- initial structure
221 self.gr1.md.om1 = Pmw.OptionMenu(self.gr1.md,
223 label_text = 'Start from',
224 items = ['PDB', 'extended', 'random' ],
225 menubutton_width = 8,
227 self.gr1.md.om1.grid(row=1,column=3, sticky=E)
229 #=================================
232 self.gr1.th = Frame(self.gr1.interior())
233 self.gr1.th.grid(row=3, column=0, columnspan=5,sticky=W+E)
235 # -- Thermostat optionmenu
236 self.gr1.th.optmenu1 = Pmw.OptionMenu(self.gr1.th,
238 label_text = 'thermostat',
239 items = ['Berendsen', 'Nose-Poincare 1999','Nose-Poincare 2001', 'Nose-Hoover', 'Langevin' ],
240 command=self.set_thermostat,
241 menubutton_width = 15
243 self.gr1.th.optmenu1.pack(side=LEFT)#grid(row=0, column=0, sticky=E)
245 # -- t_bath entryfield
246 self.gr1.th.e1 = Pmw.EntryField(self.gr1.th,
249 validate = {'validator' : 'real', 'min': 0.000001 , 'max' : 10000 },
251 self.balloon.bind(self.gr1.th.e1, "Temperature (in K) of canonical simulation.")
252 self.gr1.th.e1.component('entry').config(width=8)
253 self.gr1.th.e1.pack(side=LEFT)
255 # -- tau_bath entryfield
256 self.gr1.th.e2 = Pmw.EntryField(self.gr1.th,
258 label_text="TAU_BATH",
259 validate = {'validator' : 'real', 'min': 0.000001 , 'max' : 1000000 },
261 self.balloon.bind(self.gr1.th.e2, "(units are mtus; 1mtu=48.9 fs) \nConstant of the coupling to the thermal bath")
262 self.gr1.th.e2.component('entry').config(width=8)
263 self.gr1.th.e2.pack(side=LEFT)
266 self.gr1.th.e3 = Pmw.EntryField(self.gr1.th,
269 validate = {'validator' : 'real', 'min': 0.000001 , 'max' : 1000000 },
271 self.balloon.bind(self.gr1.th.e3, "Mass of the fictitious particle in the calculations with the Nose-Poincare & Nose-Hoover thermostats.")
272 self.gr1.th.e3.component('entry').config(width=8)
273 #self.gr1.th.e2.pack(side=LEFT)
276 #=================================
277 # - Minimization frame
278 self.gr1.mi = Frame(self.gr1.interior())
279 #self.gr1.mi.grid(row=4, column=0, columnspan=5,sticky=W+E)
281 self.gr1.mi.e1 = Pmw.EntryField(self.gr1.mi,
284 validate = {'validator' : 'integer', 'min': 0 , 'max' : 1000000 },
286 self.balloon.bind(self.gr1.mi.e1,'Maximum number of iterations of the SUMSL minimizer.')
287 self.gr1.mi.e1.component('entry').config(width=8)
288 self.gr1.mi.e1.pack(side=LEFT)
290 self.gr1.mi.e2 = Pmw.EntryField(self.gr1.mi,
293 validate = {'validator' : 'integer', 'min': 0 , 'max' : 1000000 },
295 self.balloon.bind(self.gr1.mi.e2,'Maximum number of function evaluations in a single minimization.')
296 self.gr1.mi.e2.component('entry').config(width=8)
297 self.gr1.mi.e2.pack(side=LEFT)
299 self.gr1.mi.c1 = Checkbutton(self.gr1.mi,
301 variable = self.CART )
302 self.balloon.bind(self.gr1.mi.c1,'Minimize in virtual-bond vectors instead of angles.')
303 self.gr1.mi.c1.pack(side=LEFT)
305 self.gr1.mi.c2 = Checkbutton(self.gr1.mi,
307 variable = self.OVERLAP )
308 self.balloon.bind(self.gr1.mi.c2,'Fix overlaping sidechains.')
309 self.gr1.mi.c2.pack(side=LEFT)
311 self.gr1.mi.c3 = Checkbutton(self.gr1.mi,
313 variable = self.NOSEARCHSC )
314 #self.balloon.bind(self.gr1.mi.c3,'Minimize in virtual-bond vectors instead of angles.')
315 self.gr1.mi.c3.pack(side=LEFT)
318 #=================================
320 self.gr1.re = Frame(self.gr1.interior())
321 #self.gr1.re.grid(row=5, column=0, columnspan=5,sticky=W+E)
323 self.gr1.re.e1 = Pmw.EntryField(self.gr1.re,
326 validate = {'validator' : 'integer', 'min': 1 , 'max' : 32 },
327 command = self.set_replica_widgets,
329 self.balloon.bind(self.gr1.re.e1,'Number of replicas in a REMD/MREMD run.')
330 self.gr1.re.e1.component('entry').config(width=8)
331 self.gr1.re.e1.grid(row=0, column=0, sticky=W)
333 self.gr1.re.e2 = Pmw.EntryField(self.gr1.re,
335 label_text = "NSTEX",
336 validate = {'validator' : 'integer', 'min': 0 , 'max' : 1000000 },
338 self.balloon.bind(self.gr1.re.e2,'Number of steps after which exchange is performed in REMD/MREMD runs.')
339 self.gr1.re.e2.component('entry').config(width=8)
340 self.gr1.re.e2.grid(row=0, column=1, sticky=W)
343 self.gr1.re.rs = Pmw.RadioSelect(self.gr1.re,
345 label_text = 'Replica temperatures',
346 command = self.sel_replica_mode,
347 buttontype = 'radiobutton'
348 #frame_borderwidth = 2,
349 #frame_relief = 'ridge'
351 self.gr1.re.rs.grid(row=1, column=0, columnspan=4,sticky=W)
353 for text in ('Manual', 'Range'):
354 self.gr1.re.rs.add(text)
357 self.gr1.re.tf1 = Frame(self.gr1.re, bg="blue")
358 self.gr1.re.tf1.grid(row=2,column=0, columnspan=4, sticky=W)
360 self.gr1.re.tf1.e1 = Pmw.EntryField(self.gr1.re.tf1,
362 label_text = "RETMIN",
363 validate = {'validator' : 'real', 'min': 0 , 'max' : 1000000 },
365 self.balloon.bind(self.gr1.re.tf1.e1,'Minimum temperature in a REMD/MREMD run.')
366 self.gr1.re.tf1.e1.component('entry').config(width=8)
367 self.gr1.re.tf1.e1.grid(row=0, column=0, sticky=W)
369 self.gr1.re.tf1.e2 = Pmw.EntryField(self.gr1.re.tf1,
371 label_text = "RETMAX",
372 validate = {'validator' : 'real', 'min': 0 , 'max' : 1000000 },
374 self.balloon.bind(self.gr1.re.tf1.e2,'Maxmum temperature in a REMD/MREMD run.')
375 self.gr1.re.tf1.e2.component('entry').config(width=8)
376 self.gr1.re.tf1.e2.grid(row=0, column=1, sticky=W)
379 self.gr1.re.tf2 = Frame(self.gr1.re)
380 self.gr1.re.tf2.grid(row=3,column=0, columnspan=4, sticky=W)
382 self.gr1.re.tf2.te = []
383 for i in range(0,32): #int(self.gr1.re.e1.get())):
384 self.gr1.re.tf2.te.append(Pmw.EntryField(self.gr1.re.tf2,
386 label_text='T%02d' % (i+1),
387 validate = {'validator' : 'real','min' : 0, 'max' : 1000, 'minstrict' : 0},
388 value = '%d' % (200+i*10)))
389 self.gr1.re.tf2.te[i].component('entry').config(width=3)
390 self.gr1.re.tf2.te[i].grid(row=1+(i//16), column=0+(i % 16))
392 self.gr1.re.tf2.nre = Pmw.EntryField(self.gr1.re.tf2,
394 label_text='Rep. in Temp.',
395 validate = {'validator' : 'integer','min' : 1, 'max' : 100 },
397 self.gr1.re.tf2.nre.component('entry').config(width=3)
398 self.gr1.re.tf2.nre.grid(row=1, column=17)
400 # display manual replica options
401 self.gr1.re.e1.invoke()
402 self.gr1.re.rs.invoke('Manual')
404 #=================================
405 # "Force field options" group
407 self.gr2 = Pmw.Group(self,tag_text = 'Force field options')
408 self.gr2.grid(row=2, column=0,columnspan=4,sticky=W+E,padx=10, pady=5)
410 # - Create "force field parameters" Option menu
411 self.OM2Val.set('Custom')
412 self.optmenu2 = Pmw.OptionMenu(self.gr2.interior(),
413 label_text = 'Force field parameters:',
415 menubutton_textvariable = self.OM2Val,
416 items = ['Custom','GAB','E0G', '1L2Y_1LE1','4P','3P','CASP5','ALPHABETA','BETA','ALPHA','CASP3' ],
417 initialitem = 'Custom',
418 menubutton_width = 10,
419 command=self.set_force_field
421 self.optmenu2.grid(row=0, column=0,columnspan=4,sticky=E)
423 # Force field parameters Entry Fields
425 for i in range(0,len(self.weights)):
426 self.ef.append(Pmw.EntryField(self.gr2.interior(),
428 label_text=self.weights[i],
429 validate = {'validator' : 'real','min' : 0, 'max' : 10, 'minstrict' : 0},
431 self.ef[i].component('entry').config(width=8)
432 self.ef[i].grid(row=1+(i//9), column=0+(i % 9))
434 #===================================
437 self.gr3 = Pmw.Group(self,tag_text = 'Sequence')
438 self.gr3.grid(row=3, column=0,columnspan=4,sticky=W+E,padx=10, pady=5)
440 self.gr3.f1 = Frame(self.gr3.interior())
442 self.cb2 = Pmw.ComboBox(self.gr3.f1,
444 #entry_relief = 'raised',
445 label_text = 'Selection/Object',
446 scrolledlist_items = self.objects_list
448 self.cb2.pack(side=LEFT)
450 self.gr3.btn1 = Button(self.gr3.f1, text='Refresh', padx=0, pady=0 , command = self.refresh_list)
451 self.gr3.btn1.pack(side=LEFT)
452 # Get sequence button
453 self.gr3.btn2 = Button(self.gr3.f1, text='Get Sequence', padx=0, pady=0 , command = self.get_seq)
454 self.gr3.btn2.pack(side=LEFT)
456 self.gr3.f1.pack(expand="yes",fill="both")
458 # Disulfide brige checkbox
459 self.gr3.chk = Checkbutton(self.gr3.f1, text="Write disulfide bridges", variable=self.writeSSbrige)
460 self.gr3.chk.pack(side=LEFT)
463 self.gr3.t1 = Pmw.ScrolledText(self.gr3.interior(),
465 columnheader_width = 3,
476 # Sequence text - create the header line
478 for column in range(1,21):
479 headerline = headerline + ('%-4s' % str(column) )
480 self.gr3.t1.component('columnheader').insert('0.0',headerline)
482 self.gr3.t1.pack(expand="yes",fill="both")
485 btn3=Button(self, text='Write Input', padx=0, pady=0, command = self.ok)
486 btn3.grid(row=10, column=0, columnspan=2,sticky=N+W+S+E)
487 btn4=Button(self, text='Close', padx=0, pady=0, command = self.myHide)
488 btn4.grid(row=10, column=2, columnspan=2,sticky=N+W+S+E)
490 # create callback to prevent window kill
491 self.protocol("WM_DELETE_WINDOW", self.myHide)
493 def ToggleColor(self):
494 if self.colorize.get()==1:
495 for i in range(0,len(self.res_states)):
496 UNRESInpGenWindow.ccb[i].config(state=ACTIVE, bg=self.res_states[i][1], activebackground=self.res_states[i][1], relief=RAISED, overrelief=RAISED)
498 for i in range(0,len(self.res_states)):
499 UNRESInpGenWindow.ccb[i].config(state=DISABLED, bg=self.Default_Color , activebackground=self.Default_Color, relief=RAISED, overrelief=RAISED)
508 if self.state() == "normal":
510 elif self.state() == "withdrawn":
513 def get_selections(self):
514 self.objects_list = []
515 for item in cmd.get_names("all"):
516 if cmd.get_type(item)=="object:molecule":
517 self.objects_list.append(item)
518 if cmd.get_type(item)=="selection":
520 self.objects_list.append(item)
522 def get_nonstandard(self):
524 cmd.iterate("(all)","stored.list.append(resn)")
525 stored.list=list(Set(stored.list)) # remove duplicates
526 # Remove standard amino acids and water from list
527 for m in ['HIS','ASP','ARG','PHE','ALA','CYS','GLY','GLN','GLU','LYS','LEU','MET','ASN','SER','TYR','THR','ILE','TRP','PRO','VAL','HOH']:
529 stored.list.remove(m)
532 UNRESInpGenWindow.cbcr1.setlist(stored.list)
534 def refresh_list(self):
536 old = self.objects_list
538 old_cb2=self.cb2.getvalue()[0]
541 self.get_selections()
543 # Update selectionlist if needed
544 if not(old==self.objects_list):
545 self.cb2.setlist(self.objects_list)
546 self.cb2.setlist(self.objects_list)
548 if not(old_cb2 in self.objects_list):
549 # No - clear the combobox entry
550 self.cb2.component('entryfield').clear()
552 # Yes - set the old value
553 self.cb2.selectitem(old_cb2,setentry=1)
557 # Get the number of chains
559 nchains=int(len(cmd.get_chains(self.cb2.getvalue()[0])))
569 for chain in range(0,nchains):
570 # Get only amonoacids, N-terminus acyl and C-terminus amide
571 # example: (1uRC and chain F and (n. ca or (resn ACE and n. C) or (resn NH2 and n. N)))
572 # No chain information or only one chain
574 atomchain=cmd.get_model(str(self.cb2.getvalue()[0])+" & (n. ca|(resn ACE & n. C)|(resn NH2+NHH+NME & n. N))").atom
575 # Chain information is present
577 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
578 # dodaj separator lancuchow
580 self.seq_list.append("D ")
584 # Zamiana chronionych
585 # ACE ALA ALA NH2 D ACE ALA ALA NH2
586 # GLY ALA ALA GLY D GLY ALA ALA GLY
587 # Zamiana niechronionych
589 # D ALA ALA D ALA ALA D
591 # j - licznik pozycji reszty
595 if str(i.resn)=="NH2":
596 self.seq_list.append("GLY")
597 elif str(i.resn)=="NHH":
598 self.seq_list.append("GLY")
599 elif str(i.resn)=="NME":
600 self.seq_list.append("GLY")
601 elif str(i.resn)=="ACE":
602 self.seq_list.append("GLY")
603 elif str(i.resn)=="GLY":
604 self.seq_list.append("GLY")
606 if j==0 and chain==0:
607 self.seq_list.append("D ")
608 self.seq_list.append(str(i.resn))
610 elif j==len(atomchain)-1 and chain==(nchains-1):
611 self.seq_list.append(str(i.resn))
612 self.seq_list.append("D ")
615 self.seq_list.append(str(i.resn))
618 #row_header='0' - old header
621 self.gr3.t1.tag_configure('dummy', background = 'LightBlue1')
623 self.gr3.t1.tag_configure('cysteine', background = 'LightGoldenrod1')
626 for i in range(len(self.seq_list)):
628 if self.seq_list[i]=="D ":
629 tag1 = '%d.%d' % (rows+1, ((len(seq_data)-rows)%80))
630 tag2 = '%d.%d' % (rows+1, ((len(seq_data)-rows)%80)+3)
634 if self.seq_list[i]=="CYS" or self.seq_list[i]=="CYX":
635 tag1 = '%d.%d' % (rows+1, ((len(seq_data)-rows)%80))
636 tag2 = '%d.%d' % (rows+1, ((len(seq_data)-rows)%80)+3)
637 CysTagList.append(tag1)
638 CysTagList.append(tag2)
641 seq_data=seq_data+self.seq_list[i]+" "
645 seq_data=seq_data+'\n'
647 #row_header=row_header+'\n'+str(rows*20) - old header
648 row_header=row_header+'\n'+str(rows+1)
651 self.gr3.t1.insert('end',seq_data)
654 apply(self.gr3.t1.tag_add, ('dummy',) + tuple(tagList))
656 apply(self.gr3.t1.tag_add, ('cysteine',) + tuple(CysTagList))
659 self.gr3.t1.component('rowheader').delete(1.0, END)
660 self.gr3.t1.component('rowheader').insert('end',row_header)
663 def switch_options(self,calctype):
665 Displays the options available to set depending on the currently
666 selected calculation type
669 self.gr1.th.grid_remove()
670 self.gr1.md.grid_remove()
671 self.gr1.mi.grid_remove()
672 self.gr1.re.grid_remove()
674 if self.OM1Val.get()=="MD":
675 self.gr1.md.grid(row=2, column=0, columnspan=5, sticky=W+E)
676 self.gr1.th.grid(row=3, column=0, columnspan=5, sticky=W+E)
677 elif self.OM1Val.get()=="REMD/MREMD":
678 self.gr1.md.grid(row=2, column=0, columnspan=5, sticky=W+E)
679 self.gr1.th.grid(row=3, column=0, columnspan=5, sticky=W+E)
680 self.gr1.re.grid(row=5, column=0, columnspan=5, sticky=W+E)
681 elif self.OM1Val.get()=="MINIMIZE":
682 self.gr1.mi.grid(row=4,column=0,columnspan=5, sticky=W+E)
684 def sel_replica_mode(self,mode):
686 Display replica temperatures settings
689 self.gr1.re.tf1.grid_remove()
690 self.gr1.re.tf2.grid_remove()
692 self.gr1.re.tf1.grid(row=2,column=0, columnspan=4, sticky=W)
694 self.gr1.re.tf2.grid(row=3,column=0, columnspan=4, sticky=W)
698 def set_replica_widgets(self):
700 Refresh list of available temperature widgets in manual mode
702 #print self.gr1.re.e1.get()
703 for i in range(0,32): #int(self.gr1.re.e1.get())):
705 if i<int(self.gr1.re.e1.get()):
706 self.gr1.re.tf2.te[i].component('entry').config(state=NORMAL)
708 self.gr1.re.tf2.te[i].component('entry').config(state=DISABLED)
714 def set_force_field(self, pole):
716 Enables/disables entryfields for force field perameters depending
717 on the currently selected force field
719 for ff in self.force_fields:
722 for i in range(0,len(self.weights)):
723 if ff.has_key(self.weights[i]):
724 self.ef[i].setvalue(ff.get(self.weights[i]))
725 self.ef[i].component('entry').config(state=NORMAL)
727 self.ef[i].component('entry').config(state=DISABLED)
730 for i in range(0,len(self.weights)):
731 self.ef[i].component('entry').config(state=NORMAL)
733 def set_thermostat(self,thermostat):
735 Display additional widget acording to selected thermostat
738 self.gr1.th.e2.pack_forget()
739 self.gr1.th.e3.pack_forget()
740 if thermostat=='Berendsen':
741 self.gr1.th.e2.pack(side=LEFT)
742 elif thermostat=='Nose-Poincare 1999' or thermostat=='Nose-Poincare 2001' or thermostat=='Nose-Hoover':
743 self.gr1.th.e3.pack(side=LEFT)
745 def fortran_format(self,s):
747 Formats string containing keywords to wrap over 80 columns.
748 Input string should be one line.
753 if column+len(k)+1<80:
757 tmpstr+=" "*(80-column)+"&\n"+k+" "
762 def get_weights(self):
764 Get the force field weights
767 for i in range(0,len(self.weights)):
768 if self.ef[i].component('entry').cget("state")=="normal":
769 s+=self.weights[i]+"="+self.ef[i].getvalue()+" "
772 def get_md_opt(self):
774 Get MD options for main input
776 s = "NSTEP="+self.gr1.md.e1.getvalue()+" NTWE="+self.gr1.md.e2.getvalue()+" "
777 s+= "NTWX="+self.gr1.md.e3.getvalue()+" DT="+self.gr1.md.e4.getvalue()+" "
778 s+= "DAMAX="+self.gr1.md.e5.getvalue()+" DVMAX="+self.gr1.md.e6.getvalue()+" "
779 s+= "RESET_VEL="+self.gr1.md.e7.getvalue()+" "
782 term=self.gr1.th.optmenu1.getvalue()
784 if term=="Berendsen":
785 s+="TBF TAU_BATH="+self.gr1.th.e2.getvalue()+" "
786 elif term=="Nose-Poincare 1999":
787 s+="NOSEPOINCARE99 Q_NP="+self.gr1.th.e3.getvalue()+" "
788 elif term=="Nose-Poincare 2001":
789 s+="NOSEPOINCARE01 Q_NP="+self.gr1.th.e3.getvalue()+" "
790 elif term=="Nose-Hoover":
791 s+="NOSEHOOVER96 Q_NP="+self.gr1.th.e3.getvalue()+" "
792 elif term=="Langevin":
795 s+="T_BATH="+self.gr1.th.e1.getvalue()+" "
798 def get_minim_opt(self):
800 Get minimization options
802 s = "MAXMIN="+self.gr1.mi.e1.getvalue()+" MAXFUN="+self.gr1.mi.e2.getvalue()
806 def get_mremd_opt(self):
808 Generates a sting containing REMD?MREMD main options for input
810 s = "NREP="+self.gr1.re.e1.get()+" NSTEX="+self.gr1.re.e2.get()+" "
811 if self.gr1.re.rs.getvalue()=="Range":
812 s+="RETMIN="+self.gr1.re.tf1.e1.get()+"RETMAX="+self.gr1.re.tf1.e2.get()
815 s+=" TRAJ1FILE REST1FILE SYNC"
819 def get_mremd_temp_opt(self):
821 Generate a strong containing temperatures for REMD/MREMD "manual mode"
824 for i in range(0,int(self.gr1.re.e1.get())):
825 s+=self.gr1.re.tf2.te[i].get()+" "
829 def get_mremd_replicas(self):
831 Generates a string containing number of replicas in every temperature for REMD/MREMD calculations.
832 For REMD calculations contains only sequence of ones.
835 for i in range(0,int(self.gr1.re.e1.get())):
836 s+=self.gr1.re.tf2.nre.get()+" "
840 def get_seq_data(self):
842 Dumps the sequence and disulfide bridge information
844 # write sequence length
845 s = str(self.seq_length)+"\n"
847 chains=cmd.get_chains(self.cb2.getvalue()[0])
850 # apply one space before each sequence line
851 seq=self.gr3.t1.get()
852 for line in seq.split('\n'):
854 # remove last newline character
857 # disulfide bridges - get half-cysteines by selection:
858 # sele (bto. ((object) & r. CYS+CYX & n. SG) )& n. SG
859 ncys=cmd.get_model("(bto. (("+str(self.cb2.getvalue()[0])+") & r. CYS+CYX & n. SG)) & n. SG").atom
863 # Is "Write disulfide brige" checked?
865 if self.writeSSbrige.get():
866 # write number of half-cysteines
867 s+=str(len(ncys))+"\n"
869 # No half-cysteines, cys position = 0
872 # Write half-cysteine positions in sequence
875 first=cmd.get_model(str(self.cb2.getvalue()[0])+"& chain "+str(chains[0])+" & n. ca")
877 # calculate base offset in first chain (if dummy atom present offset = 1 )
878 if first.atom[0].resn=="GLY":
883 # create dictionary of PDB chain/resi to UNRES_index
886 # calculate residue index offset from first residue in chain containing half-cysteine
887 fresinchain=cmd.get_model(str(self.cb2.getvalue()[0])+"& chain "+c.chain+" & n. ca").atom
888 roff=int(c.resi)-int(fresinchain[0].resi)+1
895 resb+=len(cmd.get_model(str(self.cb2.getvalue()[0])+"& chain "+r+" & n. ca").atom)
897 # add key/value to dictionary
898 unresidx[c.chain+"/"+str(c.resi)]=boff+resb+coff+roff
899 s+=" "+str(boff+resb+coff+roff)
902 # Write the number of disulfide bridges
903 s+=" "+str(nSSbr)+"\n"
907 # get neibhoring Sulfur atom
908 opis=c.chain+str(c.resi)
909 lista_mostkow.append(opis)
910 nbr=cmd.get_model("(bto. ("+str(self.cb2.getvalue()[0])+" & resi "+str(c.resi)+"& n. SG & chain "+str(c.chain)+")) & n. SG").atom[0]
911 opis2=nbr.chain+str(nbr.resi)
912 if opis2 not in lista_mostkow:
913 # Write witch half-cysteines build the i-th disulfide bridge
914 s+=" "+str(unresidx[c.chain+"/"+str(c.resi)])+" "+str(unresidx[nbr.chain+"/"+str(nbr.resi)])+"\n"
915 #print c.chain, c.resn,c.resi,"-S-S-", nbr.chain, nbr.resn,nbr.resi
923 def write_cshell(self, cshname,prefix):
925 Writes the C-shell script needed to run UNRES calculations
927 s='#!/bin/csh -f\n#\n# C-shell script generated by UNRESInpGen.py v'+UNRESInpGen_version+' \n#\n'
929 s+='#--------------------------------------------------------------------\n'
930 s+='# Uncomment and set these variables to run MPI versions of UNRES\n'
931 s+='#setenv UNRES_ROOT /path/to/root/directory/of/unrespack\n'
932 s+='#setenv UNRES_BIN /path/to/unres_binary.exe\n'
933 s+='#--------------------------------------------------------------------\n'
935 # number of processors per energy
936 if self.OM1Val.get()=="MD":
937 s+='setenv FGPROCS 1\n'
940 if self.OM2Val.get()=="CASP3":
946 s+='setenv PREFIX '+prefix+'\n'
949 s+='setenv OUT1FILE YES\n'
951 # force filed parameters
952 s+='#---------------------------------------------------------------------\n'
953 s+='setenv DD $UNRES_ROOT/PARAM\n'
955 if self.OM2Val.get()=="CASP3":
956 s+='setenv BONDPAR $DD/bond.parm\nsetenv THETPAR $DD/thetaml.5parm\nsetenv ROTPAR $DD/scgauss.parm\n'
957 s+='setenv TORPAR $DD/torsion_cryst.parm\nsetenv TORDPAR $DD/torsion_double_631Gdp.parm\nsetenv SIDEPAR $DD/scinter_LJ.parm\n'
958 s+='setenv ELEPAR $DD/electr.parm\nsetenv SCPPAR $DD/scp.parm\nsetenv FOURIER $DD/fourier_GAP.parm\n'
959 s+='setenv SCCORPAR $DD/rotcorr_AM1.parm\n'
960 elif self.OM2Val.get()=="ALPHA" or self.OM2Val.get()=="BETA" or self.OM2Val.get()=="ALPHABETA":
961 s+='setenv BONDPAR $DD/bond.parm\nsetenv THETPAR $DD/thetaml.5parm\nsetenv ROTPAR $DD/scgauss.parm\n'
962 s+='setenv TORPAR $DD/torsion_ecepp.parm\nsetenv TORDPAR $DD/torsion_double_631Gdp.parm\nsetenv SIDEPAR $DD/scinter_GB.parm\n'
963 s+='setenv ELEPAR $DD/electr.parm\nsetenv SCPPAR $DD/scp.parm\nsetenv FOURIER $DD/fourier_GAP.parm\nsetenv SCCORPAR $DD/rotcorr_AM1.parm\n'
964 elif self.OM2Val.get()=="CASP5":
965 s+='setenv BONDPAR $DD/bond.parm\nsetenv THETPAR $DD/thetaml.5parm\nsetenv ROTPAR $DD/scgauss.parm\n'
966 s+='setenv TORPAR $DD/torsion_631Gdp.parm\nsetenv TORDPAR $DD/torsion_double_631Gdp.parm\nsetenv SIDEPAR $DD/scinter_GB.parm\n'
967 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'
968 elif self.OM2Val.get()=="3P":
969 s+='setenv BONDPAR $DD/bond.parm\nsetenv THETPAR $DD/thetaml.5parm\nsetenv ROTPAR $DD/scgauss.parm\n'
970 s+='setenv TORPAR $DD/torsion_631Gdp.parm\nsetenv TORDPAR $DD/torsion_double_631Gdp.parm\nsetenv SIDEPAR $DD/sc_GB_opt.3P7_iter81_1r\n'
971 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'
972 elif self.OM2Val.get()=="4P":
973 s+='setenv BONDPAR $DD/bond.parm\nsetenv THETPAR $DD/thetaml.5parm\nsetenv ROTPAR $DD/scgauss.parm\n'
974 s+='setenv TORPAR $DD/torsion_631Gdp.parm\nsetenv TORDPAR $DD/torsion_double_631Gdp.parm\nsetenv SIDEPAR $DD/sc_GB_opt.4P5_iter33_3r\n'
975 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'
976 elif self.OM2Val.get()=="GAB":
977 s+='setenv BONDPAR $DD/bond.parm\nsetenv THETPAR $DD/thetaml.5parm\nsetenv ROTPAR $DD/scgauss.parm\n'
978 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'
979 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/sccor_pdb_shelly.dat\n'
980 elif self.OM2Val.get()=="E0G":
981 s+='setenv BONDPAR $DD/bond.parm\nsetenv THETPAR $DD/thetaml.5parm\nsetenv ROTPAR $DD/scgauss.parm\n'
982 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'
983 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'
984 elif self.OM2Val.get()=="1L2Y_1LE1":
985 s+='setenv BONDPAR $DD/bond_AM1.parm\nsetenv THETPAR $DD/thetaml.5parm\nsetenv ROTPAR $DD/rotamers_AM1_aura.10022007.parm\n'
986 s+='setenv TORPAR $DD/torsion_631Gdp.parm\nsetenv TORDPAR $DD/torsion_double_631Gdp.parm\nsetenv SIDEPAR $DD/scinter_$POT.parm\n'
987 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/sccor_pdb_shelly.dat\n'
988 elif self.OM2Val.get()=="Custom":
989 s+='setenv BONDPAR $DD/.parm\nsetenv THETPAR $DD/.parm\nsetenv ROTPAR $DD/.parm\n'
990 s+='setenv TORPAR $DD/.parm\nsetenv TORDPAR $DD/.parm\nsetenv SIDEPAR $DD/.parm\n'
991 s+='setenv ELEPAR $DD/.parm\nsetenv SCPPAR $DD/.parm\nsetenv FOURIER $DD/.parm\nsetenv SCCORPAR $DD/.parm\n'
995 s+='setenv PATTERN $DD/patterns.cart\n'
996 s+='#---------------------------------------------------------------------\n'
999 f = open(cshname, 'w')
1004 def setenv_info(self):
1005 print '''IMPORTANT: Remember to set the following envirament variables for your shell before starting calculations:
1006 UNRES_ROOT - the root directory where UNRES is installed on your system (should contain PARAM directory)
1007 UNRES_BIN - the UNRES binary you want to execute
1013 Writes the actual input
1016 ('Input files','*.inp'),
1019 # Write error handling for empty sequence
1021 s=self.gr3.t1.getvalue()
1022 if len(s.strip())==0:
1023 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\".")
1025 # Display dialog window
1026 fout = tkFileDialog.asksaveasfile(parent=self,mode='w',filetypes=myFormats,title='Save input')
1028 print "Saving input file %s" % fout.name
1030 text2save=self.fortran_format(self.e1.get())
1032 mainopt="SEED="+self.gr1.e1.get()+" "
1033 if self.OM1Val.get()=="MD":
1034 mainopt+="MD PDBREF"
1035 if self.gr1.md.om1.getvalue()=="PDB":
1036 mainopt+=" PDBSTART"
1037 elif self.gr1.md.om1.getvalue()=="extended":
1040 mainopt+=" RAND_CONF"
1041 elif self.OM1Val.get()=="REMD/MREMD":
1042 mainopt+="RE PDBREF"
1043 if self.gr1.md.om1.getvalue()=="PDB":
1044 mainopt+=" PDBSTART"
1045 elif self.gr1.md.om1.getvalue()=="extended":
1048 mainopt+=" RAND_CONF"
1050 elif self.OM1Val.get()=="MINIMIZE":
1051 mainopt+="PDBREF PDBSTART MINIMIZE RESCALE_MODE=0"
1054 if self.OVERLAP.get():
1056 if self.NOSEARCHSC.get():
1057 mainopt+=" NOSERARCHSC"
1058 text2save+=self.fortran_format(mainopt)
1061 if self.OM1Val.get()=="MD":
1062 text2save+=self.fortran_format(self.get_md_opt())
1063 elif self.OM1Val.get()=="REMD/MREMD":
1064 text2save+=self.fortran_format(self.get_md_opt())
1065 text2save+=self.fortran_format(self.get_mremd_opt())
1066 text2save+=self.fortran_format(self.get_mremd_temp_opt())
1067 text2save+=self.fortran_format(self.get_mremd_replicas())
1068 elif self.OM1Val.get()=="MINIMIZE":
1069 text2save+=self.fortran_format(self.get_minim_opt())
1071 # Get force fields parameters
1072 text2save+=self.fortran_format(self.get_weights())
1075 pdbreffn=str(self.cb2.getvalue()[0])+"_pdbref.pdb"
1076 text2save+=pdbreffn+"\n"
1077 print "Saving PDB reference structure %s" % (os.path.join(os.path.dirname(fout.name),pdbreffn))
1078 cmd.save(os.path.join(os.path.dirname(fout.name),pdbreffn), self.cb2.getvalue()[0])
1081 cshellfn=os.path.join(os.path.dirname(fout.name),"unres_"+os.path.basename(os.path.splitext(fout.name)[0])+".csh")
1082 print "Writing C-shell script %s" % (cshellfn)
1083 prefix=os.path.basename(os.path.splitext(fout.name)[0])
1084 self.write_cshell(cshellfn,prefix)
1087 text2save+=self.get_seq_data()
1089 fout.write(text2save)
1092 # ENV Varaiables info