diff --git a/apps/main/templates/experiment_mix.html b/apps/main/templates/experiment_mix.html index 25cadb0..39318af 100644 --- a/apps/main/templates/experiment_mix.html +++ b/apps/main/templates/experiment_mix.html @@ -21,6 +21,14 @@ document.location = "{% url 'url_delete_mix_experiment' id_exp %}"; }); + $('input[type=radio][name=mode]').change(function() { + if (this.value == '0') { + $('input[type=radio][name=operation]').prop('disabled', false); + }else{ + $('input[type=radio][name=operation]').prop('disabled', true); + } + }); + {% endblock %} \ No newline at end of file diff --git a/apps/main/templatetags/main_tags.py b/apps/main/templatetags/main_tags.py index f8dc366..f2a3e11 100644 --- a/apps/main/templatetags/main_tags.py +++ b/apps/main/templatetags/main_tags.py @@ -34,5 +34,6 @@ def get_verbose_field_name(instance, field_name): """ Returns verbose_name for a field. """ - + if field_name=='ipp_unit': + return 'Inter pulse period [Km(Units)]' return mark_safe(instance._meta.get_field(field_name).verbose_name) \ No newline at end of file diff --git a/apps/main/views.py b/apps/main/views.py index c0693a6..3fa78cb 100644 --- a/apps/main/views.py +++ b/apps/main/views.py @@ -44,10 +44,15 @@ CONF_MODELS = { } MIX_MODES = { + '0': 'P', + '1': 'S', +} + +MIX_OPERATIONS = { '0': 'OR', '1': 'XOR', '2': 'AND', - '3': 'NAND' + '3': 'NAND', } @@ -680,33 +685,40 @@ def experiment_mix(request, id_exp): if request.method=='GET': form = RCMixConfigurationForm(confs=rc_confs, initial=initial) - if request.method=='POST': - + if request.method=='POST': result = mix.parameters if '{}|'.format(request.POST['experiment']) in result: messages.error(request, 'Configuration already added') else: + if 'operation' in request.POST: + operation = MIX_OPERATIONS[request.POST['operation']] + else: + operation = '---' + + mode = MIX_MODES[request.POST['mode']] + if result: - result = '{}-{}|{}|{}|{}'.format(mix.parameters, - request.POST['experiment'], - MIX_MODES[request.POST['operation']], - float(request.POST['delay']), - parse_mask(request.POST.getlist('mask')) - ) + result = '{}-{}|{}|{}|{}|{}'.format(mix.parameters, + request.POST['experiment'], + mode, + operation, + float(request.POST['delay']), + parse_mask(request.POST.getlist('mask')) + ) else: - result = '{}|{}|{}|{}'.format(request.POST['experiment'], - MIX_MODES[request.POST['operation']], - float(request.POST['delay']), - parse_mask(request.POST.getlist('mask')) - ) + result = '{}|{}|{}|{}|{}'.format(request.POST['experiment'], + mode, + operation, + float(request.POST['delay']), + parse_mask(request.POST.getlist('mask')) + ) mix.parameters = result mix.name = request.POST['name'] mix.save() mix.update_pulses() - - + initial['result'] = parse_mix_result(result) initial['name'] = mix.name @@ -741,24 +753,28 @@ def experiment_mix_delete(request, id_exp): def parse_mix_result(s): values = s.split('-') - html = '' + html = 'EXP MOD OPE DELAY MASK\r\n' + if not values or values[0] in ('', ' '): + return mark_safe(html) for i, value in enumerate(values): if not value: continue - pk, mode, delay, mask = value.split('|') + pk, mode, operation, delay, mask = value.split('|') conf = RCConfiguration.objects.get(pk=pk) if i==0: - html += '{:20.18}{:4}{:9}km{:>6}\r\n'.format( - conf.name[:18], + html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format( + conf.name, + mode, '---', delay, mask) else: - html += '{:20.18}{:4}{:9}km{:>6}\r\n'.format( - conf.name[:18], + html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format( + conf.name, mode, + operation, delay, mask) diff --git a/apps/rc/forms.py b/apps/rc/forms.py index ea71382..ca86665 100644 --- a/apps/rc/forms.py +++ b/apps/rc/forms.py @@ -78,7 +78,7 @@ class RCConfigurationForm(forms.ModelForm): class Meta: model = RCConfiguration - exclude = ('type', 'parameters', 'status', 'mix') + exclude = ('type', 'parameters', 'status', 'total_units', 'mix') def clean(self): form_data = super(RCConfigurationForm, self).clean() @@ -99,6 +99,9 @@ class RCMixConfigurationForm(forms.Form): clock_divider = forms.CharField(widget=forms.HiddenInput()) name = forms.CharField() experiment = forms.ChoiceField() + mode = forms.ChoiceField(widget=forms.RadioSelect(), + choices=[(0, 'Parallel'), (1, 'Sequence')], + initial=0) operation = forms.ChoiceField(widget=forms.RadioSelect(), choices=[(0, 'OR'), (1, 'XOR'), (2, 'AND'), (3, 'NAND')], initial=1) @@ -121,8 +124,7 @@ class RCMixConfigurationForm(forms.Form): self.fields['delay'].widget = KmUnitWidget(attrs = {'km2unit':km2unit}) self.fields['clock_in'].initial = clock_in self.fields['clock_divider'].initial = clock_divider - - + class RCLineForm(forms.ModelForm): diff --git a/apps/rc/models.py b/apps/rc/models.py index 3332571..db8d0c6 100644 --- a/apps/rc/models.py +++ b/apps/rc/models.py @@ -57,17 +57,18 @@ DAT_CMDS = { class RCConfiguration(Configuration): - ipp = models.FloatField(verbose_name='Inter pulse period (Km)', validators=[MinValueValidator(1), MaxValueValidator(9000)], default=300) + ipp = models.FloatField(verbose_name='Inter pulse period [Km]', validators=[MinValueValidator(1), MaxValueValidator(9000)], default=300) ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1), MaxValueValidator(300)], default=1) - clock_in = models.FloatField(verbose_name='Clock in (MHz)', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1) + clock_in = models.FloatField(verbose_name='Clock in [MHz]', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1) clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1) - clock = models.FloatField(verbose_name='Clock Master (MHz)', blank=True, default=1) - time_before = models.PositiveIntegerField(verbose_name='Time before (μS)', default=12) - time_after = models.PositiveIntegerField(verbose_name='Time after (μS)', default=1) + clock = models.FloatField(verbose_name='Clock Master [MHz]', blank=True, default=1) + time_before = models.PositiveIntegerField(verbose_name='Time before [μS]', default=12) + time_after = models.PositiveIntegerField(verbose_name='Time after [μS]', default=1) sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0) sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40) control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False) control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False) + total_units = models.PositiveIntegerField(default=0) mix = models.BooleanField(default=False) class Meta: @@ -88,6 +89,11 @@ class RCConfiguration(Configuration): return reverse('url_import_rc_conf', args=[str(self.id)]) @property + def ipp_unit(self): + + return '{} ({})'.format(self.ipp, int(self.ipp*self.km2unit)) + + @property def us2unit(self): return self.clock_in/self.clock_divider @@ -334,12 +340,11 @@ class RCConfiguration(Configuration): f = RCFile(filename) self.dict_to_parms(f.data) self.update_pulses() - self.save() def update_pulses(self): for line in self.get_lines(): - line.update_pulses() + line.update_pulses() def plot_pulses(self): @@ -349,9 +354,7 @@ class RCConfiguration(Configuration): from bokeh.mpl import to_bokeh from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, PreviewSaveTool - lines = self.get_lines() - - max_value = self.ipp*self.km2unit*self.ntx + lines = self.get_lines() N = len(lines) fig = plt.figure(figsize=(10, 2+N*0.5)) @@ -360,7 +363,7 @@ class RCConfiguration(Configuration): for i, line in enumerate(lines): labels.append(line.get_name()) - l = ax.plot((0, max_value),(N-i-1, N-i-1)) + l = ax.plot((0, self.total_units),(N-i-1, N-i-1)) points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points() if tup<>(0,0)] ax.broken_barh(points, (N-i-1, 0.5), edgecolor=l[0].get_color(), facecolor='none') @@ -496,7 +499,7 @@ class RCLine(models.Model): def pulses_as_array(self): - y = np.zeros(self.rc_configuration.ntx*self.rc_configuration.ipp*self.rc_configuration.km2unit) + y = np.zeros(self.rc_configuration.total_units) for tup in ast.literal_eval(self.pulses): y[tup[0]:tup[1]] = 1 @@ -534,7 +537,7 @@ class RCLine(models.Model): ipp = self.rc_configuration.ipp ntx = self.rc_configuration.ntx ipp_u = int(ipp*km2unit) - + total = ipp_u*ntx y = [] if self.line_type.name=='tr': @@ -661,38 +664,59 @@ class RCLine(models.Model): values = self.rc_configuration.parameters.split('-') confs = RCConfiguration.objects.filter(pk__in=[value.split('|')[0] for value in values]) modes = [value.split('|')[1] for value in values] - delays = [value.split('|')[2] for value in values] - masks = [value.split('|')[3] for value in values] + ops = [value.split('|')[2] for value in values] + delays = [value.split('|')[3] for value in values] + masks = [value.split('|')[4] for value in values] + mask = list('{:8b}'.format(int(masks[0]))) + mask.reverse() + if mask[self.channel] in ('0', '', ' '): + y = np.zeros(total, dtype=np.int8) + else: + y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array() - y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array() - ysize = len(y) for i in range(1, len(values)): mask = list('{:8b}'.format(int(masks[i]))) mask.reverse() if mask[self.channel] in ('0', '', ' '): continue - Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array() + Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array() delay = float(delays[i])*km2unit - if delay>0: - y_temp = np.empty_like(Y) - y_temp[:delay] = 0 - y_temp[delay:] = Y[:-delay] - y_tempsize = len(y_temp) - if modes[i]=='OR': + + if delay>0: + if delaylen(y): + y_new = np.zeros(delay+len(Y), dtype=np.int8) + y_new[:len(y)] = y + y = y_new + y_temp = np.zeros(delay+len(Y), dtype=np.int8) + y_temp[-len(Y):] = Y + elif delay+len(Y)==len(y): + y_temp = np.zeros(delay+len(Y)) + y_temp[-len(Y):] = Y + + if ops[i]=='OR': y = y | y_temp - elif modes[i]=='XOR': + elif ops[i]=='XOR': y = y ^ y_temp - elif modes[i]=='AND': + elif ops[i]=='AND': y = y & y_temp - elif modes[i]=='NAND': + elif ops[i]=='NAND': y = y & ~y_temp - + + total = len(y) y = self.array_to_points(y) else: y = [] + if self.rc_configuration.total_units <> total: + self.rc_configuration.total_units = total + self.rc_configuration.save() + self.pulses = y self.save() diff --git a/apps/rc/views.py b/apps/rc/views.py index e5e59b0..995cea2 100644 --- a/apps/rc/views.py +++ b/apps/rc/views.py @@ -27,7 +27,7 @@ def conf(request, conf_id): kwargs = {} kwargs['dev_conf'] = conf kwargs['rc_lines'] = lines - kwargs['dev_conf_keys'] = ['name', 'ipp', 'ntx', 'clock_in', 'clock_divider', 'clock', + kwargs['dev_conf_keys'] = ['name', 'ipp_unit', 'ntx', 'clock_in', 'clock_divider', 'clock', 'time_before', 'time_after', 'sync', 'sampling_reference', 'control_tx', 'control_sw'] kwargs['title'] = 'RC Configuration' @@ -116,7 +116,7 @@ def conf_edit(request, conf_id): line.save() #update pulses field - conf.update_pulses() + conf.update_pulses() messages.success(request, 'RC Configuration successfully updated')