##// END OF EJS Templates
Fix Mix RC configurations...
Juan C. Espinoza -
r238:3478b6e05998
parent child
Show More
@@ -1,1665 +1,1665
1 from datetime import datetime
1 from datetime import datetime
2
2
3 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
3 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
4 from django.utils.safestring import mark_safe
4 from django.utils.safestring import mark_safe
5 from django.http import HttpResponseRedirect
5 from django.http import HttpResponseRedirect
6 from django.core.urlresolvers import reverse
6 from django.core.urlresolvers import reverse
7 from django.db.models import Q
7 from django.db.models import Q
8 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
8 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
9 from django.contrib import messages
9 from django.contrib import messages
10 from django.http.request import QueryDict
10 from django.http.request import QueryDict
11
11
12 try:
12 try:
13 from urllib.parse import urlencode
13 from urllib.parse import urlencode
14 except ImportError:
14 except ImportError:
15 from urllib import urlencode
15 from urllib import urlencode
16
16
17 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
17 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
18 from .forms import OperationSearchForm, FilterForm, ChangeIpForm
18 from .forms import OperationSearchForm, FilterForm, ChangeIpForm
19
19
20 from .tasks import task_start, task_stop
20 from .tasks import task_start, task_stop
21
21
22 from apps.rc.forms import RCConfigurationForm, RCLineCode
22 from apps.rc.forms import RCConfigurationForm, RCLineCode, RCMixConfigurationForm
23 from apps.dds.forms import DDSConfigurationForm
23 from apps.dds.forms import DDSConfigurationForm
24 from apps.jars.forms import JARSConfigurationForm
24 from apps.jars.forms import JARSConfigurationForm
25 from apps.cgs.forms import CGSConfigurationForm
25 from apps.cgs.forms import CGSConfigurationForm
26 from apps.abs.forms import ABSConfigurationForm
26 from apps.abs.forms import ABSConfigurationForm
27 from apps.usrp.forms import USRPConfigurationForm
27 from apps.usrp.forms import USRPConfigurationForm
28
28
29 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment
29 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment
30 from apps.cgs.models import CGSConfiguration
30 from apps.cgs.models import CGSConfiguration
31 from apps.jars.models import JARSConfiguration, EXPERIMENT_TYPE
31 from apps.jars.models import JARSConfiguration, EXPERIMENT_TYPE
32 from apps.usrp.models import USRPConfiguration
32 from apps.usrp.models import USRPConfiguration
33 from apps.abs.models import ABSConfiguration
33 from apps.abs.models import ABSConfiguration
34 from apps.rc.models import RCConfiguration, RCLine, RCLineType
34 from apps.rc.models import RCConfiguration, RCLine, RCLineType
35 from apps.dds.models import DDSConfiguration
35 from apps.dds.models import DDSConfiguration
36
36
37 from django.contrib.auth.decorators import login_required
37 from django.contrib.auth.decorators import login_required
38 from django.contrib.auth.decorators import user_passes_test
38 from django.contrib.auth.decorators import user_passes_test
39 from django.contrib.admin.views.decorators import staff_member_required
39 from django.contrib.admin.views.decorators import staff_member_required
40
40
41 import ast
41 import ast
42
42
43 CONF_FORMS = {
43 CONF_FORMS = {
44 'rc': RCConfigurationForm,
44 'rc': RCConfigurationForm,
45 'dds': DDSConfigurationForm,
45 'dds': DDSConfigurationForm,
46 'jars': JARSConfigurationForm,
46 'jars': JARSConfigurationForm,
47 'cgs': CGSConfigurationForm,
47 'cgs': CGSConfigurationForm,
48 'abs': ABSConfigurationForm,
48 'abs': ABSConfigurationForm,
49 'usrp': USRPConfigurationForm,
49 'usrp': USRPConfigurationForm,
50 }
50 }
51
51
52 CONF_MODELS = {
52 CONF_MODELS = {
53 'rc': RCConfiguration,
53 'rc': RCConfiguration,
54 'dds': DDSConfiguration,
54 'dds': DDSConfiguration,
55 'jars': JARSConfiguration,
55 'jars': JARSConfiguration,
56 'cgs': CGSConfiguration,
56 'cgs': CGSConfiguration,
57 'abs': ABSConfiguration,
57 'abs': ABSConfiguration,
58 'usrp': USRPConfiguration,
58 'usrp': USRPConfiguration,
59 }
59 }
60
60
61 MIX_MODES = {
61 MIX_MODES = {
62 '0': 'P',
62 '0': 'P',
63 '1': 'S',
63 '1': 'S',
64 }
64 }
65
65
66 MIX_OPERATIONS = {
66 MIX_OPERATIONS = {
67 '0': 'OR',
67 '0': 'OR',
68 '1': 'XOR',
68 '1': 'XOR',
69 '2': 'AND',
69 '2': 'AND',
70 '3': 'NAND',
70 '3': 'NAND',
71 }
71 }
72
72
73 def index(request):
73 def index(request):
74 kwargs = {'no_sidebar':True}
74 kwargs = {'no_sidebar':True}
75
75
76 return render(request, 'index.html', kwargs)
76 return render(request, 'index.html', kwargs)
77
77
78
78
79 def locations(request):
79 def locations(request):
80
80
81 page = request.GET.get('page')
81 page = request.GET.get('page')
82 order = ('name',)
82 order = ('name',)
83
83
84 kwargs = get_paginator(Location, page, order)
84 kwargs = get_paginator(Location, page, order)
85
85
86 kwargs['keys'] = ['name', 'description']
86 kwargs['keys'] = ['name', 'description']
87 kwargs['title'] = 'Radar System'
87 kwargs['title'] = 'Radar System'
88 kwargs['suptitle'] = 'List'
88 kwargs['suptitle'] = 'List'
89 kwargs['no_sidebar'] = True
89 kwargs['no_sidebar'] = True
90
90
91 return render(request, 'base_list.html', kwargs)
91 return render(request, 'base_list.html', kwargs)
92
92
93
93
94 def location(request, id_loc):
94 def location(request, id_loc):
95
95
96 location = get_object_or_404(Location, pk=id_loc)
96 location = get_object_or_404(Location, pk=id_loc)
97
97
98 kwargs = {}
98 kwargs = {}
99 kwargs['location'] = location
99 kwargs['location'] = location
100 kwargs['location_keys'] = ['name', 'description']
100 kwargs['location_keys'] = ['name', 'description']
101
101
102 kwargs['title'] = 'Location'
102 kwargs['title'] = 'Location'
103 kwargs['suptitle'] = 'Details'
103 kwargs['suptitle'] = 'Details'
104
104
105 return render(request, 'location.html', kwargs)
105 return render(request, 'location.html', kwargs)
106
106
107
107
108 @user_passes_test(lambda u:u.is_staff)
108 @user_passes_test(lambda u:u.is_staff)
109 def location_new(request):
109 def location_new(request):
110
110
111 if request.method == 'GET':
111 if request.method == 'GET':
112 form = LocationForm()
112 form = LocationForm()
113
113
114 if request.method == 'POST':
114 if request.method == 'POST':
115 form = LocationForm(request.POST)
115 form = LocationForm(request.POST)
116
116
117 if form.is_valid():
117 if form.is_valid():
118 form.save()
118 form.save()
119 return redirect('url_locations')
119 return redirect('url_locations')
120
120
121 kwargs = {}
121 kwargs = {}
122 kwargs['form'] = form
122 kwargs['form'] = form
123 kwargs['title'] = 'Radar System'
123 kwargs['title'] = 'Radar System'
124 kwargs['suptitle'] = 'New'
124 kwargs['suptitle'] = 'New'
125 kwargs['button'] = 'Create'
125 kwargs['button'] = 'Create'
126
126
127 return render(request, 'base_edit.html', kwargs)
127 return render(request, 'base_edit.html', kwargs)
128
128
129
129
130 @user_passes_test(lambda u:u.is_staff)
130 @user_passes_test(lambda u:u.is_staff)
131 def location_edit(request, id_loc):
131 def location_edit(request, id_loc):
132
132
133 location = get_object_or_404(Location, pk=id_loc)
133 location = get_object_or_404(Location, pk=id_loc)
134
134
135 if request.method=='GET':
135 if request.method=='GET':
136 form = LocationForm(instance=location)
136 form = LocationForm(instance=location)
137
137
138 if request.method=='POST':
138 if request.method=='POST':
139 form = LocationForm(request.POST, instance=location)
139 form = LocationForm(request.POST, instance=location)
140
140
141 if form.is_valid():
141 if form.is_valid():
142 form.save()
142 form.save()
143 return redirect('url_locations')
143 return redirect('url_locations')
144
144
145 kwargs = {}
145 kwargs = {}
146 kwargs['form'] = form
146 kwargs['form'] = form
147 kwargs['title'] = 'Location'
147 kwargs['title'] = 'Location'
148 kwargs['suptitle'] = 'Edit'
148 kwargs['suptitle'] = 'Edit'
149 kwargs['button'] = 'Update'
149 kwargs['button'] = 'Update'
150
150
151 return render(request, 'base_edit.html', kwargs)
151 return render(request, 'base_edit.html', kwargs)
152
152
153
153
154 @user_passes_test(lambda u:u.is_staff)
154 @user_passes_test(lambda u:u.is_staff)
155 def location_delete(request, id_loc):
155 def location_delete(request, id_loc):
156
156
157 location = get_object_or_404(Location, pk=id_loc)
157 location = get_object_or_404(Location, pk=id_loc)
158
158
159 if request.method=='POST':
159 if request.method=='POST':
160
160
161 if request.user.is_staff:
161 if request.user.is_staff:
162 location.delete()
162 location.delete()
163 return redirect('url_locations')
163 return redirect('url_locations')
164
164
165 messages.error(request, 'Not enough permission to delete this object')
165 messages.error(request, 'Not enough permission to delete this object')
166 return redirect(location.get_absolute_url())
166 return redirect(location.get_absolute_url())
167
167
168 kwargs = {
168 kwargs = {
169 'title': 'Delete',
169 'title': 'Delete',
170 'suptitle': 'Location',
170 'suptitle': 'Location',
171 'object': location,
171 'object': location,
172 'previous': location.get_absolute_url(),
172 'previous': location.get_absolute_url(),
173 'delete': True
173 'delete': True
174 }
174 }
175
175
176 return render(request, 'confirm.html', kwargs)
176 return render(request, 'confirm.html', kwargs)
177
177
178
178
179 def devices(request):
179 def devices(request):
180
180
181 page = request.GET.get('page')
181 page = request.GET.get('page')
182 order = ('device_type', 'name')
182 order = ('device_type', 'name')
183
183
184 kwargs = get_paginator(Device, page, order)
184 kwargs = get_paginator(Device, page, order)
185 kwargs['keys'] = ['name', 'ip_address', 'port_address', 'device_type']
185 kwargs['keys'] = ['name', 'ip_address', 'port_address', 'device_type']
186 kwargs['title'] = 'Device'
186 kwargs['title'] = 'Device'
187 kwargs['suptitle'] = 'List'
187 kwargs['suptitle'] = 'List'
188 kwargs['no_sidebar'] = True
188 kwargs['no_sidebar'] = True
189
189
190 return render(request, 'base_list.html', kwargs)
190 return render(request, 'base_list.html', kwargs)
191
191
192
192
193 def device(request, id_dev):
193 def device(request, id_dev):
194
194
195 device = get_object_or_404(Device, pk=id_dev)
195 device = get_object_or_404(Device, pk=id_dev)
196
196
197 kwargs = {}
197 kwargs = {}
198 kwargs['device'] = device
198 kwargs['device'] = device
199 kwargs['device_keys'] = ['device_type', 'name', 'ip_address', 'port_address', 'description']
199 kwargs['device_keys'] = ['device_type', 'name', 'ip_address', 'port_address', 'description']
200
200
201 kwargs['title'] = 'Device'
201 kwargs['title'] = 'Device'
202 kwargs['suptitle'] = 'Details'
202 kwargs['suptitle'] = 'Details'
203
203
204 return render(request, 'device.html', kwargs)
204 return render(request, 'device.html', kwargs)
205
205
206
206
207 @user_passes_test(lambda u:u.is_staff)
207 @user_passes_test(lambda u:u.is_staff)
208 def device_new(request):
208 def device_new(request):
209
209
210 if request.method == 'GET':
210 if request.method == 'GET':
211 form = DeviceForm()
211 form = DeviceForm()
212
212
213 if request.method == 'POST':
213 if request.method == 'POST':
214 form = DeviceForm(request.POST)
214 form = DeviceForm(request.POST)
215
215
216 if form.is_valid():
216 if form.is_valid():
217 form.save()
217 form.save()
218 return redirect('url_devices')
218 return redirect('url_devices')
219
219
220 kwargs = {}
220 kwargs = {}
221 kwargs['form'] = form
221 kwargs['form'] = form
222 kwargs['title'] = 'Device'
222 kwargs['title'] = 'Device'
223 kwargs['suptitle'] = 'New'
223 kwargs['suptitle'] = 'New'
224 kwargs['button'] = 'Create'
224 kwargs['button'] = 'Create'
225
225
226 return render(request, 'base_edit.html', kwargs)
226 return render(request, 'base_edit.html', kwargs)
227
227
228
228
229 @user_passes_test(lambda u:u.is_staff)
229 @user_passes_test(lambda u:u.is_staff)
230 def device_edit(request, id_dev):
230 def device_edit(request, id_dev):
231
231
232 device = get_object_or_404(Device, pk=id_dev)
232 device = get_object_or_404(Device, pk=id_dev)
233
233
234 if request.method=='GET':
234 if request.method=='GET':
235 form = DeviceForm(instance=device)
235 form = DeviceForm(instance=device)
236
236
237 if request.method=='POST':
237 if request.method=='POST':
238 form = DeviceForm(request.POST, instance=device)
238 form = DeviceForm(request.POST, instance=device)
239
239
240 if form.is_valid():
240 if form.is_valid():
241 form.save()
241 form.save()
242 return redirect(device.get_absolute_url())
242 return redirect(device.get_absolute_url())
243
243
244 kwargs = {}
244 kwargs = {}
245 kwargs['form'] = form
245 kwargs['form'] = form
246 kwargs['title'] = 'Device'
246 kwargs['title'] = 'Device'
247 kwargs['suptitle'] = 'Edit'
247 kwargs['suptitle'] = 'Edit'
248 kwargs['button'] = 'Update'
248 kwargs['button'] = 'Update'
249
249
250 return render(request, 'base_edit.html', kwargs)
250 return render(request, 'base_edit.html', kwargs)
251
251
252
252
253 @user_passes_test(lambda u:u.is_staff)
253 @user_passes_test(lambda u:u.is_staff)
254 def device_delete(request, id_dev):
254 def device_delete(request, id_dev):
255
255
256 device = get_object_or_404(Device, pk=id_dev)
256 device = get_object_or_404(Device, pk=id_dev)
257
257
258 if request.method=='POST':
258 if request.method=='POST':
259
259
260 if request.user.is_staff:
260 if request.user.is_staff:
261 device.delete()
261 device.delete()
262 return redirect('url_devices')
262 return redirect('url_devices')
263
263
264 messages.error(request, 'Not enough permission to delete this object')
264 messages.error(request, 'Not enough permission to delete this object')
265 return redirect(device.get_absolute_url())
265 return redirect(device.get_absolute_url())
266
266
267 kwargs = {
267 kwargs = {
268 'title': 'Delete',
268 'title': 'Delete',
269 'suptitle': 'Device',
269 'suptitle': 'Device',
270 'object': device,
270 'object': device,
271 'previous': device.get_absolute_url(),
271 'previous': device.get_absolute_url(),
272 'delete': True
272 'delete': True
273 }
273 }
274
274
275 return render(request, 'confirm.html', kwargs)
275 return render(request, 'confirm.html', kwargs)
276
276
277
277
278 @user_passes_test(lambda u:u.is_staff)
278 @user_passes_test(lambda u:u.is_staff)
279 def device_change_ip(request, id_dev):
279 def device_change_ip(request, id_dev):
280
280
281 device = get_object_or_404(Device, pk=id_dev)
281 device = get_object_or_404(Device, pk=id_dev)
282
282
283 if request.method=='POST':
283 if request.method=='POST':
284
284
285 if request.user.is_staff:
285 if request.user.is_staff:
286 device.change_ip(**request.POST.dict())
286 device.change_ip(**request.POST.dict())
287 level, message = device.message.split('|')
287 level, message = device.message.split('|')
288 messages.add_message(request, level, message)
288 messages.add_message(request, level, message)
289 else:
289 else:
290 messages.error(request, 'Not enough permission to delete this object')
290 messages.error(request, 'Not enough permission to delete this object')
291 return redirect(device.get_absolute_url())
291 return redirect(device.get_absolute_url())
292
292
293 kwargs = {
293 kwargs = {
294 'title': 'Device',
294 'title': 'Device',
295 'suptitle': 'Change IP',
295 'suptitle': 'Change IP',
296 'object': device,
296 'object': device,
297 'previous': device.get_absolute_url(),
297 'previous': device.get_absolute_url(),
298 'form': ChangeIpForm(initial={'ip_address':device.ip_address}),
298 'form': ChangeIpForm(initial={'ip_address':device.ip_address}),
299 'message' : ' ',
299 'message' : ' ',
300 }
300 }
301
301
302 return render(request, 'confirm.html', kwargs)
302 return render(request, 'confirm.html', kwargs)
303
303
304
304
305 def campaigns(request):
305 def campaigns(request):
306
306
307 page = request.GET.get('page')
307 page = request.GET.get('page')
308 order = ('start_date',)
308 order = ('start_date',)
309 filters = request.GET.copy()
309 filters = request.GET.copy()
310
310
311 kwargs = get_paginator(Campaign, page, order, filters)
311 kwargs = get_paginator(Campaign, page, order, filters)
312
312
313 form = FilterForm(initial=request.GET, extra_fields=['range_date', 'tags','template'])
313 form = FilterForm(initial=request.GET, extra_fields=['range_date', 'tags','template'])
314 kwargs['keys'] = ['name', 'start_date', 'end_date']
314 kwargs['keys'] = ['name', 'start_date', 'end_date']
315 kwargs['title'] = 'Campaign'
315 kwargs['title'] = 'Campaign'
316 kwargs['suptitle'] = 'List'
316 kwargs['suptitle'] = 'List'
317 kwargs['no_sidebar'] = True
317 kwargs['no_sidebar'] = True
318 kwargs['form'] = form
318 kwargs['form'] = form
319 filters.pop('page', None)
319 filters.pop('page', None)
320 kwargs['q'] = urlencode(filters)
320 kwargs['q'] = urlencode(filters)
321
321
322 return render(request, 'base_list.html', kwargs)
322 return render(request, 'base_list.html', kwargs)
323
323
324
324
325 def campaign(request, id_camp):
325 def campaign(request, id_camp):
326
326
327 campaign = get_object_or_404(Campaign, pk=id_camp)
327 campaign = get_object_or_404(Campaign, pk=id_camp)
328 experiments = Experiment.objects.filter(campaign=campaign)
328 experiments = Experiment.objects.filter(campaign=campaign)
329
329
330 form = CampaignForm(instance=campaign)
330 form = CampaignForm(instance=campaign)
331
331
332 kwargs = {}
332 kwargs = {}
333 kwargs['campaign'] = campaign
333 kwargs['campaign'] = campaign
334 kwargs['campaign_keys'] = ['template', 'name', 'start_date', 'end_date', 'tags', 'description']
334 kwargs['campaign_keys'] = ['template', 'name', 'start_date', 'end_date', 'tags', 'description']
335
335
336 kwargs['experiments'] = experiments
336 kwargs['experiments'] = experiments
337 kwargs['experiment_keys'] = ['name', 'radar_system', 'start_time', 'end_time']
337 kwargs['experiment_keys'] = ['name', 'radar_system', 'start_time', 'end_time']
338
338
339 kwargs['title'] = 'Campaign'
339 kwargs['title'] = 'Campaign'
340 kwargs['suptitle'] = 'Details'
340 kwargs['suptitle'] = 'Details'
341
341
342 kwargs['form'] = form
342 kwargs['form'] = form
343 kwargs['button'] = 'Add Experiment'
343 kwargs['button'] = 'Add Experiment'
344
344
345 return render(request, 'campaign.html', kwargs)
345 return render(request, 'campaign.html', kwargs)
346
346
347
347
348 @user_passes_test(lambda u:u.is_staff)
348 @user_passes_test(lambda u:u.is_staff)
349 def campaign_new(request):
349 def campaign_new(request):
350
350
351 kwargs = {}
351 kwargs = {}
352
352
353 if request.method == 'GET':
353 if request.method == 'GET':
354
354
355 if 'template' in request.GET:
355 if 'template' in request.GET:
356 if request.GET['template']=='0':
356 if request.GET['template']=='0':
357 form = NewForm(initial={'create_from':2},
357 form = NewForm(initial={'create_from':2},
358 template_choices=Campaign.objects.filter(template=True).values_list('id', 'name'))
358 template_choices=Campaign.objects.filter(template=True).values_list('id', 'name'))
359 else:
359 else:
360 kwargs['button'] = 'Create'
360 kwargs['button'] = 'Create'
361 kwargs['experiments'] = Configuration.objects.filter(experiment=request.GET['template'])
361 kwargs['experiments'] = Configuration.objects.filter(experiment=request.GET['template'])
362 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
362 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
363 camp = Campaign.objects.get(pk=request.GET['template'])
363 camp = Campaign.objects.get(pk=request.GET['template'])
364 form = CampaignForm(instance=camp,
364 form = CampaignForm(instance=camp,
365 initial={'name':'{} [{:%Y/%m/%d}]'.format(camp.name, datetime.now()),
365 initial={'name':'{} [{:%Y/%m/%d}]'.format(camp.name, datetime.now()),
366 'template':False})
366 'template':False})
367 elif 'blank' in request.GET:
367 elif 'blank' in request.GET:
368 kwargs['button'] = 'Create'
368 kwargs['button'] = 'Create'
369 form = CampaignForm()
369 form = CampaignForm()
370 else:
370 else:
371 form = NewForm()
371 form = NewForm()
372
372
373 if request.method == 'POST':
373 if request.method == 'POST':
374 kwargs['button'] = 'Create'
374 kwargs['button'] = 'Create'
375 post = request.POST.copy()
375 post = request.POST.copy()
376 experiments = []
376 experiments = []
377
377
378 for id_exp in post.getlist('experiments'):
378 for id_exp in post.getlist('experiments'):
379 exp = Experiment.objects.get(pk=id_exp)
379 exp = Experiment.objects.get(pk=id_exp)
380 new_exp = exp.clone(template=False)
380 new_exp = exp.clone(template=False)
381 experiments.append(new_exp)
381 experiments.append(new_exp)
382
382
383 post.setlist('experiments', [])
383 post.setlist('experiments', [])
384
384
385 form = CampaignForm(post)
385 form = CampaignForm(post)
386
386
387 if form.is_valid():
387 if form.is_valid():
388 campaign = form.save()
388 campaign = form.save()
389 for exp in experiments:
389 for exp in experiments:
390 campaign.experiments.add(exp)
390 campaign.experiments.add(exp)
391 campaign.save()
391 campaign.save()
392 return redirect('url_campaign', id_camp=campaign.id)
392 return redirect('url_campaign', id_camp=campaign.id)
393
393
394 kwargs['form'] = form
394 kwargs['form'] = form
395 kwargs['title'] = 'Campaign'
395 kwargs['title'] = 'Campaign'
396 kwargs['suptitle'] = 'New'
396 kwargs['suptitle'] = 'New'
397
397
398 return render(request, 'campaign_edit.html', kwargs)
398 return render(request, 'campaign_edit.html', kwargs)
399
399
400
400
401 @user_passes_test(lambda u:u.is_staff)
401 @user_passes_test(lambda u:u.is_staff)
402 def campaign_edit(request, id_camp):
402 def campaign_edit(request, id_camp):
403
403
404 campaign = get_object_or_404(Campaign, pk=id_camp)
404 campaign = get_object_or_404(Campaign, pk=id_camp)
405
405
406 if request.method=='GET':
406 if request.method=='GET':
407 form = CampaignForm(instance=campaign)
407 form = CampaignForm(instance=campaign)
408
408
409 if request.method=='POST':
409 if request.method=='POST':
410 exps = campaign.experiments.all().values_list('pk', flat=True)
410 exps = campaign.experiments.all().values_list('pk', flat=True)
411 post = request.POST.copy()
411 post = request.POST.copy()
412 new_exps = post.getlist('experiments')
412 new_exps = post.getlist('experiments')
413 post.setlist('experiments', [])
413 post.setlist('experiments', [])
414 form = CampaignForm(post, instance=campaign)
414 form = CampaignForm(post, instance=campaign)
415
415
416 if form.is_valid():
416 if form.is_valid():
417 camp = form.save()
417 camp = form.save()
418 for id_exp in new_exps:
418 for id_exp in new_exps:
419 if int(id_exp) in exps:
419 if int(id_exp) in exps:
420 exps.pop(id_exp)
420 exps.pop(id_exp)
421 else:
421 else:
422 exp = Experiment.objects.get(pk=id_exp)
422 exp = Experiment.objects.get(pk=id_exp)
423 if exp.template:
423 if exp.template:
424 camp.experiments.add(exp.clone(template=False))
424 camp.experiments.add(exp.clone(template=False))
425 else:
425 else:
426 camp.experiments.add(exp)
426 camp.experiments.add(exp)
427
427
428 for id_exp in exps:
428 for id_exp in exps:
429 camp.experiments.remove(Experiment.objects.get(pk=id_exp))
429 camp.experiments.remove(Experiment.objects.get(pk=id_exp))
430
430
431 return redirect('url_campaign', id_camp=id_camp)
431 return redirect('url_campaign', id_camp=id_camp)
432
432
433 kwargs = {}
433 kwargs = {}
434 kwargs['form'] = form
434 kwargs['form'] = form
435 kwargs['title'] = 'Campaign'
435 kwargs['title'] = 'Campaign'
436 kwargs['suptitle'] = 'Edit'
436 kwargs['suptitle'] = 'Edit'
437 kwargs['button'] = 'Update'
437 kwargs['button'] = 'Update'
438
438
439 return render(request, 'campaign_edit.html', kwargs)
439 return render(request, 'campaign_edit.html', kwargs)
440
440
441
441
442 @user_passes_test(lambda u:u.is_staff)
442 @user_passes_test(lambda u:u.is_staff)
443 def campaign_delete(request, id_camp):
443 def campaign_delete(request, id_camp):
444
444
445 campaign = get_object_or_404(Campaign, pk=id_camp)
445 campaign = get_object_or_404(Campaign, pk=id_camp)
446
446
447 if request.method=='POST':
447 if request.method=='POST':
448 if request.user.is_staff:
448 if request.user.is_staff:
449
449
450 for exp in campaign.experiments.all():
450 for exp in campaign.experiments.all():
451 for conf in Configuration.objects.filter(experiment=exp):
451 for conf in Configuration.objects.filter(experiment=exp):
452 conf.delete()
452 conf.delete()
453 exp.delete()
453 exp.delete()
454 campaign.delete()
454 campaign.delete()
455
455
456 return redirect('url_campaigns')
456 return redirect('url_campaigns')
457
457
458 messages.error(request, 'Not enough permission to delete this object')
458 messages.error(request, 'Not enough permission to delete this object')
459 return redirect(campaign.get_absolute_url())
459 return redirect(campaign.get_absolute_url())
460
460
461 kwargs = {
461 kwargs = {
462 'title': 'Delete',
462 'title': 'Delete',
463 'suptitle': 'Campaign',
463 'suptitle': 'Campaign',
464 'object': campaign,
464 'object': campaign,
465 'previous': campaign.get_absolute_url(),
465 'previous': campaign.get_absolute_url(),
466 'delete': True
466 'delete': True
467 }
467 }
468
468
469 return render(request, 'confirm.html', kwargs)
469 return render(request, 'confirm.html', kwargs)
470
470
471
471
472 @user_passes_test(lambda u:u.is_staff)
472 @user_passes_test(lambda u:u.is_staff)
473 def campaign_export(request, id_camp):
473 def campaign_export(request, id_camp):
474
474
475 campaign = get_object_or_404(Campaign, pk=id_camp)
475 campaign = get_object_or_404(Campaign, pk=id_camp)
476 content = campaign.parms_to_dict()
476 content = campaign.parms_to_dict()
477 content_type = 'application/json'
477 content_type = 'application/json'
478 filename = '%s_%s.json' %(campaign.name, campaign.id)
478 filename = '%s_%s.json' %(campaign.name, campaign.id)
479
479
480 response = HttpResponse(content_type=content_type)
480 response = HttpResponse(content_type=content_type)
481 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
481 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
482 response.write(content)
482 response.write(content)
483
483
484 return response
484 return response
485
485
486
486
487 @user_passes_test(lambda u:u.is_staff)
487 @user_passes_test(lambda u:u.is_staff)
488 def campaign_import(request, id_camp):
488 def campaign_import(request, id_camp):
489
489
490 campaign = get_object_or_404(Campaign, pk=id_camp)
490 campaign = get_object_or_404(Campaign, pk=id_camp)
491
491
492 if request.method == 'GET':
492 if request.method == 'GET':
493 file_form = UploadFileForm()
493 file_form = UploadFileForm()
494
494
495 if request.method == 'POST':
495 if request.method == 'POST':
496 file_form = UploadFileForm(request.POST, request.FILES)
496 file_form = UploadFileForm(request.POST, request.FILES)
497
497
498 if file_form.is_valid():
498 if file_form.is_valid():
499
499
500 parms = campaign.import_from_file(request.FILES['file'])
500 parms = campaign.import_from_file(request.FILES['file'])
501
501
502 if parms:
502 if parms:
503 parms['name'] = parms['campaign']
503 parms['name'] = parms['campaign']
504
504
505 new_camp = campaign.dict_to_parms(parms, CONF_MODELS)
505 new_camp = campaign.dict_to_parms(parms, CONF_MODELS)
506
506
507 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
507 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
508
508
509 return redirect(new_camp.get_absolute_url_edit())
509 return redirect(new_camp.get_absolute_url_edit())
510
510
511 messages.error(request, "Could not import parameters from file")
511 messages.error(request, "Could not import parameters from file")
512
512
513 kwargs = {}
513 kwargs = {}
514 kwargs['title'] = 'Campaign'
514 kwargs['title'] = 'Campaign'
515 kwargs['form'] = file_form
515 kwargs['form'] = file_form
516 kwargs['suptitle'] = 'Importing file'
516 kwargs['suptitle'] = 'Importing file'
517 kwargs['button'] = 'Import'
517 kwargs['button'] = 'Import'
518
518
519 return render(request, 'campaign_import.html', kwargs)
519 return render(request, 'campaign_import.html', kwargs)
520
520
521
521
522 def experiments(request):
522 def experiments(request):
523
523
524 page = request.GET.get('page')
524 page = request.GET.get('page')
525 order = ('location',)
525 order = ('location',)
526 filters = request.GET.copy()
526 filters = request.GET.copy()
527
527
528 kwargs = get_paginator(Experiment, page, order, filters)
528 kwargs = get_paginator(Experiment, page, order, filters)
529
529
530 form = FilterForm(initial=request.GET, extra_fields=['tags','template'])
530 form = FilterForm(initial=request.GET, extra_fields=['tags','template'])
531
531
532 kwargs['keys'] = ['name', 'radar_system', 'start_time', 'end_time']
532 kwargs['keys'] = ['name', 'radar_system', 'start_time', 'end_time']
533 kwargs['title'] = 'Experiment'
533 kwargs['title'] = 'Experiment'
534 kwargs['suptitle'] = 'List'
534 kwargs['suptitle'] = 'List'
535 kwargs['no_sidebar'] = True
535 kwargs['no_sidebar'] = True
536 kwargs['form'] = form
536 kwargs['form'] = form
537 filters.pop('page', None)
537 filters.pop('page', None)
538 kwargs['q'] = urlencode(filters)
538 kwargs['q'] = urlencode(filters)
539
539
540 return render(request, 'base_list.html', kwargs)
540 return render(request, 'base_list.html', kwargs)
541
541
542
542
543 def experiment(request, id_exp):
543 def experiment(request, id_exp):
544
544
545 experiment = get_object_or_404(Experiment, pk=id_exp)
545 experiment = get_object_or_404(Experiment, pk=id_exp)
546
546
547 configurations = Configuration.objects.filter(experiment=experiment, type=0)
547 configurations = Configuration.objects.filter(experiment=experiment, type=0)
548
548
549 kwargs = {}
549 kwargs = {}
550
550
551 kwargs['experiment_keys'] = ['template', 'radar_system', 'name', 'start_time', 'end_time']
551 kwargs['experiment_keys'] = ['template', 'radar_system', 'name', 'start_time', 'end_time']
552 kwargs['experiment'] = experiment
552 kwargs['experiment'] = experiment
553
553
554 kwargs['configuration_keys'] = ['name', 'device__ip_address', 'device__port_address', 'device__status']
554 kwargs['configuration_keys'] = ['name', 'device__ip_address', 'device__port_address', 'device__status']
555 kwargs['configurations'] = configurations
555 kwargs['configurations'] = configurations
556
556
557 kwargs['title'] = 'Experiment'
557 kwargs['title'] = 'Experiment'
558 kwargs['suptitle'] = 'Details'
558 kwargs['suptitle'] = 'Details'
559
559
560 kwargs['button'] = 'Add Configuration'
560 kwargs['button'] = 'Add Configuration'
561
561
562 ###### SIDEBAR ######
562 ###### SIDEBAR ######
563 kwargs.update(sidebar(experiment=experiment))
563 kwargs.update(sidebar(experiment=experiment))
564
564
565 return render(request, 'experiment.html', kwargs)
565 return render(request, 'experiment.html', kwargs)
566
566
567
567
568 @user_passes_test(lambda u:u.is_staff)
568 @user_passes_test(lambda u:u.is_staff)
569 def experiment_new(request, id_camp=None):
569 def experiment_new(request, id_camp=None):
570
570
571 kwargs = {}
571 kwargs = {}
572
572
573 if request.method == 'GET':
573 if request.method == 'GET':
574 if 'template' in request.GET:
574 if 'template' in request.GET:
575 if request.GET['template']=='0':
575 if request.GET['template']=='0':
576 form = NewForm(initial={'create_from':2},
576 form = NewForm(initial={'create_from':2},
577 template_choices=Experiment.objects.filter(template=True).values_list('id', 'name'))
577 template_choices=Experiment.objects.filter(template=True).values_list('id', 'name'))
578 else:
578 else:
579 kwargs['button'] = 'Create'
579 kwargs['button'] = 'Create'
580 kwargs['configurations'] = Configuration.objects.filter(experiment=request.GET['template'])
580 kwargs['configurations'] = Configuration.objects.filter(experiment=request.GET['template'])
581 kwargs['configuration_keys'] = ['name', 'device__name', 'device__ip_address', 'device__port_address']
581 kwargs['configuration_keys'] = ['name', 'device__name', 'device__ip_address', 'device__port_address']
582 exp=Experiment.objects.get(pk=request.GET['template'])
582 exp=Experiment.objects.get(pk=request.GET['template'])
583 form = ExperimentForm(instance=exp,
583 form = ExperimentForm(instance=exp,
584 initial={'name': '{} [{:%Y/%m/%d}]'.format(exp.name, datetime.now()),
584 initial={'name': '{} [{:%Y/%m/%d}]'.format(exp.name, datetime.now()),
585 'template': False})
585 'template': False})
586 elif 'blank' in request.GET:
586 elif 'blank' in request.GET:
587 kwargs['button'] = 'Create'
587 kwargs['button'] = 'Create'
588 form = ExperimentForm()
588 form = ExperimentForm()
589 else:
589 else:
590 form = NewForm()
590 form = NewForm()
591
591
592 if request.method == 'POST':
592 if request.method == 'POST':
593 form = ExperimentForm(request.POST)
593 form = ExperimentForm(request.POST)
594 if form.is_valid():
594 if form.is_valid():
595 experiment = form.save()
595 experiment = form.save()
596
596
597 if 'template' in request.GET:
597 if 'template' in request.GET:
598 configurations = Configuration.objects.filter(experiment=request.GET['template'], type=0)
598 configurations = Configuration.objects.filter(experiment=request.GET['template'], type=0)
599 for conf in configurations:
599 for conf in configurations:
600 conf.clone(experiment=experiment, template=False)
600 conf.clone(experiment=experiment, template=False)
601
601
602 return redirect('url_experiment', id_exp=experiment.id)
602 return redirect('url_experiment', id_exp=experiment.id)
603
603
604 kwargs['form'] = form
604 kwargs['form'] = form
605 kwargs['title'] = 'Experiment'
605 kwargs['title'] = 'Experiment'
606 kwargs['suptitle'] = 'New'
606 kwargs['suptitle'] = 'New'
607
607
608 return render(request, 'experiment_edit.html', kwargs)
608 return render(request, 'experiment_edit.html', kwargs)
609
609
610
610
611 @user_passes_test(lambda u:u.is_staff)
611 @user_passes_test(lambda u:u.is_staff)
612 def experiment_edit(request, id_exp):
612 def experiment_edit(request, id_exp):
613
613
614 experiment = get_object_or_404(Experiment, pk=id_exp)
614 experiment = get_object_or_404(Experiment, pk=id_exp)
615
615
616 if request.method == 'GET':
616 if request.method == 'GET':
617 form = ExperimentForm(instance=experiment)
617 form = ExperimentForm(instance=experiment)
618
618
619 if request.method=='POST':
619 if request.method=='POST':
620 form = ExperimentForm(request.POST, instance=experiment)
620 form = ExperimentForm(request.POST, instance=experiment)
621
621
622 if form.is_valid():
622 if form.is_valid():
623 experiment = form.save()
623 experiment = form.save()
624 return redirect('url_experiment', id_exp=experiment.id)
624 return redirect('url_experiment', id_exp=experiment.id)
625
625
626 kwargs = {}
626 kwargs = {}
627 kwargs['form'] = form
627 kwargs['form'] = form
628 kwargs['title'] = 'Experiment'
628 kwargs['title'] = 'Experiment'
629 kwargs['suptitle'] = 'Edit'
629 kwargs['suptitle'] = 'Edit'
630 kwargs['button'] = 'Update'
630 kwargs['button'] = 'Update'
631
631
632 return render(request, 'experiment_edit.html', kwargs)
632 return render(request, 'experiment_edit.html', kwargs)
633
633
634
634
635 @user_passes_test(lambda u:u.is_staff)
635 @user_passes_test(lambda u:u.is_staff)
636 def experiment_delete(request, id_exp):
636 def experiment_delete(request, id_exp):
637
637
638 experiment = get_object_or_404(Experiment, pk=id_exp)
638 experiment = get_object_or_404(Experiment, pk=id_exp)
639
639
640 if request.method=='POST':
640 if request.method=='POST':
641 if request.user.is_staff:
641 if request.user.is_staff:
642 for conf in Configuration.objects.filter(experiment=experiment):
642 for conf in Configuration.objects.filter(experiment=experiment):
643 conf.delete()
643 conf.delete()
644 experiment.delete()
644 experiment.delete()
645 return redirect('url_experiments')
645 return redirect('url_experiments')
646
646
647 messages.error(request, 'Not enough permission to delete this object')
647 messages.error(request, 'Not enough permission to delete this object')
648 return redirect(experiment.get_absolute_url())
648 return redirect(experiment.get_absolute_url())
649
649
650 kwargs = {
650 kwargs = {
651 'title': 'Delete',
651 'title': 'Delete',
652 'suptitle': 'Experiment',
652 'suptitle': 'Experiment',
653 'object': experiment,
653 'object': experiment,
654 'previous': experiment.get_absolute_url(),
654 'previous': experiment.get_absolute_url(),
655 'delete': True
655 'delete': True
656 }
656 }
657
657
658 return render(request, 'confirm.html', kwargs)
658 return render(request, 'confirm.html', kwargs)
659
659
660
660
661 @user_passes_test(lambda u:u.is_staff)
661 @user_passes_test(lambda u:u.is_staff)
662 def experiment_export(request, id_exp):
662 def experiment_export(request, id_exp):
663
663
664 experiment = get_object_or_404(Experiment, pk=id_exp)
664 experiment = get_object_or_404(Experiment, pk=id_exp)
665 content = experiment.parms_to_dict()
665 content = experiment.parms_to_dict()
666 content_type = 'application/json'
666 content_type = 'application/json'
667 filename = '%s_%s.json' %(experiment.name, experiment.id)
667 filename = '%s_%s.json' %(experiment.name, experiment.id)
668
668
669 response = HttpResponse(content_type=content_type)
669 response = HttpResponse(content_type=content_type)
670 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
670 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
671 response.write(content)
671 response.write(content)
672
672
673 return response
673 return response
674
674
675
675
676 @user_passes_test(lambda u:u.is_staff)
676 @user_passes_test(lambda u:u.is_staff)
677 def experiment_import(request, id_exp):
677 def experiment_import(request, id_exp):
678
678
679 experiment = get_object_or_404(Experiment, pk=id_exp)
679 experiment = get_object_or_404(Experiment, pk=id_exp)
680 configurations = Configuration.objects.filter(experiment=experiment)
680 configurations = Configuration.objects.filter(experiment=experiment)
681
681
682 if request.method == 'GET':
682 if request.method == 'GET':
683 file_form = UploadFileForm()
683 file_form = UploadFileForm()
684
684
685 if request.method == 'POST':
685 if request.method == 'POST':
686 file_form = UploadFileForm(request.POST, request.FILES)
686 file_form = UploadFileForm(request.POST, request.FILES)
687
687
688 if file_form.is_valid():
688 if file_form.is_valid():
689
689
690 parms = experiment.import_from_file(request.FILES['file'])
690 parms = experiment.import_from_file(request.FILES['file'])
691
691
692 if parms:
692 if parms:
693
693
694 new_exp = experiment.dict_to_parms(parms, CONF_MODELS)
694 new_exp = experiment.dict_to_parms(parms, CONF_MODELS)
695
695
696 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
696 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
697
697
698 return redirect(new_exp.get_absolute_url_edit())
698 return redirect(new_exp.get_absolute_url_edit())
699
699
700 messages.error(request, "Could not import parameters from file")
700 messages.error(request, "Could not import parameters from file")
701
701
702 kwargs = {}
702 kwargs = {}
703 kwargs['title'] = 'Experiment'
703 kwargs['title'] = 'Experiment'
704 kwargs['form'] = file_form
704 kwargs['form'] = file_form
705 kwargs['suptitle'] = 'Importing file'
705 kwargs['suptitle'] = 'Importing file'
706 kwargs['button'] = 'Import'
706 kwargs['button'] = 'Import'
707
707
708 kwargs.update(sidebar(experiment=experiment))
708 kwargs.update(sidebar(experiment=experiment))
709
709
710 return render(request, 'experiment_import.html', kwargs)
710 return render(request, 'experiment_import.html', kwargs)
711
711
712
712
713 @user_passes_test(lambda u:u.is_staff)
713 @user_passes_test(lambda u:u.is_staff)
714 def experiment_mix(request, id_exp):
714 def experiment_mix(request, id_exp):
715
715
716 experiment = get_object_or_404(Experiment, pk=id_exp)
716 experiment = get_object_or_404(Experiment, pk=id_exp)
717 rc_confs = [conf for conf in RCConfiguration.objects.filter(experiment=id_exp,
717 rc_confs = [conf for conf in RCConfiguration.objects.filter(experiment=id_exp,
718 mix=False)]
718 mix=False)]
719
719
720 if len(rc_confs)<2:
720 if len(rc_confs)<2:
721 messages.warning(request, 'You need at least two RC Configurations to make a mix')
721 messages.warning(request, 'You need at least two RC Configurations to make a mix')
722 return redirect(experiment.get_absolute_url())
722 return redirect(experiment.get_absolute_url())
723
723
724 mix_confs = RCConfiguration.objects.filter(experiment=id_exp, mix=True)
724 mix_confs = RCConfiguration.objects.filter(experiment=id_exp, mix=True)
725
725
726 if mix_confs:
726 if mix_confs:
727 mix = mix_confs[0]
727 mix = mix_confs[0]
728 else:
728 else:
729 mix = RCConfiguration(experiment=experiment,
729 mix = RCConfiguration(experiment=experiment,
730 device=rc_confs[0].device,
730 device=rc_confs[0].device,
731 ipp=rc_confs[0].ipp,
731 ipp=rc_confs[0].ipp,
732 clock_in=rc_confs[0].clock_in,
732 clock_in=rc_confs[0].clock_in,
733 clock_divider=rc_confs[0].clock_divider,
733 clock_divider=rc_confs[0].clock_divider,
734 mix=True,
734 mix=True,
735 parameters='')
735 parameters='')
736 mix.save()
736 mix.save()
737
737
738 line_type = RCLineType.objects.get(name='mix')
738 line_type = RCLineType.objects.get(name='mix')
739 for i in range(len(rc_confs[0].get_lines())):
739 for i in range(len(rc_confs[0].get_lines())):
740 line = RCLine(rc_configuration=mix, line_type=line_type, channel=i)
740 line = RCLine(rc_configuration=mix, line_type=line_type, channel=i)
741 line.save()
741 line.save()
742
742
743 initial = {'name': mix.name,
743 initial = {'name': mix.name,
744 'result': parse_mix_result(mix.parameters),
744 'result': parse_mix_result(mix.parameters),
745 'delay': 0,
745 'delay': 0,
746 'mask': [0,1,2,3,4,5,6,7]
746 'mask': [0,1,2,3,4,5,6,7]
747 }
747 }
748
748
749 if request.method=='GET':
749 if request.method=='GET':
750 form = RCMixConfigurationForm(confs=rc_confs, initial=initial)
750 form = RCMixConfigurationForm(confs=rc_confs, initial=initial)
751
751
752 if request.method=='POST':
752 if request.method=='POST':
753 result = mix.parameters
753 result = mix.parameters
754
754
755 if '{}|'.format(request.POST['experiment']) in result:
755 if '{}|'.format(request.POST['experiment']) in result:
756 messages.error(request, 'Configuration already added')
756 messages.error(request, 'Configuration already added')
757 else:
757 else:
758 if 'operation' in request.POST:
758 if 'operation' in request.POST:
759 operation = MIX_OPERATIONS[request.POST['operation']]
759 operation = MIX_OPERATIONS[request.POST['operation']]
760 else:
760 else:
761 operation = ' '
761 operation = ' '
762
762
763 mode = MIX_MODES[request.POST['mode']]
763 mode = MIX_MODES[request.POST['mode']]
764
764
765 if result:
765 if result:
766 result = '{}-{}|{}|{}|{}|{}'.format(mix.parameters,
766 result = '{}-{}|{}|{}|{}|{}'.format(mix.parameters,
767 request.POST['experiment'],
767 request.POST['experiment'],
768 mode,
768 mode,
769 operation,
769 operation,
770 float(request.POST['delay']),
770 float(request.POST['delay']),
771 parse_mask(request.POST.getlist('mask'))
771 parse_mask(request.POST.getlist('mask'))
772 )
772 )
773 else:
773 else:
774 result = '{}|{}|{}|{}|{}'.format(request.POST['experiment'],
774 result = '{}|{}|{}|{}|{}'.format(request.POST['experiment'],
775 mode,
775 mode,
776 operation,
776 operation,
777 float(request.POST['delay']),
777 float(request.POST['delay']),
778 parse_mask(request.POST.getlist('mask'))
778 parse_mask(request.POST.getlist('mask'))
779 )
779 )
780
780
781 mix.parameters = result
781 mix.parameters = result
782 mix.name = request.POST['name']
782 mix.name = request.POST['name']
783 mix.save()
783 mix.save()
784 mix.update_pulses()
784 mix.update_pulses()
785
785
786 initial['result'] = parse_mix_result(result)
786 initial['result'] = parse_mix_result(result)
787 initial['name'] = mix.name
787 initial['name'] = mix.name
788
788
789 form = RCMixConfigurationForm(initial=initial, confs=rc_confs)
789 form = RCMixConfigurationForm(initial=initial, confs=rc_confs)
790
790
791
791
792 kwargs = {
792 kwargs = {
793 'title': 'Experiment',
793 'title': 'Experiment',
794 'suptitle': 'Mix Configurations',
794 'suptitle': 'Mix Configurations',
795 'form' : form,
795 'form' : form,
796 'extra_button': 'Delete',
796 'extra_button': 'Delete',
797 'button': 'Add',
797 'button': 'Add',
798 'cancel': 'Back',
798 'cancel': 'Back',
799 'previous': experiment.get_absolute_url(),
799 'previous': experiment.get_absolute_url(),
800 'id_exp':id_exp,
800 'id_exp':id_exp,
801
801
802 }
802 }
803
803
804 return render(request, 'experiment_mix.html', kwargs)
804 return render(request, 'experiment_mix.html', kwargs)
805
805
806
806
807 @user_passes_test(lambda u:u.is_staff)
807 @user_passes_test(lambda u:u.is_staff)
808 def experiment_mix_delete(request, id_exp):
808 def experiment_mix_delete(request, id_exp):
809
809
810 conf = RCConfiguration.objects.get(experiment=id_exp, mix=True)
810 conf = RCConfiguration.objects.get(experiment=id_exp, mix=True)
811 values = conf.parameters.split('-')
811 values = conf.parameters.split('-')
812 conf.parameters = '-'.join(values[:-1])
812 conf.parameters = '-'.join(values[:-1])
813 conf.save()
813 conf.save()
814
814
815 return redirect('url_mix_experiment', id_exp=id_exp)
815 return redirect('url_mix_experiment', id_exp=id_exp)
816
816
817
817
818
818
819 def experiment_summary(request, id_exp):
819 def experiment_summary(request, id_exp):
820
820
821 import json
821 import json
822 import ast
822 import ast
823
823
824 experiment = get_object_or_404(Experiment, pk=id_exp)
824 experiment = get_object_or_404(Experiment, pk=id_exp)
825 experiment_data = json.loads(experiment.parms_to_dict())
825 experiment_data = json.loads(experiment.parms_to_dict())
826 configurations = Configuration.objects.filter(experiment=experiment, type=0)
826 configurations = Configuration.objects.filter(experiment=experiment, type=0)
827
827
828 kwargs = {}
828 kwargs = {}
829
829
830 kwargs['experiment_keys'] = ['radar_system', 'name', 'start_time', 'end_time']
830 kwargs['experiment_keys'] = ['radar_system', 'name', 'start_time', 'end_time']
831 kwargs['experiment'] = experiment
831 kwargs['experiment'] = experiment
832
832
833 kwargs['configuration_keys'] = ['name', 'device__ip_address', 'device__port_address', 'device__status']
833 kwargs['configuration_keys'] = ['name', 'device__ip_address', 'device__port_address', 'device__status']
834 kwargs['configurations'] = configurations
834 kwargs['configurations'] = configurations
835 kwargs['experiment_data'] = experiment_data
835 kwargs['experiment_data'] = experiment_data
836
836
837 kwargs['title'] = 'Experiment Summary'
837 kwargs['title'] = 'Experiment Summary'
838 kwargs['suptitle'] = 'Details'
838 kwargs['suptitle'] = 'Details'
839
839
840 kwargs['button'] = 'Verify Parameters'
840 kwargs['button'] = 'Verify Parameters'
841
841
842 jars_conf = False
842 jars_conf = False
843 rc_conf = False
843 rc_conf = False
844
844
845 for configuration in configurations:
845 for configuration in configurations:
846 #-------------------- JARS -----------------------:
846 #-------------------- JARS -----------------------:
847 if configuration.device.device_type.name == 'jars':
847 if configuration.device.device_type.name == 'jars':
848 jars_conf = True
848 jars_conf = True
849 kwargs['jars_conf'] = jars_conf
849 kwargs['jars_conf'] = jars_conf
850 kwargs['exp_type'] = EXPERIMENT_TYPE[configuration.exp_type][1]
850 kwargs['exp_type'] = EXPERIMENT_TYPE[configuration.exp_type][1]
851 channels_number = configuration.channels_number
851 channels_number = configuration.channels_number
852 exp_type = configuration.exp_type
852 exp_type = configuration.exp_type
853 fftpoints = configuration.fftpoints
853 fftpoints = configuration.fftpoints
854 filter_parms = configuration.filter_parms
854 filter_parms = configuration.filter_parms
855 filter_parms = ast.literal_eval(filter_parms)
855 filter_parms = ast.literal_eval(filter_parms)
856 spectral_number = configuration.spectral_number
856 spectral_number = configuration.spectral_number
857
857
858 #--------------------- RC ----------------------:
858 #--------------------- RC ----------------------:
859 if configuration.device.device_type.name == 'rc':
859 if configuration.device.device_type.name == 'rc':
860 rc_conf = True
860 rc_conf = True
861 kwargs['rc_conf'] = rc_conf
861 kwargs['rc_conf'] = rc_conf
862 rc_lines = experiment_data['configurations']['rc']['lines']
862 rc_lines = experiment_data['configurations']['rc']['lines']
863 ipp = configuration.ipp
863 ipp = configuration.ipp
864 if experiment_data['configurations']['rc']['mix'] == 'True':
864 if experiment_data['configurations']['rc']['mix'] == 'True':
865 code = ''
865 code = ''
866 else:
866 else:
867 code = rc_lines[3]['code']
867 code = rc_lines[3]['code']
868
868
869 kwargs['code'] = code
869 kwargs['code'] = code
870
870
871 #---Jueves 01-12-2016---
871 #---Jueves 01-12-2016---
872
872
873 lines = configuration.get_lines()
873 lines = configuration.get_lines()
874
874
875 if lines:
875 if lines:
876
876
877 #TX Delays (TAU)
877 #TX Delays (TAU)
878 rc_delays_num = 0
878 rc_delays_num = 0
879 rc_delays = ''
879 rc_delays = ''
880 tx_lines = configuration.get_lines(line_type__name='tx')
880 tx_lines = configuration.get_lines(line_type__name='tx')
881 for tx_line in tx_lines:
881 for tx_line in tx_lines:
882 if len(tx_lines) < 2:
882 if len(tx_lines) < 2:
883 rc_delay = json.loads(tx_line.params)
883 rc_delay = json.loads(tx_line.params)
884 rc_delays = rc_delays+tx_line.get_name()+': '+rc_delay['delays']+'\n'
884 rc_delays = rc_delays+tx_line.get_name()+': '+rc_delay['delays']+'\n'
885 delay = ast.literal_eval(rc_delay['delays'])
885 delay = ast.literal_eval(rc_delay['delays'])
886 if isinstance(delay,int):
886 if isinstance(delay,int):
887 rc_delays_num += 1
887 rc_delays_num += 1
888 else:
888 else:
889 rc_delays_num += len(delay)
889 rc_delays_num += len(delay)
890 else:
890 else:
891 rc_delay = json.loads(tx_line.params)
891 rc_delay = json.loads(tx_line.params)
892 rc_delays = rc_delays+tx_line.get_name()+': '+rc_delay['delays']+'\n'
892 rc_delays = rc_delays+tx_line.get_name()+': '+rc_delay['delays']+'\n'
893 delay = ast.literal_eval(rc_delay['delays'])
893 delay = ast.literal_eval(rc_delay['delays'])
894 if isinstance(delay,int):
894 if isinstance(delay,int):
895 rc_delays_num += 1
895 rc_delays_num += 1
896 else:
896 else:
897 rc_delays_num += len(delay)
897 rc_delays_num += len(delay)
898
898
899 #TX: TXA - TXB...
899 #TX: TXA - TXB...
900 for tx_line in tx_lines:
900 for tx_line in tx_lines:
901 tx_line.name = tx_line.get_name()
901 tx_line.name = tx_line.get_name()
902 tx_line_parameters = json.loads(tx_line.params)
902 tx_line_parameters = json.loads(tx_line.params)
903 tx_line.parameters = tx_line_parameters
903 tx_line.parameters = tx_line_parameters
904
904
905 #WINDOWS
905 #WINDOWS
906 windows_lines = configuration.get_lines(line_type__name='windows')
906 windows_lines = configuration.get_lines(line_type__name='windows')
907 for windows_line in windows_lines:
907 for windows_line in windows_lines:
908 windows_line.name = windows_line.get_name()
908 windows_line.name = windows_line.get_name()
909 windows_data = json.loads(windows_line.params)
909 windows_data = json.loads(windows_line.params)
910 windows_params = windows_data['params'][0]
910 windows_params = windows_data['params'][0]
911 h0 = str(windows_params['first_height'])
911 h0 = str(windows_params['first_height'])
912 dh = str(windows_params['resolution'])
912 dh = str(windows_params['resolution'])
913 nsa = str(windows_params['number_of_samples'])
913 nsa = str(windows_params['number_of_samples'])
914 windows_line.parameters = 'Ho=' + h0 +'km\nDH=' + dh +'km\nNSA=' + nsa
914 windows_line.parameters = 'Ho=' + h0 +'km\nDH=' + dh +'km\nNSA=' + nsa
915
915
916 #CODES
916 #CODES
917 code_lines = configuration.get_lines(line_type__name='codes')
917 code_lines = configuration.get_lines(line_type__name='codes')
918 for code_line in code_lines:
918 for code_line in code_lines:
919 code_line.name = code_line.get_name()
919 code_line.name = code_line.get_name()
920 line_params = json.loads(code_line.params)
920 line_params = json.loads(code_line.params)
921 rccode = RCLineCode.objects.get(pk=int(line_params['code']))
921 rccode = RCLineCode.objects.get(pk=int(line_params['code']))
922 code_line.code_name = rccode.name
922 code_line.code_name = rccode.name
923
923
924 #PROG_PULSES
924 #PROG_PULSES
925 progpulses_lines = configuration.get_lines(line_type__name='prog_pulses')
925 progpulses_lines = configuration.get_lines(line_type__name='prog_pulses')
926 for progpulses_line in progpulses_lines:
926 for progpulses_line in progpulses_lines:
927 progpulses_line.name = progpulses_line.get_name()
927 progpulses_line.name = progpulses_line.get_name()
928 progpulses_parameters = json.loads(progpulses_line.params)
928 progpulses_parameters = json.loads(progpulses_line.params)
929 progpulses_parameters = progpulses_parameters['params'][0]
929 progpulses_parameters = progpulses_parameters['params'][0]
930 progpulses_line.parameters = 'Begin: '+str(progpulses_parameters['begin'])+' (Units)\nEnd: '+str(progpulses_parameters['end'])+' (Units)'
930 progpulses_line.parameters = 'Begin: '+str(progpulses_parameters['begin'])+' (Units)\nEnd: '+str(progpulses_parameters['end'])+' (Units)'
931
931
932
932
933
933
934 #kwargs['kwargs_channels'] = sorted(kwargs_channels, reverse=True)
934 #kwargs['kwargs_channels'] = sorted(kwargs_channels, reverse=True)
935 kwargs['lines'] = sorted(lines, reverse=True)
935 kwargs['lines'] = sorted(lines, reverse=True)
936 kwargs['rc_delays'] = rc_delays
936 kwargs['rc_delays'] = rc_delays
937 kwargs['rc_delays_num'] = rc_delays_num
937 kwargs['rc_delays_num'] = rc_delays_num
938 kwargs['tx_lines'] = tx_lines
938 kwargs['tx_lines'] = tx_lines
939 kwargs['windows_lines'] = windows_lines
939 kwargs['windows_lines'] = windows_lines
940 kwargs['code_lines'] = code_lines
940 kwargs['code_lines'] = code_lines
941 kwargs['progpulses_lines'] = progpulses_lines
941 kwargs['progpulses_lines'] = progpulses_lines
942
942
943
943
944 #--FIN: Jueves 01-12-2016---
944 #--FIN: Jueves 01-12-2016---
945
945
946 #-------------------- DDS -----------------------:
946 #-------------------- DDS -----------------------:
947 if configuration.device.device_type.name == 'dds':
947 if configuration.device.device_type.name == 'dds':
948 dds_conf = True
948 dds_conf = True
949 kwargs['dds_conf'] = dds_conf
949 kwargs['dds_conf'] = dds_conf
950
950
951 #------ RC & JARS ------:
951 #------ RC & JARS ------:
952 ipp = 937.5 #
952 ipp = 937.5 #
953 nsa = 200#
953 nsa = 200#
954 dh = 1.5 #
954 dh = 1.5 #
955 channels_number = 5 #
955 channels_number = 5 #
956
956
957 if rc_conf and jars_conf:
957 if rc_conf and jars_conf:
958 if exp_type == 0: #Short
958 if exp_type == 0: #Short
959 bytes = 2
959 bytes = 2
960 b = nsa*2*bytes*channels_number
960 b = nsa*2*bytes*channels_number
961 else: #Float
961 else: #Float
962 bytes = 4
962 bytes = 4
963 channels = channels_number + spectral_number
963 channels = channels_number + spectral_number
964 b = nsa*2*bytes*fftpoints*channels
964 b = nsa*2*bytes*fftpoints*channels
965
965
966 ipps = (ipp*pow(10,-6))/0.15
966 ipps = (ipp*pow(10,-6))/0.15
967 GB = 1048576.0*1024.0
967 GB = 1048576.0*1024.0
968 Hour = 3600
968 Hour = 3600
969 rate = b/ipps
969 rate = b/ipps
970 rate = rate *(1/GB)*(Hour)
970 rate = rate *(1/GB)*(Hour)
971 kwargs['rate'] = str(rate)+" GB/h"
971 kwargs['rate'] = str(rate)+" GB/h"
972 else:
972 else:
973 kwargs['rate'] = ''
973 kwargs['rate'] = ''
974
974
975 ###### SIDEBAR ######
975 ###### SIDEBAR ######
976 kwargs.update(sidebar(experiment=experiment))
976 kwargs.update(sidebar(experiment=experiment))
977
977
978 return render(request, 'experiment_summary.html', kwargs)
978 return render(request, 'experiment_summary.html', kwargs)
979
979
980
980
981 @user_passes_test(lambda u:u.is_staff)
981 @user_passes_test(lambda u:u.is_staff)
982 def experiment_verify(request, id_exp):
982 def experiment_verify(request, id_exp):
983
983
984 import json
984 import json
985 import ast
985 import ast
986
986
987 experiment = get_object_or_404(Experiment, pk=id_exp)
987 experiment = get_object_or_404(Experiment, pk=id_exp)
988 experiment_data = json.loads(experiment.parms_to_dict())
988 experiment_data = json.loads(experiment.parms_to_dict())
989 configurations = Configuration.objects.filter(experiment=experiment, type=0)
989 configurations = Configuration.objects.filter(experiment=experiment, type=0)
990
990
991 kwargs = {}
991 kwargs = {}
992
992
993 kwargs['experiment_keys'] = ['template', 'radar_system', 'name', 'start_time', 'end_time']
993 kwargs['experiment_keys'] = ['template', 'radar_system', 'name', 'start_time', 'end_time']
994 kwargs['experiment'] = experiment
994 kwargs['experiment'] = experiment
995
995
996 kwargs['configuration_keys'] = ['name', 'device__ip_address', 'device__port_address', 'device__status']
996 kwargs['configuration_keys'] = ['name', 'device__ip_address', 'device__port_address', 'device__status']
997 kwargs['configurations'] = configurations
997 kwargs['configurations'] = configurations
998 kwargs['experiment_data'] = experiment_data
998 kwargs['experiment_data'] = experiment_data
999
999
1000 kwargs['title'] = 'Verify Experiment'
1000 kwargs['title'] = 'Verify Experiment'
1001 kwargs['suptitle'] = 'Parameters'
1001 kwargs['suptitle'] = 'Parameters'
1002
1002
1003 kwargs['button'] = 'Update'
1003 kwargs['button'] = 'Update'
1004
1004
1005 jars_conf = False
1005 jars_conf = False
1006 rc_conf = False
1006 rc_conf = False
1007 dds_conf = False
1007 dds_conf = False
1008
1008
1009 for configuration in configurations:
1009 for configuration in configurations:
1010 #-------------------- JARS -----------------------:
1010 #-------------------- JARS -----------------------:
1011 if configuration.device.device_type.name == 'jars':
1011 if configuration.device.device_type.name == 'jars':
1012 jars_conf = True
1012 jars_conf = True
1013 jars = configuration
1013 jars = configuration
1014 kwargs['jars_conf'] = jars_conf
1014 kwargs['jars_conf'] = jars_conf
1015 filter_parms = configuration.filter_parms
1015 filter_parms = configuration.filter_parms
1016 filter_parms = ast.literal_eval(filter_parms)
1016 filter_parms = ast.literal_eval(filter_parms)
1017 kwargs['filter_parms'] = filter_parms
1017 kwargs['filter_parms'] = filter_parms
1018 #--Sampling Frequency
1018 #--Sampling Frequency
1019 clock = filter_parms['clock']
1019 clock = filter_parms['clock']
1020 filter_2 = filter_parms['filter_2']
1020 filter_2 = filter_parms['filter_2']
1021 filter_5 = filter_parms['filter_5']
1021 filter_5 = filter_parms['filter_5']
1022 filter_fir = filter_parms['filter_fir']
1022 filter_fir = filter_parms['filter_fir']
1023 samp_freq_jars = clock/filter_2/filter_5/filter_fir
1023 samp_freq_jars = clock/filter_2/filter_5/filter_fir
1024
1024
1025 kwargs['samp_freq_jars'] = samp_freq_jars
1025 kwargs['samp_freq_jars'] = samp_freq_jars
1026 kwargs['jars'] = configuration
1026 kwargs['jars'] = configuration
1027
1027
1028 #--------------------- RC ----------------------:
1028 #--------------------- RC ----------------------:
1029 if configuration.device.device_type.name == 'rc':
1029 if configuration.device.device_type.name == 'rc':
1030 rc_conf = True
1030 rc_conf = True
1031 rc = configuration
1031 rc = configuration
1032 rc_parms = configuration.parms_to_dict()
1032 rc_parms = configuration.parms_to_dict()
1033 if rc_parms['mix'] == 'True':
1033 if rc_parms['mix'] == 'True':
1034 pass
1034 pass
1035 else:
1035 else:
1036 rc_lines = rc_parms['lines']
1036 rc_lines = rc_parms['lines']
1037 dh = rc_lines[6]['params'][0]['resolution']
1037 dh = rc_lines[6]['params'][0]['resolution']
1038 #--Sampling Frequency
1038 #--Sampling Frequency
1039 samp_freq_rc = 0.15/dh
1039 samp_freq_rc = 0.15/dh
1040 kwargs['samp_freq_rc'] = samp_freq_rc
1040 kwargs['samp_freq_rc'] = samp_freq_rc
1041
1041
1042 kwargs['rc_conf'] = rc_conf
1042 kwargs['rc_conf'] = rc_conf
1043 kwargs['rc'] = configuration
1043 kwargs['rc'] = configuration
1044
1044
1045 #-------------------- DDS ----------------------:
1045 #-------------------- DDS ----------------------:
1046 if configuration.device.device_type.name == 'dds':
1046 if configuration.device.device_type.name == 'dds':
1047 dds_conf = True
1047 dds_conf = True
1048 dds = configuration
1048 dds = configuration
1049 dds_parms = configuration.parms_to_dict()
1049 dds_parms = configuration.parms_to_dict()
1050
1050
1051 kwargs['dds_conf'] = dds_conf
1051 kwargs['dds_conf'] = dds_conf
1052 kwargs['dds'] = configuration
1052 kwargs['dds'] = configuration
1053
1053
1054
1054
1055 #------------Validation------------:
1055 #------------Validation------------:
1056 #Clock
1056 #Clock
1057 if dds_conf and rc_conf and jars_conf:
1057 if dds_conf and rc_conf and jars_conf:
1058 if float(filter_parms['clock']) != float(rc_parms['clock_in']) and float(rc_parms['clock_in']) != float(dds_parms['clock']):
1058 if float(filter_parms['clock']) != float(rc_parms['clock_in']) and float(rc_parms['clock_in']) != float(dds_parms['clock']):
1059 messages.warning(request, "Devices don't have the same clock.")
1059 messages.warning(request, "Devices don't have the same clock.")
1060 elif rc_conf and jars_conf:
1060 elif rc_conf and jars_conf:
1061 if float(filter_parms['clock']) != float(rc_parms['clock_in']):
1061 if float(filter_parms['clock']) != float(rc_parms['clock_in']):
1062 messages.warning(request, "Devices don't have the same clock.")
1062 messages.warning(request, "Devices don't have the same clock.")
1063 elif rc_conf and dds_conf:
1063 elif rc_conf and dds_conf:
1064 if float(rc_parms['clock_in']) != float(dds_parms['clock']):
1064 if float(rc_parms['clock_in']) != float(dds_parms['clock']):
1065 messages.warning(request, "Devices don't have the same clock.")
1065 messages.warning(request, "Devices don't have the same clock.")
1066 if float(samp_freq_rc) != float(dds_parms['frequencyA']):
1066 if float(samp_freq_rc) != float(dds_parms['frequencyA']):
1067 messages.warning(request, "Devices don't have the same Frequency A.")
1067 messages.warning(request, "Devices don't have the same Frequency A.")
1068
1068
1069
1069
1070 #------------POST METHOD------------:
1070 #------------POST METHOD------------:
1071 if request.method == 'POST':
1071 if request.method == 'POST':
1072 if request.POST['suggest_clock']:
1072 if request.POST['suggest_clock']:
1073 try:
1073 try:
1074 suggest_clock = float(request.POST['suggest_clock'])
1074 suggest_clock = float(request.POST['suggest_clock'])
1075 except:
1075 except:
1076 messages.warning(request, "Invalid value in CLOCK IN.")
1076 messages.warning(request, "Invalid value in CLOCK IN.")
1077 return redirect('url_verify_experiment', id_exp=experiment.id)
1077 return redirect('url_verify_experiment', id_exp=experiment.id)
1078 else:
1078 else:
1079 suggest_clock = ""
1079 suggest_clock = ""
1080 if suggest_clock:
1080 if suggest_clock:
1081 if rc_conf:
1081 if rc_conf:
1082 rc.clock_in = suggest_clock
1082 rc.clock_in = suggest_clock
1083 rc.save()
1083 rc.save()
1084 if jars_conf:
1084 if jars_conf:
1085 filter_parms = jars.filter_parms
1085 filter_parms = jars.filter_parms
1086 filter_parms = ast.literal_eval(filter_parms)
1086 filter_parms = ast.literal_eval(filter_parms)
1087 filter_parms['clock'] = suggest_clock
1087 filter_parms['clock'] = suggest_clock
1088 jars.filter_parms = json.dumps(filter_parms)
1088 jars.filter_parms = json.dumps(filter_parms)
1089 jars.save()
1089 jars.save()
1090 kwargs['filter_parms'] = filter_parms
1090 kwargs['filter_parms'] = filter_parms
1091 if dds_conf:
1091 if dds_conf:
1092 dds.clock = suggest_clock
1092 dds.clock = suggest_clock
1093 dds.save()
1093 dds.save()
1094
1094
1095 if request.POST['suggest_frequencyA']:
1095 if request.POST['suggest_frequencyA']:
1096 try:
1096 try:
1097 suggest_frequencyA = float(request.POST['suggest_frequencyA'])
1097 suggest_frequencyA = float(request.POST['suggest_frequencyA'])
1098 except:
1098 except:
1099 messages.warning(request, "Invalid value in FREQUENCY A.")
1099 messages.warning(request, "Invalid value in FREQUENCY A.")
1100 return redirect('url_verify_experiment', id_exp=experiment.id)
1100 return redirect('url_verify_experiment', id_exp=experiment.id)
1101 else:
1101 else:
1102 suggest_frequencyA = ""
1102 suggest_frequencyA = ""
1103 if suggest_frequencyA:
1103 if suggest_frequencyA:
1104 if jars_conf:
1104 if jars_conf:
1105 filter_parms = jars.filter_parms
1105 filter_parms = jars.filter_parms
1106 filter_parms = ast.literal_eval(filter_parms)
1106 filter_parms = ast.literal_eval(filter_parms)
1107 filter_parms['fch'] = suggest_frequencyA
1107 filter_parms['fch'] = suggest_frequencyA
1108 jars.filter_parms = json.dumps(filter_parms)
1108 jars.filter_parms = json.dumps(filter_parms)
1109 jars.save()
1109 jars.save()
1110 kwargs['filter_parms'] = filter_parms
1110 kwargs['filter_parms'] = filter_parms
1111 if dds_conf:
1111 if dds_conf:
1112 dds.frequencyA_Mhz = request.POST['suggest_frequencyA']
1112 dds.frequencyA_Mhz = request.POST['suggest_frequencyA']
1113 dds.save()
1113 dds.save()
1114
1114
1115 ###### SIDEBAR ######
1115 ###### SIDEBAR ######
1116 kwargs.update(sidebar(experiment=experiment))
1116 kwargs.update(sidebar(experiment=experiment))
1117
1117
1118
1118
1119
1119
1120
1120
1121
1121
1122 return render(request, 'experiment_verify.html', kwargs)
1122 return render(request, 'experiment_verify.html', kwargs)
1123
1123
1124
1124
1125 @user_passes_test(lambda u:u.is_staff)
1125 #@user_passes_test(lambda u:u.is_staff)
1126 def parse_mix_result(s):
1126 def parse_mix_result(s):
1127
1127
1128 values = s.split('-')
1128 values = s.split('-')
1129 html = 'EXP MOD OPE DELAY MASK\r\n'
1129 html = 'EXP MOD OPE DELAY MASK\r\n'
1130
1130
1131 if not values or values[0] in ('', ' '):
1131 if not values or values[0] in ('', ' '):
1132 return mark_safe(html)
1132 return mark_safe(html)
1133
1133
1134 for i, value in enumerate(values):
1134 for i, value in enumerate(values):
1135 if not value:
1135 if not value:
1136 continue
1136 continue
1137 pk, mode, operation, delay, mask = value.split('|')
1137 pk, mode, operation, delay, mask = value.split('|')
1138 conf = RCConfiguration.objects.get(pk=pk)
1138 conf = RCConfiguration.objects.get(pk=pk)
1139 if i==0:
1139 if i==0:
1140 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1140 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1141 conf.name,
1141 conf.name,
1142 mode,
1142 mode,
1143 ' ',
1143 ' ',
1144 delay,
1144 delay,
1145 mask)
1145 mask)
1146 else:
1146 else:
1147 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1147 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1148 conf.name,
1148 conf.name,
1149 mode,
1149 mode,
1150 operation,
1150 operation,
1151 delay,
1151 delay,
1152 mask)
1152 mask)
1153
1153
1154 return mark_safe(html)
1154 return mark_safe(html)
1155
1155
1156 def parse_mask(l):
1156 def parse_mask(l):
1157
1157
1158 values = []
1158 values = []
1159
1159
1160 for x in range(8):
1160 for x in range(8):
1161 if '{}'.format(x) in l:
1161 if '{}'.format(x) in l:
1162 values.append(1)
1162 values.append(1)
1163 else:
1163 else:
1164 values.append(0)
1164 values.append(0)
1165
1165
1166 values.reverse()
1166 values.reverse()
1167
1167
1168 return int(''.join([str(x) for x in values]), 2)
1168 return int(''.join([str(x) for x in values]), 2)
1169
1169
1170
1170
1171 def dev_confs(request):
1171 def dev_confs(request):
1172
1172
1173
1173
1174 page = request.GET.get('page')
1174 page = request.GET.get('page')
1175 order = ('type', 'device__device_type', 'experiment')
1175 order = ('type', 'device__device_type', 'experiment')
1176 filters = request.GET.copy()
1176 filters = request.GET.copy()
1177
1177
1178 kwargs = get_paginator(Configuration, page, order, filters)
1178 kwargs = get_paginator(Configuration, page, order, filters)
1179
1179
1180 form = FilterForm(initial=request.GET, extra_fields=['tags','template'])
1180 form = FilterForm(initial=request.GET, extra_fields=['tags','template'])
1181 kwargs['keys'] = ['name', 'experiment', 'type', 'programmed_date']
1181 kwargs['keys'] = ['name', 'experiment', 'type', 'programmed_date']
1182 kwargs['title'] = 'Configuration'
1182 kwargs['title'] = 'Configuration'
1183 kwargs['suptitle'] = 'List'
1183 kwargs['suptitle'] = 'List'
1184 kwargs['no_sidebar'] = True
1184 kwargs['no_sidebar'] = True
1185 kwargs['form'] = form
1185 kwargs['form'] = form
1186 filters.pop('page', None)
1186 filters.pop('page', None)
1187 kwargs['q'] = urlencode(filters)
1187 kwargs['q'] = urlencode(filters)
1188
1188
1189 return render(request, 'base_list.html', kwargs)
1189 return render(request, 'base_list.html', kwargs)
1190
1190
1191
1191
1192 def dev_conf(request, id_conf):
1192 def dev_conf(request, id_conf):
1193
1193
1194 conf = get_object_or_404(Configuration, pk=id_conf)
1194 conf = get_object_or_404(Configuration, pk=id_conf)
1195
1195
1196 return redirect(conf.get_absolute_url())
1196 return redirect(conf.get_absolute_url())
1197
1197
1198
1198
1199 @user_passes_test(lambda u:u.is_staff)
1199 @user_passes_test(lambda u:u.is_staff)
1200 def dev_conf_new(request, id_exp=0, id_dev=0):
1200 def dev_conf_new(request, id_exp=0, id_dev=0):
1201
1201
1202 initial = {}
1202 initial = {}
1203 kwargs = {}
1203 kwargs = {}
1204
1204
1205 if id_exp!=0:
1205 if id_exp!=0:
1206 initial['experiment'] = id_exp
1206 initial['experiment'] = id_exp
1207
1207
1208 if id_dev!=0:
1208 if id_dev!=0:
1209 initial['device'] = id_dev
1209 initial['device'] = id_dev
1210
1210
1211 if request.method == 'GET':
1211 if request.method == 'GET':
1212
1212
1213 if id_dev:
1213 if id_dev:
1214 kwargs['button'] = 'Create'
1214 kwargs['button'] = 'Create'
1215 device = Device.objects.get(pk=id_dev)
1215 device = Device.objects.get(pk=id_dev)
1216 DevConfForm = CONF_FORMS[device.device_type.name]
1216 DevConfForm = CONF_FORMS[device.device_type.name]
1217 initial['name'] = request.GET['name']
1217 initial['name'] = request.GET['name']
1218 form = DevConfForm(initial=initial)
1218 form = DevConfForm(initial=initial)
1219 else:
1219 else:
1220 if 'template' in request.GET:
1220 if 'template' in request.GET:
1221 if request.GET['template']=='0':
1221 if request.GET['template']=='0':
1222 choices = [(conf.pk, '{}'.format(conf)) for conf in Configuration.objects.filter(template=True)]
1222 choices = [(conf.pk, '{}'.format(conf)) for conf in Configuration.objects.filter(template=True)]
1223 form = NewForm(initial={'create_from':2},
1223 form = NewForm(initial={'create_from':2},
1224 template_choices=choices)
1224 template_choices=choices)
1225 else:
1225 else:
1226 kwargs['button'] = 'Create'
1226 kwargs['button'] = 'Create'
1227 conf = Configuration.objects.get(pk=request.GET['template'])
1227 conf = Configuration.objects.get(pk=request.GET['template'])
1228 id_dev = conf.device.pk
1228 id_dev = conf.device.pk
1229 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1229 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1230 form = DevConfForm(instance=conf,
1230 form = DevConfForm(instance=conf,
1231 initial={'name': '{} [{:%Y/%m/%d}]'.format(conf.name, datetime.now()),
1231 initial={'name': '{} [{:%Y/%m/%d}]'.format(conf.name, datetime.now()),
1232 'template': False,
1232 'template': False,
1233 'experiment':id_exp})
1233 'experiment':id_exp})
1234 elif 'blank' in request.GET:
1234 elif 'blank' in request.GET:
1235 kwargs['button'] = 'Create'
1235 kwargs['button'] = 'Create'
1236 form = ConfigurationForm(initial=initial)
1236 form = ConfigurationForm(initial=initial)
1237 else:
1237 else:
1238 form = NewForm()
1238 form = NewForm()
1239
1239
1240 if request.method == 'POST':
1240 if request.method == 'POST':
1241
1241
1242 device = Device.objects.get(pk=request.POST['device'])
1242 device = Device.objects.get(pk=request.POST['device'])
1243 DevConfForm = CONF_FORMS[device.device_type.name]
1243 DevConfForm = CONF_FORMS[device.device_type.name]
1244
1244
1245 form = DevConfForm(request.POST)
1245 form = DevConfForm(request.POST)
1246 kwargs['button'] = 'Create'
1246 kwargs['button'] = 'Create'
1247 if form.is_valid():
1247 if form.is_valid():
1248 conf = form.save()
1248 conf = form.save()
1249
1249
1250 if 'template' in request.GET and conf.device.device_type.name=='rc':
1250 if 'template' in request.GET and conf.device.device_type.name=='rc':
1251 lines = RCLine.objects.filter(rc_configuration=request.GET['template'])
1251 lines = RCLine.objects.filter(rc_configuration=request.GET['template'])
1252 for line in lines:
1252 for line in lines:
1253 line.clone(rc_configuration=conf)
1253 line.clone(rc_configuration=conf)
1254
1254
1255 if conf.device.device_type.name=='jars':
1255 if conf.device.device_type.name=='jars':
1256 conf.add_parms_to_filter()
1256 conf.add_parms_to_filter()
1257
1257
1258 return redirect('url_dev_conf', id_conf=conf.pk)
1258 return redirect('url_dev_conf', id_conf=conf.pk)
1259
1259
1260 kwargs['id_exp'] = id_exp
1260 kwargs['id_exp'] = id_exp
1261 kwargs['form'] = form
1261 kwargs['form'] = form
1262 kwargs['title'] = 'Configuration'
1262 kwargs['title'] = 'Configuration'
1263 kwargs['suptitle'] = 'New'
1263 kwargs['suptitle'] = 'New'
1264
1264
1265
1265
1266 if id_dev != 0:
1266 if id_dev != 0:
1267 device = Device.objects.get(pk=id_dev)
1267 device = Device.objects.get(pk=id_dev)
1268 kwargs['device'] = device.device_type.name
1268 kwargs['device'] = device.device_type.name
1269
1269
1270 return render(request, 'dev_conf_edit.html', kwargs)
1270 return render(request, 'dev_conf_edit.html', kwargs)
1271
1271
1272
1272
1273 @user_passes_test(lambda u:u.is_staff)
1273 @user_passes_test(lambda u:u.is_staff)
1274 def dev_conf_edit(request, id_conf):
1274 def dev_conf_edit(request, id_conf):
1275
1275
1276 conf = get_object_or_404(Configuration, pk=id_conf)
1276 conf = get_object_or_404(Configuration, pk=id_conf)
1277
1277
1278 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1278 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1279
1279
1280 if request.method=='GET':
1280 if request.method=='GET':
1281 form = DevConfForm(instance=conf)
1281 form = DevConfForm(instance=conf)
1282
1282
1283 if request.method=='POST':
1283 if request.method=='POST':
1284 form = DevConfForm(request.POST, instance=conf)
1284 form = DevConfForm(request.POST, instance=conf)
1285
1285
1286 if form.is_valid():
1286 if form.is_valid():
1287 form.save()
1287 form.save()
1288 return redirect('url_dev_conf', id_conf=id_conf)
1288 return redirect('url_dev_conf', id_conf=id_conf)
1289
1289
1290 kwargs = {}
1290 kwargs = {}
1291 kwargs['form'] = form
1291 kwargs['form'] = form
1292 kwargs['title'] = 'Device Configuration'
1292 kwargs['title'] = 'Device Configuration'
1293 kwargs['suptitle'] = 'Edit'
1293 kwargs['suptitle'] = 'Edit'
1294 kwargs['button'] = 'Update'
1294 kwargs['button'] = 'Update'
1295
1295
1296 ###### SIDEBAR ######
1296 ###### SIDEBAR ######
1297 kwargs.update(sidebar(conf=conf))
1297 kwargs.update(sidebar(conf=conf))
1298
1298
1299 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1299 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1300
1300
1301
1301
1302 @user_passes_test(lambda u:u.is_staff)
1302 @user_passes_test(lambda u:u.is_staff)
1303 def dev_conf_start(request, id_conf):
1303 def dev_conf_start(request, id_conf):
1304
1304
1305 conf = get_object_or_404(Configuration, pk=id_conf)
1305 conf = get_object_or_404(Configuration, pk=id_conf)
1306
1306
1307 if conf.start_device():
1307 if conf.start_device():
1308 messages.success(request, conf.message)
1308 messages.success(request, conf.message)
1309 else:
1309 else:
1310 messages.error(request, conf.message)
1310 messages.error(request, conf.message)
1311
1311
1312 #conf.status_device()
1312 #conf.status_device()
1313
1313
1314 return redirect(conf.get_absolute_url())
1314 return redirect(conf.get_absolute_url())
1315
1315
1316
1316
1317 @user_passes_test(lambda u:u.is_staff)
1317 @user_passes_test(lambda u:u.is_staff)
1318 def dev_conf_stop(request, id_conf):
1318 def dev_conf_stop(request, id_conf):
1319
1319
1320 conf = get_object_or_404(Configuration, pk=id_conf)
1320 conf = get_object_or_404(Configuration, pk=id_conf)
1321
1321
1322 if conf.stop_device():
1322 if conf.stop_device():
1323 messages.success(request, conf.message)
1323 messages.success(request, conf.message)
1324 else:
1324 else:
1325 messages.error(request, conf.message)
1325 messages.error(request, conf.message)
1326
1326
1327 #conf.status_device()
1327 #conf.status_device()
1328
1328
1329 return redirect(conf.get_absolute_url())
1329 return redirect(conf.get_absolute_url())
1330
1330
1331
1331
1332 def dev_conf_status(request, id_conf):
1332 def dev_conf_status(request, id_conf):
1333
1333
1334 conf = get_object_or_404(Configuration, pk=id_conf)
1334 conf = get_object_or_404(Configuration, pk=id_conf)
1335
1335
1336 if conf.status_device():
1336 if conf.status_device():
1337 messages.success(request, conf.message)
1337 messages.success(request, conf.message)
1338 else:
1338 else:
1339 messages.error(request, conf.message)
1339 messages.error(request, conf.message)
1340
1340
1341 return redirect(conf.get_absolute_url())
1341 return redirect(conf.get_absolute_url())
1342
1342
1343
1343
1344 @user_passes_test(lambda u:u.is_staff)
1344 @user_passes_test(lambda u:u.is_staff)
1345 def dev_conf_write(request, id_conf):
1345 def dev_conf_write(request, id_conf):
1346
1346
1347 conf = get_object_or_404(Configuration, pk=id_conf)
1347 conf = get_object_or_404(Configuration, pk=id_conf)
1348
1348
1349 if conf.write_device():
1349 if conf.write_device():
1350 messages.success(request, conf.message)
1350 messages.success(request, conf.message)
1351 conf.clone(type=1, template=False)
1351 conf.clone(type=1, template=False)
1352 else:
1352 else:
1353 messages.error(request, conf.message)
1353 messages.error(request, conf.message)
1354
1354
1355 return redirect(conf.get_absolute_url())
1355 return redirect(conf.get_absolute_url())
1356
1356
1357
1357
1358 @user_passes_test(lambda u:u.is_staff)
1358 @user_passes_test(lambda u:u.is_staff)
1359 def dev_conf_read(request, id_conf):
1359 def dev_conf_read(request, id_conf):
1360
1360
1361 conf = get_object_or_404(Configuration, pk=id_conf)
1361 conf = get_object_or_404(Configuration, pk=id_conf)
1362
1362
1363 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1363 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1364
1364
1365 if request.method=='GET':
1365 if request.method=='GET':
1366
1366
1367 parms = conf.read_device()
1367 parms = conf.read_device()
1368 #conf.status_device()
1368 #conf.status_device()
1369
1369
1370 if not parms:
1370 if not parms:
1371 messages.error(request, conf.message)
1371 messages.error(request, conf.message)
1372 return redirect(conf.get_absolute_url())
1372 return redirect(conf.get_absolute_url())
1373
1373
1374 form = DevConfForm(initial=parms, instance=conf)
1374 form = DevConfForm(initial=parms, instance=conf)
1375
1375
1376 if request.method=='POST':
1376 if request.method=='POST':
1377 form = DevConfForm(request.POST, instance=conf)
1377 form = DevConfForm(request.POST, instance=conf)
1378
1378
1379 if form.is_valid():
1379 if form.is_valid():
1380 form.save()
1380 form.save()
1381 return redirect(conf.get_absolute_url())
1381 return redirect(conf.get_absolute_url())
1382
1382
1383 messages.error(request, "Parameters could not be saved")
1383 messages.error(request, "Parameters could not be saved")
1384
1384
1385 kwargs = {}
1385 kwargs = {}
1386 kwargs['id_dev'] = conf.id
1386 kwargs['id_dev'] = conf.id
1387 kwargs['form'] = form
1387 kwargs['form'] = form
1388 kwargs['title'] = 'Device Configuration'
1388 kwargs['title'] = 'Device Configuration'
1389 kwargs['suptitle'] = 'Parameters read from device'
1389 kwargs['suptitle'] = 'Parameters read from device'
1390 kwargs['button'] = 'Save'
1390 kwargs['button'] = 'Save'
1391
1391
1392 ###### SIDEBAR ######
1392 ###### SIDEBAR ######
1393 kwargs.update(sidebar(conf=conf))
1393 kwargs.update(sidebar(conf=conf))
1394
1394
1395 return render(request, '%s_conf_edit.html' %conf.device.device_type.name, kwargs)
1395 return render(request, '%s_conf_edit.html' %conf.device.device_type.name, kwargs)
1396
1396
1397
1397
1398 @user_passes_test(lambda u:u.is_staff)
1398 @user_passes_test(lambda u:u.is_staff)
1399 def dev_conf_import(request, id_conf):
1399 def dev_conf_import(request, id_conf):
1400
1400
1401 conf = get_object_or_404(Configuration, pk=id_conf)
1401 conf = get_object_or_404(Configuration, pk=id_conf)
1402 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1402 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1403
1403
1404 if request.method == 'GET':
1404 if request.method == 'GET':
1405 file_form = UploadFileForm()
1405 file_form = UploadFileForm()
1406
1406
1407 if request.method == 'POST':
1407 if request.method == 'POST':
1408 file_form = UploadFileForm(request.POST, request.FILES)
1408 file_form = UploadFileForm(request.POST, request.FILES)
1409
1409
1410 if file_form.is_valid():
1410 if file_form.is_valid():
1411
1411
1412 parms = conf.import_from_file(request.FILES['file'])
1412 parms = conf.import_from_file(request.FILES['file'])
1413
1413
1414 if parms:
1414 if parms:
1415 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
1415 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
1416 form = DevConfForm(initial=parms, instance=conf)
1416 form = DevConfForm(initial=parms, instance=conf)
1417
1417
1418 kwargs = {}
1418 kwargs = {}
1419 kwargs['id_dev'] = conf.id
1419 kwargs['id_dev'] = conf.id
1420 kwargs['form'] = form
1420 kwargs['form'] = form
1421 kwargs['title'] = 'Device Configuration'
1421 kwargs['title'] = 'Device Configuration'
1422 kwargs['suptitle'] = 'Parameters imported'
1422 kwargs['suptitle'] = 'Parameters imported'
1423 kwargs['button'] = 'Save'
1423 kwargs['button'] = 'Save'
1424 kwargs['action'] = conf.get_absolute_url_edit()
1424 kwargs['action'] = conf.get_absolute_url_edit()
1425 kwargs['previous'] = conf.get_absolute_url()
1425 kwargs['previous'] = conf.get_absolute_url()
1426
1426
1427 ###### SIDEBAR ######
1427 ###### SIDEBAR ######
1428 kwargs.update(sidebar(conf=conf))
1428 kwargs.update(sidebar(conf=conf))
1429
1429
1430 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1430 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1431
1431
1432 messages.error(request, "Could not import parameters from file")
1432 messages.error(request, "Could not import parameters from file")
1433
1433
1434 kwargs = {}
1434 kwargs = {}
1435 kwargs['id_dev'] = conf.id
1435 kwargs['id_dev'] = conf.id
1436 kwargs['title'] = 'Device Configuration'
1436 kwargs['title'] = 'Device Configuration'
1437 kwargs['form'] = file_form
1437 kwargs['form'] = file_form
1438 kwargs['suptitle'] = 'Importing file'
1438 kwargs['suptitle'] = 'Importing file'
1439 kwargs['button'] = 'Import'
1439 kwargs['button'] = 'Import'
1440
1440
1441 kwargs.update(sidebar(conf=conf))
1441 kwargs.update(sidebar(conf=conf))
1442
1442
1443 return render(request, 'dev_conf_import.html', kwargs)
1443 return render(request, 'dev_conf_import.html', kwargs)
1444
1444
1445
1445
1446 @user_passes_test(lambda u:u.is_staff)
1446 @user_passes_test(lambda u:u.is_staff)
1447 def dev_conf_export(request, id_conf):
1447 def dev_conf_export(request, id_conf):
1448
1448
1449 conf = get_object_or_404(Configuration, pk=id_conf)
1449 conf = get_object_or_404(Configuration, pk=id_conf)
1450
1450
1451 if request.method == 'GET':
1451 if request.method == 'GET':
1452 file_form = DownloadFileForm(conf.device.device_type.name)
1452 file_form = DownloadFileForm(conf.device.device_type.name)
1453
1453
1454 if request.method == 'POST':
1454 if request.method == 'POST':
1455 file_form = DownloadFileForm(conf.device.device_type.name, request.POST)
1455 file_form = DownloadFileForm(conf.device.device_type.name, request.POST)
1456
1456
1457 if file_form.is_valid():
1457 if file_form.is_valid():
1458 fields = conf.export_to_file(format = file_form.cleaned_data['format'])
1458 fields = conf.export_to_file(format = file_form.cleaned_data['format'])
1459
1459
1460 response = HttpResponse(content_type=fields['content_type'])
1460 response = HttpResponse(content_type=fields['content_type'])
1461 response['Content-Disposition'] = 'attachment; filename="%s"' %fields['filename']
1461 response['Content-Disposition'] = 'attachment; filename="%s"' %fields['filename']
1462 response.write(fields['content'])
1462 response.write(fields['content'])
1463
1463
1464 return response
1464 return response
1465
1465
1466 messages.error(request, "Could not export parameters")
1466 messages.error(request, "Could not export parameters")
1467
1467
1468 kwargs = {}
1468 kwargs = {}
1469 kwargs['id_dev'] = conf.id
1469 kwargs['id_dev'] = conf.id
1470 kwargs['title'] = 'Device Configuration'
1470 kwargs['title'] = 'Device Configuration'
1471 kwargs['form'] = file_form
1471 kwargs['form'] = file_form
1472 kwargs['suptitle'] = 'Exporting file'
1472 kwargs['suptitle'] = 'Exporting file'
1473 kwargs['button'] = 'Export'
1473 kwargs['button'] = 'Export'
1474
1474
1475 return render(request, 'dev_conf_export.html', kwargs)
1475 return render(request, 'dev_conf_export.html', kwargs)
1476
1476
1477
1477
1478 @user_passes_test(lambda u:u.is_staff)
1478 @user_passes_test(lambda u:u.is_staff)
1479 def dev_conf_delete(request, id_conf):
1479 def dev_conf_delete(request, id_conf):
1480
1480
1481 conf = get_object_or_404(Configuration, pk=id_conf)
1481 conf = get_object_or_404(Configuration, pk=id_conf)
1482
1482
1483 if request.method=='POST':
1483 if request.method=='POST':
1484 if request.user.is_staff:
1484 if request.user.is_staff:
1485 conf.delete()
1485 conf.delete()
1486 return redirect('url_dev_confs')
1486 return redirect('url_dev_confs')
1487
1487
1488 messages.error(request, 'Not enough permission to delete this object')
1488 messages.error(request, 'Not enough permission to delete this object')
1489 return redirect(conf.get_absolute_url())
1489 return redirect(conf.get_absolute_url())
1490
1490
1491 kwargs = {
1491 kwargs = {
1492 'title': 'Delete',
1492 'title': 'Delete',
1493 'suptitle': 'Experiment',
1493 'suptitle': 'Experiment',
1494 'object': conf,
1494 'object': conf,
1495 'previous': conf.get_absolute_url(),
1495 'previous': conf.get_absolute_url(),
1496 'delete': True
1496 'delete': True
1497 }
1497 }
1498
1498
1499 return render(request, 'confirm.html', kwargs)
1499 return render(request, 'confirm.html', kwargs)
1500
1500
1501
1501
1502 def sidebar(**kwargs):
1502 def sidebar(**kwargs):
1503
1503
1504 side_data = {}
1504 side_data = {}
1505
1505
1506 conf = kwargs.get('conf', None)
1506 conf = kwargs.get('conf', None)
1507 experiment = kwargs.get('experiment', None)
1507 experiment = kwargs.get('experiment', None)
1508
1508
1509 if not experiment:
1509 if not experiment:
1510 experiment = conf.experiment
1510 experiment = conf.experiment
1511
1511
1512 if experiment:
1512 if experiment:
1513 side_data['experiment'] = experiment
1513 side_data['experiment'] = experiment
1514 campaign = experiment.campaign_set.all()
1514 campaign = experiment.campaign_set.all()
1515 if campaign:
1515 if campaign:
1516 side_data['campaign'] = campaign[0]
1516 side_data['campaign'] = campaign[0]
1517 experiments = campaign[0].experiments.all()
1517 experiments = campaign[0].experiments.all()
1518 else:
1518 else:
1519 experiments = [experiment]
1519 experiments = [experiment]
1520 configurations = experiment.configuration_set.filter(type=0)
1520 configurations = experiment.configuration_set.filter(type=0)
1521 side_data['side_experiments'] = experiments
1521 side_data['side_experiments'] = experiments
1522 side_data['side_configurations'] = configurations
1522 side_data['side_configurations'] = configurations
1523
1523
1524 return side_data
1524 return side_data
1525
1525
1526 def get_paginator(model, page, order, filters={}, n=10):
1526 def get_paginator(model, page, order, filters={}, n=10):
1527
1527
1528 kwargs = {}
1528 kwargs = {}
1529 query = Q()
1529 query = Q()
1530 if isinstance(filters, QueryDict):
1530 if isinstance(filters, QueryDict):
1531 filters = filters.dict()
1531 filters = filters.dict()
1532 [filters.pop(key) for key in filters.keys() if filters[key] in ('', ' ')]
1532 [filters.pop(key) for key in filters.keys() if filters[key] in ('', ' ')]
1533 filters.pop('page', None)
1533 filters.pop('page', None)
1534
1534
1535 if 'template' in filters:
1535 if 'template' in filters:
1536 filters['template'] = True
1536 filters['template'] = True
1537 if 'start_date' in filters:
1537 if 'start_date' in filters:
1538 filters['start_date__gte'] = filters.pop('start_date')
1538 filters['start_date__gte'] = filters.pop('start_date')
1539 if 'end_date' in filters:
1539 if 'end_date' in filters:
1540 filters['start_date__lte'] = filters.pop('end_date')
1540 filters['start_date__lte'] = filters.pop('end_date')
1541 if 'tags' in filters:
1541 if 'tags' in filters:
1542 tags = filters.pop('tags')
1542 tags = filters.pop('tags')
1543 fields = [f.name for f in model._meta.get_fields()]
1543 fields = [f.name for f in model._meta.get_fields()]
1544
1544
1545 if 'tags' in fields:
1545 if 'tags' in fields:
1546 query = query | Q(tags__icontains=tags)
1546 query = query | Q(tags__icontains=tags)
1547 if 'name' in fields:
1547 if 'name' in fields:
1548 query = query | Q(name__icontains=tags)
1548 query = query | Q(name__icontains=tags)
1549 if 'location' in fields:
1549 if 'location' in fields:
1550 query = query | Q(location__name__icontains=tags)
1550 query = query | Q(location__name__icontains=tags)
1551 if 'device' in fields:
1551 if 'device' in fields:
1552 query = query | Q(device__device_type__name__icontains=tags)
1552 query = query | Q(device__device_type__name__icontains=tags)
1553
1553
1554 object_list = model.objects.filter(query, **filters).order_by(*order)
1554 object_list = model.objects.filter(query, **filters).order_by(*order)
1555 paginator = Paginator(object_list, n)
1555 paginator = Paginator(object_list, n)
1556
1556
1557 try:
1557 try:
1558 objects = paginator.page(page)
1558 objects = paginator.page(page)
1559 except PageNotAnInteger:
1559 except PageNotAnInteger:
1560 objects = paginator.page(1)
1560 objects = paginator.page(1)
1561 except EmptyPage:
1561 except EmptyPage:
1562 objects = paginator.page(paginator.num_pages)
1562 objects = paginator.page(paginator.num_pages)
1563
1563
1564 kwargs['objects'] = objects
1564 kwargs['objects'] = objects
1565 kwargs['offset'] = (int(page)-1)*n if page else 0
1565 kwargs['offset'] = (int(page)-1)*n if page else 0
1566
1566
1567 return kwargs
1567 return kwargs
1568
1568
1569 def operation(request, id_camp=None):
1569 def operation(request, id_camp=None):
1570
1570
1571 kwargs = {}
1571 kwargs = {}
1572 kwargs['title'] = 'Radars Operation'
1572 kwargs['title'] = 'Radars Operation'
1573 kwargs['no_sidebar'] = True
1573 kwargs['no_sidebar'] = True
1574 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
1574 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
1575 end_date__gte=datetime.now()).order_by('-start_date')
1575 end_date__gte=datetime.now()).order_by('-start_date')
1576
1576
1577
1577
1578 if id_camp:
1578 if id_camp:
1579 campaign = get_object_or_404(Campaign, pk = id_camp)
1579 campaign = get_object_or_404(Campaign, pk = id_camp)
1580 form = OperationForm(initial={'campaign': campaign.id}, campaigns=campaigns)
1580 form = OperationForm(initial={'campaign': campaign.id}, campaigns=campaigns)
1581 kwargs['campaign'] = campaign
1581 kwargs['campaign'] = campaign
1582 else:
1582 else:
1583 form = OperationForm(campaigns=campaigns)
1583 form = OperationForm(campaigns=campaigns)
1584 kwargs['form'] = form
1584 kwargs['form'] = form
1585 return render(request, 'operation.html', kwargs)
1585 return render(request, 'operation.html', kwargs)
1586
1586
1587 #---Experiment
1587 #---Experiment
1588 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1588 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1589 kwargs['experiment_keys'] = keys[1:]
1589 kwargs['experiment_keys'] = keys[1:]
1590 kwargs['experiments'] = experiments
1590 kwargs['experiments'] = experiments
1591 #---Radar
1591 #---Radar
1592 kwargs['locations'] = campaign.get_experiments_by_radar()
1592 kwargs['locations'] = campaign.get_experiments_by_radar()
1593 kwargs['form'] = form
1593 kwargs['form'] = form
1594
1594
1595 return render(request, 'operation.html', kwargs)
1595 return render(request, 'operation.html', kwargs)
1596
1596
1597
1597
1598 @login_required
1598 @login_required
1599 def radar_start(request, id_camp, id_radar):
1599 def radar_start(request, id_camp, id_radar):
1600
1600
1601 campaign = get_object_or_404(Campaign, pk = id_camp)
1601 campaign = get_object_or_404(Campaign, pk = id_camp)
1602 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1602 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1603 now = datetime.utcnow()
1603 now = datetime.utcnow()
1604
1604
1605 for exp in experiments:
1605 for exp in experiments:
1606 date = datetime.combine(datetime.now().date(), exp.start_time)
1606 date = datetime.combine(datetime.now().date(), exp.start_time)
1607
1607
1608 if exp.status == 2:
1608 if exp.status == 2:
1609 messages.warning(request, 'Experiment {} already running'.format(exp))
1609 messages.warning(request, 'Experiment {} already running'.format(exp))
1610 continue
1610 continue
1611
1611
1612 if exp.status == 3:
1612 if exp.status == 3:
1613 messages.warning(request, 'Experiment {} already programmed'.format(exp))
1613 messages.warning(request, 'Experiment {} already programmed'.format(exp))
1614 continue
1614 continue
1615
1615
1616 if date>campaign.end_date or date<campaign.start_date:
1616 if date>campaign.end_date or date<campaign.start_date:
1617 messages.warning(request, 'Experiment {} out of date'.format(exp))
1617 messages.warning(request, 'Experiment {} out of date'.format(exp))
1618 continue
1618 continue
1619
1619
1620 if now>=date:
1620 if now>=date:
1621 task = task_start.delay(exp.pk)
1621 task = task_start.delay(exp.pk)
1622 exp.status = task.wait()
1622 exp.status = task.wait()
1623 if exp.status==0:
1623 if exp.status==0:
1624 messages.error(request, 'Experiment {} not start'.format(exp))
1624 messages.error(request, 'Experiment {} not start'.format(exp))
1625 if exp.status==2:
1625 if exp.status==2:
1626 messages.success(request, 'Experiment {} started'.format(exp))
1626 messages.success(request, 'Experiment {} started'.format(exp))
1627 else:
1627 else:
1628 task = task_start.apply_async((exp.pk,), eta=date)
1628 task = task_start.apply_async((exp.pk,), eta=date)
1629 exp.status = 3
1629 exp.status = 3
1630 messages.success(request, 'Experiment {} programmed to start at {}'.format(exp, date))
1630 messages.success(request, 'Experiment {} programmed to start at {}'.format(exp, date))
1631
1631
1632 exp.save()
1632 exp.save()
1633
1633
1634 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1634 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1635
1635
1636
1636
1637 @login_required
1637 @login_required
1638 def radar_stop(request, id_camp, id_radar):
1638 def radar_stop(request, id_camp, id_radar):
1639
1639
1640 campaign = get_object_or_404(Campaign, pk = id_camp)
1640 campaign = get_object_or_404(Campaign, pk = id_camp)
1641 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1641 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1642
1642
1643 for exp in experiments:
1643 for exp in experiments:
1644
1644
1645 if exp.status == 2:
1645 if exp.status == 2:
1646 task = task_stop.delay(exp.pk)
1646 task = task_stop.delay(exp.pk)
1647 exp.status = task.wait()
1647 exp.status = task.wait()
1648 messages.warning(request, 'Experiment {} stopped'.format(exp))
1648 messages.warning(request, 'Experiment {} stopped'.format(exp))
1649 exp.save()
1649 exp.save()
1650 else:
1650 else:
1651 messages.error(request, 'Experiment {} not running'.format(exp))
1651 messages.error(request, 'Experiment {} not running'.format(exp))
1652
1652
1653 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1653 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1654
1654
1655
1655
1656 @login_required
1656 @login_required
1657 def radar_refresh(request, id_camp, id_radar):
1657 def radar_refresh(request, id_camp, id_radar):
1658
1658
1659 campaign = get_object_or_404(Campaign, pk = id_camp)
1659 campaign = get_object_or_404(Campaign, pk = id_camp)
1660 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1660 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1661
1661
1662 for exp in experiments:
1662 for exp in experiments:
1663 exp.get_status()
1663 exp.get_status()
1664
1664
1665 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1665 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
@@ -1,972 +1,974
1
1
2 import ast
2 import ast
3 import json
3 import json
4 import requests
4 import requests
5 import numpy as np
5 import numpy as np
6 from base64 import b64encode
6 from base64 import b64encode
7 from struct import pack
7 from struct import pack
8
8
9 from django.db import models
9 from django.db import models
10 from django.core.urlresolvers import reverse
10 from django.core.urlresolvers import reverse
11 from django.core.validators import MinValueValidator, MaxValueValidator
11 from django.core.validators import MinValueValidator, MaxValueValidator
12
12
13 from apps.main.models import Configuration
13 from apps.main.models import Configuration
14 from devices.rc import api
14 from devices.rc import api
15 from .utils import RCFile
15 from .utils import RCFile
16
16
17 # Create your models here.
17 # Create your models here.
18
18
19 LINE_TYPES = (
19 LINE_TYPES = (
20 ('none', 'Not used'),
20 ('none', 'Not used'),
21 ('tr', 'Transmission/reception selector signal'),
21 ('tr', 'Transmission/reception selector signal'),
22 ('tx', 'A modulating signal (Transmission pulse)'),
22 ('tx', 'A modulating signal (Transmission pulse)'),
23 ('codes', 'BPSK modulating signal'),
23 ('codes', 'BPSK modulating signal'),
24 ('windows', 'Sample window signal'),
24 ('windows', 'Sample window signal'),
25 ('sync', 'Synchronizing signal'),
25 ('sync', 'Synchronizing signal'),
26 ('flip', 'IPP related periodic signal'),
26 ('flip', 'IPP related periodic signal'),
27 ('prog_pulses', 'Programmable pulse'),
27 ('prog_pulses', 'Programmable pulse'),
28 ('mix', 'Mixed line'),
28 ('mix', 'Mixed line'),
29 )
29 )
30
30
31
31
32 SAMPLING_REFS = (
32 SAMPLING_REFS = (
33 ('none', 'No Reference'),
33 ('none', 'No Reference'),
34 ('begin_baud', 'Begin of the first baud'),
34 ('begin_baud', 'Begin of the first baud'),
35 ('first_baud', 'Middle of the first baud'),
35 ('first_baud', 'Middle of the first baud'),
36 ('sub_baud', 'Middle of the sub-baud')
36 ('sub_baud', 'Middle of the sub-baud')
37 )
37 )
38
38
39 DAT_CMDS = {
39 DAT_CMDS = {
40 # Pulse Design commands
40 # Pulse Design commands
41 'DISABLE' : 0, # Disables pulse generation
41 'DISABLE' : 0, # Disables pulse generation
42 'ENABLE' : 24, # Enables pulse generation
42 'ENABLE' : 24, # Enables pulse generation
43 'DELAY_START' : 40, # Write delay status to memory
43 'DELAY_START' : 40, # Write delay status to memory
44 'FLIP_START' : 48, # Write flip status to memory
44 'FLIP_START' : 48, # Write flip status to memory
45 'SAMPLING_PERIOD' : 64, # Establish Sampling Period
45 'SAMPLING_PERIOD' : 64, # Establish Sampling Period
46 'TX_ONE' : 72, # Output '0' in line TX
46 'TX_ONE' : 72, # Output '0' in line TX
47 'TX_ZERO' : 88, # Output '0' in line TX
47 'TX_ZERO' : 88, # Output '0' in line TX
48 'SW_ONE' : 104, # Output '0' in line SW
48 'SW_ONE' : 104, # Output '0' in line SW
49 'SW_ZERO' : 112, # Output '1' in line SW
49 'SW_ZERO' : 112, # Output '1' in line SW
50 'RESTART': 120, # Restarts CR8 Firmware
50 'RESTART': 120, # Restarts CR8 Firmware
51 'CONTINUE' : 253, # Function Unknown
51 'CONTINUE' : 253, # Function Unknown
52 # Commands available to new controllers
52 # Commands available to new controllers
53 # In Pulse Design Executable, the clock divisor code is written as 12 at the start, but it should be written as code 22(below) just before the final enable.
53 # In Pulse Design Executable, the clock divisor code is written as 12 at the start, but it should be written as code 22(below) just before the final enable.
54 'CLOCK_DIVISOR_INIT' : 12, # Specifies Clock Divisor. Legacy command, ignored in the actual .dat conversion
54 'CLOCK_DIVISOR_INIT' : 12, # Specifies Clock Divisor. Legacy command, ignored in the actual .dat conversion
55 'CLOCK_DIVISOR_LAST' : 22, # Specifies Clock Divisor (default 60 if not included) syntax: 255,22 254,N-1.
55 'CLOCK_DIVISOR_LAST' : 22, # Specifies Clock Divisor (default 60 if not included) syntax: 255,22 254,N-1.
56 'CLOCK_DIVIDER' : 8,
56 'CLOCK_DIVIDER' : 8,
57 }
57 }
58
58
59
59
60 class RCConfiguration(Configuration):
60 class RCConfiguration(Configuration):
61
61
62 ipp = models.FloatField(verbose_name='IPP [Km]', validators=[MinValueValidator(1), MaxValueValidator(9000)], default=300)
62 ipp = models.FloatField(verbose_name='IPP [Km]', validators=[MinValueValidator(1), MaxValueValidator(9000)], default=300)
63 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1), MaxValueValidator(400)], default=1)
63 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1), MaxValueValidator(400)], default=1)
64 clock_in = models.FloatField(verbose_name='Clock in [MHz]', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
64 clock_in = models.FloatField(verbose_name='Clock in [MHz]', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
65 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
65 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
66 clock = models.FloatField(verbose_name='Clock Master [MHz]', blank=True, default=1)
66 clock = models.FloatField(verbose_name='Clock Master [MHz]', blank=True, default=1)
67 time_before = models.PositiveIntegerField(verbose_name='Time before [&mu;S]', default=12)
67 time_before = models.PositiveIntegerField(verbose_name='Time before [&mu;S]', default=12)
68 time_after = models.PositiveIntegerField(verbose_name='Time after [&mu;S]', default=1)
68 time_after = models.PositiveIntegerField(verbose_name='Time after [&mu;S]', default=1)
69 sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
69 sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
70 sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40)
70 sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40)
71 control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False)
71 control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False)
72 control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
72 control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
73 total_units = models.PositiveIntegerField(default=0)
73 total_units = models.PositiveIntegerField(default=0)
74 mix = models.BooleanField(default=False)
74 mix = models.BooleanField(default=False)
75
75
76 class Meta:
76 class Meta:
77 db_table = 'rc_configurations'
77 db_table = 'rc_configurations'
78
78
79 def get_absolute_url_plot(self):
79 def get_absolute_url_plot(self):
80 return reverse('url_plot_rc_pulses', args=[str(self.id)])
80 return reverse('url_plot_rc_pulses', args=[str(self.id)])
81
81
82 def get_absolute_url_import(self):
82 def get_absolute_url_import(self):
83 return reverse('url_import_rc_conf', args=[str(self.id)])
83 return reverse('url_import_rc_conf', args=[str(self.id)])
84
84
85 @property
85 @property
86 def ipp_unit(self):
86 def ipp_unit(self):
87
87
88 return '{} ({})'.format(self.ipp, int(self.ipp*self.km2unit))
88 return '{} ({})'.format(self.ipp, int(self.ipp*self.km2unit))
89
89
90 @property
90 @property
91 def us2unit(self):
91 def us2unit(self):
92
92
93 return self.clock_in/self.clock_divider
93 return self.clock_in/self.clock_divider
94
94
95 @property
95 @property
96 def km2unit(self):
96 def km2unit(self):
97
97
98 return 20./3*(self.clock_in/self.clock_divider)
98 return 20./3*(self.clock_in/self.clock_divider)
99
99
100 def clone(self, **kwargs):
100 def clone(self, **kwargs):
101
101
102 lines = self.get_lines()
102 lines = self.get_lines()
103 self.pk = None
103 self.pk = None
104 self.id = None
104 self.id = None
105 for attr, value in kwargs.items():
105 for attr, value in kwargs.items():
106 setattr(self, attr, value)
106 setattr(self, attr, value)
107 self.save()
107 self.save()
108
108
109 for line in lines:
109 for line in lines:
110 line.clone(rc_configuration=self)
110 line.clone(rc_configuration=self)
111
111
112 return self
112 return self
113
113
114 def get_lines(self, **kwargs):
114 def get_lines(self, **kwargs):
115 '''
115 '''
116 Retrieve configuration lines
116 Retrieve configuration lines
117 '''
117 '''
118
118
119 return RCLine.objects.filter(rc_configuration=self.pk, **kwargs)
119 return RCLine.objects.filter(rc_configuration=self.pk, **kwargs)
120
120
121
121
122 def clean_lines(self):
122 def clean_lines(self):
123 '''
123 '''
124 '''
124 '''
125
125
126 empty_line = RCLineType.objects.get(name='none')
126 empty_line = RCLineType.objects.get(name='none')
127
127
128 for line in self.get_lines():
128 for line in self.get_lines():
129 line.line_type = empty_line
129 line.line_type = empty_line
130 line.params = '{}'
130 line.params = '{}'
131 line.save()
131 line.save()
132
132
133 def parms_to_dict(self):
133 def parms_to_dict(self):
134 '''
134 '''
135 '''
135 '''
136
136
137 ignored = ('parameters', 'type', 'polymorphic_ctype', 'configuration_ptr',
137 ignored = ('parameters', 'type', 'polymorphic_ctype', 'configuration_ptr',
138 'created_date', 'programmed_date')
138 'created_date', 'programmed_date')
139
139
140 data = {}
140 data = {}
141 for field in self._meta.fields:
141 for field in self._meta.fields:
142 if field.name in ignored:
142 if field.name in ignored:
143 continue
143 continue
144 data[field.name] = '{}'.format(field.value_from_object(self))
144 data[field.name] = '{}'.format(field.value_from_object(self))
145
145
146 data['device_id'] = data.pop('device')
146 data['device_id'] = data.pop('device')
147 data['lines'] = []
147 data['lines'] = []
148
148
149 for line in self.get_lines():
149 for line in self.get_lines():
150 line_data = json.loads(line.params)
150 line_data = json.loads(line.params)
151 if 'TX_ref' in line_data and line_data['TX_ref'] not in (0, '0'):
151 if 'TX_ref' in line_data and line_data['TX_ref'] not in (0, '0'):
152 line_data['TX_ref'] = RCLine.objects.get(pk=line_data['TX_ref']).get_name()
152 line_data['TX_ref'] = RCLine.objects.get(pk=line_data['TX_ref']).get_name()
153 if 'code' in line_data:
153 if 'code' in line_data:
154 line_data['code'] = RCLineCode.objects.get(pk=line_data['code']).name
154 line_data['code'] = RCLineCode.objects.get(pk=line_data['code']).name
155 line_data['type'] = line.line_type.name
155 line_data['type'] = line.line_type.name
156 line_data['name'] = line.get_name()
156 line_data['name'] = line.get_name()
157 data['lines'].append(line_data)
157 data['lines'].append(line_data)
158
158
159 data['delays'] = self.get_delays()
159 data['delays'] = self.get_delays()
160 data['pulses'] = self.get_pulses()
160 data['pulses'] = self.get_pulses()
161
161
162 return data
162 return data
163
163
164 def dict_to_parms(self, data):
164 def dict_to_parms(self, data):
165 '''
165 '''
166 '''
166 '''
167
167
168 self.name = data['name']
168 self.name = data['name']
169 self.ipp = float(data['ipp'])
169 self.ipp = float(data['ipp'])
170 self.ntx = int(data['ntx'])
170 self.ntx = int(data['ntx'])
171 self.clock_in = float(data['clock_in'])
171 self.clock_in = float(data['clock_in'])
172 self.clock_divider = int(data['clock_divider'])
172 self.clock_divider = int(data['clock_divider'])
173 self.clock = float(data['clock'])
173 self.clock = float(data['clock'])
174 self.time_before = data['time_before']
174 self.time_before = data['time_before']
175 self.time_after = data['time_after']
175 self.time_after = data['time_after']
176 self.sync = data['sync']
176 self.sync = data['sync']
177 self.sampling_reference = data['sampling_reference']
177 self.sampling_reference = data['sampling_reference']
178 self.total_units = self.ipp*self.ntx*self.km2unit
178 self.total_units = self.ipp*self.ntx*self.km2unit
179 self.save()
179 self.save()
180 self.clean_lines()
180 self.clean_lines()
181
181
182 lines = []
182 lines = []
183 positions = {'tx':0, 'tr':0}
183 positions = {'tx':0, 'tr':0}
184
184
185 for i, line_data in enumerate(data['lines']):
185 for i, line_data in enumerate(data['lines']):
186 name = line_data.pop('name', '')
186 name = line_data.pop('name', '')
187 line_type = RCLineType.objects.get(name=line_data.pop('type'))
187 line_type = RCLineType.objects.get(name=line_data.pop('type'))
188 if line_type.name=='codes':
188 if line_type.name=='codes':
189 code = RCLineCode.objects.get(name=line_data['code'])
189 code = RCLineCode.objects.get(name=line_data['code'])
190 line_data['code'] = code.pk
190 line_data['code'] = code.pk
191 line = RCLine.objects.filter(rc_configuration=self, channel=i)
191 line = RCLine.objects.filter(rc_configuration=self, channel=i)
192 if line:
192 if line:
193 line = line[0]
193 line = line[0]
194 line.line_type = line_type
194 line.line_type = line_type
195 line.params = json.dumps(line_data)
195 line.params = json.dumps(line_data)
196 else:
196 else:
197 line = RCLine(rc_configuration=self, line_type=line_type,
197 line = RCLine(rc_configuration=self, line_type=line_type,
198 params=json.dumps(line_data),
198 params=json.dumps(line_data),
199 channel=i)
199 channel=i)
200
200
201 if line_type.name=='tx':
201 if line_type.name=='tx':
202 line.position = positions['tx']
202 line.position = positions['tx']
203 positions['tx'] += 1
203 positions['tx'] += 1
204
204
205 if line_type.name=='tr':
205 if line_type.name=='tr':
206 line.position = positions['tr']
206 line.position = positions['tr']
207 positions['tr'] += 1
207 positions['tr'] += 1
208
208
209 line.save()
209 line.save()
210 lines.append(line)
210 lines.append(line)
211
211
212 for line, line_data in zip(lines, data['lines']):
212 for line, line_data in zip(lines, data['lines']):
213 if 'TX_ref' in line_data:
213 if 'TX_ref' in line_data:
214 params = json.loads(line.params)
214 params = json.loads(line.params)
215 if line_data['TX_ref'] in (0, '0'):
215 if line_data['TX_ref'] in (0, '0'):
216 params['TX_ref'] = '0'
216 params['TX_ref'] = '0'
217 else:
217 else:
218 params['TX_ref'] = [l.pk for l in lines if l.line_type.name=='tx' and line_data['TX_ref'] in l.get_name()][0]
218 params['TX_ref'] = [l.pk for l in lines if l.line_type.name=='tx' and line_data['TX_ref'] in l.get_name()][0]
219 line.params = json.dumps(params)
219 line.params = json.dumps(params)
220 line.save()
220 line.save()
221
221
222
222
223 def get_delays(self):
223 def get_delays(self):
224
224
225 pulses = [line.pulses_as_points() for line in self.get_lines()]
225 pulses = [line.pulses_as_points() for line in self.get_lines()]
226 points = [tup for tups in pulses for tup in tups]
226 points = [tup for tups in pulses for tup in tups]
227 points = set([x for tup in points for x in tup])
227 points = set([x for tup in points for x in tup])
228 points = list(points)
228 points = list(points)
229 points.sort()
229 points.sort()
230
230
231 if points[0]!=0:
231 if points[0]!=0:
232 points.insert(0, 0)
232 points.insert(0, 0)
233
233
234 return [points[i+1]-points[i] for i in range(len(points)-1)]
234 return [points[i+1]-points[i] for i in range(len(points)-1)]
235
235
236
236
237 def get_pulses(self, binary=True):
237 def get_pulses(self, binary=True):
238
238
239
239
240 pulses = [line.pulses_as_points() for line in self.get_lines()]
240 pulses = [line.pulses_as_points() for line in self.get_lines()]
241 tuples = [tup for tups in pulses for tup in tups]
241 tuples = [tup for tups in pulses for tup in tups]
242 points = set([x for tup in tuples for x in tup])
242 points = set([x for tup in tuples for x in tup])
243 points = list(points)
243 points = list(points)
244 points.sort()
244 points.sort()
245 states = []
245 states = []
246 last = [0 for x in pulses]
246 last = [0 for x in pulses]
247
247
248 for x in points:
248 for x in points:
249 dum = []
249 dum = []
250 for i,tups in enumerate(pulses):
250 for i,tups in enumerate(pulses):
251 ups = [tup[0] for tup in tups]
251 ups = [tup[0] for tup in tups]
252 dws = [tup[1] for tup in tups]
252 dws = [tup[1] for tup in tups]
253 if x in ups:
253 if x in ups:
254 dum.append(1)
254 dum.append(1)
255 elif x in dws:
255 elif x in dws:
256 dum.append(0)
256 dum.append(0)
257 else:
257 else:
258 dum.append(last[i])
258 dum.append(last[i])
259 states.append(dum)
259 states.append(dum)
260 last = dum
260 last = dum
261
261
262 if binary:
262 if binary:
263 ret = []
263 ret = []
264 for flips in states:
264 for flips in states:
265 flips.reverse()
265 flips.reverse()
266 ret.append(int(''.join([str(x) for x in flips]), 2))
266 ret.append(int(''.join([str(x) for x in flips]), 2))
267 states = ret
267 states = ret
268
268
269 return states[:-1]
269 return states[:-1]
270
270
271 def add_cmd(self, cmd):
271 def add_cmd(self, cmd):
272
272
273 if cmd in DAT_CMDS:
273 if cmd in DAT_CMDS:
274 return (255, DAT_CMDS[cmd])
274 return (255, DAT_CMDS[cmd])
275
275
276 def add_data(self, value):
276 def add_data(self, value):
277
277
278 return (254, value-1)
278 return (254, value-1)
279
279
280 def parms_to_binary(self, dat=True):
280 def parms_to_binary(self, dat=True):
281 '''
281 '''
282 Create "dat" stream to be send to CR
282 Create "dat" stream to be send to CR
283 '''
283 '''
284
284
285 data = bytearray()
285 data = bytearray()
286 # create header
286 # create header
287 data.extend(self.add_cmd('DISABLE'))
287 data.extend(self.add_cmd('DISABLE'))
288 data.extend(self.add_cmd('CONTINUE'))
288 data.extend(self.add_cmd('CONTINUE'))
289 data.extend(self.add_cmd('RESTART'))
289 data.extend(self.add_cmd('RESTART'))
290
290
291 if self.control_sw:
291 if self.control_sw:
292 data.extend(self.add_cmd('SW_ONE'))
292 data.extend(self.add_cmd('SW_ONE'))
293 else:
293 else:
294 data.extend(self.add_cmd('SW_ZERO'))
294 data.extend(self.add_cmd('SW_ZERO'))
295
295
296 if self.control_tx:
296 if self.control_tx:
297 data.extend(self.add_cmd('TX_ONE'))
297 data.extend(self.add_cmd('TX_ONE'))
298 else:
298 else:
299 data.extend(self.add_cmd('TX_ZERO'))
299 data.extend(self.add_cmd('TX_ZERO'))
300
300
301 # write divider
301 # write divider
302 data.extend(self.add_cmd('CLOCK_DIVIDER'))
302 data.extend(self.add_cmd('CLOCK_DIVIDER'))
303 data.extend(self.add_data(self.clock_divider))
303 data.extend(self.add_data(self.clock_divider))
304
304
305 # write delays
305 # write delays
306 data.extend(self.add_cmd('DELAY_START'))
306 data.extend(self.add_cmd('DELAY_START'))
307 # first delay is always zero
307 # first delay is always zero
308 data.extend(self.add_data(1))
308 data.extend(self.add_data(1))
309
309
310 delays = self.get_delays()
310 delays = self.get_delays()
311
311
312 for delay in delays:
312 for delay in delays:
313 while delay>252:
313 while delay>252:
314 data.extend(self.add_data(253))
314 data.extend(self.add_data(253))
315 delay -= 253
315 delay -= 253
316 data.extend(self.add_data(int(delay)))
316 data.extend(self.add_data(int(delay)))
317
317
318 # write flips
318 # write flips
319 data.extend(self.add_cmd('FLIP_START'))
319 data.extend(self.add_cmd('FLIP_START'))
320
320
321 states = self.get_pulses(binary=False)
321 states = self.get_pulses(binary=False)
322
322
323 for flips, delay in zip(states, delays):
323 for flips, delay in zip(states, delays):
324 flips.reverse()
324 flips.reverse()
325 flip = int(''.join([str(x) for x in flips]), 2)
325 flip = int(''.join([str(x) for x in flips]), 2)
326 data.extend(self.add_data(flip+1))
326 data.extend(self.add_data(flip+1))
327 while delay>252:
327 while delay>252:
328 data.extend(self.add_data(1))
328 data.extend(self.add_data(1))
329 delay -= 253
329 delay -= 253
330
330
331 # write sampling period
331 # write sampling period
332 data.extend(self.add_cmd('SAMPLING_PERIOD'))
332 data.extend(self.add_cmd('SAMPLING_PERIOD'))
333 wins = self.get_lines(line_type__name='windows')
333 wins = self.get_lines(line_type__name='windows')
334 if wins:
334 if wins:
335 win_params = json.loads(wins[0].params)['params']
335 win_params = json.loads(wins[0].params)['params']
336 if win_params:
336 if win_params:
337 dh = int(win_params[0]['resolution']*self.km2unit)
337 dh = int(win_params[0]['resolution']*self.km2unit)
338 else:
338 else:
339 dh = 1
339 dh = 1
340 else:
340 else:
341 dh = 1
341 dh = 1
342 data.extend(self.add_data(dh))
342 data.extend(self.add_data(dh))
343
343
344 # write enable
344 # write enable
345 data.extend(self.add_cmd('ENABLE'))
345 data.extend(self.add_cmd('ENABLE'))
346
346
347 if not dat:
347 if not dat:
348 return data
348 return data
349
349
350 return '\n'.join(['{}'.format(x) for x in data])
350 return '\n'.join(['{}'.format(x) for x in data])
351
351
352
352
353 def update_from_file(self, filename):
353 def update_from_file(self, filename):
354 '''
354 '''
355 Update instance from file
355 Update instance from file
356 '''
356 '''
357
357
358 f = RCFile(filename)
358 f = RCFile(filename)
359 self.dict_to_parms(f.data)
359 self.dict_to_parms(f.data)
360 self.update_pulses()
360 self.update_pulses()
361
361
362 def update_pulses(self):
362 def update_pulses(self):
363
363
364 for line in self.get_lines():
364 for line in self.get_lines():
365 line.update_pulses()
365 line.update_pulses()
366
366
367 def plot_pulses2(self, km=False):
367 def plot_pulses2(self, km=False):
368
368
369 import matplotlib.pyplot as plt
369 import matplotlib.pyplot as plt
370 from bokeh.resources import CDN
370 from bokeh.resources import CDN
371 from bokeh.embed import components
371 from bokeh.embed import components
372 from bokeh.mpl import to_bokeh
372 from bokeh.mpl import to_bokeh
373 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
373 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
374
374
375 lines = self.get_lines()
375 lines = self.get_lines()
376
376
377 N = len(lines)
377 N = len(lines)
378 npoints = self.total_units/self.km2unit if km else self.total_units
378 npoints = self.total_units/self.km2unit if km else self.total_units
379 fig = plt.figure(figsize=(12, 2+N*0.5))
379 fig = plt.figure(figsize=(12, 2+N*0.5))
380 ax = fig.add_subplot(111)
380 ax = fig.add_subplot(111)
381 labels = ['IPP']
381 labels = ['IPP']
382
382
383 for i, line in enumerate(lines):
383 for i, line in enumerate(lines):
384 labels.append(line.get_name(channel=True))
384 labels.append(line.get_name(channel=True))
385 l = ax.plot((0, npoints),(N-i-1, N-i-1))
385 l = ax.plot((0, npoints),(N-i-1, N-i-1))
386 points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
386 points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
387 ax.broken_barh(points, (N-i-1, 0.5),
387 ax.broken_barh(points, (N-i-1, 0.5),
388 edgecolor=l[0].get_color(), facecolor='none')
388 edgecolor=l[0].get_color(), facecolor='none')
389
389
390 n = 0
390 n = 0
391 f = ((self.ntx+50)/100)*5 if ((self.ntx+50)/100)*10>0 else 2
391 f = ((self.ntx+50)/100)*5 if ((self.ntx+50)/100)*10>0 else 2
392 for x in np.arange(0, npoints, self.ipp if km else self.ipp*self.km2unit):
392 for x in np.arange(0, npoints, self.ipp if km else self.ipp*self.km2unit):
393 if n%f==0:
393 if n%f==0:
394 ax.text(x, N, '%s' % n, size=10)
394 ax.text(x, N, '%s' % n, size=10)
395 n += 1
395 n += 1
396
396
397
397
398 labels.reverse()
398 labels.reverse()
399 ax.set_yticks(range(len(labels)))
399 ax.set_yticks(range(len(labels)))
400 ax.set_yticklabels(labels)
400 ax.set_yticklabels(labels)
401 ax.set_xlabel = 'Units'
401 ax.set_xlabel = 'Units'
402 plot = to_bokeh(fig, use_pandas=False)
402 plot = to_bokeh(fig, use_pandas=False)
403 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), SaveTool()]
403 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), SaveTool()]
404 plot.toolbar_location="above"
404 plot.toolbar_location="above"
405
405
406 return components(plot, CDN)
406 return components(plot, CDN)
407
407
408 def plot_pulses(self, km=False):
408 def plot_pulses(self, km=False):
409
409
410 from bokeh.plotting import figure
410 from bokeh.plotting import figure
411 from bokeh.resources import CDN
411 from bokeh.resources import CDN
412 from bokeh.embed import components
412 from bokeh.embed import components
413 from bokeh.models import FixedTicker, PrintfTickFormatter
413 from bokeh.models import FixedTicker, PrintfTickFormatter
414 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
414 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
415 from bokeh.models.sources import ColumnDataSource
415 from bokeh.models.sources import ColumnDataSource
416
416
417 lines = self.get_lines().reverse()
417 lines = self.get_lines().reverse()
418
418
419 N = len(lines)
419 N = len(lines)
420 npoints = self.total_units/self.km2unit if km else self.total_units
420 npoints = self.total_units/self.km2unit if km else self.total_units
421 ipp = self.ipp if km else self.ipp*self.km2unit
421 ipp = self.ipp if km else self.ipp*self.km2unit
422
422
423 hover = HoverTool(tooltips=[("Line", "@name"),
423 hover = HoverTool(tooltips=[("Line", "@name"),
424 ("IPP", "@ipp"),
424 ("IPP", "@ipp"),
425 ("X", "@left")])
425 ("X", "@left")])
426
426
427 tools = [PanTool(dimensions=['width']),
427 tools = [PanTool(dimensions=['width']),
428 WheelZoomTool(dimensions=['width']),
428 WheelZoomTool(dimensions=['width']),
429 hover, SaveTool()]
429 hover, SaveTool()]
430
430
431 plot = figure(width=1000,
431 plot = figure(width=1000,
432 height=40+N*50,
432 height=40+N*50,
433 y_range = (0, N),
433 y_range = (0, N),
434 tools=tools,
434 tools=tools,
435 toolbar_location='above',
435 toolbar_location='above',
436 toolbar_sticky=False,)
436 toolbar_sticky=False,)
437
437
438 plot.xaxis.axis_label = 'Km' if km else 'Units'
438 plot.xaxis.axis_label = 'Km' if km else 'Units'
439 plot.xaxis[0].formatter = PrintfTickFormatter(format='%d')
439 plot.xaxis[0].formatter = PrintfTickFormatter(format='%d')
440 plot.yaxis.axis_label = 'Pulses'
440 plot.yaxis.axis_label = 'Pulses'
441 plot.yaxis[0].ticker=FixedTicker(ticks=list(range(N)))
441 plot.yaxis[0].ticker=FixedTicker(ticks=list(range(N)))
442 plot.yaxis[0].formatter = PrintfTickFormatter(format='Line %d')
442 plot.yaxis[0].formatter = PrintfTickFormatter(format='Line %d')
443
443
444 for i, line in enumerate(lines):
444 for i, line in enumerate(lines):
445
445
446 points = [tup for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
446 points = [tup for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
447
447
448 source = ColumnDataSource(data = dict(
448 source = ColumnDataSource(data = dict(
449 bottom = [i for tup in points],
449 bottom = [i for tup in points],
450 top = [i+0.5 for tup in points],
450 top = [i+0.5 for tup in points],
451 left = [tup[0] for tup in points],
451 left = [tup[0] for tup in points],
452 right = [tup[1] for tup in points],
452 right = [tup[1] for tup in points],
453 ipp = [int(tup[0]/ipp) for tup in points],
453 ipp = [int(tup[0]/ipp) for tup in points],
454 name = [line.get_name() for tup in points]
454 name = [line.get_name() for tup in points]
455 ))
455 ))
456
456
457 plot.quad(
457 plot.quad(
458 bottom = 'bottom',
458 bottom = 'bottom',
459 top = 'top',
459 top = 'top',
460 left = 'left',
460 left = 'left',
461 right = 'right',
461 right = 'right',
462 source = source,
462 source = source,
463 fill_alpha = 0,
463 fill_alpha = 0,
464 #line_color = 'blue',
464 #line_color = 'blue',
465 )
465 )
466
466
467 plot.line([0, npoints], [i, i])#, color='blue')
467 plot.line([0, npoints], [i, i])#, color='blue')
468
468
469 return components(plot, CDN)
469 return components(plot, CDN)
470
470
471 def status_device(self):
471 def status_device(self):
472
472
473 try:
473 try:
474 self.device.status = 0
474 self.device.status = 0
475 req = requests.get(self.device.url('status'))
475 req = requests.get(self.device.url('status'))
476 payload = req.json()
476 payload = req.json()
477 if payload['status']=='enabled':
477 if payload['status']=='enabled':
478 self.device.status = 3
478 self.device.status = 3
479 elif payload['status']=='disabled':
479 elif payload['status']=='disabled':
480 self.device.status = 2
480 self.device.status = 2
481 else:
481 else:
482 self.device.status = 1
482 self.device.status = 1
483 self.device.save()
483 self.device.save()
484 self.message = payload['status']
484 self.message = payload['status']
485 return False
485 return False
486 except Exception as e:
486 except Exception as e:
487 if 'No route to host' not in str(e):
487 if 'No route to host' not in str(e):
488 self.device.status = 4
488 self.device.status = 4
489 self.device.save()
489 self.device.save()
490 self.message = str(e)
490 self.message = str(e)
491 return False
491 return False
492
492
493 self.device.save()
493 self.device.save()
494 return True
494 return True
495
495
496 def reset_device(self):
496 def reset_device(self):
497
497
498 try:
498 try:
499 req = requests.post(self.device.url('reset'))
499 req = requests.post(self.device.url('reset'))
500 payload = req.json()
500 payload = req.json()
501 if payload['reset']=='ok':
501 if payload['reset']=='ok':
502 self.message = 'RC restarted'
502 self.message = 'RC restarted'
503 else:
503 else:
504 self.message = 'RC restart not ok'
504 self.message = 'RC restart not ok'
505 self.device.status = 4
505 self.device.status = 4
506 self.device.save()
506 self.device.save()
507 except Exception as e:
507 except Exception as e:
508 self.message = str(e)
508 self.message = str(e)
509 return False
509 return False
510
510
511 return True
511 return True
512
512
513 def stop_device(self):
513 def stop_device(self):
514
514
515 try:
515 try:
516 req = requests.post(self.device.url('stop'))
516 req = requests.post(self.device.url('stop'))
517 payload = req.json()
517 payload = req.json()
518 if payload['stop']=='ok':
518 if payload['stop']=='ok':
519 self.device.status = 2
519 self.device.status = 2
520 self.device.save()
520 self.device.save()
521 self.message = 'RC stopped'
521 self.message = 'RC stopped'
522 else:
522 else:
523 self.message = 'RC stop not ok'
523 self.message = 'RC stop not ok'
524 self.device.status = 4
524 self.device.status = 4
525 self.device.save()
525 self.device.save()
526 return False
526 return False
527 except Exception as e:
527 except Exception as e:
528 if 'No route to host' not in str(e):
528 if 'No route to host' not in str(e):
529 self.device.status = 4
529 self.device.status = 4
530 else:
530 else:
531 self.device.status = 0
531 self.device.status = 0
532 self.message = str(e)
532 self.message = str(e)
533 self.device.save()
533 self.device.save()
534 return False
534 return False
535
535
536 return True
536 return True
537
537
538 def start_device(self):
538 def start_device(self):
539
539
540 try:
540 try:
541 req = requests.post(self.device.url('start'))
541 req = requests.post(self.device.url('start'))
542 payload = req.json()
542 payload = req.json()
543 if payload['start']=='ok':
543 if payload['start']=='ok':
544 self.device.status = 3
544 self.device.status = 3
545 self.device.save()
545 self.device.save()
546 self.message = 'RC running'
546 self.message = 'RC running'
547 else:
547 else:
548 self.message = 'RC start not ok'
548 self.message = 'RC start not ok'
549 return False
549 return False
550 except Exception as e:
550 except Exception as e:
551 if 'No route to host' not in str(e):
551 if 'No route to host' not in str(e):
552 self.device.status = 4
552 self.device.status = 4
553 else:
553 else:
554 self.device.status = 0
554 self.device.status = 0
555 self.message = str(e)
555 self.message = str(e)
556 self.device.save()
556 self.device.save()
557 return False
557 return False
558
558
559 return True
559 return True
560
560
561 def write_device(self):
561 def write_device(self):
562
562
563 values = zip(self.get_pulses(),
563 values = zip(self.get_pulses(),
564 [x-1 for x in self.get_delays()])
564 [x-1 for x in self.get_delays()])
565
565
566 data = bytearray()
566 data = bytearray()
567 #reset
567 #reset
568 data.extend((128, 0))
568 data.extend((128, 0))
569 #disable
569 #disable
570 data.extend((129, 0))
570 data.extend((129, 0))
571 #divider
571 #divider
572 data.extend((131, self.clock_divider-1))
572 data.extend((131, self.clock_divider-1))
573 #enable writing
573 #enable writing
574 data.extend((139, 62))
574 data.extend((139, 62))
575
575
576 last = 0
576 last = 0
577 for tup in values:
577 for tup in values:
578 vals = pack('<HH', last^tup[0], tup[1])
578 vals = pack('<HH', last^tup[0], tup[1])
579 last = tup[0]
579 last = tup[0]
580 data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
580 data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
581
581
582 #enable
582 #enable
583 data.extend((129, 1))
583 data.extend((129, 1))
584
584
585 try:
585 try:
586 req = requests.post(self.device.url('write'), data=b64encode(data))
586 req = requests.post(self.device.url('write'), data=b64encode(data))
587 payload = req.json()
587 payload = req.json()
588 if payload['write']=='ok':
588 if payload['write']=='ok':
589 self.device.status = 2
589 self.device.status = 2
590 self.device.save()
590 self.device.save()
591 self.message = 'RC configured'
591 self.message = 'RC configured'
592 else:
592 else:
593 self.device.status = 1
593 self.device.status = 1
594 self.device.save()
594 self.device.save()
595 self.message = 'RC write not ok'
595 self.message = 'RC write not ok'
596 return False
596 return False
597
597
598 except Exception as e:
598 except Exception as e:
599 if 'No route to host' not in str(e):
599 if 'No route to host' not in str(e):
600 self.device.status = 4
600 self.device.status = 4
601 else:
601 else:
602 self.device.status = 0
602 self.device.status = 0
603 self.message = str(e)
603 self.message = str(e)
604 self.device.save()
604 self.device.save()
605 return False
605 return False
606
606
607 return True
607 return True
608
608
609
609
610 class RCLineCode(models.Model):
610 class RCLineCode(models.Model):
611
611
612 name = models.CharField(max_length=40)
612 name = models.CharField(max_length=40)
613 bits_per_code = models.PositiveIntegerField(default=0)
613 bits_per_code = models.PositiveIntegerField(default=0)
614 number_of_codes = models.PositiveIntegerField(default=0)
614 number_of_codes = models.PositiveIntegerField(default=0)
615 codes = models.TextField(blank=True, null=True)
615 codes = models.TextField(blank=True, null=True)
616
616
617 class Meta:
617 class Meta:
618 db_table = 'rc_line_codes'
618 db_table = 'rc_line_codes'
619 ordering = ('name',)
619 ordering = ('name',)
620
620
621 def __str__(self):
621 def __str__(self):
622 return u'%s' % self.name
622 return u'%s' % self.name
623
623
624
624
625 class RCLineType(models.Model):
625 class RCLineType(models.Model):
626
626
627 name = models.CharField(choices=LINE_TYPES, max_length=40)
627 name = models.CharField(choices=LINE_TYPES, max_length=40)
628 description = models.TextField(blank=True, null=True)
628 description = models.TextField(blank=True, null=True)
629 params = models.TextField(default='[]')
629 params = models.TextField(default='[]')
630
630
631 class Meta:
631 class Meta:
632 db_table = 'rc_line_types'
632 db_table = 'rc_line_types'
633
633
634 def __str__(self):
634 def __str__(self):
635 return u'%s - %s' % (self.name.upper(), self.get_name_display())
635 return u'%s - %s' % (self.name.upper(), self.get_name_display())
636
636
637
637
638 class RCLine(models.Model):
638 class RCLine(models.Model):
639
639
640 rc_configuration = models.ForeignKey(RCConfiguration, on_delete=models.CASCADE)
640 rc_configuration = models.ForeignKey(RCConfiguration, on_delete=models.CASCADE)
641 line_type = models.ForeignKey(RCLineType)
641 line_type = models.ForeignKey(RCLineType)
642 channel = models.PositiveIntegerField(default=0)
642 channel = models.PositiveIntegerField(default=0)
643 position = models.PositiveIntegerField(default=0)
643 position = models.PositiveIntegerField(default=0)
644 params = models.TextField(default='{}')
644 params = models.TextField(default='{}')
645 pulses = models.TextField(default='')
645 pulses = models.TextField(default='')
646
646
647 class Meta:
647 class Meta:
648 db_table = 'rc_lines'
648 db_table = 'rc_lines'
649 ordering = ['channel']
649 ordering = ['channel']
650
650
651 def __str__(self):
651 def __str__(self):
652 if self.rc_configuration:
652 if self.rc_configuration:
653 return u'%s - %s' % (self.rc_configuration, self.get_name())
653 return u'%s - %s' % (self.rc_configuration, self.get_name())
654
654
655 def clone(self, **kwargs):
655 def clone(self, **kwargs):
656
656
657 self.pk = None
657 self.pk = None
658
658
659 for attr, value in kwargs.items():
659 for attr, value in kwargs.items():
660 setattr(self, attr, value)
660 setattr(self, attr, value)
661
661
662 self.save()
662 self.save()
663
663
664 return self
664 return self
665
665
666 def get_name(self, channel=False):
666 def get_name(self, channel=False):
667
667
668 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
668 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
669 s = ''
669 s = ''
670
670
671 if self.line_type.name in ('tx',):
671 if self.line_type.name in ('tx',):
672 s = chars[self.position]
672 s = chars[self.position]
673 elif self.line_type.name in ('codes', 'windows', 'tr'):
673 elif self.line_type.name in ('codes', 'windows', 'tr'):
674 if 'TX_ref' in json.loads(self.params):
674 if 'TX_ref' in json.loads(self.params):
675 pk = json.loads(self.params)['TX_ref']
675 pk = json.loads(self.params)['TX_ref']
676 if pk in (0, '0'):
676 if pk in (0, '0'):
677 s = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
677 s = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
678 else:
678 else:
679 ref = RCLine.objects.get(pk=pk)
679 ref = RCLine.objects.get(pk=pk)
680 s = chars[ref.position]
680 s = chars[ref.position]
681 s = '({})'.format(s)
681 s = '({})'.format(s)
682
682
683 s = '{}{}'.format(self.line_type.name.upper(), s)
683 s = '{}{}'.format(self.line_type.name.upper(), s)
684
684
685 if channel:
685 if channel:
686 return '{} {}'.format(s, self.channel)
686 return '{} {}'.format(s, self.channel)
687 else:
687 else:
688 return s
688 return s
689
689
690 def get_lines(self, **kwargs):
690 def get_lines(self, **kwargs):
691
691
692 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
692 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
693
693
694 def pulses_as_array(self):
694 def pulses_as_array(self):
695
695
696 y = np.zeros(self.rc_configuration.total_units)
696 y = np.zeros(self.rc_configuration.total_units)
697
697
698 for tup in ast.literal_eval(self.pulses):
698 for tup in ast.literal_eval(self.pulses):
699 y[tup[0]:tup[1]] = 1
699 y[tup[0]:tup[1]] = 1
700
700
701 return y.astype(np.int8)
701 return y.astype(np.int8)
702
702
703 def pulses_as_points(self, km=False):
703 def pulses_as_points(self, km=False):
704
704
705 if km:
705 if km:
706 unit2km = 1/self.rc_configuration.km2unit
706 unit2km = 1/self.rc_configuration.km2unit
707 return [(tup[0]*unit2km, tup[1]*unit2km) for tup in ast.literal_eval(self.pulses)]
707 return [(tup[0]*unit2km, tup[1]*unit2km) for tup in ast.literal_eval(self.pulses)]
708 else:
708 else:
709 return ast.literal_eval(self.pulses)
709 return ast.literal_eval(self.pulses)
710
710
711 def get_win_ref(self, params, tx_id, km2unit):
711 def get_win_ref(self, params, tx_id, km2unit):
712
712
713 ref = self.rc_configuration.sampling_reference
713 ref = self.rc_configuration.sampling_reference
714 codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
714 codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
715
715
716 if codes:
716 if codes:
717 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/len(json.loads(codes[0].params)['codes'][0])
717 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/len(json.loads(codes[0].params)['codes'][0])
718 else:
718 else:
719 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
719 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
720
720
721 if ref=='first_baud':
721 if ref=='first_baud':
722 return int(1 + round((tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit))
722 return int(1 + round((tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit))
723 elif ref=='sub_baud':
723 elif ref=='sub_baud':
724 return np.ceil(1 + params['first_height']*km2unit - params['resolution']*km2unit/2)
724 return np.ceil(1 + params['first_height']*km2unit - params['resolution']*km2unit/2)
725 else:
725 else:
726 return 0
726 return 0
727
727
728 def update_pulses(self):
728 def update_pulses(self):
729 '''
729 '''
730 Update pulses field
730 Update pulses field
731 '''
731 '''
732
732
733 km2unit = self.rc_configuration.km2unit
733 km2unit = self.rc_configuration.km2unit
734 us2unit = self.rc_configuration.us2unit
734 us2unit = self.rc_configuration.us2unit
735 ipp = self.rc_configuration.ipp
735 ipp = self.rc_configuration.ipp
736 ntx = int(self.rc_configuration.ntx)
736 ntx = int(self.rc_configuration.ntx)
737 ipp_u = int(ipp*km2unit)
737 ipp_u = int(ipp*km2unit)
738 total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units
738 total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units
739 y = []
739 y = []
740
740
741 if self.line_type.name=='tr':
741 if self.line_type.name=='tr':
742 tr_params = json.loads(self.params)
742 tr_params = json.loads(self.params)
743
743
744 if tr_params['TX_ref'] in ('0', 0):
744 if tr_params['TX_ref'] in ('0', 0):
745 txs = self.get_lines(line_type__name='tx')
745 txs = self.get_lines(line_type__name='tx')
746 else:
746 else:
747 txs = RCLine.objects.filter(pk=tr_params['TX_ref'])
747 txs = RCLine.objects.filter(pk=tr_params['TX_ref'])
748
748
749 for tx in txs:
749 for tx in txs:
750 params = json.loads(tx.params)
750 params = json.loads(tx.params)
751
751
752 if float(params['pulse_width'])==0:
752 if float(params['pulse_width'])==0:
753 continue
753 continue
754 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
754 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
755 width = float(params['pulse_width'])*km2unit+int(self.rc_configuration.time_before*us2unit)
755 width = float(params['pulse_width'])*km2unit+int(self.rc_configuration.time_before*us2unit)
756 before = 0
756 before = 0
757 after = int(self.rc_configuration.time_after*us2unit)
757 after = int(self.rc_configuration.time_after*us2unit)
758
758
759 y_tx = self.points(ntx, ipp_u, width,
759 y_tx = self.points(ntx, ipp_u, width,
760 delay=delays,
760 delay=delays,
761 before=before,
761 before=before,
762 after=after,
762 after=after,
763 sync=self.rc_configuration.sync)
763 sync=self.rc_configuration.sync)
764
764
765 ranges = params['range'].split(',')
765 ranges = params['range'].split(',')
766
766
767 if len(ranges)>0 and ranges[0]!='0':
767 if len(ranges)>0 and ranges[0]!='0':
768 y_tx = self.mask_ranges(y_tx, ranges)
768 y_tx = self.mask_ranges(y_tx, ranges)
769
769
770 tr_ranges = tr_params['range'].split(',')
770 tr_ranges = tr_params['range'].split(',')
771
771
772 if len(tr_ranges)>0 and tr_ranges[0]!='0':
772 if len(tr_ranges)>0 and tr_ranges[0]!='0':
773 y_tx = self.mask_ranges(y_tx, tr_ranges)
773 y_tx = self.mask_ranges(y_tx, tr_ranges)
774
774
775 y.extend(y_tx)
775 y.extend(y_tx)
776
776
777 self.pulses = str(y)
777 self.pulses = str(y)
778 y = self.array_to_points(self.pulses_as_array())
778 y = self.array_to_points(self.pulses_as_array())
779
779
780 elif self.line_type.name=='tx':
780 elif self.line_type.name=='tx':
781 params = json.loads(self.params)
781 params = json.loads(self.params)
782 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
782 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
783 width = float(params['pulse_width'])*km2unit
783 width = float(params['pulse_width'])*km2unit
784
784
785 if width>0:
785 if width>0:
786 before = int(self.rc_configuration.time_before*us2unit)
786 before = int(self.rc_configuration.time_before*us2unit)
787 after = 0
787 after = 0
788
788
789 y = self.points(ntx, ipp_u, width,
789 y = self.points(ntx, ipp_u, width,
790 delay=delays,
790 delay=delays,
791 before=before,
791 before=before,
792 after=after,
792 after=after,
793 sync=self.rc_configuration.sync)
793 sync=self.rc_configuration.sync)
794
794
795 ranges = params['range'].split(',')
795 ranges = params['range'].split(',')
796
796
797 if len(ranges)>0 and ranges[0]!='0':
797 if len(ranges)>0 and ranges[0]!='0':
798 y = self.mask_ranges(y, ranges)
798 y = self.mask_ranges(y, ranges)
799
799
800 elif self.line_type.name=='flip':
800 elif self.line_type.name=='flip':
801 n = float(json.loads(self.params)['number_of_flips'])
801 n = float(json.loads(self.params)['number_of_flips'])
802 width = n*ipp*km2unit
802 width = n*ipp*km2unit
803 y = self.points(int((ntx+1)/(2*n)), ipp_u*n*2, width)
803 y = self.points(int((ntx+1)/(2*n)), ipp_u*n*2, width)
804
804
805 elif self.line_type.name=='codes':
805 elif self.line_type.name=='codes':
806 params = json.loads(self.params)
806 params = json.loads(self.params)
807 tx = RCLine.objects.get(pk=params['TX_ref'])
807 tx = RCLine.objects.get(pk=params['TX_ref'])
808 tx_params = json.loads(tx.params)
808 tx_params = json.loads(tx.params)
809 delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
809 delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
810 f = int(float(tx_params['pulse_width'])*km2unit/len(params['codes'][0]))
810 f = int(float(tx_params['pulse_width'])*km2unit/len(params['codes'][0]))
811 codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in params['codes']]
811 codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in params['codes']]
812 codes = [self.array_to_points(code) for code in codes]
812 codes = [self.array_to_points(code) for code in codes]
813 n = len(codes)
813 n = len(codes)
814
814
815 ranges = tx_params['range'].split(',')
815 ranges = tx_params['range'].split(',')
816 if len(ranges)>0 and ranges[0]!='0':
816 if len(ranges)>0 and ranges[0]!='0':
817 dum = self.mask_ranges(tx.pulses_as_points(), ranges)
817 dum = self.mask_ranges(tx.pulses_as_points(), ranges)
818 else:
818 else:
819 dum = tx.pulses_as_points()
819 dum = tx.pulses_as_points()
820
820
821 for i, tup in enumerate(dum):
821 for i, tup in enumerate(dum):
822 if tup==(0,0): continue
822 if tup==(0,0): continue
823 code = codes[i%n]
823 code = codes[i%n]
824 y.extend([(c[0]+tup[0], c[1]+tup[0]) for c in code])
824 y.extend([(c[0]+tup[0], c[1]+tup[0]) for c in code])
825
825
826 elif self.line_type.name=='sync':
826 elif self.line_type.name=='sync':
827 params = json.loads(self.params)
827 params = json.loads(self.params)
828 n = ipp_u*ntx
828 n = ipp_u*ntx
829 if params['invert'] in ('1', 1):
829 if params['invert'] in ('1', 1):
830 y = [(n-1, n)]
830 y = [(n-1, n)]
831 else:
831 else:
832 y = [(0, 1)]
832 y = [(0, 1)]
833
833
834 elif self.line_type.name=='prog_pulses':
834 elif self.line_type.name=='prog_pulses':
835 params = json.loads(self.params)
835 params = json.loads(self.params)
836 if int(params['periodic'])==0:
836 if int(params['periodic'])==0:
837 nntx = 1
837 nntx = 1
838 nipp = ipp_u*ntx
838 nipp = ipp_u*ntx
839 else:
839 else:
840 nntx = ntx
840 nntx = ntx
841 nipp = ipp_u
841 nipp = ipp_u
842
842
843 if 'params' in params and len(params['params'])>0:
843 if 'params' in params and len(params['params'])>0:
844 for p in params['params']:
844 for p in params['params']:
845 y_pp = self.points(nntx, nipp,
845 y_pp = self.points(nntx, nipp,
846 p['end']-p['begin'],
846 p['end']-p['begin'],
847 before=p['begin'])
847 before=p['begin'])
848
848
849 y.extend(y_pp)
849 y.extend(y_pp)
850
850
851 elif self.line_type.name=='windows':
851 elif self.line_type.name=='windows':
852 params = json.loads(self.params)
852 params = json.loads(self.params)
853 if 'params' in params and len(params['params'])>0:
853 if 'params' in params and len(params['params'])>0:
854 tr_params = json.loads(self.get_lines(line_type__name='tr')[0].params)
854 tr_params = json.loads(self.get_lines(line_type__name='tr')[0].params)
855 tr_ranges = tr_params['range'].split(',')
855 tr_ranges = tr_params['range'].split(',')
856 for p in params['params']:
856 for p in params['params']:
857 y_win = self.points(ntx, ipp_u,
857 y_win = self.points(ntx, ipp_u,
858 p['resolution']*p['number_of_samples']*km2unit,
858 p['resolution']*p['number_of_samples']*km2unit,
859 before=int(self.rc_configuration.time_before*us2unit),
859 before=int(self.rc_configuration.time_before*us2unit),
860 sync=self.rc_configuration.sync+self.get_win_ref(p, params['TX_ref'], km2unit))
860 sync=self.rc_configuration.sync+self.get_win_ref(p, params['TX_ref'], km2unit))
861
861
862
862
863 if len(tr_ranges)>0 and tr_ranges[0]!='0':
863 if len(tr_ranges)>0 and tr_ranges[0]!='0':
864 y_win = self.mask_ranges(y_win, tr_ranges)
864 y_win = self.mask_ranges(y_win, tr_ranges)
865
865
866 y.extend(y_win)
866 y.extend(y_win)
867
867
868 elif self.line_type.name=='mix':
868 elif self.line_type.name=='mix':
869 values = self.rc_configuration.parameters.split('-')
869 values = self.rc_configuration.parameters.split('-')
870 confs = [RCConfiguration.objects.get(pk=value.split('|')[0]) for value in values]
870 confs = [RCConfiguration.objects.get(pk=value.split('|')[0]) for value in values]
871 modes = [value.split('|')[1] for value in values]
871 modes = [value.split('|')[1] for value in values]
872 ops = [value.split('|')[2] for value in values]
872 ops = [value.split('|')[2] for value in values]
873 delays = [value.split('|')[3] for value in values]
873 delays = [value.split('|')[3] for value in values]
874 masks = [value.split('|')[4] for value in values]
874 masks = [value.split('|')[4] for value in values]
875 mask = list('{:8b}'.format(int(masks[0])))
875 mask = list('{:8b}'.format(int(masks[0])))
876 mask.reverse()
876 mask.reverse()
877 if mask[self.channel] in ('0', '', ' '):
877 if mask[self.channel] in ('0', '', ' '):
878 y = np.zeros(confs[0].total_units, dtype=np.int8)
878 y = np.zeros(confs[0].total_units, dtype=np.int8)
879 else:
879 else:
880 y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
880 y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
881
881
882 for i in range(1, len(values)):
882 for i in range(1, len(values)):
883 mask = list('{:8b}'.format(int(masks[i])))
883 mask = list('{:8b}'.format(int(masks[i])))
884 mask.reverse()
884 mask.reverse()
885
885
886 if mask[self.channel] in ('0', '', ' '):
886 if mask[self.channel] in ('0', '', ' '):
887 continue
887 continue
888 Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
888 Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
889 delay = float(delays[i])*km2unit
889 delay = float(delays[i])*km2unit
890
890
891 if modes[i]=='P':
891 if modes[i]=='P':
892 if delay>0:
892 if delay>0:
893 if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y):
893 if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y):
894 y_temp = np.empty_like(Y)
894 y_temp = np.empty_like(Y)
895 y_temp[:delay] = 0
895 y_temp[:delay] = 0
896 y_temp[delay:] = Y[:-delay]
896 y_temp[delay:] = Y[:-delay]
897 elif delay+len(Y)>len(y):
897 elif delay+len(Y)>len(y):
898 y_new = np.zeros(delay+len(Y), dtype=np.int8)
898 y_new = np.zeros(delay+len(Y), dtype=np.int8)
899 y_new[:len(y)] = y
899 y_new[:len(y)] = y
900 y = y_new
900 y = y_new
901 y_temp = np.zeros(delay+len(Y), dtype=np.int8)
901 y_temp = np.zeros(delay+len(Y), dtype=np.int8)
902 y_temp[-len(Y):] = Y
902 y_temp[-len(Y):] = Y
903 elif delay+len(Y)==len(y):
903 elif delay+len(Y)==len(y):
904 y_temp = np.zeros(delay+len(Y))
904 y_temp = np.zeros(delay+len(Y))
905 y_temp[-len(Y):] = Y
905 y_temp[-len(Y):] = Y
906 elif delay+len(Y)<len(y):
906 elif delay+len(Y)<len(y):
907 y_temp = np.zeros(len(y), dtype=np.int8)
907 y_temp = np.zeros(len(y), dtype=np.int8)
908 y_temp[delay:delay+len(Y)] = Y
908 y_temp[delay:delay+len(Y)] = Y
909 else:
910 y_temp = Y.copy()
909
911
910 if ops[i]=='OR':
912 if ops[i]=='OR':
911 y = y | y_temp
913 y = y | y_temp
912 elif ops[i]=='XOR':
914 elif ops[i]=='XOR':
913 y = y ^ y_temp
915 y = y ^ y_temp
914 elif ops[i]=='AND':
916 elif ops[i]=='AND':
915 y = y & y_temp
917 y = y & y_temp
916 elif ops[i]=='NAND':
918 elif ops[i]=='NAND':
917 y = y & ~y_temp
919 y = y & ~y_temp
918 else:
920 else:
919 y = np.concatenate([y, Y])
921 y = np.concatenate([y, Y])
920
922
921 total = len(y)
923 total = len(y)
922 y = self.array_to_points(y)
924 y = self.array_to_points(y)
923
925
924 else:
926 else:
925 y = []
927 y = []
926
928
927 if self.rc_configuration.total_units != total:
929 if self.rc_configuration.total_units != total:
928 self.rc_configuration.total_units = total
930 self.rc_configuration.total_units = total
929 self.rc_configuration.save()
931 self.rc_configuration.save()
930
932
931 self.pulses = str(y)
933 self.pulses = str(y)
932 self.save()
934 self.save()
933
935
934 @staticmethod
936 @staticmethod
935 def array_to_points(X):
937 def array_to_points(X):
936
938
937 d = X[1:]-X[:-1]
939 d = X[1:]-X[:-1]
938
940
939 up = np.where(d==1)[0]
941 up = np.where(d==1)[0]
940 if X[0]==1:
942 if X[0]==1:
941 up = np.concatenate((np.array([-1]), up))
943 up = np.concatenate((np.array([-1]), up))
942 up += 1
944 up += 1
943
945
944 dw = np.where(d==-1)[0]
946 dw = np.where(d==-1)[0]
945 if X[-1]==1:
947 if X[-1]==1:
946 dw = np.concatenate((dw, np.array([len(X)-1])))
948 dw = np.concatenate((dw, np.array([len(X)-1])))
947 dw += 1
949 dw += 1
948
950
949 return [(tup[0], tup[1]) for tup in zip(up, dw)]
951 return [(tup[0], tup[1]) for tup in zip(up, dw)]
950
952
951 @staticmethod
953 @staticmethod
952 def mask_ranges(Y, ranges):
954 def mask_ranges(Y, ranges):
953
955
954 y = [(0, 0) for __ in Y]
956 y = [(0, 0) for __ in Y]
955
957
956 for index in ranges:
958 for index in ranges:
957 if '-' in index:
959 if '-' in index:
958 args = [int(a) for a in index.split('-')]
960 args = [int(a) for a in index.split('-')]
959 y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
961 y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
960 else:
962 else:
961 y[int(index)-1] = Y[int(index)-1]
963 y[int(index)-1] = Y[int(index)-1]
962
964
963 return y
965 return y
964
966
965 @staticmethod
967 @staticmethod
966 def points(ntx, ipp, width, delay=[0], before=0, after=0, sync=0):
968 def points(ntx, ipp, width, delay=[0], before=0, after=0, sync=0):
967
969
968 delays = len(delay)
970 delays = len(delay)
969
971
970 Y = [(int(ipp*x+before+delay[x%delays]+sync), int(ipp*x+width+before+delay[x%delays]+after+sync)) for x in range(ntx)]
972 Y = [(int(ipp*x+before+delay[x%delays]+sync), int(ipp*x+width+before+delay[x%delays]+after+sync)) for x in range(ntx)]
971
973
972 return Y
974 return Y
General Comments 0
You need to be logged in to leave comments. Login now