##// END OF EJS Templates
update rc/models.py to last version:...
jrojas -
r418:d19764ba5024 ver_3Julio
parent child
Show More
@@ -1,1107 +1,1107
1
1
2
2
3 import ast
3 import ast
4 import json
4 import json
5 import requests
5 import requests
6 import numpy as np
6 import numpy as np
7 from base64 import b64encode
7 from base64 import b64encode
8 from struct import pack
8 from struct import pack
9
9
10 from django.db import models
10 from django.db import models
11 from django.urls import reverse
11 from django.urls import reverse
12 from django.core.validators import MinValueValidator, MaxValueValidator
12 from django.core.validators import MinValueValidator, MaxValueValidator
13
13
14 from apps.main.models import Configuration
14 from apps.main.models import Configuration
15 from apps.main.utils import Params
15 from apps.main.utils import Params
16 from devices.rc import api
16 from devices.rc import api
17 from apps.rc.utils import RCFile
17 from apps.rc.utils import RCFile
18
18
19
19
20 LINE_TYPES = (
20 LINE_TYPES = (
21 ('none', 'Not used'),
21 ('none', 'Not used'),
22 ('tr', 'Transmission/reception selector signal'),
22 ('tr', 'Transmission/reception selector signal'),
23 ('tx', 'A modulating signal (Transmission pulse)'),
23 ('tx', 'A modulating signal (Transmission pulse)'),
24 ('codes', 'BPSK modulating signal'),
24 ('codes', 'BPSK modulating signal'),
25 ('windows', 'Sample window signal'),
25 ('windows', 'Sample window signal'),
26 ('sync', 'Synchronizing signal'),
26 ('sync', 'Synchronizing signal'),
27 ('flip', 'IPP related periodic signal'),
27 ('flip', 'IPP related periodic signal'),
28 ('prog_pulses', 'Programmable pulse'),
28 ('prog_pulses', 'Programmable pulse'),
29 ('mix', 'Mixed line'),
29 ('mix', 'Mixed line'),
30 )
30 )
31
31
32
32
33 SAMPLING_REFS = (
33 SAMPLING_REFS = (
34 ('none', 'No Reference'),
34 ('none', 'No Reference'),
35 ('begin_baud', 'Begin of the first baud'),
35 ('begin_baud', 'Begin of the first baud'),
36 ('first_baud', 'Middle of the first baud'),
36 ('first_baud', 'Middle of the first baud'),
37 ('sub_baud', 'Middle of the sub-baud')
37 ('sub_baud', 'Middle of the sub-baud')
38 )
38 )
39
39
40 DAT_CMDS = {
40 DAT_CMDS = {
41 # Pulse Design commands
41 # Pulse Design commands
42 'DISABLE' : 0, # Disables pulse generation
42 'DISABLE' : 0, # Disables pulse generation
43 'ENABLE' : 24, # Enables pulse generation
43 'ENABLE' : 24, # Enables pulse generation
44 'DELAY_START' : 40, # Write delay status to memory
44 'DELAY_START' : 40, # Write delay status to memory
45 'FLIP_START' : 48, # Write flip status to memory
45 'FLIP_START' : 48, # Write flip status to memory
46 'SAMPLING_PERIOD' : 64, # Establish Sampling Period
46 'SAMPLING_PERIOD' : 64, # Establish Sampling Period
47 'TX_ONE' : 72, # Output '0' in line TX
47 'TX_ONE' : 72, # Output '0' in line TX
48 'TX_ZERO' : 88, # Output '0' in line TX
48 'TX_ZERO' : 88, # Output '0' in line TX
49 'SW_ONE' : 104, # Output '0' in line SW
49 'SW_ONE' : 104, # Output '0' in line SW
50 'SW_ZERO' : 112, # Output '1' in line SW
50 'SW_ZERO' : 112, # Output '1' in line SW
51 'RESTART': 120, # Restarts CR8 Firmware
51 'RESTART': 120, # Restarts CR8 Firmware
52 'CONTINUE' : 253, # Function Unknown
52 'CONTINUE' : 253, # Function Unknown
53 # Commands available to new controllers
53 # Commands available to new controllers
54 # 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 # 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.
55 'CLOCK_DIVISOR_INIT' : 12, # Specifies Clock Divisor. Legacy command, ignored in the actual .dat conversion
55 'CLOCK_DIVISOR_INIT' : 12, # Specifies Clock Divisor. Legacy command, ignored in the actual .dat conversion
56 'CLOCK_DIVISOR_LAST' : 22, # Specifies Clock Divisor (default 60 if not included) syntax: 255,22 254,N-1.
56 'CLOCK_DIVISOR_LAST' : 22, # Specifies Clock Divisor (default 60 if not included) syntax: 255,22 254,N-1.
57 'CLOCK_DIVIDER' : 8,
57 'CLOCK_DIVIDER' : 8,
58 }
58 }
59
59
60 MAX_BITS = 8
60 MAX_BITS = 8
61
61
62 # Rotate left: 0b1001 --> 0b0011
62 # Rotate left: 0b1001 --> 0b0011
63 rol = lambda val, r_bits: \
63 rol = lambda val, r_bits: \
64 (val << r_bits%MAX_BITS) & (2**MAX_BITS-1) | \
64 (val << r_bits%MAX_BITS) & (2**MAX_BITS-1) | \
65 ((val & (2**MAX_BITS-1)) >> (MAX_BITS-(r_bits%MAX_BITS)))
65 ((val & (2**MAX_BITS-1)) >> (MAX_BITS-(r_bits%MAX_BITS)))
66
66
67 # Rotate right: 0b1001 --> 0b1100
67 # Rotate right: 0b1001 --> 0b1100
68 ror = lambda val, r_bits: \
68 ror = lambda val, r_bits: \
69 ((val & (2**MAX_BITS-1)) >> r_bits%MAX_BITS) | \
69 ((val & (2**MAX_BITS-1)) >> r_bits%MAX_BITS) | \
70 (val << (MAX_BITS-(r_bits%MAX_BITS)) & (2**MAX_BITS-1))
70 (val << (MAX_BITS-(r_bits%MAX_BITS)) & (2**MAX_BITS-1))
71
71
72
72
73 class RCConfiguration(Configuration):
73 class RCConfiguration(Configuration):
74
74
75 ipp = models.FloatField(verbose_name='IPP [Km]', validators=[MinValueValidator(1)], default=300)
75 ipp = models.FloatField(verbose_name='IPP [Km]', validators=[MinValueValidator(1)], default=300)
76 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1)], default=1)
76 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1)], default=1)
77 clock_in = models.FloatField(verbose_name='Clock in [MHz]', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
77 clock_in = models.FloatField(verbose_name='Clock in [MHz]', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
78 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
78 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
79 clock = models.FloatField(verbose_name='Clock Master [MHz]', blank=True, default=1)
79 clock = models.FloatField(verbose_name='Clock Master [MHz]', blank=True, default=1)
80 time_before = models.PositiveIntegerField(verbose_name='Time before [&mu;S]', default=12)
80 time_before = models.PositiveIntegerField(verbose_name='Time before [&mu;S]', default=12)
81 time_after = models.PositiveIntegerField(verbose_name='Time after [&mu;S]', default=1)
81 time_after = models.PositiveIntegerField(verbose_name='Time after [&mu;S]', default=1)
82 sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
82 sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
83 ch_monitor = models.PositiveIntegerField(verbose_name='Channel Monitor', validators=[MinValueValidator(0), MaxValueValidator(15)], default=6)
83 sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40)
84 sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40)
84 control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False)
85 control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False)
85 control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
86 control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
86 total_units = models.PositiveIntegerField(default=0)
87 total_units = models.PositiveIntegerField(default=0)
87 mix = models.BooleanField(default=False)
88 mix = models.BooleanField(default=False)
88
89
89 class Meta:
90 class Meta:
90 db_table = 'rc_configurations'
91 db_table = 'rc_configurations'
91
92
92 def get_absolute_url_plot(self):
93 def get_absolute_url_plot(self):
93 return reverse('url_plot_rc_pulses', args=[str(self.id)])
94 return reverse('url_plot_rc_pulses', args=[str(self.id)])
94
95
95 @property
96 @property
96 def ipp_unit(self):
97 def ipp_unit(self):
97
98
98 return '{} ({})'.format(self.ipp, int(self.ipp*self.km2unit))
99 return '{} ({})'.format(self.ipp, int(self.ipp*self.km2unit))
99
100
100 @property
101 @property
101 def us2unit(self):
102 def us2unit(self):
102
103
103 return self.clock_in/self.clock_divider
104 return self.clock_in/self.clock_divider
104
105
105 @property
106 @property
106 def km2unit(self):
107 def km2unit(self):
107
108
108 return 20./3*(self.clock_in/self.clock_divider)
109 return 20./3*(self.clock_in/self.clock_divider)
109
110
110 def clone(self, **kwargs):
111 def clone(self, **kwargs):
111
112
112 lines = self.get_lines()
113 lines = self.get_lines()
113 self.pk = None
114 self.pk = None
114 self.id = None
115 self.id = None
115 for attr, value in kwargs.items():
116 for attr, value in kwargs.items():
116 setattr(self, attr, value)
117 setattr(self, attr, value)
117 self.save()
118 self.save()
118
119
119 for line in lines:
120 for line in lines:
120 line.clone(rc_configuration=self)
121 line.clone(rc_configuration=self)
121
122
122 new_lines = self.get_lines()
123 new_lines = self.get_lines()
123 for line in new_lines:
124 for line in new_lines:
124 line_params = json.loads(line.params)
125 line_params = json.loads(line.params)
125 if 'TX_ref' in line_params and (line_params['TX_ref'] != '0'):
126 if 'TX_ref' in line_params and (line_params['TX_ref'] != '0'):
126 ref_line = RCLine.objects.get(pk=line_params['TX_ref'])
127 ref_line = RCLine.objects.get(pk=line_params['TX_ref'])
127 line_params['TX_ref'] = ['{}'.format(l.pk) for l in new_lines if l.get_name()==ref_line.get_name()][0]
128 line_params['TX_ref'] = ['{}'.format(l.pk) for l in new_lines if l.get_name()==ref_line.get_name()][0]
128 line.params = json.dumps(line_params)
129 line.params = json.dumps(line_params)
129 line.save()
130 line.save()
130
131
131 return self
132 return self
132
133
133 def get_lines(self, **kwargs):
134 def get_lines(self, **kwargs):
134 '''
135 '''
135 Retrieve configuration lines
136 Retrieve configuration lines
136 '''
137 '''
137
138
138 return RCLine.objects.filter(rc_configuration=self.pk, **kwargs)
139 return RCLine.objects.filter(rc_configuration=self.pk, **kwargs)
139
140
140
141
141 def clean_lines(self):
142 def clean_lines(self):
142 '''
143 '''
143 '''
144 '''
144
145
145 empty_line = RCLineType.objects.get(name='none')
146 empty_line = RCLineType.objects.get(name='none')
146
147
147 for line in self.get_lines():
148 for line in self.get_lines():
148 line.line_type = empty_line
149 line.line_type = empty_line
149 line.params = '{}'
150 line.params = '{}'
150 line.save()
151 line.save()
151
152
152 def dict_to_parms(self, params, id=None):
153 def dict_to_parms(self, params, id=None):
153 '''
154 '''
154 '''
155 '''
155
156
156 if id:
157 if id:
157 data = Params(params).get_conf(id_conf=id)
158 data = Params(params).get_conf(id_conf=id)
158 else:
159 else:
159 data = Params(params).get_conf(dtype='rc')
160 data = Params(params).get_conf(dtype='rc')
160
161
161 #print(data)
162 #print(data)
162 # self.name = data['name']
163 # self.name = data['name']
163 self.ipp = data['ipp']
164 self.ipp = data['ipp']
164 self.ntx = data['ntx']
165 self.ntx = data['ntx']
165 self.clock_in = data['clock_in']
166 self.clock_in = data['clock_in']
166 self.clock_divider = data['clock_divider']
167 self.clock_divider = data['clock_divider']
167 self.clock = data['clock']
168 self.clock = data['clock']
168 self.time_before = data['time_before']
169 self.time_before = data['time_before']
169 self.time_after = data['time_after']
170 self.time_after = data['time_after']
170 self.sync = data['sync']
171 self.sync = data['sync']
171 self.sampling_reference = data['sampling_reference']
172 self.sampling_reference = data['sampling_reference']
172 self.total_units = self.ipp*self.ntx*self.km2unit
173 self.total_units = self.ipp*self.ntx*self.km2unit
173 self.save()
174 self.save()
174 self.clean_lines()
175 self.clean_lines()
175
176
176 #print(params)
177 #print(params)
177
178
178 positions = {'tx':0, 'tr':0}
179 positions = {'tx':0, 'tr':0}
179 for i, id in enumerate(data['lines']):
180 for i, id in enumerate(data['lines']):
180 line_data = params['lines']['byId'][id]
181 line_data = params['lines']['byId'][id]
181 line_type = RCLineType.objects.get(name=line_data['line_type'])
182 line_type = RCLineType.objects.get(name=line_data['line_type'])
182 if line_type.name == 'codes':
183 if line_type.name == 'codes':
183 code = RCLineCode.objects.get(name=line_data['params']['code'])
184 code = RCLineCode.objects.get(name=line_data['params']['code'])
184 line_data['params']['code'] = code.pk
185 line_data['params']['code'] = code.pk
185 if line_type.name == 'tx':
186 if line_type.name == 'tx':
186 position = positions['tx']
187 position = positions['tx']
187 positions['tx'] += 1
188 positions['tx'] += 1
188 elif line_type.name == 'tr':
189 elif line_type.name == 'tr':
189 position = positions['tr']
190 position = positions['tr']
190 positions['tr'] += 1
191 positions['tr'] += 1
191 else:
192 else:
192 position = 0
193 position = 0
193 line, dum = RCLine.objects.update_or_create(
194 line, dum = RCLine.objects.update_or_create(
194 rc_configuration=self,
195 rc_configuration=self,
195 channel=i,
196 channel=i,
196 position=position,
197 position=position,
197 defaults={
198 defaults={
198 'line_type': line_type,
199 'line_type': line_type,
199 'params': json.dumps(line_data['params'])
200 'params': json.dumps(line_data['params'])
200 }
201 }
201 )
202 )
202
203
203 for i, line in enumerate(self.get_lines()):
204 for i, line in enumerate(self.get_lines()):
204 line_params = json.loads(line.params)
205 line_params = json.loads(line.params)
205 if 'TX_ref' in line_params:
206 if 'TX_ref' in line_params:
206 if line_params['TX_ref'] in (0, '0'):
207 if line_params['TX_ref'] in (0, '0'):
207 line_params['TX_ref'] = '0'
208 line_params['TX_ref'] = '0'
208 else:
209 else:
209 ref_id = '{}'.format(line_params['TX_ref'])
210 ref_id = '{}'.format(line_params['TX_ref'])
210 ref_line = params['lines']['byId'][ref_id]
211 ref_line = params['lines']['byId'][ref_id]
211 line_params['TX_ref'] = RCLine.objects.get(
212 line_params['TX_ref'] = RCLine.objects.get(
212 rc_configuration=self,
213 rc_configuration=self,
213 params=json.dumps(ref_line['params'])
214 params=json.dumps(ref_line['params'])
214 ).pk
215 ).pk
215 line.params = json.dumps(line_params)
216 line.params = json.dumps(line_params)
216 print(line.params)
217 print(line.params)
217 line.save()
218 line.save()
218 print("Fin de dict to param")
219 print("Fin de dict to param")
219
220
220 def get_delays(self):
221 def get_delays(self):
221
222
222 pulses = [line.pulses_as_points() for line in self.get_lines()]
223 pulses = [line.pulses_as_points() for line in self.get_lines()]
223 points = [tup for tups in pulses for tup in tups]
224 points = [tup for tups in pulses for tup in tups]
224 points = set([x for tup in points for x in tup])
225 points = set([x for tup in points for x in tup])
225 points = list(points)
226 points = list(points)
226 points.sort()
227 points.sort()
227
228
228 if points[0]!=0:
229 if points[0]!=0:
229 points.insert(0, 0)
230 points.insert(0, 0)
230
231
231 return [points[i+1]-points[i] for i in range(len(points)-1)]
232 return [points[i+1]-points[i] for i in range(len(points)-1)]
232
233
233 def get_pulses(self, binary=True):
234 def get_pulses(self, binary=True):
234
235
235 pulses = [line.pulses_as_points() for line in self.get_lines()]
236 pulses = [line.pulses_as_points() for line in self.get_lines()]
236 tuples = [tup for tups in pulses for tup in tups]
237 tuples = [tup for tups in pulses for tup in tups]
237 points = set([x for tup in tuples for x in tup])
238 points = set([x for tup in tuples for x in tup])
238 points = list(points)
239 points = list(points)
239 points.sort()
240 points.sort()
240 states = []
241 states = []
241 last = [0 for x in pulses]
242 last = [0 for x in pulses]
242 n_pulses = len(pulses)
243 n_pulses = len(pulses)
243 print('len_pulses', n_pulses)
244 print('len_pulses', n_pulses)
244 print('len_points', len(points))
245 print('len_points', len(points))
245 ups_arr = [[] for _ in range(n_pulses)]
246 ups_arr = [[] for _ in range(n_pulses)]
246 dws_arr = [[] for _ in range(n_pulses)]
247 dws_arr = [[] for _ in range(n_pulses)]
247
248
248 for i, tups in enumerate(pulses):
249 for i, tups in enumerate(pulses):
249 ups_arr[i] = [tup[0] for tup in tups if tup!=(0,0)]
250 ups_arr[i] = [tup[0] for tup in tups if tup!=(0,0)]
250 dws_arr[i] = [tup[1] for tup in tups if tup!=(0,0)]
251 dws_arr[i] = [tup[1] for tup in tups if tup!=(0,0)]
251 print('len_points*n_pulses',len(points)*n_pulses)
252 print('len_points*n_pulses',len(points)*n_pulses)
252 #print('ups_arr', ups_arr)
253 #print('ups_arr', ups_arr)
253 #print('dws_arr', dws_arr)
254 #print('dws_arr', dws_arr)
254
255
255 #####################Code for load configuration#########################
256 #####################Code for load configuration#########################
256 for x in points:
257 for x in points:
257 dum = []
258 dum = []
258 print('loading', x*100/max(points))
259 print('loading', x*100/max(points))
259
260
260 for i in range(n_pulses):
261 for i in range(n_pulses):
261 if x in ups_arr[i]:
262 if x in ups_arr[i]:
262 dum.append(1)
263 dum.append(1)
263 elif x in dws_arr[i]:
264 elif x in dws_arr[i]:
264 dum.append(0)
265 dum.append(0)
265 else:
266 else:
266 dum.append(last[i])
267 dum.append(last[i])
267 #print(dum)
268 #print(dum)
268 states.append(dum)
269 states.append(dum)
269 last = dum
270 last = dum
270 print("Finish loading")
271 #########################################################################
271 #########################################################################
272
272
273 if binary:
273 if binary:
274 ret = []
274 ret = []
275 for flips in states:
275 for flips in states:
276 flips.reverse()
276 flips.reverse()
277 ret.append(int(''.join([str(x) for x in flips]), 2))
277 ret.append(int(''.join([str(x) for x in flips]), 2))
278 states = ret
278 states = ret
279 #print(states[:-1])
279 #print(states[:-1])
280 #print('len_states',len(states[:-1]))
280 #print('len_states',len(states[:-1]))
281
281
282 return states[:-1]
282 return states[:-1]
283
283
284 def add_cmd(self, cmd):
284 def add_cmd(self, cmd):
285
285
286 if cmd in DAT_CMDS:
286 if cmd in DAT_CMDS:
287 return (255, DAT_CMDS[cmd])
287 return (255, DAT_CMDS[cmd])
288
288
289 def add_data(self, value):
289 def add_data(self, value):
290
290
291 return (254, value-1)
291 return (254, value-1)
292
292
293 def parms_to_binary(self, dat=True):
293 def parms_to_binary(self, dat=True):
294 '''
294 '''
295 Create "dat" stream to be send to CR
295 Create "dat" stream to be send to CR
296 '''
296 '''
297
297
298 data = bytearray()
298 data = bytearray()
299 # create header
299 # create header
300 data.extend(self.add_cmd('DISABLE'))
300 data.extend(self.add_cmd('DISABLE'))
301 data.extend(self.add_cmd('CONTINUE'))
301 data.extend(self.add_cmd('CONTINUE'))
302 data.extend(self.add_cmd('RESTART'))
302 data.extend(self.add_cmd('RESTART'))
303
303
304 if self.control_sw:
304 if self.control_sw:
305 data.extend(self.add_cmd('SW_ONE'))
305 data.extend(self.add_cmd('SW_ONE'))
306 else:
306 else:
307 data.extend(self.add_cmd('SW_ZERO'))
307 data.extend(self.add_cmd('SW_ZERO'))
308
308
309 if self.control_tx:
309 if self.control_tx:
310 data.extend(self.add_cmd('TX_ONE'))
310 data.extend(self.add_cmd('TX_ONE'))
311 else:
311 else:
312 data.extend(self.add_cmd('TX_ZERO'))
312 data.extend(self.add_cmd('TX_ZERO'))
313
313
314 # write divider
314 # write divider
315 data.extend(self.add_cmd('CLOCK_DIVIDER'))
315 data.extend(self.add_cmd('CLOCK_DIVIDER'))
316 data.extend(self.add_data(self.clock_divider))
316 data.extend(self.add_data(self.clock_divider))
317
317
318 # write delays
318 # write delays
319 data.extend(self.add_cmd('DELAY_START'))
319 data.extend(self.add_cmd('DELAY_START'))
320 # first delay is always zero
320 # first delay is always zero
321 data.extend(self.add_data(1))
321 data.extend(self.add_data(1))
322
322
323 delays = self.get_delays()
323 delays = self.get_delays()
324
324
325 for delay in delays:
325 for delay in delays:
326 while delay>252:
326 while delay>252:
327 data.extend(self.add_data(253))
327 data.extend(self.add_data(253))
328 delay -= 253
328 delay -= 253
329 data.extend(self.add_data(int(delay)))
329 data.extend(self.add_data(int(delay)))
330
330
331 # write flips
331 # write flips
332 data.extend(self.add_cmd('FLIP_START'))
332 data.extend(self.add_cmd('FLIP_START'))
333
333
334 states = self.get_pulses(binary=True)
334 states = self.get_pulses(binary=True)
335
335
336
336
337 last = 0
337 last = 0
338 for flip, delay in zip(states, delays):
338 for flip, delay in zip(states, delays):
339 data.extend(self.add_data((flip^last)+1))
339 data.extend(self.add_data((flip^last)+1))
340 last = flip
340 last = flip
341 while delay>252:
341 while delay>252:
342 data.extend(self.add_data(1))
342 data.extend(self.add_data(1))
343 delay -= 253
343 delay -= 253
344
344
345 # write sampling period
345 # write sampling period
346 data.extend(self.add_cmd('SAMPLING_PERIOD'))
346 data.extend(self.add_cmd('SAMPLING_PERIOD'))
347 wins = self.get_lines(line_type__name='windows')
347 wins = self.get_lines(line_type__name='windows')
348 if wins:
348 if wins:
349 win_params = json.loads(wins[0].params)['params']
349 win_params = json.loads(wins[0].params)['params']
350 if win_params:
350 if win_params:
351 dh = int(win_params[0]['resolution']*self.km2unit)
351 dh = int(win_params[0]['resolution']*self.km2unit)
352 else:
352 else:
353 dh = 1
353 dh = 1
354 else:
354 else:
355 dh = 1
355 dh = 1
356 data.extend(self.add_data(dh))
356 data.extend(self.add_data(dh))
357
357
358 # write enable
358 # write enable
359 data.extend(self.add_cmd('ENABLE'))
359 data.extend(self.add_cmd('ENABLE'))
360
360
361 if not dat:
361 if not dat:
362 return data
362 return data
363
363
364 return '\n'.join(['{}'.format(x) for x in data])
364 return '\n'.join(['{}'.format(x) for x in data])
365
365
366 def update_pulses(self):
366 def update_pulses(self):
367 contador = 0
367 contador = 0
368 for line in self.get_lines():
368 for line in self.get_lines():
369 contador=contador+1
369 contador=contador+1
370 print(contador)
370 print(contador)
371 line.update_pulses()
371 line.update_pulses()
372
372
373 def plot_pulses2(self, km=False):
373 def plot_pulses2(self, km=False):
374
374
375 import matplotlib
375 import matplotlib
376 matplotlib.use('Agg')
376 matplotlib.use('Agg')
377 import matplotlib.pyplot as plt
377 import matplotlib.pyplot as plt
378 from bokeh.resources import CDN
378 from bokeh.resources import CDN
379 from bokeh.embed import components
379 from bokeh.embed import components
380 from bokeh.mpl import to_bokeh
380 from bokeh.mpl import to_bokeh
381 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
381 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
382
382
383 lines = self.get_lines()
383 lines = self.get_lines()
384
384
385 N = len(lines)
385 N = len(lines)
386 npoints = self.total_units/self.km2unit if km else self.total_units
386 npoints = self.total_units/self.km2unit if km else self.total_units
387 fig = plt.figure(figsize=(12, 2+N*0.5))
387 fig = plt.figure(figsize=(12, 2+N*0.5))
388 ax = fig.add_subplot(111)
388 ax = fig.add_subplot(111)
389 labels = ['IPP']
389 labels = ['IPP']
390
390
391 for i, line in enumerate(lines):
391 for i, line in enumerate(lines):
392 labels.append(line.get_name(channel=True))
392 labels.append(line.get_name(channel=True))
393 l = ax.plot((0, npoints),(N-i-1, N-i-1))
393 l = ax.plot((0, npoints),(N-i-1, N-i-1))
394 points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
394 points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
395 ax.broken_barh(points, (N-i-1, 0.5),
395 ax.broken_barh(points, (N-i-1, 0.5),
396 edgecolor=l[0].get_color(), facecolor='none')
396 edgecolor=l[0].get_color(), facecolor='none')
397
397
398 n = 0
398 n = 0
399 f = ((self.ntx+50)/100)*5 if ((self.ntx+50)/100)*10>0 else 2
399 f = ((self.ntx+50)/100)*5 if ((self.ntx+50)/100)*10>0 else 2
400 for x in np.arange(0, npoints, self.ipp if km else self.ipp*self.km2unit):
400 for x in np.arange(0, npoints, self.ipp if km else self.ipp*self.km2unit):
401 if n%f==0:
401 if n%f==0:
402 ax.text(x, N, '%s' % n, size=10)
402 ax.text(x, N, '%s' % n, size=10)
403 n += 1
403 n += 1
404
404
405 labels.reverse()
405 labels.reverse()
406 ax.set_yticks(range(len(labels)))
406 ax.set_yticks(range(len(labels)))
407 ax.set_yticklabels(labels)
407 ax.set_yticklabels(labels)
408 ax.set_xlabel = 'Units'
408 ax.set_xlabel = 'Units'
409 plot = to_bokeh(fig, use_pandas=False)
409 plot = to_bokeh(fig, use_pandas=False)
410 plot.tools = [PanTool(dimensions="width"), WheelZoomTool(dimensions="width"), ResetTool(), SaveTool()]
410 plot.tools = [PanTool(dimensions="width"), WheelZoomTool(dimensions="width"), ResetTool(), SaveTool()]
411 plot.toolbar_location="above"
411 plot.toolbar_location="above"
412
412
413 return components(plot, CDN)
413 return components(plot, CDN)
414
414
415 def plot_pulses(self, km=False):
415 def plot_pulses(self, km=False):
416
416
417 from bokeh.plotting import figure
417 from bokeh.plotting import figure
418 from bokeh.resources import CDN
418 from bokeh.resources import CDN
419 from bokeh.embed import components
419 from bokeh.embed import components
420 from bokeh.models import FixedTicker, PrintfTickFormatter, Label
420 from bokeh.models import FixedTicker, PrintfTickFormatter, Label
421 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
421 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
422 from bokeh.models.sources import ColumnDataSource
422 from bokeh.models.sources import ColumnDataSource
423
423
424 lines = self.get_lines().reverse()
424 lines = self.get_lines().reverse()
425
425
426 N = len(lines)
426 N = len(lines)
427 npoints = self.total_units/self.km2unit if km else self.total_units
427 npoints = self.total_units/self.km2unit if km else self.total_units
428 ipp = self.ipp if km else self.ipp*self.km2unit
428 ipp = self.ipp if km else self.ipp*self.km2unit
429
429
430 hover = HoverTool(tooltips=[("Line", "@name"),
430 hover = HoverTool(tooltips=[("Line", "@name"),
431 ("IPP", "@ipp"),
431 ("IPP", "@ipp"),
432 ("X", "@left")])
432 ("X", "@left")])
433
433
434 tools = [PanTool(dimensions="width"),
434 tools = [PanTool(dimensions="width"),
435 WheelZoomTool(dimensions="width"),
435 WheelZoomTool(dimensions="width"),
436 hover, SaveTool()]
436 hover, SaveTool()]
437
437
438 plot = figure(width=1000,
438 plot = figure(width=1000,
439 height=40+N*50,
439 height=40+N*50,
440 y_range = (0, N),
440 y_range = (0, N),
441 tools=tools,
441 tools=tools,
442 toolbar_location='above',
442 toolbar_location='above',
443 toolbar_sticky=False,)
443 toolbar_sticky=False,)
444
444
445 pulses = [line.pulses_as_points() for line in self.get_lines()]
445 pulses = [line.pulses_as_points() for line in self.get_lines()]
446 tuples = [tup for tups in pulses for tup in tups]
446 tuples = [tup for tups in pulses for tup in tups]
447 points = set([x for tup in tuples for x in tup])
447 points = set([x for tup in tuples for x in tup])
448 capacity_bytes = round((8*(len(points)-1)+12)/2) # se divide entre 2 porque la mitad era solo para direcciones
448 capacity_bytes = round((8*(len(points)-1)+12)/2) # se divide entre 2 porque la mitad era solo para direcciones
449 capacity_percent = (capacity_bytes/2097152)*100
449 capacity_percent = (capacity_bytes/2097152)*100
450 # Add the used memory message
450 # Add the used memory message
451 x_label_memory = Label(x=900, y=-1.5, text='Used memory of '+str(capacity_bytes)+'/2097152 bytes ('+'%.3f'%capacity_percent+'%)', text_align="right", x_units='screen', text_font_size='14pt')
451 x_label_memory = Label(x=900, y=-1.5, text='Used memory of '+str(capacity_bytes)+'/2097152 bytes ('+'%.3f'%capacity_percent+'%)', text_align="right", x_units='screen', text_font_size='14pt')
452 plot.add_layout(x_label_memory, 'below')
452 plot.add_layout(x_label_memory, 'below')
453
453
454 plot.xaxis.axis_label = 'Km' if km else 'Units'
454 plot.xaxis.axis_label = 'Km' if km else 'Units'
455 plot.xaxis[0].formatter = PrintfTickFormatter(format='%d')
455 plot.xaxis[0].formatter = PrintfTickFormatter(format='%d')
456 plot.yaxis.axis_label = 'Pulses'
456 plot.yaxis.axis_label = 'Pulses'
457 plot.yaxis[0].ticker=FixedTicker(ticks=list(range(N)))
457 plot.yaxis[0].ticker=FixedTicker(ticks=list(range(N)))
458 plot.yaxis[0].formatter = PrintfTickFormatter(format='Line %d')
458 plot.yaxis[0].formatter = PrintfTickFormatter(format='Line %d')
459
459
460 for i, line in enumerate(lines):
460 for i, line in enumerate(lines):
461
461
462 points = [tup for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
462 points = [tup for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
463
463
464 source = ColumnDataSource(data = dict(
464 source = ColumnDataSource(data = dict(
465 bottom = [i for tup in points],
465 bottom = [i for tup in points],
466 top = [i+0.5 for tup in points],
466 top = [i+0.5 for tup in points],
467 left = [tup[0] for tup in points],
467 left = [tup[0] for tup in points],
468 right = [tup[1] for tup in points],
468 right = [tup[1] for tup in points],
469 ipp = [int(tup[0]/ipp) for tup in points],
469 ipp = [int(tup[0]/ipp) for tup in points],
470 name = [line.get_name() for tup in points]
470 name = [line.get_name() for tup in points]
471 ))
471 ))
472
472
473 plot.quad(
473 plot.quad(
474 bottom = 'bottom',
474 bottom = 'bottom',
475 top = 'top',
475 top = 'top',
476 left = 'left',
476 left = 'left',
477 right = 'right',
477 right = 'right',
478 source = source,
478 source = source,
479 fill_alpha = 0,
479 fill_alpha = 0,
480 #line_color = 'blue',
480 #line_color = 'blue',
481 )
481 )
482
482
483 plot.line([0, npoints], [i, i])#, color='blue')
483 plot.line([0, npoints], [i, i])#, color='blue')
484
484
485 return components(plot, CDN)
485 return components(plot, CDN)
486
486
487 def request(self, cmd, method='get', **kwargs):
487 def request(self, cmd, method='get', **kwargs):
488
488
489 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
489 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
490 payload = req.json()
490 payload = req.json()
491
491
492 return payload
492 return payload
493
493
494 def status_device(self):
494 def status_device(self):
495
495
496 try:
496 try:
497 self.device.status = 0
497 self.device.status = 0
498 payload = self.request('status')
498 payload = self.request('status')
499 if payload['status']=='enable':
499 if payload['status']=='enable':
500 self.device.status = 3
500 self.device.status = 3
501 elif payload['status']=='disable':
501 elif payload['status']=='disable':
502 self.device.status = 2
502 self.device.status = 2
503 else:
503 else:
504 self.device.status = 1
504 self.device.status = 1
505 self.device.save()
505 self.device.save()
506 self.message = 'RC status: {}'.format(payload['status'])
506 self.message = 'RC status: {}'.format(payload['status'])
507 return False
507 return False
508 except Exception as e:
508 except Exception as e:
509 if 'No route to host' not in str(e):
509 if 'No route to host' not in str(e):
510 self.device.status = 4
510 self.device.status = 4
511 self.device.save()
511 self.device.save()
512 self.message = 'RC status: {}'.format(str(e))
512 self.message = 'RC status: {}'.format(str(e))
513 return False
513 return False
514
514
515 self.device.save()
515 self.device.save()
516 return True
516 return True
517
517
518 def reset_device(self):
518 def reset_device(self):
519
519
520 try:
520 try:
521 payload = self.request('reset', 'post')
521 payload = self.request('reset', 'post')
522 if payload['reset']=='ok':
522 if payload['reset']=='ok':
523 self.message = 'RC restarted OK'
523 self.message = 'RC restarted OK'
524 self.device.status = 2
524 self.device.status = 2
525 self.device.save()
525 self.device.save()
526 else:
526 else:
527 self.message = 'RC restart fail'
527 self.message = 'RC restart fail'
528 self.device.status = 4
528 self.device.status = 4
529 self.device.save()
529 self.device.save()
530 except Exception as e:
530 except Exception as e:
531 self.message = 'RC reset: {}'.format(str(e))
531 self.message = 'RC reset: {}'.format(str(e))
532 return False
532 return False
533
533
534 return True
534 return True
535
535
536 def stop_device(self):
536 def stop_device(self):
537
537
538 try:
538 try:
539 payload = self.request('stop', 'post')
539 payload = self.request('stop', 'post')
540 self.message = 'RC stop: {}'.format(payload['stop'])
540 self.message = 'RC stop: {}'.format(payload['stop'])
541 if payload['stop']=='ok':
541 if payload['stop']=='ok':
542 self.device.status = 2
542 self.device.status = 2
543 self.device.save()
543 self.device.save()
544 else:
544 else:
545 self.device.status = 4
545 self.device.status = 4
546 self.device.save()
546 self.device.save()
547 return False
547 return False
548 except Exception as e:
548 except Exception as e:
549 if 'No route to host' not in str(e):
549 if 'No route to host' not in str(e):
550 self.device.status = 4
550 self.device.status = 4
551 else:
551 else:
552 self.device.status = 0
552 self.device.status = 0
553 self.message = 'RC stop: {}'.format(str(e))
553 self.message = 'RC stop: {}'.format(str(e))
554 self.device.save()
554 self.device.save()
555 return False
555 return False
556
556
557 return True
557 return True
558
558
559 def start_device(self):
559 def start_device(self):
560
560
561 try:
561 try:
562 payload = self.request('start', 'post')
562 payload = self.request('start', 'post')
563 self.message = 'RC start: {}'.format(payload['start'])
563 self.message = 'RC start: {}'.format(payload['start'])
564 if payload['start']=='ok':
564 if payload['start']=='ok':
565 self.device.status = 3
565 self.device.status = 3
566 self.device.save()
566 self.device.save()
567 else:
567 else:
568 return False
568 return False
569 except Exception as e:
569 except Exception as e:
570 if 'No route to host' not in str(e):
570 if 'No route to host' not in str(e):
571 self.device.status = 4
571 self.device.status = 4
572 else:
572 else:
573 self.device.status = 0
573 self.device.status = 0
574 self.message = 'RC start: {}'.format(str(e))
574 self.message = 'RC start: {}'.format(str(e))
575 self.device.save()
575 self.device.save()
576 return False
576 return False
577
577
578 return True
578 return True
579
579
580 def write_device(self, raw=False):
580 def write_device(self, raw=False):
581 print("write device")
581 print("write device")
582 ##############Comando status a CGS para hacer programacion ############
582 ##############Comando status a CGS para hacer programacion ############
583 try:
583 try:
584 self.device.status = 0
584 self.device.status = 0
585 cgs = self.request('status_cgs')
585 cgs = self.request('status_cgs')
586 print('CGS status ok') # solo para depurar lo que devuelve CGS
586 print('CGS status ok') # solo para depurar lo que devuelve CGS
587 except Exception as e:
587 except Exception as e:
588 cgs = {'multiplier': 60, 'divider': 10, 'reference_clk': 1} # simulando parametros devueltos por el cgs
588 cgs = {'multiplier': 60, 'divider': 10, 'reference_clk': 1} # simulando parametros devueltos por el cgs
589 if 'No route to host' not in str(e):
589 if 'No route to host' not in str(e):
590 self.device.status = 4
590 self.device.status = 4
591 self.device.save()
591 self.device.save()
592 self.message = 'CGS status: {}'.format(str(e))
592 self.message = 'CGS status: {}'.format(str(e))
593 print('not cgs status')
593 print('not cgs status')
594
594
595 print(cgs)
595 print(cgs)
596
596
597 if not raw:
597 if not raw:
598 clock = RCClock.objects.get(rc_configuration=self)
598 clock = RCClock.objects.get(rc_configuration=self)
599 print('clock_freq', clock.frequency)
599 print('clock_freq', clock.frequency)
600 print('clock_mult', clock.multiplier)
600 print('clock_mult', clock.multiplier)
601 print('clock_div', clock.divisor)
601 print('clock_div', clock.divisor)
602 print('clock_ref', clock.reference)
602 print('clock_ref', clock.reference)
603 print('cgs', cgs)
603 print('cgs', cgs)
604 if clock.mode:
604 if clock.mode:
605 data = {'default': clock.frequency} # mult=72, div=12
605 data = {'default': clock.frequency} # mult=72, div=12
606 else:
606 else:
607 data = {'manual': [clock.multiplier, clock.divisor, clock.reference]}
607 data = {'manual': [clock.multiplier, clock.divisor, clock.reference]}
608 print('data', data)
608 print('data', data)
609 int_cgs_multiplier=int(cgs['multiplier'])
609 int_cgs_multiplier=int(cgs['multiplier'])
610 int_cgs_divisor=int(cgs['divider'])
610 int_cgs_divisor=int(cgs['divider'])
611 int_cgs_reference=int(cgs['reference_clk'])
611 int_cgs_reference=int(cgs['reference_clk'])
612 print(cgs['divider'])
612 print(cgs['divider'])
613
613
614 if clock.multiplier != int_cgs_multiplier or clock.divisor != int_cgs_divisor or clock.reference != int_cgs_reference:
614 if clock.multiplier != int_cgs_multiplier or clock.divisor != int_cgs_divisor or clock.reference != int_cgs_reference:
615 print("Program CGS...")
615 print("Program CGS...")
616 payload = self.request('setfreq', 'post', data=json.dumps(data))#data=data)#data=json.dumps(data))
616 payload = self.request('setfreq', 'post', data=json.dumps(data))#data=data)#data=json.dumps(data))
617 if payload['command'] != 'ok':
617 if payload['command'] != 'ok':
618 self.message = 'RC write: {}'.format(payload['command'])
618 self.message = 'RC write: {}'.format(payload['command'])
619 else:
619 else:
620 self.message = payload['programming']
620 self.message = payload['programming']
621 if payload['programming'] == 'fail':
621 if payload['programming'] == 'fail':
622 self.message = 'RC write: error programming CGS chip'
622 self.message = 'RC write: error programming CGS chip'
623 else:
623 else:
624 print("Not program CGS...")
624 print("Not program CGS...")
625
625
626 values = []
626 values = []
627 print('wait delay values...')
627 print('wait delay values...')
628 for pulse, delay in zip(self.get_pulses(), self.get_delays()):
628 for pulse, delay in zip(self.get_pulses(), self.get_delays()):
629 #print('wait zip...')
629 #print('wait zip...')
630 while delay > 65536:
630 while delay > 65536:
631 values.append((pulse, 65535))
631 values.append((pulse, 65535))
632 delay -= 65536
632 delay -= 65536
633 values.append((pulse, delay-1))
633 values.append((pulse, delay-1))
634 data = bytearray()
634 data = bytearray()
635 #reset
635 #reset
636 data.extend((128, 0))
636 data.extend((128, 0))
637 #disable
637 #disable
638 data.extend((129, 0))
638 data.extend((129, 0))
639 #SW switch
639 #SW switch
640 if self.control_sw:
640 if self.control_sw:
641 data.extend((130, 2))
641 data.extend((130, 2))
642 else:
642 else:
643 data.extend((130, 0))
643 data.extend((130, 0))
644 #divider
644 #divider
645 data.extend((131, self.clock_divider-1))
645 data.extend((131, self.clock_divider-1))
646 #enable writing
646 #enable writing
647 data.extend((139, 62))
647 data.extend((139, 62))
648
648
649 last = 0
649 last = 0
650 print('wait data...')
650 print('wait data...')
651 for tup in values:
651 for tup in values:
652 vals = pack('<HH', last^tup[0], tup[1])
652 vals = pack('<HH', last^tup[0], tup[1])
653 last = tup[0]
653 last = tup[0]
654 data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
654 data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
655
655
656 #enable
656 #enable
657 data.extend((129, 1))
657 data.extend((129, 1))
658 print('len',len(data))
658 print('len',len(data))
659
659
660 if raw:
660 if raw:
661 return b64encode(data)
661 return b64encode(data)
662
662
663 #try:
663 #try:
664 print('requests')
664 print('requests')
665 payload = self.request('stop', 'post')
665 payload = self.request('stop', 'post')
666 payload = self.request('reset', 'post')
666 payload = self.request('reset', 'post')
667 #payload = self.request('divider', 'post', data={'divider': self.clock_divider-1})
667 #payload = self.request('divider', 'post', data={'divider': self.clock_divider-1})
668 #payload = self.request('write', 'post', data=b64encode(bytearray((139, 62))), timeout=20)
668 #payload = self.request('write', 'post', data=b64encode(bytearray((139, 62))), timeout=20)
669 n = len(data)
669 n = len(data)
670 print('len: ',n)
670 print('len: ',n)
671 x = 0
671 x = 0
672 cnt = 0
672 cnt = 0
673 while x < n:
673 while x < n:
674 print('writing...', cnt)
674 print('writing...', cnt)
675 payload = self.request('write', 'post', data=b64encode(data[x:x+16384]))#(data))#
675 payload = self.request('write', 'post', data=b64encode(data[x:x+16384]))#(data))#
676 x += 16384
676 x += 16384
677 cnt += 1#time.sleep(1)
677 cnt += 1#time.sleep(1)
678 print('writing...', x*100/n)
678 print('writing...', x*100/n)
679
679
680 if payload['write']=='ok':
680 if payload['write']=='ok':
681 self.device.status = 3
681 self.device.status = 3
682 self.device.save()
682 self.device.save()
683 self.message = 'RC configured and started'
683 self.message = 'RC configured and started'
684 else:
684 else:
685 self.device.status = 1
685 self.device.status = 1
686 self.device.save()
686 self.device.save()
687 self.message = 'RC write: {}'.format(payload['write'])
687 self.message = 'RC write: {}'.format(payload['write'])
688 return False
688 return False
689
689
690 #payload = self.request('start', 'post')
690 #payload = self.request('start', 'post')
691
691
692 #except Exception as e:
692 #except Exception as e:
693 # if 'No route to host' not in str(e):
693 # if 'No route to host' not in str(e):
694 # self.device.status = 4
694 # self.device.status = 4
695 # else:
695 # else:
696 # self.device.status = 0
696 # self.device.status = 0
697 # self.message = 'RC write: {}'.format(str(e))
697 # self.message = 'RC write: {}'.format(str(e))
698 # self.device.save()
698 # self.device.save()
699 # return False
699 # return False
700
700
701 return True
701 return True
702
702
703
703
704 def get_absolute_url_import(self):
704 def get_absolute_url_import(self):
705 return reverse('url_import_rc_conf', args=[str(self.id)])
705 return reverse('url_import_rc_conf', args=[str(self.id)])
706
706
707
707
708 class RCLineCode(models.Model):
708 class RCLineCode(models.Model):
709
709
710 name = models.CharField(max_length=40)
710 name = models.CharField(max_length=40)
711 bits_per_code = models.PositiveIntegerField(default=0)
711 bits_per_code = models.PositiveIntegerField(default=0)
712 number_of_codes = models.PositiveIntegerField(default=0)
712 number_of_codes = models.PositiveIntegerField(default=0)
713 codes = models.TextField(blank=True, null=True)
713 codes = models.TextField(blank=True, null=True)
714
714
715 class Meta:
715 class Meta:
716 db_table = 'rc_line_codes'
716 db_table = 'rc_line_codes'
717 ordering = ('name',)
717 ordering = ('name',)
718
718
719 def __str__(self):
719 def __str__(self):
720 return u'%s' % self.name
720 return u'%s' % self.name
721
721
722
722
723 class RCLineType(models.Model):
723 class RCLineType(models.Model):
724
724
725 name = models.CharField(choices=LINE_TYPES, max_length=40)
725 name = models.CharField(choices=LINE_TYPES, max_length=40)
726 description = models.TextField(blank=True, null=True)
726 description = models.TextField(blank=True, null=True)
727 params = models.TextField(default='[]')
727 params = models.TextField(default='[]')
728
728
729 class Meta:
729 class Meta:
730 db_table = 'rc_line_types'
730 db_table = 'rc_line_types'
731
731
732 def __str__(self):
732 def __str__(self):
733 return u'%s - %s' % (self.name.upper(), self.get_name_display())
733 return u'%s - %s' % (self.name.upper(), self.get_name_display())
734
734
735
735
736 class RCLine(models.Model):
736 class RCLine(models.Model):
737
737
738 rc_configuration = models.ForeignKey('RCConfiguration', on_delete=models.CASCADE)
738 rc_configuration = models.ForeignKey('RCConfiguration', on_delete=models.CASCADE)
739 line_type = models.ForeignKey('RCLineType',on_delete=models.CASCADE)
739 line_type = models.ForeignKey('RCLineType',on_delete=models.CASCADE)
740 channel = models.PositiveIntegerField(default=0)
740 channel = models.PositiveIntegerField(default=0)
741 position = models.PositiveIntegerField(default=0)
741 position = models.PositiveIntegerField(default=0)
742 params = models.TextField(default='{}')
742 params = models.TextField(default='{}')
743 pulses = models.TextField(default='')
743 pulses = models.TextField(default='')
744
744
745 class Meta:
745 class Meta:
746 db_table = 'rc_lines'
746 db_table = 'rc_lines'
747 ordering = ['channel']
747 ordering = ['channel']
748
748
749 def __str__(self):
749 def __str__(self):
750 if self.rc_configuration:
750 if self.rc_configuration:
751 return u'{}|{} - {}'.format(self.pk, self.get_name(), self.rc_configuration.name)
751 return u'{}|{} - {}'.format(self.pk, self.get_name(), self.rc_configuration.name)
752
752
753 def jsonify(self):
753 def jsonify(self):
754
754
755 data = {}
755 data = {}
756 data['params'] = json.loads(self.params)
756 data['params'] = json.loads(self.params)
757 data['id'] = '{}'.format(self.pk)
757 data['id'] = '{}'.format(self.pk)
758 data['line_type'] = self.line_type.name
758 data['line_type'] = self.line_type.name
759 data['name'] = self.get_name()
759 data['name'] = self.get_name()
760 if data['line_type']=='codes':
760 if data['line_type']=='codes':
761 data['params']['code'] = RCLineCode.objects.get(pk=data['params']['code']).name
761 data['params']['code'] = RCLineCode.objects.get(pk=data['params']['code']).name
762
762
763 return data
763 return data
764
764
765
765
766 def clone(self, **kwargs):
766 def clone(self, **kwargs):
767
767
768 self.pk = None
768 self.pk = None
769 self.id = None
769 self.id = None
770
770
771 for attr, value in kwargs.items():
771 for attr, value in kwargs.items():
772 setattr(self, attr, value)
772 setattr(self, attr, value)
773
773
774 self.save()
774 self.save()
775
775
776 return self
776 return self
777
777
778 def get_name(self, channel=False):
778 def get_name(self, channel=False):
779
779
780 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
780 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
781 s = ''
781 s = ''
782
782
783 if self.line_type.name in ('tx',):
783 if self.line_type.name in ('tx',):
784 s = chars[self.position]
784 s = chars[self.position]
785 elif self.line_type.name in ('codes', 'windows', 'tr'):
785 elif self.line_type.name in ('codes', 'windows', 'tr'):
786 if 'TX_ref' in json.loads(self.params):
786 if 'TX_ref' in json.loads(self.params):
787 pk = json.loads(self.params)['TX_ref']
787 pk = json.loads(self.params)['TX_ref']
788 if pk in (0, '0'):
788 if pk in (0, '0'):
789 s = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
789 s = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
790 else:
790 else:
791 ref = RCLine.objects.get(pk=pk)
791 ref = RCLine.objects.get(pk=pk)
792 s = chars[ref.position]
792 s = chars[ref.position]
793 s = '({})'.format(s)
793 s = '({})'.format(s)
794
794
795 s = '{}{}'.format(self.line_type.name.upper(), s)
795 s = '{}{}'.format(self.line_type.name.upper(), s)
796
796
797 if channel:
797 if channel:
798 return '{} {}'.format(s, self.channel)
798 return '{} {}'.format(s, self.channel)
799 else:
799 else:
800 return s
800 return s
801
801
802 def get_lines(self, **kwargs):
802 def get_lines(self, **kwargs):
803
803
804 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
804 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
805
805
806 def pulses_as_array(self):
806 def pulses_as_array(self):
807
807
808 y = np.zeros(self.rc_configuration.total_units)
808 y = np.zeros(self.rc_configuration.total_units)
809
809
810 for tup in ast.literal_eval(self.pulses):
810 for tup in ast.literal_eval(self.pulses):
811 y[tup[0]:tup[1]] = 1
811 y[tup[0]:tup[1]] = 1
812
812
813 return y.astype(np.int8)
813 return y.astype(np.int8)
814
814
815 def pulses_as_points(self, km=False):
815 def pulses_as_points(self, km=False):
816
816
817 if km:
817 if km:
818 unit2km = 1/self.rc_configuration.km2unit
818 unit2km = 1/self.rc_configuration.km2unit
819 return [(tup[0]*unit2km, tup[1]*unit2km) for tup in ast.literal_eval(self.pulses)]
819 return [(tup[0]*unit2km, tup[1]*unit2km) for tup in ast.literal_eval(self.pulses)]
820 else:
820 else:
821 return ast.literal_eval(self.pulses)
821 return ast.literal_eval(self.pulses)
822
822
823 def get_win_ref(self, params, tx_id, km2unit):
823 def get_win_ref(self, params, tx_id, km2unit):
824
824
825 ref = self.rc_configuration.sampling_reference
825 ref = self.rc_configuration.sampling_reference
826 codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
826 codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
827
827
828 if codes:
828 if codes:
829 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/len(json.loads(codes[0].params)['codes'][0])
829 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/len(json.loads(codes[0].params)['codes'][0])
830 else:
830 else:
831 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
831 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
832
832
833 if ref=='first_baud':
833 if ref=='first_baud':
834 return int(1 + round((tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit))
834 return int(1 + round((tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit))
835 elif ref=='sub_baud':
835 elif ref=='sub_baud':
836 return np.ceil(1 + params['first_height']*km2unit - params['resolution']*km2unit/2)
836 return np.ceil(1 + params['first_height']*km2unit - params['resolution']*km2unit/2)
837 else:
837 else:
838 return 0
838 return 0
839
839
840 def update_pulses(self):
840 def update_pulses(self):
841 '''
841 '''
842 Update pulses field
842 Update pulses field
843 '''
843 '''
844
844
845 km2unit = self.rc_configuration.km2unit
845 km2unit = self.rc_configuration.km2unit
846 us2unit = self.rc_configuration.us2unit
846 us2unit = self.rc_configuration.us2unit
847 ipp = self.rc_configuration.ipp
847 ipp = self.rc_configuration.ipp
848 ntx = int(self.rc_configuration.ntx)
848 ntx = int(self.rc_configuration.ntx)
849 ipp_u = int(ipp*km2unit)
849 ipp_u = int(ipp*km2unit)
850 total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units
850 total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units
851 y = []
851 y = []
852
852
853 if self.line_type.name=='tr':
853 if self.line_type.name=='tr':
854 tr_params = json.loads(self.params)
854 tr_params = json.loads(self.params)
855 #print(tr_params)
855 #print(tr_params)
856 #print(tr_params['TX_ref'])
856 #print(tr_params['TX_ref'])
857 if tr_params['TX_ref'] in ('0', 0):
857 if tr_params['TX_ref'] in ('0', 0):
858 txs = self.get_lines(line_type__name='tx')
858 txs = self.get_lines(line_type__name='tx')
859 else:
859 else:
860 txs = RCLine.objects.filter(pk=tr_params['TX_ref'])
860 txs = RCLine.objects.filter(pk=tr_params['TX_ref'])
861
861
862 for tx in txs:
862 for tx in txs:
863 params = json.loads(tx.params)
863 params = json.loads(tx.params)
864
864
865 if float(params['pulse_width'])==0:
865 if float(params['pulse_width'])==0:
866 continue
866 continue
867 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
867 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
868 width = float(params['pulse_width'])*km2unit+int(self.rc_configuration.time_before*us2unit)
868 width = float(params['pulse_width'])*km2unit+int(self.rc_configuration.time_before*us2unit)
869 before = 0
869 before = 0
870 after = int(self.rc_configuration.time_after*us2unit)
870 after = int(self.rc_configuration.time_after*us2unit)
871
871
872 y_tx = self.points(ntx, ipp_u, width,
872 y_tx = self.points(ntx, ipp_u, width,
873 delay=delays,
873 delay=delays,
874 before=before,
874 before=before,
875 after=after,
875 after=after,
876 sync=self.rc_configuration.sync)
876 sync=self.rc_configuration.sync)
877
877
878 ranges = params['range'].split(',')
878 ranges = params['range'].split(',')
879
879
880 if len(ranges)>0 and ranges[0]!='0':
880 if len(ranges)>0 and ranges[0]!='0':
881 y_tx = self.mask_ranges(y_tx, ranges)
881 y_tx = self.mask_ranges(y_tx, ranges)
882
882
883 tr_ranges = tr_params['range'].split(',')
883 tr_ranges = tr_params['range'].split(',')
884
884
885 if len(tr_ranges)>0 and tr_ranges[0]!='0':
885 if len(tr_ranges)>0 and tr_ranges[0]!='0':
886 y_tx = self.mask_ranges(y_tx, tr_ranges)
886 y_tx = self.mask_ranges(y_tx, tr_ranges)
887
887
888 y.extend(y_tx)
888 y.extend(y_tx)
889
889
890 self.pulses = str(y)
890 self.pulses = str(y)
891 y = self.array_to_points(self.pulses_as_array())
891 y = self.array_to_points(self.pulses_as_array())
892
892
893 elif self.line_type.name=='tx':
893 elif self.line_type.name=='tx':
894 params = json.loads(self.params)
894 params = json.loads(self.params)
895 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
895 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
896 width = float(params['pulse_width'])*km2unit
896 width = float(params['pulse_width'])*km2unit
897
897
898 if width>0:
898 if width>0:
899 before = int(self.rc_configuration.time_before*us2unit)
899 before = int(self.rc_configuration.time_before*us2unit)
900 after = 0
900 after = 0
901
901
902 y = self.points(ntx, ipp_u, width,
902 y = self.points(ntx, ipp_u, width,
903 delay=delays,
903 delay=delays,
904 before=before,
904 before=before,
905 after=after,
905 after=after,
906 sync=self.rc_configuration.sync)
906 sync=self.rc_configuration.sync)
907
907
908 ranges = params['range'].split(',')
908 ranges = params['range'].split(',')
909
909
910 if len(ranges)>0 and ranges[0]!='0':
910 if len(ranges)>0 and ranges[0]!='0':
911 y = self.mask_ranges(y, ranges)
911 y = self.mask_ranges(y, ranges)
912
912
913 elif self.line_type.name=='flip':
913 elif self.line_type.name=='flip':
914 n = float(json.loads(self.params)['number_of_flips'])
914 n = float(json.loads(self.params)['number_of_flips'])
915 width = n*ipp*km2unit
915 width = n*ipp*km2unit
916 y = self.points(int((ntx+1)/(2*n)), ipp_u*n*2, width)
916 y = self.points(int((ntx+1)/(2*n)), ipp_u*n*2, width)
917
917
918 elif self.line_type.name=='codes':
918 elif self.line_type.name=='codes':
919 params = json.loads(self.params)
919 params = json.loads(self.params)
920 tx = RCLine.objects.get(pk=params['TX_ref'])
920 tx = RCLine.objects.get(pk=params['TX_ref'])
921 tx_params = json.loads(tx.params)
921 tx_params = json.loads(tx.params)
922 delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
922 delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
923 f = int(float(tx_params['pulse_width'])*km2unit/len(params['codes'][0]))
923 f = int(float(tx_params['pulse_width'])*km2unit/len(params['codes'][0]))
924 codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in params['codes']]
924 codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in params['codes']]
925 codes = [self.array_to_points(code) for code in codes]
925 codes = [self.array_to_points(code) for code in codes]
926 n = len(codes)
926 n = len(codes)
927
927
928 ranges = tx_params['range'].split(',')
928 ranges = tx_params['range'].split(',')
929 if len(ranges)>0 and ranges[0]!='0':
929 if len(ranges)>0 and ranges[0]!='0':
930 dum = self.mask_ranges(tx.pulses_as_points(), ranges)
930 dum = self.mask_ranges(tx.pulses_as_points(), ranges)
931 else:
931 else:
932 dum = tx.pulses_as_points()
932 dum = tx.pulses_as_points()
933
933
934 for i, tup in enumerate(dum):
934 for i, tup in enumerate(dum):
935 if tup==(0,0): continue
935 if tup==(0,0): continue
936 code = codes[i%n]
936 code = codes[i%n]
937 y.extend([(c[0]+tup[0], c[1]+tup[0]) for c in code])
937 y.extend([(c[0]+tup[0], c[1]+tup[0]) for c in code])
938
938
939 elif self.line_type.name=='sync':
939 elif self.line_type.name=='sync':
940 params = json.loads(self.params)
940 params = json.loads(self.params)
941 n = ipp_u*ntx
941 n = ipp_u*ntx
942 if params['invert'] in ('1', 1):
942 if params['invert'] in ('1', 1):
943 y = [(n-1, n)]
943 y = [(n-1, n)]
944 else:
944 else:
945 y = [(0, 1)]
945 y = [(0, 1)]
946
946
947 elif self.line_type.name=='prog_pulses':
947 elif self.line_type.name=='prog_pulses':
948 params = json.loads(self.params)
948 params = json.loads(self.params)
949 if int(params['periodic'])==0:
949 if int(params['periodic'])==0:
950 nntx = 1
950 nntx = 1
951 nipp = ipp_u*ntx
951 nipp = ipp_u*ntx
952 else:
952 else:
953 nntx = ntx
953 nntx = ntx
954 nipp = ipp_u
954 nipp = ipp_u
955
955
956 if 'params' in params and len(params['params'])>0:
956 if 'params' in params and len(params['params'])>0:
957 for p in params['params']:
957 for p in params['params']:
958 y_pp = self.points(nntx, nipp,
958 y_pp = self.points(nntx, nipp,
959 p['end']-p['begin'],
959 p['end']-p['begin'],
960 before=p['begin'])
960 before=p['begin'])
961
961
962 y.extend(y_pp)
962 y.extend(y_pp)
963
963
964 elif self.line_type.name=='windows':
964 elif self.line_type.name=='windows':
965 params = json.loads(self.params)
965 params = json.loads(self.params)
966 if 'params' in params and len(params['params'])>0:
966 if 'params' in params and len(params['params'])>0:
967 tx = RCLine.objects.get(pk=params['TX_ref'])
967 tx = RCLine.objects.get(pk=params['TX_ref'])
968 tx_params = json.loads(tx.params)
968 tx_params = json.loads(tx.params)
969 ranges = tx_params['range'].split(',')
969 ranges = tx_params['range'].split(',')
970 for p in params['params']:
970 for p in params['params']:
971 y_win = self.points(ntx, ipp_u,
971 y_win = self.points(ntx, ipp_u,
972 p['resolution']*p['number_of_samples']*km2unit,
972 p['resolution']*p['number_of_samples']*km2unit,
973 before=int(self.rc_configuration.time_before*us2unit)+p['first_height']*km2unit,
973 before=int(self.rc_configuration.time_before*us2unit)+p['first_height']*km2unit,
974 sync=self.rc_configuration.sync+self.get_win_ref(p, params['TX_ref'], km2unit))
974 sync=self.rc_configuration.sync+self.get_win_ref(p, params['TX_ref'], km2unit))
975
975
976
976
977 if len(ranges)>0 and ranges[0]!='0':
977 if len(ranges)>0 and ranges[0]!='0':
978 y_win = self.mask_ranges(y_win, ranges)
978 y_win = self.mask_ranges(y_win, ranges)
979
979
980 y.extend(y_win)
980 y.extend(y_win)
981
981
982 elif self.line_type.name=='mix':
982 elif self.line_type.name=='mix':
983 values = self.rc_configuration.parameters.split('-')
983 values = self.rc_configuration.parameters.split('-')
984 confs = [RCConfiguration.objects.get(pk=value.split('|')[0]) for value in values]
984 confs = [RCConfiguration.objects.get(pk=value.split('|')[0]) for value in values]
985 modes = [value.split('|')[1] for value in values]
985 modes = [value.split('|')[1] for value in values]
986 ops = [value.split('|')[2] for value in values]
986 ops = [value.split('|')[2] for value in values]
987 delays = [value.split('|')[3] for value in values]
987 delays = [value.split('|')[3] for value in values]
988 masks = [value.split('|')[4] for value in values]
988 masks = [value.split('|')[4] for value in values]
989 print("masks")
989 print("masks")
990 print(masks)
990 print(masks)
991 print('{:8b}'.format(int(masks[0])))
991 print('{:8b}'.format(int(masks[0])))
992 mask = list('{:8b}'.format(int(masks[0])))
992 mask = list('{:8b}'.format(int(masks[0])))
993 print("mask")
993 print("mask")
994 print(mask)
994 print(mask)
995 mask.reverse()
995 mask.reverse()
996 print("mask reverse")
996 print("mask reverse")
997 print(mask)
997 print(mask)
998 if mask[self.channel] in ('0', '', ' '):
998 if mask[self.channel] in ('0', '', ' '):
999 y = np.zeros(confs[0].total_units, dtype=np.int8)
999 y = np.zeros(confs[0].total_units, dtype=np.int8)
1000 else:
1000 else:
1001 y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
1001 y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
1002
1002
1003 for i in range(1, len(values)):
1003 for i in range(1, len(values)):
1004 mask = list('{:8b}'.format(int(masks[i])))
1004 mask = list('{:8b}'.format(int(masks[i])))
1005 mask.reverse()
1005 mask.reverse()
1006
1006
1007 if mask[self.channel] in ('0', '', ' '):
1007 if mask[self.channel] in ('0', '', ' '):
1008 continue
1008 continue
1009 Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
1009 Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
1010 delay = float(delays[i])*km2unit
1010 delay = float(delays[i])*km2unit
1011
1011
1012 if modes[i]=='P':
1012 if modes[i]=='P':
1013 if delay>0:
1013 if delay>0:
1014 if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y):
1014 if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y):
1015 y_temp = np.empty_like(Y)
1015 y_temp = np.empty_like(Y)
1016 y_temp[:delay] = 0
1016 y_temp[:delay] = 0
1017 y_temp[delay:] = Y[:-delay]
1017 y_temp[delay:] = Y[:-delay]
1018 elif delay+len(Y)>len(y):
1018 elif delay+len(Y)>len(y):
1019 y_new = np.zeros(delay+len(Y), dtype=np.int8)
1019 y_new = np.zeros(delay+len(Y), dtype=np.int8)
1020 y_new[:len(y)] = y
1020 y_new[:len(y)] = y
1021 y = y_new
1021 y = y_new
1022 y_temp = np.zeros(delay+len(Y), dtype=np.int8)
1022 y_temp = np.zeros(delay+len(Y), dtype=np.int8)
1023 y_temp[-len(Y):] = Y
1023 y_temp[-len(Y):] = Y
1024 elif delay+len(Y)==len(y):
1024 elif delay+len(Y)==len(y):
1025 y_temp = np.zeros(delay+len(Y))
1025 y_temp = np.zeros(delay+len(Y))
1026 y_temp[-len(Y):] = Y
1026 y_temp[-len(Y):] = Y
1027 elif delay+len(Y)<len(y):
1027 elif delay+len(Y)<len(y):
1028 y_temp = np.zeros(len(y), dtype=np.int8)
1028 y_temp = np.zeros(len(y), dtype=np.int8)
1029 y_temp[delay:delay+len(Y)] = Y
1029 y_temp[delay:delay+len(Y)] = Y
1030 else:
1030 else:
1031 y_temp = Y.copy()
1031 y_temp = Y.copy()
1032
1032
1033 if ops[i]=='OR':
1033 if ops[i]=='OR':
1034 y = y | y_temp
1034 y = y | y_temp
1035 elif ops[i]=='XOR':
1035 elif ops[i]=='XOR':
1036 y = y ^ y_temp
1036 y = y ^ y_temp
1037 elif ops[i]=='AND':
1037 elif ops[i]=='AND':
1038 y = y & y_temp
1038 y = y & y_temp
1039 elif ops[i]=='NAND':
1039 elif ops[i]=='NAND':
1040 y = y & ~y_temp
1040 y = y & ~y_temp
1041 else:
1041 else:
1042 y = np.concatenate([y, Y])
1042 y = np.concatenate([y, Y])
1043
1043
1044 total = len(y)
1044 total = len(y)
1045 y = self.array_to_points(y)
1045 y = self.array_to_points(y)
1046
1046
1047 else:
1047 else:
1048 y = []
1048 y = []
1049
1049
1050 if self.rc_configuration.total_units != total:
1050 if self.rc_configuration.total_units != total:
1051 self.rc_configuration.total_units = total
1051 self.rc_configuration.total_units = total
1052 self.rc_configuration.save()
1052 self.rc_configuration.save()
1053
1053
1054 self.pulses = str(y)
1054 self.pulses = str(y)
1055 self.save()
1055 self.save()
1056
1056
1057 @staticmethod
1057 @staticmethod
1058 def array_to_points(X):
1058 def array_to_points(X):
1059
1059
1060 if X.size==0:
1060 if X.size==0:
1061 return []
1061 return []
1062
1062
1063 d = X[1:]-X[:-1]
1063 d = X[1:]-X[:-1]
1064
1064
1065 up = np.where(d==1)[0]
1065 up = np.where(d==1)[0]
1066 if X[0]==1:
1066 if X[0]==1:
1067 up = np.concatenate((np.array([-1]), up))
1067 up = np.concatenate((np.array([-1]), up))
1068 up += 1
1068 up += 1
1069
1069
1070 dw = np.where(d==-1)[0]
1070 dw = np.where(d==-1)[0]
1071 if X[-1]==1:
1071 if X[-1]==1:
1072 dw = np.concatenate((dw, np.array([len(X)-1])))
1072 dw = np.concatenate((dw, np.array([len(X)-1])))
1073 dw += 1
1073 dw += 1
1074
1074
1075 return [(tup[0], tup[1]) for tup in zip(up, dw)]
1075 return [(tup[0], tup[1]) for tup in zip(up, dw)]
1076
1076
1077 @staticmethod
1077 @staticmethod
1078 def mask_ranges(Y, ranges):
1078 def mask_ranges(Y, ranges):
1079
1079
1080 y = [(0, 0) for __ in Y]
1080 y = [(0, 0) for __ in Y]
1081
1081
1082 for index in ranges:
1082 for index in ranges:
1083 if '-' in index:
1083 if '-' in index:
1084 args = [int(a) for a in index.split('-')]
1084 args = [int(a) for a in index.split('-')]
1085 y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
1085 y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
1086 else:
1086 else:
1087 y[int(index)-1] = Y[int(index)-1]
1087 y[int(index)-1] = Y[int(index)-1]
1088
1088
1089 return y
1089 return y
1090
1090
1091 @staticmethod
1091 @staticmethod
1092 def points(ntx, ipp, width, delay=[0], before=0, after=0, sync=0):
1092 def points(ntx, ipp, width, delay=[0], before=0, after=0, sync=0):
1093
1093
1094 delays = len(delay)
1094 delays = len(delay)
1095
1095
1096 Y = [(int(ipp*x+before+delay[x%delays]+sync), int(ipp*x+width+before+delay[x%delays]+after+sync)) for x in range(ntx)]
1096 Y = [(int(ipp*x+before+delay[x%delays]+sync), int(ipp*x+width+before+delay[x%delays]+after+sync)) for x in range(ntx)]
1097
1097
1098 return Y
1098 return Y
1099
1099
1100 class RCClock(models.Model):
1100 class RCClock(models.Model):
1101
1101
1102 rc_configuration = models.ForeignKey('RCConfiguration', on_delete=models.CASCADE)
1102 rc_configuration = models.ForeignKey('RCConfiguration', on_delete=models.CASCADE)
1103 mode = models.BooleanField(default=True, choices=((True, 'Auto'), (False, 'Manual')))
1103 mode = models.BooleanField(default=True, choices=((True, 'Auto'), (False, 'Manual')))
1104 multiplier = models.PositiveIntegerField(default=60)
1104 multiplier = models.PositiveIntegerField(default=60)
1105 divisor = models.PositiveIntegerField(default=10)
1105 divisor = models.PositiveIntegerField(default=10)
1106 reference = models.PositiveSmallIntegerField(default=1, choices=((0, 'Internal (25MHz)'), (1, 'External (10MHz)')))
1106 reference = models.PositiveSmallIntegerField(default=1, choices=((0, 'Internal (25MHz)'), (1, 'External (10MHz)')))
1107 frequency = models.FloatField(default=60.0)
1107 frequency = models.FloatField(default=60.0)
General Comments 0
You need to be logged in to leave comments. Login now