missing residues error for pdb file or id
[django_unres.git] / django_simple / todo / forms.py
index 7ca4ce3..8fda381 100644 (file)
@@ -5,6 +5,31 @@ from .models import MD_START
 from .models import MD_LANG
 from .models import FF_CHOICE
 import json
+import urllib
+
+def pdb_missing_res(file):
+   msg=''
+   newchain = True
+   ires=[]
+   for line in file:
+      if line[0:6] == 'ATOM  ' and line[13:15] == 'CA':
+               i = int(line[22:26])
+               if ires and i==ires[-1]:
+                 continue
+               if newchain or i==ires[-1]+1:
+                 ires.append(i)
+                 newchain = False
+               else:
+                 msg = 'chain breaks between residues '+\
+                   str(ires[-1])+' and '+str(i)+\
+                   ', server cannot add missing residues to PDB file'
+                 break
+      if line[0:3] == 'TER':
+               newchain = True
+      if line[0:3] == 'END':
+               break
+   
+   return(msg)
 
 class MultiWidgetBasic(forms.MultiWidget):
     def __init__(self, count, attrs=None):
@@ -43,9 +68,38 @@ class TaskForm(forms.Form):
 
 class TaskForm_min(forms.Form):
      name = forms.CharField(max_length=20)
-     file1 = forms.FileField(label='Upload a PDB file',
-     help_text='continuous (without breaks) protein chains,use TER to divide chains')
-                        
+     file1 = forms.FileField(label='Upload a PDB file',required=False,
+      help_text='continuous (without breaks) protein chains,use TER to divide chains')
+     pdbid = forms.CharField(min_length=4,max_length=4,required=False,
+      widget=forms.TextInput(attrs={'size':4, 'maxlength':4, 'title':'PDB code'}),
+      label='or PDB code')                   
+
+     def clean(self):
+             cleaned_data = super(TaskForm_min, self).clean()
+
+             pdbid = cleaned_data.get("pdbid") 
+             file1 = cleaned_data.get("file1")
+              
+             if not pdbid and not file1:
+                msg = 'provide pdb file or pdb code'
+                self.add_error('file1', msg)
+              
+             if pdbid:
+               test=urllib.urlopen('http://files.rcsb.org/download/'+pdbid+'.pdb')     
+               if test.code != 200:
+                 msg = 'wrong pdb code'
+                 self.add_error('pdbid', msg)
+               else:
+                 msg=pdb_missing_res(test)
+                 if msg != '':
+                   self.add_error('pdbid',msg)
+               test.close()
+               
+             if file1:
+                 msg=pdb_missing_res(file1)
+                 if msg != '':
+                   self.add_error('file1',msg)
+
             
 class TaskForm_min_a(forms.Form):
      name = forms.CharField(max_length=20)
@@ -59,8 +113,11 @@ class TaskForm_min_a(forms.Form):
                   help_text='maximum number of iterations')
      min_maxfun = forms.IntegerField(label='MAXFUN',initial=15000,
                   help_text='maximum number of function evaluations')
