##// END OF EJS Templates
DDS commands working...
Miguel Urco -
r57:2d56fb753e14
parent child
Show More
@@ -1,36 +1,31
1 1 from django import forms
2 2 from apps.main.models import Device
3 3 from .models import DDSConfiguration
4 4
5 5 # from django.core.validators import MinValueValidator, MaxValueValidator
6 6
7 EXT_TYPES = (
8 ('dds', '.dds'),
9 ('json', '.json'),
10 )
11
12 7 class DDSConfigurationForm(forms.ModelForm):
13 8
14 9 def __init__(self, *args, **kwargs):
15 10 #request = kwargs.pop('request')
16 11 super(DDSConfigurationForm, self).__init__(*args, **kwargs)
17 12
18 13 instance = getattr(self, 'instance', None)
19 14
20 15 if instance and instance.pk:
21 16
22 17 devices = Device.objects.filter(device_type__name='dds')
23 18
24 19 self.fields['experiment'].widget.attrs['readonly'] = True
25 20 self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
26 21
27 22 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
28 23
29
30 def clean(self):
31 # Custom validation to force an integer when type of unit = "Unit"
32 return
24 #
25 # def clean(self):
26 # # Custom validation to force an integer when type of unit = "Unit"
27 # return
33 28
34 29 class Meta:
35 30 model = DDSConfiguration
36 31 exclude = ('type', 'parameters', 'status') No newline at end of file
@@ -1,203 +1,228
1 1 from django.db import models
2 2 from apps.main.models import Configuration
3 3 # Create your models here.
4 4
5 5 from django.core.validators import MinValueValidator, MaxValueValidator
6 6 from django.core.exceptions import ValidationError
7 7
8 from devices.dds import api, data, files
8 from devices.dds import api, data
9 9
10 10 ENABLE_TYPE = (
11 11 (False, 'Disabled'),
12 12 (True, 'Enabled'),
13 13 )
14 14 MOD_TYPES = (
15 15 (0, 'Single Tone'),
16 16 (1, 'FSK'),
17 17 (2, 'Ramped FSK'),
18 18 (3, 'Chirp'),
19 19 (4, 'BPSK'),
20 20 )
21 21
22 22 class DDSConfiguration(Configuration):
23 23
24 24 DDS_NBITS = 48
25 25
26 26 clock = models.FloatField(verbose_name='Clock Input (MHz)',validators=[MinValueValidator(5), MaxValueValidator(75)], null=True)
27 27 multiplier = models.PositiveIntegerField(verbose_name='Multiplier',validators=[MinValueValidator(1), MaxValueValidator(20)], default=4)
28 28
29 29 frequencyA_Mhz = models.DecimalField(verbose_name='Frequency A (MHz)', validators=[MinValueValidator(0), MaxValueValidator(150)], max_digits=19, decimal_places=16, null=True)
30 30 frequencyA = models.BigIntegerField(verbose_name='Frequency A (Decimal)',validators=[MinValueValidator(0), MaxValueValidator(2**DDS_NBITS-1)], null=True)
31 31
32 32 frequencyB_Mhz = models.DecimalField(verbose_name='Frequency B (MHz)', validators=[MinValueValidator(0), MaxValueValidator(150)], max_digits=19, decimal_places=16, blank=True, null=True)
33 33 frequencyB = models.BigIntegerField(verbose_name='Frequency B (Decimal)',validators=[MinValueValidator(0), MaxValueValidator(2**DDS_NBITS-1)], blank=True, null=True)
34 34
35 phaseB_degrees = models.FloatField(verbose_name='Phase B (Degrees)', validators=[MinValueValidator(0), MaxValueValidator(360)], blank=True, null=True)
36
37 35 phaseA_degrees = models.FloatField(verbose_name='Phase A (Degrees)', validators=[MinValueValidator(0), MaxValueValidator(360)], default=0)
38 36
37 phaseB_degrees = models.FloatField(verbose_name='Phase B (Degrees)', validators=[MinValueValidator(0), MaxValueValidator(360)], blank=True, null=True)
38
39 39 modulation = models.PositiveIntegerField(verbose_name='Modulation Type', choices = MOD_TYPES, default = 0)
40 40
41 41 amplitude_enabled = models.BooleanField(verbose_name='Amplitude Control', choices=ENABLE_TYPE, default=False)
42 42
43 43 amplitudeI = models.PositiveIntegerField(verbose_name='Amplitude CH1',validators=[MinValueValidator(0), MaxValueValidator(2**12-1)], blank=True, null=True)
44 44 amplitudeQ = models.PositiveIntegerField(verbose_name='Amplitude CH2',validators=[MinValueValidator(0), MaxValueValidator(2**12-1)], blank=True, null=True)
45 45
46 46
47 47 def get_nbits(self):
48 48
49 49 return self.DDS_NBITS
50 50
51 51 def clean(self):
52 52
53 53 if self.modulation in [1,2,3]:
54 54 if self.frequencyB is None or self.frequencyB_Mhz is None:
55 55 raise ValidationError({
56 56 'frequencyB': 'Frequency modulation has to be defined when FSK or Chirp modulation is selected'
57 57 })
58 58
59 59 if self.modulation in [4,]:
60 60 if self.phaseB_degrees is None:
61 61 raise ValidationError({
62 62 'phaseB': 'Phase modulation has to be defined when BPSK modulation is selected'
63 63 })
64
64
65 self.frequencyA_Mhz = data.binary_to_freq(self.frequencyA, self.clock*self.multiplier)
66 self.frequencyB_Mhz = data.binary_to_freq(self.frequencyB, self.clock*self.multiplier)
67
65 68 def verify_frequencies(self):
66 69
67 70 return True
68 71
69 72 def parms_to_dict(self):
70 73
71 74 parameters = {}
72 75
73 76 parameters['clock'] = float(self.clock)
74 77 parameters['multiplier'] = int(self.multiplier)
78
75 79 parameters['frequencyA'] = int(self.frequencyA)
76 parameters['frequencyB'] = int(self.frequencyB)
80 parameters['frequencyA_Mhz'] = float(self.frequencyA_Mhz)
81
77 82 parameters['phaseA'] = data.phase_to_binary(self.phaseA_degrees)
78 parameters['phaseB'] = data.phase_to_binary(self.phaseB_degrees)
79 parameters['frequencyA_Mhz'] = int(self.frequencyA_Mhz)
80 parameters['frequencyB_Mhz'] = int(self.frequencyB_Mhz)
81 83 parameters['phaseA_degrees'] = float(self.phaseA_degrees)
82 parameters['phaseB_degrees'] = float(self.phaseB_degrees)
84
83 85 parameters['modulation'] = int(self.modulation)
84 parameters['amplitude_enabled'] = int(self.amplitude_enabled)
86 parameters['amplitude_enabled'] = bool(self.amplitude_enabled)
87
88 if self.frequencyB:
89 parameters['frequencyB'] = int(self.frequencyB)
90 parameters['frequencyB_Mhz'] = float(self.frequencyB_Mhz)
91 else:
92 parameters['frequencyB'] = 0
93 parameters['frequencyB_Mhz'] = 0
85 94
95 if self.phaseB_degrees:
96 parameters['phaseB_degrees'] = float(self.phaseB_degrees)
97 parameters['phaseB'] = data.phase_to_binary(self.phaseB_degrees)
98 else:
99 parameters['phaseB_degrees'] = 0
100 parameters['phaseB'] = 0
101
86 102 if self.amplitudeI:
87 103 parameters['amplitudeI'] = int(self.amplitudeI)
88 104 else:
89 105 parameters['amplitudeI'] = 0
90 106
91 107 if self.amplitudeQ:
92 108 parameters['amplitudeQ'] = int(self.amplitudeQ)
93 109 else:
94 110 parameters['amplitudeQ'] = 0
95 111
96 112 return parameters
97 113
114 def parms_to_text(self):
115
116 my_dict = self.parms_to_dict()
117
118 text = data.dict_to_text(my_dict)
119
120 return text
121
98 122 def dict_to_parms(self, parameters):
99 123
100 124 self.clock = parameters['clock']
101 125 self.multiplier = parameters['multiplier']
102 126 self.frequencyA = parameters['frequencyA']
103 127 self.frequencyB = parameters['frequencyB']
104 128 self.frequencyA_Mhz = parameters['frequencyA_Mhz']
105 129 self.frequencyB_Mhz = parameters['frequencyB_Mhz']
106 130 self.phaseA_degrees = parameters['phaseA_degrees']
107 131 self.phaseB_degrees = parameters['phaseB_degrees']
108 132 self.modulation = parameters['modulation']
109 133 self.amplitude_enabled = parameters['amplitude_enabled']
110 134
111 135 def import_from_file(self, fp):
112
113 import os
114
136
137 import os, json
138
115 139 parms = {}
116
117 path, ext = os.path.splitext(fp)
118
140
141 path, ext = os.path.splitext(fp.name)
142
119 143 if ext == '.json':
120 parms = files.read_json_file(fp)
121
144 parms = json.load(fp)
145
122 146 if ext == '.dds':
123 parms = files.read_dds_file(fp)
147 lines = fp.readlines()
148 parms = data.text_to_dict(lines)
124 149
125 150 return parms
126 151
127 152 def status_device(self):
128 153
129 154 answer = api.status(ip = self.device.ip_address,
130 155 port = self.device.port_address)
131 156
132 157 self.device.status = int(answer[0])
133 158 self.message = answer[2:]
134 159
135 160 self.device.save()
136 161
137 162 return self.device.status
138 163
139 164 def reset_device(self):
140 165
141 166 answer = api.reset(ip = self.device.ip_address,
142 167 port = self.device.port_address)
143 168
144 169 if answer[0] != "1":
145 170 self.message = answer[0:]
146 171 return 0
147 172
148 173 self.message = answer[2:]
149 174 return 1
150 175
151 176 def stop_device(self):
152 177
153 178 answer = api.disable_rf(ip = self.device.ip_address,
154 179 port = self.device.port_address)
155 180
156 181 if answer[0] != "1":
157 182 self.message = answer[0:]
158 183 return 0
159 184
160 185 self.message = answer[2:]
161 186 return 1
162 187
163 188 def start_device(self):
164 189
165 190 answer = api.enable_rf(ip = self.device.ip_address,
166 191 port = self.device.port_address)
167 192
168 193 if answer[0] != "1":
169 194 self.message = answer[0:]
170 195 return 0
171 196
172 197 self.message = answer[2:]
173 198 return 1
174 199
175 200 def read_device(self):
176 201
177 202 parms = api.read_config(ip = self.device.ip_address,
178 203 port = self.device.port_address)
179 204
180 205 if not parms:
181 206 self.message = "Could not read DDS parameters from this device"
182 207 return parms
183 208
184 209 self.message = ""
185 210 return parms
186 211
187 212
188 213 def write_device(self):
189 214
190 215 answer = api.write_config(ip = self.device.ip_address,
191 216 port = self.device.port_address,
192 217 parms = self.parms_to_dict())
193 218
194 219 if answer[0] != "1":
195 220 self.message = answer[0:]
196 221 return 0
197 222
198 223 self.message = answer[2:]
199 224 return 1
200 225
201 226 class Meta:
202 227 db_table = 'dds_configurations'
203 228 No newline at end of file
@@ -1,234 +1,234
1 1 # Create your views here.
2 2 from django.shortcuts import redirect, render, get_object_or_404
3 3
4 4 # from apps.main.models import Experiment, Configuration
5 5 from apps.main.views import sidebar
6 6
7 7 from .models import DDSConfiguration
8 8 from .forms import DDSConfigurationForm
9 9 # Create your views here.
10 10
11 11 def dds_conf(request, id_conf):
12 12
13 13 conf = get_object_or_404(DDSConfiguration, pk=id_conf)
14 14
15 15 kwargs = {}
16 16
17 kwargs['status'] = conf.device.status
17 kwargs['status'] = conf.device.get_status_display()
18 18
19 19 # if not kwargs['connected']:
20 20 # messages.error(request, message=answer)
21 21
22 22 kwargs['dev_conf'] = conf
23 23 kwargs['dev_conf_keys'] = ['name',
24 24 'experiment',
25 25 'device',
26 26 'clock',
27 27 'multiplier',
28 28 'frequencyA_Mhz',
29 29 'frequencyA',
30 30 'frequencyB_Mhz',
31 31 'frequencyB',
32 32 'phaseA_degrees',
33 33 'phaseB_degrees',
34 34 'modulation',
35 35 'amplitude_enabled',
36 36 'amplitudeI',
37 37 'amplitudeQ']
38 38
39 39 kwargs['title'] = 'DDS Configuration'
40 40 kwargs['suptitle'] = 'Details'
41 41
42 42 kwargs['button'] = 'Edit Configuration'
43 43
44 44 ###### SIDEBAR ######
45 45 kwargs.update(sidebar(conf))
46 46
47 47 return render(request, 'dds_conf.html', kwargs)
48 48
49 49 def dds_conf_edit(request, id_conf):
50 50
51 51 conf = get_object_or_404(DDSConfiguration, pk=id_conf)
52 52
53 53 if request.method=='GET':
54 54 form = DDSConfigurationForm(instance=conf)
55 55
56 56 if request.method=='POST':
57 57 form = DDSConfigurationForm(request.POST, instance=conf)
58 58
59 59 if form.is_valid():
60 60 conf = form.save(commit=False)
61 61
62 62 if conf.verify_frequencies():
63 63
64 64 conf.save()
65 65 return redirect('url_dds_conf', id_conf=conf.id)
66 66
67 67 ##ERRORS
68
68
69 69 kwargs = {}
70 70 kwargs['id_dev'] = conf.id
71 71 kwargs['form'] = form
72 72 kwargs['title'] = 'Device Configuration'
73 73 kwargs['suptitle'] = 'Edit'
74 74 kwargs['button'] = 'Save'
75 75
76 76 ###### SIDEBAR ######
77 77 kwargs.update(sidebar(conf))
78 78
79 79 return render(request, 'dds_conf_edit.html', kwargs)
80 80
81 81 # def dds_conf_import(request, id_conf):
82 82 #
83 83 # conf = get_object_or_404(DDSConfiguration, pk=id_conf)
84 84 #
85 85 # if request.method == 'GET':
86 86 # file_form = UploadFileForm()
87 87 #
88 88 # if request.method == 'POST':
89 89 # file_form = UploadFileForm(request.POST, request.FILES)
90 90 #
91 91 # if file_form.is_valid():
92 92 #
93 93 # parms = files.read_dds_file(request.FILES['file'])
94 94 #
95 95 # if parms:
96 96 #
97 97 # if not parms['clock']:
98 98 # messages.warning(request, "Clock Input could not be imported from '%s'. Please fill it out." %request.FILES['file'].name)
99 99 # else:
100 100 # messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
101 101 #
102 102 # form = DDSConfigurationForm(initial=parms, instance=conf)
103 103 #
104 104 # kwargs = {}
105 105 # kwargs['id_dev'] = conf.id
106 106 # kwargs['form'] = form
107 107 # kwargs['title'] = 'Device Configuration'
108 108 # kwargs['suptitle'] = 'Parameters imported'
109 109 # kwargs['button'] = 'Save'
110 110 # kwargs['action'] = conf.get_absolute_url_edit()
111 111 # kwargs['previous'] = conf.get_absolute_url()
112 112 #
113 113 # ###### SIDEBAR ######
114 114 # kwargs.update(sidebar(conf))
115 115 #
116 116 # return render(request, 'dds_conf_edit.html', kwargs)
117 117 #
118 118 # messages.error(request, "Could not import parameters from file")
119 119 #
120 120 # kwargs = {}
121 121 # kwargs['id_dev'] = conf.id
122 122 # kwargs['title'] = 'Device Configuration'
123 123 # kwargs['form'] = file_form
124 124 # kwargs['suptitle'] = 'Importing file'
125 125 # kwargs['button'] = 'Import'
126 126 #
127 127 # kwargs.update(sidebar(conf))
128 128 #
129 129 # return render(request, 'dds_conf_import.html', kwargs)
130 130 #
131 131 # def dds_conf_export(request, id_conf):
132 132 #
133 133 # conf = get_object_or_404(DDSConfiguration, pk=id_conf)
134 134 #
135 135 # response = HttpResponse(content_type='text/plain')
136 136 # response['Content-Disposition'] = 'attachment; filename="%s.dds"' %conf.name
137 137 # response.write(conf.export_parms_to_dict())
138 138 #
139 139 # return response
140 140 #
141 141 # def dds_conf_start(request, id_conf):
142 142 #
143 143 # conf = get_object_or_404(DDSConfiguration, pk=id_conf)
144 144 #
145 145 # if conf.start_device():
146 146 # messages.success(request, conf.message)
147 147 # else:
148 148 # messages.error(request, conf.message)
149 149 #
150 150 # return redirect('url_dds_conf', id_conf=conf.id)
151 151 #
152 152 # def dds_conf_stop(request, id_conf):
153 153 #
154 154 # conf = get_object_or_404(DDSConfiguration, pk=id_conf)
155 155 #
156 156 # if conf.stop_device():
157 157 # messages.success(request, conf.message)
158 158 # else:
159 159 # messages.error(request, conf.message)
160 160 #
161 161 # return redirect('url_dds_conf', id_conf=conf.id)
162 162 #
163 163 # def dds_conf_status(request, id_conf):
164 164 #
165 165 # conf = get_object_or_404(DDSConfiguration, pk=id_conf)
166 166 #
167 167 # if conf.status_device():
168 168 # messages.success(request, conf.message)
169 169 # else:
170 170 # messages.error(request, conf.message)
171 171 #
172 172 # return redirect('url_dds_conf', id_conf=conf.id)
173 173 #
174 174 #
175 175 # def dds_conf_write(request, id_conf):
176 176 #
177 177 # conf = get_object_or_404(DDSConfiguration, pk=id_conf)
178 178 #
179 179 # answer = conf.write_device()
180 180 #
181 181 # if answer:
182 182 # messages.success(request, conf.message)
183 183 #
184 184 # conf.pk = None
185 185 # conf.id = None
186 186 # conf.type = 1
187 187 # conf.template = 0
188 188 # conf.save()
189 189 #
190 190 # else:
191 191 # messages.error(request, conf.message)
192 192 #
193 193 # return redirect('url_dds_conf', id_conf=id_conf)
194 194 #
195 195 # def dds_conf_read(request, id_conf):
196 196 #
197 197 # conf = get_object_or_404(DDSConfiguration, pk=id_conf)
198 198 #
199 199 # if request.method=='GET':
200 200 #
201 201 # parms = conf.read_device()
202 202 #
203 203 # if not parms:
204 204 # messages.error(request, conf.message)
205 205 # return redirect('url_dds_conf', id_conf=conf.id)
206 206 #
207 207 # messages.warning(request, "Clock Input cannot be read from device. Please fill it out.")
208 208 #
209 209 # form = DDSConfigurationForm(initial=parms, instance=conf)
210 210 #
211 211 # if request.method=='POST':
212 212 # form = DDSConfigurationForm(request.POST, instance=conf)
213 213 #
214 214 # if form.is_valid():
215 215 # dds_model = form.save(commit=False)
216 216 #
217 217 # if dds_model.verify_frequencies():
218 218 #
219 219 # dds_model.save()
220 220 # return redirect('url_dds_conf', id_conf=conf.id)
221 221 #
222 222 # messages.error(request, "DDS parameters could not be saved")
223 223 #
224 224 # kwargs = {}
225 225 # kwargs['id_dev'] = conf.id
226 226 # kwargs['form'] = form
227 227 # kwargs['title'] = 'Device Configuration'
228 228 # kwargs['suptitle'] = 'Parameters read from device'
229 229 # kwargs['button'] = 'Save'
230 230 #
231 231 # ###### SIDEBAR ######
232 232 # kwargs.update(sidebar(conf))
233 233 #
234 234 # return render(request, 'dds_conf_edit.html', kwargs) No newline at end of file
@@ -1,80 +1,106
1 1 from django import forms
2 2 from django.utils.safestring import mark_safe
3 3
4 4 from .models import DeviceType, Device, Experiment, Campaign, Configuration, Location
5 5
6 FILE_FORMAT = (
7 ('json', 'json'),
8 )
9
10 DDS_FILE_FORMAT = (
11 ('json', 'json'),
12 ('text', 'dds')
13 )
14
15 RC_FILE_FORMAT = (
16 ('json', 'json'),
17 ('text', 'rc')
18 )
19
6 20 def add_empty_choice(choices, pos=0, label='-----'):
7 21 if len(choices)>0:
8 22 choices = list(choices)
9 23 choices.insert(0, (0, label))
10 24 return choices
11 25 else:
12 26 return [(0, label)]
13 27
14 28 class DatepickerWidget(forms.widgets.TextInput):
15 29 def render(self, name, value, attrs=None):
16 30 input_html = super(DatepickerWidget, self).render(name, value, attrs)
17 31 html = '<div class="input-group date">'+input_html+'<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span></div>'
18 32 return mark_safe(html)
19 33
20 34 class TimepickerWidget(forms.widgets.TextInput):
21 35 def render(self, name, value, attrs=None):
22 36 input_html = super(TimepickerWidget, self).render(name, value, attrs)
23 37 html = '<div class="input-group time">'+input_html+'<span class="input-group-addon"><i class="glyphicon glyphicon-time"></i></span></div>'
24 38 return mark_safe(html)
25 39
26 40 class CampaignForm(forms.ModelForm):
27 41 def __init__(self, *args, **kwargs):
28 42 super(CampaignForm, self).__init__(*args, **kwargs)
29 43 self.fields['start_date'].widget = DatepickerWidget(self.fields['start_date'].widget.attrs)
30 44 self.fields['end_date'].widget = DatepickerWidget(self.fields['end_date'].widget.attrs)
31 45
32 46 class Meta:
33 47 model = Campaign
34 48 exclude = ['']
35 49
36 50 class ExperimentForm(forms.ModelForm):
37 51
38 52 def __init__(self, *args, **kwargs):
39 53 super(ExperimentForm, self).__init__(*args, **kwargs)
40 54 self.fields['start_time'].widget = TimepickerWidget(self.fields['start_time'].widget.attrs)
41 55 self.fields['end_time'].widget = TimepickerWidget(self.fields['end_time'].widget.attrs)
42 56
43 57 self.fields['campaign'].widget.attrs['readonly'] = True
44 58
45 59 class Meta:
46 60 model = Experiment
47 61 exclude = ['']
48 62
49 63 class LocationForm(forms.ModelForm):
50 64 class Meta:
51 65 model = Location
52 66 exclude = ['']
53 67
54 68 class DeviceForm(forms.ModelForm):
55 69 class Meta:
56 70 model = Device
57 71 exclude = ['status']
58 72
59 73 class ConfigurationForm(forms.ModelForm):
60 74 class Meta:
61 75 model = Configuration
62 76 exclude = ['type', 'created_date', 'programmed_date', 'parameters']
63 77
64 78 class DeviceTypeForm(forms.Form):
65 79 device_type = forms.ChoiceField(choices=add_empty_choice(DeviceType.objects.all().order_by('name').values_list('id', 'name')))
66 80
67 81
68 82 class UploadFileForm(forms.Form):
69 83
70 84 file = forms.FileField()
71
85
72 86 class DownloadFileForm(forms.Form):
73 87
74 format = forms.ComboField()
88 format = forms.ChoiceField(choices= ((0, 'json'),) )
89
90 def __init__(self, device_type, *args, **kwargs):
91
92 super(DownloadFileForm, self).__init__(*args, **kwargs)
93
94 self.fields['format'].choices = FILE_FORMAT
95
96 if device_type == 'dds':
97 self.fields['format'].choices = DDS_FILE_FORMAT
98
99 if device_type == 'rc':
100 self.fields['format'].choices = RC_FILE_FORMAT
75 101
76 102 class OperationForm(forms.Form):
77 103 # today = datetime.today()
78 104 # -----Campaigns from this month------
79 105 campaign = forms.ChoiceField(choices=Campaign.objects.all().order_by('-start_date').values_list('id', 'name')[:5], label="Campaign")
80 106 No newline at end of file
@@ -1,273 +1,295
1 1 from django.db import models
2 2 from polymorphic import PolymorphicModel
3 3
4 4 from django.core.urlresolvers import reverse
5 5
6 6 CONF_STATES = (
7 7 (0, 'Disconnected'),
8 8 (1, 'Connected'),
9 9 (1, 'Running'),
10 10 )
11 11
12 12 CONF_TYPES = (
13 13 (0, 'Active'),
14 14 (1, 'Historical'),
15 15 )
16 16
17 17 DEV_STATES = (
18 18 (0, 'No connected'),
19 19 (1, 'Connected'),
20 20 (2, 'Configured'),
21 21 (3, 'Running'),
22 22 )
23 23
24 24 DEV_TYPES = (
25 25 ('', 'Select a device type'),
26 26 ('rc', 'Radar Controller'),
27 27 ('dds', 'Direct Digital Synthesizer'),
28 28 ('jars', 'Jicamarca Radar Acquisition System'),
29 29 ('usrp', 'Universal Software Radio Peripheral'),
30 30 ('cgs', 'Clock Generator System'),
31 31 ('abs', 'Automatic Beam Switching'),
32 32 )
33 33
34 34 DEV_PORTS = {
35 35 'rc' : 2000,
36 36 'dds' : 2000,
37 37 'jars' : 2000,
38 38 'usrp' : 2000,
39 39 'cgs' : 8080,
40 40 'abs' : 8080
41 41 }
42 42
43 43 RADAR_STATES = (
44 44 (0, 'No connected'),
45 45 (1, 'Connnected'),
46 46 (2, 'Configured'),
47 47 (3, 'Running'),
48 48 (4, 'Scheduled'),
49 49 )
50 50 # Create your models here.
51 51
52 52
53 53 class Location(models.Model):
54 54
55 55 name = models.CharField(max_length = 30)
56 56 description = models.TextField(blank=True, null=True)
57 57
58 58 class Meta:
59 59 db_table = 'db_location'
60 60
61 61 def __unicode__(self):
62 62 return u'%s' % self.name
63 63
64 64 class DeviceType(models.Model):
65 65
66 66 name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'rc')
67 67 description = models.TextField(blank=True, null=True)
68 68
69 69 class Meta:
70 70 db_table = 'db_device_types'
71 71
72 72 def __unicode__(self):
73 73 return u'%s' % self.get_name_display()
74 74
75 75 class Device(models.Model):
76 76
77 77 device_type = models.ForeignKey(DeviceType, on_delete=models.CASCADE)
78 78 location = models.ForeignKey(Location, on_delete=models.CASCADE)
79 79
80 80 name = models.CharField(max_length=40, default='')
81 81 ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
82 82 port_address = models.PositiveSmallIntegerField(default=2000)
83 83 description = models.TextField(blank=True, null=True)
84 84 status = models.PositiveSmallIntegerField(default=0, choices=DEV_STATES)
85 85
86 86 class Meta:
87 87 db_table = 'db_devices'
88 88
89 89 def __unicode__(self):
90 90 return u'%s | %s' % (self.name, self.ip_address)
91 91
92 92 def get_status(self):
93 93
94 94 return self.status
95 95
96 96
97 97 class Campaign(models.Model):
98 98
99 99 template = models.BooleanField(default=False)
100 100
101 101 name = models.CharField(max_length=40, unique=True)
102 102 start_date = models.DateTimeField(blank=True, null=True)
103 103 end_date = models.DateTimeField(blank=True, null=True)
104 104 tags = models.CharField(max_length=40)
105 105 description = models.TextField(blank=True, null=True)
106 106
107 107 class Meta:
108 108 db_table = 'db_campaigns'
109 109
110 110 def __unicode__(self):
111 111 return u'%s' % (self.name)
112 112
113 113 # class Radar(models.Model):
114 114 #
115 115 # # name = models.CharField(max_length = 30)
116 116 # experiment = models.ForeignKey('Experiment', on_delete=models.CASCADE)
117 117 # location = models.OneToOneField('Location', on_delete=models.CASCADE)
118 118 # status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
119 119 #
120 120 # class Meta:
121 121 # db_table = 'db_radar'
122 122 #
123 123 # def __unicode__(self):
124 124 # return u'%s' % self.location
125 125
126 126
127 127 class Experiment(models.Model):
128 128
129 129 template = models.BooleanField(default=False)
130 130
131 131 campaign = models.ForeignKey('Campaign', null=True, blank=True, on_delete=models.CASCADE)
132 132 location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
133 133
134 134 name = models.CharField(max_length=40, default='')
135 135 start_time = models.TimeField(default='00:00:00')
136 136 end_time = models.TimeField(default='23:59:59')
137 137
138 138 class Meta:
139 139 db_table = 'db_experiments'
140 140
141 141 def __unicode__(self):
142 142 return u'%s' % (self.name)
143 143
144 144 class Configuration(PolymorphicModel):
145 145
146 146 template = models.BooleanField(default=False)
147 147
148 148 name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
149 149
150 150 experiment = models.ForeignKey('Experiment', null=True, blank=True, on_delete=models.CASCADE)
151 151 device = models.ForeignKey(Device, on_delete=models.CASCADE)
152 152
153 153 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
154 154
155 155 created_date = models.DateTimeField(auto_now_add=True)
156 156 programmed_date = models.DateTimeField(auto_now=True)
157 157
158 158 parameters = models.TextField(default='{}')
159 159
160 160 message = ""
161 161
162 162 class Meta:
163 163 db_table = 'db_configurations'
164 164
165 165 def __unicode__(self):
166 return u'[%s - %s]: %s' % (self.experiment.name,
167 self.experiment.name,
168 self.device.name)
166 return u'[%s, %s]: %s' % (self.experiment.name,
167 self.device.name,
168 self.name)
169 169
170 170 def parms_to_dict(self):
171 171
172 172 parameters = {}
173 173
174 174 for key in self.__dict__.keys():
175 175 parameters[key] = getattr(self, key)
176 176
177 177 return parameters
178 178
179 def parms_to_text(self):
180
181 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
182
183 return ''
184
185 def parms_to_binary(self):
186
187 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
188
189 return ''
190
179 191 def dict_to_parms(self, parameters):
180 192
181 193 if type(parameters) != type({}):
182 194 return
183 195
184 196 for key in parameters.keys():
185 197 setattr(self, key, parameters[key])
186 198
187 199 def export_to_file(self, format="json"):
188 200
189 201 import json
190 202
191 content_type = 'application/json'
192 filename = '%s.json' %self.name
193 content = json.dumps(self.params_to_dict())
203 content_type = ''
194 204
195 205 if format == 'text':
196 206 content_type = 'text/plain'
197 filename = '%s.%s' %(self.name, self.device.device_type.name)
198 content = self.params_to_text()
207 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
208 content = self.parms_to_text()
199 209
200 210 if format == 'binary':
201 211 content_type = 'application/octet-stream'
202 filename = '%s.bin' %self.name
203 content = self.params_to_binary()
212 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
213 content = self.parms_to_binary()
214
215 if not content_type:
216 content_type = 'application/json'
217 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
218 content = json.dumps(self.parms_to_dict())
204 219
205 220 fields = {'content_type':content_type,
206 221 'filename':filename,
207 222 'content':content
208 223 }
209 224
210 225 return fields
211 226
212 def import_from_file(self, filename):
227 def import_from_file(self, fp):
228
229 import os, json
230
231 parms = {}
232
233 path, ext = os.path.splitext(fp.name)
213 234
214 raise NotImplementedError, "This method should be implemented in each Configuration model"
235 if ext == '.json':
236 parms = json.load(fp)
215 237
216 return {}
238 return parms
217 239
218 240 def status_device(self):
219 241
220 raise NotImplementedError, "This method should be implemented in each Configuration model"
242 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
221 243
222 244 return None
223 245
224 246 def stop_device(self):
225 247
226 raise NotImplementedError, "This method should be implemented in each Configuration model"
248 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
227 249
228 250 return None
229 251
230 252 def start_device(self):
231 253
232 raise NotImplementedError, "This method should be implemented in each Configuration model"
254 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
233 255
234 256 return None
235 257
236 258 def write_device(self, parms):
237 259
238 raise NotImplementedError, "This method should be implemented in each Configuration model"
260 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
239 261
240 262 return None
241 263
242 264 def read_device(self):
243 265
244 raise NotImplementedError, "This method should be implemented in each Configuration model"
266 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
245 267
246 268 return None
247 269
248 270 def get_absolute_url(self):
249 271 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
250 272
251 273 def get_absolute_url_edit(self):
252 274 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
253 275
254 276 def get_absolute_url_import(self):
255 277 return reverse('url_import_dev_conf', args=[str(self.id)])
256 278
257 279 def get_absolute_url_export(self):
258 280 return reverse('url_export_dev_conf', args=[str(self.id)])
259 281
260 282 def get_absolute_url_write(self):
261 283 return reverse('url_write_dev_conf', args=[str(self.id)])
262 284
263 285 def get_absolute_url_read(self):
264 286 return reverse('url_read_dev_conf', args=[str(self.id)])
265 287
266 288 def get_absolute_url_start(self):
267 289 return reverse('url_start_dev_conf', args=[str(self.id)])
268 290
269 291 def get_absolute_url_stop(self):
270 292 return reverse('url_stop_dev_conf', args=[str(self.id)])
271 293
272 294 def get_absolute_url_status(self):
273 295 return reverse('url_status_dev_conf', args=[str(self.id)]) No newline at end of file
@@ -1,141 +1,143
1 1 <!DOCTYPE html>
2 2 {% load static %}
3 3 <html lang="en">
4 4 <head>
5 5 <meta charset="utf-8">
6 6 <title>{% block title %}Jicamarca Integrated Radar System:::::{% endblock %}</title>
7 7 <meta name="description" content="">
8 8 <meta name="author" content="">
9 9 <meta name="viewport" content="width=device-width, initial-scale=1">
10 10 {# bootstrap_css #}
11 11 <link href="{% static 'css/bootstrap-flatly.min.css' %}" media="all" rel="stylesheet">
12 12 <style type="text/css">
13 13 body {padding-top: 60px}
14 14 .logo {padding-top: 5px; height: 50px}
15 15 .clickable-row {cursor: pointer;}
16 16 .col-no-padding { padding-left:0; }
17 17 </style>
18 18 <!--[if lt IE 9]>
19 19 <script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
20 20 <![endif]-->
21 21 {% block extra-head %}
22 22 {% endblock %}
23 23 </head>
24 24
25 25 <body>
26 26
27 27 {% block main_menu %}
28 28 <nav class="navbar navbar-default navbar-fixed-top" role="banner">
29 29 <div class="container-fluid">
30 30 <div class="navbar-header">
31 31 <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navigationbar">
32 32 <span class="sr-only">Toggle navigation</span>
33 33 <span class="icon-bar"></span>
34 34 <span class="icon-bar"></span>
35 35 <span class="icon-bar"></span>
36 36 </button>
37 37 <a class="navbar-brand" href="{% url 'index' %}" style="padding-top:1px"><img class="logo" alt="JRO" src="{% static "images/logo-jro-white-trans.png" %}"></a>
38 38 </div>
39 39 <div class="collapse navbar-collapse" id="navigationbar">
40 40 <ul class="nav navbar-nav">
41 41 <li class=" dropdown {% block operation-active %}{% endblock %}"><a href="{% url 'url_operation'%}">Operation</a>
42 42 </li>
43 43 <li class=" dropdown {% block conf-active %}{% endblock %}">
44 <a href="#" class="dropdown-toggle" data-toggle="dropdown">Configuration<span class="caret"></span></a>
44 <a href="#" class="dropdown-toggle" data-toggle="dropdown">New<span class="caret"></span></a>
45 45 <ul class="dropdown-menu" role="menu">
46 <li><a href="#">Campaigns</a></li>
47 <li><a href="#">Radars</a></li>
48 <li><a href="#">Devices</a></li>
46 <li><a href="{% url 'url_add_campaign' %}">Campaign</a></li>
47 <li><a href="{% url 'url_add_experiment' 0%}">Experiment</a></li>
48 <li><a href="{% url 'url_add_dev_conf' 0%}">Device Configuration</a></li>
49 <li><a href="{% url 'url_add_device'%}">Radar/Device</a></li>
50
49 51 </ul>
50 52 </li>
51 53 <li class=" dropdown {% block test-active %}{% endblock %}">
52 54 <a href="#" class="dropdown-toggle" data-toggle="dropdown">Test<span class="caret"></span></a>
53 55 <ul class="dropdown-menu" role="menu">
54 56 <li><a href="{% url 'url_experiments' %}">Experiments</a></li>
55 57 <li><a href="{% url 'url_devices' %}">Devices</a></li>
56 58 </ul>
57 59 </li>
58 60 <li class=" dropdown {% block search-active %}{% endblock %}">
59 61 <a href="#" class="dropdown-toggle" data-toggle="dropdown">Search<span class="caret"></span></a>
60 62 <ul class="dropdown-menu" role="menu">
61 63 <li><a href="{% url 'url_campaigns' %}">Campaigns</a></li>
62 64 <li><a href="{% url 'url_experiments' %}">Experiments</a></li>
63 65 <li><a href="{% url 'url_dev_confs' %}">Configurations</a></li>
64 66 </ul>
65 67 </li>
66 68 </ul>
67 69 <ul class="nav navbar-nav navbar-right">
68 70 <li class="nav-divider"></li>
69 71 {% if user.is_authenticated %}
70 72 <li class="dropdown">
71 73 <a href="#" class="dropdown-toggle" data-toggle="dropdown">Hi {{ user.username }}<span class="caret"></span></a>
72 74 <ul class="dropdown-menu" role="menu">
73 75 <li><a href="#">Control Panel</a></li>
74 76 <li><a href="{% url 'django.contrib.auth.views.logout' %}">Logout</a></li>
75 77 </ul>
76 78 </li>
77 79 {% else %}
78 80 <li><a href="{% url 'django.contrib.auth.views.login' %}?next={{request.get_full_path}}">Login</a></li>
79 81 {% endif %}
80 82 </ul>
81 83 </div>
82 84 </div>
83 85 </nav>
84 86 <div style="clear: both;"></div>
85 87 {% endblock %}
86 88
87 89 <div class="container">
88 90 <div id="page" class="row" style="min-height:600px">
89 91
90 92 <div class="col-md-3 hidden-xs hidden-sm" role="complementary">
91 93 <br><br>
92 94 <div id="sidebar">
93 95 {% block sidebar%}
94 96 {% endblock %}
95 97 </div>
96 98 </div>
97 99
98 100 <div class="col-md-9 col-xs-12" role="main">
99 101 <div class="page-header">
100 102 <h1>{% block content-title %}{% endblock %} <small>{% block content-suptitle %}{% endblock %}</small></h1>
101 103 </div>
102 104 {% block messages %}
103 105 {% if messages %}
104 106 {% for message in messages %}
105 107 <div class="alert alert-{% if message.tags %}{% if 'error' in message.tags %}danger{% else %}{{ message.tags }}{% endif %}{% else %}info{% endif %} alert-dismissible" role="alert">
106 108 <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
107 109 <strong>{{message.tags|title}}!</strong> {{ message }}
108 110 </div>
109 111 {% endfor %}
110 112 {% endif %}
111 113 {% endblock %}
112 114
113 115 {% block content %}
114 116 {% endblock %}
115 117
116 118 </div>
117 119
118 120 </div><!--/row-->
119 121 </div> <!-- container -->
120 122
121 123 <div id="debug">{{debug}}</div>
122 124
123 125 {% block footer %}
124 126 <footer class="footer">
125 127 <div class="container">
126 128 <p><hr></p>
127 129 <p>
128 130 &copy; <a href="http://jro.igp.gob.pe">Jicamarca Radio Observatory</a> - {% now "Y" %}
129 131 </p>
130 132 </div>
131 133 </footer>
132 134 {% endblock %}
133 135
134 136 {# bootstrap_javascript jquery=True #}
135 137 <script src="{% static 'js/jquery.min.js' %}"></script>
136 138 <script src="{% static 'js/bootstrap.min.js' %}"></script>
137 139 {% block extra-js %}
138 140 {% endblock%}
139 141 </body>
140 142 </html>
141 143
@@ -1,72 +1,72
1 1 {% extends "base.html" %}
2 2 {% load bootstrap3 %}
3 3 {% load static %}
4 4 {% load main_tags %}
5 5
6 6 {% block conf-active %}active{% endblock %}
7 7
8 8 {% block content-title %}{{title}}{% endblock %}
9 9 {% block content-suptitle %}{{suptitle}}{% endblock %}
10 10
11 11 {% block content %}
12 12
13 13 <span class=" dropdown pull-right">
14 14 <a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-menu-hamburger" aria-hidden="true"></span> <span class="caret"></span></a>
15 15 <ul class="dropdown-menu" role="menu">
16 16 <li><a href="{{ dev_conf.get_absolute_url_edit }}"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit</a></li>
17 17 <li><a href="{{ dev_conf.get_absolute_url_import }}"><span class="glyphicon glyphicon-import" aria-hidden="true"></span> Import </a></li>
18 18 <li><a href="{{ dev_conf.get_absolute_url_export }}"><span class="glyphicon glyphicon-export" aria-hidden="true"></span> Export </a></li>
19 19 <li><a>----------------</a></li>
20 20 <li><a href="{{ dev_conf.get_absolute_url_status }}"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span> Status</a></li>
21 21 <li><a href="{{ dev_conf.get_absolute_url_start}}"><span class="glyphicon glyphicon-play" aria-hidden="true"></span> Start</a></li>
22 22 <li><a href="{{ dev_conf.get_absolute_url_stop }}"><span class="glyphicon glyphicon-stop" aria-hidden="true"></span> Stop</a></li>
23 23 <li><a href="{{ dev_conf.get_absolute_url_write }}"><span class="glyphicon glyphicon-download" aria-hidden="true"></span> Write</a></li>
24 24 <li><a href="{{ dev_conf.get_absolute_url_read }}"><span class="glyphicon glyphicon-upload" aria-hidden="true"></span> Read</a></li>
25 25 </ul>
26 26 </span>
27 27
28 28 <table class="table table-bordered">
29 29 <tr>
30 30 <th>Status</th>
31 <td>{%if status %} <span class="glyphicon glyphicon-ok-circle text-success" aria-hidden="true"></span> {{status}} {% else %} <span class="glyphicon glyphicon-remove-circle text-danger" aria-hidden="true"></span> Disconnected {% endif %}</td>
31 <td>{%if status != "No connected" %} <span class="glyphicon glyphicon-ok-circle text-success" aria-hidden="true"></span> {{status}} {% else %} <span class="glyphicon glyphicon-remove-circle text-danger" aria-hidden="true"></span> {{status}} {% endif %}</td>
32 32 </tr>
33 33
34 34 {% for key in dev_conf_keys %}
35 35 <tr>
36 36 <th>{% get_verbose_field_name dev_conf key %}</th>
37 37 <td>{{dev_conf|attr:key}}</td>
38 38 </tr>
39 39 {% endfor %}
40 40 </table>
41 41
42 42 {% endblock %}
43 43
44 44 {% block sidebar%}
45 45 {% include "sidebar_devices.html" %}
46 46 {% endblock %}
47 47
48 48 {% block extra-js%}
49 49 <script type="text/javascript">
50 50
51 51 $("#bt_edit").click(function() {
52 52 document.location = "{{ dev_conf.get_absolute_url_edit }}";
53 53 });
54 54
55 55 $("#bt_read").click(function() {
56 56 document.location = "{{ dev_conf.get_absolute_url_read }}";
57 57 });
58 58
59 59 $("#bt_write").click(function() {
60 60 document.location = "{{ dev_conf.get_absolute_url_write }}";
61 61 });
62 62
63 63 $("#bt_import").click(function() {
64 64 document.location = "{{ dev_conf.get_absolute_url_import }}";
65 65 });
66 66
67 67 $("#bt_export").click(function() {
68 68 document.location = "{{ dev_conf.get_absolute_url_export }}";
69 69 });
70 70
71 71 </script>
72 72 {% endblock %} No newline at end of file
@@ -1,799 +1,805
1 1 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
2 2 from django.contrib import messages
3 3
4 4 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm
5 5 from apps.cgs.forms import CGSConfigurationForm
6 6 from apps.jars.forms import JARSConfigurationForm
7 7 from apps.usrp.forms import USRPConfigurationForm
8 8 from apps.abs.forms import ABSConfigurationForm
9 9 from apps.rc.forms import RCConfigurationForm
10 10 from apps.dds.forms import DDSConfigurationForm
11 11
12 12 from .models import Campaign, Experiment, Device, Configuration, Location
13 13 from apps.cgs.models import CGSConfiguration
14 14 from apps.jars.models import JARSConfiguration
15 15 from apps.usrp.models import USRPConfiguration
16 16 from apps.abs.models import ABSConfiguration
17 17 from apps.rc.models import RCConfiguration
18 18 from apps.dds.models import DDSConfiguration
19 19
20 20 # Create your views here.
21 21
22 22 CONF_FORMS = {
23 23 'rc': RCConfigurationForm,
24 24 'dds': DDSConfigurationForm,
25 25 'jars': JARSConfigurationForm,
26 26 'cgs': CGSConfigurationForm,
27 27 'abs': ABSConfigurationForm,
28 28 'usrp': USRPConfigurationForm,
29 29 }
30 30
31 31 CONF_MODELS = {
32 32 'rc': RCConfiguration,
33 33 'dds': DDSConfiguration,
34 34 'jars': JARSConfiguration,
35 35 'cgs': CGSConfiguration,
36 36 'abs': ABSConfiguration,
37 37 'usrp': USRPConfiguration,
38 38 }
39 39
40 40 def index(request):
41 41 kwargs = {}
42 42
43 43 return render(request, 'index.html', kwargs)
44 44
45 45 def locations(request):
46 46
47 47 locations = Location.objects.all().order_by('name')
48 48
49 49 keys = ['id', 'name', 'description']
50 50
51 51 kwargs = {}
52 52 kwargs['location_keys'] = keys[1:]
53 53 kwargs['locations'] = locations
54 54 kwargs['title'] = 'Location'
55 55 kwargs['suptitle'] = 'List'
56 56 kwargs['button'] = 'New Location'
57 57
58 58 return render(request, 'locations.html', kwargs)
59 59
60 60 def location(request, id_loc):
61 61
62 62 location = get_object_or_404(Location, pk=id_loc)
63 63
64 64 kwargs = {}
65 65 kwargs['location'] = location
66 66 kwargs['location_keys'] = ['name', 'description']
67 67
68 68 kwargs['title'] = 'Location'
69 69 kwargs['suptitle'] = 'Details'
70 70
71 71 return render(request, 'location.html', kwargs)
72 72
73 73 def location_new(request):
74 74
75 75 if request.method == 'GET':
76 76 form = LocationForm()
77 77
78 78 if request.method == 'POST':
79 79 form = LocationForm(request.POST)
80 80
81 81 if form.is_valid():
82 82 form.save()
83 83 return redirect('url_locations')
84 84
85 85 kwargs = {}
86 86 kwargs['form'] = form
87 87 kwargs['title'] = 'Location'
88 88 kwargs['suptitle'] = 'New'
89 89 kwargs['button'] = 'Create'
90 90
91 91 return render(request, 'location_edit.html', kwargs)
92 92
93 93 def location_edit(request, id_loc):
94 94
95 95 location = get_object_or_404(Location, pk=id_loc)
96 96
97 97 if request.method=='GET':
98 98 form = LocationForm(instance=location)
99 99
100 100 if request.method=='POST':
101 101 form = LocationForm(request.POST, instance=location)
102 102
103 103 if form.is_valid():
104 104 form.save()
105 105 return redirect('url_locations')
106 106
107 107 kwargs = {}
108 108 kwargs['form'] = form
109 109 kwargs['title'] = 'Location'
110 110 kwargs['suptitle'] = 'Edit'
111 111 kwargs['button'] = 'Update'
112 112
113 113 return render(request, 'location_edit.html', kwargs)
114 114
115 115 def location_delete(request, id_loc):
116 116
117 117 location = get_object_or_404(Location, pk=id_loc)
118 118
119 119 if request.method=='POST':
120 120
121 121 if request.user.is_staff:
122 122 location.delete()
123 123 return redirect('url_locations')
124 124
125 125 return HttpResponse("Not enough permission to delete this object")
126 126
127 127 kwargs = {'object':location, 'loc_active':'active',
128 128 'url_cancel':'url_location', 'id_item':id_loc}
129 129
130 130 return render(request, 'item_delete.html', kwargs)
131 131
132 132 def devices(request):
133 133
134 134 devices = Device.objects.all().order_by('device_type__name')
135 135
136 136 # keys = ['id', 'device_type__name', 'name', 'ip_address']
137 137 keys = ['id', 'name', 'ip_address', 'port_address', 'device_type']
138 138
139 139 kwargs = {}
140 140 kwargs['device_keys'] = keys[1:]
141 141 kwargs['devices'] = devices#.values(*keys)
142 142 kwargs['title'] = 'Device'
143 143 kwargs['suptitle'] = 'List'
144 144 kwargs['button'] = 'New Device'
145 145
146 146 return render(request, 'devices.html', kwargs)
147 147
148 148 def device(request, id_dev):
149 149
150 150 device = get_object_or_404(Device, pk=id_dev)
151 151
152 152 kwargs = {}
153 153 kwargs['device'] = device
154 154 kwargs['device_keys'] = ['device_type', 'name', 'ip_address', 'port_address', 'description']
155 155
156 156 kwargs['title'] = 'Device'
157 157 kwargs['suptitle'] = 'Details'
158 158
159 159 return render(request, 'device.html', kwargs)
160 160
161 161 def device_new(request):
162 162
163 163 if request.method == 'GET':
164 164 form = DeviceForm()
165 165
166 166 if request.method == 'POST':
167 167 form = DeviceForm(request.POST)
168 168
169 169 if form.is_valid():
170 170 form.save()
171 171 return redirect('url_devices')
172 172
173 173 kwargs = {}
174 174 kwargs['form'] = form
175 175 kwargs['title'] = 'Device'
176 176 kwargs['suptitle'] = 'New'
177 177 kwargs['button'] = 'Create'
178 178
179 179 return render(request, 'device_edit.html', kwargs)
180 180
181 181 def device_edit(request, id_dev):
182 182
183 183 device = get_object_or_404(Device, pk=id_dev)
184 184
185 185 if request.method=='GET':
186 186 form = DeviceForm(instance=device)
187 187
188 188 if request.method=='POST':
189 189 form = DeviceForm(request.POST, instance=device)
190 190
191 191 if form.is_valid():
192 192 form.save()
193 193 return redirect('url_devices')
194 194
195 195 kwargs = {}
196 196 kwargs['form'] = form
197 197 kwargs['title'] = 'Device'
198 198 kwargs['suptitle'] = 'Edit'
199 199 kwargs['button'] = 'Update'
200 200
201 201 return render(request, 'device_edit.html', kwargs)
202 202
203 203 def device_delete(request, id_dev):
204 204
205 205 device = get_object_or_404(Device, pk=id_dev)
206 206
207 207 if request.method=='POST':
208 208
209 209 if request.user.is_staff:
210 210 device.delete()
211 211 return redirect('url_devices')
212 212
213 213 return HttpResponse("Not enough permission to delete this object")
214 214
215 215 kwargs = {'object':device, 'dev_active':'active',
216 216 'url_cancel':'url_device', 'id_item':id_dev}
217 217
218 218 return render(request, 'item_delete.html', kwargs)
219 219
220 220 def campaigns(request):
221 221
222 222 campaigns = Campaign.objects.all().order_by('start_date')
223 223
224 224 keys = ['id', 'name', 'start_date', 'end_date']
225 225
226 226 kwargs = {}
227 227 kwargs['campaign_keys'] = keys[1:]
228 228 kwargs['campaigns'] = campaigns#.values(*keys)
229 229 kwargs['title'] = 'Campaign'
230 230 kwargs['suptitle'] = 'List'
231 231 kwargs['button'] = 'New Campaign'
232 232
233 233 return render(request, 'campaigns.html', kwargs)
234 234
235 235 def campaign(request, id_camp):
236 236
237 237 campaign = get_object_or_404(Campaign, pk=id_camp)
238 238 experiments = Experiment.objects.filter(campaign=campaign)
239 239
240 240 form = CampaignForm(instance=campaign)
241 241
242 242 kwargs = {}
243 243 kwargs['campaign'] = campaign
244 244 kwargs['campaign_keys'] = ['name', 'start_date', 'end_date', 'tags', 'description']
245 245
246 246 keys = ['id', 'name', 'start_time', 'end_time']
247 247
248 248 kwargs['experiment_keys'] = keys[1:]
249 249 kwargs['experiments'] = experiments.values(*keys)
250 250
251 251 kwargs['title'] = 'Campaign'
252 252 kwargs['suptitle'] = 'Details'
253 253
254 254 kwargs['form'] = form
255 255 kwargs['button'] = 'Add Experiment'
256 256
257 257 return render(request, 'campaign.html', kwargs)
258 258
259 259 def campaign_new(request):
260 260
261 261 if request.method == 'GET':
262 262 form = CampaignForm()
263 263
264 264 if request.method == 'POST':
265 265 form = CampaignForm(request.POST)
266 266
267 267 if form.is_valid():
268 268 campaign = form.save()
269 269 return redirect('url_campaign', id_camp=campaign.id)
270 270
271 271 kwargs = {}
272 272 kwargs['form'] = form
273 273 kwargs['title'] = 'Campaign'
274 274 kwargs['suptitle'] = 'New'
275 275 kwargs['button'] = 'Create'
276 276
277 277 return render(request, 'campaign_edit.html', kwargs)
278 278
279 279 def campaign_edit(request, id_camp):
280 280
281 281 campaign = get_object_or_404(Campaign, pk=id_camp)
282 282
283 283 if request.method=='GET':
284 284 form = CampaignForm(instance=campaign)
285 285
286 286 if request.method=='POST':
287 287 form = CampaignForm(request.POST, instance=campaign)
288 288
289 289 if form.is_valid():
290 290 form.save()
291 291 return redirect('url_campaign', id_camp=id_camp)
292 292
293 293 kwargs = {}
294 294 kwargs['form'] = form
295 295 kwargs['title'] = 'Campaign'
296 296 kwargs['suptitle'] = 'Edit'
297 297 kwargs['button'] = 'Update'
298 298
299 299 return render(request, 'campaign_edit.html', kwargs)
300 300
301 301 def campaign_delete(request, id_camp):
302 302
303 303 campaign = get_object_or_404(Campaign, pk=id_camp)
304 304
305 305 if request.method=='POST':
306 306 if request.user.is_staff:
307 307 campaign.delete()
308 308 return redirect('url_campaigns')
309 309
310 310 return HttpResponse("Not enough permission to delete this object")
311 311
312 312 kwargs = {'object':campaign, 'camp_active':'active',
313 313 'url_cancel':'url_campaign', 'id_item':id_camp}
314 314
315 315 return render(request, 'item_delete.html', kwargs)
316 316
317 317 def experiments(request):
318 318
319 319 experiment_list = Experiment.objects.all().order_by('campaign')
320 320
321 321 keys = ['id', 'name', 'start_time', 'end_time', 'campaign']
322 322
323 323 kwargs = {}
324 324
325 325 kwargs['experiment_keys'] = keys[1:]
326 326 kwargs['experiments'] = experiment_list#.values(*keys)
327 327
328 328 kwargs['title'] = 'Experiment'
329 329 kwargs['suptitle'] = 'List'
330 330 kwargs['button'] = 'New Experiment'
331 331
332 332 return render(request, 'experiments.html', kwargs)
333 333
334 334 def experiment(request, id_exp):
335 335
336 336 experiment = get_object_or_404(Experiment, pk=id_exp)
337 337
338 338 experiments = Experiment.objects.filter(campaign=experiment.campaign)
339 339 configurations = Configuration.objects.filter(experiment=experiment, type=0)
340 340
341 341 kwargs = {}
342 342
343 343 exp_keys = ['id', 'campaign', 'location', 'name', 'start_time', 'end_time']
344 344 conf_keys = ['id', 'device__name', 'device__device_type', 'device__ip_address', 'device__port_address']
345 345
346 346 conf_labels = ['id', 'device__name', 'device_type', 'ip_address', 'port_address']
347 347
348 348 kwargs['experiment_keys'] = exp_keys[1:]
349 349 kwargs['experiment'] = experiment
350 350
351 351 kwargs['experiments'] = experiments.values(*exp_keys)
352 352
353 353 kwargs['configuration_labels'] = conf_labels[1:]
354 354 kwargs['configuration_keys'] = conf_keys[1:]
355 355 kwargs['configurations'] = configurations #.values(*conf_keys)
356 356
357 357 kwargs['title'] = 'Experiment'
358 358 kwargs['suptitle'] = 'Details'
359 359
360 360 kwargs['button'] = 'Add Configuration'
361 361
362 362 return render(request, 'experiment.html', kwargs)
363 363
364 364 def experiment_new(request, id_camp=0):
365 365
366 366 if request.method == 'GET':
367 367 form = ExperimentForm(initial={'campaign':id_camp})
368 368
369 369 if request.method == 'POST':
370 370 form = ExperimentForm(request.POST, initial={'campaign':id_camp})
371 371
372 372 if form.is_valid():
373 373 experiment = form.save()
374 374 return redirect('url_experiment', id_exp=experiment.id)
375 375
376 376 kwargs = {}
377 377 kwargs['form'] = form
378 378 kwargs['title'] = 'Experiment'
379 379 kwargs['suptitle'] = 'New'
380 380 kwargs['button'] = 'Create'
381 381
382 382 return render(request, 'experiment_edit.html', kwargs)
383 383
384 384 def experiment_edit(request, id_exp):
385 385
386 386 experiment = get_object_or_404(Experiment, pk=id_exp)
387 387
388 388 if request.method == 'GET':
389 389 form = ExperimentForm(instance=experiment)
390 390
391 391 if request.method=='POST':
392 392 form = ExperimentForm(request.POST, instance=experiment)
393 393
394 394 if form.is_valid():
395 395 experiment = form.save()
396 396 return redirect('url_experiment', id_exp=experiment.id)
397 397
398 398 kwargs = {}
399 399 kwargs['form'] = form
400 400 kwargs['title'] = 'Experiment'
401 401 kwargs['suptitle'] = 'Edit'
402 402 kwargs['button'] = 'Update'
403 403
404 404 return render(request, 'experiment_edit.html', kwargs)
405 405
406 406 def experiment_delete(request, id_exp):
407 407
408 408 experiment = get_object_or_404(Experiment, pk=id_exp)
409 409
410 410 if request.method=='POST':
411 411 if request.user.is_staff:
412 412 id_camp = experiment.campaign.id
413 413 experiment.delete()
414 414 return redirect('url_campaign', id_camp=id_camp)
415 415
416 416 return HttpResponse("Not enough permission to delete this object")
417 417
418 418 kwargs = {'object':experiment, 'exp_active':'active',
419 419 'url_cancel':'url_experiment', 'id_item':id_exp}
420 420
421 421 return render(request, 'item_delete.html', kwargs)
422 422
423 423 def dev_confs(request):
424 424
425 425 configurations = Configuration.objects.all().order_by('type', 'device__device_type', 'experiment')
426 426
427 427 # keys = ['id', 'device__device_type__name', 'device__name', 'experiment__campaign__name', 'experiment__name']
428 428
429 429 keys = ['id', 'device', 'experiment', 'type', 'programmed_date']
430 430
431 431 kwargs = {}
432 432
433 433 kwargs['configuration_keys'] = keys[1:]
434 434 kwargs['configurations'] = configurations#.values(*keys)
435 435
436 436 kwargs['title'] = 'Configuration'
437 437 kwargs['suptitle'] = 'List'
438 438 kwargs['button'] = 'New Configuration'
439 439
440 440 return render(request, 'dev_confs.html', kwargs)
441 441
442 442 def dev_conf(request, id_conf):
443 443
444 444 conf = get_object_or_404(Configuration, pk=id_conf)
445 445
446 446 DevConfModel = CONF_MODELS[conf.device.device_type.name]
447 447 dev_conf = DevConfModel.objects.get(pk=id_conf)
448 448
449 449 kwargs = {}
450 450 kwargs['dev_conf'] = dev_conf
451 451 kwargs['dev_conf_keys'] = ['name', 'experiment', 'device']
452 452
453 453 kwargs['title'] = 'Configuration'
454 454 kwargs['suptitle'] = 'Details'
455 455
456 456 kwargs['button'] = 'Edit Configuration'
457 457
458 458 ###### SIDEBAR ######
459 459 kwargs.update(sidebar(conf))
460 460
461 461 return render(request, 'dev_conf.html', kwargs)
462 462
463 463 def dev_conf_new(request, id_exp=0):
464 464
465 465 if request.method == 'GET':
466 466 form = ConfigurationForm(initial={'experiment':id_exp})
467 467
468 468 if request.method == 'POST':
469 469 experiment = Experiment.objects.get(pk=request.POST['experiment'])
470 470 device = Device.objects.get(pk=request.POST['device'])
471 471
472 472 DevConfForm = CONF_FORMS[device.device_type.name]
473 473
474 474 form = DevConfForm(request.POST, initial={'experiment':experiment.id})
475 475
476 476 if form.is_valid():
477 477 dev_conf = form.save()
478 478
479 479 return redirect('url_experiment', id_exp=experiment.id)
480 480
481 481 kwargs = {}
482 482 kwargs['form'] = form
483 483 kwargs['title'] = 'Configuration'
484 484 kwargs['suptitle'] = 'New'
485 485 kwargs['button'] = 'Create'
486 486
487 487 return render(request, 'dev_conf_edit.html', kwargs)
488 488
489 489 def dev_conf_edit(request, id_conf):
490 490
491 491 conf = get_object_or_404(Configuration, pk=id_conf)
492 492
493 493 DevConfModel = CONF_MODELS[conf.device.device_type.name]
494 494 DevConfForm = CONF_FORMS[conf.device.device_type.name]
495 495
496 496 dev_conf = DevConfModel.objects.get(pk=id_conf)
497 497
498 498 if request.method=='GET':
499 499 form = DevConfForm(instance=dev_conf)
500 500
501 501 if request.method=='POST':
502 502 form = DevConfForm(request.POST, instance=dev_conf)
503 503
504 504 if form.is_valid():
505 505 form.save()
506 506 return redirect('url_dev_conf', id_conf=id_conf)
507 507
508 508 kwargs = {}
509 509 kwargs['form'] = form
510 510 kwargs['title'] = 'Device Configuration'
511 511 kwargs['suptitle'] = 'Edit'
512 512 kwargs['button'] = 'Update'
513 513
514 514 ###### SIDEBAR ######
515 515 kwargs.update(sidebar(conf))
516 516
517 return render(request, 'dev_conf_edit.html', kwargs)
517 return render(request, '%s_conf_edit.html' %conf.device.device_type.name, kwargs)
518 518
519 519 def dev_conf_start(request, id_conf):
520 520
521 521 conf = get_object_or_404(Configuration, pk=id_conf)
522 522
523 523 DevConfModel = CONF_MODELS[conf.device.device_type.name]
524 524
525 525 conf = DevConfModel.objects.get(pk=id_conf)
526 526
527 527 if conf.start_device():
528 528 messages.success(request, conf.message)
529 529 else:
530 530 messages.error(request, conf.message)
531
531
532 conf.status_device()
533
532 534 return redirect(conf.get_absolute_url())
533 535
534 536 def dev_conf_stop(request, id_conf):
535 537
536 538 conf = get_object_or_404(Configuration, pk=id_conf)
537 539
538 540 DevConfModel = CONF_MODELS[conf.device.device_type.name]
539 541
540 542 conf = DevConfModel.objects.get(pk=id_conf)
541 543
542 544 if conf.stop_device():
543 545 messages.success(request, conf.message)
544 546 else:
545 547 messages.error(request, conf.message)
546 548
549 conf.status_device()
550
547 551 return redirect(conf.get_absolute_url())
548 552
549 553 def dev_conf_status(request, id_conf):
550 554
551 555 conf = get_object_or_404(Configuration, pk=id_conf)
552 556
553 557 DevConfModel = CONF_MODELS[conf.device.device_type.name]
554 558
555 559 conf = DevConfModel.objects.get(pk=id_conf)
556 560
557 561 if conf.status_device():
558 562 messages.success(request, conf.message)
559 563 else:
560 564 messages.error(request, conf.message)
561 565
562 566 return redirect(conf.get_absolute_url())
563 567
564 568
565 569 def dev_conf_write(request, id_conf):
566 570
567 571 conf = get_object_or_404(Configuration, pk=id_conf)
568 572
569 573 DevConfModel = CONF_MODELS[conf.device.device_type.name]
570 574
571 575 conf = DevConfModel.objects.get(pk=id_conf)
572 576
573 577 answer = conf.write_device()
578 conf.status_device()
574 579
575 580 if answer:
576 581 messages.success(request, conf.message)
577 582
583 #Creating a historical configuration
578 584 conf.pk = None
579 585 conf.id = None
580 586 conf.type = 1
581 587 conf.template = 0
582 588 conf.save()
583 589
590 #Original configuration
591 conf = DevConfModel.objects.get(pk=id_conf)
584 592 else:
585 593 messages.error(request, conf.message)
586 594
587 595 return redirect(conf.get_absolute_url())
588 596
589 597 def dev_conf_read(request, id_conf):
590 598
591 599 conf = get_object_or_404(Configuration, pk=id_conf)
592 600
593 601 DevConfModel = CONF_MODELS[conf.device.device_type.name]
594 602 DevConfForm = CONF_FORMS[conf.device.device_type.name]
595 603
596 604 conf = DevConfModel.objects.get(pk=id_conf)
597 605
598 606 if request.method=='GET':
599 607
600 608 parms = conf.read_device()
609 conf.status_device()
601 610
602 611 if not parms:
603 612 messages.error(request, conf.message)
604 613 return redirect(conf.get_absolute_url())
605 614
606 615 form = DevConfForm(initial=parms, instance=conf)
607 616
608 617 if request.method=='POST':
609 618 form = DevConfForm(request.POST, instance=conf)
610 619
611 620 if form.is_valid():
612 dev_model = form.save(commit=False)
613
614 if dev_model.save():
615 return redirect(conf.get_absolute_url())
621 form.save()
622 return redirect(conf.get_absolute_url())
616 623
617 624 messages.error(request, "Parameters could not be saved")
618 625
619 626 kwargs = {}
620 627 kwargs['id_dev'] = conf.id
621 628 kwargs['form'] = form
622 629 kwargs['title'] = 'Device Configuration'
623 630 kwargs['suptitle'] = 'Parameters read from device'
624 631 kwargs['button'] = 'Save'
625 632
626 633 ###### SIDEBAR ######
627 634 kwargs.update(sidebar(conf))
628 635
629 return render(conf.get_absolute_url_edit())
636 return render(request, '%s_conf_edit.html' %conf.device.device_type.name, kwargs)
630 637
631 638 def dev_conf_import(request, id_conf):
632 639
633 640 conf = get_object_or_404(Configuration, pk=id_conf)
634 641
635 642 DevConfModel = CONF_MODELS[conf.device.device_type.name]
636 643 DevConfForm = CONF_FORMS[conf.device.device_type.name]
637 644
638 645 conf = DevConfModel.objects.get(pk=id_conf)
639 646
640 647 if request.method == 'GET':
641 648 file_form = UploadFileForm()
642 649
643 650 if request.method == 'POST':
644 651 file_form = UploadFileForm(request.POST, request.FILES)
645 652
646 653 if file_form.is_valid():
647 654
648 655 parms = conf.import_from_file(request.FILES['file'])
649 656
650 657 if parms:
651
652 658 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
653
659 print parms
654 660 form = DevConfForm(initial=parms, instance=conf)
655 661
656 662 kwargs = {}
657 663 kwargs['id_dev'] = conf.id
658 664 kwargs['form'] = form
659 665 kwargs['title'] = 'Device Configuration'
660 666 kwargs['suptitle'] = 'Parameters imported'
661 667 kwargs['button'] = 'Save'
662 668 kwargs['action'] = conf.get_absolute_url_edit()
663 669 kwargs['previous'] = conf.get_absolute_url()
664 670
665 671 ###### SIDEBAR ######
666 672 kwargs.update(sidebar(conf))
667 673
668 674 return render(request, '%s_conf_edit.html' %conf.device.device_type.name, kwargs)
669 675
670 676 messages.error(request, "Could not import parameters from file")
671 677
672 678 kwargs = {}
673 679 kwargs['id_dev'] = conf.id
674 680 kwargs['title'] = 'Device Configuration'
675 681 kwargs['form'] = file_form
676 682 kwargs['suptitle'] = 'Importing file'
677 683 kwargs['button'] = 'Import'
678 684
679 685 kwargs.update(sidebar(conf))
680 686
681 687 return render(request, 'dev_conf_import.html', kwargs)
682 688
683 689 def dev_conf_export(request, id_conf):
684 690
685 691 conf = get_object_or_404(Configuration, pk=id_conf)
686 692
687 693 DevConfModel = CONF_MODELS[conf.device.device_type.name]
688 694
689 695 conf = DevConfModel.objects.get(pk=id_conf)
690 696
691 697 if request.method == 'GET':
692 file_form = DownloadFileForm()
698 file_form = DownloadFileForm(conf.device.device_type.name)
693 699
694 700 if request.method == 'POST':
695 file_form = DownloadFileForm(request.POST)
701 file_form = DownloadFileForm(conf.device.device_type.name, request.POST)
696 702
697 703 if file_form.is_valid():
698 fields = conf.export_to_file(format = file_form.format)
704 fields = conf.export_to_file(format = file_form.cleaned_data['format'])
699 705
700 706 response = HttpResponse(content_type=fields['content_type'])
701 707 response['Content-Disposition'] = 'attachment; filename="%s"' %fields['filename']
702 708 response.write(fields['content'])
703 709
704 710 return response
705 711
706 712 messages.error(request, "Could not export parameters")
707 713
708 714 kwargs = {}
709 715 kwargs['id_dev'] = conf.id
710 716 kwargs['title'] = 'Device Configuration'
711 717 kwargs['form'] = file_form
712 718 kwargs['suptitle'] = 'Exporting file'
713 719 kwargs['button'] = 'Export'
714 720
715 721 return render(request, 'dev_conf_export.html', kwargs)
716 722
717 723 def dev_conf_delete(request, id_conf):
718 724
719 725 conf = get_object_or_404(Configuration, pk=id_conf)
720 726
721 727 if request.method=='POST':
722 728 if request.user.is_staff:
723 729 id_exp = conf.experiment.id
724 730 conf.delete()
725 731 return redirect('url_experiment', id_exp=id_exp)
726 732
727 733 return HttpResponse("Not enough permission to delete this object")
728 734
729 735 kwargs = {'object':conf, 'conf_active':'active',
730 736 'url_cancel':'url_dev_conf', 'id_item':id_conf}
731 737
732 738 ###### SIDEBAR ######
733 739 kwargs.update(sidebar(conf))
734 740
735 741 return render(request, 'item_delete.html', kwargs)
736 742
737 743 def sidebar(conf):
738 744
739 745 experiments = Experiment.objects.filter(campaign=conf.experiment.campaign)
740 746 configurations = Configuration.objects.filter(experiment=conf.experiment, type=0)
741 747
742 748 exp_keys = ['id', 'campaign', 'name', 'start_time', 'end_time']
743 749 conf_keys = ['id', 'device']
744 750
745 751 kwargs = {}
746 752
747 753 kwargs['dev_conf'] = conf
748 754
749 755 kwargs['experiment_keys'] = exp_keys[1:]
750 756 kwargs['experiments'] = experiments.values(*exp_keys)
751 757
752 758 kwargs['configuration_keys'] = conf_keys[1:]
753 759 kwargs['configurations'] = configurations #.values(*conf_keys)
754 760
755 761 return kwargs
756 762
757 763
758 764 def operation(request, id_camp=None):
759 765
760 766 if not id_camp:
761 767 campaigns = Campaign.objects.all().order_by('-start_date')
762 768
763 769 if not campaigns:
764 770 return render(request, 'operation.html', {})
765 771
766 772 id_camp = campaigns[0].id
767 773
768 774 campaign = get_object_or_404(Campaign, pk = id_camp)
769 775
770 776 if request.method=='GET':
771 777 form = OperationForm(initial={'campaign': id_camp})
772 778
773 779 if request.method=='POST':
774 780 form = OperationForm(request.POST, initial={'campaign':campaign.id})
775 781
776 782 if form.is_valid():
777 783 return redirect('url_operation', id_camp=campaign.id)
778 784
779 785 locations = Location.objects.filter(experiment__campaign__pk = campaign.id)
780 786 experiments = Experiment.objects.filter(campaign=campaign)
781 787 experiments = [Experiment.objects.filter(location__pk=location.id) for location in locations]
782 788
783 789 kwargs = {}
784 790 #---Campaign
785 791 kwargs['campaign'] = campaign
786 792 kwargs['campaign_keys'] = ['name', 'start_date', 'end_date', 'tags', 'description']
787 793 #---Experimet
788 794 keys = ['id', 'name', 'start_time', 'end_time']
789 795 kwargs['experiment_keys'] = keys[1:]
790 796 kwargs['experiments'] = experiments
791 797 #---Radar
792 798 kwargs['locations'] = locations
793 799 #---Else
794 800 kwargs['title'] = 'Campaign'
795 801 kwargs['suptitle'] = campaign.name
796 802 kwargs['form'] = form
797 803 kwargs['button'] = 'Apply'
798 804
799 805 return render(request, 'operation.html', kwargs) No newline at end of file
@@ -1,926 +1,926
1 1 import ast
2 2 import json
3 import numpy as np
4 import matplotlib.pyplot as plt
5 from matplotlib import cm
3 # import numpy as np
4 # import matplotlib.pyplot as plt
5 # from matplotlib import cm
6 6
7 7 class Pulse_Design_Racp:
8 8 """A class to define the .racp output from Pulse Design """
9 9 def __init__(self):
10 10 self.header = {'version': '1103', 'data':[]}
11 11 self.radar_param = {'header': '*****Radar Controller Parameters**********', 'data':[]}
12 12 self.system_param1 = {'header': '******System Parameters*******************', 'data':[]}
13 13 self.system_param2 = {'header': '******System Parameters*******************', 'data':[]}
14 14 self.process_param = {'header': '******Process Parameters******************', 'data':[]}
15 15 self.xml = None
16 16
17 17 self.header_fields = [
18 18 {'name': 'EXPERIMENT TYPE', 'xml': 'Experiment/Process/Signal_pre_processing/Type_of_experiment'},
19 19 {'name': 'EXPERIMENT NAME', 'xml': 'Experiment', 'xml_attr_value':'name'}]
20 20 self.radar_param_fields = [
21 21 {'name': 'IPP', 'xml': 'Experiment/Controller/IPP/Width'},
22 22 {'name': 'NTX', 'xml': 'Experiment/Controller/NTX'},
23 23 {'name': 'TXA', 'xml': 'Experiment/Controller/Transmitters/TX', 'xml_attr':'id', 'xml_attr_find':'txa', 'xml_sub_pattern':'Width'},
24 24 {'name': 'TXB', 'xml': 'Experiment/Controller/Transmitters/TX', 'xml_attr':'id', 'xml_attr_find':'txb', 'xml_sub_pattern':'Width'},
25 25 {'name': '***', 'xml':'', 'type':'pulse_enable'},
26 26 {'name': '***', 'xml':'', 'type': 'Line4'},
27 27 {'name': '***', 'xml':'', 'type': 'Line5'},
28 28 {'name': '***', 'xml':'', 'type': 'Line6'},
29 29 {'name': '***', 'xml':'', 'type':'txb_delays_info'},
30 30 {'name': '***', 'xml':'', 'type': 'Line7'},
31 31 {'name': 'SAMPLING REFERENCE', 'xml':'Experiment/Controller/Ctl_Setting/Sampling_reference'},
32 32 {'name': 'RELOJ', 'xml':'Experiment/Controller/Clock/Clock_final'},
33 33 {'name': 'CLOCK DIVIDER', 'xml':'Experiment/Controller/Clock/Clock_div', 'hide':['1']},
34 34 {'name': 'TR_BEFORE', 'xml':'Experiment/Controller/Spc_Setting/Time_before'},
35 35 {'name': 'TR_AFTER', 'xml':'Experiment/Controller/Spc_Setting/Time_after'},
36 36 {'name': 'WINDOW IN LINE 5&6', 'xml':'', 'value':'NO'},
37 37 {'name': 'SYNCHRO DELAY', 'xml':'Experiment/Controller/Spc_Setting/Sync_delay', 'hide':['0']}]
38 38 self.system_param1_fields = [
39 39 {'name': 'Number of Cards', 'xml':'Experiment/Process/JARS/Number_of_cards', 'hide':['0']},
40 40 {'name': '***', 'xml':'', 'type':'cards_info'},
41 41 {'name': '***', 'xml':'', 'type':'channels_info'},
42 42 {'name': 'RAW DATA DIRECTORY', 'xml':'Experiment/Process/Data_storage/Directory'},
43 43 {'name': 'CREATE DIRECTORY PER DAY', 'xml':'Experiment/Process/Data_storage/Directory_per_day', 'type':'checkbox_YES_NO'},
44 44 {'name': 'INCLUDE EXPNAME IN DIRECTORY', 'xml':'Experiment/Process/Data_storage/Expname_in_directory', 'type':'checkbox_YES_NO'}]
45 45 self.system_param2_fields = [
46 46 {'name': 'ADC Resolution', 'xml':'', 'value':'12'}, # Default is 8, JARS is 12
47 47 {'name': 'PCI DIO BusWidth', 'xml':'', 'value':'32'}, # Default for JARS
48 48 {'name': 'RAW DATA BLOCKS', 'xml':'Experiment/Process/Data_arrangement/Data_blocks'}]
49 49 self.process_param_fields = [
50 50 {'name': 'DATATYPE', 'xml': 'Experiment/Process/Signal_pre_processing/Type_of_data'},
51 51 {'name': 'DATA ARRANGE', 'xml':'', 'value':'CONTIGUOUS_CH'}, #TODO
52 52 {'name': 'COHERENT INTEGRATION STRIDE', 'xml':'Experiment/Process/Signal_pre_processing/Integration_stride'},
53 53 {'name': '------------------', 'xml':'', 'type':'separator'},
54 54 {'name': 'ACQUIRED PROFILES', 'xml':'Experiment/Process/Data_arrangement/Acquired_profiles'},
55 55 {'name': 'PROFILES PER BLOCK', 'xml':'Experiment/Process/Data_arrangement/Profiles_per_block'},
56 56 {'name': '------------------', 'xml':'', 'type':'separator'},
57 57 {'name': 'BEGIN ON START', 'xml':'Experiment/Process/Schedule/Begin_on_Start', 'type': 'checkbox_YES_NO'},
58 58 {'name': 'BEGIN_TIME', 'xml':'Experiment/Process/Schedule/Start', 'hide':['']},
59 59 {'name': 'END_TIME', 'xml':'Experiment/Process/Schedule/End', 'hide':['']},
60 60 {'name': 'VIEW RAW DATA', 'xml':'Experiment/Process/Data_arrangement/View_raw_data', 'type': 'checkbox_YES_NO'},
61 61 {'name': 'REFRESH RATE', 'xml':'', 'value':'1'}, #TODO
62 62 {'name': '------------------', 'xml':'', 'type':'separator'},
63 63 {'name': 'SEND STATUS TO FTP', 'xml':'', 'type':'checkbox_YES_NO', 'value':'NO'}, #TODO
64 64 {'name': 'FTP SERVER', 'xml':'', 'hide':[None, '']}, #TODO
65 65 {'name': 'FTP USER', 'xml':'', 'hide':[None, '']}, #TODO
66 66 {'name': 'FTP PASSWD', 'xml':'', 'hide':[None, '']}, #TODO
67 67 {'name': 'FTP DIR', 'xml':'', 'hide':[None, '']}, #TODO
68 68 {'name': 'FTP FILE', 'xml':'', 'hide':[None, '']}, #TODO
69 69 {'name': 'FTP INTERVAL', 'xml':'', 'hide':[None, '']}, #TODO
70 70 {'name': 'SAVE STATUS AND BLOCK', 'xml':'', 'type':'checkbox_YES_NO', 'value':'NO'}, #TODO
71 71 {'name': 'GENERATE RTI', 'xml':'', 'type':'checkbox_YES_NO', 'value':'NO'}, #TODO
72 72 {'name': 'SEND RTI AND BLOCK', 'xml':'Process_acquired_profiles', 'type':'checkbox_YES_NO'}, #TODO
73 73 {'name': 'FTP INTERVAL', 'xml':'', 'value':'60'}, #TODO
74 74 {'name': '------------------', 'xml':'', 'type':'separator'},
75 75 {'name': 'COMPORT CONFIG', 'xml':'', 'value':'Com1 CBR_9600 TWOSTOPBITS NOPARITY'}, #TODO
76 76 {'name': 'JAM CONFIGURE FILE', 'xml':'', 'value':''}, #TODO
77 77 {'name': 'ACQUISITION SYSTEM', 'xml':'', 'value':'JARS'}, #TODO
78 78 {'name': '******************', 'xml':'', 'type':'acq_system_config_params'},
79 79 {'name': 'SAVE DATA', 'xml':'', 'value':'YES'}, #TODO
80 80 {'name': '******************', 'xml':'', 'type':'rc_seq_config_params'},
81 81 {'name': 'RC_STOP_SEQUENCE', 'xml':'', 'value':'255,0,255,8'},
82 82 {'name': 'RC_START_SEQUENCE', 'xml':'', 'value':'255,24'}]
83 83
84 84 def get_field_value(self, field, user_value):
85 85 if 'type' in field and field['type'] == 'checkbox_YES_NO': # Check for existence of value
86 86 if (user_value is None) or (user_value == 'None'):
87 87 user_value = 'NO'
88 88 elif user_value == 'on':
89 89 user_value = 'YES'
90 90 if 'value' in field and not(user_value): # Replace by default value
91 91 user_value = field['value']
92 92 if 'extra' in field and field['extra'] == 'upper': # Uppercase values
93 93 user_value = user_value.upper()
94 94 return str(user_value)
95 95
96 96 def load_xml(self, xml):
97 97 self.xml = xml
98 98 for field in self.header_fields:
99 99 self.add_line_output(self.header['data'], field)
100 100 for field in self.radar_param_fields:
101 101 self.add_line_output(self.radar_param['data'], field)
102 102 for field in self.system_param1_fields:
103 103 self.add_line_output(self.system_param1['data'], field)
104 104 for field in self.system_param2_fields:
105 105 self.add_line_output(self.system_param2['data'], field)
106 106 for field in self.process_param_fields:
107 107 self.add_line_output(self.process_param['data'], field)
108 108
109 109
110 110
111 111 def add_line_output(self, text_array, param_field):
112 112 name = param_field['name']
113 113 xml_l = param_field['xml']
114 114 acq_number_of_cards = int(self.xml.find('Experiment/Process/JARS/Number_of_cards').text)
115 115 acq_channels_per_card = int(self.xml.find('Experiment/Process/JARS/Channels_per_card').text)
116 116 number_of_acq_channels = acq_number_of_cards * acq_channels_per_card
117 117
118 118 if 'xml_attr' in param_field and 'xml_attr_find' in param_field:
119 119 sub_pattern = False
120 120 if 'xml_sub_pattern' in param_field:
121 121 sub_pattern = param_field['xml_sub_pattern']
122 122 element = self.xml.find_by_attribute_value(xml_l, param_field['xml_attr'], param_field['xml_attr_find'],sub_pattern)
123 123 else:
124 124 element = self.xml.find(xml_l)
125 125
126 126 if 'xml_attr_value' in param_field:
127 127 value = element.get(param_field['xml_attr_value'])
128 128 else:
129 129 value = ''
130 130 if xml_l == '' and 'value' in param_field:
131 131 value = param_field['value']
132 132 elif hasattr(element, 'text'):
133 133 value = element.text
134 134
135 135 if 'type' in param_field and param_field['type'] == 'separator': # Check for existence of value
136 136 text_array.append('------------------------------------------')
137 137 return
138 138 if 'type' in param_field and param_field['type'] == 'acq_system_config_params': # Get Acquisition System Parameters and add them
139 139 text_array.append("************JARS CONFIGURATION PARAMETERS************")
140 140 if self.xml.find('Experiment/Process/JARS/Filter').text:
141 141 # Notice that we need to use backslashes for the filter path
142 142 text_array.append("Jars_Filter="+self.xml.find('Experiment/Process/JARS/Filter_dir').text +'\\'+ self.xml.find('Experiment/Process/JARS/Filter').text)
143 143 else:
144 144 text_array.append("Jars_Filter=")
145 145 text_array.append("JARS_Collection_Mode="+self.xml.find('Experiment/Process/JARS/JARS_Collection_Mode').text)
146 146 text_array.append("SAVE_DATA=YES")
147 147 text_array.append("*****************************************************")
148 148 return
149 149 if 'type' in param_field and param_field['type'] == 'rc_seq_config_params': # Get Acquisition System Parameters and add them
150 150 text_array.append("****************RC SEQUENCES******************")
151 151 return
152 152 if 'type' in param_field:
153 153 if param_field['type'] == 'pulse_enable':
154 154 txa_enable = self.xml.find_by_attribute_value('Experiment/Controller/Transmitters/TX', 'id', 'txa', 'Pulses')
155 155 if txa_enable.text is not None:
156 156 text_array.append('Pulse selection_TXA='+txa_enable.text)
157 157 txb_enable = self.xml.find_by_attribute_value('Experiment/Controller/Transmitters/TX', 'id', 'txb', 'Pulses')
158 158 if txb_enable.text is not None:
159 159 text_array.append('Pulse selection_TXB='+txb_enable.text)
160 160 tr_enable = self.xml.find('Experiment/Controller/IPP/Pulses')
161 161 if tr_enable.text is not None:
162 162 text_array.append('Pulse selection_TR='+tr_enable.text)
163 163 return
164 164 elif param_field['type'] == 'Line4' or param_field['type'] == 'Line5' or param_field['type'] == 'Line6' or param_field['type'] == 'Line7':
165 165 code_name = 'Code_A'
166 166 line_number = '4'
167 167 line_parenthesis = ''
168 168 line_prepend = ''
169 169
170 170 if param_field['type'] == 'Line5':
171 171 code_name = 'Code_B'
172 172 line_number = '5'
173 173 line_parenthesis = ' (Line 5)'
174 174 line_prepend = 'L5_'
175 175 elif param_field['type'] == 'Line6':
176 176 code_name = 'Code_C'
177 177 line_number = '6'
178 178 line_parenthesis = ' (Line 6)'
179 179 line_prepend = 'L6_'
180 180 elif param_field['type'] == 'Line7':
181 181 code_name = 'Code_D'
182 182 line_number = '7'
183 183 line_parenthesis = ' (Line 7)'
184 184 line_prepend = 'L7_'
185 185
186 186 code_channel = self.xml.find_by_attribute_value('Experiment/Controller/Code_channels/Code_channel', 'id', code_name, 'Mode').text
187 187 if code_channel == 'FLIP':
188 188 value = self.xml.find_by_attribute_value('Experiment/Controller/Code_channels/Code_channel', 'id', code_name, 'Flip').text
189 189 flip_name = 'L'+line_number+'_FLIP' + line_parenthesis
190 190 if param_field['type'] == 'Line5':
191 191 flip_name = 'FLIP1'
192 192 elif param_field['type'] == 'Line6':
193 193 flip_name = 'FLIP2'
194 194 text_array.append(flip_name + '='+value)
195 195 elif code_channel == 'CODE':
196 196 code_data = self.xml.find_by_attribute_value('Experiment/Controller/Code_channels/Code_channel', 'id', code_name, 'Code')
197 197 Code_reference = code_data.find('Code_reference').text
198 198 Code_select = code_data.find('Code_select').text
199 199 Code_number = code_data.find('Code_number').text
200 200 Code_bits = code_data.find('Code_bits').text
201 201 custom_codes = get_custom_code_data(Code_select, int(Code_number), int(Code_bits))
202 202 text_array.append('Code Type' + line_parenthesis + '='+Code_select)
203 203 text_array.append('Number of Codes' + line_parenthesis + '='+Code_number)
204 204 text_array.append('Code Width' + line_parenthesis + '='+Code_bits)
205 205 for zero_idx, custom_code in enumerate(custom_codes):
206 206 text_array.append(line_prepend+'COD('+str(zero_idx)+')='+custom_code)
207 207 # Calculate Codes
208 208 text_array.append('L'+line_number+'_REFERENCE='+Code_reference.upper())
209 209 elif code_channel == 'Sampling':
210 210 sampling_name = 'Sampling Windows (Line ' + line_number + ')'
211 211 prepend = 'L'+line_number+'_'
212 212 if param_field['type'] == 'Line7':
213 213 sampling_name = 'Sampling Windows'
214 214 prepend = ''
215 215 sampling_data = self.xml.find_by_attribute_value('Experiment/Controller/Code_channels/Code_channel', 'id', code_name, 'Sampling')
216 216 Code_reference = sampling_data.find('Code_reference').text.upper()
217 217 samples = sampling_data.find('Samples')
218 218 text_array.append(sampling_name+'='+str(len(samples)))
219 219 for zero_idx, sample in enumerate(samples):
220 220 text_array.append(prepend+'H0('+str(zero_idx)+')='+sample.find('FH').text)
221 221 text_array.append(prepend+'NSA('+str(zero_idx)+')='+sample.find('NSA').text)
222 222 text_array.append(prepend+'DH('+str(zero_idx)+')='+sample.find('DH').text)
223 223 text_array.append('L'+line_number+'_REFERENCE='+Code_reference.upper())
224 224 elif code_channel == 'Synchro':
225 225 text_array.append('Line'+line_number+'=Synchro')
226 226 elif code_channel == 'Portion_Spec':
227 227 portion_data = self.xml.find_by_attribute_value('Experiment/Controller/Code_channels/Code_channel', 'id', code_name, 'PortionSpec')
228 228 periodic = portion_data.find('Periodic').text
229 229 portions = portion_data.find('Portions')
230 230 text_array.append('L'+line_number+' Number Of Portions='+str(len(portions)))
231 231 for zero_idx, portion in enumerate(portions):
232 232 text_array.append('PORTION_BEGIN('+str(zero_idx)+')='+portion.find('Begin_units').text)
233 233 text_array.append('PORTION_END('+str(zero_idx)+')='+portion.find('End_units').text)
234 234 if periodic == '1':
235 235 text_array.append('L'+line_number+' Portions IPP Periodic=YES')
236 236 else:
237 237 text_array.append('L'+line_number+' Portions IPP Periodic=NO')
238 238 return
239 239 elif param_field['type'] == 'txb_delays_info':
240 240 txb_delays = self.xml.find_by_attribute_value('Experiment/Controller/Transmitters/TX', 'id', 'txb', 'Delays')
241 241 text_array.append("Number of Taus="+str(len(txb_delays)))
242 242 for zero_index, txb_delay in enumerate(txb_delays):
243 243 text_array.append('TAU('+str(zero_index)+')='+str(txb_delay.text))
244 244 return
245 245 elif param_field['type'] == 'cards_info': # Get Cards info
246 246 if not(acq_number_of_cards == '0'):
247 247 for card in range(acq_number_of_cards):
248 248 name = 'Card('+str(card)+')'
249 249 text_array.append(name + "=" + str(card))
250 250 return
251 251 elif param_field['type'] == 'channels_info': # Get Channel info
252 252 text_array.append("Number of Channels="+str(number_of_acq_channels))
253 253 if not(number_of_acq_channels == '0'):
254 254 acq_channels = self.xml.find('Experiment/Process/Acq_channel_selection')
255 255 enabled_channels = []
256 256 channel_names =[]
257 257 for acq_channel in acq_channels:
258 258 acq_channel_number = acq_channel.get('id')
259 259 acq_channel_name = acq_channel.find('Name').text
260 260 enabled = False
261 261 if hasattr(acq_channel.find('Enabled'), 'text'):
262 262 enabled = acq_channel.find('Enabled').text
263 263 if enabled == 'on':
264 264 text_array.append("Channel("+acq_channel_number+")=" + str(int(acq_channel_number)+1))
265 265 enabled_channels.append(acq_channel_number)
266 266 channel_names.append(acq_channel_name)
267 267 text_array.append("Antennas_Names="+str(len(enabled_channels)))
268 268 for index, channel in enumerate(enabled_channels):
269 269 text_array.append("AntennaName(" + str(int(channel)+1) + ")="+str(channel_names[index]))
270 270 return
271 271 if 'hide' in param_field and value in param_field['hide']: # Check to see if value should be written
272 272 return
273 273 text_array.append(name + "=" + self.get_field_value(param_field, value))
274 274
275 275 def convert_to_racp(self):
276 276 output = []
277 277 # HEADER
278 278 for line in self.header['data']:
279 279 output.append(line)
280 280 output.append('HEADER VERSION='+self.header['version'])
281 281 # RADAR PARAMETERS
282 282 output.append(self.radar_param['header'])
283 283 for line in self.radar_param['data']:
284 284 output.append(line)
285 285 # SYSTEM PARAMETERS
286 286 output.append(self.system_param1['header'])
287 287 for line in self.system_param1['data']:
288 288 output.append(line)
289 289 output.append(self.system_param2['header'])
290 290 for line in self.system_param2['data']:
291 291 output.append(line)
292 292 # PROCESS PARAMETERS
293 293 output.append(self.process_param['header'])
294 294 for line in self.process_param['data']:
295 295 output.append(line)
296 296
297 297 racp_content = "\n".join([str(x) for x in output])
298 298 return racp_content
299 299
300 300 def reduce_code_bits(code_bits, bits_per_code):
301 301 return code_bits[:bits_per_code]
302 302
303 303 def zeropad_code_bits(code_bits, custom_bits_per_code):
304 304 return code_bits.ljust(custom_bits_per_code, "0")
305 305
306 306
307 307 def get_custom_code_data(codename, number_of_codes, bits_per_code):
308 308 import json
309 309 import copy
310 310 json_data=open('../js/pulse_code_values.json')
311 311 PD_pulse_codes = json.load(json_data)
312 312 selected_code = copy.copy(PD_pulse_codes[codename])
313 313
314 314 modified_binary_codes = []
315 315 for i in range (number_of_codes):
316 316 if (i >= selected_code['number_of_codes']):
317 317 # We just repeat the first code.
318 318 modified_binary_codes.append(selected_code['binary_codes'][0])
319 319 else:
320 320 modified_binary_codes.append(selected_code['binary_codes'][i])
321 321 # Now adjust the width
322 322 if (bits_per_code <= selected_code['bits_per_code']):
323 323 modified_binary_codes = [reduce_code_bits(x, bits_per_code) for x in modified_binary_codes]
324 324 else: # Zero pad to the right
325 325 modified_binary_codes = [zeropad_code_bits(x, bits_per_code) for x in modified_binary_codes]
326 326 return modified_binary_codes
327 327
328 328 class Pulse_Design_Mixed_Racp:
329 329 """A class to define the .racp output from Pulse Design """
330 330 def __init__(self, number_of_experiments):
331 331 self.header = {'version': '1103'}
332 332 self.radar_param = {'header': '*****Radar Controller Parameters**********'}
333 333 self.system_param1 = {'header': '******System Parameters*******************'}
334 334 self.system_param2 = {'header': '******System Parameters*******************'}
335 335 self.process_param = {'header': '******Process Parameters******************'}
336 336 self.xml = None
337 337 self.number_of_experiments = number_of_experiments
338 338 self.header_fields = {}
339 339 self.radar_param_fields = {}
340 340 self.system_param1_fields = {}
341 341 self.system_param2_fields = {}
342 342 self.process_param_fields = {}
343 343
344 344 for i in range(self.number_of_experiments):
345 345 self.header['data_experiment_number_'+str(i)] = []
346 346 self.radar_param['data_experiment_number_'+str(i)] = []
347 347 self.system_param1['data_experiment_number_'+str(i)] = []
348 348 self.system_param2['data_experiment_number_'+str(i)] = []
349 349 self.process_param['data_experiment_number_'+str(i)] = []
350 350
351 351 self.header_fields['indices_experiment_number_'+str(i)] = []
352 352 self.radar_param_fields['indices_experiment_number_'+str(i)] = []
353 353 self.system_param1_fields['indices_experiment_number_'+str(i)] = []
354 354 self.system_param2_fields['indices_experiment_number_'+str(i)] = []
355 355 self.process_param_fields['indices_experiment_number_'+str(i)] = []
356 356
357 357 self.header_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'EXPERIMENT TYPE', 'xml': 'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment/Process/Signal_pre_processing/Type_of_experiment'})
358 358 self.header_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'EXPERIMENT NAME', 'xml': 'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment', 'xml_attr_value':'name'})
359 359 self.radar_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'IPP', 'xml': 'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment/Controller/IPP/Width'})
360 360 self.radar_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'NTX', 'xml': 'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment/Controller/NTX'})
361 361 self.radar_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'TXA', 'xml': 'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment/Controller/Transmitters/TX', 'xml_attr':'id', 'xml_attr_find':'txa', 'xml_sub_pattern':'Width'})
362 362 self.radar_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'TXB', 'xml': 'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment/Controller/Transmitters/TX', 'xml_attr':'id', 'xml_attr_find':'txb', 'xml_sub_pattern':'Width'})
363 363 self.radar_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '***', 'xml':'', 'type':'pulse_enable'})
364 364 self.radar_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '***', 'xml':'', 'type': 'Line4'})
365 365 self.radar_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '***', 'xml':'', 'type': 'Line5'})
366 366 self.radar_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '***', 'xml':'', 'type': 'Line6'})
367 367 self.radar_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '***', 'xml':'', 'type':'txb_delays_info'})
368 368 self.radar_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '***', 'xml':'', 'type': 'Line7'})
369 369 self.radar_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'SAMPLING REFERENCE', 'xml':'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment/Controller/Ctl_Setting/Sampling_reference'})
370 370 self.radar_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'RELOJ', 'xml':'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment/Controller/Clock/Clock_final'})
371 371 self.radar_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'CLOCK DIVIDER', 'xml':'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment/Controller/Clock/Clock_div', 'hide':['1']})
372 372 self.radar_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'TR_BEFORE', 'xml':'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment/Controller/Spc_Setting/Time_before'})
373 373 self.radar_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'TR_AFTER', 'xml':'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment/Controller/Spc_Setting/Time_after'})
374 374 self.radar_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'WINDOW IN LINE 5&6', 'xml':'', 'value':'NO'})
375 375 self.radar_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'SYNCHRO DELAY', 'xml':'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment/Controller/Spc_Setting/Sync_delay', 'hide':['0']})
376 376 self.system_param1_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'Number of Cards', 'xml':'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment/Process/JARS/Number_of_cards', 'hide':['0']})
377 377 self.system_param1_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '***', 'xml':'', 'type':'cards_info'})
378 378 self.system_param1_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '***', 'xml':'', 'type':'channels_info'})
379 379 self.system_param1_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'RAW DATA DIRECTORY', 'xml':'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment/Process/Data_storage/Directory'})
380 380 self.system_param1_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'CREATE DIRECTORY PER DAY', 'xml':'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment/Process/Data_storage/Directory_per_day', 'type':'checkbox_YES_NO'})
381 381 self.system_param1_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'INCLUDE EXPNAME IN DIRECTORY', 'xml':'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment/Process/Data_storage/Expname_in_directory', 'type':'checkbox_YES_NO'})
382 382 self.system_param2_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'ADC Resolution', 'xml':'', 'value':'12'})# Default is 8, JARS is 12
383 383 self.system_param2_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'PCI DIO BusWidth', 'xml':'', 'value':'32'}) # Default for JARS
384 384 self.system_param2_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'RAW DATA BLOCKS', 'xml':'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment/Process/Data_arrangement/Data_blocks'})
385 385 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'DATATYPE', 'xml': 'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment/Process/Signal_pre_processing/Type_of_data'})
386 386 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'DATA ARRANGE', 'xml':'', 'value':'CONTIGUOUS_CH'})
387 387 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'COHERENT INTEGRATION STRIDE', 'xml':'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment/Process/Signal_pre_processing/Integration_stride'})
388 388 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '------------------', 'xml':'', 'type':'separator'})
389 389 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'ACQUIRED PROFILES', 'xml':'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment/Process/Data_arrangement/Acquired_profiles'})
390 390 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'PROFILES PER BLOCK', 'xml':'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment/Process/Data_arrangement/Profiles_per_block'})
391 391 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '------------------', 'xml':'', 'type':'separator'})
392 392 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'BEGIN ON START', 'xml':'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment/Process/Schedule/Begin_on_Start', 'type': 'checkbox_YES_NO'})
393 393 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'BEGIN_TIME', 'xml':'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment/Process/Schedule/Start', 'hide':['']})
394 394 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'END_TIME', 'xml':'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment/Process/Schedule/End', 'hide':['']})
395 395 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'VIEW RAW DATA', 'xml':'Experiments/List/Experiment['+str(i)+']/XML_contents/Pulse_Design/Experiment/Process/Data_arrangement/View_raw_data', 'type': 'checkbox_YES_NO'})
396 396 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'REFRESH RATE', 'xml':'', 'value':'1'})
397 397 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '------------------', 'xml':'', 'type':'separator'})
398 398 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'SEND STATUS TO FTP', 'xml':'', 'type':'checkbox_YES_NO', 'value':'NO'})
399 399 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'FTP SERVER', 'xml':'', 'hide':[None, '']})
400 400 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'FTP USER', 'xml':'', 'hide':[None, '']})
401 401 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'FTP PASSWD', 'xml':'', 'hide':[None, '']})
402 402 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'FTP DIR', 'xml':'', 'hide':[None, '']})
403 403 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'FTP FILE', 'xml':'', 'hide':[None, '']})
404 404 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'FTP INTERVAL', 'xml':'', 'hide':[None, '']})
405 405 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'SAVE STATUS AND BLOCK', 'xml':'', 'type':'checkbox_YES_NO', 'value':'NO'})
406 406 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'GENERATE RTI', 'xml':'', 'type':'checkbox_YES_NO', 'value':'NO'})
407 407 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'SEND RTI AND BLOCK', 'xml':'Process_acquired_profiles', 'type':'checkbox_YES_NO'})
408 408 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'FTP INTERVAL', 'xml':'', 'value':'60'})
409 409 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '------------------', 'xml':'', 'type':'separator'})
410 410 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'COMPORT CONFIG', 'xml':'', 'value':'Com1 CBR_9600 TWOSTOPBITS NOPARITY'})
411 411 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'JAM CONFIGURE FILE', 'xml':'', 'value':''})
412 412 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'ACQUISITION SYSTEM', 'xml':'', 'value':'JARS'})
413 413 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '******************', 'xml':'', 'type':'acq_system_config_params'})
414 414 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'SAVE DATA', 'xml':'', 'value':'YES'})
415 415 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '******************', 'xml':'', 'type':'rc_seq_config_params'})
416 416 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'RC_STOP_SEQUENCE', 'xml':'', 'value':'255,0,255,8'})
417 417 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'RC_START_SEQUENCE', 'xml':'', 'value':'255,24'})
418 418 def get_field_value(self, field, user_value):
419 419 if 'type' in field and field['type'] == 'checkbox_YES_NO': # Check for existence of value
420 420 if (user_value is None) or (user_value == 'None'):
421 421 user_value = 'NO'
422 422 elif user_value == 'on':
423 423 user_value = 'YES'
424 424 if 'value' in field and not(user_value): # Replace by default value
425 425 user_value = field['value']
426 426 if 'extra' in field and field['extra'] == 'upper': # Uppercase values
427 427 user_value = user_value.upper()
428 428 return str(user_value)
429 429
430 430 def load_xml(self, xml):
431 431 self.xml = xml
432 432 for i in range(self.number_of_experiments):
433 433 for field in self.header_fields['indices_experiment_number_'+str(i)]:
434 434 self.add_line_output(self.header['data_experiment_number_'+str(i)], field)
435 435 for field in self.radar_param_fields['indices_experiment_number_'+str(i)]:
436 436 self.add_line_output(self.radar_param['data_experiment_number_'+str(i)], field)
437 437 for field in self.system_param1_fields['indices_experiment_number_'+str(i)]:
438 438 self.add_line_output(self.system_param1['data_experiment_number_'+str(i)], field)
439 439 for field in self.system_param2_fields['indices_experiment_number_'+str(i)]:
440 440 self.add_line_output(self.system_param2['data_experiment_number_'+str(i)], field)
441 441 for field in self.process_param_fields['indices_experiment_number_'+str(i)]:
442 442 self.add_line_output(self.process_param['data_experiment_number_'+str(i)], field)
443 443
444 444
445 445
446 446 def add_line_output(self, text_array, param_field):
447 447
448 448
449 449 name = param_field['name']
450 450 xml_l = param_field['xml']
451 451 id = str(param_field['number_experiment'])
452 452 acq_number_of_cards = int(self.xml.find('Experiments/List/Experiment['+id+']/XML_contents/Pulse_Design/Experiment/Process/JARS/Number_of_cards').text)
453 453 acq_channels_per_card = int(self.xml.find('Experiments/List/Experiment['+id+']/XML_contents/Pulse_Design/Experiment/Process/JARS/Channels_per_card').text)
454 454 number_of_acq_channels = acq_number_of_cards * acq_channels_per_card
455 455
456 456
457 457
458 458 if 'xml_attr' in param_field and 'xml_attr_find' in param_field:
459 459 sub_pattern = False
460 460 if 'xml_sub_pattern' in param_field:
461 461 sub_pattern = param_field['xml_sub_pattern']
462 462 element = self.xml.find_by_attribute_value(xml_l, param_field['xml_attr'], param_field['xml_attr_find'],sub_pattern)
463 463 else:
464 464 element = self.xml.find(xml_l)
465 465
466 466 if 'xml_attr_value' in param_field:
467 467 value = element.get(param_field['xml_attr_value'])
468 468 else:
469 469 value = ''
470 470 if xml_l == '' and 'value' in param_field:
471 471 value = param_field['value']
472 472 elif hasattr(element, 'text'):
473 473 value = element.text
474 474
475 475 if 'type' in param_field and param_field['type'] == 'separator': # Check for existence of value
476 476 text_array.append('------------------------------------------')
477 477 return
478 478 if 'type' in param_field and param_field['type'] == 'acq_system_config_params': # Get Acquisition System Parameters and add them
479 479 text_array.append("************JARS CONFIGURATION PARAMETERS************")
480 480 if self.xml.find('Experiments/List/Experiment['+id+']/XML_contents/Pulse_Design/Experiment/Process/JARS/Filter').text:
481 481 # Notice that we need to use backslashes for the filter path
482 482 text_array.append("Jars_Filter="+self.xml.find('Experiments/List/Experiment['+id+']/XML_contents/Pulse_Design/Experiment/Process/JARS/Filter_dir').text +'\\'+ self.xml.find('Experiments/List/Experiment['+id+']/XML_contents/Pulse_Design/Experiment/Process/JARS/Filter').text)
483 483 else:
484 484 text_array.append("Jars_Filter=")
485 485 text_array.append("JARS_Collection_Mode="+self.xml.find('Experiments/List/Experiment['+id+']/XML_contents/Pulse_Design/Experiment/Process/JARS/JARS_Collection_Mode').text)
486 486 text_array.append("SAVE_DATA=YES")
487 487 text_array.append("*****************************************************")
488 488 return
489 489 if 'type' in param_field and param_field['type'] == 'rc_seq_config_params': # Get Acquisition System Parameters and add them
490 490 text_array.append("****************RC SEQUENCES******************")
491 491 return
492 492 ##{'name': '***', 'xml':'', 'type':'pulse_enable'},
493 493 if 'type' in param_field:
494 494 if param_field['type'] == 'pulse_enable':
495 495 txa_enable = self.xml.find_by_attribute_value('Experiments/List/Experiment['+id+']/XML_contents/Pulse_Design/Experiment/Controller/Transmitters/TX', 'id', 'txa', 'Pulses')
496 496 if txa_enable.text is not None:
497 497 text_array.append('Pulse selection_TXA='+txa_enable.text)
498 498 txb_enable = self.xml.find_by_attribute_value('Experiments/List/Experiment['+id+']/XML_contents/Pulse_Design/Experiment/Controller/Transmitters/TX', 'id', 'txb', 'Pulses')
499 499 if txb_enable.text is not None:
500 500 text_array.append('Pulse selection_TXB='+txb_enable.text)
501 501 tr_enable = self.xml.find('Experiments/List/Experiment['+id+']/XML_contents/Pulse_Design/Experiment/Controller/IPP/Pulses')
502 502 if tr_enable.text is not None:
503 503 text_array.append('Experiments/List/Experiment['+id+']/XML_contents/Pulse_Design/Pulse selection_TR='+tr_enable.text)
504 504 return
505 505 elif param_field['type'] == 'Line4' or param_field['type'] == 'Line5' or param_field['type'] == 'Line6' or param_field['type'] == 'Line7':
506 506 code_name = 'Code_A'
507 507 line_number = '4'
508 508 line_parenthesis = ''
509 509 line_prepend = ''
510 510
511 511 if param_field['type'] == 'Line5':
512 512 code_name = 'Code_B'
513 513 line_number = '5'
514 514 line_parenthesis = ' (Line 5)'
515 515 line_prepend = 'L5_'
516 516 elif param_field['type'] == 'Line6':
517 517 code_name = 'Code_C'
518 518 line_number = '6'
519 519 line_parenthesis = ' (Line 6)'
520 520 line_prepend = 'L6_'
521 521 elif param_field['type'] == 'Line7':
522 522 code_name = 'Code_D'
523 523 line_number = '7'
524 524 line_parenthesis = ' (Line 7)'
525 525 line_prepend = 'L7_'
526 526
527 527 code_channel = self.xml.find_by_attribute_value('Experiments/List/Experiment['+id+']/XML_contents/Pulse_Design/Experiment/Controller/Code_channels/Code_channel', 'id', code_name, 'Mode').text
528 528 if code_channel == 'FLIP':
529 529 value = self.xml.find_by_attribute_value('Experiments/List/Experiment['+id+']/XML_contents/Pulse_Design/Experiment/Controller/Code_channels/Code_channel', 'id', code_name, 'Flip').text
530 530 flip_name = 'L'+line_number+'_FLIP' + line_parenthesis
531 531 if param_field['type'] == 'Line5':
532 532 flip_name = 'FLIP1'
533 533 elif param_field['type'] == 'Line6':
534 534 flip_name = 'FLIP2'
535 535 text_array.append(flip_name + '='+value)
536 536 elif code_channel == 'CODE':
537 537 code_data = self.xml.find_by_attribute_value('Experiments/List/Experiment['+id+']/XML_contents/Pulse_Design/Experiment/Controller/Code_channels/Code_channel', 'id', code_name, 'Code')
538 538 Code_reference = code_data.find('Code_reference').text
539 539 Code_select = code_data.find('Code_select').text
540 540 Code_number = code_data.find('Code_number').text
541 541 Code_bits = code_data.find('Code_bits').text
542 542 custom_codes = get_custom_code_data(Code_select, int(Code_number), int(Code_bits))
543 543 text_array.append('Code Type' + line_parenthesis + '='+Code_select)
544 544 text_array.append('Number of Codes' + line_parenthesis + '='+Code_number)
545 545 text_array.append('Code Width' + line_parenthesis + '='+Code_bits)
546 546 for zero_idx, custom_code in enumerate(custom_codes):
547 547 text_array.append(line_prepend+'COD('+str(zero_idx)+')='+custom_code)
548 548 # Calculate Codes
549 549 text_array.append('L'+line_number+'_REFERENCE='+Code_reference.upper())
550 550 elif code_channel == 'Sampling':
551 551 sampling_name = 'Sampling Windows (Line ' + line_number + ')'
552 552 prepend = 'L'+line_number+'_'
553 553 if param_field['type'] == 'Line7':
554 554 sampling_name = 'Sampling Windows'
555 555 prepend = ''
556 556 sampling_data = self.xml.find_by_attribute_value('Experiments/List/Experiment['+id+']/XML_contents/Pulse_Design/Experiment/Controller/Code_channels/Code_channel', 'id', code_name, 'Sampling')
557 557 Code_reference = sampling_data.find('Code_reference').text.upper()
558 558 samples = sampling_data.find('Samples')
559 559 text_array.append(sampling_name+'='+str(len(samples)))
560 560 for zero_idx, sample in enumerate(samples):
561 561 text_array.append(prepend+'H0('+str(zero_idx)+')='+sample.find('FH').text)
562 562 text_array.append(prepend+'NSA('+str(zero_idx)+')='+sample.find('NSA').text)
563 563 text_array.append(prepend+'DH('+str(zero_idx)+')='+sample.find('DH').text)
564 564 text_array.append('L'+line_number+'_REFERENCE='+Code_reference.upper())
565 565 elif code_channel == 'Synchro':
566 566 text_array.append('Line'+line_number+'=Synchro')
567 567 elif code_channel == 'Portion_Spec':
568 568 portion_data = self.xml.find_by_attribute_value('Experiments/List/Experiment['+id+']/XML_contents/Pulse_Design/Experiment/Controller/Code_channels/Code_channel', 'id', code_name, 'PortionSpec')
569 569 periodic = portion_data.find('Periodic').text
570 570 portions = portion_data.find('Portions')
571 571 text_array.append('L'+line_number+' Number Of Portions='+str(len(portions)))
572 572 for zero_idx, portion in enumerate(portions):
573 573 text_array.append('PORTION_BEGIN('+str(zero_idx)+')='+portion.find('Begin_units').text)
574 574 text_array.append('PORTION_END('+str(zero_idx)+')='+portion.find('End_units').text)
575 575 if periodic == '1':
576 576 text_array.append('L'+line_number+' Portions IPP Periodic=YES')
577 577 else:
578 578 text_array.append('L'+line_number+' Portions IPP Periodic=NO')
579 579 return
580 580 elif param_field['type'] == 'txb_delays_info':
581 581 txb_delays = self.xml.find_by_attribute_value('Experiments/List/Experiment['+id+']/XML_contents/Pulse_Design/Experiment/Controller/Transmitters/TX', 'id', 'txb', 'Delays')
582 582 text_array.append("Number of Taus="+str(len(txb_delays)))
583 583 for zero_index, txb_delay in enumerate(txb_delays):
584 584 text_array.append('TAU('+str(zero_index)+')='+str(txb_delay.text))
585 585 return
586 586 elif param_field['type'] == 'cards_info': # Get Cards info
587 587 if not(acq_number_of_cards == '0'):
588 588 for card in range(acq_number_of_cards):
589 589 name = 'Card('+str(card)+')'
590 590 text_array.append(name + "=" + str(card))
591 591 return
592 592 elif param_field['type'] == 'channels_info': # Get Channel info
593 593 text_array.append("Number of Channels="+str(number_of_acq_channels))
594 594 if not(number_of_acq_channels == '0'):
595 595 acq_channels = self.xml.find('Experiments/List/Experiment['+id+']/XML_contents/Pulse_Design/Experiment/Process/Acq_channel_selection')
596 596 enabled_channels = []
597 597 channel_names =[]
598 598 for acq_channel in acq_channels:
599 599 acq_channel_number = acq_channel.get('id')
600 600 acq_channel_name = acq_channel.find('Name').text
601 601 enabled = False
602 602 if hasattr(acq_channel.find('Enabled'), 'text'):
603 603 enabled = acq_channel.find('Enabled').text
604 604 if enabled == 'on':
605 605 text_array.append("Channel("+acq_channel_number+")=" + str(int(acq_channel_number)+1))
606 606 enabled_channels.append(acq_channel_number)
607 607 channel_names.append(acq_channel_name)
608 608 text_array.append("Antennas_Names="+str(len(enabled_channels)))
609 609 for index, channel in enumerate(enabled_channels):
610 610 text_array.append("AntennaName(" + str(int(channel)+1) + ")="+str(channel_names[index]))
611 611 return
612 612 if 'hide' in param_field and value in param_field['hide']: # Check to see if value should be written
613 613 return
614 614 text_array.append(name + "=" + self.get_field_value(param_field, value))
615 615
616 616 def convert_to_racp(self):
617 617 output = []
618 618 # HEADER
619 619 for i in range(self.number_of_experiments):
620 620 for line in self.header['data_experiment_number_'+str(i)]:
621 621 output.append(line)
622 622 output.append('HEADER VERSION='+self.header['version'])
623 623 # RADAR PARAMETERS
624 624 output.append(self.radar_param['header'])
625 625 for line in self.radar_param['data_experiment_number_'+str(i)]:
626 626 output.append(line)
627 627 # SYSTEM PARAMETERS
628 628 output.append(self.system_param1['header'])
629 629 for line in self.system_param1['data_experiment_number_'+str(i)]:
630 630 output.append(line)
631 631 output.append(self.system_param2['header'])
632 632 for line in self.system_param2['data_experiment_number_'+str(i)]:
633 633 output.append(line)
634 634 # PROCESS PARAMETERS
635 635 output.append(self.process_param['header'])
636 636 for line in self.process_param['data_experiment_number_'+str(i)]:
637 637 output.append(line)
638 638 output.append("\n")
639 639
640 640 racp_content = "\n".join([str(x) for x in output])
641 641 return racp_content
642 642
643 643 class RCFile(object):
644 644
645 645 def __init__(self, f=None):
646 646
647 647 self.data = {}
648 648 if isinstance(f, str):
649 649 self.f = open(f)
650 650 self.name = f.split('/')[-1]
651 651 elif hasattr(f, 'read'):
652 652 self.f = f
653 653 self.name = f.name.split('/')[-1]
654 654 else:
655 655 self.f = f
656 656 self.name = None
657 657
658 658 if self.f:
659 659 if 'racp' in self.name:
660 660 self.parse_racp()
661 661 elif 'dat' in self.name:
662 662 self.parse_dat()
663 663
664 664 def get_line_parameters(self, data, line):
665 665
666 666 line_params = {}
667 667 for label in data:
668 668 if 'L%d' % line in label or '(Line %d)' % line in label or 'Line%d' % line in label:
669 669 line_params[label] = data[label]
670 670 return line_params
671 671
672 672 def parse_racp(self):
673 673
674 674 data = {}
675 675 raw_data = [s.strip() for s in self.f.readlines()]
676 676 for line in raw_data:
677 677 if line and '=' in line:
678 678 label, value = line.strip().split('=')
679 679 data[label] = value
680 680 self.data['experiment_type'] = data['EXPERIMENT TYPE']
681 681 self.data['header_version'] = data['HEADER VERSION']
682 682 self.data['name'] = data['EXPERIMENT NAME']
683 683 self.data['ipp'] = float(data['IPP'])
684 684 self.data['ntx'] = int(data['NTX'])
685 685 if 'CLOCK DIVIDER' in data:
686 686 self.data['clock_divider'] = int(data['CLOCK DIVIDER'])
687 687 else:
688 688 self.data['clock_divider'] = 1
689 689 self.data['clock'] = float(data['RELOJ'])*self.data['clock_divider']
690 690 self.data['time_before'] = int(data['TR_BEFORE'])
691 691 self.data['time_after'] = int(data['TR_AFTER'])
692 692 if 'SYNCHRO DELAY' in data:
693 693 self.data['sync'] = int(data['SYNCHRO DELAY'])
694 694 else:
695 695 self.data['sync'] = 0
696 696 self.data['lines'] = []
697 697
698 698 #Add TR line
699 699 if 'Pulse selection_TR' in data:
700 700 if 'A' in data['Pulse selection_TR']:
701 701 rng = data['Pulse selection_TR'].replace('A', '')
702 702 elif 'B' in data['Pulse selection_TR']:
703 703 rng = data['Pulse selection_TR'].replace('B', '')
704 704 else:
705 705 rng = data['Pulse selection_TR']
706 706 line = {'type':'tr', 'range': rng, 'TX_ref':'TXA'}
707 707 else:
708 708 line = {'type': 'tr', 'range': 0, 'TX_ref': '0'}
709 709
710 710 self.data['lines'].append(line)
711 711
712 712 #Add TX's lines
713 713 if 'TXA' in data:
714 714 line = {'type':'tx', 'pulse_width':data['TXA'], 'delays':'0'}
715 715 if 'Pulse selection_TXA' in data:
716 716 line['range'] = data['Pulse selection_TXA']
717 717 else:
718 718 line['range'] = '0'
719 719 self.data['lines'].append(line)
720 720
721 721 if 'TXB' in data:
722 722 line = {'type':'tx', 'pulse_width':data['TXB'], 'delays':'0'}
723 723 if 'Pulse selection_TXB' in data:
724 724 line['range'] = data['Pulse selection_TXB']
725 725 else:
726 726 line['range'] = '0'
727 727
728 728 if 'Number of Taus' in data:
729 729 delays = [data['TAU({0})'.format(i)] for i in range(int(data['Number of Taus']))]
730 730 line['delays'] = ','.join(delays)
731 731
732 732 self.data['lines'].append(line)
733 733
734 734 #Add Other lines (4-6)
735 735 for n in range(4, 7):
736 736 params = self.get_line_parameters(data, n)
737 737 labels = params.keys()
738 738
739 739 if 'L%d_FLIP' % n in labels:
740 740 line = {'type':'flip', 'number_of_flips':data['L%d_FLIP' % n]}
741 741 elif 'Code Type' in data and n==4:
742 742 line = {'type':'codes', 'code':data['Code Type'], 'TX_ref':data['L%d_REFERENCE' % n]}
743 743 elif 'Code Type (Line %d)' % n in labels:
744 744 line = {'type':'codes', 'code':data['Code Type (Line %d)' % n], 'TX_ref':data['L%d_REFERENCE' % n]}
745 745 elif 'Sampling Windows (Line %d)' % n in data:
746 746 line = {'type':'windows', 'TX_ref':data['L%d_REFERENCE' % n]}
747 747 windows = []
748 748 for w in range(int(data['Sampling Windows (Line %d)' % n])):
749 749 windows.append({'first_height':float(data['L%d_H0(%d)' % (n, w)]),
750 750 'number_of_samples':int(data['L%d_NSA(%d)' % (n, w)]),
751 751 'resolution':float(data['L%d_DH(%d)' % (n, w)])}
752 752 )
753 753 line['params'] = windows
754 754 elif 'Line%d' % n in labels and data['Line%d' % n]=='Synchro':
755 755 line = {'type':'sync', 'invert':0}
756 756 elif 'L%d Number Of Portions' % n in labels:
757 757 line = {'type':'prog_pulses'}
758 758 if 'L%s Portions IPP Periodic' % n in data:
759 759 line['periodic'] = 1 if data['L%s Portions IPP Periodic' % n]=='YES' else 0
760 760 portions = []
761 761 x = raw_data.index('L%d Number Of Portions=%s' % (n, data['L%d Number Of Portions' % n]))
762 762 for w in range(int(data['L%d Number Of Portions' % n])):
763 763 begin = raw_data[x+1+2*w].split('=')[-1]
764 764 end = raw_data[x+2+2*w].split('=')[-1]
765 765 portions.append({'begin':int(begin),
766 766 'end':int(end)}
767 767 )
768 768 line['params'] = portions
769 769 elif 'FLIP1' in data and n==5:
770 770 line = {'type':'flip', 'number_of_flips':data['FLIP1']}
771 771 elif 'FLIP2' in data and n==6:
772 772 line = {'type':'flip', 'number_of_flips':data['FLIP2']}
773 773 else:
774 774 line = {'type':'none'}
775 775
776 776 self.data['lines'].append(line)
777 777
778 778 #Add line 7 (windows)
779 779 if 'Sampling Windows' in data:
780 780 line = {'type':'windows', 'TX_ref':data['L7_REFERENCE']}
781 781 windows = []
782 782 x = raw_data.index('Sampling Windows=%s' % data['Sampling Windows'])
783 783 for w in range(int(data['Sampling Windows'])):
784 784 h0 = raw_data[x+1+3*w].split('=')[-1]
785 785 nsa = raw_data[x+2+3*w].split('=')[-1]
786 786 dh = raw_data[x+3+3*w].split('=')[-1]
787 787 windows.append({'first_height':float(h0),
788 788 'number_of_samples':int(nsa),
789 789 'resolution':float(dh)}
790 790 )
791 791 line['params'] = windows
792 792 self.data['lines'].append(line)
793 793 else:
794 794 self.data['lines'].append({'type':'none'})
795 795
796 796 #Add line 8 (synchro inverted)
797 797 self.data['lines'].append({'type':'sync', 'invert':1})
798 798
799 799 return
800 800
801 801 def parse_dat(self):
802 802 pass
803 803
804 804
805 805 def get_json(self, indent=None):
806 806 return json.dumps(self.data, indent=indent)
807 807
808 808
809 809 def pulses_to_bar(X):
810 810
811 811
812 812 d = X[1:]-X[:-1]
813 813
814 814 up = np.where(d==1)[0]
815 815 if X[0]==1:
816 816 up = np.concatenate((np.array([-1]), up))
817 817 up += 1
818 818
819 819 dw = np.where(d==-1)[0]
820 820 if X[-1]==1:
821 821 dw = np.concatenate((dw, np.array([len(X)-1])))
822 822 dw += 1
823 823
824 824 return [(tup[0], tup[1]-tup[0]) for tup in zip(up, dw)]
825 825
826 826
827 827 def pulses_from_code(ipp, ntx, codes, width, before=0):
828 828
829 829 if ntx>len(codes):
830 830 ipp_codes = [c for __ in xrange(ntx) for c in codes][:ntx]
831 831 else:
832 832 ipp_codes = codes[:ntx]
833 833
834 834 f = width/len(codes[0])
835 835
836 836 ipp_codes = [''.join([s*f for s in code]) for code in ipp_codes]
837 837
838 838 if before>0:
839 839 sbefore = '{0:0{1}d}'.format(0, before)
840 840 else:
841 841 sbefore = ''
842 842
843 843 temp = ['{0}{1}{2:0{3}d}'.format(sbefore, ipp_codes[i], 0, int(ipp)-len(ipp_codes[i])-before) for i in range(ntx)]
844 844
845 845 return (np.fromstring(''.join(temp), dtype=np.uint8)-48).astype(np.int8)
846 846
847 847
848 848 def create_mask(ranges, ipp, ntx, sync):
849 849
850 850 x = np.arange(ipp*ntx)
851 851 iranges = set()
852 852
853 853 for index in ranges:
854 854 if '-' in index:
855 855 args = [int(a) for a in index.split('-')]
856 856 iranges = iranges.union([i for i in range(args[0], args[1]+1)])
857 857 else:
858 858 iranges.add(int(index))
859 859
860 860 y = np.any([(x>=(idx-1)*ipp+sync) & (x<idx*ipp+sync) for idx in iranges], axis=0).astype(np.int8)
861 861
862 862 return y
863 863
864 864
865 865 def pulses(X, period, width, delay=0, before=0, after=0, sync=0, shift=0):
866 866
867 867 delay_array = delay
868 868
869 869 if isinstance(delay, (list, tuple)):
870 870 delay_array = np.ones(len(X))
871 871 delays = [d for __ in xrange(len(X)/(period*len(delay))) for d in delay]
872 872 for i, delay in enumerate(delays):
873 873 delay_array[np.arange(period*i, period*(i+1))] *= delay
874 874
875 875 if after>0:
876 876 width += after+before
877 877 before = 0
878 878
879 879 Y = ((X%period<width+delay_array+before+sync) & (X%period>=delay_array+before+sync)).astype(np.int8)
880 880
881 881 if shift>0:
882 882 y = np.empty_like(Y)
883 883 y[:shift] = 0
884 884 y[shift:] = Y[:-shift]
885 885 return y
886 886 else:
887 887 return Y
888 888
889 889
890 890 def plot_pulses(unit, maximun, lines):
891 891
892 892 from bokeh.resources import CDN
893 893 from bokeh.embed import components
894 894 from bokeh.mpl import to_bokeh
895 895 from bokeh.plotting import figure
896 896 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, PreviewSaveTool
897 897
898 898
899 899 N = len(lines)
900 900 fig = plt.figure(figsize=(10, 2+N*0.5))
901 901 ax = fig.add_subplot(111)
902 902 labels = []
903 903 data = []
904 904 for i, line in enumerate(lines):
905 905 print line
906 906 labels.append(line.get_name())
907 907 ax.broken_barh(pulses_to_bar(line.pulses_as_array()), (N-i-1, 0.5),
908 908 edgecolor='none', facecolor='#2c3e50')
909 909 #data.append(line.pulses_as_array())
910 910
911 911
912 912 #labels.append('{:3.2f} Km'.format(unit*100))
913 913 #ax.broken_barh(pulses_to_bar(pulses(np.arange(0, maximun), 200, 100)), (0, 0.5),
914 914 # edgecolor='none', facecolor='#ae3910')
915 915
916 916
917 917 #ax.pcolor(data, cmap=cm.Blues, vmin=0, vmax=1)
918 918
919 919 labels.reverse()
920 920 #plot = figure(x_range=[0, maximun], y_range=[0, N])
921 921 #plot.image(image=[np.logical_not(data).astype(np.int8)], x=[0], y=[0], dh=[N], dw=[maximun], palette='Blues9')
922 922 ax.set_yticklabels(labels)
923 923 plot = to_bokeh(fig, use_pandas=False)
924 924 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), PreviewSaveTool()]
925 925
926 926 return components(plot, CDN)
@@ -1,171 +1,410
1 1 '''
2 2 Created on Feb 15, 2016
3 3
4 4 @author: Miguel Urco
5 5 '''
6 6 import struct
7 import string
7 8
8 9 DDS_NBITS = 48
9 10
11 FILE_STRUCTURE = """Phase Adjust Register 1
12 -----------------------
13 00000000
14 00000000
15 -----------------------
16 Phase Adjust Register 2
17 -----------------------
18 00000000
19 00000000
20 -----------------------
21 Frequency Tuning Word 1
22 -----------------------
23 00000000
24 00000000
25 00000000
26 00000000
27 00000000
28 00000000
29 -----------------------
30 Frequency Tuning Word 2
31 -----------------------
32 00000000
33 00000000
34 00000000
35 00000000
36 00000000
37 00000000
38 -----------------------
39 Delta Frequency Word
40 -----------------------
41 00000000
42 00000000
43 00000000
44 00000000
45 00000000
46 00000000
47 -----------------------
48 Update Clock
49 -----------------------
50 00000000
51 00000000
52 00000000
53 00000000
54 -----------------------
55 Ramp Rate Clock
56 -----------------------
57 00000000
58 00000000
59 00000000
60 -----------------------
61 Control Register
62 -----------------------
63 00000000
64 00000000
65 00000000
66 00000000
67 -----------------------
68 Output Shaped Keying I
69 Multiplier
70 -----------------------
71 00000000
72 00000000
73 -----------------------
74 Output Shaped Keying Q
75 Multiplier
76 -----------------------
77 00000000
78 00000000
79 -----------------------
80 Output Shaped Keying
81 Ramp Rate
82 -----------------------
83 00000000
84 -----------------------
85 QDAC
86 -----------------------
87 00000000
88 00000000
89 -----------------------
90 CLOCK INPUT
91 -----------------------
92 10.00000000"""
93
10 94 def freq_to_binary(freq, mclock):
11 95
12 binary = (float(freq)/mclock)*(2**DDS_NBITS)
96 if not mclock:
97 return None
98
99 try:
100 binary = int((float(freq)/mclock)*(2**DDS_NBITS))
101 except:
102 return 0
13 103
14 104 return binary
15 105
16 106 def binary_to_freq(binary, mclock):
17 107
18 freq = (float(binary)/(2**DDS_NBITS))*mclock
108 if not mclock:
109 return None
110
111 try:
112 freq = (float(binary)/(2**DDS_NBITS))*mclock
113 except:
114 return 0
19 115
20 116 return freq
21 117
22 118 def phase_to_binary(phase):
23 119
24 binary = float(phase)*8192/180.0
120 try:
121 binary = int(float(phase)*8192/180.0)
122 except:
123 return 0
25 124
26 125 return binary
27 126
28 127 def binary_to_phase(binary):
29 128
30 phase = float(binary)*180.0/8192
129 try:
130 phase = float(binary)*180.0/8192
131 except:
132 return 0
31 133
32 134 return phase
33 135
34 def dds_str_to_dict(registers):
136 def __fill_dds_dict(parms):
137
138 my_dict = {'clock' : None,
139 'multiplier' : 1,
140 'frequencyA' : 0,
141 'frequencyB' : 0,
142 'frequencyA_Mhz' : 0,
143 'frequencyB_Mhz' : 0,
144 'phaseA_degress' : 0,
145 'phaseB_degress' : 0,
146 'modulation' : 0,
147 'amplitudeI' : 0,
148 'amplitudeQ' : 0,
149 'amplitude_enabled' : 0,
150 'delta_frequency' : 0,
151 'update_clock' : 0,
152 'ramp_rate_clock' : 0,
153 'amplitude_ramp_rate' : 0,
154 'qdac' : 0
155 }
156
157 my_dict.update(parms)
158 my_dict['phaseA'] = phase_to_binary(my_dict['phaseA_degrees'])
159 my_dict['phaseB'] = phase_to_binary(my_dict['phaseB_degrees'])
160
161 pll_range = 0
162 if my_dict['clock'] >= 200:
163 pll_range = 1
164
165 pll_bypass = 0
166 if my_dict['multiplier'] < 4:
167 pll_bypass = 1
168
169 control_register = (1 << 28) + \
170 (pll_range << 22) + (pll_bypass << 21) + \
171 (my_dict['multiplier'] << 16) + \
172 (my_dict['modulation'] << 9) + \
173 (my_dict['amplitude_enabled'] << 5)
174
175 my_dict['control_register'] = control_register
176
177 return my_dict
178
179 def dds_str_to_dict(registers, clock=None):
35 180
36 181 """
37 182 Output:
38 183 parms : Dictionary with keys
39 184 multiplier :
40 185 frequencyA :
41 186 frequencyB :
42 187 frequencyA_Mhz :
43 188 frequencyB_Mhz :
44 189 modulation :
45 190 phaseA_degrees :
46 191 phaseB_degrees :
47 192 amplitudeI :
48 193 amplitudeQ :
49 194
50 195 """
51 196
52 197 if not registers:
53 198 return {}
54 199
55 200 if len(registers) != 0x28:
56 201 return {}
57 202
58 203 phaseA = struct.unpack('>H', registers[0x0:0x2])[0]
59 204 phaseB = struct.unpack('>H', registers[0x2:0x4])[0]
60 205
61 206 frequencyA = struct.unpack('>Q', '\x00\x00' + registers[0x04:0x0A])[0]
62 207 frequencyB = struct.unpack('>Q', '\x00\x00' + registers[0x0A:0x10])[0]
63 208
64 209 delta_frequency = struct.unpack('>Q', '\x00\x00' + registers[0x10:0x16])[0]
65 210
66 211 update_clock = struct.unpack('>I', registers[0x16:0x1A])[0]
67 212
68 213 ramp_rate_clock = struct.unpack('>I', '\x00' + registers[0x1A:0x1D])[0]
69 214
70 215 control_register = struct.unpack('>I', registers[0x1D:0x21])[0]
71 216
72 217 amplitudeI = struct.unpack('>H', registers[0x21:0x23])[0]
73 218 amplitudeQ = struct.unpack('>H', registers[0x23:0x25])[0]
74 219
75 220 amp_ramp_rate = ord(registers[0x25])
76 221
77 222 qdac = struct.unpack('>H', registers[0x26:0x28])[0]
78 223
79 224 multiplier = (control_register & 0x001F0000) >> 16
80 225 modulation = (control_register & 0x00000E00) >> 9
81 226 amplitude_enabled = (control_register & 0x00000020) >> 5
82 227
83 parms = {'clock' : None,
228 frequencyA_Mhz = None
229 frequencyB_Mhz = None
230
231 if clock:
232 mclock = clock*multiplier
233 frequencyA_Mhz = binary_to_freq(frequencyA, mclock)
234 frequencyB_Mhz = binary_to_freq(frequencyB, mclock)
235
236 parms = {'clock' : clock,
84 237 'multiplier' : multiplier,
85 238 'frequencyA' : frequencyA,
86 239 'frequencyB' : frequencyB,
87 'frequencyA_Mhz' : None,
88 'frequencyB_Mhz' : None,
240 'frequencyA_Mhz' : frequencyA_Mhz,
241 'frequencyB_Mhz' : frequencyB_Mhz,
89 242 'phaseA' : phaseA,
90 243 'phaseB' : phaseB,
91 244 'phaseA_degrees' : binary_to_phase(phaseA),
92 245 'phaseB_degrees' : binary_to_phase(phaseB),
93 246 'modulation' : modulation,
94 247 'amplitudeI' : amplitudeI,
95 248 'amplitudeQ' : amplitudeQ,
96 249 'amplitude_enabled' : amplitude_enabled,
97 250 'delta_frequency' : delta_frequency,
98 251 'update_clock' : update_clock,
99 252 'ramp_rate_clock' : ramp_rate_clock,
100 253 'amp_ramp_rate' : amp_ramp_rate,
101 254 'qdac' : qdac
102 255 }
103 256
104 257 return parms
105 258
106 259 def dict_to_dds_str(parms):
107 260 """
108 261 Input:
109 262 parms : Dictionary with keys
110 263 multiplier : 4 to 20
111 264 frequencyA : 0 to (2**48-1) equivalent to: 0 - "Master clock"
112 265 frequencyB : 0 to (2**48-1) equivalent to: 0 - "Master clock"
113 266 modulation : 0 to 3
114 267 phaseA_degrees : 0 - 360 degrees
115 268 phaseB_degrees : 0 - 360 degrees
116 269 amplitudeI : 0 to (2**12-1) equivalent to: 0 - 100%
117 270 amplitudeQ : 0 to (2**12-1) equivalent to: 0 - 100%
118 271 """
119 272
120 my_dict = {'clock' : None,
121 'multiplier' : 1,
122 'frequencyA' : 0,
123 'frequencyB' : 0,
124 'frequencyA_Mhz' : 0,
125 'frequencyB_Mhz' : 0,
126 'phaseA_degress' : 0,
127 'phaseB_degress' : 0,
128 'modulation' : 0,
129 'amplitudeI' : 0,
130 'amplitudeQ' : 0,
131 'amplitude_enabled' : 0,
132 'delta_frequency' : 0,
133 'update_clock' : 0,
134 'ramp_rate_clock' : 0,
135 'amplitude_ramp_rate' : 0,
136 'qdac' : 0
137 }
138
139 print "PArms", parms
140
141 my_dict.update(parms)
142 my_dict['phaseA'] = phase_to_binary(my_dict['phaseA_degrees'])
143 my_dict['phaseB'] = phase_to_binary(my_dict['phaseB_degrees'])
273 my_dict = __fill_dds_dict(parms)
144 274
145 275 registers = ""
146 276
147 control_register = (my_dict['multiplier'] << 16) + (my_dict['modulation'] << 9) + (my_dict['amplitude_enabled'] << 5)
148
149 277 registers += struct.pack(">H", my_dict['phaseA'])
150 278 registers += struct.pack(">H", my_dict['phaseB'])
151 279
152 280 registers += struct.pack(">Q", my_dict['frequencyA'])[2:]
153 281 registers += struct.pack(">Q", my_dict['frequencyB'])[2:]
154 282
155 283 registers += struct.pack(">Q", my_dict['delta_frequency'])[2:]
156 284
157 285 registers += struct.pack(">I", my_dict['update_clock'])
158 286
159 287 registers += struct.pack(">I", my_dict['ramp_rate_clock'])[1:]
160 288
161 registers += struct.pack(">I", control_register)
289 registers += struct.pack(">I", my_dict['control_register'])
162 290
163 291 registers += struct.pack(">H", my_dict['amplitudeI'])
164 292
165 293 registers += struct.pack(">H", my_dict['amplitudeQ'])
166 294
167 295 registers += chr(my_dict['amplitude_ramp_rate'])
168 296
169 297 registers += struct.pack(">H", my_dict['qdac'])
170 298
171 return registers No newline at end of file
299 return registers
300
301 def text_to_dict(lines):
302
303 registers = ""
304 registers_v2 = []
305
306 for this_line in lines:
307 this_line = str.strip(this_line)
308
309 if str.isalpha(this_line):
310 continue
311
312 if not str.isdigit(this_line):
313 try:
314 value = float(this_line)
315 except:
316 continue
317
318 registers_v2.append(value)
319 continue
320
321 if len(this_line) != 8:
322 continue
323
324 registers += chr(string.atoi(this_line,2))
325
326 mclock = None
327 if len(registers_v2) > 0:
328 mclock = registers_v2[0]
329
330 my_dict = dds_str_to_dict(registers, mclock)
331
332 return my_dict
333
334 def dict_to_text(parms):
335 """
336 It creates formatted DDS text using dictionary values.
337 """
338 my_dict = __fill_dds_dict(parms)
339
340 lines = FILE_STRUCTURE.split('\n')
341
342 cad = '{0:016b}'.format(my_dict['phaseA'])
343 lines[2] = cad[0:8]
344 lines[3] = cad[8:16]
345
346 cad = '{0:016b}'.format(my_dict['phaseB'])
347 lines[7] = cad[0:8]
348 lines[8] = cad[8:16]
349
350 cad = '{0:048b}'.format(my_dict['frequencyA'])
351 lines[12] = cad[0:8]
352 lines[13] = cad[8:16]
353 lines[14] = cad[16:24]
354 lines[15] = cad[24:32]
355 lines[16] = cad[32:40]
356 lines[17] = cad[40:48]
357
358 cad = '{0:048b}'.format(my_dict['frequencyB'])
359 lines[21] = cad[0:8]
360 lines[22] = cad[8:16]
361 lines[23] = cad[16:24]
362 lines[24] = cad[24:32]
363 lines[25] = cad[32:40]
364 lines[26] = cad[40:48]
365
366 cad = '{0:048b}'.format(my_dict['delta_frequency'])
367 lines[30] = cad[0:8]
368 lines[31] = cad[8:16]
369 lines[32] = cad[16:24]
370 lines[33] = cad[24:32]
371 lines[34] = cad[32:40]
372 lines[35] = cad[40:48]
373
374 cad = '{0:032b}'.format(my_dict['update_clock'])
375 lines[39] = cad[0:8]
376 lines[40] = cad[8:16]
377 lines[41] = cad[16:24]
378 lines[42] = cad[24:32]
379
380 cad = '{0:024b}'.format(my_dict['ramp_rate_clock'])
381 lines[46] = cad[0:8]
382 lines[47] = cad[8:16]
383 lines[48] = cad[16:24]
384
385 cad = '{0:032b}'.format(my_dict['control_register'])
386 lines[52] = cad[0:8]
387 lines[53] = cad[8:16]
388 lines[54] = cad[16:24]
389 lines[55] = cad[24:32]
390
391 cad = '{0:016b}'.format(my_dict['amplitudeI'])
392 lines[60] = cad[0:8]
393 lines[61] = cad[8:16]
394
395 cad = '{0:016b}'.format(my_dict['amplitudeQ'])
396 lines[66] = cad[0:8]
397 lines[67] = cad[8:16]
398
399 cad = '{0:08b}'.format(my_dict['amplitude_ramp_rate'])
400 lines[72] = cad[0:8]
401
402 cad = '{0:016b}'.format(my_dict['qdac'])
403 lines[76] = cad[0:8]
404 lines[77] = cad[8:16]
405
406 lines[81] = '%10.8f' %my_dict['clock']
407
408 text = '\n'.join(lines)
409
410 return text No newline at end of file
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now