UNRES-Dock peptide sequence no pdb
[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 from django.utils.safestring import mark_safe
8 import json
9 import urllib
10
11 aa_3letter = [
12      'DPR','DLY','DAR','DHI','DAS','DGL','DSG','DGN','DSN','DTH',
13      'DAL','DTY','DTR','DVA','DLE','DIL','DPN','MED','DCY',
14      'CYS','MET','PHE','ILE','LEU','VAL','TRP','TYR','ALA','GLY','THR',
15      'SER','GLN','ASN','GLU','ASP','HIS','ARG','LYS','PRO',
16      'SME','AIB','ABU','DBZ']
17
18
19 def pdb_code_chain(pdbid):
20
21     msg=''
22     chain=''
23     if len(pdbid)>4:
24        if pdbid[4]!=':':
25          return('use : between pdb code and chain id, like 5G3Q:B to select single chain')
26        chain=pdbid[5]
27        pdbid=pdbid[:4]    
28     
29     test=urllib.urlopen('http://files.rcsb.org/download/'+pdbid+'.pdb')     
30     if test.code != 200:
31           msg = 'wrong pdb code'
32     else:
33           msg=pdb_missing_res_chain(test,chain)
34     test.close()
35     return(msg)
36
37 def pdb_missing_res_chain(file,chain):
38    msg=''
39    newchain = True
40    ires=[]
41    for line in file:
42       if line[0:6] == 'ATOM  ' and line[13:15] == 'CA' and (line[21] == chain or chain==''):
43                i = int(line[22:26])
44                ch = line[21]
45                if line[17:20] not in aa_3letter:
46                  msg='residue '+line[17:20]+' '+str(i)+' not recognized'
47                  return(msg)
48                if ires and i==ires[-1]:
49                  continue
50                if newchain or i==ires[-1]+1:
51                  ires.append(i)
52                  newchain = False
53                else:
54                  msg = 'chain breaks between residues '+\
55                    str(ires[-1])+' and '+str(i)+' of chain '+ch+\
56                    ', server cannot add missing residues to PDB file - please repair the structure using e.g. Modeller'
57                  break
58       if line[0:3] == 'TER':
59                newchain = True
60       if line[0:3] == 'END':
61                break
62    
63    if len(ires) == 0:
64         if chain == '':
65                msg='no CA atoms in this pdb'
66         else:
67                msg='wrong chain id'
68    return(msg)
69
70
71 def code_2d(line):
72    msg=''
73    set ='HEC-'
74    line2 = ''.join([c for c in line if c in set])
75    if line2 != line:
76     msg='use only H,E,C or - letters'
77    return(msg)
78
79
80 class MultiWidgetBasic(forms.MultiWidget):
81     def __init__(self, count, attrs=None):
82         self.count=count
83         widgets = []
84         for i in range(self.count):
85            widgets.append(forms.TextInput())
86         super(MultiWidgetBasic, self).__init__(widgets, attrs)
87
88     template_name = 'multi.html'
89
90     def decompress(self, value):
91         if value:
92             return json.loads(value)
93         else:
94             return ['', '']
95
96
97 class MultiExampleField(forms.fields.MultiValueField):
98     def __init__(self, count, *args, **kwargs):
99         self.count=count
100         self.widget = MultiWidgetBasic(self.count)
101         list_fields = []
102         for i in range(self.count):
103            list_fields.append(forms.fields.CharField(max_length=15))
104         super(MultiExampleField, self).__init__(list_fields, *args, **kwargs)
105
106     def compress(self, values):
107         ## compress list to single object                                               
108         return json.dumps(values)
109
110
111 class TaskForm(forms.Form):
112     name = forms.CharField(max_length=40,widget=forms.TextInput(attrs={'size':40, 'maxlength':40}))
113
114
115 class TaskForm_min(forms.Form):
116      name = forms.CharField(max_length=40,widget=forms.TextInput(attrs={'size':40, 'maxlength':40}))
117      file1 = forms.FileField(label='Upload a PDB file',required=False,
118       help_text='continuous (without breaks) protein chains,use TER to divide chains')
119      pdbid = forms.CharField(min_length=4,max_length=6,required=False,
120       widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
121       label='or PDB code (:chain)')                   
122
123      def clean(self):
124              cleaned_data = super(TaskForm_min, self).clean()
125
126              pdbid = cleaned_data.get("pdbid") 
127              file1 = cleaned_data.get("file1")
128               
129              if not pdbid and not file1:
130                 msg = 'provide pdb file or pdb code'
131                 self.add_error('file1', msg)
132               
133              if pdbid:
134                msg=pdb_code_chain(pdbid)
135                if msg != '':
136                    self.add_error('pdbid',msg)
137                
138              if file1:
139                  msg=pdb_missing_res_chain(file1,'')
140                  if msg != '':
141                    self.add_error('file1',msg)
142
143             
144 class TaskForm_min_a(forms.Form):
145      name = forms.CharField(max_length=40,widget=forms.TextInput(attrs={'size':40, 'maxlength':40}))
146
147      unres_ff = forms.ChoiceField(choices=FF_CHOICE,widget=forms.RadioSelect,
148                            label='Force Field',initial='FF2')
149 #     min_choice = forms.ChoiceField(choices=MIN_CHOICE,label='minimization algorithm')
150      min_overlap = forms.BooleanField(required=False,label='remove overlap')
151      min_searchsc = forms.BooleanField(required=False,label='MC for sidechain overlap')
152      min_maxmin = forms.IntegerField(label='MAXMIN',initial=10000,
153                   help_text='maximum number of iterations')
154      min_maxfun = forms.IntegerField(label='MAXFUN',initial=15000,
155                   help_text='maximum number of function evaluations')
156      file1 = forms.FileField(label='Upload a PDB file',required=False,
157         help_text='continuous (without breaks) protein chains,use TER to divide chains')
158      pdbid = forms.CharField(min_length=4,max_length=6,required=False,
159       widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
160       label='or PDB code (:chain)')                   
161
162      min_unres_pdb = forms.BooleanField(required=False,label='uploaded input unres PDB',
163                   help_text='(CA and CB atoms only, CB represents SC in UNRES)')
164      min_pdbout = forms.BooleanField(required=False,label='output PDB',initial='true')
165      boxx = forms.FloatField(label='Box X',initial=1000.0,
166                        help_text='box x dimension')
167      boxy = forms.FloatField(label='Box Y',initial=1000.0,
168                        help_text='box y dimension')
169      boxz = forms.FloatField(label='Box Z',initial=1000.0,
170                        help_text='box z dimension')
171
172      def clean(self):
173              cleaned_data = super(TaskForm_min_a, self).clean()
174
175              pdbid = cleaned_data.get("pdbid") 
176              file1 = cleaned_data.get("file1")
177               
178              if not pdbid and not file1:
179                 msg = 'provide pdb file or pdb code'
180                 self.add_error('file1', msg)
181               
182              if pdbid:
183                  msg=pdb_code_chain(pdbid)
184                  if msg != '':
185                    self.add_error('pdbid',msg)
186                
187              if file1:
188                  msg=pdb_missing_res_chain(file1,'')
189                  if msg != '':
190                    self.add_error('file1',msg)
191
192
193 class TaskForm_md(forms.Form):
194      name = forms.CharField(max_length=40,widget=forms.TextInput(attrs={'size':40, 'maxlength':40}))
195
196      md_start = forms.ChoiceField(choices=MD_START,widget=forms.RadioSelect,
197                       label='starting structure',initial='extconf')
198      md_seq = forms.CharField(label='Sequence',
199                      help_text='aminoacid sequence using one letter code<br>'+
200                      'field is ignored when uploading starting/reference PDB file',
201                      required=False,
202                      widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
203      file1 = forms.FileField(label='Upload a PDB file',required=False,
204                   help_text='starting structure for pdbstart/reference structure')
205      pdbid = forms.CharField(min_length=4,max_length=6,required=False,
206       widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
207       label='or PDB code (:chain)')                   
208      md_pdbref = forms.BooleanField(required=False,label='PDB reference structure')
209      md_temp = forms.FloatField(label='temperature',initial=300,
210                   help_text='bath temperature')
211      md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
212                   help_text='total number of steps',max_value=10000000)
213      md_seed = forms.IntegerField(label='SEED',initial=-39912345,
214                   help_text='seed for random number generator')
215                   
216      def clean(self):
217              cleaned_data = super(TaskForm_md, self).clean()
218
219              md_start = cleaned_data.get("md_start") 
220              file1 = cleaned_data.get("file1")
221              pdbid = cleaned_data.get("pdbid")
222              md_seq = cleaned_data.get("md_seq")
223              md_pdbref = cleaned_data.get("md_pdbref")
224               
225              if md_start == 'pdbstart' and not (file1 or pdbid):
226                 msg = 'pdbstart with no PDB file or code'
227                 self.add_error('file1', msg)
228
229              if md_pdbref and not (file1 or pdbid):
230                 msg = 'pdbref with no PDB file or code'
231                 self.add_error('file1', msg)
232
233
234              if md_start != 'pdbstart' and not md_pdbref and not md_seq:
235                 msg = 'extended/random chain with no sequence'
236                 self.add_error('md_seq', msg)
237
238              if pdbid:
239                  msg=pdb_code_chain(pdbid)
240                  if msg != '':
241                    self.add_error('pdbid',msg)
242                
243              if file1:
244                  msg=pdb_missing_res_chain(file1,'')
245                  if msg != '':
246                    self.add_error('file1',msg)
247
248                         
249 class TaskForm_md_a(forms.Form):
250      name = forms.CharField(max_length=40,widget=forms.TextInput(attrs={'size':40, 'maxlength':40}))
251
252      unres_ff = forms.ChoiceField(choices=FF_CHOICE,widget=forms.RadioSelect,
253                            label='Force Field',initial='FF2')
254      md_start = forms.ChoiceField(choices=MD_START,widget=forms.RadioSelect,
255                       label='starting structure',initial='extconf')
256      md_seq = forms.CharField(label='Sequence',
257                      help_text='aminoacid sequence using one letter code<br>'+
258                      'field is ignored when uploading starting/reference PDB file',
259                      required=False,
260                      widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
261      md_2d = forms.CharField(label='Secondary structure restraints',
262                      help_text='single letter code: H helix, E extended/beta, C or - no restraints',
263                      required=False,
264                      widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
265
266      file1 = forms.FileField(label='Upload a PDB file',required=False,
267                   help_text='starting structure for pdbstart/reference structure')
268      pdbid = forms.CharField(min_length=4,max_length=6,required=False,
269       widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
270       label='or PDB code (:chain)')                   
271      md_pdbref = forms.BooleanField(required=False,label='PDB reference structure')                  
272      md_temp = forms.FloatField(label='temperature',initial=300,
273                   help_text='bath temperature')
274      md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
275                   help_text='total number of steps',max_value=10000000)
276      md_seed = forms.IntegerField(label='SEED',initial=-39912345,
277                   help_text='seed for random number generator')
278
279      md_ntwe = forms.IntegerField(label='NTWE',initial=1000,
280                help_text='write statfile every ntwe steps')
281      md_ntwx = forms.IntegerField(label='NTWX',initial=1000,
282                help_text='write trajectory every ntwe steps',min_value=100)
283      md_dt = forms.FloatField(label='DT',initial=0.2,
284                   help_text='time step [mtu=48.9 fs]')
285      md_lang = forms.ChoiceField(choices=MD_LANG,label='thermostat')
286      md_tau = forms.FloatField(label='tau_bath',initial=1.0,
287                   help_text='coupling to the thermal bath (Berendsen)')
288      md_scal_fric = forms.FloatField(label='scal_froc',initial=0.02,
289                   help_text='scaling of the friction coefficients (Langevin)')
290      md_respa = forms.BooleanField(required=False,initial=True,label='RESPA')
291      md_mdpdb = forms.BooleanField(required=False,label='trajectory as PDB')
292
293      boxx = forms.FloatField(label='Box X',initial=1000.0,
294                        help_text='box x dimension')
295      boxy = forms.FloatField(label='Box Y',initial=1000.0,
296                        help_text='box y dimension')
297      boxz = forms.FloatField(label='Box Z',initial=1000.0,
298                        help_text='box z dimension')
299
300      def clean(self):
301              cleaned_data = super(TaskForm_md_a, self).clean()
302
303              md_start = cleaned_data.get("md_start") 
304              file1 = cleaned_data.get("file1")
305              pdbid = cleaned_data.get("pdbid")
306              md_seq = cleaned_data.get("md_seq")
307              md_pdbref = cleaned_data.get("md_pdbref")
308              md_2d = cleaned_data.get("md_2d")
309               
310              if md_start == 'pdbstart' and not (file1 or pdbid):
311                 msg = 'pdbstart with no PDB file or code'
312                 self.add_error('file1', msg)
313
314              if md_pdbref and not (file1 or pdbid):
315                 msg = 'pdbref with no PDB file or code'
316                 self.add_error('file1', msg)
317
318
319              if md_start != 'pdbstart' and not md_pdbref and not md_seq:
320                 msg = 'extended/random chain with no sequence'
321                 self.add_error('md_seq', msg)
322
323              if pdbid:
324                  msg=pdb_code_chain(pdbid)
325                  if msg != '':
326                    self.add_error('pdbid',msg)
327                
328              if file1:
329                  msg=pdb_missing_res_chain(file1,'')
330                  if msg != '':
331                    self.add_error('file1',msg)
332              
333              if md_2d:
334                  msg=code_2d(md_2d)
335                  if msg != '':
336                    self.add_error('md_2d',msg)
337
338 class TaskForm_remd(forms.Form):
339      name = forms.CharField(max_length=40,widget=forms.TextInput(attrs={'size':40, 'maxlength':40}))
340
341      md_start = forms.ChoiceField(choices=MD_START,widget=forms.RadioSelect,
342                       label='starting structure',initial='extconf')
343      md_seq = forms.CharField(label='Sequence',
344                      help_text='aminoacid sequence using one letter code<br>'+
345                         'field is ignored when uploading starting/reference PDB file',
346                      required=False,
347                      widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
348      file1 = forms.FileField(label='Upload a PDB file',required=False,
349                   help_text='starting structure for pdbstart/reference structure')
350      pdbid = forms.CharField(min_length=4,max_length=6,required=False,
351       widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
352       label='or PDB code (:chain)')                   
353      md_pdbref = forms.BooleanField(required=False,label='PDB reference structure')                  
354      md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
355                   help_text='total number of steps',max_value=10000000)
356      md_seed = forms.IntegerField(label='SEED',initial=-39912345,
357                   help_text='seed for random number generator')
358                   
359      def clean(self):
360              cleaned_data = super(TaskForm_remd, self).clean()
361
362              md_start = cleaned_data.get("md_start") 
363              file1 = cleaned_data.get("file1")
364              pdbid = cleaned_data.get("pdbid")
365              md_seq = cleaned_data.get("md_seq")
366              md_pdbref = cleaned_data.get("md_pdbref")
367               
368              if md_start == 'pdbstart' and not (file1 or pdbid):
369                 msg = 'pdbstart with no PDB file or code'
370                 self.add_error('file1', msg)
371
372              if md_pdbref and not (file1 or pdbid):
373                 msg = 'pdbref with no PDB file or code'
374                 self.add_error('file1', msg)
375
376              if md_start != 'pdbstart' and not md_pdbref and not md_seq:
377                 msg = 'extended/random chain with no sequence'
378                 self.add_error('md_seq', msg)
379
380              if pdbid:
381                  msg=pdb_code_chain(pdbid)
382                  if msg != '':
383                    self.add_error('pdbid',msg)
384                
385              if file1:
386                  msg=pdb_missing_res_chain(file1,'')
387                  if msg != '':
388                    self.add_error('file1',msg)
389
390                              
391 class TaskForm_remd_a(forms.Form):
392      name = forms.CharField(max_length=40,widget=forms.TextInput(attrs={'size':40, 'maxlength':40}))
393
394      unres_ff = forms.ChoiceField(choices=FF_CHOICE,widget=forms.RadioSelect,
395                            label='Force Field',initial='FF2')
396      md_start = forms.ChoiceField(choices=MD_START,widget=forms.RadioSelect,
397                       label='starting structure',initial='extconf')
398      md_seq = forms.CharField(label='Sequence',
399                      help_text='aminoacid sequence using one letter code<br>'+
400                       'field is ignored when uploading starting/reference PDB file',
401                      required=False,
402                      widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
403      md_2d = forms.CharField(label='Secondary structure restraints',
404                      help_text='single letter code: H helix, E extended/beta, C or - no restraints',
405                      required=False,
406                      widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
407      file1 = forms.FileField(label='Upload a PDB file',required=False,
408                   help_text='starting structure for pdbstart/reference structure')
409      pdbid = forms.CharField(min_length=4,max_length=6,required=False,
410       widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
411       label='or PDB code (:chain)')                   
412      md_pdbref = forms.BooleanField(required=False,label='PDB reference structure')                  
413      md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
414                   help_text='total number of steps',max_value=10000000)
415      md_seed = forms.IntegerField(label='SEED',initial=-39912345,
416                   help_text='seed for random number generator')
417      md_ntwe = forms.IntegerField(label='NTWE',initial=1000,
418                help_text='write statfile every ntwe steps')
419      md_dt = forms.FloatField(label='DT',initial=0.2,
420                   help_text='time step [mtu = 48.9 fs]')
421      md_lang = forms.ChoiceField(choices=MD_LANG,label='thermostat')
422      md_tau = forms.FloatField(label='tau_bath',initial=1.0,
423                   help_text='coupling to the thermal bath (Berendsen)')
424      md_scal_fric = forms.FloatField(label='scal_froc',initial=0.02,
425                   help_text='scaling of the friction coefficients (Langevin)')
426      min_maxfun = forms.IntegerField(label='MAXFUN',initial=5000,
427                   help_text='preminim maximum number of function evaluations<br>'+
428                   'used for start from pdb or random start')
429      remd_nrep = forms.IntegerField(label='NREP',initial=8,
430                   help_text='number of replicas')
431      remd_nstex = forms.IntegerField(label='NSTEX',initial=1000,
432                   help_text='exchange and write trajectory every nstex steps')
433      md_ntwx = forms.IntegerField(label='NTWX',initial=1000,min_value=100,
434                help_text='write trajectory every ntwx steps')
435      remd_cluter_temp = forms.FloatField(label='TEMPER',
436                   help_text='temperature for cluster analysis',initial=280)                  
437 #     remd_traj1file = forms.BooleanField(required=False,label='single trajectory file',initial='true')
438 #     remd_rest1file = forms.BooleanField(required=False,label='single restart file',initial='true')
439
440      md_respa = forms.BooleanField(required=False,initial=True,label='RESPA')
441
442      boxx = forms.FloatField(label='Box X',initial=1000.0,
443                        help_text='box x dimension')
444      boxy = forms.FloatField(label='Box Y',initial=1000.0,
445                        help_text='box y dimension')
446      boxz = forms.FloatField(label='Box Z',initial=1000.0,
447                        help_text='box z dimension')
448
449
450      wsaxs = forms.FloatField(label='SAXS weight',initial=100.0,
451                             help_text='weight for SAXS restraint term')
452      scal_rad = forms.FloatField(label='Scal_rad (SAXS)',initial=1.0,
453                             help_text='downscaling factor of residue radii used in SAXS restraints')
454      saxs_data = forms.CharField(label='P(r) SAXS data',
455                      help_text='distance distribution from SAXS, two columns: r and P(r)',
456                      required=False,
457                      widget=forms.Textarea(attrs={'cols': 25, 'rows': 20}))
458
459
460      def clean(self):
461              cleaned_data = super(TaskForm_remd_a, self).clean()
462
463              md_start = cleaned_data.get("md_start") 
464              file1 = cleaned_data.get("file1")
465              pdbid = cleaned_data.get("pdbid")
466              md_seq = cleaned_data.get("md_seq")
467              md_pdbref = cleaned_data.get("md_pdbref")
468              md_2d = cleaned_data.get("md_2d")
469               
470              if md_start == 'pdbstart' and not (file1 or pdbid):
471                 msg = 'pdbstart with no PDB file or code'
472                 self.add_error('file1', msg)
473
474              if md_pdbref and not (file1 or pdbid):
475                 msg = 'pdbref with no PDB file or code'
476                 self.add_error('file1', msg)
477
478
479              if md_start != 'pdbstart' and not md_pdbref and not md_seq:
480                 msg = 'extended/random chain with no sequence'
481                 self.add_error('md_seq', msg)
482
483              if pdbid:
484                  msg=pdb_code_chain(pdbid)
485                  if msg != '':
486                    self.add_error('pdbid',msg)
487                
488              if file1:
489                  msg=pdb_missing_res_chain(file1,'')
490                  if msg != '':
491                    self.add_error('file1',msg)
492
493              if md_2d:
494                  msg=code_2d(md_2d)
495                  if msg != '':
496                    self.add_error('md_2d',msg)
497
498
499 class TaskForm_dock(forms.Form):
500      name = forms.CharField(max_length=40,widget=forms.TextInput(attrs={'size':40, 'maxlength':40}))
501
502      file1 = forms.FileField(label='Upload a PDB file1',required=False,
503                   help_text='starting structure for chain1')
504      pdbid = forms.CharField(min_length=4,max_length=6,required=False,
505       widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
506       label='or PDB code (:chain)')                   
507
508
509      md_seq = forms.CharField(label=mark_safe('Sequence of chain2 <br /> for dock peptide'),
510                      help_text='aminoacid sequence using one letter code<br>'+
511                         'field is ignored when uploading PDB file2',
512                      required=False,
513                      widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
514
515
516      file2 = forms.FileField(label='Upload a PDB file2',required=False,
517                   help_text='starting structure for chain2')
518      pdbid2 = forms.CharField(min_length=4,max_length=6,required=False,
519       widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
520       label='or PDB code (:chain)')                   
521
522
523      md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
524                   help_text='total number of steps', max_value=10000000)
525      md_seed = forms.IntegerField(label='SEED',initial=-39912345,
526                   help_text='seed for random number generator')
527      dock_peptide = forms.BooleanField(required=False,initial=False,
528             label='dock peptide',help_text='no constraints on chain2')                  
529                   
530      def clean(self):
531              cleaned_data = super(TaskForm_dock, self).clean()
532
533              file1 = cleaned_data.get("file1")
534              pdbid = cleaned_data.get("pdbid")
535              file2 = cleaned_data.get("file2")
536              pdbid2 = cleaned_data.get("pdbid2")
537              md_seq = cleaned_data.get("md_seq")
538
539               
540              if not (file1 or pdbid):
541                 msg = 'no PDB file or code for chain1'
542                 self.add_error('file1', msg)
543
544              if not (file2 or pdbid2 or md_seq):
545                 msg = 'no PDB file or code or sequence for chain2'
546                 self.add_error('file2', msg)
547
548              if pdbid:
549                  msg=pdb_code_chain(pdbid)
550                  if msg != '':
551                    self.add_error('pdbid',msg)
552                
553              if file1:
554                  msg=pdb_missing_res_chain(file1,'')
555                  if msg != '':
556                    self.add_error('file1',msg)
557
558              if pdbid2:
559                  msg=pdb_code_chain(pdbid2)
560                  if msg != '':
561                    self.add_error('pdbid2',msg)
562                
563              if file2:
564                  msg=pdb_missing_res_chain(file2,'')
565                  if msg != '':
566                    self.add_error('file2',msg)
567
568 class TaskForm_dock_a(forms.Form):
569      name = forms.CharField(max_length=40,widget=forms.TextInput(attrs={'size':40, 'maxlength':40}))
570
571      file1 = forms.FileField(label='Upload a PDB file1',required=False,
572                   help_text='starting structure for chain1')
573      pdbid = forms.CharField(min_length=4,max_length=6,required=False,
574       widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
575       label='or PDB code (:chain)')                   
576
577      md_seq = forms.CharField(label=mark_safe('Sequence of chain2 <br /> for dock peptide'),
578                      help_text='aminoacid sequence using one letter code<br>'+
579                         'field is ignored when uploading PDB file2',
580                      required=False,
581                      widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
582
583
584      file2 = forms.FileField(label='Upload a PDB file2',required=False,
585                   help_text='starting structure for chain2')
586      pdbid2 = forms.CharField(min_length=4,max_length=6,required=False,
587       widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
588       label='or PDB code (:chain)')                   
589
590
591      md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
592                   help_text='total number of steps', max_value=10000000)
593      md_seed = forms.IntegerField(label='SEED',initial=-39912345,
594                   help_text='seed for random number generator')
595      dock_peptide = forms.BooleanField(required=False,initial=False,
596             label='dock peptide',help_text='no constraints on 2nd chain')                  
597                   
598
599      unres_ff = forms.ChoiceField(choices=FF_CHOICE,widget=forms.RadioSelect,
600                            label='Force Field',initial='FF2')
601
602      md_ntwe = forms.IntegerField(label='NTWE',initial=1000,
603                help_text='write statfile every ntwe steps')
604      md_dt = forms.FloatField(label='DT',initial=0.2,
605                   help_text='time step [mtu = 48.9 fs]')
606      md_lang = forms.ChoiceField(choices=MD_LANG,label='thermostat')
607      md_tau = forms.FloatField(label='tau_bath',initial=1.0,
608                   help_text='coupling to the thermal bath (Berendsen)')
609      md_scal_fric = forms.FloatField(label='scal_froc',initial=0.02,
610                   help_text='scaling of the friction coefficients (Langevin)')
611      min_maxfun = forms.IntegerField(label='MAXFUN',initial=5000,
612                   help_text='preminim maximum number of function evaluations<br>'+
613                   'used for start from pdb or random start')
614      remd_nrep = forms.IntegerField(label='NREP',initial=8,
615                   help_text='number of replicas')
616      remd_nstex = forms.IntegerField(label='NSTEX',initial=1000,
617                   help_text='exchange and write trajectory every nstex steps')
618      md_ntwx = forms.IntegerField(label='NTWX',initial=1000,min_value=100,
619                help_text='write trajectory every ntwx steps')
620      remd_cluter_temp = forms.FloatField(label='TEMPER',
621                   help_text='temperature for cluster analysis',initial=280)                  
622
623
624      def clean(self):
625              cleaned_data = super(TaskForm_dock_a, self).clean()
626
627              file1 = cleaned_data.get("file1")
628              pdbid = cleaned_data.get("pdbid")
629              file2 = cleaned_data.get("file2")
630              pdbid2 = cleaned_data.get("pdbid2")
631              md_seq = cleaned_data.get("md_seq")
632               
633              if not (file1 or pdbid):
634                 msg = 'no PDB file or code for chain1'
635                 self.add_error('file1', msg)
636
637              if not (file2 or pdbid2 or md_seq):
638                 msg = 'no PDB file or code or sequence for chain2'
639                 self.add_error('file2', msg)
640
641              if pdbid:
642                  msg=pdb_code_chain(pdbid)
643                  if msg != '':
644                    self.add_error('pdbid',msg)
645                
646              if file1:
647                  msg=pdb_missing_res_chain(file1,'')
648                  if msg != '':
649                    self.add_error('file1',msg)
650
651              if pdbid2:
652                  msg=pdb_code_chain(pdbid2)
653                  if msg != '':
654                    self.add_error('pdbid2',msg)
655                
656              if file2:
657                  msg=pdb_missing_res_chain(file2,'')
658                  if msg != '':
659                    self.add_error('file2',msg)
660
661
662 class TaskForm_list(forms.Form):
663     name = forms.CharField(max_length=40,disabled=True,required=False)
664     nrep = forms.IntegerField(disabled=True,required=False,label='NREP')
665
666     def __init__(self, count, *args, **kwargs):
667         super(TaskForm_list, self).__init__(*args, **kwargs)
668         self.count=count
669         self.fields['temperatures'] = MultiExampleField(self.count)
670         self.fields['multiplexing'] = MultiExampleField(self.count)        
671      
672
673