FF2 name for E0LL2Y
[django_unres.git] / django_simple / todo / forms.py
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
7 import json
8 import urllib
9
10 def code_2d(line):
11    msg=''
12    set ='HEC-'
13    line2 = ''.join([c for c in line if c in set])
14    if line2 != line:
15     msg='use only H,E,C or - letters'
16    return(msg)
17
18 def pdb_missing_res(file):
19    msg=''
20    newchain = True
21    ires=[]
22    for line in file:
23       if line[0:6] == 'ATOM  ' and line[13:15] == 'CA':
24                i = int(line[22:26])
25                if ires and i==ires[-1]:
26                  continue
27                if newchain or i==ires[-1]+1:
28                  ires.append(i)
29                  newchain = False
30                else:
31                  msg = 'chain breaks between residues '+\
32                    str(ires[-1])+' and '+str(i)+\
33                    ', server cannot add missing residues to PDB file - please repair the structure using e.g. Modeller'
34                  break
35       if line[0:3] == 'TER':
36                newchain = True
37       if line[0:3] == 'END':
38                break
39    
40    return(msg)
41
42 class MultiWidgetBasic(forms.MultiWidget):
43     def __init__(self, count, attrs=None):
44         self.count=count
45         widgets = []
46         for i in range(self.count):
47            widgets.append(forms.TextInput())
48         super(MultiWidgetBasic, self).__init__(widgets, attrs)
49
50     template_name = 'multi.html'
51
52     def decompress(self, value):
53         if value:
54             return json.loads(value)
55         else:
56             return ['', '']
57
58
59 class MultiExampleField(forms.fields.MultiValueField):
60     def __init__(self, count, *args, **kwargs):
61         self.count=count
62         self.widget = MultiWidgetBasic(self.count)
63         list_fields = []
64         for i in range(self.count):
65            list_fields.append(forms.fields.CharField(max_length=15))
66         super(MultiExampleField, self).__init__(list_fields, *args, **kwargs)
67
68     def compress(self, values):
69         ## compress list to single object                                               
70         return json.dumps(values)
71
72
73 class TaskForm(forms.Form):
74     name = forms.CharField(max_length=20)
75
76
77 class TaskForm_min(forms.Form):
78      name = forms.CharField(max_length=20)
79      file1 = forms.FileField(label='Upload a PDB file',required=False,
80       help_text='continuous (without breaks) protein chains,use TER to divide chains')
81      pdbid = forms.CharField(min_length=4,max_length=4,required=False,
82       widget=forms.TextInput(attrs={'size':4, 'maxlength':4, 'title':'PDB code'}),
83       label='or PDB code')                   
84
85      def clean(self):
86              cleaned_data = super(TaskForm_min, self).clean()
87
88              pdbid = cleaned_data.get("pdbid") 
89              file1 = cleaned_data.get("file1")
90               
91              if not pdbid and not file1:
92                 msg = 'provide pdb file or pdb code'
93                 self.add_error('file1', msg)
94               
95              if pdbid:
96                test=urllib.urlopen('http://files.rcsb.org/download/'+pdbid+'.pdb')     
97                if test.code != 200:
98                  msg = 'wrong pdb code'
99                  self.add_error('pdbid', msg)
100                else:
101                  msg=pdb_missing_res(test)
102                  if msg != '':
103                    self.add_error('pdbid',msg)
104                test.close()
105                
106              if file1:
107                  msg=pdb_missing_res(file1)
108                  if msg != '':
109                    self.add_error('file1',msg)
110
111             
112 class TaskForm_min_a(forms.Form):
113      name = forms.CharField(max_length=20)
114
115      unres_ff = forms.ChoiceField(choices=FF_CHOICE,widget=forms.RadioSelect,
116                            label='Force Field',initial='FF2')
117 #     min_choice = forms.ChoiceField(choices=MIN_CHOICE,label='minimization algorithm')
118      min_overlap = forms.BooleanField(required=False,label='remove overlap')
119      min_searchsc = forms.BooleanField(required=False,label='MC for sidechain overlap')
120      min_maxmin = forms.IntegerField(label='MAXMIN',initial=10000,
121                   help_text='maximum number of iterations')
122      min_maxfun = forms.IntegerField(label='MAXFUN',initial=15000,
123                   help_text='maximum number of function evaluations')
124      file1 = forms.FileField(label='Upload a PDB file',required=False,
125         help_text='continuous (without breaks) protein chains,use TER to divide chains')
126      pdbid = forms.CharField(min_length=4,max_length=4,required=False,
127       widget=forms.TextInput(attrs={'size':4, 'maxlength':4, 'title':'PDB code'}),
128       label='or PDB code')                   
129
130      min_unres_pdb = forms.BooleanField(required=False,label='uploaded input unres PDB',
131                   help_text='(CA and CB atoms only, CB represents SC in UNRES)')
132      min_pdbout = forms.BooleanField(required=False,label='output PDB',initial='true')
133      boxx = forms.FloatField(label='Box X',initial=1000.0,
134                        help_text='box x dimension')
135      boxy = forms.FloatField(label='Box Y',initial=1000.0,
136                        help_text='box y dimension')
137      boxz = forms.FloatField(label='Box Z',initial=1000.0,
138                        help_text='box z dimension')
139
140      def clean(self):
141              cleaned_data = super(TaskForm_min_a, self).clean()
142
143              pdbid = cleaned_data.get("pdbid") 
144              file1 = cleaned_data.get("file1")
145               
146              if not pdbid and not file1:
147                 msg = 'provide pdb file or pdb code'
148                 self.add_error('file1', msg)
149               
150              if pdbid:
151                test=urllib.urlopen('http://files.rcsb.org/download/'+pdbid+'.pdb')     
152                if test.code != 200:
153                  msg = 'wrong pdb code'
154                  self.add_error('pdbid', msg)
155                else:
156                  msg=pdb_missing_res(test)
157                  if msg != '':
158                    self.add_error('pdbid',msg)
159                test.close()
160                
161              if file1:
162                  msg=pdb_missing_res(file1)
163                  if msg != '':
164                    self.add_error('file1',msg)
165
166
167 class TaskForm_md(forms.Form):
168      name = forms.CharField(max_length=20)
169
170      md_start = forms.ChoiceField(choices=MD_START,widget=forms.RadioSelect,
171                       label='starting structure',initial='extconf')
172      md_seq = forms.CharField(label='Sequence',
173                      help_text='aminoacid sequence using one letter code<br>'+
174                      'field is ignored when uploading starting/reference PDB file',
175                      required=False,
176                      widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
177      file1 = forms.FileField(label='Upload a PDB file',required=False,
178                   help_text='starting structure for pdbstart/reference structure')
179      pdbid = forms.CharField(min_length=4,max_length=4,required=False,
180       widget=forms.TextInput(attrs={'size':4, 'maxlength':4, 'title':'PDB code'}),
181       label='or PDB code')                   
182      md_pdbref = forms.BooleanField(required=False,label='PDB reference structure')
183      md_temp = forms.FloatField(label='temperature',initial=300,
184                   help_text='bath temperature')
185      md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
186                   help_text='total number of steps')
187      md_seed = forms.IntegerField(label='SEED',initial=-39912345,
188                   help_text='seed for random number generator')
189                   
190      def clean(self):
191              cleaned_data = super(TaskForm_md, self).clean()
192
193              md_start = cleaned_data.get("md_start") 
194              file1 = cleaned_data.get("file1")
195              pdbid = cleaned_data.get("pdbid")
196              md_seq = cleaned_data.get("md_seq")
197              md_pdbref = cleaned_data.get("md_pdbref")
198               
199              if md_start == 'pdbstart' and not (file1 or pdbid):
200                 msg = 'pdbstart with no PDB file or code'
201                 self.add_error('file1', msg)
202
203              if md_pdbref and not (file1 or pdbid):
204                 msg = 'pdbref with no PDB file or code'
205                 self.add_error('file1', msg)
206
207
208              if md_start != 'pdbstart' and not md_pdbref and not md_seq:
209                 msg = 'extended/random chain with no sequence'
210                 self.add_error('md_seq', msg)
211
212              if pdbid:
213                test=urllib.urlopen('http://files.rcsb.org/download/'+pdbid+'.pdb')     
214                if test.code != 200:
215                  msg = 'wrong pdb code'
216                  self.add_error('pdbid', msg)
217                else:
218                  msg=pdb_missing_res(test)
219                  if msg != '':
220                    self.add_error('pdbid',msg)
221                test.close()
222                
223              if file1:
224                  msg=pdb_missing_res(file1)
225                  if msg != '':
226                    self.add_error('file1',msg)
227
228                         
229 class TaskForm_md_a(forms.Form):
230      name = forms.CharField(max_length=20)
231
232      unres_ff = forms.ChoiceField(choices=FF_CHOICE,widget=forms.RadioSelect,
233                            label='Force Field',initial='FF2')
234      md_start = forms.ChoiceField(choices=MD_START,widget=forms.RadioSelect,
235                       label='starting structure',initial='extconf')
236      md_seq = forms.CharField(label='Sequence',
237                      help_text='aminoacid sequence using one letter code<br>'+
238                      'field is ignored when uploading starting/reference PDB file',
239                      required=False,
240                      widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
241      md_2d = forms.CharField(label='Secondary structure restraints',
242                      help_text='single letter code: H - helix, E - extended/beta, C or - no restraints',
243                      required=False,
244                      widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
245
246      file1 = forms.FileField(label='Upload a PDB file',required=False,
247                   help_text='starting structure for pdbstart/reference structure')
248      pdbid = forms.CharField(min_length=4,max_length=4,required=False,
249       widget=forms.TextInput(attrs={'size':4, 'maxlength':4, 'title':'PDB code'}),
250       label='or PDB code')                   
251      md_pdbref = forms.BooleanField(required=False,label='PDB reference structure')                  
252      md_temp = forms.FloatField(label='temperature',initial=300,
253                   help_text='bath temperature')
254      md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
255                   help_text='total number of steps')
256      md_seed = forms.IntegerField(label='SEED',initial=-39912345,
257                   help_text='seed for random number generator')
258
259      md_ntwe = forms.IntegerField(label='NTWE',initial=1000,
260                help_text='write statfile every ntwe steps')
261      md_ntwx = forms.IntegerField(label='NTWX',initial=1000,
262                help_text='write trajectory every ntwe steps')
263      md_dt = forms.FloatField(label='DT',initial=0.2,
264                   help_text='time step [mtu=48.9 fs]')
265      md_lang = forms.ChoiceField(choices=MD_LANG,label='thermostat')
266      md_tau = forms.FloatField(label='tau_bath',initial=1.0,
267                   help_text='coupling to the thermal bath (Berendsen)')
268      md_scal_fric = forms.FloatField(label='scal_froc',initial=0.02,
269                   help_text='scaling of the friction coefficients (Langevin)')
270      md_respa = forms.BooleanField(required=False,initial=True,label='RESPA')
271      md_mdpdb = forms.BooleanField(required=False,label='trajectory as PDB')
272
273      boxx = forms.FloatField(label='Box X',initial=1000.0,
274                        help_text='box x dimension')
275      boxy = forms.FloatField(label='Box Y',initial=1000.0,
276                        help_text='box y dimension')
277      boxz = forms.FloatField(label='Box Z',initial=1000.0,
278                        help_text='box z dimension')
279
280      def clean(self):
281              cleaned_data = super(TaskForm_md_a, self).clean()
282
283              md_start = cleaned_data.get("md_start") 
284              file1 = cleaned_data.get("file1")
285              pdbid = cleaned_data.get("pdbid")
286              md_seq = cleaned_data.get("md_seq")
287              md_pdbref = cleaned_data.get("md_pdbref")
288              md_2d = cleaned_data.get("md_2d")
289               
290              if md_start == 'pdbstart' and not (file1 or pdbid):
291                 msg = 'pdbstart with no PDB file or code'
292                 self.add_error('file1', msg)
293
294              if md_pdbref and not (file1 or pdbid):
295                 msg = 'pdbref with no PDB file or code'
296                 self.add_error('file1', msg)
297
298
299              if md_start != 'pdbstart' and not md_pdbref and not md_seq:
300                 msg = 'extended/random chain with no sequence'
301                 self.add_error('md_seq', msg)
302
303              if pdbid:
304                test=urllib.urlopen('http://files.rcsb.org/download/'+pdbid+'.pdb')     
305                if test.code != 200:
306                  msg = 'wrong pdb code'
307                  self.add_error('pdbid', msg)
308                else:
309                  msg=pdb_missing_res(test)
310                  if msg != '':
311                    self.add_error('pdbid',msg)
312                test.close()
313                
314              if file1:
315                  msg=pdb_missing_res(file1)
316                  if msg != '':
317                    self.add_error('file1',msg)
318              
319              if md_2d:
320                  msg=code_2d(md_2d)
321                  if msg != '':
322                    self.add_error('md_2d',msg)
323
324 class TaskForm_remd(forms.Form):
325      name = forms.CharField(max_length=20)
326
327      md_start = forms.ChoiceField(choices=MD_START,widget=forms.RadioSelect,
328                       label='starting structure',initial='extconf')
329      md_seq = forms.CharField(label='Sequence',
330                      help_text='aminoacid sequence using one letter code<br>'+
331                         'field is ignored when uploading starting/reference PDB file',
332                      required=False,
333                      widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
334      file1 = forms.FileField(label='Upload a PDB file',required=False,
335                   help_text='starting structure for pdbstart/reference structure')
336      pdbid = forms.CharField(min_length=4,max_length=4,required=False,
337       widget=forms.TextInput(attrs={'size':4, 'maxlength':4, 'title':'PDB code'}),
338       label='or PDB code')                   
339      md_pdbref = forms.BooleanField(required=False,label='PDB reference structure')                  
340      md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
341                   help_text='total number of steps')
342      md_seed = forms.IntegerField(label='SEED',initial=-39912345,
343                   help_text='seed for random number generator')
344                   
345      def clean(self):
346              cleaned_data = super(TaskForm_remd, self).clean()
347
348              md_start = cleaned_data.get("md_start") 
349              file1 = cleaned_data.get("file1")
350              pdbid = cleaned_data.get("pdbid")
351              md_seq = cleaned_data.get("md_seq")
352              md_pdbref = cleaned_data.get("md_pdbref")
353               
354              if md_start == 'pdbstart' and not (file1 or pdbid):
355                 msg = 'pdbstart with no PDB file or code'
356                 self.add_error('file1', msg)
357
358              if md_pdbref and not (file1 or pdbid):
359                 msg = 'pdbref with no PDB file or code'
360                 self.add_error('file1', msg)
361
362              if md_start != 'pdbstart' and not md_pdbref and not md_seq:
363                 msg = 'extended/random chain with no sequence'
364                 self.add_error('md_seq', msg)
365
366              if pdbid:
367                test=urllib.urlopen('http://files.rcsb.org/download/'+pdbid+'.pdb')     
368                if test.code != 200:
369                  msg = 'wrong pdb code'
370                  self.add_error('pdbid', msg)
371                else:
372                  msg=pdb_missing_res(test)
373                  if msg != '':
374                    self.add_error('pdbid',msg)
375                test.close()
376                
377              if file1:
378                  msg=pdb_missing_res(file1)
379                  if msg != '':
380                    self.add_error('file1',msg)
381
382                              
383 class TaskForm_remd_a(forms.Form):
384      name = forms.CharField(max_length=20)
385
386      unres_ff = forms.ChoiceField(choices=FF_CHOICE,widget=forms.RadioSelect,
387                            label='Force Field',initial='FF2')
388      md_start = forms.ChoiceField(choices=MD_START,widget=forms.RadioSelect,
389                       label='starting structure',initial='extconf')
390      md_seq = forms.CharField(label='Sequence',
391                      help_text='aminoacid sequence using one letter code<br>'+
392                       'field is ignored when uploading starting/reference PDB file',
393                      required=False,
394                      widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
395      md_2d = forms.CharField(label='Secondary structure restraints',
396                      help_text='single letter code: H - helix, E - extended/beta, C or - no restraints',
397                      required=False,
398                      widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
399      file1 = forms.FileField(label='Upload a PDB file',required=False,
400                   help_text='starting structure for pdbstart/reference structure')
401      pdbid = forms.CharField(min_length=4,max_length=4,required=False,
402       widget=forms.TextInput(attrs={'size':4, 'maxlength':4, 'title':'PDB code'}),
403       label='or PDB code')                   
404      md_pdbref = forms.BooleanField(required=False,label='PDB reference structure')                  
405      md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
406                   help_text='total number of steps')
407      md_seed = forms.IntegerField(label='SEED',initial=-39912345,
408                   help_text='seed for random number generator')
409      md_ntwe = forms.IntegerField(label='NTWE',initial=1000,
410                help_text='write statfile every ntwe steps')
411      md_dt = forms.FloatField(label='DT',initial=0.2,
412                   help_text='time step [mtu = 48.9 fs]')
413      md_lang = forms.ChoiceField(choices=MD_LANG,label='thermostat')
414      md_tau = forms.FloatField(label='tau_bath',initial=1.0,
415                   help_text='coupling to the thermal bath (Berendsen)')
416      md_scal_fric = forms.FloatField(label='scal_froc',initial=0.02,
417                   help_text='scaling of the friction coefficients (Langevin)')
418      remd_nrep = forms.IntegerField(label='NREP',initial=8,
419                   help_text='number of replicas')
420      remd_nstex = forms.IntegerField(label='NSTEX',initial=1000,
421                   help_text='exchange and write trajectory every nstex steps')
422      md_ntwx = forms.IntegerField(label='NTWX',initial=1000,
423                help_text='write trajectory every ntwx steps')
424      remd_cluter_temp = forms.FloatField(label='TEMPER',
425                   help_text='temperature for cluster analysis',initial=280)                  
426 #     remd_traj1file = forms.BooleanField(required=False,label='single trajectory file',initial='true')
427 #     remd_rest1file = forms.BooleanField(required=False,label='single restart file',initial='true')
428
429      md_respa = forms.BooleanField(required=False,initial=True,label='RESPA')
430
431      boxx = forms.FloatField(label='Box X',initial=1000.0,
432                        help_text='box x dimension')
433      boxy = forms.FloatField(label='Box Y',initial=1000.0,
434                        help_text='box y dimension')
435      boxz = forms.FloatField(label='Box Z',initial=1000.0,
436                        help_text='box z dimension')
437
438
439      wsaxs = forms.FloatField(label='SAXS weight',initial=100.0,
440                             help_text='weight for SAXS restraint term')
441      scal_rad = forms.FloatField(label='Scal_rad (SAXS)',initial=1.0,
442                             help_text='downscaling factor of residue radii used in SAXS restraints')
443      saxs_data = forms.CharField(label='P(r) SAXS data',
444                      help_text='distance distribution from SAXS, two columns: r and P(r)',
445                      required=False,
446                      widget=forms.Textarea(attrs={'cols': 25, 'rows': 20}))
447
448
449      def clean(self):
450              cleaned_data = super(TaskForm_remd_a, self).clean()
451
452              md_start = cleaned_data.get("md_start") 
453              file1 = cleaned_data.get("file1")
454              pdbid = cleaned_data.get("pdbid")
455              md_seq = cleaned_data.get("md_seq")
456              md_pdbref = cleaned_data.get("md_pdbref")
457              md_2d = cleaned_data.get("md_2d")
458               
459              if md_start == 'pdbstart' and not (file1 or pdbid):
460                 msg = 'pdbstart with no PDB file or code'
461                 self.add_error('file1', msg)
462
463              if md_pdbref and not (file1 or pdbid):
464                 msg = 'pdbref with no PDB file or code'
465                 self.add_error('file1', msg)
466
467
468              if md_start != 'pdbstart' and not md_pdbref and not md_seq:
469                 msg = 'extended/random chain with no sequence'
470                 self.add_error('md_seq', msg)
471
472              if pdbid:
473                test=urllib.urlopen('http://files.rcsb.org/download/'+pdbid+'.pdb')     
474                if test.code != 200:
475                  msg = 'wrong pdb code'
476                  self.add_error('pdbid', msg)
477                else:
478                  msg=pdb_missing_res(test)
479                  if msg != '':
480                    self.add_error('pdbid',msg)
481                test.close()
482                
483              if file1:
484                  msg=pdb_missing_res(file1)
485                  if msg != '':
486                    self.add_error('file1',msg)
487
488              if md_2d:
489                  msg=code_2d(md_2d)
490                  if msg != '':
491                    self.add_error('md_2d',msg)
492
493
494
495 class TaskForm_list(forms.Form):
496     name = forms.CharField(max_length=20,disabled=True,required=False)
497     nrep = forms.IntegerField(disabled=True,required=False,label='NREP')
498
499     def __init__(self, count, *args, **kwargs):
500         super(TaskForm_list, self).__init__(*args, **kwargs)
501         self.count=count
502         self.fields['temperatures'] = MultiExampleField(self.count)
503         self.fields['multiplexing'] = MultiExampleField(self.count)        
504      
505
506