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
10 def pdb_code_chain(pdbid):
16 return('use : between pdb code and chain id, like 5G3Q:B to select single chain')
20 test=urllib.urlopen('http://files.rcsb.org/download/'+pdbid+'.pdb')
22 msg = 'wrong pdb code'
24 msg=pdb_missing_res_chain(test,chain)
28 def pdb_missing_res_chain(file,chain):
33 if line[0:6] == 'ATOM ' and line[13:15] == 'CA' and (line[21] == chain or chain==''):
36 if ires and i==ires[-1]:
38 if newchain or i==ires[-1]+1:
42 msg = 'chain breaks between residues '+\
43 str(ires[-1])+' and '+str(i)+' of chain '+ch+\
44 ', server cannot add missing residues to PDB file - please repair the structure using e.g. Modeller'
46 if line[0:3] == 'TER':
48 if line[0:3] == 'END':
59 line2 = ''.join([c for c in line if c in set])
61 msg='use only H,E,C or - letters'
64 def pdb_missing_res(file):
69 if line[0:6] == 'ATOM ' and line[13:15] == 'CA':
71 if ires and i==ires[-1]:
73 if newchain or i==ires[-1]+1:
77 msg = 'chain breaks between residues '+\
78 str(ires[-1])+' and '+str(i)+\
79 ', server cannot add missing residues to PDB file - please repair the structure using e.g. Modeller'
81 if line[0:3] == 'TER':
83 if line[0:3] == 'END':
88 class MultiWidgetBasic(forms.MultiWidget):
89 def __init__(self, count, attrs=None):
92 for i in range(self.count):
93 widgets.append(forms.TextInput())
94 super(MultiWidgetBasic, self).__init__(widgets, attrs)
96 template_name = 'multi.html'
98 def decompress(self, value):
100 return json.loads(value)
105 class MultiExampleField(forms.fields.MultiValueField):
106 def __init__(self, count, *args, **kwargs):
108 self.widget = MultiWidgetBasic(self.count)
110 for i in range(self.count):
111 list_fields.append(forms.fields.CharField(max_length=15))
112 super(MultiExampleField, self).__init__(list_fields, *args, **kwargs)
114 def compress(self, values):
115 ## compress list to single object
116 return json.dumps(values)
119 class TaskForm(forms.Form):
120 name = forms.CharField(max_length=20)
123 class TaskForm_min(forms.Form):
124 name = forms.CharField(max_length=20)
125 file1 = forms.FileField(label='Upload a PDB file',required=False,
126 help_text='continuous (without breaks) protein chains,use TER to divide chains')
127 pdbid = forms.CharField(min_length=4,max_length=6,required=False,
128 widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
129 label='or PDB code (:chain)')
132 cleaned_data = super(TaskForm_min, self).clean()
134 pdbid = cleaned_data.get("pdbid")
135 file1 = cleaned_data.get("file1")
137 if not pdbid and not file1:
138 msg = 'provide pdb file or pdb code'
139 self.add_error('file1', msg)
142 msg=pdb_code_chain(pdbid)
144 self.add_error('pdbid',msg)
147 msg=pdb_missing_res(file1)
149 self.add_error('file1',msg)
152 class TaskForm_min_a(forms.Form):
153 name = forms.CharField(max_length=20)
155 unres_ff = forms.ChoiceField(choices=FF_CHOICE,widget=forms.RadioSelect,
156 label='Force Field',initial='FF2')
157 # min_choice = forms.ChoiceField(choices=MIN_CHOICE,label='minimization algorithm')
158 min_overlap = forms.BooleanField(required=False,label='remove overlap')
159 min_searchsc = forms.BooleanField(required=False,label='MC for sidechain overlap')
160 min_maxmin = forms.IntegerField(label='MAXMIN',initial=10000,
161 help_text='maximum number of iterations')
162 min_maxfun = forms.IntegerField(label='MAXFUN',initial=15000,
163 help_text='maximum number of function evaluations')
164 file1 = forms.FileField(label='Upload a PDB file',required=False,
165 help_text='continuous (without breaks) protein chains,use TER to divide chains')
166 pdbid = forms.CharField(min_length=4,max_length=6,required=False,
167 widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
168 label='or PDB code (:chain)')
170 min_unres_pdb = forms.BooleanField(required=False,label='uploaded input unres PDB',
171 help_text='(CA and CB atoms only, CB represents SC in UNRES)')
172 min_pdbout = forms.BooleanField(required=False,label='output PDB',initial='true')
173 boxx = forms.FloatField(label='Box X',initial=1000.0,
174 help_text='box x dimension')
175 boxy = forms.FloatField(label='Box Y',initial=1000.0,
176 help_text='box y dimension')
177 boxz = forms.FloatField(label='Box Z',initial=1000.0,
178 help_text='box z dimension')
181 cleaned_data = super(TaskForm_min_a, self).clean()
183 pdbid = cleaned_data.get("pdbid")
184 file1 = cleaned_data.get("file1")
186 if not pdbid and not file1:
187 msg = 'provide pdb file or pdb code'
188 self.add_error('file1', msg)
191 msg=pdb_code_chain(pdbid)
193 self.add_error('pdbid',msg)
196 msg=pdb_missing_res(file1)
198 self.add_error('file1',msg)
201 class TaskForm_md(forms.Form):
202 name = forms.CharField(max_length=20)
204 md_start = forms.ChoiceField(choices=MD_START,widget=forms.RadioSelect,
205 label='starting structure',initial='extconf')
206 md_seq = forms.CharField(label='Sequence',
207 help_text='aminoacid sequence using one letter code<br>'+
208 'field is ignored when uploading starting/reference PDB file',
210 widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
211 file1 = forms.FileField(label='Upload a PDB file',required=False,
212 help_text='starting structure for pdbstart/reference structure')
213 pdbid = forms.CharField(min_length=4,max_length=6,required=False,
214 widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
215 label='or PDB code (:chain)')
216 md_pdbref = forms.BooleanField(required=False,label='PDB reference structure')
217 md_temp = forms.FloatField(label='temperature',initial=300,
218 help_text='bath temperature')
219 md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
220 help_text='total number of steps')
221 md_seed = forms.IntegerField(label='SEED',initial=-39912345,
222 help_text='seed for random number generator')
225 cleaned_data = super(TaskForm_md, self).clean()
227 md_start = cleaned_data.get("md_start")
228 file1 = cleaned_data.get("file1")
229 pdbid = cleaned_data.get("pdbid")
230 md_seq = cleaned_data.get("md_seq")
231 md_pdbref = cleaned_data.get("md_pdbref")
233 if md_start == 'pdbstart' and not (file1 or pdbid):
234 msg = 'pdbstart with no PDB file or code'
235 self.add_error('file1', msg)
237 if md_pdbref and not (file1 or pdbid):
238 msg = 'pdbref with no PDB file or code'
239 self.add_error('file1', msg)
242 if md_start != 'pdbstart' and not md_pdbref and not md_seq:
243 msg = 'extended/random chain with no sequence'
244 self.add_error('md_seq', msg)
247 msg=pdb_code_chain(pdbid)
249 self.add_error('pdbid',msg)
252 msg=pdb_missing_res(file1)
254 self.add_error('file1',msg)
257 class TaskForm_md_a(forms.Form):
258 name = forms.CharField(max_length=20)
260 unres_ff = forms.ChoiceField(choices=FF_CHOICE,widget=forms.RadioSelect,
261 label='Force Field',initial='FF2')
262 md_start = forms.ChoiceField(choices=MD_START,widget=forms.RadioSelect,
263 label='starting structure',initial='extconf')
264 md_seq = forms.CharField(label='Sequence',
265 help_text='aminoacid sequence using one letter code<br>'+
266 'field is ignored when uploading starting/reference PDB file',
268 widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
269 md_2d = forms.CharField(label='Secondary structure restraints',
270 help_text='single letter code: H - helix, E - extended/beta, C or - no restraints',
272 widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
274 file1 = forms.FileField(label='Upload a PDB file',required=False,
275 help_text='starting structure for pdbstart/reference structure')
276 pdbid = forms.CharField(min_length=4,max_length=6,required=False,
277 widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
278 label='or PDB code (:chain)')
279 md_pdbref = forms.BooleanField(required=False,label='PDB reference structure')
280 md_temp = forms.FloatField(label='temperature',initial=300,
281 help_text='bath temperature')
282 md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
283 help_text='total number of steps')
284 md_seed = forms.IntegerField(label='SEED',initial=-39912345,
285 help_text='seed for random number generator')
287 md_ntwe = forms.IntegerField(label='NTWE',initial=1000,
288 help_text='write statfile every ntwe steps')
289 md_ntwx = forms.IntegerField(label='NTWX',initial=1000,
290 help_text='write trajectory every ntwe steps')
291 md_dt = forms.FloatField(label='DT',initial=0.2,
292 help_text='time step [mtu=48.9 fs]')
293 md_lang = forms.ChoiceField(choices=MD_LANG,label='thermostat')
294 md_tau = forms.FloatField(label='tau_bath',initial=1.0,
295 help_text='coupling to the thermal bath (Berendsen)')
296 md_scal_fric = forms.FloatField(label='scal_froc',initial=0.02,
297 help_text='scaling of the friction coefficients (Langevin)')
298 md_respa = forms.BooleanField(required=False,initial=True,label='RESPA')
299 md_mdpdb = forms.BooleanField(required=False,label='trajectory as PDB')
301 boxx = forms.FloatField(label='Box X',initial=1000.0,
302 help_text='box x dimension')
303 boxy = forms.FloatField(label='Box Y',initial=1000.0,
304 help_text='box y dimension')
305 boxz = forms.FloatField(label='Box Z',initial=1000.0,
306 help_text='box z dimension')
309 cleaned_data = super(TaskForm_md_a, self).clean()
311 md_start = cleaned_data.get("md_start")
312 file1 = cleaned_data.get("file1")
313 pdbid = cleaned_data.get("pdbid")
314 md_seq = cleaned_data.get("md_seq")
315 md_pdbref = cleaned_data.get("md_pdbref")
316 md_2d = cleaned_data.get("md_2d")
318 if md_start == 'pdbstart' and not (file1 or pdbid):
319 msg = 'pdbstart with no PDB file or code'
320 self.add_error('file1', msg)
322 if md_pdbref and not (file1 or pdbid):
323 msg = 'pdbref with no PDB file or code'
324 self.add_error('file1', msg)
327 if md_start != 'pdbstart' and not md_pdbref and not md_seq:
328 msg = 'extended/random chain with no sequence'
329 self.add_error('md_seq', msg)
332 msg=pdb_code_chain(pdbid)
334 self.add_error('pdbid',msg)
337 msg=pdb_missing_res(file1)
339 self.add_error('file1',msg)
344 self.add_error('md_2d',msg)
346 class TaskForm_remd(forms.Form):
347 name = forms.CharField(max_length=20)
349 md_start = forms.ChoiceField(choices=MD_START,widget=forms.RadioSelect,
350 label='starting structure',initial='extconf')
351 md_seq = forms.CharField(label='Sequence',
352 help_text='aminoacid sequence using one letter code<br>'+
353 'field is ignored when uploading starting/reference PDB file',
355 widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
356 file1 = forms.FileField(label='Upload a PDB file',required=False,
357 help_text='starting structure for pdbstart/reference structure')
358 pdbid = forms.CharField(min_length=4,max_length=6,required=False,
359 widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
360 label='or PDB code (:chain)')
361 md_pdbref = forms.BooleanField(required=False,label='PDB reference structure')
362 md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
363 help_text='total number of steps')
364 md_seed = forms.IntegerField(label='SEED',initial=-39912345,
365 help_text='seed for random number generator')
368 cleaned_data = super(TaskForm_remd, self).clean()
370 md_start = cleaned_data.get("md_start")
371 file1 = cleaned_data.get("file1")
372 pdbid = cleaned_data.get("pdbid")
373 md_seq = cleaned_data.get("md_seq")
374 md_pdbref = cleaned_data.get("md_pdbref")
376 if md_start == 'pdbstart' and not (file1 or pdbid):
377 msg = 'pdbstart with no PDB file or code'
378 self.add_error('file1', msg)
380 if md_pdbref and not (file1 or pdbid):
381 msg = 'pdbref with no PDB file or code'
382 self.add_error('file1', msg)
384 if md_start != 'pdbstart' and not md_pdbref and not md_seq:
385 msg = 'extended/random chain with no sequence'
386 self.add_error('md_seq', msg)
389 msg=pdb_code_chain(pdbid)
391 self.add_error('pdbid',msg)
394 msg=pdb_missing_res(file1)
396 self.add_error('file1',msg)
399 class TaskForm_remd_a(forms.Form):
400 name = forms.CharField(max_length=20)
402 unres_ff = forms.ChoiceField(choices=FF_CHOICE,widget=forms.RadioSelect,
403 label='Force Field',initial='FF2')
404 md_start = forms.ChoiceField(choices=MD_START,widget=forms.RadioSelect,
405 label='starting structure',initial='extconf')
406 md_seq = forms.CharField(label='Sequence',
407 help_text='aminoacid sequence using one letter code<br>'+
408 'field is ignored when uploading starting/reference PDB file',
410 widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
411 md_2d = forms.CharField(label='Secondary structure restraints',
412 help_text='single letter code: H - helix, E - extended/beta, C or - no restraints',
414 widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
415 file1 = forms.FileField(label='Upload a PDB file',required=False,
416 help_text='starting structure for pdbstart/reference structure')
417 pdbid = forms.CharField(min_length=4,max_length=6,required=False,
418 widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
419 label='or PDB code (:chain)')
420 md_pdbref = forms.BooleanField(required=False,label='PDB reference structure')
421 md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
422 help_text='total number of steps')
423 md_seed = forms.IntegerField(label='SEED',initial=-39912345,
424 help_text='seed for random number generator')
425 md_ntwe = forms.IntegerField(label='NTWE',initial=1000,
426 help_text='write statfile every ntwe steps')
427 md_dt = forms.FloatField(label='DT',initial=0.2,
428 help_text='time step [mtu = 48.9 fs]')
429 md_lang = forms.ChoiceField(choices=MD_LANG,label='thermostat')
430 md_tau = forms.FloatField(label='tau_bath',initial=1.0,
431 help_text='coupling to the thermal bath (Berendsen)')
432 md_scal_fric = forms.FloatField(label='scal_froc',initial=0.02,
433 help_text='scaling of the friction coefficients (Langevin)')
434 remd_nrep = forms.IntegerField(label='NREP',initial=8,
435 help_text='number of replicas')
436 remd_nstex = forms.IntegerField(label='NSTEX',initial=1000,
437 help_text='exchange and write trajectory every nstex steps')
438 md_ntwx = forms.IntegerField(label='NTWX',initial=1000,
439 help_text='write trajectory every ntwx steps')
440 remd_cluter_temp = forms.FloatField(label='TEMPER',
441 help_text='temperature for cluster analysis',initial=280)
442 # remd_traj1file = forms.BooleanField(required=False,label='single trajectory file',initial='true')
443 # remd_rest1file = forms.BooleanField(required=False,label='single restart file',initial='true')
445 md_respa = forms.BooleanField(required=False,initial=True,label='RESPA')
447 boxx = forms.FloatField(label='Box X',initial=1000.0,
448 help_text='box x dimension')
449 boxy = forms.FloatField(label='Box Y',initial=1000.0,
450 help_text='box y dimension')
451 boxz = forms.FloatField(label='Box Z',initial=1000.0,
452 help_text='box z dimension')
455 wsaxs = forms.FloatField(label='SAXS weight',initial=100.0,
456 help_text='weight for SAXS restraint term')
457 scal_rad = forms.FloatField(label='Scal_rad (SAXS)',initial=1.0,
458 help_text='downscaling factor of residue radii used in SAXS restraints')
459 saxs_data = forms.CharField(label='P(r) SAXS data',
460 help_text='distance distribution from SAXS, two columns: r and P(r)',
462 widget=forms.Textarea(attrs={'cols': 25, 'rows': 20}))
466 cleaned_data = super(TaskForm_remd_a, self).clean()
468 md_start = cleaned_data.get("md_start")
469 file1 = cleaned_data.get("file1")
470 pdbid = cleaned_data.get("pdbid")
471 md_seq = cleaned_data.get("md_seq")
472 md_pdbref = cleaned_data.get("md_pdbref")
473 md_2d = cleaned_data.get("md_2d")
475 if md_start == 'pdbstart' and not (file1 or pdbid):
476 msg = 'pdbstart with no PDB file or code'
477 self.add_error('file1', msg)
479 if md_pdbref and not (file1 or pdbid):
480 msg = 'pdbref with no PDB file or code'
481 self.add_error('file1', msg)
484 if md_start != 'pdbstart' and not md_pdbref and not md_seq:
485 msg = 'extended/random chain with no sequence'
486 self.add_error('md_seq', msg)
489 msg=pdb_code_chain(pdbid)
491 self.add_error('pdbid',msg)
494 msg=pdb_missing_res(file1)
496 self.add_error('file1',msg)
501 self.add_error('md_2d',msg)
505 class TaskForm_list(forms.Form):
506 name = forms.CharField(max_length=20,disabled=True,required=False)
507 nrep = forms.IntegerField(disabled=True,required=False,label='NREP')
509 def __init__(self, count, *args, **kwargs):
510 super(TaskForm_list, self).__init__(*args, **kwargs)
512 self.fields['temperatures'] = MultiExampleField(self.count)
513 self.fields['multiplexing'] = MultiExampleField(self.count)