##// END OF EJS Templates
Fix importing racp, fix sub-baudio windows reference ...
Juan C. Espinoza -
r237:d6f68eb3d3c3
parent child
Show More
@@ -1,969 +1,972
1
1
2 import ast
2 import ast
3 import json
3 import json
4 import requests
4 import requests
5 import numpy as np
5 import numpy as np
6 from base64 import b64encode
6 from base64 import b64encode
7 from struct import pack
7 from struct import pack
8
8
9 from django.db import models
9 from django.db import models
10 from django.core.urlresolvers import reverse
10 from django.core.urlresolvers import reverse
11 from django.core.validators import MinValueValidator, MaxValueValidator
11 from django.core.validators import MinValueValidator, MaxValueValidator
12
12
13 from apps.main.models import Configuration
13 from apps.main.models import Configuration
14 from devices.rc import api
14 from devices.rc import api
15 from .utils import RCFile
15 from .utils import RCFile
16
16
17 # Create your models here.
17 # Create your models here.
18
18
19 LINE_TYPES = (
19 LINE_TYPES = (
20 ('none', 'Not used'),
20 ('none', 'Not used'),
21 ('tr', 'Transmission/reception selector signal'),
21 ('tr', 'Transmission/reception selector signal'),
22 ('tx', 'A modulating signal (Transmission pulse)'),
22 ('tx', 'A modulating signal (Transmission pulse)'),
23 ('codes', 'BPSK modulating signal'),
23 ('codes', 'BPSK modulating signal'),
24 ('windows', 'Sample window signal'),
24 ('windows', 'Sample window signal'),
25 ('sync', 'Synchronizing signal'),
25 ('sync', 'Synchronizing signal'),
26 ('flip', 'IPP related periodic signal'),
26 ('flip', 'IPP related periodic signal'),
27 ('prog_pulses', 'Programmable pulse'),
27 ('prog_pulses', 'Programmable pulse'),
28 ('mix', 'Mixed line'),
28 ('mix', 'Mixed line'),
29 )
29 )
30
30
31
31
32 SAMPLING_REFS = (
32 SAMPLING_REFS = (
33 ('none', 'No Reference'),
33 ('none', 'No Reference'),
34 ('begin_baud', 'Begin of the first baud'),
34 ('begin_baud', 'Begin of the first baud'),
35 ('first_baud', 'Middle of the first baud'),
35 ('first_baud', 'Middle of the first baud'),
36 ('sub_baud', 'Middle of the sub-baud')
36 ('sub_baud', 'Middle of the sub-baud')
37 )
37 )
38
38
39 DAT_CMDS = {
39 DAT_CMDS = {
40 # Pulse Design commands
40 # Pulse Design commands
41 'DISABLE' : 0, # Disables pulse generation
41 'DISABLE' : 0, # Disables pulse generation
42 'ENABLE' : 24, # Enables pulse generation
42 'ENABLE' : 24, # Enables pulse generation
43 'DELAY_START' : 40, # Write delay status to memory
43 'DELAY_START' : 40, # Write delay status to memory
44 'FLIP_START' : 48, # Write flip status to memory
44 'FLIP_START' : 48, # Write flip status to memory
45 'SAMPLING_PERIOD' : 64, # Establish Sampling Period
45 'SAMPLING_PERIOD' : 64, # Establish Sampling Period
46 'TX_ONE' : 72, # Output '0' in line TX
46 'TX_ONE' : 72, # Output '0' in line TX
47 'TX_ZERO' : 88, # Output '0' in line TX
47 'TX_ZERO' : 88, # Output '0' in line TX
48 'SW_ONE' : 104, # Output '0' in line SW
48 'SW_ONE' : 104, # Output '0' in line SW
49 'SW_ZERO' : 112, # Output '1' in line SW
49 'SW_ZERO' : 112, # Output '1' in line SW
50 'RESTART': 120, # Restarts CR8 Firmware
50 'RESTART': 120, # Restarts CR8 Firmware
51 'CONTINUE' : 253, # Function Unknown
51 'CONTINUE' : 253, # Function Unknown
52 # Commands available to new controllers
52 # Commands available to new controllers
53 # 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.
53 # 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 'CLOCK_DIVISOR_INIT' : 12, # Specifies Clock Divisor. Legacy command, ignored in the actual .dat conversion
54 'CLOCK_DIVISOR_INIT' : 12, # Specifies Clock Divisor. Legacy command, ignored in the actual .dat conversion
55 'CLOCK_DIVISOR_LAST' : 22, # Specifies Clock Divisor (default 60 if not included) syntax: 255,22 254,N-1.
55 'CLOCK_DIVISOR_LAST' : 22, # Specifies Clock Divisor (default 60 if not included) syntax: 255,22 254,N-1.
56 'CLOCK_DIVIDER' : 8,
56 'CLOCK_DIVIDER' : 8,
57 }
57 }
58
58
59
59
60 class RCConfiguration(Configuration):
60 class RCConfiguration(Configuration):
61
61
62 ipp = models.FloatField(verbose_name='IPP [Km]', validators=[MinValueValidator(1), MaxValueValidator(9000)], default=300)
62 ipp = models.FloatField(verbose_name='IPP [Km]', validators=[MinValueValidator(1), MaxValueValidator(9000)], default=300)
63 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1), MaxValueValidator(400)], default=1)
63 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1), MaxValueValidator(400)], default=1)
64 clock_in = models.FloatField(verbose_name='Clock in [MHz]', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
64 clock_in = models.FloatField(verbose_name='Clock in [MHz]', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
65 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
65 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
66 clock = models.FloatField(verbose_name='Clock Master [MHz]', blank=True, default=1)
66 clock = models.FloatField(verbose_name='Clock Master [MHz]', blank=True, default=1)
67 time_before = models.PositiveIntegerField(verbose_name='Time before [μS]', default=12)
67 time_before = models.PositiveIntegerField(verbose_name='Time before [μS]', default=12)
68 time_after = models.PositiveIntegerField(verbose_name='Time after [μS]', default=1)
68 time_after = models.PositiveIntegerField(verbose_name='Time after [μS]', default=1)
69 sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
69 sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
70 sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40)
70 sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40)
71 control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False)
71 control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False)
72 control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
72 control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
73 total_units = models.PositiveIntegerField(default=0)
73 total_units = models.PositiveIntegerField(default=0)
74 mix = models.BooleanField(default=False)
74 mix = models.BooleanField(default=False)
75
75
76 class Meta:
76 class Meta:
77 db_table = 'rc_configurations'
77 db_table = 'rc_configurations'
78
78
79 def get_absolute_url_plot(self):
79 def get_absolute_url_plot(self):
80 return reverse('url_plot_rc_pulses', args=[str(self.id)])
80 return reverse('url_plot_rc_pulses', args=[str(self.id)])
81
81
82 def get_absolute_url_import(self):
82 def get_absolute_url_import(self):
83 return reverse('url_import_rc_conf', args=[str(self.id)])
83 return reverse('url_import_rc_conf', args=[str(self.id)])
84
84
85 @property
85 @property
86 def ipp_unit(self):
86 def ipp_unit(self):
87
87
88 return '{} ({})'.format(self.ipp, int(self.ipp*self.km2unit))
88 return '{} ({})'.format(self.ipp, int(self.ipp*self.km2unit))
89
89
90 @property
90 @property
91 def us2unit(self):
91 def us2unit(self):
92
92
93 return self.clock_in/self.clock_divider
93 return self.clock_in/self.clock_divider
94
94
95 @property
95 @property
96 def km2unit(self):
96 def km2unit(self):
97
97
98 return 20./3*(self.clock_in/self.clock_divider)
98 return 20./3*(self.clock_in/self.clock_divider)
99
99
100 def clone(self, **kwargs):
100 def clone(self, **kwargs):
101
101
102 lines = self.get_lines()
102 lines = self.get_lines()
103 self.pk = None
103 self.pk = None
104 self.id = None
104 self.id = None
105 for attr, value in kwargs.items():
105 for attr, value in kwargs.items():
106 setattr(self, attr, value)
106 setattr(self, attr, value)
107 self.save()
107 self.save()
108
108
109 for line in lines:
109 for line in lines:
110 line.clone(rc_configuration=self)
110 line.clone(rc_configuration=self)
111
111
112 return self
112 return self
113
113
114 def get_lines(self, **kwargs):
114 def get_lines(self, **kwargs):
115 '''
115 '''
116 Retrieve configuration lines
116 Retrieve configuration lines
117 '''
117 '''
118
118
119 return RCLine.objects.filter(rc_configuration=self.pk, **kwargs)
119 return RCLine.objects.filter(rc_configuration=self.pk, **kwargs)
120
120
121
121
122 def clean_lines(self):
122 def clean_lines(self):
123 '''
123 '''
124 '''
124 '''
125
125
126 empty_line = RCLineType.objects.get(name='none')
126 empty_line = RCLineType.objects.get(name='none')
127
127
128 for line in self.get_lines():
128 for line in self.get_lines():
129 line.line_type = empty_line
129 line.line_type = empty_line
130 line.params = '{}'
130 line.params = '{}'
131 line.save()
131 line.save()
132
132
133 def parms_to_dict(self):
133 def parms_to_dict(self):
134 '''
134 '''
135 '''
135 '''
136
136
137 ignored = ('parameters', 'type', 'polymorphic_ctype', 'configuration_ptr',
137 ignored = ('parameters', 'type', 'polymorphic_ctype', 'configuration_ptr',
138 'created_date', 'programmed_date')
138 'created_date', 'programmed_date')
139
139
140 data = {}
140 data = {}
141 for field in self._meta.fields:
141 for field in self._meta.fields:
142 if field.name in ignored:
142 if field.name in ignored:
143 continue
143 continue
144 data[field.name] = '{}'.format(field.value_from_object(self))
144 data[field.name] = '{}'.format(field.value_from_object(self))
145
145
146 data['device_id'] = data.pop('device')
146 data['device_id'] = data.pop('device')
147 data['lines'] = []
147 data['lines'] = []
148
148
149 for line in self.get_lines():
149 for line in self.get_lines():
150 line_data = json.loads(line.params)
150 line_data = json.loads(line.params)
151 if 'TX_ref' in line_data and line_data['TX_ref'] not in (0, '0'):
151 if 'TX_ref' in line_data and line_data['TX_ref'] not in (0, '0'):
152 line_data['TX_ref'] = RCLine.objects.get(pk=line_data['TX_ref']).get_name()
152 line_data['TX_ref'] = RCLine.objects.get(pk=line_data['TX_ref']).get_name()
153 if 'code' in line_data:
153 if 'code' in line_data:
154 line_data['code'] = RCLineCode.objects.get(pk=line_data['code']).name
154 line_data['code'] = RCLineCode.objects.get(pk=line_data['code']).name
155 line_data['type'] = line.line_type.name
155 line_data['type'] = line.line_type.name
156 line_data['name'] = line.get_name()
156 line_data['name'] = line.get_name()
157 data['lines'].append(line_data)
157 data['lines'].append(line_data)
158
158
159 data['delays'] = self.get_delays()
159 data['delays'] = self.get_delays()
160 data['pulses'] = self.get_pulses()
160 data['pulses'] = self.get_pulses()
161
161
162 return data
162 return data
163
163
164 def dict_to_parms(self, data):
164 def dict_to_parms(self, data):
165 '''
165 '''
166 '''
166 '''
167
167
168 self.name = data['name']
168 self.name = data['name']
169 self.ipp = float(data['ipp'])
169 self.ipp = float(data['ipp'])
170 self.ntx = int(data['ntx'])
170 self.ntx = int(data['ntx'])
171 self.clock_in = float(data['clock_in'])
171 self.clock_in = float(data['clock_in'])
172 self.clock_divider = int(data['clock_divider'])
172 self.clock_divider = int(data['clock_divider'])
173 self.clock = float(data['clock'])
173 self.clock = float(data['clock'])
174 self.time_before = data['time_before']
174 self.time_before = data['time_before']
175 self.time_after = data['time_after']
175 self.time_after = data['time_after']
176 self.sync = data['sync']
176 self.sync = data['sync']
177 self.sampling_reference = data['sampling_reference']
177 self.sampling_reference = data['sampling_reference']
178 self.total_units = self.ipp*self.ntx*self.km2unit
178 self.total_units = self.ipp*self.ntx*self.km2unit
179 self.save()
179 self.save()
180 self.clean_lines()
180 self.clean_lines()
181
181
182 lines = []
182 lines = []
183 positions = {'tx':0, 'tr':0}
183 positions = {'tx':0, 'tr':0}
184
184
185 for i, line_data in enumerate(data['lines']):
185 for i, line_data in enumerate(data['lines']):
186 name = line_data.pop('name', '')
186 name = line_data.pop('name', '')
187 line_type = RCLineType.objects.get(name=line_data.pop('type'))
187 line_type = RCLineType.objects.get(name=line_data.pop('type'))
188 if line_type.name=='codes':
188 if line_type.name=='codes':
189 code = RCLineCode.objects.get(name=line_data['code'])
189 code = RCLineCode.objects.get(name=line_data['code'])
190 line_data['code'] = code.pk
190 line_data['code'] = code.pk
191 line = RCLine.objects.filter(rc_configuration=self, channel=i)
191 line = RCLine.objects.filter(rc_configuration=self, channel=i)
192 if line:
192 if line:
193 line = line[0]
193 line = line[0]
194 line.line_type = line_type
194 line.line_type = line_type
195 line.params = json.dumps(line_data)
195 line.params = json.dumps(line_data)
196 else:
196 else:
197 line = RCLine(rc_configuration=self, line_type=line_type,
197 line = RCLine(rc_configuration=self, line_type=line_type,
198 params=json.dumps(line_data),
198 params=json.dumps(line_data),
199 channel=i)
199 channel=i)
200
200
201 if line_type.name=='tx':
201 if line_type.name=='tx':
202 line.position = positions['tx']
202 line.position = positions['tx']
203 positions['tx'] += 1
203 positions['tx'] += 1
204
204
205 if line_type.name=='tr':
205 if line_type.name=='tr':
206 line.position = positions['tr']
206 line.position = positions['tr']
207 positions['tr'] += 1
207 positions['tr'] += 1
208
208
209 line.save()
209 line.save()
210 lines.append(line)
210 lines.append(line)
211
211
212 for line, line_data in zip(lines, data['lines']):
212 for line, line_data in zip(lines, data['lines']):
213 if 'TX_ref' in line_data:
213 if 'TX_ref' in line_data:
214 params = json.loads(line.params)
214 params = json.loads(line.params)
215 if line_data['TX_ref'] in (0, '0'):
215 if line_data['TX_ref'] in (0, '0'):
216 params['TX_ref'] = '0'
216 params['TX_ref'] = '0'
217 else:
217 else:
218 params['TX_ref'] = [l.pk for l in lines if l.line_type.name=='tx' and line_data['TX_ref'] in l.get_name()][0]
218 params['TX_ref'] = [l.pk for l in lines if l.line_type.name=='tx' and line_data['TX_ref'] in l.get_name()][0]
219 line.params = json.dumps(params)
219 line.params = json.dumps(params)
220 line.save()
220 line.save()
221
221
222
222
223 def get_delays(self):
223 def get_delays(self):
224
224
225 pulses = [line.pulses_as_points() for line in self.get_lines()]
225 pulses = [line.pulses_as_points() for line in self.get_lines()]
226 points = [tup for tups in pulses for tup in tups]
226 points = [tup for tups in pulses for tup in tups]
227 points = set([x for tup in points for x in tup])
227 points = set([x for tup in points for x in tup])
228 points = list(points)
228 points = list(points)
229 points.sort()
229 points.sort()
230
230
231 if points[0]!=0:
231 if points[0]!=0:
232 points.insert(0, 0)
232 points.insert(0, 0)
233
233
234 return [points[i+1]-points[i] for i in range(len(points)-1)]
234 return [points[i+1]-points[i] for i in range(len(points)-1)]
235
235
236
236
237 def get_pulses(self, binary=True):
237 def get_pulses(self, binary=True):
238
238
239
239
240 pulses = [line.pulses_as_points() for line in self.get_lines()]
240 pulses = [line.pulses_as_points() for line in self.get_lines()]
241 tuples = [tup for tups in pulses for tup in tups]
241 tuples = [tup for tups in pulses for tup in tups]
242 points = set([x for tup in tuples for x in tup])
242 points = set([x for tup in tuples for x in tup])
243 points = list(points)
243 points = list(points)
244 points.sort()
244 points.sort()
245 states = []
245 states = []
246 last = [0 for x in pulses]
246 last = [0 for x in pulses]
247
247
248 for x in points:
248 for x in points:
249 dum = []
249 dum = []
250 for i,tups in enumerate(pulses):
250 for i,tups in enumerate(pulses):
251 ups = [tup[0] for tup in tups]
251 ups = [tup[0] for tup in tups]
252 dws = [tup[1] for tup in tups]
252 dws = [tup[1] for tup in tups]
253 if x in ups:
253 if x in ups:
254 dum.append(1)
254 dum.append(1)
255 elif x in dws:
255 elif x in dws:
256 dum.append(0)
256 dum.append(0)
257 else:
257 else:
258 dum.append(last[i])
258 dum.append(last[i])
259 states.append(dum)
259 states.append(dum)
260 last = dum
260 last = dum
261
261
262 if binary:
262 if binary:
263 ret = []
263 ret = []
264 for flips in states:
264 for flips in states:
265 flips.reverse()
265 flips.reverse()
266 ret.append(int(''.join([str(x) for x in flips]), 2))
266 ret.append(int(''.join([str(x) for x in flips]), 2))
267 states = ret
267 states = ret
268
268
269 return states[:-1]
269 return states[:-1]
270
270
271 def add_cmd(self, cmd):
271 def add_cmd(self, cmd):
272
272
273 if cmd in DAT_CMDS:
273 if cmd in DAT_CMDS:
274 return (255, DAT_CMDS[cmd])
274 return (255, DAT_CMDS[cmd])
275
275
276 def add_data(self, value):
276 def add_data(self, value):
277
277
278 return (254, value-1)
278 return (254, value-1)
279
279
280 def parms_to_binary(self, dat=True):
280 def parms_to_binary(self, dat=True):
281 '''
281 '''
282 Create "dat" stream to be send to CR
282 Create "dat" stream to be send to CR
283 '''
283 '''
284
284
285 data = bytearray()
285 data = bytearray()
286 # create header
286 # create header
287 data.extend(self.add_cmd('DISABLE'))
287 data.extend(self.add_cmd('DISABLE'))
288 data.extend(self.add_cmd('CONTINUE'))
288 data.extend(self.add_cmd('CONTINUE'))
289 data.extend(self.add_cmd('RESTART'))
289 data.extend(self.add_cmd('RESTART'))
290
290
291 if self.control_sw:
291 if self.control_sw:
292 data.extend(self.add_cmd('SW_ONE'))
292 data.extend(self.add_cmd('SW_ONE'))
293 else:
293 else:
294 data.extend(self.add_cmd('SW_ZERO'))
294 data.extend(self.add_cmd('SW_ZERO'))
295
295
296 if self.control_tx:
296 if self.control_tx:
297 data.extend(self.add_cmd('TX_ONE'))
297 data.extend(self.add_cmd('TX_ONE'))
298 else:
298 else:
299 data.extend(self.add_cmd('TX_ZERO'))
299 data.extend(self.add_cmd('TX_ZERO'))
300
300
301 # write divider
301 # write divider
302 data.extend(self.add_cmd('CLOCK_DIVIDER'))
302 data.extend(self.add_cmd('CLOCK_DIVIDER'))
303 data.extend(self.add_data(self.clock_divider))
303 data.extend(self.add_data(self.clock_divider))
304
304
305 # write delays
305 # write delays
306 data.extend(self.add_cmd('DELAY_START'))
306 data.extend(self.add_cmd('DELAY_START'))
307 # first delay is always zero
307 # first delay is always zero
308 data.extend(self.add_data(1))
308 data.extend(self.add_data(1))
309
309
310 delays = self.get_delays()
310 delays = self.get_delays()
311
311
312 for delay in delays:
312 for delay in delays:
313 while delay>252:
313 while delay>252:
314 data.extend(self.add_data(253))
314 data.extend(self.add_data(253))
315 delay -= 253
315 delay -= 253
316 data.extend(self.add_data(int(delay)))
316 data.extend(self.add_data(int(delay)))
317
317
318 # write flips
318 # write flips
319 data.extend(self.add_cmd('FLIP_START'))
319 data.extend(self.add_cmd('FLIP_START'))
320
320
321 states = self.get_pulses(binary=False)
321 states = self.get_pulses(binary=False)
322
322
323 for flips, delay in zip(states, delays):
323 for flips, delay in zip(states, delays):
324 flips.reverse()
324 flips.reverse()
325 flip = int(''.join([str(x) for x in flips]), 2)
325 flip = int(''.join([str(x) for x in flips]), 2)
326 data.extend(self.add_data(flip+1))
326 data.extend(self.add_data(flip+1))
327 while delay>252:
327 while delay>252:
328 data.extend(self.add_data(1))
328 data.extend(self.add_data(1))
329 delay -= 253
329 delay -= 253
330
330
331 # write sampling period
331 # write sampling period
332 data.extend(self.add_cmd('SAMPLING_PERIOD'))
332 data.extend(self.add_cmd('SAMPLING_PERIOD'))
333 wins = self.get_lines(line_type__name='windows')
333 wins = self.get_lines(line_type__name='windows')
334 if wins:
334 if wins:
335 win_params = json.loads(wins[0].params)['params']
335 win_params = json.loads(wins[0].params)['params']
336 if win_params:
336 if win_params:
337 dh = int(win_params[0]['resolution']*self.km2unit)
337 dh = int(win_params[0]['resolution']*self.km2unit)
338 else:
338 else:
339 dh = 1
339 dh = 1
340 else:
340 else:
341 dh = 1
341 dh = 1
342 data.extend(self.add_data(dh))
342 data.extend(self.add_data(dh))
343
343
344 # write enable
344 # write enable
345 data.extend(self.add_cmd('ENABLE'))
345 data.extend(self.add_cmd('ENABLE'))
346
346
347 if not dat:
347 if not dat:
348 return data
348 return data
349
349
350 return '\n'.join(['{}'.format(x) for x in data])
350 return '\n'.join(['{}'.format(x) for x in data])
351
351
352
352
353 def update_from_file(self, filename):
353 def update_from_file(self, filename):
354 '''
354 '''
355 Update instance from file
355 Update instance from file
356 '''
356 '''
357
357
358 f = RCFile(filename)
358 f = RCFile(filename)
359 self.dict_to_parms(f.data)
359 self.dict_to_parms(f.data)
360 self.update_pulses()
360 self.update_pulses()
361
361
362 def update_pulses(self):
362 def update_pulses(self):
363
363
364 for line in self.get_lines():
364 for line in self.get_lines():
365 line.update_pulses()
365 line.update_pulses()
366
366
367 def plot_pulses2(self, km=False):
367 def plot_pulses2(self, km=False):
368
368
369 import matplotlib.pyplot as plt
369 import matplotlib.pyplot as plt
370 from bokeh.resources import CDN
370 from bokeh.resources import CDN
371 from bokeh.embed import components
371 from bokeh.embed import components
372 from bokeh.mpl import to_bokeh
372 from bokeh.mpl import to_bokeh
373 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
373 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
374
374
375 lines = self.get_lines()
375 lines = self.get_lines()
376
376
377 N = len(lines)
377 N = len(lines)
378 npoints = self.total_units/self.km2unit if km else self.total_units
378 npoints = self.total_units/self.km2unit if km else self.total_units
379 fig = plt.figure(figsize=(12, 2+N*0.5))
379 fig = plt.figure(figsize=(12, 2+N*0.5))
380 ax = fig.add_subplot(111)
380 ax = fig.add_subplot(111)
381 labels = ['IPP']
381 labels = ['IPP']
382
382
383 for i, line in enumerate(lines):
383 for i, line in enumerate(lines):
384 labels.append(line.get_name(channel=True))
384 labels.append(line.get_name(channel=True))
385 l = ax.plot((0, npoints),(N-i-1, N-i-1))
385 l = ax.plot((0, npoints),(N-i-1, N-i-1))
386 points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
386 points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
387 ax.broken_barh(points, (N-i-1, 0.5),
387 ax.broken_barh(points, (N-i-1, 0.5),
388 edgecolor=l[0].get_color(), facecolor='none')
388 edgecolor=l[0].get_color(), facecolor='none')
389
389
390 n = 0
390 n = 0
391 f = ((self.ntx+50)/100)*5 if ((self.ntx+50)/100)*10>0 else 2
391 f = ((self.ntx+50)/100)*5 if ((self.ntx+50)/100)*10>0 else 2
392 for x in np.arange(0, npoints, self.ipp if km else self.ipp*self.km2unit):
392 for x in np.arange(0, npoints, self.ipp if km else self.ipp*self.km2unit):
393 if n%f==0:
393 if n%f==0:
394 ax.text(x, N, '%s' % n, size=10)
394 ax.text(x, N, '%s' % n, size=10)
395 n += 1
395 n += 1
396
396
397
397
398 labels.reverse()
398 labels.reverse()
399 ax.set_yticks(range(len(labels)))
399 ax.set_yticks(range(len(labels)))
400 ax.set_yticklabels(labels)
400 ax.set_yticklabels(labels)
401 ax.set_xlabel = 'Units'
401 ax.set_xlabel = 'Units'
402 plot = to_bokeh(fig, use_pandas=False)
402 plot = to_bokeh(fig, use_pandas=False)
403 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), SaveTool()]
403 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), SaveTool()]
404 plot.toolbar_location="above"
404 plot.toolbar_location="above"
405
405
406 return components(plot, CDN)
406 return components(plot, CDN)
407
407
408 def plot_pulses(self, km=False):
408 def plot_pulses(self, km=False):
409
409
410 from bokeh.plotting import figure
410 from bokeh.plotting import figure
411 from bokeh.resources import CDN
411 from bokeh.resources import CDN
412 from bokeh.embed import components
412 from bokeh.embed import components
413 from bokeh.models import FixedTicker, PrintfTickFormatter
413 from bokeh.models import FixedTicker, PrintfTickFormatter
414 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
414 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
415 from bokeh.models.sources import ColumnDataSource
415 from bokeh.models.sources import ColumnDataSource
416
416
417 lines = self.get_lines().reverse()
417 lines = self.get_lines().reverse()
418
418
419 N = len(lines)
419 N = len(lines)
420 npoints = self.total_units/self.km2unit if km else self.total_units
420 npoints = self.total_units/self.km2unit if km else self.total_units
421 ipp = self.ipp if km else self.ipp*self.km2unit
421 ipp = self.ipp if km else self.ipp*self.km2unit
422
422
423 hover = HoverTool(tooltips=[("Line", "@name"),
423 hover = HoverTool(tooltips=[("Line", "@name"),
424 ("IPP", "@ipp"),
424 ("IPP", "@ipp"),
425 ("X", "@left")])
425 ("X", "@left")])
426
426
427 tools = [PanTool(dimensions=['width']),
427 tools = [PanTool(dimensions=['width']),
428 WheelZoomTool(dimensions=['width']),
428 WheelZoomTool(dimensions=['width']),
429 hover, SaveTool()]
429 hover, SaveTool()]
430
430
431 plot = figure(width=1000,
431 plot = figure(width=1000,
432 height=40+N*50,
432 height=40+N*50,
433 y_range = (0, N),
433 y_range = (0, N),
434 tools=tools,
434 tools=tools,
435 toolbar_location='above',
435 toolbar_location='above',
436 toolbar_sticky=False,)
436 toolbar_sticky=False,)
437
437
438 plot.xaxis.axis_label = 'Km' if km else 'Units'
438 plot.xaxis.axis_label = 'Km' if km else 'Units'
439 plot.xaxis[0].formatter = PrintfTickFormatter(format='%d')
439 plot.xaxis[0].formatter = PrintfTickFormatter(format='%d')
440 plot.yaxis.axis_label = 'Pulses'
440 plot.yaxis.axis_label = 'Pulses'
441 plot.yaxis[0].ticker=FixedTicker(ticks=list(range(N)))
441 plot.yaxis[0].ticker=FixedTicker(ticks=list(range(N)))
442 plot.yaxis[0].formatter = PrintfTickFormatter(format='Line %d')
442 plot.yaxis[0].formatter = PrintfTickFormatter(format='Line %d')
443
443
444 for i, line in enumerate(lines):
444 for i, line in enumerate(lines):
445
445
446 points = [tup for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
446 points = [tup for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
447
447
448 source = ColumnDataSource(data = dict(
448 source = ColumnDataSource(data = dict(
449 bottom = [i for tup in points],
449 bottom = [i for tup in points],
450 top = [i+0.5 for tup in points],
450 top = [i+0.5 for tup in points],
451 left = [tup[0] for tup in points],
451 left = [tup[0] for tup in points],
452 right = [tup[1] for tup in points],
452 right = [tup[1] for tup in points],
453 ipp = [int(tup[0]/ipp) for tup in points],
453 ipp = [int(tup[0]/ipp) for tup in points],
454 name = [line.get_name() for tup in points]
454 name = [line.get_name() for tup in points]
455 ))
455 ))
456
456
457 plot.quad(
457 plot.quad(
458 bottom = 'bottom',
458 bottom = 'bottom',
459 top = 'top',
459 top = 'top',
460 left = 'left',
460 left = 'left',
461 right = 'right',
461 right = 'right',
462 source = source,
462 source = source,
463 fill_alpha = 0,
463 fill_alpha = 0,
464 #line_color = 'blue',
464 #line_color = 'blue',
465 )
465 )
466
466
467 plot.line([0, npoints], [i, i])#, color='blue')
467 plot.line([0, npoints], [i, i])#, color='blue')
468
468
469 return components(plot, CDN)
469 return components(plot, CDN)
470
470
471 def status_device(self):
471 def status_device(self):
472
472
473 try:
473 try:
474 self.device.status = 0
474 self.device.status = 0
475 req = requests.get(self.device.url('status'))
475 req = requests.get(self.device.url('status'))
476 payload = req.json()
476 payload = req.json()
477 if payload['status']=='enabled':
477 if payload['status']=='enabled':
478 self.device.status = 3
478 self.device.status = 3
479 elif payload['status']=='disabled':
479 elif payload['status']=='disabled':
480 self.device.status = 2
480 self.device.status = 2
481 else:
481 else:
482 self.device.status = 1
482 self.device.status = 1
483 self.device.save()
483 self.device.save()
484 self.message = payload['status']
484 self.message = payload['status']
485 return False
485 return False
486 except Exception as e:
486 except Exception as e:
487 if 'No route to host' not in str(e):
487 if 'No route to host' not in str(e):
488 self.device.status = 4
488 self.device.status = 4
489 self.device.save()
489 self.device.save()
490 self.message = str(e)
490 self.message = str(e)
491 return False
491 return False
492
492
493 self.device.save()
493 self.device.save()
494 return True
494 return True
495
495
496 def reset_device(self):
496 def reset_device(self):
497
497
498 try:
498 try:
499 req = requests.post(self.device.url('reset'))
499 req = requests.post(self.device.url('reset'))
500 payload = req.json()
500 payload = req.json()
501 if payload['reset']=='ok':
501 if payload['reset']=='ok':
502 self.message = 'RC restarted'
502 self.message = 'RC restarted'
503 else:
503 else:
504 self.message = 'RC restart not ok'
504 self.message = 'RC restart not ok'
505 self.device.status = 4
505 self.device.status = 4
506 self.device.save()
506 self.device.save()
507 except Exception as e:
507 except Exception as e:
508 self.message = str(e)
508 self.message = str(e)
509 return False
509 return False
510
510
511 return True
511 return True
512
512
513 def stop_device(self):
513 def stop_device(self):
514
514
515 try:
515 try:
516 req = requests.post(self.device.url('stop'))
516 req = requests.post(self.device.url('stop'))
517 payload = req.json()
517 payload = req.json()
518 if payload['stop']=='ok':
518 if payload['stop']=='ok':
519 self.device.status = 2
519 self.device.status = 2
520 self.device.save()
520 self.device.save()
521 self.message = 'RC stopped'
521 self.message = 'RC stopped'
522 else:
522 else:
523 self.message = 'RC stop not ok'
523 self.message = 'RC stop not ok'
524 self.device.status = 4
524 self.device.status = 4
525 self.device.save()
525 self.device.save()
526 return False
526 return False
527 except Exception as e:
527 except Exception as e:
528 if 'No route to host' not in str(e):
528 if 'No route to host' not in str(e):
529 self.device.status = 4
529 self.device.status = 4
530 else:
530 else:
531 self.device.status = 0
531 self.device.status = 0
532 self.message = str(e)
532 self.message = str(e)
533 self.device.save()
533 self.device.save()
534 return False
534 return False
535
535
536 return True
536 return True
537
537
538 def start_device(self):
538 def start_device(self):
539
539
540 try:
540 try:
541 req = requests.post(self.device.url('start'))
541 req = requests.post(self.device.url('start'))
542 payload = req.json()
542 payload = req.json()
543 if payload['start']=='ok':
543 if payload['start']=='ok':
544 self.device.status = 3
544 self.device.status = 3
545 self.device.save()
545 self.device.save()
546 self.message = 'RC running'
546 self.message = 'RC running'
547 else:
547 else:
548 self.message = 'RC start not ok'
548 self.message = 'RC start not ok'
549 return False
549 return False
550 except Exception as e:
550 except Exception as e:
551 if 'No route to host' not in str(e):
551 if 'No route to host' not in str(e):
552 self.device.status = 4
552 self.device.status = 4
553 else:
553 else:
554 self.device.status = 0
554 self.device.status = 0
555 self.message = str(e)
555 self.message = str(e)
556 self.device.save()
556 self.device.save()
557 return False
557 return False
558
558
559 return True
559 return True
560
560
561 def write_device(self):
561 def write_device(self):
562
562
563 values = zip(self.get_pulses(),
563 values = zip(self.get_pulses(),
564 [x-1 for x in self.get_delays()])
564 [x-1 for x in self.get_delays()])
565
565
566 data = bytearray()
566 data = bytearray()
567 #reset
567 #reset
568 data.extend((128, 0))
568 data.extend((128, 0))
569 #disable
569 #disable
570 data.extend((129, 0))
570 data.extend((129, 0))
571 #divider
571 #divider
572 data.extend((131, self.clock_divider-1))
572 data.extend((131, self.clock_divider-1))
573 #enable writing
573 #enable writing
574 data.extend((139, 62))
574 data.extend((139, 62))
575
575
576 last = 0
576 last = 0
577 for tup in values:
577 for tup in values:
578 vals = pack('<HH', last^tup[0], tup[1])
578 vals = pack('<HH', last^tup[0], tup[1])
579 last = tup[0]
579 last = tup[0]
580 data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
580 data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
581
581
582 #enable
582 #enable
583 data.extend((129, 1))
583 data.extend((129, 1))
584
584
585 try:
585 try:
586 req = requests.post(self.device.url('write'), data=b64encode(data))
586 req = requests.post(self.device.url('write'), data=b64encode(data))
587 payload = req.json()
587 payload = req.json()
588 if payload['write']=='ok':
588 if payload['write']=='ok':
589 self.device.status = 2
589 self.device.status = 2
590 self.device.save()
590 self.device.save()
591 self.message = 'RC configured'
591 self.message = 'RC configured'
592 else:
592 else:
593 self.device.status = 1
593 self.device.status = 1
594 self.device.save()
594 self.device.save()
595 self.message = 'RC write not ok'
595 self.message = 'RC write not ok'
596 return False
596 return False
597
597
598 except Exception as e:
598 except Exception as e:
599 if 'No route to host' not in str(e):
599 if 'No route to host' not in str(e):
600 self.device.status = 4
600 self.device.status = 4
601 else:
601 else:
602 self.device.status = 0
602 self.device.status = 0
603 self.message = str(e)
603 self.message = str(e)
604 self.device.save()
604 self.device.save()
605 return False
605 return False
606
606
607 return True
607 return True
608
608
609
609
610 class RCLineCode(models.Model):
610 class RCLineCode(models.Model):
611
611
612 name = models.CharField(max_length=40)
612 name = models.CharField(max_length=40)
613 bits_per_code = models.PositiveIntegerField(default=0)
613 bits_per_code = models.PositiveIntegerField(default=0)
614 number_of_codes = models.PositiveIntegerField(default=0)
614 number_of_codes = models.PositiveIntegerField(default=0)
615 codes = models.TextField(blank=True, null=True)
615 codes = models.TextField(blank=True, null=True)
616
616
617 class Meta:
617 class Meta:
618 db_table = 'rc_line_codes'
618 db_table = 'rc_line_codes'
619 ordering = ('name',)
619 ordering = ('name',)
620
620
621 def __str__(self):
621 def __str__(self):
622 return u'%s' % self.name
622 return u'%s' % self.name
623
623
624
624
625 class RCLineType(models.Model):
625 class RCLineType(models.Model):
626
626
627 name = models.CharField(choices=LINE_TYPES, max_length=40)
627 name = models.CharField(choices=LINE_TYPES, max_length=40)
628 description = models.TextField(blank=True, null=True)
628 description = models.TextField(blank=True, null=True)
629 params = models.TextField(default='[]')
629 params = models.TextField(default='[]')
630
630
631 class Meta:
631 class Meta:
632 db_table = 'rc_line_types'
632 db_table = 'rc_line_types'
633
633
634 def __str__(self):
634 def __str__(self):
635 return u'%s - %s' % (self.name.upper(), self.get_name_display())
635 return u'%s - %s' % (self.name.upper(), self.get_name_display())
636
636
637
637
638 class RCLine(models.Model):
638 class RCLine(models.Model):
639
639
640 rc_configuration = models.ForeignKey(RCConfiguration, on_delete=models.CASCADE)
640 rc_configuration = models.ForeignKey(RCConfiguration, on_delete=models.CASCADE)
641 line_type = models.ForeignKey(RCLineType)
641 line_type = models.ForeignKey(RCLineType)
642 channel = models.PositiveIntegerField(default=0)
642 channel = models.PositiveIntegerField(default=0)
643 position = models.PositiveIntegerField(default=0)
643 position = models.PositiveIntegerField(default=0)
644 params = models.TextField(default='{}')
644 params = models.TextField(default='{}')
645 pulses = models.TextField(default='')
645 pulses = models.TextField(default='')
646
646
647 class Meta:
647 class Meta:
648 db_table = 'rc_lines'
648 db_table = 'rc_lines'
649 ordering = ['channel']
649 ordering = ['channel']
650
650
651 def __str__(self):
651 def __str__(self):
652 if self.rc_configuration:
652 if self.rc_configuration:
653 return u'%s - %s' % (self.rc_configuration, self.get_name())
653 return u'%s - %s' % (self.rc_configuration, self.get_name())
654
654
655 def clone(self, **kwargs):
655 def clone(self, **kwargs):
656
656
657 self.pk = None
657 self.pk = None
658
658
659 for attr, value in kwargs.items():
659 for attr, value in kwargs.items():
660 setattr(self, attr, value)
660 setattr(self, attr, value)
661
661
662 self.save()
662 self.save()
663
663
664 return self
664 return self
665
665
666 def get_name(self, channel=False):
666 def get_name(self, channel=False):
667
667
668 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
668 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
669 s = ''
669 s = ''
670
670
671 if self.line_type.name in ('tx',):
671 if self.line_type.name in ('tx',):
672 s = chars[self.position]
672 s = chars[self.position]
673 elif self.line_type.name in ('codes', 'windows', 'tr'):
673 elif self.line_type.name in ('codes', 'windows', 'tr'):
674 if 'TX_ref' in json.loads(self.params):
674 if 'TX_ref' in json.loads(self.params):
675 pk = json.loads(self.params)['TX_ref']
675 pk = json.loads(self.params)['TX_ref']
676 if pk in (0, '0'):
676 if pk in (0, '0'):
677 s = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
677 s = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
678 else:
678 else:
679 ref = RCLine.objects.get(pk=pk)
679 ref = RCLine.objects.get(pk=pk)
680 s = chars[ref.position]
680 s = chars[ref.position]
681 s = '({})'.format(s)
681 s = '({})'.format(s)
682
682
683 s = '{}{}'.format(self.line_type.name.upper(), s)
683 s = '{}{}'.format(self.line_type.name.upper(), s)
684
684
685 if channel:
685 if channel:
686 return '{} {}'.format(s, self.channel)
686 return '{} {}'.format(s, self.channel)
687 else:
687 else:
688 return s
688 return s
689
689
690 def get_lines(self, **kwargs):
690 def get_lines(self, **kwargs):
691
691
692 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
692 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
693
693
694 def pulses_as_array(self):
694 def pulses_as_array(self):
695
695
696 y = np.zeros(self.rc_configuration.total_units)
696 y = np.zeros(self.rc_configuration.total_units)
697
697
698 for tup in ast.literal_eval(self.pulses):
698 for tup in ast.literal_eval(self.pulses):
699 y[tup[0]:tup[1]] = 1
699 y[tup[0]:tup[1]] = 1
700
700
701 return y.astype(np.int8)
701 return y.astype(np.int8)
702
702
703 def pulses_as_points(self, km=False):
703 def pulses_as_points(self, km=False):
704
704
705 if km:
705 if km:
706 unit2km = 1/self.rc_configuration.km2unit
706 unit2km = 1/self.rc_configuration.km2unit
707 return [(tup[0]*unit2km, tup[1]*unit2km) for tup in ast.literal_eval(self.pulses)]
707 return [(tup[0]*unit2km, tup[1]*unit2km) for tup in ast.literal_eval(self.pulses)]
708 else:
708 else:
709 return ast.literal_eval(self.pulses)
709 return ast.literal_eval(self.pulses)
710
710
711 def get_win_ref(self, params, tx_id, km2unit):
711 def get_win_ref(self, params, tx_id, km2unit):
712
712
713 ref = self.rc_configuration.sampling_reference
713 ref = self.rc_configuration.sampling_reference
714 codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
714 codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
715
715
716 if codes:
716 if codes:
717 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/len(json.loads(codes[0].params)['codes'][0])
717 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/len(json.loads(codes[0].params)['codes'][0])
718 else:
718 else:
719 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
719 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
720
720
721 if ref=='first_baud':
721 if ref=='first_baud':
722 return int(1 + round((tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit))
722 return int(1 + round((tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit))
723 elif ref=='sub_baud':
723 elif ref=='sub_baud':
724 return int(1 + round(params['first_height']*km2unit - params['resolution']*km2unit/2))
724 return np.ceil(1 + params['first_height']*km2unit - params['resolution']*km2unit/2)
725 else:
725 else:
726 return 0
726 return 0
727
727
728 def update_pulses(self):
728 def update_pulses(self):
729 '''
729 '''
730 Update pulses field
730 Update pulses field
731 '''
731 '''
732
732
733 km2unit = self.rc_configuration.km2unit
733 km2unit = self.rc_configuration.km2unit
734 us2unit = self.rc_configuration.us2unit
734 us2unit = self.rc_configuration.us2unit
735 ipp = self.rc_configuration.ipp
735 ipp = self.rc_configuration.ipp
736 ntx = int(self.rc_configuration.ntx)
736 ntx = int(self.rc_configuration.ntx)
737 ipp_u = int(ipp*km2unit)
737 ipp_u = int(ipp*km2unit)
738 total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units
738 total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units
739 y = []
739 y = []
740
740
741 if self.line_type.name=='tr':
741 if self.line_type.name=='tr':
742 tr_params = json.loads(self.params)
742 tr_params = json.loads(self.params)
743
743
744 if tr_params['TX_ref'] in ('0', 0):
744 if tr_params['TX_ref'] in ('0', 0):
745 txs = self.get_lines(line_type__name='tx')
745 txs = self.get_lines(line_type__name='tx')
746 else:
746 else:
747 txs = RCLine.objects.filter(pk=tr_params['TX_ref'])
747 txs = RCLine.objects.filter(pk=tr_params['TX_ref'])
748
748
749 for tx in txs:
749 for tx in txs:
750 params = json.loads(tx.params)
750 params = json.loads(tx.params)
751
751
752 if float(params['pulse_width'])==0:
752 if float(params['pulse_width'])==0:
753 continue
753 continue
754 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
754 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
755 width = float(params['pulse_width'])*km2unit+int(self.rc_configuration.time_before*us2unit)
755 width = float(params['pulse_width'])*km2unit+int(self.rc_configuration.time_before*us2unit)
756 before = 0
756 before = 0
757 after = int(self.rc_configuration.time_after*us2unit)
757 after = int(self.rc_configuration.time_after*us2unit)
758
758
759 y_tx = self.points(ntx, ipp_u, width,
759 y_tx = self.points(ntx, ipp_u, width,
760 delay=delays,
760 delay=delays,
761 before=before,
761 before=before,
762 after=after,
762 after=after,
763 sync=self.rc_configuration.sync)
763 sync=self.rc_configuration.sync)
764
764
765 ranges = params['range'].split(',')
765 ranges = params['range'].split(',')
766
766
767 if len(ranges)>0 and ranges[0]!='0':
767 if len(ranges)>0 and ranges[0]!='0':
768 y_tx = self.mask_ranges(y_tx, ranges)
768 y_tx = self.mask_ranges(y_tx, ranges)
769
769
770 tr_ranges = tr_params['range'].split(',')
770 tr_ranges = tr_params['range'].split(',')
771
771
772 if len(tr_ranges)>0 and tr_ranges[0]!='0':
772 if len(tr_ranges)>0 and tr_ranges[0]!='0':
773 y_tx = self.mask_ranges(y_tx, tr_ranges)
773 y_tx = self.mask_ranges(y_tx, tr_ranges)
774
774
775 y.extend(y_tx)
775 y.extend(y_tx)
776
776
777 self.pulses = str(y)
777 self.pulses = str(y)
778 y = self.array_to_points(self.pulses_as_array())
778 y = self.array_to_points(self.pulses_as_array())
779
779
780 elif self.line_type.name=='tx':
780 elif self.line_type.name=='tx':
781 params = json.loads(self.params)
781 params = json.loads(self.params)
782 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
782 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
783 width = float(params['pulse_width'])*km2unit
783 width = float(params['pulse_width'])*km2unit
784
784
785 if width>0:
785 if width>0:
786 before = int(self.rc_configuration.time_before*us2unit)
786 before = int(self.rc_configuration.time_before*us2unit)
787 after = 0
787 after = 0
788
788
789 y = self.points(ntx, ipp_u, width,
789 y = self.points(ntx, ipp_u, width,
790 delay=delays,
790 delay=delays,
791 before=before,
791 before=before,
792 after=after,
792 after=after,
793 sync=self.rc_configuration.sync)
793 sync=self.rc_configuration.sync)
794
794
795 ranges = params['range'].split(',')
795 ranges = params['range'].split(',')
796
796
797 if len(ranges)>0 and ranges[0]!='0':
797 if len(ranges)>0 and ranges[0]!='0':
798 y = self.mask_ranges(y, ranges)
798 y = self.mask_ranges(y, ranges)
799
799
800 elif self.line_type.name=='flip':
800 elif self.line_type.name=='flip':
801 n = float(json.loads(self.params)['number_of_flips'])
801 n = float(json.loads(self.params)['number_of_flips'])
802 width = n*ipp*km2unit
802 width = n*ipp*km2unit
803 y = self.points(int((ntx+1)/(2*n)), ipp_u*n*2, width)
803 y = self.points(int((ntx+1)/(2*n)), ipp_u*n*2, width)
804
804
805 elif self.line_type.name=='codes':
805 elif self.line_type.name=='codes':
806 params = json.loads(self.params)
806 params = json.loads(self.params)
807 tx = RCLine.objects.get(pk=params['TX_ref'])
807 tx = RCLine.objects.get(pk=params['TX_ref'])
808 tx_params = json.loads(tx.params)
808 tx_params = json.loads(tx.params)
809 delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
809 delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
810 f = int(float(tx_params['pulse_width'])*km2unit/len(params['codes'][0]))
810 f = int(float(tx_params['pulse_width'])*km2unit/len(params['codes'][0]))
811 codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in params['codes']]
811 codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in params['codes']]
812 codes = [self.array_to_points(code) for code in codes]
812 codes = [self.array_to_points(code) for code in codes]
813 n = len(codes)
813 n = len(codes)
814
814
815 for i, tup in enumerate(tx.pulses_as_points()):
816 code = codes[i%n]
817 y.extend([(c[0]+tup[0], c[1]+tup[0]) for c in code])
818
819 ranges = tx_params['range'].split(',')
815 ranges = tx_params['range'].split(',')
820 if len(ranges)>0 and ranges[0]!='0':
816 if len(ranges)>0 and ranges[0]!='0':
821 y = self.mask_ranges(y, ranges)
817 dum = self.mask_ranges(tx.pulses_as_points(), ranges)
818 else:
819 dum = tx.pulses_as_points()
820
821 for i, tup in enumerate(dum):
822 if tup==(0,0): continue
823 code = codes[i%n]
824 y.extend([(c[0]+tup[0], c[1]+tup[0]) for c in code])
822
825
823 elif self.line_type.name=='sync':
826 elif self.line_type.name=='sync':
824 params = json.loads(self.params)
827 params = json.loads(self.params)
825 n = ipp_u*ntx
828 n = ipp_u*ntx
826 if params['invert'] in ('1', 1):
829 if params['invert'] in ('1', 1):
827 y = [(n-1, n)]
830 y = [(n-1, n)]
828 else:
831 else:
829 y = [(0, 1)]
832 y = [(0, 1)]
830
833
831 elif self.line_type.name=='prog_pulses':
834 elif self.line_type.name=='prog_pulses':
832 params = json.loads(self.params)
835 params = json.loads(self.params)
833 if int(params['periodic'])==0:
836 if int(params['periodic'])==0:
834 nntx = 1
837 nntx = 1
835 nipp = ipp_u*ntx
838 nipp = ipp_u*ntx
836 else:
839 else:
837 nntx = ntx
840 nntx = ntx
838 nipp = ipp_u
841 nipp = ipp_u
839
842
840 if 'params' in params and len(params['params'])>0:
843 if 'params' in params and len(params['params'])>0:
841 for p in params['params']:
844 for p in params['params']:
842 y_pp = self.points(nntx, nipp,
845 y_pp = self.points(nntx, nipp,
843 p['end']-p['begin'],
846 p['end']-p['begin'],
844 before=p['begin'])
847 before=p['begin'])
845
848
846 y.extend(y_pp)
849 y.extend(y_pp)
847
850
848 elif self.line_type.name=='windows':
851 elif self.line_type.name=='windows':
849 params = json.loads(self.params)
852 params = json.loads(self.params)
850
851 if 'params' in params and len(params['params'])>0:
853 if 'params' in params and len(params['params'])>0:
852 tr_params = json.loads(self.get_lines(line_type__name='tr')[0].params)
854 tr_params = json.loads(self.get_lines(line_type__name='tr')[0].params)
853 tr_ranges = tr_params['range'].split(',')
855 tr_ranges = tr_params['range'].split(',')
854 for p in params['params']:
856 for p in params['params']:
855 y_win = self.points(ntx, ipp_u,
857 y_win = self.points(ntx, ipp_u,
856 p['resolution']*p['number_of_samples']*km2unit,
858 p['resolution']*p['number_of_samples']*km2unit,
857 before=int(self.rc_configuration.time_before*us2unit),
859 before=int(self.rc_configuration.time_before*us2unit),
858 sync=self.get_win_ref(p, params['TX_ref'], km2unit))
860 sync=self.rc_configuration.sync+self.get_win_ref(p, params['TX_ref'], km2unit))
859
861
862
860 if len(tr_ranges)>0 and tr_ranges[0]!='0':
863 if len(tr_ranges)>0 and tr_ranges[0]!='0':
861 y_win = self.mask_ranges(y_win, tr_ranges)
864 y_win = self.mask_ranges(y_win, tr_ranges)
862
865
863 y.extend(y_win)
866 y.extend(y_win)
864
867
865 elif self.line_type.name=='mix':
868 elif self.line_type.name=='mix':
866 values = self.rc_configuration.parameters.split('-')
869 values = self.rc_configuration.parameters.split('-')
867 confs = [RCConfiguration.objects.get(pk=value.split('|')[0]) for value in values]
870 confs = [RCConfiguration.objects.get(pk=value.split('|')[0]) for value in values]
868 modes = [value.split('|')[1] for value in values]
871 modes = [value.split('|')[1] for value in values]
869 ops = [value.split('|')[2] for value in values]
872 ops = [value.split('|')[2] for value in values]
870 delays = [value.split('|')[3] for value in values]
873 delays = [value.split('|')[3] for value in values]
871 masks = [value.split('|')[4] for value in values]
874 masks = [value.split('|')[4] for value in values]
872 mask = list('{:8b}'.format(int(masks[0])))
875 mask = list('{:8b}'.format(int(masks[0])))
873 mask.reverse()
876 mask.reverse()
874 if mask[self.channel] in ('0', '', ' '):
877 if mask[self.channel] in ('0', '', ' '):
875 y = np.zeros(confs[0].total_units, dtype=np.int8)
878 y = np.zeros(confs[0].total_units, dtype=np.int8)
876 else:
879 else:
877 y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
880 y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
878
881
879 for i in range(1, len(values)):
882 for i in range(1, len(values)):
880 mask = list('{:8b}'.format(int(masks[i])))
883 mask = list('{:8b}'.format(int(masks[i])))
881 mask.reverse()
884 mask.reverse()
882
885
883 if mask[self.channel] in ('0', '', ' '):
886 if mask[self.channel] in ('0', '', ' '):
884 continue
887 continue
885 Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
888 Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
886 delay = float(delays[i])*km2unit
889 delay = float(delays[i])*km2unit
887
890
888 if modes[i]=='P':
891 if modes[i]=='P':
889 if delay>0:
892 if delay>0:
890 if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y):
893 if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y):
891 y_temp = np.empty_like(Y)
894 y_temp = np.empty_like(Y)
892 y_temp[:delay] = 0
895 y_temp[:delay] = 0
893 y_temp[delay:] = Y[:-delay]
896 y_temp[delay:] = Y[:-delay]
894 elif delay+len(Y)>len(y):
897 elif delay+len(Y)>len(y):
895 y_new = np.zeros(delay+len(Y), dtype=np.int8)
898 y_new = np.zeros(delay+len(Y), dtype=np.int8)
896 y_new[:len(y)] = y
899 y_new[:len(y)] = y
897 y = y_new
900 y = y_new
898 y_temp = np.zeros(delay+len(Y), dtype=np.int8)
901 y_temp = np.zeros(delay+len(Y), dtype=np.int8)
899 y_temp[-len(Y):] = Y
902 y_temp[-len(Y):] = Y
900 elif delay+len(Y)==len(y):
903 elif delay+len(Y)==len(y):
901 y_temp = np.zeros(delay+len(Y))
904 y_temp = np.zeros(delay+len(Y))
902 y_temp[-len(Y):] = Y
905 y_temp[-len(Y):] = Y
903 elif delay+len(Y)<len(y):
906 elif delay+len(Y)<len(y):
904 y_temp = np.zeros(len(y), dtype=np.int8)
907 y_temp = np.zeros(len(y), dtype=np.int8)
905 y_temp[delay:delay+len(Y)] = Y
908 y_temp[delay:delay+len(Y)] = Y
906
909
907 if ops[i]=='OR':
910 if ops[i]=='OR':
908 y = y | y_temp
911 y = y | y_temp
909 elif ops[i]=='XOR':
912 elif ops[i]=='XOR':
910 y = y ^ y_temp
913 y = y ^ y_temp
911 elif ops[i]=='AND':
914 elif ops[i]=='AND':
912 y = y & y_temp
915 y = y & y_temp
913 elif ops[i]=='NAND':
916 elif ops[i]=='NAND':
914 y = y & ~y_temp
917 y = y & ~y_temp
915 else:
918 else:
916 y = np.concatenate([y, Y])
919 y = np.concatenate([y, Y])
917
920
918 total = len(y)
921 total = len(y)
919 y = self.array_to_points(y)
922 y = self.array_to_points(y)
920
923
921 else:
924 else:
922 y = []
925 y = []
923
926
924 if self.rc_configuration.total_units != total:
927 if self.rc_configuration.total_units != total:
925 self.rc_configuration.total_units = total
928 self.rc_configuration.total_units = total
926 self.rc_configuration.save()
929 self.rc_configuration.save()
927
930
928 self.pulses = str(y)
931 self.pulses = str(y)
929 self.save()
932 self.save()
930
933
931 @staticmethod
934 @staticmethod
932 def array_to_points(X):
935 def array_to_points(X):
933
936
934 d = X[1:]-X[:-1]
937 d = X[1:]-X[:-1]
935
938
936 up = np.where(d==1)[0]
939 up = np.where(d==1)[0]
937 if X[0]==1:
940 if X[0]==1:
938 up = np.concatenate((np.array([-1]), up))
941 up = np.concatenate((np.array([-1]), up))
939 up += 1
942 up += 1
940
943
941 dw = np.where(d==-1)[0]
944 dw = np.where(d==-1)[0]
942 if X[-1]==1:
945 if X[-1]==1:
943 dw = np.concatenate((dw, np.array([len(X)-1])))
946 dw = np.concatenate((dw, np.array([len(X)-1])))
944 dw += 1
947 dw += 1
945
948
946 return [(tup[0], tup[1]) for tup in zip(up, dw)]
949 return [(tup[0], tup[1]) for tup in zip(up, dw)]
947
950
948 @staticmethod
951 @staticmethod
949 def mask_ranges(Y, ranges):
952 def mask_ranges(Y, ranges):
950
953
951 y = [(0, 0) for __ in Y]
954 y = [(0, 0) for __ in Y]
952
955
953 for index in ranges:
956 for index in ranges:
954 if '-' in index:
957 if '-' in index:
955 args = [int(a) for a in index.split('-')]
958 args = [int(a) for a in index.split('-')]
956 y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
959 y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
957 else:
960 else:
958 y[int(index-1)] = Y[int(index-1)]
961 y[int(index)-1] = Y[int(index)-1]
959
962
960 return y
963 return y
961
964
962 @staticmethod
965 @staticmethod
963 def points(ntx, ipp, width, delay=[0], before=0, after=0, sync=0):
966 def points(ntx, ipp, width, delay=[0], before=0, after=0, sync=0):
964
967
965 delays = len(delay)
968 delays = len(delay)
966
969
967 Y = [(int(ipp*x+before+delay[x%delays]+sync), int(ipp*x+width+before+delay[x%delays]+after+sync)) for x in range(ntx)]
970 Y = [(int(ipp*x+before+delay[x%delays]+sync), int(ipp*x+width+before+delay[x%delays]+after+sync)) for x in range(ntx)]
968
971
969 return Y
972 return Y
@@ -1,209 +1,213
1
1
2 import json
2 import json
3
3
4
5 def parse_range(s):
6
7 vars = ('TXA,', 'A,', 'TXB,', 'B,', 'TXA', 'TXB', 'A', 'B')
8
9 for var in vars:
10 if var in s:
11 s = s.replace(var, '')
12 if 'A' in var:
13 ref = 'TXA'
14 else:
15 ref = 'TXB'
16 return ref, s
17
18 return '0', s
19
20
4 class RCFile(object):
21 class RCFile(object):
5 '''
22 '''
6 Class to handle Radar controller configuration files
23 Class to handle Radar controller configuration files
7 '''
24 '''
8
25
9 def __init__(self, f=None):
26 def __init__(self, f=None):
10
27
11 self.data = {}
28 self.data = {}
29 self.line = ''
12 if isinstance(f, str):
30 if isinstance(f, str):
13 self.f = open(f)
31 self.f = open(f)
14 self.name = f.split('/')[-1]
32 self.name = f.split('/')[-1]
15 elif hasattr(f, 'read'):
33 elif hasattr(f, 'read'):
16 self.f = f
34 self.f = f
17 self.name = f.name.split('/')[-1]
35 self.name = f.name.split('/')[-1]
18 else:
36 else:
19 self.f = f
37 self.f = f
20 self.name = None
38 self.name = None
21
39
22 if self.f:
40 if self.f:
23 if 'racp' in self.name:
41 if 'racp' in self.name:
24 self.parse_racp()
42 self.parse_racp()
25 elif 'dat' in self.name:
43 elif 'dat' in self.name:
26 self.parse_dat()
44 self.parse_dat()
27 elif 'json' in self.name:
45 elif 'json' in self.name:
28 self.data = json.load(self.f)
46 self.data = json.load(self.f)
29
47
30 self.f.close()
48 self.f.close()
31
49
32 def get_line_parameters(self, data, line):
50 def get_line_parameters(self, data, line):
33
51
34 line_params = {}
52 line_params = {}
35 for label in data:
53 for label in data:
36 if 'L%d' % line in label or '(Line %d)' % line in label or 'Line%d' % line in label:
54 if 'L%d' % line in label or '(Line %d)' % line in label or 'Line%d' % line in label:
37 line_params[label] = data[label]
55 line_params[label] = data[label]
38 return line_params
56 return line_params
39
57
40 def parse_racp(self):
58 def parse_racp(self):
41
59
42 data = {}
60 data = {}
43 raw_data = [s.strip() for s in self.f.readlines()]
61 raw_data = [s.strip() for s in self.f.readlines()]
44
62
45 for line in raw_data:
63 for line in raw_data:
46 if line and '=' in line:
64 if line and '=' in line:
47 label, value = line.strip().split('=')
65 label, value = line.strip().split('=')
48 data[label] = value
66 data[label] = value
49
67
50 self.data['experiment_type'] = data['EXPERIMENT TYPE']
68 self.data['experiment_type'] = data['EXPERIMENT TYPE']
51 self.data['header_version'] = data['HEADER VERSION']
69 self.data['header_version'] = data['HEADER VERSION']
52 self.data['name'] = data['EXPERIMENT NAME']
70 self.data['name'] = data['EXPERIMENT NAME']
53 self.data['ipp'] = float(data['IPP'])
71 self.data['ipp'] = float(data['IPP'])
54 self.data['ntx'] = int(data['NTX'])
72 self.data['ntx'] = int(data['NTX'])
55
73
56 if 'CLOCK DIVIDER' in data:
74 if 'CLOCK DIVIDER' in data:
57 self.data['clock_divider'] = int(data['CLOCK DIVIDER'])
75 self.data['clock_divider'] = int(data['CLOCK DIVIDER'])
58 else:
76 else:
59 self.data['clock_divider'] = 1
77 self.data['clock_divider'] = 1
60 self.data['clock_in'] = float(data['RELOJ'])*self.data['clock_divider']
78 self.data['clock_in'] = float(data['RELOJ'])*self.data['clock_divider']
61 self.data['clock'] = float(data['RELOJ'])
79 self.data['clock'] = float(data['RELOJ'])
62 self.data['time_before'] = int(data['TR_BEFORE'])
80 self.data['time_before'] = int(data['TR_BEFORE'])
63 self.data['time_after'] = int(data['TR_AFTER'])
81 self.data['time_after'] = int(data['TR_AFTER'])
64
82
65 if 'SYNCHRO DELAY' in data:
83 if 'SYNCHRO DELAY' in data:
66 self.data['sync'] = int(data['SYNCHRO DELAY'])
84 self.data['sync'] = int(data['SYNCHRO DELAY'])
67 else:
85 else:
68 self.data['sync'] = 0
86 self.data['sync'] = 0
69 self.data['lines'] = []
87 self.data['lines'] = []
70
88
71 if 'SAMPLING REFERENCE' in data:
89 if 'SAMPLING REFERENCE' in data:
72 if data['SAMPLING REFERENCE']=='MIDDLE OF FIRST BAUD':
90 if data['SAMPLING REFERENCE']=='MIDDLE OF FIRST BAUD':
73 self.data['sampling_reference'] = 'first_baud'
91 self.data['sampling_reference'] = 'first_baud'
74 elif data['SAMPLING REFERENCE']=='MIDDLE OF FIRST SUB-BAUD':
92 elif data['SAMPLING REFERENCE']=='MIDDLE OF FIRST SUB-BAUD':
75 self.data['sampling_reference'] = 'sub_baud'
93 self.data['sampling_reference'] = 'sub_baud'
76 else:
94 else:
77 self.data['sampling_reference'] = 'none'
95 self.data['sampling_reference'] = 'none'
78
96
79 #Add TR line
97 #Add TR line
80 if 'Pulse selection_TR' in data:
98 if 'Pulse selection_TR' in data:
81 if 'A,' in data['Pulse selection_TR']:
99 ref, rng = parse_range(data['Pulse selection_TR'])
82 rng = data['Pulse selection_TR'].replace('A,', '')
83 ref = 'TXA'
84 elif 'A' in data['Pulse selection_TR']:
85 rng = data['Pulse selection_TR'].replace('A', '')
86 ref = 'TXA'
87 elif 'B,' in data['Pulse selection_TR']:
88 rng = data['Pulse selection_TR'].replace('B,', '')
89 ref = 'TXB'
90 elif 'B' in data['Pulse selection_TR']:
91 rng = data['Pulse selection_TR'].replace('B', '')
92 ref = 'TXB'
93 else:
94 rng = data['Pulse selection_TR']
95 ref = '0'
96 line = {'type':'tr', 'range': rng if rng else '0', 'TX_ref':ref}
100 line = {'type':'tr', 'range': rng if rng else '0', 'TX_ref':ref}
97 else:
101 else:
98 line = {'type': 'tr', 'range': '0', 'TX_ref': '0'}
102 line = {'type': 'tr', 'range': '0', 'TX_ref': '0'}
99
103
100 self.data['lines'].append(line)
104 self.data['lines'].append(line)
101
105
102 #Add TX's lines
106 #Add TX's lines
103 if 'TXA' in data:
107 if 'TXA' in data:
104 line = {'type':'tx', 'pulse_width':data['TXA'], 'delays':'0'}
108 line = {'type':'tx', 'pulse_width':data['TXA'], 'delays':'0'}
105 if 'Pulse selection_TXA' in data:
109 if 'Pulse selection_TXA' in data:
106 line['range'] = data['Pulse selection_TXA']
110 line['range'] = data['Pulse selection_TXA']
107 else:
111 else:
108 line['range'] = '0'
112 line['range'] = '0'
109 self.data['lines'].append(line)
113 self.data['lines'].append(line)
110 else:
114 else:
111 self.data['lines'].append({'type':'tx', 'pulse_width':'0', 'delays':'0', 'range':'0'})
115 self.data['lines'].append({'type':'tx', 'pulse_width':'0', 'delays':'0', 'range':'0'})
112
116
113 if 'TXB' in data:
117 if 'TXB' in data:
114 line = {'type':'tx', 'pulse_width':data['TXB'], 'delays':'0'}
118 line = {'type':'tx', 'pulse_width':data['TXB'], 'delays':'0'}
115 if 'Pulse selection_TXB' in data:
119 if 'Pulse selection_TXB' in data:
116 line['range'] = data['Pulse selection_TXB']
120 line['range'] = data['Pulse selection_TXB']
117 else:
121 else:
118 line['range'] = '0'
122 line['range'] = '0'
119
123
120 if 'Number of Taus' in data:
124 if 'Number of Taus' in data:
121 delays = [data['TAU({0})'.format(i)] for i in range(int(data['Number of Taus']))]
125 delays = [data['TAU({0})'.format(i)] for i in range(int(data['Number of Taus']))]
122 line['delays'] = ','.join(delays)
126 line['delays'] = ','.join(delays)
123
127
124 self.data['lines'].append(line)
128 self.data['lines'].append(line)
125 else:
129 else:
126 self.data['lines'].append({'type':'tx', 'pulse_width':'0', 'delays':'0', 'range':'0'})
130 self.data['lines'].append({'type':'tx', 'pulse_width':'0', 'delays':'0', 'range':'0'})
127
131
128 #Add Other lines (4-6)
132 #Add Other lines (4-6)
129 for n in range(4, 7):
133 for n in range(4, 7):
130 params = self.get_line_parameters(data, n)
134 params = self.get_line_parameters(data, n)
131 labels = params.keys()
135 labels = params.keys()
132
136
133 if 'L%d_FLIP' % n in labels:
137 if 'L%d_FLIP' % n in labels:
134 line = {'type':'flip', 'number_of_flips':data['L%d_FLIP' % n]}
138 line = {'type':'flip', 'number_of_flips':data['L%d_FLIP' % n]}
135 elif 'Code Type' in data and n==4:
139 elif 'Code Type' in data and n==4:
136 line = {'type':'codes', 'code':data['Code Type'], 'TX_ref':data['L%d_REFERENCE' % n]}
140 line = {'type':'codes', 'code':data['Code Type'], 'TX_ref':data['L%d_REFERENCE' % n]}
137 if 'Number of Codes' in data:
141 if 'Number of Codes' in data:
138 line['codes'] = [data['COD({})'.format(x)] for x in range(int(data['Number of Codes']))]
142 line['codes'] = [data['COD({})'.format(x)] for x in range(int(data['Number of Codes']))]
139 elif 'Code Type (Line %d)' % n in labels:
143 elif 'Code Type (Line %d)' % n in labels:
140 line = {'type':'codes', 'code':data['Code Type (Line %d)' % n], 'TX_ref':data['L%d_REFERENCE' % n]}
144 line = {'type':'codes', 'code':data['Code Type (Line %d)' % n], 'TX_ref':data['L%d_REFERENCE' % n]}
141 if 'Number of Codes (Line %d)' % n in data:
145 if 'Number of Codes (Line %d)' % n in data:
142 line['codes'] = [data['L{}_COD({})'.format(n, x)] for x in range(int(data['Number of Codes (Line %d)' % n]))]
146 line['codes'] = [data['L{}_COD({})'.format(n, x)] for x in range(int(data['Number of Codes (Line %d)' % n]))]
143 elif 'Sampling Windows (Line %d)' % n in data:
147 elif 'Sampling Windows (Line %d)' % n in data:
144 line = {'type':'windows', 'TX_ref':data['L%d_REFERENCE' % n]}
148 line = {'type':'windows', 'TX_ref':data['L%d_REFERENCE' % n]}
145 windows = []
149 windows = []
146 for w in range(int(data['Sampling Windows (Line %d)' % n])):
150 for w in range(int(data['Sampling Windows (Line %d)' % n])):
147 windows.append({'first_height':float(data['L%d_H0(%d)' % (n, w)]),
151 windows.append({'first_height':float(data['L%d_H0(%d)' % (n, w)]),
148 'resolution':float(data['L%d_DH(%d)' % (n, w)]),
152 'resolution':float(data['L%d_DH(%d)' % (n, w)]),
149 'number_of_samples':int(data['L%d_NSA(%d)' % (n, w)]),
153 'number_of_samples':int(data['L%d_NSA(%d)' % (n, w)]),
150 'last_height':float(data['L%d_DH(%d)' % (n, w)])*(int(data['L%d_NSA(%d)' % (n, w)])-1)+float(data['L%d_H0(%d)' % (n, w)])
154 'last_height':float(data['L%d_DH(%d)' % (n, w)])*(int(data['L%d_NSA(%d)' % (n, w)])-1)+float(data['L%d_H0(%d)' % (n, w)])
151 }
155 }
152 )
156 )
153 line['params'] = windows
157 line['params'] = windows
154 elif 'Line%d' % n in labels and data['Line%d' % n]=='Synchro':
158 elif 'Line%d' % n in labels and data['Line%d' % n]=='Synchro':
155 line = {'type':'sync', 'invert':0}
159 line = {'type':'sync', 'invert':0}
156 elif 'L%d Number Of Portions' % n in labels:
160 elif 'L%d Number Of Portions' % n in labels:
157 line = {'type':'prog_pulses'}
161 line = {'type':'prog_pulses'}
158 if 'L%s Portions IPP Periodic' % n in data:
162 if 'L%s Portions IPP Periodic' % n in data:
159 line['periodic'] = 1 if data['L%s Portions IPP Periodic' % n]=='YES' else 0
163 line['periodic'] = 1 if data['L%s Portions IPP Periodic' % n]=='YES' else 0
160 portions = []
164 portions = []
161 x = raw_data.index('L%d Number Of Portions=%s' % (n, data['L%d Number Of Portions' % n]))
165 x = raw_data.index('L%d Number Of Portions=%s' % (n, data['L%d Number Of Portions' % n]))
162 for w in range(int(data['L%d Number Of Portions' % n])):
166 for w in range(int(data['L%d Number Of Portions' % n])):
163 begin = raw_data[x+1+2*w].split('=')[-1]
167 begin = raw_data[x+1+2*w].split('=')[-1]
164 end = raw_data[x+2+2*w].split('=')[-1]
168 end = raw_data[x+2+2*w].split('=')[-1]
165 portions.append({'begin':int(begin),
169 portions.append({'begin':int(begin),
166 'end':int(end)}
170 'end':int(end)}
167 )
171 )
168 line['params'] = portions
172 line['params'] = portions
169 elif 'FLIP1' in data and n==5:
173 elif 'FLIP1' in data and n==5:
170 line = {'type':'flip', 'number_of_flips':data['FLIP1']}
174 line = {'type':'flip', 'number_of_flips':data['FLIP1']}
171 elif 'FLIP2' in data and n==6:
175 elif 'FLIP2' in data and n==6:
172 line = {'type':'flip', 'number_of_flips':data['FLIP2']}
176 line = {'type':'flip', 'number_of_flips':data['FLIP2']}
173 else:
177 else:
174 line = {'type':'none'}
178 line = {'type':'none'}
175
179
176 self.data['lines'].append(line)
180 self.data['lines'].append(line)
177
181
178 #Add line 7 (windows)
182 #Add line 7 (windows)
179 if 'Sampling Windows' in data:
183 if 'Sampling Windows' in data:
180 line = {'type':'windows', 'TX_ref':data['L7_REFERENCE']}
184 line = {'type':'windows', 'TX_ref':data['L7_REFERENCE']}
181 windows = []
185 windows = []
182 x = raw_data.index('Sampling Windows=%s' % data['Sampling Windows'])
186 x = raw_data.index('Sampling Windows=%s' % data['Sampling Windows'])
183 for w in range(int(data['Sampling Windows'])):
187 for w in range(int(data['Sampling Windows'])):
184 h0 = raw_data[x+1+3*w].split('=')[-1]
188 h0 = raw_data[x+1+3*w].split('=')[-1]
185 nsa = raw_data[x+2+3*w].split('=')[-1]
189 nsa = raw_data[x+2+3*w].split('=')[-1]
186 dh = raw_data[x+3+3*w].split('=')[-1]
190 dh = raw_data[x+3+3*w].split('=')[-1]
187 windows.append({'first_height':float(h0),
191 windows.append({'first_height':float(h0),
188 'number_of_samples':int(nsa),
192 'number_of_samples':int(nsa),
189 'resolution':float(dh),
193 'resolution':float(dh),
190 'last_height':float(h0)+float(dh)*(int(nsa)-1)}
194 'last_height':float(h0)+float(dh)*(int(nsa)-1)}
191 )
195 )
192 line['params'] = windows
196 line['params'] = windows
193 self.data['lines'].append(line)
197 self.data['lines'].append(line)
194 else:
198 else:
195 self.data['lines'].append({'type':'none'})
199 self.data['lines'].append({'type':'none'})
196
200
197 #Add line 8 (synchro inverted)
201 #Add line 8 (synchro inverted)
198 self.data['lines'].append({'type':'sync', 'invert':1})
202 self.data['lines'].append({'type':'sync', 'invert':1})
199
203
200 return
204 return
201
205
202 def parse_dat(self):
206 def parse_dat(self):
203 pass
207 pass
204
208
205
209
206 def get_json(self, indent=None):
210 def get_json(self, indent=None):
207 return json.dumps(self.data, indent=indent)
211 return json.dumps(self.data, indent=indent)
208
212
209
213
General Comments 0
You need to be logged in to leave comments. Login now