de8d085a8a90e3c2eec7d04c4b9b34ac03b9502e
[django_unres.git] / django_simple / todo / views.py
1 from django.contrib.auth.decorators import login_required
2 from django.shortcuts import redirect, render, get_object_or_404
3 from django.contrib.auth.models import User
4 from .forms import *
5 from .models import Task
6 import datetime
7 import os
8 import subprocess
9 import json
10 from lazysignup.decorators import allow_lazy_user
11 from lazysignup.utils import is_lazy_user
12
13 res_codes = [
14                 # 20 canonical amino acids
15                 ('CYS', 'C'), ('ASP', 'D'), ('SER', 'S'), ('GLN', 'Q'),
16                 ('LYS', 'K'), ('ILE', 'I'), ('PRO', 'P'), ('THR', 'T'),
17                 ('PHE', 'F'), ('ASN', 'N'), ('GLY', 'G'), ('HIS', 'H'),
18                 ('LEU', 'L'), ('ARG', 'R'), ('TRP', 'W'), ('ALA', 'A'),
19                 ('VAL', 'V'), ('GLU', 'E'), ('TYR', 'Y'), ('MET', 'M'),
20                 ('HSD', 'H'),('HSE', 'H'),('HSP', 'H'),
21                 ('HIE', 'H'), ('HID', 'H'),('HIP', 'H'),
22                 ('CYX', 'C'),
23                ]
24
25 three_to_one = dict(res_codes)
26
27 def seq_add_x(sequence):
28     if sequence[0] != 'G':
29         sequence='X'+sequence
30     if sequence[-1] != 'G':
31         sequence=sequence+'X'
32     set ='CDSQKIPTFNGHLRWAVEYMX'
33     sequence = ''.join([c for c in sequence if c in set])
34
35     return(sequence)    
36
37 def from_pdb(file):
38     sequence = []
39     ssbond = []
40     ssbond_ch = []
41     ires = []
42     chain_start = {}
43     chain_end = {}
44     unres_shift = {}
45     chain=[]
46     ichain=0
47     newchain = True
48     
49     for line in file:
50             if line[0:6] == 'COMPND' and line[11:17] == 'CHAIN:':
51               tmp=line[18:]
52               chain_=tmp.split(', ')
53               chain_[-1]=chain_[-1][0]
54               chain.extend(chain_)
55     
56             if line[0:6] == 'ATOM  ' and line[13:15] == 'CA':
57               aa = three_to_one.get(line[17:20])
58               i = int(line[22:26])
59               if newchain or i!=ires[-1]:
60                 sequence.append(aa)
61                 ires.append(i)
62                 if newchain:
63                  if len(chain)>0:
64                   chain_start[chain[ichain]]=i
65                  newchain = False
66             if line[0:3] == 'TER':
67               sequence.append('XX')
68               if len(chain)>0:
69                chain_end[chain[ichain]]=i
70               ichain=ichain+1
71               newchain = True
72             if line[0:6] == 'SSBOND':
73               b=[]
74               b.append(int(line[17:21]))
75               b.append(int(line[31:35]))
76               ssbond.append(b)
77               c = []
78               c.append((line[15:16]))
79               c.append((line[29:30]))
80               ssbond_ch.append(c)                                                                      
81             if line[0:3] == 'END':
82               break
83     while sequence[-1] == 'XX':
84             del sequence[-1]
85     if sequence[0] != 'G':
86             sequence.insert(0,'X')
87             ssbond=[ [e[0]+1,e[1]+1] for e in ssbond]
88     if sequence[-1] != 'G':
89             sequence.append('X')
90     seq=''.join(sequence)
91 #    if ires[0] != 1:
92 #            ssbond=[ [e[0]-ires[0]+1,e[1]-ires[0]+1] for e in ssbond]
93     i=0
94     for c in chain:
95       unres_shift[c]=i+chain_start[c]
96       i=i-(chain_end[c]-chain_start[c])-3
97     ssbond=[ [e[0]-unres_shift[c[0]]+1,e[1]-unres_shift[c[1]]+1] for e,c in zip(ssbond,ssbond_ch)]     
98
99     return seq,json.dumps(ssbond)
100
101
102 @login_required
103 def index(request):
104     user = request.user
105     tasks = Task.objects.filter(owner=user).order_by('-created_date')
106     variable = ''
107     return render(request, "index.html", {
108             'tasks': tasks
109         })
110
111 @allow_lazy_user
112 def add(request):
113     if request.method == 'POST':
114         form = TaskForm(request.POST)
115         if form.is_valid():
116             name = form.cleaned_data["name"]
117             user = request.user
118             task = Task(name=name,owner=user,ready=False)
119             task.save()
120             return redirect('add_min',task_id=task.id)
121     return redirect('/')
122
123 @login_required
124 def add_min(request,task_id):
125     task = get_object_or_404(Task, id=task_id)
126     if request.method == 'POST':
127         form = TaskForm_min(request.POST,request.FILES)
128         if form.is_valid():
129              task.name=form.cleaned_data["name"]
130              task.type="min"
131              task.myfile1=form.cleaned_data["file1"]
132
133              seq,task.ssbond=from_pdb(task.myfile1)
134              task.md_seq=""
135              for i in range(0,len(seq),40):
136                     task.md_seq=task.md_seq+seq[i:i+40]+" "
137
138              task.ready=True
139              basename = str(task.owner)
140              suffix = datetime.datetime.now().strftime("%y%m%d_%H%M%S")
141              task.jobdirname = "_".join([basename, suffix])
142              
143              task.save()
144              return redirect('/')
145     else:
146         data= {'name':task.name}
147         form = TaskForm_min(initial=data)
148     p_type='minimization'
149     basic_adv=True    
150     return render(request, 'edit.html', {'form': form, 'task':task, 'basic_adv':basic_adv, 'p_type':p_type})
151
152 @login_required
153 def add_min_a(request,task_id):
154     task = get_object_or_404(Task, id=task_id)
155     if request.method == 'POST':
156         form = TaskForm_min_a(request.POST,request.FILES)
157         if form.is_valid():
158              task.name=form.cleaned_data["name"]
159              task.type="min"
160              task.min_choice=form.cleaned_data["min_choice"]
161              task.min_overlap=form.cleaned_data["min_overlap"]
162              task.min_searchsc=form.cleaned_data["min_searchsc"]
163              task.min_maxmin=form.cleaned_data["min_maxmin"]
164              task.min_maxfun=form.cleaned_data["min_maxfun"]
165              task.min_pdbout=form.cleaned_data["min_pdbout"]
166              task.myfile1=form.cleaned_data["file1"]
167              task.min_unres_pdb=form.cleaned_data["min_unres_pdb"]
168              task.unres_ff=form.cleaned_data["unres_ff"]
169              task.boxx=form.cleaned_data["boxx"]
170              task.boxy=form.cleaned_data["boxy"]             
171              task.boxz=form.cleaned_data["boxz"]             
172
173              seq,task.ssbond=from_pdb(task.myfile1)
174              task.md_seq=""
175              for i in range(0,len(seq),40):
176                 task.md_seq=task.md_seq+seq[i:i+40]+" "
177                                                            
178
179              task.ready=True
180              basename = str(task.owner)
181              suffix = datetime.datetime.now().strftime("%y%m%d_%H%M%S")
182              task.jobdirname = "_".join([basename, suffix])
183              
184              task.save()
185              return redirect('/')
186     else:
187         data= {'name':task.name}
188         form = TaskForm_min_a(initial=data)
189     basic_adv=False
190     p_type='minimization - advanced options'
191     return render(request, 'edit.html', {'form': form, 'task':task, 'basic_adv':basic_adv, 'p_type':p_type})
192
193 @login_required
194 def add_md(request,task_id):
195     task = get_object_or_404(Task, id=task_id)
196     if request.method == 'POST':
197         form = TaskForm_md(request.POST,request.FILES)
198         if form.is_valid():
199              task.name=form.cleaned_data["name"]
200              task.type="md"
201              task.md_seed=form.cleaned_data["md_seed"]
202              task.md_start=form.cleaned_data["md_start"]
203              task.md_temp=form.cleaned_data["md_temp"]
204              task.md_nstep=form.cleaned_data["md_nstep"]
205              
206              task.myfile1=form.cleaned_data["file1"]
207              task.md_pdbref=form.cleaned_data["md_pdbref"]             
208
209              task.md_seq=""
210              if task.md_start == "pdbstart" or task.md_pdbref:
211                seq,task.ssbond=from_pdb(task.myfile1)
212              else:
213                seq=seq_add_x(form.cleaned_data["md_seq"])
214                        
215              for i in range(0,len(seq),40):
216                 task.md_seq=task.md_seq+seq[i:i+40]+" "
217              
218              if task.md_start != "pdbstart":
219                 task.ssbond=''
220
221              task.ready=True
222              basename = str(task.owner)
223              suffix = datetime.datetime.now().strftime("%y%m%d_%H%M%S")
224              task.jobdirname = "_".join([basename, suffix])
225              
226              task.save()
227              if is_lazy_user(request.user):
228               return render(request, "details.html",{'task':task})
229              else:
230               return redirect('/')
231     else:
232         data= {'name':task.name}
233         form = TaskForm_md(initial=data)
234     basic_adv=True
235     p_type='molecular dynamics'
236     return render(request, 'edit.html', {'form': form, 'task':task, 'basic_adv':basic_adv, 'p_type':p_type})
237
238 @login_required
239 def add_md_a(request,task_id):
240     task = get_object_or_404(Task, id=task_id)
241     if request.method == 'POST':
242         form = TaskForm_md_a(request.POST,request.FILES)
243         if form.is_valid():
244              task.name=form.cleaned_data["name"]
245              task.type="md"
246
247              task.myfile1=form.cleaned_data["file1"]
248              task.md_start=form.cleaned_data["md_start"]
249              task.md_pdbref=form.cleaned_data["md_pdbref"]             
250
251              task.md_seq=""
252              if task.md_start == "pdbstart" or task.md_pdbref:
253                seq,task.ssbond=from_pdb(task.myfile1)
254              else:
255                seq=seq_add_x(form.cleaned_data["md_seq"])
256              for i in range(0,len(seq),40):
257                 task.md_seq=task.md_seq+seq[i:i+40]+" "
258
259              if task.md_start != "pdbstart":
260                 task.ssbond=''
261
262              task.md_seed=form.cleaned_data["md_seed"]
263
264              task.md_temp=form.cleaned_data["md_temp"]
265              task.md_nstep=form.cleaned_data["md_nstep"]
266              task.md_ntwe=form.cleaned_data["md_ntwe"]
267              task.md_ntwx=form.cleaned_data["md_ntwx"]
268              task.md_dt=form.cleaned_data["md_dt"]
269              task.md_lang=form.cleaned_data["md_lang"]
270              task.md_tau=form.cleaned_data["md_tau"]
271              task.md_scal_fric=form.cleaned_data["md_scal_fric"]
272              task.md_mdpdb=form.cleaned_data["md_mdpdb"]
273              task.unres_ff=form.cleaned_data["unres_ff"]
274              task.boxx=form.cleaned_data["boxx"]
275              task.boxy=form.cleaned_data["boxy"]             
276              task.boxz=form.cleaned_data["boxz"]             
277
278              
279              task.ready=True
280              basename = str(task.owner)
281              suffix = datetime.datetime.now().strftime("%y%m%d_%H%M%S")
282              task.jobdirname = "_".join([basename, suffix])
283              
284              task.save()
285              return redirect('/')
286     else:
287         data= {'name':task.name}
288         form = TaskForm_md_a(initial=data)
289     basic_adv=False
290     p_type='molecular dynamics - advanced options'
291     return render(request, 'edit.html', {'form': form, 'task':task, 'basic_adv':basic_adv, 'p_type':p_type})
292
293 @login_required
294 def add_remd(request,task_id):
295     task = get_object_or_404(Task, id=task_id)
296     if request.method == 'POST':
297         form = TaskForm_remd(request.POST,request.FILES)
298         if form.is_valid():
299              task.name=form.cleaned_data["name"]
300              task.type="remd"
301              task.md_start=form.cleaned_data["md_start"]
302              task.myfile1=form.cleaned_data["file1"]
303              task.md_pdbref=form.cleaned_data["md_pdbref"]
304              task.md_ntwx=task.remd_nstex 
305
306              task.md_seq=""
307              if task.md_start == "pdbstart" or task.md_pdbref:
308                seq,task.ssbond=from_pdb(task.myfile1)
309              else:
310                seq=seq_add_x(form.cleaned_data["md_seq"])
311              for i in range(0,len(seq),40):
312                 task.md_seq=task.md_seq+seq[i:i+40]+" "
313
314              if task.md_start != "pdbstart":
315                 task.ssbond=''
316
317              task.md_seed=form.cleaned_data["md_seed"]
318
319              task.md_nstep=form.cleaned_data["md_nstep"]
320
321
322              task.ready=True
323              
324              basename = str(task.owner)
325              suffix = datetime.datetime.now().strftime("%y%m%d_%H%M%S")
326              task.jobdirname = "_".join([basename, suffix])
327              
328              task.save()
329              return redirect('/')
330     else:
331         data= {'name':task.name}
332         form = TaskForm_remd(initial=data)
333     basic_adv=True
334     p_type='replica exchange molecular dynamics'
335     return render(request, 'edit.html', {'form': form, 'task':task, 'basic_adv':basic_adv, 'p_type':p_type})
336
337 @login_required
338 def add_remd_a(request,task_id):
339     task = get_object_or_404(Task, id=task_id)
340     if request.method == 'POST':
341         form = TaskForm_remd_a(request.POST,request.FILES)
342         if form.is_valid():
343              task.name=form.cleaned_data["name"]
344              task.type="remd"
345
346              task.myfile1=form.cleaned_data["file1"]
347              task.md_start=form.cleaned_data["md_start"]  
348              task.md_pdbref=form.cleaned_data["md_pdbref"]                        
349
350              task.md_seq=""
351              if task.md_start == "pdbstart" or task.md_pdbref:
352                seq,task.ssbond=from_pdb(task.myfile1)
353              else:
354                seq=seq_add_x(form.cleaned_data["md_seq"])
355              for i in range(0,len(seq),40):
356                 task.md_seq=task.md_seq+seq[i:i+40]+" "
357
358              if task.md_start != "pdbstart":
359                 task.ssbond=''
360
361              task.md_seed=form.cleaned_data["md_seed"]
362              task.md_nstep=form.cleaned_data["md_nstep"]
363              task.md_dt=form.cleaned_data["md_dt"]
364              task.md_lang=form.cleaned_data["md_lang"]
365              task.md_tau=form.cleaned_data["md_tau"]
366              task.md_scal_fric=form.cleaned_data["md_scal_fric"]
367              task.remd_nrep=form.cleaned_data["remd_nrep"]
368              task.remd_nstex=form.cleaned_data["remd_nstex"]
369              task.md_ntwx=form.cleaned_data["md_ntwx"]             
370              task.md_ntwe=form.cleaned_data["md_ntwe"]
371 #             task.remd_traj1file=form.cleaned_data["remd_traj1file"]
372 #             task.remd_rest1file=form.cleaned_data["remd_rest1file"]
373
374              task.boxx=form.cleaned_data["boxx"]
375              task.boxy=form.cleaned_data["boxy"]             
376              task.boxz=form.cleaned_data["boxz"]             
377
378
379              task.remd_cluter_temp=form.cleaned_data["remd_cluter_temp"]
380              task.unres_ff=form.cleaned_data["unres_ff"]
381              
382              basename = str(task.owner)
383              suffix = datetime.datetime.now().strftime("%y%m%d_%H%M%S")
384              task.jobdirname = "_".join([basename, suffix])
385              
386              task.save()
387              return redirect('addmlist',task_id=task.id)
388     else:
389         data= {'name':task.name}
390         form = TaskForm_remd_a(initial=data)
391     basic_adv=False
392     p_type='replica exchange molecular dynamics - advanced options'
393     return render(request, 'edit.html', {'form': form, 'task':task, 'basic_adv':basic_adv, 'p_type':p_type})
394
395 @login_required
396 def addmlist(request,task_id):
397     task = get_object_or_404(Task, id=task_id)
398     if request.method == 'POST':
399         form = TaskForm_list(task.remd_nrep,request.POST)
400         if form.is_valid():
401              task.remd_multi_t=form.cleaned_data["temperatures"]
402              task.remd_multi_m=form.cleaned_data["multiplexing"]             
403              task.ready=True
404              
405              task.save()
406              return redirect('/')
407     else:
408       if task.unres_ff == 'E0LL2Y':
409         data= {'name':task.name,'nrep':task.remd_nrep,'multiplexing':
410         '["1", "1", "1", "1", "1", "1", "1", "1"]',
411         'temperatures':
412         '["270", "280", "290", "300", "310", "320", "330", "345"]'
413         }
414       else: 
415         data= {'name':task.name,'nrep':task.remd_nrep,'multiplexing':
416         '["1", "1", "1", "1", "1", "1", "1", "1"]',
417         'temperatures':
418         '["250", "260", "270", "280", "290", "300", "315", "330"]'
419         }
420       
421       form = TaskForm_list(task.remd_nrep,initial=data)
422     p_type='replica exchange molecular dynamics - advanced options'
423     return render(request, 'edit_lista.html', {'form': form, 'task':task, 'p_type':p_type})
424
425 def details(request,task_id):
426     task = get_object_or_404(Task, id=task_id)
427     return render(request, "details.html",{'task':task})
428
429 @login_required
430 def delete(request, task_id):
431     Task.objects.get(id=task_id).delete()
432     return redirect('/')
433
434 @login_required
435 def refresh_done(request):
436     user = request.user
437     tasks = Task.objects.filter(owner=user).order_by('-created_date')
438     for task in tasks:
439       if os.path.isfile(task.jobdirname+'/finished') and not task.done:
440          task.done=True
441
442          with open(task.jobdirname+'/file.out_GB000', 'r') as f:
443
444            if task.type=='min' or task.type=='md':
445              text=""
446              for line in f:
447                if 'ETOT' in line:
448                   task.etot=line.split()[1]
449
450                if 'RMS deviation' in line:
451                   text=text+line
452                   i=1
453                   for line1 in f:
454                      text=text+line1
455                      i+=1
456                      if i>6:
457                        break
458                if 'Total wall' in line:
459                   text=text+line
460                   
461            elif task.type=='remd':
462              j=0
463              text="Acceptance for replica exchanges\n"
464              for line in f:
465                         
466                if 'ACC' in line:
467                     j+=1
468                     text=text+line
469                     if j==task.remd_nrep:
470                        j=1
471                        text="Acceptance for replica exchanges\n"+line
472
473                if 'Total wall' in line:
474                   text=text+line
475                        
476          task.results_text=text
477
478
479          if task.md_pdbref and task.type=='remd':
480          
481           for i in range(1,6):
482            try:
483             with open(task.jobdirname+'/file_wham_T'+str(int(task.remd_cluter_temp))+'K_000'+str(i)+'.pdb', 'r') as f:
484                  line=f.readline()
485                  if i==1:
486                      task.remd_model1=' '.join(line.split()[-6:])
487                  elif i==2:
488                      task.remd_model2=' '.join(line.split()[-6:])
489                  elif i==3:
490                      task.remd_model3=' '.join(line.split()[-6:])
491                  elif i==4:
492                      task.remd_model4=' '.join(line.split()[-6:])
493                  elif i==5:
494                      task.remd_model5=' '.join(line.split()[-6:])
495            except EnvironmentError:
496             print 'file_wham_T*pdb open error'
497           for i in range(1,6):
498             with open(task.jobdirname+'/tmscore'+str(i)+'.out', 'r') as f:
499                text=''
500                for line in f:
501                  if 'RMSD of  the common residues=' in line:
502                    text=' RMSD='+line.split()[5]
503                  if 'TM-score    =' in line:
504                    text=text+' TMscore='+line.split()[2]
505                  if 'GDT-TS-score=' in line:
506                    text=text+' GDT_TS='+line.split()[1]
507                     
508                if i==1:
509                      task.remd_model1=task.remd_model1+text
510                elif i==2:
511                      task.remd_model2=task.remd_model2+text
512                elif i==3:
513                      task.remd_model3=task.remd_model3+text
514                elif i==4:
515                      task.remd_model4=task.remd_model4+text
516                elif i==5:
517                      task.remd_model5=task.remd_model5+text
518
519
520
521          if task.type=='remd':  
522           with open(task.jobdirname+'/file_cluster_clust.out_000', 'r') as f:
523
524            for line in f:
525              if 'sumprob' in line:
526                 i=0
527                 for line1 in f:
528                   i+=1
529                   if i>6:
530                        break
531                   if i==1:
532                      task.remd_model1=task.remd_model1+' Cluster1 probability= '+line1.split()[2]
533                   elif i==2:
534                      task.remd_model2=task.remd_model2+' Cluster2 probability= '+line1.split()[2]
535                   elif i==3:
536                      task.remd_model3=task.remd_model3+' Cluster3 probability= '+line1.split()[2]
537                   elif i==4:
538                      task.remd_model4=task.remd_model4+' Cluster4 probability= '+line1.split()[2]
539                   elif i==5:
540                      task.remd_model5=task.remd_model5+' Cluster5 probability= '+line1.split()[2]
541                      
542          
543
544          task.save()
545       elif os.path.isfile(task.jobdirname+'/file_GB000.stat') and not task.done:
546          if (task.type=='min'):
547            task.running =1
548          else:
549            with open(task.jobdirname+'/file_GB000.stat', 'r') as f:
550               line=''
551               for line in f:
552                 pass
553               if line != '':
554                 last = line.split()[0]
555               else:
556                 last = 0
557            task.running=int(1+int(last)*100.0/task.md_nstep)
558            if task.running>100:
559              task.running=100
560          task.save()
561
562     proc = subprocess.Popen('/opt/torque/bin/qstat', stdout=subprocess.PIPE)
563     njob=0
564     nq=0
565     for line in proc.stdout:
566       if 'piasek4' in line:
567         if line.split()[1]=='test_server':
568           njob+=1
569           if line.split()[-2]=='Q':
570             nq+=1
571     variable='Idle jobs='+str(nq)+' Total jobs='+str(njob)
572
573     if is_lazy_user(request.user):
574      return redirect('/details/'+str(task.id)+'/')
575     else:
576      return render(request, "index.html", {
577                 'tasks': tasks ,
578                 'variable' : variable
579                         })
580     
581 #   return redirect('/')