43fac0eb336d352b8727fcc91cc01d7b7ab1e56f
[qcg-portal.git] / qcg / utils.py
1 # coding=utf-8
2 import os
3 import string
4 import random
5
6 from django.core.paginator import Paginator
7 from django.utils.formats import date_format
8 from django.utils.timezone import localtime
9 from pyqcg import QCG
10 from pyqcg.utils import Credential
11 from pyqcg.description import JobDescription
12
13 from filex.ftp import FTPOperation
14 from qcg import constants
15
16
17 from django.utils import encoding
18 # for Debugging
19 from pprint import pprint
20
21 def get_attributes(obj, attrs):
22     return {name: getattr(obj, name) for name in attrs if getattr(obj, name) is not None}
23
24
25 def username_from_dn(dn):
26     _, username = dn.rsplit('=', 1)
27
28     return username
29
30
31 def try_parse_int(s, default=None, base=10):
32     try:
33         return int(s, base)
34     except (TypeError, ValueError):
35         return default
36
37
38 def paginator_context(request, objects, per_page=constants.PER_PAGE):
39     paginator = Paginator(objects, per_page)
40
41     page_num = try_parse_int(request.GET.get('page'), 1)
42     if not (1 <= page_num <= paginator.num_pages):
43         page_num = 1
44
45     pages_range = range(max(2, min(page_num - 2, paginator.num_pages - 4)),
46                         min(max(page_num + 2, 5), paginator.num_pages) + 1)
47
48     return {'page': paginator.page(page_num), 'num_pages': paginator.num_pages, 'pages_range': pages_range}
49
50
51 def localtime_str(datetime):
52     return date_format(localtime(datetime), 'DATETIME_FORMAT')
53
54
55 def random_id(size=8, chars=string.ascii_uppercase + string.digits):
56     return ''.join(random.choice(chars) for _ in range(size))
57
58
59 def chunks(seq, size):
60     return (seq[pos:pos + size] for pos in xrange(0, len(seq), size))
61
62 def generate_md_inputfile(params):
63     md_input = list()
64     # Opis pliku wyjsciowego
65     opis=params['note'][:80]
66     md_input.append(encoding.smart_str(opis, encoding='ascii', errors='ignore'))
67     # Dane kontrolne obliczen
68     md_input.append('SEED=-3059743 PDBREFONE_LETTER MD EXTCONF RESCALE_MODE=2')
69     ctl_data='nstep='+str(params['nstep'])+' ntwe='+str(params['ntwe'])
70     ctl_data+=' ntwx='+str(params['ntwx'])+' dt='+str(params['dt'])+' damax='+str(params['damax'])+'lang=0 tbf'
71     md_input.append('{:<79}&'.format(ctl_data))
72     md_input.append('tau_bath=1.0 t_bath=300 reset_vel=10000 respa ntime_split=1 maxtime_split=512')
73     # Paramatry pól siłowych
74     if params['force_field'] == 'GAB':
75         # Wagi pola GAB
76         md_input.append('WLONG=1.35279 WSCP=1.59304 WELEC=0.71534 WBOND=1.00000 WANG=1.13873            &')
77         md_input.append('WSCLOC=0.16258 WTOR=1.98599 WTORD=1.57069 WCORRH=0.42887 WCORR5=0.00000        &')
78         md_input.append('WCORR6=0.00000 WEL_LOC=0.16036 WTURN3=1.68722 WTURN4=0.66230 WTURN6=0.00000    &')
79         md_input.append('WVDWPP=0.11371 WHPB=1.00000                                                    &')
80         md_input.append('CUTOFF=7.00000 WCORR4=0.00000 WSCCOR=0.0')
81     else:
82         # Wagi pola E0LLY
83         md_input.append('WLONG=1.00000 WSCP=1.23315 WELEC=0.84476 WBOND=1.00000 WANG=0.62954            &')
84         md_input.append('WSCLOC=0.10554 WTOR=1.84316 WTORD=1.26571 WCORRH=0.19212 WCORR5=0.00000        &')
85         md_input.append('WCORR6=0.00000 WEL_LOC=0.37357 WTURN3=1.40323 WTURN4=0.64673 WTURN6=0.00000    &')
86         md_input.append('WVDWPP=0.23173 WHPB=1.00000 WSCCOR=0.0                                         &')
87         md_input.append('CUTOFF=7.00000 WCORR4=0.00000')
88     # Plik PDB    
89     md_input.append(params['pdb_file'].split('/')[-1])
90     # Sekwencja aminokwasów
91     md_input.append(len(params['sequence']))
92     seq_str=params['sequence']
93     while seq_str:
94         md_input.append(seq_str[:80])
95         seq_str=seq_str[80:]
96     md_input.append(' 0')
97     md_input.append(' 0')
98     
99     return md_input
100
101
102 def to_job_desc(params, proxy):
103     QCG.start()
104     desc = JobDescription(Credential(proxy))
105     desc.sequence=None
106
107     direct_map = ('env_variables', 'executable', 'arguments', 'note', 'grant', 'hosts', 'properties', 'queue', 'procs',
108                   'wall_time', 'memory', 'memory_per_slot', 'modules', 'input', 'stage_in', 'native', 'notify',
109                   'preprocess', 'postprocess', 'persistent')
110
111     for name in direct_map:
112         if params[name]:
113             setattr(desc, name, params[name])
114
115     if params['application']:
116         desc.set_application(*params['application'])
117         desc.stage_in += [params['master_file']]
118         desc.arguments.insert(0, os.path.basename(params['master_file']))
119     if params['script']:
120         ftp = FTPOperation(proxy)
121
122         ftp.mkdir(constants.QCG_DATA_URL, parents=True)
123         url = os.path.join(constants.QCG_DATA_URL, 'script.{}.sh'.format(random_id()))
124         ftp.put(url)
125
126         for chunk in chunks(params['script'], 4096):
127             ftp.stream.put(chunk)
128         ftp.stream.put(None)
129         ftp.wait()
130
131         desc.executable = url
132     if params['nodes']:
133         desc.set_nodes(*params['nodes'])
134     if params['reservation']:
135         desc.set_reservation(params['reservation'])
136     if params['watch_output']:
137         desc.set_watch_output(params['watch_output'], params['watch_output_pattern'])
138     if params['sequence']:
139         desc.sequence=params['sequence']
140
141     # TODO monitoring
142
143     print "Hello from to_job_desc function"
144     pprint(params)
145     print desc.sequence
146     
147     return desc
148
149
150 def to_form_data(xml):
151     # prevent circular import errors
152     from forms import JobDescriptionForm
153
154     QCG.start()
155     desc = JobDescription()
156     desc.xml_description = xml
157     #desc.sequence=None
158
159     direct_map = ('env_variables', 'executable', 'arguments', 'note', 'grant', 'hosts', 'properties', 'queue', 'procs',
160                   'wall_time', 'memory', 'memory_per_slot', 'modules', 'input', 'stage_in', 'native', 'persistent')
161
162     params = {}
163     for name in direct_map:
164         attr = getattr(desc, name)
165         if isinstance(attr, bool) or attr:
166             params[name] = attr
167
168     if desc.application is not None:
169         app_name, app_ver = desc.application
170         params['application'] = app_name if app_ver is None else app_name + '/' + app_name
171         stage_in = params['stage_in']
172         params['stage_in'], params['master_file'] = stage_in[:-1], stage_in[-1]
173         params['arguments'] = params['arguments'][1:]
174     if desc.nodes is not None:
175         params['nodes'] = ':'.join(map(str, desc.nodes))
176     if desc.reservation is not None:
177         res_id, res_type = desc.reservation
178         params['reservation'] = res_id
179     if desc.notify is not None:
180         params['notify_type'], params['notify_address'] = desc.notify.split(':')
181     if desc.watch_output is not None:
182         watch_output, params['watch_output_pattern'] = desc.watch_output
183         params['watch_output_type'], params['watch_output_address'] = watch_output.split(':')
184     if desc.preprocess is not None:
185         if desc.preprocess.startswith('gsiftp://'):
186             params['preprocess_type'] = JobDescriptionForm.Process.SCRIPT
187             params['preprocess_script'] = desc.preprocess
188         else:
189             params['preprocess_type'] = JobDescriptionForm.Process.CMD
190             params['preprocess_cmd'] = desc.preprocess
191     if desc.postprocess is not None:
192         if desc.postprocess.startswith('gsiftp://'):
193             params['postprocess_type'] = JobDescriptionForm.Process.SCRIPT
194             params['postprocess_script'] = desc.postprocess
195         else:
196             params['postprocess_type'] = JobDescriptionForm.Process.CMD
197             params['postprocess_cmd'] = desc.postprocess
198
199     
200     print "Hello from to_form_data function"
201     pprint(params)
202     return params