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
11 'DPR','DLY','DAR','DHI','DAS','DGL','DSG','DGN','DSN','DTH',
12 'DYY','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']
17 def pdb_code_chain(pdbid):
23 return('use : between pdb code and chain id, like 5G3Q:B to select single chain')
27 test=urllib.urlopen('http://files.rcsb.org/download/'+pdbid+'.pdb')
29 msg = 'wrong pdb code'
31 msg=pdb_missing_res_chain(test,chain)
35 def pdb_missing_res_chain(file,chain):
40 if line[0:6] == 'ATOM ' and line[13:15] == 'CA' and (line[21] == chain or chain==''):
43 if line[17:20] not in aa_3letter:
44 msg='residue '+line[17:20]+' '+str(i)+' not recognized'
46 if ires and i==ires[-1]:
48 if newchain or i==ires[-1]+1:
52 msg = 'chain breaks between residues '+\
53 str(ires[-1])+' and '+str(i)+' of chain '+ch+\
54 ', server cannot add missing residues to PDB file - please repair the structure using e.g. Modeller'
56 if line[0:3] == 'TER':
58 if line[0:3] == 'END':
63 msg='no CA atoms in this pdb'
72 line2 = ''.join([c for c in line if c in set])
74 msg='use only H,E,C or - letters'
78 class MultiWidgetBasic(forms.MultiWidget):
79 def __init__(self, count, attrs=None):
82 for i in range(self.count):
83 widgets.append(forms.TextInput())
84 super(MultiWidgetBasic, self).__init__(widgets, attrs)
86 template_name = 'multi.html'
88 def decompress(self, value):
90 return json.loads(value)
95 class MultiExampleField(forms.fields.MultiValueField):
96 def __init__(self, count, *args, **kwargs):
98 self.widget = MultiWidgetBasic(self.count)
100 for i in range(self.count):
101 list_fields.append(forms.fields.CharField(max_length=15))
102 super(MultiExampleField, self).__init__(list_fields, *args, **kwargs)
104 def compress(self, values):
105 ## compress list to single object
106 return json.dumps(values)
109 class TaskForm(forms.Form):
110 name = forms.CharField(max_length=20)
113 class TaskForm_min(forms.Form):
114 name = forms.CharField(max_length=20)
115 file1 = forms.FileField(label='Upload a PDB file',required=False,
116 help_text='continuous (without breaks) protein chains,use TER to divide chains')
117 pdbid = forms.CharField(min_length=4,max_length=6,required=False,
118 widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
119 label='or PDB code (:chain)')
122 cleaned_data = super(TaskForm_min, self).clean()
124 pdbid = cleaned_data.get("pdbid")
125 file1 = cleaned_data.get("file1")
127 if not pdbid and not file1:
128 msg = 'provide pdb file or pdb code'
129 self.add_error('file1', msg)
132 msg=pdb_code_chain(pdbid)
134 self.add_error('pdbid',msg)
137 msg=pdb_missing_res_chain(file1,'')
139 self.add_error('file1',msg)
142 class TaskForm_min_a(forms.Form):
143 name = forms.CharField(max_length=20)
145 unres_ff = forms.ChoiceField(choices=FF_CHOICE,widget=forms.RadioSelect,
146 label='Force Field',initial='FF2')
147 # min_choice = forms.ChoiceField(choices=MIN_CHOICE,label='minimization algorithm')
148 min_overlap = forms.BooleanField(required=False,label='remove overlap')
149 min_searchsc = forms.BooleanField(required=False,label='MC for sidechain overlap')
150 min_maxmin = forms.IntegerField(label='MAXMIN',initial=10000,
151 help_text='maximum number of iterations')
152 min_maxfun = forms.IntegerField(label='MAXFUN',initial=15000,
153 help_text='maximum number of function evaluations')
154 file1 = forms.FileField(label='Upload a PDB file',required=False,
155 help_text='continuous (without breaks) protein chains,use TER to divide chains')
156 pdbid = forms.CharField(min_length=4,max_length=6,required=False,
157 widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
158 label='or PDB code (:chain)')
160 min_unres_pdb = forms.BooleanField(required=False,label='uploaded input unres PDB',
161 help_text='(CA and CB atoms only, CB represents SC in UNRES)')
162 min_pdbout = forms.BooleanField(required=False,label='output PDB',initial='true')
163 boxx = forms.FloatField(label='Box X',initial=1000.0,
164 help_text='box x dimension')
165 boxy = forms.FloatField(label='Box Y',initial=1000.0,
166 help_text='box y dimension')
167 boxz = forms.FloatField(label='Box Z',initial=1000.0,
168 help_text='box z dimension')
171 cleaned_data = super(TaskForm_min_a, self).clean()
173 pdbid = cleaned_data.get("pdbid")
174 file1 = cleaned_data.get("file1")
176 if not pdbid and not file1:
177 msg = 'provide pdb file or pdb code'
178 self.add_error('file1', msg)
181 msg=pdb_code_chain(pdbid)
183 self.add_error('pdbid',msg)
186 msg=pdb_missing_res_chain(file1,'')
188 self.add_error('file1',msg)
191 class TaskForm_md(forms.Form):
192 name = forms.CharField(max_length=20)
194 md_start = forms.ChoiceField(choices=MD_START,widget=forms.RadioSelect,
195 label='starting structure',initial='extconf')
196 md_seq = forms.CharField(label='Sequence',
197 help_text='aminoacid sequence using one letter code<br>'+
198 'field is ignored when uploading starting/reference PDB file',
200 widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
201 file1 = forms.FileField(label='Upload a PDB file',required=False,
202 help_text='starting structure for pdbstart/reference structure')
203 pdbid = forms.CharField(min_length=4,max_length=6,required=False,
204 widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
205 label='or PDB code (:chain)')
206 md_pdbref = forms.BooleanField(required=False,label='PDB reference structure')
207 md_temp = forms.FloatField(label='temperature',initial=300,
208 help_text='bath temperature')
209 md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
210 help_text='total number of steps')
211 md_seed = forms.IntegerField(label='SEED',initial=-39912345,
212 help_text='seed for random number generator')
215 cleaned_data = super(TaskForm_md, self).clean()
217 md_start = cleaned_data.get("md_start")
218 file1 = cleaned_data.get("file1")
219 pdbid = cleaned_data.get("pdbid")
220 md_seq = cleaned_data.get("md_seq")
221 md_pdbref = cleaned_data.get("md_pdbref")
223 if md_start == 'pdbstart' and not (file1 or pdbid):
224 msg = 'pdbstart with no PDB file or code'
225 self.add_error('file1', msg)
227 if md_pdbref and not (file1 or pdbid):
228 msg = 'pdbref with no PDB file or code'
229 self.add_error('file1', msg)
232 if md_start != 'pdbstart' and not md_pdbref and not md_seq:
233 msg = 'extended/random chain with no sequence'
234 self.add_error('md_seq', msg)
237 msg=pdb_code_chain(pdbid)
239 self.add_error('pdbid',msg)
242 msg=pdb_missing_res_chain(file1,'')
244 self.add_error('file1',msg)
247 class TaskForm_md_a(forms.Form):
248 name = forms.CharField(max_length=20)
250 unres_ff = forms.ChoiceField(choices=FF_CHOICE,widget=forms.RadioSelect,
251 label='Force Field',initial='FF2')
252 md_start = forms.ChoiceField(choices=MD_START,widget=forms.RadioSelect,
253 label='starting structure',initial='extconf')
254 md_seq = forms.CharField(label='Sequence',
255 help_text='aminoacid sequence using one letter code<br>'+
256 'field is ignored when uploading starting/reference PDB file',
258 widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
259 md_2d = forms.CharField(label='Secondary structure restraints',
260 help_text='single letter code: H - helix, E - extended/beta, C or - no restraints',
262 widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
264 file1 = forms.FileField(label='Upload a PDB file',required=False,
265 help_text='starting structure for pdbstart/reference structure')
266 pdbid = forms.CharField(min_length=4,max_length=6,required=False,
267 widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
268 label='or PDB code (:chain)')
269 md_pdbref = forms.BooleanField(required=False,label='PDB reference structure')
270 md_temp = forms.FloatField(label='temperature',initial=300,
271 help_text='bath temperature')
272 md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
273 help_text='total number of steps')
274 md_seed = forms.IntegerField(label='SEED',initial=-39912345,
275 help_text='seed for random number generator')
277 md_ntwe = forms.IntegerField(label='NTWE',initial=1000,
278 help_text='write statfile every ntwe steps')
279 md_ntwx = forms.IntegerField(label='NTWX',initial=1000,
280 help_text='write trajectory every ntwe steps')
281 md_dt = forms.FloatField(label='DT',initial=0.2,
282 help_text='time step [mtu=48.9 fs]')
283 md_lang = forms.ChoiceField(choices=MD_LANG,label='thermostat')
284 md_tau = forms.FloatField(label='tau_bath',initial=1.0,
285 help_text='coupling to the thermal bath (Berendsen)')
286 md_scal_fric = forms.FloatField(label='scal_froc',initial=0.02,
287 help_text='scaling of the friction coefficients (Langevin)')
288 md_respa = forms.BooleanField(required=False,initial=True,label='RESPA')
289 md_mdpdb = forms.BooleanField(required=False,label='trajectory as PDB')
291 boxx = forms.FloatField(label='Box X',initial=1000.0,
292 help_text='box x dimension')
293 boxy = forms.FloatField(label='Box Y',initial=1000.0,
294 help_text='box y dimension')
295 boxz = forms.FloatField(label='Box Z',initial=1000.0,
296 help_text='box z dimension')
299 cleaned_data = super(TaskForm_md_a, self).clean()
301 md_start = cleaned_data.get("md_start")
302 file1 = cleaned_data.get("file1")
303 pdbid = cleaned_data.get("pdbid")
304 md_seq = cleaned_data.get("md_seq")
305 md_pdbref = cleaned_data.get("md_pdbref")
306 md_2d = cleaned_data.get("md_2d")
308 if md_start == 'pdbstart' and not (file1 or pdbid):
309 msg = 'pdbstart with no PDB file or code'
310 self.add_error('file1', msg)
312 if md_pdbref and not (file1 or pdbid):
313 msg = 'pdbref with no PDB file or code'
314 self.add_error('file1', msg)
317 if md_start != 'pdbstart' and not md_pdbref and not md_seq:
318 msg = 'extended/random chain with no sequence'
319 self.add_error('md_seq', msg)
322 msg=pdb_code_chain(pdbid)
324 self.add_error('pdbid',msg)
327 msg=pdb_missing_res_chain(file1,'')
329 self.add_error('file1',msg)
334 self.add_error('md_2d',msg)
336 class TaskForm_remd(forms.Form):
337 name = forms.CharField(max_length=20)
339 md_start = forms.ChoiceField(choices=MD_START,widget=forms.RadioSelect,
340 label='starting structure',initial='extconf')
341 md_seq = forms.CharField(label='Sequence',
342 help_text='aminoacid sequence using one letter code<br>'+
343 'field is ignored when uploading starting/reference PDB file',
345 widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
346 file1 = forms.FileField(label='Upload a PDB file',required=False,
347 help_text='starting structure for pdbstart/reference structure')
348 pdbid = forms.CharField(min_length=4,max_length=6,required=False,
349 widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
350 label='or PDB code (:chain)')
351 md_pdbref = forms.BooleanField(required=False,label='PDB reference structure')
352 md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
353 help_text='total number of steps')
354 md_seed = forms.IntegerField(label='SEED',initial=-39912345,
355 help_text='seed for random number generator')
358 cleaned_data = super(TaskForm_remd, self).clean()
360 md_start = cleaned_data.get("md_start")
361 file1 = cleaned_data.get("file1")
362 pdbid = cleaned_data.get("pdbid")
363 md_seq = cleaned_data.get("md_seq")
364 md_pdbref = cleaned_data.get("md_pdbref")
366 if md_start == 'pdbstart' and not (file1 or pdbid):
367 msg = 'pdbstart with no PDB file or code'
368 self.add_error('file1', msg)
370 if md_pdbref and not (file1 or pdbid):
371 msg = 'pdbref with no PDB file or code'
372 self.add_error('file1', msg)
374 if md_start != 'pdbstart' and not md_pdbref and not md_seq:
375 msg = 'extended/random chain with no sequence'
376 self.add_error('md_seq', msg)
379 msg=pdb_code_chain(pdbid)
381 self.add_error('pdbid',msg)
384 msg=pdb_missing_res_chain(file1,'')
386 self.add_error('file1',msg)
389 class TaskForm_remd_a(forms.Form):
390 name = forms.CharField(max_length=20)
392 unres_ff = forms.ChoiceField(choices=FF_CHOICE,widget=forms.RadioSelect,
393 label='Force Field',initial='FF2')
394 md_start = forms.ChoiceField(choices=MD_START,widget=forms.RadioSelect,
395 label='starting structure',initial='extconf')
396 md_seq = forms.CharField(label='Sequence',
397 help_text='aminoacid sequence using one letter code<br>'+
398 'field is ignored when uploading starting/reference PDB file',
400 widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
401 md_2d = forms.CharField(label='Secondary structure restraints',
402 help_text='single letter code: H - helix, E - extended/beta, C or - no restraints',
404 widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
405 file1 = forms.FileField(label='Upload a PDB file',required=False,
406 help_text='starting structure for pdbstart/reference structure')
407 pdbid = forms.CharField(min_length=4,max_length=6,required=False,
408 widget=forms.TextInput(attrs={'size':6, 'maxlength':6, 'title':'PDB code or PDB code:chain id'}),
409 label='or PDB code (:chain)')
410 md_pdbref = forms.BooleanField(required=False,label='PDB reference structure')
411 md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
412 help_text='total number of steps')
413 md_seed = forms.IntegerField(label='SEED',initial=-39912345,
414 help_text='seed for random number generator')
415 md_ntwe = forms.IntegerField(label='NTWE',initial=1000,
416 help_text='write statfile every ntwe steps')
417 md_dt = forms.FloatField(label='DT',initial=0.2,
418 help_text='time step [mtu = 48.9 fs]')
419 md_lang = forms.ChoiceField(choices=MD_LANG,label='thermostat')
420 md_tau = forms.FloatField(label='tau_bath',initial=1.0,
421 help_text='coupling to the thermal bath (Berendsen)')
422 md_scal_fric = forms.FloatField(label='scal_froc',initial=0.02,
423 help_text='scaling of the friction coefficients (Langevin)')
424 remd_nrep = forms.IntegerField(label='NREP',initial=8,
425 help_text='number of replicas')
426 remd_nstex = forms.IntegerField(label='NSTEX',initial=1000,
427 help_text='exchange and write trajectory every nstex steps')
428 md_ntwx = forms.IntegerField(label='NTWX',initial=1000,
429 help_text='write trajectory every ntwx steps')
430 remd_cluter_temp = forms.FloatField(label='TEMPER',
431 help_text='temperature for cluster analysis',initial=280)
432 # remd_traj1file = forms.BooleanField(required=False,label='single trajectory file',initial='true')
433 # remd_rest1file = forms.BooleanField(required=False,label='single restart file',initial='true')
435 md_respa = forms.BooleanField(required=False,initial=True,label='RESPA')
437 boxx = forms.FloatField(label='Box X',initial=1000.0,
438 help_text='box x dimension')
439 boxy = forms.FloatField(label='Box Y',initial=1000.0,
440 help_text='box y dimension')
441 boxz = forms.FloatField(label='Box Z',initial=1000.0,
442 help_text='box z dimension')
445 wsaxs = forms.FloatField(label='SAXS weight',initial=100.0,
446 help_text='weight for SAXS restraint term')
447 scal_rad = forms.FloatField(label='Scal_rad (SAXS)',initial=1.0,
448 help_text='downscaling factor of residue radii used in SAXS restraints')
449 saxs_data = forms.CharField(label='P(r) SAXS data',
450 help_text='distance distribution from SAXS, two columns: r and P(r)',
452 widget=forms.Textarea(attrs={'cols': 25, 'rows': 20}))
456 cleaned_data = super(TaskForm_remd_a, self).clean()
458 md_start = cleaned_data.get("md_start")
459 file1 = cleaned_data.get("file1")
460 pdbid = cleaned_data.get("pdbid")
461 md_seq = cleaned_data.get("md_seq")
462 md_pdbref = cleaned_data.get("md_pdbref")
463 md_2d = cleaned_data.get("md_2d")
465 if md_start == 'pdbstart' and not (file1 or pdbid):
466 msg = 'pdbstart with no PDB file or code'
467 self.add_error('file1', msg)
469 if md_pdbref and not (file1 or pdbid):
470 msg = 'pdbref with no PDB file or code'
471 self.add_error('file1', msg)
474 if md_start != 'pdbstart' and not md_pdbref and not md_seq:
475 msg = 'extended/random chain with no sequence'
476 self.add_error('md_seq', msg)
479 msg=pdb_code_chain(pdbid)
481 self.add_error('pdbid',msg)
484 msg=pdb_missing_res_chain(file1,'')
486 self.add_error('file1',msg)
491 self.add_error('md_2d',msg)
495 class TaskForm_list(forms.Form):
496 name = forms.CharField(max_length=20,disabled=True,required=False)
497 nrep = forms.IntegerField(disabled=True,required=False,label='NREP')
499 def __init__(self, count, *args, **kwargs):
500 super(TaskForm_list, self).__init__(*args, **kwargs)
502 self.fields['temperatures'] = MultiExampleField(self.count)
503 self.fields['multiplexing'] = MultiExampleField(self.count)