##// END OF EJS Templates
Fix mix RC configurations for different ipp's...
Juan C. Espinoza -
r112:90a1581a0938
parent child
Show More
@@ -1,26 +1,34
1 1 {% extends "base_edit.html" %}
2 2 {% load bootstrap3 %}
3 3 {% load static %}
4 4 {% load main_tags %}
5 5 {% block extra-head %}
6 6 <link href="{% static 'css/bootstrap-datetimepicker.min.css' %}" media="screen" rel="stylesheet">
7 7 <style type="text/css">
8 8 .tabuled {font-family: Courier New}
9 9 .check-inline {display: inline}
10 10 </style>
11 11 {% endblock %}
12 12
13 13 {% block extra-js%}
14 14 <script src="{% static 'js/moment.min.js' %}"></script>
15 15 <script src="{% static 'js/bootstrap-datetimepicker.min.js' %}"></script>
16 16 <script src="{% static 'js/cr.js' %}"></script>
17 17
18 18 <script type="text/javascript">
19 19
20 20 $("#bt_Delete").click(function() {
21 21 document.location = "{% url 'url_delete_mix_experiment' id_exp %}";
22 22 });
23 23
24 $('input[type=radio][name=mode]').change(function() {
25 if (this.value == '0') {
26 $('input[type=radio][name=operation]').prop('disabled', false);
27 }else{
28 $('input[type=radio][name=operation]').prop('disabled', true);
29 }
30 });
31
24 32 </script>
25 33
26 34 {% endblock %} No newline at end of file
@@ -1,38 +1,39
1 1 from django.template.defaulttags import register
2 2 from django.utils.safestring import mark_safe
3 3
4 4 @register.filter
5 5 def attr(instance, key):
6 6
7 7 display_key = "get_" + key + "_display"
8 8
9 9 if hasattr(instance, display_key):
10 10 return getattr(instance, display_key)()
11 11
12 12 if hasattr(instance, key):
13 13 return getattr(instance, key)
14 14
15 15 return instance.get(key)
16 16
17 17 @register.filter
18 18 def title(s):
19 19 return s.split('__')[-1].replace('_', ' ').title()
20 20
21 21 @register.filter
22 22 def value(instance, key):
23 23
24 24 item = instance
25 25 if key=='name':
26 26 return '%s' % item
27 27 for my_key in key.split("__"):
28 28 item = attr(item, my_key)
29 29
30 30 return item
31 31
32 32 @register.simple_tag
33 33 def get_verbose_field_name(instance, field_name):
34 34 """
35 35 Returns verbose_name for a field.
36 36 """
37
37 if field_name=='ipp_unit':
38 return 'Inter pulse period [Km(Units)]'
38 39 return mark_safe(instance._meta.get_field(field_name).verbose_name) No newline at end of file
@@ -1,1363 +1,1379
1 1 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
2 2 from django.utils.safestring import mark_safe
3 3 from django.http import HttpResponseRedirect
4 4 from django.core.urlresolvers import reverse
5 5 from django.contrib import messages
6 6 from datetime import datetime
7 7
8 8 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
9 9 from .forms import OperationSearchForm
10 10 from apps.cgs.forms import CGSConfigurationForm
11 11 from apps.jars.forms import JARSConfigurationForm
12 12 from apps.usrp.forms import USRPConfigurationForm
13 13 from apps.abs.forms import ABSConfigurationForm
14 14 from apps.rc.forms import RCConfigurationForm, RCMixConfigurationForm
15 15 from apps.dds.forms import DDSConfigurationForm
16 16
17 17 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment
18 18 from apps.cgs.models import CGSConfiguration
19 19 from apps.jars.models import JARSConfiguration
20 20 from apps.usrp.models import USRPConfiguration
21 21 from apps.abs.models import ABSConfiguration
22 22 from apps.rc.models import RCConfiguration, RCLine, RCLineType
23 23 from apps.dds.models import DDSConfiguration
24 24
25 25 # Create your views here.
26 26
27 27 CONF_FORMS = {
28 28 'rc': RCConfigurationForm,
29 29 'rc_mix': RCMixConfigurationForm,
30 30 'dds': DDSConfigurationForm,
31 31 'jars': JARSConfigurationForm,
32 32 'cgs': CGSConfigurationForm,
33 33 'abs': ABSConfigurationForm,
34 34 'usrp': USRPConfigurationForm,
35 35 }
36 36
37 37 CONF_MODELS = {
38 38 'rc': RCConfiguration,
39 39 'dds': DDSConfiguration,
40 40 'jars': JARSConfiguration,
41 41 'cgs': CGSConfiguration,
42 42 'abs': ABSConfiguration,
43 43 'usrp': USRPConfiguration,
44 44 }
45 45
46 46 MIX_MODES = {
47 '0': 'P',
48 '1': 'S',
49 }
50
51 MIX_OPERATIONS = {
47 52 '0': 'OR',
48 53 '1': 'XOR',
49 54 '2': 'AND',
50 '3': 'NAND'
55 '3': 'NAND',
51 56 }
52 57
53 58
54 59 def index(request):
55 60 kwargs = {}
56 61
57 62 return render(request, 'index.html', kwargs)
58 63
59 64
60 65 def locations(request):
61 66
62 67 locations = Location.objects.all().order_by('name')
63 68
64 69 keys = ['id', 'name', 'description']
65 70
66 71 kwargs = {}
67 72 kwargs['location_keys'] = keys[1:]
68 73 kwargs['locations'] = locations
69 74 kwargs['title'] = 'Location'
70 75 kwargs['suptitle'] = 'List'
71 76 kwargs['button'] = 'New Location'
72 77
73 78 return render(request, 'locations.html', kwargs)
74 79
75 80
76 81 def location(request, id_loc):
77 82
78 83 location = get_object_or_404(Location, pk=id_loc)
79 84
80 85 kwargs = {}
81 86 kwargs['location'] = location
82 87 kwargs['location_keys'] = ['name', 'description']
83 88
84 89 kwargs['title'] = 'Location'
85 90 kwargs['suptitle'] = 'Details'
86 91
87 92 return render(request, 'location.html', kwargs)
88 93
89 94
90 95 def location_new(request):
91 96
92 97 if request.method == 'GET':
93 98 form = LocationForm()
94 99
95 100 if request.method == 'POST':
96 101 form = LocationForm(request.POST)
97 102
98 103 if form.is_valid():
99 104 form.save()
100 105 return redirect('url_locations')
101 106
102 107 kwargs = {}
103 108 kwargs['form'] = form
104 109 kwargs['title'] = 'Location'
105 110 kwargs['suptitle'] = 'New'
106 111 kwargs['button'] = 'Create'
107 112
108 113 return render(request, 'location_edit.html', kwargs)
109 114
110 115
111 116 def location_edit(request, id_loc):
112 117
113 118 location = get_object_or_404(Location, pk=id_loc)
114 119
115 120 if request.method=='GET':
116 121 form = LocationForm(instance=location)
117 122
118 123 if request.method=='POST':
119 124 form = LocationForm(request.POST, instance=location)
120 125
121 126 if form.is_valid():
122 127 form.save()
123 128 return redirect('url_locations')
124 129
125 130 kwargs = {}
126 131 kwargs['form'] = form
127 132 kwargs['title'] = 'Location'
128 133 kwargs['suptitle'] = 'Edit'
129 134 kwargs['button'] = 'Update'
130 135
131 136 return render(request, 'location_edit.html', kwargs)
132 137
133 138
134 139 def location_delete(request, id_loc):
135 140
136 141 location = get_object_or_404(Location, pk=id_loc)
137 142
138 143 if request.method=='POST':
139 144
140 145 if request.user.is_staff:
141 146 location.delete()
142 147 return redirect('url_locations')
143 148
144 149 messages.error(request, 'Not enough permission to delete this object')
145 150 return redirect(location.get_absolute_url())
146 151
147 152 kwargs = {
148 153 'title': 'Delete',
149 154 'suptitle': 'Location',
150 155 'object': location,
151 156 'previous': location.get_absolute_url(),
152 157 'delete': True
153 158 }
154 159
155 160 return render(request, 'confirm.html', kwargs)
156 161
157 162
158 163 def devices(request):
159 164
160 165 devices = Device.objects.all().order_by('device_type__name')
161 166
162 167 # keys = ['id', 'device_type__name', 'name', 'ip_address']
163 168 keys = ['id', 'name', 'ip_address', 'port_address', 'device_type']
164 169
165 170 kwargs = {}
166 171 kwargs['device_keys'] = keys[1:]
167 172 kwargs['devices'] = devices#.values(*keys)
168 173 kwargs['title'] = 'Device'
169 174 kwargs['suptitle'] = 'List'
170 175 kwargs['button'] = 'New Device'
171 176
172 177 return render(request, 'devices.html', kwargs)
173 178
174 179
175 180 def device(request, id_dev):
176 181
177 182 device = get_object_or_404(Device, pk=id_dev)
178 183
179 184 kwargs = {}
180 185 kwargs['device'] = device
181 186 kwargs['device_keys'] = ['device_type', 'name', 'ip_address', 'port_address', 'description']
182 187
183 188 kwargs['title'] = 'Device'
184 189 kwargs['suptitle'] = 'Details'
185 190
186 191 return render(request, 'device.html', kwargs)
187 192
188 193
189 194 def device_new(request):
190 195
191 196 if request.method == 'GET':
192 197 form = DeviceForm()
193 198
194 199 if request.method == 'POST':
195 200 form = DeviceForm(request.POST)
196 201
197 202 if form.is_valid():
198 203 form.save()
199 204 return redirect('url_devices')
200 205
201 206 kwargs = {}
202 207 kwargs['form'] = form
203 208 kwargs['title'] = 'Device'
204 209 kwargs['suptitle'] = 'New'
205 210 kwargs['button'] = 'Create'
206 211
207 212 return render(request, 'device_edit.html', kwargs)
208 213
209 214
210 215 def device_edit(request, id_dev):
211 216
212 217 device = get_object_or_404(Device, pk=id_dev)
213 218
214 219 if request.method=='GET':
215 220 form = DeviceForm(instance=device)
216 221
217 222 if request.method=='POST':
218 223 form = DeviceForm(request.POST, instance=device)
219 224
220 225 if form.is_valid():
221 226 form.save()
222 227 return redirect(device.get_absolute_url())
223 228
224 229 kwargs = {}
225 230 kwargs['form'] = form
226 231 kwargs['title'] = 'Device'
227 232 kwargs['suptitle'] = 'Edit'
228 233 kwargs['button'] = 'Update'
229 234
230 235 return render(request, 'device_edit.html', kwargs)
231 236
232 237
233 238 def device_delete(request, id_dev):
234 239
235 240 device = get_object_or_404(Device, pk=id_dev)
236 241
237 242 if request.method=='POST':
238 243
239 244 if request.user.is_staff:
240 245 device.delete()
241 246 return redirect('url_devices')
242 247
243 248 messages.error(request, 'Not enough permission to delete this object')
244 249 return redirect(device.get_absolute_url())
245 250
246 251 kwargs = {
247 252 'title': 'Delete',
248 253 'suptitle': 'Device',
249 254 'object': device,
250 255 'previous': device.get_absolute_url(),
251 256 'delete': True
252 257 }
253 258
254 259 return render(request, 'confirm.html', kwargs)
255 260
256 261
257 262 def campaigns(request):
258 263
259 264 campaigns = Campaign.objects.all().order_by('start_date')
260 265
261 266 keys = ['id', 'name', 'start_date', 'end_date']
262 267
263 268 kwargs = {}
264 269 kwargs['campaign_keys'] = keys[1:]
265 270 kwargs['campaigns'] = campaigns#.values(*keys)
266 271 kwargs['title'] = 'Campaign'
267 272 kwargs['suptitle'] = 'List'
268 273 kwargs['button'] = 'New Campaign'
269 274
270 275 return render(request, 'campaigns.html', kwargs)
271 276
272 277
273 278 def campaign(request, id_camp):
274 279
275 280 campaign = get_object_or_404(Campaign, pk=id_camp)
276 281 experiments = Experiment.objects.filter(campaign=campaign)
277 282
278 283 form = CampaignForm(instance=campaign)
279 284
280 285 kwargs = {}
281 286 kwargs['campaign'] = campaign
282 287 kwargs['campaign_keys'] = ['template', 'name', 'start_date', 'end_date', 'tags', 'description']
283 288
284 289 kwargs['experiments'] = experiments
285 290 kwargs['experiment_keys'] = ['name', 'radar', 'start_time', 'end_time']
286 291
287 292 kwargs['title'] = 'Campaign'
288 293 kwargs['suptitle'] = 'Details'
289 294
290 295 kwargs['form'] = form
291 296 kwargs['button'] = 'Add Experiment'
292 297
293 298 return render(request, 'campaign.html', kwargs)
294 299
295 300
296 301 def campaign_new(request):
297 302
298 303 kwargs = {}
299 304
300 305 if request.method == 'GET':
301 306
302 307 if 'template' in request.GET:
303 308 if request.GET['template']=='0':
304 309 form = NewForm(initial={'create_from':2},
305 310 template_choices=Campaign.objects.filter(template=True).values_list('id', 'name'))
306 311 else:
307 312 kwargs['button'] = 'Create'
308 313 kwargs['experiments'] = Configuration.objects.filter(experiment=request.GET['template'])
309 314 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
310 315 camp = Campaign.objects.get(pk=request.GET['template'])
311 316 form = CampaignForm(instance=camp,
312 317 initial={'name':'{} [{:%Y/%m/%d}]'.format(camp.name, datetime.now()),
313 318 'template':False})
314 319 elif 'blank' in request.GET:
315 320 kwargs['button'] = 'Create'
316 321 form = CampaignForm()
317 322 else:
318 323 form = NewForm()
319 324
320 325 if request.method == 'POST':
321 326 kwargs['button'] = 'Create'
322 327 post = request.POST.copy()
323 328 experiments = []
324 329
325 330 for id_exp in post.getlist('experiments'):
326 331 exp = Experiment.objects.get(pk=id_exp)
327 332 new_exp = exp.clone(template=False)
328 333 experiments.append(new_exp)
329 334
330 335 post.setlist('experiments', [])
331 336
332 337 form = CampaignForm(post)
333 338
334 339 if form.is_valid():
335 340 campaign = form.save()
336 341 for exp in experiments:
337 342 campaign.experiments.add(exp)
338 343 campaign.save()
339 344 return redirect('url_campaign', id_camp=campaign.id)
340 345
341 346 kwargs['form'] = form
342 347 kwargs['title'] = 'Campaign'
343 348 kwargs['suptitle'] = 'New'
344 349
345 350 return render(request, 'campaign_edit.html', kwargs)
346 351
347 352
348 353 def campaign_edit(request, id_camp):
349 354
350 355 campaign = get_object_or_404(Campaign, pk=id_camp)
351 356
352 357 if request.method=='GET':
353 358 form = CampaignForm(instance=campaign)
354 359
355 360 if request.method=='POST':
356 361 exps = campaign.experiments.all().values_list('pk', flat=True)
357 362 post = request.POST.copy()
358 363 new_exps = post.getlist('experiments')
359 364 post.setlist('experiments', [])
360 365 form = CampaignForm(post, instance=campaign)
361 366
362 367 if form.is_valid():
363 368 camp = form.save()
364 369 for id_exp in new_exps:
365 370 if int(id_exp) in exps:
366 371 exps.pop(id_exp)
367 372 else:
368 373 exp = Experiment.objects.get(pk=id_exp)
369 374 if exp.template:
370 375 camp.experiments.add(exp.clone(template=False))
371 376 else:
372 377 camp.experiments.add(exp)
373 378
374 379 for id_exp in exps:
375 380 camp.experiments.remove(Experiment.objects.get(pk=id_exp))
376 381
377 382 return redirect('url_campaign', id_camp=id_camp)
378 383
379 384 kwargs = {}
380 385 kwargs['form'] = form
381 386 kwargs['title'] = 'Campaign'
382 387 kwargs['suptitle'] = 'Edit'
383 388 kwargs['button'] = 'Update'
384 389
385 390 return render(request, 'campaign_edit.html', kwargs)
386 391
387 392
388 393 def campaign_delete(request, id_camp):
389 394
390 395 campaign = get_object_or_404(Campaign, pk=id_camp)
391 396
392 397 if request.method=='POST':
393 398 if request.user.is_staff:
394 399
395 400 for exp in campaign.experiments.all():
396 401 for conf in Configuration.objects.filter(experiment=exp):
397 402 conf.delete()
398 403 exp.delete()
399 404 campaign.delete()
400 405
401 406 return redirect('url_campaigns')
402 407
403 408 messages.error(request, 'Not enough permission to delete this object')
404 409 return redirect(campaign.get_absolute_url())
405 410
406 411 kwargs = {
407 412 'title': 'Delete',
408 413 'suptitle': 'Campaign',
409 414 'object': campaign,
410 415 'previous': campaign.get_absolute_url(),
411 416 'delete': True
412 417 }
413 418
414 419 return render(request, 'confirm.html', kwargs)
415 420
416 421 def campaign_export(request, id_camp):
417 422
418 423 campaign = get_object_or_404(Campaign, pk=id_camp)
419 424 content = campaign.parms_to_dict()
420 425 content_type = 'application/json'
421 426 filename = '%s_%s.json' %(campaign.name, campaign.id)
422 427
423 428 response = HttpResponse(content_type=content_type)
424 429 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
425 430 response.write(content)
426 431
427 432 return response
428 433
429 434
430 435 def campaign_import(request, id_camp):
431 436
432 437 campaign = get_object_or_404(Campaign, pk=id_camp)
433 438
434 439 if request.method == 'GET':
435 440 file_form = UploadFileForm()
436 441
437 442 if request.method == 'POST':
438 443 file_form = UploadFileForm(request.POST, request.FILES)
439 444
440 445 if file_form.is_valid():
441 446
442 447 parms = campaign.import_from_file(request.FILES['file'])
443 448
444 449 if parms:
445 450 parms['name'] = parms['campaign']
446 451
447 452 new_camp = campaign.dict_to_parms(parms, CONF_MODELS)
448 453
449 454 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
450 455
451 456 return redirect(new_camp.get_absolute_url_edit())
452 457
453 458 messages.error(request, "Could not import parameters from file")
454 459
455 460 kwargs = {}
456 461 kwargs['title'] = 'Campaign'
457 462 kwargs['form'] = file_form
458 463 kwargs['suptitle'] = 'Importing file'
459 464 kwargs['button'] = 'Import'
460 465
461 466 return render(request, 'campaign_import.html', kwargs)
462 467
463 468
464 469 def experiments(request):
465 470
466 471 experiment_list = Experiment.objects.all()
467 472
468 473 keys = ['id', 'name', 'start_time', 'end_time']
469 474
470 475 kwargs = {}
471 476
472 477 kwargs['experiment_keys'] = keys[1:]
473 478 kwargs['experiments'] = experiment_list
474 479
475 480 kwargs['title'] = 'Experiment'
476 481 kwargs['suptitle'] = 'List'
477 482 kwargs['button'] = 'New Experiment'
478 483
479 484 return render(request, 'experiments.html', kwargs)
480 485
481 486
482 487 def experiment(request, id_exp):
483 488
484 489 experiment = get_object_or_404(Experiment, pk=id_exp)
485 490
486 491 configurations = Configuration.objects.filter(experiment=experiment, type=0)
487 492
488 493 kwargs = {}
489 494
490 495 kwargs['experiment_keys'] = ['template', 'radar', 'name', 'start_time', 'end_time']
491 496 kwargs['experiment'] = experiment
492 497
493 498 kwargs['configuration_keys'] = ['name', 'device__device_type', 'device__ip_address', 'device__port_address']
494 499 kwargs['configurations'] = configurations
495 500
496 501 kwargs['title'] = 'Experiment'
497 502 kwargs['suptitle'] = 'Details'
498 503
499 504 kwargs['button'] = 'Add Configuration'
500 505
501 506 ###### SIDEBAR ######
502 507 kwargs.update(sidebar(experiment=experiment))
503 508
504 509 return render(request, 'experiment.html', kwargs)
505 510
506 511
507 512 def experiment_new(request, id_camp=None):
508 513
509 514 kwargs = {}
510 515
511 516 if request.method == 'GET':
512 517 if 'template' in request.GET:
513 518 if request.GET['template']=='0':
514 519 form = NewForm(initial={'create_from':2},
515 520 template_choices=Experiment.objects.filter(template=True).values_list('id', 'name'))
516 521 else:
517 522 kwargs['button'] = 'Create'
518 523 kwargs['configurations'] = Configuration.objects.filter(experiment=request.GET['template'])
519 524 kwargs['configuration_keys'] = ['name', 'device__name', 'device__ip_address', 'device__port_address']
520 525 exp=Experiment.objects.get(pk=request.GET['template'])
521 526 form = ExperimentForm(instance=exp,
522 527 initial={'name': '{} [{:%Y/%m/%d}]'.format(exp.name, datetime.now()),
523 528 'template': False})
524 529 elif 'blank' in request.GET:
525 530 kwargs['button'] = 'Create'
526 531 form = ExperimentForm()
527 532 else:
528 533 form = NewForm()
529 534
530 535 if request.method == 'POST':
531 536 form = ExperimentForm(request.POST)
532 537 if form.is_valid():
533 538 experiment = form.save()
534 539
535 540 if 'template' in request.GET:
536 541 configurations = Configuration.objects.filter(experiment=request.GET['template'], type=0)
537 542 for conf in configurations:
538 543 conf.clone(experiment=experiment, template=False)
539 544
540 545 return redirect('url_experiment', id_exp=experiment.id)
541 546
542 547 kwargs['form'] = form
543 548 kwargs['title'] = 'Experiment'
544 549 kwargs['suptitle'] = 'New'
545 550
546 551 return render(request, 'experiment_edit.html', kwargs)
547 552
548 553
549 554 def experiment_edit(request, id_exp):
550 555
551 556 experiment = get_object_or_404(Experiment, pk=id_exp)
552 557
553 558 if request.method == 'GET':
554 559 form = ExperimentForm(instance=experiment)
555 560
556 561 if request.method=='POST':
557 562 form = ExperimentForm(request.POST, instance=experiment)
558 563
559 564 if form.is_valid():
560 565 experiment = form.save()
561 566 return redirect('url_experiment', id_exp=experiment.id)
562 567
563 568 kwargs = {}
564 569 kwargs['form'] = form
565 570 kwargs['title'] = 'Experiment'
566 571 kwargs['suptitle'] = 'Edit'
567 572 kwargs['button'] = 'Update'
568 573
569 574 return render(request, 'experiment_edit.html', kwargs)
570 575
571 576
572 577 def experiment_delete(request, id_exp):
573 578
574 579 experiment = get_object_or_404(Experiment, pk=id_exp)
575 580
576 581 if request.method=='POST':
577 582 if request.user.is_staff:
578 583 for conf in Configuration.objects.filter(experiment=experiment):
579 584 conf.delete()
580 585 experiment.delete()
581 586 return redirect('url_experiments')
582 587
583 588 messages.error(request, 'Not enough permission to delete this object')
584 589 return redirect(experiment.get_absolute_url())
585 590
586 591 kwargs = {
587 592 'title': 'Delete',
588 593 'suptitle': 'Experiment',
589 594 'object': experiment,
590 595 'previous': experiment.get_absolute_url(),
591 596 'delete': True
592 597 }
593 598
594 599 return render(request, 'confirm.html', kwargs)
595 600
596 601
597 602 def experiment_export(request, id_exp):
598 603
599 604 experiment = get_object_or_404(Experiment, pk=id_exp)
600 605 content = experiment.parms_to_dict()
601 606 content_type = 'application/json'
602 607 filename = '%s_%s.json' %(experiment.name, experiment.id)
603 608
604 609 response = HttpResponse(content_type=content_type)
605 610 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
606 611 response.write(content)
607 612
608 613 return response
609 614
610 615 def experiment_import(request, id_exp):
611 616
612 617 experiment = get_object_or_404(Experiment, pk=id_exp)
613 618 configurations = Configuration.objects.filter(experiment=experiment)
614 619
615 620 if request.method == 'GET':
616 621 file_form = UploadFileForm()
617 622
618 623 if request.method == 'POST':
619 624 file_form = UploadFileForm(request.POST, request.FILES)
620 625
621 626 if file_form.is_valid():
622 627
623 628 parms = experiment.import_from_file(request.FILES['file'])
624 629
625 630 if parms:
626 631
627 632 new_exp = experiment.dict_to_parms(parms, CONF_MODELS)
628 633
629 634 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
630 635
631 636 return redirect(new_exp.get_absolute_url_edit())
632 637
633 638 messages.error(request, "Could not import parameters from file")
634 639
635 640 kwargs = {}
636 641 kwargs['title'] = 'Experiment'
637 642 kwargs['form'] = file_form
638 643 kwargs['suptitle'] = 'Importing file'
639 644 kwargs['button'] = 'Import'
640 645
641 646 kwargs.update(sidebar(experiment=experiment))
642 647
643 648 return render(request, 'experiment_import.html', kwargs)
644 649
645 650 def experiment_mix(request, id_exp):
646 651
647 652 experiment = get_object_or_404(Experiment, pk=id_exp)
648 653 rc_confs = [conf for conf in RCConfiguration.objects.filter(experiment=id_exp,
649 654 mix=False)]
650 655
651 656 if len(rc_confs)<2:
652 657 messages.warning(request, 'You need at least two RC Configurations to make a mix')
653 658 return redirect(experiment.get_absolute_url())
654 659
655 660 mix_confs = RCConfiguration.objects.filter(experiment=id_exp, mix=True)
656 661
657 662 if mix_confs:
658 663 mix = mix_confs[0]
659 664 else:
660 665 mix = RCConfiguration(experiment=experiment,
661 666 device=rc_confs[0].device,
662 667 ipp=rc_confs[0].ipp,
663 668 clock_in=rc_confs[0].clock_in,
664 669 clock_divider=rc_confs[0].clock_divider,
665 670 mix=True,
666 671 parameters='')
667 672 mix.save()
668 673
669 674 line_type = RCLineType.objects.get(name='mix')
670 675 for i in range(len(rc_confs[0].get_lines())):
671 676 line = RCLine(rc_configuration=mix, line_type=line_type, channel=i)
672 677 line.save()
673 678
674 679 initial = {'name': mix.name,
675 680 'result': parse_mix_result(mix.parameters),
676 681 'delay': 0,
677 682 'mask': [0,1,2,3,4,5,6,7]
678 683 }
679 684
680 685 if request.method=='GET':
681 686 form = RCMixConfigurationForm(confs=rc_confs, initial=initial)
682 687
683 if request.method=='POST':
684
688 if request.method=='POST':
685 689 result = mix.parameters
686 690
687 691 if '{}|'.format(request.POST['experiment']) in result:
688 692 messages.error(request, 'Configuration already added')
689 693 else:
694 if 'operation' in request.POST:
695 operation = MIX_OPERATIONS[request.POST['operation']]
696 else:
697 operation = '---'
698
699 mode = MIX_MODES[request.POST['mode']]
700
690 701 if result:
691 result = '{}-{}|{}|{}|{}'.format(mix.parameters,
692 request.POST['experiment'],
693 MIX_MODES[request.POST['operation']],
694 float(request.POST['delay']),
695 parse_mask(request.POST.getlist('mask'))
696 )
702 result = '{}-{}|{}|{}|{}|{}'.format(mix.parameters,
703 request.POST['experiment'],
704 mode,
705 operation,
706 float(request.POST['delay']),
707 parse_mask(request.POST.getlist('mask'))
708 )
697 709 else:
698 result = '{}|{}|{}|{}'.format(request.POST['experiment'],
699 MIX_MODES[request.POST['operation']],
700 float(request.POST['delay']),
701 parse_mask(request.POST.getlist('mask'))
702 )
710 result = '{}|{}|{}|{}|{}'.format(request.POST['experiment'],
711 mode,
712 operation,
713 float(request.POST['delay']),
714 parse_mask(request.POST.getlist('mask'))
715 )
703 716
704 717 mix.parameters = result
705 718 mix.name = request.POST['name']
706 719 mix.save()
707 720 mix.update_pulses()
708
709
721
710 722 initial['result'] = parse_mix_result(result)
711 723 initial['name'] = mix.name
712 724
713 725 form = RCMixConfigurationForm(initial=initial, confs=rc_confs)
714 726
715 727
716 728 kwargs = {
717 729 'title': 'Experiment',
718 730 'suptitle': 'Mix Configurations',
719 731 'form' : form,
720 732 'extra_button': 'Delete',
721 733 'button': 'Add',
722 734 'cancel': 'Back',
723 735 'previous': experiment.get_absolute_url(),
724 736 'id_exp':id_exp,
725 737
726 738 }
727 739
728 740 return render(request, 'experiment_mix.html', kwargs)
729 741
730 742
731 743 def experiment_mix_delete(request, id_exp):
732 744
733 745 conf = RCConfiguration.objects.get(experiment=id_exp, mix=True)
734 746 values = conf.parameters.split('-')
735 747 conf.parameters = '-'.join(values[:-1])
736 748 conf.save()
737 749
738 750 return redirect('url_mix_experiment', id_exp=id_exp)
739 751
740 752
741 753 def parse_mix_result(s):
742 754
743 755 values = s.split('-')
744 html = ''
756 html = 'EXP MOD OPE DELAY MASK\r\n'
745 757
758 if not values or values[0] in ('', ' '):
759 return mark_safe(html)
746 760
747 761 for i, value in enumerate(values):
748 762 if not value:
749 763 continue
750 pk, mode, delay, mask = value.split('|')
764 pk, mode, operation, delay, mask = value.split('|')
751 765 conf = RCConfiguration.objects.get(pk=pk)
752 766 if i==0:
753 html += '{:20.18}{:4}{:9}km{:>6}\r\n'.format(
754 conf.name[:18],
767 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
768 conf.name,
769 mode,
755 770 '---',
756 771 delay,
757 772 mask)
758 773 else:
759 html += '{:20.18}{:4}{:9}km{:>6}\r\n'.format(
760 conf.name[:18],
774 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
775 conf.name,
761 776 mode,
777 operation,
762 778 delay,
763 779 mask)
764 780
765 781 return mark_safe(html)
766 782
767 783 def parse_mask(l):
768 784
769 785 values = []
770 786
771 787 for x in range(8):
772 788 if '{}'.format(x) in l:
773 789 values.append(1)
774 790 else:
775 791 values.append(0)
776 792
777 793 values.reverse()
778 794
779 795 return int(''.join([str(x) for x in values]), 2)
780 796
781 797
782 798 def dev_confs(request):
783 799
784 800 configurations = Configuration.objects.all().order_by('type', 'device__device_type', 'experiment')
785 801
786 802 kwargs = {}
787 803
788 804 kwargs['configuration_keys'] = ['device', 'name', 'experiment', 'type', 'programmed_date']
789 805 kwargs['configurations'] = configurations
790 806
791 807 kwargs['title'] = 'Configuration'
792 808 kwargs['suptitle'] = 'List'
793 809
794 810 return render(request, 'dev_confs.html', kwargs)
795 811
796 812
797 813 def dev_conf(request, id_conf):
798 814
799 815 conf = get_object_or_404(Configuration, pk=id_conf)
800 816
801 817 return redirect(conf.get_absolute_url())
802 818
803 819
804 820 def dev_conf_new(request, id_exp=0, id_dev=0):
805 821
806 822 initial = {}
807 823 kwargs = {}
808 824
809 825 if id_exp<>0:
810 826 initial['experiment'] = id_exp
811 827
812 828 if id_dev<>0:
813 829 initial['device'] = id_dev
814 830
815 831 if request.method == 'GET':
816 832
817 833 if id_dev:
818 834 kwargs['button'] = 'Create'
819 835 device = Device.objects.get(pk=id_dev)
820 836 DevConfForm = CONF_FORMS[device.device_type.name]
821 837 initial['name'] = request.GET['name']
822 838 form = DevConfForm(initial=initial)
823 839 else:
824 840 if 'template' in request.GET:
825 841 if request.GET['template']=='0':
826 842 form = NewForm(initial={'create_from':2},
827 843 template_choices=Configuration.objects.filter(template=True).values_list('id', 'name'))
828 844 else:
829 845 kwargs['button'] = 'Create'
830 846 conf = Configuration.objects.get(pk=request.GET['template'])
831 847 DevConfForm = CONF_FORMS[conf.device.device_type.name]
832 848 form = DevConfForm(instance=conf,
833 849 initial={'name': '{} [{:%Y/%m/%d}]'.format(conf.name, datetime.now()),
834 850 'template': False})
835 851 elif 'blank' in request.GET:
836 852 kwargs['button'] = 'Create'
837 853 form = ConfigurationForm(initial=initial)
838 854 else:
839 855 form = NewForm()
840 856
841 857 if request.method == 'POST':
842 858
843 859 device = Device.objects.get(pk=request.POST['device'])
844 860 DevConfForm = CONF_FORMS[device.device_type.name]
845 861
846 862 form = DevConfForm(request.POST)
847 863
848 864 if form.is_valid():
849 865 conf = form.save()
850 866
851 867 if 'template' in request.GET and conf.device.device_type.name=='rc':
852 868 lines = RCLine.objects.filter(rc_configuration=request.GET['template'])
853 869 for line in lines:
854 870 line.clone(rc_configuration=conf)
855 871
856 872 return redirect('url_dev_conf', id_conf=conf.pk)
857 873
858 874
859 875 kwargs['id_exp'] = id_exp
860 876 kwargs['form'] = form
861 877 kwargs['title'] = 'Configuration'
862 878 kwargs['suptitle'] = 'New'
863 879
864 880
865 881 if id_dev != 0:
866 882 device = Device.objects.get(pk=id_dev)
867 883 if 'dds' in device.device_type.name:
868 884 kwargs['dds_device'] = True
869 885
870 886 return render(request, 'dev_conf_edit.html', kwargs)
871 887
872 888
873 889 def dev_conf_edit(request, id_conf):
874 890
875 891 conf = get_object_or_404(Configuration, pk=id_conf)
876 892
877 893 DevConfModel = CONF_MODELS[conf.device.device_type.name]
878 894 DevConfForm = CONF_FORMS[conf.device.device_type.name]
879 895
880 896 dev_conf = DevConfModel.objects.get(pk=id_conf)
881 897
882 898 if request.method=='GET':
883 899 form = DevConfForm(instance=dev_conf)
884 900
885 901 if request.method=='POST':
886 902 form = DevConfForm(request.POST, instance=dev_conf)
887 903
888 904 if form.is_valid():
889 905 form.save()
890 906 return redirect('url_dev_conf', id_conf=id_conf)
891 907
892 908 kwargs = {}
893 909 kwargs['form'] = form
894 910 kwargs['title'] = 'Device Configuration'
895 911 kwargs['suptitle'] = 'Edit'
896 912 kwargs['button'] = 'Update'
897 913
898 914 ###### SIDEBAR ######
899 915 kwargs.update(sidebar(conf=conf))
900 916
901 917 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
902 918
903 919
904 920 def dev_conf_start(request, id_conf):
905 921
906 922 conf = get_object_or_404(Configuration, pk=id_conf)
907 923
908 924 DevConfModel = CONF_MODELS[conf.device.device_type.name]
909 925
910 926 conf = DevConfModel.objects.get(pk=id_conf)
911 927
912 928 if conf.start_device():
913 929 messages.success(request, conf.message)
914 930 else:
915 931 messages.error(request, conf.message)
916 932
917 933 conf.status_device()
918 934
919 935 return redirect(conf.get_absolute_url())
920 936
921 937
922 938 def dev_conf_stop(request, id_conf):
923 939
924 940 conf = get_object_or_404(Configuration, pk=id_conf)
925 941
926 942 DevConfModel = CONF_MODELS[conf.device.device_type.name]
927 943
928 944 conf = DevConfModel.objects.get(pk=id_conf)
929 945
930 946 if conf.stop_device():
931 947 messages.success(request, conf.message)
932 948 else:
933 949 messages.error(request, conf.message)
934 950
935 951 conf.status_device()
936 952
937 953 return redirect(conf.get_absolute_url())
938 954
939 955
940 956 def dev_conf_status(request, id_conf):
941 957
942 958 conf = get_object_or_404(Configuration, pk=id_conf)
943 959
944 960 DevConfModel = CONF_MODELS[conf.device.device_type.name]
945 961
946 962 conf = DevConfModel.objects.get(pk=id_conf)
947 963
948 964 if conf.status_device():
949 965 messages.success(request, conf.message)
950 966 else:
951 967 messages.error(request, conf.message)
952 968
953 969 return redirect(conf.get_absolute_url())
954 970
955 971
956 972 def dev_conf_write(request, id_conf):
957 973
958 974 conf = get_object_or_404(Configuration, pk=id_conf)
959 975
960 976 DevConfModel = CONF_MODELS[conf.device.device_type.name]
961 977
962 978 conf = DevConfModel.objects.get(pk=id_conf)
963 979
964 980 answer = conf.write_device()
965 981 conf.status_device()
966 982
967 983 if answer:
968 984 messages.success(request, conf.message)
969 985
970 986 #Creating a historical configuration
971 987 conf.clone(type=0, template=False)
972 988
973 989 #Original configuration
974 990 conf = DevConfModel.objects.get(pk=id_conf)
975 991 else:
976 992 messages.error(request, conf.message)
977 993
978 994 return redirect(conf.get_absolute_url())
979 995
980 996
981 997 def dev_conf_read(request, id_conf):
982 998
983 999 conf = get_object_or_404(Configuration, pk=id_conf)
984 1000
985 1001 DevConfModel = CONF_MODELS[conf.device.device_type.name]
986 1002 DevConfForm = CONF_FORMS[conf.device.device_type.name]
987 1003
988 1004 conf = DevConfModel.objects.get(pk=id_conf)
989 1005
990 1006 if request.method=='GET':
991 1007
992 1008 parms = conf.read_device()
993 1009 conf.status_device()
994 1010
995 1011 if not parms:
996 1012 messages.error(request, conf.message)
997 1013 return redirect(conf.get_absolute_url())
998 1014
999 1015 form = DevConfForm(initial=parms, instance=conf)
1000 1016
1001 1017 if request.method=='POST':
1002 1018 form = DevConfForm(request.POST, instance=conf)
1003 1019
1004 1020 if form.is_valid():
1005 1021 form.save()
1006 1022 return redirect(conf.get_absolute_url())
1007 1023
1008 1024 messages.error(request, "Parameters could not be saved")
1009 1025
1010 1026 kwargs = {}
1011 1027 kwargs['id_dev'] = conf.id
1012 1028 kwargs['form'] = form
1013 1029 kwargs['title'] = 'Device Configuration'
1014 1030 kwargs['suptitle'] = 'Parameters read from device'
1015 1031 kwargs['button'] = 'Save'
1016 1032
1017 1033 ###### SIDEBAR ######
1018 1034 kwargs.update(sidebar(conf=conf))
1019 1035
1020 1036 return render(request, '%s_conf_edit.html' %conf.device.device_type.name, kwargs)
1021 1037
1022 1038
1023 1039 def dev_conf_import(request, id_conf):
1024 1040
1025 1041 conf = get_object_or_404(Configuration, pk=id_conf)
1026 1042
1027 1043 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1028 1044 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1029 1045 conf = DevConfModel.objects.get(pk=id_conf)
1030 1046
1031 1047 if request.method == 'GET':
1032 1048 file_form = UploadFileForm()
1033 1049
1034 1050 if request.method == 'POST':
1035 1051 file_form = UploadFileForm(request.POST, request.FILES)
1036 1052
1037 1053 if file_form.is_valid():
1038 1054
1039 1055 parms = conf.import_from_file(request.FILES['file'])
1040 1056
1041 1057 if parms:
1042 1058 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
1043 1059 form = DevConfForm(initial=parms, instance=conf)
1044 1060
1045 1061 kwargs = {}
1046 1062 kwargs['id_dev'] = conf.id
1047 1063 kwargs['form'] = form
1048 1064 kwargs['title'] = 'Device Configuration'
1049 1065 kwargs['suptitle'] = 'Parameters imported'
1050 1066 kwargs['button'] = 'Save'
1051 1067 kwargs['action'] = conf.get_absolute_url_edit()
1052 1068 kwargs['previous'] = conf.get_absolute_url()
1053 1069
1054 1070 ###### SIDEBAR ######
1055 1071 kwargs.update(sidebar(conf=conf))
1056 1072
1057 1073 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1058 1074
1059 1075 messages.error(request, "Could not import parameters from file")
1060 1076
1061 1077 kwargs = {}
1062 1078 kwargs['id_dev'] = conf.id
1063 1079 kwargs['title'] = 'Device Configuration'
1064 1080 kwargs['form'] = file_form
1065 1081 kwargs['suptitle'] = 'Importing file'
1066 1082 kwargs['button'] = 'Import'
1067 1083
1068 1084 kwargs.update(sidebar(conf=conf))
1069 1085
1070 1086 return render(request, 'dev_conf_import.html', kwargs)
1071 1087
1072 1088
1073 1089 def dev_conf_export(request, id_conf):
1074 1090
1075 1091 conf = get_object_or_404(Configuration, pk=id_conf)
1076 1092
1077 1093 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1078 1094
1079 1095 conf = DevConfModel.objects.get(pk=id_conf)
1080 1096
1081 1097 if request.method == 'GET':
1082 1098 file_form = DownloadFileForm(conf.device.device_type.name)
1083 1099
1084 1100 if request.method == 'POST':
1085 1101 file_form = DownloadFileForm(conf.device.device_type.name, request.POST)
1086 1102
1087 1103 if file_form.is_valid():
1088 1104 fields = conf.export_to_file(format = file_form.cleaned_data['format'])
1089 1105
1090 1106 response = HttpResponse(content_type=fields['content_type'])
1091 1107 response['Content-Disposition'] = 'attachment; filename="%s"' %fields['filename']
1092 1108 response.write(fields['content'])
1093 1109
1094 1110 return response
1095 1111
1096 1112 messages.error(request, "Could not export parameters")
1097 1113
1098 1114 kwargs = {}
1099 1115 kwargs['id_dev'] = conf.id
1100 1116 kwargs['title'] = 'Device Configuration'
1101 1117 kwargs['form'] = file_form
1102 1118 kwargs['suptitle'] = 'Exporting file'
1103 1119 kwargs['button'] = 'Export'
1104 1120
1105 1121 return render(request, 'dev_conf_export.html', kwargs)
1106 1122
1107 1123
1108 1124 def dev_conf_delete(request, id_conf):
1109 1125
1110 1126 conf = get_object_or_404(Configuration, pk=id_conf)
1111 1127
1112 1128 if request.method=='POST':
1113 1129 if request.user.is_staff:
1114 1130 conf.delete()
1115 1131 return redirect('url_dev_confs')
1116 1132
1117 1133 messages.error(request, 'Not enough permission to delete this object')
1118 1134 return redirect(conf.get_absolute_url())
1119 1135
1120 1136 kwargs = {
1121 1137 'title': 'Delete',
1122 1138 'suptitle': 'Experiment',
1123 1139 'object': conf,
1124 1140 'previous': conf.get_absolute_url(),
1125 1141 'delete': True
1126 1142 }
1127 1143
1128 1144 return render(request, 'confirm.html', kwargs)
1129 1145
1130 1146
1131 1147 def sidebar(**kwargs):
1132 1148
1133 1149 side_data = {}
1134 1150
1135 1151 conf = kwargs.get('conf', None)
1136 1152 experiment = kwargs.get('experiment', None)
1137 1153
1138 1154 if not experiment:
1139 1155 experiment = conf.experiment
1140 1156
1141 1157 if experiment:
1142 1158 side_data['experiment'] = experiment
1143 1159 campaign = experiment.campaign_set.all()
1144 1160 if campaign:
1145 1161 side_data['campaign'] = campaign[0]
1146 1162 experiments = campaign[0].experiments.all()
1147 1163 else:
1148 1164 experiments = [experiment]
1149 1165 configurations = experiment.configuration_set.filter(type=0)
1150 1166 side_data['side_experiments'] = experiments
1151 1167 side_data['side_configurations'] = configurations
1152 1168
1153 1169 return side_data
1154 1170
1155 1171
1156 1172 def operation(request, id_camp=None):
1157 1173
1158 1174 if not id_camp:
1159 1175 campaigns = Campaign.objects.all().order_by('-start_date')
1160 1176
1161 1177 if not campaigns:
1162 1178 kwargs = {}
1163 1179 kwargs['title'] = 'No Campaigns'
1164 1180 kwargs['suptitle'] = 'Empty'
1165 1181 return render(request, 'operation.html', kwargs)
1166 1182
1167 1183 id_camp = campaigns[0].id
1168 1184
1169 1185 campaign = get_object_or_404(Campaign, pk = id_camp)
1170 1186
1171 1187 if request.method=='GET':
1172 1188 form = OperationForm(initial={'campaign': campaign.id}, length = 5)
1173 1189
1174 1190 if request.method=='POST':
1175 1191 form = OperationForm(request.POST, initial={'campaign':campaign.id}, length = 5)
1176 1192
1177 1193 if form.is_valid():
1178 1194 return redirect('url_operation', id_camp=campaign.id)
1179 1195 #locations = Location.objects.filter(experiment__campaign__pk = campaign.id).distinct()
1180 1196 experiments = Experiment.objects.filter(campaign__pk=campaign.id)
1181 1197 #for exs in experiments:
1182 1198 # exs.get_status()
1183 1199 locations= Location.objects.filter(experiment=experiments).distinct()
1184 1200 #experiments = [Experiment.objects.filter(location__pk=location.id).filter(campaign__pk=campaign.id) for location in locations]
1185 1201 kwargs = {}
1186 1202 #---Campaign
1187 1203 kwargs['campaign'] = campaign
1188 1204 kwargs['campaign_keys'] = ['name', 'start_date', 'end_date', 'tags', 'description']
1189 1205 #---Experiment
1190 1206 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1191 1207 kwargs['experiment_keys'] = keys[1:]
1192 1208 kwargs['experiments'] = experiments
1193 1209 #---Radar
1194 1210 kwargs['locations'] = locations
1195 1211 #---Else
1196 1212 kwargs['title'] = 'Campaign'
1197 1213 kwargs['suptitle'] = campaign.name
1198 1214 kwargs['form'] = form
1199 1215 kwargs['button'] = 'Search'
1200 1216 kwargs['details'] = True
1201 1217 kwargs['search_button'] = True
1202 1218
1203 1219 return render(request, 'operation.html', kwargs)
1204 1220
1205 1221
1206 1222 def operation_search(request, id_camp=None):
1207 1223
1208 1224
1209 1225 if not id_camp:
1210 1226 campaigns = Campaign.objects.all().order_by('-start_date')
1211 1227
1212 1228 if not campaigns:
1213 1229 return render(request, 'operation.html', {})
1214 1230
1215 1231 id_camp = campaigns[0].id
1216 1232 campaign = get_object_or_404(Campaign, pk = id_camp)
1217 1233
1218 1234 if request.method=='GET':
1219 1235 form = OperationSearchForm(initial={'campaign': campaign.id})
1220 1236
1221 1237 if request.method=='POST':
1222 1238 form = OperationSearchForm(request.POST, initial={'campaign':campaign.id})
1223 1239
1224 1240 if form.is_valid():
1225 1241 return redirect('url_operation', id_camp=campaign.id)
1226 1242
1227 1243 #locations = Location.objects.filter(experiment__campaign__pk = campaign.id).distinct()
1228 1244 experiments = Experiment.objects.filter(campaign__pk=campaign.id)
1229 1245 #for exs in experiments:
1230 1246 # exs.get_status()
1231 1247 locations= Location.objects.filter(experiment=experiments).distinct()
1232 1248 form = OperationSearchForm(initial={'campaign': campaign.id})
1233 1249
1234 1250 kwargs = {}
1235 1251 #---Campaign
1236 1252 kwargs['campaign'] = campaign
1237 1253 kwargs['campaign_keys'] = ['name', 'start_date', 'end_date', 'tags', 'description']
1238 1254 #---Experiment
1239 1255 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1240 1256 kwargs['experiment_keys'] = keys[1:]
1241 1257 kwargs['experiments'] = experiments
1242 1258 #---Radar
1243 1259 kwargs['locations'] = locations
1244 1260 #---Else
1245 1261 kwargs['title'] = 'Campaign'
1246 1262 kwargs['suptitle'] = campaign.name
1247 1263 kwargs['form'] = form
1248 1264 kwargs['button'] = 'Select'
1249 1265 kwargs['details'] = True
1250 1266 kwargs['search_button'] = False
1251 1267
1252 1268 return render(request, 'operation.html', kwargs)
1253 1269
1254 1270
1255 1271 def radar_play(request, id_camp, id_radar):
1256 1272 campaign = get_object_or_404(Campaign, pk = id_camp)
1257 1273 radar = get_object_or_404(Location, pk = id_radar)
1258 1274 today = datetime.today()
1259 1275 now = today.time()
1260 1276
1261 1277 #--Clear Old Experiments From RunningExperiment Object
1262 1278 running_experiment = RunningExperiment.objects.filter(radar=radar)
1263 1279 if running_experiment:
1264 1280 running_experiment = running_experiment[0]
1265 1281 running_experiment.running_experiment.clear()
1266 1282 running_experiment.save()
1267 1283
1268 1284 #--If campaign datetime is ok:
1269 1285 if today >= campaign.start_date and today <= campaign.end_date:
1270 1286 experiments = Experiment.objects.filter(campaign=campaign).filter(location=radar)
1271 1287 for exp in experiments:
1272 1288 #--If experiment time is ok:
1273 1289 if now >= exp.start_time and now <= exp.end_time:
1274 1290 configurations = Configuration.objects.filter(experiment = exp)
1275 1291 for conf in configurations:
1276 1292 if 'cgs' in conf.device.device_type.name:
1277 1293 conf.status_device()
1278 1294 else:
1279 1295 answer = conf.start_device()
1280 1296 conf.status_device()
1281 1297 #--Running Experiment
1282 1298 old_running_experiment = RunningExperiment.objects.filter(radar=radar)
1283 1299 #--If RunningExperiment element exists
1284 1300 if old_running_experiment:
1285 1301 old_running_experiment = old_running_experiment[0]
1286 1302 old_running_experiment.running_experiment.add(exp)
1287 1303 old_running_experiment.status = 3
1288 1304 old_running_experiment.save()
1289 1305 #--Create a new Running_Experiment Object
1290 1306 else:
1291 1307 new_running_experiment = RunningExperiment(
1292 1308 radar = radar,
1293 1309 status = 3,
1294 1310 )
1295 1311 new_running_experiment.save()
1296 1312 new_running_experiment.running_experiment.add(exp)
1297 1313 new_running_experiment.save()
1298 1314
1299 1315 if answer:
1300 1316 messages.success(request, conf.message)
1301 1317 exp.status=2
1302 1318 exp.save()
1303 1319 else:
1304 1320 messages.error(request, conf.message)
1305 1321 else:
1306 1322 if exp.status == 1 or exp.status == 3:
1307 1323 exp.status=3
1308 1324 exp.save()
1309 1325
1310 1326
1311 1327 route = request.META['HTTP_REFERER']
1312 1328 route = str(route)
1313 1329 if 'search' in route:
1314 1330 return HttpResponseRedirect(reverse('url_operation_search', args=[id_camp]))
1315 1331 else:
1316 1332 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1317 1333
1318 1334
1319 1335 def radar_stop(request, id_camp, id_radar):
1320 1336 campaign = get_object_or_404(Campaign, pk = id_camp)
1321 1337 radar = get_object_or_404(Location, pk = id_radar)
1322 1338 experiments = Experiment.objects.filter(campaign=campaign).filter(location=radar)
1323 1339
1324 1340 for exp in experiments:
1325 1341 configurations = Configuration.objects.filter(experiment = exp)
1326 1342 for conf in configurations:
1327 1343 if 'cgs' in conf.device.device_type.name:
1328 1344 conf.status_device()
1329 1345 else:
1330 1346 answer = conf.stop_device()
1331 1347 conf.status_device()
1332 1348
1333 1349 if answer:
1334 1350 messages.success(request, conf.message)
1335 1351 exp.status=1
1336 1352 exp.save()
1337 1353 else:
1338 1354 messages.error(request, conf.message)
1339 1355
1340 1356
1341 1357 route = request.META['HTTP_REFERER']
1342 1358 route = str(route)
1343 1359 if 'search' in route:
1344 1360 return HttpResponseRedirect(reverse('url_operation_search', args=[id_camp]))
1345 1361 else:
1346 1362 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1347 1363
1348 1364
1349 1365 def radar_refresh(request, id_camp, id_radar):
1350 1366
1351 1367 campaign = get_object_or_404(Campaign, pk = id_camp)
1352 1368 radar = get_object_or_404(Location, pk = id_radar)
1353 1369 experiments = Experiment.objects.filter(campaign=campaign).filter(location=radar)
1354 1370 for exs in experiments:
1355 1371 exs.get_status()
1356 1372
1357 1373 route = request.META['HTTP_REFERER']
1358 1374 route = str(route)
1359 1375 if 'search' in route:
1360 1376 return HttpResponseRedirect(reverse('url_operation_search', args=[id_camp]))
1361 1377 else:
1362 1378 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1363 1379
@@ -1,370 +1,372
1 1 import os
2 2 import ast
3 3 import json
4 4
5 5 from django import forms
6 6 from django.utils.safestring import mark_safe
7 7 from apps.main.models import Device
8 8 from apps.main.forms import add_empty_choice
9 9 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode
10 10 from .widgets import KmUnitWidget, KmUnitHzWidget, KmUnitDcWidget, UnitKmWidget, DefaultWidget, CodesWidget, HiddenWidget, HCheckboxSelectMultiple
11 11
12 12 def create_choices_from_model(model, conf_id, all=False):
13 13
14 14 if model=='RCLine':
15 15 instance = RCConfiguration.objects.get(pk=conf_id)
16 16 choices = [(line.pk, line.get_name()) for line in instance.get_lines(line_type__name='tx')]
17 17 choices = add_empty_choice(choices, label='All')
18 18 else:
19 19 instance = globals()[model]
20 20 choices = instance.objects.all().values_list('pk', 'name')
21 21
22 22 return choices
23 23
24 24
25 25 class ExtFileField(forms.FileField):
26 26 """
27 27 Same as forms.FileField, but you can specify a file extension whitelist.
28 28
29 29 >>> from django.core.files.uploadedfile import SimpleUploadedFile
30 30 >>>
31 31 >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
32 32 >>>
33 33 >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
34 34 >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
35 35 >>>
36 36 >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
37 37 Traceback (most recent call last):
38 38 ...
39 39 ValidationError: [u'Not allowed filetype!']
40 40 """
41 41 def __init__(self, *args, **kwargs):
42 42 extensions = kwargs.pop("extensions")
43 43 self.extensions = [i.lower() for i in extensions]
44 44
45 45 super(ExtFileField, self).__init__(*args, **kwargs)
46 46
47 47 def clean(self, *args, **kwargs):
48 48 data = super(ExtFileField, self).clean(*args, **kwargs)
49 49 filename = data.name
50 50 ext = os.path.splitext(filename)[1]
51 51 ext = ext.lower()
52 52 if ext not in self.extensions:
53 53 raise forms.ValidationError('Not allowed file type: %s' % ext)
54 54
55 55
56 56 class RCConfigurationForm(forms.ModelForm):
57 57
58 58 def __init__(self, *args, **kwargs):
59 59 super(RCConfigurationForm, self).__init__(*args, **kwargs)
60 60
61 61 instance = getattr(self, 'instance', None)
62 62
63 63 if instance and instance.pk:
64 64
65 65 devices = Device.objects.filter(device_type__name='rc')
66 66 if instance.experiment:
67 67 self.fields['experiment'].widget.attrs['read_only'] = True
68 68 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
69 69 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
70 70 self.fields['ipp'].widget = KmUnitHzWidget(attrs={'km2unit':instance.km2unit})
71 71 self.fields['clock'].widget.attrs['readonly'] = True
72 72
73 73 self.fields['time_before'].label = mark_safe(self.fields['time_before'].label)
74 74 self.fields['time_after'].label = mark_safe(self.fields['time_after'].label)
75 75
76 76 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
77 77 self.fields['experiment'].widget.attrs['disabled'] = 'disabled'
78 78
79 79 class Meta:
80 80 model = RCConfiguration
81 exclude = ('type', 'parameters', 'status', 'mix')
81 exclude = ('type', 'parameters', 'status', 'total_units', 'mix')
82 82
83 83 def clean(self):
84 84 form_data = super(RCConfigurationForm, self).clean()
85 85
86 86 if 'clock_divider' in form_data:
87 87 if form_data['clock_divider']<1:
88 88 self.add_error('clock_divider', 'Invalid Value')
89 89 else:
90 90 if form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))%10<>0:
91 91 self.add_error('ipp', 'Invalid IPP units={}'.format(form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))))
92 92
93 93 return form_data
94 94
95 95
96 96 class RCMixConfigurationForm(forms.Form):
97 97
98 98 clock_in = forms.CharField(widget=forms.HiddenInput())
99 99 clock_divider = forms.CharField(widget=forms.HiddenInput())
100 100 name = forms.CharField()
101 101 experiment = forms.ChoiceField()
102 mode = forms.ChoiceField(widget=forms.RadioSelect(),
103 choices=[(0, 'Parallel'), (1, 'Sequence')],
104 initial=0)
102 105 operation = forms.ChoiceField(widget=forms.RadioSelect(),
103 106 choices=[(0, 'OR'), (1, 'XOR'), (2, 'AND'), (3, 'NAND')],
104 107 initial=1)
105 108 delay = forms.CharField()
106 109 mask = forms.MultipleChoiceField(choices=[(0, 'L1'),(1, 'L2'),(2, 'L3'),(3, 'L4'),(4, 'L5'),(5, 'L6'),(6, 'L7'),(7, 'L8')],
107 110 widget=HCheckboxSelectMultiple())
108 111 result = forms.CharField(required=False,
109 112 widget=forms.Textarea(attrs={'readonly':True, 'rows':5, 'class':'tabuled'}))
110 113
111 114 def __init__(self, *args, **kwargs):
112 115 confs = kwargs.pop('confs', [])
113 116 if confs:
114 117 km2unit = confs[0].km2unit
115 118 clock_in = confs[0].clock_in
116 119 clock_divider = confs[0].clock_divider
117 120 else:
118 121 km2unit = clock_in = clock_divider = 0
119 122 super(RCMixConfigurationForm, self).__init__(*args, **kwargs)
120 123 self.fields['experiment'].choices = [(conf.pk, '{} | {}'.format(conf.pk, conf.name)) for conf in confs]
121 124 self.fields['delay'].widget = KmUnitWidget(attrs = {'km2unit':km2unit})
122 125 self.fields['clock_in'].initial = clock_in
123 126 self.fields['clock_divider'].initial = clock_divider
124
125
127
126 128
127 129 class RCLineForm(forms.ModelForm):
128 130
129 131 def __init__(self, *args, **kwargs):
130 132 self.extra_fields = kwargs.pop('extra_fields', [])
131 133 super(RCLineForm, self).__init__(*args, **kwargs)
132 134
133 135 if 'initial' in kwargs and 'line_type' in kwargs['initial']:
134 136 line_type = RCLineType.objects.get(pk=kwargs['initial']['line_type'])
135 137
136 138 if 'code_id' in kwargs['initial']:
137 139 model_initial = kwargs['initial']['code_id']
138 140 else:
139 141 model_initial = 0
140 142
141 143 params = json.loads(line_type.params)
142 144
143 145 for label, value in self.extra_fields.items():
144 146 if label=='params':
145 147 continue
146 148
147 149 if 'model' in params[label]:
148 150 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
149 151 kwargs['initial']['rc_configuration']),
150 152 initial=model_initial)
151 153
152 154
153 155 else:
154 156 if label=='codes' and 'code_id' in kwargs['initial']:
155 157 self.fields[label] = forms.CharField(initial=RCLineCode.objects.get(pk=kwargs['initial']['code_id']).codes)
156 158 else:
157 159 self.fields[label] = forms.CharField(initial=value['value'])
158 160
159 161 if label=='codes':
160 162 self.fields[label].widget = CodesWidget()
161 163
162 164 if self.data:
163 165 line_type = RCLineType.objects.get(pk=self.data['line_type'])
164 166
165 167 if 'code_id' in self.data:
166 168 model_initial = self.data['code_id']
167 169 else:
168 170 model_initial = 0
169 171
170 172 params = json.loads(line_type.params)
171 173
172 174 for label, value in self.extra_fields.items():
173 175 if label=='params':
174 176 continue
175 177
176 178 if 'model' in params[label]:
177 179 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
178 180 self.data['rc_configuration']),
179 181 initial=model_initial)
180 182
181 183
182 184 else:
183 185 if label=='codes' and 'code' in self.data:
184 186 self.fields[label] = forms.CharField(initial=self.data['codes'])
185 187 else:
186 188 self.fields[label] = forms.CharField(initial=self.data[label])
187 189
188 190 if label=='codes':
189 191 self.fields[label].widget = CodesWidget()
190 192
191 193
192 194 class Meta:
193 195 model = RCLine
194 196 fields = ('rc_configuration', 'line_type', 'channel')
195 197 widgets = {
196 198 'channel': forms.HiddenInput(),
197 199 }
198 200
199 201
200 202 def clean(self):
201 203
202 204 form_data = self.cleaned_data
203 205 if 'code' in self.data and self.data['TX_ref']=="0":
204 206 self.add_error('TX_ref', 'Choose a valid TX reference')
205 207
206 208 return form_data
207 209
208 210
209 211 def save(self):
210 212 line = super(RCLineForm, self).save()
211 213
212 214 #auto add channel
213 215 line.channel = RCLine.objects.filter(rc_configuration=line.rc_configuration).count()-1
214 216
215 217 #auto add position for TX, TR & CODE
216 218 if line.line_type.name in ('tx', ):
217 219 line.position = RCLine.objects.filter(rc_configuration=line.rc_configuration, line_type=line.line_type).count()-1
218 220
219 221 #save extra fields in params
220 222 params = {}
221 223 for label, value in self.extra_fields.items():
222 224 if label=='params':
223 225 params['params'] = []
224 226 elif label=='codes':
225 227 params[label] = [s for s in self.data[label].split('\r\n') if s]
226 228 else:
227 229 params[label] = self.data[label]
228 230 line.params = json.dumps(params)
229 231 line.save()
230 232 return
231 233
232 234
233 235 class RCLineViewForm(forms.Form):
234 236
235 237 def __init__(self, *args, **kwargs):
236 238
237 239 extra_fields = kwargs.pop('extra_fields')
238 240 line = kwargs.pop('line')
239 241 subform = kwargs.pop('subform', False)
240 242 super(RCLineViewForm, self).__init__(*args, **kwargs)
241 243
242 244 if subform:
243 245 params = json.loads(line.line_type.params)['params']
244 246 else:
245 247 params = json.loads(line.line_type.params)
246 248
247 249 for label, value in extra_fields.items():
248 250
249 251 if label=='params':
250 252 continue
251 253 if 'ref' in label:
252 254 if value in (0, '0'):
253 255 value = 'All'
254 256 else:
255 257 value = RCLine.objects.get(pk=value).get_name()
256 258 elif label=='code':
257 259 value = RCLineCode.objects.get(pk=value).name
258 260
259 261 self.fields[label] = forms.CharField(initial=value)
260 262
261 263 if 'widget' in params[label]:
262 264 km2unit = line.rc_configuration.km2unit
263 265 if params[label]['widget']=='km':
264 266 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
265 267 elif params[label]['widget']=='unit':
266 268 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
267 269 elif params[label]['widget']=='dc':
268 270 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
269 271 elif params[label]['widget']=='codes':
270 272 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
271 273 else:
272 274 self.fields[label].widget = DefaultWidget(attrs={'disabled':True})
273 275
274 276
275 277 class RCLineEditForm(forms.ModelForm):
276 278
277 279 def __init__(self, *args, **kwargs):
278 280
279 281 extra_fields = kwargs.pop('extra_fields', [])
280 282 conf = kwargs.pop('conf', False)
281 283 line = kwargs.pop('line')
282 284 subform = kwargs.pop('subform', False)
283 285
284 286 super(RCLineEditForm, self).__init__(*args, **kwargs)
285 287
286 288 if subform is not False:
287 289 params = json.loads(line.line_type.params)['params']
288 290 count = subform
289 291 else:
290 292 params = json.loads(line.line_type.params)
291 293 count = -1
292 294
293 295 for label, value in extra_fields.items():
294 296
295 297 if label in ('params',):
296 298 continue
297 299 if 'help' in params[label]:
298 300 help_text = params[label]['help']
299 301 else:
300 302 help_text = ''
301 303
302 304 if 'model' in params[label]:
303 305 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'], conf.id),
304 306 initial=value,
305 307 widget=forms.Select(attrs={'name':'%s|%s|%s' % (count, line.id, label)}),
306 308 help_text=help_text)
307 309
308 310 else:
309 311
310 312 self.fields[label] = forms.CharField(initial=value, help_text=help_text)
311 313
312 314 if label in ('code', ):
313 315 self.fields[label].widget = HiddenWidget(attrs={'name':'%s|%s|%s' % (count, line.id, label)})
314 316
315 317 elif 'widget' in params[label]:
316 318 km2unit = line.rc_configuration.km2unit
317 319 if params[label]['widget']=='km':
318 320 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
319 321 elif params[label]['widget']=='unit':
320 322 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
321 323 elif params[label]['widget']=='dc':
322 324 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
323 325 elif params[label]['widget']=='codes':
324 326 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
325 327 else:
326 328 self.fields[label].widget = DefaultWidget(attrs={'name':'%s|%s|%s' % (count, line.id, label)})
327 329
328 330
329 331 class Meta:
330 332 model = RCLine
331 333 exclude = ('rc_configuration', 'line_type', 'channel', 'position', 'params', 'pulses')
332 334
333 335
334 336 class RCSubLineEditForm(forms.Form):
335 337
336 338 def __init__(self, *args, **kwargs):
337 339 extra_fields = kwargs.pop('extra_fields')
338 340 count = kwargs.pop('count')
339 341 line = kwargs.pop('line')
340 342 super(RCSubLineEditForm, self).__init__(*args, **kwargs)
341 343 for label, value in extra_fields.items():
342 344 self.fields[label] = forms.CharField(initial=value,
343 345 widget=forms.TextInput(attrs={'name':'%s|%s|%s' % (count, line, label)}))
344 346
345 347
346 348 class RCImportForm(forms.Form):
347 349
348 350 file_name = ExtFileField(extensions=['.racp', '.json', '.dat'])
349 351
350 352
351 353 class RCLineCodesForm(forms.ModelForm):
352 354
353 355 def __init__(self, *args, **kwargs):
354 356 super(RCLineCodesForm, self).__init__(*args, **kwargs)
355 357
356 358 if 'initial' in kwargs:
357 359 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
358 360 initial=kwargs['initial']['code'])
359 361 if 'instance' in kwargs:
360 362 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
361 363 initial=kwargs['instance'].pk)
362 364
363 365 self.fields['codes'].widget = CodesWidget()
364 366
365 367
366 368 class Meta:
367 369 model = RCLineCode
368 370 exclude = ('name',)
369 371
370 372 No newline at end of file
@@ -1,737 +1,761
1 1
2 2 import ast
3 3 import json
4 4 import numpy as np
5 5
6 6 from polymorphic import PolymorphicModel
7 7
8 8 from django.db import models
9 9 from django.core.urlresolvers import reverse
10 10 from django.core.validators import MinValueValidator, MaxValueValidator
11 11
12 12 from apps.main.models import Configuration
13 13 from devices.rc import api
14 14 from .utils import RCFile
15 15
16 16 # Create your models here.
17 17
18 18 LINE_TYPES = (
19 19 ('none', 'Not used'),
20 20 ('tr', 'Transmission/reception selector signal'),
21 21 ('tx', 'A modulating signal (Transmission pulse)'),
22 22 ('codes', 'BPSK modulating signal'),
23 23 ('windows', 'Sample window signal'),
24 24 ('sync', 'Synchronizing signal'),
25 25 ('flip', 'IPP related periodic signal'),
26 26 ('prog_pulses', 'Programmable pulse'),
27 27 ('mix', 'Mixed line'),
28 28 )
29 29
30 30
31 31 SAMPLING_REFS = (
32 32 ('none', 'No Reference'),
33 33 ('first_baud', 'Middle of the first baud'),
34 34 ('sub_baud', 'Middle of the sub-baud')
35 35 )
36 36
37 37 DAT_CMDS = {
38 38 # Pulse Design commands
39 39 'DISABLE' : 0, # Disables pulse generation
40 40 'ENABLE' : 24, # Enables pulse generation
41 41 'DELAY_START' : 40, # Write delay status to memory
42 42 'FLIP_START' : 48, # Write flip status to memory
43 43 'SAMPLING_PERIOD' : 64, # Establish Sampling Period
44 44 'TX_ONE' : 72, # Output '0' in line TX
45 45 'TX_ZERO' : 88, # Output '0' in line TX
46 46 'SW_ONE' : 104, # Output '0' in line SW
47 47 'SW_ZERO' : 112, # Output '1' in line SW
48 48 'RESTART': 120, # Restarts CR8 Firmware
49 49 'CONTINUE' : 253, # Function Unknown
50 50 # Commands available to new controllers
51 51 # 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.
52 52 'CLOCK_DIVISOR_INIT' : 12, # Specifies Clock Divisor. Legacy command, ignored in the actual .dat conversion
53 53 'CLOCK_DIVISOR_LAST' : 22, # Specifies Clock Divisor (default 60 if not included) syntax: 255,22 254,N-1.
54 54 'CLOCK_DIVIDER' : 8,
55 55 }
56 56
57 57
58 58 class RCConfiguration(Configuration):
59 59
60 ipp = models.FloatField(verbose_name='Inter pulse period (Km)', validators=[MinValueValidator(1), MaxValueValidator(9000)], default=300)
60 ipp = models.FloatField(verbose_name='Inter pulse period [Km]', validators=[MinValueValidator(1), MaxValueValidator(9000)], default=300)
61 61 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1), MaxValueValidator(300)], default=1)
62 clock_in = models.FloatField(verbose_name='Clock in (MHz)', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
62 clock_in = models.FloatField(verbose_name='Clock in [MHz]', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
63 63 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
64 clock = models.FloatField(verbose_name='Clock Master (MHz)', blank=True, default=1)
65 time_before = models.PositiveIntegerField(verbose_name='Time before (&mu;S)', default=12)
66 time_after = models.PositiveIntegerField(verbose_name='Time after (&mu;S)', default=1)
64 clock = models.FloatField(verbose_name='Clock Master [MHz]', blank=True, default=1)
65 time_before = models.PositiveIntegerField(verbose_name='Time before [&mu;S]', default=12)
66 time_after = models.PositiveIntegerField(verbose_name='Time after [&mu;S]', default=1)
67 67 sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
68 68 sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40)
69 69 control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False)
70 70 control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
71 total_units = models.PositiveIntegerField(default=0)
71 72 mix = models.BooleanField(default=False)
72 73
73 74 class Meta:
74 75 db_table = 'rc_configurations'
75 76
76 77
77 78 def __unicode__(self):
78 79
79 80 if self.mix:
80 81 return u'[MIXED]: %s' % self.name
81 82 else:
82 83 return u'[%s]: %s' % (self.device.name, self.name)
83 84
84 85 def get_absolute_url_plot(self):
85 86 return reverse('url_plot_rc_pulses', args=[str(self.id)])
86 87
87 88 def get_absolute_url_import(self):
88 89 return reverse('url_import_rc_conf', args=[str(self.id)])
89 90
90 91 @property
92 def ipp_unit(self):
93
94 return '{} ({})'.format(self.ipp, int(self.ipp*self.km2unit))
95
96 @property
91 97 def us2unit(self):
92 98
93 99 return self.clock_in/self.clock_divider
94 100
95 101 @property
96 102 def km2unit(self):
97 103
98 104 return 20./3*(self.clock_in/self.clock_divider)
99 105
100 106 def clone(self, **kwargs):
101 107
102 108 lines = self.get_lines()
103 109 self.pk = None
104 110 self.id = None
105 111 for attr, value in kwargs.items():
106 112 setattr(self, attr, value)
107 113 self.save()
108 114
109 115 for line in lines:
110 116 line.clone(rc_configuration=self)
111 117
112 118 return self
113 119
114 120 def get_lines(self, **kwargs):
115 121 '''
116 122 Retrieve configuration lines
117 123 '''
118 124
119 125 return RCLine.objects.filter(rc_configuration=self.pk, **kwargs)
120 126
121 127
122 128 def clean_lines(self):
123 129 '''
124 130 '''
125 131
126 132 empty_line = RCLineType.objects.get(name='none')
127 133
128 134 for line in self.get_lines():
129 135 line.line_type = empty_line
130 136 line.params = '{}'
131 137 line.save()
132 138
133 139 def parms_to_dict(self):
134 140 '''
135 141 '''
136 142
137 143 ignored = ('parameters', 'type', 'polymorphic_ctype', 'configuration_ptr',
138 144 'created_date', 'programmed_date')
139 145
140 146 data = {}
141 147 for field in self._meta.fields:
142 148 if field.name in ignored:
143 149 continue
144 150 data[field.name] = '{}'.format(field.value_from_object(self))
145 151
146 152 data['lines'] = []
147 153
148 154 for line in self.get_lines():
149 155 line_data = json.loads(line.params)
150 156 if 'TX_ref' in line_data and line_data['TX_ref'] not in (0, '0'):
151 157 line_data['TX_ref'] = RCLine.objects.get(pk=line_data['TX_ref']).get_name()
152 158 if 'code' in line_data:
153 159 line_data['code'] = RCLineCode.objects.get(pk=line_data['code']).name
154 160 line_data['type'] = line.line_type.name
155 161 data['lines'].append(line_data)
156 162
157 163 data['delays'] = self.get_delays()
158 164 data['pulses'] = self.get_pulses()
159 165
160 166 return data
161 167
162 168 def dict_to_parms(self, data):
163 169 '''
164 170 '''
165 171
166 172 self.name = data['name']
167 173 self.ipp = data['ipp']
168 174 self.ntx = data['ntx']
169 175 self.clock_in = data['clock_in']
170 176 self.clock_divider = data['clock_divider']
171 177 self.clock = data['clock']
172 178 self.time_before = data['time_before']
173 179 self.time_after = data['time_after']
174 180 self.sync = data['sync']
175 181 self.sampling_reference = data['sampling_reference']
176 182 self.clean_lines()
177 183
178 184 lines = []
179 185 positions = {'tx':0, 'tr':0}
180 186
181 187 for i, line_data in enumerate(data['lines']):
182 188 line_type = RCLineType.objects.get(name=line_data.pop('type'))
183 189 if line_type.name=='codes':
184 190 code = RCLineCode.objects.get(name=line_data['code'])
185 191 line_data['code'] = code.pk
186 192 line = RCLine.objects.filter(rc_configuration=self, channel=i)
187 193 if line:
188 194 line = line[0]
189 195 line.line_type = line_type
190 196 line.params = json.dumps(line_data)
191 197 else:
192 198 line = RCLine(rc_configuration=self, line_type=line_type,
193 199 params=json.dumps(line_data),
194 200 channel=i)
195 201
196 202 if line_type.name=='tx':
197 203 line.position = positions['tx']
198 204 positions['tx'] += 1
199 205
200 206 if line_type.name=='tr':
201 207 line.position = positions['tr']
202 208 positions['tr'] += 1
203 209
204 210 line.save()
205 211 lines.append(line)
206 212
207 213 for line, line_data in zip(lines, data['lines']):
208 214 if 'TX_ref' in line_data:
209 215 params = json.loads(line.params)
210 216 if line_data['TX_ref'] in (0, '0'):
211 217 params['TX_ref'] = '0'
212 218 else:
213 219 params['TX_ref'] = [l.pk for l in lines if l.line_type.name=='tx' and l.get_name()==line_data['TX_ref']][0]
214 220 line.params = json.dumps(params)
215 221 line.save()
216 222
217 223
218 224 def get_delays(self):
219 225
220 226 pulses = [line.pulses_as_points() for line in self.get_lines()]
221 227 points = [tup for tups in pulses for tup in tups]
222 228 points = set([x for tup in points for x in tup])
223 229 points = list(points)
224 230 points.sort()
225 231
226 232 if points[0]<>0:
227 233 points.insert(0, 0)
228 234
229 235 return [points[i+1]-points[i] for i in range(len(points)-1)]
230 236
231 237
232 238 def get_pulses(self, binary=True):
233 239
234 240 pulses = [line.pulses_as_points() for line in self.get_lines()]
235 241 points = [tup for tups in pulses for tup in tups]
236 242 points = set([x for tup in points for x in tup])
237 243 points = list(points)
238 244 points.sort()
239 245
240 246 line_points = [line.pulses_as_points() for line in self.get_lines()]
241 247 line_points = [[(x, x+y) for x,y in tups] for tups in line_points]
242 248 line_points = [[t for x in tups for t in x] for tups in line_points]
243 249 states = [[1 if x in tups else 0 for tups in line_points] for x in points]
244 250
245 251 if binary:
246 252 states.reverse()
247 253 states = [int(''.join([str(x) for x in flips]), 2) for flips in states]
248 254
249 255 return states[:-1]
250 256
251 257 def add_cmd(self, cmd):
252 258
253 259 if cmd in DAT_CMDS:
254 260 return (255, DAT_CMDS[cmd])
255 261
256 262 def add_data(self, value):
257 263
258 264 return (254, value-1)
259 265
260 266 def parms_to_binary(self):
261 267 '''
262 268 Create "dat" stream to be send to CR
263 269 '''
264 270
265 271 data = []
266 272 # create header
267 273 data.append(self.add_cmd('DISABLE'))
268 274 data.append(self.add_cmd('CONTINUE'))
269 275 data.append(self.add_cmd('RESTART'))
270 276
271 277 if self.control_sw:
272 278 data.append(self.add_cmd('SW_ONE'))
273 279 else:
274 280 data.append(self.add_cmd('SW_ZERO'))
275 281
276 282 if self.control_tx:
277 283 data.append(self.add_cmd('TX_ONE'))
278 284 else:
279 285 data.append(self.add_cmd('TX_ZERO'))
280 286
281 287 # write divider
282 288 data.append(self.add_cmd('CLOCK_DIVIDER'))
283 289 data.append(self.add_data(self.clock_divider))
284 290
285 291 # write delays
286 292 data.append(self.add_cmd('DELAY_START'))
287 293 # first delay is always zero
288 294 data.append(self.add_data(1))
289 295
290 296 delays = self.get_delays()
291 297
292 298 for delay in delays:
293 299 while delay>252:
294 300 data.append(self.add_data(253))
295 301 delay -= 253
296 302 data.append(self.add_data(delay))
297 303
298 304 # write flips
299 305 data.append(self.add_cmd('FLIP_START'))
300 306
301 307 states = self.get_pulses(binary=False)
302 308
303 309 for flips, delay in zip(states, delays):
304 310 flips.reverse()
305 311 flip = int(''.join([str(x) for x in flips]), 2)
306 312 data.append(self.add_data(flip+1))
307 313 while delay>252:
308 314 data.append(self.add_data(1))
309 315 delay -= 253
310 316
311 317 # write sampling period
312 318 data.append(self.add_cmd('SAMPLING_PERIOD'))
313 319 wins = self.get_lines(line_type__name='windows')
314 320 if wins:
315 321 win_params = json.loads(wins[0].params)['params']
316 322 if win_params:
317 323 dh = int(win_params[0]['resolution']*self.km2unit)
318 324 else:
319 325 dh = 1
320 326 else:
321 327 dh = 1
322 328 data.append(self.add_data(dh))
323 329
324 330 # write enable
325 331 data.append(self.add_cmd('ENABLE'))
326 332
327 333 return '\n'.join(['{}'.format(x) for tup in data for x in tup])
328 334
329 335 def update_from_file(self, filename):
330 336 '''
331 337 Update instance from file
332 338 '''
333 339
334 340 f = RCFile(filename)
335 341 self.dict_to_parms(f.data)
336 342 self.update_pulses()
337 self.save()
338 343
339 344 def update_pulses(self):
340 345
341 346 for line in self.get_lines():
342 line.update_pulses()
347 line.update_pulses()
343 348
344 349 def plot_pulses(self):
345 350
346 351 import matplotlib.pyplot as plt
347 352 from bokeh.resources import CDN
348 353 from bokeh.embed import components
349 354 from bokeh.mpl import to_bokeh
350 355 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, PreviewSaveTool
351 356
352 lines = self.get_lines()
353
354 max_value = self.ipp*self.km2unit*self.ntx
357 lines = self.get_lines()
355 358
356 359 N = len(lines)
357 360 fig = plt.figure(figsize=(10, 2+N*0.5))
358 361 ax = fig.add_subplot(111)
359 362 labels = []
360 363
361 364 for i, line in enumerate(lines):
362 365 labels.append(line.get_name())
363 l = ax.plot((0, max_value),(N-i-1, N-i-1))
366 l = ax.plot((0, self.total_units),(N-i-1, N-i-1))
364 367 points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points() if tup<>(0,0)]
365 368 ax.broken_barh(points, (N-i-1, 0.5),
366 369 edgecolor=l[0].get_color(), facecolor='none')
367 370
368 371 labels.reverse()
369 372 ax.set_yticklabels(labels)
370 373 plot = to_bokeh(fig, use_pandas=False)
371 374 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), PreviewSaveTool()]
372 375
373 376 return components(plot, CDN)
374 377
375 378 def status_device(self):
376 379
377 380 return 0
378 381
379 382 def stop_device(self):
380 383
381 384 answer = api.disable(ip = self.device.ip_address,
382 385 port = self.device.port_address)
383 386
384 387 if answer[0] != "1":
385 388 self.message = answer[0:]
386 389 return 0
387 390
388 391 self.message = answer[2:]
389 392 return 1
390 393
391 394 def start_device(self):
392 395
393 396 answer = api.enable(ip = self.device.ip_address,
394 397 port = self.device.port_address)
395 398
396 399 if answer[0] != "1":
397 400 self.message = answer[0:]
398 401 return 0
399 402
400 403 self.message = answer[2:]
401 404 return 1
402 405
403 406 def write_device(self):
404 407 answer = api.write_config(ip = self.device.ip_address,
405 408 port = self.device.port_address,
406 409 parms = self.parms_to_dict())
407 410
408 411 if answer[0] != "1":
409 412 self.message = answer[0:]
410 413 return 0
411 414
412 415 self.message = answer[2:]
413 416 return 1
414 417
415 418
416 419 class RCLineCode(models.Model):
417 420
418 421 name = models.CharField(max_length=40)
419 422 bits_per_code = models.PositiveIntegerField(default=0)
420 423 number_of_codes = models.PositiveIntegerField(default=0)
421 424 codes = models.TextField(blank=True, null=True)
422 425
423 426 class Meta:
424 427 db_table = 'rc_line_codes'
425 428 ordering = ('name',)
426 429
427 430 def __unicode__(self):
428 431 return u'%s' % self.name
429 432
430 433
431 434 class RCLineType(models.Model):
432 435
433 436 name = models.CharField(choices=LINE_TYPES, max_length=40)
434 437 description = models.TextField(blank=True, null=True)
435 438 params = models.TextField(default='[]')
436 439
437 440 class Meta:
438 441 db_table = 'rc_line_types'
439 442
440 443 def __unicode__(self):
441 444 return u'%s - %s' % (self.name.upper(), self.get_name_display())
442 445
443 446
444 447 class RCLine(models.Model):
445 448
446 449 rc_configuration = models.ForeignKey(RCConfiguration, on_delete=models.CASCADE)
447 450 line_type = models.ForeignKey(RCLineType)
448 451 channel = models.PositiveIntegerField(default=0)
449 452 position = models.PositiveIntegerField(default=0)
450 453 params = models.TextField(default='{}')
451 454 pulses = models.TextField(default='')
452 455
453 456 class Meta:
454 457 db_table = 'rc_lines'
455 458 ordering = ['channel']
456 459
457 460 def __unicode__(self):
458 461 if self.rc_configuration:
459 462 return u'%s - %s' % (self.rc_configuration, self.get_name())
460 463
461 464 def clone(self, **kwargs):
462 465
463 466 self.pk = None
464 467
465 468 for attr, value in kwargs.items():
466 469 setattr(self, attr, value)
467 470
468 471 self.save()
469 472
470 473 return self
471 474
472 475 def get_name(self):
473 476
474 477 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
475 478 s = ''
476 479
477 480 if self.line_type.name in ('tx',):
478 481 s = chars[self.position]
479 482 elif self.line_type.name in ('codes', 'windows', 'tr'):
480 483 if 'TX_ref' in json.loads(self.params):
481 484 pk = json.loads(self.params)['TX_ref']
482 485 if pk in (0, '0'):
483 486 s = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
484 487 else:
485 488 ref = RCLine.objects.get(pk=pk)
486 489 s = chars[ref.position]
487 490
488 491 if s:
489 492 return '{}({}) {}'.format(self.line_type.name.upper(), s, self.channel)
490 493 else:
491 494 return '{} {}'.format(self.line_type.name.upper(), self.channel)
492 495
493 496 def get_lines(self, **kwargs):
494 497
495 498 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
496 499
497 500 def pulses_as_array(self):
498 501
499 y = np.zeros(self.rc_configuration.ntx*self.rc_configuration.ipp*self.rc_configuration.km2unit)
502 y = np.zeros(self.rc_configuration.total_units)
500 503
501 504 for tup in ast.literal_eval(self.pulses):
502 505 y[tup[0]:tup[1]] = 1
503 506
504 507 return y.astype(np.int8)
505 508
506 509 def pulses_as_points(self):
507 510
508 511 return ast.literal_eval(self.pulses)
509 512
510 513 def get_win_ref(self, params, tx_id, km2unit):
511 514
512 515 ref = self.rc_configuration.sampling_reference
513 516 codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
514 517
515 518 if codes:
516 519 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/len(json.loads(codes[0].params)['codes'][0])
517 520 else:
518 521 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
519 522
520 523 if ref=='first_baud':
521 524 return int(1 + (tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit)
522 525 elif ref=='sub_baud':
523 526 return int(1 + params['first_height']*km2unit - params['resolution']*km2unit/2)
524 527 else:
525 528 return 0
526 529
527 530 def update_pulses(self):
528 531 '''
529 532 Update pulses field
530 533 '''
531 534
532 535 km2unit = self.rc_configuration.km2unit
533 536 us2unit = self.rc_configuration.us2unit
534 537 ipp = self.rc_configuration.ipp
535 538 ntx = self.rc_configuration.ntx
536 539 ipp_u = int(ipp*km2unit)
537
540 total = ipp_u*ntx
538 541 y = []
539 542
540 543 if self.line_type.name=='tr':
541 544 tr_params = json.loads(self.params)
542 545
543 546 if tr_params['TX_ref'] in ('0', 0):
544 547 txs = self.get_lines(line_type__name='tx')
545 548 else:
546 549 txs = [RCLine.objects.filter(pk=tr_params['TX_ref'])]
547 550
548 551 for tx in txs:
549 552 params = json.loads(tx.params)
550 553 if float(params['pulse_width'])==0:
551 554 continue
552 555 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
553 556 width = float(params['pulse_width'])*km2unit+int(self.rc_configuration.time_before*us2unit)
554 557 before = 0
555 558 after = int(self.rc_configuration.time_after*us2unit)
556 559
557 560 y_tx = self.points(ntx, ipp_u, width,
558 561 delay=delays,
559 562 before=before,
560 563 after=after,
561 564 sync=self.rc_configuration.sync)
562 565
563 566 ranges = params['range'].split(',')
564 567
565 568 if len(ranges)>0 and ranges[0]<>'0':
566 569 y_tx = self.mask_ranges(y_tx, ranges)
567 570
568 571 tr_ranges = tr_params['range'].split(',')
569 572
570 573 if len(tr_ranges)>0 and tr_ranges[0]<>'0':
571 574 y_tx = self.mask_ranges(y_tx, tr_ranges)
572 575
573 576 y.extend(y_tx)
574 577
575 578 elif self.line_type.name=='tx':
576 579 params = json.loads(self.params)
577 580 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
578 581 width = float(params['pulse_width'])*km2unit
579 582
580 583 if width>0:
581 584 before = int(self.rc_configuration.time_before*us2unit)
582 585 after = 0
583 586
584 587 y = self.points(ntx, ipp_u, width,
585 588 delay=delays,
586 589 before=before,
587 590 after=after,
588 591 sync=self.rc_configuration.sync)
589 592
590 593 ranges = params['range'].split(',')
591 594
592 595 if len(ranges)>0 and ranges[0]<>'0':
593 596 y = self.mask_ranges(y, ranges)
594 597
595 598 elif self.line_type.name=='flip':
596 599 n = float(json.loads(self.params)['number_of_flips'])
597 600 width = n*ipp*km2unit
598 601 y = self.points(int((ntx+1)/(2*n)), ipp_u*n*2, width)
599 602
600 603 elif self.line_type.name=='codes':
601 604 params = json.loads(self.params)
602 605 tx = RCLine.objects.get(pk=params['TX_ref'])
603 606 tx_params = json.loads(tx.params)
604 607 delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
605 608 f = int(float(tx_params['pulse_width'])*km2unit)/len(params['codes'][0])
606 609 codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in params['codes']]
607 610 codes = [self.array_to_points(code) for code in codes]
608 611 n = len(codes)
609 612
610 613 for i, tup in enumerate(tx.pulses_as_points()):
611 614 code = codes[i%n]
612 615 y.extend([(c[0]+tup[0], c[1]+tup[0]) for c in code])
613 616
614 617 ranges = tx_params['range'].split(',')
615 618 if len(ranges)>0 and ranges[0]<>'0':
616 619 y = self.mask_ranges(y, ranges)
617 620
618 621 elif self.line_type.name=='sync':
619 622 params = json.loads(self.params)
620 623 n = ipp_u*ntx
621 624 if params['invert'] in ('1', 1):
622 625 y = [(n-1, n)]
623 626 else:
624 627 y = [(0, 1)]
625 628
626 629 elif self.line_type.name=='prog_pulses':
627 630 params = json.loads(self.params)
628 631 if int(params['periodic'])==0:
629 632 nntx = 1
630 633 nipp = ipp_u*ntx
631 634 else:
632 635 nntx = ntx
633 636 nipp = ipp_u
634 637
635 638 if 'params' in params and len(params['params'])>0:
636 639 for p in params['params']:
637 640 y_pp = self.points(nntx, nipp,
638 641 p['end']-p['begin'],
639 642 before=p['begin'])
640 643
641 644 y.extend(y_pp)
642 645
643 646 elif self.line_type.name=='windows':
644 647 params = json.loads(self.params)
645 648
646 649 if 'params' in params and len(params['params'])>0:
647 650 tr_params = json.loads(self.get_lines(line_type__name='tr')[0].params)
648 651 tr_ranges = tr_params['range'].split(',')
649 652 for p in params['params']:
650 653 y_win = self.points(ntx, ipp_u,
651 654 p['resolution']*p['number_of_samples']*km2unit,
652 655 before=int(self.rc_configuration.time_before*us2unit)+self.get_win_ref(p, params['TX_ref'], km2unit),
653 656 sync=self.rc_configuration.sync)
654 657
655 658 if len(tr_ranges)>0 and tr_ranges[0]<>'0':
656 659 y_win = self.mask_ranges(y_win, tr_ranges)
657 660
658 661 y.extend(y_win)
659 662
660 663 elif self.line_type.name=='mix':
661 664 values = self.rc_configuration.parameters.split('-')
662 665 confs = RCConfiguration.objects.filter(pk__in=[value.split('|')[0] for value in values])
663 666 modes = [value.split('|')[1] for value in values]
664 delays = [value.split('|')[2] for value in values]
665 masks = [value.split('|')[3] for value in values]
667 ops = [value.split('|')[2] for value in values]
668 delays = [value.split('|')[3] for value in values]
669 masks = [value.split('|')[4] for value in values]
670 mask = list('{:8b}'.format(int(masks[0])))
671 mask.reverse()
672 if mask[self.channel] in ('0', '', ' '):
673 y = np.zeros(total, dtype=np.int8)
674 else:
675 y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
666 676
667 y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
668 ysize = len(y)
669 677 for i in range(1, len(values)):
670 678 mask = list('{:8b}'.format(int(masks[i])))
671 679 mask.reverse()
672 680
673 681 if mask[self.channel] in ('0', '', ' '):
674 682 continue
675 Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
683 Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
676 684 delay = float(delays[i])*km2unit
677 if delay>0:
678 y_temp = np.empty_like(Y)
679 y_temp[:delay] = 0
680 y_temp[delay:] = Y[:-delay]
681 y_tempsize = len(y_temp)
682 if modes[i]=='OR':
685
686 if delay>0:
687 if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y):
688 y_temp = np.empty_like(Y)
689 y_temp[:delay] = 0
690 y_temp[delay:] = Y[:-delay]
691 elif delay+len(Y)>len(y):
692 y_new = np.zeros(delay+len(Y), dtype=np.int8)
693 y_new[:len(y)] = y
694 y = y_new
695 y_temp = np.zeros(delay+len(Y), dtype=np.int8)
696 y_temp[-len(Y):] = Y
697 elif delay+len(Y)==len(y):
698 y_temp = np.zeros(delay+len(Y))
699 y_temp[-len(Y):] = Y
700
701 if ops[i]=='OR':
683 702 y = y | y_temp
684 elif modes[i]=='XOR':
703 elif ops[i]=='XOR':
685 704 y = y ^ y_temp
686 elif modes[i]=='AND':
705 elif ops[i]=='AND':
687 706 y = y & y_temp
688 elif modes[i]=='NAND':
707 elif ops[i]=='NAND':
689 708 y = y & ~y_temp
690
709
710 total = len(y)
691 711 y = self.array_to_points(y)
692 712
693 713 else:
694 714 y = []
695 715
716 if self.rc_configuration.total_units <> total:
717 self.rc_configuration.total_units = total
718 self.rc_configuration.save()
719
696 720 self.pulses = y
697 721 self.save()
698 722
699 723 @staticmethod
700 724 def array_to_points(X):
701 725
702 726 d = X[1:]-X[:-1]
703 727
704 728 up = np.where(d==1)[0]
705 729 if X[0]==1:
706 730 up = np.concatenate((np.array([-1]), up))
707 731 up += 1
708 732
709 733 dw = np.where(d==-1)[0]
710 734 if X[-1]==1:
711 735 dw = np.concatenate((dw, np.array([len(X)-1])))
712 736 dw += 1
713 737
714 738 return [(tup[0], tup[1]) for tup in zip(up, dw)]
715 739
716 740 @staticmethod
717 741 def mask_ranges(Y, ranges):
718 742
719 743 y = [(0, 0) for __ in Y]
720 744
721 745 for index in ranges:
722 746 if '-' in index:
723 747 args = [int(a) for a in index.split('-')]
724 748 y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
725 749 else:
726 750 y[int(index-1)] = Y[int(index-1)]
727 751
728 752 return y
729 753
730 754 @staticmethod
731 755 def points(ntx, ipp, width, delay=[0], before=0, after=0, sync=0):
732 756
733 757 delays = len(delay)
734 758
735 759 Y = [(ipp*x+before+delay[x%delays], ipp*x+width+before+delay[x%delays]+after) for x in range(ntx)]
736 760
737 761 return Y No newline at end of file
@@ -1,370 +1,370
1 1
2 2 import json
3 3
4 4 from django.contrib import messages
5 5 from django.utils.safestring import mark_safe
6 6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
7 7
8 8 from apps.main.models import Configuration, Experiment, Device
9 9 from apps.main.views import sidebar
10 10
11 11 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode
12 12 from .forms import RCConfigurationForm, RCLineForm, RCLineViewForm, RCLineEditForm, RCImportForm, RCLineCodesForm
13 13
14 14
15 15 def conf(request, conf_id):
16 16
17 17 conf = get_object_or_404(RCConfiguration, pk=conf_id)
18 18
19 19 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
20 20
21 21 for line in lines:
22 22 params = json.loads(line.params)
23 23 line.form = RCLineViewForm(extra_fields=params, line=line)
24 24 if 'params' in params:
25 25 line.subforms = [RCLineViewForm(extra_fields=fields, line=line, subform=True) for fields in params['params']]
26 26
27 27 kwargs = {}
28 28 kwargs['dev_conf'] = conf
29 29 kwargs['rc_lines'] = lines
30 kwargs['dev_conf_keys'] = ['name', 'ipp', 'ntx', 'clock_in', 'clock_divider', 'clock',
30 kwargs['dev_conf_keys'] = ['name', 'ipp_unit', 'ntx', 'clock_in', 'clock_divider', 'clock',
31 31 'time_before', 'time_after', 'sync', 'sampling_reference', 'control_tx', 'control_sw']
32 32
33 33 kwargs['title'] = 'RC Configuration'
34 34 kwargs['suptitle'] = 'Details'
35 35
36 36 kwargs['button'] = 'Edit Configuration'
37 37 ###### SIDEBAR ######
38 38 kwargs.update(sidebar(conf=conf))
39 39
40 40 return render(request, 'rc_conf.html', kwargs)
41 41
42 42
43 43 def conf_edit(request, conf_id):
44 44
45 45 conf = get_object_or_404(RCConfiguration, pk=conf_id)
46 46
47 47 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
48 48
49 49 for line in lines:
50 50 params = json.loads(line.params)
51 51 line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params)
52 52 line.subform = False
53 53
54 54 if 'params' in params:
55 55 line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])]
56 56 line.subform = True
57 57
58 58 if request.method=='GET':
59 59
60 60 form = RCConfigurationForm(instance=conf)
61 61
62 62 elif request.method=='POST':
63 63
64 64 line_data = {}
65 65 conf_data = {}
66 66 extras = []
67 67
68 68 #classified post fields
69 69 for label,value in request.POST.items():
70 70 if label=='csrfmiddlewaretoken':
71 71 continue
72 72
73 73 if label.count('|')==0:
74 74 conf_data[label] = value
75 75 continue
76 76
77 77 elif label.split('|')[0]<>'-1':
78 78 extras.append(label)
79 79 continue
80 80
81 81 x, pk, name = label.split('|')
82 82
83 83 if name=='codes':
84 84 value = [s for s in value.split('\r\n') if s]
85 85
86 86 if pk in line_data:
87 87 line_data[pk][name] = value
88 88 else:
89 89 line_data[pk] = {name:value}
90 90
91 91 #update conf
92 92 form = RCConfigurationForm(conf_data, instance=conf)
93 93
94 94 if form.is_valid():
95 95
96 96 form.save()
97 97
98 98 #update lines fields
99 99 extras.sort()
100 100 for label in extras:
101 101 x, pk, name = label.split('|')
102 102 if pk not in line_data:
103 103 line_data[pk] = {}
104 104 if 'params' not in line_data[pk]:
105 105 line_data[pk]['params'] = []
106 106 if len(line_data[pk]['params'])<int(x)+1:
107 107 line_data[pk]['params'].append({})
108 108 line_data[pk]['params'][int(x)][name] = float(request.POST[label])
109 109
110 110 for pk, params in line_data.items():
111 111 line = RCLine.objects.get(pk=pk)
112 112 if line.line_type.name in ('windows', 'prog_pulses'):
113 113 if 'params' not in params:
114 114 params['params'] = []
115 115 line.params = json.dumps(params)
116 116 line.save()
117 117
118 118 #update pulses field
119 conf.update_pulses()
119 conf.update_pulses()
120 120
121 121 messages.success(request, 'RC Configuration successfully updated')
122 122
123 123 return redirect(conf.get_absolute_url())
124 124
125 125 kwargs = {}
126 126 kwargs['dev_conf'] = conf
127 127 kwargs['form'] = form
128 128 kwargs['rc_lines'] = lines
129 129 kwargs['edit'] = True
130 130
131 131 kwargs['title'] = 'RC Configuration'
132 132 kwargs['suptitle'] = 'Edit'
133 133 kwargs['button'] = 'Update'
134 134 kwargs['previous'] = conf.get_absolute_url()
135 135
136 136 return render(request, 'rc_conf_edit.html', kwargs)
137 137
138 138
139 139 def add_line(request, conf_id, line_type_id=None, code_id=None):
140 140
141 141 conf = get_object_or_404(RCConfiguration, pk=conf_id)
142 142
143 143 if request.method=='GET':
144 144 if line_type_id:
145 145 line_type = get_object_or_404(RCLineType, pk=line_type_id)
146 146
147 147 if code_id:
148 148 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id, 'code_id': code_id},
149 149 extra_fields=json.loads(line_type.params))
150 150 else:
151 151 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id},
152 152 extra_fields=json.loads(line_type.params))
153 153 else:
154 154 line_type = {'id':0}
155 155 form = RCLineForm(initial={'rc_configuration':conf_id})
156 156
157 157 if request.method=='POST':
158 158
159 159 line_type = get_object_or_404(RCLineType, pk=line_type_id)
160 160 form = RCLineForm(request.POST,
161 161 extra_fields=json.loads(line_type.params))
162 162
163 163 if form.is_valid():
164 164 form.save()
165 165 form.instance.update_pulses()
166 166 return redirect('url_edit_rc_conf', conf.id)
167 167
168 168 kwargs = {}
169 169 kwargs['form'] = form
170 170 kwargs['title'] = 'RC Configuration'
171 171 kwargs['suptitle'] = 'Add Line'
172 172 kwargs['button'] = 'Add'
173 173 kwargs['previous'] = conf.get_absolute_url_edit()
174 174 kwargs['dev_conf'] = conf
175 175 kwargs['line_type'] = line_type
176 176
177 177 return render(request, 'rc_add_line.html', kwargs)
178 178
179 179 def edit_codes(request, conf_id, line_id, code_id=None):
180 180
181 181 conf = get_object_or_404(RCConfiguration, pk=conf_id)
182 182 line = get_object_or_404(RCLine, pk=line_id)
183 183 params = json.loads(line.params)
184 184
185 185 if request.method=='GET':
186 186 if code_id:
187 187 code = get_object_or_404(RCLineCode, pk=code_id)
188 188 form = RCLineCodesForm(instance=code)
189 189 else:
190 190 initial = {'code': params['code'],
191 191 'codes': params['codes'] if 'codes' in params else [],
192 192 'number_of_codes': len(params['codes']) if 'codes' in params else 0,
193 193 'bits_per_code': len(params['codes'][0]) if 'codes' in params else 0,
194 194 }
195 195 form = RCLineCodesForm(initial=initial)
196 196
197 197 if request.method=='POST':
198 198 form = RCLineCodesForm(request.POST)
199 199 if form.is_valid():
200 200 params['code'] = request.POST['code']
201 201 params['codes'] = [s for s in request.POST['codes'].split('\r\n') if s]
202 202 line.params = json.dumps(params)
203 203 line.save()
204 204 messages.success(request, 'Line: "%s" has been updated.' % line)
205 205 return redirect('url_edit_rc_conf', conf.id)
206 206
207 207 kwargs = {}
208 208 kwargs['form'] = form
209 209 kwargs['title'] = line
210 210 kwargs['suptitle'] = 'Edit'
211 211 kwargs['button'] = 'Update'
212 212 kwargs['dev_conf'] = conf
213 213 kwargs['previous'] = conf.get_absolute_url_edit()
214 214 kwargs['line'] = line
215 215
216 216 return render(request, 'rc_edit_codes.html', kwargs)
217 217
218 218 def add_subline(request, conf_id, line_id):
219 219
220 220 conf = get_object_or_404(RCConfiguration, pk=conf_id)
221 221 line = get_object_or_404(RCLine, pk=line_id)
222 222
223 223 if request.method == 'POST':
224 224 if line:
225 225 params = json.loads(line.params)
226 226 subparams = json.loads(line.line_type.params)
227 227 if 'params' in subparams:
228 228 dum = {}
229 229 for key, value in subparams['params'].items():
230 230 dum[key] = value['value']
231 231 params['params'].append(dum)
232 232 line.params = json.dumps(params)
233 233 line.save()
234 234 return redirect('url_edit_rc_conf', conf.id)
235 235
236 236 kwargs = {}
237 237
238 238 kwargs['title'] = 'Add new'
239 239 kwargs['suptitle'] = '%s to %s' % (line.line_type.name, line)
240 240
241 241 return render(request, 'confirm.html', kwargs)
242 242
243 243 def remove_line(request, conf_id, line_id):
244 244
245 245 conf = get_object_or_404(RCConfiguration, pk=conf_id)
246 246 line = get_object_or_404(RCLine, pk=line_id)
247 247
248 248 if request.method == 'POST':
249 249 if line:
250 250 try:
251 251 channel = line.channel
252 252 line.delete()
253 253 for ch in range(channel+1, RCLine.objects.filter(rc_configuration=conf).count()+1):
254 254 l = RCLine.objects.get(rc_configuration=conf, channel=ch)
255 255 l.channel = l.channel-1
256 256 l.save()
257 257 messages.success(request, 'Line: "%s" has been deleted.' % line)
258 258 except:
259 259 messages.error(request, 'Unable to delete line: "%s".' % line)
260 260
261 261 return redirect('url_edit_rc_conf', conf.id)
262 262
263 263 kwargs = {}
264 264
265 265 kwargs['object'] = line
266 266 kwargs['delete_view'] = True
267 267 kwargs['title'] = 'Confirm delete'
268 268 kwargs['previous'] = conf.get_absolute_url_edit()
269 269 return render(request, 'confirm.html', kwargs)
270 270
271 271
272 272 def remove_subline(request, conf_id, line_id, subline_id):
273 273
274 274 conf = get_object_or_404(RCConfiguration, pk=conf_id)
275 275 line = get_object_or_404(RCLine, pk=line_id)
276 276
277 277 if request.method == 'POST':
278 278 if line:
279 279 params = json.loads(line.params)
280 280 params['params'].remove(params['params'][int(subline_id)-1])
281 281 line.params = json.dumps(params)
282 282 line.save()
283 283
284 284 return redirect('url_edit_rc_conf', conf.id)
285 285
286 286 kwargs = {}
287 287
288 288 kwargs['object'] = line
289 289 kwargs['object_name'] = line.line_type.name
290 290 kwargs['delete_view'] = True
291 291 kwargs['title'] = 'Confirm delete'
292 292
293 293 return render(request, 'confirm.html', kwargs)
294 294
295 295
296 296 def update_lines_position(request, conf_id):
297 297
298 298 conf = get_object_or_404(RCConfiguration, pk=conf_id)
299 299
300 300 if request.method=='POST':
301 301 ch = 0
302 302 for item in request.POST['items'].split('&'):
303 303 line = RCLine.objects.get(pk=item.split('=')[-1])
304 304 line.channel = ch
305 305 line.save()
306 306 ch += 1
307 307
308 308 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
309 309
310 310 for line in lines:
311 311 params = json.loads(line.params)
312 312 line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params)
313 313
314 314 if 'params' in params:
315 315 line.subform = True
316 316 line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])]
317 317
318 318 html = render(request, 'rc_lines.html', {'dev_conf':conf, 'rc_lines':lines, 'edit':True})
319 319 data = {'html': html.content}
320 320
321 321 return HttpResponse(json.dumps(data), content_type="application/json")
322 322 return redirect('url_edit_rc_conf', conf.id)
323 323
324 324
325 325 def import_file(request, conf_id):
326 326
327 327 conf = get_object_or_404(RCConfiguration, pk=conf_id)
328 328 if request.method=='POST':
329 329 form = RCImportForm(request.POST, request.FILES)
330 330 if form.is_valid():
331 331 try:
332 332 conf.update_from_file(request.FILES['file_name'])
333 333 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
334 334 return redirect(conf.get_absolute_url_edit())
335 335
336 336 except Exception as e:
337 337 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], e))
338 338
339 339 else:
340 340 messages.warning(request, 'Your current configuration will be replaced')
341 341 form = RCImportForm()
342 342
343 343 kwargs = {}
344 344 kwargs['form'] = form
345 345 kwargs['title'] = 'RC Configuration'
346 346 kwargs['suptitle'] = 'Import file'
347 347 kwargs['button'] = 'Upload'
348 348 kwargs['previous'] = conf.get_absolute_url()
349 349
350 350 return render(request, 'rc_import.html', kwargs)
351 351
352 352
353 353 def plot_pulses(request, conf_id):
354 354
355 355 conf = get_object_or_404(RCConfiguration, pk=conf_id)
356 356
357 357 script, div = conf.plot_pulses()
358 358
359 359 kwargs = {}
360 360
361 361 kwargs['title'] = 'RC Pulses'
362 362 kwargs['suptitle'] = conf.name
363 363 kwargs['div'] = mark_safe(div)
364 364 kwargs['script'] = mark_safe(script)
365 365
366 366 if 'json' in request.GET:
367 367 return HttpResponse(json.dumps({'div':mark_safe(div), 'script':mark_safe(script)}), content_type="application/json")
368 368 else:
369 369 return render(request, 'rc_pulses.html', kwargs)
370 370
General Comments 0
You need to be logged in to leave comments. Login now