##// 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 from apps.main.models import Device
7 from apps.main.models import Device
8 from apps.main.forms import add_empty_choice
8 from apps.main.forms import add_empty_choice
9 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode
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 def create_choices_from_model(model, conf_id, all=False):
12 def create_choices_from_model(model, conf_id, all=False):
13
13
14 if model=='RCLine':
14 if model=='RCLine':
15 instance = RCConfiguration.objects.get(pk=conf_id)
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 choices = add_empty_choice(choices, label='All')
17 choices = add_empty_choice(choices, label='All')
18 else:
18 else:
19 instance = globals()[model]
19 instance = globals()[model]
@@ -64,7 +64,7 class RCConfigurationForm(forms.ModelForm):
64
64
65 devices = Device.objects.filter(device_type__name='rc')
65 devices = Device.objects.filter(device_type__name='rc')
66 if instance.experiment:
66 if instance.experiment:
67 self.fields['experiment'].widget.attrs['disabled'] = 'disabled'
67 self.fields['experiment'].widget.attrs['read_only'] = True
68 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
68 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
69 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
69 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
70 self.fields['ipp'].widget = KmUnitHzWidget(attrs={'km2unit':instance.km2unit})
70 self.fields['ipp'].widget = KmUnitHzWidget(attrs={'km2unit':instance.km2unit})
@@ -91,7 +91,39 class RCConfigurationForm(forms.ModelForm):
91 self.add_error('ipp', 'Invalid IPP units={}'.format(form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))))
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 return form_data
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 class RCLineForm(forms.ModelForm):
127 class RCLineForm(forms.ModelForm):
96
128
97 def __init__(self, *args, **kwargs):
129 def __init__(self, *args, **kwargs):
@@ -10,6 +10,7 from django.core.urlresolvers import reverse
10 from django.core.validators import MinValueValidator, MaxValueValidator
10 from django.core.validators import MinValueValidator, MaxValueValidator
11
11
12 from apps.main.models import Configuration
12 from apps.main.models import Configuration
13 from devices.rc import api
13 from .utils import RCFile, pulses, pulses_from_code, create_mask, pulses_to_points
14 from .utils import RCFile, pulses, pulses_from_code, create_mask, pulses_to_points
14
15
15 # Create your models here.
16 # Create your models here.
@@ -23,6 +24,7 LINE_TYPES = (
23 ('sync', 'Synchronizing signal'),
24 ('sync', 'Synchronizing signal'),
24 ('flip', 'IPP related periodic signal'),
25 ('flip', 'IPP related periodic signal'),
25 ('prog_pulses', 'Programmable pulse'),
26 ('prog_pulses', 'Programmable pulse'),
27 ('mix', 'Mixed line'),
26 )
28 )
27
29
28
30
@@ -55,23 +57,30 DAT_CMDS = {
55
57
56 class RCConfiguration(Configuration):
58 class RCConfiguration(Configuration):
57
59
58 ipp = models.FloatField(verbose_name='Inter pulse period (Km)', validators=[MinValueValidator(1), MaxValueValidator(1000)], default=10)
60 ipp = models.FloatField(verbose_name='Inter pulse period (Km)', validators=[MinValueValidator(1), MaxValueValidator(9000)], default=300)
59 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
61 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1), MaxValueValidator(300)], default=1)
60 clock_in = models.FloatField(verbose_name='Clock in (MHz)', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
62 clock_in = models.FloatField(verbose_name='Clock in (MHz)', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
61 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
63 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
62 clock = models.FloatField(verbose_name='Clock Master (MHz)', blank=True, default=1)
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)
65 time_before = models.PositiveIntegerField(verbose_name='Time before (μS)', default=12)
64 time_after = models.PositiveIntegerField(verbose_name='Time after (μS)', default=0)
66 time_after = models.PositiveIntegerField(verbose_name='Time after (μS)', default=1)
65 sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
67 sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
66 sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40)
68 sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40)
67 control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False)
69 control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False)
68 control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
70 control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
69
71 mix = models.BooleanField(default=False)
70
72
71 class Meta:
73 class Meta:
72 db_table = 'rc_configurations'
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 def get_absolute_url_plot(self):
84 def get_absolute_url_plot(self):
76 return reverse('url_plot_rc_pulses', args=[str(self.id)])
85 return reverse('url_plot_rc_pulses', args=[str(self.id)])
77
86
@@ -83,13 +92,11 class RCConfiguration(Configuration):
83
92
84 return self.clock_in/self.clock_divider
93 return self.clock_in/self.clock_divider
85
94
86
87 @property
95 @property
88 def km2unit(self):
96 def km2unit(self):
89
97
90 return 20./3*(self.clock_in/self.clock_divider)
98 return 20./3*(self.clock_in/self.clock_divider)
91
99
92
93 def clone(self, **kwargs):
100 def clone(self, **kwargs):
94
101
95 lines = self.get_lines()
102 lines = self.get_lines()
@@ -104,15 +111,13 class RCConfiguration(Configuration):
104
111
105 return self
112 return self
106
113
107 def get_lines(self, type=None):
114 def get_lines(self, **kwargs):
108 '''
115 '''
109 Retrieve configuration lines
116 Retrieve configuration lines
110 '''
117 '''
111
118
112 if type is not None:
119 return RCLine.objects.filter(rc_configuration=self.pk, **kwargs)
113 return RCLine.objects.filter(rc_configuration=self.pk, line_type__name=type)
120
114 else:
115 return RCLine.objects.filter(rc_configuration=self.pk)
116
121
117 def clean_lines(self):
122 def clean_lines(self):
118 '''
123 '''
@@ -146,9 +151,67 class RCConfiguration(Configuration):
146 line_data['type'] = line.line_type.name
151 line_data['type'] = line.line_type.name
147 data['lines'].append(line_data)
152 data['lines'].append(line_data)
148
153
154 data['delays'] = self.get_delays()
155 data['pulses'] = self.get_pulses()
149
156
150 return data
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 def get_delays(self):
215 def get_delays(self):
153
216
154 pulses = [line.get_pulses() for line in self.get_lines()]
217 pulses = [line.get_pulses() for line in self.get_lines()]
@@ -163,14 +226,24 class RCConfiguration(Configuration):
163 return [points[i+1]-points[i] for i in range(len(points)-1)]
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 line_points = [pulses_to_points(line.pulses_as_array()) for line in self.get_lines()]
237 line_points = [pulses_to_points(line.pulses_as_array()) for line in self.get_lines()]
169 line_points = [[(x, x+y) for x,y in tups] for tups in line_points]
238 line_points = [[(x, x+y) for x,y in tups] for tups in line_points]
170 line_points = [[t for x in tups for t in x] for tups in line_points]
239 line_points = [[t for x in tups for t in x] for tups in line_points]
171 states = [[1 if x in tups else 0 for tups in line_points] for x in points]
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 def add_cmd(self, cmd):
248 def add_cmd(self, cmd):
176
249
@@ -210,17 +283,8 class RCConfiguration(Configuration):
210 data.append(self.add_cmd('DELAY_START'))
283 data.append(self.add_cmd('DELAY_START'))
211 # first delay is always zero
284 # first delay is always zero
212 data.append(self.add_data(1))
285 data.append(self.add_data(1))
213 line_points = [pulses_to_points(line.pulses_as_array()) for line in self.get_lines()]
286
214 points = [tup for tups in line_points for tup in tups]
287 delays = self.get_delays()
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)]
224
288
225 for delay in delays:
289 for delay in delays:
226 while delay>252:
290 while delay>252:
@@ -230,10 +294,10 class RCConfiguration(Configuration):
230
294
231 # write flips
295 # write flips
232 data.append(self.add_cmd('FLIP_START'))
296 data.append(self.add_cmd('FLIP_START'))
233 line_points = [[(x, x+y) for x,y in tups] for tups in line_points]
297
234 line_points = [[t for x in tups for t in x] for tups in line_points]
298 states = self.get_pulses(binary=False)
235 states = [[1 if x in tups else 0 for tups in line_points] for x in points]
299
236 for flips, delay in zip(states[:-1], delays):
300 for flips, delay in zip(states, delays):
237 flips.reverse()
301 flips.reverse()
238 flip = int(''.join([str(x) for x in flips]), 2)
302 flip = int(''.join([str(x) for x in flips]), 2)
239 data.append(self.add_data(flip+1))
303 data.append(self.add_data(flip+1))
@@ -243,7 +307,7 class RCConfiguration(Configuration):
243
307
244 # write sampling period
308 # write sampling period
245 data.append(self.add_cmd('SAMPLING_PERIOD'))
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 if wins:
311 if wins:
248 win_params = json.loads(wins[0].params)['params']
312 win_params = json.loads(wins[0].params)['params']
249 if win_params:
313 if win_params:
@@ -265,63 +329,59 class RCConfiguration(Configuration):
265 '''
329 '''
266
330
267 f = RCFile(filename)
331 f = RCFile(filename)
268 data = f.data
332 self.dict_to_parms(f.data)
269 self.name = data['name']
333
270 self.ipp = data['ipp']
334 def update_pulses(self):
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}
283
335
284 for i, line_data in enumerate(data['lines']):
336 for line in self.get_lines():
285 line_type = RCLineType.objects.get(name=line_data.pop('type'))
337 if line.line_type.name=='tr':
286 if line_type.name=='codes':
338 continue
287 code = RCLineCode.objects.get(name=line_data['code'])
339 line.update_pulses()
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()
319
340
320
341 for tr in self.get_lines(line_type__name='tr'):
342 tr.update_pulses()
343
321 def status_device(self):
344 def status_device(self):
322
345
323 return 0
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 class RCLineCode(models.Model):
385 class RCLineCode(models.Model):
326
386
327 name = models.CharField(max_length=40)
387 name = models.CharField(max_length=40)
@@ -336,6 +396,7 class RCLineCode(models.Model):
336 def __unicode__(self):
396 def __unicode__(self):
337 return u'%s' % self.name
397 return u'%s' % self.name
338
398
399
339 class RCLineType(models.Model):
400 class RCLineType(models.Model):
340
401
341 name = models.CharField(choices=LINE_TYPES, max_length=40)
402 name = models.CharField(choices=LINE_TYPES, max_length=40)
@@ -388,29 +449,24 class RCLine(models.Model):
388 return self.line_type.name.upper()
449 return self.line_type.name.upper()
389 pk = json.loads(self.params)['TX_ref']
450 pk = json.loads(self.params)['TX_ref']
390 if pk in (0, '0'):
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 return '%s (%s)' % (self.line_type.name.upper(), refs)
453 return '%s (%s)' % (self.line_type.name.upper(), refs)
393 else:
454 else:
394 ref = RCLine.objects.get(pk=pk)
455 ref = RCLine.objects.get(pk=pk)
395 return '%s (%s)' % (self.line_type.name.upper(), chars[ref.position])
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 return '%s %s' % (self.line_type.name.upper(), self.channel)
458 return '%s %s' % (self.line_type.name.upper(), self.channel)
398 else:
459 else:
399 return self.line_type.name.upper()
460 return self.line_type.name.upper()
400
461
401 def get_lines(self, type=None):
462 def get_lines(self, **kwargs):
402
463
403 if type is not None:
464 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
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
408
465
409 def pulses_as_array(self):
466 def pulses_as_array(self):
410
467
411 return (np.fromstring(self.pulses, dtype=np.uint8)-48).astype(np.int8)
468 return (np.fromstring(self.pulses, dtype=np.uint8)-48).astype(np.int8)
412
469
413
414 def get_pulses(self):
470 def get_pulses(self):
415
471
416 X = self.pulses_as_array()
472 X = self.pulses_as_array()
@@ -432,12 +488,10 class RCLine(models.Model):
432 def get_win_ref(self, params, tx_id, km2unit):
488 def get_win_ref(self, params, tx_id, km2unit):
433
489
434 ref = self.rc_configuration.sampling_reference
490 ref = self.rc_configuration.sampling_reference
435
491 codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
436 codes = [line for line in self.get_lines(type='code') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
492
437
493 if codes:
438 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])
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
441 else:
495 else:
442 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
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 if self.line_type.name=='tr':
518 if self.line_type.name=='tr':
465 params = json.loads(self.params)
519 params = json.loads(self.params)
466 if params['TX_ref'] in ('0', 0):
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 else:
522 else:
469 txs = [tx.update_pulses(save=False, tr=True) for tx in RCLine.objects.filter(pk=params['TX_ref'])]
523 txs = [tx.update_pulses(save=False, tr=True) for tx in RCLine.objects.filter(pk=params['TX_ref'])]
470 if len(txs)==0 or 0 in [len(tx) for tx in txs]:
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 elif self.line_type.name=='codes':
553 elif self.line_type.name=='codes':
500 params = json.loads(self.params)
554 params = json.loads(self.params)
501 #codes = ast.literal_eval(RCLineCode.objects.get(pk=json.loads(self.params)['code']).codes)
502 tx = RCLine.objects.get(pk=params['TX_ref'])
555 tx = RCLine.objects.get(pk=params['TX_ref'])
503 tx_params = json.loads(tx.params)
556 tx_params = json.loads(tx.params)
504
557 delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
505 y = pulses_from_code(ipp_u, ntx, params['codes'],
558 y = pulses_from_code(tx.pulses_as_array(),
506 int(float(tx_params['pulse_width'])*km2unit),
559 params['codes'],
507 before=int(self.rc_configuration.time_before*us2unit)+self.rc_configuration.sync)
560 int(float(tx_params['pulse_width'])*km2unit))
508
561
509 ranges = tx_params['range'].split(',')
562 ranges = tx_params['range'].split(',')
510 if len(ranges)>0 and ranges[0]<>'0':
563 if len(ranges)>0 and ranges[0]<>'0':
@@ -533,20 +586,53 class RCLine(models.Model):
533
586
534 elif self.line_type.name=='windows':
587 elif self.line_type.name=='windows':
535 params = json.loads(self.params)
588 params = json.loads(self.params)
589
536 if 'params' in params and len(params['params'])>0:
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 y = sum([pulses(x, ipp_u, pp['resolution']*pp['number_of_samples']*km2unit,
591 y = sum([pulses(x, ipp_u, pp['resolution']*pp['number_of_samples']*km2unit,
540 shift=0,
592 shift=0,
541 before=int(self.rc_configuration.time_before*us2unit)+self.get_win_ref(pp, params['TX_ref'],km2unit),
593 before=int(self.rc_configuration.time_before*us2unit)+self.get_win_ref(pp, params['TX_ref'],km2unit),
542 sync=self.rc_configuration.sync) for pp in params['params']])
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 ranges = json.loads(tr.params)['range'].split(',')
596 ranges = json.loads(tr.params)['range'].split(',')
545 if len(ranges)>0 and ranges[0]<>'0':
597 if len(ranges)>0 and ranges[0]<>'0':
546 mask = create_mask(ranges, ipp_u, ntx, self.rc_configuration.sync)
598 mask = create_mask(ranges, ipp_u, ntx, self.rc_configuration.sync)
547 y = y & mask
599 y = y & mask
548 else:
600 else:
549 y = np.zeros(ipp_u*ntx)
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 else:
636 else:
551 y = np.zeros(ipp_u*ntx)
637 y = np.zeros(ipp_u*ntx)
552
638
@@ -555,5 +641,5 class RCLine(models.Model):
555 self.save()
641 self.save()
556 else:
642 else:
557 return y
643 return y
558
644
559 No newline at end of file
645
@@ -223,27 +223,28 def pulses_to_points(X):
223 dw += 1
223 dw += 1
224
224
225 return [(tup[0], tup[1]-tup[0]) for tup in zip(up, dw)]
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):
229 d = X[1:]-X[:-1]
231 ipp_codes = [c for __ in xrange(ntx) for c in codes][:ntx]
232 else:
233 ipp_codes = codes[:ntx]
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:
239 y = np.zeros(len(X))
240 sbefore = '{0:0{1}d}'.format(0, before)
241 else:
242 sbefore = ''
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 def create_mask(ranges, ipp, ntx, sync):
250 def create_mask(ranges, ipp, ntx, sync):
@@ -301,10 +302,10 def plot_pulses(unit, maximun, lines):
301 labels = []
302 labels = []
302
303
303 for i, line in enumerate(lines):
304 for i, line in enumerate(lines):
304 print line
305 labels.append(line.get_name())
305 labels.append(line.get_name())
306 l = ax.plot((0, maximun),(N-i-1, N-i-1))
306 ax.broken_barh(pulses_to_points(line.pulses_as_array()), (N-i-1, 0.5),
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 labels.reverse()
310 labels.reverse()
310 ax.set_yticklabels(labels)
311 ax.set_yticklabels(labels)
@@ -117,13 +117,7 def conf_edit(request, conf_id):
117 line.save()
117 line.save()
118
118
119 #update pulses field
119 #update pulses field
120 for line in conf.get_lines():
120 conf.update_pulses()
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()
127
121
128 messages.success(request, 'RC Configuration successfully updated')
122 messages.success(request, 'RC Configuration successfully updated')
129
123
@@ -376,7 +370,7 def view_pulses(request, conf_id):
376
370
377 unit = (conf.clock/conf.clock_divider)*3./20
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 script, div = plot_pulses(unit, N, lines)
375 script, div = plot_pulses(unit, N, lines)
382
376
@@ -1,9 +1,12
1
1
2 import ast
2 import ast
3 import json
3 import json
4 from itertools import chain
4
5
5 from django import forms
6 from django import forms
6 from django.utils.safestring import mark_safe
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 class KmUnitWidget(forms.widgets.TextInput):
12 class KmUnitWidget(forms.widgets.TextInput):
@@ -26,7 +29,7 class KmUnitWidget(forms.widgets.TextInput):
26 if 'line' in attrs:
29 if 'line' in attrs:
27 label += '_{0}'.format(attrs['line'].pk)
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 script = '''<script type="text/javascript">
34 script = '''<script type="text/javascript">
32 $(document).ready(function () {{
35 $(document).ready(function () {{
@@ -162,7 +165,7 class KmUnitDcWidget(forms.widgets.TextInput):
162
165
163 label += '_{0}'.format(attrs['line'].pk)
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 html = '''<div class="col-md-12 col-no-padding">
170 html = '''<div class="col-md-12 col-no-padding">
168 <div class="col-md-3 col-no-padding"><input type="number" {0} class="form-control" id="id_{1}" name="{2}" value="{3}"></div>
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 $("#id_{label}_dc").change(function() {{
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 $("#id_{label}_unit").val(str2unit($("#id_{label}").val()));
195 $("#id_{label}_unit").val(str2unit($("#id_{label}").val()));
193 }});
196 }});
194 }});
197 }});
@@ -242,4 +245,31 class CodesWidget(forms.widgets.Textarea):
242 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)
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 return mark_safe(html)
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 No newline at end of file
275
General Comments 0
You need to be logged in to leave comments. Login now