3000f8035929bc4407b2b89775ed61ed54913f71
[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 aa_3letter = [
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']
16
17
18 def pdb_code_chain(pdbid):
19
20     msg=''
21     chain=''
22     if len(pdbid)>4:
23        if pdbid[4]!=':':
24          return('use : between pdb code and chain id, like 5G3Q:B to select single chain')
25        chain=pdbid[5]
26        pdbid=pdbid[:4]    
27     
28     test=urllib.urlopen('http://files.rcsb.org/download/'+pdbid+'.pdb')     
29     if test.code != 200:
30           msg = 'wrong pdb code'
31     else:
32           msg=pdb_missing_res_chain(test,chain)
33     test.close()
34     return(msg)
35
36 def pdb_missing_res_chain(file,chain):
37    msg=''
38    newchain = True
39    ires=[]
40    for line in file:
41       if line[0:6] == 'ATOM  ' and line[13:15] == 'CA' and (line[21] == chain or chain==''):
42                i = int(line[22:26])
43                ch = line[21]
44                if line[17:20] not in aa_3letter:
45                  msg='residue '+line[17:20]+' '+str(i)+' not recognized'
46                  return(msg)
47                if ires and i==ires[-1]:
48                  continue
49                if newchain or i==ires[-1]+1:
50                  ires.append(i)
51                  newchain = False
52                else:
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'
56                  break
57       if line[0:3] == 'TER':
58                newchain = True
59       if line[0:3] == 'END':
60                break
61    
62    if len(ires) == 0:
63         if chain == '':
64                msg='no CA atoms in this pdb'
65         else:
66                msg='wrong chain id'
67    return(msg)
68
69
70 def code_2d(line):
71    msg=''
72    set ='HEC-'
73    line2 = ''.join([c for c in line if c in set])
74    if line2 != line:
75     msg='use only H,E,C or - letters'
76    return(msg)
77
78
79 class MultiWidgetBasic(forms.MultiWidget):
80     def __init__(self, count, attrs=None):
81         self.count=count
82         widgets = []
83         for i in range(self.count):
84            widgets.append(forms.TextInput())
85         super(MultiWidgetBasic, self).__init__(widgets, attrs)
86
87     template_name = 'multi.html'
88
89     def decompress(self, value):
90         if value:
91             return json.loads(value)
92         else:
93             return ['', '']
94
95
96 class MultiExampleField(forms.fields.MultiValueField):
97     def __init__(self, count, *args, **kwargs):
98         self.count=count
99         self.widget = MultiWidgetBasic(self.count)
100         list_fields = []
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)
104
105     def compress(self, values):
106         ## compress list to single object                                               
107         return json.dumps(values)
108
109
110 class TaskForm(forms.Form):
111     name = forms.CharField(max_length=40,widget=forms.TextInput(attrs={'size':40, 'maxlength':40}))
112
113
114 class TaskForm_min(forms.Form):
115      name = forms.CharField(max_length=40,widget=forms.TextInput(attrs={'size':40, 'maxlength':40}))
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)')                   
121
122      def clean(self):
123              cleaned_data = super(TaskForm_min, self).clean()
124
125              pdbid = cleaned_data.get("pdbid") 
126              file1 = cleaned_data.get("file1")
127               
128              if not pdbid and not file1:
129                 msg = 'provide pdb file or pdb code'
130                 self.add_error('file1', msg)
131               
132              if pdbid:
133                msg=pdb_code_chain(pdbid)
134                if msg != '':
135                    self.add_error('pdbid',msg)
136                
137              if file1:
138                  msg=pdb_missing_res_chain(file1,'')
139                  if msg != '':
140                    self.add_error('file1',msg)
141
142             
143 class TaskForm_min_a(forms.Form):
144      name = forms.CharField(max_length=40,widget=forms.TextInput(attrs={'size':40, 'maxlength':40}))
145
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)')                   
160
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')
170
171      def clean(self):
172              cleaned_data = super(TaskForm_min_a, self).clean()
173
174              pdbid = cleaned_data.get("pdbid") 
175              file1 = cleaned_data.get("file1")
176               
177              if not pdbid and not file1:
178                 msg = 'provide pdb file or pdb code'
179                 self.add_error('file1', msg)
180               
181              if pdbid:
182                  msg=pdb_code_chain(pdbid)
183                  if msg != '':
184                    self.add_error('pdbid',msg)
185                
186              if file1:
187                  msg=pdb_missing_res_chain(file1,'')
188                  if msg != '':
189                    self.add_error('file1',msg)
190
191
192 class TaskForm_md(forms.Form):
193      name = forms.CharField(max_length=40,widget=forms.TextInput(attrs={'size':40, 'maxlength':40}))
194
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',
200                      required=False,
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',max_value=10000000)
212      md_seed = forms.IntegerField(label='SEED',initial=-39912345,
213                   help_text='seed for random number generator')
214                   
215      def clean(self):
216              cleaned_data = super(TaskForm_md, self).clean()
217
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")
223               
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)
227
228              if md_pdbref and not (file1 or pdbid):
229                 msg = 'pdbref with no PDB file or code'
230                 self.add_error('file1', msg)
231
232
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)
236
237              if pdbid:
238                  msg=pdb_code_chain(pdbid)
239                  if msg != '':
240                    self.add_error('pdbid',msg)
241                
242              if file1:
243                  msg=pdb_missing_res_chain(file1,'')
244                  if msg != '':
245                    self.add_error('file1',msg)
246
247                         
248 class TaskForm_md_a(forms.Form):
249      name = forms.CharField(max_length=40,widget=forms.TextInput(attrs={'size':40, 'maxlength':40}))
250
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',
258                      required=False,
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',
262                      required=False,
263                      widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
264
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',max_value=10000000)
275      md_seed = forms.IntegerField(label='SEED',initial=-39912345,
276                   help_text='seed for random number generator')
277
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',min_value=100)
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')
291
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')
298
299      def clean(self):
300              cleaned_data = super(TaskForm_md_a, self).clean()
301
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")
308               
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)
312
313              if md_pdbref and not (file1 or pdbid):
314                 msg = 'pdbref with no PDB file or code'
315                 self.add_error('file1', msg)
316
317
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)
321
322              if pdbid:
323                  msg=pdb_code_chain(pdbid)
324                  if msg != '':
325                    self.add_error('pdbid',msg)
326                
327              if file1:
328                  msg=pdb_missing_res_chain(file1,'')
329                  if msg != '':
330                    self.add_error('file1',msg)
331              
332              if md_2d:
333                  msg=code_2d(md_2d)
334                  if msg != '':
335                    self.add_error('md_2d',msg)
336
337 class TaskForm_remd(forms.Form):
338      name = forms.CharField(max_length=40,widget=forms.TextInput(attrs={'size':40, 'maxlength':40}))
339
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',
345                      required=False,
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',max_value=10000000)
355      md_seed = forms.IntegerField(label='SEED',initial=-39912345,
356                   help_text='seed for random number generator')
357                   
358      def clean(self):
359              cleaned_data = super(TaskForm_remd, self).clean()
360
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")
366               
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)
370
371              if md_pdbref and not (file1 or pdbid):
372                 msg = 'pdbref with no PDB file or code'
373                 self.add_error('file1', msg)
374
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)
378
379              if pdbid:
380                  msg=pdb_code_chain(pdbid)
381                  if msg != '':
382                    self.add_error('pdbid',msg)
383                
384              if file1:
385                  msg=pdb_missing_res_chain(file1,'')
386                  if msg != '':
387                    self.add_error('file1',msg)
388
389                              
390 class TaskForm_remd_a(forms.Form):
391      name = forms.CharField(max_length=40,widget=forms.TextInput(attrs={'size':40, 'maxlength':40}))
392
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',
400                      required=False,
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',
404                      required=False,
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',max_value=10000000)
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,min_value=100,
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')
438
439      md_respa = forms.BooleanField(required=False,initial=True,label='RESPA')
440
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')
447
448
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)',
455                      required=False,
456                      widget=forms.Textarea(attrs={'cols': 25, 'rows': 20}))
457
458
459      def clean(self):
460              cleaned_data = super(TaskForm_remd_a, self).clean()
461
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")
468               
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)
472
473              if md_pdbref and not (file1 or pdbid):
474                 msg = 'pdbref with no PDB file or code'
475                 self.add_error('file1', msg)
476
477
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)
481
482              if pdbid:
483                  msg=pdb_code_chain(pdbid)
484                  if msg != '':
485                    self.add_error('pdbid',msg)
486                
487              if file1:
488                  msg=pdb_missing_res_chain(file1,'')
489                  if msg != '':
490                    self.add_error('file1',msg)
491
492              if md_2d:
493                  msg=code_2d(md_2d)
494                  if msg != '':
495                    self.add_error('md_2d',msg)
496
497
498 class TaskForm_dock(forms.Form):
499      name = forms.CharField(max_length=40,widget=forms.TextInput(attrs={'size':40, 'maxlength':40}))
500
501      file1 = forms.FileField(label='Upload a PDB file1',required=False,
502                   help_text='starting structure for chain1')
503      pdbid = forms.CharField(min_length=4,max_length=6,required=False,
504       widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
505       label='or PDB code (:chain)')                   
506
507
508      file2 = forms.FileField(label='Upload a PDB file2',required=False,
509                   help_text='starting structure for chain2')
510      pdbid2 = forms.CharField(min_length=4,max_length=6,required=False,
511       widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
512       label='or PDB code (:chain)')                   
513
514
515      md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
516                   help_text='total number of steps', max_value=10000000)
517      md_seed = forms.IntegerField(label='SEED',initial=-39912345,
518                   help_text='seed for random number generator')
519      dock_peptide = forms.BooleanField(required=False,initial=False,
520             label='dock peptide',help_text='no constrains on 2nd chain')                  
521                   
522      def clean(self):
523              cleaned_data = super(TaskForm_dock, self).clean()
524
525              file1 = cleaned_data.get("file1")
526              pdbid = cleaned_data.get("pdbid")
527              file2 = cleaned_data.get("file2")
528              pdbid2 = cleaned_data.get("pdbid2")
529
530               
531              if not (file1 or pdbid):
532                 msg = 'no PDB file or code for chain1'
533                 self.add_error('file1', msg)
534
535              if not (file2 or pdbid2):
536                 msg = 'no PDB file or code for chain2'
537                 self.add_error('file2', msg)
538
539              if pdbid:
540                  msg=pdb_code_chain(pdbid)
541                  if msg != '':
542                    self.add_error('pdbid',msg)
543                
544              if file1:
545                  msg=pdb_missing_res_chain(file1,'')
546                  if msg != '':
547                    self.add_error('file1',msg)
548
549              if pdbid2:
550                  msg=pdb_code_chain(pdbid2)
551                  if msg != '':
552                    self.add_error('pdbid2',msg)
553                
554              if file2:
555                  msg=pdb_missing_res_chain(file2,'')
556                  if msg != '':
557                    self.add_error('file2',msg)
558
559 class TaskForm_dock_a(forms.Form):
560      name = forms.CharField(max_length=40,widget=forms.TextInput(attrs={'size':40, 'maxlength':40}))
561
562      file1 = forms.FileField(label='Upload a PDB file1',required=False,
563                   help_text='starting structure for chain1')
564      pdbid = forms.CharField(min_length=4,max_length=6,required=False,
565       widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
566       label='or PDB code (:chain)')                   
567
568
569      file2 = forms.FileField(label='Upload a PDB file2',required=False,
570                   help_text='starting structure for chain2')
571      pdbid2 = forms.CharField(min_length=4,max_length=6,required=False,
572       widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
573       label='or PDB code (:chain)')                   
574
575
576      md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
577                   help_text='total number of steps', max_value=10000000)
578      md_seed = forms.IntegerField(label='SEED',initial=-39912345,
579                   help_text='seed for random number generator')
580      dock_peptide = forms.BooleanField(required=False,initial=False,
581             label='dock peptide',help_text='no constrains on 2nd chain')                  
582                   
583
584      unres_ff = forms.ChoiceField(choices=FF_CHOICE,widget=forms.RadioSelect,
585                            label='Force Field',initial='FF2')
586
587      md_ntwe = forms.IntegerField(label='NTWE',initial=1000,
588                help_text='write statfile every ntwe steps')
589      md_dt = forms.FloatField(label='DT',initial=0.2,
590                   help_text='time step [mtu = 48.9 fs]')
591      md_lang = forms.ChoiceField(choices=MD_LANG,label='thermostat')
592      md_tau = forms.FloatField(label='tau_bath',initial=1.0,
593                   help_text='coupling to the thermal bath (Berendsen)')
594      md_scal_fric = forms.FloatField(label='scal_froc',initial=0.02,
595                   help_text='scaling of the friction coefficients (Langevin)')
596      min_maxfun = forms.IntegerField(label='MAXFUN',initial=5000,
597                   help_text='preminim maximum number of function evaluations<br>'+
598                   'used for start from pdb or random start')
599      remd_nrep = forms.IntegerField(label='NREP',initial=8,
600                   help_text='number of replicas')
601      remd_nstex = forms.IntegerField(label='NSTEX',initial=1000,
602                   help_text='exchange and write trajectory every nstex steps')
603      md_ntwx = forms.IntegerField(label='NTWX',initial=1000,min_value=100,
604                help_text='write trajectory every ntwx steps')
605      remd_cluter_temp = forms.FloatField(label='TEMPER',
606                   help_text='temperature for cluster analysis',initial=280)                  
607
608
609      def clean(self):
610              cleaned_data = super(TaskForm_dock_a, self).clean()
611
612              file1 = cleaned_data.get("file1")
613              pdbid = cleaned_data.get("pdbid")
614              file2 = cleaned_data.get("file2")
615              pdbid2 = cleaned_data.get("pdbid2")
616
617               
618              if not (file1 or pdbid):
619                 msg = 'no PDB file or code for chain1'
620                 self.add_error('file1', msg)
621
622              if not (file2 or pdbid2):
623                 msg = 'no PDB file or code for chain2'
624                 self.add_error('file2', msg)
625
626              if pdbid:
627                  msg=pdb_code_chain(pdbid)
628                  if msg != '':
629                    self.add_error('pdbid',msg)
630                
631              if file1:
632                  msg=pdb_missing_res_chain(file1,'')
633                  if msg != '':
634                    self.add_error('file1',msg)
635
636              if pdbid2:
637                  msg=pdb_code_chain(pdbid2)
638                  if msg != '':
639                    self.add_error('pdbid2',msg)
640                
641              if file2:
642                  msg=pdb_missing_res_chain(file2,'')
643                  if msg != '':
644                    self.add_error('file2',msg)
645
646
647 class TaskForm_list(forms.Form):
648     name = forms.CharField(max_length=40,disabled=True,required=False)
649     nrep = forms.IntegerField(disabled=True,required=False,label='NREP')
650
651     def __init__(self, count, *args, **kwargs):
652         super(TaskForm_list, self).__init__(*args, **kwargs)
653         self.count=count
654         self.fields['temperatures'] = MultiExampleField(self.count)
655         self.fields['multiplexing'] = MultiExampleField(self.count)        
656      
657
658