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