##// 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 RC_FILE_FORMAT = (
15 RC_FILE_FORMAT = (
16 ('json', 'json'),
16 ('json', 'json'),
17 ('text', 'rc')
17 ('text', 'racp'),
18 ('binary', 'dat'),
18 )
19 )
19
20
20 def add_empty_choice(choices, pos=0, label='-----'):
21 def add_empty_choice(choices, pos=0, label='-----'):
@@ -176,9 +176,15 class Configuration(PolymorphicModel):
176 db_table = 'db_configurations'
176 db_table = 'db_configurations'
177
177
178 def __unicode__(self):
178 def __unicode__(self):
179 return u'[%s, %s]: %s' % (self.experiment.name,
179
180 self.device.name,
180 if self.experiment:
181 self.name)
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 def parms_to_dict(self):
189 def parms_to_dict(self):
184
190
@@ -228,7 +234,7 class Configuration(PolymorphicModel):
228 if not content_type:
234 if not content_type:
229 content_type = 'application/json'
235 content_type = 'application/json'
230 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
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 fields = {'content_type':content_type,
239 fields = {'content_type':content_type,
234 'filename':filename,
240 'filename':filename,
@@ -18,6 +18,7
18 <!--[if lt IE 9]>
18 <!--[if lt IE 9]>
19 <script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
19 <script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
20 <![endif]-->
20 <![endif]-->
21 <script src="{% static 'js/jquery.min.js' %}"></script>
21 {% block extra-head %}
22 {% block extra-head %}
22 {% endblock %}
23 {% endblock %}
23 </head>
24 </head>
@@ -134,7 +135,7
134 {% endblock %}
135 {% endblock %}
135
136
136 {# bootstrap_javascript jquery=True #}
137 {# bootstrap_javascript jquery=True #}
137 <script src="{% static 'js/jquery.min.js' %}"></script>
138
138 <script src="{% static 'js/bootstrap.min.js' %}"></script>
139 <script src="{% static 'js/bootstrap.min.js' %}"></script>
139 {% block extra-js %}
140 {% block extra-js %}
140 {% endblock%}
141 {% endblock%}
@@ -10,12 +10,15
10
10
11 {% block content %}
11 {% block content %}
12
12
13 {% block menu-actions %}
13 <span class=" dropdown pull-right">
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 <ul class="dropdown-menu" role="menu">
16 <ul class="dropdown-menu" role="menu">
16 <li><a href="{{ dev_conf.get_absolute_url_edit }}"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit</a></li>
17 <li><a href="{{ dev_conf.get_absolute_url_edit }}"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit</a></li>
17 <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_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 <li><a>----------------</a></li>
22 <li><a>----------------</a></li>
20 <li><a href="{{ dev_conf.get_absolute_url_status }}"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span> Status</a></li>
23 <li><a href="{{ dev_conf.get_absolute_url_status }}"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span> Status</a></li>
21 {% if not no_play %}
24 {% if not no_play %}
@@ -26,7 +29,8
26 <li><a href="{{ dev_conf.get_absolute_url_read }}"><span class="glyphicon glyphicon-upload" aria-hidden="true"></span> Read</a></li>
29 <li><a href="{{ dev_conf.get_absolute_url_read }}"><span class="glyphicon glyphicon-upload" aria-hidden="true"></span> Read</a></li>
27 </ul>
30 </ul>
28 </span>
31 </span>
29
32 {% endblock %}
33
30 <table class="table table-bordered">
34 <table class="table table-bordered">
31 <tr>
35 <tr>
32 <th>Status</th>
36 <th>Status</th>
@@ -41,6 +45,9
41 {% endfor %}
45 {% endfor %}
42 </table>
46 </table>
43
47
48 {% block extra-content %}
49 {% endblock %}
50
44 {% endblock %}
51 {% endblock %}
45
52
46 {% block sidebar%}
53 {% block sidebar%}
@@ -20,6 +20,11
20 {% bootstrap_form form layout='horizontal' size='medium' %}
20 {% bootstrap_form form layout='horizontal' size='medium' %}
21 <div style="clear: both;"></div>
21 <div style="clear: both;"></div>
22 <br>
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 <div class="pull-right">
28 <div class="pull-right">
24 <button type="button" class="btn btn-primary" onclick="{% if previous %}window.location.replace('{{ previous }}');{% else %}history.go(-1);{% endif %}">Cancel</button>
29 <button type="button" class="btn btn-primary" onclick="{% if previous %}window.location.replace('{{ previous }}');{% else %}history.go(-1);{% endif %}">Cancel</button>
25 <button type="submit" class="btn btn-primary">{{button}}</button>
30 <button type="submit" class="btn btn-primary">{{button}}</button>
@@ -32,4 +37,10
32 {% endblock %}
37 {% endblock %}
33
38
34 {% block extra-js%}
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 {% endblock %} No newline at end of file
46 {% endblock %}
@@ -61,14 +61,17
61 {% endif %}
61 {% endif %}
62
62
63 {% if dev_conf %}
63 {% if dev_conf %}
64 <div class="panel panel-default">
64
65 <div class="panel-heading">
65 {% if campaign %}
66 <h4>Campaign</h4>
66 <div class="panel panel-default">
67 </div>
67 <div class="panel-heading">
68 <div class="list-group">
68 <h4>Campaign</h4>
69 <a href="{% url 'url_campaign' dev_conf.experiment.campaign.id %}" class="list-group-item active" >{{ dev_conf.experiment.campaign.name }}</a>
69 </div>
70 </div>
70 <div class="list-group">
71 </div>
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 {% if experiments %}
76 {% if experiments %}
74 <div class="panel panel-default">
77 <div class="panel panel-default">
@@ -1,4 +1,5
1 from django.template.defaulttags import register
1 from django.template.defaulttags import register
2 from django.utils.safestring import mark_safe
2
3
3 @register.filter
4 @register.filter
4 def attr(instance, key):
5 def attr(instance, key):
@@ -32,4 +33,5 def get_verbose_field_name(instance, field_name):
32 """
33 """
33 Returns verbose_name for a field.
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 url(r'^experiment/(?P<id_exp>-?\d+)/delete/$', 'apps.main.views.experiment_delete', name='url_delete_experiment'),
26 url(r'^experiment/(?P<id_exp>-?\d+)/delete/$', 'apps.main.views.experiment_delete', name='url_delete_experiment'),
27
27
28 url(r'^experiment/(?P<id_exp>-?\d+)/new_dev_conf/$', 'apps.main.views.dev_conf_new', name='url_add_dev_conf'),
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 url(r'^dev_conf/$', 'apps.main.views.dev_confs', name='url_dev_confs'),
30 url(r'^dev_conf/$', 'apps.main.views.dev_confs', name='url_dev_confs'),
30 url(r'^dev_conf/(?P<id_conf>-?\d+)/$', 'apps.main.views.dev_conf', name='url_dev_conf'),
31 url(r'^dev_conf/(?P<id_conf>-?\d+)/$', 'apps.main.views.dev_conf', name='url_dev_conf'),
31 url(r'^dev_conf/(?P<id_conf>-?\d+)/edit/$', 'apps.main.views.dev_conf_edit', name='url_edit_dev_conf'),
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 return render(request, 'experiment.html', kwargs)
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 if request.method == 'GET':
396 if request.method == 'GET':
397 form = ExperimentForm(initial={'campaign':id_camp})
397 form = ExperimentForm(initial={'campaign':id_camp})
@@ -473,42 +473,42 def dev_conf(request, id_conf):
473
473
474 conf = get_object_or_404(Configuration, pk=id_conf)
474 conf = get_object_or_404(Configuration, pk=id_conf)
475
475
476 DevConfModel = CONF_MODELS[conf.device.device_type.name]
476 return redirect(conf.get_absolute_url())
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']
482
477
483 kwargs['title'] = 'Configuration'
478
484 kwargs['suptitle'] = 'Details'
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 ######
483 if id_exp==0:
489 kwargs.update(sidebar(conf))
484 initial['experiment'] = id_exp
490
485
491 return render(request, 'dev_conf.html', kwargs)
486 if id_dev<>0:
492
487 initial['device'] = id_dev
493 def dev_conf_new(request, id_exp=0):
494
488
495 if request.method == 'GET':
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 if request.method == 'POST':
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 DevConfForm = CONF_FORMS[device.device_type.name]
501 DevConfForm = CONF_FORMS[device.device_type.name]
503
502
504 form = DevConfForm(request.POST, initial={'experiment':experiment.id})
503 form = DevConfForm(request.POST)
505
504
506 if form.is_valid():
505 if form.is_valid():
507 dev_conf = form.save()
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 kwargs = {}
510 kwargs = {}
511 kwargs['id_exp'] = id_exp
512 kwargs['form'] = form
512 kwargs['form'] = form
513 kwargs['title'] = 'Configuration'
513 kwargs['title'] = 'Configuration'
514 kwargs['suptitle'] = 'New'
514 kwargs['suptitle'] = 'New'
@@ -701,7 +701,7 def dev_conf_import(request, id_conf):
701 ###### SIDEBAR ######
701 ###### SIDEBAR ######
702 kwargs.update(sidebar(conf))
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 messages.error(request, "Could not import parameters from file")
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 def sidebar(conf):
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 kwargs = {}
775 kwargs = {}
782
776
783 kwargs['dev_conf'] = conf
777 if conf.experiment:
784
778 experiments = Experiment.objects.filter(campaign=conf.experiment.campaign)
785 kwargs['experiment_keys'] = exp_keys[1:]
779 configurations = Configuration.objects.filter(experiment=conf.experiment, type=0)
786 kwargs['experiments'] = experiments.values(*exp_keys)
780 exp_keys = ['id', 'campaign', 'name', 'start_time', 'end_time']
787
781 kwargs['experiment_keys'] = exp_keys[1:]
788 kwargs['configuration_keys'] = conf_keys[1:]
782 kwargs['experiments'] = experiments.values(*exp_keys)
789 kwargs['configurations'] = configurations #.values(*conf_keys)
783 conf_keys = ['id', 'device']
784 kwargs['configuration_keys'] = conf_keys[1:]
785 kwargs['configurations'] = configurations #.values(*conf_keys)
790
786
791 return kwargs
787 return kwargs
792
788
@@ -1,4 +1,5
1 import os
1 import os
2 import ast
2 import json
3 import json
3
4
4 from django import forms
5 from django import forms
@@ -6,17 +7,19 from django.utils.safestring import mark_safe
6 from apps.main.models import Device
7 from apps.main.models import Device
7 from apps.main.forms import add_empty_choice
8 from apps.main.forms import add_empty_choice
8 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode
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 if model=='RCLine':
14 if model=='RCLine':
13 instance = RCConfiguration.objects.get(pk=conf_id)
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 else:
18 else:
16 instance = globals()[model]
19 instance = globals()[model]
17 choices = instance.objects.all().values_list('pk', 'name')
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 class ExtFileField(forms.FileField):
25 class ExtFileField(forms.FileField):
@@ -47,35 +50,9 class ExtFileField(forms.FileField):
47 ext = os.path.splitext(filename)[1]
50 ext = os.path.splitext(filename)[1]
48 ext = ext.lower()
51 ext = ext.lower()
49 if ext not in self.extensions:
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 class RCConfigurationForm(forms.ModelForm):
56 class RCConfigurationForm(forms.ModelForm):
80
57
81 def __init__(self, *args, **kwargs):
58 def __init__(self, *args, **kwargs):
@@ -86,33 +63,98 class RCConfigurationForm(forms.ModelForm):
86 if instance and instance.pk:
63 if instance and instance.pk:
87
64
88 devices = Device.objects.filter(device_type__name='rc')
65 devices = Device.objects.filter(device_type__name='rc')
89
66 if instance.experiment:
90 self.fields['experiment'].widget.attrs['readonly'] = True
67 self.fields['experiment'].widget.attrs['readonly'] = True
91 self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
68 self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
92
93 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
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 class Meta:
77 class Meta:
96 model = RCConfiguration
78 model = RCConfiguration
97 exclude = ('type', 'parameters', 'status')
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 class RCLineForm(forms.ModelForm):
93 class RCLineForm(forms.ModelForm):
102
94
103 def __init__(self, *args, **kwargs):
95 def __init__(self, *args, **kwargs):
104 self.extra_fields = kwargs.pop('extra_fields', [])
96 self.extra_fields = kwargs.pop('extra_fields', [])
105 super(RCLineForm, self).__init__(*args, **kwargs)
97 super(RCLineForm, self).__init__(*args, **kwargs)
106 if 'initial'in kwargs:
98
107 for item in self.extra_fields:
99 if 'initial' in kwargs and 'line_type' in kwargs['initial']:
108 if item['name']=='params':
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 continue
140 continue
110 if 'model' in item:
141
111 self.fields[item['name']] = forms.ChoiceField(choices=create_choices_from_model(item['model'],
142 if 'model' in params[label]:
112 kwargs['initial']['rc_configuration']))
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 else:
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 class Meta:
158 class Meta:
117 model = RCLine
159 model = RCLine
118 fields = ('rc_configuration', 'line_type', 'channel')
160 fields = ('rc_configuration', 'line_type', 'channel')
@@ -120,6 +162,16 class RCLineForm(forms.ModelForm):
120 'channel': forms.HiddenInput(),
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 def save(self):
175 def save(self):
124 line = super(RCLineForm, self).save()
176 line = super(RCLineForm, self).save()
125
177
@@ -132,11 +184,13 class RCLineForm(forms.ModelForm):
132
184
133 #save extra fields in params
185 #save extra fields in params
134 params = {}
186 params = {}
135 for item in self.extra_fields:
187 for label, value in self.extra_fields.items():
136 if item['name']=='params':
188 if label=='params':
137 params['params'] = []
189 params['params'] = []
190 elif label=='codes':
191 params[label] = [s for s in self.data[label].split('\r\n') if s]
138 else:
192 else:
139 params[item['name']] = self.data[item['name']]
193 params[label] = self.data[label]
140 line.params = json.dumps(params)
194 line.params = json.dumps(params)
141 line.save()
195 line.save()
142 return
196 return
@@ -145,12 +199,19 class RCLineForm(forms.ModelForm):
145 class RCLineViewForm(forms.Form):
199 class RCLineViewForm(forms.Form):
146
200
147 def __init__(self, *args, **kwargs):
201 def __init__(self, *args, **kwargs):
202
148 extra_fields = kwargs.pop('extra_fields')
203 extra_fields = kwargs.pop('extra_fields')
149 line = kwargs.pop('line')
204 line = kwargs.pop('line')
150 subform = kwargs.pop('subform', False)
205 subform = kwargs.pop('subform', False)
151 super(RCLineViewForm, self).__init__(*args, **kwargs)
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 for label, value in extra_fields.items():
213 for label, value in extra_fields.items():
214
154 if label=='params':
215 if label=='params':
155 continue
216 continue
156 if 'ref' in label:
217 if 'ref' in label:
@@ -158,48 +219,79 class RCLineViewForm(forms.Form):
158 value = 'All'
219 value = 'All'
159 else:
220 else:
160 value = RCLine.objects.get(pk=value).get_name()
221 value = RCLine.objects.get(pk=value).get_name()
161 elif 'code' in label:
222 elif label=='code':
162 value = RCLineCode.objects.get(pk=value).name
223 value = RCLineCode.objects.get(pk=value).name
163
224
164 self.fields[label] = forms.CharField(initial=value)
225 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)
170
226
171 if 'widget' in params[label]:
227 if 'widget' in params[label]:
228 km2unit = line.rc_configuration.km2unit
172 if params[label]['widget']=='km':
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 else:
237 else:
175 self.fields[label].widget = DefaultWidget()
238 self.fields[label].widget = DefaultWidget(attrs={'disabled':True})
239
176
240
177 class RCLineEditForm(forms.ModelForm):
241 class RCLineEditForm(forms.ModelForm):
178
242
179 def __init__(self, *args, **kwargs):
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 super(RCLineEditForm, self).__init__(*args, **kwargs)
250 super(RCLineEditForm, self).__init__(*args, **kwargs)
182 if 'initial'in kwargs:
251
183 for item, values in self.extra_fields.items():
252 if subform is not False:
184 if item=='params':
253 params = json.loads(line.line_type.params)['params']
185 continue
254 count = subform
186 if 'help' in values:
255 else:
187 help_text = values['help']
256 params = json.loads(line.line_type.params)
188 else:
257 count = -1
189 help_text = ''
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:
274 else:
192 self.fields[item] = forms.ChoiceField(choices=create_choices_from_model(values['model'], kwargs['initial']['rc_configuration']),
275
193 initial=values['value'],
276 self.fields[label] = forms.CharField(initial=value, help_text=help_text)
194 widget=forms.Select(attrs={'name':'%s|%s' % (kwargs['initial']['line'], item)}),
277
195 help_text=help_text)
278 if label in ('code', ):
196
279 self.fields[label].widget = HiddenWidget(attrs={'name':'%s|%s|%s' % (count, line.id, label)})
197 else:
280
198 self.fields[item] = forms.CharField(initial=values['value'],
281 elif 'widget' in params[label]:
199 widget=forms.TextInput(attrs={'name':'%s|%s' % (kwargs['initial']['line'], item)}),
282 km2unit = line.rc_configuration.km2unit
200 help_text=help_text)
283 if params[label]['widget']=='km':
201
284 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
202
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 class Meta:
295 class Meta:
204 model = RCLine
296 model = RCLine
205 exclude = ('rc_configuration', 'line_type', 'channel', 'position', 'params', 'pulses')
297 exclude = ('rc_configuration', 'line_type', 'channel', 'position', 'params', 'pulses')
@@ -220,4 +312,25 class RCSubLineEditForm(forms.Form):
220 class RCImportForm(forms.Form):
312 class RCImportForm(forms.Form):
221
313
222 file_name = ExtFileField(extensions=['.racp', '.json', '.dat'])
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 No newline at end of file
336
@@ -6,10 +6,12 import numpy as np
6 from polymorphic import PolymorphicModel
6 from polymorphic import PolymorphicModel
7
7
8 from django.db import models
8 from django.db import models
9 from django.core.urlresolvers import reverse
9 from django.core.validators import MinValueValidator, MaxValueValidator
10 from django.core.validators import MinValueValidator, MaxValueValidator
10
11
11 from apps.main.models import Configuration
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 # Create your models here.
15 # Create your models here.
14
16
15 LINE_TYPES = (
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 class RCConfiguration(Configuration):
56 class RCConfiguration(Configuration):
28
57
29 ipp = models.FloatField(verbose_name='Inter pulse period (Km)', validators=[MinValueValidator(1), MaxValueValidator(1000)], default=10)
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)
59 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
31 clock = models.FloatField(verbose_name='Clock Master (MHz)', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
60 clock_in = models.FloatField(verbose_name='Clock in (MHz)', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
32 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
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)
62 clock = models.FloatField(verbose_name='Clock Master (MHz)', blank=True, default=1)
34 time_after = models.PositiveIntegerField(verbose_name='Time after', default=0)
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 sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
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 class Meta:
71 class Meta:
38 db_table = 'rc_configurations'
72 db_table = 'rc_configurations'
39
73
40 def get_number_position(self):
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)
84 return self.clock_in/self.clock_divider
43 if lines:
85
44 return max([line.position for line in lines])
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')
90 return 20./3*(self.clock_in/self.clock_divider)
49 return [(line.pk, line.get_name()) for line in lines]
91
50
92
51 def get_lines(self, type=None):
93 def get_lines(self, type=None):
94 '''
95 Retrieve configuration lines
96 '''
52
97
53 if type is not None:
98 if type is not None:
54 return RCLine.objects.filter(rc_configuration=self.pk, line_type__name=type)
99 return RCLine.objects.filter(rc_configuration=self.pk, line_type__name=type)
55 else:
100 else:
56 return RCLine.objects.filter(rc_configuration=self.pk)
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 class RCLineCode(models.Model):
307 class RCLineCode(models.Model):
60
308
@@ -97,15 +345,18 class RCLine(models.Model):
97 ordering = ['channel']
345 ordering = ['channel']
98
346
99 def __unicode__(self):
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 def get_name(self):
351 def get_name(self):
103
352
104 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
353 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
105
354
106 if self.line_type.name in ('tx',):
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 elif self.line_type.name in ('codes', 'windows', 'tr'):
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 pk = json.loads(self.params)['TX_ref']
360 pk = json.loads(self.params)['TX_ref']
110 if pk in (0, '0'):
361 if pk in (0, '0'):
111 refs = ','.join(chars[l.position] for l in self.rc_configuration.get_lines('tx'))
362 refs = ','.join(chars[l.position] for l in self.rc_configuration.get_lines('tx'))
@@ -113,7 +364,7 class RCLine(models.Model):
113 else:
364 else:
114 ref = RCLine.objects.get(pk=pk)
365 ref = RCLine.objects.get(pk=pk)
115 return '%s (%s)' % (self.line_type.name.upper(), chars[ref.position])
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 return '%s %s' % (self.line_type.name.upper(), self.channel)
368 return '%s %s' % (self.line_type.name.upper(), self.channel)
118 else:
369 else:
119 return self.line_type.name.upper()
370 return self.line_type.name.upper()
@@ -125,21 +376,59 class RCLine(models.Model):
125 else:
376 else:
126 return RCLine.objects.filter(rc_configuration=self.rc_configuration)
377 return RCLine.objects.filter(rc_configuration=self.rc_configuration)
127
378
379
128 def pulses_as_array(self):
380 def pulses_as_array(self):
129
381
130 return (np.fromstring(self.pulses, dtype=np.uint8)-48).astype(np.int8)
382 return (np.fromstring(self.pulses, dtype=np.uint8)-48).astype(np.int8)
131
383
132 @property
384
133 def km2unit(self):
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 def update_pulses(self, save=True, tr=False):
422 def update_pulses(self, save=True, tr=False):
138 print self
423 '''
139 KM2U = 20./3*(self.rc_configuration.clock/self.rc_configuration.clock_divider)
424 Update pulses field
425 '''
426
427 km2unit = self.rc_configuration.km2unit
428 us2unit = self.rc_configuration.us2unit
140 ipp = self.rc_configuration.ipp
429 ipp = self.rc_configuration.ipp
141 ntx = self.rc_configuration.ntx
430 ntx = self.rc_configuration.ntx
142 ipp_u = int(ipp*KM2U)
431 ipp_u = int(ipp*km2unit)
143
432
144 x = np.arange(0, ipp_u*ntx)
433 x = np.arange(0, ipp_u*ntx)
145
434
@@ -152,7 +441,7 class RCLine(models.Model):
152 if len(txs)==0 or 0 in [len(tx) for tx in txs]:
441 if len(txs)==0 or 0 in [len(tx) for tx in txs]:
153 return
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 ranges = params['range'].split(',')
446 ranges = params['range'].split(',')
158 if len(ranges)>0 and ranges[0]<>'0':
447 if len(ranges)>0 and ranges[0]<>'0':
@@ -161,31 +450,32 class RCLine(models.Model):
161
450
162 elif self.line_type.name=='tx':
451 elif self.line_type.name=='tx':
163 params = json.loads(self.params)
452 params = json.loads(self.params)
164 delays = [float(d)*KM2U for d in params['delays'].split(',') if d]
453 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
165 y = pulses(x, ipp_u, float(params['pulse_width'])*KM2U,
454 y = pulses(x, ipp_u, float(params['pulse_width'])*km2unit,
166 delay=delays,
455 delay=delays,
167 before=self.rc_configuration.time_before,
456 before=int(self.rc_configuration.time_before*us2unit),
168 after=self.rc_configuration.time_after if tr else 0,
457 after=int(self.rc_configuration.time_after*us2unit) if tr else 0,
169 sync=self.rc_configuration.sync)
458 sync=self.rc_configuration.sync)
459
170 ranges = params['range'].split(',')
460 ranges = params['range'].split(',')
171
461
172 if len(ranges)>0 and ranges[0]<>'0':
462 if len(ranges)>0 and ranges[0]<>'0':
173 mask = create_mask(ranges, ipp_u, ntx, self.rc_configuration.sync)
463 mask = create_mask(ranges, ipp_u, ntx, self.rc_configuration.sync)
174 y = y & mask
464 y = y & mask
175
465
176 elif self.line_type.name=='flip':
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 y = pulses(x, 2*width, width)
468 y = pulses(x, 2*width, width)
179
469
180 elif self.line_type.name=='codes':
470 elif self.line_type.name=='codes':
181 params = json.loads(self.params)
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 tx = RCLine.objects.get(pk=params['TX_ref'])
473 tx = RCLine.objects.get(pk=params['TX_ref'])
184 tx_params = json.loads(tx.params)
474 tx_params = json.loads(tx.params)
185
475
186 y = pulses_from_code(ipp_u, ntx, codes,
476 y = pulses_from_code(ipp_u, ntx, params['codes'],
187 int(float(tx_params['pulse_width'])*KM2U),
477 int(float(tx_params['pulse_width'])*km2unit),
188 before=self.rc_configuration.time_before+self.rc_configuration.sync)
478 before=int(self.rc_configuration.time_before*us2unit)+self.rc_configuration.sync)
189
479
190 ranges = tx_params['range'].split(',')
480 ranges = tx_params['range'].split(',')
191 if len(ranges)>0 and ranges[0]<>'0':
481 if len(ranges)>0 and ranges[0]<>'0':
@@ -215,9 +505,12 class RCLine(models.Model):
215 elif self.line_type.name=='windows':
505 elif self.line_type.name=='windows':
216 params = json.loads(self.params)
506 params = json.loads(self.params)
217 if 'params' in params and len(params['params'])>0:
507 if 'params' in params and len(params['params'])>0:
218 y = sum([pulses(x, ipp_u, pp['resolution']*pp['number_of_samples']*KM2U,
508 print 'REFS'
219 delay=(pp['first_height']-pp['resolution'])*KM2U,
509 print [self.get_win_ref(pp, params['TX_ref'],km2unit) for pp in params['params']]
220 before=self.rc_configuration.time_before) 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 tr = self.get_lines('tr')[0]
514 tr = self.get_lines('tr')[0]
222 ranges = json.loads(tr.params)['range'].split(',')
515 ranges = json.loads(tr.params)['range'].split(',')
223 if len(ranges)>0 and ranges[0]<>'0':
516 if len(ranges)>0 and ranges[0]<>'0':
@@ -233,4 +526,5 class RCLine(models.Model):
233 self.save()
526 self.save()
234 else:
527 else:
235 return y
528 return y
236 No newline at end of file
529
530 No newline at end of file
@@ -9,5 +9,10
9 document.location = url + $(this).val()+"/";
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 </script>
17 </script>
13 {% endblock %} No newline at end of file
18 {% endblock %}
@@ -3,24 +3,11
3 {% load bootstrap3 %}
3 {% load bootstrap3 %}
4 {% load main_tags %}
4 {% load main_tags %}
5
5
6 {% block extra-head %}
6 {% block extra-menu-actions %}
7 <link href="http://cdn.pydata.org/bokeh/release/bokeh-0.11.1.min.css" rel="stylesheet" type="text/css">
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 {% endblock %}
8 {% endblock %}
9
9
10 {% block content %}
10 {% block extra-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
24
11
25 <div class="clearfix"></div>
12 <div class="clearfix"></div>
26 <h2>RC Lines</h2><hr>
13 <h2>RC Lines</h2><hr>
@@ -28,54 +15,4
28 {% include "rc_lines.html" %}
15 {% include "rc_lines.html" %}
29 </div>
16 </div>
30
17
31 <br>
18 {% endblock extra-content%}
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
@@ -7,6 +7,8
7 /* show the move cursor as the user moves the mouse over the panel header.*/
7 /* show the move cursor as the user moves the mouse over the panel header.*/
8 .panel-default { cursor: move; }
8 .panel-default { cursor: move; }
9 </style>
9 </style>
10 <script src="{% static 'js/jquery-ui.min.js' %}"></script>
11
10 {% endblock %}
12 {% endblock %}
11
13
12 {% block content %}
14 {% block content %}
@@ -30,7 +32,7
30
32
31 {% block extra-js%}
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 <script type="text/javascript">
37 <script type="text/javascript">
36
38
@@ -46,6 +48,10
46 document.location = "/rc/{{dev_conf.id}}/line/"+$(this).val()+"/add_subline/";
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 $("#bt_add_line").click(function() {
55 $("#bt_add_line").click(function() {
50 document.location = "{% url 'url_add_rc_line' dev_conf.id%}";
56 document.location = "{% url 'url_add_rc_line' dev_conf.id%}";
51 });
57 });
@@ -15,21 +15,25
15 <div id="collapse{{line.id}}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading{{line.id}}">
15 <div id="collapse{{line.id}}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading{{line.id}}">
16 <div class="panel-body">
16 <div class="panel-body">
17 {% bootstrap_form line.form layout='horizontal' size='small' %}
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 %}
33 {% if edit and line.line_type.name == 'codes' %}
21 <div class="form-group form-group-sm">
34 <br>
22 <label class="col-md-3 control-label">{{line.line_type.name}}-{{ forloop.counter }}</label>
35 <button type="button" class="btn btn-sm btn-default" style="margin-left: 10px" name="bt_edit_codes" value="{{line.pk}}">Edit</button>
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>
36 {% endif %}
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
37
34 </div>
38 </div>
35 </div>
39 </div>
@@ -8,18 +8,11
8 {% endblock %}
8 {% endblock %}
9
9
10 {% block content %}
10 {% block content %}
11
11 <div id="div_plot">{{div}}</div>
12
13
14 <div id="div_plot">{{div}}</div>
15
16
17
18 {% endblock %}
12 {% endblock %}
19
13
20 {% block extra-js%}
14 {% block extra-js%}
21
15
22 <script src="{% static 'js/jquery-ui.min.js' %}"></script>
23 <script src="{% static 'js/bokeh-0.11.1.min.js' %}"></script>
16 <script src="{% static 'js/bokeh-0.11.1.min.js' %}"></script>
24
17
25 {{script}}
18 {{script}}
@@ -7,12 +7,14 urlpatterns = (
7 url(r'^(?P<conf_id>-?\d+)/plot/$', 'apps.rc.views.view_pulses', name='url_plot_rc_pulses'),
7 url(r'^(?P<conf_id>-?\d+)/plot/$', 'apps.rc.views.view_pulses', name='url_plot_rc_pulses'),
8 url(r'^(?P<id_conf>-?\d+)/write/$', 'apps.main.views.dev_conf_write', name='url_write_rc_conf'),
8 url(r'^(?P<id_conf>-?\d+)/write/$', 'apps.main.views.dev_conf_write', name='url_write_rc_conf'),
9 url(r'^(?P<id_conf>-?\d+)/read/$', 'apps.main.views.dev_conf_read', name='url_read_rc_conf'),
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 url(r'^(?P<conf_id>-?\d+)/add_line/$', 'apps.rc.views.add_line', name='url_add_rc_line'),
11 url(r'^(?P<conf_id>-?\d+)/add_line/$', 'apps.rc.views.add_line', name='url_add_rc_line'),
13 url(r'^(?P<conf_id>-?\d+)/add_line/(?P<line_type_id>-?\d+)/$', 'apps.rc.views.add_line', name='url_add_rc_line'),
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 url(r'^(?P<conf_id>-?\d+)/update_position/$', 'apps.rc.views.update_lines_position', name='url_update_rc_lines_position'),
14 url(r'^(?P<conf_id>-?\d+)/update_position/$', 'apps.rc.views.update_lines_position', name='url_update_rc_lines_position'),
15 url(r'^(?P<conf_id>-?\d+)/line/(?P<line_id>-?\d+)/delete/$', 'apps.rc.views.remove_line', name='url_remove_rc_line'),
15 url(r'^(?P<conf_id>-?\d+)/line/(?P<line_id>-?\d+)/delete/$', 'apps.rc.views.remove_line', name='url_remove_rc_line'),
16 url(r'^(?P<conf_id>-?\d+)/line/(?P<line_id>-?\d+)/add_subline/$', 'apps.rc.views.add_subline', name='url_add_rc_subline'),
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 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'),
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']
2 import json
450 xml_l = param_field['xml']
3 import numpy as np
451 id = str(param_field['number_experiment'])
4 import matplotlib.pyplot as plt
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")
639
5
640 racp_content = "\n".join([str(x) for x in output])
641 return racp_content
642
6
643 class RCFile(object):
7 class RCFile(object):
8 '''
9 Class to handle Radar controller configuration files
10 '''
644
11
645 def __init__(self, f=None):
12 def __init__(self, f=None):
646
13
@@ -660,6 +27,10 class RCFile(object):
660 self.parse_racp()
27 self.parse_racp()
661 elif 'dat' in self.name:
28 elif 'dat' in self.name:
662 self.parse_dat()
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 def get_line_parameters(self, data, line):
35 def get_line_parameters(self, data, line):
665
36
@@ -673,39 +44,61 class RCFile(object):
673
44
674 data = {}
45 data = {}
675 raw_data = [s.strip() for s in self.f.readlines()]
46 raw_data = [s.strip() for s in self.f.readlines()]
47
676 for line in raw_data:
48 for line in raw_data:
677 if line and '=' in line:
49 if line and '=' in line:
678 label, value = line.strip().split('=')
50 label, value = line.strip().split('=')
679 data[label] = value
51 data[label] = value
52
680 self.data['experiment_type'] = data['EXPERIMENT TYPE']
53 self.data['experiment_type'] = data['EXPERIMENT TYPE']
681 self.data['header_version'] = data['HEADER VERSION']
54 self.data['header_version'] = data['HEADER VERSION']
682 self.data['name'] = data['EXPERIMENT NAME']
55 self.data['name'] = data['EXPERIMENT NAME']
683 self.data['ipp'] = float(data['IPP'])
56 self.data['ipp'] = float(data['IPP'])
684 self.data['ntx'] = int(data['NTX'])
57 self.data['ntx'] = int(data['NTX'])
58
685 if 'CLOCK DIVIDER' in data:
59 if 'CLOCK DIVIDER' in data:
686 self.data['clock_divider'] = int(data['CLOCK DIVIDER'])
60 self.data['clock_divider'] = int(data['CLOCK DIVIDER'])
687 else:
61 else:
688 self.data['clock_divider'] = 1
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 self.data['time_before'] = int(data['TR_BEFORE'])
65 self.data['time_before'] = int(data['TR_BEFORE'])
691 self.data['time_after'] = int(data['TR_AFTER'])
66 self.data['time_after'] = int(data['TR_AFTER'])
67
692 if 'SYNCHRO DELAY' in data:
68 if 'SYNCHRO DELAY' in data:
693 self.data['sync'] = int(data['SYNCHRO DELAY'])
69 self.data['sync'] = int(data['SYNCHRO DELAY'])
694 else:
70 else:
695 self.data['sync'] = 0
71 self.data['sync'] = 0
696 self.data['lines'] = []
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 #Add TR line
82 #Add TR line
699 if 'Pulse selection_TR' in data:
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 rng = data['Pulse selection_TR'].replace('A', '')
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 elif 'B' in data['Pulse selection_TR']:
93 elif 'B' in data['Pulse selection_TR']:
703 rng = data['Pulse selection_TR'].replace('B', '')
94 rng = data['Pulse selection_TR'].replace('B', '')
95 ref = 'TXB'
704 else:
96 else:
705 rng = data['Pulse selection_TR']
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 else:
100 else:
708 line = {'type': 'tr', 'range': 0, 'TX_ref': '0'}
101 line = {'type': 'tr', 'range': '0', 'TX_ref': '0'}
709
102
710 self.data['lines'].append(line)
103 self.data['lines'].append(line)
711
104
@@ -717,7 +110,9 class RCFile(object):
717 else:
110 else:
718 line['range'] = '0'
111 line['range'] = '0'
719 self.data['lines'].append(line)
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 if 'TXB' in data:
116 if 'TXB' in data:
722 line = {'type':'tx', 'pulse_width':data['TXB'], 'delays':'0'}
117 line = {'type':'tx', 'pulse_width':data['TXB'], 'delays':'0'}
723 if 'Pulse selection_TXB' in data:
118 if 'Pulse selection_TXB' in data:
@@ -730,6 +125,8 class RCFile(object):
730 line['delays'] = ','.join(delays)
125 line['delays'] = ','.join(delays)
731
126
732 self.data['lines'].append(line)
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 #Add Other lines (4-6)
131 #Add Other lines (4-6)
735 for n in range(4, 7):
132 for n in range(4, 7):
@@ -740,8 +137,12 class RCFile(object):
740 line = {'type':'flip', 'number_of_flips':data['L%d_FLIP' % n]}
137 line = {'type':'flip', 'number_of_flips':data['L%d_FLIP' % n]}
741 elif 'Code Type' in data and n==4:
138 elif 'Code Type' in data and n==4:
742 line = {'type':'codes', 'code':data['Code Type'], 'TX_ref':data['L%d_REFERENCE' % n]}
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 elif 'Code Type (Line %d)' % n in labels:
142 elif 'Code Type (Line %d)' % n in labels:
744 line = {'type':'codes', 'code':data['Code Type (Line %d)' % n], 'TX_ref':data['L%d_REFERENCE' % n]}
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 elif 'Sampling Windows (Line %d)' % n in data:
146 elif 'Sampling Windows (Line %d)' % n in data:
746 line = {'type':'windows', 'TX_ref':data['L%d_REFERENCE' % n]}
147 line = {'type':'windows', 'TX_ref':data['L%d_REFERENCE' % n]}
747 windows = []
148 windows = []
@@ -800,13 +201,13 class RCFile(object):
800
201
801 def parse_dat(self):
202 def parse_dat(self):
802 pass
203 pass
803
204
804
205
805 def get_json(self, indent=None):
206 def get_json(self, indent=None):
806 return json.dumps(self.data, indent=indent)
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 d = X[1:]-X[:-1]
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 if shift>0:
282 if shift>0:
882 y = np.empty_like(Y)
283 y = np.empty_like(Y)
883 y[:shift] = 0
284 y[:shift] = 0
884 y[shift:] = Y[:-shift]
285 y[shift:] = Y[:-shift]
885 return y
286 return y
886 else:
287 else:
887 return Y
288 return Y
@@ -891,34 +292,21 def plot_pulses(unit, maximun, lines):
891
292
892 from bokeh.resources import CDN
293 from bokeh.resources import CDN
893 from bokeh.embed import components
294 from bokeh.embed import components
894 from bokeh.mpl import to_bokeh
295 from bokeh.mpl import to_bokeh
895 from bokeh.plotting import figure
896 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, PreviewSaveTool
296 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, PreviewSaveTool
897
297
898
899 N = len(lines)
298 N = len(lines)
900 fig = plt.figure(figsize=(10, 2+N*0.5))
299 fig = plt.figure(figsize=(10, 2+N*0.5))
901 ax = fig.add_subplot(111)
300 ax = fig.add_subplot(111)
902 labels = []
301 labels = []
903 data = []
302
904 for i, line in enumerate(lines):
303 for i, line in enumerate(lines):
905 print line
304 print line
906 labels.append(line.get_name())
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 edgecolor='none', facecolor='#2c3e50')
307 edgecolor='none', facecolor='#2c3e50')
909 #data.append(line.pulses_as_array())
308
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
919 labels.reverse()
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 ax.set_yticklabels(labels)
310 ax.set_yticklabels(labels)
923 plot = to_bokeh(fig, use_pandas=False)
311 plot = to_bokeh(fig, use_pandas=False)
924 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), PreviewSaveTool()]
312 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), PreviewSaveTool()]
@@ -1,3 +1,4
1
1 import json
2 import json
2
3
3 from django.contrib import messages
4 from django.contrib import messages
@@ -8,8 +9,8 from apps.main.models import Configuration, Experiment, Device
8 from apps.main.views import sidebar
9 from apps.main.views import sidebar
9
10
10 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode
11 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode
11 from .forms import RCConfigurationForm, RCLineForm, RCLineViewForm, RCLineEditForm, RCSubLineEditForm, RCImportForm
12 from .forms import RCConfigurationForm, RCLineForm, RCLineViewForm, RCLineEditForm, RCImportForm, RCLineCodesForm
12 from .utils import RCFile, plot_pulses
13 from .utils import plot_pulses
13
14
14
15
15 def conf(request, conf_id):
16 def conf(request, conf_id):
@@ -27,8 +28,8 def conf(request, conf_id):
27 kwargs = {}
28 kwargs = {}
28 kwargs['dev_conf'] = conf
29 kwargs['dev_conf'] = conf
29 kwargs['rc_lines'] = lines
30 kwargs['rc_lines'] = lines
30 kwargs['dev_conf_keys'] = ['name', 'ipp', 'ntx', 'clock', 'clock_divider',
31 kwargs['dev_conf_keys'] = ['name', 'ipp', 'ntx', 'clock_in', 'clock_divider', 'clock',
31 'time_before', 'time_after', 'sync']
32 'time_before', 'time_after', 'sync', 'sampling_reference', 'control_tx', 'control_sw']
32
33
33 kwargs['title'] = 'RC Configuration'
34 kwargs['title'] = 'RC Configuration'
34 kwargs['suptitle'] = 'Details'
35 kwargs['suptitle'] = 'Details'
@@ -46,21 +47,14 def conf_edit(request, conf_id):
46
47
47 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
48 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
48
49
49 for line in lines:
50 for line in lines:
50 line_type = get_object_or_404(RCLineType, pk=line.line_type.id)
51 params = json.loads(line.params)
51 extra_fields = json.loads(line_type.params)
52 line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params)
52 params = json.loads(line.params)
53 line.subform = False
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)
60
54
61 if 'params' in params:
55 if 'params' in params:
56 line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])]
62 line.subform = True
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 if request.method=='GET':
59 if request.method=='GET':
66
60
@@ -76,22 +70,26 def conf_edit(request, conf_id):
76 for label,value in request.POST.items():
70 for label,value in request.POST.items():
77 if label=='csrfmiddlewaretoken':
71 if label=='csrfmiddlewaretoken':
78 continue
72 continue
73
79 if label.count('|')==0:
74 if label.count('|')==0:
80 conf_data[label] = value
75 conf_data[label] = value
81 continue
76 continue
82 elif label.count('|')==2:
77
78 elif label.split('|')[0]<>'-1':
83 extras.append(label)
79 extras.append(label)
84 continue
80 continue
85
81
86 pk, name = label.split('|')
82 x, pk, name = label.split('|')
87
83
84 if name=='codes':
85 value = [s for s in value.split('\r\n') if s]
86
88 if pk in line_data:
87 if pk in line_data:
89 line_data[pk][name] = value
88 line_data[pk][name] = value
90 else:
89 else:
91 line_data[pk] = {name:value}
90 line_data[pk] = {name:value}
92
91
93 #update conf
92 #update conf
94
95 form = RCConfigurationForm(conf_data, instance=conf)
93 form = RCConfigurationForm(conf_data, instance=conf)
96
94
97 if form.is_valid():
95 if form.is_valid():
@@ -125,7 +123,7 def conf_edit(request, conf_id):
125 line.update_pulses()
123 line.update_pulses()
126
124
127 for tr in conf.get_lines('tr'):
125 for tr in conf.get_lines('tr'):
128 tr.update_pulses()
126 tr.update_pulses()
129
127
130 messages.success(request, 'RC Configuration successfully updated')
128 messages.success(request, 'RC Configuration successfully updated')
131
129
@@ -147,21 +145,29 def conf_edit(request, conf_id):
147 return render(request, 'rc_conf_edit.html', kwargs)
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 conf = get_object_or_404(RCConfiguration, pk=conf_id)
150 conf = get_object_or_404(RCConfiguration, pk=conf_id)
153
151
154 if request.method=='GET':
152 if request.method=='GET':
155 if line_type_id:
153 if line_type_id:
156 line_type = get_object_or_404(RCLineType, pk=line_type_id)
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},
155
158 extra_fields=json.loads(line_type.params))
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 else:
162 else:
163 line_type = {'id':0}
160 form = RCLineForm(initial={'rc_configuration':conf_id})
164 form = RCLineForm(initial={'rc_configuration':conf_id})
161
165
162 if request.method=='POST':
166 if request.method=='POST':
167
163 line_type = get_object_or_404(RCLineType, pk=line_type_id)
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 if form.is_valid():
172 if form.is_valid():
167 form.save()
173 form.save()
@@ -175,11 +181,51 def add_line(request, conf_id, line_type_id=None):
175 kwargs['button'] = 'Add'
181 kwargs['button'] = 'Add'
176 kwargs['previous'] = conf.get_absolute_url_edit()
182 kwargs['previous'] = conf.get_absolute_url_edit()
177 kwargs['dev_conf'] = conf
183 kwargs['dev_conf'] = conf
184 kwargs['line_type'] = line_type
178
185
179 kwargs.update(sidebar(conf))
186 kwargs.update(sidebar(conf))
180
187
181 return render(request, 'rc_add_line.html', kwargs)
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 def add_subline(request, conf_id, line_id):
229 def add_subline(request, conf_id, line_id):
184
230
185 conf = get_object_or_404(RCConfiguration, pk=conf_id)
231 conf = get_object_or_404(RCConfiguration, pk=conf_id)
@@ -188,13 +234,12 def add_subline(request, conf_id, line_id):
188 if request.method == 'POST':
234 if request.method == 'POST':
189 if line:
235 if line:
190 params = json.loads(line.params)
236 params = json.loads(line.params)
191 if 'params' in params:
237 subparams = json.loads(line.line_type.params)
192 subparams = json.loads(line.line_type.params)
238 if 'params' in subparams:
193 base = [p for p in subparams if p['name']=='params'][0]['form']
239 dum = {}
194 new = {}
240 for key, value in subparams['params'].items():
195 for p in base:
241 dum[key] = value['value']
196 new[p['name']] = p['value']
242 params['params'].append(dum)
197 params['params'].append(new)
198 line.params = json.dumps(params)
243 line.params = json.dumps(params)
199 line.save()
244 line.save()
200 return redirect('url_edit_rc_conf', conf.id)
245 return redirect('url_edit_rc_conf', conf.id)
@@ -234,6 +279,7 def remove_line(request, conf_id, line_id):
234 kwargs['previous'] = conf.get_absolute_url_edit()
279 kwargs['previous'] = conf.get_absolute_url_edit()
235 return render(request, 'confirm.html', kwargs)
280 return render(request, 'confirm.html', kwargs)
236
281
282
237 def remove_subline(request, conf_id, line_id, subline_id):
283 def remove_subline(request, conf_id, line_id, subline_id):
238
284
239 conf = get_object_or_404(RCConfiguration, pk=conf_id)
285 conf = get_object_or_404(RCConfiguration, pk=conf_id)
@@ -273,13 +319,19 def update_lines_position(request, conf_id):
273 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
319 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
274
320
275 for line in lines:
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 data = {'html': html.content}
330 data = {'html': html.content}
280
331
281 return HttpResponse(json.dumps(data), content_type="application/json")
332 return HttpResponse(json.dumps(data), content_type="application/json")
282 return redirect('url_edit_rc_conf', conf.id)
333 return redirect('url_edit_rc_conf', conf.id)
334
283
335
284 def import_file(request, conf_id):
336 def import_file(request, conf_id):
285
337
@@ -289,59 +341,17 def import_file(request, conf_id):
289 if form.is_valid():
341 if form.is_valid():
290 #try:
342 #try:
291 if True:
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']):
345 conf.update_from_file(request.FILES['file_name'])
306 line_type = RCLineType.objects.get(name=line_data.pop('type'))
346 conf.save()
307 if line_type.name=='codes':
347
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
338 for line in conf.get_lines():
348 for line in conf.get_lines():
339 if line.line_type.name=='tr':
349 if line.line_type.name=='tr':
340 continue
350 continue
341 line.update_pulses()
351 line.update_pulses()
342
352
343 for tr in conf.get_lines('tr'):
353 for tr in conf.get_lines('tr'):
344 tr.update_pulses()
354 tr.update_pulses()
345
355
346 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
356 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
347 return redirect(conf.get_absolute_url())
357 return redirect(conf.get_absolute_url())
@@ -351,8 +361,7 def import_file(request, conf_id):
351
361
352 else:
362 else:
353 messages.warning(request, 'Your current configuration will be replaced')
363 messages.warning(request, 'Your current configuration will be replaced')
354 form = RCImportForm()
364 form = RCImportForm()
355
356
365
357 kwargs = {}
366 kwargs = {}
358 kwargs['form'] = form
367 kwargs['form'] = form
@@ -362,7 +371,7 def import_file(request, conf_id):
362 kwargs['previous'] = conf.get_absolute_url()
371 kwargs['previous'] = conf.get_absolute_url()
363
372
364 return render(request, 'rc_import.html', kwargs)
373 return render(request, 'rc_import.html', kwargs)
365
374
366
375
367 def view_pulses(request, conf_id):
376 def view_pulses(request, conf_id):
368
377
@@ -373,17 +382,14 def view_pulses(request, conf_id):
373
382
374 N = int(conf.ipp*(conf.clock/conf.clock_divider)*20./3)*conf.ntx
383 N = int(conf.ipp*(conf.clock/conf.clock_divider)*20./3)*conf.ntx
375
384
376 script, div = plot_pulses(unit, N, lines)
385 script, div = plot_pulses(unit, N, lines)
377
378 kwargs = {'div':mark_safe(div), 'script':mark_safe(script)}
379
386
380 if 'json' in request.GET:
387 kwargs = {}
381
382 return HttpResponse(json.dumps(kwargs), content_type="application/json")
383
384 else:
385
386
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 'django.contrib.staticfiles.finders.FileSystemFinder',
121 'django.contrib.staticfiles.finders.FileSystemFinder',
122 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
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
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now