##// END OF EJS Templates
- Update rc app...
Juan C. Espinoza -
r79:46ff8f6d35d9
parent child
Show More
@@ -0,0 +1,9
1 [
2 {"fields": {"name": "JRO", "description": ""}, "model": "main.location", "pk": 1},
3 {"fields": {"name": "JASMET", "description": ""}, "model": "main.location", "pk": 2},
4 {"fields": {"name": "SOUSY", "description": ""}, "model": "main.location", "pk": 3},
5 {"fields": {"name": "rc", "description": ""}, "model": "main.devicetype", "pk": 1},
6 {"fields": {"name": "dds", "description": ""}, "model": "main.devicetype", "pk": 2},
7 {"fields": {"name": "cgs", "description": ""}, "model": "main.devicetype", "pk": 3},
8 {"fields": {"name": "jars", "description": ""}, "model": "main.devicetype", "pk": 4}
9 ]
@@ -0,0 +1,26
1 [{"fields": {"number_of_codes": 0, "codes": "[]", "name": "None", "bits_per_code": 0}, "model": "rc.rclinecode", "pk": 1},
2 {"fields": {"number_of_codes": 2, "codes": "[u'11101101', u'11100010']", "name": "COMPLEMENTARY_CODE_8", "bits_per_code": 8}, "model": "rc.rclinecode", "pk": 2},
3 {"fields": {"number_of_codes": 1, "codes": "[u'1101101001000100010001111000']", "name": "BINARY_CODE_28", "bits_per_code": 28}, "model": "rc.rclinecode", "pk": 3},
4 {"fields": {"number_of_codes": 2, "codes": "[u'11', u'10']", "name": "COMPLEMENTARY_CODE_2", "bits_per_code": 2}, "model": "rc.rclinecode", "pk": 4},
5 {"fields": {"number_of_codes": 2, "codes": "[u'1110110111100010111011010001110111101101111000100001001011100010', u'1110110111100010111011010001110100010010000111011110110100011101']", "name": "COMPLEMENTARY_CODE_64", "bits_per_code": 64}, "model": "rc.rclinecode", "pk": 5},
6 {"fields": {"number_of_codes": 1, "codes": "[u'11100010010']", "name": "BARKER11", "bits_per_code": 11}, "model": "rc.rclinecode", "pk": 6},
7 {"fields": {"number_of_codes": 2, "codes": "[u'1111100110101' ]", "name": "BARKER13", "bits_per_code": 13}, "model": "rc.rclinecode", "pk": 7},
8 {"fields": {"number_of_codes": 2, "codes": "[u'1101101001000100010001111000', u'0010010110111011101110000111']", "name": "BINARY_CODE_28_FLIP", "bits_per_code": 28}, "model": "rc.rclinecode", "pk": 8},
9 {"fields": {"number_of_codes": 2, "codes": "[u'11101101111000101110110100011101', u'11101101111000100001001011100010']", "name": "COMPLEMENTARY_CODE_32", "bits_per_code": 32}, "model": "rc.rclinecode", "pk": 9},
10 {"fields": {"number_of_codes": 128, "codes": "[u'1111000100100101', u'1011001010010111', u'1101001000100000', u'1001000110010010', u'1110001001111011', u'1010000111001001', u'1100000101111110', u'1000001011001100', u'1111101001010110', u'1011100111100100', u'1101100101010011', u'1001101011100001', u'1110100100001000', u'1010101010111010', u'1100101000001101', u'1000100110111111', u'1111010010011100', u'1011011100101110', u'1101011110011001', u'1001010000101011', u'1110011111000010', u'1010010001110000', u'1100010011000111', u'1000011101110101', u'1111111111101111', u'1011110001011101', u'1101110011101010', u'1001111101011000', u'1110110010110001', u'1010111100000011', u'1100111110110100', u'1000110000000110', u'0011111000000011', u'0111110110110001', u'0001110100000110', u'0101111010110100', u'0010110101011101', u'0110111011101111', u'0000111001011000', u'0100110111101010', u'0011010101110000', u'0111011011000010', u'0001011001110101', u'0101010111000111', u'0010011000101110', u'0110010110011100', u'0000010100101011', u'0100011010011001', u'0011101110111010', u'0111100000001000', u'0001100010111111', u'0101101100001101', u'0010100011100100', u'0110101101010110', u'0000101111100001', u'0100100001010011', u'0011000011001001', u'0111001101111011', u'0001001111001100', u'0101000001111110', u'0010001110010111', u'0110000000100101', u'0000000010010010', u'0100001100100000', u'1010110011001110', u'1110111101111100', u'1000111111001011', u'1100110001111001', u'1011111110010000', u'1111110000100010', u'1001110010010101', u'1101111100100111', u'1010011110111101', u'1110010000001111', u'1000010010111000', u'1100011100001010', u'1011010011100011', u'1111011101010001', u'1001011111100110', u'1101010001010100', u'1010100101110111', u'1110101011000101', u'1000101001110010', u'1100100111000000', u'1011101000101001', u'1111100110011011', u'1001100100101100', u'1101101010011110', u'1010001000000100', u'1110000110110110', u'1000000100000001', u'1100001010110011', u'1011000101011010', u'1111001011101000', u'1001001001011111', u'1101000111101101', u'1100100111000110', u'1000101001110100', u'1110101011000011', u'1010100101110001', u'1101101010011000', u'1001100100101010', u'1111100110011101', u'1011101000101111', u'1100001010110101', u'1000000100000111', u'1110000110110000', u'1010001000000010', u'1101000111101011', u'1001001001011001', u'1111001011101110', u'1011000101011100', u'1100110001111111', u'1000111111001101', u'1110111101111010', u'1010110011001000', u'1101111100100001', u'1001110010010011', u'1111110000100100', u'1011111110010110', u'1100011100001100', u'1000010010111110', u'1110010000001001', u'1010011110111011', u'1101010001010010', u'1001011111100000', u'1111011101010111', u'1011010011100101']", "name": "AC128", "bits_per_code": 16}, "model": "rc.rclinecode", "pk": 10},
11 {"fields": {"number_of_codes": 2, "codes": "[u'11101101111000101110110100011101111011011110001000010010111000101110110111100010111011010001110100010010000111011110110100011101', u'11101101111000101110110100011101111011011110001000010010111000100001001000011101000100101110001011101101111000100001001011100010']", "name": "COMPLEMENTARY_CODE_128", "bits_per_code": 128}, "model": "rc.rclinecode", "pk": 11},
12 {"fields": {"number_of_codes": 2, "codes": "[u'1110110111100010', u'1110110100011101']", "name": "COMPLEMENTARY_CODE_16", "bits_per_code": 16}, "model": "rc.rclinecode", "pk": 12},
13 {"fields": {"number_of_codes": 1, "codes": "[u'11']", "name": "BARKER2", "bits_per_code": 2}, "model": "rc.rclinecode", "pk": 13},
14 {"fields": {"number_of_codes": 1, "codes": "[u'110']", "name": "BARKER3", "bits_per_code": 3}, "model": "rc.rclinecode", "pk": 14},
15 {"fields": {"number_of_codes": 2, "codes": "[u'1110', u'1101']", "name": "COMPLEMENTARY_CODE_4", "bits_per_code": 4}, "model": "rc.rclinecode", "pk": 15},
16 {"fields": {"number_of_codes": 1, "codes": "[u'1110010']", "name": "BARKER7", "bits_per_code": 7}, "model": "rc.rclinecode", "pk": 16},
17 {"fields": {"number_of_codes": 1, "codes": "[u'1101']", "name": "BARKER4", "bits_per_code": 4}, "model": "rc.rclinecode", "pk": 17},
18 {"fields": {"number_of_codes": 1, "codes": "[u'11101']", "name": "BARKER5", "bits_per_code": 5}, "model": "rc.rclinecode", "pk": 18},
19 {"fields": {"params": "{\"TX_ref\": {\"model\": \"RCLine\", \"value\": \"\"}, \"range\": { \"value\": 0, \"help\": \"Frame numbers or frame ranges separated by commas, use 0 for all frames eg: 1,2,10-15\"}}", "name": "tr", "description": ""}, "model": "rc.rclinetype", "pk": 1},
20 {"fields": {"params": "{\"pulse_width\":{\"value\": 0, \"widget\":\"dc\"},\r\n \"delays\":{\"value\": \"\", \"widget\":\"km\", \"help\": \"Delay entries separated by commas (TAUs)\"},\r\n \"range\":{\"value\": 0, \"help\": \"Frame numbers or frame ranges separated by commas, use 0 for all frames eg: 1,2,10-15\"}}", "name": "tx", "description": ""}, "model": "rc.rclinetype", "pk": 2},
21 {"fields": {"params": "{\"TX_ref\": {\"model\": \"RCLine\", \"value\": \"\"}, \"code\": {\"model\":\"RCLineCode\",\"value\": \"\"}, \"codes\":{\"value\":\"\", \"widget\":\"codes\"}}", "name": "codes", "description": ""}, "model": "rc.rclinetype", "pk": 3},
22 {"fields": {"params": "{ \"TX_ref\":{\"model\": \"RCLine\", \"value\": \"\"}, \"params\": {\"first_height\":{ \"value\": 0, \"widget\":\"km\"},\"resolution\": {\"value\": 0, \"widget\":\"km\"}, \"number_of_samples\": { \"value\": 0, \"help\":\"number of samples (NSA)\"}}}", "name": "windows", "description": ""}, "model": "rc.rclinetype", "pk": 4},
23 {"fields": {"params": "{\"invert\":{\"value\": 0, \"help\": \"Set to 1 for synchro pulse at the end\"}}", "name": "sync", "description": ""}, "model": "rc.rclinetype", "pk": 5},
24 {"fields": {"params": "{ \"periodic\": { \"value\": 0, \"help\": \"Set to 1 for IPP periodic\"}, \"params\": {\"begin\": { \"value\": 0, \"widget\":\"unit\"}, \"end\": {\"value\": 0, \"widget\":\"unit\"}}}", "name": "prog_pulses", "description": ""}, "model": "rc.rclinetype", "pk": 6},
25 {"fields": {"params": "{\"number_of_flips\": {\"value\": 0}}", "name": "flip", "description": ""}, "model": "rc.rclinetype", "pk": 7},
26 {"fields": {"params": "{}", "name": "none", "description": ""}, "model": "rc.rclinetype", "pk": 8}]
@@ -0,0 +1,71
1 var km_fields = [];
2 var unit_fields = [];
3 var dc_fields = [];
4
5
6 function str2hz(s){
7
8 return 150000*Math.pow(parseFloat(s), -1);
9 }
10
11
12 function str2unit(s){
13 var km2unit = (20/3)*(parseFloat($('#id_clock_in').val())/parseFloat($('#id_clock_divider').val()));
14 var ret = "";
15 values = s.split(",");
16 for (i=0; i<values.length; i++) {
17 ret += parseFloat(values[i])*km2unit;
18 ret += ",";
19 }
20 return ret.substring(0, ret.length-1);
21 }
22
23
24 function str2km(s){
25 var km2unit = (20/3)*(parseFloat($('#id_clock_in').val())/parseFloat($('#id_clock_divider').val()));
26 var ret = "";
27 values = s.split(",");
28 for (i=0; i<values.length; i++) {
29 ret += parseFloat(values[i])/km2unit;
30 ret += ",";
31 }
32 return ret.substring(0, ret.length-1);
33 }
34
35 function str2dc(s){
36
37 return parseFloat(s)*100/parseFloat($('#id_ipp').val())
38 }
39
40
41 function updateUnits() {
42
43 for (j=0; j<km_fields.length; j++){
44 label_unit = "#"+km_fields[j]+"_unit";
45 label = "#"+km_fields[j];
46 $(label_unit).val(str2unit($(label).val()));
47 }
48 }
49
50
51 function updateDc() {
52
53 for (j=0; j<dc_fields.length; j++){
54 label_dc = "#"+dc_fields[j]+"_dc";
55 label = "#"+dc_fields[j];
56 $(label_dc).val(str2dc($(label).val()));
57 }
58 }
59
60
61
62 $("#id_clock_in").change(function() {
63 $("#id_clock").val(parseFloat($('#id_clock_in').val())/parseFloat($('#id_clock_divider').val()));
64 updateUnits();
65 });
66
67 $("#id_clock_divider").change(function() {
68 $("#id_clock").val(parseFloat($('#id_clock_in').val())/parseFloat($('#id_clock_divider').val()));
69 updateUnits();
70 });
71
@@ -0,0 +1,63
1 {% extends "dev_conf_edit.html" %}
2
3 {% block extra-js%}
4
5 <script type="text/javascript">
6
7 $("#bt_Flip").click(function() {
8
9 var codes = $("#id_codes").val().split("\n");
10
11 if (codes.length>0) {
12 var mask = (Math.pow(2, codes[codes.length-1].length)-1)
13 var code = ~parseInt(codes[codes.length-1], 2) >>> 0;
14 codes[codes.length-1] = (code).toString(2);
15 //codes[codes.length-1] = mask.toString(2);
16
17 $("#id_codes").val(codes.join("\n"));
18 }
19
20 });
21
22 $("#id_code").change(function() {
23 var url = "{% url 'url_edit_rc_codes' dev_conf.id line.id %}";
24 document.location = url+ $(this).val() + "/";
25 });
26
27 $("#id_bits_per_code").change(function() {
28
29 var codes = $("#id_codes").val().split("\n");
30
31 for (i=0; i<codes.length; i++){
32 if (codes[i].length>$(this).val()){
33 codes[i] = codes[i].substr(0, parseInt($(this).val()));
34 }else{
35 codes[i] = codes[i]+Array(parseInt($(this).val())-codes[i].length+1).join("0");
36 }
37 }
38
39 $("#id_codes").val(codes.join("\n"));
40
41 });
42
43 $("#id_number_of_codes").change(function() {
44
45 var codes = $("#id_codes").val().split("\n");
46
47 if (codes.length>$(this).val()){
48 codes = codes.slice(0, $(this).val())
49 }else{
50 n = parseInt($(this).val())-codes.length;
51 while (n>0){
52 codes.splice(codes.length, 0, codes[0]);
53 n--;
54 }
55 }
56
57 $("#id_codes").val(codes.join("\n"));
58
59 });
60
61
62 </script>
63 {% endblock %} No newline at end of file
@@ -0,0 +1,245
1
2 import ast
3 import json
4
5 from django import forms
6 from django.utils.safestring import mark_safe
7
8
9 class KmUnitWidget(forms.widgets.TextInput):
10
11 def render(self, label, value, attrs=None):
12
13 if isinstance(value, (int, float)):
14 unit = int(value*attrs['km2unit'])
15 elif isinstance(value, basestring):
16 units = []
17 values = [s for s in value.split(',') if s]
18 for val in values:
19 units.append('{0:.0f}'.format(float(val)*attrs['km2unit']))
20
21 unit = ','.join(units)
22
23 disabled = 'disabled' if attrs.get('disabled', False) else ''
24 name = attrs.get('name', label)
25
26 if 'line' in attrs:
27 label += '_{0}'.format(attrs['line'].pk)
28
29 html = '<div class="col-md-12 col-no-padding"><div class="col-md-5 col-no-padding"><input type="text" {0} class="form-control" id="id_{1}" name="{2}" value="{3}"></div><div class="col-md-1 col-no-padding">Km</div><div class="col-md-5 col-no-padding"><input type="text" {4} class="form-control" id="id_{5}_unit" value="{6}"></div><div class="col-md-1 col-no-padding">Units</div></div>'.format(disabled, label, name, value, disabled, label, unit)
30
31 script = '''<script type="text/javascript">
32 $(document).ready(function () {{
33
34 km_fields.push("id_{label}");
35 unit_fields.push("id_{label}_unit");
36
37 $("#id_{label}").change(function() {{
38 $("#id_{label}_unit").val(Math.round(str2unit($(this).val())));
39 $("#id_{label}").val(str2km($("#id_{label}_unit").val()));
40 }});
41 $("#id_{label}_unit").change(function() {{
42 $(this).val(Math.round(parseFloat($(this).val())));
43 $("#id_{label}").val(str2km($(this).val()));
44 }});
45 }});
46 </script>'''.format(label=label)
47
48 if disabled:
49 return mark_safe(html)
50 else:
51 return mark_safe(html+script)
52
53
54 class UnitKmWidget(forms.widgets.TextInput):
55
56 def render(self, label, value, attrs=None):
57
58 if isinstance(value, (int, float)):
59 km = value/attrs['km2unit']
60 elif isinstance(value, basestring):
61 kms = []
62 values = [s for s in value.split(',') if s]
63 for val in values:
64 kms.append('{0:.0f}'.format(float(val)/attrs['km2unit']))
65
66 km = ','.join(kms)
67
68 disabled = 'disabled' if attrs.get('disabled', False) else ''
69 name = attrs.get('name', label)
70
71 if 'line' in attrs:
72 label += '_{0}'.format(attrs['line'].pk)
73
74 html = '''<div class="col-md-12 col-no-padding">
75 <div class="col-md-5 col-no-padding"><input type="number" {0} class="form-control" id="id_{1}_unit" name="{2}" value="{3}"></div>
76 <div class="col-md-1 col-no-padding">Units</div>
77 <div class="col-md-5 col-no-padding"><input type="number" {4} class="form-control" id="id_{5}" value="{6}"></div>
78 <div class="col-md-1 col-no-padding">Km</div></div>'''.format(disabled, label, name, value, disabled, label, km)
79
80 script = '''<script type="text/javascript">
81 $(document).ready(function () {{
82
83 km_fields.push("id_{label}");
84 unit_fields.push("id_{label}_unit");
85
86 $("#id_{label}").change(function() {{
87 $("#id_{label}_unit").val(str2unit($(this).val()));
88 }});
89 $("#id_{label}_unit").change(function() {{
90 $("#id_{label}").val(str2km($(this).val()));
91 }});
92 }});
93 </script>'''.format(label=label)
94
95 if disabled:
96 return mark_safe(html)
97 else:
98 return mark_safe(html+script)
99
100
101 class KmUnitHzWidget(forms.widgets.TextInput):
102
103 def render(self, label, value, attrs=None):
104
105 unit = float(value)*attrs['km2unit']
106 if unit%10==0:
107 unit = int(unit)
108 hz = 150000*float(value)**-1
109
110 disabled = 'disabled' if attrs.get('disabled', False) else ''
111 name = attrs.get('name', label)
112
113 if 'line' in attrs:
114 label += '_{0}'.format(attrs['line'].pk)
115
116 html = '''<div class="col-md-12 col-no-padding">
117 <div class="col-md-3 col-no-padding"><input type="number" {0} class="form-control" id="id_{1}" name="{2}" value="{3}"></div>
118 <div class="col-md-1 col-no-padding">Km</div>
119 <div class="col-md-3 col-no-padding"><input type="number" {4} class="form-control" id="id_{1}_unit" value="{5}"></div>
120 <div class="col-md-1 col-no-padding">Units</div>
121 <div class="col-md-3 col-no-padding"><input type="number" {4} class="form-control" id="id_{1}_hz" value="{6}"></div>
122 <div class="col-md-1 col-no-padding">Hz</div>
123 </div>'''.format(disabled, label, name, value, disabled, unit, hz)
124
125 script = '''<script type="text/javascript">
126 $(document).ready(function () {{
127 km_fields.push("id_{label}");
128 unit_fields.push("id_{label}_unit");
129 $("#id_{label}").change(function() {{
130 $("#id_{label}_unit").val(str2unit($(this).val()));
131 $("#id_{label}_hz").val(str2hz($(this).val()));
132 updateDc();
133 }});
134 $("#id_{label}_unit").change(function() {{
135 $(this).val(Math.round(parseFloat($(this).val())/10)*10);
136 $("#id_{label}").val(str2km($(this).val()));
137 $("#id_{label}_hz").val(str2hz($("#id_{label}").val()));
138 updateDc();
139 }});
140 $("#id_{label}_hz").change(function() {{
141 $("#id_{label}").val(str2hz($(this).val()));
142 $("#id_{label}_unit").val(str2unit($("#id_{label}").val()));
143 updateDc();
144 }});
145 }});
146 </script>'''.format(label=label)
147
148 if disabled:
149 return mark_safe(html)
150 else:
151 return mark_safe(html+script)
152
153
154 class KmUnitDcWidget(forms.widgets.TextInput):
155
156 def render(self, label, value, attrs=None):
157
158 unit = int(float(value)*attrs['km2unit'])
159
160 disabled = 'disabled' if attrs.get('disabled', False) else ''
161 name = attrs.get('name', label)
162
163 label += '_{0}'.format(attrs['line'].pk)
164
165 dc = float(json.loads(attrs['line'].params)['pulse_width'])*attrs['line'].rc_configuration.ipp/100
166
167 html = '''<div class="col-md-12 col-no-padding">
168 <div class="col-md-3 col-no-padding"><input type="number" {0} class="form-control" id="id_{1}" name="{2}" value="{3}"></div>
169 <div class="col-md-1 col-no-padding">Km</div>
170 <div class="col-md-3 col-no-padding"><input type="number" {4} class="form-control" id="id_{1}_unit" value="{5}"></div>
171 <div class="col-md-1 col-no-padding">Units</div>
172 <div class="col-md-3 col-no-padding"><input type="number" {4} class="form-control" id="id_{1}_dc" value="{6}"></div>
173 <div class="col-md-1 col-no-padding">DC[%]</div>
174 </div>'''.format(disabled, label, name, value, disabled, unit, dc)
175
176 script = '''<script type="text/javascript">
177 $(document).ready(function () {{
178 km_fields.push("id_{label}");
179 unit_fields.push("id_{label}_unit");
180 dc_fields.push("id_{label}");
181 $("#id_{label}").change(function() {{
182 $("#id_{label}_unit").val(str2unit($(this).val()));
183 $("#id_{label}_dc").val(str2dc($("#id_{label}").val()));
184 }});
185 $("#id_{label}_unit").change(function() {{
186 $("#id_{label}").val(str2km($(this).val()));
187 $("#id_{label}_dc").val(str2dc($("#id_{label}").val()));
188 }});
189
190 $("#id_{label}_dc").change(function() {{
191 $("#id_{label}").val(parseFloat($(this).val())*parseFloat($("#id_ipp").val())/100);
192 $("#id_{label}_unit").val(str2unit($("#id_{label}").val()));
193 }});
194 }});
195 </script>'''.format(label=label)
196
197 if disabled:
198 return mark_safe(html)
199 else:
200 return mark_safe(html+script)
201
202
203 class DefaultWidget(forms.widgets.TextInput):
204
205 def render(self, label, value, attrs=None):
206
207 disabled = 'disabled' if attrs.get('disabled', False) else ''
208 name = attrs.get('name', label)
209
210 html = '<div class="col-md-12 col-no-padding"><div class="col-md-5 col-no-padding"><input {0} type="text" class="form-control" id="id_{1}" name="{2}" value="{3}"></div></div>'.format(disabled, label, name, value)
211
212 return mark_safe(html)
213
214
215 class HiddenWidget(forms.widgets.HiddenInput):
216
217 def render(self, label, value, attrs=None):
218
219 disabled = 'disabled' if attrs.get('disabled', False) else ''
220 name = self.attrs.get('name', label)
221
222 html = '<input {0} type="hidden" class="form-control" id="id_{1}" name="{2}" value="{3}">'.format(disabled, label, name, value)
223
224 return mark_safe(html)
225
226
227 class CodesWidget(forms.widgets.Textarea):
228
229 def render(self, label, value, attrs=None):
230
231 disabled = 'disabled' if attrs.get('disabled', False) else ''
232 name = attrs.get('name', label)
233
234 if '[' in value:
235 value = ast.literal_eval(value)
236
237 if isinstance(value, list):
238 codes = '\r\n'.join(value)
239 else:
240 codes = value
241
242 html = '<textarea rows="5" {0} class="form-control" id="id_{1}" name="{2}" style="white-space:nowrap; overflow:scroll;">{3}</textarea>'.format(disabled, label, name, codes)
243
244 return mark_safe(html)
245 No newline at end of file
@@ -1,126 +1,127
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 6 FILE_FORMAT = (
7 7 ('json', 'json'),
8 8 )
9 9
10 10 DDS_FILE_FORMAT = (
11 11 ('json', 'json'),
12 12 ('text', 'dds')
13 13 )
14 14
15 15 RC_FILE_FORMAT = (
16 16 ('json', 'json'),
17 ('text', 'rc')
17 ('text', 'racp'),
18 ('binary', 'dat'),
18 19 )
19 20
20 21 def add_empty_choice(choices, pos=0, label='-----'):
21 22 if len(choices)>0:
22 23 choices = list(choices)
23 24 choices.insert(0, (0, label))
24 25 return choices
25 26 else:
26 27 return [(0, label)]
27 28
28 29 class DatepickerWidget(forms.widgets.TextInput):
29 30 def render(self, name, value, attrs=None):
30 31 input_html = super(DatepickerWidget, self).render(name, value, attrs)
31 32 html = '<div class="input-group date">'+input_html+'<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span></div>'
32 33 return mark_safe(html)
33 34
34 35 class TimepickerWidget(forms.widgets.TextInput):
35 36 def render(self, name, value, attrs=None):
36 37 input_html = super(TimepickerWidget, self).render(name, value, attrs)
37 38 html = '<div class="input-group time">'+input_html+'<span class="input-group-addon"><i class="glyphicon glyphicon-time"></i></span></div>'
38 39 return mark_safe(html)
39 40
40 41 class CampaignForm(forms.ModelForm):
41 42 def __init__(self, *args, **kwargs):
42 43 super(CampaignForm, self).__init__(*args, **kwargs)
43 44 self.fields['start_date'].widget = DatepickerWidget(self.fields['start_date'].widget.attrs)
44 45 self.fields['end_date'].widget = DatepickerWidget(self.fields['end_date'].widget.attrs)
45 46
46 47 class Meta:
47 48 model = Campaign
48 49 exclude = ['']
49 50
50 51 class ExperimentForm(forms.ModelForm):
51 52
52 53 def __init__(self, *args, **kwargs):
53 54 super(ExperimentForm, self).__init__(*args, **kwargs)
54 55 self.fields['start_time'].widget = TimepickerWidget(self.fields['start_time'].widget.attrs)
55 56 self.fields['end_time'].widget = TimepickerWidget(self.fields['end_time'].widget.attrs)
56 57
57 58 self.fields['campaign'].widget.attrs['readonly'] = True
58 59
59 60 class Meta:
60 61 model = Experiment
61 62 exclude = ['']
62 63
63 64 class LocationForm(forms.ModelForm):
64 65 class Meta:
65 66 model = Location
66 67 exclude = ['']
67 68
68 69 class DeviceForm(forms.ModelForm):
69 70 class Meta:
70 71 model = Device
71 72 exclude = ['status']
72 73
73 74 class ConfigurationForm(forms.ModelForm):
74 75 class Meta:
75 76 model = Configuration
76 77 exclude = ['type', 'created_date', 'programmed_date', 'parameters']
77 78
78 79 class DeviceTypeForm(forms.Form):
79 80 device_type = forms.ChoiceField(choices=add_empty_choice(DeviceType.objects.all().order_by('name').values_list('id', 'name')))
80 81
81 82
82 83 class UploadFileForm(forms.Form):
83 84
84 85 file = forms.FileField()
85 86
86 87 class DownloadFileForm(forms.Form):
87 88
88 89 format = forms.ChoiceField(choices= ((0, 'json'),) )
89 90
90 91 def __init__(self, device_type, *args, **kwargs):
91 92
92 93 super(DownloadFileForm, self).__init__(*args, **kwargs)
93 94
94 95 self.fields['format'].choices = FILE_FORMAT
95 96
96 97 if device_type == 'dds':
97 98 self.fields['format'].choices = DDS_FILE_FORMAT
98 99
99 100 if device_type == 'rc':
100 101 self.fields['format'].choices = RC_FILE_FORMAT
101 102
102 103 class OperationForm(forms.Form):
103 104 # today = datetime.today()
104 105 # -----Campaigns from this month------[:5]
105 106 campaign = forms.ChoiceField(label="Campaign")
106 107
107 108 def __init__(self, *args, **kwargs):
108 109
109 110 if 'length' not in kwargs.keys():
110 111 length = None
111 112 else:
112 113 length = kwargs['length']
113 114
114 115 kwargs.pop('length')
115 116
116 117 super(OperationForm, self).__init__(*args, **kwargs)
117 118 self.fields['campaign'].choices=Campaign.objects.all().order_by('-start_date').values_list('id', 'name')[:length]
118 119
119 120 class OperationSearchForm(forms.Form):
120 121 # -----ALL Campaigns------
121 122 campaign = forms.ChoiceField(label="Campaign")
122 123
123 124 def __init__(self, *args, **kwargs):
124 125 super(OperationSearchForm, self).__init__(*args, **kwargs)
125 126 self.fields['campaign'].choices=Campaign.objects.all().order_by('-start_date').values_list('id', 'name')
126 127 No newline at end of file
@@ -1,308 +1,314
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 (2, 'Running'),
10 10 )
11 11
12 12 EXP_STATES = (
13 13 (0,'Error'), #RED
14 14 (1,'Configurated'), #BLUE
15 15 (2,'Running'), #GREEN
16 16 (3,'Waiting'), #YELLOW
17 17 (4,'Nothing'), #WHITE
18 18 )
19 19
20 20 CONF_TYPES = (
21 21 (0, 'Active'),
22 22 (1, 'Historical'),
23 23 )
24 24
25 25 DEV_STATES = (
26 26 (0, 'No connected'),
27 27 (1, 'Connected'),
28 28 (2, 'Configured'),
29 29 (3, 'Running'),
30 30 )
31 31
32 32 DEV_TYPES = (
33 33 ('', 'Select a device type'),
34 34 ('rc', 'Radar Controller'),
35 35 ('dds', 'Direct Digital Synthesizer'),
36 36 ('jars', 'Jicamarca Radar Acquisition System'),
37 37 ('usrp', 'Universal Software Radio Peripheral'),
38 38 ('cgs', 'Clock Generator System'),
39 39 ('abs', 'Automatic Beam Switching'),
40 40 )
41 41
42 42 DEV_PORTS = {
43 43 'rc' : 2000,
44 44 'dds' : 2000,
45 45 'jars' : 2000,
46 46 'usrp' : 2000,
47 47 'cgs' : 8080,
48 48 'abs' : 8080
49 49 }
50 50
51 51 RADAR_STATES = (
52 52 (0, 'No connected'),
53 53 (1, 'Connnected'),
54 54 (2, 'Configured'),
55 55 (3, 'Running'),
56 56 (4, 'Scheduled'),
57 57 )
58 58 # Create your models here.
59 59
60 60
61 61 class Location(models.Model):
62 62
63 63 name = models.CharField(max_length = 30)
64 64 description = models.TextField(blank=True, null=True)
65 65
66 66 class Meta:
67 67 db_table = 'db_location'
68 68
69 69 def __unicode__(self):
70 70 return u'%s' % self.name
71 71
72 72 class DeviceType(models.Model):
73 73
74 74 name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'rc')
75 75 description = models.TextField(blank=True, null=True)
76 76
77 77 class Meta:
78 78 db_table = 'db_device_types'
79 79
80 80 def __unicode__(self):
81 81 return u'%s' % self.get_name_display()
82 82
83 83 class Device(models.Model):
84 84
85 85 device_type = models.ForeignKey(DeviceType, on_delete=models.CASCADE)
86 86 location = models.ForeignKey(Location, on_delete=models.CASCADE)
87 87
88 88 name = models.CharField(max_length=40, default='')
89 89 ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
90 90 port_address = models.PositiveSmallIntegerField(default=2000)
91 91 description = models.TextField(blank=True, null=True)
92 92 status = models.PositiveSmallIntegerField(default=0, choices=DEV_STATES)
93 93
94 94 class Meta:
95 95 db_table = 'db_devices'
96 96
97 97 def __unicode__(self):
98 98 return u'%s | %s' % (self.name, self.ip_address)
99 99
100 100 def get_status(self):
101 101
102 102 return self.status
103 103
104 104
105 105 class Campaign(models.Model):
106 106
107 107 template = models.BooleanField(default=False)
108 108
109 109 name = models.CharField(max_length=40, unique=True)
110 110 start_date = models.DateTimeField(blank=True, null=True)
111 111 end_date = models.DateTimeField(blank=True, null=True)
112 112 tags = models.CharField(max_length=40)
113 113 description = models.TextField(blank=True, null=True)
114 114
115 115 class Meta:
116 116 db_table = 'db_campaigns'
117 117
118 118 def __unicode__(self):
119 119 return u'%s' % (self.name)
120 120
121 121 # class Radar(models.Model):
122 122 #
123 123 # # name = models.CharField(max_length = 30)
124 124 # experiment = models.ForeignKey('Experiment', on_delete=models.CASCADE)
125 125 # location = models.OneToOneField('Location', on_delete=models.CASCADE)
126 126 # status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
127 127 #
128 128 # class Meta:
129 129 # db_table = 'db_radar'
130 130 #
131 131 # def __unicode__(self):
132 132 # return u'%s' % self.location
133 133
134 134 #class RunningExperiment(models.Model):
135 135 # radar = models.OneToOneField('Location', on_delete=models.CASCADE)
136 136 # running_experiment = models.OneToOneField('Experiment', on_delete=models.CASCADE)
137 137 # status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
138 138
139 139
140 140 class Experiment(models.Model):
141 141
142 142 template = models.BooleanField(default=False)
143 143
144 144 campaign = models.ForeignKey('Campaign', null=True, blank=True, on_delete=models.CASCADE)
145 145 location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
146 146
147 147 name = models.CharField(max_length=40, default='')
148 148 start_time = models.TimeField(default='00:00:00')
149 149 end_time = models.TimeField(default='23:59:59')
150 150
151 151 class Meta:
152 152 db_table = 'db_experiments'
153 153
154 154 def __unicode__(self):
155 155 return u'%s' % (self.name)
156 156
157 157 class Configuration(PolymorphicModel):
158 158
159 159 template = models.BooleanField(default=False)
160 160
161 161 name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
162 162
163 163 experiment = models.ForeignKey('Experiment', null=True, blank=True, on_delete=models.CASCADE)
164 164 device = models.ForeignKey(Device, on_delete=models.CASCADE)
165 165
166 166 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
167 167
168 168 created_date = models.DateTimeField(auto_now_add=True)
169 169 programmed_date = models.DateTimeField(auto_now=True)
170 170
171 171 parameters = models.TextField(default='{}')
172 172
173 173 message = ""
174 174
175 175 class Meta:
176 176 db_table = 'db_configurations'
177 177
178 178 def __unicode__(self):
179 return u'[%s, %s]: %s' % (self.experiment.name,
180 self.device.name,
181 self.name)
179
180 if self.experiment:
181 return u'[%s, %s]: %s' % (self.experiment.name,
182 self.device.name,
183 self.name)
184 else:
185 return u'%s' % self.device.name
186
187
182 188
183 189 def parms_to_dict(self):
184 190
185 191 parameters = {}
186 192
187 193 for key in self.__dict__.keys():
188 194 parameters[key] = getattr(self, key)
189 195
190 196 return parameters
191 197
192 198 def parms_to_text(self):
193 199
194 200 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
195 201
196 202 return ''
197 203
198 204 def parms_to_binary(self):
199 205
200 206 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
201 207
202 208 return ''
203 209
204 210 def dict_to_parms(self, parameters):
205 211
206 212 if type(parameters) != type({}):
207 213 return
208 214
209 215 for key in parameters.keys():
210 216 setattr(self, key, parameters[key])
211 217
212 218 def export_to_file(self, format="json"):
213 219
214 220 import json
215 221
216 222 content_type = ''
217 223
218 224 if format == 'text':
219 225 content_type = 'text/plain'
220 226 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
221 227 content = self.parms_to_text()
222 228
223 229 if format == 'binary':
224 230 content_type = 'application/octet-stream'
225 231 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
226 232 content = self.parms_to_binary()
227 233
228 234 if not content_type:
229 235 content_type = 'application/json'
230 236 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
231 content = json.dumps(self.parms_to_dict())
237 content = json.dumps(self.parms_to_dict(), indent=2)
232 238
233 239 fields = {'content_type':content_type,
234 240 'filename':filename,
235 241 'content':content
236 242 }
237 243
238 244 return fields
239 245
240 246 def import_from_file(self, fp):
241 247
242 248 import os, json
243 249
244 250 parms = {}
245 251
246 252 path, ext = os.path.splitext(fp.name)
247 253
248 254 if ext == '.json':
249 255 parms = json.load(fp)
250 256
251 257 return parms
252 258
253 259 def status_device(self):
254 260
255 261 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
256 262
257 263 return None
258 264
259 265 def stop_device(self):
260 266
261 267 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
262 268
263 269 return None
264 270
265 271 def start_device(self):
266 272
267 273 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
268 274
269 275 return None
270 276
271 277 def write_device(self, parms):
272 278
273 279 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
274 280
275 281 return None
276 282
277 283 def read_device(self):
278 284
279 285 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
280 286
281 287 return None
282 288
283 289 def get_absolute_url(self):
284 290 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
285 291
286 292 def get_absolute_url_edit(self):
287 293 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
288 294
289 295 def get_absolute_url_import(self):
290 296 return reverse('url_import_dev_conf', args=[str(self.id)])
291 297
292 298 def get_absolute_url_export(self):
293 299 return reverse('url_export_dev_conf', args=[str(self.id)])
294 300
295 301 def get_absolute_url_write(self):
296 302 return reverse('url_write_dev_conf', args=[str(self.id)])
297 303
298 304 def get_absolute_url_read(self):
299 305 return reverse('url_read_dev_conf', args=[str(self.id)])
300 306
301 307 def get_absolute_url_start(self):
302 308 return reverse('url_start_dev_conf', args=[str(self.id)])
303 309
304 310 def get_absolute_url_stop(self):
305 311 return reverse('url_stop_dev_conf', args=[str(self.id)])
306 312
307 313 def get_absolute_url_status(self):
308 314 return reverse('url_status_dev_conf', args=[str(self.id)]) No newline at end of file
@@ -1,143 +1,144
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 <script src="{% static 'js/jquery.min.js' %}"></script>
21 22 {% block extra-head %}
22 23 {% endblock %}
23 24 </head>
24 25
25 26 <body>
26 27
27 28 {% block main_menu %}
28 29 <nav class="navbar navbar-default navbar-fixed-top" role="banner">
29 30 <div class="container-fluid">
30 31 <div class="navbar-header">
31 32 <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navigationbar">
32 33 <span class="sr-only">Toggle navigation</span>
33 34 <span class="icon-bar"></span>
34 35 <span class="icon-bar"></span>
35 36 <span class="icon-bar"></span>
36 37 </button>
37 38 <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 39 </div>
39 40 <div class="collapse navbar-collapse" id="navigationbar">
40 41 <ul class="nav navbar-nav">
41 42 <li class=" dropdown {% block operation-active %}{% endblock %}"><a href="{% url 'url_operation'%}">Operation</a>
42 43 </li>
43 44 <li class=" dropdown {% block conf-active %}{% endblock %}">
44 45 <a href="#" class="dropdown-toggle" data-toggle="dropdown">New<span class="caret"></span></a>
45 46 <ul class="dropdown-menu" role="menu">
46 47 <li><a href="{% url 'url_add_campaign' %}">Campaign</a></li>
47 48 <li><a href="{% url 'url_add_experiment' 0%}">Experiment</a></li>
48 49 <li><a href="{% url 'url_add_dev_conf' 0%}">Device Configuration</a></li>
49 50 <li><a href="{% url 'url_add_device'%}">Radar/Device</a></li>
50 51
51 52 </ul>
52 53 </li>
53 54 <li class=" dropdown {% block test-active %}{% endblock %}">
54 55 <a href="#" class="dropdown-toggle" data-toggle="dropdown">Test<span class="caret"></span></a>
55 56 <ul class="dropdown-menu" role="menu">
56 57 <li><a href="{% url 'url_experiments' %}">Experiments</a></li>
57 58 <li><a href="{% url 'url_devices' %}">Devices</a></li>
58 59 </ul>
59 60 </li>
60 61 <li class=" dropdown {% block search-active %}{% endblock %}">
61 62 <a href="#" class="dropdown-toggle" data-toggle="dropdown">Search<span class="caret"></span></a>
62 63 <ul class="dropdown-menu" role="menu">
63 64 <li><a href="{% url 'url_campaigns' %}">Campaigns</a></li>
64 65 <li><a href="{% url 'url_experiments' %}">Experiments</a></li>
65 66 <li><a href="{% url 'url_dev_confs' %}">Configurations</a></li>
66 67 </ul>
67 68 </li>
68 69 </ul>
69 70 <ul class="nav navbar-nav navbar-right">
70 71 <li class="nav-divider"></li>
71 72 {% if user.is_authenticated %}
72 73 <li class="dropdown">
73 74 <a href="#" class="dropdown-toggle" data-toggle="dropdown">Hi {{ user.username }}<span class="caret"></span></a>
74 75 <ul class="dropdown-menu" role="menu">
75 76 <li><a href="#">Control Panel</a></li>
76 77 <li><a href="{% url 'django.contrib.auth.views.logout' %}">Logout</a></li>
77 78 </ul>
78 79 </li>
79 80 {% else %}
80 81 <li><a href="{% url 'django.contrib.auth.views.login' %}?next={{request.get_full_path}}">Login</a></li>
81 82 {% endif %}
82 83 </ul>
83 84 </div>
84 85 </div>
85 86 </nav>
86 87 <div style="clear: both;"></div>
87 88 {% endblock %}
88 89
89 90 <div class="container">
90 91 <div id="page" class="row" style="min-height:600px">
91 92
92 93 <div class="col-md-3 hidden-xs hidden-sm" role="complementary">
93 94 <br><br>
94 95 <div id="sidebar">
95 96 {% block sidebar%}
96 97 {% endblock %}
97 98 </div>
98 99 </div>
99 100
100 101 <div class="col-md-9 col-xs-12" role="main">
101 102 <div class="page-header">
102 103 <h1>{% block content-title %}{% endblock %} <small>{% block content-suptitle %}{% endblock %}</small></h1>
103 104 </div>
104 105 {% block messages %}
105 106 {% if messages %}
106 107 {% for message in messages %}
107 108 <div class="alert alert-{% if message.tags %}{% if 'error' in message.tags %}danger{% else %}{{ message.tags }}{% endif %}{% else %}info{% endif %} alert-dismissible" role="alert">
108 109 <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
109 110 <strong>{{message.tags|title}}!</strong> {{ message }}
110 111 </div>
111 112 {% endfor %}
112 113 {% endif %}
113 114 {% endblock %}
114 115
115 116 {% block content %}
116 117 {% endblock %}
117 118
118 119 </div>
119 120
120 121 </div><!--/row-->
121 122 </div> <!-- container -->
122 123
123 124 <div id="debug">{{debug}}</div>
124 125
125 126 {% block footer %}
126 127 <footer class="footer">
127 128 <div class="container">
128 129 <p><hr></p>
129 130 <p>
130 131 &copy; <a href="http://jro.igp.gob.pe">Jicamarca Radio Observatory</a> - {% now "Y" %}
131 132 </p>
132 133 </div>
133 134 </footer>
134 135 {% endblock %}
135 136
136 137 {# bootstrap_javascript jquery=True #}
137 <script src="{% static 'js/jquery.min.js' %}"></script>
138
138 139 <script src="{% static 'js/bootstrap.min.js' %}"></script>
139 140 {% block extra-js %}
140 141 {% endblock%}
141 142 </body>
142 143 </html>
143 144
@@ -1,74 +1,81
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 {% block menu-actions %}
13 14 <span class=" dropdown pull-right">
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 <a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-menu-hamburger" aria-hidden="true"></span></a>
15 16 <ul class="dropdown-menu" role="menu">
16 17 <li><a href="{{ dev_conf.get_absolute_url_edit }}"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit</a></li>
17 18 <li><a href="{{ dev_conf.get_absolute_url_import }}"><span class="glyphicon glyphicon-import" aria-hidden="true"></span> Import </a></li>
18 <li><a href="{{ dev_conf.get_absolute_url_export }}"><span class="glyphicon glyphicon-export" aria-hidden="true"></span> Export </a></li>
19 <li><a href="{{ dev_conf.get_absolute_url_export }}"><span class="glyphicon glyphicon-export" aria-hidden="true"></span> Export </a></li>
20 {% block extra-menu-actions %}
21 {% endblock %}
19 22 <li><a>----------------</a></li>
20 23 <li><a href="{{ dev_conf.get_absolute_url_status }}"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span> Status</a></li>
21 24 {% if not no_play %}
22 25 <li><a href="{{ dev_conf.get_absolute_url_start}}"><span class="glyphicon glyphicon-play" aria-hidden="true"></span> Start</a></li>
23 26 <li><a href="{{ dev_conf.get_absolute_url_stop }}"><span class="glyphicon glyphicon-stop" aria-hidden="true"></span> Stop</a></li>
24 27 {% endif %}
25 28 <li><a href="{{ dev_conf.get_absolute_url_write }}"><span class="glyphicon glyphicon-download" aria-hidden="true"></span> Write</a></li>
26 29 <li><a href="{{ dev_conf.get_absolute_url_read }}"><span class="glyphicon glyphicon-upload" aria-hidden="true"></span> Read</a></li>
27 30 </ul>
28 31 </span>
29
32 {% endblock %}
33
30 34 <table class="table table-bordered">
31 35 <tr>
32 36 <th>Status</th>
33 37 <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>
34 38 </tr>
35 39
36 40 {% for key in dev_conf_keys %}
37 41 <tr>
38 42 <th>{% get_verbose_field_name dev_conf key %}</th>
39 43 <td>{{dev_conf|attr:key}}</td>
40 44 </tr>
41 45 {% endfor %}
42 46 </table>
43 47
48 {% block extra-content %}
49 {% endblock %}
50
44 51 {% endblock %}
45 52
46 53 {% block sidebar%}
47 54 {% include "sidebar_devices.html" %}
48 55 {% endblock %}
49 56
50 57 {% block extra-js%}
51 58 <script type="text/javascript">
52 59
53 60 $("#bt_edit").click(function() {
54 61 document.location = "{{ dev_conf.get_absolute_url_edit }}";
55 62 });
56 63
57 64 $("#bt_read").click(function() {
58 65 document.location = "{{ dev_conf.get_absolute_url_read }}";
59 66 });
60 67
61 68 $("#bt_write").click(function() {
62 69 document.location = "{{ dev_conf.get_absolute_url_write }}";
63 70 });
64 71
65 72 $("#bt_import").click(function() {
66 73 document.location = "{{ dev_conf.get_absolute_url_import }}";
67 74 });
68 75
69 76 $("#bt_export").click(function() {
70 77 document.location = "{{ dev_conf.get_absolute_url_export }}";
71 78 });
72 79
73 80 </script>
74 81 {% endblock %} No newline at end of file
@@ -1,35 +1,46
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 {% if form.is_multipart %}
14 14 <form class="form" enctype="multipart/form-data" method="post" action="{{action}}">
15 15 {% else %}
16 16 <form class="form" method="post" action="{{action}}">
17 17 {% endif %}
18 18
19 19 {% csrf_token %}
20 20 {% bootstrap_form form layout='horizontal' size='medium' %}
21 21 <div style="clear: both;"></div>
22 22 <br>
23 {% if extra_button %}
24 <div class="pull-left">
25 <button type="button" class="btn btn-primary" id="bt_{{extra_button}}">{{extra_button}}</button>
26 </div>
27 {% endif %}
23 28 <div class="pull-right">
24 29 <button type="button" class="btn btn-primary" onclick="{% if previous %}window.location.replace('{{ previous }}');{% else %}history.go(-1);{% endif %}">Cancel</button>
25 30 <button type="submit" class="btn btn-primary">{{button}}</button>
26 31 </div>
27 32 </form>
28 33 {% endblock %}
29 34
30 35 {% block sidebar%}
31 36 {% include "sidebar_devices.html" %}
32 37 {% endblock %}
33 38
34 39 {% block extra-js%}
40 <script type="text/javascript">
41 $("#id_device").change(function() {
42 var url = "{% url 'url_add_dev_conf' id_exp %}";
43 document.location = url+ $(this).val() + "/";
44 });
45 </script>
35 46 {% endblock %} No newline at end of file
@@ -1,100 +1,103
1 1 {% if campaign %}
2 2 <div class="panel panel-default">
3 3 <div class="panel-heading">
4 4 <h4>Campaign</h4>
5 5 </div>
6 6 <div class="list-group">
7 7 <a href="{% url 'url_campaign' campaign.id %}" class="list-group-item active" >{{ campaign.name }}</a>
8 8 </div>
9 9 </div>
10 10
11 11 {% if experiments %}
12 12 <div class="panel panel-default">
13 13 <div class="panel-heading">
14 14 <h4>Experiments</h4>
15 15 </div>
16 16 <div class="list-group">
17 17 {% for item in experiments %}
18 18 <a href="{% url 'url_experiment' item.id %}" class="list-group-item {{item.active}}">{{item.name}}</a>
19 19 {% endfor %}
20 20 </div>
21 21 </div>
22 22 {% endif %}
23 23 {% endif %}
24 24
25 25 {% if experiment %}
26 26 <div class="panel panel-default">
27 27 <div class="panel-heading">
28 28 <h4>Campaign</h4>
29 29 </div>
30 30 <div class="list-group">
31 31 <a href="{% url 'url_campaign' experiment.campaign.id %}" class="list-group-item active" >{{ experiment.campaign.name }}</a>
32 32 </div>
33 33 </div>
34 34
35 35 {% if experiments %}
36 36 <div class="panel panel-default">
37 37 <div class="panel-heading">
38 38 <h4>Experiments</h4>
39 39 </div>
40 40 <div class="list-group">
41 41 {% for item in experiments %}
42 42 <a href="{% url 'url_experiment' item.id %}" class="list-group-item {%if item.id == experiment.id%}active{%endif%}">{{item.name}}</a>
43 43 {% endfor %}
44 44 </div>
45 45 </div>
46 46 {% endif %}
47 47
48 48 {% if configurations %}
49 49 <div class="panel panel-default">
50 50 <div class="panel-heading">
51 51 <h4>Device Configurations</h4>
52 52 </div>
53 53 <div class="list-group">
54 54 {% for item in configurations %}
55 55 <a href="{{item.get_absolute_url}}" class="list-group-item {{item.active}}">{{item.device.name}}</a>
56 56 {% endfor %}
57 57 </div>
58 58 </div>
59 59 {% endif %}
60 60
61 61 {% endif %}
62 62
63 63 {% if dev_conf %}
64 <div class="panel panel-default">
65 <div class="panel-heading">
66 <h4>Campaign</h4>
67 </div>
68 <div class="list-group">
69 <a href="{% url 'url_campaign' dev_conf.experiment.campaign.id %}" class="list-group-item active" >{{ dev_conf.experiment.campaign.name }}</a>
70 </div>
71 </div>
64
65 {% if campaign %}
66 <div class="panel panel-default">
67 <div class="panel-heading">
68 <h4>Campaign</h4>
69 </div>
70 <div class="list-group">
71 <a href="{% url 'url_campaign' dev_conf.experiment.campaign.id %}" class="list-group-item active" >{{ dev_conf.experiment.campaign.name }}</a>
72 </div>
73 </div>
74 {% endif %}
72 75
73 76 {% if experiments %}
74 77 <div class="panel panel-default">
75 78 <div class="panel-heading">
76 79 <h4>Experiments</h4>
77 80 </div>
78 81 <div class="list-group">
79 82 {% for item in experiments %}
80 83 <a href="{% url 'url_experiment' item.id %}" class="list-group-item {%if item.id == dev_conf.experiment.id%}active{%endif%}">{{item.name}}</a>
81 84 {% endfor %}
82 85 </div>
83 86 </div>
84 87 {% endif %}
85 88
86 89 {% if configurations %}
87 90 <div class="panel panel-default">
88 91 <div class="panel-heading">
89 92 <h4>Device Configurations</h4>
90 93 </div>
91 94 <div class="list-group">
92 95 {% for item in configurations %}
93 96 <a href="{{item.get_absolute_url}}" class="list-group-item {%if item.id == dev_conf.id%}active{%endif%}">{{item.device.name}}</a>
94 97 {% endfor %}
95 98 </div>
96 99 </div>
97 100 {% endif %}
98 101
99 102
100 103 {% endif %}
@@ -1,35 +1,37
1 1 from django.template.defaulttags import register
2 from django.utils.safestring import mark_safe
2 3
3 4 @register.filter
4 5 def attr(instance, key):
5 6
6 7 display_key = "get_" + key + "_display"
7 8
8 9 if hasattr(instance, display_key):
9 10 return getattr(instance, display_key)()
10 11
11 12 if hasattr(instance, key):
12 13 return getattr(instance, key)
13 14
14 15 return instance.get(key)
15 16
16 17 @register.filter
17 18 def title(s):
18 19 return s.replace('_', ' ').title()
19 20
20 21 @register.filter
21 22 def value(instance, key):
22 23
23 24 item = instance
24 25 for my_key in key.split("__"):
25 26 item = attr(item, my_key)
26 27
27 28 print item
28 29 return item
29 30
30 31 @register.simple_tag
31 32 def get_verbose_field_name(instance, field_name):
32 33 """
33 34 Returns verbose_name for a field.
34 35 """
35 return instance._meta.get_field(field_name).verbose_name.title() No newline at end of file
36
37 return mark_safe(instance._meta.get_field(field_name).verbose_name) No newline at end of file
@@ -1,47 +1,48
1 1 from django.conf.urls import url
2 2
3 3 urlpatterns = (
4 4 url(r'^location/new/$', 'apps.main.views.location_new', name='url_add_location'),
5 5 url(r'^location/$', 'apps.main.views.locations', name='url_locations'),
6 6 url(r'^location/(?P<id_loc>-?\d+)/$', 'apps.main.views.location', name='url_location'),
7 7 url(r'^location/(?P<id_loc>-?\d+)/edit/$', 'apps.main.views.location_edit', name='url_edit_location'),
8 8 url(r'^location/(?P<id_loc>-?\d+)/delete/$', 'apps.main.views.location_delete', name='url_delete_location'),
9 9
10 10 url(r'^device/new/$', 'apps.main.views.device_new', name='url_add_device'),
11 11 url(r'^device/$', 'apps.main.views.devices', name='url_devices'),
12 12 url(r'^device/(?P<id_dev>-?\d+)/$', 'apps.main.views.device', name='url_device'),
13 13 url(r'^device/(?P<id_dev>-?\d+)/edit/$', 'apps.main.views.device_edit', name='url_edit_device'),
14 14 url(r'^device/(?P<id_dev>-?\d+)/delete/$', 'apps.main.views.device_delete', name='url_delete_device'),
15 15
16 16 url(r'^campaign/new/$', 'apps.main.views.campaign_new', name='url_add_campaign'),
17 17 url(r'^campaign/$', 'apps.main.views.campaigns', name='url_campaigns'),
18 18 url(r'^campaign/(?P<id_camp>-?\d+)/$', 'apps.main.views.campaign', name='url_campaign'),
19 19 url(r'^campaign/(?P<id_camp>-?\d+)/edit/$', 'apps.main.views.campaign_edit', name='url_edit_campaign'),
20 20 url(r'^campaign/(?P<id_camp>-?\d+)/delete/$', 'apps.main.views.campaign_delete', name='url_delete_campaign'),
21 21
22 22 url(r'^campaign/(?P<id_camp>-?\d+)/new_experiment/$', 'apps.main.views.experiment_new', name='url_add_experiment'),
23 23 url(r'^experiment/$', 'apps.main.views.experiments', name='url_experiments'),
24 24 url(r'^experiment/(?P<id_exp>-?\d+)/$', 'apps.main.views.experiment', name='url_experiment'),
25 25 url(r'^experiment/(?P<id_exp>-?\d+)/edit/$', 'apps.main.views.experiment_edit', name='url_edit_experiment'),
26 26 url(r'^experiment/(?P<id_exp>-?\d+)/delete/$', 'apps.main.views.experiment_delete', name='url_delete_experiment'),
27 27
28 28 url(r'^experiment/(?P<id_exp>-?\d+)/new_dev_conf/$', 'apps.main.views.dev_conf_new', name='url_add_dev_conf'),
29 url(r'^experiment/(?P<id_exp>-?\d+)/new_dev_conf/(?P<id_dev>-?\d+)/$', 'apps.main.views.dev_conf_new', name='url_add_dev_conf'),
29 30 url(r'^dev_conf/$', 'apps.main.views.dev_confs', name='url_dev_confs'),
30 31 url(r'^dev_conf/(?P<id_conf>-?\d+)/$', 'apps.main.views.dev_conf', name='url_dev_conf'),
31 32 url(r'^dev_conf/(?P<id_conf>-?\d+)/edit/$', 'apps.main.views.dev_conf_edit', name='url_edit_dev_conf'),
32 33 url(r'^dev_conf/(?P<id_conf>-?\d+)/delete/$', 'apps.main.views.dev_conf_delete', name='url_delete_dev_conf'),
33 34
34 35 url(r'^dev_conf/(?P<id_conf>-?\d+)/write/$', 'apps.main.views.dev_conf_write', name='url_write_dev_conf'),
35 36 url(r'^dev_conf/(?P<id_conf>-?\d+)/read/$', 'apps.main.views.dev_conf_read', name='url_read_dev_conf'),
36 37 url(r'^dev_conf/(?P<id_conf>-?\d+)/import/$', 'apps.main.views.dev_conf_import', name='url_import_dev_conf'),
37 38 url(r'^dev_conf/(?P<id_conf>-?\d+)/export/$', 'apps.main.views.dev_conf_export', name='url_export_dev_conf'),
38 39 url(r'^dev_conf/(?P<id_conf>-?\d+)/start/$', 'apps.main.views.dev_conf_start', name='url_start_dev_conf'),
39 40 url(r'^dev_conf/(?P<id_conf>-?\d+)/stop/$', 'apps.main.views.dev_conf_stop', name='url_stop_dev_conf'),
40 41 url(r'^dev_conf/(?P<id_conf>-?\d+)/status/$', 'apps.main.views.dev_conf_status', name='url_status_dev_conf'),
41 42
42 43 url(r'^operation/$', 'apps.main.views.operation', name='url_operation'),
43 44 url(r'^operation/search/$', 'apps.main.views.operation_search', name='url_operation_search'),
44 45 url(r'^operation/search/(?P<id_camp>-?\d+)/$', 'apps.main.views.operation_search', name='url_operation_search'),
45 46 url(r'^operation/(?P<id_camp>-?\d+)/$', 'apps.main.views.operation', name='url_operation'),
46 47
47 48 )
@@ -1,892 +1,888
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 .forms import OperationSearchForm
6 6 from apps.cgs.forms import CGSConfigurationForm
7 7 from apps.jars.forms import JARSConfigurationForm
8 8 from apps.usrp.forms import USRPConfigurationForm
9 9 from apps.abs.forms import ABSConfigurationForm
10 10 from apps.rc.forms import RCConfigurationForm
11 11 from apps.dds.forms import DDSConfigurationForm
12 12
13 13 from .models import Campaign, Experiment, Device, Configuration, Location#, RunningExperiment
14 14 from apps.cgs.models import CGSConfiguration
15 15 from apps.jars.models import JARSConfiguration
16 16 from apps.usrp.models import USRPConfiguration
17 17 from apps.abs.models import ABSConfiguration
18 18 from apps.rc.models import RCConfiguration
19 19 from apps.dds.models import DDSConfiguration
20 20
21 21 # Create your views here.
22 22
23 23 CONF_FORMS = {
24 24 'rc': RCConfigurationForm,
25 25 'dds': DDSConfigurationForm,
26 26 'jars': JARSConfigurationForm,
27 27 'cgs': CGSConfigurationForm,
28 28 'abs': ABSConfigurationForm,
29 29 'usrp': USRPConfigurationForm,
30 30 }
31 31
32 32 CONF_MODELS = {
33 33 'rc': RCConfiguration,
34 34 'dds': DDSConfiguration,
35 35 'jars': JARSConfiguration,
36 36 'cgs': CGSConfiguration,
37 37 'abs': ABSConfiguration,
38 38 'usrp': USRPConfiguration,
39 39 }
40 40
41 41 def index(request):
42 42 kwargs = {}
43 43
44 44 return render(request, 'index.html', kwargs)
45 45
46 46 def locations(request):
47 47
48 48 locations = Location.objects.all().order_by('name')
49 49
50 50 keys = ['id', 'name', 'description']
51 51
52 52 kwargs = {}
53 53 kwargs['location_keys'] = keys[1:]
54 54 kwargs['locations'] = locations
55 55 kwargs['title'] = 'Location'
56 56 kwargs['suptitle'] = 'List'
57 57 kwargs['button'] = 'New Location'
58 58
59 59 return render(request, 'locations.html', kwargs)
60 60
61 61 def location(request, id_loc):
62 62
63 63 location = get_object_or_404(Location, pk=id_loc)
64 64
65 65 kwargs = {}
66 66 kwargs['location'] = location
67 67 kwargs['location_keys'] = ['name', 'description']
68 68
69 69 kwargs['title'] = 'Location'
70 70 kwargs['suptitle'] = 'Details'
71 71
72 72 return render(request, 'location.html', kwargs)
73 73
74 74 #def location_play(request, id_camp, id_loc):
75 75
76 76 # campaign = get_object_or_404(Campaign, pk=id_camp)
77 77 # print campaign
78 78 # location = get_object_or_404(Location, pk=id_loc)
79 79 # experiments = Experiment.objects.filter(location__pk=location.id).filter(campaign__pk=campaign.id)
80 80 # locations = Location.objects.filter(pk=id_loc)
81 81
82 82 # if request.method=='GET':
83 83 # form = OperationForm(initial={'campaign': campaign.id})
84 84
85 85 # kwargs = {}
86 86 #---Campaign
87 87 # kwargs['campaign'] = campaign
88 88 # kwargs['campaign_keys'] = ['name', 'start_date', 'end_date', 'tags', 'description']
89 89 #---Experiment
90 90 # keys = ['id', 'name', 'start_time', 'end_time']
91 91 # kwargs['experiment_keys'] = keys[1:]
92 92 # kwargs['experiments'] = experiments
93 93 #---Radar
94 94 # kwargs['location'] = location
95 95 #---Else
96 96 # kwargs['title'] = 'Campaign'
97 97 # kwargs['suptitle'] = campaign.name
98 98 # kwargs['form'] = form
99 99 # kwargs['button'] = 'Search'
100 100
101 101 # return render(request, 'operation_play.html', kwargs)
102 102
103 103 def location_new(request):
104 104
105 105 if request.method == 'GET':
106 106 form = LocationForm()
107 107
108 108 if request.method == 'POST':
109 109 form = LocationForm(request.POST)
110 110
111 111 if form.is_valid():
112 112 form.save()
113 113 return redirect('url_locations')
114 114
115 115 kwargs = {}
116 116 kwargs['form'] = form
117 117 kwargs['title'] = 'Location'
118 118 kwargs['suptitle'] = 'New'
119 119 kwargs['button'] = 'Create'
120 120
121 121 return render(request, 'location_edit.html', kwargs)
122 122
123 123 def location_edit(request, id_loc):
124 124
125 125 location = get_object_or_404(Location, pk=id_loc)
126 126
127 127 if request.method=='GET':
128 128 form = LocationForm(instance=location)
129 129
130 130 if request.method=='POST':
131 131 form = LocationForm(request.POST, instance=location)
132 132
133 133 if form.is_valid():
134 134 form.save()
135 135 return redirect('url_locations')
136 136
137 137 kwargs = {}
138 138 kwargs['form'] = form
139 139 kwargs['title'] = 'Location'
140 140 kwargs['suptitle'] = 'Edit'
141 141 kwargs['button'] = 'Update'
142 142
143 143 return render(request, 'location_edit.html', kwargs)
144 144
145 145 def location_delete(request, id_loc):
146 146
147 147 location = get_object_or_404(Location, pk=id_loc)
148 148
149 149 if request.method=='POST':
150 150
151 151 if request.user.is_staff:
152 152 location.delete()
153 153 return redirect('url_locations')
154 154
155 155 return HttpResponse("Not enough permission to delete this object")
156 156
157 157 kwargs = {'object':location, 'loc_active':'active',
158 158 'url_cancel':'url_location', 'id_item':id_loc}
159 159
160 160 return render(request, 'item_delete.html', kwargs)
161 161
162 162 def devices(request):
163 163
164 164 devices = Device.objects.all().order_by('device_type__name')
165 165
166 166 # keys = ['id', 'device_type__name', 'name', 'ip_address']
167 167 keys = ['id', 'name', 'ip_address', 'port_address', 'device_type']
168 168
169 169 kwargs = {}
170 170 kwargs['device_keys'] = keys[1:]
171 171 kwargs['devices'] = devices#.values(*keys)
172 172 kwargs['title'] = 'Device'
173 173 kwargs['suptitle'] = 'List'
174 174 kwargs['button'] = 'New Device'
175 175
176 176 return render(request, 'devices.html', kwargs)
177 177
178 178 def device(request, id_dev):
179 179
180 180 device = get_object_or_404(Device, pk=id_dev)
181 181
182 182 kwargs = {}
183 183 kwargs['device'] = device
184 184 kwargs['device_keys'] = ['device_type', 'name', 'ip_address', 'port_address', 'description']
185 185
186 186 kwargs['title'] = 'Device'
187 187 kwargs['suptitle'] = 'Details'
188 188
189 189 return render(request, 'device.html', kwargs)
190 190
191 191 def device_new(request):
192 192
193 193 if request.method == 'GET':
194 194 form = DeviceForm()
195 195
196 196 if request.method == 'POST':
197 197 form = DeviceForm(request.POST)
198 198
199 199 if form.is_valid():
200 200 form.save()
201 201 return redirect('url_devices')
202 202
203 203 kwargs = {}
204 204 kwargs['form'] = form
205 205 kwargs['title'] = 'Device'
206 206 kwargs['suptitle'] = 'New'
207 207 kwargs['button'] = 'Create'
208 208
209 209 return render(request, 'device_edit.html', kwargs)
210 210
211 211 def device_edit(request, id_dev):
212 212
213 213 device = get_object_or_404(Device, pk=id_dev)
214 214
215 215 if request.method=='GET':
216 216 form = DeviceForm(instance=device)
217 217
218 218 if request.method=='POST':
219 219 form = DeviceForm(request.POST, instance=device)
220 220
221 221 if form.is_valid():
222 222 form.save()
223 223 return redirect('url_devices')
224 224
225 225 kwargs = {}
226 226 kwargs['form'] = form
227 227 kwargs['title'] = 'Device'
228 228 kwargs['suptitle'] = 'Edit'
229 229 kwargs['button'] = 'Update'
230 230
231 231 return render(request, 'device_edit.html', kwargs)
232 232
233 233 def device_delete(request, id_dev):
234 234
235 235 device = get_object_or_404(Device, pk=id_dev)
236 236
237 237 if request.method=='POST':
238 238
239 239 if request.user.is_staff:
240 240 device.delete()
241 241 return redirect('url_devices')
242 242
243 243 return HttpResponse("Not enough permission to delete this object")
244 244
245 245 kwargs = {'object':device, 'dev_active':'active',
246 246 'url_cancel':'url_device', 'id_item':id_dev}
247 247
248 248 return render(request, 'item_delete.html', kwargs)
249 249
250 250 def campaigns(request):
251 251
252 252 campaigns = Campaign.objects.all().order_by('start_date')
253 253
254 254 keys = ['id', 'name', 'start_date', 'end_date']
255 255
256 256 kwargs = {}
257 257 kwargs['campaign_keys'] = keys[1:]
258 258 kwargs['campaigns'] = campaigns#.values(*keys)
259 259 kwargs['title'] = 'Campaign'
260 260 kwargs['suptitle'] = 'List'
261 261 kwargs['button'] = 'New Campaign'
262 262
263 263 return render(request, 'campaigns.html', kwargs)
264 264
265 265 def campaign(request, id_camp):
266 266
267 267 campaign = get_object_or_404(Campaign, pk=id_camp)
268 268 experiments = Experiment.objects.filter(campaign=campaign)
269 269
270 270 form = CampaignForm(instance=campaign)
271 271
272 272 kwargs = {}
273 273 kwargs['campaign'] = campaign
274 274 kwargs['campaign_keys'] = ['name', 'start_date', 'end_date', 'tags', 'description']
275 275
276 276 keys = ['id', 'name', 'start_time', 'end_time']
277 277
278 278 kwargs['experiment_keys'] = keys[1:]
279 279 kwargs['experiments'] = experiments.values(*keys)
280 280
281 281 kwargs['title'] = 'Campaign'
282 282 kwargs['suptitle'] = 'Details'
283 283
284 284 kwargs['form'] = form
285 285 kwargs['button'] = 'Add Experiment'
286 286
287 287 return render(request, 'campaign.html', kwargs)
288 288
289 289 def campaign_new(request):
290 290
291 291 if request.method == 'GET':
292 292 form = CampaignForm()
293 293
294 294 if request.method == 'POST':
295 295 form = CampaignForm(request.POST)
296 296
297 297 if form.is_valid():
298 298 campaign = form.save()
299 299 return redirect('url_campaign', id_camp=campaign.id)
300 300
301 301 kwargs = {}
302 302 kwargs['form'] = form
303 303 kwargs['title'] = 'Campaign'
304 304 kwargs['suptitle'] = 'New'
305 305 kwargs['button'] = 'Create'
306 306
307 307 return render(request, 'campaign_edit.html', kwargs)
308 308
309 309 def campaign_edit(request, id_camp):
310 310
311 311 campaign = get_object_or_404(Campaign, pk=id_camp)
312 312
313 313 if request.method=='GET':
314 314 form = CampaignForm(instance=campaign)
315 315
316 316 if request.method=='POST':
317 317 form = CampaignForm(request.POST, instance=campaign)
318 318
319 319 if form.is_valid():
320 320 form.save()
321 321 return redirect('url_campaign', id_camp=id_camp)
322 322
323 323 kwargs = {}
324 324 kwargs['form'] = form
325 325 kwargs['title'] = 'Campaign'
326 326 kwargs['suptitle'] = 'Edit'
327 327 kwargs['button'] = 'Update'
328 328
329 329 return render(request, 'campaign_edit.html', kwargs)
330 330
331 331 def campaign_delete(request, id_camp):
332 332
333 333 campaign = get_object_or_404(Campaign, pk=id_camp)
334 334
335 335 if request.method=='POST':
336 336 if request.user.is_staff:
337 337 campaign.delete()
338 338 return redirect('url_campaigns')
339 339
340 340 return HttpResponse("Not enough permission to delete this object")
341 341
342 342 kwargs = {'object':campaign, 'camp_active':'active',
343 343 'url_cancel':'url_campaign', 'id_item':id_camp}
344 344
345 345 return render(request, 'item_delete.html', kwargs)
346 346
347 347 def experiments(request):
348 348
349 349 experiment_list = Experiment.objects.all().order_by('campaign')
350 350
351 351 keys = ['id', 'name', 'start_time', 'end_time', 'campaign']
352 352
353 353 kwargs = {}
354 354
355 355 kwargs['experiment_keys'] = keys[1:]
356 356 kwargs['experiments'] = experiment_list#.values(*keys)
357 357
358 358 kwargs['title'] = 'Experiment'
359 359 kwargs['suptitle'] = 'List'
360 360 kwargs['button'] = 'New Experiment'
361 361
362 362 return render(request, 'experiments.html', kwargs)
363 363
364 364 def experiment(request, id_exp):
365 365
366 366 experiment = get_object_or_404(Experiment, pk=id_exp)
367 367
368 368 experiments = Experiment.objects.filter(campaign=experiment.campaign)
369 369 configurations = Configuration.objects.filter(experiment=experiment, type=0)
370 370
371 371 kwargs = {}
372 372
373 373 exp_keys = ['id', 'campaign', 'location', 'name', 'start_time', 'end_time']
374 374 conf_keys = ['id', 'device__name', 'device__device_type', 'device__ip_address', 'device__port_address']
375 375
376 376 conf_labels = ['id', 'device__name', 'device_type', 'ip_address', 'port_address']
377 377
378 378 kwargs['experiment_keys'] = exp_keys[1:]
379 379 kwargs['experiment'] = experiment
380 380
381 381 kwargs['experiments'] = experiments.values(*exp_keys)
382 382
383 383 kwargs['configuration_labels'] = conf_labels[1:]
384 384 kwargs['configuration_keys'] = conf_keys[1:]
385 385 kwargs['configurations'] = configurations #.values(*conf_keys)
386 386
387 387 kwargs['title'] = 'Experiment'
388 388 kwargs['suptitle'] = 'Details'
389 389
390 390 kwargs['button'] = 'Add Configuration'
391 391
392 392 return render(request, 'experiment.html', kwargs)
393 393
394 def experiment_new(request, id_camp=0):
394 def experiment_new(request, id_camp=None):
395 395
396 396 if request.method == 'GET':
397 397 form = ExperimentForm(initial={'campaign':id_camp})
398 398
399 399 if request.method == 'POST':
400 400 form = ExperimentForm(request.POST, initial={'campaign':id_camp})
401 401
402 402 if form.is_valid():
403 403 experiment = form.save()
404 404 return redirect('url_experiment', id_exp=experiment.id)
405 405
406 406 kwargs = {}
407 407 kwargs['form'] = form
408 408 kwargs['title'] = 'Experiment'
409 409 kwargs['suptitle'] = 'New'
410 410 kwargs['button'] = 'Create'
411 411
412 412 return render(request, 'experiment_edit.html', kwargs)
413 413
414 414 def experiment_edit(request, id_exp):
415 415
416 416 experiment = get_object_or_404(Experiment, pk=id_exp)
417 417
418 418 if request.method == 'GET':
419 419 form = ExperimentForm(instance=experiment)
420 420
421 421 if request.method=='POST':
422 422 form = ExperimentForm(request.POST, instance=experiment)
423 423
424 424 if form.is_valid():
425 425 experiment = form.save()
426 426 return redirect('url_experiment', id_exp=experiment.id)
427 427
428 428 kwargs = {}
429 429 kwargs['form'] = form
430 430 kwargs['title'] = 'Experiment'
431 431 kwargs['suptitle'] = 'Edit'
432 432 kwargs['button'] = 'Update'
433 433
434 434 return render(request, 'experiment_edit.html', kwargs)
435 435
436 436 def experiment_delete(request, id_exp):
437 437
438 438 experiment = get_object_or_404(Experiment, pk=id_exp)
439 439
440 440 if request.method=='POST':
441 441 if request.user.is_staff:
442 442 id_camp = experiment.campaign.id
443 443 experiment.delete()
444 444 return redirect('url_campaign', id_camp=id_camp)
445 445
446 446 return HttpResponse("Not enough permission to delete this object")
447 447
448 448 kwargs = {'object':experiment, 'exp_active':'active',
449 449 'url_cancel':'url_experiment', 'id_item':id_exp}
450 450
451 451 return render(request, 'item_delete.html', kwargs)
452 452
453 453 def dev_confs(request):
454 454
455 455 configurations = Configuration.objects.all().order_by('type', 'device__device_type', 'experiment')
456 456
457 457 # keys = ['id', 'device__device_type__name', 'device__name', 'experiment__campaign__name', 'experiment__name']
458 458
459 459 keys = ['id', 'device', 'experiment', 'type', 'programmed_date']
460 460
461 461 kwargs = {}
462 462
463 463 kwargs['configuration_keys'] = keys[1:]
464 464 kwargs['configurations'] = configurations#.values(*keys)
465 465
466 466 kwargs['title'] = 'Configuration'
467 467 kwargs['suptitle'] = 'List'
468 468 kwargs['button'] = 'New Configuration'
469 469
470 470 return render(request, 'dev_confs.html', kwargs)
471 471
472 472 def dev_conf(request, id_conf):
473 473
474 474 conf = get_object_or_404(Configuration, pk=id_conf)
475 475
476 DevConfModel = CONF_MODELS[conf.device.device_type.name]
477 dev_conf = DevConfModel.objects.get(pk=id_conf)
478
479 kwargs = {}
480 kwargs['dev_conf'] = dev_conf
481 kwargs['dev_conf_keys'] = ['name', 'experiment', 'device']
476 return redirect(conf.get_absolute_url())
482 477
483 kwargs['title'] = 'Configuration'
484 kwargs['suptitle'] = 'Details'
478
479 def dev_conf_new(request, id_exp=0, id_dev=0):
485 480
486 kwargs['button'] = 'Edit Configuration'
481 initial = {}
487 482
488 ###### SIDEBAR ######
489 kwargs.update(sidebar(conf))
483 if id_exp==0:
484 initial['experiment'] = id_exp
490 485
491 return render(request, 'dev_conf.html', kwargs)
492
493 def dev_conf_new(request, id_exp=0):
486 if id_dev<>0:
487 initial['device'] = id_dev
494 488
495 489 if request.method == 'GET':
496 form = ConfigurationForm(initial={'experiment':id_exp})
490 if id_dev==0:
491 form = ConfigurationForm(initial=initial)
492 else:
493 device = Device.objects.get(pk=id_dev)
494 DevConfForm = CONF_FORMS[device.device_type.name]
495
496 form = DevConfForm(initial=initial)
497 497
498 498 if request.method == 'POST':
499 experiment = Experiment.objects.get(pk=request.POST['experiment'])
500 device = Device.objects.get(pk=request.POST['device'])
501 499
500 device = Device.objects.get(pk=request.POST['device'])
502 501 DevConfForm = CONF_FORMS[device.device_type.name]
503
504 form = DevConfForm(request.POST, initial={'experiment':experiment.id})
502
503 form = DevConfForm(request.POST)
505 504
506 505 if form.is_valid():
507 506 dev_conf = form.save()
508 507
509 return redirect('url_experiment', id_exp=experiment.id)
508 return redirect('url_dev_confs')
510 509
511 510 kwargs = {}
511 kwargs['id_exp'] = id_exp
512 512 kwargs['form'] = form
513 513 kwargs['title'] = 'Configuration'
514 514 kwargs['suptitle'] = 'New'
515 515 kwargs['button'] = 'Create'
516 516
517 517 return render(request, 'dev_conf_edit.html', kwargs)
518 518
519 519 def dev_conf_edit(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 DevConfForm = CONF_FORMS[conf.device.device_type.name]
525 525
526 526 dev_conf = DevConfModel.objects.get(pk=id_conf)
527 527
528 528 if request.method=='GET':
529 529 form = DevConfForm(instance=dev_conf)
530 530
531 531 if request.method=='POST':
532 532 form = DevConfForm(request.POST, instance=dev_conf)
533 533
534 534 if form.is_valid():
535 535 form.save()
536 536 return redirect('url_dev_conf', id_conf=id_conf)
537 537
538 538 kwargs = {}
539 539 kwargs['form'] = form
540 540 kwargs['title'] = 'Device Configuration'
541 541 kwargs['suptitle'] = 'Edit'
542 542 kwargs['button'] = 'Update'
543 543
544 544 ###### SIDEBAR ######
545 545 kwargs.update(sidebar(conf))
546 546
547 547 return render(request, '%s_conf_edit.html' %conf.device.device_type.name, kwargs)
548 548
549 549 def dev_conf_start(request, id_conf):
550 550
551 551 conf = get_object_or_404(Configuration, pk=id_conf)
552 552
553 553 DevConfModel = CONF_MODELS[conf.device.device_type.name]
554 554
555 555 conf = DevConfModel.objects.get(pk=id_conf)
556 556
557 557 if conf.start_device():
558 558 messages.success(request, conf.message)
559 559 else:
560 560 messages.error(request, conf.message)
561 561
562 562 conf.status_device()
563 563
564 564 return redirect(conf.get_absolute_url())
565 565
566 566 def dev_conf_stop(request, id_conf):
567 567
568 568 conf = get_object_or_404(Configuration, pk=id_conf)
569 569
570 570 DevConfModel = CONF_MODELS[conf.device.device_type.name]
571 571
572 572 conf = DevConfModel.objects.get(pk=id_conf)
573 573
574 574 if conf.stop_device():
575 575 messages.success(request, conf.message)
576 576 else:
577 577 messages.error(request, conf.message)
578 578
579 579 conf.status_device()
580 580
581 581 return redirect(conf.get_absolute_url())
582 582
583 583 def dev_conf_status(request, id_conf):
584 584
585 585 conf = get_object_or_404(Configuration, pk=id_conf)
586 586
587 587 DevConfModel = CONF_MODELS[conf.device.device_type.name]
588 588
589 589 conf = DevConfModel.objects.get(pk=id_conf)
590 590
591 591 if conf.status_device():
592 592 messages.success(request, conf.message)
593 593 else:
594 594 messages.error(request, conf.message)
595 595
596 596 return redirect(conf.get_absolute_url())
597 597
598 598
599 599 def dev_conf_write(request, id_conf):
600 600
601 601 conf = get_object_or_404(Configuration, pk=id_conf)
602 602
603 603 DevConfModel = CONF_MODELS[conf.device.device_type.name]
604 604
605 605 conf = DevConfModel.objects.get(pk=id_conf)
606 606
607 607 answer = conf.write_device()
608 608 conf.status_device()
609 609
610 610 if answer:
611 611 messages.success(request, conf.message)
612 612
613 613 #Creating a historical configuration
614 614 conf.pk = None
615 615 conf.id = None
616 616 conf.type = 1
617 617 conf.template = 0
618 618 conf.save()
619 619
620 620 #Original configuration
621 621 conf = DevConfModel.objects.get(pk=id_conf)
622 622 else:
623 623 messages.error(request, conf.message)
624 624
625 625 return redirect(conf.get_absolute_url())
626 626
627 627 def dev_conf_read(request, id_conf):
628 628
629 629 conf = get_object_or_404(Configuration, pk=id_conf)
630 630
631 631 DevConfModel = CONF_MODELS[conf.device.device_type.name]
632 632 DevConfForm = CONF_FORMS[conf.device.device_type.name]
633 633
634 634 conf = DevConfModel.objects.get(pk=id_conf)
635 635
636 636 if request.method=='GET':
637 637
638 638 parms = conf.read_device()
639 639 conf.status_device()
640 640
641 641 if not parms:
642 642 messages.error(request, conf.message)
643 643 return redirect(conf.get_absolute_url())
644 644
645 645 form = DevConfForm(initial=parms, instance=conf)
646 646
647 647 if request.method=='POST':
648 648 form = DevConfForm(request.POST, instance=conf)
649 649
650 650 if form.is_valid():
651 651 form.save()
652 652 return redirect(conf.get_absolute_url())
653 653
654 654 messages.error(request, "Parameters could not be saved")
655 655
656 656 kwargs = {}
657 657 kwargs['id_dev'] = conf.id
658 658 kwargs['form'] = form
659 659 kwargs['title'] = 'Device Configuration'
660 660 kwargs['suptitle'] = 'Parameters read from device'
661 661 kwargs['button'] = 'Save'
662 662
663 663 ###### SIDEBAR ######
664 664 kwargs.update(sidebar(conf))
665 665
666 666 return render(request, '%s_conf_edit.html' %conf.device.device_type.name, kwargs)
667 667
668 668 def dev_conf_import(request, id_conf):
669 669
670 670 conf = get_object_or_404(Configuration, pk=id_conf)
671 671
672 672 DevConfModel = CONF_MODELS[conf.device.device_type.name]
673 673 DevConfForm = CONF_FORMS[conf.device.device_type.name]
674 674
675 675 conf = DevConfModel.objects.get(pk=id_conf)
676 676
677 677 if request.method == 'GET':
678 678 file_form = UploadFileForm()
679 679
680 680 if request.method == 'POST':
681 681 file_form = UploadFileForm(request.POST, request.FILES)
682 682
683 683 if file_form.is_valid():
684 684
685 685 parms = conf.import_from_file(request.FILES['file'])
686 686
687 687 if parms:
688 688 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
689 689 print parms
690 690 form = DevConfForm(initial=parms, instance=conf)
691 691
692 692 kwargs = {}
693 693 kwargs['id_dev'] = conf.id
694 694 kwargs['form'] = form
695 695 kwargs['title'] = 'Device Configuration'
696 696 kwargs['suptitle'] = 'Parameters imported'
697 697 kwargs['button'] = 'Save'
698 698 kwargs['action'] = conf.get_absolute_url_edit()
699 699 kwargs['previous'] = conf.get_absolute_url()
700 700
701 701 ###### SIDEBAR ######
702 702 kwargs.update(sidebar(conf))
703 703
704 return render(request, '%s_conf_edit.html' %conf.device.device_type.name, kwargs)
704 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
705 705
706 706 messages.error(request, "Could not import parameters from file")
707 707
708 708 kwargs = {}
709 709 kwargs['id_dev'] = conf.id
710 710 kwargs['title'] = 'Device Configuration'
711 711 kwargs['form'] = file_form
712 712 kwargs['suptitle'] = 'Importing file'
713 713 kwargs['button'] = 'Import'
714 714
715 715 kwargs.update(sidebar(conf))
716 716
717 717 return render(request, 'dev_conf_import.html', kwargs)
718 718
719 719 def dev_conf_export(request, id_conf):
720 720
721 721 conf = get_object_or_404(Configuration, pk=id_conf)
722 722
723 723 DevConfModel = CONF_MODELS[conf.device.device_type.name]
724 724
725 725 conf = DevConfModel.objects.get(pk=id_conf)
726 726
727 727 if request.method == 'GET':
728 728 file_form = DownloadFileForm(conf.device.device_type.name)
729 729
730 730 if request.method == 'POST':
731 731 file_form = DownloadFileForm(conf.device.device_type.name, request.POST)
732 732
733 733 if file_form.is_valid():
734 734 fields = conf.export_to_file(format = file_form.cleaned_data['format'])
735 735
736 736 response = HttpResponse(content_type=fields['content_type'])
737 737 response['Content-Disposition'] = 'attachment; filename="%s"' %fields['filename']
738 738 response.write(fields['content'])
739 739
740 740 return response
741 741
742 742 messages.error(request, "Could not export parameters")
743 743
744 744 kwargs = {}
745 745 kwargs['id_dev'] = conf.id
746 746 kwargs['title'] = 'Device Configuration'
747 747 kwargs['form'] = file_form
748 748 kwargs['suptitle'] = 'Exporting file'
749 749 kwargs['button'] = 'Export'
750 750
751 751 return render(request, 'dev_conf_export.html', kwargs)
752 752
753 753 def dev_conf_delete(request, id_conf):
754 754
755 755 conf = get_object_or_404(Configuration, pk=id_conf)
756 756
757 757 if request.method=='POST':
758 758 if request.user.is_staff:
759 759 id_exp = conf.experiment.id
760 760 conf.delete()
761 761 return redirect('url_experiment', id_exp=id_exp)
762 762
763 763 return HttpResponse("Not enough permission to delete this object")
764 764
765 765 kwargs = {'object':conf, 'conf_active':'active',
766 766 'url_cancel':'url_dev_conf', 'id_item':id_conf}
767 767
768 768 ###### SIDEBAR ######
769 769 kwargs.update(sidebar(conf))
770 770
771 771 return render(request, 'item_delete.html', kwargs)
772 772
773 773 def sidebar(conf):
774 774
775 experiments = Experiment.objects.filter(campaign=conf.experiment.campaign)
776 configurations = Configuration.objects.filter(experiment=conf.experiment, type=0)
777
778 exp_keys = ['id', 'campaign', 'name', 'start_time', 'end_time']
779 conf_keys = ['id', 'device']
780
781 775 kwargs = {}
782 776
783 kwargs['dev_conf'] = conf
784
785 kwargs['experiment_keys'] = exp_keys[1:]
786 kwargs['experiments'] = experiments.values(*exp_keys)
787
788 kwargs['configuration_keys'] = conf_keys[1:]
789 kwargs['configurations'] = configurations #.values(*conf_keys)
777 if conf.experiment:
778 experiments = Experiment.objects.filter(campaign=conf.experiment.campaign)
779 configurations = Configuration.objects.filter(experiment=conf.experiment, type=0)
780 exp_keys = ['id', 'campaign', 'name', 'start_time', 'end_time']
781 kwargs['experiment_keys'] = exp_keys[1:]
782 kwargs['experiments'] = experiments.values(*exp_keys)
783 conf_keys = ['id', 'device']
784 kwargs['configuration_keys'] = conf_keys[1:]
785 kwargs['configurations'] = configurations #.values(*conf_keys)
790 786
791 787 return kwargs
792 788
793 789
794 790 def operation(request, id_camp=None):
795 791
796 792 if not id_camp:
797 793 campaigns = Campaign.objects.all().order_by('-start_date')
798 794
799 795 if not campaigns:
800 796 kwargs = {}
801 797 kwargs['title'] = 'No Campaigns'
802 798 kwargs['suptitle'] = 'Empty'
803 799 return render(request, 'operation.html', kwargs)
804 800
805 801 id_camp = campaigns[0].id
806 802
807 803 campaign = get_object_or_404(Campaign, pk = id_camp)
808 804
809 805 if request.method=='GET':
810 806 form = OperationForm(initial={'campaign': campaign.id}, length = 5)
811 807
812 808 if request.method=='POST':
813 809 form = OperationForm(request.POST, initial={'campaign':campaign.id}, length = 5)
814 810
815 811 if form.is_valid():
816 812 return redirect('url_operation', id_camp=campaign.id)
817 813 locations = Location.objects.filter(experiment__campaign__pk = campaign.id).distinct()
818 814 experiments = Experiment.objects.filter(campaign__pk=campaign.id)
819 815 #experiments = [Experiment.objects.filter(location__pk=location.id).filter(campaign__pk=campaign.id) for location in locations]
820 816 kwargs = {}
821 817 #---Campaign
822 818 kwargs['campaign'] = campaign
823 819 kwargs['campaign_keys'] = ['name', 'start_date', 'end_date', 'tags', 'description']
824 820 #---Experiment
825 821 keys = ['id', 'name', 'start_time', 'end_time']
826 822 kwargs['experiment_keys'] = keys[1:]
827 823 kwargs['experiments'] = experiments
828 824 #---Radar
829 825 kwargs['locations'] = locations
830 826 #---Else
831 827 kwargs['title'] = 'Campaign'
832 828 kwargs['suptitle'] = campaign.name
833 829 kwargs['form'] = form
834 830 kwargs['button'] = 'Search'
835 831 kwargs['details'] = True
836 832 kwargs['search_button'] = True
837 833
838 834 return render(request, 'operation.html', kwargs)
839 835
840 836 def operation_search(request, id_camp=None, location_play = None):
841 837
842 838
843 839 if not id_camp:
844 840 campaigns = Campaign.objects.all().order_by('-start_date')
845 841 form = OperationSearchForm()
846 842
847 843 if not campaigns:
848 844 return render(request, 'operation.html', {})
849 845
850 846 id_camp = campaigns[0].id
851 847 campaign = get_object_or_404(Campaign, pk = id_camp)
852 848
853 849 kwargs = {}
854 850 kwargs['title'] = 'All Campaigns'
855 851 kwargs['form'] = form
856 852 kwargs['details'] = True
857 853 return render(request, 'operation.html', kwargs)
858 854
859 855 else:
860 856 campaign = get_object_or_404(Campaign, pk = id_camp)
861 857 locations = Location.objects.filter(experiment__campaign__pk = campaign.id).distinct()
862 858 experiments = Experiment.objects.filter(campaign__pk=campaign.id)
863 859 #experiments = [Experiment.objects.filter(location__pk=location.id).filter(campaign__pk=campaign.id) for location in locations]
864 860 form = OperationSearchForm(initial={'campaign': campaign.id})
865 861
866 862 kwargs = {}
867 863 #---Campaign
868 864 kwargs['campaign'] = campaign
869 865 kwargs['campaign_keys'] = ['name', 'start_date', 'end_date', 'tags', 'description']
870 866 #---Experiment
871 867 keys = ['id', 'name', 'start_time', 'end_time']
872 868 kwargs['experiment_keys'] = keys[1:]
873 869 kwargs['experiments'] = experiments
874 870 #---Radar
875 871 kwargs['locations'] = locations
876 872 #---Else
877 873 kwargs['title'] = 'Campaign'
878 874 kwargs['suptitle'] = campaign.name
879 875 kwargs['form'] = form
880 876 kwargs['button'] = 'Select'
881 877 kwargs['details'] = True
882 878 kwargs['search_button'] = False
883 879
884 880
885 881 if request.method=='POST':
886 882 form = OperationSearchForm(request.POST, initial={'campaign':campaign.id})
887 883
888 884 if form.is_valid():
889 885 return redirect('operation.html', id_camp=campaign.id)
890 886
891 887
892 888 return render(request, 'operation.html', kwargs) No newline at end of file
@@ -1,223 +1,336
1 1 import os
2 import ast
2 3 import json
3 4
4 5 from django import forms
5 6 from django.utils.safestring import mark_safe
6 7 from apps.main.models import Device
7 8 from apps.main.forms import add_empty_choice
8 9 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode
10 from .widgets import KmUnitWidget, KmUnitHzWidget, KmUnitDcWidget, UnitKmWidget, DefaultWidget, CodesWidget, HiddenWidget
9 11
10 def create_choices_from_model(model, conf_id):
12 def create_choices_from_model(model, conf_id, all=False):
11 13
12 14 if model=='RCLine':
13 15 instance = RCConfiguration.objects.get(pk=conf_id)
14 choices = instance.get_refs_lines()
16 choices = [(line.pk, line.get_name()) for line in instance.get_lines(type='tx')]
17 choices = add_empty_choice(choices, label='All')
15 18 else:
16 19 instance = globals()[model]
17 20 choices = instance.objects.all().values_list('pk', 'name')
18 21
19 return add_empty_choice(choices, label='All')
22 return choices
20 23
21 24
22 25 class ExtFileField(forms.FileField):
23 26 """
24 27 Same as forms.FileField, but you can specify a file extension whitelist.
25 28
26 29 >>> from django.core.files.uploadedfile import SimpleUploadedFile
27 30 >>>
28 31 >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
29 32 >>>
30 33 >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
31 34 >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
32 35 >>>
33 36 >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
34 37 Traceback (most recent call last):
35 38 ...
36 39 ValidationError: [u'Not allowed filetype!']
37 40 """
38 41 def __init__(self, *args, **kwargs):
39 42 extensions = kwargs.pop("extensions")
40 43 self.extensions = [i.lower() for i in extensions]
41 44
42 45 super(ExtFileField, self).__init__(*args, **kwargs)
43 46
44 47 def clean(self, *args, **kwargs):
45 48 data = super(ExtFileField, self).clean(*args, **kwargs)
46 49 filename = data.name
47 50 ext = os.path.splitext(filename)[1]
48 51 ext = ext.lower()
49 52 if ext not in self.extensions:
50 raise forms.ValidationError('Not allowed filetype: %s' % ext)
53 raise forms.ValidationError('Not allowed file type: %s' % ext)
51 54
52 55
53 class KmUnitWidget(forms.widgets.TextInput):
54
55 def render(self, name, value, attrs=None):
56
57 if isinstance(value, (int, float)):
58 unit = int(value*attrs['line'].km2unit)
59 elif isinstance(value, basestring):
60 units = []
61 values = [s for s in value.split(',') if s]
62 for val in values:
63 units.append('{0:.0f}'.format(float(val)*attrs['line'].km2unit))
64
65 unit = ','.join(units)
66
67 html = '<div class="col-md-4"><input disabled type="text" class="form-control" id="id_{0}" value="{1}"></div><div class="col-md-1">Km</div><div class="col-md-4"><input disabled type="text" class="form-control" value="{2}"></div><div class="col-md-1">Units</div>'.format(name, value, unit)
68
69 return mark_safe(html)
70
71 class DefaultWidget(forms.widgets.TextInput):
72
73 def render(self, name, value, attrs=None):
74
75 html = '<div class="col-md-4"><input disabled type="text" class="form-control" id="id_{0}" value="{1}"></div>'.format(name, value)
76
77 return mark_safe(html)
78
79 56 class RCConfigurationForm(forms.ModelForm):
80 57
81 58 def __init__(self, *args, **kwargs):
82 59 super(RCConfigurationForm, self).__init__(*args, **kwargs)
83 60
84 61 instance = getattr(self, 'instance', None)
85 62
86 63 if instance and instance.pk:
87 64
88 65 devices = Device.objects.filter(device_type__name='rc')
89
90 self.fields['experiment'].widget.attrs['readonly'] = True
91 self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
92
66 if instance.experiment:
67 self.fields['experiment'].widget.attrs['readonly'] = True
68 self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
93 69 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
70 self.fields['ipp'].widget = KmUnitHzWidget(attrs={'km2unit':instance.km2unit})
71 self.fields['clock'].widget.attrs['readonly'] = True
72
73 self.fields['time_before'].label = mark_safe(self.fields['time_before'].label)
74 self.fields['time_after'].label = mark_safe(self.fields['time_after'].label)
75
94 76
95 77 class Meta:
96 78 model = RCConfiguration
97 79 exclude = ('type', 'parameters', 'status')
98 80
99
81 def clean(self):
82 form_data = super(RCConfigurationForm, self).clean()
83
84 if 'clock_divider' in form_data:
85 if form_data['clock_divider']<1:
86 self.add_error('clock_divider', 'Invalid Value')
87 else:
88 if form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))%10<>0:
89 self.add_error('ipp', 'Invalid IPP units={}'.format(form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))))
90
91 return form_data
100 92
101 93 class RCLineForm(forms.ModelForm):
102 94
103 95 def __init__(self, *args, **kwargs):
104 96 self.extra_fields = kwargs.pop('extra_fields', [])
105 97 super(RCLineForm, self).__init__(*args, **kwargs)
106 if 'initial'in kwargs:
107 for item in self.extra_fields:
108 if item['name']=='params':
98
99 if 'initial' in kwargs and 'line_type' in kwargs['initial']:
100 line_type = RCLineType.objects.get(pk=kwargs['initial']['line_type'])
101
102 if 'code_id' in kwargs['initial']:
103 model_initial = kwargs['initial']['code_id']
104 else:
105 model_initial = 0
106
107 params = json.loads(line_type.params)
108
109 for label, value in self.extra_fields.items():
110 if label=='params':
111 continue
112
113 if 'model' in params[label]:
114 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
115 kwargs['initial']['rc_configuration']),
116 initial=model_initial)
117
118
119 else:
120 if label=='codes' and 'code_id' in kwargs['initial']:
121 self.fields[label] = forms.CharField(initial=RCLineCode.objects.get(pk=kwargs['initial']['code_id']).codes)
122 else:
123 self.fields[label] = forms.CharField(initial=value['value'])
124
125 if label=='codes':
126 self.fields[label].widget = CodesWidget()
127
128 if self.data:
129 line_type = RCLineType.objects.get(pk=self.data['line_type'])
130
131 if 'code_id' in self.data:
132 model_initial = self.data['code_id']
133 else:
134 model_initial = 0
135
136 params = json.loads(line_type.params)
137
138 for label, value in self.extra_fields.items():
139 if label=='params':
109 140 continue
110 if 'model' in item:
111 self.fields[item['name']] = forms.ChoiceField(choices=create_choices_from_model(item['model'],
112 kwargs['initial']['rc_configuration']))
141
142 if 'model' in params[label]:
143 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
144 self.data['rc_configuration']),
145 initial=model_initial)
146
147
113 148 else:
114 self.fields[item['name']] = forms.CharField(initial=item['value'])
149 if label=='codes' and 'code' in self.data:
150 self.fields[label] = forms.CharField(initial=self.data['codes'])
151 else:
152 self.fields[label] = forms.CharField(initial=self.data[label])
115 153
154 if label=='codes':
155 self.fields[label].widget = CodesWidget()
156
157
116 158 class Meta:
117 159 model = RCLine
118 160 fields = ('rc_configuration', 'line_type', 'channel')
119 161 widgets = {
120 162 'channel': forms.HiddenInput(),
121 163 }
122 164
165
166 def clean(self):
167
168 form_data = self.cleaned_data
169 if 'code' in self.data and self.data['TX_ref']=="0":
170 self.add_error('TX_ref', 'Choose a valid TX reference')
171
172 return form_data
173
174
123 175 def save(self):
124 176 line = super(RCLineForm, self).save()
125 177
126 178 #auto add channel
127 179 line.channel = RCLine.objects.filter(rc_configuration=line.rc_configuration).count()-1
128 180
129 181 #auto add position for TX, TR & CODE
130 182 if line.line_type.name in ('tx', ):
131 183 line.position = RCLine.objects.filter(rc_configuration=line.rc_configuration, line_type=line.line_type).count()-1
132 184
133 185 #save extra fields in params
134 186 params = {}
135 for item in self.extra_fields:
136 if item['name']=='params':
187 for label, value in self.extra_fields.items():
188 if label=='params':
137 189 params['params'] = []
190 elif label=='codes':
191 params[label] = [s for s in self.data[label].split('\r\n') if s]
138 192 else:
139 params[item['name']] = self.data[item['name']]
193 params[label] = self.data[label]
140 194 line.params = json.dumps(params)
141 195 line.save()
142 196 return
143 197
144 198
145 199 class RCLineViewForm(forms.Form):
146 200
147 201 def __init__(self, *args, **kwargs):
202
148 203 extra_fields = kwargs.pop('extra_fields')
149 204 line = kwargs.pop('line')
150 205 subform = kwargs.pop('subform', False)
151 206 super(RCLineViewForm, self).__init__(*args, **kwargs)
152 print line
207
208 if subform:
209 params = json.loads(line.line_type.params)['params']
210 else:
211 params = json.loads(line.line_type.params)
212
153 213 for label, value in extra_fields.items():
214
154 215 if label=='params':
155 216 continue
156 217 if 'ref' in label:
157 218 if value in (0, '0'):
158 219 value = 'All'
159 220 else:
160 221 value = RCLine.objects.get(pk=value).get_name()
161 elif 'code' in label:
222 elif label=='code':
162 223 value = RCLineCode.objects.get(pk=value).name
163 224
164 self.fields[label] = forms.CharField(initial=value)
165
166 if subform:
167 params = json.loads(line.line_type.params)['params']
168 else:
169 params = json.loads(line.line_type.params)
225 self.fields[label] = forms.CharField(initial=value)
170 226
171 227 if 'widget' in params[label]:
228 km2unit = line.rc_configuration.km2unit
172 229 if params[label]['widget']=='km':
173 self.fields[label].widget = KmUnitWidget(attrs={'line':line})
230 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
231 elif params[label]['widget']=='unit':
232 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
233 elif params[label]['widget']=='dc':
234 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
235 elif params[label]['widget']=='codes':
236 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
174 237 else:
175 self.fields[label].widget = DefaultWidget()
238 self.fields[label].widget = DefaultWidget(attrs={'disabled':True})
239
176 240
177 241 class RCLineEditForm(forms.ModelForm):
178 242
179 243 def __init__(self, *args, **kwargs):
180 self.extra_fields = kwargs.pop('extra_fields', [])
244
245 extra_fields = kwargs.pop('extra_fields', [])
246 conf = kwargs.pop('conf', False)
247 line = kwargs.pop('line')
248 subform = kwargs.pop('subform', False)
249
181 250 super(RCLineEditForm, self).__init__(*args, **kwargs)
182 if 'initial'in kwargs:
183 for item, values in self.extra_fields.items():
184 if item=='params':
185 continue
186 if 'help' in values:
187 help_text = values['help']
188 else:
189 help_text = ''
251
252 if subform is not False:
253 params = json.loads(line.line_type.params)['params']
254 count = subform
255 else:
256 params = json.loads(line.line_type.params)
257 count = -1
258
259 for label, value in extra_fields.items():
260
261 if label in ('params',):
262 continue
263 if 'help' in params[label]:
264 help_text = params[label]['help']
265 else:
266 help_text = ''
267
268 if 'model' in params[label]:
269 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'], conf.id),
270 initial=value,
271 widget=forms.Select(attrs={'name':'%s|%s|%s' % (count, line.id, label)}),
272 help_text=help_text)
190 273
191 if 'model' in values:
192 self.fields[item] = forms.ChoiceField(choices=create_choices_from_model(values['model'], kwargs['initial']['rc_configuration']),
193 initial=values['value'],
194 widget=forms.Select(attrs={'name':'%s|%s' % (kwargs['initial']['line'], item)}),
195 help_text=help_text)
196
197 else:
198 self.fields[item] = forms.CharField(initial=values['value'],
199 widget=forms.TextInput(attrs={'name':'%s|%s' % (kwargs['initial']['line'], item)}),
200 help_text=help_text)
201
202
274 else:
275
276 self.fields[label] = forms.CharField(initial=value, help_text=help_text)
277
278 if label in ('code', ):
279 self.fields[label].widget = HiddenWidget(attrs={'name':'%s|%s|%s' % (count, line.id, label)})
280
281 elif 'widget' in params[label]:
282 km2unit = line.rc_configuration.km2unit
283 if params[label]['widget']=='km':
284 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
285 elif params[label]['widget']=='unit':
286 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
287 elif params[label]['widget']=='dc':
288 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
289 elif params[label]['widget']=='codes':
290 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
291 else:
292 self.fields[label].widget = DefaultWidget(attrs={'name':'%s|%s|%s' % (count, line.id, label)})
293
294
203 295 class Meta:
204 296 model = RCLine
205 297 exclude = ('rc_configuration', 'line_type', 'channel', 'position', 'params', 'pulses')
206 298
207 299
208 300 class RCSubLineEditForm(forms.Form):
209 301
210 302 def __init__(self, *args, **kwargs):
211 303 extra_fields = kwargs.pop('extra_fields')
212 304 count = kwargs.pop('count')
213 305 line = kwargs.pop('line')
214 306 super(RCSubLineEditForm, self).__init__(*args, **kwargs)
215 307 for label, value in extra_fields.items():
216 308 self.fields[label] = forms.CharField(initial=value,
217 309 widget=forms.TextInput(attrs={'name':'%s|%s|%s' % (count, line, label)}))
218 310
219 311
220 312 class RCImportForm(forms.Form):
221 313
222 314 file_name = ExtFileField(extensions=['.racp', '.json', '.dat'])
315
316
317 class RCLineCodesForm(forms.ModelForm):
318
319 def __init__(self, *args, **kwargs):
320 super(RCLineCodesForm, self).__init__(*args, **kwargs)
321
322 if 'initial' in kwargs:
323 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
324 initial=kwargs['initial']['code'])
325 if 'instance' in kwargs:
326 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
327 initial=kwargs['instance'].pk)
328
329 self.fields['codes'].widget = CodesWidget()
330
331
332 class Meta:
333 model = RCLineCode
334 exclude = ('name',)
335
223 336 No newline at end of file
@@ -1,236 +1,530
1 1
2 2 import ast
3 3 import json
4 4 import numpy as np
5 5
6 6 from polymorphic import PolymorphicModel
7 7
8 8 from django.db import models
9 from django.core.urlresolvers import reverse
9 10 from django.core.validators import MinValueValidator, MaxValueValidator
10 11
11 12 from apps.main.models import Configuration
12 from .utils import pulses, pulses_from_code, create_mask
13 from .utils import RCFile, pulses, pulses_from_code, create_mask, pulses_to_points
14
13 15 # Create your models here.
14 16
15 17 LINE_TYPES = (
16 18 ('none', 'Not used'),
17 19 ('tr', 'Transmission/reception selector signal'),
18 20 ('tx', 'A modulating signal (Transmission pulse)'),
19 21 ('codes', 'BPSK modulating signal'),
20 22 ('windows', 'Sample window signal'),
21 23 ('sync', 'Synchronizing signal'),
22 24 ('flip', 'IPP related periodic signal'),
23 25 ('prog_pulses', 'Programmable pulse'),
24 26 )
25 27
26 28
29 SAMPLING_REFS = (
30 ('none', 'No Reference'),
31 ('first_baud', 'Middle of the first baud'),
32 ('sub_baud', 'Middle of the sub-baud')
33 )
34
35 DAT_CMDS = {
36 # Pulse Design commands
37 'DISABLE' : 0, # Disables pulse generation
38 'ENABLE' : 24, # Enables pulse generation
39 'DELAY_START' : 40, # Write delay status to memory
40 'FLIP_START' : 48, # Write flip status to memory
41 'SAMPLING_PERIOD' : 64, # Establish Sampling Period
42 'TX_ONE' : 72, # Output '0' in line TX
43 'TX_ZERO' : 88, # Output '0' in line TX
44 'SW_ONE' : 104, # Output '0' in line SW
45 'SW_ZERO' : 112, # Output '1' in line SW
46 'RESTART': 120, # Restarts CR8 Firmware
47 'CONTINUE' : 253, # Function Unknown
48 # Commands available to new controllers
49 # In Pulse Design Executable, the clock divisor code is written as 12 at the start, but it should be written as code 22(below) just before the final enable.
50 'CLOCK_DIVISOR_INIT' : 12, # Specifies Clock Divisor. Legacy command, ignored in the actual .dat conversion
51 'CLOCK_DIVISOR_LAST' : 22, # Specifies Clock Divisor (default 60 if not included) syntax: 255,22 254,N-1.
52 'CLOCK_DIVIDER' : 8,
53 }
54
55
27 56 class RCConfiguration(Configuration):
28 57
29 58 ipp = models.FloatField(verbose_name='Inter pulse period (Km)', validators=[MinValueValidator(1), MaxValueValidator(1000)], default=10)
30 ntx = models.PositiveIntegerField(verbose_name='Number of TX', default=1)
31 clock = models.FloatField(verbose_name='Clock Master (MHz)', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
59 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
60 clock_in = models.FloatField(verbose_name='Clock in (MHz)', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
32 61 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
33 time_before = models.PositiveIntegerField(verbose_name='Time before', default=0)
34 time_after = models.PositiveIntegerField(verbose_name='Time after', default=0)
62 clock = models.FloatField(verbose_name='Clock Master (MHz)', blank=True, default=1)
63 time_before = models.PositiveIntegerField(verbose_name='Time before (&mu;S)', default=0)
64 time_after = models.PositiveIntegerField(verbose_name='Time after (&mu;S)', default=0)
35 65 sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
66 sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40)
67 control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False)
68 control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
69
36 70
37 71 class Meta:
38 72 db_table = 'rc_configurations'
39
40 def get_number_position(self):
73
74
75 def get_absolute_url_plot(self):
76 return reverse('url_plot_rc_pulses', args=[str(self.id)])
77
78 def get_absolute_url_import(self):
79 return reverse('url_import_rc_conf', args=[str(self.id)])
80
81 @property
82 def us2unit(self):
41 83
42 lines = RCLine.objects.filter(rc_configuration=self.rc_configuration)
43 if lines:
44 return max([line.position for line in lines])
84 return self.clock_in/self.clock_divider
85
45 86
46 def get_refs_lines(self):
87 @property
88 def km2unit(self):
47 89
48 lines = RCLine.objects.filter(rc_configuration=self.pk, line_type__name='tx')
49 return [(line.pk, line.get_name()) for line in lines]
90 return 20./3*(self.clock_in/self.clock_divider)
91
50 92
51 93 def get_lines(self, type=None):
94 '''
95 Retrieve configuration lines
96 '''
52 97
53 98 if type is not None:
54 99 return RCLine.objects.filter(rc_configuration=self.pk, line_type__name=type)
55 100 else:
56 101 return RCLine.objects.filter(rc_configuration=self.pk)
57 102
103 def clean_lines(self):
104 '''
105 '''
106
107 empty_line = RCLineType.objects.get(pk=8)
108
109 for line in self.get_lines():
110 line.line_type = empty_line
111 line.params = '{}'
112 line.save()
113
114 def parms_to_dict(self):
115 '''
116 '''
117
118 data = {}
119 for field in self._meta.fields:
120
121 data[field.name] = '{}'.format(field.value_from_object(self))
122
123 data.pop('parameters')
124 data['lines'] = []
125
126 for line in self.get_lines():
127 line_data = json.loads(line.params)
128 if 'TX_ref' in line_data and line_data['TX_ref'] not in (0, '0'):
129 line_data['TX_ref'] = RCLine.objects.get(pk=line_data['TX_ref']).get_name()
130 if 'code' in line_data:
131 line_data['code'] = RCLineCode.objects.get(pk=line_data['code']).name
132 line_data['type'] = line.line_type.name
133 data['lines'].append(line_data)
134
135
136 return data
137
138 def get_delays(self):
139
140 pulses = [line.get_pulses() for line in self.get_lines()]
141 points = [tup for tups in pulses for tup in tups]
142 points = set([x for tup in points for x in tup])
143 points = list(points)
144 points.sort()
145
146 if points[0]<>0:
147 points.insert(0, 0)
148
149 return [points[i+1]-points[i] for i in range(len(points)-1)]
150
151
152 def get_flips(self):
153
154 line_points = [pulses_to_points(line.pulses_as_array()) for line in self.get_lines()]
155 line_points = [[(x, x+y) for x,y in tups] for tups in line_points]
156 line_points = [[t for x in tups for t in x] for tups in line_points]
157 states = [[1 if x in tups else 0 for tups in line_points] for x in points]
158
159 return states
160
161 def add_cmd(self, cmd):
162
163 if cmd in DAT_CMDS:
164 return (255, DAT_CMDS[cmd])
165
166 def add_data(self, value):
167
168 return (254, value-1)
169
170 def parms_to_binary(self):
171 '''
172 Create "dat" stream to be send to CR
173 '''
174
175 data = []
176 # create header
177 data.append(self.add_cmd('DISABLE'))
178 data.append(self.add_cmd('CONTINUE'))
179 data.append(self.add_cmd('RESTART'))
180
181 if self.control_sw:
182 data.append(self.add_cmd('SW_ONE'))
183 else:
184 data.append(self.add_cmd('SW_ZERO'))
185
186 if self.control_tx:
187 data.append(self.add_cmd('TX_ONE'))
188 else:
189 data.append(self.add_cmd('TX_ZERO'))
190
191 # write divider
192 data.append(self.add_cmd('CLOCK_DIVIDER'))
193 data.append(self.add_data(self.clock_divider))
194
195 # write delays
196 data.append(self.add_cmd('DELAY_START'))
197 # first delay is always zero
198 data.append(self.add_data(1))
199 line_points = [pulses_to_points(line.pulses_as_array()) for line in self.get_lines()]
200 points = [tup for tups in line_points for tup in tups]
201 points = [(x, x+y) for x,y in points]
202 points = set([x for tup in points for x in tup])
203 points = list(points)
204 points.sort()
205
206 if points[0]<>0:
207 points.insert(0, 0)
208
209 delays = [points[i+1]-points[i] for i in range(len(points)-1)]
210
211 for delay in delays:
212 while delay>252:
213 data.append(self.add_data(253))
214 delay -= 253
215 data.append(self.add_data(delay))
216
217 # write flips
218 data.append(self.add_cmd('FLIP_START'))
219 line_points = [[(x, x+y) for x,y in tups] for tups in line_points]
220 line_points = [[t for x in tups for t in x] for tups in line_points]
221 states = [[1 if x in tups else 0 for tups in line_points] for x in points]
222 for flips, delay in zip(states[:-1], delays):
223 flips.reverse()
224 flip = int(''.join([str(x) for x in flips]), 2)
225 data.append(self.add_data(flip+1))
226 while delay>252:
227 data.append(self.add_data(1))
228 delay -= 253
229
230 # write sampling period
231 data.append(self.add_cmd('SAMPLING_PERIOD'))
232 wins = self.get_lines(type='windows')
233 if wins:
234 win_params = json.loads(wins[0].params)['params']
235 if win_params:
236 dh = int(win_params[0]['resolution']*self.km2unit)
237 else:
238 dh = 1
239 else:
240 dh = 1
241 data.append(self.add_data(dh))
242
243 # write enable
244 data.append(self.add_cmd('ENABLE'))
245
246 return '\n'.join(['{}'.format(x) for tup in data for x in tup])
247
248 def update_from_file(self, filename):
249 '''
250 Update instance from file
251 '''
252
253 f = RCFile(filename)
254 data = f.data
255 self.name = data['name']
256 self.ipp = data['ipp']
257 self.ntx = data['ntx']
258 self.clock_in = data['clock_in']
259 self.clock_divider = data['clock_divider']
260 self.clock = data['clock']
261 self.time_before = data['time_before']
262 self.time_after = data['time_after']
263 self.sync = data['sync']
264 self.sampling_reference = data['sampling_reference']
265 self.clean_lines()
266
267 lines = []
268 positions = {'tx':0, 'tr':0}
269
270 for i, line_data in enumerate(data['lines']):
271 line_type = RCLineType.objects.get(name=line_data.pop('type'))
272 if line_type.name=='codes':
273 code = RCLineCode.objects.get(name=line_data['code'])
274 line_data['code'] = code.pk
275 line = RCLine.objects.filter(rc_configuration=self, channel=i)
276 if line:
277 line = line[0]
278 line.line_type = line_type
279 line.params = json.dumps(line_data)
280 else:
281 line = RCLine(rc_configuration=self, line_type=line_type,
282 params=json.dumps(line_data),
283 channel=i)
284
285 if line_type.name=='tx':
286 line.position = positions['tx']
287 positions['tx'] += 1
288
289 if line_type.name=='tr':
290 line.position = positions['tr']
291 positions['tr'] += 1
292
293 line.save()
294 lines.append(line)
295
296 for line, line_data in zip(lines, data['lines']):
297 if 'TX_ref' in line_data:
298 params = json.loads(line.params)
299 if line_data['TX_ref'] in (0, '0'):
300 params['TX_ref'] = '0'
301 else:
302 params['TX_ref'] = [l.pk for l in lines if l.line_type.name=='tx' and l.get_name()==line_data['TX_ref']][0]
303 line.params = json.dumps(params)
304 line.save()
305
58 306
59 307 class RCLineCode(models.Model):
60 308
61 309 name = models.CharField(max_length=40)
62 310 bits_per_code = models.PositiveIntegerField(default=0)
63 311 number_of_codes = models.PositiveIntegerField(default=0)
64 312 codes = models.TextField(blank=True, null=True)
65 313
66 314 class Meta:
67 315 db_table = 'rc_line_codes'
68 316 ordering = ('name',)
69 317
70 318 def __unicode__(self):
71 319 return u'%s' % self.name
72 320
73 321 class RCLineType(models.Model):
74 322
75 323 name = models.CharField(choices=LINE_TYPES, max_length=40)
76 324 description = models.TextField(blank=True, null=True)
77 325 params = models.TextField(default='[]')
78 326
79 327 class Meta:
80 328 db_table = 'rc_line_types'
81 329
82 330 def __unicode__(self):
83 331 return u'%s - %s' % (self.name.upper(), self.get_name_display())
84 332
85 333
86 334 class RCLine(models.Model):
87 335
88 336 rc_configuration = models.ForeignKey(RCConfiguration)
89 337 line_type = models.ForeignKey(RCLineType)
90 338 channel = models.PositiveIntegerField(default=0)
91 339 position = models.PositiveIntegerField(default=0)
92 340 params = models.TextField(default='{}')
93 341 pulses = models.TextField(default='')
94 342
95 343 class Meta:
96 344 db_table = 'rc_lines'
97 345 ordering = ['channel']
98 346
99 347 def __unicode__(self):
100 return u'%s - %s' % (self.rc_configuration, self.get_name())
348 if self.rc_configuration:
349 return u'%s - %s' % (self.rc_configuration, self.get_name())
101 350
102 351 def get_name(self):
103 352
104 353 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
105 354
106 355 if self.line_type.name in ('tx',):
107 return '%s %s' % (self.line_type.name.upper(), chars[self.position])
356 return '%s%s' % (self.line_type.name.upper(), chars[self.position])
108 357 elif self.line_type.name in ('codes', 'windows', 'tr'):
358 if 'TX_ref' not in json.loads(self.params):
359 return self.line_type.name.upper()
109 360 pk = json.loads(self.params)['TX_ref']
110 361 if pk in (0, '0'):
111 362 refs = ','.join(chars[l.position] for l in self.rc_configuration.get_lines('tx'))
112 363 return '%s (%s)' % (self.line_type.name.upper(), refs)
113 364 else:
114 365 ref = RCLine.objects.get(pk=pk)
115 366 return '%s (%s)' % (self.line_type.name.upper(), chars[ref.position])
116 elif self.line_type.name in ('flip', 'prog_pulses', 'sync'):
367 elif self.line_type.name in ('flip', 'prog_pulses', 'sync', 'none'):
117 368 return '%s %s' % (self.line_type.name.upper(), self.channel)
118 369 else:
119 370 return self.line_type.name.upper()
120 371
121 372 def get_lines(self, type=None):
122 373
123 374 if type is not None:
124 375 return RCLine.objects.filter(rc_configuration=self.rc_configuration, line_type__name=type)
125 376 else:
126 377 return RCLine.objects.filter(rc_configuration=self.rc_configuration)
127 378
379
128 380 def pulses_as_array(self):
129 381
130 382 return (np.fromstring(self.pulses, dtype=np.uint8)-48).astype(np.int8)
131 383
132 @property
133 def km2unit(self):
384
385 def get_pulses(self):
386
387 X = self.pulses_as_array()
388
389 d = X[1:]-X[:-1]
390
391 up = np.where(d==1)[0]
392 if X[0]==1:
393 up = np.concatenate((np.array([-1]), up))
394 up += 1
395
396 dw = np.where(d==-1)[0]
397 if X[-1]==1:
398 dw = np.concatenate((dw, np.array([len(X)-1])))
399 dw += 1
400
401 return [(tup[0], tup[1]) for tup in zip(up, dw)]
402
403 def get_win_ref(self, params, tx_id, km2unit):
404
405 ref = self.rc_configuration.sampling_reference
406
407 codes = [line for line in self.get_lines(type='code') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
408
409 if codes:
410 code_line = RCLineCode.objects.get(pk=json.loads(codes[0].params)['code'])
411 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/code_line.bits_per_code
412 else:
413 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
134 414
135 return 20./3*(self.rc_configuration.clock/self.rc_configuration.clock_divider)
415 if ref=='first_baud':
416 return int(1 + (tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit)
417 elif ref=='sub_baud':
418 return int(1 + params['first_height']*km2unit - params['resolution']*km2unit/2)
419 else:
420 return 0
136 421
137 422 def update_pulses(self, save=True, tr=False):
138 print self
139 KM2U = 20./3*(self.rc_configuration.clock/self.rc_configuration.clock_divider)
423 '''
424 Update pulses field
425 '''
426
427 km2unit = self.rc_configuration.km2unit
428 us2unit = self.rc_configuration.us2unit
140 429 ipp = self.rc_configuration.ipp
141 430 ntx = self.rc_configuration.ntx
142 ipp_u = int(ipp*KM2U)
431 ipp_u = int(ipp*km2unit)
143 432
144 433 x = np.arange(0, ipp_u*ntx)
145 434
146 435 if self.line_type.name=='tr':
147 436 params = json.loads(self.params)
148 437 if params['TX_ref'] in ('0', 0):
149 438 txs = [tx.update_pulses(save=False, tr=True) for tx in self.get_lines('tx')]
150 439 else:
151 440 txs = [tx.update_pulses(save=False, tr=True) for tx in RCLine.objects.filter(pk=params['TX_ref'])]
152 441 if len(txs)==0 or 0 in [len(tx) for tx in txs]:
153 442 return
154 443
155 y = np.any(txs, axis=0, out=np.ones(ipp_u*ntx))
444 y = np.any(txs, axis=0, out=np.ones(ipp_u*ntx))
156 445
157 446 ranges = params['range'].split(',')
158 447 if len(ranges)>0 and ranges[0]<>'0':
159 448 mask = create_mask(ranges, ipp_u, ntx, self.rc_configuration.sync)
160 449 y = y.astype(np.int8) & mask
161 450
162 451 elif self.line_type.name=='tx':
163 452 params = json.loads(self.params)
164 delays = [float(d)*KM2U for d in params['delays'].split(',') if d]
165 y = pulses(x, ipp_u, float(params['pulse_width'])*KM2U,
453 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
454 y = pulses(x, ipp_u, float(params['pulse_width'])*km2unit,
166 455 delay=delays,
167 before=self.rc_configuration.time_before,
168 after=self.rc_configuration.time_after if tr else 0,
456 before=int(self.rc_configuration.time_before*us2unit),
457 after=int(self.rc_configuration.time_after*us2unit) if tr else 0,
169 458 sync=self.rc_configuration.sync)
459
170 460 ranges = params['range'].split(',')
171
461
172 462 if len(ranges)>0 and ranges[0]<>'0':
173 463 mask = create_mask(ranges, ipp_u, ntx, self.rc_configuration.sync)
174 464 y = y & mask
175 465
176 466 elif self.line_type.name=='flip':
177 width = float(json.loads(self.params)['number_of_flips'])*ipp*KM2U
467 width = float(json.loads(self.params)['number_of_flips'])*ipp*km2unit
178 468 y = pulses(x, 2*width, width)
179 469
180 470 elif self.line_type.name=='codes':
181 471 params = json.loads(self.params)
182 codes = ast.literal_eval(RCLineCode.objects.get(pk=json.loads(self.params)['code']).codes)
472 #codes = ast.literal_eval(RCLineCode.objects.get(pk=json.loads(self.params)['code']).codes)
183 473 tx = RCLine.objects.get(pk=params['TX_ref'])
184 474 tx_params = json.loads(tx.params)
185 475
186 y = pulses_from_code(ipp_u, ntx, codes,
187 int(float(tx_params['pulse_width'])*KM2U),
188 before=self.rc_configuration.time_before+self.rc_configuration.sync)
476 y = pulses_from_code(ipp_u, ntx, params['codes'],
477 int(float(tx_params['pulse_width'])*km2unit),
478 before=int(self.rc_configuration.time_before*us2unit)+self.rc_configuration.sync)
189 479
190 480 ranges = tx_params['range'].split(',')
191 481 if len(ranges)>0 and ranges[0]<>'0':
192 482 mask = create_mask(ranges, ipp_u, ntx, self.rc_configuration.sync)
193 483 y = y.astype(np.int8) & mask
194 484
195 485 elif self.line_type.name=='sync':
196 486 params = json.loads(self.params)
197 487 y = np.zeros(ipp_u*ntx)
198 488 if params['invert'] in ('1', 1):
199 489 y[-1] = 1
200 490 else:
201 491 y[0] = 1
202 492
203 493 elif self.line_type.name=='prog_pulses':
204 494 params = json.loads(self.params)
205 495 if int(params['periodic'])==0:
206 496 nntx = ntx
207 497 else:
208 498 nntx = 1
209 499
210 500 if 'params' in params and len(params['params'])>0:
211 501 y = sum([pulses(x, ipp_u*nntx, (pp['end']-pp['begin']), shift=pp['begin']) for pp in params['params']])
212 502 else:
213 503 y = np.zeros(ipp_u*ntx)
214 504
215 505 elif self.line_type.name=='windows':
216 506 params = json.loads(self.params)
217 507 if 'params' in params and len(params['params'])>0:
218 y = sum([pulses(x, ipp_u, pp['resolution']*pp['number_of_samples']*KM2U,
219 delay=(pp['first_height']-pp['resolution'])*KM2U,
220 before=self.rc_configuration.time_before) for pp in params['params']])
508 print 'REFS'
509 print [self.get_win_ref(pp, params['TX_ref'],km2unit) for pp in params['params']]
510 y = sum([pulses(x, ipp_u, pp['resolution']*pp['number_of_samples']*km2unit,
511 shift=0,
512 before=int(self.rc_configuration.time_before*us2unit)+self.get_win_ref(pp, params['TX_ref'],km2unit),
513 sync=self.rc_configuration.sync) for pp in params['params']])
221 514 tr = self.get_lines('tr')[0]
222 515 ranges = json.loads(tr.params)['range'].split(',')
223 516 if len(ranges)>0 and ranges[0]<>'0':
224 517 mask = create_mask(ranges, ipp_u, ntx, self.rc_configuration.sync)
225 518 y = y & mask
226 519 else:
227 520 y = np.zeros(ipp_u*ntx)
228 521 else:
229 522 y = np.zeros(ipp_u*ntx)
230 523
231 524 if save:
232 525 self.pulses = (y+48).astype(np.uint8).tostring()
233 526 self.save()
234 527 else:
235 528 return y
236 No newline at end of file
529
530 No newline at end of file
@@ -1,13 +1,18
1 1 {% extends "dev_conf_edit.html" %}
2 2
3 3 {% block extra-js%}
4 4
5 5 <script type="text/javascript">
6 6
7 7 $("#id_line_type").change(function() {
8 8 var url = "{% url 'url_add_rc_line' dev_conf.id %}";
9 9 document.location = url + $(this).val()+"/";
10 10 });
11 11
12 $("#id_code").change(function() {
13 var url = "{% url 'url_add_rc_line' dev_conf.id line_type.id %}";
14 document.location = url+ "code/" + $(this).val() + "/";
15 });
16
12 17 </script>
13 18 {% endblock %} No newline at end of file
@@ -1,81 +1,18
1 1 {% extends "dev_conf.html" %}
2 2 {% load static %}
3 3 {% load bootstrap3 %}
4 4 {% load main_tags %}
5 5
6 {% block extra-head %}
7 <link href="http://cdn.pydata.org/bokeh/release/bokeh-0.11.1.min.css" rel="stylesheet" type="text/css">
6 {% block extra-menu-actions %}
7 <li><a href="{{ dev_conf.get_absolute_url_plot }}" target="_blank"><span class="glyphicon glyphicon-picture" aria-hidden="true"></span> View Pulses </a></li>
8 8 {% endblock %}
9 9
10 {% block content %}
11 <table class="table table-bordered">
12 <tr>
13 <th>Status</th>
14 <td>{%if connected == True %} <span class="glyphicon glyphicon-ok-circle text-success" aria-hidden="true"></span> Connected {% else %} <span class="glyphicon glyphicon-remove-circle text-danger" aria-hidden="true"></span> Disconnected {% endif %}</td>
15 </tr>
16 {% for key in dev_conf_keys %}
17 <tr>
18 <th>{% get_verbose_field_name dev_conf key %}</th>
19 <td>{{dev_conf|attr:key}}</td>
20 </tr>
21 {% endfor %}
22 </table>
23
10 {% block extra-content %}
24 11
25 12 <div class="clearfix"></div>
26 13 <h2>RC Lines</h2><hr>
27 14 <div class="panel-group" id="div_lines" role="tablist" aria-multiselectable="true">
28 15 {% include "rc_lines.html" %}
29 16 </div>
30 17
31 <br>
32 <button class="btn btn-primary pull-right" style="margin-left: 10px" id="bt_export">Export</button>
33 <button class="btn btn-primary pull-right" style="margin-left: 10px" id="bt_import">Import</button>
34 <button class="btn btn-primary pull-right" style="margin-left: 10px" id="bt_edit">Edit</button>
35
36 <button class="btn btn-primary pull-left" style="margin-left: 10px" id="bt_read">Read</button>
37 <button class="btn btn-primary pull-left" style="margin-left: 10px" id="bt_write">Write</button>
38 <button class="btn btn-primary pull-left" style="margin-left: 10px" id="bt_pulses">Pulses</button>
39
40 <div class="modal fade" id="pulsesModal" tabindex="-1" role="dialog">
41 <div class="modal-dialog modal-lg">
42 <div class="modal-content">
43 <div class="modal-header">
44 <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
45 <h4 class="modal-title">RC Pulses</h4>
46 </div>
47 <div class="modal-body">
48 <div id="div_plot"></div>
49 <div id="div_script"></div>
50 </div>
51 </div><!-- /.modal-content -->
52 </div><!-- /.modal-dialog -->
53 </div><!-- /.modal -->
54
55 {% endblock %}
56
57 {% block extra-js%}
58
59 <script src="{% static 'js/jquery-ui.min.js' %}"></script>
60 <script src="{% static 'js/bokeh-0.11.1.min.js' %}"></script>
61
62 <script type="text/javascript">
63
64 $("#bt_import").click(function() {
65 document.location = "{% url 'url_import_rc_conf' dev_conf.id %}";
66 });
67
68 $("#bt_edit").click(function() {
69 document.location = "{% url 'url_edit_rc_conf' dev_conf.id %}";
70 });
71
72 $("#bt_pulses").click(function() {
73 $.get( "plot/?json", {}, function(data){
74 $("#div_plot").html(data.div);
75 $("#div_script").html(data.script);
76 });
77 $('#pulsesModal').modal();
78 });
79
80 </script>
81 {% endblock %} No newline at end of file
18 {% endblock extra-content%}
@@ -1,67 +1,73
1 1 {% extends "dev_conf_edit.html" %}
2 2 {% load bootstrap3 %}
3 3 {% load static %}
4 4
5 5 {% block extra-head %}
6 6 <style type="text/css">
7 7 /* show the move cursor as the user moves the mouse over the panel header.*/
8 8 .panel-default { cursor: move; }
9 9 </style>
10 <script src="{% static 'js/jquery-ui.min.js' %}"></script>
11
10 12 {% endblock %}
11 13
12 14 {% block content %}
13 15 <form class="form" method="post">
14 16 {% csrf_token %}
15 17 {% bootstrap_form form layout='horizontal' size='medium' %}
16 18 <div style="clear: both;"></div>
17 19 <h2>RC Lines</h2><hr>
18 20 <div class="panel-group" id="div_lines" role="tablist" aria-multiselectable="true">
19 21 {% include "rc_lines.html" %}
20 22 </div>
21 23 <div style="clear: both;"></div>
22 24 <br>
23 25 <div class="pull-right">
24 26 <button type="button" class="btn btn-primary" onclick="{% if previous %}window.location.replace('{{ previous }}');{% else %}history.go(-1);{% endif %}">Cancel</button>
25 27 <button type="button" class="btn btn-primary" id="bt_add_line">Add Line</button>
26 28 <button type="submit" class="btn btn-primary">{{button}}</button>
27 29 </div>
28 30 </form>
29 31 {% endblock %}
30 32
31 33 {% block extra-js%}
32 34
33 <script src="{% static 'js/jquery-ui.min.js' %}"></script>
35 <script src="{% static 'js/cr.js' %}"></script>
34 36
35 37 <script type="text/javascript">
36 38
37 39 $("#div_lines").on("click", "button[name=bt_remove_line]", function(){
38 40 document.location = "/rc/{{dev_conf.id}}/line/"+$(this).val()+"/delete/";
39 41 });
40 42
41 43 $("#div_lines").on("click", "button[name=bt_remove_subline]", function(){
42 44 document.location = $(this).data('url');
43 45 });
44 46
45 47 $("#div_lines").on("click", "button[name=bt_add_subline]", function(){
46 48 document.location = "/rc/{{dev_conf.id}}/line/"+$(this).val()+"/add_subline/";
47 49 });
48 50
51 $("#div_lines").on("click", "button[name=bt_edit_codes]", function(){
52 document.location = "/rc/{{dev_conf.id}}/line/"+$(this).val()+"/codes/";
53 });
54
49 55 $("#bt_add_line").click(function() {
50 56 document.location = "{% url 'url_add_rc_line' dev_conf.id%}";
51 57 });
52 58
53 59 $(".panel-group").sortable({
54 60 //placeholder: "ui-state-highlight",
55 61 update: function( event, ui ) {
56 62 var sorted = $( ".panel-group" ).sortable( "serialize", { key: "item" } );
57 63 var url = "{% url 'url_update_rc_lines_position' dev_conf.id %}";
58 64 var csrf_token = "{{csrf_token}}";
59 65 $.post( url, { 'items': sorted, 'csrfmiddlewaretoken': csrf_token }, function(data){
60 66 $("#div_lines").html(data.html);
61 67 });
62 68 }
63 69 });
64 70
65 71 </script>
66 72 {% endblock %}
67 73 No newline at end of file
@@ -1,37 +1,41
1 1 {% load bootstrap3 %}
2 2
3 3 {% for line in rc_lines %}
4 4 <div class="panel panel-default" id="panel-{{line.id}}">
5 5 <div class="panel-heading" role="tab" id="heading{{line.id}}">
6 6 <h4 class="panel-title">
7 7 <a role="button" data-toggle="collapse" data-parent="#div_lines" href="#collapse{{line.id}}" aria-expanded="true" aria-controls="collapse{{line.id}}">
8 8 CH{{line.channel}} - {{line.get_name}}
9 9 </a>
10 10 {% if edit %}
11 11 <button type="button" class="btn-xs btn-default pull-right" name="bt_remove_line" value="{{line.pk}}"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></button>
12 12 {% endif %}
13 13 </h4>
14 14 </div>
15 15 <div id="collapse{{line.id}}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading{{line.id}}">
16 16 <div class="panel-body">
17 17 {% bootstrap_form line.form layout='horizontal' size='small' %}
18 <br><br>
18 <br><br>
19 {% for f in line.subforms %}
20 <div class="form-group form-group-sm">
21 <label class="col-md-3 control-label">{{line.line_type.name}}-{{ forloop.counter }}</label>
22 <div class="col-md-9">{% if edit %}<button type='button' name="bt_remove_subline" class="btn-xs btn-default" data-url="{% url 'url_remove_rc_subline' dev_conf.id line.id forloop.counter %}"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></button>{% endif %}</div>
23 </div><div class="clearfix"></div>
24 {% bootstrap_form f layout='horizontal' size='small' %}
25 <div class="clearfix"></div>
26 {% endfor %}
27
28 {% if edit and line.subform %}
29 <br>
30 <button type="button" class="btn btn-sm btn-default" style="margin-left: 10px" name="bt_add_subline" value="{{line.pk}}">Add {{line.line_type.name}}</button>
31 {% endif %}
19 32
20 {% for f in line.subforms %}
21 <div class="form-group form-group-sm">
22 <label class="col-md-3 control-label">{{line.line_type.name}}-{{ forloop.counter }}</label>
23 <div class="col-md-9">{% if edit %}<button type='button' name="bt_remove_subline" class="btn-xs btn-default" data-url="{% url 'url_remove_rc_subline' dev_conf.id line.id forloop.counter %}"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></button>{% endif %}</div>
24 </div><div class="clearfix"></div>
25 {% bootstrap_form f layout='horizontal' size='small' %}
26 <div class="clearfix"></div>
27 {% endfor %}
28
29 {% if edit and line.subform %}
30 <br>
31 <button type="button" class="btn btn-sm btn-default" style="margin-left: 10px" name="bt_add_subline" value="{{line.pk}}">Add {{line.line_type.name}}</button>
32 {% endif %}
33 {% if edit and line.line_type.name == 'codes' %}
34 <br>
35 <button type="button" class="btn btn-sm btn-default" style="margin-left: 10px" name="bt_edit_codes" value="{{line.pk}}">Edit</button>
36 {% endif %}
33 37
34 38 </div>
35 39 </div>
36 40 </div>
37 41 {% endfor%}
@@ -1,27 +1,20
1 1 {% extends "dev_conf.html" %}
2 2 {% load static %}
3 3 {% load bootstrap3 %}
4 4 {% load main_tags %}
5 5
6 6 {% block extra-head %}
7 7 <link href="http://cdn.pydata.org/bokeh/release/bokeh-0.11.1.min.css" rel="stylesheet" type="text/css">
8 8 {% endblock %}
9 9
10 10 {% block content %}
11
12
13
14 <div id="div_plot">{{div}}</div>
15
16
17
11 <div id="div_plot">{{div}}</div>
18 12 {% endblock %}
19 13
20 14 {% block extra-js%}
21 15
22 <script src="{% static 'js/jquery-ui.min.js' %}"></script>
23 16 <script src="{% static 'js/bokeh-0.11.1.min.js' %}"></script>
24 17
25 18 {{script}}
26 19
27 20 {% endblock %} No newline at end of file
@@ -1,18 +1,20
1 1 from django.conf.urls import url
2 2
3 3 urlpatterns = (
4 4 url(r'^(?P<conf_id>-?\d+)/$', 'apps.rc.views.conf', name='url_rc_conf'),
5 5 url(r'^(?P<conf_id>-?\d+)/import/$', 'apps.rc.views.import_file', name='url_import_rc_conf'),
6 6 url(r'^(?P<conf_id>-?\d+)/edit/$', 'apps.rc.views.conf_edit', name='url_edit_rc_conf'),
7 7 url(r'^(?P<conf_id>-?\d+)/plot/$', 'apps.rc.views.view_pulses', name='url_plot_rc_pulses'),
8 8 url(r'^(?P<id_conf>-?\d+)/write/$', 'apps.main.views.dev_conf_write', name='url_write_rc_conf'),
9 9 url(r'^(?P<id_conf>-?\d+)/read/$', 'apps.main.views.dev_conf_read', name='url_read_rc_conf'),
10 url(r'^(?P<id_conf>-?\d+)/export/$', 'apps.main.views.dev_conf_export', name='url_export_rc_conf'),
11 10
12 11 url(r'^(?P<conf_id>-?\d+)/add_line/$', 'apps.rc.views.add_line', name='url_add_rc_line'),
13 12 url(r'^(?P<conf_id>-?\d+)/add_line/(?P<line_type_id>-?\d+)/$', 'apps.rc.views.add_line', name='url_add_rc_line'),
13 url(r'^(?P<conf_id>-?\d+)/add_line/(?P<line_type_id>-?\d+)/code/(?P<code_id>-?\d+)/$', 'apps.rc.views.add_line', name='url_add_rc_line_code'),
14 14 url(r'^(?P<conf_id>-?\d+)/update_position/$', 'apps.rc.views.update_lines_position', name='url_update_rc_lines_position'),
15 15 url(r'^(?P<conf_id>-?\d+)/line/(?P<line_id>-?\d+)/delete/$', 'apps.rc.views.remove_line', name='url_remove_rc_line'),
16 16 url(r'^(?P<conf_id>-?\d+)/line/(?P<line_id>-?\d+)/add_subline/$', 'apps.rc.views.add_subline', name='url_add_rc_subline'),
17 url(r'^(?P<conf_id>-?\d+)/line/(?P<line_id>-?\d+)/codes/$', 'apps.rc.views.edit_codes', name='url_edit_rc_codes'),
18 url(r'^(?P<conf_id>-?\d+)/line/(?P<line_id>-?\d+)/codes/(?P<code_id>-?\d+)/$', 'apps.rc.views.edit_codes', name='url_edit_rc_codes'),
17 19 url(r'^(?P<conf_id>-?\d+)/line/(?P<line_id>-?\d+)/subline/(?P<subline_id>-?\d+)/delete/$', 'apps.rc.views.remove_subline', name='url_remove_rc_subline'),
18 20 )
This diff has been collapsed as it changes many lines, (718 lines changed) Show them Hide them
@@ -1,926 +1,314
1 import ast
2 import json
3 # import numpy as np
4 # import matplotlib.pyplot as plt
5 # from matplotlib import cm
6
7 class Pulse_Design_Racp:
8 """A class to define the .racp output from Pulse Design """
9 def __init__(self):
10 self.header = {'version': '1103', 'data':[]}
11 self.radar_param = {'header': '*****Radar Controller Parameters**********', 'data':[]}
12 self.system_param1 = {'header': '******System Parameters*******************', 'data':[]}
13 self.system_param2 = {'header': '******System Parameters*******************', 'data':[]}
14 self.process_param = {'header': '******Process Parameters******************', 'data':[]}
15 self.xml = None
16
17 self.header_fields = [
18 {'name': 'EXPERIMENT TYPE', 'xml': 'Experiment/Process/Signal_pre_processing/Type_of_experiment'},
19 {'name': 'EXPERIMENT NAME', 'xml': 'Experiment', 'xml_attr_value':'name'}]
20 self.radar_param_fields = [
21 {'name': 'IPP', 'xml': 'Experiment/Controller/IPP/Width'},
22 {'name': 'NTX', 'xml': 'Experiment/Controller/NTX'},
23 {'name': 'TXA', 'xml': 'Experiment/Controller/Transmitters/TX', 'xml_attr':'id', 'xml_attr_find':'txa', 'xml_sub_pattern':'Width'},
24 {'name': 'TXB', 'xml': 'Experiment/Controller/Transmitters/TX', 'xml_attr':'id', 'xml_attr_find':'txb', 'xml_sub_pattern':'Width'},
25 {'name': '***', 'xml':'', 'type':'pulse_enable'},
26 {'name': '***', 'xml':'', 'type': 'Line4'},
27 {'name': '***', 'xml':'', 'type': 'Line5'},
28 {'name': '***', 'xml':'', 'type': 'Line6'},
29 {'name': '***', 'xml':'', 'type':'txb_delays_info'},
30 {'name': '***', 'xml':'', 'type': 'Line7'},
31 {'name': 'SAMPLING REFERENCE', 'xml':'Experiment/Controller/Ctl_Setting/Sampling_reference'},
32 {'name': 'RELOJ', 'xml':'Experiment/Controller/Clock/Clock_final'},
33 {'name': 'CLOCK DIVIDER', 'xml':'Experiment/Controller/Clock/Clock_div', 'hide':['1']},
34 {'name': 'TR_BEFORE', 'xml':'Experiment/Controller/Spc_Setting/Time_before'},
35 {'name': 'TR_AFTER', 'xml':'Experiment/Controller/Spc_Setting/Time_after'},
36 {'name': 'WINDOW IN LINE 5&6', 'xml':'', 'value':'NO'},
37 {'name': 'SYNCHRO DELAY', 'xml':'Experiment/Controller/Spc_Setting/Sync_delay', 'hide':['0']}]
38 self.system_param1_fields = [
39 {'name': 'Number of Cards', 'xml':'Experiment/Process/JARS/Number_of_cards', 'hide':['0']},
40 {'name': '***', 'xml':'', 'type':'cards_info'},
41 {'name': '***', 'xml':'', 'type':'channels_info'},
42 {'name': 'RAW DATA DIRECTORY', 'xml':'Experiment/Process/Data_storage/Directory'},
43 {'name': 'CREATE DIRECTORY PER DAY', 'xml':'Experiment/Process/Data_storage/Directory_per_day', 'type':'checkbox_YES_NO'},
44 {'name': 'INCLUDE EXPNAME IN DIRECTORY', 'xml':'Experiment/Process/Data_storage/Expname_in_directory', 'type':'checkbox_YES_NO'}]
45 self.system_param2_fields = [
46 {'name': 'ADC Resolution', 'xml':'', 'value':'12'}, # Default is 8, JARS is 12
47 {'name': 'PCI DIO BusWidth', 'xml':'', 'value':'32'}, # Default for JARS
48 {'name': 'RAW DATA BLOCKS', 'xml':'Experiment/Process/Data_arrangement/Data_blocks'}]
49 self.process_param_fields = [
50 {'name': 'DATATYPE', 'xml': 'Experiment/Process/Signal_pre_processing/Type_of_data'},
51 {'name': 'DATA ARRANGE', 'xml':'', 'value':'CONTIGUOUS_CH'}, #TODO
52 {'name': 'COHERENT INTEGRATION STRIDE', 'xml':'Experiment/Process/Signal_pre_processing/Integration_stride'},
53 {'name': '------------------', 'xml':'', 'type':'separator'},
54 {'name': 'ACQUIRED PROFILES', 'xml':'Experiment/Process/Data_arrangement/Acquired_profiles'},
55 {'name': 'PROFILES PER BLOCK', 'xml':'Experiment/Process/Data_arrangement/Profiles_per_block'},
56 {'name': '------------------', 'xml':'', 'type':'separator'},
57 {'name': 'BEGIN ON START', 'xml':'Experiment/Process/Schedule/Begin_on_Start', 'type': 'checkbox_YES_NO'},
58 {'name': 'BEGIN_TIME', 'xml':'Experiment/Process/Schedule/Start', 'hide':['']},
59 {'name': 'END_TIME', 'xml':'Experiment/Process/Schedule/End', 'hide':['']},
60 {'name': 'VIEW RAW DATA', 'xml':'Experiment/Process/Data_arrangement/View_raw_data', 'type': 'checkbox_YES_NO'},
61 {'name': 'REFRESH RATE', 'xml':'', 'value':'1'}, #TODO
62 {'name': '------------------', 'xml':'', 'type':'separator'},
63 {'name': 'SEND STATUS TO FTP', 'xml':'', 'type':'checkbox_YES_NO', 'value':'NO'}, #TODO
64 {'name': 'FTP SERVER', 'xml':'', 'hide':[None, '']}, #TODO
65 {'name': 'FTP USER', 'xml':'', 'hide':[None, '']}, #TODO
66 {'name': 'FTP PASSWD', 'xml':'', 'hide':[None, '']}, #TODO
67 {'name': 'FTP DIR', 'xml':'', 'hide':[None, '']}, #TODO
68 {'name': 'FTP FILE', 'xml':'', 'hide':[None, '']}, #TODO
69 {'name': 'FTP INTERVAL', 'xml':'', 'hide':[None, '']}, #TODO
70 {'name': 'SAVE STATUS AND BLOCK', 'xml':'', 'type':'checkbox_YES_NO', 'value':'NO'}, #TODO
71 {'name': 'GENERATE RTI', 'xml':'', 'type':'checkbox_YES_NO', 'value':'NO'}, #TODO
72 {'name': 'SEND RTI AND BLOCK', 'xml':'Process_acquired_profiles', 'type':'checkbox_YES_NO'}, #TODO
73 {'name': 'FTP INTERVAL', 'xml':'', 'value':'60'}, #TODO
74 {'name': '------------------', 'xml':'', 'type':'separator'},
75 {'name': 'COMPORT CONFIG', 'xml':'', 'value':'Com1 CBR_9600 TWOSTOPBITS NOPARITY'}, #TODO
76 {'name': 'JAM CONFIGURE FILE', 'xml':'', 'value':''}, #TODO
77 {'name': 'ACQUISITION SYSTEM', 'xml':'', 'value':'JARS'}, #TODO
78 {'name': '******************', 'xml':'', 'type':'acq_system_config_params'},
79 {'name': 'SAVE DATA', 'xml':'', 'value':'YES'}, #TODO
80 {'name': '******************', 'xml':'', 'type':'rc_seq_config_params'},
81 {'name': 'RC_STOP_SEQUENCE', 'xml':'', 'value':'255,0,255,8'},
82 {'name': 'RC_START_SEQUENCE', 'xml':'', 'value':'255,24'}]
83
84 def get_field_value(self, field, user_value):
85 if 'type' in field and field['type'] == 'checkbox_YES_NO': # Check for existence of value
86 if (user_value is None) or (user_value == 'None'):
87 user_value = 'NO'
88 elif user_value == 'on':
89 user_value = 'YES'
90 if 'value' in field and not(user_value): # Replace by default value
91 user_value = field['value']
92 if 'extra' in field and field['extra'] == 'upper': # Uppercase values
93 user_value = user_value.upper()
94 return str(user_value)
95
96 def load_xml(self, xml):
97 self.xml = xml
98 for field in self.header_fields:
99 self.add_line_output(self.header['data'], field)
100 for field in self.radar_param_fields:
101 self.add_line_output(self.radar_param['data'], field)
102 for field in self.system_param1_fields:
103 self.add_line_output(self.system_param1['data'], field)
104 for field in self.system_param2_fields:
105 self.add_line_output(self.system_param2['data'], field)
106 for field in self.process_param_fields:
107 self.add_line_output(self.process_param['data'], field)
108
109
110
111 def add_line_output(self, text_array, param_field):
112 name = param_field['name']
113 xml_l = param_field['xml']
114 acq_number_of_cards = int(self.xml.find('Experiment/Process/JARS/Number_of_cards').text)
115 acq_channels_per_card = int(self.xml.find('Experiment/Process/JARS/Channels_per_card').text)
116 number_of_acq_channels = acq_number_of_cards * acq_channels_per_card
117
118 if 'xml_attr' in param_field and 'xml_attr_find' in param_field:
119 sub_pattern = False
120 if 'xml_sub_pattern' in param_field:
121 sub_pattern = param_field['xml_sub_pattern']
122 element = self.xml.find_by_attribute_value(xml_l, param_field['xml_attr'], param_field['xml_attr_find'],sub_pattern)
123 else:
124 element = self.xml.find(xml_l)
125
126 if 'xml_attr_value' in param_field:
127 value = element.get(param_field['xml_attr_value'])
128 else:
129 value = ''
130 if xml_l == '' and 'value' in param_field:
131 value = param_field['value']
132 elif hasattr(element, 'text'):
133 value = element.text
134
135 if 'type' in param_field and param_field['type'] == 'separator': # Check for existence of value
136 text_array.append('------------------------------------------')
137 return
138 if 'type' in param_field and param_field['type'] == 'acq_system_config_params': # Get Acquisition System Parameters and add them
139 text_array.append("************JARS CONFIGURATION PARAMETERS************")
140 if self.xml.find('Experiment/Process/JARS/Filter').text:
141 # Notice that we need to use backslashes for the filter path
142 text_array.append("Jars_Filter="+self.xml.find('Experiment/Process/JARS/Filter_dir').text +'\\'+ self.xml.find('Experiment/Process/JARS/Filter').text)
143 else:
144 text_array.append("Jars_Filter=")
145 text_array.append("JARS_Collection_Mode="+self.xml.find('Experiment/Process/JARS/JARS_Collection_Mode').text)
146 text_array.append("SAVE_DATA=YES")
147 text_array.append("*****************************************************")
148 return
149 if 'type' in param_field and param_field['type'] == 'rc_seq_config_params': # Get Acquisition System Parameters and add them
150 text_array.append("****************RC SEQUENCES******************")
151 return
152 if 'type' in param_field:
153 if param_field['type'] == 'pulse_enable':
154 txa_enable = self.xml.find_by_attribute_value('Experiment/Controller/Transmitters/TX', 'id', 'txa', 'Pulses')
155 if txa_enable.text is not None:
156 text_array.append('Pulse selection_TXA='+txa_enable.text)
157 txb_enable = self.xml.find_by_attribute_value('Experiment/Controller/Transmitters/TX', 'id', 'txb', 'Pulses')
158 if txb_enable.text is not None:
159 text_array.append('Pulse selection_TXB='+txb_enable.text)
160 tr_enable = self.xml.find('Experiment/Controller/IPP/Pulses')
161 if tr_enable.text is not None:
162 text_array.append('Pulse selection_TR='+tr_enable.text)
163 return
164 elif param_field['type'] == 'Line4' or param_field['type'] == 'Line5' or param_field['type'] == 'Line6' or param_field['type'] == 'Line7':
165 code_name = 'Code_A'
166 line_number = '4'
167 line_parenthesis = ''
168 line_prepend = ''
169
170 if param_field['type'] == 'Line5':
171 code_name = 'Code_B'
172 line_number = '5'
173 line_parenthesis = ' (Line 5)'
174 line_prepend = 'L5_'
175 elif param_field['type'] == 'Line6':
176 code_name = 'Code_C'
177 line_number = '6'
178 line_parenthesis = ' (Line 6)'
179 line_prepend = 'L6_'
180 elif param_field['type'] == 'Line7':
181 code_name = 'Code_D'
182 line_number = '7'
183 line_parenthesis = ' (Line 7)'
184 line_prepend = 'L7_'
185
186 code_channel = self.xml.find_by_attribute_value('Experiment/Controller/Code_channels/Code_channel', 'id', code_name, 'Mode').text
187 if code_channel == 'FLIP':
188 value = self.xml.find_by_attribute_value('Experiment/Controller/Code_channels/Code_channel', 'id', code_name, 'Flip').text
189 flip_name = 'L'+line_number+'_FLIP' + line_parenthesis
190 if param_field['type'] == 'Line5':
191 flip_name = 'FLIP1'
192 elif param_field['type'] == 'Line6':
193 flip_name = 'FLIP2'
194 text_array.append(flip_name + '='+value)
195 elif code_channel == 'CODE':
196 code_data = self.xml.find_by_attribute_value('Experiment/Controller/Code_channels/Code_channel', 'id', code_name, 'Code')
197 Code_reference = code_data.find('Code_reference').text
198 Code_select = code_data.find('Code_select').text
199 Code_number = code_data.find('Code_number').text
200 Code_bits = code_data.find('Code_bits').text
201 custom_codes = get_custom_code_data(Code_select, int(Code_number), int(Code_bits))
202 text_array.append('Code Type' + line_parenthesis + '='+Code_select)
203 text_array.append('Number of Codes' + line_parenthesis + '='+Code_number)
204 text_array.append('Code Width' + line_parenthesis + '='+Code_bits)
205 for zero_idx, custom_code in enumerate(custom_codes):
206 text_array.append(line_prepend+'COD('+str(zero_idx)+')='+custom_code)
207 # Calculate Codes
208 text_array.append('L'+line_number+'_REFERENCE='+Code_reference.upper())
209 elif code_channel == 'Sampling':
210 sampling_name = 'Sampling Windows (Line ' + line_number + ')'
211 prepend = 'L'+line_number+'_'
212 if param_field['type'] == 'Line7':
213 sampling_name = 'Sampling Windows'
214 prepend = ''
215 sampling_data = self.xml.find_by_attribute_value('Experiment/Controller/Code_channels/Code_channel', 'id', code_name, 'Sampling')
216 Code_reference = sampling_data.find('Code_reference').text.upper()
217 samples = sampling_data.find('Samples')
218 text_array.append(sampling_name+'='+str(len(samples)))
219 for zero_idx, sample in enumerate(samples):
220 text_array.append(prepend+'H0('+str(zero_idx)+')='+sample.find('FH').text)
221 text_array.append(prepend+'NSA('+str(zero_idx)+')='+sample.find('NSA').text)
222 text_array.append(prepend+'DH('+str(zero_idx)+')='+sample.find('DH').text)
223 text_array.append('L'+line_number+'_REFERENCE='+Code_reference.upper())
224 elif code_channel == 'Synchro':
225 text_array.append('Line'+line_number+'=Synchro')
226 elif code_channel == 'Portion_Spec':
227 portion_data = self.xml.find_by_attribute_value('Experiment/Controller/Code_channels/Code_channel', 'id', code_name, 'PortionSpec')
228 periodic = portion_data.find('Periodic').text
229 portions = portion_data.find('Portions')
230 text_array.append('L'+line_number+' Number Of Portions='+str(len(portions)))
231 for zero_idx, portion in enumerate(portions):
232 text_array.append('PORTION_BEGIN('+str(zero_idx)+')='+portion.find('Begin_units').text)
233 text_array.append('PORTION_END('+str(zero_idx)+')='+portion.find('End_units').text)
234 if periodic == '1':
235 text_array.append('L'+line_number+' Portions IPP Periodic=YES')
236 else:
237 text_array.append('L'+line_number+' Portions IPP Periodic=NO')
238 return
239 elif param_field['type'] == 'txb_delays_info':
240 txb_delays = self.xml.find_by_attribute_value('Experiment/Controller/Transmitters/TX', 'id', 'txb', 'Delays')
241 text_array.append("Number of Taus="+str(len(txb_delays)))
242 for zero_index, txb_delay in enumerate(txb_delays):
243 text_array.append('TAU('+str(zero_index)+')='+str(txb_delay.text))
244 return
245 elif param_field['type'] == 'cards_info': # Get Cards info
246 if not(acq_number_of_cards == '0'):
247 for card in range(acq_number_of_cards):
248 name = 'Card('+str(card)+')'
249 text_array.append(name + "=" + str(card))
250 return
251 elif param_field['type'] == 'channels_info': # Get Channel info
252 text_array.append("Number of Channels="+str(number_of_acq_channels))
253 if not(number_of_acq_channels == '0'):
254 acq_channels = self.xml.find('Experiment/Process/Acq_channel_selection')
255 enabled_channels = []
256 channel_names =[]
257 for acq_channel in acq_channels:
258 acq_channel_number = acq_channel.get('id')
259 acq_channel_name = acq_channel.find('Name').text
260 enabled = False
261 if hasattr(acq_channel.find('Enabled'), 'text'):
262 enabled = acq_channel.find('Enabled').text
263 if enabled == 'on':
264 text_array.append("Channel("+acq_channel_number+")=" + str(int(acq_channel_number)+1))
265 enabled_channels.append(acq_channel_number)
266 channel_names.append(acq_channel_name)
267 text_array.append("Antennas_Names="+str(len(enabled_channels)))
268 for index, channel in enumerate(enabled_channels):
269 text_array.append("AntennaName(" + str(int(channel)+1) + ")="+str(channel_names[index]))
270 return
271 if 'hide' in param_field and value in param_field['hide']: # Check to see if value should be written
272 return
273 text_array.append(name + "=" + self.get_field_value(param_field, value))
274
275 def convert_to_racp(self):
276 output = []
277 # HEADER
278 for line in self.header['data']:
279 output.append(line)
280 output.append('HEADER VERSION='+self.header['version'])
281 # RADAR PARAMETERS
282 output.append(self.radar_param['header'])
283 for line in self.radar_param['data']:
284 output.append(line)
285 # SYSTEM PARAMETERS
286 output.append(self.system_param1['header'])
287 for line in self.system_param1['data']:
288 output.append(line)
289 output.append(self.system_param2['header'])
290 for line in self.system_param2['data']:
291 output.append(line)
292 # PROCESS PARAMETERS
293 output.append(self.process_param['header'])
294 for line in self.process_param['data']:
295 output.append(line)
296
297 racp_content = "\n".join([str(x) for x in output])
298 return racp_content
299
300 def reduce_code_bits(code_bits, bits_per_code):
301 return code_bits[:bits_per_code]
302
303 def zeropad_code_bits(code_bits, custom_bits_per_code):
304 return code_bits.ljust(custom_bits_per_code, "0")
305
306
307 def get_custom_code_data(codename, number_of_codes, bits_per_code):
308 import json
309 import copy
310 json_data=open('../js/pulse_code_values.json')
311 PD_pulse_codes = json.load(json_data)
312 selected_code = copy.copy(PD_pulse_codes[codename])
313
314 modified_binary_codes = []
315 for i in range (number_of_codes):
316 if (i >= selected_code['number_of_codes']):
317 # We just repeat the first code.
318 modified_binary_codes.append(selected_code['binary_codes'][0])
319 else:
320 modified_binary_codes.append(selected_code['binary_codes'][i])
321 # Now adjust the width
322 if (bits_per_code <= selected_code['bits_per_code']):
323 modified_binary_codes = [reduce_code_bits(x, bits_per_code) for x in modified_binary_codes]
324 else: # Zero pad to the right
325 modified_binary_codes = [zeropad_code_bits(x, bits_per_code) for x in modified_binary_codes]
326 return modified_binary_codes
327
328 class Pulse_Design_Mixed_Racp:
329 """A class to define the .racp output from Pulse Design """
330 def __init__(self, number_of_experiments):
331 self.header = {'version': '1103'}
332 self.radar_param = {'header': '*****Radar Controller Parameters**********'}
333 self.system_param1 = {'header': '******System Parameters*******************'}
334 self.system_param2 = {'header': '******System Parameters*******************'}
335 self.process_param = {'header': '******Process Parameters******************'}
336 self.xml = None
337 self.number_of_experiments = number_of_experiments
338 self.header_fields = {}
339 self.radar_param_fields = {}
340 self.system_param1_fields = {}
341 self.system_param2_fields = {}
342 self.process_param_fields = {}
343
344 for i in range(self.number_of_experiments):
345 self.header['data_experiment_number_'+str(i)] = []
346 self.radar_param['data_experiment_number_'+str(i)] = []
347 self.system_param1['data_experiment_number_'+str(i)] = []
348 self.system_param2['data_experiment_number_'+str(i)] = []
349 self.process_param['data_experiment_number_'+str(i)] = []
350
351 self.header_fields['indices_experiment_number_'+str(i)] = []
352 self.radar_param_fields['indices_experiment_number_'+str(i)] = []
353 self.system_param1_fields['indices_experiment_number_'+str(i)] = []
354 self.system_param2_fields['indices_experiment_number_'+str(i)] = []
355 self.process_param_fields['indices_experiment_number_'+str(i)] = []
356
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 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 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 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 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 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 self.radar_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '***', 'xml':'', 'type':'pulse_enable'})
364 self.radar_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '***', 'xml':'', 'type': 'Line4'})
365 self.radar_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '***', 'xml':'', 'type': 'Line5'})
366 self.radar_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '***', 'xml':'', 'type': 'Line6'})
367 self.radar_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '***', 'xml':'', 'type':'txb_delays_info'})
368 self.radar_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '***', 'xml':'', 'type': 'Line7'})
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 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 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 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 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 self.radar_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'WINDOW IN LINE 5&6', 'xml':'', 'value':'NO'})
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 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 self.system_param1_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '***', 'xml':'', 'type':'cards_info'})
378 self.system_param1_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '***', 'xml':'', 'type':'channels_info'})
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 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 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 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 self.system_param2_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'PCI DIO BusWidth', 'xml':'', 'value':'32'}) # Default for JARS
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 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 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'DATA ARRANGE', 'xml':'', 'value':'CONTIGUOUS_CH'})
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 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '------------------', 'xml':'', 'type':'separator'})
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 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 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '------------------', 'xml':'', 'type':'separator'})
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 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 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 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 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'REFRESH RATE', 'xml':'', 'value':'1'})
397 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '------------------', 'xml':'', 'type':'separator'})
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 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'FTP SERVER', 'xml':'', 'hide':[None, '']})
400 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'FTP USER', 'xml':'', 'hide':[None, '']})
401 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'FTP PASSWD', 'xml':'', 'hide':[None, '']})
402 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'FTP DIR', 'xml':'', 'hide':[None, '']})
403 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'FTP FILE', 'xml':'', 'hide':[None, '']})
404 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'FTP INTERVAL', 'xml':'', 'hide':[None, '']})
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 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'GENERATE RTI', 'xml':'', 'type':'checkbox_YES_NO', 'value':'NO'})
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 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'FTP INTERVAL', 'xml':'', 'value':'60'})
409 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '------------------', 'xml':'', 'type':'separator'})
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 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'JAM CONFIGURE FILE', 'xml':'', 'value':''})
412 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'ACQUISITION SYSTEM', 'xml':'', 'value':'JARS'})
413 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '******************', 'xml':'', 'type':'acq_system_config_params'})
414 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'SAVE DATA', 'xml':'', 'value':'YES'})
415 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': '******************', 'xml':'', 'type':'rc_seq_config_params'})
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 self.process_param_fields['indices_experiment_number_'+str(i)].append({'number_experiment': i,'name': 'RC_START_SEQUENCE', 'xml':'', 'value':'255,24'})
418 def get_field_value(self, field, user_value):
419 if 'type' in field and field['type'] == 'checkbox_YES_NO': # Check for existence of value
420 if (user_value is None) or (user_value == 'None'):
421 user_value = 'NO'
422 elif user_value == 'on':
423 user_value = 'YES'
424 if 'value' in field and not(user_value): # Replace by default value
425 user_value = field['value']
426 if 'extra' in field and field['extra'] == 'upper': # Uppercase values
427 user_value = user_value.upper()
428 return str(user_value)
429
430 def load_xml(self, xml):
431 self.xml = xml
432 for i in range(self.number_of_experiments):
433 for field in self.header_fields['indices_experiment_number_'+str(i)]:
434 self.add_line_output(self.header['data_experiment_number_'+str(i)], field)
435 for field in self.radar_param_fields['indices_experiment_number_'+str(i)]:
436 self.add_line_output(self.radar_param['data_experiment_number_'+str(i)], field)
437 for field in self.system_param1_fields['indices_experiment_number_'+str(i)]:
438 self.add_line_output(self.system_param1['data_experiment_number_'+str(i)], field)
439 for field in self.system_param2_fields['indices_experiment_number_'+str(i)]:
440 self.add_line_output(self.system_param2['data_experiment_number_'+str(i)], field)
441 for field in self.process_param_fields['indices_experiment_number_'+str(i)]:
442 self.add_line_output(self.process_param['data_experiment_number_'+str(i)], field)
443
444
445
446 def add_line_output(self, text_array, param_field):
447
448 1
449 name = param_field['name']
450 xml_l = param_field['xml']
451 id = str(param_field['number_experiment'])
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 acq_channels_per_card = int(self.xml.find('Experiments/List/Experiment['+id+']/XML_contents/Pulse_Design/Experiment/Process/JARS/Channels_per_card').text)
454 number_of_acq_channels = acq_number_of_cards * acq_channels_per_card
455
456
457
458 if 'xml_attr' in param_field and 'xml_attr_find' in param_field:
459 sub_pattern = False
460 if 'xml_sub_pattern' in param_field:
461 sub_pattern = param_field['xml_sub_pattern']
462 element = self.xml.find_by_attribute_value(xml_l, param_field['xml_attr'], param_field['xml_attr_find'],sub_pattern)
463 else:
464 element = self.xml.find(xml_l)
465
466 if 'xml_attr_value' in param_field:
467 value = element.get(param_field['xml_attr_value'])
468 else:
469 value = ''
470 if xml_l == '' and 'value' in param_field:
471 value = param_field['value']
472 elif hasattr(element, 'text'):
473 value = element.text
474
475 if 'type' in param_field and param_field['type'] == 'separator': # Check for existence of value
476 text_array.append('------------------------------------------')
477 return
478 if 'type' in param_field and param_field['type'] == 'acq_system_config_params': # Get Acquisition System Parameters and add them
479 text_array.append("************JARS CONFIGURATION PARAMETERS************")
480 if self.xml.find('Experiments/List/Experiment['+id+']/XML_contents/Pulse_Design/Experiment/Process/JARS/Filter').text:
481 # Notice that we need to use backslashes for the filter path
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 else:
484 text_array.append("Jars_Filter=")
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 text_array.append("SAVE_DATA=YES")
487 text_array.append("*****************************************************")
488 return
489 if 'type' in param_field and param_field['type'] == 'rc_seq_config_params': # Get Acquisition System Parameters and add them
490 text_array.append("****************RC SEQUENCES******************")
491 return
492 ##{'name': '***', 'xml':'', 'type':'pulse_enable'},
493 if 'type' in param_field:
494 if param_field['type'] == 'pulse_enable':
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 if txa_enable.text is not None:
497 text_array.append('Pulse selection_TXA='+txa_enable.text)
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 if txb_enable.text is not None:
500 text_array.append('Pulse selection_TXB='+txb_enable.text)
501 tr_enable = self.xml.find('Experiments/List/Experiment['+id+']/XML_contents/Pulse_Design/Experiment/Controller/IPP/Pulses')
502 if tr_enable.text is not None:
503 text_array.append('Experiments/List/Experiment['+id+']/XML_contents/Pulse_Design/Pulse selection_TR='+tr_enable.text)
504 return
505 elif param_field['type'] == 'Line4' or param_field['type'] == 'Line5' or param_field['type'] == 'Line6' or param_field['type'] == 'Line7':
506 code_name = 'Code_A'
507 line_number = '4'
508 line_parenthesis = ''
509 line_prepend = ''
510
511 if param_field['type'] == 'Line5':
512 code_name = 'Code_B'
513 line_number = '5'
514 line_parenthesis = ' (Line 5)'
515 line_prepend = 'L5_'
516 elif param_field['type'] == 'Line6':
517 code_name = 'Code_C'
518 line_number = '6'
519 line_parenthesis = ' (Line 6)'
520 line_prepend = 'L6_'
521 elif param_field['type'] == 'Line7':
522 code_name = 'Code_D'
523 line_number = '7'
524 line_parenthesis = ' (Line 7)'
525 line_prepend = 'L7_'
526
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 if code_channel == 'FLIP':
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 flip_name = 'L'+line_number+'_FLIP' + line_parenthesis
531 if param_field['type'] == 'Line5':
532 flip_name = 'FLIP1'
533 elif param_field['type'] == 'Line6':
534 flip_name = 'FLIP2'
535 text_array.append(flip_name + '='+value)
536 elif code_channel == 'CODE':
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 Code_reference = code_data.find('Code_reference').text
539 Code_select = code_data.find('Code_select').text
540 Code_number = code_data.find('Code_number').text
541 Code_bits = code_data.find('Code_bits').text
542 custom_codes = get_custom_code_data(Code_select, int(Code_number), int(Code_bits))
543 text_array.append('Code Type' + line_parenthesis + '='+Code_select)
544 text_array.append('Number of Codes' + line_parenthesis + '='+Code_number)
545 text_array.append('Code Width' + line_parenthesis + '='+Code_bits)
546 for zero_idx, custom_code in enumerate(custom_codes):
547 text_array.append(line_prepend+'COD('+str(zero_idx)+')='+custom_code)
548 # Calculate Codes
549 text_array.append('L'+line_number+'_REFERENCE='+Code_reference.upper())
550 elif code_channel == 'Sampling':
551 sampling_name = 'Sampling Windows (Line ' + line_number + ')'
552 prepend = 'L'+line_number+'_'
553 if param_field['type'] == 'Line7':
554 sampling_name = 'Sampling Windows'
555 prepend = ''
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 Code_reference = sampling_data.find('Code_reference').text.upper()
558 samples = sampling_data.find('Samples')
559 text_array.append(sampling_name+'='+str(len(samples)))
560 for zero_idx, sample in enumerate(samples):
561 text_array.append(prepend+'H0('+str(zero_idx)+')='+sample.find('FH').text)
562 text_array.append(prepend+'NSA('+str(zero_idx)+')='+sample.find('NSA').text)
563 text_array.append(prepend+'DH('+str(zero_idx)+')='+sample.find('DH').text)
564 text_array.append('L'+line_number+'_REFERENCE='+Code_reference.upper())
565 elif code_channel == 'Synchro':
566 text_array.append('Line'+line_number+'=Synchro')
567 elif code_channel == 'Portion_Spec':
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 periodic = portion_data.find('Periodic').text
570 portions = portion_data.find('Portions')
571 text_array.append('L'+line_number+' Number Of Portions='+str(len(portions)))
572 for zero_idx, portion in enumerate(portions):
573 text_array.append('PORTION_BEGIN('+str(zero_idx)+')='+portion.find('Begin_units').text)
574 text_array.append('PORTION_END('+str(zero_idx)+')='+portion.find('End_units').text)
575 if periodic == '1':
576 text_array.append('L'+line_number+' Portions IPP Periodic=YES')
577 else:
578 text_array.append('L'+line_number+' Portions IPP Periodic=NO')
579 return
580 elif param_field['type'] == 'txb_delays_info':
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 text_array.append("Number of Taus="+str(len(txb_delays)))
583 for zero_index, txb_delay in enumerate(txb_delays):
584 text_array.append('TAU('+str(zero_index)+')='+str(txb_delay.text))
585 return
586 elif param_field['type'] == 'cards_info': # Get Cards info
587 if not(acq_number_of_cards == '0'):
588 for card in range(acq_number_of_cards):
589 name = 'Card('+str(card)+')'
590 text_array.append(name + "=" + str(card))
591 return
592 elif param_field['type'] == 'channels_info': # Get Channel info
593 text_array.append("Number of Channels="+str(number_of_acq_channels))
594 if not(number_of_acq_channels == '0'):
595 acq_channels = self.xml.find('Experiments/List/Experiment['+id+']/XML_contents/Pulse_Design/Experiment/Process/Acq_channel_selection')
596 enabled_channels = []
597 channel_names =[]
598 for acq_channel in acq_channels:
599 acq_channel_number = acq_channel.get('id')
600 acq_channel_name = acq_channel.find('Name').text
601 enabled = False
602 if hasattr(acq_channel.find('Enabled'), 'text'):
603 enabled = acq_channel.find('Enabled').text
604 if enabled == 'on':
605 text_array.append("Channel("+acq_channel_number+")=" + str(int(acq_channel_number)+1))
606 enabled_channels.append(acq_channel_number)
607 channel_names.append(acq_channel_name)
608 text_array.append("Antennas_Names="+str(len(enabled_channels)))
609 for index, channel in enumerate(enabled_channels):
610 text_array.append("AntennaName(" + str(int(channel)+1) + ")="+str(channel_names[index]))
611 return
612 if 'hide' in param_field and value in param_field['hide']: # Check to see if value should be written
613 return
614 text_array.append(name + "=" + self.get_field_value(param_field, value))
615
616 def convert_to_racp(self):
617 output = []
618 # HEADER
619 for i in range(self.number_of_experiments):
620 for line in self.header['data_experiment_number_'+str(i)]:
621 output.append(line)
622 output.append('HEADER VERSION='+self.header['version'])
623 # RADAR PARAMETERS
624 output.append(self.radar_param['header'])
625 for line in self.radar_param['data_experiment_number_'+str(i)]:
626 output.append(line)
627 # SYSTEM PARAMETERS
628 output.append(self.system_param1['header'])
629 for line in self.system_param1['data_experiment_number_'+str(i)]:
630 output.append(line)
631 output.append(self.system_param2['header'])
632 for line in self.system_param2['data_experiment_number_'+str(i)]:
633 output.append(line)
634 # PROCESS PARAMETERS
635 output.append(self.process_param['header'])
636 for line in self.process_param['data_experiment_number_'+str(i)]:
637 output.append(line)
638 output.append("\n")
2 import json
3 import numpy as np
4 import matplotlib.pyplot as plt
639 5
640 racp_content = "\n".join([str(x) for x in output])
641 return racp_content
642 6
643 7 class RCFile(object):
8 '''
9 Class to handle Radar controller configuration files
10 '''
644 11
645 12 def __init__(self, f=None):
646 13
647 14 self.data = {}
648 15 if isinstance(f, str):
649 16 self.f = open(f)
650 17 self.name = f.split('/')[-1]
651 18 elif hasattr(f, 'read'):
652 19 self.f = f
653 20 self.name = f.name.split('/')[-1]
654 21 else:
655 22 self.f = f
656 23 self.name = None
657 24
658 25 if self.f:
659 26 if 'racp' in self.name:
660 27 self.parse_racp()
661 28 elif 'dat' in self.name:
662 29 self.parse_dat()
30 elif 'json' in self.name:
31 self.data = json.load(self.f)
32
33 self.f.close()
663 34
664 35 def get_line_parameters(self, data, line):
665 36
666 37 line_params = {}
667 38 for label in data:
668 39 if 'L%d' % line in label or '(Line %d)' % line in label or 'Line%d' % line in label:
669 40 line_params[label] = data[label]
670 41 return line_params
671 42
672 43 def parse_racp(self):
673 44
674 45 data = {}
675 46 raw_data = [s.strip() for s in self.f.readlines()]
47
676 48 for line in raw_data:
677 49 if line and '=' in line:
678 50 label, value = line.strip().split('=')
679 51 data[label] = value
52
680 53 self.data['experiment_type'] = data['EXPERIMENT TYPE']
681 54 self.data['header_version'] = data['HEADER VERSION']
682 55 self.data['name'] = data['EXPERIMENT NAME']
683 56 self.data['ipp'] = float(data['IPP'])
684 57 self.data['ntx'] = int(data['NTX'])
58
685 59 if 'CLOCK DIVIDER' in data:
686 60 self.data['clock_divider'] = int(data['CLOCK DIVIDER'])
687 61 else:
688 62 self.data['clock_divider'] = 1
689 self.data['clock'] = float(data['RELOJ'])*self.data['clock_divider']
63 self.data['clock_in'] = float(data['RELOJ'])*self.data['clock_divider']
64 self.data['clock'] = float(data['RELOJ'])
690 65 self.data['time_before'] = int(data['TR_BEFORE'])
691 66 self.data['time_after'] = int(data['TR_AFTER'])
67
692 68 if 'SYNCHRO DELAY' in data:
693 69 self.data['sync'] = int(data['SYNCHRO DELAY'])
694 70 else:
695 71 self.data['sync'] = 0
696 72 self.data['lines'] = []
697
73
74 if 'SAMPLING REFERENCE' in data:
75 if data['SAMPLING REFERENCE']=='MIDDLE OF FIRST BAUD':
76 self.data['sampling_reference'] = 'first_baud'
77 elif data['SAMPLING REFERENCE']=='MIDDLE OF FIRST SUB-BAUD':
78 self.data['sampling_reference'] = 'sub_baud'
79 else:
80 self.data['sampling_reference'] = 'none'
81
698 82 #Add TR line
699 83 if 'Pulse selection_TR' in data:
700 if 'A' in data['Pulse selection_TR']:
84 if 'A,' in data['Pulse selection_TR']:
85 rng = data['Pulse selection_TR'].replace('A,', '')
86 ref = 'TXA'
87 elif 'A' in data['Pulse selection_TR']:
701 88 rng = data['Pulse selection_TR'].replace('A', '')
89 ref = 'TXA'
90 elif 'B,' in data['Pulse selection_TR']:
91 rng = data['Pulse selection_TR'].replace('B,', '')
92 ref = 'TXB'
702 93 elif 'B' in data['Pulse selection_TR']:
703 94 rng = data['Pulse selection_TR'].replace('B', '')
95 ref = 'TXB'
704 96 else:
705 97 rng = data['Pulse selection_TR']
706 line = {'type':'tr', 'range': rng, 'TX_ref':'TXA'}
98 ref = '0'
99 line = {'type':'tr', 'range': rng if rng else '0', 'TX_ref':ref}
707 100 else:
708 line = {'type': 'tr', 'range': 0, 'TX_ref': '0'}
101 line = {'type': 'tr', 'range': '0', 'TX_ref': '0'}
709 102
710 103 self.data['lines'].append(line)
711 104
712 105 #Add TX's lines
713 106 if 'TXA' in data:
714 107 line = {'type':'tx', 'pulse_width':data['TXA'], 'delays':'0'}
715 108 if 'Pulse selection_TXA' in data:
716 109 line['range'] = data['Pulse selection_TXA']
717 110 else:
718 111 line['range'] = '0'
719 112 self.data['lines'].append(line)
720
113 else:
114 self.data['lines'].append({'type':'tx', 'pulse_width':'0', 'delays':'0', 'range':'0'})
115
721 116 if 'TXB' in data:
722 117 line = {'type':'tx', 'pulse_width':data['TXB'], 'delays':'0'}
723 118 if 'Pulse selection_TXB' in data:
724 119 line['range'] = data['Pulse selection_TXB']
725 120 else:
726 121 line['range'] = '0'
727 122
728 123 if 'Number of Taus' in data:
729 124 delays = [data['TAU({0})'.format(i)] for i in range(int(data['Number of Taus']))]
730 125 line['delays'] = ','.join(delays)
731 126
732 127 self.data['lines'].append(line)
128 else:
129 self.data['lines'].append({'type':'tx', 'pulse_width':'0', 'delays':'0', 'range':'0'})
733 130
734 131 #Add Other lines (4-6)
735 132 for n in range(4, 7):
736 133 params = self.get_line_parameters(data, n)
737 134 labels = params.keys()
738 135
739 136 if 'L%d_FLIP' % n in labels:
740 137 line = {'type':'flip', 'number_of_flips':data['L%d_FLIP' % n]}
741 138 elif 'Code Type' in data and n==4:
742 139 line = {'type':'codes', 'code':data['Code Type'], 'TX_ref':data['L%d_REFERENCE' % n]}
140 if 'Number of Codes' in data:
141 line['codes'] = [data['COD({})'.format(x)] for x in range(int(data['Number of Codes']))]
743 142 elif 'Code Type (Line %d)' % n in labels:
744 143 line = {'type':'codes', 'code':data['Code Type (Line %d)' % n], 'TX_ref':data['L%d_REFERENCE' % n]}
144 if 'Number of Codes (Line %d)' % n in data:
145 line['codes'] = [data['L{}_COD({})'.format(n, x)] for x in range(int(data['Number of Codes (Line %d)' % n]))]
745 146 elif 'Sampling Windows (Line %d)' % n in data:
746 147 line = {'type':'windows', 'TX_ref':data['L%d_REFERENCE' % n]}
747 148 windows = []
748 149 for w in range(int(data['Sampling Windows (Line %d)' % n])):
749 150 windows.append({'first_height':float(data['L%d_H0(%d)' % (n, w)]),
750 151 'number_of_samples':int(data['L%d_NSA(%d)' % (n, w)]),
751 152 'resolution':float(data['L%d_DH(%d)' % (n, w)])}
752 153 )
753 154 line['params'] = windows
754 155 elif 'Line%d' % n in labels and data['Line%d' % n]=='Synchro':
755 156 line = {'type':'sync', 'invert':0}
756 157 elif 'L%d Number Of Portions' % n in labels:
757 158 line = {'type':'prog_pulses'}
758 159 if 'L%s Portions IPP Periodic' % n in data:
759 160 line['periodic'] = 1 if data['L%s Portions IPP Periodic' % n]=='YES' else 0
760 161 portions = []
761 162 x = raw_data.index('L%d Number Of Portions=%s' % (n, data['L%d Number Of Portions' % n]))
762 163 for w in range(int(data['L%d Number Of Portions' % n])):
763 164 begin = raw_data[x+1+2*w].split('=')[-1]
764 165 end = raw_data[x+2+2*w].split('=')[-1]
765 166 portions.append({'begin':int(begin),
766 167 'end':int(end)}
767 168 )
768 169 line['params'] = portions
769 170 elif 'FLIP1' in data and n==5:
770 171 line = {'type':'flip', 'number_of_flips':data['FLIP1']}
771 172 elif 'FLIP2' in data and n==6:
772 173 line = {'type':'flip', 'number_of_flips':data['FLIP2']}
773 174 else:
774 175 line = {'type':'none'}
775 176
776 177 self.data['lines'].append(line)
777 178
778 179 #Add line 7 (windows)
779 180 if 'Sampling Windows' in data:
780 181 line = {'type':'windows', 'TX_ref':data['L7_REFERENCE']}
781 182 windows = []
782 183 x = raw_data.index('Sampling Windows=%s' % data['Sampling Windows'])
783 184 for w in range(int(data['Sampling Windows'])):
784 185 h0 = raw_data[x+1+3*w].split('=')[-1]
785 186 nsa = raw_data[x+2+3*w].split('=')[-1]
786 187 dh = raw_data[x+3+3*w].split('=')[-1]
787 188 windows.append({'first_height':float(h0),
788 189 'number_of_samples':int(nsa),
789 190 'resolution':float(dh)}
790 191 )
791 192 line['params'] = windows
792 193 self.data['lines'].append(line)
793 194 else:
794 195 self.data['lines'].append({'type':'none'})
795 196
796 197 #Add line 8 (synchro inverted)
797 198 self.data['lines'].append({'type':'sync', 'invert':1})
798 199
799 200 return
800 201
801 202 def parse_dat(self):
802 203 pass
803
204
804 205
805 206 def get_json(self, indent=None):
806 207 return json.dumps(self.data, indent=indent)
807 208
808 209
809 def pulses_to_bar(X):
210 def pulses_to_points(X):
810 211
811 212
812 213 d = X[1:]-X[:-1]
813 214
814 215 up = np.where(d==1)[0]
815 216 if X[0]==1:
816 217 up = np.concatenate((np.array([-1]), up))
817 218 up += 1
818 219
819 220 dw = np.where(d==-1)[0]
820 221 if X[-1]==1:
821 222 dw = np.concatenate((dw, np.array([len(X)-1])))
822 223 dw += 1
823 224
824 225 return [(tup[0], tup[1]-tup[0]) for tup in zip(up, dw)]
825 226
826 227
827 228 def pulses_from_code(ipp, ntx, codes, width, before=0):
828 229
829 230 if ntx>len(codes):
830 231 ipp_codes = [c for __ in xrange(ntx) for c in codes][:ntx]
831 232 else:
832 233 ipp_codes = codes[:ntx]
833 234
834 235 f = width/len(codes[0])
835 236
836 237 ipp_codes = [''.join([s*f for s in code]) for code in ipp_codes]
837 238
838 239 if before>0:
839 240 sbefore = '{0:0{1}d}'.format(0, before)
840 241 else:
841 242 sbefore = ''
842 243
843 244 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 245
845 246 return (np.fromstring(''.join(temp), dtype=np.uint8)-48).astype(np.int8)
846 247
847 248
848 249 def create_mask(ranges, ipp, ntx, sync):
849 250
850 251 x = np.arange(ipp*ntx)
851 252 iranges = set()
852 253
853 254 for index in ranges:
854 255 if '-' in index:
855 256 args = [int(a) for a in index.split('-')]
856 257 iranges = iranges.union([i for i in range(args[0], args[1]+1)])
857 258 else:
858 259 iranges.add(int(index))
859 260
860 261 y = np.any([(x>=(idx-1)*ipp+sync) & (x<idx*ipp+sync) for idx in iranges], axis=0).astype(np.int8)
861 262
862 263 return y
863 264
864 265
865 266 def pulses(X, period, width, delay=0, before=0, after=0, sync=0, shift=0):
866 267
867 268 delay_array = delay
868 269
869 270 if isinstance(delay, (list, tuple)):
870 271 delay_array = np.ones(len(X))
871 272 delays = [d for __ in xrange(len(X)/(period*len(delay))) for d in delay]
872 273 for i, delay in enumerate(delays):
873 274 delay_array[np.arange(period*i, period*(i+1))] *= delay
874 275
875 276 if after>0:
876 277 width += after+before
877 278 before = 0
878 279
879 280 Y = ((X%period<width+delay_array+before+sync) & (X%period>=delay_array+before+sync)).astype(np.int8)
880 281
881 282 if shift>0:
882 283 y = np.empty_like(Y)
883 284 y[:shift] = 0
884 y[shift:] = Y[:-shift]
285 y[shift:] = Y[:-shift]
885 286 return y
886 287 else:
887 288 return Y
888 289
889 290
890 291 def plot_pulses(unit, maximun, lines):
891 292
892 293 from bokeh.resources import CDN
893 294 from bokeh.embed import components
894 from bokeh.mpl import to_bokeh
895 from bokeh.plotting import figure
295 from bokeh.mpl import to_bokeh
896 296 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, PreviewSaveTool
897 297
898
899 298 N = len(lines)
900 299 fig = plt.figure(figsize=(10, 2+N*0.5))
901 300 ax = fig.add_subplot(111)
902 301 labels = []
903 data = []
302
904 303 for i, line in enumerate(lines):
905 304 print line
906 305 labels.append(line.get_name())
907 ax.broken_barh(pulses_to_bar(line.pulses_as_array()), (N-i-1, 0.5),
306 ax.broken_barh(pulses_to_points(line.pulses_as_array()), (N-i-1, 0.5),
908 307 edgecolor='none', facecolor='#2c3e50')
909 #data.append(line.pulses_as_array())
910
911
912 #labels.append('{:3.2f} Km'.format(unit*100))
913 #ax.broken_barh(pulses_to_bar(pulses(np.arange(0, maximun), 200, 100)), (0, 0.5),
914 # edgecolor='none', facecolor='#ae3910')
915
916
917 #ax.pcolor(data, cmap=cm.Blues, vmin=0, vmax=1)
918
308
919 309 labels.reverse()
920 #plot = figure(x_range=[0, maximun], y_range=[0, N])
921 #plot.image(image=[np.logical_not(data).astype(np.int8)], x=[0], y=[0], dh=[N], dw=[maximun], palette='Blues9')
922 310 ax.set_yticklabels(labels)
923 311 plot = to_bokeh(fig, use_pandas=False)
924 312 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), PreviewSaveTool()]
925 313
926 314 return components(plot, CDN)
@@ -1,389 +1,395
1
1 2 import json
2 3
3 4 from django.contrib import messages
4 5 from django.utils.safestring import mark_safe
5 6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
6 7
7 8 from apps.main.models import Configuration, Experiment, Device
8 9 from apps.main.views import sidebar
9 10
10 11 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode
11 from .forms import RCConfigurationForm, RCLineForm, RCLineViewForm, RCLineEditForm, RCSubLineEditForm, RCImportForm
12 from .utils import RCFile, plot_pulses
12 from .forms import RCConfigurationForm, RCLineForm, RCLineViewForm, RCLineEditForm, RCImportForm, RCLineCodesForm
13 from .utils import plot_pulses
13 14
14 15
15 16 def conf(request, conf_id):
16 17
17 18 conf = get_object_or_404(RCConfiguration, pk=conf_id)
18 19
19 20 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
20 21
21 22 for line in lines:
22 23 params = json.loads(line.params)
23 24 line.form = RCLineViewForm(extra_fields=params, line=line)
24 25 if 'params' in params:
25 26 line.subforms = [RCLineViewForm(extra_fields=fields, line=line, subform=True) for fields in params['params']]
26 27
27 28 kwargs = {}
28 29 kwargs['dev_conf'] = conf
29 30 kwargs['rc_lines'] = lines
30 kwargs['dev_conf_keys'] = ['name', 'ipp', 'ntx', 'clock', 'clock_divider',
31 'time_before', 'time_after', 'sync']
31 kwargs['dev_conf_keys'] = ['name', 'ipp', 'ntx', 'clock_in', 'clock_divider', 'clock',
32 'time_before', 'time_after', 'sync', 'sampling_reference', 'control_tx', 'control_sw']
32 33
33 34 kwargs['title'] = 'RC Configuration'
34 35 kwargs['suptitle'] = 'Details'
35 36
36 37 kwargs['button'] = 'Edit Configuration'
37 38 ###### SIDEBAR ######
38 39 kwargs.update(sidebar(conf))
39 40
40 41 return render(request, 'rc_conf.html', kwargs)
41 42
42 43
43 44 def conf_edit(request, conf_id):
44 45
45 46 conf = get_object_or_404(RCConfiguration, pk=conf_id)
46 47
47 48 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
48 49
49 for line in lines:
50 line_type = get_object_or_404(RCLineType, pk=line.line_type.id)
51 extra_fields = json.loads(line_type.params)
52 params = json.loads(line.params)
53 for item, values in extra_fields.items():
54 if item=='params':
55 continue
56 values['value'] = params[item]
57
58 line.form = RCLineEditForm(initial={'rc_configuration':conf_id, 'line_type': line.line_type.id, 'line': line.id},
59 extra_fields=extra_fields)
50 for line in lines:
51 params = json.loads(line.params)
52 line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params)
53 line.subform = False
60 54
61 55 if 'params' in params:
56 line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])]
62 57 line.subform = True
63 line.subforms = [RCSubLineEditForm(extra_fields=fields, line=line.id, count=i) for i, fields in enumerate(params['params'])]
64 58
65 59 if request.method=='GET':
66 60
67 61 form = RCConfigurationForm(instance=conf)
68 62
69 63 elif request.method=='POST':
70 64
71 65 line_data = {}
72 66 conf_data = {}
73 67 extras = []
74 68
75 69 #classified post fields
76 70 for label,value in request.POST.items():
77 71 if label=='csrfmiddlewaretoken':
78 72 continue
73
79 74 if label.count('|')==0:
80 75 conf_data[label] = value
81 76 continue
82 elif label.count('|')==2:
77
78 elif label.split('|')[0]<>'-1':
83 79 extras.append(label)
84 80 continue
85 81
86 pk, name = label.split('|')
87
82 x, pk, name = label.split('|')
83
84 if name=='codes':
85 value = [s for s in value.split('\r\n') if s]
86
88 87 if pk in line_data:
89 88 line_data[pk][name] = value
90 89 else:
91 90 line_data[pk] = {name:value}
92 91
93 92 #update conf
94
95 93 form = RCConfigurationForm(conf_data, instance=conf)
96 94
97 95 if form.is_valid():
98 96
99 97 form.save()
100 98
101 99 #update lines fields
102 100 extras.sort()
103 101 for label in extras:
104 102 x, pk, name = label.split('|')
105 103 if pk not in line_data:
106 104 line_data[pk] = {}
107 105 if 'params' not in line_data[pk]:
108 106 line_data[pk]['params'] = []
109 107 if len(line_data[pk]['params'])<int(x)+1:
110 108 line_data[pk]['params'].append({})
111 109 line_data[pk]['params'][int(x)][name] = float(request.POST[label])
112 110
113 111 for pk, params in line_data.items():
114 112 line = RCLine.objects.get(pk=pk)
115 113 if line.line_type.name in ('windows', 'prog_pulses'):
116 114 if 'params' not in params:
117 115 params['params'] = []
118 116 line.params = json.dumps(params)
119 117 line.save()
120 118
121 119 #update pulses field
122 120 for line in conf.get_lines():
123 121 if line.line_type.name=='tr':
124 122 continue
125 123 line.update_pulses()
126 124
127 125 for tr in conf.get_lines('tr'):
128 tr.update_pulses()
126 tr.update_pulses()
129 127
130 128 messages.success(request, 'RC Configuration successfully updated')
131 129
132 130 return redirect(conf.get_absolute_url())
133 131
134 132 kwargs = {}
135 133 kwargs['dev_conf'] = conf
136 134 kwargs['form'] = form
137 135 kwargs['rc_lines'] = lines
138 136 kwargs['edit'] = True
139 137
140 138 kwargs['title'] = 'RC Configuration'
141 139 kwargs['suptitle'] = 'Edit'
142 140 kwargs['button'] = 'Update'
143 141 kwargs['previous'] = conf.get_absolute_url()
144 142
145 143 kwargs.update(sidebar(conf))
146 144
147 145 return render(request, 'rc_conf_edit.html', kwargs)
148 146
149 147
150 def add_line(request, conf_id, line_type_id=None):
148 def add_line(request, conf_id, line_type_id=None, code_id=None):
151 149
152 150 conf = get_object_or_404(RCConfiguration, pk=conf_id)
153 151
154 152 if request.method=='GET':
155 153 if line_type_id:
156 154 line_type = get_object_or_404(RCLineType, pk=line_type_id)
157 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id},
158 extra_fields=json.loads(line_type.params))
155
156 if code_id:
157 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id, 'code_id': code_id},
158 extra_fields=json.loads(line_type.params))
159 else:
160 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id},
161 extra_fields=json.loads(line_type.params))
159 162 else:
163 line_type = {'id':0}
160 164 form = RCLineForm(initial={'rc_configuration':conf_id})
161 165
162 166 if request.method=='POST':
167
163 168 line_type = get_object_or_404(RCLineType, pk=line_type_id)
164 form = RCLineForm(request.POST, extra_fields=json.loads(line_type.params))
169 form = RCLineForm(request.POST,
170 extra_fields=json.loads(line_type.params))
165 171
166 172 if form.is_valid():
167 173 form.save()
168 174 form.instance.update_pulses()
169 175 return redirect('url_edit_rc_conf', conf.id)
170 176
171 177 kwargs = {}
172 178 kwargs['form'] = form
173 179 kwargs['title'] = 'RC Configuration'
174 180 kwargs['suptitle'] = 'Add Line'
175 181 kwargs['button'] = 'Add'
176 182 kwargs['previous'] = conf.get_absolute_url_edit()
177 183 kwargs['dev_conf'] = conf
184 kwargs['line_type'] = line_type
178 185
179 186 kwargs.update(sidebar(conf))
180 187
181 188 return render(request, 'rc_add_line.html', kwargs)
182 189
190 def edit_codes(request, conf_id, line_id, code_id=None):
191
192 conf = get_object_or_404(RCConfiguration, pk=conf_id)
193 line = get_object_or_404(RCLine, pk=line_id)
194 params = json.loads(line.params)
195
196 if request.method=='GET':
197 if code_id:
198 code = get_object_or_404(RCLineCode, pk=code_id)
199 form = RCLineCodesForm(instance=code)
200 else:
201 initial = {'code': params['code'],
202 'codes': params['codes'] if 'codes' in params else [],
203 'number_of_codes': len(params['codes']) if 'codes' in params else 0,
204 'bits_per_code': len(params['codes'][0]) if 'codes' in params else 0,
205 }
206 form = RCLineCodesForm(initial=initial)
207
208 if request.method=='POST':
209 form = RCLineCodesForm(request.POST)
210 if form.is_valid():
211 params['code'] = request.POST['code']
212 params['codes'] = [s for s in request.POST['codes'].split('\r\n') if s]
213 line.params = json.dumps(params)
214 line.save()
215 messages.success(request, 'Line: "%s" has been updated.' % line)
216 return redirect('url_edit_rc_conf', conf.id)
217
218 kwargs = {}
219 kwargs['form'] = form
220 kwargs['title'] = line
221 kwargs['suptitle'] = 'Edit'
222 kwargs['button'] = 'Update'
223 kwargs['dev_conf'] = conf
224 kwargs['previous'] = conf.get_absolute_url_edit()
225 kwargs['line'] = line
226
227 return render(request, 'rc_edit_codes.html', kwargs)
228
183 229 def add_subline(request, conf_id, line_id):
184 230
185 231 conf = get_object_or_404(RCConfiguration, pk=conf_id)
186 232 line = get_object_or_404(RCLine, pk=line_id)
187 233
188 234 if request.method == 'POST':
189 235 if line:
190 236 params = json.loads(line.params)
191 if 'params' in params:
192 subparams = json.loads(line.line_type.params)
193 base = [p for p in subparams if p['name']=='params'][0]['form']
194 new = {}
195 for p in base:
196 new[p['name']] = p['value']
197 params['params'].append(new)
237 subparams = json.loads(line.line_type.params)
238 if 'params' in subparams:
239 dum = {}
240 for key, value in subparams['params'].items():
241 dum[key] = value['value']
242 params['params'].append(dum)
198 243 line.params = json.dumps(params)
199 244 line.save()
200 245 return redirect('url_edit_rc_conf', conf.id)
201 246
202 247 kwargs = {}
203 248
204 249 kwargs['title'] = 'Add new'
205 250 kwargs['suptitle'] = '%s to %s' % (line.line_type.name, line)
206 251
207 252 return render(request, 'confirm.html', kwargs)
208 253
209 254 def remove_line(request, conf_id, line_id):
210 255
211 256 conf = get_object_or_404(RCConfiguration, pk=conf_id)
212 257 line = get_object_or_404(RCLine, pk=line_id)
213 258
214 259 if request.method == 'POST':
215 260 if line:
216 261 try:
217 262 channel = line.channel
218 263 line.delete()
219 264 for ch in range(channel+1, RCLine.objects.filter(rc_configuration=conf).count()+1):
220 265 l = RCLine.objects.get(rc_configuration=conf, channel=ch)
221 266 l.channel = l.channel-1
222 267 l.save()
223 268 messages.success(request, 'Line: "%s" has been deleted.' % line)
224 269 except:
225 270 messages.error(request, 'Unable to delete line: "%s".' % line)
226 271
227 272 return redirect('url_edit_rc_conf', conf.id)
228 273
229 274 kwargs = {}
230 275
231 276 kwargs['object'] = line
232 277 kwargs['delete_view'] = True
233 278 kwargs['title'] = 'Confirm delete'
234 279 kwargs['previous'] = conf.get_absolute_url_edit()
235 280 return render(request, 'confirm.html', kwargs)
236 281
282
237 283 def remove_subline(request, conf_id, line_id, subline_id):
238 284
239 285 conf = get_object_or_404(RCConfiguration, pk=conf_id)
240 286 line = get_object_or_404(RCLine, pk=line_id)
241 287
242 288 if request.method == 'POST':
243 289 if line:
244 290 params = json.loads(line.params)
245 291 params['params'].remove(params['params'][int(subline_id)-1])
246 292 line.params = json.dumps(params)
247 293 line.save()
248 294
249 295 return redirect('url_edit_rc_conf', conf.id)
250 296
251 297 kwargs = {}
252 298
253 299 kwargs['object'] = line
254 300 kwargs['object_name'] = line.line_type.name
255 301 kwargs['delete_view'] = True
256 302 kwargs['title'] = 'Confirm delete'
257 303
258 304 return render(request, 'confirm.html', kwargs)
259 305
260 306
261 307 def update_lines_position(request, conf_id):
262 308
263 309 conf = get_object_or_404(RCConfiguration, pk=conf_id)
264 310
265 311 if request.method=='POST':
266 312 ch = 0
267 313 for item in request.POST['items'].split('&'):
268 314 line = RCLine.objects.get(pk=item.split('=')[-1])
269 315 line.channel = ch
270 316 line.save()
271 317 ch += 1
272 318
273 319 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
274 320
275 321 for line in lines:
276 line.form = RCLineViewForm(extra_fields=json.loads(line.params))
322 params = json.loads(line.params)
323 line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params)
324
325 if 'params' in params:
326 line.subform = True
327 line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])]
277 328
278 html = render(request, 'rc_lines.html', {'rc_lines':lines, 'edit':True})
329 html = render(request, 'rc_lines.html', {'dev_conf':conf, 'rc_lines':lines, 'edit':True})
279 330 data = {'html': html.content}
280 331
281 332 return HttpResponse(json.dumps(data), content_type="application/json")
282 333 return redirect('url_edit_rc_conf', conf.id)
334
283 335
284 336 def import_file(request, conf_id):
285 337
286 338 conf = get_object_or_404(RCConfiguration, pk=conf_id)
287 339 if request.method=='POST':
288 340 form = RCImportForm(request.POST, request.FILES)
289 341 if form.is_valid():
290 342 #try:
291 343 if True:
292 f = RCFile(request.FILES['file_name'])
293 data = f.data
294 conf.ipp = data['ipp']
295 conf.ntx = data['ntx']
296 conf.clock = data['clock']
297 conf.clock_divider = data['clock_divider']
298 conf.time_before = data['time_before']
299 conf.time_after = data['time_after']
300 conf.sync = data['sync']
301 conf.save()
302 lines = []
303 positions = {'tx':0, 'tr':0}
304 344
305 for i, line_data in enumerate(data['lines']):
306 line_type = RCLineType.objects.get(name=line_data.pop('type'))
307 if line_type.name=='codes':
308 code = RCLineCode.objects.get(name=line_data['code'])
309 line_data['code'] = code.pk
310 line = RCLine.objects.filter(rc_configuration=conf, channel=i)
311 if line:
312 line = line[0]
313 line.line_type = line_type
314 line.params = json.dumps(line_data)
315 else:
316 line = RCLine(rc_configuration=conf, line_type=line_type,
317 params=json.dumps(line_data),
318 channel=i)
319
320 if line_type.name=='tx':
321 line.position = positions['tx']
322 positions['tx'] += 1
323
324 if line_type.name=='tr':
325 line.position = positions['tr']
326 positions['tr'] += 1
327
328 line.save()
329 lines.append(line)
330
331 for line, line_data in zip(lines, data['lines']):
332 if 'TX_ref' in line_data:
333 params = json.loads(line.params)
334 params['TX_ref'] = [l.pk for l in lines if l.line_type.name=='tx' and l.get_name().replace(' ', '')==line_data['TX_ref']][0]
335 line.params = json.dumps(params)
336 line.save()
337
345 conf.update_from_file(request.FILES['file_name'])
346 conf.save()
347
338 348 for line in conf.get_lines():
339 349 if line.line_type.name=='tr':
340 350 continue
341 351 line.update_pulses()
342 352
343 353 for tr in conf.get_lines('tr'):
344 tr.update_pulses()
354 tr.update_pulses()
345 355
346 356 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
347 357 return redirect(conf.get_absolute_url())
348 358
349 359 #except Exception as e:
350 360 # messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], e))
351 361
352 362 else:
353 363 messages.warning(request, 'Your current configuration will be replaced')
354 form = RCImportForm()
355
364 form = RCImportForm()
356 365
357 366 kwargs = {}
358 367 kwargs['form'] = form
359 368 kwargs['title'] = 'RC Configuration'
360 369 kwargs['suptitle'] = 'Import file'
361 370 kwargs['button'] = 'Upload'
362 371 kwargs['previous'] = conf.get_absolute_url()
363 372
364 373 return render(request, 'rc_import.html', kwargs)
365
374
366 375
367 376 def view_pulses(request, conf_id):
368 377
369 378 conf = get_object_or_404(RCConfiguration, pk=conf_id)
370 379 lines = RCLine.objects.filter(rc_configuration=conf)
371 380
372 381 unit = (conf.clock/conf.clock_divider)*3./20
373 382
374 383 N = int(conf.ipp*(conf.clock/conf.clock_divider)*20./3)*conf.ntx
375 384
376 script, div = plot_pulses(unit, N, lines)
377
378 kwargs = {'div':mark_safe(div), 'script':mark_safe(script)}
385 script, div = plot_pulses(unit, N, lines)
379 386
380 if 'json' in request.GET:
381
382 return HttpResponse(json.dumps(kwargs), content_type="application/json")
383
384 else:
385
386
387 kwargs = {}
387 388
388 return render(request, 'rc_pulses.html', kwargs)
389 kwargs['title'] = 'RC Pulses'
390 kwargs['suptitle'] = conf.name
391 kwargs['div'] = mark_safe(div)
392 kwargs['script'] = mark_safe(script)
393
394 return render(request, 'rc_pulses.html', kwargs)
389 395
@@ -1,123 +1,129
1 1 """
2 2 Django settings for radarsys project.
3 3
4 4 Generated by 'django-admin startproject' using Django 1.8.6.
5 5
6 6 For more information on this file, see
7 7 https://docs.djangoproject.com/en/1.8/topics/settings/
8 8
9 9 For the full list of settings and their values, see
10 10 https://docs.djangoproject.com/en/1.8/ref/settings/
11 11 """
12 12
13 13 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
14 14 import os
15 15
16 16 BASE_DIR = os.path.dirname(os.path.abspath(__file__))
17 17
18 18 # Quick-start development settings - unsuitable for production
19 19 # See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
20 20
21 21 # SECURITY WARNING: keep the secret key used in production secret!
22 22 SECRET_KEY = 'xshb$k5fc-+j16)cvyffj&9u__0q3$l!hieh#+tbzqg)*f^km0'
23 23
24 24 # SECURITY WARNING: don't run with debug turned on in production!
25 25 DEBUG = True
26 26
27 27 ALLOWED_HOSTS = []
28 28
29 29 # Application definition
30 30
31 31 INSTALLED_APPS = (
32 32 'django.contrib.admin',
33 33 'django.contrib.auth',
34 34 'django.contrib.contenttypes',
35 35 'django.contrib.sessions',
36 36 'django.contrib.messages',
37 37 'django.contrib.staticfiles',
38 38 'bootstrap3',
39 39 'polymorphic',
40 40 'apps.accounts',
41 41 'apps.main',
42 42 'apps.misc',
43 43 'apps.rc',
44 44 'apps.dds',
45 45 'apps.cgs',
46 46 'apps.jars',
47 47 'apps.usrp',
48 48 'apps.abs',
49 49 )
50 50
51 51 MIDDLEWARE_CLASSES = (
52 52 'django.contrib.sessions.middleware.SessionMiddleware',
53 53 'django.middleware.common.CommonMiddleware',
54 54 'django.middleware.csrf.CsrfViewMiddleware',
55 55 'django.contrib.auth.middleware.AuthenticationMiddleware',
56 56 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
57 57 'django.contrib.messages.middleware.MessageMiddleware',
58 58 'django.middleware.clickjacking.XFrameOptionsMiddleware',
59 59 'django.middleware.security.SecurityMiddleware',
60 60 )
61 61
62 62 ROOT_URLCONF = 'radarsys.urls'
63 63
64 64 TEMPLATES = [
65 65 {
66 66 'BACKEND': 'django.template.backends.django.DjangoTemplates',
67 67 'DIRS': [os.path.join(BASE_DIR, "templates").replace('\\', '/'),],
68 68 'APP_DIRS': True,
69 69 'OPTIONS': {
70 70 'context_processors': [
71 71 'django.template.context_processors.debug',
72 72 'django.template.context_processors.request',
73 73 'django.contrib.auth.context_processors.auth',
74 74 'django.contrib.messages.context_processors.messages',
75 75 ],
76 76 },
77 77 },
78 78 ]
79 79
80 80 WSGI_APPLICATION = 'radarsys.wsgi.application'
81 81
82 82
83 83 # Database
84 84 # https://docs.djangoproject.com/en/1.8/ref/settings/#databases
85 85
86 86 DATABASES = {
87 87 'default': {
88 88 'ENGINE': 'django.db.backends.mysql',
89 89 'NAME': 'radarsys',
90 90 'USER': 'developer',
91 91 'PASSWORD': 'idi2015',
92 92 }
93 93 }
94 94
95 95
96 96 # Internationalization
97 97 # https://docs.djangoproject.com/en/1.8/topics/i18n/
98 98
99 99 LANGUAGE_CODE = 'en-us'
100 100
101 101 TIME_ZONE = None
102 102
103 103 USE_I18N = True
104 104
105 105 USE_L10N = True
106 106
107 107 USE_TZ = False
108 108
109 109 # Static files (CSS, JavaScript, Images)
110 110 # https://docs.djangoproject.com/en/1.8/howto/static-files/
111 111
112 112 STATIC_URL = '/static/'
113 113 STATIC_ROOT = '/var/www/html/static/'
114 114
115 115 STATICFILES_DIRS = (
116 116 os.path.join(BASE_DIR, 'apps', 'main', 'static'),
117 117
118 118 )
119 119
120 120 STATICFILES_FINDERS = (
121 121 'django.contrib.staticfiles.finders.FileSystemFinder',
122 122 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
123 123 )
124
125 FIXTURE_DIRS = (
126 os.path.join(BASE_DIR, 'apps', 'rc', 'fixtures'),
127 os.path.join(BASE_DIR, 'apps', 'main', 'fixtures'),
128
129 )
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now