1 from django import forms
2 from .models import Task
3 from .models import MIN_CHOICE
4 from .models import MD_START
5 from .models import MD_LANG
6 from .models import FF_CHOICE
11 'DPR','DLY','DAR','DHI','DAS','DGL','DSG','DGN','DSN','DTH',
12 'DAL','DTY','DTR','DVA','DLE','DIL','DPN','MED','DCY',
13 'CYS','MET','PHE','ILE','LEU','VAL','TRP','TYR','ALA','GLY','THR',
14 'SER','GLN','ASN','GLU','ASP','HIS','ARG','LYS','PRO',
15 'SME','AIB','ABU','DBZ']
18 def pdb_code_chain(pdbid):
24 return('use : between pdb code and chain id, like 5G3Q:B to select single chain')
28 test=urllib.urlopen('http://files.rcsb.org/download/'+pdbid+'.pdb')
30 msg = 'wrong pdb code'
32 msg=pdb_missing_res_chain(test,chain)
36 def pdb_missing_res_chain(file,chain):
41 if line[0:6] == 'ATOM ' and line[13:15] == 'CA' and (line[21] == chain or chain==''):
44 if line[17:20] not in aa_3letter:
45 msg='residue '+line[17:20]+' '+str(i)+' not recognized'
47 if ires and i==ires[-1]:
49 if newchain or i==ires[-1]+1:
53 msg = 'chain breaks between residues '+\
54 str(ires[-1])+' and '+str(i)+' of chain '+ch+\
55 ', server cannot add missing residues to PDB file - please repair the structure using e.g. Modeller'
57 if line[0:3] == 'TER':
59 if line[0:3] == 'END':
64 msg='no CA atoms in this pdb'
73 line2 = ''.join([c for c in line if c in set])
75 msg='use only H,E,C or - letters'
79 class MultiWidgetBasic(forms.MultiWidget):
80 def __init__(self, count, attrs=None):
83 for i in range(self.count):
84 widgets.append(forms.TextInput())
85 super(MultiWidgetBasic, self).__init__(widgets, attrs)
87 template_name = 'multi.html'
89 def decompress(self, value):
91 return json.loads(value)
96 class MultiExampleField(forms.fields.MultiValueField):
97 def __init__(self, count, *args, **kwargs):
99 self.widget = MultiWidgetBasic(self.count)
101 for i in range(self.count):
102 list_fields.append(forms.fields.CharField(max_length=15))
103 super(MultiExampleField, self).__init__(list_fields, *args, **kwargs)
105 def compress(self, values):
106 ## compress list to single object
107 return json.dumps(values)
110 class TaskForm(forms.Form):
111 name = forms.CharField(max_length=20)
114 class TaskForm_min(forms.Form):
115 name = forms.CharField(max_length=20)
116 file1 = forms.FileField(label='Upload a PDB file',required=False,
117 help_text='continuous (without breaks) protein chains,use TER to divide chains')
118 pdbid = forms.CharField(min_length=4,max_length=6,required=False,
119 widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
120 label='or PDB code (:chain)')
123 cleaned_data = super(TaskForm_min, self).clean()
125 pdbid = cleaned_data.get("pdbid")
126 file1 = cleaned_data.get("file1")
128 if not pdbid and not file1:
129 msg = 'provide pdb file or pdb code'
130 self.add_error('file1', msg)
133 msg=pdb_code_chain(pdbid)
135 self.add_error('pdbid',msg)
138 msg=pdb_missing_res_chain(file1,'')
140 self.add_error('file1',msg)
143 class TaskForm_min_a(forms.Form):
144 name = forms.CharField(max_length=20)
146 unres_ff = forms.ChoiceField(choices=FF_CHOICE,widget=forms.RadioSelect,
147 label='Force Field',initial='FF2')
148 # min_choice = forms.ChoiceField(choices=MIN_CHOICE,label='minimization algorithm')
149 min_overlap = forms.BooleanField(required=False,label='remove overlap')
150 min_searchsc = forms.BooleanField(required=False,label='MC for sidechain overlap')
151 min_maxmin = forms.IntegerField(label='MAXMIN',initial=10000,
152 help_text='maximum number of iterations')
153 min_maxfun = forms.IntegerField(label='MAXFUN',initial=15000,
154 help_text='maximum number of function evaluations')
155 file1 = forms.FileField(label='Upload a PDB file',required=False,
156 help_text='continuous (without breaks) protein chains,use TER to divide chains')
157 pdbid = forms.CharField(min_length=4,max_length=6,required=False,
158 widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
159 label='or PDB code (:chain)')
161 min_unres_pdb = forms.BooleanField(required=False,label='uploaded input unres PDB',
162 help_text='(CA and CB atoms only, CB represents SC in UNRES)')
163 min_pdbout = forms.BooleanField(required=False,label='output PDB',initial='true')
164 boxx = forms.FloatField(label='Box X',initial=1000.0,
165 help_text='box x dimension')
166 boxy = forms.FloatField(label='Box Y',initial=1000.0,
167 help_text='box y dimension')
168 boxz = forms.FloatField(label='Box Z',initial=1000.0,
169 help_text='box z dimension')
172 cleaned_data = super(TaskForm_min_a, self).clean()
174 pdbid = cleaned_data.get("pdbid")
175 file1 = cleaned_data.get("file1")
177 if not pdbid and not file1:
178 msg = 'provide pdb file or pdb code'
179 self.add_error('file1', msg)
182 msg=pdb_code_chain(pdbid)
184 self.add_error('pdbid',msg)
187 msg=pdb_missing_res_chain(file1,'')
189 self.add_error('file1',msg)
192 class TaskForm_md(forms.Form):
193 name = forms.CharField(max_length=20)
195 md_start = forms.ChoiceField(choices=MD_START,widget=forms.RadioSelect,
196 label='starting structure',initial='extconf')
197 md_seq = forms.CharField(label='Sequence',
198 help_text='aminoacid sequence using one letter code<br>'+
199 'field is ignored when uploading starting/reference PDB file',
201 widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
202 file1 = forms.FileField(label='Upload a PDB file',required=False,
203 help_text='starting structure for pdbstart/reference structure')
204 pdbid = forms.CharField(min_length=4,max_length=6,required=False,
205 widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
206 label='or PDB code (:chain)')
207 md_pdbref = forms.BooleanField(required=False,label='PDB reference structure')
208 md_temp = forms.FloatField(label='temperature',initial=300,
209 help_text='bath temperature')
210 md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
211 help_text='total number of steps')
212 md_seed = forms.IntegerField(label='SEED',initial=-39912345,
213 help_text='seed for random number generator')
216 cleaned_data = super(TaskForm_md, self).clean()
218 md_start = cleaned_data.get("md_start")
219 file1 = cleaned_data.get("file1")
220 pdbid = cleaned_data.get("pdbid")
221 md_seq = cleaned_data.get("md_seq")
222 md_pdbref = cleaned_data.get("md_pdbref")
224 if md_start == 'pdbstart' and not (file1 or pdbid):
225 msg = 'pdbstart with no PDB file or code'
226 self.add_error('file1', msg)
228 if md_pdbref and not (file1 or pdbid):
229 msg = 'pdbref with no PDB file or code'
230 self.add_error('file1', msg)
233 if md_start != 'pdbstart' and not md_pdbref and not md_seq:
234 msg = 'extended/random chain with no sequence'
235 self.add_error('md_seq', msg)
238 msg=pdb_code_chain(pdbid)
240 self.add_error('pdbid',msg)
243 msg=pdb_missing_res_chain(file1,'')
245 self.add_error('file1',msg)
248 class TaskForm_md_a(forms.Form):
249 name = forms.CharField(max_length=20)
251 unres_ff = forms.ChoiceField(choices=FF_CHOICE,widget=forms.RadioSelect,
252 label='Force Field',initial='FF2')
253 md_start = forms.ChoiceField(choices=MD_START,widget=forms.RadioSelect,
254 label='starting structure',initial='extconf')
255 md_seq = forms.CharField(label='Sequence',
256 help_text='aminoacid sequence using one letter code<br>'+
257 'field is ignored when uploading starting/reference PDB file',
259 widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
260 md_2d = forms.CharField(label='Secondary structure restraints',
261 help_text='single letter code: H - helix, E - extended/beta, C or - no restraints',
263 widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
265 file1 = forms.FileField(label='Upload a PDB file',required=False,
266 help_text='starting structure for pdbstart/reference structure')
267 pdbid = forms.CharField(min_length=4,max_length=6,required=False,
268 widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
269 label='or PDB code (:chain)')
270 md_pdbref = forms.BooleanField(required=False,label='PDB reference structure')
271 md_temp = forms.FloatField(label='temperature',initial=300,
272 help_text='bath temperature')
273 md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
274 help_text='total number of steps')
275 md_seed = forms.IntegerField(label='SEED',initial=-39912345,
276 help_text='seed for random number generator')
278 md_ntwe = forms.IntegerField(label='NTWE',initial=1000,
279 help_text='write statfile every ntwe steps')
280 md_ntwx = forms.IntegerField(label='NTWX',initial=1000,
281 help_text='write trajectory every ntwe steps')
282 md_dt = forms.FloatField(label='DT',initial=0.2,
283 help_text='time step [mtu=48.9 fs]')
284 md_lang = forms.ChoiceField(choices=MD_LANG,label='thermostat')
285 md_tau = forms.FloatField(label='tau_bath',initial=1.0,
286 help_text='coupling to the thermal bath (Berendsen)')
287 md_scal_fric = forms.FloatField(label='scal_froc',initial=0.02,
288 help_text='scaling of the friction coefficients (Langevin)')
289 md_respa = forms.BooleanField(required=False,initial=True,label='RESPA')
290 md_mdpdb = forms.BooleanField(required=False,label='trajectory as PDB')
292 boxx = forms.FloatField(label='Box X',initial=1000.0,
293 help_text='box x dimension')
294 boxy = forms.FloatField(label='Box Y',initial=1000.0,
295 help_text='box y dimension')
296 boxz = forms.FloatField(label='Box Z',initial=1000.0,
297 help_text='box z dimension')
300 cleaned_data = super(TaskForm_md_a, self).clean()
302 md_start = cleaned_data.get("md_start")
303 file1 = cleaned_data.get("file1")
304 pdbid = cleaned_data.get("pdbid")
305 md_seq = cleaned_data.get("md_seq")
306 md_pdbref = cleaned_data.get("md_pdbref")
307 md_2d = cleaned_data.get("md_2d")
309 if md_start == 'pdbstart' and not (file1 or pdbid):
310 msg = 'pdbstart with no PDB file or code'
311 self.add_error('file1', msg)
313 if md_pdbref and not (file1 or pdbid):
314 msg = 'pdbref with no PDB file or code'
315 self.add_error('file1', msg)
318 if md_start != 'pdbstart' and not md_pdbref and not md_seq:
319 msg = 'extended/random chain with no sequence'
320 self.add_error('md_seq', msg)
323 msg=pdb_code_chain(pdbid)
325 self.add_error('pdbid',msg)
328 msg=pdb_missing_res_chain(file1,'')
330 self.add_error('file1',msg)
335 self.add_error('md_2d',msg)
337 class TaskForm_remd(forms.Form):
338 name = forms.CharField(max_length=20)
340 md_start = forms.ChoiceField(choices=MD_START,widget=forms.RadioSelect,
341 label='starting structure',initial='extconf')
342 md_seq = forms.CharField(label='Sequence',
343 help_text='aminoacid sequence using one letter code<br>'+
344 'field is ignored when uploading starting/reference PDB file',
346 widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
347 file1 = forms.FileField(label='Upload a PDB file',required=False,
348 help_text='starting structure for pdbstart/reference structure')
349 pdbid = forms.CharField(min_length=4,max_length=6,required=False,
350 widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
351 label='or PDB code (:chain)')
352 md_pdbref = forms.BooleanField(required=False,label='PDB reference structure')
353 md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
354 help_text='total number of steps')
355 md_seed = forms.IntegerField(label='SEED',initial=-39912345,
356 help_text='seed for random number generator')
359 cleaned_data = super(TaskForm_remd, self).clean()
361 md_start = cleaned_data.get("md_start")
362 file1 = cleaned_data.get("file1")
363 pdbid = cleaned_data.get("pdbid")
364 md_seq = cleaned_data.get("md_seq")
365 md_pdbref = cleaned_data.get("md_pdbref")
367 if md_start == 'pdbstart' and not (file1 or pdbid):
368 msg = 'pdbstart with no PDB file or code'
369 self.add_error('file1', msg)
371 if md_pdbref and not (file1 or pdbid):
372 msg = 'pdbref with no PDB file or code'
373 self.add_error('file1', msg)
375 if md_start != 'pdbstart' and not md_pdbref and not md_seq:
376 msg = 'extended/random chain with no sequence'
377 self.add_error('md_seq', msg)
380 msg=pdb_code_chain(pdbid)
382 self.add_error('pdbid',msg)
385 msg=pdb_missing_res_chain(file1,'')
387 self.add_error('file1',msg)
390 class TaskForm_remd_a(forms.Form):
391 name = forms.CharField(max_length=20)
393 unres_ff = forms.ChoiceField(choices=FF_CHOICE,widget=forms.RadioSelect,
394 label='Force Field',initial='FF2')
395 md_start = forms.ChoiceField(choices=MD_START,widget=forms.RadioSelect,
396 label='starting structure',initial='extconf')
397 md_seq = forms.CharField(label='Sequence',
398 help_text='aminoacid sequence using one letter code<br>'+
399 'field is ignored when uploading starting/reference PDB file',
401 widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
402 md_2d = forms.CharField(label='Secondary structure restraints',
403 help_text='single letter code: H - helix, E - extended/beta, C or - no restraints',
405 widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
406 file1 = forms.FileField(label='Upload a PDB file',required=False,
407 help_text='starting structure for pdbstart/reference structure')
408 pdbid = forms.CharField(min_length=4,max_length=6,required=False,
409 widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
410 label='or PDB code (:chain)')
411 md_pdbref = forms.BooleanField(required=False,label='PDB reference structure')
412 md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
413 help_text='total number of steps')
414 md_seed = forms.IntegerField(label='SEED',initial=-39912345,
415 help_text='seed for random number generator')
416 md_ntwe = forms.IntegerField(label='NTWE',initial=1000,
417 help_text='write statfile every ntwe steps')
418 md_dt = forms.FloatField(label='DT',initial=0.2,
419 help_text='time step [mtu = 48.9 fs]')
420 md_lang = forms.ChoiceField(choices=MD_LANG,label='thermostat')
421 md_tau = forms.FloatField(label='tau_bath',initial=1.0,
422 help_text='coupling to the thermal bath (Berendsen)')
423 md_scal_fric = forms.FloatField(label='scal_froc',initial=0.02,
424 help_text='scaling of the friction coefficients (Langevin)')
425 min_maxfun = forms.IntegerField(label='MAXFUN',initial=5000,
426 help_text='preminim maximum number of function evaluations<br>'+
427 'used for start from pdb or random start')
428 remd_nrep = forms.IntegerField(label='NREP',initial=8,
429 help_text='number of replicas')
430 remd_nstex = forms.IntegerField(label='NSTEX',initial=1000,
431 help_text='exchange and write trajectory every nstex steps')
432 md_ntwx = forms.IntegerField(label='NTWX',initial=1000,
433 help_text='write trajectory every ntwx steps')
434 remd_cluter_temp = forms.FloatField(label='TEMPER',
435 help_text='temperature for cluster analysis',initial=280)
436 # remd_traj1file = forms.BooleanField(required=False,label='single trajectory file',initial='true')
437 # remd_rest1file = forms.BooleanField(required=False,label='single restart file',initial='true')
439 md_respa = forms.BooleanField(required=False,initial=True,label='RESPA')
441 boxx = forms.FloatField(label='Box X',initial=1000.0,
442 help_text='box x dimension')
443 boxy = forms.FloatField(label='Box Y',initial=1000.0,
444 help_text='box y dimension')
445 boxz = forms.FloatField(label='Box Z',initial=1000.0,
446 help_text='box z dimension')
449 wsaxs = forms.FloatField(label='SAXS weight',initial=100.0,
450 help_text='weight for SAXS restraint term')
451 scal_rad = forms.FloatField(label='Scal_rad (SAXS)',initial=1.0,
452 help_text='downscaling factor of residue radii used in SAXS restraints')
453 saxs_data = forms.CharField(label='P(r) SAXS data',
454 help_text='distance distribution from SAXS, two columns: r and P(r)',
456 widget=forms.Textarea(attrs={'cols': 25, 'rows': 20}))
460 cleaned_data = super(TaskForm_remd_a, self).clean()
462 md_start = cleaned_data.get("md_start")
463 file1 = cleaned_data.get("file1")
464 pdbid = cleaned_data.get("pdbid")
465 md_seq = cleaned_data.get("md_seq")
466 md_pdbref = cleaned_data.get("md_pdbref")
467 md_2d = cleaned_data.get("md_2d")
469 if md_start == 'pdbstart' and not (file1 or pdbid):
470 msg = 'pdbstart with no PDB file or code'
471 self.add_error('file1', msg)
473 if md_pdbref and not (file1 or pdbid):
474 msg = 'pdbref with no PDB file or code'
475 self.add_error('file1', msg)
478 if md_start != 'pdbstart' and not md_pdbref and not md_seq:
479 msg = 'extended/random chain with no sequence'
480 self.add_error('md_seq', msg)
483 msg=pdb_code_chain(pdbid)
485 self.add_error('pdbid',msg)
488 msg=pdb_missing_res_chain(file1,'')
490 self.add_error('file1',msg)
495 self.add_error('md_2d',msg)
499 class TaskForm_list(forms.Form):
500 name = forms.CharField(max_length=20,disabled=True,required=False)
501 nrep = forms.IntegerField(disabled=True,required=False,label='NREP')
503 def __init__(self, count, *args, **kwargs):
504 super(TaskForm_list, self).__init__(*args, **kwargs)
506 self.fields['temperatures'] = MultiExampleField(self.count)
507 self.fields['multiplexing'] = MultiExampleField(self.count)