-     file1 = forms.FileField(label='Upload a PDB file',
+     file1 = forms.FileField(label='Upload a PDB file',required=False,
         help_text='continuous (without breaks) protein chains,use TER to divide chains')
+     pdbid = forms.CharField(min_length=4,max_length=4,required=False,
+      widget=forms.TextInput(attrs={'size':4, 'maxlength':4, 'title':'PDB code'}),
+      label='or PDB code')                   
 
      min_unres_pdb = forms.BooleanField(required=False,label='uploaded input unres PDB',
                   help_text='(CA and CB atoms only, CB represents SC in UNRES)')
@@ -72,6 +129,32 @@ class TaskForm_min_a(forms.Form):
      boxz = forms.FloatField(label='Box Z',initial=1000.0,
                        help_text='box z dimension')
 
+     def clean(self):
+             cleaned_data = super(TaskForm_min_a, self).clean()
+
+             pdbid = cleaned_data.get("pdbid") 
+             file1 = cleaned_data.get("file1")
+              
+             if not pdbid and not file1:
+                msg = 'provide pdb file or pdb code'
+                self.add_error('file1', msg)
+              
+             if pdbid:
+               test=urllib.urlopen('http://files.rcsb.org/download/'+pdbid+'.pdb')     
+               if test.code != 200:
+                 msg = 'wrong pdb code'
+                 self.add_error('pdbid', msg)
+               else:
+                 msg=pdb_missing_res(test)
+                 if msg != '':
+                   self.add_error('pdbid',msg)
+               test.close()
+               
+             if file1:
+                 msg=pdb_missing_res(file1)
+                 if msg != '':
+                   self.add_error('file1',msg)
+
 
 class TaskForm_md(forms.Form):
      name = forms.CharField(max_length=20)
@@ -85,6 +168,9 @@ class TaskForm_md(forms.Form):
                      widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
      file1 = forms.FileField(label='Upload a PDB file',required=False,
                   help_text='starting structure for pdbstart/reference structure')
+     pdbid = forms.CharField(min_length=4,max_length=4,required=False,
+      widget=forms.TextInput(attrs={'size':4, 'maxlength':4, 'title':'PDB code'}),
+      label='or PDB code')                   
      md_pdbref = forms.BooleanField(required=False,label='PDB reference structure')
      md_temp = forms.FloatField(label='temperature',initial=300,
                   help_text='bath temperature')
@@ -98,15 +184,16 @@ class TaskForm_md(forms.Form):
 
              md_start = cleaned_data.get("md_start") 
              file1 = cleaned_data.get("file1")
+             pdbid = cleaned_data.get("pdbid")
              md_seq = cleaned_data.get("md_seq")
              md_pdbref = cleaned_data.get("md_pdbref")
               
-             if md_start == 'pdbstart' and not file1:
-                msg = 'pdbstart with no PDB file'
+             if md_start == 'pdbstart' and not (file1 or pdbid):
+                msg = 'pdbstart with no PDB file or code'
                 self.add_error('file1', msg)
 
-             if md_pdbref and not file1:
-                msg = 'pdbref with no PDB file'
+             if md_pdbref and not (file1 or pdbid):
+                msg = 'pdbref with no PDB file or code'
                 self.add_error('file1', msg)
 
 
@@ -114,6 +201,22 @@ class TaskForm_md(forms.Form):
                 msg = 'extended/random chain with no sequence'
                 self.add_error('md_seq', msg)
 
+             if pdbid:
+               test=urllib.urlopen('http://files.rcsb.org/download/'+pdbid+'.pdb')     
+               if test.code != 200:
+                 msg = 'wrong pdb code'
+                 self.add_error('pdbid', msg)
+               else:
+                 msg=pdb_missing_res(test)
+                 if msg != '':
+                   self.add_error('pdbid',msg)
+               test.close()
+               
+             if file1:
+                 msg=pdb_missing_res(file1)
+                 if msg != '':
+                   self.add_error('file1',msg)
+
                         
 class TaskForm_md_a(forms.Form):
      name = forms.CharField(max_length=20)
@@ -129,6 +232,9 @@ class TaskForm_md_a(forms.Form):
                      widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
      file1 = forms.FileField(label='Upload a PDB file',required=False,
                   help_text='starting structure for pdbstart/reference structure')
+     pdbid = forms.CharField(min_length=4,max_length=4,required=False,
+      widget=forms.TextInput(attrs={'size':4, 'maxlength':4, 'title':'PDB code'}),
+      label='or PDB code')                   
      md_pdbref = forms.BooleanField(required=False,label='PDB reference structure')                  
      md_temp = forms.FloatField(label='temperature',initial=300,
                   help_text='bath temperature')
@@ -162,15 +268,16 @@ class TaskForm_md_a(forms.Form):
 
              md_start = cleaned_data.get("md_start") 
              file1 = cleaned_data.get("file1")
+             pdbid = cleaned_data.get("pdbid")
              md_seq = cleaned_data.get("md_seq")
              md_pdbref = cleaned_data.get("md_pdbref")
               
-             if md_start == 'pdbstart' and not file1:
-                msg = 'pdbstart with no PDB file'
+             if md_start == 'pdbstart' and not (file1 or pdbid):
+                msg = 'pdbstart with no PDB file or code'
                 self.add_error('file1', msg)
 
-             if md_pdbref and not file1:
-                msg = 'pdbref with no PDB file'
+             if md_pdbref and not (file1 or pdbid):
+                msg = 'pdbref with no PDB file or code'
                 self.add_error('file1', msg)
 
 
@@ -178,6 +285,22 @@ class TaskForm_md_a(forms.Form):
                 msg = 'extended/random chain with no sequence'
                 self.add_error('md_seq', msg)
 
+             if pdbid:
+               test=urllib.urlopen('http://files.rcsb.org/download/'+pdbid+'.pdb')     
+               if test.code != 200:
+                 msg = 'wrong pdb code'
+                 self.add_error('pdbid', msg)
+               else:
+                 msg=pdb_missing_res(test)
+                 if msg != '':
+                   self.add_error('pdbid',msg)
+               test.close()
+               
+             if file1:
+                 msg=pdb_missing_res(file1)
+                 if msg != '':
+                   self.add_error('file1',msg)
+
 
 class TaskForm_remd(forms.Form):
      name = forms.CharField(max_length=20)
@@ -191,6 +314,9 @@ class TaskForm_remd(forms.Form):
                      widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
      file1 = forms.FileField(label='Upload a PDB file',required=False,
                   help_text='starting structure for pdbstart/reference structure')
+     pdbid = forms.CharField(min_length=4,max_length=4,required=False,
+      widget=forms.TextInput(attrs={'size':4, 'maxlength':4, 'title':'PDB code'}),
+      label='or PDB code')                   
      md_pdbref = forms.BooleanField(required=False,label='PDB reference structure')                  
      md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
                   help_text='total number of steps')
