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