##// END OF EJS Templates
Update RC app (add support for mix configurations, bug plotting window line, )...
Juan C. Espinoza -
r107:9a3b62311f15
parent child
Show More
@@ -7,13 +7,13 from django.utils.safestring import mark_safe
7 7 from apps.main.models import Device
8 8 from apps.main.forms import add_empty_choice
9 9 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode
10 from .widgets import KmUnitWidget, KmUnitHzWidget, KmUnitDcWidget, UnitKmWidget, DefaultWidget, CodesWidget, HiddenWidget
10 from .widgets import KmUnitWidget, KmUnitHzWidget, KmUnitDcWidget, UnitKmWidget, DefaultWidget, CodesWidget, HiddenWidget, HCheckboxSelectMultiple
11 11
12 12 def create_choices_from_model(model, conf_id, all=False):
13 13
14 14 if model=='RCLine':
15 15 instance = RCConfiguration.objects.get(pk=conf_id)
16 choices = [(line.pk, line.get_name()) for line in instance.get_lines(type='tx')]
16 choices = [(line.pk, line.get_name()) for line in instance.get_lines(line_type__name='tx')]
17 17 choices = add_empty_choice(choices, label='All')
18 18 else:
19 19 instance = globals()[model]
@@ -64,7 +64,7 class RCConfigurationForm(forms.ModelForm):
64 64
65 65 devices = Device.objects.filter(device_type__name='rc')
66 66 if instance.experiment:
67 self.fields['experiment'].widget.attrs['disabled'] = 'disabled'
67 self.fields['experiment'].widget.attrs['read_only'] = True
68 68 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
69 69 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
70 70 self.fields['ipp'].widget = KmUnitHzWidget(attrs={'km2unit':instance.km2unit})
@@ -91,7 +91,39 class RCConfigurationForm(forms.ModelForm):
91 91 self.add_error('ipp', 'Invalid IPP units={}'.format(form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))))
92 92
93 93 return form_data
94
94
95
96 class RCMixConfigurationForm(forms.Form):
97
98 clock_in = forms.CharField(widget=forms.HiddenInput())
99 clock_divider = forms.CharField(widget=forms.HiddenInput())
100 name = forms.CharField()
101 experiment = forms.ChoiceField()
102 operation = forms.ChoiceField(widget=forms.RadioSelect(),
103 choices=[(0, 'OR'), (1, 'XOR'), (2, 'AND'), (3, 'NAND')],
104 initial=1)
105 delay = forms.CharField()
106 mask = forms.MultipleChoiceField(choices=[(0, 'L1'),(1, 'L2'),(2, 'L3'),(3, 'L4'),(4, 'L5'),(5, 'L6'),(6, 'L7'),(7, 'L8')],
107 widget=HCheckboxSelectMultiple())
108 result = forms.CharField(required=False,
109 widget=forms.Textarea(attrs={'readonly':True, 'rows':5, 'class':'tabuled'}))
110
111 def __init__(self, *args, **kwargs):
112 confs = kwargs.pop('confs', [])
113 if confs:
114 km2unit = confs[0].km2unit
115 clock_in = confs[0].clock_in
116 clock_divider = confs[0].clock_divider
117 else:
118 km2unit = clock_in = clock_divider = 0
119 super(RCMixConfigurationForm, self).__init__(*args, **kwargs)
120 self.fields['experiment'].choices = [(conf.pk, '{} | {}'.format(conf.pk, conf.name)) for conf in confs]
121 self.fields['delay'].widget = KmUnitWidget(attrs = {'km2unit':km2unit})
122 self.fields['clock_in'].initial = clock_in
123 self.fields['clock_divider'].initial = clock_divider
124
125
126
95 127 class RCLineForm(forms.ModelForm):
96 128
97 129 def __init__(self, *args, **kwargs):
@@ -10,6 +10,7 from django.core.urlresolvers import reverse
10 10 from django.core.validators import MinValueValidator, MaxValueValidator
11 11
12 12 from apps.main.models import Configuration
13 from devices.rc import api
13 14 from .utils import RCFile, pulses, pulses_from_code, create_mask, pulses_to_points
14 15
15 16 # Create your models here.
@@ -23,6 +24,7 LINE_TYPES = (
23 24 ('sync', 'Synchronizing signal'),
24 25 ('flip', 'IPP related periodic signal'),
25 26 ('prog_pulses', 'Programmable pulse'),
27 ('mix', 'Mixed line'),
26 28 )
27 29
28 30
@@ -55,23 +57,30 DAT_CMDS = {
55 57
56 58 class RCConfiguration(Configuration):
57 59
58 ipp = models.FloatField(verbose_name='Inter pulse period (Km)', validators=[MinValueValidator(1), MaxValueValidator(1000)], default=10)
59 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
60 ipp = models.FloatField(verbose_name='Inter pulse period (Km)', validators=[MinValueValidator(1), MaxValueValidator(9000)], default=300)
61 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1), MaxValueValidator(300)], default=1)
60 62 clock_in = models.FloatField(verbose_name='Clock in (MHz)', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
61 63 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
62 64 clock = models.FloatField(verbose_name='Clock Master (MHz)', blank=True, default=1)
63 time_before = models.PositiveIntegerField(verbose_name='Time before (μS)', default=0)
64 time_after = models.PositiveIntegerField(verbose_name='Time after (μS)', default=0)
65 time_before = models.PositiveIntegerField(verbose_name='Time before (μS)', default=12)
66 time_after = models.PositiveIntegerField(verbose_name='Time after (μS)', default=1)
65 67 sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
66 68 sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40)
67 69 control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False)
68 70 control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
69
71 mix = models.BooleanField(default=False)
70 72
71 73 class Meta:
72 74 db_table = 'rc_configurations'
73 75
74 76
77 def __unicode__(self):
78
79 if self.mix:
80 return u'[MIXED]: %s' % self.name
81 else:
82 return u'[%s]: %s' % (self.device.name, self.name)
83
75 84 def get_absolute_url_plot(self):
76 85 return reverse('url_plot_rc_pulses', args=[str(self.id)])
77 86
@@ -83,13 +92,11 class RCConfiguration(Configuration):
83 92
84 93 return self.clock_in/self.clock_divider
85 94
86
87 95 @property
88 96 def km2unit(self):
89 97
90 98 return 20./3*(self.clock_in/self.clock_divider)
91 99
92
93 100 def clone(self, **kwargs):
94 101
95 102 lines = self.get_lines()
@@ -104,15 +111,13 class RCConfiguration(Configuration):
104 111
105 112 return self
106 113
107 def get_lines(self, type=None):
114 def get_lines(self, **kwargs):
108 115 '''
109 116 Retrieve configuration lines
110 117 '''
111 118
112 if type is not None:
113 return RCLine.objects.filter(rc_configuration=self.pk, line_type__name=type)
114 else:
115 return RCLine.objects.filter(rc_configuration=self.pk)
119 return RCLine.objects.filter(rc_configuration=self.pk, **kwargs)
120
116 121
117 122 def clean_lines(self):
118 123 '''
@@ -146,9 +151,67 class RCConfiguration(Configuration):
146 151 line_data['type'] = line.line_type.name
147 152 data['lines'].append(line_data)
148 153
154 data['delays'] = self.get_delays()
155 data['pulses'] = self.get_pulses()
149 156
150 157 return data
151 158
159 def dict_to_parms(self, data):
160 '''
161 '''
162
163 self.name = data['name']
164 self.ipp = data['ipp']
165 self.ntx = data['ntx']
166 self.clock_in = data['clock_in']
167 self.clock_divider = data['clock_divider']
168 self.clock = data['clock']
169 self.time_before = data['time_before']
170 self.time_after = data['time_after']
171 self.sync = data['sync']
172 self.sampling_reference = data['sampling_reference']
173 self.clean_lines()
174
175 lines = []
176 positions = {'tx':0, 'tr':0}
177
178 for i, line_data in enumerate(data['lines']):
179 line_type = RCLineType.objects.get(name=line_data.pop('type'))
180 if line_type.name=='codes':
181 code = RCLineCode.objects.get(name=line_data['code'])
182 line_data['code'] = code.pk
183 line = RCLine.objects.filter(rc_configuration=self, channel=i)
184 if line:
185 line = line[0]
186 line.line_type = line_type
187 line.params = json.dumps(line_data)
188 else:
189 line = RCLine(rc_configuration=self, line_type=line_type,
190 params=json.dumps(line_data),
191 channel=i)
192
193 if line_type.name=='tx':
194 line.position = positions['tx']
195 positions['tx'] += 1
196
197 if line_type.name=='tr':
198 line.position = positions['tr']
199 positions['tr'] += 1
200
201 line.save()
202 lines.append(line)
203
204 for line, line_data in zip(lines, data['lines']):
205 if 'TX_ref' in line_data:
206 params = json.loads(line.params)
207 if line_data['TX_ref'] in (0, '0'):
208 params['TX_ref'] = '0'
209 else:
210 params['TX_ref'] = [l.pk for l in lines if l.line_type.name=='tx' and l.get_name()==line_data['TX_ref']][0]
211 line.params = json.dumps(params)
212 line.save()
213
214
152 215 def get_delays(self):
153 216
154 217 pulses = [line.get_pulses() for line in self.get_lines()]
@@ -163,14 +226,24 class RCConfiguration(Configuration):
163 226 return [points[i+1]-points[i] for i in range(len(points)-1)]
164 227
165 228
166 def get_flips(self):
229 def get_pulses(self, binary=True):
230
231 pulses = [line.get_pulses() for line in self.get_lines()]
232 points = [tup for tups in pulses for tup in tups]
233 points = set([x for tup in points for x in tup])
234 points = list(points)
235 points.sort()
167 236
168 237 line_points = [pulses_to_points(line.pulses_as_array()) for line in self.get_lines()]
169 238 line_points = [[(x, x+y) for x,y in tups] for tups in line_points]
170 239 line_points = [[t for x in tups for t in x] for tups in line_points]
171 240 states = [[1 if x in tups else 0 for tups in line_points] for x in points]
172 241
173 return states
242 if binary:
243 states.reverse()
244 states = [int(''.join([str(x) for x in flips]), 2) for flips in states]
245
246 return states[:-1]
174 247
175 248 def add_cmd(self, cmd):
176 249
@@ -210,17 +283,8 class RCConfiguration(Configuration):
210 283 data.append(self.add_cmd('DELAY_START'))
211 284 # first delay is always zero
212 285 data.append(self.add_data(1))
213 line_points = [pulses_to_points(line.pulses_as_array()) for line in self.get_lines()]
214 points = [tup for tups in line_points for tup in tups]
215 points = [(x, x+y) for x,y in points]
216 points = set([x for tup in points for x in tup])
217 points = list(points)
218 points.sort()
219
220 if points[0]<>0:
221 points.insert(0, 0)
222
223 delays = [points[i+1]-points[i] for i in range(len(points)-1)]
286
287 delays = self.get_delays()
224 288
225 289 for delay in delays:
226 290 while delay>252:
@@ -230,10 +294,10 class RCConfiguration(Configuration):
230 294
231 295 # write flips
232 296 data.append(self.add_cmd('FLIP_START'))
233 line_points = [[(x, x+y) for x,y in tups] for tups in line_points]
234 line_points = [[t for x in tups for t in x] for tups in line_points]
235 states = [[1 if x in tups else 0 for tups in line_points] for x in points]
236 for flips, delay in zip(states[:-1], delays):
297
298 states = self.get_pulses(binary=False)
299
300 for flips, delay in zip(states, delays):
237 301 flips.reverse()
238 302 flip = int(''.join([str(x) for x in flips]), 2)
239 303 data.append(self.add_data(flip+1))
@@ -243,7 +307,7 class RCConfiguration(Configuration):
243 307
244 308 # write sampling period
245 309 data.append(self.add_cmd('SAMPLING_PERIOD'))
246 wins = self.get_lines(type='windows')
310 wins = self.get_lines(line_type__name='windows')
247 311 if wins:
248 312 win_params = json.loads(wins[0].params)['params']
249 313 if win_params:
@@ -265,63 +329,59 class RCConfiguration(Configuration):
265 329 '''
266 330
267 331 f = RCFile(filename)
268 data = f.data
269 self.name = data['name']
270 self.ipp = data['ipp']
271 self.ntx = data['ntx']
272 self.clock_in = data['clock_in']
273 self.clock_divider = data['clock_divider']
274 self.clock = data['clock']
275 self.time_before = data['time_before']
276 self.time_after = data['time_after']
277 self.sync = data['sync']
278 self.sampling_reference = data['sampling_reference']
279 self.clean_lines()
280
281 lines = []
282 positions = {'tx':0, 'tr':0}
332 self.dict_to_parms(f.data)
333
334 def update_pulses(self):
283 335
284 for i, line_data in enumerate(data['lines']):
285 line_type = RCLineType.objects.get(name=line_data.pop('type'))
286 if line_type.name=='codes':
287 code = RCLineCode.objects.get(name=line_data['code'])
288 line_data['code'] = code.pk
289 line = RCLine.objects.filter(rc_configuration=self, channel=i)
290 if line:
291 line = line[0]
292 line.line_type = line_type
293 line.params = json.dumps(line_data)
294 else:
295 line = RCLine(rc_configuration=self, line_type=line_type,
296 params=json.dumps(line_data),
297 channel=i)
298
299 if line_type.name=='tx':
300 line.position = positions['tx']
301 positions['tx'] += 1
302
303 if line_type.name=='tr':
304 line.position = positions['tr']
305 positions['tr'] += 1
306
307 line.save()
308 lines.append(line)
309
310 for line, line_data in zip(lines, data['lines']):
311 if 'TX_ref' in line_data:
312 params = json.loads(line.params)
313 if line_data['TX_ref'] in (0, '0'):
314 params['TX_ref'] = '0'
315 else:
316 params['TX_ref'] = [l.pk for l in lines if l.line_type.name=='tx' and l.get_name()==line_data['TX_ref']][0]
317 line.params = json.dumps(params)
318 line.save()
336 for line in self.get_lines():
337 if line.line_type.name=='tr':
338 continue
339 line.update_pulses()
319 340
320
341 for tr in self.get_lines(line_type__name='tr'):
342 tr.update_pulses()
343
321 344 def status_device(self):
322 345
323 346 return 0
324 347
348 def stop_device(self):
349
350 answer = api.disable(ip = self.device.ip_address,
351 port = self.device.port_address)
352
353 if answer[0] != "1":
354 self.message = answer[0:]
355 return 0
356
357 self.message = answer[2:]
358 return 1
359
360 def start_device(self):
361
362 answer = api.enable(ip = self.device.ip_address,
363 port = self.device.port_address)
364
365 if answer[0] != "1":
366 self.message = answer[0:]
367 return 0
368
369 self.message = answer[2:]
370 return 1
371
372 def write_device(self):
373 answer = api.write_config(ip = self.device.ip_address,
374 port = self.device.port_address,
375 parms = self.parms_to_dict())
376
377 if answer[0] != "1":
378 self.message = answer[0:]
379 return 0
380
381 self.message = answer[2:]
382 return 1
383
384
325 385 class RCLineCode(models.Model):
326 386
327 387 name = models.CharField(max_length=40)
@@ -336,6 +396,7 class RCLineCode(models.Model):
336 396 def __unicode__(self):
337 397 return u'%s' % self.name
338 398
399
339 400 class RCLineType(models.Model):
340 401
341 402 name = models.CharField(choices=LINE_TYPES, max_length=40)
@@ -388,29 +449,24 class RCLine(models.Model):
388 449 return self.line_type.name.upper()
389 450 pk = json.loads(self.params)['TX_ref']
390 451 if pk in (0, '0'):
391 refs = ','.join(chars[l.position] for l in self.rc_configuration.get_lines('tx'))
452 refs = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
392 453 return '%s (%s)' % (self.line_type.name.upper(), refs)
393 454 else:
394 455 ref = RCLine.objects.get(pk=pk)
395 456 return '%s (%s)' % (self.line_type.name.upper(), chars[ref.position])
396 elif self.line_type.name in ('flip', 'prog_pulses', 'sync', 'none'):
457 elif self.line_type.name in ('flip', 'prog_pulses', 'sync', 'none', 'mix'):
397 458 return '%s %s' % (self.line_type.name.upper(), self.channel)
398 459 else:
399 460 return self.line_type.name.upper()
400 461
401 def get_lines(self, type=None):
402
403 if type is not None:
404 return RCLine.objects.filter(rc_configuration=self.rc_configuration, line_type__name=type)
405 else:
406 return RCLine.objects.filter(rc_configuration=self.rc_configuration)
407
462 def get_lines(self, **kwargs):
463
464 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
408 465
409 466 def pulses_as_array(self):
410 467
411 468 return (np.fromstring(self.pulses, dtype=np.uint8)-48).astype(np.int8)
412 469
413
414 470 def get_pulses(self):
415 471
416 472 X = self.pulses_as_array()
@@ -432,12 +488,10 class RCLine(models.Model):
432 488 def get_win_ref(self, params, tx_id, km2unit):
433 489
434 490 ref = self.rc_configuration.sampling_reference
435
436 codes = [line for line in self.get_lines(type='code') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
437
438 if codes:
439 code_line = RCLineCode.objects.get(pk=json.loads(codes[0].params)['code'])
440 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/code_line.bits_per_code
491 codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
492
493 if codes:
494 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/len(json.loads(codes[0].params)['codes'][0])
441 495 else:
442 496 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
443 497
@@ -464,7 +518,7 class RCLine(models.Model):
464 518 if self.line_type.name=='tr':
465 519 params = json.loads(self.params)
466 520 if params['TX_ref'] in ('0', 0):
467 txs = [tx.update_pulses(save=False, tr=True) for tx in self.get_lines('tx')]
521 txs = [tx.update_pulses(save=False, tr=True) for tx in self.get_lines(line_type__name='tx')]
468 522 else:
469 523 txs = [tx.update_pulses(save=False, tr=True) for tx in RCLine.objects.filter(pk=params['TX_ref'])]
470 524 if len(txs)==0 or 0 in [len(tx) for tx in txs]:
@@ -498,13 +552,12 class RCLine(models.Model):
498 552
499 553 elif self.line_type.name=='codes':
500 554 params = json.loads(self.params)
501 #codes = ast.literal_eval(RCLineCode.objects.get(pk=json.loads(self.params)['code']).codes)
502 555 tx = RCLine.objects.get(pk=params['TX_ref'])
503 556 tx_params = json.loads(tx.params)
504
505 y = pulses_from_code(ipp_u, ntx, params['codes'],
506 int(float(tx_params['pulse_width'])*km2unit),
507 before=int(self.rc_configuration.time_before*us2unit)+self.rc_configuration.sync)
557 delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
558 y = pulses_from_code(tx.pulses_as_array(),
559 params['codes'],
560 int(float(tx_params['pulse_width'])*km2unit))
508 561
509 562 ranges = tx_params['range'].split(',')
510 563 if len(ranges)>0 and ranges[0]<>'0':
@@ -533,20 +586,53 class RCLine(models.Model):
533 586
534 587 elif self.line_type.name=='windows':
535 588 params = json.loads(self.params)
589
536 590 if 'params' in params and len(params['params'])>0:
537 print 'REFS'
538 print [self.get_win_ref(pp, params['TX_ref'],km2unit) for pp in params['params']]
539 591 y = sum([pulses(x, ipp_u, pp['resolution']*pp['number_of_samples']*km2unit,
540 592 shift=0,
541 593 before=int(self.rc_configuration.time_before*us2unit)+self.get_win_ref(pp, params['TX_ref'],km2unit),
542 594 sync=self.rc_configuration.sync) for pp in params['params']])
543 tr = self.get_lines('tr')[0]
595 tr = self.get_lines(line_type__name='tr')[0]
544 596 ranges = json.loads(tr.params)['range'].split(',')
545 597 if len(ranges)>0 and ranges[0]<>'0':
546 598 mask = create_mask(ranges, ipp_u, ntx, self.rc_configuration.sync)
547 599 y = y & mask
548 600 else:
549 601 y = np.zeros(ipp_u*ntx)
602
603 elif self.line_type.name=='mix':
604 values = self.rc_configuration.parameters.split('-')
605 confs = RCConfiguration.objects.filter(pk__in=[value.split('|')[0] for value in values])
606 modes = [value.split('|')[1] for value in values]
607 delays = [value.split('|')[2] for value in values]
608 masks = [value.split('|')[3] for value in values]
609
610 y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
611
612 for i in range(1, len(values)):
613 mask = list('{:8b}'.format(int(masks[i])))
614 mask.reverse()
615
616 if mask[self.channel] in ('0', '', ' '):
617 continue
618 Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
619 delay = float(delays[i])*km2unit
620 if delay>0:
621 y_temp = np.empty_like(Y)
622 y_temp[:delay] = 0
623 y_temp[delay:] = Y[:-delay]
624
625 if modes[i]=='OR':
626 y2 = y | y_temp
627 elif modes[i]=='XOR':
628 y2 = y ^ y_temp
629 elif modes[i]=='AND':
630 y2 = y & y_temp
631 elif modes[i]=='NAND':
632 y2 = y & ~y_temp
633
634 y = y2
635
550 636 else:
551 637 y = np.zeros(ipp_u*ntx)
552 638
@@ -555,5 +641,5 class RCLine(models.Model):
555 641 self.save()
556 642 else:
557 643 return y
558
644
559 645 No newline at end of file
@@ -223,27 +223,28 def pulses_to_points(X):
223 223 dw += 1
224 224
225 225 return [(tup[0], tup[1]-tup[0]) for tup in zip(up, dw)]
226
227 226
228 def pulses_from_code(ipp, ntx, codes, width, before=0):
227 def pulses_from_code(X, codes, width):
229 228
230 if ntx>len(codes):
231 ipp_codes = [c for __ in xrange(ntx) for c in codes][:ntx]
232 else:
233 ipp_codes = codes[:ntx]
229 d = X[1:]-X[:-1]
234 230
235 f = width/len(codes[0])
231 up = np.where(d==1)[0]
232 if X[0]==1:
233 up = np.concatenate((np.array([-1]), up))
234 up += 1
236 235
237 ipp_codes = [''.join([s*f for s in code]) for code in ipp_codes]
236 f = width/len(codes[0])
237 codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in codes]
238 238
239 if before>0:
240 sbefore = '{0:0{1}d}'.format(0, before)
241 else:
242 sbefore = ''
239 y = np.zeros(len(X))
243 240
244 temp = ['{0}{1}{2:0{3}d}'.format(sbefore, ipp_codes[i], 0, int(ipp)-len(ipp_codes[i])-before) for i in range(ntx)]
241 j=0
242 n = len(codes)
243 for i in up:
244 y[i:i+width] = codes[j%n]
245 j += 1
245 246
246 return (np.fromstring(''.join(temp), dtype=np.uint8)-48).astype(np.int8)
247 return y
247 248
248 249
249 250 def create_mask(ranges, ipp, ntx, sync):
@@ -301,10 +302,10 def plot_pulses(unit, maximun, lines):
301 302 labels = []
302 303
303 304 for i, line in enumerate(lines):
304 print line
305 305 labels.append(line.get_name())
306 l = ax.plot((0, maximun),(N-i-1, N-i-1))
306 307 ax.broken_barh(pulses_to_points(line.pulses_as_array()), (N-i-1, 0.5),
307 edgecolor='none', facecolor='#2c3e50')
308 edgecolor=l[0].get_color(), facecolor='none')
308 309
309 310 labels.reverse()
310 311 ax.set_yticklabels(labels)
@@ -117,13 +117,7 def conf_edit(request, conf_id):
117 117 line.save()
118 118
119 119 #update pulses field
120 for line in conf.get_lines():
121 if line.line_type.name=='tr':
122 continue
123 line.update_pulses()
124
125 for tr in conf.get_lines('tr'):
126 tr.update_pulses()
120 conf.update_pulses()
127 121
128 122 messages.success(request, 'RC Configuration successfully updated')
129 123
@@ -376,7 +370,7 def view_pulses(request, conf_id):
376 370
377 371 unit = (conf.clock/conf.clock_divider)*3./20
378 372
379 N = int(conf.ipp*(conf.clock/conf.clock_divider)*20./3)*conf.ntx
373 N = conf.ipp*conf.km2unit*conf.ntx
380 374
381 375 script, div = plot_pulses(unit, N, lines)
382 376
@@ -1,9 +1,12
1 1
2 2 import ast
3 3 import json
4 from itertools import chain
4 5
5 6 from django import forms
6 7 from django.utils.safestring import mark_safe
8 from django.utils.encoding import force_unicode
9 from django.utils.html import conditional_escape
7 10
8 11
9 12 class KmUnitWidget(forms.widgets.TextInput):
@@ -26,7 +29,7 class KmUnitWidget(forms.widgets.TextInput):
26 29 if 'line' in attrs:
27 30 label += '_{0}'.format(attrs['line'].pk)
28 31
29 html = '<div class="col-md-12 col-no-padding"><div class="col-md-5 col-no-padding"><input type="text" {0} class="form-control" id="id_{1}" name="{2}" value="{3}"></div><div class="col-md-1 col-no-padding">Km</div><div class="col-md-5 col-no-padding"><input type="text" {4} class="form-control" id="id_{5}_unit" value="{6}"></div><div class="col-md-1 col-no-padding">Units</div></div>'.format(disabled, label, name, value, disabled, label, unit)
32 html = '<div class="col-md-12 col-no-padding"><div class="col-md-5 col-no-padding"><input type="text" {0} class="form-control" id="id_{1}" name="{2}" value="{3}"></div><div class="col-md-1 col-no-padding">Km</div><div class="col-md-5 col-no-padding"><input type="text" {4} class="form-control" id="id_{5}_unit" value="{6}"></div><div class="col-md-1 col-no-padding">Units</div></div><br>'.format(disabled, label, name, value, disabled, label, unit)
30 33
31 34 script = '''<script type="text/javascript">
32 35 $(document).ready(function () {{
@@ -162,7 +165,7 class KmUnitDcWidget(forms.widgets.TextInput):
162 165
163 166 label += '_{0}'.format(attrs['line'].pk)
164 167
165 dc = float(json.loads(attrs['line'].params)['pulse_width'])*attrs['line'].rc_configuration.ipp/100
168 dc = float(json.loads(attrs['line'].params)['pulse_width'])*100/attrs['line'].rc_configuration.ipp
166 169
167 170 html = '''<div class="col-md-12 col-no-padding">
168 171 <div class="col-md-3 col-no-padding"><input type="number" {0} class="form-control" id="id_{1}" name="{2}" value="{3}"></div>
@@ -188,7 +191,7 class KmUnitDcWidget(forms.widgets.TextInput):
188 191 }});
189 192
190 193 $("#id_{label}_dc").change(function() {{
191 $("#id_{label}").val(parseFloat($(this).val())*parseFloat($("#id_ipp").val())/100);
194 $("#id_{label}").val(parseFloat($(this).val())*100/parseFloat($("#id_ipp").val()));
192 195 $("#id_{label}_unit").val(str2unit($("#id_{label}").val()));
193 196 }});
194 197 }});
@@ -242,4 +245,31 class CodesWidget(forms.widgets.Textarea):
242 245 html = '<textarea rows="5" {0} class="form-control" id="id_{1}" name="{2}" style="white-space:nowrap; overflow:scroll;">{3}</textarea>'.format(disabled, label, name, codes)
243 246
244 247 return mark_safe(html)
248
249 class HCheckboxSelectMultiple(forms.CheckboxSelectMultiple):
250
251 def render(self, name, value, attrs=None, choices=()):
252
253 if value is None: value = []
254 has_id = attrs and 'id' in attrs
255 final_attrs = self.build_attrs(attrs, name=name)
256 output = [u'<br><ul>']
257 # Normalize to strings
258 str_values = set([force_unicode(v) for v in value])
259 for i, (option_value, option_label) in enumerate(chain(self.choices, choices)):
260 # If an ID attribute was given, add a numeric index as a suffix,
261 # so that the checkboxes don't all have the same ID attribute.
262 if has_id:
263 final_attrs = dict(final_attrs, id='%s_%s' % (attrs['id'], i))
264 label_for = u' for="%s"' % final_attrs['id']
265 else:
266 label_for = ''
267
268 cb = forms.CheckboxInput(final_attrs, check_test=lambda value: value in str_values)
269 option_value = force_unicode(option_value)
270 rendered_cb = cb.render(name, option_value)
271 option_label = conditional_escape(force_unicode(option_label))
272 output.append(u'<span><label%s>%s %s</label></span>' % (label_for, rendered_cb, option_label))
273 output.append(u'</div><br>')
274 return mark_safe(u'\n'.join(output))
245 275 No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now