@@ -21,6 +21,14 | |||
|
21 | 21 | document.location = "{% url 'url_delete_mix_experiment' id_exp %}"; |
|
22 | 22 | }); |
|
23 | 23 | |
|
24 | $('input[type=radio][name=mode]').change(function() { | |
|
25 | if (this.value == '0') { | |
|
26 | $('input[type=radio][name=operation]').prop('disabled', false); | |
|
27 | }else{ | |
|
28 | $('input[type=radio][name=operation]').prop('disabled', true); | |
|
29 | } | |
|
30 | }); | |
|
31 | ||
|
24 | 32 | </script> |
|
25 | 33 | |
|
26 | 34 | {% endblock %} No newline at end of file |
@@ -34,5 +34,6 def get_verbose_field_name(instance, field_name): | |||
|
34 | 34 | """ |
|
35 | 35 | Returns verbose_name for a field. |
|
36 | 36 | """ |
|
37 | ||
|
37 | if field_name=='ipp_unit': | |
|
38 | return 'Inter pulse period [Km(Units)]' | |
|
38 | 39 | return mark_safe(instance._meta.get_field(field_name).verbose_name) No newline at end of file |
@@ -44,10 +44,15 CONF_MODELS = { | |||
|
44 | 44 | } |
|
45 | 45 | |
|
46 | 46 | MIX_MODES = { |
|
47 | '0': 'P', | |
|
48 | '1': 'S', | |
|
49 | } | |
|
50 | ||
|
51 | MIX_OPERATIONS = { | |
|
47 | 52 | '0': 'OR', |
|
48 | 53 | '1': 'XOR', |
|
49 | 54 | '2': 'AND', |
|
50 | '3': 'NAND' | |
|
55 | '3': 'NAND', | |
|
51 | 56 | } |
|
52 | 57 | |
|
53 | 58 | |
@@ -680,33 +685,40 def experiment_mix(request, id_exp): | |||
|
680 | 685 | if request.method=='GET': |
|
681 | 686 | form = RCMixConfigurationForm(confs=rc_confs, initial=initial) |
|
682 | 687 | |
|
683 |
if request.method=='POST': |
|
|
684 | ||
|
688 | if request.method=='POST': | |
|
685 | 689 | result = mix.parameters |
|
686 | 690 | |
|
687 | 691 | if '{}|'.format(request.POST['experiment']) in result: |
|
688 | 692 | messages.error(request, 'Configuration already added') |
|
689 | 693 | else: |
|
694 | if 'operation' in request.POST: | |
|
695 | operation = MIX_OPERATIONS[request.POST['operation']] | |
|
696 | else: | |
|
697 | operation = '---' | |
|
698 | ||
|
699 | mode = MIX_MODES[request.POST['mode']] | |
|
700 | ||
|
690 | 701 | if result: |
|
691 | result = '{}-{}|{}|{}|{}'.format(mix.parameters, | |
|
692 |
|
|
|
693 |
|
|
|
694 |
|
|
|
695 |
|
|
|
696 |
|
|
|
702 | result = '{}-{}|{}|{}|{}|{}'.format(mix.parameters, | |
|
703 | request.POST['experiment'], | |
|
704 | mode, | |
|
705 | operation, | |
|
706 | float(request.POST['delay']), | |
|
707 | parse_mask(request.POST.getlist('mask')) | |
|
708 | ) | |
|
697 | 709 | else: |
|
698 | result = '{}|{}|{}|{}'.format(request.POST['experiment'], | |
|
699 |
|
|
|
700 |
|
|
|
701 |
|
|
|
702 |
|
|
|
710 | result = '{}|{}|{}|{}|{}'.format(request.POST['experiment'], | |
|
711 | mode, | |
|
712 | operation, | |
|
713 | float(request.POST['delay']), | |
|
714 | parse_mask(request.POST.getlist('mask')) | |
|
715 | ) | |
|
703 | 716 | |
|
704 | 717 | mix.parameters = result |
|
705 | 718 | mix.name = request.POST['name'] |
|
706 | 719 | mix.save() |
|
707 | 720 | mix.update_pulses() |
|
708 | ||
|
709 | ||
|
721 | ||
|
710 | 722 | initial['result'] = parse_mix_result(result) |
|
711 | 723 | initial['name'] = mix.name |
|
712 | 724 | |
@@ -741,24 +753,28 def experiment_mix_delete(request, id_exp): | |||
|
741 | 753 | def parse_mix_result(s): |
|
742 | 754 | |
|
743 | 755 | values = s.split('-') |
|
744 | html = '' | |
|
756 | html = 'EXP MOD OPE DELAY MASK\r\n' | |
|
745 | 757 | |
|
758 | if not values or values[0] in ('', ' '): | |
|
759 | return mark_safe(html) | |
|
746 | 760 | |
|
747 | 761 | for i, value in enumerate(values): |
|
748 | 762 | if not value: |
|
749 | 763 | continue |
|
750 | pk, mode, delay, mask = value.split('|') | |
|
764 | pk, mode, operation, delay, mask = value.split('|') | |
|
751 | 765 | conf = RCConfiguration.objects.get(pk=pk) |
|
752 | 766 | if i==0: |
|
753 | html += '{:20.18}{:4}{:9}km{:>6}\r\n'.format( | |
|
754 |
conf.name |
|
|
767 | html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format( | |
|
768 | conf.name, | |
|
769 | mode, | |
|
755 | 770 | '---', |
|
756 | 771 | delay, |
|
757 | 772 | mask) |
|
758 | 773 | else: |
|
759 | html += '{:20.18}{:4}{:9}km{:>6}\r\n'.format( | |
|
760 |
conf.name |
|
|
774 | html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format( | |
|
775 | conf.name, | |
|
761 | 776 | mode, |
|
777 | operation, | |
|
762 | 778 | delay, |
|
763 | 779 | mask) |
|
764 | 780 |
@@ -78,7 +78,7 class RCConfigurationForm(forms.ModelForm): | |||
|
78 | 78 | |
|
79 | 79 | class Meta: |
|
80 | 80 | model = RCConfiguration |
|
81 | exclude = ('type', 'parameters', 'status', 'mix') | |
|
81 | exclude = ('type', 'parameters', 'status', 'total_units', 'mix') | |
|
82 | 82 | |
|
83 | 83 | def clean(self): |
|
84 | 84 | form_data = super(RCConfigurationForm, self).clean() |
@@ -99,6 +99,9 class RCMixConfigurationForm(forms.Form): | |||
|
99 | 99 | clock_divider = forms.CharField(widget=forms.HiddenInput()) |
|
100 | 100 | name = forms.CharField() |
|
101 | 101 | experiment = forms.ChoiceField() |
|
102 | mode = forms.ChoiceField(widget=forms.RadioSelect(), | |
|
103 | choices=[(0, 'Parallel'), (1, 'Sequence')], | |
|
104 | initial=0) | |
|
102 | 105 | operation = forms.ChoiceField(widget=forms.RadioSelect(), |
|
103 | 106 | choices=[(0, 'OR'), (1, 'XOR'), (2, 'AND'), (3, 'NAND')], |
|
104 | 107 | initial=1) |
@@ -121,8 +124,7 class RCMixConfigurationForm(forms.Form): | |||
|
121 | 124 | self.fields['delay'].widget = KmUnitWidget(attrs = {'km2unit':km2unit}) |
|
122 | 125 | self.fields['clock_in'].initial = clock_in |
|
123 | 126 | self.fields['clock_divider'].initial = clock_divider |
|
124 | ||
|
125 | ||
|
127 | ||
|
126 | 128 | |
|
127 | 129 | class RCLineForm(forms.ModelForm): |
|
128 | 130 |
@@ -57,17 +57,18 DAT_CMDS = { | |||
|
57 | 57 | |
|
58 | 58 | class RCConfiguration(Configuration): |
|
59 | 59 | |
|
60 |
ipp = models.FloatField(verbose_name='Inter pulse period |
|
|
60 | ipp = models.FloatField(verbose_name='Inter pulse period [Km]', validators=[MinValueValidator(1), MaxValueValidator(9000)], default=300) | |
|
61 | 61 | ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1), MaxValueValidator(300)], default=1) |
|
62 |
clock_in = models.FloatField(verbose_name='Clock in |
|
|
62 | clock_in = models.FloatField(verbose_name='Clock in [MHz]', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1) | |
|
63 | 63 | clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1) |
|
64 |
clock = models.FloatField(verbose_name='Clock Master |
|
|
65 |
time_before = models.PositiveIntegerField(verbose_name='Time before |
|
|
66 |
time_after = models.PositiveIntegerField(verbose_name='Time after |
|
|
64 | clock = models.FloatField(verbose_name='Clock Master [MHz]', blank=True, default=1) | |
|
65 | time_before = models.PositiveIntegerField(verbose_name='Time before [μS]', default=12) | |
|
66 | time_after = models.PositiveIntegerField(verbose_name='Time after [μS]', default=1) | |
|
67 | 67 | sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0) |
|
68 | 68 | sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40) |
|
69 | 69 | control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False) |
|
70 | 70 | control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False) |
|
71 | total_units = models.PositiveIntegerField(default=0) | |
|
71 | 72 | mix = models.BooleanField(default=False) |
|
72 | 73 | |
|
73 | 74 | class Meta: |
@@ -88,6 +89,11 class RCConfiguration(Configuration): | |||
|
88 | 89 | return reverse('url_import_rc_conf', args=[str(self.id)]) |
|
89 | 90 | |
|
90 | 91 | @property |
|
92 | def ipp_unit(self): | |
|
93 | ||
|
94 | return '{} ({})'.format(self.ipp, int(self.ipp*self.km2unit)) | |
|
95 | ||
|
96 | @property | |
|
91 | 97 | def us2unit(self): |
|
92 | 98 | |
|
93 | 99 | return self.clock_in/self.clock_divider |
@@ -334,12 +340,11 class RCConfiguration(Configuration): | |||
|
334 | 340 | f = RCFile(filename) |
|
335 | 341 | self.dict_to_parms(f.data) |
|
336 | 342 | self.update_pulses() |
|
337 | self.save() | |
|
338 | 343 | |
|
339 | 344 | def update_pulses(self): |
|
340 | 345 | |
|
341 | 346 | for line in self.get_lines(): |
|
342 | line.update_pulses() | |
|
347 | line.update_pulses() | |
|
343 | 348 | |
|
344 | 349 | def plot_pulses(self): |
|
345 | 350 | |
@@ -349,9 +354,7 class RCConfiguration(Configuration): | |||
|
349 | 354 | from bokeh.mpl import to_bokeh |
|
350 | 355 | from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, PreviewSaveTool |
|
351 | 356 | |
|
352 | lines = self.get_lines() | |
|
353 | ||
|
354 | max_value = self.ipp*self.km2unit*self.ntx | |
|
357 | lines = self.get_lines() | |
|
355 | 358 | |
|
356 | 359 | N = len(lines) |
|
357 | 360 | fig = plt.figure(figsize=(10, 2+N*0.5)) |
@@ -360,7 +363,7 class RCConfiguration(Configuration): | |||
|
360 | 363 | |
|
361 | 364 | for i, line in enumerate(lines): |
|
362 | 365 | labels.append(line.get_name()) |
|
363 |
l = ax.plot((0, |
|
|
366 | l = ax.plot((0, self.total_units),(N-i-1, N-i-1)) | |
|
364 | 367 | points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points() if tup<>(0,0)] |
|
365 | 368 | ax.broken_barh(points, (N-i-1, 0.5), |
|
366 | 369 | edgecolor=l[0].get_color(), facecolor='none') |
@@ -496,7 +499,7 class RCLine(models.Model): | |||
|
496 | 499 | |
|
497 | 500 | def pulses_as_array(self): |
|
498 | 501 | |
|
499 |
y = np.zeros(self.rc_configuration. |
|
|
502 | y = np.zeros(self.rc_configuration.total_units) | |
|
500 | 503 | |
|
501 | 504 | for tup in ast.literal_eval(self.pulses): |
|
502 | 505 | y[tup[0]:tup[1]] = 1 |
@@ -534,7 +537,7 class RCLine(models.Model): | |||
|
534 | 537 | ipp = self.rc_configuration.ipp |
|
535 | 538 | ntx = self.rc_configuration.ntx |
|
536 | 539 | ipp_u = int(ipp*km2unit) |
|
537 | ||
|
540 | total = ipp_u*ntx | |
|
538 | 541 | y = [] |
|
539 | 542 | |
|
540 | 543 | if self.line_type.name=='tr': |
@@ -661,38 +664,59 class RCLine(models.Model): | |||
|
661 | 664 | values = self.rc_configuration.parameters.split('-') |
|
662 | 665 | confs = RCConfiguration.objects.filter(pk__in=[value.split('|')[0] for value in values]) |
|
663 | 666 | modes = [value.split('|')[1] for value in values] |
|
664 |
|
|
|
665 |
|
|
|
667 | ops = [value.split('|')[2] for value in values] | |
|
668 | delays = [value.split('|')[3] for value in values] | |
|
669 | masks = [value.split('|')[4] for value in values] | |
|
670 | mask = list('{:8b}'.format(int(masks[0]))) | |
|
671 | mask.reverse() | |
|
672 | if mask[self.channel] in ('0', '', ' '): | |
|
673 | y = np.zeros(total, dtype=np.int8) | |
|
674 | else: | |
|
675 | y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array() | |
|
666 | 676 | |
|
667 | y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array() | |
|
668 | ysize = len(y) | |
|
669 | 677 | for i in range(1, len(values)): |
|
670 | 678 | mask = list('{:8b}'.format(int(masks[i]))) |
|
671 | 679 | mask.reverse() |
|
672 | 680 | |
|
673 | 681 | if mask[self.channel] in ('0', '', ' '): |
|
674 | 682 | continue |
|
675 | Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array() | |
|
683 | Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array() | |
|
676 | 684 | delay = float(delays[i])*km2unit |
|
677 | if delay>0: | |
|
678 | y_temp = np.empty_like(Y) | |
|
679 | y_temp[:delay] = 0 | |
|
680 |
y_temp |
|
|
681 |
y_temp |
|
|
682 | if modes[i]=='OR': | |
|
685 | ||
|
686 | if delay>0: | |
|
687 | if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y): | |
|
688 | y_temp = np.empty_like(Y) | |
|
689 | y_temp[:delay] = 0 | |
|
690 | y_temp[delay:] = Y[:-delay] | |
|
691 | elif delay+len(Y)>len(y): | |
|
692 | y_new = np.zeros(delay+len(Y), dtype=np.int8) | |
|
693 | y_new[:len(y)] = y | |
|
694 | y = y_new | |
|
695 | y_temp = np.zeros(delay+len(Y), dtype=np.int8) | |
|
696 | y_temp[-len(Y):] = Y | |
|
697 | elif delay+len(Y)==len(y): | |
|
698 | y_temp = np.zeros(delay+len(Y)) | |
|
699 | y_temp[-len(Y):] = Y | |
|
700 | ||
|
701 | if ops[i]=='OR': | |
|
683 | 702 | y = y | y_temp |
|
684 |
elif |
|
|
703 | elif ops[i]=='XOR': | |
|
685 | 704 | y = y ^ y_temp |
|
686 |
elif |
|
|
705 | elif ops[i]=='AND': | |
|
687 | 706 | y = y & y_temp |
|
688 |
elif |
|
|
707 | elif ops[i]=='NAND': | |
|
689 | 708 | y = y & ~y_temp |
|
690 |
|
|
|
709 | ||
|
710 | total = len(y) | |
|
691 | 711 | y = self.array_to_points(y) |
|
692 | 712 | |
|
693 | 713 | else: |
|
694 | 714 | y = [] |
|
695 | 715 | |
|
716 | if self.rc_configuration.total_units <> total: | |
|
717 | self.rc_configuration.total_units = total | |
|
718 | self.rc_configuration.save() | |
|
719 | ||
|
696 | 720 | self.pulses = y |
|
697 | 721 | self.save() |
|
698 | 722 |
@@ -27,7 +27,7 def conf(request, conf_id): | |||
|
27 | 27 | kwargs = {} |
|
28 | 28 | kwargs['dev_conf'] = conf |
|
29 | 29 | kwargs['rc_lines'] = lines |
|
30 | kwargs['dev_conf_keys'] = ['name', 'ipp', 'ntx', 'clock_in', 'clock_divider', 'clock', | |
|
30 | kwargs['dev_conf_keys'] = ['name', 'ipp_unit', 'ntx', 'clock_in', 'clock_divider', 'clock', | |
|
31 | 31 | 'time_before', 'time_after', 'sync', 'sampling_reference', 'control_tx', 'control_sw'] |
|
32 | 32 | |
|
33 | 33 | kwargs['title'] = 'RC Configuration' |
@@ -116,7 +116,7 def conf_edit(request, conf_id): | |||
|
116 | 116 | line.save() |
|
117 | 117 | |
|
118 | 118 | #update pulses field |
|
119 |
conf.update_pulses() |
|
|
119 | conf.update_pulses() | |
|
120 | 120 | |
|
121 | 121 | messages.success(request, 'RC Configuration successfully updated') |
|
122 | 122 |
General Comments 0
You need to be logged in to leave comments.
Login now