##// 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
@@ -14,7 +14,8 DDS_FILE_FORMAT = (
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='-----'):
@@ -176,9 +176,15 class Configuration(PolymorphicModel):
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
@@ -228,7 +234,7 class Configuration(PolymorphicModel):
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,
@@ -18,6 +18,7
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>
@@ -134,7 +135,7
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%}
@@ -10,12 +10,15
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 %}
@@ -26,7 +29,8
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>
@@ -41,6 +45,9
41 45 {% endfor %}
42 46 </table>
43 47
48 {% block extra-content %}
49 {% endblock %}
50
44 51 {% endblock %}
45 52
46 53 {% block sidebar%}
@@ -20,6 +20,11
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>
@@ -32,4 +37,10
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
@@ -61,14 +61,17
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">
@@ -1,4 +1,5
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):
@@ -32,4 +33,5 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
@@ -26,6 +26,7 urlpatterns = (
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'),
@@ -391,7 +391,7 def experiment(request, id_exp):
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})
@@ -473,42 +473,42 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'
@@ -701,7 +701,7 def dev_conf_import(request, id_conf):
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
@@ -772,21 +772,17 def dev_conf_delete(request, id_conf):
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
@@ -1,4 +1,5
1 1 import os
2 import ast
2 3 import json
3 4
4 5 from django import forms
@@ -6,17 +7,19 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):
@@ -47,35 +50,9 class ExtFileField(forms.FileField):
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):
@@ -86,33 +63,98 class RCConfigurationForm(forms.ModelForm):
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')
@@ -120,6 +162,16 class RCLineForm(forms.ModelForm):
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
@@ -132,11 +184,13 class RCLineForm(forms.ModelForm):
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
@@ -145,12 +199,19 class RCLineForm(forms.ModelForm):
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:
@@ -158,48 +219,79 class RCLineViewForm(forms.Form):
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')
@@ -220,4 +312,25 class RCSubLineEditForm(forms.Form):
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
@@ -6,10 +6,12 import numpy as np
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 = (
@@ -24,37 +26,283 LINE_TYPES = (
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
@@ -97,15 +345,18 class RCLine(models.Model):
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'))
@@ -113,7 +364,7 class RCLine(models.Model):
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()
@@ -125,21 +376,59 class RCLine(models.Model):
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
@@ -152,7 +441,7 class RCLine(models.Model):
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':
@@ -161,31 +450,32 class RCLine(models.Model):
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':
@@ -215,9 +505,12 class RCLine(models.Model):
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':
@@ -233,4 +526,5 class RCLine(models.Model):
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
@@ -9,5 +9,10
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
@@ -3,24 +3,11
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>
@@ -28,54 +15,4
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%}
@@ -7,6 +7,8
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 %}
@@ -30,7 +32,7
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
@@ -46,6 +48,10
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 });
@@ -15,21 +15,25
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>
@@ -8,18 +8,11
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}}
@@ -7,12 +7,14 urlpatterns = (
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,646 +1,13
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
@@ -660,6 +27,10 class RCFile(object):
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
@@ -673,39 +44,61 class RCFile(object):
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
@@ -717,7 +110,9 class RCFile(object):
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:
@@ -730,6 +125,8 class RCFile(object):
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):
@@ -740,8 +137,12 class RCFile(object):
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 = []
@@ -800,13 +201,13 class RCFile(object):
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]
@@ -881,7 +282,7 def pulses(X, period, width, delay=0, before=0, after=0, sync=0, shift=0):
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
@@ -891,34 +292,21 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()]
@@ -1,3 +1,4
1
1 2 import json
2 3
3 4 from django.contrib import messages
@@ -8,8 +9,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):
@@ -27,8 +28,8 def conf(request, conf_id):
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'
@@ -46,21 +47,14 def conf_edit(request, 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
@@ -76,22 +70,26 def conf_edit(request, conf_id):
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():
@@ -125,7 +123,7 def conf_edit(request, conf_id):
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
@@ -147,21 +145,29 def conf_edit(request, conf_id):
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()
@@ -175,11 +181,51 def add_line(request, conf_id, line_type_id=None):
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)
@@ -188,13 +234,12 def add_subline(request, conf_id, line_id):
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)
@@ -234,6 +279,7 def remove_line(request, conf_id, line_id):
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)
@@ -273,13 +319,19 def update_lines_position(request, conf_id):
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
@@ -289,59 +341,17 def import_file(request, conf_id):
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())
@@ -351,8 +361,7 def import_file(request, conf_id):
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
@@ -362,7 +371,7 def import_file(request, conf_id):
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
@@ -373,17 +382,14 def view_pulses(request, conf_id):
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
@@ -121,3 +121,9 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