From 82791b88ae92bf23ffe19bdeebceb49e3262cb8a 2016-08-18 13:04:53 From: Juan C. Espinoza Date: 2016-08-18 13:04:53 Subject: [PATCH] sync repo git-svn-id: http://jro-dev.igp.gob.pe/svn/jro_hard/radarsys/trunk/webapp@178 aa17d016-51d5-4e8b-934c-7b2bbb1bbe71 --- diff --git a/apps/jars/forms.py b/apps/jars/forms.py index f877964..93f584b 100644 --- a/apps/jars/forms.py +++ b/apps/jars/forms.py @@ -1,3 +1,5 @@ +import os + from django import forms from apps.main.models import Device, Experiment from .models import JARSConfiguration, JARSfilter @@ -42,4 +44,40 @@ class JARSfilterForm(forms.ModelForm): class Meta: model = JARSfilter - exclude = ('type', 'parameters', 'status') \ No newline at end of file + exclude = ('type', 'parameters', 'status') + +class ExtFileField(forms.FileField): + """ + Same as forms.FileField, but you can specify a file extension whitelist. + + >>> from django.core.files.uploadedfile import SimpleUploadedFile + >>> + >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt")) + >>> + >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content')) + >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content')) + >>> + >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content')) + Traceback (most recent call last): + ... + ValidationError: [u'Not allowed filetype!'] + """ + def __init__(self, *args, **kwargs): + extensions = kwargs.pop("extensions") + self.extensions = [i.lower() for i in extensions] + + super(ExtFileField, self).__init__(*args, **kwargs) + + def clean(self, *args, **kwargs): + data = super(ExtFileField, self).clean(*args, **kwargs) + filename = data.name + ext = os.path.splitext(filename)[1] + ext = ext.lower() + if ext not in self.extensions: + raise forms.ValidationError('Not allowed file type: %s' % ext) + + +class JARSImportForm(forms.Form): + + #file_name = ExtFileField(extensions=['.racp', '.json', '.dat']) + file_name = ExtFileField(extensions=['.json']) \ No newline at end of file diff --git a/apps/jars/models.py b/apps/jars/models.py index 9e3bd16..dbd8a96 100644 --- a/apps/jars/models.py +++ b/apps/jars/models.py @@ -1,8 +1,12 @@ from django.db import models from apps.main.models import Configuration from django.core.validators import MinValueValidator, MaxValueValidator +from django.core.urlresolvers import reverse +from devices.jars import api from apps.rc.models import RCConfiguration + +import json # Create your models here. EXPERIMENT_TYPE = ( @@ -77,12 +81,15 @@ class JARSConfiguration(Configuration): cards_number = models.PositiveIntegerField(verbose_name='Number of Cards', validators=[MinValueValidator(1), MaxValueValidator(4)], default = 1) channels_number = models.PositiveIntegerField(verbose_name='Number of Channels', validators=[MinValueValidator(1), MaxValueValidator(8)], default = 5) channels = models.CharField(verbose_name='Channels', max_length=15, default = '1,2,3,4,5') - rd_directory = models.CharField(verbose_name='Raw Data Directory', max_length=40, default='', blank=True, null=True) - raw_data_blocks = models.PositiveIntegerField(verbose_name='Raw Data Blocks', validators=[MaxValueValidator(5000)], default=120) + rd_directory = models.CharField(verbose_name='Raw Data Directory', max_length=200, default='', blank=True, null=True) + pd_directory = models.CharField(verbose_name='Process Data Directory', max_length=200, default='', blank=True, null=True) + #raw_data_blocks = models.PositiveIntegerField(verbose_name='Raw Data Blocks', validators=[MaxValueValidator(5000)], default=120) data_type = models.PositiveIntegerField(verbose_name='Data Type', choices=DATA_TYPE, default=0) acq_profiles = models.PositiveIntegerField(verbose_name='Acquired Profiles', validators=[MaxValueValidator(5000)], default=400) profiles_block = models.PositiveIntegerField(verbose_name='Profiles Per Block', validators=[MaxValueValidator(5000)], default=400) + ftp_interval = models.PositiveIntegerField(verbose_name='FTP Interval', default=60) fftpoints = models.PositiveIntegerField(verbose_name='FFT Points',default=16) + cohe_integr_str = models.PositiveIntegerField(verbose_name='Coh. Int. Stride',validators=[MinValueValidator(1)], default=30) cohe_integr = models.PositiveIntegerField(verbose_name='Coherent Integrations',validators=[MinValueValidator(1)], default=30) incohe_integr = models.PositiveIntegerField(verbose_name='Incoherent Integrations',validators=[MinValueValidator(1)], default=30) filter = models.ForeignKey(JARSfilter, on_delete=models.CASCADE, null=True) @@ -90,9 +97,10 @@ class JARSConfiguration(Configuration): spectral = models.CharField(verbose_name='Combinations', max_length=5000, default = '[0, 0],') create_directory = models.BooleanField(verbose_name='Create Directory Per Day', default=True) include_expname = models.BooleanField(verbose_name='Experiment Name in Directory', default=True) - acq_link = models.BooleanField(verbose_name='Acquisition Link', default=True) - view_raw_data = models.BooleanField(verbose_name='View Raw Data', default=True) + #acq_link = models.BooleanField(verbose_name='Acquisition Link', default=True) + #view_raw_data = models.BooleanField(verbose_name='View Raw Data', default=True) save_ch_dc = models.BooleanField(verbose_name='Save Channels DC', default=True) + save_data = models.BooleanField(verbose_name='Save Data', default=True) filter_parms = models.CharField(max_length=10000, default='{}') class Meta: @@ -102,6 +110,7 @@ class JARSConfiguration(Configuration): parameters = {} + parameters['device_id'] = self.device.id parameters['name'] = self.name #parameters['rc'] = self.rc.name parameters['exp_type'] = self.exp_type @@ -110,26 +119,31 @@ class JARSConfiguration(Configuration): parameters['channels_number'] = self.channels_number parameters['channels'] = self.channels parameters['rd_directory'] = self.rd_directory - parameters['raw_data_blocks'] = self.raw_data_blocks + #parameters['raw_data_blocks'] = self.raw_data_blocks parameters['data_type'] = self.data_type + parameters['cohe_integr_str'] = self.cohe_integr_str parameters['acq_profiles'] = self.acq_profiles parameters['profiles_block'] = self.profiles_block + parameters['ftp_interval'] = self.ftp_interval parameters['fftpoints'] = self.fftpoints parameters['cohe_integr'] = self.cohe_integr #parameters['incohe_integr'] = self.incohe_integr parameters['filter'] = self.filter.name + parameters['filter_parms'] = self.filter_parms #parameters['spectral_number'] = self.spectral_number #parameters['spectral'] = self.spectral parameters['create_directory'] = bool(self.create_directory) parameters['include_expname'] = bool(self.include_expname) - parameters['acq_link'] = bool(self.acq_link) - parameters['view_raw_data'] = bool(self.view_raw_data) + #parameters['acq_link'] = bool(self.acq_link) + #parameters['view_raw_data'] = bool(self.view_raw_data) parameters['save_ch_dc'] = bool(self.save_ch_dc) + parameters['save_data'] = bool(self.save_data) if parameters['exptype'] == 'PDATA': parameters['incohe_integr'] = self.incohe_integr parameters['spectral_number'] = self.spectral_number parameters['spectral'] = self.spectral + parameters['pd_directory'] = self.pd_directory return parameters @@ -139,39 +153,116 @@ class JARSConfiguration(Configuration): def dict_to_parms(self, parameters): + self.name = parameters['name'] + self.device.id = int(parameters['device_id']) + self.exp_type = int(parameters['exp_type']) if parameters['exptype'] == 'PDATA': self.incohe_integr = parameters['incohe_integr'] self.spectral_number = parameters['spectral_number'] - self.spectral = parameters['spectral'] + self.spectral = parameters['spectral'] + self.pd_directory = parameters['pd_directory'] self.cards_number = int(parameters['cards_number']) self.channels_number = int(parameters['channels_number']) self.channels = parameters['channels'] self.rd_directory = parameters['rd_directory'] - self.raw_data_blocks = parameters['raw_data_blocks'] + #self.raw_data_blocks = parameters['raw_data_blocks'] self.data_type = parameters['data_type'] + self.cohe_integr_str = parameters['cohe_integr_str'] self.acq_profiles = parameters['acq_profiles'] self.profiles_block = parameters['profiles_block'] + self.ftp_interval = parameters['ftp_interval'] self.fftpoints = parameters['fftpoints'] self.cohe_integr = parameters['cohe_integr'] - filter_name = parameters['filter'] - self.filter = JARS.objects.get(name=filter_name) - self.save() + filter_name = parameters['filter'] + self.filter = JARSfilter.objects.get(name=filter_name) self.add_parms_to_filter() + self.filter_parms = parameters['filter_parms'] self.create_directory = bool(parameters['create_directory']) self.include_expname = bool(parameters['include_expname']) - self.acq_link = bool(parameters['acq_link']) - self.view_raw_data = bool(parameters['view_raw_data']) + #self.acq_link = bool(parameters['acq_link']) + #self.view_raw_data = bool(parameters['view_raw_data']) self.save_ch_dc = bool(parameters['save_ch_dc']) + self.save_data = bool(parameters['save_data']) def status_device(self): - return + + answer = api.status(self.device.ip_address,self.device.port_address) + self.device.status = int(answer[0]) + self.message = answer[2:] + self.device.save() + + return self.device.status + + def stop_device(self): + + answer = api.stop(self.device.ip_address,self.device.port_address) + self.device.status = int(answer[0]) + self.message = answer[2:] + self.device.save() + + return self.device.status def read_device(self): - return + + answer = api.read(self.device.ip_address,self.device.port_address) + self.device.status = int(answer[0]) + try: + data = json.loads(answer[2:]) + parms = data['configurations']['jars'] + except: + self.device.status = 0 + self.device.save() + self.message = 'Could not read JARS configuration.' + return '' + + #self.dict_to_parms(parms) + self.message = 'Current JARS configuration was read successfully.' + self.device.save() + return parms + def write_device(self): - return \ No newline at end of file + + data = self.experiment.parms_to_dict() + data = json.loads(data) + data['configurations']['dds'] ='' + data['configurations']['cgs'] ='' + data['configurations']['rc']['pulses']='' + data['configurations']['rc']['delays']='' + json_data = json.dumps(data) + + answer = api.configure(self.device.ip_address,self.device.port_address,json_data) + #print answer + self.device.status = int(answer[0]) + self.message = answer[2:] + + self.device.save() + + return self.device.status + + + def echo(self): + + answer = api.echo(self.device.ip_address,self.device.port_address,'(=') + #print answer + self.device.status = int(answer[0]) + self.message = answer[2:] + + self.device.save() + + return #self.device.status + + def update_from_file(self, parameters): + + self.dict_to_parms(parameters) + self.save() + + def get_absolute_url_import(self): + return reverse('url_import_jars_conf', args=[str(self.id)]) + + def get_absolute_url_read(self): + return reverse('url_read_jars_conf', args=[str(self.id)]) \ No newline at end of file diff --git a/apps/jars/templates/jars_import.html b/apps/jars/templates/jars_import.html new file mode 100644 index 0000000..b105cc5 --- /dev/null +++ b/apps/jars/templates/jars_import.html @@ -0,0 +1 @@ +{% extends "dev_conf_edit.html" %} diff --git a/apps/jars/urls.py b/apps/jars/urls.py index 90f588c..8287982 100644 --- a/apps/jars/urls.py +++ b/apps/jars/urls.py @@ -6,4 +6,6 @@ urlpatterns = ( url(r'^(?P-?\d+)/new_filter/$', 'apps.jars.views.new_filter', name='url_new_jars_filter'), url(r'^(?P-?\d+)/view_filter/(?P-?\d+)/$', 'apps.jars.views.view_filter', name='url_jars_filter'), url(r'^(?P-?\d+)/view_filter/(?P-?\d+)/edit$', 'apps.jars.views.edit_filter', name='url_edit_jars_filter'), + url(r'^(?P-?\d+)/import/$', 'apps.jars.views.import_file', name='url_import_jars_conf'), + url(r'^(?P-?\d+)/read/$', 'apps.jars.views.read_conf', name='url_read_jars_conf'), ) diff --git a/apps/jars/views.py b/apps/jars/views.py index f1e9ce2..764163a 100644 --- a/apps/jars/views.py +++ b/apps/jars/views.py @@ -7,7 +7,7 @@ from apps.main.models import Device from apps.main.views import sidebar from .models import JARSConfiguration, JARSfilter -from .forms import JARSConfigurationForm, JARSfilterForm +from .forms import JARSConfigurationForm, JARSfilterForm, JARSImportForm # Create your views here. def jars_conf(request, id_conf): @@ -24,18 +24,22 @@ def jars_conf(request, id_conf): kwargs['dev_conf'] = conf kwargs['dev_conf_keys'] = ['name', 'cards_number', 'channels_number', 'channels', - 'rd_directory', 'raw_data_blocks', 'data_type', - 'acq_profiles', 'profiles_block', 'fftpoints', + 'rd_directory', 'pd_directory', + 'data_type', + 'acq_profiles', 'profiles_block', 'ftp_interval', 'fftpoints', + 'cohe_integr_str', 'incohe_integr', 'cohe_integr', 'filter', 'spectral_number', 'spectral', 'create_directory', 'include_expname', - 'acq_link', 'view_raw_data', 'save_ch_dc',] + 'save_ch_dc', 'save_data'] kwargs['title'] = 'JARS Configuration' kwargs['suptitle'] = 'Details' kwargs['button'] = 'Edit Configuration' - kwargs['no_play'] = True + #kwargs['no_play'] = True + + kwargs['only_stop'] = True ###### SIDEBAR ###### kwargs.update(sidebar(conf=conf)) @@ -70,6 +74,74 @@ def jars_conf_edit(request, id_conf): return render(request, 'jars_conf_edit.html', kwargs) +def import_file(request, conf_id): + + conf = get_object_or_404(JARSConfiguration, pk=conf_id) + if request.method=='POST': + form = JARSImportForm(request.POST, request.FILES) + if form.is_valid(): + try: + parms = conf.import_from_file(request.FILES['file_name']) + + if parms: + conf.update_from_file(parms) + messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name']) + return redirect(conf.get_absolute_url_edit()) + + except Exception as e: + messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], e)) + + else: + messages.warning(request, 'Your current configuration will be replaced') + form = JARSImportForm() + + kwargs = {} + kwargs['form'] = form + kwargs['title'] = 'JARS Configuration' + kwargs['suptitle'] = 'Import file' + kwargs['button'] = 'Upload' + kwargs['previous'] = conf.get_absolute_url() + + return render(request, 'jars_import.html', kwargs) + +def read_conf(request, conf_id): + + conf = get_object_or_404(JARSConfiguration, pk=conf_id) + #filter = get_object_or_404(JARSfilter, pk=filter_id) + + if request.method=='GET': + + parms = conf.read_device() + conf.status_device() + + if not parms: + messages.error(request, conf.message) + return redirect(conf.get_absolute_url()) + + form = JARSConfigurationForm(initial=parms, instance=conf) + + if request.method=='POST': + form = JARSConfigurationForm(request.POST, instance=conf) + + if form.is_valid(): + form.save() + return redirect(conf.get_absolute_url()) + + messages.error(request, "Parameters could not be saved") + + kwargs = {} + kwargs['id_dev'] = conf.id + kwargs['filter_id'] = conf.filter.id + kwargs['form'] = form + kwargs['title'] = 'Device Configuration' + kwargs['suptitle'] = 'Parameters read from device' + kwargs['button'] = 'Save' + + ###### SIDEBAR ###### + kwargs.update(sidebar(conf=conf)) + + return render(request, 'jars_conf_edit.html', kwargs) + def view_filter(request, conf_id, filter_id): conf = get_object_or_404(JARSConfiguration, pk=conf_id) diff --git a/apps/main/models.py b/apps/main/models.py index 1cb2f13..0465cab 100644 --- a/apps/main/models.py +++ b/apps/main/models.py @@ -376,6 +376,16 @@ class Experiment(models.Model): #--For ABS Device: #--For USRP Device: #--For JARS Device: + if conf_type == 'jars': + device = get_object_or_404(Device, pk=parms['configurations']['jars']['device_id']) + DevConfModel = CONF_MODELS[conf_type] + confjars_form = DevConfModel( + experiment = self, + name = 'JARS', + device=device, + ) + confjars_form.dict_to_parms(parms['configurations']['jars']) + confjars_form.save() #--For RC Device: if conf_type == 'rc': device = get_object_or_404(Device, pk=parms['configurations']['rc']['device_id']) diff --git a/apps/main/templates/dev_conf.html b/apps/main/templates/dev_conf.html index 2b113a9..171ce2b 100644 --- a/apps/main/templates/dev_conf.html +++ b/apps/main/templates/dev_conf.html @@ -23,7 +23,9 @@
  • ----------------
  • Status
  • {% if not no_play %} -
  • Start
  • + {% if not only_stop %} +
  • Start
  • + {% endif %}
  • Stop
  • {% endif %}
  • Write
  • diff --git a/apps/main/templates/experiment_summary.html b/apps/main/templates/experiment_summary.html index 5fb82da..b888a18 100644 --- a/apps/main/templates/experiment_summary.html +++ b/apps/main/templates/experiment_summary.html @@ -38,67 +38,77 @@ {% endfor %} -
    -

    Parameters

    -
    -
    - {% for configuration in configurations %} + {% if configuration.device.device_type.name == 'dds' %} - - +
    +

    DDS

    +
    +
    + +
    dds(=
    + + +
    dds(=
    {% endif %} {% if configuration.device.device_type.name == 'rc' %} - - IPP(km){{experiment_data.configurations.rc.ipp}} - NTX{{experiment_data.configurations.rc.ntx}} - TX{{tx}} - Code{{code}} - Sampling Window{{window|linebreaks}} - {% endif %} +
    +

    CR

    +
    +
    - {% if configuration.device.device_type.name == 'rc_mix' %} - - rc_mix(= + + + + + + + +
    IPP(km){{experiment_data.configurations.rc.ipp}}
    NTX{{experiment_data.configurations.rc.ntx}}
    TX{{tx}}
    Code{{code}}
    Sampling Window{{window|linebreaks}}
    {% endif %} {% if configuration.device.device_type.name == 'jars' %} - - Data Type{{exp_type}} - # Channels{{configuration.channels_number}} - Coh Int{{configuration.cohe_integr}} - FFT Points{{configuration.fftpoints}} - {% if exp_type == 'PDATA'%} - Inc Int{{configuration.incohe_integr}} - Spec. Comb.{{configuration.spectral}} - {% endif %} - Acq Prof{{configuration.acq_profiles}} - Prof x Block{{configuration.profiles_block}} - Block x File(= - {% endif %} - - {% if configuration.device.device_type.name == 'usrp' %} - - usrp(= - {% endif %} - - {% if configuration.device.device_type.name == 'cgs' %} - - - - - - {% endif %} +
    +

    JARS

    +
    +
    - {% if configuration.device.device_type.name == 'abs' %} - - abs(= + + + + + + + {% if exp_type == 'PDATA'%} + + + {% endif %} + + + +
    Data Type{{exp_type}}
    # Channels{{configuration.channels_number}}
    Coh Int{{configuration.cohe_integr}}
    FFT Points{{configuration.fftpoints}}
    Inc Int{{configuration.incohe_integr}}
    Spec. Comb.{{configuration.spectral}}
    Acq Prof{{configuration.acq_profiles}}
    Prof x Block{{configuration.profiles_block}}
    Block x File{{ configuration.raw_data_blocks }}
    {% endif %} + {% endfor %} + + +
    +

    Extra Parameters

    +
    +
    + + +{% if jars_conf %} + +{% endif %} +{% if dds_conf %} + +{% endif %}
    Rate (MB/h){{ rate }}
    Vmax (m/s){{ rate }}
    +
    @@ -121,5 +131,9 @@ document.location = "{% url 'url_experiment' experiment.id%}"; }); + $("#bt_verify").click(function() { + document.location = "{% url 'url_verify_experiment' experiment.id%}"; + }); + {% endblock %} \ No newline at end of file diff --git a/apps/main/templates/experiment_verify.html b/apps/main/templates/experiment_verify.html new file mode 100644 index 0000000..5c1f7af --- /dev/null +++ b/apps/main/templates/experiment_verify.html @@ -0,0 +1,145 @@ +{% extends "base.html" %} +{% load bootstrap3 %} +{% load static %} +{% load main_tags %} +{% block extra-head %} + +{% endblock %} + +{% block exp-active %}active{% endblock %} + +{% block content-title %}{{title}}{% endblock %} +{% block content-suptitle %}{{suptitle}}{% endblock %} + +{% block content %} + +{% block menu-actions %} + +{% endblock %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParametersDDSRCJARS=P
    Clock In{{ dds.clock }}{{ rc.clock_in }}{{ filter_parms.clock }}
    Frequency A (Mhz){{ dds.frequencyA_Mhz }}x{{ filter_parms.fch }}
    Frequency A (Decimal){{ dds.frequencyA }}x{{ filter_parms.fch_decimal }}
    Sampling Frequency (MHz){{ dds.frequencyA }}{{ samp_freq_rc }}{{ samp_freq_jars }}
    + + + +
    +

    Extra Parameters

    +
    +
    + + +{% for configuration in configurations %} + {% if configuration.device.device_type.name == 'jars' %} + + {% endif %} +{% endfor %} +
    Rate(MB/h){{ rate }}
    + + +
    + + +
    + +{% endblock %} + +{% block sidebar%} + {% include "sidebar_devices.html" %} +{% endblock %} + +{% block extra-js%} + +{% endblock %} \ No newline at end of file diff --git a/apps/main/urls.py b/apps/main/urls.py index c7eb84b..9854607 100644 --- a/apps/main/urls.py +++ b/apps/main/urls.py @@ -31,6 +31,7 @@ urlpatterns = ( url(r'^experiment/(?P-?\d+)/mix/$', 'apps.main.views.experiment_mix', name='url_mix_experiment'), url(r'^experiment/(?P-?\d+)/mix/delete/$', 'apps.main.views.experiment_mix_delete', name='url_delete_mix_experiment'), url(r'^experiment/(?P-?\d+)/summary/$', 'apps.main.views.experiment_summary', name='url_sum_experiment'), + url(r'^experiment/(?P-?\d+)/verify/$', 'apps.main.views.experiment_verify', name='url_verify_experiment'), url(r'^experiment/(?P-?\d+)/new_dev_conf/$', 'apps.main.views.dev_conf_new', name='url_add_dev_conf'), url(r'^experiment/(?P-?\d+)/new_dev_conf/(?P-?\d+)/$', 'apps.main.views.dev_conf_new', name='url_add_dev_conf'), diff --git a/apps/main/views.py b/apps/main/views.py index 050d03d..bfb9245 100644 --- a/apps/main/views.py +++ b/apps/main/views.py @@ -25,6 +25,7 @@ from apps.abs.models import ABSConfiguration from apps.rc.models import RCConfiguration, RCLine, RCLineType from apps.dds.models import DDSConfiguration from django.http.request import QueryDict +#from __builtin__ import False # Create your views here. @@ -756,6 +757,7 @@ def experiment_mix_delete(request, id_exp): def experiment_summary(request, id_exp): import json + import ast experiment = get_object_or_404(Experiment, pk=id_exp) experiment_data = json.loads(experiment.parms_to_dict()) @@ -775,12 +777,28 @@ def experiment_summary(request, id_exp): kwargs['button'] = 'Verify Parameters' + jars_conf = False + rc_conf = False + for configuration in configurations: + #-------------------- JARS -----------------------: if configuration.device.device_type.name == 'jars': - kwargs['exp_type'] = EXPERIMENT_TYPE[configuration.exp_type][1] - + jars_conf = True + kwargs['jars_conf'] = jars_conf + kwargs['exp_type'] = EXPERIMENT_TYPE[configuration.exp_type][1] + channels_number = configuration.channels_number + exp_type = configuration.exp_type + fftpoints = configuration.fftpoints + filter_parms = configuration.filter_parms + filter_parms = ast.literal_eval(filter_parms) + spectral_number = configuration.spectral_number + + #--------------------- RC ----------------------: if configuration.device.device_type.name == 'rc': + rc_conf = True + kwargs['rc_conf'] = rc_conf rc_lines = experiment_data['configurations']['rc']['lines'] + ipp = configuration.ipp if experiment_data['configurations']['rc']['mix'] == 'True': tx = '' code = '' @@ -805,12 +823,136 @@ def experiment_summary(request, id_exp): kwargs['tx'] = tx kwargs['code'] = code kwargs['window'] = window - + + #-------------------- DDS -----------------------: + if configuration.device.device_type.name == 'dds': + dds_conf = True + kwargs['dds_conf'] = dds_conf + + #------ RC & JARS ------: + ipp = 937.5 # + nsa = 200# + dh = 1.5 # + channels_number = 5 # + + if rc_conf and jars_conf: + if exp_type == 0: #Short + bytes = 2 + b = nsa*2*bytes*channels_number + else: #Float + bytes = 4 + channels = channels_number + spectral_number + b = nsa*2*bytes*fftpoints*channels + + ipps = (ipp*pow(10,-6))/0.15 + GB = 1048576.0*1024.0 + Hour = 3600 + rate = b/ipps + rate = rate *(1/GB)*(Hour) + kwargs['rate'] = str(rate)+" GB/h" + else: + kwargs['rate'] = '' + ###### SIDEBAR ###### kwargs.update(sidebar(experiment=experiment)) return render(request, 'experiment_summary.html', kwargs) +def experiment_verify(request, id_exp): + + import json + import ast + + experiment = get_object_or_404(Experiment, pk=id_exp) + experiment_data = json.loads(experiment.parms_to_dict()) + configurations = Configuration.objects.filter(experiment=experiment, type=0) + + kwargs = {} + + kwargs['experiment_keys'] = ['template', 'radar_system', 'name', 'start_time', 'end_time'] + kwargs['experiment'] = experiment + + kwargs['configuration_keys'] = ['name', 'device__ip_address', 'device__port_address', 'device__status'] + kwargs['configurations'] = configurations + kwargs['experiment_data'] = experiment_data + + kwargs['title'] = 'Verify Experiment' + kwargs['suptitle'] = 'Parameters' + + kwargs['button'] = 'Update' + + jars_conf = False + rc_conf = False + dds_conf = False + + for configuration in configurations: + #-------------------- JARS -----------------------: + if configuration.device.device_type.name == 'jars': + jars_conf = True + kwargs['jars_conf'] = jars_conf + filter_parms = configuration.filter_parms + filter_parms = ast.literal_eval(filter_parms) + kwargs['filter_parms'] = filter_parms + #--Sampling Frequency + clock = filter_parms['clock'] + filter_2 = filter_parms['filter_2'] + filter_5 = filter_parms['filter_5'] + filter_fir = filter_parms['filter_fir'] + samp_freq_jars = clock/filter_2/filter_5/filter_fir + + kwargs['samp_freq_jars'] = samp_freq_jars + kwargs['jars'] = configuration + + #--------------------- RC ----------------------: + if configuration.device.device_type.name == 'rc': + rc_conf = True + rc_parms = configuration.parms_to_dict() + if rc_parms['mix'] == 'True': + pass + else: + rc_lines = rc_parms['lines'] + dh = rc_lines[6]['params'][0]['resolution'] + #--Sampling Frequency + samp_freq_rc = 0.15/dh + kwargs['samp_freq_rc'] = samp_freq_rc + + kwargs['rc_conf'] = rc_conf + kwargs['rc'] = configuration + + #-------------------- DDS ----------------------: + if configuration.device.device_type.name == 'dds': + dds_conf = True + dds_parms = configuration.parms_to_dict() + + kwargs['dds_conf'] = dds_conf + kwargs['dds'] = configuration + + + #------------Validation------------: + #Clock + if dds_conf and rc_conf and jars_conf: + if filter_parms['clock'] != rc_parms['clock_in'] and rc_parms['clock_in'] != dds_parms['clock']: + messages.warning(request, "Devices don't have the same clock.") + elif rc_conf and jars_conf: + if filter_parms['clock'] != rc_parms['clock_in']: + messages.warning(request, "Devices don't have the same clock.") + elif rc_conf and dds_conf: + if rc_parms['clock_in'] != dds_parms['clock']: + messages.warning(request, "Devices don't have the same clock.") + if float(samp_freq_rc) != float(dds_parms['frequencyA']): + messages.warning(request, "Devices don't have the same Frequency A.") + + + + ###### SIDEBAR ###### + kwargs.update(sidebar(experiment=experiment)) + + + + + + return render(request, 'experiment_verify.html', kwargs) + def parse_mix_result(s): @@ -1055,7 +1197,7 @@ def dev_conf_write(request, id_conf): messages.success(request, conf.message) #Creating a historical configuration - conf.clone(type=0, template=False) + conf.clone(type=1, template=False) #Original configuration conf = DevConfModel.objects.get(pk=id_conf) diff --git a/apps/rc/fixtures/rc_initial_data.json b/apps/rc/fixtures/rc_initial_data.json index ddd87e4..72b6bb7 100644 --- a/apps/rc/fixtures/rc_initial_data.json +++ b/apps/rc/fixtures/rc_initial_data.json @@ -20,7 +20,7 @@ {"fields": {"params": "{\"TX_ref\": {\"model\": \"RCLine\", \"value\": \"\"}, \"range\": { \"value\": 0, \"help\": \"Frame numbers or frame ranges separated by commas, use 0 for all frames eg: 1,2,10-15\"}}", "name": "tr", "description": ""}, "model": "rc.rclinetype", "pk": 1}, {"fields": {"params": "{\"pulse_width\":{\"value\": 0, \"widget\":\"dc\"},\r\n \"delays\":{\"value\": \"\", \"widget\":\"km\", \"help\": \"Delay entries separated by commas (TAUs)\"},\r\n \"range\":{\"value\": 0, \"help\": \"Frame numbers or frame ranges separated by commas, use 0 for all frames eg: 1,2,10-15\"}}", "name": "tx", "description": ""}, "model": "rc.rclinetype", "pk": 2}, {"fields": {"params": "{\"TX_ref\": {\"model\": \"RCLine\", \"value\": \"\"}, \"code\": {\"model\":\"RCLineCode\",\"value\": \"\"}, \"codes\":{\"value\":\"\", \"widget\":\"codes\"}}", "name": "codes", "description": ""}, "model": "rc.rclinetype", "pk": 3}, - {"fields": {"params": "{ \"TX_ref\":{\"model\": \"RCLine\", \"value\": \"\"}, \"params\": {\"first_height\":{ \"value\": 0, \"widget\":\"km\"},\"resolution\": {\"value\": 0, \"widget\":\"km\"}, \"number_of_samples\": { \"value\": 0, \"help\":\"number of samples (NSA)\"}}}", "name": "windows", "description": ""}, "model": "rc.rclinetype", "pk": 4}, + {"fields": {"params": "{ \"TX_ref\":{\"model\": \"RCLine\", \"value\": \"\"}, \"params\": {\"first_height\":{ \"value\": 0, \"widget\":\"km\"},\"resolution\": {\"value\": 0, \"widget\":\"km\"}, \"number_of_samples\": { \"value\": 0, \"help\":\"number of samples (NSA)\"}, \"last_height\": { \"value\": 0}}}", "name": "windows", "description": ""}, "model": "rc.rclinetype", "pk": 4}, {"fields": {"params": "{\"invert\":{\"value\": 0, \"help\": \"Set to 1 for synchro pulse at the end\"}}", "name": "sync", "description": ""}, "model": "rc.rclinetype", "pk": 5}, {"fields": {"params": "{ \"periodic\": { \"value\": 0, \"help\": \"Set to 1 for IPP periodic\"}, \"params\": {\"begin\": { \"value\": 0, \"widget\":\"unit\"}, \"end\": {\"value\": 0, \"widget\":\"unit\"}}}", "name": "prog_pulses", "description": ""}, "model": "rc.rclinetype", "pk": 6}, {"fields": {"params": "{\"number_of_flips\": {\"value\": 0}}", "name": "flip", "description": ""}, "model": "rc.rclinetype", "pk": 7}, diff --git a/apps/rc/models.py b/apps/rc/models.py index 011a9d6..3ef3c73 100644 --- a/apps/rc/models.py +++ b/apps/rc/models.py @@ -30,6 +30,7 @@ LINE_TYPES = ( SAMPLING_REFS = ( ('none', 'No Reference'), + ('begin_baud', 'Begin of the first baud'), ('first_baud', 'Middle of the first baud'), ('sub_baud', 'Middle of the sub-baud') ) @@ -145,12 +146,13 @@ class RCConfiguration(Configuration): data['lines'] = [] for line in self.get_lines(): - line_data = json.loads(line.params) + line_data = json.loads(line.params) if 'TX_ref' in line_data and line_data['TX_ref'] not in (0, '0'): - line_data['TX_ref'] = RCLine.objects.get(pk=line_data['TX_ref']).get_name() + line_data['TX_ref'] = line.get_name() if 'code' in line_data: line_data['code'] = RCLineCode.objects.get(pk=line_data['code']).name line_data['type'] = line.line_type.name + line_data['name'] = line.get_name() data['lines'].append(line_data) data['delays'] = self.get_delays() @@ -341,7 +343,7 @@ class RCConfiguration(Configuration): for line in self.get_lines(): line.update_pulses() - def plot_pulses(self): + def plot_pulses(self, km=False): import matplotlib.pyplot as plt from bokeh.resources import CDN @@ -352,19 +354,29 @@ class RCConfiguration(Configuration): lines = self.get_lines() N = len(lines) + npoints = self.total_units/self.km2unit if km else self.total_units fig = plt.figure(figsize=(10, 2+N*0.5)) ax = fig.add_subplot(111) - labels = [] + labels = ['IPP'] for i, line in enumerate(lines): - labels.append(line.get_name()) - 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)] + labels.append(line.get_name(channel=True)) + l = ax.plot((0, npoints),(N-i-1, N-i-1)) + points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points(km=km) if tup<>(0,0)] ax.broken_barh(points, (N-i-1, 0.5), edgecolor=l[0].get_color(), facecolor='none') + n = 0 + f = ((self.ntx+50)/100)*5 if ((self.ntx+50)/100)*10>0 else 2 + for x in np.arange(0, npoints, self.ipp if km else self.ipp*self.km2unit): + if n%f==0: + ax.text(x, N, '%s' % n, size=10) + n += 1 + + labels.reverse() ax.set_yticklabels(labels) + ax.set_xlabel = 'Units' plot = to_bokeh(fig, use_pandas=False) plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), PreviewSaveTool()] @@ -468,7 +480,7 @@ class RCLine(models.Model): return self - def get_name(self): + def get_name(self, channel=False): chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' s = '' @@ -484,10 +496,13 @@ class RCLine(models.Model): ref = RCLine.objects.get(pk=pk) s = chars[ref.position] s = '({})'.format(s) - if s: - return '{}{} {}'.format(self.line_type.name.upper(), s, self.channel) + + s = '{}{}'.format(self.line_type.name.upper(), s) + + if channel: + return '{} {}'.format(s, self.channel) else: - return '{} {}'.format(self.line_type.name.upper(), self.channel) + return s def get_lines(self, **kwargs): @@ -502,9 +517,13 @@ class RCLine(models.Model): return y.astype(np.int8) - def pulses_as_points(self): + def pulses_as_points(self, km=False): - return ast.literal_eval(self.pulses) + if km: + unit2km = 1/self.rc_configuration.km2unit + return [(tup[0]*unit2km, tup[1]*unit2km) for tup in ast.literal_eval(self.pulses)] + else: + return ast.literal_eval(self.pulses) def get_win_ref(self, params, tx_id, km2unit): diff --git a/apps/rc/static/js/cr.js b/apps/rc/static/js/cr.js index 4624c11..06d50e0 100644 --- a/apps/rc/static/js/cr.js +++ b/apps/rc/static/js/cr.js @@ -14,7 +14,18 @@ function str2unit(s){ var ret = ""; values = s.split(","); for (i=0; i0){ + llabel = label.replace("first_height", "last_height"); + rlabel = label.replace("first_height", "resolution"); + nlabel = label.replace("first_height", "number_of_samples"); + value = parseFloat($(label).val())+parseFloat($(rlabel).val())*(parseInt($(nlabel).val())-1); + $(llabel).val(value); + } + + if (label.indexOf("resolution")>0){ + llabel = label.replace("resolution", "last_height"); + flabel = label.replace("resolution", "first_height"); + nlabel = label.replace("resolution", "number_of_samples"); + value = parseFloat($(flabel).val())+parseFloat($(label).val())*(parseInt($(nlabel).val())-1); + $(llabel).val(value); + } + + if (label.indexOf("number_of_samples")>0){ + llabel = label.replace("number_of_samples", "last_height"); + rlabel = label.replace("number_of_samples", "resolution"); + flabel = label.replace("number_of_samples", "first_height"); + value = parseFloat($(flabel).val())+parseFloat($(rlabel).val())*(parseInt($(label).val())-1); + $(llabel).val(value); + } + + if (label.indexOf("last_height")>0){ + flabel = label.replace("last_height", "first_height"); + rlabel = label.replace("last_height", "resolution"); + nlabel = label.replace("last_height", "number_of_samples"); + + nvalue = Math.round((parseFloat($(label).val())-parseFloat($(flabel).val()))/parseFloat($(rlabel).val()))+1; + $(nlabel).val(nvalue); + value = parseFloat($(flabel).val())+parseFloat($(rlabel).val())*(nvalue-1); + $(label).val(value); + } + +} $("#id_clock_in").change(function() { $("#id_clock").val(parseFloat($('#id_clock_in').val())/parseFloat($('#id_clock_divider').val())); diff --git a/apps/rc/templates/rc_conf.html b/apps/rc/templates/rc_conf.html index eb4620a..908d85d 100644 --- a/apps/rc/templates/rc_conf.html +++ b/apps/rc/templates/rc_conf.html @@ -10,9 +10,18 @@ {% block extra-content %}
    -

    RC Lines


    +

    RC Lines

    +
    {% include "rc_lines.html" %}
    {% endblock extra-content%} + +{% block extra-js%} + +{% endblock %} \ No newline at end of file diff --git a/apps/rc/templates/rc_conf_edit.html b/apps/rc/templates/rc_conf_edit.html index 59eaea2..caefff5 100644 --- a/apps/rc/templates/rc_conf_edit.html +++ b/apps/rc/templates/rc_conf_edit.html @@ -68,6 +68,10 @@ } }); + $("#bt_toggle").click(function() { + $(".panel-collapse").collapse('toggle') + }); + {% endblock %} \ No newline at end of file diff --git a/apps/rc/templates/rc_lines.html b/apps/rc/templates/rc_lines.html index f72b811..647beab 100644 --- a/apps/rc/templates/rc_lines.html +++ b/apps/rc/templates/rc_lines.html @@ -1,5 +1,7 @@ {% load bootstrap3 %} - +


    {% for line in rc_lines %}