##// END OF EJS Templates
Improve RC pulses plot and Operation view...
Juan C. Espinoza -
r175:a7fbf14a85a6
parent child
Show More
@@ -124,6 +124,11 class Device(models.Model):
124
124
125 return color
125 return color
126
126
127 @property
128 def url(self):
129
130 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
131
127 def get_absolute_url(self):
132 def get_absolute_url(self):
128 return reverse('url_device', args=[str(self.id)])
133 return reverse('url_device', args=[str(self.id)])
129
134
@@ -37,7 +37,7
37 <table class="table table-bordered">
37 <table class="table table-bordered">
38 <tr>
38 <tr>
39 <th>Status</th>
39 <th>Status</th>
40 <td>{%if status != "No connected" %} <span class="glyphicon glyphicon-ok-circle text-success" aria-hidden="true"></span> {{status}} {% else %} <span class="glyphicon glyphicon-remove-circle text-danger" aria-hidden="true"></span> {{status}} {% endif %}</td>
40 <td class="text-{{dev_conf.device.status_color}}"> {{dev_conf.device.get_status_display}} </td>
41 </tr>
41 </tr>
42
42
43 {% for key in dev_conf_keys %}
43 {% for key in dev_conf_keys %}
@@ -57,11 +57,12
57
57
58 {% for item in location.experiments %}
58 {% for item in location.experiments %}
59 {% if location.name in item.location.name %}
59 {% if location.name in item.location.name %}
60
61 <tr class="clickable-row" data-href="{% url 'url_experiment' item.id %}" >
60 <tr class="clickable-row" data-href="{% url 'url_experiment' item.id %}" >
62 <td>{{ forloop.counter }}</td>
61 <td>{{ forloop.counter }}</td>
63 {% for key in experiment_keys %}
62 {% for key in experiment_keys %}
64 {% if 'status' in key %}
63 {% if 'name' in key %}
64 <td class="col-md-5">{{ item|value:key }}</td>
65 {% elif 'status' in key %}
65 <td class="text-{{item.status_color}}">{{ item|value:key }}</td>
66 <td class="text-{{item.status_color}}">{{ item|value:key }}</td>
66 {% else %}
67 {% else %}
67 <td>{{ item|value:key }}</td>
68 <td>{{ item|value:key }}</td>
@@ -1399,6 +1399,7 def get_paginator(model, page, order, filters={}, n=10):
1399 def operation(request, id_camp=None):
1399 def operation(request, id_camp=None):
1400
1400
1401 kwargs = {}
1401 kwargs = {}
1402 kwargs['no_sidebar'] = True
1402 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
1403 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
1403 end_date__gte=datetime.now()).order_by('-start_date')
1404 end_date__gte=datetime.now()).order_by('-start_date')
1404
1405
@@ -1412,8 +1413,6 def operation(request, id_camp=None):
1412 kwargs['form'] = form
1413 kwargs['form'] = form
1413 return render(request, 'operation.html', kwargs)
1414 return render(request, 'operation.html', kwargs)
1414
1415
1415
1416
1417 #---Experiment
1416 #---Experiment
1418 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1417 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1419 kwargs['experiment_keys'] = keys[1:]
1418 kwargs['experiment_keys'] = keys[1:]
@@ -1423,7 +1422,7 def operation(request, id_camp=None):
1423 #---Else
1422 #---Else
1424 kwargs['title'] = 'Campaign'
1423 kwargs['title'] = 'Campaign'
1425 kwargs['suptitle'] = campaign.name
1424 kwargs['suptitle'] = campaign.name
1426 kwargs['form'] = form
1425 kwargs['form'] = form
1427
1426
1428 return render(request, 'operation.html', kwargs)
1427 return render(request, 'operation.html', kwargs)
1429
1428
@@ -1,7 +1,9
1
1
2 import ast
2 import ast
3 import json
3 import json
4 import requests
4 import numpy as np
5 import numpy as np
6 from base64 import b64encode
5
7
6 from django.db import models
8 from django.db import models
7 from django.core.urlresolvers import reverse
9 from django.core.urlresolvers import reverse
@@ -258,60 +260,60 class RCConfiguration(Configuration):
258 def add_data(self, value):
260 def add_data(self, value):
259
261
260 return (254, value-1)
262 return (254, value-1)
261
263
262 def parms_to_binary(self):
264 def parms_to_binary(self, dat=True):
263 '''
265 '''
264 Create "dat" stream to be send to CR
266 Create "dat" stream to be send to CR
265 '''
267 '''
266
268
267 data = []
269 data = bytearray()
268 # create header
270 # create header
269 data.append(self.add_cmd('DISABLE'))
271 data.extend(self.add_cmd('DISABLE'))
270 data.append(self.add_cmd('CONTINUE'))
272 data.extend(self.add_cmd('CONTINUE'))
271 data.append(self.add_cmd('RESTART'))
273 data.extend(self.add_cmd('RESTART'))
272
274
273 if self.control_sw:
275 if self.control_sw:
274 data.append(self.add_cmd('SW_ONE'))
276 data.extend(self.add_cmd('SW_ONE'))
275 else:
277 else:
276 data.append(self.add_cmd('SW_ZERO'))
278 data.extend(self.add_cmd('SW_ZERO'))
277
279
278 if self.control_tx:
280 if self.control_tx:
279 data.append(self.add_cmd('TX_ONE'))
281 data.extend(self.add_cmd('TX_ONE'))
280 else:
282 else:
281 data.append(self.add_cmd('TX_ZERO'))
283 data.extend(self.add_cmd('TX_ZERO'))
282
284
283 # write divider
285 # write divider
284 data.append(self.add_cmd('CLOCK_DIVIDER'))
286 data.extend(self.add_cmd('CLOCK_DIVIDER'))
285 data.append(self.add_data(self.clock_divider))
287 data.extend(self.add_data(self.clock_divider))
286
288
287 # write delays
289 # write delays
288 data.append(self.add_cmd('DELAY_START'))
290 data.extend(self.add_cmd('DELAY_START'))
289 # first delay is always zero
291 # first delay is always zero
290 data.append(self.add_data(1))
292 data.extend(self.add_data(1))
291
293
292 delays = self.get_delays()
294 delays = self.get_delays()
293
295
294 for delay in delays:
296 for delay in delays:
295 while delay>252:
297 while delay>252:
296 data.append(self.add_data(253))
298 data.extend(self.add_data(253))
297 delay -= 253
299 delay -= 253
298 data.append(self.add_data(delay))
300 data.extend(self.add_data(int(delay)))
299
301
300 # write flips
302 # write flips
301 data.append(self.add_cmd('FLIP_START'))
303 data.extend(self.add_cmd('FLIP_START'))
302
304
303 states = self.get_pulses(binary=False)
305 states = self.get_pulses(binary=False)
304
306
305 for flips, delay in zip(states, delays):
307 for flips, delay in zip(states, delays):
306 flips.reverse()
308 flips.reverse()
307 flip = int(''.join([str(x) for x in flips]), 2)
309 flip = int(''.join([str(x) for x in flips]), 2)
308 data.append(self.add_data(flip+1))
310 data.extend(self.add_data(flip+1))
309 while delay>252:
311 while delay>252:
310 data.append(self.add_data(1))
312 data.extend(self.add_data(1))
311 delay -= 253
313 delay -= 253
312
314
313 # write sampling period
315 # write sampling period
314 data.append(self.add_cmd('SAMPLING_PERIOD'))
316 data.extend(self.add_cmd('SAMPLING_PERIOD'))
315 wins = self.get_lines(line_type__name='windows')
317 wins = self.get_lines(line_type__name='windows')
316 if wins:
318 if wins:
317 win_params = json.loads(wins[0].params)['params']
319 win_params = json.loads(wins[0].params)['params']
@@ -321,12 +323,16 class RCConfiguration(Configuration):
321 dh = 1
323 dh = 1
322 else:
324 else:
323 dh = 1
325 dh = 1
324 data.append(self.add_data(dh))
326 data.extend(self.add_data(dh))
325
327
326 # write enable
328 # write enable
327 data.append(self.add_cmd('ENABLE'))
329 data.extend(self.add_cmd('ENABLE'))
330
331 if not dat:
332 return data
333
334 return '\n'.join(['{}'.format(x) for x in data])
328
335
329 return '\n'.join(['{}'.format(x) for tup in data for x in tup])
330
336
331 def update_from_file(self, filename):
337 def update_from_file(self, filename):
332 '''
338 '''
@@ -342,7 +348,7 class RCConfiguration(Configuration):
342 for line in self.get_lines():
348 for line in self.get_lines():
343 line.update_pulses()
349 line.update_pulses()
344
350
345 def plot_pulses(self, km=False):
351 def plot_pulses2(self, km=False):
346
352
347 import matplotlib.pyplot as plt
353 import matplotlib.pyplot as plt
348 from bokeh.resources import CDN
354 from bokeh.resources import CDN
@@ -354,7 +360,7 class RCConfiguration(Configuration):
354
360
355 N = len(lines)
361 N = len(lines)
356 npoints = self.total_units/self.km2unit if km else self.total_units
362 npoints = self.total_units/self.km2unit if km else self.total_units
357 fig = plt.figure(figsize=(10, 2+N*0.5))
363 fig = plt.figure(figsize=(12, 2+N*0.5))
358 ax = fig.add_subplot(111)
364 ax = fig.add_subplot(111)
359 labels = ['IPP']
365 labels = ['IPP']
360
366
@@ -377,52 +383,138 class RCConfiguration(Configuration):
377 ax.set_yticks(range(len(labels)))
383 ax.set_yticks(range(len(labels)))
378 ax.set_yticklabels(labels)
384 ax.set_yticklabels(labels)
379 ax.set_xlabel = 'Units'
385 ax.set_xlabel = 'Units'
380 plot = to_bokeh(fig, use_pandas=False)
386 plot = to_bokeh(fig, use_pandas=False)
381 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), SaveTool()]
387 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), SaveTool()]
382 plot.toolbar_location="above"
388 plot.toolbar_location="above"
383
389
384 return components(plot, CDN)
390 return components(plot, CDN)
385
391
386 def status_device(self):
392 def plot_pulses(self, km=False):
387
393
388 return 0
394 from bokeh.plotting import figure
395 from bokeh.resources import CDN
396 from bokeh.embed import components
397 from bokeh.models import FixedTicker, PrintfTickFormatter
398 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
399 from bokeh.models.sources import ColumnDataSource
389
400
390 def stop_device(self):
401 lines = self.get_lines().reverse()
402
403 N = len(lines)
404 npoints = self.total_units/self.km2unit if km else self.total_units
405 ipp = self.ipp if km else self.ipp*self.km2unit
406
407 hover = HoverTool(tooltips=[("Line", "@name"),
408 ("IPP", "@ipp"),
409 ("X", "@left")])
410
411 tools = [PanTool(dimensions=['width']),
412 WheelZoomTool(dimensions=['width']),
413 hover, SaveTool()]
414
415 plot = figure(width=1000,
416 height=40+N*50,
417 y_range = (0, N),
418 tools=tools,
419 toolbar_location='above',
420 toolbar_sticky=False,)
421
422 plot.xaxis.axis_label = 'Km' if km else 'Units'
423 plot.xaxis[0].formatter = PrintfTickFormatter(format='%d')
424 plot.yaxis.axis_label = 'Pulses'
425 plot.yaxis[0].ticker=FixedTicker(ticks=list(range(N)))
426 plot.yaxis[0].formatter = PrintfTickFormatter(format='Line %d')
427
428 for i, line in enumerate(lines):
429
430 points = [tup for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
431
432 source = ColumnDataSource(data = dict(
433 bottom = [i for tup in points],
434 top = [i+0.5 for tup in points],
435 left = [tup[0] for tup in points],
436 right = [tup[1] for tup in points],
437 ipp = [int(tup[0]/ipp) for tup in points],
438 name = [line.get_name() for tup in points]
439 ))
440
441 plot.quad(
442 bottom = 'bottom',
443 top = 'top',
444 left = 'left',
445 right = 'right',
446 source = source,
447 fill_alpha = 0,
448 #line_color = 'blue',
449 )
450
451 plot.line([0, npoints], [i, i])#, color='blue')
452
453 return components(plot, CDN)
391
454
392 answer = api.disable(ip = self.device.ip_address,
455 def status_device(self):
393 port = self.device.port_address)
394
456
395 if answer[0] != "1":
457 try:
396 self.message = answer[0:]
458 req = requests.get(self.device.url)
459 payload = req.json()
460 if payload['status']=='ok':
461 self.device.status = 3
462 else:
463 self.device.status = 1
464 except:
465 self.device.status = 0
466
467 self.device.save()
468
469 return self.device.status
470
471
472 def reset_device(self):
473
474 payload = bytearray()
475 payload.extend(self.add_cmd('RESTART'))
476 data = b64encode(payload)
477 req = requests.put(self.device.url, data)
478
479 if data==req.text.encode('utf8'):
480 return 1
481 else:
397 return 0
482 return 0
483
484 def stop_device(self):
398
485
399 self.message = answer[2:]
486 payload = bytearray()
400 return 1
487 payload.extend(self.add_cmd('DISABLE'))
488 data = b64encode(payload)
489 req = requests.put(self.device.url, data)
490
491 if data==req.text.encode('utf8'):
492 return 1
493 else:
494 return 0
401
495
402 def start_device(self):
496 def start_device(self):
403
497
404 answer = api.enable(ip = self.device.ip_address,
498 payload = bytearray()
405 port = self.device.port_address)
499 payload.extend(self.add_cmd('ENABLE'))
406
500 data = b64encode(payload)
407 if answer[0] != "1":
501 req = requests.put(self.device.url, data)
408 self.message = answer[0:]
502
503 if data==req.text.encode('utf8'):
504 return 1
505 else:
409 return 0
506 return 0
410
507
411 self.message = answer[2:]
412 return 1
413
414 def write_device(self):
508 def write_device(self):
415 answer = api.write_config(ip = self.device.ip_address,
509
416 port = self.device.port_address,
510 data = b64encode(self.parms_to_binary(dat=False))
417 parms = self.parms_to_dict())
511 req = requests.put(self.device.url, data)
418
512 print(req.text)
419 if answer[0] != "1":
513 if data==req.text.encode('utf8'):
420 self.message = answer[0:]
514 return 1
515 else:
421 return 0
516 return 0
422
517
423 self.message = answer[2:]
424 return 1
425
426
518
427 class RCLineCode(models.Model):
519 class RCLineCode(models.Model):
428
520
@@ -550,7 +642,7 class RCLine(models.Model):
550 km2unit = self.rc_configuration.km2unit
642 km2unit = self.rc_configuration.km2unit
551 us2unit = self.rc_configuration.us2unit
643 us2unit = self.rc_configuration.us2unit
552 ipp = self.rc_configuration.ipp
644 ipp = self.rc_configuration.ipp
553 ntx = self.rc_configuration.ntx
645 ntx = int(self.rc_configuration.ntx)
554 ipp_u = int(ipp*km2unit)
646 ipp_u = int(ipp*km2unit)
555 total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units
647 total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units
556 y = []
648 y = []
@@ -7,6 +7,7 urlpatterns = (
7 url(r'^(?P<conf_id>-?\d+)/import/$', views.import_file, name='url_import_rc_conf'),
7 url(r'^(?P<conf_id>-?\d+)/import/$', views.import_file, name='url_import_rc_conf'),
8 url(r'^(?P<conf_id>-?\d+)/edit/$', views.conf_edit, name='url_edit_rc_conf'),
8 url(r'^(?P<conf_id>-?\d+)/edit/$', views.conf_edit, name='url_edit_rc_conf'),
9 url(r'^(?P<conf_id>-?\d+)/plot/$', views.plot_pulses, name='url_plot_rc_pulses'),
9 url(r'^(?P<conf_id>-?\d+)/plot/$', views.plot_pulses, name='url_plot_rc_pulses'),
10 url(r'^(?P<conf_id>-?\d+)/plot2/$', views.plot_pulses2, name='url_plot_rc_pulses'),
10 #url(r'^(?P<id_conf>-?\d+)/write/$', 'apps.main.views.dev_conf_write', name='url_write_rc_conf'),
11 #url(r'^(?P<id_conf>-?\d+)/write/$', 'apps.main.views.dev_conf_write', name='url_write_rc_conf'),
11 #url(r'^(?P<id_conf>-?\d+)/read/$', 'apps.main.views.dev_conf_read', name='url_read_rc_conf'),
12 #url(r'^(?P<id_conf>-?\d+)/read/$', 'apps.main.views.dev_conf_read', name='url_read_rc_conf'),
12
13
@@ -360,7 +360,31 def plot_pulses(request, conf_id):
360 script, div = conf.plot_pulses(km=km)
360 script, div = conf.plot_pulses(km=km)
361
361
362 kwargs = {}
362 kwargs = {}
363 kwargs['no_sidebar'] = True
364 kwargs['title'] = 'RC Pulses'
365 kwargs['suptitle'] = conf.name
366 kwargs['div'] = mark_safe(div)
367 kwargs['script'] = mark_safe(script)
368 kwargs['units'] = conf.km2unit
369 kwargs['kms'] = 1/conf.km2unit
370
371 if km:
372 kwargs['km_selected'] = True
373
374 if 'json' in request.GET:
375 return HttpResponse(json.dumps({'div':mark_safe(div), 'script':mark_safe(script)}), content_type="application/json")
376 else:
377 return render(request, 'rc_pulses.html', kwargs)
378
379 def plot_pulses2(request, conf_id):
363
380
381 conf = get_object_or_404(RCConfiguration, pk=conf_id)
382 km = True if 'km' in request.GET else False
383
384 script, div = conf.plot_pulses2(km=km)
385
386 kwargs = {}
387 kwargs['no_sidebar'] = True
364 kwargs['title'] = 'RC Pulses'
388 kwargs['title'] = 'RC Pulses'
365 kwargs['suptitle'] = conf.name
389 kwargs['suptitle'] = conf.name
366 kwargs['div'] = mark_safe(div)
390 kwargs['div'] = mark_safe(div)
General Comments 0
You need to be logged in to leave comments. Login now