@@ -202,21 +328,38 @@ class TaskForm_remd(forms.Form):
 
              md_start = cleaned_data.get("md_start") 
              file1 = cleaned_data.get("file1")
+             pdbid = cleaned_data.get("pdbid")
              md_seq = cleaned_data.get("md_seq")
              md_pdbref = cleaned_data.get("md_pdbref")
               
-             if md_start == 'pdbstart' and not file1:
-                msg = 'pdbstart with no PDB file'
+             if md_start == 'pdbstart' and not (file1 or pdbid):
+                msg = 'pdbstart with no PDB file or code'
                 self.add_error('file1', msg)
 
-             if md_pdbref and not file1:
-                msg = 'pdbref with no PDB file'
+             if md_pdbref and not (file1 or pdbid):
+                msg = 'pdbref with no PDB file or code'
                 self.add_error('file1', msg)
 
              if md_start != 'pdbstart' and not md_pdbref and not md_seq:
                 msg = 'extended/random chain with no sequence'
                 self.add_error('md_seq', msg)
 
+             if pdbid:
+               test=urllib.urlopen('http://files.rcsb.org/download/'+pdbid+'.pdb')     
+               if test.code != 200:
+                 msg = 'wrong pdb code'
+                 self.add_error('pdbid', msg)
+               else:
+                 msg=pdb_missing_res(test)
+                 if msg != '':
+                   self.add_error('pdbid',msg)
+               test.close()
+               
+             if file1:
+                 msg=pdb_missing_res(file1)
+                 if msg != '':
+                   self.add_error('file1',msg)
+
                              
 class TaskForm_remd_a(forms.Form):
      name = forms.CharField(max_length=20)
@@ -232,6 +375,9 @@ class TaskForm_remd_a(forms.Form):
                      widget=forms.Textarea(attrs={'cols': 70, 'rows': 2}))
      file1 = forms.FileField(label='Upload a PDB file',required=False,
                   help_text='starting structure for pdbstart/reference structure')
+     pdbid = forms.CharField(min_length=4,max_length=4,required=False,
+      widget=forms.TextInput(attrs={'size':4, 'maxlength':4, 'title':'PDB code'}),
+      label='or PDB code')                   
      md_pdbref = forms.BooleanField(required=False,label='PDB reference structure')                  
      md_nstep = forms.IntegerField(label='NSTEP',initial=200000,
                   help_text='total number of steps')
@@ -270,15 +416,16 @@ class TaskForm_remd_a(forms.Form):
 
              md_start = cleaned_data.get("md_start") 
              file1 = cleaned_data.get("file1")
+             pdbid = cleaned_data.get("pdbid")
              md_seq = cleaned_data.get("md_seq")
              md_pdbref = cleaned_data.get("md_pdbref")
               
-             if md_start == 'pdbstart' and not file1:
-                msg = 'pdbstart with no PDB file'
+             if md_start == 'pdbstart' and not (file1 or pdbid):
+                msg = 'pdbstart with no PDB file or code'
                 self.add_error('file1', msg)
 
-             if md_pdbref and not file1:
-                msg = 'pdbref with no PDB file'
+             if md_pdbref and not (file1 or pdbid):
+                msg = 'pdbref with no PDB file or code'
                 self.add_error('file1', msg)
 
 
@@ -286,6 +433,23 @@ class TaskForm_remd_a(forms.Form):
                 msg = 'extended/random chain with no sequence'
                 self.add_error('md_seq', msg)
 
+             if pdbid:
+               test=urllib.urlopen('http://files.rcsb.org/download/'+pdbid+'.pdb')     
+               if test.code != 200:
+                 msg = 'wrong pdb code'
+                 self.add_error('pdbid', msg)
+               else:
+                 msg=pdb_missing_res(test)
+                 if msg != '':
+                   self.add_error('pdbid',msg)
+               test.close()
+               
+             if file1:
+                 msg=pdb_missing_res(file1)
+                 if msg != '':
+                   self.add_error('file1',msg)
+
+
 
 class TaskForm_list(forms.Form):
     name = forms.CharField(max_length=20,disabled=True,required=False)