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