##// END OF EJS Templates
Se resolvió plot pattern de ABS
Renato Huallpa -
r390:5670a70fd8d1
parent child
Show More
@@ -1,33 +1,33
1
1
2 REDIS_HOST=radarsys-redis
2 REDIS_HOST=radarsys-redis
3 REDIS_PORT=6300
3 REDIS_PORT=6300
4 POSTGRES_PORT_5432_TCP_ADDR=radarsys-postgres
4 POSTGRES_PORT_5432_TCP_ADDR=radarsys-postgres
5 POSTGRES_PORT_5432_TCP_PORT=5432
5 POSTGRES_PORT_5432_TCP_PORT=5432
6 #POSTGRES_HOST=postgres
6 #POSTGRES_HOST=postgres
7 POSTGRES_HOST=localhost
7 POSTGRES_HOST=localhost
8 POSTGRES_USER=docker
8 POSTGRES_USER=docker
9 POSTGRES_PASSWORD=docker
9 POSTGRES_PASSWORD=docker
10 POSTGRES_DB=radarsys
10 POSTGRES_DB=radarsys
11
11
12 # DB_NAME=radarsys
12 # DB_NAME=radarsys
13 # DB_USER=docker
13 # DB_USER=docker
14 # DB_PASSWORD=docker
14 # DB_PASSWORD=docker
15 PGDATA=/var/lib/postgresql/data
15 PGDATA=/var/lib/postgresql/data
16 LC_ALL=C.UTF-8
16 LC_ALL=C.UTF-8
17 TZ=America/Lima
17 TZ=America/Lima
18 DOCKER_DATA=/data/dockers/radarsys/
18 DOCKER_DATA=/data/dockers/radarsys/
19 LOCAL_IP=192.168.1.128
19 LOCAL_IP=192.168.1.128
20
20
21 MQTT_SERVER=10.10.10.200
21 # MQTT_SERVER=10.10.10.200
22 # MQTT_SERVER = 192.168.100.5
22 MQTT_SERVER = 192.168.100.5
23 MQTT_PORT = 1883
23 MQTT_PORT = 1883
24 MQTT_KEEPALIVE = 3660
24 MQTT_KEEPALIVE = 3660
25
25
26 MQTT_USER_ATRAD=atrad
26 MQTT_USER_ATRAD=atrad
27 MQTT_PASSWORD_ATRAD = atrad
27 MQTT_PASSWORD_ATRAD = atrad
28 MQTT_USER = abs
28 MQTT_USER = abs
29 MQTT_PASSWORD = abs
29 MQTT_PASSWORD = abs
30 MQTT_CLIENT_ID= abs_id
30 MQTT_CLIENT_ID= abs_id
31 TOPIC_ABS=abs/beams
31 TOPIC_ABS=abs/beams
32 TOPIC_ABS_ACK=abs/beams_ack
32 TOPIC_ABS_ACK=abs/beams_ack
33 TOPIC_ABS_CHANGE=abs/change_beam
33 TOPIC_ABS_CHANGE=abs/change_beam
@@ -1,1081 +1,1083
1 from django.db import models
1 from django.db import models
2 from apps.main.models import Configuration , User
2 from apps.main.models import Configuration , User
3 from django.urls import reverse
3 from django.urls import reverse
4 from celery.execute import send_task
4 from celery.execute import send_task
5 from datetime import datetime
5 from datetime import datetime
6 import ast
6 import ast
7 import socket
7 import socket
8 import json
8 import json
9 import requests
9 import requests
10 import struct
10 import struct
11 import os, sys, time
11 import os, sys, time
12
12
13 from .mqtt import client as mqtt_client
13 from .mqtt import client as mqtt_client
14 from radarsys.socketconfig import sio as sio
14 from radarsys.socketconfig import sio as sio
15 import json
15 import json
16
16
17 antenna_default = json.dumps({
17 antenna_default = json.dumps({
18 "antenna_up": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
18 "antenna_up": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
19 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
19 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
20 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
20 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
21 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
21 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
22 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
22 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
23 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
23 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
24 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
24 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
25 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0]
25 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0]
26 ]
26 ]
27 ,
27 ,
28 "antenna_down": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
28 "antenna_down": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
29 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
29 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
30 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
30 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
31 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
31 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
32 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
32 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
33 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
33 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
34 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
34 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
35 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0]],
35 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0]],
36 })
36 })
37
37
38
38
39 tx_default = json.dumps({
39 tx_default = json.dumps({
40 "up": [[1,1,1,1,0,0,0,0],
40 "up": [[1,1,1,1,0,0,0,0],
41 [1,1,1,1,0,0,0,0],
41 [1,1,1,1,0,0,0,0],
42 [1,1,1,1,0,0,0,0],
42 [1,1,1,1,0,0,0,0],
43 [1,1,1,1,0,0,0,0],
43 [1,1,1,1,0,0,0,0],
44 [0,0,0,0,1,1,1,1],
44 [0,0,0,0,1,1,1,1],
45 [0,0,0,0,1,1,1,1],
45 [0,0,0,0,1,1,1,1],
46 [0,0,0,0,1,1,1,1],
46 [0,0,0,0,1,1,1,1],
47 [0,0,0,0,1,1,1,1]],
47 [0,0,0,0,1,1,1,1]],
48
48
49 "down": [[1,1,1,1,0,0,0,0],
49 "down": [[1,1,1,1,0,0,0,0],
50 [1,1,1,1,0,0,0,0],
50 [1,1,1,1,0,0,0,0],
51 [1,1,1,1,0,0,0,0],
51 [1,1,1,1,0,0,0,0],
52 [1,1,1,1,0,0,0,0],
52 [1,1,1,1,0,0,0,0],
53 [0,0,0,0,1,1,1,1],
53 [0,0,0,0,1,1,1,1],
54 [0,0,0,0,1,1,1,1],
54 [0,0,0,0,1,1,1,1],
55 [0,0,0,0,1,1,1,1],
55 [0,0,0,0,1,1,1,1],
56 [0,0,0,0,1,1,1,1]],
56 [0,0,0,0,1,1,1,1]],
57 })
57 })
58
58
59 rx_default = json.dumps({
59 rx_default = json.dumps({
60 "up": [[1,1,1,1,0,0,0,0],
60 "up": [[1,1,1,1,0,0,0,0],
61 [1,1,1,1,0,0,0,0],
61 [1,1,1,1,0,0,0,0],
62 [1,1,1,1,0,0,0,0],
62 [1,1,1,1,0,0,0,0],
63 [1,1,1,1,0,0,0,0],
63 [1,1,1,1,0,0,0,0],
64 [0,0,0,0,1,1,1,1],
64 [0,0,0,0,1,1,1,1],
65 [0,0,0,0,1,1,1,1],
65 [0,0,0,0,1,1,1,1],
66 [0,0,0,0,1,1,1,1],
66 [0,0,0,0,1,1,1,1],
67 [0,0,0,0,1,1,1,1]],
67 [0,0,0,0,1,1,1,1]],
68
68
69 "down": [[1,1,1,1,0,0,0,0],
69 "down": [[1,1,1,1,0,0,0,0],
70 [1,1,1,1,0,0,0,0],
70 [1,1,1,1,0,0,0,0],
71 [1,1,1,1,0,0,0,0],
71 [1,1,1,1,0,0,0,0],
72 [1,1,1,1,0,0,0,0],
72 [1,1,1,1,0,0,0,0],
73 [0,0,0,0,1,1,1,1],
73 [0,0,0,0,1,1,1,1],
74 [0,0,0,0,1,1,1,1],
74 [0,0,0,0,1,1,1,1],
75 [0,0,0,0,1,1,1,1],
75 [0,0,0,0,1,1,1,1],
76 [0,0,0,0,1,1,1,1]],
76 [0,0,0,0,1,1,1,1]],
77 })
77 })
78
78
79 status_default = '0000000000000000000000000000000000000000000000000000000000000000'
79 status_default = '0000000000000000000000000000000000000000000000000000000000000000'
80 default_messages = {}
80 default_messages = {}
81
81
82 for i in range(1,65):
82 for i in range(1,65):
83 default_messages[str(i)] = "Module "+str(i)
83 default_messages[str(i)] = "Module "+str(i)
84
84
85
85
86 ues_default = json.dumps({
86 ues_default = json.dumps({
87 "up": [0.533333,0.00000,1.06667,0.00000],
87 "up": [0.533333,0.00000,1.06667,0.00000],
88 "down": [0.533333,0.00000,1.06667,0.00000]
88 "down": [0.533333,0.00000,1.06667,0.00000]
89 })
89 })
90
90
91 onlyrx_default = json.dumps({
91 onlyrx_default = json.dumps({
92 "up": False,
92 "up": False,
93 "down": False
93 "down": False
94 })
94 })
95
95
96 def up_convertion(cadena):
96 def up_convertion(cadena):
97 valores = []
97 valores = []
98 for c in cadena:
98 for c in cadena:
99 if c == 1.0: valores=valores+['000']
99 if c == 1.0: valores=valores+['000']
100 if c == 2.0: valores=valores+['001']
100 if c == 2.0: valores=valores+['001']
101 if c == 3.0: valores=valores+['010']
101 if c == 3.0: valores=valores+['010']
102 if c == 0.0: valores=valores+['011']
102 if c == 0.0: valores=valores+['011']
103 if c == 0.5: valores=valores+['100']
103 if c == 0.5: valores=valores+['100']
104 if c == 1.5: valores=valores+['101']
104 if c == 1.5: valores=valores+['101']
105 if c == 2.5: valores=valores+['110']
105 if c == 2.5: valores=valores+['110']
106 if c == 3.5: valores=valores+['111']
106 if c == 3.5: valores=valores+['111']
107
107
108 return valores
108 return valores
109
109
110 def up_conv_bits(value):
110 def up_conv_bits(value):
111
111
112 if value == 1.0: bits="000"
112 if value == 1.0: bits="000"
113 if value == 2.0: bits="001"
113 if value == 2.0: bits="001"
114 if value == 3.0: bits="010"
114 if value == 3.0: bits="010"
115 if value == 0.0: bits="011"
115 if value == 0.0: bits="011"
116 if value == 0.5: bits="100"
116 if value == 0.5: bits="100"
117 if value == 1.5: bits="101"
117 if value == 1.5: bits="101"
118 if value == 2.5: bits="110"
118 if value == 2.5: bits="110"
119 if value == 3.5: bits="111"
119 if value == 3.5: bits="111"
120
120
121 return bits
121 return bits
122
122
123 def down_convertion(cadena):
123 def down_convertion(cadena):
124 valores = []
124 valores = []
125 for c in cadena:
125 for c in cadena:
126 if c == 1.0: valores=valores+['000']
126 if c == 1.0: valores=valores+['000']
127 if c == 2.0: valores=valores+['001']
127 if c == 2.0: valores=valores+['001']
128 if c == 3.0: valores=valores+['010']
128 if c == 3.0: valores=valores+['010']
129 if c == 0.0: valores=valores+['011']
129 if c == 0.0: valores=valores+['011']
130 if c == 0.5: valores=valores+['100']
130 if c == 0.5: valores=valores+['100']
131 if c == 1.5: valores=valores+['101']
131 if c == 1.5: valores=valores+['101']
132 if c == 2.5: valores=valores+['110']
132 if c == 2.5: valores=valores+['110']
133 if c == 3.5: valores=valores+['111']
133 if c == 3.5: valores=valores+['111']
134
134
135 return valores
135 return valores
136
136
137 def down_conv_bits(value):
137 def down_conv_bits(value):
138
138
139 if value == 1.0: bits="000"
139 if value == 1.0: bits="000"
140 if value == 2.0: bits="001"
140 if value == 2.0: bits="001"
141 if value == 3.0: bits="010"
141 if value == 3.0: bits="010"
142 if value == 0.0: bits="011"
142 if value == 0.0: bits="011"
143 if value == 0.5: bits="100"
143 if value == 0.5: bits="100"
144 if value == 1.5: bits="101"
144 if value == 1.5: bits="101"
145 if value == 2.5: bits="110"
145 if value == 2.5: bits="110"
146 if value == 3.5: bits="111"
146 if value == 3.5: bits="111"
147
147
148 return bits
148 return bits
149
149
150 def up_conv_value(bits):
150 def up_conv_value(bits):
151
151
152 if bits == "000": value=1.0
152 if bits == "000": value=1.0
153 if bits == "001": value=2.0
153 if bits == "001": value=2.0
154 if bits == "010": value=3.0
154 if bits == "010": value=3.0
155 if bits == "011": value=0.0
155 if bits == "011": value=0.0
156 if bits == "100": value=0.5
156 if bits == "100": value=0.5
157 if bits == "101": value=1.5
157 if bits == "101": value=1.5
158 if bits == "110": value=2.5
158 if bits == "110": value=2.5
159 if bits == "111": value=3.5
159 if bits == "111": value=3.5
160
160
161 return value
161 return value
162
162
163 def down_conv_value(bits):
163 def down_conv_value(bits):
164
164
165 if bits == "000": value=1.0
165 if bits == "000": value=1.0
166 if bits == "001": value=2.0
166 if bits == "001": value=2.0
167 if bits == "010": value=3.0
167 if bits == "010": value=3.0
168 if bits == "011": value=0.0
168 if bits == "011": value=0.0
169 if bits == "100": value=0.5
169 if bits == "100": value=0.5
170 if bits == "101": value=1.5
170 if bits == "101": value=1.5
171 if bits == "110": value=2.5
171 if bits == "110": value=2.5
172 if bits == "111": value=3.5
172 if bits == "111": value=3.5
173
173
174 return value
174 return value
175
175
176 def ip2position(module_number):
176 def ip2position(module_number):
177 j=0
177 j=0
178 i=0
178 i=0
179 for x in range(0,module_number-1):
179 for x in range(0,module_number-1):
180 j=j+1
180 j=j+1
181 if j==8:
181 if j==8:
182 i=i+1
182 i=i+1
183 j=0
183 j=0
184
184
185 pos = [i,j]
185 pos = [i,j]
186 return pos
186 return pos
187
187
188
188
189 def fromBinary2Char(binary_string):
189 def fromBinary2Char(binary_string):
190 number = int(binary_string, 2)
190 number = int(binary_string, 2)
191 #Plus 33 to avoid more than 1 characters values such as: '\x01'-'\x1f'
191 #Plus 33 to avoid more than 1 characters values such as: '\x01'-'\x1f'
192 number = number + 33
192 number = number + 33
193 char = chr(number)
193 char = chr(number)
194 return char
194 return char
195
195
196 def fromChar2Binary(char):
196 def fromChar2Binary(char):
197 number = ord(char) - 33
197 number = ord(char) - 33
198 #Minus 33 to get the real value
198 #Minus 33 to get the real value
199 bits = bin(number)[2:]
199 bits = bin(number)[2:]
200 #To ensure we have a string with 6bits
200 #To ensure we have a string with 6bits
201 if len(bits) < 6:
201 if len(bits) < 6:
202 bits = bits.zfill(6)
202 bits = bits.zfill(6)
203 return bits
203 return bits
204
204
205 OPERATION_MODES = (
205 OPERATION_MODES = (
206 (0, 'Manual'),
206 (0, 'Manual'),
207 (1, 'Automatic'),
207 (1, 'Automatic'),
208 )
208 )
209
209
210 class ABSConfiguration(Configuration):
210 class ABSConfiguration(Configuration):
211 active_beam = models.PositiveSmallIntegerField(verbose_name='Active Beam', default=0)
211 active_beam = models.PositiveSmallIntegerField(verbose_name='Active Beam', default=0)
212 module_status = models.CharField(verbose_name='Module Status', max_length=10000, default=status_default)
212 module_status = models.CharField(verbose_name='Module Status', max_length=10000, default=status_default)
213 operation_mode = models.PositiveSmallIntegerField(verbose_name='Operation Mode', choices=OPERATION_MODES, default = 0)
213 operation_mode = models.PositiveSmallIntegerField(verbose_name='Operation Mode', choices=OPERATION_MODES, default = 0)
214 operation_value = models.FloatField(verbose_name='Periodic (seconds)', default="10", null=True, blank=True)
214 operation_value = models.FloatField(verbose_name='Periodic (seconds)', default="10", null=True, blank=True)
215 module_messages = models.CharField(verbose_name='Modules Messages', max_length=10000, default=json.dumps(default_messages))
215 module_messages = models.CharField(verbose_name='Modules Messages', max_length=10000, default=json.dumps(default_messages))
216
216
217 class Meta:
217 class Meta:
218 db_table = 'abs_configurations'
218 db_table = 'abs_configurations'
219
219
220 def get_absolute_url_plot(self):
220 def get_absolute_url_plot(self):
221 return reverse('url_plot_abs_patterns', args=[str(self.id)])
221 return reverse('url_plot_abs_patterns', args=[str(self.id)])
222
222
223
223
224 def parms_to_dict(self):
224 def parms_to_dict(self):
225
225
226 parameters = {}
226 parameters = {}
227
227
228 parameters['device_id'] = self.device.id
228 parameters['device_id'] = self.device.id
229 parameters['label'] = self.label
229 parameters['label'] = self.label
230 parameters['device_type'] = self.device.device_type.name
230 parameters['device_type'] = self.device.device_type.name
231 parameters['beams'] = {}
231 parameters['beams'] = {}
232
232
233 beams = ABSBeam.objects.filter(abs_conf=self)
233 beams = ABSBeam.objects.filter(abs_conf=self)
234 b=1
234 b=1
235 for beam in beams:
235 for beam in beams:
236 #absbeam = ABSBeam.objects.get(pk=beams[beam])
236 #absbeam = ABSBeam.objects.get(pk=beams[beam])
237 parameters['beams']['beam'+str(b)] = beam.parms_to_dict()#absbeam.parms_to_dict()
237 parameters['beams']['beam'+str(b)] = beam.parms_to_dict()#absbeam.parms_to_dict()
238 b+=1
238 b+=1
239
239
240 return parameters
240 return parameters
241
241
242
242
243 def dict_to_parms(self, parameters):
243 def dict_to_parms(self, parameters):
244
244
245 self.label = parameters['label']
245 self.label = parameters['label']
246
246
247 absbeams = ABSBeam.objects.filter(abs_conf=self)
247 absbeams = ABSBeam.objects.filter(abs_conf=self)
248 beams = parameters['beams']
248 beams = parameters['beams']
249
249
250 if absbeams:
250 if absbeams:
251 beams_number = len(beams)
251 beams_number = len(beams)
252 absbeams_number = len(absbeams)
252 absbeams_number = len(absbeams)
253 if beams_number==absbeams_number:
253 if beams_number==absbeams_number:
254 i = 1
254 i = 1
255 for absbeam in absbeams:
255 for absbeam in absbeams:
256 absbeam.dict_to_parms(beams['beam'+str(i)])
256 absbeam.dict_to_parms(beams['beam'+str(i)])
257 i = i+1
257 i = i+1
258 elif beams_number > absbeams_number:
258 elif beams_number > absbeams_number:
259 i = 1
259 i = 1
260 for absbeam in absbeams:
260 for absbeam in absbeams:
261 absbeam.dict_to_parms(beams['beam'+str(i)])
261 absbeam.dict_to_parms(beams['beam'+str(i)])
262 i=i+1
262 i=i+1
263 for x in range(i,beams_number+1):
263 for x in range(i,beams_number+1):
264 new_beam = ABSBeam(
264 new_beam = ABSBeam(
265 name =beams['beam'+str(i)]['name'],
265 name =beams['beam'+str(i)]['name'],
266 antenna =json.dumps(beams['beam'+str(i)]['antenna']),
266 antenna =json.dumps(beams['beam'+str(i)]['antenna']),
267 abs_conf = self,
267 abs_conf = self,
268 tx =json.dumps(beams['beam'+str(i)]['tx']),
268 tx =json.dumps(beams['beam'+str(i)]['tx']),
269 rx =json.dumps(beams['beam'+str(i)]['rx']),
269 rx =json.dumps(beams['beam'+str(i)]['rx']),
270 ues =json.dumps(beams['beam'+str(i)]['ues']),
270 ues =json.dumps(beams['beam'+str(i)]['ues']),
271 only_rx =json.dumps(beams['beam'+str(i)]['only_rx'])
271 only_rx =json.dumps(beams['beam'+str(i)]['only_rx'])
272 )
272 )
273 new_beam.save()
273 new_beam.save()
274 i=i+1
274 i=i+1
275 else: #beams_number < absbeams_number:
275 else: #beams_number < absbeams_number:
276 i = 1
276 i = 1
277 for absbeam in absbeams:
277 for absbeam in absbeams:
278 if i <= beams_number:
278 if i <= beams_number:
279 absbeam.dict_to_parms(beams['beam'+str(i)])
279 absbeam.dict_to_parms(beams['beam'+str(i)])
280 i=i+1
280 i=i+1
281 else:
281 else:
282 absbeam.delete()
282 absbeam.delete()
283 else:
283 else:
284 for beam in beams:
284 for beam in beams:
285 new_beam = ABSBeam(
285 new_beam = ABSBeam(
286 name =beams[beam]['name'],
286 name =beams[beam]['name'],
287 antenna =json.dumps(beams[beam]['antenna']),
287 antenna =json.dumps(beams[beam]['antenna']),
288 abs_conf = self,
288 abs_conf = self,
289 tx =json.dumps(beams[beam]['tx']),
289 tx =json.dumps(beams[beam]['tx']),
290 rx =json.dumps(beams[beam]['rx']),
290 rx =json.dumps(beams[beam]['rx']),
291 ues =json.dumps(beams[beam]['ues']),
291 ues =json.dumps(beams[beam]['ues']),
292 only_rx =json.dumps(beams[beam]['only_rx'])
292 only_rx =json.dumps(beams[beam]['only_rx'])
293 )
293 )
294 new_beam.save()
294 new_beam.save()
295
295
296
296
297
297
298 def update_from_file(self, parameters):
298 def update_from_file(self, parameters):
299
299
300 self.dict_to_parms(parameters)
300 self.dict_to_parms(parameters)
301 self.save()
301 self.save()
302
302
303
303
304 def get_beams(self, **kwargs):
304 def get_beams(self, **kwargs):
305 '''
305 '''
306 This function returns ABS Configuration beams
306 This function returns ABS Configuration beams
307 '''
307 '''
308 return ABSBeam.objects.filter(abs_conf=self.pk, **kwargs)
308 return ABSBeam.objects.filter(abs_conf=self.pk, **kwargs)
309
309
310 def clone(self, **kwargs):
310 def clone(self, **kwargs):
311
311
312 beams = self.get_beams()
312 beams = self.get_beams()
313 self.pk = None
313 self.pk = None
314 self.id = None
314 self.id = None
315 for attr, value in kwargs.items():
315 for attr, value in kwargs.items():
316 setattr(self, attr, value)
316 setattr(self, attr, value)
317 self.save()
317 self.save()
318
318
319 for beam in beams:
319 for beam in beams:
320 beam.clone(abs_conf=self)
320 beam.clone(abs_conf=self)
321
321
322 #-----For Active Beam-----
322 #-----For Active Beam-----
323 new_beams = ABSBeam.objects.filter(abs_conf=self)
323 new_beams = ABSBeam.objects.filter(abs_conf=self)
324 self.active_beam = new_beams[0].id
324 self.active_beam = new_beams[0].id
325 self.save()
325 self.save()
326 #-----For Active Beam-----
326 #-----For Active Beam-----
327 #-----For Device Status---
327 #-----For Device Status---
328 self.device.status = 3
328 self.device.status = 3
329 self.device.save()
329 self.device.save()
330 #-----For Device Status---
330 #-----For Device Status---
331
331
332 return self
332 return self
333
333
334
334
335 def start_device(self):
335 def start_device(self):
336
336
337 if self.device.status == 3:
337 if self.device.status == 3:
338
338
339 try:
339 try:
340 #self.write_device()
340 #self.write_device()
341 send_task('task_change_beam', [self.id],)
341 send_task('task_change_beam', [self.id],)
342 print("*************************RUNNING ABS**************************",flush=True)
342 self.message = 'ABS running'
343 self.message = 'ABS running'
343
344
344 except Exception as e:
345 except Exception as e:
345 self.message = str(e)
346 self.message = str(e)
346 return False
347 return False
347
348
348 return True
349 return True
349
350
350 else:
351 else:
351 self.message = 'Please, select Write ABS Device first.'
352 self.message = 'Please, select Write ABS Device first.'
352 return False
353 return False
353
354
354
355
355 def stop_device(self):
356 def stop_device(self):
356 self.device.status = 2
357 self.device.status = 2
357 self.device.save()
358 self.device.save()
358 self.message = 'ABS has been stopped.'
359 self.message = 'ABS has been stopped.'
360 print("*************************STOPPED ABS**************************",flush=True)
359 self.save()
361 self.save()
360
362
361 return True
363 return True
362
364
363 def stop_device_mqtt(self):
365 def stop_device_mqtt(self):
364
366
365 self.device.status = 2
367 self.device.status = 2
366 self.device.save()
368 self.device.save()
367 self.message = 'ABS has been stopped.'
369 self.message = 'ABS has been stopped.'
368 self.save()
370 self.save()
369
371
370 mqtt_client.publish(os.environ.get('TOPIC_ABS', 'abs/beams'),"STOP")
372 mqtt_client.publish(os.environ.get('TOPIC_ABS', 'abs/beams'),"STOP")
371
373
372 return True
374 return True
373
375
374 def write_device(self):
376 def write_device(self):
375
377
376 """
378 """
377 This function sends the beams list to every abs module.
379 This function sends the beams list to every abs module.
378 It needs 'module_conf' function
380 It needs 'module_conf' function
379 """
381 """
380 print("Write 3")
382 print("Write 3")
381
383
382 beams = ABSBeam.objects.filter(abs_conf=self)
384 beams = ABSBeam.objects.filter(abs_conf=self)
383 nbeams = len(beams)
385 nbeams = len(beams)
384
386
385 # Se manda a cero RC para poder realizar cambio de beam
387 # Se manda a cero RC para poder realizar cambio de beam
386 if self.experiment is None:
388 if self.experiment is None:
387 confs = []
389 confs = []
388 else:
390 else:
389 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
391 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
390 confdds = ''
392 confdds = ''
391 confjars = ''
393 confjars = ''
392 confrc = ''
394 confrc = ''
393 #TO STOP DEVICES: DDS-JARS-RC
395 #TO STOP DEVICES: DDS-JARS-RC
394 for i in range(0,len(confs)):
396 for i in range(0,len(confs)):
395 if i==0:
397 if i==0:
396 for conf in confs:
398 for conf in confs:
397 if conf.device.device_type.name == 'dds':
399 if conf.device.device_type.name == 'dds':
398 confdds = conf
400 confdds = conf
399 confdds.stop_device()
401 confdds.stop_device()
400 break
402 break
401 if i==1:
403 if i==1:
402 for conf in confs:
404 for conf in confs:
403 if conf.device.device_type.name == 'jars':
405 if conf.device.device_type.name == 'jars':
404 confjars = conf
406 confjars = conf
405 confjars.stop_device()
407 confjars.stop_device()
406 break
408 break
407 if i==2:
409 if i==2:
408 for conf in confs:
410 for conf in confs:
409 if conf.device.device_type.name == 'rc':
411 if conf.device.device_type.name == 'rc':
410 confrc = conf
412 confrc = conf
411 confrc.stop_device()
413 confrc.stop_device()
412 break
414 break
413
415
414 '''
416 '''
415 if self.connected_modules() == 0 :
417 if self.connected_modules() == 0 :
416 print("No encuentra modulos")
418 print("No encuentra modulos")
417 self.message = "No ABS Module detected."
419 self.message = "No ABS Module detected."
418 return False
420 return False
419 '''
421 '''
420 #-------------Write each abs module-----------
422 #-------------Write each abs module-----------
421
423
422 if beams:
424 if beams:
423 block_id = 0
425 block_id = 0
424 message = 'SNDF{:03d}{:02d}{:02d}'.format(nbeams, nbeams, block_id)
426 message = 'SNDF{:03d}{:02d}{:02d}'.format(nbeams, nbeams, block_id)
425 for i, status in enumerate(self.module_status):
427 for i, status in enumerate(self.module_status):
426 message += ''.join([fromBinary2Char(beam.module_6bits(i)) for beam in beams])
428 message += ''.join([fromBinary2Char(beam.module_6bits(i)) for beam in beams])
427 status = ['0'] * 64
429 status = ['0'] * 64
428 n = 0
430 n = 0
429
431
430 print("Llega una antes entrar a multicast4")
432 print("Llega una antes entrar a multicast4")
431
433
432 sock = self.send_multicast(message)
434 sock = self.send_multicast(message)
433
435
434 while True:
436 while True:
435 #for i in range(32):
437 #for i in range(32):
436 try:
438 try:
437 data, address = sock.recvfrom(1024)
439 data, address = sock.recvfrom(1024)
438 print (address, data)
440 print (address, data)
439 data = data.decode("utf-8")
441 data = data.decode("utf-8")
440 if data == '1':
442 if data == '1':
441 status[int(address[0][10:])-1] = '3'
443 status[int(address[0][10:])-1] = '3'
442 #print (int(address[0][10:])-1)
444 #print (int(address[0][10:])-1)
443 elif data == '0':
445 elif data == '0':
444 status[int(address[0][10:])-1] = '1'
446 status[int(address[0][10:])-1] = '1'
445 except socket.timeout:
447 except socket.timeout:
446 print('Timeout')
448 print('Timeout')
447 break
449 break
448 except Exception as e:
450 except Exception as e:
449 print ('Error {}'.format(e))
451 print ('Error {}'.format(e))
450 n += 1
452 n += 1
451 sock.close()
453 sock.close()
452 else:
454 else:
453 self.message = "ABS Configuration does not have beams"
455 self.message = "ABS Configuration does not have beams"
454 print('No beams')
456 print('No beams')
455 #Start DDS-RC-JARS
457 #Start DDS-RC-JARS
456 if confdds:
458 if confdds:
457 confdds.start_device()
459 confdds.start_device()
458 if confrc:
460 if confrc:
459 #print confrc
461 #print confrc
460 confrc.start_device()
462 confrc.start_device()
461 if confjars:
463 if confjars:
462 confjars.start_device()
464 confjars.start_device()
463 return False
465 return False
464
466
465 if n == 64:
467 if n == 64:
466 self.message = "Could not write ABS Modules"
468 self.message = "Could not write ABS Modules"
467 self.device.status = 0
469 self.device.status = 0
468 self.module_status = ''.join(status)
470 self.module_status = ''.join(status)
469 self.save()
471 self.save()
470 print('Could not write ABS')
472 print('Could not write ABS')
471 #Start DDS-RC-JARS
473 #Start DDS-RC-JARS
472 if confdds:
474 if confdds:
473 confdds.start_device()
475 confdds.start_device()
474 if confrc:
476 if confrc:
475 #print confrc
477 #print confrc
476 confrc.start_device()
478 confrc.start_device()
477 if confjars:
479 if confjars:
478 confjars.start_device()
480 confjars.start_device()
479 return False
481 return False
480 else:
482 else:
481 self.message = "ABS Beams List have been sent to ABS Modules"
483 self.message = "ABS Beams List have been sent to ABS Modules"
482 print('ABS beams list sent')
484 print('ABS beams list sent')
483 self.active_beam = beams[0].pk
485 self.active_beam = beams[0].pk
484
486
485 #Start DDS-RC-JARS
487 #Start DDS-RC-JARS
486 if confdds:
488 if confdds:
487 confdds.start_device()
489 confdds.start_device()
488 if confrc:
490 if confrc:
489 #print confrc
491 #print confrc
490 confrc.start_device()
492 confrc.start_device()
491 if confjars:
493 if confjars:
492 confjars.start_device()
494 confjars.start_device()
493
495
494 print('Inicia intento de salvar device.status')
496 print('Inicia intento de salvar device.status')
495 self.device.status = 3
497 self.device.status = 3
496 self.module_status = ''.join(status)
498 self.module_status = ''.join(status)
497 #print(status)
499 #print(status)
498 self.save()
500 self.save()
499 print('Estatus salvado')
501 print('Estatus salvado')
500 conf_active, __ = ABSActive.objects.get_or_create(pk=1)
502 conf_active, __ = ABSActive.objects.get_or_create(pk=1)
501 conf_active.conf = self
503 conf_active.conf = self
502 conf_active.save()
504 conf_active.save()
503 return True
505 return True
504
506
505 def write_device_mqtt(self):
507 def write_device_mqtt(self):
506
508
507 if self.experiment is None:
509 if self.experiment is None:
508 confs = []
510 confs = []
509 else:
511 else:
510 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
512 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
511 confdds = ''
513 confdds = ''
512 confjars = ''
514 confjars = ''
513 confrc = ''
515 confrc = ''
514 #TO STOP DEVICES: DDS-JARS-RC
516 #TO STOP DEVICES: DDS-JARS-RC
515 for i in range(0,len(confs)):
517 for i in range(0,len(confs)):
516 if i==0:
518 if i==0:
517 for conf in confs:
519 for conf in confs:
518 if conf.device.device_type.name == 'dds':
520 if conf.device.device_type.name == 'dds':
519 confdds = conf
521 confdds = conf
520 confdds.stop_device()
522 confdds.stop_device()
521 break
523 break
522 if i==1:
524 if i==1:
523 for conf in confs:
525 for conf in confs:
524 if conf.device.device_type.name == 'jars':
526 if conf.device.device_type.name == 'jars':
525 confjars = conf
527 confjars = conf
526 confjars.stop_device()
528 confjars.stop_device()
527 break
529 break
528 if i==2:
530 if i==2:
529 for conf in confs:
531 for conf in confs:
530 if conf.device.device_type.name == 'rc':
532 if conf.device.device_type.name == 'rc':
531 confrc = conf
533 confrc = conf
532 confrc.stop_device()
534 confrc.stop_device()
533 break
535 break
534
536
535 apuntes_up_down=''
537 apuntes_up_down=''
536 beams = ABSBeam.objects.filter(abs_conf=self)
538 beams = ABSBeam.objects.filter(abs_conf=self)
537
539
538 inicializacion="{\"beams\":["
540 inicializacion="{\"beams\":["
539 finalizacion="]}"
541 finalizacion="]}"
540
542
541 for beam in beams:
543 for beam in beams:
542 beam.antenna=beam.antenna[1:]
544 beam.antenna=beam.antenna[1:]
543 info="{\"id\":"+str(beam.id)+","+beam.antenna + ","
545 info="{\"id\":"+str(beam.id)+","+beam.antenna + ","
544 apuntes_up_down=apuntes_up_down+info
546 apuntes_up_down=apuntes_up_down+info
545
547
546 apuntes_up_down=apuntes_up_down[:len(apuntes_up_down)-1]
548 apuntes_up_down=apuntes_up_down[:len(apuntes_up_down)-1]
547 apuntes_up_down=inicializacion+ apuntes_up_down+finalizacion
549 apuntes_up_down=inicializacion+ apuntes_up_down+finalizacion
548 mqtt_client.publish(os.environ.get('TOPIC_ABS', 'abs/beams'),apuntes_up_down)
550 mqtt_client.publish(os.environ.get('TOPIC_ABS', 'abs/beams'),apuntes_up_down)
549
551
550 #Start DDS-RC-JARS
552 #Start DDS-RC-JARS
551 if confdds:
553 if confdds:
552 confdds.start_device()
554 confdds.start_device()
553 if confrc:
555 if confrc:
554 #print confrc
556 #print confrc
555 confrc.start_device()
557 confrc.start_device()
556 if confjars:
558 if confjars:
557 confjars.start_device()
559 confjars.start_device()
558
560
559 return True
561 return True
560
562
561 def read_module(self, module):
563 def read_module(self, module):
562
564
563 """
565 """
564 Read out-bits (up-down) of 1 abs module NOT for Configuration
566 Read out-bits (up-down) of 1 abs module NOT for Configuration
565 """
567 """
566
568
567 ip_address = self.device.ip_address
569 ip_address = self.device.ip_address
568 ip_address = ip_address.split('.')
570 ip_address = ip_address.split('.')
569 module_seq = (ip_address[0],ip_address[1],ip_address[2])
571 module_seq = (ip_address[0],ip_address[1],ip_address[2])
570 dot = '.'
572 dot = '.'
571 module_ip = dot.join(module_seq)+'.'+str(module)
573 module_ip = dot.join(module_seq)+'.'+str(module)
572 module_port = self.device.port_address
574 module_port = self.device.port_address
573 read_route = 'http://'+module_ip+':'+str(module_port)+'/read'
575 read_route = 'http://'+module_ip+':'+str(module_port)+'/read'
574
576
575 module_status = json.loads(self.module_status)
577 module_status = json.loads(self.module_status)
576 print(read_route)
578 print(read_route)
577
579
578 module_bits = ''
580 module_bits = ''
579
581
580 try:
582 try:
581 r_read = requests.get(read_route, timeout=0.5)
583 r_read = requests.get(read_route, timeout=0.5)
582 answer = r_read.json()
584 answer = r_read.json()
583 module_bits = answer['allbits']
585 module_bits = answer['allbits']
584 except:
586 except:
585 return {}
587 return {}
586
588
587 return module_bits
589 return module_bits
588
590
589 def read_device(self):
591 def read_device(self):
590
592
591 parms = {}
593 parms = {}
592 # Reads active modules.
594 # Reads active modules.
593 module_status = json.loads(self.module_status)
595 module_status = json.loads(self.module_status)
594 total = 0
596 total = 0
595 for status in module_status:
597 for status in module_status:
596 if module_status[status] != 0:
598 if module_status[status] != 0:
597 module_bits = self.read_module(int(status))
599 module_bits = self.read_module(int(status))
598 bits={}
600 bits={}
599 if module_bits:
601 if module_bits:
600 bits = (str(module_bits['um2']) + str(module_bits['um1']) + str(module_bits['um0']) +
602 bits = (str(module_bits['um2']) + str(module_bits['um1']) + str(module_bits['um0']) +
601 str(module_bits['dm2']) + str(module_bits['dm1']) + str(module_bits['dm0']) )
603 str(module_bits['dm2']) + str(module_bits['dm1']) + str(module_bits['dm0']) )
602 parms[str(status)] = bits
604 parms[str(status)] = bits
603
605
604 total +=1
606 total +=1
605
607
606 if total==0:
608 if total==0:
607 self.message = "No ABS Module detected. Please select 'Status'."
609 self.message = "No ABS Module detected. Please select 'Status'."
608 return False
610 return False
609
611
610
612
611
613
612 self.message = "ABS Modules have been read"
614 self.message = "ABS Modules have been read"
613 #monitoreo_tx = JROABSClnt_01CeCnMod000000MNTR10
615 #monitoreo_tx = JROABSClnt_01CeCnMod000000MNTR10
614 return parms
616 return parms
615
617
616
618
617 def connected_modules(self):
619 def connected_modules(self):
618 """
620 """
619 This function returns the number of connected abs-modules without updating.
621 This function returns the number of connected abs-modules without updating.
620 """
622 """
621 num = 0
623 num = 0
622 print(self.module_status)
624 print(self.module_status)
623 for i, status in enumerate(self.module_status):
625 for i, status in enumerate(self.module_status):
624 if status != '0':
626 if status != '0':
625 num += 1
627 num += 1
626 #print('status {}:{}'.format(i+1, status))
628 #print('status {}:{}'.format(i+1, status))
627 return num
629 return num
628
630
629 def send_multicast(self, message):
631 def send_multicast(self, message):
630 #print("Send multicast")
632 #print("Send multicast")
631 multicast_group = ('224.3.29.71', 10000)
633 multicast_group = ('224.3.29.71', 10000)
632 # Create the datagram socket
634 # Create the datagram socket
633 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
635 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
634 sock.settimeout(1)
636 sock.settimeout(1)
635 local_ip = os.environ.get('LOCAL_IP', '0.0.0.0')
637 local_ip = os.environ.get('LOCAL_IP', '0.0.0.0')
636 local_ip = '0.0.0.0'
638 local_ip = '0.0.0.0'
637 print("He llegado a IP local")
639 print("He llegado a IP local")
638
640
639 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(local_ip))
641 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(local_ip))
640 sock.sendto(message.encode(), multicast_group)
642 sock.sendto(message.encode(), multicast_group)
641 print('Sending ' + message)
643 print('Sending ' + message)
642 return sock
644 return sock
643
645
644 def status_device(self):
646 def status_device(self):
645 """
647 """
646 This function returns the status of all abs-modules as one.
648 This function returns the status of all abs-modules as one.
647 If at least one module is connected, its answer is "1"
649 If at least one module is connected, its answer is "1"
648 """
650 """
649 print ('Status device')
651 print ('Status device')
650 print (self.active_beam)
652 print (self.active_beam)
651 beams = ABSBeam.objects.filter(abs_conf=self)
653 beams = ABSBeam.objects.filter(abs_conf=self)
652 #print beams[self.active_beam-1].module_6bits(0)
654 #print beams[self.active_beam-1].module_6bits(0)
653 active = ABSActive.objects.get(pk=1)
655 active = ABSActive.objects.get(pk=1)
654 if active.conf != self:
656 if active.conf != self:
655 self.message = 'La configuracion actual es la del siguiente enlace %s.' % active.conf.get_absolute_url()
657 self.message = 'La configuracion actual es la del siguiente enlace %s.' % active.conf.get_absolute_url()
656 self.message += "\n"
658 self.message += "\n"
657 self.message += 'Se debe realizar un write en esta configuracion para luego obtener un status valido.'
659 self.message += 'Se debe realizar un write en esta configuracion para luego obtener un status valido.'
658
660
659 return False
661 return False
660
662
661 sock = self.send_multicast('MNTR')
663 sock = self.send_multicast('MNTR')
662
664
663 n = 0
665 n = 0
664 status = ['0'] * 64
666 status = ['0'] * 64
665
667
666 while True:
668 while True:
667 #for i in range(32):
669 #for i in range(32):
668 #if True:
670 #if True:
669 try:
671 try:
670 print("Recibiendo")
672 print("Recibiendo")
671 address = None
673 address = None
672 data, address = sock.recvfrom(2)
674 data, address = sock.recvfrom(2)
673 print (address, data)
675 print (address, data)
674 print("!!!!")
676 print("!!!!")
675 data = data.decode()
677 data = data.decode()
676 aux_mon = "1"
678 aux_mon = "1"
677 aux_expected = aux_mon
679 aux_expected = aux_mon
678 if(len(data)==2):
680 if(len(data)==2):
679 print ("data[1]: ")
681 print ("data[1]: ")
680 print (data[1])
682 print (data[1])
681 aux_mon = fromChar2Binary(data[1])
683 aux_mon = fromChar2Binary(data[1])
682 print (aux_mon)
684 print (aux_mon)
683 aux_i = (str(address[0]).split('.'))[3]
685 aux_i = (str(address[0]).split('.'))[3]
684 print (aux_i)
686 print (aux_i)
685 print ('Active beam')
687 print ('Active beam')
686 beam_active = ABSBeam.objects.get(pk=self.active_beam)
688 beam_active = ABSBeam.objects.get(pk=self.active_beam)
687 print (beam_active)
689 print (beam_active)
688 aux_expected = beam_active.module_6bits(int(aux_i)-1)
690 aux_expected = beam_active.module_6bits(int(aux_i)-1)
689 print (aux_expected)
691 print (aux_expected)
690
692
691 print ("data[0]: ")
693 print ("data[0]: ")
692 print (data[0])
694 print (data[0])
693
695
694 if data[0] == '1':
696 if data[0] == '1':
695 status[int(address[0][10:])-1] = '3'
697 status[int(address[0][10:])-1] = '3'
696 if aux_mon == aux_expected:
698 if aux_mon == aux_expected:
697 print ('Es igual')
699 print ('Es igual')
698 else:
700 else:
699 print ('Es diferente')
701 print ('Es diferente')
700 status[int(address[0][10:])-1] = '2'
702 status[int(address[0][10:])-1] = '2'
701
703
702 elif data[0] == '0':
704 elif data[0] == '0':
703 status[int(address[0][10:])-1] = '1'
705 status[int(address[0][10:])-1] = '1'
704 n += 1
706 n += 1
705 print('Module: {} connected'.format(address))
707 print('Module: {} connected'.format(address))
706 except socket.timeout:
708 except socket.timeout:
707 print('Timeout')
709 print('Timeout')
708 break
710 break
709 except:
711 except:
710 print('Module: {} error'.format(address))
712 print('Module: {} error'.format(address))
711 pass
713 pass
712
714
713 sock.close()
715 sock.close()
714
716
715 if n > 0:
717 if n > 0:
716 self.message = 'ABS modules Status have been updated.'
718 self.message = 'ABS modules Status have been updated.'
717 self.device.status = 1
719 self.device.status = 1
718 else:
720 else:
719 self.device.status = 0
721 self.device.status = 0
720 self.message = 'No ABS module is connected.'
722 self.message = 'No ABS module is connected.'
721 self.module_status = ''.join(status)
723 self.module_status = ''.join(status)
722 self.save()
724 self.save()
723
725
724 return self.device.status
726 return self.device.status
725
727
726
728
727 def send_beam(self, beam_pos):
729 def send_beam(self, beam_pos):
728 """
730 """
729 This function connects to a multicast group and sends the beam number
731 This function connects to a multicast group and sends the beam number
730 to all abs modules.
732 to all abs modules.
731 """
733 """
732 print ('Send beam')
734 print ('Send beam')
733 print (self.active_beam)
735 print (self.active_beam)
734 beams = ABSBeam.objects.filter(abs_conf=self)
736 beams = ABSBeam.objects.filter(abs_conf=self)
735 #print beams[self.active_beam-1].module_6bits(0)
737 #print beams[self.active_beam-1].module_6bits(0)
736 active = ABSActive.objects.get(pk=1)
738 active = ABSActive.objects.get(pk=1)
737 if active.conf != self:
739 if active.conf != self:
738 self.message = 'La configuracion actual es la del siguiente enlace %s.' % active.conf.get_absolute_url()
740 self.message = 'La configuracion actual es la del siguiente enlace %s.' % active.conf.get_absolute_url()
739 self.message += "\n"
741 self.message += "\n"
740 self.message += 'Se debe realizar un write en esta configuracion para luego obtener un status valido.'
742 self.message += 'Se debe realizar un write en esta configuracion para luego obtener un status valido.'
741
743
742 return False
744 return False
743
745
744 # Se manda a cero RC para poder realizar cambio de beam
746 # Se manda a cero RC para poder realizar cambio de beam
745 if self.experiment is None:
747 if self.experiment is None:
746 confs = []
748 confs = []
747 else:
749 else:
748 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
750 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
749 confdds = ''
751 confdds = ''
750 confjars = ''
752 confjars = ''
751 confrc = ''
753 confrc = ''
752 #TO STOP DEVICES: DDS-JARS-RC
754 #TO STOP DEVICES: DDS-JARS-RC
753 for i in range(0,len(confs)):
755 for i in range(0,len(confs)):
754 if i==0:
756 if i==0:
755 for conf in confs:
757 for conf in confs:
756 if conf.device.device_type.name == 'dds':
758 if conf.device.device_type.name == 'dds':
757 confdds = conf
759 confdds = conf
758 confdds.stop_device()
760 confdds.stop_device()
759 break
761 break
760 if i==1:
762 if i==1:
761 for conf in confs:
763 for conf in confs:
762 if conf.device.device_type.name == 'jars':
764 if conf.device.device_type.name == 'jars':
763 confjars = conf
765 confjars = conf
764 confjars.stop_device()
766 confjars.stop_device()
765 break
767 break
766 if i==2:
768 if i==2:
767 for conf in confs:
769 for conf in confs:
768 if conf.device.device_type.name == 'rc':
770 if conf.device.device_type.name == 'rc':
769 confrc = conf
771 confrc = conf
770 confrc.stop_device()
772 confrc.stop_device()
771 break
773 break
772 if beam_pos > 0:
774 if beam_pos > 0:
773 beam_pos = beam_pos - 1
775 beam_pos = beam_pos - 1
774 else:
776 else:
775 beam_pos = 0
777 beam_pos = 0
776
778
777 #El indice del apunte debe ser menor que el numero total de apuntes
779 #El indice del apunte debe ser menor que el numero total de apuntes
778 #El servidor tcp en el embebido comienza a contar desde 0
780 #El servidor tcp en el embebido comienza a contar desde 0
779 status = ['0'] * 64
781 status = ['0'] * 64
780 message = 'CHGB{}'.format(beam_pos)
782 message = 'CHGB{}'.format(beam_pos)
781 sock = self.send_multicast(message)
783 sock = self.send_multicast(message)
782 while True:
784 while True:
783 #for i in range(32):
785 #for i in range(32):
784 try:
786 try:
785 data, address = sock.recvfrom(1024)
787 data, address = sock.recvfrom(1024)
786 print (address, data)
788 print (address, data)
787 data = data.decode()
789 data = data.decode()
788 if data == '1':
790 if data == '1':
789 status[int(address[0][10:])-1] = '3'
791 status[int(address[0][10:])-1] = '3'
790 elif data == '0':
792 elif data == '0':
791 status[int(address[0][10:])-1] = '1'
793 status[int(address[0][10:])-1] = '1'
792 except socket.timeout:
794 except socket.timeout:
793 print('Timeout')
795 print('Timeout')
794 break
796 break
795 except Exception as e:
797 except Exception as e:
796 print ('Error {}'.format(e))
798 print ('Error {}'.format(e))
797 pass
799 pass
798
800
799 sock.close()
801 sock.close()
800
802
801 #Start DDS-RC-JARS
803 #Start DDS-RC-JARS
802 if confdds:
804 if confdds:
803 confdds.start_device()
805 confdds.start_device()
804 if confrc:
806 if confrc:
805 #print confrc
807 #print confrc
806 confrc.start_device()
808 confrc.start_device()
807 if confjars:
809 if confjars:
808 confjars.start_device()
810 confjars.start_device()
809
811
810 self.message = "ABS Beam has been changed"
812 self.message = "ABS Beam has been changed"
811 self.module_status = ''.join(status)
813 self.module_status = ''.join(status)
812 self.save()
814 self.save()
813 return True
815 return True
814
816
815
817
816 def get_absolute_url_import(self):
818 def get_absolute_url_import(self):
817 return reverse('url_import_abs_conf', args=[str(self.id)])
819 return reverse('url_import_abs_conf', args=[str(self.id)])
818
820
819 class ABSActive(models.Model):
821 class ABSActive(models.Model):
820 conf = models.ForeignKey(ABSConfiguration, null=True, verbose_name='ABS Configuration', on_delete=models.CASCADE)
822 conf = models.ForeignKey(ABSConfiguration, null=True, verbose_name='ABS Configuration', on_delete=models.CASCADE)
821
823
822 class Meta:
824 class Meta:
823 db_table = 'abs_absactive'
825 db_table = 'abs_absactive'
824
826
825 class ABSBeam(models.Model):
827 class ABSBeam(models.Model):
826
828
827 name = models.CharField(max_length=60, default='Beam')
829 name = models.CharField(max_length=60, default='Beam')
828 antenna = models.CharField(verbose_name='Antenna', max_length=1000, default=antenna_default)
830 antenna = models.CharField(verbose_name='Antenna', max_length=1000, default=antenna_default)
829 abs_conf = models.ForeignKey('ABSConfiguration', null=True,
831 abs_conf = models.ForeignKey('ABSConfiguration', null=True,
830 verbose_name='ABS Configuration', on_delete=models.CASCADE)
832 verbose_name='ABS Configuration', on_delete=models.CASCADE)
831 tx = models.CharField(verbose_name='Tx', max_length=1000, default=tx_default)
833 tx = models.CharField(verbose_name='Tx', max_length=1000, default=tx_default)
832 rx = models.CharField(verbose_name='Rx', max_length=1000, default=rx_default)
834 rx = models.CharField(verbose_name='Rx', max_length=1000, default=rx_default)
833 s_time = models.TimeField(verbose_name='Star Time', default='00:00:00')
835 s_time = models.TimeField(verbose_name='Star Time', default='00:00:00')
834 e_time = models.TimeField(verbose_name='End Time', default='23:59:59')
836 e_time = models.TimeField(verbose_name='End Time', default='23:59:59')
835 ues = models.CharField(verbose_name='Ues', max_length=100, default=ues_default)
837 ues = models.CharField(verbose_name='Ues', max_length=100, default=ues_default)
836 only_rx = models.CharField(verbose_name='Only RX', max_length=40, default=onlyrx_default)
838 only_rx = models.CharField(verbose_name='Only RX', max_length=40, default=onlyrx_default)
837
839
838 class Meta:
840 class Meta:
839 db_table = 'abs_beams'
841 db_table = 'abs_beams'
840
842
841 def __unicode__(self):
843 def __unicode__(self):
842 return u'%s' % (self.name)
844 return u'%s' % (self.name)
843
845
844 def parms_to_dict(self):
846 def parms_to_dict(self):
845
847
846 parameters = {}
848 parameters = {}
847 parameters['name'] = self.name
849 parameters['name'] = self.name
848 parameters['antenna'] = ast.literal_eval(self.antenna)
850 parameters['antenna'] = ast.literal_eval(self.antenna)
849 parameters['abs_conf'] = self.abs_conf.name
851 parameters['abs_conf'] = self.abs_conf.name
850 parameters['tx'] = ast.literal_eval(self.tx)
852 parameters['tx'] = ast.literal_eval(self.tx)
851 parameters['rx'] = ast.literal_eval(self.rx)
853 parameters['rx'] = ast.literal_eval(self.rx)
852 parameters['s_time'] = self.s_time.strftime("%H:%M:%S")
854 parameters['s_time'] = self.s_time.strftime("%H:%M:%S")
853 parameters['e_time'] = self.e_time.strftime("%H:%M:%S")
855 parameters['e_time'] = self.e_time.strftime("%H:%M:%S")
854 parameters['ues'] = ast.literal_eval(self.ues)
856 parameters['ues'] = ast.literal_eval(self.ues)
855 parameters['only_rx'] = json.loads(self.only_rx)
857 parameters['only_rx'] = json.loads(self.only_rx)
856
858
857 return parameters
859 return parameters
858
860
859 def dict_to_parms(self, parameters):
861 def dict_to_parms(self, parameters):
860
862
861 self.name = parameters['name']
863 self.name = parameters['name']
862 self.antenna = json.dumps(parameters['antenna'])
864 self.antenna = json.dumps(parameters['antenna'])
863 #self.abs_conf = parameters['abs_conf']
865 #self.abs_conf = parameters['abs_conf']
864 self.tx = json.dumps(parameters['tx'])
866 self.tx = json.dumps(parameters['tx'])
865 self.rx = json.dumps(parameters['rx'])
867 self.rx = json.dumps(parameters['rx'])
866 #self.s_time = parameters['s_time']
868 #self.s_time = parameters['s_time']
867 #self.e_time = parameters['e_time']
869 #self.e_time = parameters['e_time']
868 self.ues = json.dumps(parameters['ues'])
870 self.ues = json.dumps(parameters['ues'])
869 self.only_rx = json.dumps(parameters['only_rx'])
871 self.only_rx = json.dumps(parameters['only_rx'])
870 self.save()
872 self.save()
871
873
872
874
873 def clone(self, **kwargs):
875 def clone(self, **kwargs):
874
876
875 self.pk = None
877 self.pk = None
876 self.id = None
878 self.id = None
877 for attr, value in kwargs.items():
879 for attr, value in kwargs.items():
878 setattr(self, attr, value)
880 setattr(self, attr, value)
879
881
880 self.save()
882 self.save()
881
883
882 return self
884 return self
883
885
884
886
885 def module_6bits(self, module):
887 def module_6bits(self, module):
886 """
888 """
887 This function reads antenna pattern and choose 6bits (upbits-downbits) for one abs module
889 This function reads antenna pattern and choose 6bits (upbits-downbits) for one abs module
888 """
890 """
889 module += 1
891 module += 1
890 if module > 64:
892 if module > 64:
891 beam_bits = ""
893 beam_bits = ""
892 return beam_bits
894 return beam_bits
893
895
894 data = ast.literal_eval(self.antenna)
896 data = ast.literal_eval(self.antenna)
895 up_data = data['antenna_up']
897 up_data = data['antenna_up']
896 down_data = data['antenna_down']
898 down_data = data['antenna_down']
897
899
898 pos = ip2position(module)
900 pos = ip2position(module)
899 up_value = up_data[pos[0]][pos[1]]
901 up_value = up_data[pos[0]][pos[1]]
900 down_value = down_data[pos[0]][pos[1]]
902 down_value = down_data[pos[0]][pos[1]]
901
903
902 up_bits = up_conv_bits(up_value)
904 up_bits = up_conv_bits(up_value)
903 down_bits = down_conv_bits(down_value)
905 down_bits = down_conv_bits(down_value)
904 beam_bits = up_bits+down_bits
906 beam_bits = up_bits+down_bits
905
907
906 return beam_bits
908 return beam_bits
907
909
908
910
909 @property
911 @property
910 def get_upvalues(self):
912 def get_upvalues(self):
911 """
913 """
912 This function reads antenna pattern and show the up-value of one abs module
914 This function reads antenna pattern and show the up-value of one abs module
913 """
915 """
914
916
915 data = ast.literal_eval(self.antenna)
917 data = ast.literal_eval(self.antenna)
916 up_data = data['antenna_up']
918 up_data = data['antenna_up']
917
919
918 up_values = []
920 up_values = []
919 for data in up_data:
921 for data in up_data:
920 for i in range(0,8):
922 for i in range(0,8):
921 up_values.append(data[i])
923 up_values.append(data[i])
922
924
923 return up_values
925 return up_values
924
926
925 @property
927 @property
926 def antenna_upvalues(self):
928 def antenna_upvalues(self):
927 """
929 """
928 This function reads antenna pattern and show the up - values of one abs beam
930 This function reads antenna pattern and show the up - values of one abs beam
929 in a particular order
931 in a particular order
930 """
932 """
931 data = ast.literal_eval(self.antenna)
933 data = ast.literal_eval(self.antenna)
932 up_data = data['antenna_up']
934 up_data = data['antenna_up']
933
935
934 return up_data
936 return up_data
935
937
936 @property
938 @property
937 def antenna_downvalues(self):
939 def antenna_downvalues(self):
938 """
940 """
939 This function reads antenna pattern and show the down - values of one abs beam
941 This function reads antenna pattern and show the down - values of one abs beam
940 in a particular order
942 in a particular order
941 """
943 """
942 data = ast.literal_eval(self.antenna)
944 data = ast.literal_eval(self.antenna)
943 down_data = data['antenna_down']
945 down_data = data['antenna_down']
944
946
945 return down_data
947 return down_data
946
948
947 @property
949 @property
948 def get_downvalues(self):
950 def get_downvalues(self):
949 """
951 """
950 This function reads antenna pattern and show the down-value of one abs module
952 This function reads antenna pattern and show the down-value of one abs module
951 """
953 """
952
954
953 data = ast.literal_eval(self.antenna)
955 data = ast.literal_eval(self.antenna)
954 down_data = data['antenna_down']
956 down_data = data['antenna_down']
955
957
956 down_values = []
958 down_values = []
957 for data in down_data:
959 for data in down_data:
958 for i in range(0,8):
960 for i in range(0,8):
959 down_values.append(data[i])
961 down_values.append(data[i])
960
962
961 return down_values
963 return down_values
962
964
963 @property
965 @property
964 def get_up_ues(self):
966 def get_up_ues(self):
965 """
967 """
966 This function shows the up-ues-value of one beam
968 This function shows the up-ues-value of one beam
967 """
969 """
968 data = ast.literal_eval(self.ues)
970 data = ast.literal_eval(self.ues)
969 up_ues = data['up']
971 up_ues = data['up']
970
972
971 return up_ues
973 return up_ues
972
974
973 @property
975 @property
974 def get_down_ues(self):
976 def get_down_ues(self):
975 """
977 """
976 This function shows the down-ues-value of one beam
978 This function shows the down-ues-value of one beam
977 """
979 """
978 data = ast.literal_eval(self.ues)
980 data = ast.literal_eval(self.ues)
979 down_ues = data['down']
981 down_ues = data['down']
980
982
981 return down_ues
983 return down_ues
982
984
983 @property
985 @property
984 def get_up_onlyrx(self):
986 def get_up_onlyrx(self):
985 """
987 """
986 This function shows the up-onlyrx-value of one beam
988 This function shows the up-onlyrx-value of one beam
987 """
989 """
988 data = json.loads(self.only_rx)
990 data = json.loads(self.only_rx)
989 up_onlyrx = data['up']
991 up_onlyrx = data['up']
990
992
991 return up_onlyrx
993 return up_onlyrx
992
994
993 @property
995 @property
994 def get_down_onlyrx(self):
996 def get_down_onlyrx(self):
995 """
997 """
996 This function shows the down-onlyrx-value of one beam
998 This function shows the down-onlyrx-value of one beam
997 """
999 """
998 data = json.loads(self.only_rx)
1000 data = json.loads(self.only_rx)
999 down_onlyrx = data['down']
1001 down_onlyrx = data['down']
1000
1002
1001 return down_onlyrx
1003 return down_onlyrx
1002
1004
1003 @property
1005 @property
1004 def get_tx(self):
1006 def get_tx(self):
1005 """
1007 """
1006 This function shows the tx-values of one beam
1008 This function shows the tx-values of one beam
1007 """
1009 """
1008 data = json.loads(self.tx)
1010 data = json.loads(self.tx)
1009
1011
1010 return data
1012 return data
1011
1013
1012 @property
1014 @property
1013 def get_uptx(self):
1015 def get_uptx(self):
1014 """
1016 """
1015 This function shows the up-tx-values of one beam
1017 This function shows the up-tx-values of one beam
1016 """
1018 """
1017 data = json.loads(self.tx)
1019 data = json.loads(self.tx)
1018 up_data = data['up']
1020 up_data = data['up']
1019
1021
1020 up_values = []
1022 up_values = []
1021 for data in up_data:
1023 for data in up_data:
1022 for i in range(0,8):
1024 for i in range(0,8):
1023 up_values.append(data[i])
1025 up_values.append(data[i])
1024
1026
1025 return up_values
1027 return up_values
1026
1028
1027 @property
1029 @property
1028 def get_downtx(self):
1030 def get_downtx(self):
1029 """
1031 """
1030 This function shows the down-tx-values of one beam
1032 This function shows the down-tx-values of one beam
1031 """
1033 """
1032 data = json.loads(self.tx)
1034 data = json.loads(self.tx)
1033 down_data = data['down']
1035 down_data = data['down']
1034
1036
1035 down_values = []
1037 down_values = []
1036 for data in down_data:
1038 for data in down_data:
1037 for i in range(0,8):
1039 for i in range(0,8):
1038 down_values.append(data[i])
1040 down_values.append(data[i])
1039
1041
1040 return down_values
1042 return down_values
1041
1043
1042
1044
1043
1045
1044 @property
1046 @property
1045 def get_rx(self):
1047 def get_rx(self):
1046 """
1048 """
1047 This function shows the rx-values of one beam
1049 This function shows the rx-values of one beam
1048 """
1050 """
1049 data = json.loads(self.rx)
1051 data = json.loads(self.rx)
1050
1052
1051 return data
1053 return data
1052
1054
1053 @property
1055 @property
1054 def get_uprx(self):
1056 def get_uprx(self):
1055 """
1057 """
1056 This function shows the up-rx-values of one beam
1058 This function shows the up-rx-values of one beam
1057 """
1059 """
1058 data = json.loads(self.rx)
1060 data = json.loads(self.rx)
1059 up_data = data['up']
1061 up_data = data['up']
1060
1062
1061 up_values = []
1063 up_values = []
1062 for data in up_data:
1064 for data in up_data:
1063 for i in range(0,8):
1065 for i in range(0,8):
1064 up_values.append(data[i])
1066 up_values.append(data[i])
1065
1067
1066 return up_values
1068 return up_values
1067
1069
1068 @property
1070 @property
1069 def get_downrx(self):
1071 def get_downrx(self):
1070 """
1072 """
1071 This function shows the down-rx-values of one beam
1073 This function shows the down-rx-values of one beam
1072 """
1074 """
1073 data = json.loads(self.rx)
1075 data = json.loads(self.rx)
1074 down_data = data['down']
1076 down_data = data['down']
1075
1077
1076 down_values = []
1078 down_values = []
1077 for data in down_data:
1079 for data in down_data:
1078 for i in range(0,8):
1080 for i in range(0,8):
1079 down_values.append(data[i])
1081 down_values.append(data[i])
1080
1082
1081 return down_values
1083 return down_values
@@ -1,11 +1,7
1 {% load static %}
1 {% load static %}
2 {% load django_bootstrap5 %}
2 {% load django_bootstrap5 %}
3 {% load main_tags %}
3 {% load main_tags %}
4
4
5 {% block content %}
5 <img id="imgMainDown" src="{% url 'url_plot_beam' beam.abs_conf.id beam.id 'down' %}" alt="Error ploting..." style="width: 250px;height:250px; background-image: url({% static 'images/loader.gif' %});background-repeat: no-repeat;background-position: 50% 50%;">
6
6
7 <div id="PictureOverJRODown" style="float: right">
8 <img id="imgMainDown" src="{% url 'url_plot_beam' beam.abs_conf.id beam.id 'down' %}" alt="Error ploting..." style="width:340px;height:340px; background-image: url({% static 'images/loader.gif' %});background-repeat: no-repeat;background-position: 50% 50%;">
9 </div>
10
7
11 {% endblock %}
@@ -1,624 +1,642
1 {% load static %}
1 {% load static %}
2 {% load django_bootstrap5 %}
2 {% load django_bootstrap5 %}
3 {% load main_tags %}
3 {% load main_tags %}
4
4
5 {% block content %}
5 {% block content %}
6 <style>
6 <style>
7
7
8 .abs {
8 .abs {
9 border: 2px solid #00334d;
9 border: 2px solid #00334d;
10 vertical-align: center;
10 vertical-align: center;
11 display: inline-block;
11 display: inline-block;
12 font-size: 95%;
12 font-size: 95%;
13 }
13 }
14
14
15 .abs tr{
15 .abs tr{
16 border-bottom: 0px solid #00334d;
16 border-bottom: 0px solid #00334d;
17 }
17 }
18
18
19 .abs td{
19 .abs td{
20 border-right: 0px solid #00334d;
20 border-right: 0px solid #00334d;
21 text-align: center;
21 text-align: center;
22 padding: 4px;
22 padding: 4px;
23 }
23 }
24
24
25 .pattern {
25 .pattern {
26 border: 2px solid #00334d;
26 border: 2px solid #00334d;
27 vertical-align: center;
27 vertical-align: center;
28 font-weight: bold;
28 font-weight: bold;
29 text-align: center;
29 text-align: center;
30 }
30 }
31 .pattern tr{
31 .pattern tr{
32 border: 1px solid #ffffff;
32 border: 1px solid #ffffff;
33 background-color: #ecf0f1;
33 background-color: #ecf0f1;
34 }
34 }
35 .pattern td{
35 .pattern td{
36 border: 2px solid #e2e2e7;
36 border: 2px solid #e2e2e7;
37 text-align: center;
37 text-align: center;
38 }
38 }
39
39
40 .north_quarter{
40 .north_quarter{
41 border: 2px solid #00334d;
41 border: 2px solid #00334d;
42 vertical-align: center;
42 vertical-align: center;
43 font-weight: bold;
43 font-weight: bold;
44 }
44 }
45 .north_quarter tr{
45 .north_quarter tr{
46 border: 1px solid #ffffff;
46 border: 1px solid #ffffff;
47 background-color: #ecf0f1;
47 background-color: #ecf0f1;
48 }
48 }
49 .north_quarter td{
49 .north_quarter td{
50 border: 2px solid #e2e2e7;
50 border: 2px solid #e2e2e7;
51 text-align: center;
51 text-align: center;
52 }
52 }
53
53
54 .east_quarter{
54 .east_quarter{
55 border: 2px solid #00334d;
55 border: 2px solid #00334d;
56 vertical-align: center;
56 vertical-align: center;
57 font-weight: bold;
57 font-weight: bold;
58 }
58 }
59 .east_quarter tr{
59 .east_quarter tr{
60 border: 1px solid #ffffff;
60 border: 1px solid #ffffff;
61 background-color: #ecf0f1;
61 background-color: #ecf0f1;
62 }
62 }
63 .east_quarter td{
63 .east_quarter td{
64 border: 2px solid #e2e2e7;
64 border: 2px solid #e2e2e7;
65 text-align: center;
65 text-align: center;
66 }
66 }
67
67
68 .west_quarter{
68 .west_quarter{
69 border: 2px solid #00334d;
69 border: 2px solid #00334d;
70 vertical-align: center;
70 vertical-align: center;
71 font-weight: bold;
71 font-weight: bold;
72 }
72 }
73 .west_quarter tr{
73 .west_quarter tr{
74 border: 1px solid #ffffff;
74 border: 1px solid #ffffff;
75 background-color: #ecf0f1;
75 background-color: #ecf0f1;
76 }
76 }
77 .west_quarter td{
77 .west_quarter td{
78 border: 2px solid #e2e2e7;
78 border: 2px solid #e2e2e7;
79 text-align: center;
79 text-align: center;
80 }
80 }
81
81
82 .south_quarter{
82 .south_quarter{
83 border: 2px solid #00334d;
83 border: 2px solid #00334d;
84 vertical-align: center;
84 vertical-align: center;
85 font-weight: bold;
85 font-weight: bold;
86 }
86 }
87 .south_quarter tr{
87 .south_quarter tr{
88 border: 1px solid #ffffff;
88 border: 1px solid #ffffff;
89 background-color: #ecf0f1;
89 background-color: #ecf0f1;
90 }
90 }
91 .south_quarter td{
91 .south_quarter td{
92 border: 2px solid #e2e2e7;
92 border: 2px solid #e2e2e7;
93 text-align: center;
93 text-align: center;
94 }
94 }
95
95
96 .abs_tx {
96 .abs_tx {
97 border: 2px solid #00334d;
97 border: 2px solid #00334d;
98 vertical-align: center;
98 vertical-align: center;
99 display: inline-block;
99 display: inline-block;
100 vertical-align: top;
100 vertical-align: top;
101 margin-left: 10px;
101 margin-left: 10px;
102 vertical-align: top;
102 vertical-align: top;
103 font-size: 95%;
103 font-size: 95%;
104 }
104 }
105
105
106
106
107
107
108 .abs_tx tr:nth-last-child(1){
108 .abs_tx tr:nth-last-child(1){
109 border-bottom: 0px solid #00334d;
109 border-bottom: 0px solid #00334d;
110 }
110 }
111 .abs_tx td {
111 .abs_tx td {
112 text-align: center;
112 text-align: center;
113 padding: 4px;
113 padding: 4px;
114 }
114 }
115
115
116 .abs_rx {
116 .abs_rx {
117 border: 2px solid #00334d;
117 border: 2px solid #00334d;
118 vertical-align: center;
118 vertical-align: center;
119 display: inline-block;
119 display: inline-block;
120 margin-left: 10px;
120 margin-left: 10px;
121 text-align: center;
121 text-align: center;
122 font-size: 95%;
122 font-size: 95%;
123 }
123 }
124
124
125
125 .image_plot {
126 border: 2px solid #00334d;
127 display: inline-block;
128 vertical-align: 50px;
129 margin-left: 10px;
130 }
126
131
127 .abs_rx tr:nth-last-child(1){
132 .abs_rx tr:nth-last-child(1){
128 border-bottom: 0px solid #00334d;
133 border-bottom: 0px solid #00334d;
129 }
134 }
130 .abs_rx td {
135 .abs_rx td {
131 text-align: center;
136 text-align: center;
132 padding: 4px;
137 padding: 4px;
133 }
138 }
134
139
135 .tx {
140 .tx {
136 border: 2px solid #00334d;
141 border: 2px solid #00334d;
137 vertical-align: center;
142 vertical-align: center;
138 font-weight: bold;
143 font-weight: bold;
139 }
144 }
140 .tx tr{
145 .tx tr{
141 border: 1px solid #ffffff;
146 border: 1px solid #ffffff;
142 background-color: #ecf0f1;
147 background-color: #ecf0f1;
143 }
148 }
144 .tx td{
149 .tx td{
145 border: 2px solid #e2e2e7;
150 border: 2px solid #e2e2e7;
146 text-align: center;
151 text-align: center;
147 }
152 }
148
153
149
154
150 .rx {
155 .rx {
151 border: 2px solid #00334d;
156 border: 2px solid #00334d;
152 vertical-align: center;
157 vertical-align: center;
153 font-weight: bold;
158 font-weight: bold;
154 }
159 }
155 .rx tr{
160 .rx tr{
156 border: 1px solid #ffffff;
161 border: 1px solid #ffffff;
157 background-color: #ecf0f1;
162 background-color: #ecf0f1;
158 }
163 }
159 .rx td{
164 .rx td{
160 border: 2px solid #e2e2e7;
165 border: 2px solid #e2e2e7;
161 text-align: center;
166 text-align: center;
162 }
167 }
163
168
164 .pattern_image{
169 .pattern_image{
165 display: inline-block;
170 display: inline-block;
166 }
171 }
167
172
168 </style>
173 </style>
169
174
170
175
171 <div id="UP" class="panel-group">
176 <div id="UP" class="panel-group">
172 <div class="panel panel-default">
177 <div class="panel panel-default">
173 <div class="panel-heading">UP</div>
178 <div class="panel-heading">UP</div>
174 <div class="panel-body">
179 <div class="panel-body">
175 <table class="abs">
180 <table class="abs">
176 <tr>
181 <tr>
177 <td> <b>Antenna</b>
182 <td> <b>Antenna</b>
178 <table id="antenna_up" class="pattern">
183 <table id="antenna_up" class="pattern">
179 <tr>
184 <tr>
180 <td> North Quarter
185 <td> North Quarter
181 <table class="north_quarter">
186 <table class="north_quarter">
182 <tr> <td>{{beam.get_upvalues.0}}</td> <td>{{beam.get_upvalues.1}}</td> <td>{{beam.get_upvalues.2}}</td> <td>{{beam.get_upvalues.3}}</td> </tr>
187 <tr> <td>{{beam.get_upvalues.0}}</td> <td>{{beam.get_upvalues.1}}</td> <td>{{beam.get_upvalues.2}}</td> <td>{{beam.get_upvalues.3}}</td> </tr>
183 <tr> <td>{{beam.get_upvalues.8}}</td> <td>{{beam.get_upvalues.9}}</td> <td>{{beam.get_upvalues.10}}</td> <td>{{beam.get_upvalues.11}}</td> </tr>
188 <tr> <td>{{beam.get_upvalues.8}}</td> <td>{{beam.get_upvalues.9}}</td> <td>{{beam.get_upvalues.10}}</td> <td>{{beam.get_upvalues.11}}</td> </tr>
184 <tr> <td>{{beam.get_upvalues.16}}</td> <td>{{beam.get_upvalues.17}}</td> <td>{{beam.get_upvalues.18}}</td> <td>{{beam.get_upvalues.19}}</td> </tr>
189 <tr> <td>{{beam.get_upvalues.16}}</td> <td>{{beam.get_upvalues.17}}</td> <td>{{beam.get_upvalues.18}}</td> <td>{{beam.get_upvalues.19}}</td> </tr>
185 <tr> <td>{{beam.get_upvalues.24}}</td> <td>{{beam.get_upvalues.25}}</td> <td>{{beam.get_upvalues.26}}</td> <td>{{beam.get_upvalues.27}}</td> </tr>
190 <tr> <td>{{beam.get_upvalues.24}}</td> <td>{{beam.get_upvalues.25}}</td> <td>{{beam.get_upvalues.26}}</td> <td>{{beam.get_upvalues.27}}</td> </tr>
186 </table>
191 </table>
187 </td>
192 </td>
188 <td> East Quarter
193 <td> East Quarter
189 <table class="east_quarter">
194 <table class="east_quarter">
190 <tr> <td>{{beam.get_upvalues.4}}</td> <td>{{beam.get_upvalues.5}}</td> <td>{{beam.get_upvalues.6}}</td> <td>{{beam.get_upvalues.7}}</td> </tr>
195 <tr> <td>{{beam.get_upvalues.4}}</td> <td>{{beam.get_upvalues.5}}</td> <td>{{beam.get_upvalues.6}}</td> <td>{{beam.get_upvalues.7}}</td> </tr>
191 <tr> <td>{{beam.get_upvalues.12}}</td> <td>{{beam.get_upvalues.13}}</td> <td>{{beam.get_upvalues.14}}</td> <td>{{beam.get_upvalues.15}}</td> </tr>
196 <tr> <td>{{beam.get_upvalues.12}}</td> <td>{{beam.get_upvalues.13}}</td> <td>{{beam.get_upvalues.14}}</td> <td>{{beam.get_upvalues.15}}</td> </tr>
192 <tr> <td>{{beam.get_upvalues.20}}</td> <td>{{beam.get_upvalues.21}}</td> <td>{{beam.get_upvalues.22}}</td> <td>{{beam.get_upvalues.23}}</td> </tr>
197 <tr> <td>{{beam.get_upvalues.20}}</td> <td>{{beam.get_upvalues.21}}</td> <td>{{beam.get_upvalues.22}}</td> <td>{{beam.get_upvalues.23}}</td> </tr>
193 <tr> <td>{{beam.get_upvalues.28}}</td> <td>{{beam.get_upvalues.29}}</td> <td>{{beam.get_upvalues.30}}</td> <td>{{beam.get_upvalues.31}}</td> </tr>
198 <tr> <td>{{beam.get_upvalues.28}}</td> <td>{{beam.get_upvalues.29}}</td> <td>{{beam.get_upvalues.30}}</td> <td>{{beam.get_upvalues.31}}</td> </tr>
194 </table>
199 </table>
195 </td>
200 </td>
196 </tr>
201 </tr>
197 <tr>
202 <tr>
198 <td> West Quarter
203 <td> West Quarter
199 <table class="west_quarter">
204 <table class="west_quarter">
200 <tr> <td>{{beam.get_upvalues.32}}</td> <td>{{beam.get_upvalues.33}}</td> <td>{{beam.get_upvalues.34}}</td> <td>{{beam.get_upvalues.35}}</td> </tr>
205 <tr> <td>{{beam.get_upvalues.32}}</td> <td>{{beam.get_upvalues.33}}</td> <td>{{beam.get_upvalues.34}}</td> <td>{{beam.get_upvalues.35}}</td> </tr>
201 <tr> <td>{{beam.get_upvalues.40}}</td> <td>{{beam.get_upvalues.41}}</td> <td>{{beam.get_upvalues.42}}</td> <td>{{beam.get_upvalues.43}}</td> </tr>
206 <tr> <td>{{beam.get_upvalues.40}}</td> <td>{{beam.get_upvalues.41}}</td> <td>{{beam.get_upvalues.42}}</td> <td>{{beam.get_upvalues.43}}</td> </tr>
202 <tr> <td>{{beam.get_upvalues.48}}</td> <td>{{beam.get_upvalues.49}}</td> <td>{{beam.get_upvalues.50}}</td> <td>{{beam.get_upvalues.51}}</td> </tr>
207 <tr> <td>{{beam.get_upvalues.48}}</td> <td>{{beam.get_upvalues.49}}</td> <td>{{beam.get_upvalues.50}}</td> <td>{{beam.get_upvalues.51}}</td> </tr>
203 <tr> <td>{{beam.get_upvalues.56}}</td> <td>{{beam.get_upvalues.57}}</td> <td>{{beam.get_upvalues.58}}</td> <td>{{beam.get_upvalues.59}}</td> </tr>
208 <tr> <td>{{beam.get_upvalues.56}}</td> <td>{{beam.get_upvalues.57}}</td> <td>{{beam.get_upvalues.58}}</td> <td>{{beam.get_upvalues.59}}</td> </tr>
204 </table>
209 </table>
205 </td>
210 </td>
206 <td> South Quarter
211 <td> South Quarter
207 <table class="south_quarter">
212 <table class="south_quarter">
208 <tr> <td>{{beam.get_upvalues.36}}</td> <td>{{beam.get_upvalues.37}}</td> <td>{{beam.get_upvalues.38}}</td> <td>{{beam.get_upvalues.39}}</td> </tr>
213 <tr> <td>{{beam.get_upvalues.36}}</td> <td>{{beam.get_upvalues.37}}</td> <td>{{beam.get_upvalues.38}}</td> <td>{{beam.get_upvalues.39}}</td> </tr>
209 <tr> <td>{{beam.get_upvalues.44}}</td> <td>{{beam.get_upvalues.45}}</td> <td>{{beam.get_upvalues.46}}</td> <td>{{beam.get_upvalues.47}}</td> </tr>
214 <tr> <td>{{beam.get_upvalues.44}}</td> <td>{{beam.get_upvalues.45}}</td> <td>{{beam.get_upvalues.46}}</td> <td>{{beam.get_upvalues.47}}</td> </tr>
210 <tr> <td>{{beam.get_upvalues.52}}</td> <td>{{beam.get_upvalues.53}}</td> <td>{{beam.get_upvalues.54}}</td> <td>{{beam.get_upvalues.55}}</td> </tr>
215 <tr> <td>{{beam.get_upvalues.52}}</td> <td>{{beam.get_upvalues.53}}</td> <td>{{beam.get_upvalues.54}}</td> <td>{{beam.get_upvalues.55}}</td> </tr>
211 <tr> <td>{{beam.get_upvalues.60}}</td> <td>{{beam.get_upvalues.61}}</td> <td>{{beam.get_upvalues.62}}</td> <td>{{beam.get_upvalues.63}}</td> </tr>
216 <tr> <td>{{beam.get_upvalues.60}}</td> <td>{{beam.get_upvalues.61}}</td> <td>{{beam.get_upvalues.62}}</td> <td>{{beam.get_upvalues.63}}</td> </tr>
212 </table>
217 </table>
213 </td>
218 </td>
214 </tr>
219 </tr>
215 </table>
220 </table>
216 </td>
221 </td>
217 </tr>
222 </tr>
218 </table>
223 </table>
219
224
220
225
221 <table class="abs_tx">
226 <table class="abs_tx">
222 <tr>
227 <tr>
223 <td> <b>TX</b>
228 <td> <b>TX</b>
224 <table id="tx_up" class="tx">
229 <table id="tx_up" class="tx">
225 <tr>
230 <tr>
226 <td> North Quarter
231 <td> North Quarter
227 <table align="center" class="north_quarter">
232 <table align="center" class="north_quarter">
228 <tr>
233 <tr>
229 <td>{{beam.get_tx.up.0.0}}</td> <td>{{beam.get_tx.up.0.1}}</td> <td>{{beam.get_tx.up.0.2}}</td> <td>{{beam.get_tx.up.0.3}}</td>
234 <td>{{beam.get_tx.up.0.0}}</td> <td>{{beam.get_tx.up.0.1}}</td> <td>{{beam.get_tx.up.0.2}}</td> <td>{{beam.get_tx.up.0.3}}</td>
230 </tr>
235 </tr>
231 <tr>
236 <tr>
232 <td>{{beam.get_tx.up.1.0}}</td> <td>{{beam.get_tx.up.1.1}}</td> <td>{{beam.get_tx.up.1.2}}</td> <td>{{beam.get_tx.up.1.3}}</td>
237 <td>{{beam.get_tx.up.1.0}}</td> <td>{{beam.get_tx.up.1.1}}</td> <td>{{beam.get_tx.up.1.2}}</td> <td>{{beam.get_tx.up.1.3}}</td>
233 </tr>
238 </tr>
234 <tr>
239 <tr>
235 <td>{{beam.get_tx.up.2.0}}</td> <td>{{beam.get_tx.up.2.1}}</td> <td>{{beam.get_tx.up.2.2}}</td> <td>{{beam.get_tx.up.2.3}}</td>
240 <td>{{beam.get_tx.up.2.0}}</td> <td>{{beam.get_tx.up.2.1}}</td> <td>{{beam.get_tx.up.2.2}}</td> <td>{{beam.get_tx.up.2.3}}</td>
236 </tr>
241 </tr>
237 <tr>
242 <tr>
238 <td>{{beam.get_tx.up.3.0}}</td> <td>{{beam.get_tx.up.3.1}}</td> <td>{{beam.get_tx.up.3.2}}</td> <td>{{beam.get_tx.up.3.3}}</td>
243 <td>{{beam.get_tx.up.3.0}}</td> <td>{{beam.get_tx.up.3.1}}</td> <td>{{beam.get_tx.up.3.2}}</td> <td>{{beam.get_tx.up.3.3}}</td>
239 </tr>
244 </tr>
240 </table>
245 </table>
241 </td>
246 </td>
242 <td> East Quarter
247 <td> East Quarter
243 <table align="center" class="east_quarter">
248 <table align="center" class="east_quarter">
244 <tr>
249 <tr>
245 <td>{{beam.get_tx.up.0.4}}</td> <td>{{beam.get_tx.up.0.5}}</td> <td>{{beam.get_tx.up.0.6}}</td> <td>{{beam.get_tx.up.0.7}}</td>
250 <td>{{beam.get_tx.up.0.4}}</td> <td>{{beam.get_tx.up.0.5}}</td> <td>{{beam.get_tx.up.0.6}}</td> <td>{{beam.get_tx.up.0.7}}</td>
246 </tr>
251 </tr>
247 <tr>
252 <tr>
248 <td>{{beam.get_tx.up.1.4}}</td> <td>{{beam.get_tx.up.1.5}}</td> <td>{{beam.get_tx.up.1.6}}</td> <td>{{beam.get_tx.up.1.7}}</td>
253 <td>{{beam.get_tx.up.1.4}}</td> <td>{{beam.get_tx.up.1.5}}</td> <td>{{beam.get_tx.up.1.6}}</td> <td>{{beam.get_tx.up.1.7}}</td>
249 </tr>
254 </tr>
250 <tr>
255 <tr>
251 <td>{{beam.get_tx.up.2.4}}</td> <td>{{beam.get_tx.up.2.5}}</td> <td>{{beam.get_tx.up.2.6}}</td> <td>{{beam.get_tx.up.2.7}}</td>
256 <td>{{beam.get_tx.up.2.4}}</td> <td>{{beam.get_tx.up.2.5}}</td> <td>{{beam.get_tx.up.2.6}}</td> <td>{{beam.get_tx.up.2.7}}</td>
252 </tr>
257 </tr>
253 <tr>
258 <tr>
254 <td>{{beam.get_tx.up.3.4}}</td> <td>{{beam.get_tx.up.3.5}}</td> <td>{{beam.get_tx.up.3.6}}</td> <td>{{beam.get_tx.up.3.7}}</td>
259 <td>{{beam.get_tx.up.3.4}}</td> <td>{{beam.get_tx.up.3.5}}</td> <td>{{beam.get_tx.up.3.6}}</td> <td>{{beam.get_tx.up.3.7}}</td>
255 </tr>
260 </tr>
256 </table>
261 </table>
257 </td>
262 </td>
258 </tr>
263 </tr>
259 <tr>
264 <tr>
260 <td> West Quarter
265 <td> West Quarter
261 <table align="center" class="west_quarter">
266 <table align="center" class="west_quarter">
262 <tr>
267 <tr>
263 <td>{{beam.get_tx.up.4.0}}</td> <td>{{beam.get_tx.up.4.1}}</td> <td>{{beam.get_tx.up.4.2}}</td> <td>{{beam.get_tx.up.4.3}}</td>
268 <td>{{beam.get_tx.up.4.0}}</td> <td>{{beam.get_tx.up.4.1}}</td> <td>{{beam.get_tx.up.4.2}}</td> <td>{{beam.get_tx.up.4.3}}</td>
264 </tr>
269 </tr>
265 <tr>
270 <tr>
266 <td>{{beam.get_tx.up.5.0}}</td> <td>{{beam.get_tx.up.5.1}}</td> <td>{{beam.get_tx.up.5.2}}</td> <td>{{beam.get_tx.up.5.3}}</td>
271 <td>{{beam.get_tx.up.5.0}}</td> <td>{{beam.get_tx.up.5.1}}</td> <td>{{beam.get_tx.up.5.2}}</td> <td>{{beam.get_tx.up.5.3}}</td>
267 </tr>
272 </tr>
268 <tr>
273 <tr>
269 <td>{{beam.get_tx.up.6.0}}</td> <td>{{beam.get_tx.up.6.1}}</td> <td>{{beam.get_tx.up.6.2}}</td> <td>{{beam.get_tx.up.6.3}}</td>
274 <td>{{beam.get_tx.up.6.0}}</td> <td>{{beam.get_tx.up.6.1}}</td> <td>{{beam.get_tx.up.6.2}}</td> <td>{{beam.get_tx.up.6.3}}</td>
270 </tr>
275 </tr>
271 <tr>
276 <tr>
272 <td>{{beam.get_tx.up.7.0}}</td> <td>{{beam.get_tx.up.7.1}}</td> <td>{{beam.get_tx.up.7.2}}</td> <td>{{beam.get_tx.up.7.3}}</td>
277 <td>{{beam.get_tx.up.7.0}}</td> <td>{{beam.get_tx.up.7.1}}</td> <td>{{beam.get_tx.up.7.2}}</td> <td>{{beam.get_tx.up.7.3}}</td>
273 </tr>
278 </tr>
274 </table>
279 </table>
275 </td>
280 </td>
276 <td> South Quarter
281 <td> South Quarter
277 <table align="center" class="south_quarter">
282 <table align="center" class="south_quarter">
278 <tr>
283 <tr>
279 <td>{{beam.get_tx.up.4.4}}</td> <td>{{beam.get_tx.up.4.5}}</td> <td>{{beam.get_tx.up.4.6}}</td> <td>{{beam.get_tx.up.4.7}}</td>
284 <td>{{beam.get_tx.up.4.4}}</td> <td>{{beam.get_tx.up.4.5}}</td> <td>{{beam.get_tx.up.4.6}}</td> <td>{{beam.get_tx.up.4.7}}</td>
280 </tr>
285 </tr>
281 <tr>
286 <tr>
282 <td>{{beam.get_tx.up.5.4}}</td> <td>{{beam.get_tx.up.5.5}}</td> <td>{{beam.get_tx.up.5.6}}</td> <td>{{beam.get_tx.up.5.7}}</td>
287 <td>{{beam.get_tx.up.5.4}}</td> <td>{{beam.get_tx.up.5.5}}</td> <td>{{beam.get_tx.up.5.6}}</td> <td>{{beam.get_tx.up.5.7}}</td>
283 </tr>
288 </tr>
284 <tr>
289 <tr>
285 <td>{{beam.get_tx.up.6.4}}</td> <td>{{beam.get_tx.up.6.5}}</td> <td>{{beam.get_tx.up.6.6}}</td> <td>{{beam.get_tx.up.6.7}}</td>
290 <td>{{beam.get_tx.up.6.4}}</td> <td>{{beam.get_tx.up.6.5}}</td> <td>{{beam.get_tx.up.6.6}}</td> <td>{{beam.get_tx.up.6.7}}</td>
286 </tr>
291 </tr>
287 <tr>
292 <tr>
288 <td>{{beam.get_tx.up.7.4}}</td> <td>{{beam.get_tx.up.7.5}}</td> <td>{{beam.get_tx.up.7.6}}</td> <td>{{beam.get_tx.up.7.7}}</td>
293 <td>{{beam.get_tx.up.7.4}}</td> <td>{{beam.get_tx.up.7.5}}</td> <td>{{beam.get_tx.up.7.6}}</td> <td>{{beam.get_tx.up.7.7}}</td>
289 </tr>
294 </tr>
290 </table>
295 </table>
291 </td>
296 </td>
292 </tr>
297 </tr>
293 </table>
298 </table>
294 </td>
299 </td>
295 </tr>
300 </tr>
296 </table>
301 </table>
297
302
298
303
299 <table class="abs_rx">
304 <table class="abs_rx">
300 <tr>
305 <tr>
301 <td> <b>RX</b>
306 <td> <b>RX</b>
302 <table id="rx_up" class="rx">
307 <table id="rx_up" class="rx">
303 <tr>
308 <tr>
304 <td> North Quarter
309 <td> North Quarter
305 <table align="center" class="north_quarter">
310 <table align="center" class="north_quarter">
306 <tr>
311 <tr>
307 <td>{{beam.get_rx.up.0.0}}</td> <td>{{beam.get_rx.up.0.1}}</td> <td>{{beam.get_rx.up.0.2}}</td> <td>{{beam.get_rx.up.0.3}}</td>
312 <td>{{beam.get_rx.up.0.0}}</td> <td>{{beam.get_rx.up.0.1}}</td> <td>{{beam.get_rx.up.0.2}}</td> <td>{{beam.get_rx.up.0.3}}</td>
308 </tr>
313 </tr>
309 <tr>
314 <tr>
310 <td>{{beam.get_rx.up.1.0}}</td> <td>{{beam.get_rx.up.1.1}}</td> <td>{{beam.get_rx.up.1.2}}</td> <td>{{beam.get_rx.up.1.3}}</td>
315 <td>{{beam.get_rx.up.1.0}}</td> <td>{{beam.get_rx.up.1.1}}</td> <td>{{beam.get_rx.up.1.2}}</td> <td>{{beam.get_rx.up.1.3}}</td>
311 </tr>
316 </tr>
312 <tr>
317 <tr>
313 <td>{{beam.get_rx.up.2.0}}</td> <td>{{beam.get_rx.up.2.1}}</td> <td>{{beam.get_rx.up.2.2}}</td> <td>{{beam.get_rx.up.2.3}}</td>
318 <td>{{beam.get_rx.up.2.0}}</td> <td>{{beam.get_rx.up.2.1}}</td> <td>{{beam.get_rx.up.2.2}}</td> <td>{{beam.get_rx.up.2.3}}</td>
314 </tr>
319 </tr>
315 <tr>
320 <tr>
316 <td>{{beam.get_rx.up.3.0}}</td> <td>{{beam.get_rx.up.3.1}}</td> <td>{{beam.get_rx.up.3.2}}</td> <td>{{beam.get_rx.up.3.3}}</td>
321 <td>{{beam.get_rx.up.3.0}}</td> <td>{{beam.get_rx.up.3.1}}</td> <td>{{beam.get_rx.up.3.2}}</td> <td>{{beam.get_rx.up.3.3}}</td>
317 </tr>
322 </tr>
318 </table>
323 </table>
319 </td>
324 </td>
320 <td> East Quarter
325 <td> East Quarter
321 <table align="center" class="east_quarter">
326 <table align="center" class="east_quarter">
322 <tr>
327 <tr>
323 <td>{{beam.get_rx.up.0.4}}</td> <td>{{beam.get_rx.up.0.5}}</td> <td>{{beam.get_rx.up.0.6}}</td> <td>{{beam.get_rx.up.0.7}}</td>
328 <td>{{beam.get_rx.up.0.4}}</td> <td>{{beam.get_rx.up.0.5}}</td> <td>{{beam.get_rx.up.0.6}}</td> <td>{{beam.get_rx.up.0.7}}</td>
324 </tr>
329 </tr>
325 <tr>
330 <tr>
326 <td>{{beam.get_rx.up.1.4}}</td> <td>{{beam.get_rx.up.1.5}}</td> <td>{{beam.get_rx.up.1.6}}</td> <td>{{beam.get_rx.up.1.7}}</td>
331 <td>{{beam.get_rx.up.1.4}}</td> <td>{{beam.get_rx.up.1.5}}</td> <td>{{beam.get_rx.up.1.6}}</td> <td>{{beam.get_rx.up.1.7}}</td>
327 </tr>
332 </tr>
328 <tr>
333 <tr>
329 <td>{{beam.get_rx.up.2.4}}</td> <td>{{beam.get_rx.up.2.5}}</td> <td>{{beam.get_rx.up.2.6}}</td> <td>{{beam.get_rx.up.2.7}}</td>
334 <td>{{beam.get_rx.up.2.4}}</td> <td>{{beam.get_rx.up.2.5}}</td> <td>{{beam.get_rx.up.2.6}}</td> <td>{{beam.get_rx.up.2.7}}</td>
330 </tr>
335 </tr>
331 <tr>
336 <tr>
332 <td>{{beam.get_rx.up.3.4}}</td> <td>{{beam.get_rx.up.3.5}}</td> <td>{{beam.get_rx.up.3.6}}</td> <td>{{beam.get_rx.up.3.7}}</td>
337 <td>{{beam.get_rx.up.3.4}}</td> <td>{{beam.get_rx.up.3.5}}</td> <td>{{beam.get_rx.up.3.6}}</td> <td>{{beam.get_rx.up.3.7}}</td>
333 </tr>
338 </tr>
334 </table>
339 </table>
335 </td>
340 </td>
336 </tr>
341 </tr>
337 <tr>
342 <tr>
338 <td> West Quarter
343 <td> West Quarter
339 <table align="center" class="west_quarter">
344 <table align="center" class="west_quarter">
340 <tr>
345 <tr>
341 <td>{{beam.get_rx.up.4.0}}</td> <td>{{beam.get_rx.up.4.1}}</td> <td>{{beam.get_rx.up.4.2}}</td> <td>{{beam.get_rx.up.4.3}}</td>
346 <td>{{beam.get_rx.up.4.0}}</td> <td>{{beam.get_rx.up.4.1}}</td> <td>{{beam.get_rx.up.4.2}}</td> <td>{{beam.get_rx.up.4.3}}</td>
342 </tr>
347 </tr>
343 <tr>
348 <tr>
344 <td>{{beam.get_rx.up.5.0}}</td> <td>{{beam.get_rx.up.5.1}}</td> <td>{{beam.get_rx.up.5.2}}</td> <td>{{beam.get_rx.up.5.3}}</td>
349 <td>{{beam.get_rx.up.5.0}}</td> <td>{{beam.get_rx.up.5.1}}</td> <td>{{beam.get_rx.up.5.2}}</td> <td>{{beam.get_rx.up.5.3}}</td>
345 </tr>
350 </tr>
346 <tr>
351 <tr>
347 <td>{{beam.get_rx.up.6.0}}</td> <td>{{beam.get_rx.up.6.1}}</td> <td>{{beam.get_rx.up.6.2}}</td> <td>{{beam.get_rx.up.6.3}}</td>
352 <td>{{beam.get_rx.up.6.0}}</td> <td>{{beam.get_rx.up.6.1}}</td> <td>{{beam.get_rx.up.6.2}}</td> <td>{{beam.get_rx.up.6.3}}</td>
348 </tr>
353 </tr>
349 <tr>
354 <tr>
350 <td>{{beam.get_rx.up.7.0}}</td> <td>{{beam.get_rx.up.7.1}}</td> <td>{{beam.get_rx.up.7.2}}</td> <td>{{beam.get_rx.up.7.3}}</td>
355 <td>{{beam.get_rx.up.7.0}}</td> <td>{{beam.get_rx.up.7.1}}</td> <td>{{beam.get_rx.up.7.2}}</td> <td>{{beam.get_rx.up.7.3}}</td>
351 </tr>
356 </tr>
352 </table>
357 </table>
353 </td>
358 </td>
354 <td> South Quarter
359 <td> South Quarter
355 <table align="center" class="south_quarter">
360 <table align="center" class="south_quarter">
356 <tr>
361 <tr>
357 <td>{{beam.get_rx.up.4.4}}</td> <td>{{beam.get_rx.up.4.5}}</td> <td>{{beam.get_rx.up.4.6}}</td> <td>{{beam.get_rx.up.4.7}}</td>
362 <td>{{beam.get_rx.up.4.4}}</td> <td>{{beam.get_rx.up.4.5}}</td> <td>{{beam.get_rx.up.4.6}}</td> <td>{{beam.get_rx.up.4.7}}</td>
358 </tr>
363 </tr>
359 <tr>
364 <tr>
360 <td>{{beam.get_rx.up.5.4}}</td> <td>{{beam.get_rx.up.5.5}}</td> <td>{{beam.get_rx.up.5.6}}</td> <td>{{beam.get_rx.up.5.7}}</td>
365 <td>{{beam.get_rx.up.5.4}}</td> <td>{{beam.get_rx.up.5.5}}</td> <td>{{beam.get_rx.up.5.6}}</td> <td>{{beam.get_rx.up.5.7}}</td>
361 </tr>
366 </tr>
362 <tr>
367 <tr>
363 <td>{{beam.get_rx.up.6.4}}</td> <td>{{beam.get_rx.up.6.5}}</td> <td>{{beam.get_rx.up.6.6}}</td> <td>{{beam.get_rx.up.6.7}}</td>
368 <td>{{beam.get_rx.up.6.4}}</td> <td>{{beam.get_rx.up.6.5}}</td> <td>{{beam.get_rx.up.6.6}}</td> <td>{{beam.get_rx.up.6.7}}</td>
364 </tr>
369 </tr>
365 <tr>
370 <tr>
366 <td>{{beam.get_rx.up.7.4}}</td> <td>{{beam.get_rx.up.7.5}}</td> <td>{{beam.get_rx.up.7.6}}</td> <td>{{beam.get_rx.up.7.7}}</td>
371 <td>{{beam.get_rx.up.7.4}}</td> <td>{{beam.get_rx.up.7.5}}</td> <td>{{beam.get_rx.up.7.6}}</td> <td>{{beam.get_rx.up.7.7}}</td>
367 </tr>
372 </tr>
368 </table>
373 </table>
369 </td>
374 </td>
370 </tr>
375 </tr>
371 </table>
376 </table>
372 </td>
377 </td>
373 </tr>
378 </tr>
374 </table>
379 </table>
375
380
376 {% if not edit %}
381 <table class="image_plot">
377 {% include "abs_uppattern_img.html" %}
382 <tr>
378 {% endif %}
383 <td>
384 {% if not edit %}
385 {% include "abs_uppattern_img.html" %}
386 {% endif %}
387 <!-- <img id="imgMains" src="{% url 'url_plot_beam' beam.abs_conf.id beam.id 'up' %}" alt="Error ploting..." style="width: 250px;height:250px; background-image: url({% static 'images/loader.gif' %});background-repeat: no-repeat;background-position: 50% 50%;"> -->
388 </td>
389 </tr>
390 </table>
379
391
380 <br>
392 <br>
381
393
382 <div id="up_ues" style="display: inline-block">
394 <div id="up_ues" style="display: inline-block">
383 Ues: {{beam.get_up_ues}}
395 Ues: {{beam.get_up_ues}}
384 </div>
396 </div>
385
397
386 <div style="margin-left: 70px; display: inline-block">
398 <div style="margin-left: 70px; display: inline-block">
387 <input type="checkbox" id="up_onlyrx" {% if beam.get_up_onlyrx == True %} checked="True" {% endif %} disabled>
399 <input type="checkbox" id="up_onlyrx" {% if beam.get_up_onlyrx == True %} checked="True" {% endif %} disabled>
388 Only RX
400 Only RX
389 </input>
401 </input>
390 </div>
402 </div>
391
403
392 </div>
404 </div>
393 </div>
405 </div>
394 </div>
406 </div>
395
407
396 <div id="DOWN" class="panel-group">
408 <div id="DOWN" class="panel-group">
397 <div class="panel panel-default">
409 <div class="panel panel-default">
398 <div class="panel-heading">DOWN</div>
410 <div class="panel-heading">DOWN</div>
399 <div class="panel-body">
411 <div class="panel-body">
400 <table class="abs">
412 <table class="abs">
401 <tr>
413 <tr>
402 <td> <b>Antenna</b>
414 <td> <b>Antenna</b>
403 <table id="antenna_down" class="pattern">
415 <table id="antenna_down" class="pattern">
404 <tr>
416 <tr>
405 <td> <b>North Quarter</b>
417 <td> <b>North Quarter</b>
406 <table class="north_quarter">
418 <table class="north_quarter">
407 <tr> <td>{{beam.get_downvalues.0}}</td> <td>{{beam.get_downvalues.1}}</td> <td>{{beam.get_downvalues.2}}</td> <td>{{beam.get_downvalues.3}}</td> </tr>
419 <tr> <td>{{beam.get_downvalues.0}}</td> <td>{{beam.get_downvalues.1}}</td> <td>{{beam.get_downvalues.2}}</td> <td>{{beam.get_downvalues.3}}</td> </tr>
408 <tr> <td>{{beam.get_downvalues.8}}</td> <td>{{beam.get_downvalues.9}}</td> <td>{{beam.get_downvalues.10}}</td> <td>{{beam.get_downvalues.11}}</td> </tr>
420 <tr> <td>{{beam.get_downvalues.8}}</td> <td>{{beam.get_downvalues.9}}</td> <td>{{beam.get_downvalues.10}}</td> <td>{{beam.get_downvalues.11}}</td> </tr>
409 <tr> <td>{{beam.get_downvalues.16}}</td> <td>{{beam.get_downvalues.17}}</td> <td>{{beam.get_downvalues.18}}</td> <td>{{beam.get_downvalues.19}}</td> </tr>
421 <tr> <td>{{beam.get_downvalues.16}}</td> <td>{{beam.get_downvalues.17}}</td> <td>{{beam.get_downvalues.18}}</td> <td>{{beam.get_downvalues.19}}</td> </tr>
410 <tr> <td>{{beam.get_downvalues.24}}</td> <td>{{beam.get_downvalues.25}}</td> <td>{{beam.get_downvalues.26}}</td> <td>{{beam.get_downvalues.27}}</td> </tr>
422 <tr> <td>{{beam.get_downvalues.24}}</td> <td>{{beam.get_downvalues.25}}</td> <td>{{beam.get_downvalues.26}}</td> <td>{{beam.get_downvalues.27}}</td> </tr>
411 </table>
423 </table>
412 </td>
424 </td>
413 <td> <b>East Quarter</b>
425 <td> <b>East Quarter</b>
414 <table class="east_quarter">
426 <table class="east_quarter">
415 <tr> <td>{{beam.get_downvalues.4}}</td> <td>{{beam.get_downvalues.5}}</td> <td>{{beam.get_downvalues.6}}</td> <td>{{beam.get_downvalues.7}}</td> </tr>
427 <tr> <td>{{beam.get_downvalues.4}}</td> <td>{{beam.get_downvalues.5}}</td> <td>{{beam.get_downvalues.6}}</td> <td>{{beam.get_downvalues.7}}</td> </tr>
416 <tr> <td>{{beam.get_downvalues.12}}</td> <td>{{beam.get_downvalues.13}}</td> <td>{{beam.get_downvalues.14}}</td> <td>{{beam.get_downvalues.15}}</td> </tr>
428 <tr> <td>{{beam.get_downvalues.12}}</td> <td>{{beam.get_downvalues.13}}</td> <td>{{beam.get_downvalues.14}}</td> <td>{{beam.get_downvalues.15}}</td> </tr>
417 <tr> <td>{{beam.get_downvalues.20}}</td> <td>{{beam.get_downvalues.21}}</td> <td>{{beam.get_downvalues.22}}</td> <td>{{beam.get_downvalues.23}}</td> </tr>
429 <tr> <td>{{beam.get_downvalues.20}}</td> <td>{{beam.get_downvalues.21}}</td> <td>{{beam.get_downvalues.22}}</td> <td>{{beam.get_downvalues.23}}</td> </tr>
418 <tr> <td>{{beam.get_downvalues.28}}</td> <td>{{beam.get_downvalues.29}}</td> <td>{{beam.get_downvalues.30}}</td> <td>{{beam.get_downvalues.31}}</td> </tr>
430 <tr> <td>{{beam.get_downvalues.28}}</td> <td>{{beam.get_downvalues.29}}</td> <td>{{beam.get_downvalues.30}}</td> <td>{{beam.get_downvalues.31}}</td> </tr>
419 </table>
431 </table>
420 </td>
432 </td>
421 </tr>
433 </tr>
422 <tr>
434 <tr>
423 <td> <b>West Quarter</b>
435 <td> <b>West Quarter</b>
424 <table class="west_quarter">
436 <table class="west_quarter">
425 <tr> <td>{{beam.get_downvalues.32}}</td> <td>{{beam.get_downvalues.33}}</td> <td>{{beam.get_downvalues.34}}</td> <td>{{beam.get_downvalues.35}}</td> </tr>
437 <tr> <td>{{beam.get_downvalues.32}}</td> <td>{{beam.get_downvalues.33}}</td> <td>{{beam.get_downvalues.34}}</td> <td>{{beam.get_downvalues.35}}</td> </tr>
426 <tr> <td>{{beam.get_downvalues.40}}</td> <td>{{beam.get_downvalues.41}}</td> <td>{{beam.get_downvalues.42}}</td> <td>{{beam.get_downvalues.43}}</td> </tr>
438 <tr> <td>{{beam.get_downvalues.40}}</td> <td>{{beam.get_downvalues.41}}</td> <td>{{beam.get_downvalues.42}}</td> <td>{{beam.get_downvalues.43}}</td> </tr>
427 <tr> <td>{{beam.get_downvalues.48}}</td> <td>{{beam.get_downvalues.49}}</td> <td>{{beam.get_downvalues.50}}</td> <td>{{beam.get_downvalues.51}}</td> </tr>
439 <tr> <td>{{beam.get_downvalues.48}}</td> <td>{{beam.get_downvalues.49}}</td> <td>{{beam.get_downvalues.50}}</td> <td>{{beam.get_downvalues.51}}</td> </tr>
428 <tr> <td>{{beam.get_downvalues.56}}</td> <td>{{beam.get_downvalues.57}}</td> <td>{{beam.get_downvalues.58}}</td> <td>{{beam.get_downvalues.59}}</td> </tr>
440 <tr> <td>{{beam.get_downvalues.56}}</td> <td>{{beam.get_downvalues.57}}</td> <td>{{beam.get_downvalues.58}}</td> <td>{{beam.get_downvalues.59}}</td> </tr>
429 </table>
441 </table>
430 </td>
442 </td>
431 <td> <b>South Quarter</b>
443 <td> <b>South Quarter</b>
432 <table class="south_quarter">
444 <table class="south_quarter">
433 <tr> <td>{{beam.get_downvalues.36}}</td> <td>{{beam.get_downvalues.37}}</td> <td>{{beam.get_downvalues.38}}</td> <td>{{beam.get_downvalues.39}}</td> </tr>
445 <tr> <td>{{beam.get_downvalues.36}}</td> <td>{{beam.get_downvalues.37}}</td> <td>{{beam.get_downvalues.38}}</td> <td>{{beam.get_downvalues.39}}</td> </tr>
434 <tr> <td>{{beam.get_downvalues.44}}</td> <td>{{beam.get_downvalues.45}}</td> <td>{{beam.get_downvalues.46}}</td> <td>{{beam.get_downvalues.47}}</td> </tr>
446 <tr> <td>{{beam.get_downvalues.44}}</td> <td>{{beam.get_downvalues.45}}</td> <td>{{beam.get_downvalues.46}}</td> <td>{{beam.get_downvalues.47}}</td> </tr>
435 <tr> <td>{{beam.get_downvalues.52}}</td> <td>{{beam.get_downvalues.53}}</td> <td>{{beam.get_downvalues.54}}</td> <td>{{beam.get_downvalues.55}}</td> </tr>
447 <tr> <td>{{beam.get_downvalues.52}}</td> <td>{{beam.get_downvalues.53}}</td> <td>{{beam.get_downvalues.54}}</td> <td>{{beam.get_downvalues.55}}</td> </tr>
436 <tr> <td>{{beam.get_downvalues.60}}</td> <td>{{beam.get_downvalues.61}}</td> <td>{{beam.get_downvalues.62}}</td> <td>{{beam.get_downvalues.63}}</td> </tr>
448 <tr> <td>{{beam.get_downvalues.60}}</td> <td>{{beam.get_downvalues.61}}</td> <td>{{beam.get_downvalues.62}}</td> <td>{{beam.get_downvalues.63}}</td> </tr>
437 </table>
449 </table>
438 </td>
450 </td>
439 </tr>
451 </tr>
440 </table>
452 </table>
441 </td>
453 </td>
442 </tr>
454 </tr>
443 </table>
455 </table>
444
456
445 <table class="abs_tx">
457 <table class="abs_tx">
446 <tr>
458 <tr>
447 <td> <b>TX</b>
459 <td> <b>TX</b>
448 <table id="tx_down" class="tx">
460 <table id="tx_down" class="tx">
449 <tr>
461 <tr>
450 <td> <b>North Quarter</b>
462 <td> <b>North Quarter</b>
451 <table align="center" class="north_quarter">
463 <table align="center" class="north_quarter">
452 <tr>
464 <tr>
453 <td>{{beam.get_tx.down.0.0}}</td> <td>{{beam.get_tx.down.0.1}}</td> <td>{{beam.get_tx.down.0.2}}</td> <td>{{beam.get_tx.down.0.3}}</td>
465 <td>{{beam.get_tx.down.0.0}}</td> <td>{{beam.get_tx.down.0.1}}</td> <td>{{beam.get_tx.down.0.2}}</td> <td>{{beam.get_tx.down.0.3}}</td>
454 </tr>
466 </tr>
455 <tr>
467 <tr>
456 <td>{{beam.get_tx.down.1.0}}</td> <td>{{beam.get_tx.down.1.1}}</td> <td>{{beam.get_tx.down.1.2}}</td> <td>{{beam.get_tx.down.1.3}}</td>
468 <td>{{beam.get_tx.down.1.0}}</td> <td>{{beam.get_tx.down.1.1}}</td> <td>{{beam.get_tx.down.1.2}}</td> <td>{{beam.get_tx.down.1.3}}</td>
457 </tr>
469 </tr>
458 <tr>
470 <tr>
459 <td>{{beam.get_tx.down.2.0}}</td> <td>{{beam.get_tx.down.2.1}}</td> <td>{{beam.get_tx.down.2.2}}</td> <td>{{beam.get_tx.down.2.3}}</td>
471 <td>{{beam.get_tx.down.2.0}}</td> <td>{{beam.get_tx.down.2.1}}</td> <td>{{beam.get_tx.down.2.2}}</td> <td>{{beam.get_tx.down.2.3}}</td>
460 </tr>
472 </tr>
461 <tr>
473 <tr>
462 <td>{{beam.get_tx.down.3.0}}</td> <td>{{beam.get_tx.down.3.1}}</td> <td>{{beam.get_tx.down.3.2}}</td> <td>{{beam.get_tx.down.3.3}}</td>
474 <td>{{beam.get_tx.down.3.0}}</td> <td>{{beam.get_tx.down.3.1}}</td> <td>{{beam.get_tx.down.3.2}}</td> <td>{{beam.get_tx.down.3.3}}</td>
463 </tr>
475 </tr>
464 </table>
476 </table>
465 </td>
477 </td>
466 <td> <b>East Quarter</b>
478 <td> <b>East Quarter</b>
467 <table align="center" class="east_quarter">
479 <table align="center" class="east_quarter">
468 <tr>
480 <tr>
469 <td>{{beam.get_tx.down.0.4}}</td> <td>{{beam.get_tx.down.0.5}}</td> <td>{{beam.get_tx.down.0.6}}</td> <td>{{beam.get_tx.down.0.7}}</td>
481 <td>{{beam.get_tx.down.0.4}}</td> <td>{{beam.get_tx.down.0.5}}</td> <td>{{beam.get_tx.down.0.6}}</td> <td>{{beam.get_tx.down.0.7}}</td>
470 </tr>
482 </tr>
471 <tr>
483 <tr>
472 <td>{{beam.get_tx.down.1.4}}</td> <td>{{beam.get_tx.down.1.5}}</td> <td>{{beam.get_tx.down.1.6}}</td> <td>{{beam.get_tx.down.1.7}}</td>
484 <td>{{beam.get_tx.down.1.4}}</td> <td>{{beam.get_tx.down.1.5}}</td> <td>{{beam.get_tx.down.1.6}}</td> <td>{{beam.get_tx.down.1.7}}</td>
473 </tr>
485 </tr>
474 <tr>
486 <tr>
475 <td>{{beam.get_tx.down.2.4}}</td> <td>{{beam.get_tx.down.2.5}}</td> <td>{{beam.get_tx.down.2.6}}</td> <td>{{beam.get_tx.down.2.7}}</td>
487 <td>{{beam.get_tx.down.2.4}}</td> <td>{{beam.get_tx.down.2.5}}</td> <td>{{beam.get_tx.down.2.6}}</td> <td>{{beam.get_tx.down.2.7}}</td>
476 </tr>
488 </tr>
477 <tr>
489 <tr>
478 <td>{{beam.get_tx.down.3.4}}</td> <td>{{beam.get_tx.down.3.5}}</td> <td>{{beam.get_tx.down.3.6}}</td> <td>{{beam.get_tx.down.3.7}}</td>
490 <td>{{beam.get_tx.down.3.4}}</td> <td>{{beam.get_tx.down.3.5}}</td> <td>{{beam.get_tx.down.3.6}}</td> <td>{{beam.get_tx.down.3.7}}</td>
479 </tr>
491 </tr>
480 </table>
492 </table>
481 </td>
493 </td>
482 </tr>
494 </tr>
483 <tr>
495 <tr>
484 <td> <b>West Quarter</b>
496 <td> <b>West Quarter</b>
485 <table align="center" class="west_quarter">
497 <table align="center" class="west_quarter">
486 <tr>
498 <tr>
487 <td>{{beam.get_tx.down.4.0}}</td> <td>{{beam.get_tx.down.4.1}}</td> <td>{{beam.get_tx.down.4.2}}</td> <td>{{beam.get_tx.down.4.3}}</td>
499 <td>{{beam.get_tx.down.4.0}}</td> <td>{{beam.get_tx.down.4.1}}</td> <td>{{beam.get_tx.down.4.2}}</td> <td>{{beam.get_tx.down.4.3}}</td>
488 </tr>
500 </tr>
489 <tr>
501 <tr>
490 <td>{{beam.get_tx.down.5.0}}</td> <td>{{beam.get_tx.down.5.1}}</td> <td>{{beam.get_tx.down.5.2}}</td> <td>{{beam.get_tx.down.5.3}}</td>
502 <td>{{beam.get_tx.down.5.0}}</td> <td>{{beam.get_tx.down.5.1}}</td> <td>{{beam.get_tx.down.5.2}}</td> <td>{{beam.get_tx.down.5.3}}</td>
491 </tr>
503 </tr>
492 <tr>
504 <tr>
493 <td>{{beam.get_tx.down.6.0}}</td> <td>{{beam.get_tx.down.6.1}}</td> <td>{{beam.get_tx.down.6.2}}</td> <td>{{beam.get_tx.down.6.3}}</td>
505 <td>{{beam.get_tx.down.6.0}}</td> <td>{{beam.get_tx.down.6.1}}</td> <td>{{beam.get_tx.down.6.2}}</td> <td>{{beam.get_tx.down.6.3}}</td>
494 </tr>
506 </tr>
495 <tr>
507 <tr>
496 <td>{{beam.get_tx.down.7.0}}</td> <td>{{beam.get_tx.down.7.1}}</td> <td>{{beam.get_tx.down.7.2}}</td> <td>{{beam.get_tx.down.7.3}}</td>
508 <td>{{beam.get_tx.down.7.0}}</td> <td>{{beam.get_tx.down.7.1}}</td> <td>{{beam.get_tx.down.7.2}}</td> <td>{{beam.get_tx.down.7.3}}</td>
497 </tr>
509 </tr>
498 </table>
510 </table>
499 </td>
511 </td>
500 <td> <b>South Quarter</b>
512 <td> <b>South Quarter</b>
501 <table align="center" class="south_quarter">
513 <table align="center" class="south_quarter">
502 <tr>
514 <tr>
503 <td>{{beam.get_tx.down.4.4}}</td> <td>{{beam.get_tx.down.4.5}}</td> <td>{{beam.get_tx.down.4.6}}</td> <td>{{beam.get_tx.down.4.7}}</td>
515 <td>{{beam.get_tx.down.4.4}}</td> <td>{{beam.get_tx.down.4.5}}</td> <td>{{beam.get_tx.down.4.6}}</td> <td>{{beam.get_tx.down.4.7}}</td>
504 </tr>
516 </tr>
505 <tr>
517 <tr>
506 <td>{{beam.get_tx.down.5.4}}</td> <td>{{beam.get_tx.down.5.5}}</td> <td>{{beam.get_tx.down.5.6}}</td> <td>{{beam.get_tx.down.5.7}}</td>
518 <td>{{beam.get_tx.down.5.4}}</td> <td>{{beam.get_tx.down.5.5}}</td> <td>{{beam.get_tx.down.5.6}}</td> <td>{{beam.get_tx.down.5.7}}</td>
507 </tr>
519 </tr>
508 <tr>
520 <tr>
509 <td>{{beam.get_tx.down.6.4}}</td> <td>{{beam.get_tx.down.6.5}}</td> <td>{{beam.get_tx.down.6.6}}</td> <td>{{beam.get_tx.down.6.7}}</td>
521 <td>{{beam.get_tx.down.6.4}}</td> <td>{{beam.get_tx.down.6.5}}</td> <td>{{beam.get_tx.down.6.6}}</td> <td>{{beam.get_tx.down.6.7}}</td>
510 </tr>
522 </tr>
511 <tr>
523 <tr>
512 <td>{{beam.get_tx.down.7.4}}</td> <td>{{beam.get_tx.down.7.5}}</td> <td>{{beam.get_tx.down.7.6}}</td> <td>{{beam.get_tx.down.7.7}}</td>
524 <td>{{beam.get_tx.down.7.4}}</td> <td>{{beam.get_tx.down.7.5}}</td> <td>{{beam.get_tx.down.7.6}}</td> <td>{{beam.get_tx.down.7.7}}</td>
513 </tr>
525 </tr>
514 </table>
526 </table>
515 </td>
527 </td>
516 </tr>
528 </tr>
517 </table>
529 </table>
518 </td>
530 </td>
519 </tr>
531 </tr>
520 </table>
532 </table>
521
533
522
534
523 <table class="abs_rx">
535 <table class="abs_rx">
524 <tr>
536 <tr>
525 <td> <b>RX</b>
537 <td> <b>RX</b>
526 <table id="rx_down" class="rx">
538 <table id="rx_down" class="rx">
527 <tr>
539 <tr>
528 <td> <b>North Quarter</b>
540 <td> <b>North Quarter</b>
529 <table align="center" class="north_quarter">
541 <table align="center" class="north_quarter">
530 <tr>
542 <tr>
531 <td>{{beam.get_rx.down.0.0}}</td> <td>{{beam.get_rx.down.0.1}}</td> <td>{{beam.get_rx.down.0.2}}</td> <td>{{beam.get_rx.down.0.3}}</td>
543 <td>{{beam.get_rx.down.0.0}}</td> <td>{{beam.get_rx.down.0.1}}</td> <td>{{beam.get_rx.down.0.2}}</td> <td>{{beam.get_rx.down.0.3}}</td>
532 </tr>
544 </tr>
533 <tr>
545 <tr>
534 <td>{{beam.get_rx.down.1.0}}</td> <td>{{beam.get_rx.down.1.1}}</td> <td>{{beam.get_rx.down.1.2}}</td> <td>{{beam.get_rx.down.1.3}}</td>
546 <td>{{beam.get_rx.down.1.0}}</td> <td>{{beam.get_rx.down.1.1}}</td> <td>{{beam.get_rx.down.1.2}}</td> <td>{{beam.get_rx.down.1.3}}</td>
535 </tr>
547 </tr>
536 <tr>
548 <tr>
537 <td>{{beam.get_rx.down.2.0}}</td> <td>{{beam.get_rx.down.2.1}}</td> <td>{{beam.get_rx.down.2.2}}</td> <td>{{beam.get_rx.down.2.3}}</td>
549 <td>{{beam.get_rx.down.2.0}}</td> <td>{{beam.get_rx.down.2.1}}</td> <td>{{beam.get_rx.down.2.2}}</td> <td>{{beam.get_rx.down.2.3}}</td>
538 </tr>
550 </tr>
539 <tr>
551 <tr>
540 <td>{{beam.get_rx.down.3.0}}</td> <td>{{beam.get_rx.down.3.1}}</td> <td>{{beam.get_rx.down.3.2}}</td> <td>{{beam.get_rx.down.3.3}}</td>
552 <td>{{beam.get_rx.down.3.0}}</td> <td>{{beam.get_rx.down.3.1}}</td> <td>{{beam.get_rx.down.3.2}}</td> <td>{{beam.get_rx.down.3.3}}</td>
541 </tr>
553 </tr>
542 </table>
554 </table>
543 </td>
555 </td>
544 <td> <b>East Quarter</b>
556 <td> <b>East Quarter</b>
545 <table align="center" class="east_quarter">
557 <table align="center" class="east_quarter">
546 <tr>
558 <tr>
547 <td>{{beam.get_rx.down.0.4}}</td> <td>{{beam.get_rx.down.0.5}}</td> <td>{{beam.get_rx.down.0.6}}</td> <td>{{beam.get_rx.down.0.7}}</td>
559 <td>{{beam.get_rx.down.0.4}}</td> <td>{{beam.get_rx.down.0.5}}</td> <td>{{beam.get_rx.down.0.6}}</td> <td>{{beam.get_rx.down.0.7}}</td>
548 </tr>
560 </tr>
549 <tr>
561 <tr>
550 <td>{{beam.get_rx.down.1.4}}</td> <td>{{beam.get_rx.down.1.5}}</td> <td>{{beam.get_rx.down.1.6}}</td> <td>{{beam.get_rx.down.1.7}}</td>
562 <td>{{beam.get_rx.down.1.4}}</td> <td>{{beam.get_rx.down.1.5}}</td> <td>{{beam.get_rx.down.1.6}}</td> <td>{{beam.get_rx.down.1.7}}</td>
551 </tr>
563 </tr>
552 <tr>
564 <tr>
553 <td>{{beam.get_rx.down.2.4}}</td> <td>{{beam.get_rx.down.2.5}}</td> <td>{{beam.get_rx.down.2.6}}</td> <td>{{beam.get_rx.down.2.7}}</td>
565 <td>{{beam.get_rx.down.2.4}}</td> <td>{{beam.get_rx.down.2.5}}</td> <td>{{beam.get_rx.down.2.6}}</td> <td>{{beam.get_rx.down.2.7}}</td>
554 </tr>
566 </tr>
555 <tr>
567 <tr>
556 <td>{{beam.get_rx.down.3.4}}</td> <td>{{beam.get_rx.down.3.5}}</td> <td>{{beam.get_rx.down.3.6}}</td> <td>{{beam.get_rx.down.3.7}}</td>
568 <td>{{beam.get_rx.down.3.4}}</td> <td>{{beam.get_rx.down.3.5}}</td> <td>{{beam.get_rx.down.3.6}}</td> <td>{{beam.get_rx.down.3.7}}</td>
557 </tr>
569 </tr>
558 </table>
570 </table>
559 </td>
571 </td>
560 </tr>
572 </tr>
561 <tr>
573 <tr>
562 <td> <b>West Quarter</b>
574 <td> <b>West Quarter</b>
563 <table align="center" class="west_quarter">
575 <table align="center" class="west_quarter">
564 <tr>
576 <tr>
565 <td>{{beam.get_rx.down.4.0}}</td> <td>{{beam.get_rx.down.4.1}}</td> <td>{{beam.get_rx.down.4.2}}</td> <td>{{beam.get_rx.down.4.3}}</td>
577 <td>{{beam.get_rx.down.4.0}}</td> <td>{{beam.get_rx.down.4.1}}</td> <td>{{beam.get_rx.down.4.2}}</td> <td>{{beam.get_rx.down.4.3}}</td>
566 </tr>
578 </tr>
567 <tr>
579 <tr>
568 <td>{{beam.get_rx.down.5.0}}</td> <td>{{beam.get_rx.down.5.1}}</td> <td>{{beam.get_rx.down.5.2}}</td> <td>{{beam.get_rx.down.5.3}}</td>
580 <td>{{beam.get_rx.down.5.0}}</td> <td>{{beam.get_rx.down.5.1}}</td> <td>{{beam.get_rx.down.5.2}}</td> <td>{{beam.get_rx.down.5.3}}</td>
569 </tr>
581 </tr>
570 <tr>
582 <tr>
571 <td>{{beam.get_rx.down.6.0}}</td> <td>{{beam.get_rx.down.6.1}}</td> <td>{{beam.get_rx.down.6.2}}</td> <td>{{beam.get_rx.down.6.3}}</td>
583 <td>{{beam.get_rx.down.6.0}}</td> <td>{{beam.get_rx.down.6.1}}</td> <td>{{beam.get_rx.down.6.2}}</td> <td>{{beam.get_rx.down.6.3}}</td>
572 </tr>
584 </tr>
573 <tr>
585 <tr>
574 <td>{{beam.get_rx.down.7.0}}</td> <td>{{beam.get_rx.down.7.1}}</td> <td>{{beam.get_rx.down.7.2}}</td> <td>{{beam.get_rx.down.7.3}}</td>
586 <td>{{beam.get_rx.down.7.0}}</td> <td>{{beam.get_rx.down.7.1}}</td> <td>{{beam.get_rx.down.7.2}}</td> <td>{{beam.get_rx.down.7.3}}</td>
575 </tr>
587 </tr>
576 </table>
588 </table>
577 </td>
589 </td>
578 <td> <b>South Quarter</b>
590 <td> <b>South Quarter</b>
579 <table class="south_quarter">
591 <table class="south_quarter">
580 <tr>
592 <tr>
581 <td>{{beam.get_rx.down.4.4}}</td> <td>{{beam.get_rx.down.4.5}}</td> <td>{{beam.get_rx.down.4.6}}</td> <td>{{beam.get_rx.down.4.7}}</td>
593 <td>{{beam.get_rx.down.4.4}}</td> <td>{{beam.get_rx.down.4.5}}</td> <td>{{beam.get_rx.down.4.6}}</td> <td>{{beam.get_rx.down.4.7}}</td>
582 </tr>
594 </tr>
583 <tr>
595 <tr>
584 <td>{{beam.get_rx.down.5.4}}</td> <td>{{beam.get_rx.down.5.5}}</td> <td>{{beam.get_rx.down.5.6}}</td> <td>{{beam.get_rx.down.5.7}}</td>
596 <td>{{beam.get_rx.down.5.4}}</td> <td>{{beam.get_rx.down.5.5}}</td> <td>{{beam.get_rx.down.5.6}}</td> <td>{{beam.get_rx.down.5.7}}</td>
585 </tr>
597 </tr>
586 <tr>
598 <tr>
587 <td>{{beam.get_rx.down.6.4}}</td> <td>{{beam.get_rx.down.6.5}}</td> <td>{{beam.get_rx.down.6.6}}</td> <td>{{beam.get_rx.down.6.7}}</td>
599 <td>{{beam.get_rx.down.6.4}}</td> <td>{{beam.get_rx.down.6.5}}</td> <td>{{beam.get_rx.down.6.6}}</td> <td>{{beam.get_rx.down.6.7}}</td>
588 </tr>
600 </tr>
589 <tr>
601 <tr>
590 <td>{{beam.get_rx.down.7.4}}</td> <td>{{beam.get_rx.down.7.5}}</td> <td>{{beam.get_rx.down.7.6}}</td> <td>{{beam.get_rx.down.7.7}}</td>
602 <td>{{beam.get_rx.down.7.4}}</td> <td>{{beam.get_rx.down.7.5}}</td> <td>{{beam.get_rx.down.7.6}}</td> <td>{{beam.get_rx.down.7.7}}</td>
591 </tr>
603 </tr>
592 </table>
604 </table>
593 </td>
605 </td>
594 </tr>
606 </tr>
595 </table>
607 </table>
596 </td>
608 </td>
597 </tr>
609 </tr>
598 </table>
610 </table>
599
611
600 {% if not edit %}
612 <table class="image_plot">
601 {% include "abs_downpattern_img.html" %}
613 <tr>
602 {% endif %}
614 <td>
615 {% if not edit %}
616 {% include "abs_downpattern_img.html" %}
617 {% endif %}
618 </td>
619 </tr>
620 </table>
603
621
604 <br>
622 <br>
605
623
606 <div id="down_ues" style="display: inline-block">
624 <div id="down_ues" style="display: inline-block">
607 Ues: {{beam.get_down_ues}}
625 Ues: {{beam.get_down_ues}}
608 </div>
626 </div>
609
627
610 <div style="margin-left: 70px; display: inline-block">
628 <div style="margin-left: 70px; display: inline-block">
611 <input type="checkbox" id="up_onlyrx" {% if beam.get_down_onlyrx == True %} checked="True" {% endif %} disabled>
629 <input type="checkbox" id="up_onlyrx" {% if beam.get_down_onlyrx == True %} checked="True" {% endif %} disabled>
612 Only RX
630 Only RX
613 </input>
631 </input>
614 </div>
632 </div>
615
633
616 </div>
634 </div>
617 </div>
635 </div>
618 </div>
636 </div>
619
637
620 {% endblock %}
638 {% endblock %}
621
639
622 <script>
640 <script>
623
641
624 </script>
642 </script>
@@ -1,48 +1,48
1 {% extends "dev_conf.html" %}
1 {% extends "dev_conf.html" %}
2 {% load static %}
2 {% load static %}
3 {% load django_bootstrap5 %}
3 {% load django_bootstrap5 %}
4 {% load main_tags %}
4 {% load main_tags %}
5
5
6 {% block content %}
6 {% block content %}
7
7
8 {% if abs_beams %}
8 {% if abs_beams %}
9 <div>
9 <div>
10 <h4>Beams:</h4>
10 <h4>Beams:</h4>
11
11
12 <div class="container">
12 <div class="container">
13 <div class="btn-group">
13 <div class="btn-group">
14 {% for abs_beam in abs_beams %}
14 {% for abs_beam in abs_beams %}
15 <button id="bt_beam{{ forloop.counter }}" type="button" class="btn btn-default">{{ forloop.counter }}</button>
15 <button id="bt_beam{{ forloop.counter }}" type="button" class="btn btn-default">{{ forloop.counter }}</button>
16 {% endfor %}
16 {% endfor %}
17 </div>
17 </div>
18 </div>
18 </div>
19
19
20
20
21 </div>
21 </div>
22 <br>
22 <br>
23
23
24 {% if beam %}
24 {% if beam %}
25 {% include "abs_pattern.html" %}
25 {% include "abs_pattern.html" %}
26 {% endif %}
26 {% endif %}
27
27
28 {% else %}
28 {% else %}
29 <div>
29 <div>
30 <h4>Beams:</h4>
30 <h4>Beams:</h4>
31 <p style="color:#b4bcc2; margin-left: 5%;"><i>No Beams...</i></p>
31 <p style="color:#b4bcc2; margin-left: 5%;"><i>No Beams...</i></p>
32 </div>
32 </div>
33 {% endif %}
33 {% endif %}
34
34
35
35
36 <script>
36 <script>
37 {% for abs_beam in abs_beams %}
37 {% for abs_beam in abs_beams %}
38 $("#bt_beam{{ forloop.counter }}").click(function() {
38 $("#bt_beam{{ forloop.counter }}").click(function() {
39 document.location = "{% url 'url_plot_abs_patterns' abs_beam.abs_conf.id abs_beam.id %}";
39 document.location = "{% url 'url_plot_abs_patterns2' abs_beam.abs_conf.id abs_beam.id %}";
40 });
40 });
41 {% endfor %}
41 {% endfor %}
42 //function ChangeColor() {
42 //function ChangeColor() {
43 // document.getElementById("button_1").style.backgroundColor = "#2c3e50";
43 // document.getElementById("button_1").style.backgroundColor = "#2c3e50";
44 // document.getElementById("button_1").style.color = "#ecf0f1";
44 // document.getElementById("button_1").style.color = "#ecf0f1";
45 //}
45 //}
46 </script>
46 </script>
47
47
48 {% endblock %}
48 {% endblock %}
@@ -1,11 +1,5
1 {% load static %}
1 {% load static %}
2 {% load django_bootstrap5 %}
2 {% load django_bootstrap5 %}
3 {% load main_tags %}
3 {% load main_tags %}
4
4
5 {% block content %}
5 <img id="imgMainUp" src="{% url 'url_plot_beam' beam.abs_conf.id beam.id 'up' %}" alt="Error ploting..." style="width: 250px;height:250px; background-image: url({% static 'images/loader.gif' %});background-repeat: no-repeat;background-position: 50% 50%;">
6
7 <div id="PictureOverJROUp" style="float: right">
8 <img id="imgMain" src="{% url 'url_plot_beam' beam.abs_conf.id beam.id 'up' %}" alt="Error ploting..." style="width:340px;height:340px; background-image: url({% static 'images/loader.gif' %});background-repeat: no-repeat;background-position: 50% 50%;">
9 </div>
10
11 {% endblock %}
@@ -1,18 +1,18
1 from django.urls import path
1 from django.urls import path
2
2
3 from apps.abs import views
3 from apps.abs import views
4
4
5 urlpatterns = (
5 urlpatterns = (
6 path('<int:id_conf>/', views.abs_conf, name='url_abs_conf'),
6 path('<int:id_conf>/', views.abs_conf, name='url_abs_conf'),
7 path('<int:id_conf>/edit/', views.abs_conf_edit, name='url_edit_abs_conf'),
7 path('<int:id_conf>/edit/', views.abs_conf_edit, name='url_edit_abs_conf'),
8 path('alert/', views.abs_conf_alert, name='url_alert_abs_conf'),
8 path('alert/', views.abs_conf_alert, name='url_alert_abs_conf'),
9 path('<int:id_conf>/import/', views.import_file, name='url_import_abs_conf'),
9 path('<int:id_conf>/import/', views.import_file, name='url_import_abs_conf'),
10 #url(r'^(?P<id_conf>-?\d+)/status/', views.abs_conf, {'status_request':True},name='url_status_abs_conf'),
10 #url(r'^(?P<id_conf>-?\d+)/status/', views.abs_conf, {'status_request':True},name='url_status_abs_conf'),
11 path('<int:id_conf>/change_beam/<int:id_beam>/', views.send_beam, name='url_send_beam'),
11 path('<int:id_conf>/change_beam/<int:id_beam>/', views.send_beam, name='url_send_beam'),
12 path('<int:id_conf>/plot/', views.plot_patterns, name='url_plot_abs_patterns'),
12 path('<int:id_conf>/plot/', views.plot_patterns, name='url_plot_abs_patterns'),
13 path('<int:id_conf>/plot/<int:id_beam>/', views.plot_patterns, name='url_plot_abs_patterns'),
13 path('<int:id_conf>/plot/<int:id_beam>/', views.plot_patterns, name='url_plot_abs_patterns2'),
14 path('<int:id_conf>/plot/<int:id_beam>/<int:antenna>/pattern.png', views.plot_pattern, name='url_plot_beam'),
14 path('<int:id_conf>/plot/<int:id_beam>/<slug:antenna>/pattern.png/', views.plot_pattern, name='url_plot_beam'),
15 path('<int:id_conf>/add_beam/', views.add_beam, name='url_add_abs_beam'),
15 path('<int:id_conf>/add_beam/', views.add_beam, name='url_add_abs_beam'),
16 path('<int:id_conf>/beam/<int:id_beam>/delete/', views.remove_beam, name='url_remove_abs_beam'),
16 path('<int:id_conf>/beam/<int:id_beam>/delete/', views.remove_beam, name='url_remove_abs_beam'),
17 path('<int:id_conf>/beam/<int:id_beam>/edit/', views.edit_beam, name='url_edit_abs_beam'),
17 path('<int:id_conf>/beam/<int:id_beam>/edit/', views.edit_beam, name='url_edit_abs_beam'),
18 )
18 )
@@ -1,620 +1,620
1 """
1 """
2 The module GRAPHICS_OVERJRO.py gathers classes or/and functions to create graphics from OVER-JRO
2 The module GRAPHICS_OVERJRO.py gathers classes or/and functions to create graphics from OVER-JRO
3 project (e.g. antenna patterns, skynoise, ...).
3 project (e.g. antenna patterns, skynoise, ...).
4
4
5 MODULES CALLED:
5 MODULES CALLED:
6 TIME, NUMPY, MATPLOTLIB, TIMETOOLS
6 TIME, NUMPY, MATPLOTLIB, TIMETOOLS
7
7
8 MODIFICATION HISTORY:
8 MODIFICATION HISTORY:
9 Created by Ing. Freddy Galindo (frederickgalindo@gmail.com). ROJ Oct 18, 2009.
9 Created by Ing. Freddy Galindo (frederickgalindo@gmail.com). ROJ Oct 18, 2009.
10 """
10 """
11
11
12 import time
12 import time
13 import numpy
13 import numpy
14 import sys
14 import sys
15 import os
15 import os
16
16
17 # set HOME environment variable to a directory the httpd server can write to
17 # set HOME environment variable to a directory the httpd server can write to
18 #os.environ[ 'HOME' ] = '/usr/local/www/htdocs/overJro/tempReports'
18 #os.environ[ 'HOME' ] = '/usr/local/www/htdocs/overJro/tempReports'
19 #os.environ[ 'HOME' ] = '/home/dsuarez/Pictures'
19 #os.environ[ 'HOME' ] = '/home/dsuarez/Pictures'
20 #os.environ[ 'HOME' ] = '/tmp/'
20 #os.environ[ 'HOME' ] = '/tmp/'
21 import matplotlib
21 import matplotlib
22 #if ide==1:
22 #if ide==1:
23 # matplotlib.use('Qt4Agg')
23 # matplotlib.use('Qt4Agg')
24 #elif ide==2:
24 #elif ide==2:
25 # matplotlib.use("Agg")
25 # matplotlib.use("Agg")
26 #else:
26 #else:
27 # matplotlib.use('TKAgg')
27 # matplotlib.use('TKAgg')
28 matplotlib.use("Agg")
28 matplotlib.use("Agg")
29 #matplotlib.interactive(1)
29 #matplotlib.interactive(1)
30 import matplotlib.pyplot
30 import matplotlib.pyplot
31 #import Numeric
31 #import Numeric
32 #import scipy
32 #import scipy
33 import scipy.interpolate
33 import scipy.interpolate
34
34
35 from .Astro_Coords import Equatorial , CelestialBodies
35 from .Astro_Coords import Equatorial , CelestialBodies
36 from .TimeTools import Time , Julian
36 from .TimeTools import Time , Julian
37 from .Graphics_Miscens import ColorTable
37 from .Graphics_Miscens import ColorTable
38 from .Misc_Routines import CoFactors,Vector
38 from .Misc_Routines import CoFactors,Vector
39
39
40 class AntPatternPlot:
40 class AntPatternPlot:
41 def __init__(self):
41 def __init__(self):
42 """
42 """
43 AntPatternPlot creates an object to call methods to plot the antenna pattern.
43 AntPatternPlot creates an object to call methods to plot the antenna pattern.
44
44
45 Modification History
45 Modification History
46 --------------------
46 --------------------
47 Created by Freddy Galindo, ROJ, 06 October 2009.
47 Created by Freddy Galindo, ROJ, 06 October 2009.
48 """
48 """
49
49
50 self.fig = matplotlib.pyplot.figure(figsize=(8,8), facecolor='white')
50 self.fig = matplotlib.pyplot.figure(figsize=(8,8), facecolor='white')
51 self.ax = self.fig.add_subplot(111)
51 self.ax = self.fig.add_subplot(111)
52
52
53 def contPattern(self,iplot=0,gpath='',filename='',mesg='',amp=None ,x=None ,y=None ,getCut=None,title='', save=True):
53 def contPattern(self,iplot=0,gpath='',filename='',mesg='',amp=None ,x=None ,y=None ,getCut=None,title='', save=True):
54 """
54 """
55 contPattern plots a contour map of the antenna pattern.
55 contPattern plots a contour map of the antenna pattern.
56
56
57 Parameters
57 Parameters
58 ----------
58 ----------
59 iplot = A integer to specify if the plot is the first, second, ... The default va-
59 iplot = A integer to specify if the plot is the first, second, ... The default va-
60 lue is 0.
60 lue is 0.
61
61
62 Examples
62 Examples
63 --------
63 --------
64 >> Over_Jro.JroPattern(pattern=2).contPattern()
64 >> Over_Jro.JroPattern(pattern=2).contPattern()
65
65
66 Modification history
66 Modification history
67 --------------------
67 --------------------
68 Converted to Python by Freddy R. Galindo, ROJ, 06 October 2009.
68 Converted to Python by Freddy R. Galindo, ROJ, 06 October 2009.
69 """
69 """
70
70
71 if getCut == 1:
71 if getCut == 1:
72 return
72 return
73
73
74 xmax = numpy.max(x)
74 xmax = numpy.max(x)
75 xmin = numpy.min(x)
75 xmin = numpy.min(x)
76 ymax = numpy.max(y)
76 ymax = numpy.max(y)
77 ymin = numpy.min(y)
77 ymin = numpy.min(y)
78
78
79 levels = numpy.array([1e-3,1e-2,1e-1,0.5,1.0])
79 levels = numpy.array([1e-3,1e-2,1e-1,0.5,1.0])
80 tmp = numpy.round(10*numpy.log10(levels),decimals=1)
80 tmp = numpy.round(10*numpy.log10(levels),decimals=1)
81 labels = []
81 labels = []
82 for i in numpy.arange(5):labels.append(str(numpy.int(tmp[i])))
82 for i in numpy.arange(5):labels.append(str(int(tmp[i])))
83
83
84
84
85 colors = ((0,0,1.),(0,170/255.,0),(127/255.,1.,0),(1.,109/255.,0),(128/255.,0,0))
85 colors = ((0,0,1.),(0,170/255.,0),(127/255.,1.,0),(1.,109/255.,0),(128/255.,0,0))
86 CS = self.ax.contour(x,y,amp.transpose(),levels,colors=colors)
86 CS = self.ax.contour(x,y,amp.transpose(),levels,colors=colors)
87 fmt = {}
87 fmt = {}
88 for l,s in zip(CS.levels,labels):
88 for l,s in zip(CS.levels,labels):
89 fmt[l] = s
89 fmt[l] = s
90
90
91 self.ax.annotate('Ng',xy=(-0.05,1.04),xytext=(0.01,0.962),xycoords='axes fraction',arrowprops=dict(facecolor='black', width=1.,shrink=0.2),fontsize=15.)
91 self.ax.annotate('Ng',xy=(-0.05,1.04),xytext=(0.01,0.962),xycoords='axes fraction',arrowprops=dict(facecolor='black', width=1.,shrink=0.2),fontsize=15.)
92 self.ax.annotate(mesg,xy=(0,0),xytext=(0.01,0.01),xycoords='figure fraction')
92 self.ax.annotate(mesg,xy=(0,0),xytext=(0.01,0.01),xycoords='figure fraction')
93 self.ax.clabel(CS,CS.levels,inline=True,fmt=fmt,fontsize=10)
93 self.ax.clabel(CS,CS.levels,inline=True,fmt=fmt,fontsize=10)
94 self.ax.set_xlim(xmin,xmax)
94 self.ax.set_xlim(xmin,xmax)
95 self.ax.set_ylim(ymin,ymax)
95 self.ax.set_ylim(ymin,ymax)
96 self.ax.set_title("Total Pattern: " + title)
96 self.ax.set_title("Total Pattern: " + title)
97 self.ax.set_xlabel("West to South")
97 self.ax.set_xlabel("West to South")
98 self.ax.set_ylabel("West to North")
98 self.ax.set_ylabel("West to North")
99 self.ax.grid(True)
99 self.ax.grid(True)
100
100
101 if save:
101 if save:
102 save_fig = os.path.join(gpath,filename)
102 save_fig = os.path.join(gpath,filename)
103 self.fig.savefig(save_fig,format='png')
103 self.fig.savefig(save_fig,format='png')
104
104
105
105
106
106
107 def close(self):
107 def close(self):
108
108
109 matplotlib.pyplot.close(self.fig)
109 matplotlib.pyplot.close(self.fig)
110
110
111 def plotRaDec(self,gpath=None,filename=None,jd=2452640.5,ra_obs=None,xg=None,yg=None,x=None,y=None, save=True):
111 def plotRaDec(self,gpath=None,filename=None,jd=2452640.5,ra_obs=None,xg=None,yg=None,x=None,y=None, save=True):
112 """
112 """
113 plotRaDec draws right ascension and declination lines on a JRO plane. This function
113 plotRaDec draws right ascension and declination lines on a JRO plane. This function
114 must call after conPattern.
114 must call after conPattern.
115
115
116 Parameters
116 Parameters
117 ----------
117 ----------
118 jd = A scalar giving the Julian date.
118 jd = A scalar giving the Julian date.
119 ra_obs = Scalar giving the right ascension of the observatory.
119 ra_obs = Scalar giving the right ascension of the observatory.
120 xg = A 3-element array to specify ..
120 xg = A 3-element array to specify ..
121 yg = A 3-element array to specify ..
121 yg = A 3-element array to specify ..
122
122
123 Examples
123 Examples
124 --------
124 --------
125 >> Over_Jro.JroPattern(pattern=2).contPattern()
125 >> Over_Jro.JroPattern(pattern=2).contPattern()
126 >> Over_Jro.JroPattern(pattern=2).plotRaDec(jd=jd,ra_obs=ra_obs,xg=xg,yg=yg)
126 >> Over_Jro.JroPattern(pattern=2).plotRaDec(jd=jd,ra_obs=ra_obs,xg=xg,yg=yg)
127
127
128 Modification history
128 Modification history
129 --------------------
129 --------------------
130 Converted to Python by Freddy R. Galindo, ROJ, 06 October 2009.
130 Converted to Python by Freddy R. Galindo, ROJ, 06 October 2009.
131 """
131 """
132
132
133 # Finding RA of observatory for a specific date
133 # Finding RA of observatory for a specific date
134 if ra_obs is None:ra_obs = numpy.array([23.37060849])
134 if ra_obs is None:ra_obs = numpy.array([23.37060849])
135 if xg is None:xg = numpy.array([0.62918474,-0.77725579,0.])
135 if xg is None:xg = numpy.array([0.62918474,-0.77725579,0.])
136 if yg is None:yg = numpy.array([0.77700346,0.62898048,0.02547905])
136 if yg is None:yg = numpy.array([0.77700346,0.62898048,0.02547905])
137
137
138 # Getting HA and DEC axes
138 # Getting HA and DEC axes
139 mindec = -28; maxdec = 4; incdec = 2.
139 mindec = -28; maxdec = 4; incdec = 2.
140 ndec = numpy.int((maxdec - mindec)/incdec) + 1
140 ndec = int((maxdec - mindec)/incdec) + 1
141
141
142 minha = -20; maxha = 20; incha = 2.
142 minha = -20; maxha = 20; incha = 2.
143 nha = numpy.int((maxha - minha)/incha) + 1
143 nha = int((maxha - minha)/incha) + 1
144
144
145 #mcosx = numpy.zeros((nha,ndec))
145 #mcosx = numpy.zeros((nha,ndec))
146 #mcosy = numpy.zeros((nha,ndec))
146 #mcosy = numpy.zeros((nha,ndec))
147
147
148 ha_axes = numpy.reshape(numpy.arange(nha)*incha + minha,(nha,1))
148 ha_axes = numpy.reshape(numpy.arange(nha)*incha + minha,(nha,1))
149 ones_dec = numpy.reshape(numpy.zeros(ndec) + 1,(ndec,1))
149 ones_dec = numpy.reshape(numpy.zeros(ndec) + 1,(ndec,1))
150 ha_axes = numpy.dot(ha_axes,ones_dec.transpose())
150 ha_axes = numpy.dot(ha_axes,ones_dec.transpose())
151 ha_axes2 = numpy.array(ra_obs - ha_axes)
151 ha_axes2 = numpy.array(ra_obs - ha_axes)
152
152
153 dec_axes = numpy.reshape(numpy.arange(ndec)*incdec + mindec,(ndec,1))
153 dec_axes = numpy.reshape(numpy.arange(ndec)*incdec + mindec,(ndec,1))
154 ones_ra = numpy.reshape(numpy.zeros(nha) + 1,(nha,1))
154 ones_ra = numpy.reshape(numpy.zeros(nha) + 1,(nha,1))
155 dec_axes = numpy.dot(ones_ra,dec_axes.transpose())
155 dec_axes = numpy.dot(ones_ra,dec_axes.transpose())
156 dec_axes2 = numpy.array(dec_axes)
156 dec_axes2 = numpy.array(dec_axes)
157
157
158 ObjHor = Equatorial(ha_axes2,dec_axes2,jd)
158 ObjHor = Equatorial(ha_axes2,dec_axes2,jd)
159 [alt,az,ha] = ObjHor.change2AltAz()
159 [alt,az,ha] = ObjHor.change2AltAz()
160
160
161 z = numpy.transpose(alt)*CoFactors.d2r ; z = z.flatten()
161 z = numpy.transpose(alt)*CoFactors.d2r ; z = z.flatten()
162 az = numpy.transpose(az)*CoFactors.d2r ; az = az.flatten()
162 az = numpy.transpose(az)*CoFactors.d2r ; az = az.flatten()
163
163
164 vect = numpy.array([numpy.cos(z)*numpy.sin(az),numpy.cos(z)*numpy.cos(az),numpy.sin(z)])
164 vect = numpy.array([numpy.cos(z)*numpy.sin(az),numpy.cos(z)*numpy.cos(az),numpy.sin(z)])
165
165
166 xg = numpy.atleast_2d(xg)
166 xg = numpy.atleast_2d(xg)
167 dcosx = numpy.array(numpy.dot(xg,vect))
167 dcosx = numpy.array(numpy.dot(xg,vect))
168 yg = numpy.atleast_2d(yg)
168 yg = numpy.atleast_2d(yg)
169 dcosy = numpy.array(numpy.dot(yg,vect))
169 dcosy = numpy.array(numpy.dot(yg,vect))
170
170
171 mcosx = dcosx.reshape(ndec,nha)
171 mcosx = dcosx.reshape(ndec,nha)
172 mcosy = dcosy.reshape(ndec,nha)
172 mcosy = dcosy.reshape(ndec,nha)
173
173
174 # Defining NAN for points outof limits.
174 # Defining NAN for points outof limits.
175 xmax = numpy.max(x)
175 xmax = numpy.max(x)
176 xmin = numpy.min(x)
176 xmin = numpy.min(x)
177 ymax = numpy.max(y)
177 ymax = numpy.max(y)
178 ymin = numpy.min(y)
178 ymin = numpy.min(y)
179
179
180 factor = 1.3
180 factor = 1.3
181 noval = numpy.where((mcosx>(xmax*factor)) | (mcosx<(xmin*factor)))
181 noval = numpy.where((mcosx>(xmax*factor)) | (mcosx<(xmin*factor)))
182 if noval[0].size>0:mcosx[noval] = numpy.nan
182 if noval[0].size>0:mcosx[noval] = numpy.nan
183 noval = numpy.where((mcosy>(ymax*factor)) | (mcosy<(ymin*factor)))
183 noval = numpy.where((mcosy>(ymax*factor)) | (mcosy<(ymin*factor)))
184 if noval[0].size>0:mcosy[noval] = numpy.nan
184 if noval[0].size>0:mcosy[noval] = numpy.nan
185
185
186 # Plotting HA and declination grid.
186 # Plotting HA and declination grid.
187 iha0 = numpy.int((0 - minha)/incha)
187 iha0 = int((0 - minha)/incha)
188 idec0 = numpy.int((-14 - mindec)/incdec)
188 idec0 = int((-14 - mindec)/incdec)
189
189
190 colorgrid = (1.,109/255.,0)
190 colorgrid = (1.,109/255.,0)
191 self.ax.plot(mcosx.transpose(),mcosy.transpose(),color=colorgrid,linestyle='--')
191 self.ax.plot(mcosx.transpose(),mcosy.transpose(),color=colorgrid,linestyle='--')
192 for idec in numpy.arange(ndec):
192 for idec in numpy.arange(ndec):
193 if idec != idec0:
193 if idec != idec0:
194 valx = (mcosx[idec,iha0]<=xmax) & (mcosx[idec,iha0]>=xmin)
194 valx = (mcosx[idec,iha0]<=xmax) & (mcosx[idec,iha0]>=xmin)
195 valy = (mcosy[idec,iha0]<=ymax) & (mcosy[idec,iha0]>=ymin)
195 valy = (mcosy[idec,iha0]<=ymax) & (mcosy[idec,iha0]>=ymin)
196 if valx & valy:
196 if valx & valy:
197 text = str(numpy.int(mindec + incdec*idec))+'$^o$'
197 text = str(int(mindec + incdec*idec))+'$^o$'
198 self.ax.text(mcosx[idec,iha0],mcosy[idec,iha0],text)
198 self.ax.text(mcosx[idec,iha0],mcosy[idec,iha0],text)
199
199
200 matplotlib.pyplot.plot(mcosx,mcosy,color=colorgrid,linestyle='--')
200 matplotlib.pyplot.plot(mcosx,mcosy,color=colorgrid,linestyle='--')
201 for iha in numpy.arange(nha):
201 for iha in numpy.arange(nha):
202 if iha != iha0:
202 if iha != iha0:
203 valx = (mcosx[idec0,iha]<=xmax) & (mcosx[idec0,iha]>=xmin)
203 valx = (mcosx[idec0,iha]<=xmax) & (mcosx[idec0,iha]>=xmin)
204 valy = (mcosy[idec0,iha]<=ymax) & (mcosy[idec0,iha]>=ymin)
204 valy = (mcosy[idec0,iha]<=ymax) & (mcosy[idec0,iha]>=ymin)
205 if valx & valy:
205 if valx & valy:
206 text = str(4*numpy.int(minha + incha*iha))+"'"
206 text = str(4*int(minha + incha*iha))+"'"
207 self.ax.text(mcosx[idec0,iha],mcosy[idec0,iha],text)
207 self.ax.text(mcosx[idec0,iha],mcosy[idec0,iha],text)
208
208
209 if save:
209 if save:
210 save_fig = os.path.join(gpath,filename)
210 save_fig = os.path.join(gpath,filename)
211 matplotlib.pyplot.savefig(save_fig,format='png')
211 matplotlib.pyplot.savefig(save_fig,format='png')
212
212
213
213
214 def plotBField(self,gpath,filename,dcos,alpha, nlon, nlat, dcosxrange, dcosyrange, heights, alpha_i, save=True):
214 def plotBField(self,gpath,filename,dcos,alpha, nlon, nlat, dcosxrange, dcosyrange, heights, alpha_i, save=True):
215 """
215 """
216 plotBField draws the magnetic field in a directional cosines plot.
216 plotBField draws the magnetic field in a directional cosines plot.
217
217
218 Parameters
218 Parameters
219 ----------
219 ----------
220 dcos = An 4-dimensional array giving the directional cosines of the magnetic field
220 dcos = An 4-dimensional array giving the directional cosines of the magnetic field
221 over the desired place.
221 over the desired place.
222 alpha = An 3-dimensional array giving the angle of the magnetic field over the desi-
222 alpha = An 3-dimensional array giving the angle of the magnetic field over the desi-
223 red place.
223 red place.
224 nlon = An integer to specify the number of elements per longitude.
224 nlon = An integer to specify the number of elements per longitude.
225 nlat = An integer to specify the number of elements per latitude.
225 nlat = An integer to specify the number of elements per latitude.
226 dcosxrange = A 2-element array giving the range of the directional cosines in the
226 dcosxrange = A 2-element array giving the range of the directional cosines in the
227 "x" axis.
227 "x" axis.
228 dcosyrange = A 2-element array giving the range of the directional cosines in the
228 dcosyrange = A 2-element array giving the range of the directional cosines in the
229 "y" axis.
229 "y" axis.
230 heights = An array giving the heights (km) where the magnetic field will be modeled By default the magnetic field will be computed at 100, 500 and 1000km.
230 heights = An array giving the heights (km) where the magnetic field will be modeled By default the magnetic field will be computed at 100, 500 and 1000km.
231 alpha_i = Angle to interpolate the magnetic field.
231 alpha_i = Angle to interpolate the magnetic field.
232 Modification History
232 Modification History
233 --------------------
233 --------------------
234 Converted to Python by Freddy R. Galindo, ROJ, 07 October 2009.
234 Converted to Python by Freddy R. Galindo, ROJ, 07 October 2009.
235 """
235 """
236
236
237 handles = []
237 handles = []
238 objects = []
238 objects = []
239 colors = ['k','m','c','b','g','r','y']
239 colors = ['k','m','c','b','g','r','y']
240 marker = ['-+','-*','-D','-x','-s','->','-o','-^']
240 marker = ['-+','-*','-D','-x','-s','->','-o','-^']
241
241
242 alpha_location = numpy.zeros((nlon,2,heights.size))
242 alpha_location = numpy.zeros((nlon,2,heights.size))
243
243
244 for ih in numpy.arange(heights.size):
244 for ih in numpy.arange(heights.size):
245 alpha_location[:,0,ih] = dcos[:,0,ih,0]
245 alpha_location[:,0,ih] = dcos[:,0,ih,0]
246 for ilon in numpy.arange(nlon):
246 for ilon in numpy.arange(nlon):
247 myx = (alpha[ilon,:,ih])[::-1]
247 myx = (alpha[ilon,:,ih])[::-1]
248 myy = (dcos[ilon,:,ih,0])[::-1]
248 myy = (dcos[ilon,:,ih,0])[::-1]
249 tck = scipy.interpolate.splrep(myx,myy,s=0)
249 tck = scipy.interpolate.splrep(myx,myy,s=0)
250 mydcosx = scipy.interpolate.splev(alpha_i,tck,der=0)
250 mydcosx = scipy.interpolate.splev(alpha_i,tck,der=0)
251
251
252 myx = (alpha[ilon,:,ih])[::-1]
252 myx = (alpha[ilon,:,ih])[::-1]
253 myy = (dcos[ilon,:,ih,1])[::-1]
253 myy = (dcos[ilon,:,ih,1])[::-1]
254 tck = scipy.interpolate.splrep(myx,myy,s=0)
254 tck = scipy.interpolate.splrep(myx,myy,s=0)
255 mydcosy = scipy.interpolate.splev(alpha_i,tck,der=0)
255 mydcosy = scipy.interpolate.splev(alpha_i,tck,der=0)
256 alpha_location[ilon,:,ih] = numpy.array([mydcosx, mydcosy])
256 alpha_location[ilon,:,ih] = numpy.array([mydcosx, mydcosy])
257
257
258
258
259 ObjFig, = self.ax.plot(alpha_location[:,0,ih],alpha_location[:,1,ih],
259 ObjFig, = self.ax.plot(alpha_location[:,0,ih],alpha_location[:,1,ih],
260 marker[ih % 8],color=colors[numpy.int(ih/8)],ms=4.5,lw=0.5)
260 marker[ih % 8],color=colors[int(ih/8)],ms=4.5,lw=0.5)
261 handles.append(ObjFig)
261 handles.append(ObjFig)
262 objects.append(numpy.str(heights[ih]) + ' km')
262 objects.append(str(heights[ih]) + ' km')
263
263
264 self.ax.legend(handles,objects,loc="lower right", numpoints=1, handlelength=0.3,
264 self.ax.legend(handles,objects,loc="lower right", numpoints=1, handlelength=0.3,
265 handletextpad=0.02, borderpad=0.3, labelspacing=0.1)
265 handletextpad=0.02, borderpad=0.3, labelspacing=0.1)
266
266
267 if save:
267 if save:
268 save_fig = os.path.join(gpath,filename)
268 save_fig = os.path.join(gpath,filename)
269 matplotlib.pyplot.savefig(save_fig,format='png')
269 matplotlib.pyplot.savefig(save_fig,format='png')
270
270
271
271
272
272
273 class BFieldPlot:
273 class BFieldPlot:
274 def __init__(self):
274 def __init__(self):
275 """
275 """
276 BFieldPlot creates an object for drawing magnetic Field lines over Jicamarca.
276 BFieldPlot creates an object for drawing magnetic Field lines over Jicamarca.
277
277
278 Modification History
278 Modification History
279 --------------------
279 --------------------
280 Created by Freddy Galindo, ROJ, 07 October 2009.
280 Created by Freddy Galindo, ROJ, 07 October 2009.
281 """
281 """
282
282
283 self.alpha_location = 1
283 self.alpha_location = 1
284 # pass
284 # pass
285
285
286 def plotBField(self,gpath,filename,dcos,alpha, nlon, nlat, dcosxrange, dcosyrange, heights, alpha_i):
286 def plotBField(self,gpath,filename,dcos,alpha, nlon, nlat, dcosxrange, dcosyrange, heights, alpha_i):
287 """
287 """
288 plotBField draws the magnetic field in a directional cosines plot.
288 plotBField draws the magnetic field in a directional cosines plot.
289
289
290 Parameters
290 Parameters
291 ----------
291 ----------
292 dcos = An 4-dimensional array giving the directional cosines of the magnetic field
292 dcos = An 4-dimensional array giving the directional cosines of the magnetic field
293 over the desired place.
293 over the desired place.
294 alpha = An 3-dimensional array giving the angle of the magnetic field over the desi-
294 alpha = An 3-dimensional array giving the angle of the magnetic field over the desi-
295 red place.
295 red place.
296 nlon = An integer to specify the number of elements per longitude.
296 nlon = An integer to specify the number of elements per longitude.
297 nlat = An integer to specify the number of elements per latitude.
297 nlat = An integer to specify the number of elements per latitude.
298 dcosxrange = A 2-element array giving the range of the directional cosines in the
298 dcosxrange = A 2-element array giving the range of the directional cosines in the
299 "x" axis.
299 "x" axis.
300 dcosyrange = A 2-element array giving the range of the directional cosines in the
300 dcosyrange = A 2-element array giving the range of the directional cosines in the
301 "y" axis.
301 "y" axis.
302 heights = An array giving the heights (km) where the magnetic field will be modeled By default the magnetic field will be computed at 100, 500 and 1000km.
302 heights = An array giving the heights (km) where the magnetic field will be modeled By default the magnetic field will be computed at 100, 500 and 1000km.
303 alpha_i = Angle to interpolate the magnetic field.
303 alpha_i = Angle to interpolate the magnetic field.
304 Modification History
304 Modification History
305 --------------------
305 --------------------
306 Converted to Python by Freddy R. Galindo, ROJ, 07 October 2009.
306 Converted to Python by Freddy R. Galindo, ROJ, 07 October 2009.
307 """
307 """
308
308
309 handles = []
309 handles = []
310 objects = []
310 objects = []
311 colors = ['k','m','c','b','g','r','y']
311 colors = ['k','m','c','b','g','r','y']
312 marker = ['-+','-*','-D','-x','-s','->','-o','-^']
312 marker = ['-+','-*','-D','-x','-s','->','-o','-^']
313
313
314 alpha_location = numpy.zeros((nlon,2,heights.size))
314 alpha_location = numpy.zeros((nlon,2,heights.size))
315
315
316 for ih in numpy.arange(heights.size):
316 for ih in numpy.arange(heights.size):
317 alpha_location[:,0,ih] = dcos[:,0,ih,0]
317 alpha_location[:,0,ih] = dcos[:,0,ih,0]
318 for ilon in numpy.arange(nlon):
318 for ilon in numpy.arange(nlon):
319 myx = (alpha[ilon,:,ih])[::-1]
319 myx = (alpha[ilon,:,ih])[::-1]
320 myy = (dcos[ilon,:,ih,0])[::-1]
320 myy = (dcos[ilon,:,ih,0])[::-1]
321 tck = scipy.interpolate.splrep(myx,myy,s=0)
321 tck = scipy.interpolate.splrep(myx,myy,s=0)
322 mydcosx = scipy.interpolate.splev(alpha_i,tck,der=0)
322 mydcosx = scipy.interpolate.splev(alpha_i,tck,der=0)
323
323
324 myx = (alpha[ilon,:,ih])[::-1]
324 myx = (alpha[ilon,:,ih])[::-1]
325 myy = (dcos[ilon,:,ih,1])[::-1]
325 myy = (dcos[ilon,:,ih,1])[::-1]
326 tck = scipy.interpolate.splrep(myx,myy,s=0)
326 tck = scipy.interpolate.splrep(myx,myy,s=0)
327 mydcosy = scipy.interpolate.splev(alpha_i,tck,der=0)
327 mydcosy = scipy.interpolate.splev(alpha_i,tck,der=0)
328 alpha_location[ilon,:,ih] = numpy.array([mydcosx, mydcosy])
328 alpha_location[ilon,:,ih] = numpy.array([mydcosx, mydcosy])
329
329
330
330
331 ObjFig, = matplotlib.pyplot.plot(alpha_location[:,0,ih],alpha_location[:,1,ih], \
331 ObjFig, = matplotlib.pyplot.plot(alpha_location[:,0,ih],alpha_location[:,1,ih], \
332 marker[ih % 8],color=colors[numpy.int(ih/8)],ms=4.5,lw=0.5)
332 marker[ih % 8],color=colors[int(ih/8)],ms=4.5,lw=0.5)
333 handles.append(ObjFig)
333 handles.append(ObjFig)
334 objects.append(numpy.str(heights[ih]) + ' km')
334 objects.append(str(heights[ih]) + ' km')
335
335
336 matplotlib.pyplot.xlim(dcosxrange[0],dcosxrange[1])
336 matplotlib.pyplot.xlim(dcosxrange[0],dcosxrange[1])
337 matplotlib.pyplot.ylim(dcosyrange[0],dcosyrange[1])
337 matplotlib.pyplot.ylim(dcosyrange[0],dcosyrange[1])
338
338
339 try:
339 try:
340 ObjlegB = matplotlib.pyplot.legend(handles,objects,loc="lower right", numpoints=1, handlelength=0.3, \
340 ObjlegB = matplotlib.pyplot.legend(handles,objects,loc="lower right", numpoints=1, handlelength=0.3, \
341 handletextpad=0.02, borderpad=0.3, labelspacing=0.1)
341 handletextpad=0.02, borderpad=0.3, labelspacing=0.1)
342 except:
342 except:
343 ObjlegB = matplotlib.pyplot.legend(handles,objects,loc=[0.01,0.75], numpoints=1, handlelength=0, \
343 ObjlegB = matplotlib.pyplot.legend(handles,objects,loc=[0.01,0.75], numpoints=1, handlelength=0, \
344 pad=0.015, handletextsep=0.02,labelsep=0.01)
344 pad=0.015, handletextsep=0.02,labelsep=0.01)
345
345
346 matplotlib.pyplot.setp(ObjlegB.get_texts(),fontsize='small')
346 matplotlib.pyplot.setp(ObjlegB.get_texts(),fontsize='small')
347 matplotlib.pyplot.gca().add_artist(ObjlegB)
347 matplotlib.pyplot.gca().add_artist(ObjlegB)
348
348
349 save_fig = os.path.join(gpath,filename)
349 save_fig = os.path.join(gpath,filename)
350 matplotlib.pyplot.savefig(save_fig,format='png')
350 matplotlib.pyplot.savefig(save_fig,format='png')
351 self.alpha_location = alpha_location
351 self.alpha_location = alpha_location
352
352
353
353
354 class CelestialObjectsPlot:
354 class CelestialObjectsPlot:
355 def __init__(self,jd,dec,tod,maxha_min,show_object=None):
355 def __init__(self,jd,dec,tod,maxha_min,show_object=None):
356
356
357 self.jd = jd
357 self.jd = jd
358 self.dec = dec
358 self.dec = dec
359 self.tod = tod
359 self.tod = tod
360 self.maxha_min = maxha_min
360 self.maxha_min = maxha_min
361
361
362 if show_object==None:show_object=numpy.zeros(4)+2
362 if show_object==None:show_object=numpy.zeros(4)+2
363 self.show_object = show_object
363 self.show_object = show_object
364
364
365 self.dcosx_sun = 1
365 self.dcosx_sun = 1
366 self.dcosy_sun = 1
366 self.dcosy_sun = 1
367 self.ha_sun = 1
367 self.ha_sun = 1
368 self.time_sun = 1
368 self.time_sun = 1
369
369
370 self.dcosx_moon = 1
370 self.dcosx_moon = 1
371 self.dcosy_moon = 1
371 self.dcosy_moon = 1
372 self.ha_moon = 1
372 self.ha_moon = 1
373 self.time_moon = 1
373 self.time_moon = 1
374
374
375 self.dcosx_hydra = 1
375 self.dcosx_hydra = 1
376 self.dcosy_hydra = 1
376 self.dcosy_hydra = 1
377 self.ha_hydra = 1
377 self.ha_hydra = 1
378 self.time_hydra = 1
378 self.time_hydra = 1
379
379
380 self.dcosx_galaxy = 1
380 self.dcosx_galaxy = 1
381 self.dcosy_galaxy = 1
381 self.dcosy_galaxy = 1
382 self.ha_galaxy = 1
382 self.ha_galaxy = 1
383 self.time_galaxy = 1
383 self.time_galaxy = 1
384
384
385 def drawObject(self,glat,glon,xg,yg,dcosxrange,dcosyrange,gpath='',filename=''):
385 def drawObject(self,glat,glon,xg,yg,dcosxrange,dcosyrange,gpath='',filename=''):
386
386
387 jd = self.jd
387 jd = self.jd
388 main_dec = self.dec
388 main_dec = self.dec
389 tod = self.tod
389 tod = self.tod
390 maxha_min = self.maxha_min
390 maxha_min = self.maxha_min
391
391
392 mesg = "Drawing celestial objects over Observatory"
392 mesg = "Drawing celestial objects over Observatory"
393 # print mesg
393 # print mesg
394 # if textid!=None:textid.append(mesg)
394 # if textid!=None:textid.append(mesg)
395
395
396 maxlev = 24; minlev = 0; maxcol = 39; mincol = 10
396 maxlev = 24; minlev = 0; maxcol = 39; mincol = 10
397 handles = []
397 handles = []
398 objects = ['$Sun$','$Moon$','$Hydra$','$Galaxy$']
398 objects = ['$Sun$','$Moon$','$Hydra$','$Galaxy$']
399 marker = ['--^','--s','--*','--o']
399 marker = ['--^','--s','--*','--o']
400
400
401 # Getting RGB table to plot celestial object over Jicamarca
401 # Getting RGB table to plot celestial object over Jicamarca
402 colortable = ColorTable(table=1).readTable()
402 colortable = ColorTable(table=1).readTable()
403
403
404 for io in (numpy.arange(4)+1):
404 for io in (numpy.arange(4)+1):
405 if self.show_object[io]!=0:
405 if self.show_object[io]!=0:
406 ObjBodies = CelestialBodies()
406 ObjBodies = CelestialBodies()
407 if io==1:
407 if io==1:
408 [ra,dec,sunlon,sunobliq] = ObjBodies.sunpos(jd)
408 [ra,dec,sunlon,sunobliq] = ObjBodies.sunpos(jd)
409 elif io==2:
409 elif io==2:
410 [ra,dec,dist,moonlon,moonlat] = ObjBodies.moonpos(jd)
410 [ra,dec,dist,moonlon,moonlat] = ObjBodies.moonpos(jd)
411 elif io==3:
411 elif io==3:
412 [ra,dec] = ObjBodies.hydrapos()
412 [ra,dec] = ObjBodies.hydrapos()
413 elif io==4:
413 elif io==4:
414 [maxra,ra] = ObjBodies.skynoise_jro(dec_cut=main_dec)
414 [maxra,ra] = ObjBodies.skynoise_jro(dec_cut=main_dec)
415 ra = maxra*15.
415 ra = maxra*15.
416 dec = main_dec
416 dec = main_dec
417
417
418 ObjEq = Equatorial(ra,dec,jd,lat=glat,lon=glon)
418 ObjEq = Equatorial(ra,dec,jd,lat=glat,lon=glon)
419 [alt, az, ha] = ObjEq.change2AltAz()
419 [alt, az, ha] = ObjEq.change2AltAz()
420 vect = numpy.array([az,alt]).transpose()
420 vect = numpy.array([az,alt]).transpose()
421 vect = Vector(vect,direction=0).Polar2Rect()
421 vect = Vector(vect,direction=0).Polar2Rect()
422
422
423 dcosx = numpy.array(numpy.dot(vect,xg))
423 dcosx = numpy.array(numpy.dot(vect,xg))
424 dcosy = numpy.array(numpy.dot(vect,yg))
424 dcosy = numpy.array(numpy.dot(vect,yg))
425 wrap = numpy.where(ha>=180.)
425 wrap = numpy.where(ha>=180.)
426 if wrap[0].size>0:ha[wrap] = ha[wrap] - 360.
426 if wrap[0].size>0:ha[wrap] = ha[wrap] - 360.
427
427
428 val = numpy.where((numpy.abs(ha))<=(maxha_min*0.25))
428 val = numpy.where((numpy.abs(ha))<=(maxha_min*0.25))
429 if val[0].size>2:
429 if val[0].size>2:
430 tod_1 = tod*1.
430 tod_1 = tod*1.
431 shift_1 = numpy.where(tod>12.)
431 shift_1 = numpy.where(tod>12.)
432 tod_1[shift_1] = tod_1[shift_1] - 24.
432 tod_1[shift_1] = tod_1[shift_1] - 24.
433 tod_2 = tod*1.
433 tod_2 = tod*1.
434 shift_2 = numpy.where(tod<12.)
434 shift_2 = numpy.where(tod<12.)
435 tod_2[shift_2] = tod_2[shift_2] + 24.
435 tod_2[shift_2] = tod_2[shift_2] + 24.
436
436
437 diff0 = numpy.nanmax(tod[val]) - numpy.nanmin(tod[val])
437 diff0 = numpy.nanmax(tod[val]) - numpy.nanmin(tod[val])
438 diff1 = numpy.nanmax(tod_1[val]) - numpy.nanmin(tod_1[val])
438 diff1 = numpy.nanmax(tod_1[val]) - numpy.nanmin(tod_1[val])
439 diff2 = numpy.nanmax(tod_2[val]) - numpy.nanmin(tod_2[val])
439 diff2 = numpy.nanmax(tod_2[val]) - numpy.nanmin(tod_2[val])
440
440
441 if ((diff0<=diff1) & (diff0<=diff2)):
441 if ((diff0<=diff1) & (diff0<=diff2)):
442 tod_0 = tod
442 tod_0 = tod
443 elif ((diff1<diff0) & (diff1<diff2)):
443 elif ((diff1<diff0) & (diff1<diff2)):
444 tod_0 = tod_1
444 tod_0 = tod_1
445 else:
445 else:
446 tod_0 = tod_2
446 tod_0 = tod_2
447
447
448 if io==1:
448 if io==1:
449 self.dcosx_sun = dcosx[val]
449 self.dcosx_sun = dcosx[val]
450 self.dcosy_sun = dcosy[val]
450 self.dcosy_sun = dcosy[val]
451 self.ha_sun = ha[val]
451 self.ha_sun = ha[val]
452 self.time_sun = numpy.median(tod_0[val])
452 self.time_sun = numpy.median(tod_0[val])
453 elif io==2:
453 elif io==2:
454 self.dcosx_moon = dcosx[val]
454 self.dcosx_moon = dcosx[val]
455 self.dcosy_moon = dcosy[val]
455 self.dcosy_moon = dcosy[val]
456 self.ha_moon = ha[val]
456 self.ha_moon = ha[val]
457 self.time_moon = numpy.median(tod_0[val])
457 self.time_moon = numpy.median(tod_0[val])
458 elif io==3:
458 elif io==3:
459 self.dcosx_hydra = dcosx[val]
459 self.dcosx_hydra = dcosx[val]
460 self.dcosy_hydra = dcosy[val]
460 self.dcosy_hydra = dcosy[val]
461 self.ha_hydra = ha[val]
461 self.ha_hydra = ha[val]
462 self.time_hydra = numpy.mean(tod_0[val])
462 self.time_hydra = numpy.mean(tod_0[val])
463 elif io==4:
463 elif io==4:
464 self.dcosx_galaxy = dcosx[val]
464 self.dcosx_galaxy = dcosx[val]
465 self.dcosy_galaxy = dcosy[val]
465 self.dcosy_galaxy = dcosy[val]
466 self.ha_galaxy = ha[val]
466 self.ha_galaxy = ha[val]
467 self.time_galaxy = numpy.mean(tod_0[val])
467 self.time_galaxy = numpy.mean(tod_0[val])
468
468
469 index = numpy.mean(tod_0[val]) - minlev
469 index = numpy.mean(tod_0[val]) - minlev
470 index = (index*(maxcol - mincol)/(maxlev - minlev)) + mincol
470 index = (index*(maxcol - mincol)/(maxlev - minlev)) + mincol
471 index = numpy.int(index)
471 index = int(index)
472 figobjects, = matplotlib.pyplot.plot(dcosx[val],dcosy[val],marker[io-1],\
472 figobjects, = matplotlib.pyplot.plot(dcosx[val],dcosy[val],marker[io-1],\
473 lw=1,ms=7,mew=0,color=tuple(colortable[:,index]))
473 lw=1,ms=7,mew=0,color=tuple(colortable[:,index]))
474 handles.append(figobjects)
474 handles.append(figobjects)
475
475
476 xmax = numpy.max(dcosxrange[1])
476 xmax = numpy.max(dcosxrange[1])
477 xmin = numpy.min(dcosxrange[0])
477 xmin = numpy.min(dcosxrange[0])
478 ymax = numpy.max(dcosyrange[1])
478 ymax = numpy.max(dcosyrange[1])
479 ymin = numpy.min(dcosyrange[0])
479 ymin = numpy.min(dcosyrange[0])
480 matplotlib.pyplot.xlim(xmin,xmax)
480 matplotlib.pyplot.xlim(xmin,xmax)
481 matplotlib.pyplot.ylim(ymin,ymax)
481 matplotlib.pyplot.ylim(ymin,ymax)
482
482
483 val = numpy.where(self.show_object[1:]>0)
483 val = numpy.where(self.show_object[1:]>0)
484 objects = numpy.array(objects)
484 objects = numpy.array(objects)
485 objects = list(objects[val])
485 objects = list(objects[val])
486 try:
486 try:
487 ObjlegC = matplotlib.pyplot.legend(handles,objects,loc="lower left", numpoints=1, handlelength=0.3, \
487 ObjlegC = matplotlib.pyplot.legend(handles,objects,loc="lower left", numpoints=1, handlelength=0.3, \
488 borderpad=0.3, handletextpad=0.02,labelspacing=0.1)
488 borderpad=0.3, handletextpad=0.02,labelspacing=0.1)
489 except:
489 except:
490 ObjlegC = matplotlib.pyplot.legend(handles,objects,loc=[0.01,0.75], numpoints=1, handlelength=0, \
490 ObjlegC = matplotlib.pyplot.legend(handles,objects,loc=[0.01,0.75], numpoints=1, handlelength=0, \
491 pad=0.015, handletextsep=0.02,labelsep=0.01)
491 pad=0.015, handletextsep=0.02,labelsep=0.01)
492
492
493 matplotlib.pyplot.setp(ObjlegC.get_texts(),fontsize='small')
493 matplotlib.pyplot.setp(ObjlegC.get_texts(),fontsize='small')
494 ObjlegC.isaxes = False
494 ObjlegC.isaxes = False
495 save_fig = os.path.join(gpath,filename)
495 save_fig = os.path.join(gpath,filename)
496 matplotlib.pyplot.savefig(save_fig,format='png')
496 matplotlib.pyplot.savefig(save_fig,format='png')
497
497
498
498
499 class PatternCutPlot:
499 class PatternCutPlot:
500 def __init__(self,nsubplots):
500 def __init__(self,nsubplots):
501 self.nsubplots = nsubplots
501 self.nsubplots = nsubplots
502
502
503 self.fig = None
503 self.fig = None
504
504
505 self.__plot_width = 8
505 self.__plot_width = 8
506
506
507 if self.nsubplots == 5:
507 if self.nsubplots == 5:
508 self.__plot_height = 11
508 self.__plot_height = 11
509
509
510 if self.nsubplots == 4:
510 if self.nsubplots == 4:
511 self.__plot_height = 9
511 self.__plot_height = 9
512
512
513 if self.nsubplots == 3:
513 if self.nsubplots == 3:
514 self.__plot_height = 7
514 self.__plot_height = 7
515
515
516 if self.nsubplots == 2:
516 if self.nsubplots == 2:
517 self.__plot_height = 5
517 self.__plot_height = 5
518
518
519 if self.nsubplots == 1:
519 if self.nsubplots == 1:
520 self.__plot_height = 3
520 self.__plot_height = 3
521
521
522 self.fig = matplotlib.pyplot.figure(num = 4,figsize = (self.__plot_width, self.__plot_height))
522 self.fig = matplotlib.pyplot.figure(num = 4,figsize = (self.__plot_width, self.__plot_height))
523
523
524 if self.nsubplots < 5:
524 if self.nsubplots < 5:
525 self.__height_inch = 1.1 #altura de los subplots (pulgadas)
525 self.__height_inch = 1.1 #altura de los subplots (pulgadas)
526 top_inch = 1.5/2.7 #espacio entre el primer subplot y el limite superior del plot
526 top_inch = 1.5/2.7 #espacio entre el primer subplot y el limite superior del plot
527 self.__vspace_plot_inch = 1.0#1.5/2 # espacio vertical entre subplots
527 self.__vspace_plot_inch = 1.0#1.5/2 # espacio vertical entre subplots
528 self.__left = 0.1
528 self.__left = 0.1
529 else:
529 else:
530 self.__height_inch = 1.1 #altura de los subplots (pulgadas)
530 self.__height_inch = 1.1 #altura de los subplots (pulgadas)
531 top_inch = 1.5/2.7 #espacio entre el primer subplot y el limite superior del plot
531 top_inch = 1.5/2.7 #espacio entre el primer subplot y el limite superior del plot
532 self.__vspace_plot_inch = 1.0 # espacio vertical entre subplots
532 self.__vspace_plot_inch = 1.0 # espacio vertical entre subplots
533 self.__left = 0.1
533 self.__left = 0.1
534
534
535 self.__bottom_inch = self.__plot_height - (self.__height_inch + top_inch)
535 self.__bottom_inch = self.__plot_height - (self.__height_inch + top_inch)
536 self.__height = self.__height_inch/self.__plot_height
536 self.__height = self.__height_inch/self.__plot_height
537
537
538 self.__width = 0.8
538 self.__width = 0.8
539
539
540
540
541 def drawCut(self,io,patterns,npatterns,ha,otitle,subtitle,ptitle):
541 def drawCut(self,io,patterns,npatterns,ha,otitle,subtitle,ptitle):
542
542
543 t_cuts = ['B','Sun','Moon','Hydra','Galaxy']
543 t_cuts = ['B','Sun','Moon','Hydra','Galaxy']
544 self.__bottom = self.__bottom_inch/self.__plot_height
544 self.__bottom = self.__bottom_inch/self.__plot_height
545
545
546
546
547 subp = self.fig.add_axes([self.__left,self.__bottom,self.__width,self.__height])
547 subp = self.fig.add_axes([self.__left,self.__bottom,self.__width,self.__height])
548
548
549 on_axis_angle = -4.65562
549 on_axis_angle = -4.65562
550 for icut in numpy.arange(npatterns):
550 for icut in numpy.arange(npatterns):
551 # Getting Antenna cut.
551 # Getting Antenna cut.
552 pattern = patterns[icut]
552 pattern = patterns[icut]
553 power = numpy.abs(pattern/numpy.nanmax(pattern))
553 power = numpy.abs(pattern/numpy.nanmax(pattern))
554 max_power_db = numpy.round(10.*numpy.log10(numpy.nanmax(pattern)),2)
554 max_power_db = numpy.round(10.*numpy.log10(numpy.nanmax(pattern)),2)
555
555
556 bval = numpy.where(power[:,0]==numpy.nanmax(power))
556 bval = numpy.where(power[:,0]==numpy.nanmax(power))
557 beta = -0.25*(ha[bval[0]] + on_axis_angle)
557 beta = -0.25*(ha[bval[0]] + on_axis_angle)
558 # print 'Angle (deg): '+"%f"%(beta)
558 # print 'Angle (deg): '+"%f"%(beta)
559
559
560 subp.plot(ha,power)
560 subp.plot(ha,power)
561
561
562
562
563 xmax = numpy.max(numpy.nanmin(ha))
563 xmax = numpy.max(numpy.nanmin(ha))
564 xmin = numpy.min(numpy.nanmax(ha))
564 xmin = numpy.min(numpy.nanmax(ha))
565 ymax = numpy.max(1)
565 ymax = numpy.max(1)
566 ymin = numpy.min(0)
566 ymin = numpy.min(0)
567
567
568
568
569 subp.set_xlim(xmin, xmax)
569 subp.set_xlim(xmin, xmax)
570
570
571 subp.set_ylim(ymin, ymax)
571 subp.set_ylim(ymin, ymax)
572
572
573 subp.set_title(otitle + ' ' + ptitle,size="medium")
573 subp.set_title(otitle + ' ' + ptitle,size="medium")
574
574
575 subp.text(0.5, 1.26,subtitle[0],
575 subp.text(0.5, 1.26,subtitle[0],
576 horizontalalignment='center',
576 horizontalalignment='center',
577 verticalalignment='center',
577 verticalalignment='center',
578 transform = subp.transAxes)
578 transform = subp.transAxes)
579
579
580 xlabels = subp.get_xticks()
580 xlabels = subp.get_xticks()
581
581
582 subp.set_xticklabels(xlabels,size="small")
582 subp.set_xticklabels(xlabels,size="small")
583
583
584 ylabels = subp.get_yticks()
584 ylabels = subp.get_yticks()
585
585
586 subp.set_yticklabels(ylabels,size="small")
586 subp.set_yticklabels(ylabels,size="small")
587
587
588 subp.set_xlabel('Hour angle (min) (+ve to West)',size="small")
588 subp.set_xlabel('Hour angle (min) (+ve to West)',size="small")
589
589
590 subp.set_ylabel("Power [Max: " + str(max_power_db) + ' dB]',size="small")
590 subp.set_ylabel("Power [Max: " + str(max_power_db) + ' dB]',size="small")
591
591
592 subp.grid()
592 subp.grid()
593
593
594
594
595 self.__bottom_inch = self.__bottom_inch - (self.__height_inch + self.__vspace_plot_inch)
595 self.__bottom_inch = self.__bottom_inch - (self.__height_inch + self.__vspace_plot_inch)
596
596
597
597
598 class SkyNoisePlot:
598 class SkyNoisePlot:
599 def __init__(self,date,powr,time,time_lst):
599 def __init__(self,date,powr,time,time_lst):
600 """
600 """
601 SkyNoisePlot class creates an object which represents the SkyNoise Object to genera-
601 SkyNoisePlot class creates an object which represents the SkyNoise Object to genera-
602 te a SkyNoise map.
602 te a SkyNoise map.
603
603
604 Parameters
604 Parameters
605 ----------
605 ----------
606 date = A List of 3 elements to define the desired date ([year, month, day]).
606 date = A List of 3 elements to define the desired date ([year, month, day]).
607 powr = An array giving the SkyNoise power for the desired time.
607 powr = An array giving the SkyNoise power for the desired time.
608 time = An array giving the number of seconds since 1970 to the desired time.
608 time = An array giving the number of seconds since 1970 to the desired time.
609 time_lst = Set this input to an array to define the Local Sidereal Time of the desi-
609 time_lst = Set this input to an array to define the Local Sidereal Time of the desi-
610 red time.
610 red time.
611
611
612 Modification History
612 Modification History
613 --------------------
613 --------------------
614 Created by Freddy Galindo, ROJ, 18 October 2009.
614 Created by Freddy Galindo, ROJ, 18 October 2009.
615 """
615 """
616
616
617 self.date = date
617 self.date = date
618 self.powr = powr
618 self.powr = powr
619 self.time = time
619 self.time = time
620 self.time_lst = time_lst
620 self.time_lst = time_lst
@@ -1,1775 +1,1778
1 #!/usr/bin/python
1 #!/usr/bin/python
2 import sys, os, os.path
2 import sys, os, os.path
3 import traceback
3 import traceback
4 import cgi
4 import cgi
5 from http import cookies
5 from http import cookies
6
6
7 import time, datetime
7 import time, datetime
8 import types
8 import types
9 import numpy
9 import numpy
10 import numpy.fft
10 import numpy.fft
11 import scipy.linalg
11 import scipy.linalg
12 import scipy.special
12 import scipy.special
13 from io import StringIO
13 from io import StringIO
14
14
15
15
16 #import Misc_Routines
16 #import Misc_Routines
17 from .Misc_Routines import CoFactors
17 from .Misc_Routines import CoFactors
18 #import TimeTools
18 #import TimeTools
19 from .TimeTools import Time , Julian ,Doy2Date
19 from .TimeTools import Time , Julian ,Doy2Date
20 #import JroAntSetup
20 #import JroAntSetup
21 from .JroAntSetup import ReturnSetup
21 from .JroAntSetup import ReturnSetup
22 #import Graphics_OverJro
22 #import Graphics_OverJro
23 from .Graphics_OverJro import AntPatternPlot ,BFieldPlot,CelestialObjectsPlot,PatternCutPlot,SkyNoisePlot
23 from .Graphics_OverJro import AntPatternPlot ,BFieldPlot,CelestialObjectsPlot,PatternCutPlot,SkyNoisePlot
24 #import Astro_Coords
24 #import Astro_Coords
25 from .Astro_Coords import Geodetic ,AltAz ,CelestialBodies
25 from .Astro_Coords import Geodetic ,AltAz ,CelestialBodies
26
26
27 class JroPattern():
27 class JroPattern():
28 def __init__(self,pattern=0,path=None,filename=None,nptsx=101,nptsy=101,maxphi=5,fftopt=0, \
28 def __init__(self,pattern=0,path=None,filename=None,nptsx=101,nptsy=101,maxphi=5,fftopt=0, \
29 getcut=0,dcosx=None,dcosy=None,eomwl=6,airwl=4, **kwargs):
29 getcut=0,dcosx=None,dcosy=None,eomwl=6,airwl=4, **kwargs):
30 """
30 """
31 JroPattern class creates an object to represent the useful parameters for beam mode-
31 JroPattern class creates an object to represent the useful parameters for beam mode-
32 lling of the Jicamarca VHF radar.
32 lling of the Jicamarca VHF radar.
33
33
34 Parameters
34 Parameters
35 ----------
35 ----------
36 pattern = An integer (See JroAntSetup to know the available values) to load a prede-
36 pattern = An integer (See JroAntSetup to know the available values) to load a prede-
37 fined configuration. The default value is 0. To use a user-defined configuration
37 fined configuration. The default value is 0. To use a user-defined configuration
38 pattern must be None.
38 pattern must be None.
39 path = A string giving the directory that contains the user-configuration file. PATH
39 path = A string giving the directory that contains the user-configuration file. PATH
40 will work if pattern is None.
40 will work if pattern is None.
41 filename = A string giving the name of the user-configuration file. FILENAME will
41 filename = A string giving the name of the user-configuration file. FILENAME will
42 work if pattern is None.
42 work if pattern is None.
43 nptsx = A scalar to specify the number of points used to define the angular resolu-
43 nptsx = A scalar to specify the number of points used to define the angular resolu-
44 tion in the "x" axis. The default value is 101.
44 tion in the "x" axis. The default value is 101.
45 nptsy = A scalar to specify the number of points used to define the angular resolu-
45 nptsy = A scalar to specify the number of points used to define the angular resolu-
46 tion in the "x" axis. The default value is 101.
46 tion in the "x" axis. The default value is 101.
47 maxphi = A scalar giving the maximum (absolute) angle (in degree) to model the ante-
47 maxphi = A scalar giving the maximum (absolute) angle (in degree) to model the ante-
48 nna pattern. The default value is 5 degrees.
48 nna pattern. The default value is 5 degrees.
49 fftopt = Set this input to 1 to model the beam using FFT. To model using antenna
49 fftopt = Set this input to 1 to model the beam using FFT. To model using antenna
50 theory set to 0 (default value).
50 theory set to 0 (default value).
51 getcut = Set to 1 to show an antenna cut instead of a contour plot of itself (set to
51 getcut = Set to 1 to show an antenna cut instead of a contour plot of itself (set to
52 0). The defautl value is 0.
52 0). The defautl value is 0.
53 dcosx = An array giving the directional cosines for the x-axis. DCOSX will work if
53 dcosx = An array giving the directional cosines for the x-axis. DCOSX will work if
54 getcut is actived.
54 getcut is actived.
55 dcosy = An array giving the directional cosines for the y-axis. DCOSY will work if
55 dcosy = An array giving the directional cosines for the y-axis. DCOSY will work if
56 getcut is actived.
56 getcut is actived.
57 eomwl = A scalar giving the radar wavelength. The default value is 6m (50 MHZ).
57 eomwl = A scalar giving the radar wavelength. The default value is 6m (50 MHZ).
58 airwl = Set this input to float (or intger) to specify the wavelength (in meters) of
58 airwl = Set this input to float (or intger) to specify the wavelength (in meters) of
59 the transmitted EOM wave in the air. The default value is 4m.
59 the transmitted EOM wave in the air. The default value is 4m.
60
60
61 Modification History
61 Modification History
62 --------------------
62 --------------------
63 Converted to Object-oriented Programming by Freddy Galindo, ROJ, 20 September 2009.
63 Converted to Object-oriented Programming by Freddy Galindo, ROJ, 20 September 2009.
64 """
64 """
65
65
66
66
67
67
68 # Getting antenna configuration.
68 # Getting antenna configuration.
69 if filename:
69 if filename:
70 setup = ReturnSetup(path=path,filename=filename,pattern=pattern)
70 setup = ReturnSetup(path=path,filename=filename,pattern=pattern)
71
71
72 ues = setup["ues"]
72 ues = setup["ues"]
73 phase = setup["phase"]
73 phase = setup["phase"]
74 gaintx = setup["gaintx"]
74 gaintx = setup["gaintx"]
75 gainrx = setup["gainrx"]
75 gainrx = setup["gainrx"]
76 justrx = setup["justrx"]
76 justrx = setup["justrx"]
77 self.title = setup["title"]
77 self.title = setup["title"]
78 else:
78 else:
79 ues = kwargs["ues"]
79 ues = kwargs["ues"]
80 phase = kwargs["phases"]
80 phase = kwargs["phases"]
81 gaintx = kwargs["gain_tx"]
81 gaintx = kwargs["gain_tx"]
82 gainrx = kwargs["gain_rx"]
82 gainrx = kwargs["gain_rx"]
83 justrx = kwargs["just_rx"]
83 justrx = kwargs["just_rx"]
84 self.title = kwargs.get("title", "JRO Pattern")
84 self.title = kwargs.get("title", "JRO Pattern")
85
85
86 # Defining attributes for JroPattern class.
86 # Defining attributes for JroPattern class.
87 # Antenna configuration
87 # Antenna configuration
88
88
89 self.uestx = ues
89 self.uestx = ues
90 self.phasetx = phase
90 self.phasetx = phase
91 self.gaintx = gaintx
91 self.gaintx = gaintx
92 self.uesrx = ues
92 self.uesrx = ues
93 self.phaserx = phase
93 self.phaserx = phase
94 self.gainrx = gainrx
94 self.gainrx = gainrx
95 self.justrx = justrx
95 self.justrx = justrx
96
96
97 # Pattern resolution & method to model
97 # Pattern resolution & method to model
98 self.maxphi = maxphi
98 self.maxphi = maxphi
99 self.nptsx = nptsx
99 self.nptsx = nptsx
100 self.nptsy = nptsy
100 self.nptsy = nptsy
101 self.fftopt = fftopt
101 self.fftopt = fftopt
102
102
103 # To get a cut of the pattern.
103 # To get a cut of the pattern.
104 self.getcut = getcut
104 self.getcut = getcut
105
105
106 maxdcos = numpy.sin(maxphi*CoFactors.d2r)
106 maxdcos = numpy.sin(maxphi*CoFactors.d2r)
107 if dcosx==None:dcosx = ((numpy.arange(nptsx,dtype=float)/(nptsx-1))-0.5)*2*maxdcos
107 if dcosx==None:dcosx = ((numpy.arange(nptsx,dtype=float)/(nptsx-1))-0.5)*2*maxdcos
108 if dcosy==None:dcosy = ((numpy.arange(nptsy,dtype=float)/(nptsy-1))-0.5)*2*maxdcos
108 if dcosy==None:dcosy = ((numpy.arange(nptsy,dtype=float)/(nptsy-1))-0.5)*2*maxdcos
109 self.dcosx = dcosx
109 self.dcosx = dcosx
110 self.dcosy = dcosy
110 self.dcosy = dcosy
111 self.nx = dcosx.size
111 self.nx = dcosx.size
112 self.ny = dcosy.size*(getcut==0) + (getcut==1)
112 self.ny = dcosy.size*(getcut==0) + (getcut==1)
113
113
114 self.eomwl = eomwl
114 self.eomwl = eomwl
115 self.airwl = airwl
115 self.airwl = airwl
116
116
117 self.kk = 2.*numpy.pi/eomwl
117 self.kk = 2.*numpy.pi/eomwl
118
118
119 self.pattern = None
119 self.pattern = None
120 self.meanpos = None
120 self.meanpos = None
121 self.norpattern = None
121 self.norpattern = None
122 self.maxpattern = None
122 self.maxpattern = None
123
123
124
124
125
125
126 self.getPattern()
126 self.getPattern()
127
127
128 def getPattern(self):
128 def getPattern(self):
129 """
129 """
130 getpattern method returns the modeled total antenna pattern and its mean position.
130 getpattern method returns the modeled total antenna pattern and its mean position.
131
131
132 Return
132 Return
133 ------
133 ------
134 pattern = An array giving the Modelled antenna pattern.
134 pattern = An array giving the Modelled antenna pattern.
135 mean_pos = A 2-elements array giving the mean position of the main beam.
135 mean_pos = A 2-elements array giving the mean position of the main beam.
136
136
137 Examples
137 Examples
138 --------
138 --------
139 >> [pattern, mean_pos] = JroPattern(pattern=2).getPattern()
139 >> [pattern, mean_pos] = JroPattern(pattern=2).getPattern()
140 >> print meanpos
140 >> print meanpos
141 [ 8.08728085e-14 -4.78193873e-14]
141 [ 8.08728085e-14 -4.78193873e-14]
142
142
143 Modification history
143 Modification history
144 --------------------
144 --------------------
145 Developed by Jorge L. Chau.
145 Developed by Jorge L. Chau.
146 Converted to Python by Freddy R. Galindo, ROJ, 20 September 2009.
146 Converted to Python by Freddy R. Galindo, ROJ, 20 September 2009.
147 """
147 """
148
148
149 if (self.fftopt>0) and (self.getcut>0):
149 if (self.fftopt>0) and (self.getcut>0):
150 #print "Conflict bewteen fftopt and getcut"
150 #print "Conflict bewteen fftopt and getcut"
151 #print "To get a cut of the antenna pattern uses ffopt=0"
151 #print "To get a cut of the antenna pattern uses ffopt=0"
152 return None, None
152 return None, None
153
153
154 if (self.fftopt==0):
154 if (self.fftopt==0):
155 # Getting antenna pattern using the array method
155 # Getting antenna pattern using the array method
156 self.pattern = self.__usingArray(rx=1)
156 self.pattern = self.__usingArray(rx=1)
157 if (self.justrx==0):self.pattern = self.pattern*self.__usingArray(rx=0)
157 if (self.justrx==0):self.pattern = self.pattern*self.__usingArray(rx=0)
158
158
159 elif (self.fftopt>0):
159 elif (self.fftopt>0):
160 # Getting antenna pattern using FFT method
160 # Getting antenna pattern using FFT method
161 self.pattern = self.__usingFFT(rx=1)
161 self.pattern = self.__usingFFT(rx=1)
162 if (self.justrx==0):self.pattern = self.pattern*self.__usingFFT(rx=0)
162 if (self.justrx==0):self.pattern = self.pattern*self.__usingFFT(rx=0)
163
163
164 self.maxpattern = numpy.nanmax(self.pattern)
164 self.maxpattern = numpy.nanmax(self.pattern)
165 self.norpattern = self.pattern/self.maxpattern
165 self.norpattern = self.pattern/self.maxpattern
166 if self.getcut==0:self.__getBeamPars()
166 if self.getcut==0:self.__getBeamPars()
167
167
168 def __usingArray(self,rx):
168 def __usingArray(self,rx):
169 """
169 """
170 __usingArray method returns the Jicamarca antenna pattern computed using array model
170 __usingArray method returns the Jicamarca antenna pattern computed using array model
171
171
172 pattern = dipolepattern x modulepattern
172 pattern = dipolepattern x modulepattern
173
173
174 Parameters
174 Parameters
175 ----------
175 ----------
176 rx = Set to 1 to use the Rx information. Otherwise set to 0 for Tx.
176 rx = Set to 1 to use the Rx information. Otherwise set to 0 for Tx.
177
177
178 Return
178 Return
179 ------
179 ------
180 pattern = An array giving the modelled antenna pattern using the array model.
180 pattern = An array giving the modelled antenna pattern using the array model.
181
181
182 Modification history
182 Modification history
183 --------------------
183 --------------------
184 Developed by Jorge L. Chau.
184 Developed by Jorge L. Chau.
185 Converted to Python by Freddy R. Galindo, ROJ, 20 September 2009.
185 Converted to Python by Freddy R. Galindo, ROJ, 20 September 2009.
186 """
186 """
187
187
188 if rx==1:
188 if rx==1:
189 ues = self.uesrx
189 ues = self.uesrx
190 phase = self.phaserx
190 phase = self.phaserx
191 gain = self.gainrx
191 gain = self.gainrx
192 elif rx==0:
192 elif rx==0:
193 ues = self.uestx
193 ues = self.uestx
194 phase = self.phasetx
194 phase = self.phasetx
195 gain = self.gaintx
195 gain = self.gaintx
196
196
197 ues = ues*360./self.airwl
197 ues = ues*360./self.airwl
198 phase = phase*360./self.airwl
198 phase = phase*360./self.airwl
199
199
200 for ii in range(4):
200 for ii in range(4):
201 if ii==0:dim = numpy.array([4,0,8,4]) # WEST
201 if ii==0:dim = numpy.array([4,0,8,4]) # WEST
202 elif ii==1:dim = numpy.array([0,0,4,4]) # NORTH
202 elif ii==1:dim = numpy.array([0,0,4,4]) # NORTH
203 elif ii==2:dim = numpy.array([0,4,4,8]) # EAST
203 elif ii==2:dim = numpy.array([0,4,4,8]) # EAST
204 elif ii==3:dim = numpy.array([4,4,8,8]) # SOUTH
204 elif ii==3:dim = numpy.array([4,4,8,8]) # SOUTH
205 xi = dim[0]; xf = dim[2]; yi = dim[1]; yf = dim[3]
205 xi = dim[0]; xf = dim[2]; yi = dim[1]; yf = dim[3]
206 phase[xi:xf,yi:yf] = phase[xi:xf,yi:yf] + ues[ii]
206 phase[xi:xf,yi:yf] = phase[xi:xf,yi:yf] + ues[ii]
207
207
208 phase = -phase
208 phase = -phase
209
209
210 ar = self.eomwl*numpy.array([[0.5,6., 24.5],[0.5,6.,24.5]])
210 ar = self.eomwl*numpy.array([[0.5,6., 24.5],[0.5,6.,24.5]])
211 nr = numpy.array([[12.,4.,2.],[12.,4.,2.]])
211 nr = numpy.array([[12.,4.,2.],[12.,4.,2.]])
212 lr = 0.25*self.eomwl*numpy.array([[0,0.,0],[0.,0,0]])
212 lr = 0.25*self.eomwl*numpy.array([[0,0.,0],[0.,0,0]])
213
213
214 # Computing module and dipole patterns.
214 # Computing module and dipole patterns.
215 pattern = (numpy.abs(self.__dipPattern(ar,nr,lr)*self.__modPattern(phase,gain)))**2
215 pattern = (numpy.abs(self.__dipPattern(ar,nr,lr)*self.__modPattern(phase,gain)))**2
216
216
217 return pattern
217 return pattern
218
218
219 def __usingFFT(self,rx):
219 def __usingFFT(self,rx):
220 """
220 """
221 __usingFFT method returns the Jicamarca antenna pattern computed using The Fast Fou-
221 __usingFFT method returns the Jicamarca antenna pattern computed using The Fast Fou-
222 rier Transform.
222 rier Transform.
223
223
224 pattern = iFFT(FFT(gain*EXP(j*phase)))
224 pattern = iFFT(FFT(gain*EXP(j*phase)))
225
225
226 Parameters
226 Parameters
227 ----------
227 ----------
228 rx = Set to 1 to use the Rx information. Otherwise set to 0 for Tx.
228 rx = Set to 1 to use the Rx information. Otherwise set to 0 for Tx.
229
229
230 Return
230 Return
231 ------
231 ------
232 pattern = An array giving the modelled antenna pattern using the array model.
232 pattern = An array giving the modelled antenna pattern using the array model.
233
233
234 Modification history
234 Modification history
235 --------------------
235 --------------------
236 Developed by Jorge L. Chau.
236 Developed by Jorge L. Chau.
237 Converted to Python by Freddy R. Galindo, ROJ, 20 September 2009.
237 Converted to Python by Freddy R. Galindo, ROJ, 20 September 2009.
238 Updated to Django 4.1.5 and Python 3.9.16 by Renato Huallpa M. March 2023.
238 """
239 """
239
240
240 if rx==1:
241 if rx==1:
241 ues = self.uesrx
242 ues = self.uesrx
242 phase = self.phaserx
243 phase = self.phaserx
243 gain = self.gainrx
244 gain = self.gainrx
244 elif rx==0:
245 elif rx==0:
245 ues = self.uestx
246 ues = self.uestx
246 phase = self.phasetx
247 phase = self.phasetx
247 gain = self.gaintx
248 gain = self.gaintx
248
249
249 ues = ues*360./self.airwl
250 ues = ues*360./self.airwl
250 phase = phase*360./self.airwl
251 phase = phase*360./self.airwl
251
252
252 for ii in range(4):
253 for ii in range(4):
253 if ii==0:dim = numpy.array([4,0,8,4]) # WEST
254 if ii==0:dim = numpy.array([4,0,8,4]) # WEST
254 elif ii==1:dim = numpy.array([0,0,4,4]) # NORTH
255 elif ii==1:dim = numpy.array([0,0,4,4]) # NORTH
255 elif ii==2:dim = numpy.array([0,4,4,8]) # EAST
256 elif ii==2:dim = numpy.array([0,4,4,8]) # EAST
256 elif ii==3:dim = numpy.array([4,4,8,8]) # SOUTH
257 elif ii==3:dim = numpy.array([4,4,8,8]) # SOUTH
257 xi = dim[0]; xf = dim[2]; yi = dim[1]; yf = dim[3]
258 xi = dim[0]; xf = dim[2]; yi = dim[1]; yf = dim[3]
258 phase[xi:xf,yi:yf] = phase[xi:xf,yi:yf] + ues[ii]
259 phase[xi:xf,yi:yf] = phase[xi:xf,yi:yf] + ues[ii]
259
260
260 phase = -phase
261 phase = -phase
261
262
262 delta_x = self.eomwl/2.
263 delta_x = self.eomwl/2.
263 delta_y = self.eomwl/2.
264 delta_y = self.eomwl/2.
264
265
265 nxfft = 2048
266 nxfft = 2048
266 nyfft = 2048
267 nyfft = 2048
267 dcosx = (numpy.arange(nxfft) - (0.5*nxfft))/(nxfft*delta_x)*self.eomwl
268 dcosx = (numpy.arange(nxfft) - (0.5*nxfft))/(nxfft*delta_x)*self.eomwl
268 dcosy = (numpy.arange(nyfft) - (0.5*nyfft))/(nyfft*delta_y)*self.eomwl
269 dcosy = (numpy.arange(nyfft) - (0.5*nyfft))/(nyfft*delta_y)*self.eomwl
269
270
270 fft_gain = numpy.zeros((nxfft,nyfft))
271 fft_gain = numpy.zeros((nxfft,nyfft))
271 fft_phase = numpy.zeros((nxfft,nyfft))
272 fft_phase = numpy.zeros((nxfft,nyfft))
272
273
273 nx = 8
274 nx = 8
274 ny = 8
275 ny = 8
275 ndx =12
276 ndx =12
276 ndy =12
277 ndy =12
277 for iy in numpy.arange(ny):
278 for iy in numpy.arange(ny):
278 for ix in numpy.arange(nx):
279 for ix in numpy.arange(nx):
279 ix1 = nxfft/2-self.nx/2*ndx+ix*ndx
280 ix1 = nxfft/2-self.nx/2*ndx+ix*ndx
280 if ix<(nx/2):ix1 = ix1 - 1
281 if ix<(nx/2):ix1 = ix1 - 1
281 if ix>=(nx/2):ix1 = ix1 + 1
282 if ix>=(nx/2):ix1 = ix1 + 1
282
283
283 iy1 = nyfft/2-ny/2*ndx+iy*ndy
284 iy1 = nyfft/2-ny/2*ndx+iy*ndy
284 if iy<(ny/2):iy1 = iy1 - 1
285 if iy<(ny/2):iy1 = iy1 - 1
285 if iy>=(ny/2):iy1 = iy1 + 1
286 if iy>=(ny/2):iy1 = iy1 + 1
286
287
287 fft_gain[ix1:ix1+ndx-1,iy1:iy1+ndy-1] = gain[ix,ny-1-iy]
288 fft_gain[ix1:ix1+ndx-1,iy1:iy1+ndy-1] = gain[ix,ny-1-iy]
288 fft_phase[ix1:ix1+ndx-1,iy1:iy1+ndy-1] = phase[ix,ny-1-iy]
289 fft_phase[ix1:ix1+ndx-1,iy1:iy1+ndy-1] = phase[ix,ny-1-iy]
289
290
290
291
291 fft_phase = fft_phase*CoFactors.d2r
292 fft_phase = fft_phase*CoFactors.d2r
292
293
293 pattern = numpy.abs(numpy.fft.fft2(fft_gain*numpy.exp(numpy.complex(0,1)*fft_phase)))**2
294 pattern = numpy.abs(numpy.fft.fft2(fft_gain*numpy.exp(complex(0,1)*fft_phase)))**2
294 pattern = numpy.fft.fftshift(pattern)
295 pattern = numpy.fft.fftshift(pattern)
295
296
296 xvals = numpy.where((dcosx>=(numpy.min(self.dcosx))) & (dcosx<=(numpy.max(self.dcosx))))
297 xvals = numpy.where((dcosx>=(numpy.min(self.dcosx))) & (dcosx<=(numpy.max(self.dcosx))))
297 yvals = numpy.where((dcosy>=(numpy.min(self.dcosy))) & (dcosy<=(numpy.max(self.dcosy))))
298 yvals = numpy.where((dcosy>=(numpy.min(self.dcosy))) & (dcosy<=(numpy.max(self.dcosy))))
298
299
299 pattern = pattern[xvals[0][0]:xvals[0][-1],yvals[0][0]:yvals[0][-1]]
300 pattern = pattern[xvals[0][0]:xvals[0][-1],yvals[0][0]:yvals[0][-1]]
300
301
301 return pattern
302 return pattern
302
303
303 def __readAttenuation(self):
304 def __readAttenuation(self):
304 """
305 """
305 _readAttenuation reads the attenuations' file and returns an array giving these va-
306 _readAttenuation reads the attenuations' file and returns an array giving these va-
306 lues (dB). The ext file must be in the directory "resource".
307 lues (dB). The ext file must be in the directory "resource".
307
308
308 Return
309 Return
309 ------
310 ------
310 attenuation = An array giving attenuation values read from the text file.
311 attenuation = An array giving attenuation values read from the text file.
311
312
312 Modification history
313 Modification history
313 --------------------
314 --------------------
314 Developed by Jorge L. Chau.
315 Developed by Jorge L. Chau.
315 Converted to Python by Freddy R. Galindo, ROJ, 20 September 2009.
316 Converted to Python by Freddy R. Galindo, ROJ, 20 September 2009.
316 """
317 """
317
318
318 # attenuation = None
319 # attenuation = None
319 # # foldr = sys.path[-1] + os.sep + "resource" + os.sep
320 # # foldr = sys.path[-1] + os.sep + "resource" + os.sep
320 # base_path = os.path.dirname(os.path.abspath(__file__))
321 # base_path = os.path.dirname(os.path.abspath(__file__))
321 # #foldr = './resource'
322 # #foldr = './resource'
322 # #filen = "attenuation.txt"
323 # #filen = "attenuation.txt"
323 # attenuationFile = os.path.join(base_path,"resource","attenuation.txt")
324 # attenuationFile = os.path.join(base_path,"resource","attenuation.txt")
324 # #ff = open(os.path.join(foldr,filen),'r')
325 # #ff = open(os.path.join(foldr,filen),'r')
325 # ff = open(attenuationFile,'r')
326 # ff = open(attenuationFile,'r')
326 # print(ff.read())
327 # print(ff.read())
327 # exec(ff.read())
328 # exec(ff.read())
328 # ff.close()
329 # ff.close()
329 attenuation = numpy.array([[[-21.25,-15.25,-9.25,-3.25,03.25,09.25,15.25,21.25],
330 attenuation = numpy.array([[[-21.25,-15.25,-9.25,-3.25,03.25,09.25,15.25,21.25],
330 [-21.25,-15.25,-9.25,-3.25,03.25,09.25,15.25,21.25],
331 [-21.25,-15.25,-9.25,-3.25,03.25,09.25,15.25,21.25],
331 [-21.25,-15.25,-9.25,-3.25,03.25,09.25,15.25,21.25],
332 [-21.25,-15.25,-9.25,-3.25,03.25,09.25,15.25,21.25],
332 [-21.25,-15.25,-9.25,-3.25,03.25,09.25,15.25,21.25],
333 [-21.25,-15.25,-9.25,-3.25,03.25,09.25,15.25,21.25],
333 [-21.25,-15.25,-9.25,-3.25,03.25,09.25,15.25,21.25],
334 [-21.25,-15.25,-9.25,-3.25,03.25,09.25,15.25,21.25],
334 [-21.25,-15.25,-9.25,-3.25,03.25,09.25,15.25,21.25],
335 [-21.25,-15.25,-9.25,-3.25,03.25,09.25,15.25,21.25],
335 [-21.25,-15.25,-9.25,-3.25,03.25,09.25,15.25,21.25],
336 [-21.25,-15.25,-9.25,-3.25,03.25,09.25,15.25,21.25],
336 [-21.25,-15.25,-9.25,-3.25,03.25,09.25,15.25,21.25]],
337 [-21.25,-15.25,-9.25,-3.25,03.25,09.25,15.25,21.25]],
337 [[21.25,21.25,21.25,21.25,21.25,21.25,21.25,21.25],
338 [[21.25,21.25,21.25,21.25,21.25,21.25,21.25,21.25],
338 [15.25,15.25,15.25,15.25,15.25,15.25,15.25,15.25],
339 [15.25,15.25,15.25,15.25,15.25,15.25,15.25,15.25],
339 [09.25,09.25,09.25,09.25,09.25,09.25,09.25,09.25],
340 [09.25,09.25,09.25,09.25,09.25,09.25,09.25,09.25],
340 [03.25,03.25,03.25,03.25,03.25,03.25,03.25,03.25],
341 [03.25,03.25,03.25,03.25,03.25,03.25,03.25,03.25],
341 [-03.25,-03.25,-03.25,-03.25,-03.25,-03.25,-03.25,-03.25],
342 [-03.25,-03.25,-03.25,-03.25,-03.25,-03.25,-03.25,-03.25],
342 [-09.25,-09.25,-09.25,-09.25,-09.25,-09.25,-09.25,-09.25],
343 [-09.25,-09.25,-09.25,-09.25,-09.25,-09.25,-09.25,-09.25],
343 [-15.25,-15.25,-15.25,-15.25,-15.25,-15.25,-15.25,-15.25],
344 [-15.25,-15.25,-15.25,-15.25,-15.25,-15.25,-15.25,-15.25],
344 [-21.25,-21.25,-21.25,-21.25,-21.25,-21.25,-21.25,-21.25]]])
345 [-21.25,-21.25,-21.25,-21.25,-21.25,-21.25,-21.25,-21.25]]])
345
346
346 return attenuation
347 return attenuation
347
348
348 def __dipPattern(self,ar,nr,lr):
349 def __dipPattern(self,ar,nr,lr):
349 """
350 """
350 _dipPattern function computes the dipole's pattern to the Jicamarca radar. The next
351 _dipPattern function computes the dipole's pattern to the Jicamarca radar. The next
351 equation defines the pattern as a function of the mainlobe direction:
352 equation defines the pattern as a function of the mainlobe direction:
352
353
353 sincx = SIN(k/2*n0x*(a0x*SIN(phi)*COS(alpha)))/SIN(k/2*(a0x*SIN(phi)*COS(alpha)))
354 sincx = SIN(k/2*n0x*(a0x*SIN(phi)*COS(alpha)))/SIN(k/2*(a0x*SIN(phi)*COS(alpha)))
354 sincy = SIN(k/2*n0y*(a0y*SIN(phi)*SIN(alpha)))/SIN(k/2*(a0y*SIN(phi)*SIN(alpha)))
355 sincy = SIN(k/2*n0y*(a0y*SIN(phi)*SIN(alpha)))/SIN(k/2*(a0y*SIN(phi)*SIN(alpha)))
355 A0(phi,alpha) = sincx*sincy
356 A0(phi,alpha) = sincx*sincy
356 Parameters
357 Parameters
357 ----------
358 ----------
358 ar = ?
359 ar = ?
359 nr = ?
360 nr = ?
360 lr = ?
361 lr = ?
361
362
362 Return
363 Return
363 ------
364 ------
364 dipole = An array giving antenna pattern from the dipole point of view..
365 dipole = An array giving antenna pattern from the dipole point of view..
365
366
366 Modification history
367 Modification history
367 --------------------
368 --------------------
368 Developed by Jorge L. Chau.
369 Developed by Jorge L. Chau.
369 Converted to Python by Freddy R. Galindo, ROJ, 20 September 2009.
370 Converted to Python by Freddy R. Galindo, ROJ, 20 September 2009.
370 """
371 """
371
372
372 dipole = numpy.zeros((self.nx,self.ny),dtype=complex)
373 dipole = numpy.zeros((self.nx,self.ny),dtype=complex)
373 for iy in range(self.ny):
374 for iy in range(self.ny):
374 for ix in range(self.nx):
375 for ix in range(self.nx):
375 yindex = iy*(self.getcut==0) + ix*(self.getcut==1)
376 yindex = iy*(self.getcut==0) + ix*(self.getcut==1)
376
377
377 argx = ar[0,0]*self.dcosx[ix] - lr[0,0]
378 argx = ar[0,0]*self.dcosx[ix] - lr[0,0]
378 if argx == 0.0:
379 if argx == 0.0:
379 junkx = nr[0,0]
380 junkx = nr[0,0]
380 else:
381 else:
381 junkx = numpy.sin(0.5*self.kk*nr[0,0]*argx)/numpy.sin(0.5*self.kk*argx)
382 junkx = numpy.sin(0.5*self.kk*nr[0,0]*argx)/numpy.sin(0.5*self.kk*argx)
382
383
383
384
384 argy = ar[1,0]*self.dcosy[yindex] - lr[1,0]
385 argy = ar[1,0]*self.dcosy[yindex] - lr[1,0]
385 if argy == 0.0:
386 if argy == 0.0:
386 junky = nr[1,0]
387 junky = nr[1,0]
387 else:
388 else:
388 junky = numpy.sin(0.5*self.kk*nr[1,0]*argy)/numpy.sin(0.5*self.kk*argy)
389 junky = numpy.sin(0.5*self.kk*nr[1,0]*argy)/numpy.sin(0.5*self.kk*argy)
389
390
390
391
391 dipole[ix,iy] = junkx*junky
392 dipole[ix,iy] = junkx*junky
392
393
393 return dipole
394 return dipole
394
395
395 def __modPattern(self,phase,gain):
396 def __modPattern(self,phase,gain):
396 """
397 """
397 ModPattern computes the module's pattern to the Jicamarca radar. The next equation
398 ModPattern computes the module's pattern to the Jicamarca radar. The next equation
398 defines the pattern as a function mainlobe direction:
399 defines the pattern as a function mainlobe direction:
399
400
400 phasex = pos(x)*SIN(phi)*COS(alpha)
401 phasex = pos(x)*SIN(phi)*COS(alpha)
401 phasey = pos(y)*SIN(phi)*SIN(alpha)
402 phasey = pos(y)*SIN(phi)*SIN(alpha)
402
403
403 A1(phi,alpha) = TOTAL(gain*EXP(COMPLEX(0,k*(phasex+phasey)+phase)))
404 A1(phi,alpha) = TOTAL(gain*EXP(COMPLEX(0,k*(phasex+phasey)+phase)))
404
405
405 Parameters
406 Parameters
406 ----------
407 ----------
407 phase = Bidimensional array (8x8) giving the phase (in meters) of each module.
408 phase = Bidimensional array (8x8) giving the phase (in meters) of each module.
408 gain = Bidimensional array (8x8) giving to define modules will be active (ones)
409 gain = Bidimensional array (8x8) giving to define modules will be active (ones)
409 and which will not (zeros).
410 and which will not (zeros).
410
411
411 Return
412 Return
412 ------
413 ------
413 module = An array giving antenna pattern from the module point of view..
414 module = An array giving antenna pattern from the module point of view..
414
415
415 Modification history
416 Modification history
416 --------------------
417 --------------------
417 Developed by Jorge L. Chau.
418 Developed by Jorge L. Chau.
418 Converted to Python by Freddy R. Galindo, ROJ, 20 September 2009.
419 Converted to Python by Freddy R. Galindo, ROJ, 20 September 2009.
420 Updated to Django 4.1.5 and Python 3.9.16 by Renato Huallpa M. March 2023.
419 """
421 """
420
422
421 pos = self.eomwl*self.__readAttenuation()
423 pos = self.eomwl*self.__readAttenuation()
422 posx = pos[0,:,:]
424 posx = pos[0,:,:]
423 posy = pos[1,:,:]
425 posy = pos[1,:,:]
424
426
425 phase = phase*CoFactors.d2r
427 phase = phase*CoFactors.d2r
426 module = numpy.zeros((self.nx,self.ny),dtype=complex)
428 module = numpy.zeros((self.nx,self.ny),dtype=complex)
427 for iy in range(self.ny):
429 for iy in range(self.ny):
428 for ix in range(self.nx):
430 for ix in range(self.nx):
429 yindex = iy*(self.getcut==0) + ix*(self.getcut==1)
431 yindex = iy*(self.getcut==0) + ix*(self.getcut==1)
430 phasex = posx*self.dcosx[ix]
432 phasex = posx*self.dcosx[ix]
431 phasey = posy*self.dcosy[yindex]
433 phasey = posy*self.dcosy[yindex]
432 tmp = gain*numpy.exp(numpy.complex(0,1.)*(self.kk*(phasex+phasey)+phase))
434 tmp = gain*numpy.exp(complex(0,1.)*(self.kk*(phasex+phasey)+phase))
433 module[ix,iy] = tmp.sum()
435 module[ix,iy] = tmp.sum()
434
436
435 return module
437 return module
436
438
437 def __getBeamPars(self):
439 def __getBeamPars(self):
438 """
440 """
439 _getBeamPars computes the main-beam parameters of the antenna.
441 _getBeamPars computes the main-beam parameters of the antenna.
440
442
441 Modification history
443 Modification history
442 --------------------
444 --------------------
443 Developed by Jorge L. Chau.
445 Developed by Jorge L. Chau.
444 Converted to Python by Freddy R. Galindo, ROJ, 20 September 2009.
446 Converted to Python by Freddy R. Galindo, ROJ, 20 September 2009.
445 """
447 """
446
448
447 dx = self.dcosx[1] - self.dcosx[0]
449 dx = self.dcosx[1] - self.dcosx[0]
448 dy = self.dcosy[1] - self.dcosy[0]
450 dy = self.dcosy[1] - self.dcosy[0]
449
451
450 amp = self.norpattern
452 amp = self.norpattern
451
453
452 xx = numpy.resize(self.dcosx,(self.nx,self.nx)).transpose()
454 xx = numpy.resize(self.dcosx,(self.nx,self.nx)).transpose()
453 yy = numpy.resize(self.dcosy,(self.ny,self.ny))
455 yy = numpy.resize(self.dcosy,(self.ny,self.ny))
454
456
455 mm0 = amp[numpy.where(amp > 0.5)]
457 mm0 = amp[numpy.where(amp > 0.5)]
456 xx0 = xx[numpy.where(amp > 0.5)]
458 xx0 = xx[numpy.where(amp > 0.5)]
457 yy0 = yy[numpy.where(amp > 0.5)]
459 yy0 = yy[numpy.where(amp > 0.5)]
458
460
459 xc = numpy.sum(mm0*xx0)/numpy.sum(mm0)
461 xc = numpy.sum(mm0*xx0)/numpy.sum(mm0)
460 yc = numpy.sum(mm0*yy0)/numpy.sum(mm0)
462 yc = numpy.sum(mm0*yy0)/numpy.sum(mm0)
461 rc = numpy.sqrt(mm0.size*dx*dy/numpy.pi)
463 rc = numpy.sqrt(mm0.size*dx*dy/numpy.pi)
462
464
463 nnx = numpy.where(numpy.abs(self.dcosx - xc) < rc)
465 nnx = numpy.where(numpy.abs(self.dcosx - xc) < rc)
464 nny = numpy.where(numpy.abs(self.dcosy - yc) < rc)
466 nny = numpy.where(numpy.abs(self.dcosy - yc) < rc)
465
467
466 mm1 = amp[numpy.min(nnx):numpy.max(nnx)+1,numpy.min(nny):numpy.max(nny)+1]
468 mm1 = amp[numpy.min(nnx):numpy.max(nnx)+1,numpy.min(nny):numpy.max(nny)+1]
467 xx1 = self.dcosx[numpy.min(nnx):numpy.max(nnx)+1]
469 xx1 = self.dcosx[numpy.min(nnx):numpy.max(nnx)+1]
468 yy1 = self.dcosy[numpy.min(nny):numpy.max(nny)+1]
470 yy1 = self.dcosy[numpy.min(nny):numpy.max(nny)+1]
469
471
470 # fitting data into the main beam.
472 # fitting data into the main beam.
471 import gaussfit
473 #import apps.abs.utils.gaussfit as gaussfit
472 params = gaussfit.fitgaussian(mm1)
474 from .gaussfit import fitgaussian
475 params = fitgaussian(mm1)
473
476
474 # Tranforming from indexes to axis' values
477 # Tranforming from indexes to axis' values
475 xcenter = xx1[0] + (((xx1[xx1.size-1] - xx1[0])/(xx1.size -1))*(params[1]))
478 xcenter = xx1[0] + (((xx1[xx1.size-1] - xx1[0])/(xx1.size -1))*(params[1]))
476 ycenter = yy1[0] + (((yy1[yy1.size-1] - yy1[0])/(yy1.size -1))*(params[2]))
479 ycenter = yy1[0] + (((yy1[yy1.size-1] - yy1[0])/(yy1.size -1))*(params[2]))
477 xwidth = ((xx1[xx1.size-1] - xx1[0])/(xx1.size-1))*(params[3])*(1/CoFactors.d2r)
480 xwidth = ((xx1[xx1.size-1] - xx1[0])/(xx1.size-1))*(params[3])*(1/CoFactors.d2r)
478 ywidth = ((yy1[yy1.size-1] - yy1[0])/(yy1.size-1))*(params[4])*(1/CoFactors.d2r)
481 ywidth = ((yy1[yy1.size-1] - yy1[0])/(yy1.size-1))*(params[4])*(1/CoFactors.d2r)
479 meanwx = (xwidth*ywidth)
482 meanwx = (xwidth*ywidth)
480 meanpos = numpy.array([xcenter,ycenter])
483 meanpos = numpy.array([xcenter,ycenter])
481
484
482 #print 'Position: %f %f' %(xcenter,ycenter)
485 #print 'Position: %f %f' %(xcenter,ycenter)
483 #print 'Widths: %f %f' %(xwidth, ywidth)
486 #print 'Widths: %f %f' %(xwidth, ywidth)
484 #print 'BWHP: %f' %(2*numpy.sqrt(2*meanwx)*numpy.sqrt(-numpy.log(0.5)))
487 #print 'BWHP: %f' %(2*numpy.sqrt(2*meanwx)*numpy.sqrt(-numpy.log(0.5)))
485
488
486 self.meanpos = meanpos
489 self.meanpos = meanpos
487
490
488
491
489 class BField():
492 class BField():
490 def __init__(self,year=None,doy=None,site=1,heights=None,alpha_i=90):
493 def __init__(self,year=None,doy=None,site=1,heights=None,alpha_i=90):
491 """
494 """
492 BField class creates an object to get the Magnetic field for a specific date and
495 BField class creates an object to get the Magnetic field for a specific date and
493 height(s).
496 height(s).
494
497
495 Parameters
498 Parameters
496 ----------
499 ----------
497 year = A scalar giving the desired year. If the value is None (default value) then
500 year = A scalar giving the desired year. If the value is None (default value) then
498 the current year will be used.
501 the current year will be used.
499 doy = A scalar giving the desired day of the year. If the value is None (default va-
502 doy = A scalar giving the desired day of the year. If the value is None (default va-
500 lue) then the current doy will be used.
503 lue) then the current doy will be used.
501 site = An integer to choose the geographic coordinates of the place where the magne-
504 site = An integer to choose the geographic coordinates of the place where the magne-
502 tic field will be computed. The default value is over Jicamarca (site=1)
505 tic field will be computed. The default value is over Jicamarca (site=1)
503 heights = An array giving the heights (km) where the magnetic field will be modeled By default the magnetic field will be computed at 100, 500 and 1000km.
506 heights = An array giving the heights (km) where the magnetic field will be modeled By default the magnetic field will be computed at 100, 500 and 1000km.
504 alpha_i = Angle to interpolate the magnetic field.
507 alpha_i = Angle to interpolate the magnetic field.
505
508
506 Modification History
509 Modification History
507 --------------------
510 --------------------
508 Converted to Object-oriented Programming by Freddy Galindo, ROJ, 07 October 2009.
511 Converted to Object-oriented Programming by Freddy Galindo, ROJ, 07 October 2009.
509 """
512 """
510
513
511 tmp = time.localtime()
514 tmp = time.localtime()
512 if year==None: year = tmp[0]
515 if year==None: year = tmp[0]
513 if doy==None: doy = tmp[7]
516 if doy==None: doy = tmp[7]
514 self.year = year
517 self.year = year
515 self.doy = doy
518 self.doy = doy
516 self.site = site
519 self.site = site
517 if heights==None:heights = numpy.array([100,500,1000])
520 if heights==None:heights = numpy.array([100,500,1000])
518 self.heights = heights
521 self.heights = heights
519 self.alpha_i = alpha_i
522 self.alpha_i = alpha_i
520
523
521 def getBField(self,maglimits=numpy.array([-7,-7,7,7])):
524 def getBField(self,maglimits=numpy.array([-7,-7,7,7])):
522 """
525 """
523 getBField models the magnetic field for a different heights in a specific date.
526 getBField models the magnetic field for a different heights in a specific date.
524
527
525 Parameters
528 Parameters
526 ----------
529 ----------
527 maglimits = An 4-elements array giving ..... The default value is [-7,-7,7,7].
530 maglimits = An 4-elements array giving ..... The default value is [-7,-7,7,7].
528
531
529 Return
532 Return
530 ------
533 ------
531 dcos = An 4-dimensional array giving the directional cosines of the magnetic field
534 dcos = An 4-dimensional array giving the directional cosines of the magnetic field
532 over the desired place.
535 over the desired place.
533 alpha = An 3-dimensional array giving the angle of the magnetic field over the desi-
536 alpha = An 3-dimensional array giving the angle of the magnetic field over the desi-
534 red place.
537 red place.
535
538
536 Modification History
539 Modification History
537 --------------------
540 --------------------
538 Converted to Python by Freddy R. Galindo, ROJ, 07 October 2009.
541 Converted to Python by Freddy R. Galindo, ROJ, 07 October 2009.
539 """
542 """
540
543
541 x_ant = numpy.array([1,0,0])
544 x_ant = numpy.array([1,0,0])
542 y_ant = numpy.array([0,1,0])
545 y_ant = numpy.array([0,1,0])
543 z_ant = numpy.array([0,0,1])
546 z_ant = numpy.array([0,0,1])
544
547
545 if self.site==0:
548 if self.site==0:
546 title_site = "Magnetic equator"
549 title_site = "Magnetic equator"
547 coord_site = numpy.array([-76+52./60.,-11+57/60.,0.5])
550 coord_site = numpy.array([-76+52./60.,-11+57/60.,0.5])
548 elif self.site==1:
551 elif self.site==1:
549 title_site = 'Jicamarca'
552 title_site = 'Jicamarca'
550 coord_site = [-76-52./60.,-11-57/60.,0.5]
553 coord_site = [-76-52./60.,-11-57/60.,0.5]
551 theta = (45+5.35)*numpy.pi/180. # (50.35 and 1.46 from Fleish Thesis)
554 theta = (45+5.35)*numpy.pi/180. # (50.35 and 1.46 from Fleish Thesis)
552 delta = -1.46*numpy.pi/180
555 delta = -1.46*numpy.pi/180
553
556
554 x_ant1 = numpy.roll(self.rotvector(self.rotvector(x_ant,1,delta),3,theta),1)
557 x_ant1 = numpy.roll(self.rotvector(self.rotvector(x_ant,1,delta),3,theta),1)
555 y_ant1 = numpy.roll(self.rotvector(self.rotvector(y_ant,1,delta),3,theta),1)
558 y_ant1 = numpy.roll(self.rotvector(self.rotvector(y_ant,1,delta),3,theta),1)
556 z_ant1 = numpy.roll(self.rotvector(self.rotvector(z_ant,1,delta),3,theta),1)
559 z_ant1 = numpy.roll(self.rotvector(self.rotvector(z_ant,1,delta),3,theta),1)
557
560
558 ang0 = -1*coord_site[0]*numpy.pi/180.
561 ang0 = -1*coord_site[0]*numpy.pi/180.
559 ang1 = coord_site[1]*numpy.pi/180.
562 ang1 = coord_site[1]*numpy.pi/180.
560 x_ant = self.rotvector(self.rotvector(x_ant1,2,ang1),3,ang0)
563 x_ant = self.rotvector(self.rotvector(x_ant1,2,ang1),3,ang0)
561 y_ant = self.rotvector(self.rotvector(y_ant1,2,ang1),3,ang0)
564 y_ant = self.rotvector(self.rotvector(y_ant1,2,ang1),3,ang0)
562 z_ant = self.rotvector(self.rotvector(z_ant1,2,ang1),3,ang0)
565 z_ant = self.rotvector(self.rotvector(z_ant1,2,ang1),3,ang0)
563 else:
566 else:
564 # print "No defined Site. Skip..."
567 # print "No defined Site. Skip..."
565 return None
568 return None
566
569
567 nhei = self.heights.size
570 nhei = self.heights.size
568 pt_intercep = numpy.zeros((nhei,2))
571 pt_intercep = numpy.zeros((nhei,2))
569 nfields = 1
572 nfields = 1
570
573
571 grid_res = 0.5
574 grid_res = 0.5
572 nlon = int(numpy.int(maglimits[2] - maglimits[0])/grid_res + 1)
575 nlon = int(int(maglimits[2] - maglimits[0])/grid_res + 1)
573 nlat = int(numpy.int(maglimits[3] - maglimits[1])/grid_res + 1)
576 nlat = int(int(maglimits[3] - maglimits[1])/grid_res + 1)
574
577
575 location = numpy.zeros((nlon,nlat,2))
578 location = numpy.zeros((nlon,nlat,2))
576 mlon = numpy.atleast_2d(numpy.arange(nlon)*grid_res + maglimits[0])
579 mlon = numpy.atleast_2d(numpy.arange(nlon)*grid_res + maglimits[0])
577 mrep = numpy.atleast_2d(numpy.zeros(nlat) + 1)
580 mrep = numpy.atleast_2d(numpy.zeros(nlat) + 1)
578 location0 = numpy.dot(mlon.transpose(),mrep)
581 location0 = numpy.dot(mlon.transpose(),mrep)
579
582
580 mlat = numpy.atleast_2d(numpy.arange(nlat)*grid_res + maglimits[1])
583 mlat = numpy.atleast_2d(numpy.arange(nlat)*grid_res + maglimits[1])
581 mrep = numpy.atleast_2d(numpy.zeros(nlon) + 1)
584 mrep = numpy.atleast_2d(numpy.zeros(nlon) + 1)
582 location1 = numpy.dot(mrep.transpose(),mlat)
585 location1 = numpy.dot(mrep.transpose(),mlat)
583
586
584 location[:,:,0] = location0
587 location[:,:,0] = location0
585 location[:,:,1] = location1
588 location[:,:,1] = location1
586
589
587 alpha = numpy.zeros((nlon,nlat,nhei))
590 alpha = numpy.zeros((nlon,nlat,nhei))
588 rr = numpy.zeros((nlon,nlat,nhei,3))
591 rr = numpy.zeros((nlon,nlat,nhei,3))
589 dcos = numpy.zeros((nlon,nlat,nhei,2))
592 dcos = numpy.zeros((nlon,nlat,nhei,2))
590
593
591 global first_time
594 global first_time
592
595
593 first_time = None
596 first_time = None
594 for ilon in numpy.arange(nlon):
597 for ilon in numpy.arange(nlon):
595 for ilat in numpy.arange(nlat):
598 for ilat in numpy.arange(nlat):
596 outs = self.__bdotk(self.heights,
599 outs = self.__bdotk(self.heights,
597 self.year + self.doy/366.,
600 self.year + self.doy/366.,
598 coord_site[1],
601 coord_site[1],
599 coord_site[0],
602 coord_site[0],
600 coord_site[2],
603 coord_site[2],
601 coord_site[1]+location[ilon,ilat,1],
604 coord_site[1]+location[ilon,ilat,1],
602 location[ilon,ilat,0]*720./180.)
605 location[ilon,ilat,0]*720./180.)
603
606
604 alpha[ilon, ilat,:] = outs[1]
607 alpha[ilon, ilat,:] = outs[1]
605 rr[ilon, ilat,:,:] = outs[3]
608 rr[ilon, ilat,:,:] = outs[3]
606
609
607 mrep = numpy.atleast_2d((numpy.zeros(nhei)+1)).transpose()
610 mrep = numpy.atleast_2d((numpy.zeros(nhei)+1)).transpose()
608 tmp = outs[3]*numpy.dot(mrep,numpy.atleast_2d(x_ant))
611 tmp = outs[3]*numpy.dot(mrep,numpy.atleast_2d(x_ant))
609 tmp = tmp.sum(axis=1)
612 tmp = tmp.sum(axis=1)
610 dcos[ilon,ilat,:,0] = tmp/numpy.sqrt((outs[3]**2).sum(axis=1))
613 dcos[ilon,ilat,:,0] = tmp/numpy.sqrt((outs[3]**2).sum(axis=1))
611
614
612 mrep = numpy.atleast_2d((numpy.zeros(nhei)+1)).transpose()
615 mrep = numpy.atleast_2d((numpy.zeros(nhei)+1)).transpose()
613 tmp = outs[3]*numpy.dot(mrep,numpy.atleast_2d(y_ant))
616 tmp = outs[3]*numpy.dot(mrep,numpy.atleast_2d(y_ant))
614 tmp = tmp.sum(axis=1)
617 tmp = tmp.sum(axis=1)
615 dcos[ilon,ilat,:,1] = tmp/numpy.sqrt((outs[3]**2).sum(axis=1))
618 dcos[ilon,ilat,:,1] = tmp/numpy.sqrt((outs[3]**2).sum(axis=1))
616
619
617 return dcos, alpha, nlon, nlat
620 return dcos, alpha, nlon, nlat
618
621
619
622
620 def __bdotk(self,heights,tm,gdlat=-11.95,gdlon=-76.8667,gdalt=0.0,decd=-12.88, ham=-4.61666667):
623 def __bdotk(self,heights,tm,gdlat=-11.95,gdlon=-76.8667,gdalt=0.0,decd=-12.88, ham=-4.61666667):
621
624
622 global first_time
625 global first_time
623 # Mean Earth radius in Km WGS 84
626 # Mean Earth radius in Km WGS 84
624 a_igrf = 6371.2
627 a_igrf = 6371.2
625
628
626 bk = numpy.zeros(heights.size)
629 bk = numpy.zeros(heights.size)
627 alpha = numpy.zeros(heights.size)
630 alpha = numpy.zeros(heights.size)
628 bfm = numpy.zeros(heights.size)
631 bfm = numpy.zeros(heights.size)
629 rr = numpy.zeros((heights.size,3))
632 rr = numpy.zeros((heights.size,3))
630 rgc = numpy.zeros((heights.size,3))
633 rgc = numpy.zeros((heights.size,3))
631
634
632 ObjGeodetic = Astro_Coords.Geodetic(gdlat,gdalt)
635 ObjGeodetic = Geodetic(gdlat,gdalt)
633 [gclat,gcalt] = ObjGeodetic.change2geocentric()
636 [gclat,gcalt] = ObjGeodetic.change2geocentric()
634
637
635 gclat = gclat*numpy.pi/180.
638 gclat = gclat*numpy.pi/180.
636 gclon = gdlon*numpy.pi/180.
639 gclon = gdlon*numpy.pi/180.
637
640
638 # Antenna position from center of Earth
641 # Antenna position from center of Earth
639 ca_vector = [numpy.cos(gclat)*numpy.cos(gclon),numpy.cos(gclat)*numpy.sin(gclon),numpy.sin(gclat)]
642 ca_vector = [numpy.cos(gclat)*numpy.cos(gclon),numpy.cos(gclat)*numpy.sin(gclon),numpy.sin(gclat)]
640 ca_vector = gcalt*numpy.array(ca_vector)
643 ca_vector = gcalt*numpy.array(ca_vector)
641
644
642 dec = decd*numpy.pi/180.
645 dec = decd*numpy.pi/180.
643
646
644 # K vector respect to the center of earth.
647 # K vector respect to the center of earth.
645 klon = gclon + ham*numpy.pi/720.
648 klon = gclon + ham*numpy.pi/720.
646 k_vector = [numpy.cos(dec)*numpy.cos(klon),numpy.cos(dec)*numpy.sin(klon),numpy.sin(dec)]
649 k_vector = [numpy.cos(dec)*numpy.cos(klon),numpy.cos(dec)*numpy.sin(klon),numpy.sin(dec)]
647 k_vector = numpy.array(k_vector)
650 k_vector = numpy.array(k_vector)
648
651
649 for ih in numpy.arange(heights.size):
652 for ih in numpy.arange(heights.size):
650 # Vector from Earth's center to volume of interest
653 # Vector from Earth's center to volume of interest
651 rr[ih,:] = k_vector*heights[ih]
654 rr[ih,:] = k_vector*heights[ih]
652 cv_vector = numpy.squeeze(ca_vector) + rr[ih,:]
655 cv_vector = numpy.squeeze(ca_vector) + rr[ih,:]
653
656
654 cv_gcalt = numpy.sqrt(numpy.sum(cv_vector**2.))
657 cv_gcalt = numpy.sqrt(numpy.sum(cv_vector**2.))
655 cvxy = numpy.sqrt(numpy.sum(cv_vector[0:2]**2.))
658 cvxy = numpy.sqrt(numpy.sum(cv_vector[0:2]**2.))
656
659
657 radial = cv_vector/cv_gcalt
660 radial = cv_vector/cv_gcalt
658 east = numpy.array([-1*cv_vector[1],cv_vector[0],0])/cvxy
661 east = numpy.array([-1*cv_vector[1],cv_vector[0],0])/cvxy
659 comp1 = east[1]*radial[2] - radial[1]*east[2]
662 comp1 = east[1]*radial[2] - radial[1]*east[2]
660 comp2 = east[2]*radial[0] - radial[2]*east[0]
663 comp2 = east[2]*radial[0] - radial[2]*east[0]
661 comp3 = east[0]*radial[1] - radial[0]*east[1]
664 comp3 = east[0]*radial[1] - radial[0]*east[1]
662 north = -1*numpy.array([comp1, comp2, comp3])
665 north = -1*numpy.array([comp1, comp2, comp3])
663
666
664 rr_k = cv_vector - numpy.squeeze(ca_vector)
667 rr_k = cv_vector - numpy.squeeze(ca_vector)
665 u_rr = rr_k/numpy.sqrt(numpy.sum(rr_k**2.))
668 u_rr = rr_k/numpy.sqrt(numpy.sum(rr_k**2.))
666
669
667 cv_gclat = numpy.arctan2(cv_vector[2],cvxy)
670 cv_gclat = numpy.arctan2(cv_vector[2],cvxy)
668 cv_gclon = numpy.arctan2(cv_vector[1],cv_vector[0])
671 cv_gclon = numpy.arctan2(cv_vector[1],cv_vector[0])
669
672
670 bhei = cv_gcalt-a_igrf
673 bhei = cv_gcalt-a_igrf
671 blat = cv_gclat*180./numpy.pi
674 blat = cv_gclat*180./numpy.pi
672 blon = cv_gclon*180./numpy.pi
675 blon = cv_gclon*180./numpy.pi
673 bfield = self.__igrfkudeki(bhei,tm,blat,blon)
676 bfield = self.__igrfkudeki(bhei,tm,blat,blon)
674
677
675 B = (bfield[0]*north + bfield[1]*east - bfield[2]*radial)*1.0e-5
678 B = (bfield[0]*north + bfield[1]*east - bfield[2]*radial)*1.0e-5
676
679
677 bfm[ih] = numpy.sqrt(numpy.sum(B**2.)) #module
680 bfm[ih] = numpy.sqrt(numpy.sum(B**2.)) #module
678 bk[ih] = numpy.sum(u_rr*B)
681 bk[ih] = numpy.sum(u_rr*B)
679 alpha[ih] = numpy.arccos(bk[ih]/bfm[ih])*180/numpy.pi
682 alpha[ih] = numpy.arccos(bk[ih]/bfm[ih])*180/numpy.pi
680 rgc[ih,:] = numpy.array([cv_gclon, cv_gclat, cv_gcalt])
683 rgc[ih,:] = numpy.array([cv_gclon, cv_gclat, cv_gcalt])
681
684
682 return bk, alpha, bfm, rr, rgc
685 return bk, alpha, bfm, rr, rgc
683
686
684
687
685 def __igrfkudeki(self,heights,time,latitude,longitude,ae=6371.2):
688 def __igrfkudeki(self,heights,time,latitude,longitude,ae=6371.2):
686 """
689 """
687 __igrfkudeki calculates the International Geomagnetic Reference Field for given in-
690 __igrfkudeki calculates the International Geomagnetic Reference Field for given in-
688 put conditions based on IGRF2005 coefficients.
691 put conditions based on IGRF2005 coefficients.
689
692
690 Parameters
693 Parameters
691 ----------
694 ----------
692 heights = Scalar or vector giving the height above the Earth of the point in ques-
695 heights = Scalar or vector giving the height above the Earth of the point in ques-
693 tion in kilometers.
696 tion in kilometers.
694 time = Scalar or vector giving the decimal year of time in question (e.g. 1991.2).
697 time = Scalar or vector giving the decimal year of time in question (e.g. 1991.2).
695 latitude = Latitude of point in question in decimal degrees. Scalar or vector.
698 latitude = Latitude of point in question in decimal degrees. Scalar or vector.
696 longitude = Longitude of point in question in decimal degrees. Scalar or vector.
699 longitude = Longitude of point in question in decimal degrees. Scalar or vector.
697 ae =
700 ae =
698 first_time =
701 first_time =
699
702
700 Return
703 Return
701 ------
704 ------
702 bn =
705 bn =
703 be =
706 be =
704 bd =
707 bd =
705 bmod =
708 bmod =
706 balpha =
709 balpha =
707 first_time =
710 first_time =
708
711
709 Modification History
712 Modification History
710 --------------------
713 --------------------
711 Converted to Python by Freddy R. Galindo, ROJ, 03 October 2009.
714 Converted to Python by Freddy R. Galindo, ROJ, 03 October 2009.
712 """
715 """
713
716
714 global first_time
717 global first_time
715 global gs, hs, nvec, mvec, maxcoef
718 global gs, hs, nvec, mvec, maxcoef
716
719
717 heights = numpy.atleast_1d(heights)
720 heights = numpy.atleast_1d(heights)
718 time = numpy.atleast_1d(time)
721 time = numpy.atleast_1d(time)
719 latitude = numpy.atleast_1d(latitude)
722 latitude = numpy.atleast_1d(latitude)
720 longitude = numpy.atleast_1d(longitude)
723 longitude = numpy.atleast_1d(longitude)
721
724
722 if numpy.max(latitude)==90:
725 if numpy.max(latitude)==90:
723 # print "Field calculations are not supported at geographic poles"
726 # print "Field calculations are not supported at geographic poles"
724 pass
727 pass
725
728
726 # output arrays
729 # output arrays
727 bn = numpy.zeros(heights.size)
730 bn = numpy.zeros(heights.size)
728 be = numpy.zeros(heights.size)
731 be = numpy.zeros(heights.size)
729 bd = numpy.zeros(heights.size)
732 bd = numpy.zeros(heights.size)
730
733
731 if first_time==None:first_time=0
734 if first_time==None:first_time=0
732
735
733 time0 = time[0]
736 time0 = time[0]
734 if time!=first_time:
737 if time!=first_time:
735 #print "Getting coefficients for", time0
738 #print "Getting coefficients for", time0
736 [periods,g,h ] = self.__readIGRFcoeff()
739 [periods,g,h ] = self.__readIGRFcoeff()
737 top_year = numpy.max(periods)
740 top_year = numpy.max(periods)
738 nperiod = (top_year - 1900)/5 + 1
741 nperiod = (top_year - 1900)/5 + 1
739
742
740 maxcoef = 10
743 maxcoef = 10
741 if time0>=2000:maxcoef = 12
744 if time0>=2000:maxcoef = 12
742
745
743
746
744 # Normalization array for Schmidt fucntions
747 # Normalization array for Schmidt fucntions
745 multer = numpy.zeros((2+maxcoef,1+maxcoef)) + 1
748 multer = numpy.zeros((2+maxcoef,1+maxcoef)) + 1
746 for cn in (numpy.arange(maxcoef)+1):
749 for cn in (numpy.arange(maxcoef)+1):
747 for rm in (numpy.arange(cn)+1):
750 for rm in (numpy.arange(cn)+1):
748 tmp = numpy.arange(2*rm) + cn - rm + 1.
751 tmp = numpy.arange(2*rm) + cn - rm + 1.
749 multer[rm+1,cn] = ((-1.)**rm)*numpy.sqrt(2./tmp.prod())
752 multer[rm+1,cn] = ((-1.)**rm)*numpy.sqrt(2./tmp.prod())
750
753
751 schmidt = multer[1:,1:].transpose()
754 schmidt = multer[1:,1:].transpose()
752
755
753 # n and m arrays
756 # n and m arrays
754 nvec = numpy.atleast_2d(numpy.arange(maxcoef)+2)
757 nvec = numpy.atleast_2d(numpy.arange(maxcoef)+2)
755 mvec = numpy.atleast_2d(numpy.arange(maxcoef+1)).transpose()
758 mvec = numpy.atleast_2d(numpy.arange(maxcoef+1)).transpose()
756
759
757 # Time adjusted igrf g and h with Schmidt normalization
760 # Time adjusted igrf g and h with Schmidt normalization
758 # IGRF coefficient arrays: g0(n,m), n=1, maxcoeff,m=0, maxcoeff, ...
761 # IGRF coefficient arrays: g0(n,m), n=1, maxcoeff,m=0, maxcoeff, ...
759 if time0<top_year:
762 if time0<top_year:
760 dtime = (time0 - 1900) % 5
763 dtime = (time0 - 1900) % 5
761 ntime = (time0 - 1900 - dtime)/5
764 ntime = (time0 - 1900 - dtime)/5
762 else:
765 else:
763 # Estimating coefficients for times > top_year
766 # Estimating coefficients for times > top_year
764 dtime = (time0 - top_year) + 5
767 dtime = (time0 - top_year) + 5
765 ntime = g[:,0,0].size - 2
768 ntime = g[:,0,0].size - 2
766
769
767 g0 = g[ntime,1:maxcoef+1,:maxcoef+1]
770 g0 = g[ntime,1:maxcoef+1,:maxcoef+1]
768 h0 = h[ntime,1:maxcoef+1,:maxcoef+1]
771 h0 = h[ntime,1:maxcoef+1,:maxcoef+1]
769 gdot = g[ntime+1,1:maxcoef+1,:maxcoef+1]-g[ntime,1:maxcoef+1,:maxcoef+1]
772 gdot = g[ntime+1,1:maxcoef+1,:maxcoef+1]-g[ntime,1:maxcoef+1,:maxcoef+1]
770 hdot = h[ntime+1,1:maxcoef+1,:maxcoef+1]-h[ntime,1:maxcoef+1,:maxcoef+1]
773 hdot = h[ntime+1,1:maxcoef+1,:maxcoef+1]-h[ntime,1:maxcoef+1,:maxcoef+1]
771 gs = (g0 + dtime*(gdot/5.))*schmidt[:maxcoef,0:maxcoef+1]
774 gs = (g0 + dtime*(gdot/5.))*schmidt[:maxcoef,0:maxcoef+1]
772 hs = (h0 + dtime*(hdot/5.))*schmidt[:maxcoef,0:maxcoef+1]
775 hs = (h0 + dtime*(hdot/5.))*schmidt[:maxcoef,0:maxcoef+1]
773
776
774 first_time = time0
777 first_time = time0
775
778
776 for ii in numpy.arange(heights.size):
779 for ii in numpy.arange(heights.size):
777 # Height dependence array rad = (ae/(ae+height))**(n+3)
780 # Height dependence array rad = (ae/(ae+height))**(n+3)
778 rad = numpy.atleast_2d((ae/(ae + heights[ii]))**(nvec+1))
781 rad = numpy.atleast_2d((ae/(ae + heights[ii]))**(nvec+1))
779
782
780 # Sin and Cos of m times longitude phi arrays
783 # Sin and Cos of m times longitude phi arrays
781 mphi = mvec*longitude[ii]*numpy.pi/180.
784 mphi = mvec*longitude[ii]*numpy.pi/180.
782 cosmphi = numpy.atleast_2d(numpy.cos(mphi))
785 cosmphi = numpy.atleast_2d(numpy.cos(mphi))
783 sinmphi = numpy.atleast_2d(numpy.sin(mphi))
786 sinmphi = numpy.atleast_2d(numpy.sin(mphi))
784
787
785 # Cos of colatitude theta
788 # Cos of colatitude theta
786 c = numpy.cos((90 - latitude[ii])*numpy.pi/180.)
789 c = numpy.cos((90 - latitude[ii])*numpy.pi/180.)
787
790
788 # Legendre functions p(n,m|c)
791 # Legendre functions p(n,m|c)
789 [p,dp]= scipy.special.lpmn(maxcoef+1,maxcoef+1,c)
792 [p,dp]= scipy.special.lpmn(maxcoef+1,maxcoef+1,c)
790 p = p[:,:-1].transpose()
793 p = p[:,:-1].transpose()
791 s = numpy.sqrt((1. - c)*(1 + c))
794 s = numpy.sqrt((1. - c)*(1 + c))
792
795
793 # Generate derivative array dpdtheta = -s*dpdc
796 # Generate derivative array dpdtheta = -s*dpdc
794 dpdtheta = c*p/s
797 dpdtheta = c*p/s
795 for m in numpy.arange(maxcoef+2): dpdtheta[:,m] = m*dpdtheta[:,m]
798 for m in numpy.arange(maxcoef+2): dpdtheta[:,m] = m*dpdtheta[:,m]
796 dpdtheta = dpdtheta + numpy.roll(p,-1,axis=1)
799 dpdtheta = dpdtheta + numpy.roll(p,-1,axis=1)
797
800
798 # Extracting arrays required for field calculations
801 # Extracting arrays required for field calculations
799 p = p[1:maxcoef+1,:maxcoef+1]
802 p = p[1:maxcoef+1,:maxcoef+1]
800 dpdtheta = dpdtheta[1:maxcoef+1,:maxcoef+1]
803 dpdtheta = dpdtheta[1:maxcoef+1,:maxcoef+1]
801
804
802 # Weigh p and dpdtheta with gs and hs coefficients.
805 # Weigh p and dpdtheta with gs and hs coefficients.
803 gp = gs*p
806 gp = gs*p
804 hp = hs*p
807 hp = hs*p
805 gdpdtheta = gs*dpdtheta
808 gdpdtheta = gs*dpdtheta
806 hdpdtheta = hs*dpdtheta
809 hdpdtheta = hs*dpdtheta
807 # Calcultate field components
810 # Calcultate field components
808 matrix0 = numpy.dot(gdpdtheta,cosmphi)
811 matrix0 = numpy.dot(gdpdtheta,cosmphi)
809 matrix1 = numpy.dot(hdpdtheta,sinmphi)
812 matrix1 = numpy.dot(hdpdtheta,sinmphi)
810 bn[ii] = numpy.dot(rad,(matrix0 + matrix1))
813 bn[ii] = numpy.dot(rad,(matrix0 + matrix1))
811 matrix0 = numpy.dot(hp,(mvec*cosmphi))
814 matrix0 = numpy.dot(hp,(mvec*cosmphi))
812 matrix1 = numpy.dot(gp,(mvec*sinmphi))
815 matrix1 = numpy.dot(gp,(mvec*sinmphi))
813 be[ii] = numpy.dot((-1*rad),((matrix0 - matrix1)/s))
816 be[ii] = numpy.dot((-1*rad),((matrix0 - matrix1)/s))
814 matrix0 = numpy.dot(gp,cosmphi)
817 matrix0 = numpy.dot(gp,cosmphi)
815 matrix1 = numpy.dot(hp,sinmphi)
818 matrix1 = numpy.dot(hp,sinmphi)
816 bd[ii] = numpy.dot((-1*nvec*rad),(matrix0 + matrix1))
819 bd[ii] = numpy.dot((-1*nvec*rad),(matrix0 + matrix1))
817
820
818 bmod = numpy.sqrt(bn**2. + be**2. + bd**2.)
821 bmod = numpy.sqrt(bn**2. + be**2. + bd**2.)
819 btheta = numpy.arctan(bd/numpy.sqrt(be**2. + bn**2.))*180/numpy.pi
822 btheta = numpy.arctan(bd/numpy.sqrt(be**2. + bn**2.))*180/numpy.pi
820 balpha = numpy.arctan(be/bn)*180./numpy.pi
823 balpha = numpy.arctan(be/bn)*180./numpy.pi
821
824
822 #bn : north
825 #bn : north
823 #be : east
826 #be : east
824 #bn : radial
827 #bn : radial
825 #bmod : module
828 #bmod : module
826
829
827
830
828 return bn, be, bd, bmod, btheta, balpha
831 return bn, be, bd, bmod, btheta, balpha
829
832
830 def str2num(self, datum):
833 def str2num(self, datum):
831 try:
834 try:
832 return int(datum)
835 return int(datum)
833 except:
836 except:
834 try:
837 try:
835 return float(datum)
838 return float(datum)
836 except:
839 except:
837 return datum
840 return datum
838
841
839 def __readIGRFfile(self, filename):
842 def __readIGRFfile(self, filename):
840 list_years=[]
843 list_years=[]
841 for i in range(1,24):
844 for i in range(1,24):
842 list_years.append(1895.0 + i*5)
845 list_years.append(1895.0 + i*5)
843
846
844 epochs=list_years
847 epochs=list_years
845 epochs.append(epochs[-1]+5)
848 epochs.append(epochs[-1]+5)
846 nepochs = numpy.shape(epochs)
849 nepochs = numpy.shape(epochs)
847
850
848 gg = numpy.zeros((13,14,nepochs[0]),dtype=float)
851 gg = numpy.zeros((13,14,nepochs[0]),dtype=float)
849 hh = numpy.zeros((13,14,nepochs[0]),dtype=float)
852 hh = numpy.zeros((13,14,nepochs[0]),dtype=float)
850
853
851 coeffs_file=open(filename)
854 coeffs_file=open(filename)
852 lines=coeffs_file.readlines()
855 lines=coeffs_file.readlines()
853
856
854 coeffs_file.close()
857 coeffs_file.close()
855
858
856 for line in lines:
859 for line in lines:
857 items = line.split()
860 items = line.split()
858 g_h = items[0]
861 g_h = items[0]
859 n = self.str2num(items[1])
862 n = self.str2num(items[1])
860 m = self.str2num(items[2])
863 m = self.str2num(items[2])
861
864
862 coeffs = items[3:]
865 coeffs = items[3:]
863
866
864 for i in range(len(coeffs)-1):
867 for i in range(len(coeffs)-1):
865 coeffs[i] = self.str2num(coeffs[i])
868 coeffs[i] = self.str2num(coeffs[i])
866
869
867 #coeffs = numpy.array(coeffs)
870 #coeffs = numpy.array(coeffs)
868 ncoeffs = numpy.shape(coeffs)[0]
871 ncoeffs = numpy.shape(coeffs)[0]
869
872
870 if g_h == 'g':
873 if g_h == 'g':
871 # print n," g ",m
874 # print n," g ",m
872 gg[n-1,m,:]=coeffs
875 gg[n-1,m,:]=coeffs
873 elif g_h=='h':
876 elif g_h=='h':
874 # print n," h ",m
877 # print n," h ",m
875 hh[n-1,m,:]=coeffs
878 hh[n-1,m,:]=coeffs
876 # else :
879 # else :
877 # continue
880 # continue
878
881
879 # Ultimo Reordenamiento para almacenar .
882 # Ultimo Reordenamiento para almacenar .
880 gg[:,:,nepochs[0]-1] = gg[:,:,nepochs[0]-2] + 5*gg[:,:,nepochs[0]-1]
883 gg[:,:,nepochs[0]-1] = gg[:,:,nepochs[0]-2] + 5*gg[:,:,nepochs[0]-1]
881 hh[:,:,nepochs[0]-1] = hh[:,:,nepochs[0]-2] + 5*hh[:,:,nepochs[0]-1]
884 hh[:,:,nepochs[0]-1] = hh[:,:,nepochs[0]-2] + 5*hh[:,:,nepochs[0]-1]
882
885
883 # return numpy.array([gg,hh])
886 # return numpy.array([gg,hh])
884 periods = numpy.array(epochs)
887 periods = numpy.array(epochs)
885 g = gg
888 g = gg
886 h = hh
889 h = hh
887 return periods, g, h
890 return periods, g, h
888
891
889
892
890 def __readIGRFcoeff(self,filename="igrf10coeffs.dat"):
893 def __readIGRFcoeff(self,filename="igrf10coeffs.dat"):
891 """
894 """
892 __readIGRFcoeff reads the coefficients from a binary file which is located in the
895 __readIGRFcoeff reads the coefficients from a binary file which is located in the
893 folder "resource."
896 folder "resource."
894
897
895 Parameter
898 Parameter
896 ---------
899 ---------
897 filename = A string to specify the name of the file which contains thec coeffs. The
900 filename = A string to specify the name of the file which contains thec coeffs. The
898 default value is "igrf10coeffs.dat"
901 default value is "igrf10coeffs.dat"
899
902
900 Return
903 Return
901 ------
904 ------
902 periods = A lineal array giving...
905 periods = A lineal array giving...
903 g1 =
906 g1 =
904 h1 =
907 h1 =
905
908
906 Modification History
909 Modification History
907 --------------------
910 --------------------
908 Converted to Python by Freddy R. Galindo, ROJ, 03 October 2009.
911 Converted to Python by Freddy R. Galindo, ROJ, 03 October 2009.
909 """
912 """
910
913
911 # # igrfile = sys.path[-1] + os.sep + "resource" + os.sep + filename
914 # # igrfile = sys.path[-1] + os.sep + "resource" + os.sep + filename
912 # igrfile = os.path.join('./resource',filename)
915 # igrfile = os.path.join('./resource',filename)
913 # f = open(igrfile,'rb')
916 # f = open(igrfile,'rb')
914 # #f = open(os.getcwd() + os.sep + "resource" + os.sep + filename,'rb')
917 # #f = open(os.getcwd() + os.sep + "resource" + os.sep + filename,'rb')
915 #
918 #
916 # # Reading SkyNoise Power (lineal scale)
919 # # Reading SkyNoise Power (lineal scale)
917 # periods = numpy.fromfile(f,numpy.dtype([('var','<f4')]),23)
920 # periods = numpy.fromfile(f,numpy.dtype([('var','<f4')]),23)
918 # periods = periods['var']
921 # periods = periods['var']
919 #
922 #
920 # g = numpy.fromfile(f,numpy.dtype([('var','<f8')]),23*14*14)
923 # g = numpy.fromfile(f,numpy.dtype([('var','<f8')]),23*14*14)
921 # g = g['var'].reshape((14,14,23)).transpose()
924 # g = g['var'].reshape((14,14,23)).transpose()
922 #
925 #
923 # h = numpy.fromfile(f,numpy.dtype([('var','<f8')]),23*14*14)
926 # h = numpy.fromfile(f,numpy.dtype([('var','<f8')]),23*14*14)
924 # h = h['var'].reshape((14,14,23)).transpose()
927 # h = h['var'].reshape((14,14,23)).transpose()
925 #
928 #
926 # f.close()
929 # f.close()
927 base_path = os.path.dirname(os.path.abspath(__file__))
930 base_path = os.path.dirname(os.path.abspath(__file__))
928 filename = os.path.join(base_path,"resource","igrf11coeffs.txt")
931 filename = os.path.join(base_path,"resource","igrf11coeffs.txt")
929
932
930 period_v, g_v, h_v = self.__readIGRFfile(filename)
933 period_v, g_v, h_v = self.__readIGRFfile(filename)
931 g2 = numpy.zeros((14,14,24))
934 g2 = numpy.zeros((14,14,24))
932 h2 = numpy.zeros((14,14,24))
935 h2 = numpy.zeros((14,14,24))
933 g2[1:14,:,:] = g_v
936 g2[1:14,:,:] = g_v
934 h2[1:14,:,:] = h_v
937 h2[1:14,:,:] = h_v
935
938
936 g = numpy.transpose(g2, (2,0,1))
939 g = numpy.transpose(g2, (2,0,1))
937 h = numpy.transpose(h2, (2,0,1))
940 h = numpy.transpose(h2, (2,0,1))
938 periods = period_v.copy()
941 periods = period_v.copy()
939
942
940 return periods, g, h
943 return periods, g, h
941
944
942 def rotvector(self,vector,axis=1,ang=0):
945 def rotvector(self,vector,axis=1,ang=0):
943 """
946 """
944 rotvector function returns the new vector generated rotating the rectagular coords.
947 rotvector function returns the new vector generated rotating the rectagular coords.
945
948
946 Parameters
949 Parameters
947 ----------
950 ----------
948 vector = A lineal 3-elements array (x,y,z).
951 vector = A lineal 3-elements array (x,y,z).
949 axis = A integer to specify the axis used to rotate the coord systems. The default
952 axis = A integer to specify the axis used to rotate the coord systems. The default
950 value is 1.
953 value is 1.
951 axis = 1 -> Around "x"
954 axis = 1 -> Around "x"
952 axis = 2 -> Around "y"
955 axis = 2 -> Around "y"
953 axis = 3 -> Around "z"
956 axis = 3 -> Around "z"
954 ang = Angle of rotation (in radians). The default value is zero.
957 ang = Angle of rotation (in radians). The default value is zero.
955
958
956 Return
959 Return
957 ------
960 ------
958 rotvector = A lineal array of 3 elements giving the new coordinates.
961 rotvector = A lineal array of 3 elements giving the new coordinates.
959
962
960 Modification History
963 Modification History
961 --------------------
964 --------------------
962 Converted to Python by Freddy R. Galindo, ROJ, 01 October 2009.
965 Converted to Python by Freddy R. Galindo, ROJ, 01 October 2009.
963 """
966 """
964
967
965 if axis==1:
968 if axis==1:
966 t = [[1,0,0],[0,numpy.cos(ang),numpy.sin(ang)],[0,-numpy.sin(ang),numpy.cos(ang)]]
969 t = [[1,0,0],[0,numpy.cos(ang),numpy.sin(ang)],[0,-numpy.sin(ang),numpy.cos(ang)]]
967 elif axis==2:
970 elif axis==2:
968 t = [[numpy.cos(ang),0,-numpy.sin(ang)],[0,1,0],[numpy.sin(ang),0,numpy.cos(ang)]]
971 t = [[numpy.cos(ang),0,-numpy.sin(ang)],[0,1,0],[numpy.sin(ang),0,numpy.cos(ang)]]
969 elif axis==3:
972 elif axis==3:
970 t = [[numpy.cos(ang),numpy.sin(ang),0],[-numpy.sin(ang),numpy.cos(ang),0],[0,0,1]]
973 t = [[numpy.cos(ang),numpy.sin(ang),0],[-numpy.sin(ang),numpy.cos(ang),0],[0,0,1]]
971
974
972 rotvector = numpy.array(numpy.dot(numpy.array(t),numpy.array(vector)))
975 rotvector = numpy.array(numpy.dot(numpy.array(t),numpy.array(vector)))
973
976
974 return rotvector
977 return rotvector
975
978
976
979
977 class overJroShow:
980 class overJroShow:
978
981
979 # __serverdocspath = '/usr/local/www/htdocs'
982 # __serverdocspath = '/usr/local/www/htdocs'
980 # __tmpDir = 'overJro/tempReports'
983 # __tmpDir = 'overJro/tempReports'
981 # __serverdocspath = '/Users/dsuarez/Pictures'
984 # __serverdocspath = '/Users/dsuarez/Pictures'
982 # __tmpDir = 'overjro'
985 # __tmpDir = 'overjro'
983 __serverdocspath = ''
986 __serverdocspath = ''
984 __tmpDir = ''
987 __tmpDir = ''
985
988
986 def __init__(self, title=''):
989 def __init__(self, title=''):
987 self.year = None
990 self.year = None
988 self.month = None
991 self.month = None
989 self.dom = None
992 self.dom = None
990 self.pattern = None
993 self.pattern = None
991 self.maxphi = None
994 self.maxphi = None
992 self.heights = None
995 self.heights = None
993 self.filename = None
996 self.filename = None
994 self.showType = None
997 self.showType = None
995 self.path = None
998 self.path = None
996 self.objects = None
999 self.objects = None
997 self.nptsx = 101
1000 self.nptsx = 101
998 self.nptsy = 101
1001 self.nptsy = 101
999 self.fftopt = 0
1002 self.fftopt = 0
1000 self.site = 1
1003 self.site = 1
1001 self.dcosx = 1
1004 self.dcosx = 1
1002 self.dcosy = 1
1005 self.dcosy = 1
1003 self.dcosxrange = None
1006 self.dcosxrange = None
1004 self.dcosyrange = None
1007 self.dcosyrange = None
1005 self.maxha_min= 0.
1008 self.maxha_min= 0.
1006 self.show_object = None
1009 self.show_object = None
1007 self.dcosx_mag = None
1010 self.dcosx_mag = None
1008 self.dcosy_mag = None
1011 self.dcosy_mag = None
1009 self.ha_mag = None
1012 self.ha_mag = None
1010 self.time_mag = None
1013 self.time_mag = None
1011 self.main_dec = None
1014 self.main_dec = None
1012 self.ObjC = None
1015 self.ObjC = None
1013 self.ptitle = title
1016 self.ptitle = title
1014 self.path4plotname = None
1017 self.path4plotname = None
1015 self.plotname0 = None
1018 self.plotname0 = None
1016 self.plotname1 = None
1019 self.plotname1 = None
1017 self.plotname2 = None
1020 self.plotname2 = None
1018 self.scriptHeaders = 0
1021 self.scriptHeaders = 0
1019 self.glat = -11.95
1022 self.glat = -11.95
1020 self.glon = -76.8667
1023 self.glon = -76.8667
1021 self.UT = 5 #timezone
1024 self.UT = 5 #timezone
1022
1025
1023 self.glat = -11.951481
1026 self.glat = -11.951481
1024 self.glon = -76.874383
1027 self.glon = -76.874383
1025 # self.outputHead('Show Plot')
1028 # self.outputHead('Show Plot')
1026 # self.printBody()
1029 # self.printBody()
1027
1030
1028 def setScriptState(self):
1031 def setScriptState(self):
1029 self.madForm = cgi.FieldStorage()
1032 self.madForm = cgi.FieldStorage()
1030
1033
1031 if self.madForm.has_key('serverdocspath'):
1034 if self.madForm.has_key('serverdocspath'):
1032 self.__serverdocspath = self.madForm.getvalue('serverdocspath')#'/usr/local/www/htdocs'
1035 self.__serverdocspath = self.madForm.getvalue('serverdocspath')#'/usr/local/www/htdocs'
1033
1036
1034 if self.madForm.has_key('tmpdir'):
1037 if self.madForm.has_key('tmpdir'):
1035 self.__tmpDir = self.madForm.getvalue('tmpdir')#'overJro/tempReports'
1038 self.__tmpDir = self.madForm.getvalue('tmpdir')#'overJro/tempReports'
1036
1039
1037 if self.madForm.has_key('showType'):
1040 if self.madForm.has_key('showType'):
1038 self.showType = int(self.madForm.getvalue('showType'))
1041 self.showType = int(self.madForm.getvalue('showType'))
1039
1042
1040 if self.showType == 0 or self.showType == 1:
1043 if self.showType == 0 or self.showType == 1:
1041
1044
1042 # if self.madForm.has_key('year') and \
1045 # if self.madForm.has_key('year') and \
1043 # self.madForm.has_key('month') and \
1046 # self.madForm.has_key('month') and \
1044 # self.madForm.has_key('dom') and \
1047 # self.madForm.has_key('dom') and \
1045 # self.madForm.has_key('pattern') and \
1048 # self.madForm.has_key('pattern') and \
1046 # self.madForm.has_key('maxphi') and \
1049 # self.madForm.has_key('maxphi') and \
1047 # self.madForm.has_key('objects') and \
1050 # self.madForm.has_key('objects') and \
1048 # self.madForm.has_key('heights'):
1051 # self.madForm.has_key('heights'):
1049
1052
1050 if self.madForm.has_key('year') and \
1053 if self.madForm.has_key('year') and \
1051 self.madForm.has_key('month') and \
1054 self.madForm.has_key('month') and \
1052 self.madForm.has_key('dom') and \
1055 self.madForm.has_key('dom') and \
1053 self.madForm.has_key('maxphi') and \
1056 self.madForm.has_key('maxphi') and \
1054 self.madForm.has_key('objects') and \
1057 self.madForm.has_key('objects') and \
1055 self.madForm.has_key('heights'):
1058 self.madForm.has_key('heights'):
1056
1059
1057 self.year = int(self.madForm.getvalue('year'))
1060 self.year = int(self.madForm.getvalue('year'))
1058 self.month = int(self.madForm.getvalue('month'))
1061 self.month = int(self.madForm.getvalue('month'))
1059 self.dom = int(self.madForm.getvalue('dom'))
1062 self.dom = int(self.madForm.getvalue('dom'))
1060 self.maxphi = float(self.madForm.getvalue('maxphi'))
1063 self.maxphi = float(self.madForm.getvalue('maxphi'))
1061
1064
1062 if self.madForm.has_key('pattern'):
1065 if self.madForm.has_key('pattern'):
1063
1066
1064 tmp_pattern = self.madForm.getvalue('pattern') #pattern es predifinido en listado o definido por el usuario
1067 tmp_pattern = self.madForm.getvalue('pattern') #pattern es predifinido en listado o definido por el usuario
1065 self.pattern=[]
1068 self.pattern=[]
1066 if tmp_pattern[0] == '[':
1069 if tmp_pattern[0] == '[':
1067 tmp_pattern=tmp_pattern[1:]
1070 tmp_pattern=tmp_pattern[1:]
1068
1071
1069 if tmp_pattern[-1] == ']':
1072 if tmp_pattern[-1] == ']':
1070 tmp_pattern=tmp_pattern[0:len(tmp_pattern)-1]
1073 tmp_pattern=tmp_pattern[0:len(tmp_pattern)-1]
1071
1074
1072 for s in tmp_pattern.split(','):
1075 for s in tmp_pattern.split(','):
1073 self.pattern.append(float(s))
1076 self.pattern.append(float(s))
1074 elif self.madForm.has_key('filename'):
1077 elif self.madForm.has_key('filename'):
1075 if self.madForm.has_key('filename'):
1078 if self.madForm.has_key('filename'):
1076 self.filename = self.madForm.getvalue('filename') # nombre de archivo: patron de radiacion definido por el usuario
1079 self.filename = self.madForm.getvalue('filename') # nombre de archivo: patron de radiacion definido por el usuario
1077
1080
1078 if self.madForm.has_key('path'):
1081 if self.madForm.has_key('path'):
1079 self.path = self.madForm.getvalue('path') #path donde se encuentra el archivo: patron de radiacion del usuario
1082 self.path = self.madForm.getvalue('path') #path donde se encuentra el archivo: patron de radiacion del usuario
1080
1083
1081 else:
1084 else:
1082 print ("Content-Type: text/html\n")
1085 print ("Content-Type: text/html\n")
1083 print ('<h3> This cgi plot script was called without the proper arguments.</h3>')
1086 print ('<h3> This cgi plot script was called without the proper arguments.</h3>')
1084 print ('<p> This is a script used to plot Antenna Cuts over Jicamarca Antenna</p>')
1087 print ('<p> This is a script used to plot Antenna Cuts over Jicamarca Antenna</p>')
1085 print ('<p> Required arguments:</p>')
1088 print ('<p> Required arguments:</p>')
1086 print ('<p> pattern - chekbox indicating objects over jicamarca antenna</p>')
1089 print ('<p> pattern - chekbox indicating objects over jicamarca antenna</p>')
1087 print ('<p> or')
1090 print ('<p> or')
1088 print ('<p> filename - The pattern defined by users is a file text')
1091 print ('<p> filename - The pattern defined by users is a file text')
1089 print ('<p> path - folder with pattern files')
1092 print ('<p> path - folder with pattern files')
1090 sys.exit(0)
1093 sys.exit(0)
1091
1094
1092
1095
1093 tmp_heights = self.madForm.getvalue('heights')
1096 tmp_heights = self.madForm.getvalue('heights')
1094 self.heights=[]
1097 self.heights=[]
1095 if tmp_heights[0] == '[':
1098 if tmp_heights[0] == '[':
1096 tmp_heights=tmp_heights[1:]
1099 tmp_heights=tmp_heights[1:]
1097
1100
1098 if tmp_heights[-1] == ']':
1101 if tmp_heights[-1] == ']':
1099 tmp_heights=tmp_heights[0:len(tmp_heights)-1]
1102 tmp_heights=tmp_heights[0:len(tmp_heights)-1]
1100
1103
1101 for s in tmp_heights.split(','):
1104 for s in tmp_heights.split(','):
1102 self.heights.append(float(s))
1105 self.heights.append(float(s))
1103 self.heights = numpy.array(self.heights)
1106 self.heights = numpy.array(self.heights)
1104
1107
1105 tmp_objects = self.madForm.getvalue('objects') #lista con los objetos a graficar en el patron de radiacion
1108 tmp_objects = self.madForm.getvalue('objects') #lista con los objetos a graficar en el patron de radiacion
1106 self.objects=[]
1109 self.objects=[]
1107 if tmp_objects[0] == '[':
1110 if tmp_objects[0] == '[':
1108 tmp_objects=tmp_objects[1:]
1111 tmp_objects=tmp_objects[1:]
1109
1112
1110 if tmp_objects[-1] == ']':
1113 if tmp_objects[-1] == ']':
1111 tmp_objects=tmp_objects[0:len(tmp_objects)-1]
1114 tmp_objects=tmp_objects[0:len(tmp_objects)-1]
1112
1115
1113 for s in tmp_objects.split(','):
1116 for s in tmp_objects.split(','):
1114 self.objects.append(int(s))
1117 self.objects.append(int(s))
1115
1118
1116 if self.showType == 1:
1119 if self.showType == 1:
1117 if numpy.sum(self.objects) == 0:
1120 if numpy.sum(self.objects) == 0:
1118 if self.scriptHeaders == 0:
1121 if self.scriptHeaders == 0:
1119 print ("Content-Type: text/html\n")
1122 print ("Content-Type: text/html\n")
1120 print ('<h3> This cgi plot script was called without the proper arguments.</h3>')
1123 print ('<h3> This cgi plot script was called without the proper arguments.</h3>')
1121 print ('<p> This is a script used to plot Antenna Cuts over Jicamarca Antenna</p>')
1124 print ('<p> This is a script used to plot Antenna Cuts over Jicamarca Antenna</p>')
1122 print ('<p> Required arguments:</p>')
1125 print ('<p> Required arguments:</p>')
1123 print ('<p> objects - chekbox indicating objects over jicamarca antenna</p>')
1126 print ('<p> objects - chekbox indicating objects over jicamarca antenna</p>')
1124 print ('<p> Please, options in "Select Object" must be checked')
1127 print ('<p> Please, options in "Select Object" must be checked')
1125 sys.exit(0)
1128 sys.exit(0)
1126
1129
1127 #considerar para futura implementacion
1130 #considerar para futura implementacion
1128 if self.madForm.has_key('filename'):
1131 if self.madForm.has_key('filename'):
1129 self.filename = self.madForm.getvalue('filename') # nombre de archivo: patron de radiacion definido por el usuario
1132 self.filename = self.madForm.getvalue('filename') # nombre de archivo: patron de radiacion definido por el usuario
1130
1133
1131 if self.madForm.has_key('path'):
1134 if self.madForm.has_key('path'):
1132 self.path = self.madForm.getvalue('path') #path donde se encuentra el archivo: patron de radiacion del usuario
1135 self.path = self.madForm.getvalue('path') #path donde se encuentra el archivo: patron de radiacion del usuario
1133
1136
1134
1137
1135 else:
1138 else:
1136 if self.scriptHeaders == 0:
1139 if self.scriptHeaders == 0:
1137 print ("Content-Type: text/html\n")
1140 print ("Content-Type: text/html\n")
1138
1141
1139 print ('<h3> This cgi plot script was called without the proper arguments.</h3>')
1142 print ('<h3> This cgi plot script was called without the proper arguments.</h3>')
1140 print ('<p> This is a script used to plot Pattern Field and Celestial Objects over Jicamarca Antenna</p>')
1143 print ('<p> This is a script used to plot Pattern Field and Celestial Objects over Jicamarca Antenna</p>')
1141 print ('<p> Required arguments:</p>')
1144 print ('<p> Required arguments:</p>')
1142 print ('<p> year - year of event</p>')
1145 print ('<p> year - year of event</p>')
1143 print ('<p> month - month of event</p>')
1146 print ('<p> month - month of event</p>')
1144 print ('<p> dom - day of month</p>')
1147 print ('<p> dom - day of month</p>')
1145 print ('<p> pattern - pattern is defined by "Select an Experiment" list box</p>')
1148 print ('<p> pattern - pattern is defined by "Select an Experiment" list box</p>')
1146 print ('<p> maxphi - maxphi is defined by "Max Angle" text box</p>')
1149 print ('<p> maxphi - maxphi is defined by "Max Angle" text box</p>')
1147 print ('<p> objects - objects is a list defined by checkbox in "Select Object"</p>')
1150 print ('<p> objects - objects is a list defined by checkbox in "Select Object"</p>')
1148 print ('<p> heights - heights is defined by "Heights" text box, for default heights=[100,500,1000]</p>')
1151 print ('<p> heights - heights is defined by "Heights" text box, for default heights=[100,500,1000]</p>')
1149 print ('<p> showType - showType is a hidden element for show plot of Pattern&Object or Antenna Cuts or Sky Noise</p>')
1152 print ('<p> showType - showType is a hidden element for show plot of Pattern&Object or Antenna Cuts or Sky Noise</p>')
1150
1153
1151 sys.exit(0)
1154 sys.exit(0)
1152
1155
1153 if self.showType == 2:
1156 if self.showType == 2:
1154 if self.madForm.has_key('year') and \
1157 if self.madForm.has_key('year') and \
1155 self.madForm.has_key('month') and \
1158 self.madForm.has_key('month') and \
1156 self.madForm.has_key('dom'):
1159 self.madForm.has_key('dom'):
1157
1160
1158 self.year = int(self.madForm.getvalue('year'))
1161 self.year = int(self.madForm.getvalue('year'))
1159 self.month = int(self.madForm.getvalue('month'))
1162 self.month = int(self.madForm.getvalue('month'))
1160 self.dom = int(self.madForm.getvalue('dom'))
1163 self.dom = int(self.madForm.getvalue('dom'))
1161
1164
1162 else:
1165 else:
1163 if self.scriptHeaders == 0:
1166 if self.scriptHeaders == 0:
1164 print ("Content-Type: text/html\n")
1167 print ("Content-Type: text/html\n")
1165 print ('<h3> This cgi plot script was called without the proper arguments.</h3>')
1168 print ('<h3> This cgi plot script was called without the proper arguments.</h3>')
1166 print ('<p> This is a script used to plot Sky Noise over Jicamarca Antenna</p>')
1169 print ('<p> This is a script used to plot Sky Noise over Jicamarca Antenna</p>')
1167 print ('<p> Required arguments:</p>')
1170 print ('<p> Required arguments:</p>')
1168 print ('<p> year - year of event</p>')
1171 print ('<p> year - year of event</p>')
1169 print ('<p> month - month of event</p>')
1172 print ('<p> month - month of event</p>')
1170 print ('<p> dom - day of month</p>')
1173 print ('<p> dom - day of month</p>')
1171
1174
1172 sys.exit(0)
1175 sys.exit(0)
1173
1176
1174
1177
1175 def initParameters1(self):
1178 def initParameters1(self):
1176
1179
1177 gui=1
1180 gui=1
1178 if self.pattern==None:
1181 if self.pattern==None:
1179 if gui==1: self.filename = self.filename.split(',')
1182 if gui==1: self.filename = self.filename.split(',')
1180
1183
1181 pattern = numpy.atleast_1d(self.pattern)
1184 pattern = numpy.atleast_1d(self.pattern)
1182 filename = numpy.atleast_1d(self.filename)
1185 filename = numpy.atleast_1d(self.filename)
1183
1186
1184 npatterns = numpy.max(numpy.array([pattern.size,filename.size]))
1187 npatterns = numpy.max(numpy.array([pattern.size,filename.size]))
1185
1188
1186 self.pattern = numpy.resize(pattern,npatterns)
1189 self.pattern = numpy.resize(pattern,npatterns)
1187 self.filename = numpy.resize(filename,npatterns)
1190 self.filename = numpy.resize(filename,npatterns)
1188
1191
1189 self.doy = datetime.datetime(self.year,self.month,self.dom).timetuple().tm_yday
1192 self.doy = datetime.datetime(self.year,self.month,self.dom).timetuple().tm_yday
1190
1193
1191
1194
1192 if self.objects==None:
1195 if self.objects==None:
1193 self.objects=numpy.zeros(5)
1196 self.objects=numpy.zeros(5)
1194 else:
1197 else:
1195 tmp = numpy.atleast_1d(self.objects)
1198 tmp = numpy.atleast_1d(self.objects)
1196 self.objects = numpy.zeros(5)
1199 self.objects = numpy.zeros(5)
1197 self.objects[0:tmp.size] = tmp
1200 self.objects[0:tmp.size] = tmp
1198
1201
1199 self.show_object = self.objects
1202 self.show_object = self.objects
1200
1203
1201 self.maxha_min = 4*self.maxphi*numpy.sqrt(2)*1.25
1204 self.maxha_min = 4*self.maxphi*numpy.sqrt(2)*1.25
1202
1205
1203
1206
1204 if self.heights==None:
1207 if self.heights==None:
1205 self.heights = numpy.array([100.,500.,1000.])
1208 self.heights = numpy.array([100.,500.,1000.])
1206
1209
1207
1210
1208
1211
1209 #ROJ geographic coordinates and time zone
1212 #ROJ geographic coordinates and time zone
1210 self.glat = -11.95
1213 self.glat = -11.95
1211 self.glon = -76.8667
1214 self.glon = -76.8667
1212 self.UT = 5 #timezone
1215 self.UT = 5 #timezone
1213
1216
1214 self.glat = -11.951481
1217 self.glat = -11.951481
1215 self.glon = -76.874383
1218 self.glon = -76.874383
1216
1219
1217
1220
1218 self.junkjd = Time(self.year,self.month,self.dom).change2julday()
1221 self.junkjd = Time(self.year,self.month,self.dom).change2julday()
1219 self.junklst = Julian(self.junkjd).change2lst(longitude=self.glon)
1222 self.junklst = Julian(self.junkjd).change2lst(longitude=self.glon)
1220
1223
1221 # Finding RA of observatory for a specific date
1224 # Finding RA of observatory for a specific date
1222 self.ra_obs = self.junklst*CoFactors.h2d
1225 self.ra_obs = self.junklst*CoFactors.h2d
1223
1226
1224 def initParameters(self):
1227 def initParameters(self):
1225
1228
1226 # Defining plot filenames
1229 # Defining plot filenames
1227 self.path4plotname = os.path.join(self.__serverdocspath,self.__tmpDir)
1230 self.path4plotname = os.path.join(self.__serverdocspath,self.__tmpDir)
1228 self.plotname0 = 'over_jro_0_%i.png'% (time.time()) #plot pattern & objects
1231 self.plotname0 = 'over_jro_0_%i.png'% (time.time()) #plot pattern & objects
1229 self.plotname1 = 'over_jro_1_%i.png'% (time.time()) #plot antenna cuts
1232 self.plotname1 = 'over_jro_1_%i.png'% (time.time()) #plot antenna cuts
1230 self.plotname2 = 'over_jro_2_%i.png'% (time.time()) #plot sky noise
1233 self.plotname2 = 'over_jro_2_%i.png'% (time.time()) #plot sky noise
1231
1234
1232 # Defining antenna axes respect to geographic coordinates (See Ochs report).
1235 # Defining antenna axes respect to geographic coordinates (See Ochs report).
1233 # alfa = 1.46*Misc_Routines.CoFactors.d2r
1236 # alfa = 1.46*Misc_Routines.CoFactors.d2r
1234 # theta = 51.01*Misc_Routines.CoFactors.d2r
1237 # theta = 51.01*Misc_Routines.CoFactors.d2r
1235
1238
1236 alfa = 1.488312*CoFactors.d2r
1239 alfa = 1.488312*CoFactors.d2r
1237 th = 6.166710 + 45.0
1240 th = 6.166710 + 45.0
1238 theta = th*CoFactors.d2r
1241 theta = th*CoFactors.d2r
1239
1242
1240 sina = numpy.sin(alfa)
1243 sina = numpy.sin(alfa)
1241 cosa = numpy.cos(alfa)
1244 cosa = numpy.cos(alfa)
1242 MT1 = numpy.array([[1,0,0],[0,cosa,-sina],[0,sina,cosa]])
1245 MT1 = numpy.array([[1,0,0],[0,cosa,-sina],[0,sina,cosa]])
1243 sinb = numpy.sin(theta)
1246 sinb = numpy.sin(theta)
1244 cosb = numpy.cos(theta)
1247 cosb = numpy.cos(theta)
1245 MT2 = numpy.array([[cosb,sinb,0],[-sinb,cosb,0],[0,0,1]])
1248 MT2 = numpy.array([[cosb,sinb,0],[-sinb,cosb,0],[0,0,1]])
1246 self.MT3 = numpy.array(numpy.dot(MT2, MT1)).transpose()
1249 self.MT3 = numpy.array(numpy.dot(MT2, MT1)).transpose()
1247
1250
1248 self.xg = numpy.dot(self.MT3.transpose(),numpy.array([1,0,0]))
1251 self.xg = numpy.dot(self.MT3.transpose(),numpy.array([1,0,0]))
1249 self.yg = numpy.dot(self.MT3.transpose(),numpy.array([0,1,0]))
1252 self.yg = numpy.dot(self.MT3.transpose(),numpy.array([0,1,0]))
1250 self.zg = numpy.dot(self.MT3.transpose(),numpy.array([0,0,1]))
1253 self.zg = numpy.dot(self.MT3.transpose(),numpy.array([0,0,1]))
1251
1254
1252 def plotPattern2(self, date, phases, gain_tx, gain_rx, ues, just_rx):
1255 def plotPattern2(self, date, phases, gain_tx, gain_rx, ues, just_rx):
1253 # Plotting Antenna patterns.
1256 # Plotting Antenna patterns.
1254
1257
1255 self.initParameters()
1258 self.initParameters()
1256 self.doy = datetime.datetime(date.year,date.month,date.day).timetuple().tm_yday
1259 self.doy = datetime.datetime(date.year,date.month,date.day).timetuple().tm_yday
1257 self.junkjd = Time(self.year,self.month,self.dom).change2julday()
1260 self.junkjd = Time(self.year,self.month,self.dom).change2julday()
1258 self.junklst = Julian(self.junkjd).change2lst(longitude=self.glon)
1261 self.junklst = Julian(self.junkjd).change2lst(longitude=self.glon)
1259 self.ra_obs = self.junklst*CoFactors.h2d
1262 self.ra_obs = self.junklst*CoFactors.h2d
1260
1263
1261 date = Time(date.year,date.month,date.day).change2strdate(mode=2)
1264 date = Time(date.year,date.month,date.day).change2strdate(mode=2)
1262
1265
1263 mesg = 'Over Jicamarca: ' + date[0]
1266 mesg = 'Over Jicamarca: ' + date[0]
1264
1267
1265 ObjAnt = JroPattern(pattern=0,
1268 ObjAnt = JroPattern(pattern=0,
1266 filename=None,
1269 filename=None,
1267 path=None,
1270 path=None,
1268 nptsx=self.nptsx,
1271 nptsx=self.nptsx,
1269 nptsy=self.nptsy,
1272 nptsy=self.nptsy,
1270 #maxphi=self.maxphi,
1273 #maxphi=self.maxphi,
1271 fftopt=self.fftopt,
1274 fftopt=self.fftopt,
1272 phases=numpy.array(phases),
1275 phases=numpy.array(phases),
1273 gain_tx=numpy.array(gain_tx),
1276 gain_tx=numpy.array(gain_tx),
1274 gain_rx=numpy.array(gain_rx),
1277 gain_rx=numpy.array(gain_rx),
1275 ues=numpy.array(ues),
1278 ues=numpy.array(ues),
1276 just_rx=just_rx
1279 just_rx=just_rx
1277 )
1280 )
1278
1281
1279 dum = AntPatternPlot()
1282 dum = AntPatternPlot()
1280
1283
1281 dum.contPattern(iplot=0,
1284 dum.contPattern(iplot=0,
1282 gpath=self.path4plotname,
1285 gpath=self.path4plotname,
1283 filename=self.plotname0,
1286 filename=self.plotname0,
1284 mesg=mesg,
1287 mesg=mesg,
1285 amp=ObjAnt.norpattern,
1288 amp=ObjAnt.norpattern,
1286 x=ObjAnt.dcosx,
1289 x=ObjAnt.dcosx,
1287 y=ObjAnt.dcosy,
1290 y=ObjAnt.dcosy,
1288 getCut=ObjAnt.getcut,
1291 getCut=ObjAnt.getcut,
1289 title=self.ptitle,
1292 title=self.ptitle,
1290 save=False)
1293 save=False)
1291
1294
1292
1295
1293 dum.plotRaDec(gpath=self.path4plotname,
1296 dum.plotRaDec(gpath=self.path4plotname,
1294 filename=self.plotname0,
1297 filename=self.plotname0,
1295 jd=self.junkjd,
1298 jd=self.junkjd,
1296 ra_obs=self.ra_obs,
1299 ra_obs=self.ra_obs,
1297 xg=self.xg,
1300 xg=self.xg,
1298 yg=self.yg,
1301 yg=self.yg,
1299 x=ObjAnt.dcosx,
1302 x=ObjAnt.dcosx,
1300 y=ObjAnt.dcosy,
1303 y=ObjAnt.dcosy,
1301 save=False)
1304 save=False)
1302
1305
1303 ObjB = BField(self.year,self.doy,1,self.heights)
1306 ObjB = BField(self.year,self.doy,1,self.heights)
1304 [dcos, alpha, nlon, nlat] = ObjB.getBField()
1307 [dcos, alpha, nlon, nlat] = ObjB.getBField()
1305
1308
1306 dum.plotBField('', '',dcos,alpha,nlon,nlat,
1309 dum.plotBField('', '',dcos,alpha,nlon,nlat,
1307 self.dcosxrange,
1310 self.dcosxrange,
1308 self.dcosyrange,
1311 self.dcosyrange,
1309 ObjB.heights,
1312 ObjB.heights,
1310 ObjB.alpha_i,
1313 ObjB.alpha_i,
1311 save=False)
1314 save=False)
1312
1315
1313 return dum.fig
1316 return dum.fig
1314
1317
1315
1318
1316 def plotPattern(self):
1319 def plotPattern(self):
1317 # Plotting Antenna patterns.
1320 # Plotting Antenna patterns.
1318 npatterns = numpy.size(self.pattern)
1321 npatterns = numpy.size(self.pattern)
1319
1322
1320 if npatterns==1:
1323 if npatterns==1:
1321 if self.pattern[0] == None: npatterns = self.filename.__len__()
1324 if self.pattern[0] == None: npatterns = self.filename.__len__()
1322
1325
1323 date = TimeTools.Time(self.year,self.month,self.dom).change2strdate(mode=2)
1326 date = TimeTools.Time(self.year,self.month,self.dom).change2strdate(mode=2)
1324
1327
1325 mesg = 'Over Jicamarca: ' + date[0]
1328 mesg = 'Over Jicamarca: ' + date[0]
1326
1329
1327 title = ''
1330 title = ''
1328
1331
1329 for ii in numpy.arange(npatterns):
1332 for ii in numpy.arange(npatterns):
1330 ObjAnt = JroPattern(pattern=self.pattern[ii],
1333 ObjAnt = JroPattern(pattern=self.pattern[ii],
1331 filename=self.filename[ii],
1334 filename=self.filename[ii],
1332 path=self.path,
1335 path=self.path,
1333 nptsx=self.nptsx,
1336 nptsx=self.nptsx,
1334 nptsy=self.nptsy,
1337 nptsy=self.nptsy,
1335 maxphi=self.maxphi,
1338 maxphi=self.maxphi,
1336 fftopt=self.fftopt)
1339 fftopt=self.fftopt)
1337
1340
1338 title += ObjAnt.title
1341 title += ObjAnt.title
1339 # Plotting Contour Map
1342 # Plotting Contour Map
1340
1343
1341 self.path4plotname = '/home/jespinoza/workspace/radarsys/trunk/webapp/apps/abs/static/images'
1344 self.path4plotname = '/home/jespinoza/workspace/radarsys/trunk/webapp/apps/abs/static/images'
1342 dum = AntPatternPlot()
1345 dum = AntPatternPlot()
1343 dum.contPattern(iplot=ii,
1346 dum.contPattern(iplot=ii,
1344 gpath=self.path4plotname,
1347 gpath=self.path4plotname,
1345 filename=self.plotname0,
1348 filename=self.plotname0,
1346 mesg=mesg,
1349 mesg=mesg,
1347 amp=ObjAnt.norpattern,
1350 amp=ObjAnt.norpattern,
1348 x=ObjAnt.dcosx,
1351 x=ObjAnt.dcosx,
1349 y=ObjAnt.dcosy,
1352 y=ObjAnt.dcosy,
1350 getCut=ObjAnt.getcut,
1353 getCut=ObjAnt.getcut,
1351 title=title)
1354 title=title)
1352 # title=ObjAnt.title)
1355 # title=ObjAnt.title)
1353 # self.ptitle = ObjAnt.title
1356 # self.ptitle = ObjAnt.title
1354
1357
1355 if ii != (npatterns-1):
1358 if ii != (npatterns-1):
1356 title += '+'
1359 title += '+'
1357
1360
1358
1361
1359 vect_ant = numpy.array([ObjAnt.meanpos[0],ObjAnt.meanpos[1],numpy.sqrt(1-numpy.sum(ObjAnt.meanpos**2.))])
1362 vect_ant = numpy.array([ObjAnt.meanpos[0],ObjAnt.meanpos[1],numpy.sqrt(1-numpy.sum(ObjAnt.meanpos**2.))])
1360
1363
1361 vect_geo = numpy.dot(scipy.linalg.inv(self.MT3),vect_ant)
1364 vect_geo = numpy.dot(scipy.linalg.inv(self.MT3),vect_ant)
1362
1365
1363 vect_polar = Misc_Routines.Vector(numpy.array(vect_geo),direction=1).Polar2Rect()
1366 vect_polar = Misc_Routines.Vector(numpy.array(vect_geo),direction=1).Polar2Rect()
1364
1367
1365 [ra,dec,ha] = Astro_Coords.AltAz(vect_polar[1],vect_polar[0],self.junkjd).change2equatorial()
1368 [ra,dec,ha] = AltAz(vect_polar[1],vect_polar[0],self.junkjd).change2equatorial()
1366
1369
1367 print('Main beam position (HA(min), DEC(degrees)): %f %f')%(ha*4.,dec)
1370 print('Main beam position (HA(min), DEC(degrees)): %f %f')%(ha*4.,dec)
1368
1371
1369 self.main_dec = dec
1372 self.main_dec = dec
1370
1373
1371 self.ptitle = title
1374 self.ptitle = title
1372
1375
1373 AntPatternPlot().plotRaDec(gpath=self.path4plotname,
1376 AntPatternPlot().plotRaDec(gpath=self.path4plotname,
1374 filename=self.plotname0,
1377 filename=self.plotname0,
1375 jd=self.junkjd,
1378 jd=self.junkjd,
1376 ra_obs=self.ra_obs,
1379 ra_obs=self.ra_obs,
1377 xg=self.xg,
1380 xg=self.xg,
1378 yg=self.yg,
1381 yg=self.yg,
1379 x=ObjAnt.dcosx,
1382 x=ObjAnt.dcosx,
1380 y=ObjAnt.dcosy)
1383 y=ObjAnt.dcosy)
1381
1384
1382 self.dcosx = ObjAnt.dcosx
1385 self.dcosx = ObjAnt.dcosx
1383
1386
1384 self.dcosy = ObjAnt.dcosy
1387 self.dcosy = ObjAnt.dcosy
1385
1388
1386 self.dcosxrange = [numpy.min(self.dcosx),numpy.max(self.dcosx)]
1389 self.dcosxrange = [numpy.min(self.dcosx),numpy.max(self.dcosx)]
1387
1390
1388 self.dcosyrange = [numpy.min(self.dcosy),numpy.max(self.dcosy)]
1391 self.dcosyrange = [numpy.min(self.dcosy),numpy.max(self.dcosy)]
1389
1392
1390 def plotBfield(self):
1393 def plotBfield(self):
1391
1394
1392 if self.show_object[0]>0:
1395 if self.show_object[0]>0:
1393 # Getting B field
1396 # Getting B field
1394 ObjB = BField(self.year,self.doy,self.site,self.heights)
1397 ObjB = BField(self.year,self.doy,self.site,self.heights)
1395
1398
1396
1399
1397 [dcos, alpha, nlon, nlat] = ObjB.getBField()
1400 [dcos, alpha, nlon, nlat] = ObjB.getBField()
1398
1401
1399 # Plotting B field.
1402 # Plotting B field.
1400 # print "Drawing magnetic field over Observatory"
1403 # print "Drawing magnetic field over Observatory"
1401
1404
1402 Obj = BFieldPlot()
1405 Obj = BFieldPlot()
1403
1406
1404 Obj.plotBField(self.path4plotname,self.plotname0,dcos,alpha,nlon,nlat,self.dcosxrange,self.dcosyrange,ObjB.heights,ObjB.alpha_i)
1407 Obj.plotBField(self.path4plotname,self.plotname0,dcos,alpha,nlon,nlat,self.dcosxrange,self.dcosyrange,ObjB.heights,ObjB.alpha_i)
1405
1408
1406 if self.show_object[0]>1:
1409 if self.show_object[0]>1:
1407
1410
1408 Bhei = 0
1411 Bhei = 0
1409
1412
1410 dcosx = Obj.alpha_location[:,0,Bhei]
1413 dcosx = Obj.alpha_location[:,0,Bhei]
1411
1414
1412 dcosy = Obj.alpha_location[:,1,Bhei]
1415 dcosy = Obj.alpha_location[:,1,Bhei]
1413
1416
1414 vect_ant = [dcosx,dcosy,numpy.sqrt(1.-(dcosx**2. + dcosy**2.))]
1417 vect_ant = [dcosx,dcosy,numpy.sqrt(1.-(dcosx**2. + dcosy**2.))]
1415
1418
1416 vect_ant = numpy.array(vect_ant)
1419 vect_ant = numpy.array(vect_ant)
1417
1420
1418 vect_geo = numpy.dot(scipy.linalg.inv(self.MT3),vect_ant)
1421 vect_geo = numpy.dot(scipy.linalg.inv(self.MT3),vect_ant)
1419
1422
1420 vect_geo = numpy.array(vect_geo).transpose()
1423 vect_geo = numpy.array(vect_geo).transpose()
1421
1424
1422 vect_polar = Misc_Routines.Vector(vect_geo,direction=1).Polar2Rect()
1425 vect_polar = Misc_Routines.Vector(vect_geo,direction=1).Polar2Rect()
1423
1426
1424 [ra,dec,ha] = Astro_Coords.AltAz(vect_polar[1,:],vect_polar[0,:],self.junkjd).change2equatorial()
1427 [ra,dec,ha] = AltAz(vect_polar[1,:],vect_polar[0,:],self.junkjd).change2equatorial()
1425
1428
1426 val = numpy.where(ha>=180)
1429 val = numpy.where(ha>=180)
1427
1430
1428 if val[0].size>0:ha[val] = ha[val] -360.
1431 if val[0].size>0:ha[val] = ha[val] -360.
1429
1432
1430 val = numpy.where(numpy.abs(ha)<=self.maxphi)
1433 val = numpy.where(numpy.abs(ha)<=self.maxphi)
1431
1434
1432 if val[0].size>2:
1435 if val[0].size>2:
1433
1436
1434 self.dcosx_mag = dcosx[val]
1437 self.dcosx_mag = dcosx[val]
1435
1438
1436 self.dcosy_mag = dcosy[val]
1439 self.dcosy_mag = dcosy[val]
1437
1440
1438 self.ha_mag = ha[val]
1441 self.ha_mag = ha[val]
1439
1442
1440 self.time_mag = 0
1443 self.time_mag = 0
1441
1444
1442 def plotCelestial(self):
1445 def plotCelestial(self):
1443
1446
1444 ntod = 24.*16.
1447 ntod = 24.*16.
1445
1448
1446 tod = numpy.arange(ntod)/ntod*24.
1449 tod = numpy.arange(ntod)/ntod*24.
1447
1450
1448 [month,dom] = Doy2Date(self.year,self.doy).change2date()
1451 [month,dom] = Doy2Date(self.year,self.doy).change2date()
1449
1452
1450 jd = Time(self.year,month,dom,tod+self.UT).change2julday()
1453 jd = Time(self.year,month,dom,tod+self.UT).change2julday()
1451
1454
1452 if numpy.sum(self.show_object[1:]>0)!=0:
1455 if numpy.sum(self.show_object[1:]>0)!=0:
1453
1456
1454 self.ObjC = CelestialObjectsPlot(jd,self.main_dec,tod,self.maxha_min,self.show_object)
1457 self.ObjC = CelestialObjectsPlot(jd,self.main_dec,tod,self.maxha_min,self.show_object)
1455
1458
1456 self.ObjC.drawObject(self.glat,
1459 self.ObjC.drawObject(self.glat,
1457 self.glon,
1460 self.glon,
1458 self.xg,
1461 self.xg,
1459 self.yg,
1462 self.yg,
1460 self.dcosxrange,
1463 self.dcosxrange,
1461 self.dcosyrange,
1464 self.dcosyrange,
1462 self.path4plotname,
1465 self.path4plotname,
1463 self.plotname0)
1466 self.plotname0)
1464
1467
1465 def plotAntennaCuts(self):
1468 def plotAntennaCuts(self):
1466 # print "Drawing antenna cuts"
1469 # print "Drawing antenna cuts"
1467
1470
1468 incha = 0.05 # min
1471 incha = 0.05 # min
1469 nha = numpy.int32(2*self.maxha_min/incha) + 1.
1472 nha = numpy.int32(2*self.maxha_min/incha) + 1.
1470 newha = numpy.arange(nha)/nha*2.*self.maxha_min - self.maxha_min
1473 newha = numpy.arange(nha)/nha*2.*self.maxha_min - self.maxha_min
1471 nha_star = numpy.int32(200./incha)
1474 nha_star = numpy.int32(200./incha)
1472 star_ha = (numpy.arange(nha_star) - (nha_star/2))*nha_star
1475 star_ha = (numpy.arange(nha_star) - (nha_star/2))*nha_star
1473
1476
1474 #Init ObjCut for PatternCutPlot()
1477 #Init ObjCut for PatternCutPlot()
1475 view_objects = numpy.where(self.show_object>0)
1478 view_objects = numpy.where(self.show_object>0)
1476 subplots = len(view_objects[0])
1479 subplots = len(view_objects[0])
1477 ObjCut = PatternCutPlot(subplots)
1480 ObjCut = PatternCutPlot(subplots)
1478
1481
1479 for io in (numpy.arange(5)):
1482 for io in (numpy.arange(5)):
1480 if self.show_object[io]==2:
1483 if self.show_object[io]==2:
1481 if io==0:
1484 if io==0:
1482 if self.dcosx_mag.size!=0:
1485 if self.dcosx_mag.size!=0:
1483 dcosx = self.dcosx_mag
1486 dcosx = self.dcosx_mag
1484 dcosy = self.dcosy_mag
1487 dcosy = self.dcosy_mag
1485 dcosz = 1 - numpy.sqrt(dcosx**2. + dcosy**2.)
1488 dcosz = 1 - numpy.sqrt(dcosx**2. + dcosy**2.)
1486
1489
1487 # Finding rotation of B respec to antenna coords.
1490 # Finding rotation of B respec to antenna coords.
1488 [mm,bb] = scipy.polyfit(dcosx,dcosy,1)
1491 [mm,bb] = scipy.polyfit(dcosx,dcosy,1)
1489 alfa = 0.0
1492 alfa = 0.0
1490 theta = -1.*numpy.arctan(mm)
1493 theta = -1.*numpy.arctan(mm)
1491 sina = numpy.sin(alfa); cosa = numpy.cos(alfa)
1494 sina = numpy.sin(alfa); cosa = numpy.cos(alfa)
1492 MT1 = [[1,0,0],[0,cosa,-sina],[0,sina,cosa]]
1495 MT1 = [[1,0,0],[0,cosa,-sina],[0,sina,cosa]]
1493 MT1 = numpy.array(MT1)
1496 MT1 = numpy.array(MT1)
1494 sinb = numpy.sin(theta); cosb = numpy.cos(theta)
1497 sinb = numpy.sin(theta); cosb = numpy.cos(theta)
1495 MT2 = [[cosb,sinb,0],[-sinb,cosb,0],[0,0,1]]
1498 MT2 = [[cosb,sinb,0],[-sinb,cosb,0],[0,0,1]]
1496 MT2 = numpy.array(MT2)
1499 MT2 = numpy.array(MT2)
1497 MT3_mag = numpy.dot(MT2, MT1)
1500 MT3_mag = numpy.dot(MT2, MT1)
1498 MT3_mag = numpy.array(MT3_mag).transpose()
1501 MT3_mag = numpy.array(MT3_mag).transpose()
1499 # Getting dcos respec to B coords
1502 # Getting dcos respec to B coords
1500 vector = numpy.array([dcosx,dcosy,dcosz])
1503 vector = numpy.array([dcosx,dcosy,dcosz])
1501 nvector = numpy.dot(MT3_mag,vector)
1504 nvector = numpy.dot(MT3_mag,vector)
1502 nvector = numpy.array(nvector).transpose()
1505 nvector = numpy.array(nvector).transpose()
1503
1506
1504 ## print 'Rotation (deg) %f'%(theta/Misc_Routines.CoFactors.d2r)
1507 ## print 'Rotation (deg) %f'%(theta/Misc_Routines.CoFactors.d2r)
1505
1508
1506 yoffset = numpy.sum(nvector[:,1])/nvector[:,1].size
1509 yoffset = numpy.sum(nvector[:,1])/nvector[:,1].size
1507 # print 'Dcosyoffset %f'%(yoffset)
1510 # print 'Dcosyoffset %f'%(yoffset)
1508
1511
1509 ha = self.ha_mag*4.
1512 ha = self.ha_mag*4.
1510 time = self.time_mag
1513 time = self.time_mag
1511 width_star = 0.1 # half width in minutes
1514 width_star = 0.1 # half width in minutes
1512 otitle = 'B Perp. cut'
1515 otitle = 'B Perp. cut'
1513 # else:
1516 # else:
1514 # print "No B perp. over Observatory"
1517 # print "No B perp. over Observatory"
1515 #
1518 #
1516 #
1519 #
1517 elif io==1:
1520 elif io==1:
1518 if self.ObjC.dcosx_sun.size!=0:
1521 if self.ObjC.dcosx_sun.size!=0:
1519 dcosx = self.ObjC.dcosx_sun
1522 dcosx = self.ObjC.dcosx_sun
1520 dcosy = self.ObjC.dcosy_sun
1523 dcosy = self.ObjC.dcosy_sun
1521 ha = self.ObjC.ha_sun*4.0
1524 ha = self.ObjC.ha_sun*4.0
1522 time = self.ObjC.time_sun
1525 time = self.ObjC.time_sun
1523 width_star = 2. # half width in minutes
1526 width_star = 2. # half width in minutes
1524 otitle = 'Sun cut'
1527 otitle = 'Sun cut'
1525 # else:
1528 # else:
1526 # print "Sun is not passing over Observatory"
1529 # print "Sun is not passing over Observatory"
1527
1530
1528 elif io==2:
1531 elif io==2:
1529 if self.ObjC.dcosx_moon.size!=0:
1532 if self.ObjC.dcosx_moon.size!=0:
1530 dcosx = self.ObjC.dcosx_moon
1533 dcosx = self.ObjC.dcosx_moon
1531 dcosy = self.ObjC.dcosy_moon
1534 dcosy = self.ObjC.dcosy_moon
1532 ha = self.ObjC.ha_moon*4
1535 ha = self.ObjC.ha_moon*4
1533 time = self.ObjC.time_moon
1536 time = self.ObjC.time_moon
1534 m_distance = 404114.6 # distance to the Earth in km
1537 m_distance = 404114.6 # distance to the Earth in km
1535 m_diameter = 1734.4 # diameter in km.
1538 m_diameter = 1734.4 # diameter in km.
1536 width_star = numpy.arctan(m_distance/m_diameter)
1539 width_star = numpy.arctan(m_distance/m_diameter)
1537 width_star = width_star/2./CoFactors.d2r*4.
1540 width_star = width_star/2./CoFactors.d2r*4.
1538 otitle = 'Moon cut'
1541 otitle = 'Moon cut'
1539 # else:
1542 # else:
1540 # print "Moon is not passing over Observatory"
1543 # print "Moon is not passing over Observatory"
1541
1544
1542 elif io==3:
1545 elif io==3:
1543 if self.ObjC.dcosx_hydra.size!=0:
1546 if self.ObjC.dcosx_hydra.size!=0:
1544 dcosx = self.ObjC.dcosx_hydra
1547 dcosx = self.ObjC.dcosx_hydra
1545 dcosy = self.ObjC.dcosy_hydra
1548 dcosy = self.ObjC.dcosy_hydra
1546 ha = self.ObjC.ha_hydra*4.
1549 ha = self.ObjC.ha_hydra*4.
1547 time = self.ObjC.time_hydra
1550 time = self.ObjC.time_hydra
1548 width_star = 0.25 # half width in minutes
1551 width_star = 0.25 # half width in minutes
1549 otitle = 'Hydra cut'
1552 otitle = 'Hydra cut'
1550 # else:
1553 # else:
1551 # print "Hydra is not passing over Observatory"
1554 # print "Hydra is not passing over Observatory"
1552
1555
1553 elif io==4:
1556 elif io==4:
1554 if self.ObjC.dcosx_galaxy.size!=0:
1557 if self.ObjC.dcosx_galaxy.size!=0:
1555 dcosx = self.ObjC.dcosx_galaxy
1558 dcosx = self.ObjC.dcosx_galaxy
1556 dcosy = self.ObjC.dcosy_galaxy
1559 dcosy = self.ObjC.dcosy_galaxy
1557 ha = self.ObjC.ha_galaxy*4.
1560 ha = self.ObjC.ha_galaxy*4.
1558 time = self.ObjC.time_galaxy
1561 time = self.ObjC.time_galaxy
1559 width_star = 25. # half width in minutes
1562 width_star = 25. # half width in minutes
1560 otitle = 'Galaxy cut'
1563 otitle = 'Galaxy cut'
1561 # else:
1564 # else:
1562 # print "Galaxy center is not passing over Jicamarca"
1565 # print "Galaxy center is not passing over Jicamarca"
1563 #
1566 #
1564 #
1567 #
1565 hour = numpy.int32(time)
1568 hour = numpy.int32(time)
1566 mins = numpy.int32((time - hour)*60.)
1569 mins = numpy.int32((time - hour)*60.)
1567 secs = numpy.int32(((time - hour)*60. - mins)*60.)
1570 secs = numpy.int32(((time - hour)*60. - mins)*60.)
1568
1571
1569 ObjT = Time(self.year,self.month,self.dom,hour,mins,secs)
1572 ObjT = Time(self.year,self.month,self.dom,hour,mins,secs)
1570 subtitle = ObjT.change2strdate()
1573 subtitle = ObjT.change2strdate()
1571
1574
1572 star_cut = numpy.exp(-(star_ha/width_star)**2./2.)
1575 star_cut = numpy.exp(-(star_ha/width_star)**2./2.)
1573
1576
1574 pol = scipy.polyfit(ha,dcosx,3.)
1577 pol = scipy.polyfit(ha,dcosx,3.)
1575 polx = numpy.poly1d(pol); newdcosx = polx(newha)
1578 polx = numpy.poly1d(pol); newdcosx = polx(newha)
1576 pol = scipy.polyfit(ha,dcosy,3.)
1579 pol = scipy.polyfit(ha,dcosy,3.)
1577 poly = numpy.poly1d(pol);newdcosy = poly(newha)
1580 poly = numpy.poly1d(pol);newdcosy = poly(newha)
1578
1581
1579 patterns = []
1582 patterns = []
1580 for icut in numpy.arange(self.pattern.size):
1583 for icut in numpy.arange(self.pattern.size):
1581 # Getting Antenna cut.
1584 # Getting Antenna cut.
1582 Obj = JroPattern(dcosx=newdcosx,
1585 Obj = JroPattern(dcosx=newdcosx,
1583 dcosy=newdcosy,
1586 dcosy=newdcosy,
1584 getcut=1,
1587 getcut=1,
1585 pattern=self.pattern[icut],
1588 pattern=self.pattern[icut],
1586 path=self.path,
1589 path=self.path,
1587 filename=self.filename[icut])
1590 filename=self.filename[icut])
1588
1591
1589 Obj.getPattern()
1592 Obj.getPattern()
1590
1593
1591 patterns.append(Obj.pattern)
1594 patterns.append(Obj.pattern)
1592
1595
1593
1596
1594 ObjCut.drawCut(io,
1597 ObjCut.drawCut(io,
1595 patterns,
1598 patterns,
1596 self.pattern.size,
1599 self.pattern.size,
1597 newha,
1600 newha,
1598 otitle,
1601 otitle,
1599 subtitle,
1602 subtitle,
1600 self.ptitle)
1603 self.ptitle)
1601
1604
1602 ObjCut.saveFig(self.path4plotname,self.plotname1)
1605 ObjCut.saveFig(self.path4plotname,self.plotname1)
1603
1606
1604 def plotSkyNoise(self):
1607 def plotSkyNoise(self):
1605 # print 'Creating SkyNoise map over Jicamarca'
1608 # print 'Creating SkyNoise map over Jicamarca'
1606 dom = self.dom
1609 dom = self.dom
1607 month = self.month
1610 month = self.month
1608 year = self.year
1611 year = self.year
1609
1612
1610 julian = Time(year,month,dom).change2julday()
1613 julian = Time(year,month,dom).change2julday()
1611
1614
1612 [powr,time, lst] = Astro_Coords.CelestialBodies().skyNoise(julian)
1615 [powr,time, lst] = CelestialBodies().skyNoise(julian)
1613
1616
1614 SkyNoisePlot([year,month,dom],powr,time,lst).getPlot(self.path4plotname,self.plotname2)
1617 SkyNoisePlot([year,month,dom],powr,time,lst).getPlot(self.path4plotname,self.plotname2)
1615
1618
1616
1619
1617 def outputHead(self,title):
1620 def outputHead(self,title):
1618 print ("Content-Type: text/html")
1621 print ("Content-Type: text/html")
1619 print (self).scriptHeaders = 1
1622 print (self).scriptHeaders = 1
1620 print ('<html>')
1623 print ('<html>')
1621 print ('<head>')
1624 print ('<head>')
1622 print ('\t<title>' + title + '</title>')
1625 print ('\t<title>' + title + '</title>')
1623 print ('<style type="text/css">')
1626 print ('<style type="text/css">')
1624 print ('body')
1627 print ('body')
1625 print ('{')
1628 print ('{')
1626 print ('background-color:#ffffff;')
1629 print ('background-color:#ffffff;')
1627 print ('}')
1630 print ('}')
1628 print ('h1')
1631 print ('h1')
1629 print ('{')
1632 print ('{')
1630 print ('color:black;')
1633 print ('color:black;')
1631 print ('font-size:18px;')
1634 print ('font-size:18px;')
1632 print ('text-align:center;')
1635 print ('text-align:center;')
1633 print ('}')
1636 print ('}')
1634 print ('p')
1637 print ('p')
1635 print ('{')
1638 print ('{')
1636 print ('font-family:"Arial";')
1639 print ('font-family:"Arial";')
1637 print ('font-size:16px;')
1640 print ('font-size:16px;')
1638 print ('color:black;')
1641 print ('color:black;')
1639 print ('}')
1642 print ('}')
1640 print ('</style>')
1643 print ('</style>')
1641 # self.printJavaScript()
1644 # self.printJavaScript()
1642 print ('</head>')
1645 print ('</head>')
1643
1646
1644 def printJavaScript(self):
1647 def printJavaScript(self):
1645 print
1648 print
1646
1649
1647 def printBody(self):
1650 def printBody(self):
1648 print ('<body>')
1651 print ('<body>')
1649 # print '<h1>Test Input Parms</h1>'
1652 # print '<h1>Test Input Parms</h1>'
1650 # for key in self.madForm.keys():
1653 # for key in self.madForm.keys():
1651 # #print '<p> name=' + str(key)
1654 # #print '<p> name=' + str(key)
1652 # if type(self.madForm.getvalue(key)) == types.ListType:
1655 # if type(self.madForm.getvalue(key)) == types.ListType:
1653 # for value in self.madForm.getvalue(key):
1656 # for value in self.madForm.getvalue(key):
1654 # print '<p> name=' + str(key) + \
1657 # print '<p> name=' + str(key) + \
1655 # ' value=' + value + ''
1658 # ' value=' + value + ''
1656 # else:
1659 # else:
1657 # print '<p> name=' + str(key) + \
1660 # print '<p> name=' + str(key) + \
1658 # ' value=' + str(cgi.escape(self.madForm.getvalue(key))) + ''
1661 # ' value=' + str(cgi.escape(self.madForm.getvalue(key))) + ''
1659
1662
1660 print ('<form name="form1" method="post" target="showFrame">')
1663 print ('<form name="form1" method="post" target="showFrame">')
1661 print (' <div align="center">')
1664 print (' <div align="center">')
1662 print (' <table width=98% border="1" cellpadding="1">')
1665 print (' <table width=98% border="1" cellpadding="1">')
1663 print (' <tr>')
1666 print (' <tr>')
1664 print (' <td colspan="2" align="center">')
1667 print (' <td colspan="2" align="center">')
1665 if self.showType == 0:
1668 if self.showType == 0:
1666 print (' <IMG SRC="%s" BORDER="0" >')%(os.path.join(os.sep + self.__tmpDir,self.plotname0))
1669 print (' <IMG SRC="%s" BORDER="0" >')%(os.path.join(os.sep + self.__tmpDir,self.plotname0))
1667 if self.showType == 1:
1670 if self.showType == 1:
1668 print (' <IMG SRC="%s" BORDER="0" >')%(os.path.join(os.sep + self.__tmpDir,self.plotname1))
1671 print (' <IMG SRC="%s" BORDER="0" >')%(os.path.join(os.sep + self.__tmpDir,self.plotname1))
1669 if self.showType == 2:
1672 if self.showType == 2:
1670 print (' <IMG SRC="%s" BORDER="0" >')%(os.path.join(os.sep + self.__tmpDir,self.plotname2))
1673 print (' <IMG SRC="%s" BORDER="0" >')%(os.path.join(os.sep + self.__tmpDir,self.plotname2))
1671 print (' </td>')
1674 print (' </td>')
1672 print (' </tr>')
1675 print (' </tr>')
1673 print (' </table>')
1676 print (' </table>')
1674 print (' </div>')
1677 print (' </div>')
1675 print ('</form>')
1678 print ('</form>')
1676
1679
1677 print ('</body>')
1680 print ('</body>')
1678 print ('</html>')
1681 print ('</html>')
1679
1682
1680 #def execute(self, serverdocspath, tmpdir, currentdate, finalpath, showType=0, maxphi=5.0, objects="[1,1]", heights="[150,500,1000]"):
1683 #def execute(self, serverdocspath, tmpdir, currentdate, finalpath, showType=0, maxphi=5.0, objects="[1,1]", heights="[150,500,1000]"):
1681 def setInputParameters(self, serverpath, currentdate, finalpath, showType=0, maxphi=5.0, objects="[1,1]", heights="[150,500,1000]"):
1684 def setInputParameters(self, serverpath, currentdate, finalpath, showType=0, maxphi=5.0, objects="[1,1]", heights="[150,500,1000]"):
1682 self.objects=[]
1685 self.objects=[]
1683 self.heights=[]
1686 self.heights=[]
1684 #self.__serverdocspath = serverdocspath
1687 #self.__serverdocspath = serverdocspath
1685 self.__serverdocspath = os.path.split(serverpath)[0]
1688 self.__serverdocspath = os.path.split(serverpath)[0]
1686 #self.__tmpDir = tmpdir
1689 #self.__tmpDir = tmpdir
1687 self.__tmpDir = os.path.split(serverpath)[1]
1690 self.__tmpDir = os.path.split(serverpath)[1]
1688 self.showType = int(showType)
1691 self.showType = int(showType)
1689 self.year = int(currentdate.strftime("%Y")) # Get year of currentdate
1692 self.year = int(currentdate.strftime("%Y")) # Get year of currentdate
1690 self.month = int(currentdate.strftime("%m")) # Get month of currentdate
1693 self.month = int(currentdate.strftime("%m")) # Get month of currentdate
1691 self.dom = int(currentdate.strftime("%d")) # Get day of currentdate
1694 self.dom = int(currentdate.strftime("%d")) # Get day of currentdate
1692 self.filename = os.path.split(finalpath)[1]
1695 self.filename = os.path.split(finalpath)[1]
1693 self.path = os.path.split(finalpath)[0]
1696 self.path = os.path.split(finalpath)[0]
1694 self.maxphi = float(maxphi)
1697 self.maxphi = float(maxphi)
1695
1698
1696 tmp_objects = (objects.replace("[","")).replace("]","")
1699 tmp_objects = (objects.replace("[","")).replace("]","")
1697 for s in tmp_objects.split(','):
1700 for s in tmp_objects.split(','):
1698 self.objects.append(int(s))
1701 self.objects.append(int(s))
1699
1702
1700 tmp_heights = (heights.replace("[","")).replace("]","")
1703 tmp_heights = (heights.replace("[","")).replace("]","")
1701 for s in tmp_heights.split(','):
1704 for s in tmp_heights.split(','):
1702 self.heights.append(float(s))
1705 self.heights.append(float(s))
1703 self.heights = numpy.array(self.heights)
1706 self.heights = numpy.array(self.heights)
1704
1707
1705 def setupParameters(self):
1708 def setupParameters(self):
1706 self.initParameters()
1709 self.initParameters()
1707
1710
1708 def initParametersCGI(self):
1711 def initParametersCGI(self):
1709 self.setScriptState()
1712 self.setScriptState()
1710 self.initParameters()
1713 self.initParameters()
1711
1714
1712 def execute(self):
1715 def execute(self):
1713 if self.showType == 0 or self.showType == 1:
1716 if self.showType == 0 or self.showType == 1:
1714 self.initParameters1()
1717 self.initParameters1()
1715 self.plotPattern()
1718 self.plotPattern()
1716
1719
1717 if numpy.sum(self.show_object>0) != 0:
1720 if numpy.sum(self.show_object>0) != 0:
1718 self.plotBfield()
1721 self.plotBfield()
1719 self.plotCelestial()
1722 self.plotCelestial()
1720
1723
1721 if numpy.sum(self.show_object>1) != 0:
1724 if numpy.sum(self.show_object>1) != 0:
1722 self.plotAntennaCuts()
1725 self.plotAntennaCuts()
1723
1726
1724 if self.showType == 2:
1727 if self.showType == 2:
1725 self.plotSkyNoise()
1728 self.plotSkyNoise()
1726
1729
1727 def getPlot(self):
1730 def getPlot(self):
1728
1731
1729 return os.path.join(self.__serverdocspath,self.__tmpDir,self.plotname0)
1732 return os.path.join(self.__serverdocspath,self.__tmpDir,self.plotname0)
1730
1733
1731
1734
1732 if __name__ == '__main__':
1735 if __name__ == '__main__':
1733
1736
1734 # Script overJroShow.py
1737 # Script overJroShow.py
1735 # This script only calls the init function of the class overJroShow()
1738 # This script only calls the init function of the class overJroShow()
1736 # All work is done by the init function
1739 # All work is done by the init function
1737
1740
1738 phases = numpy.array([[2.0,0.0,1.5,1.5,1.0,1.0,1.0,0.5],
1741 phases = numpy.array([[2.0,0.0,1.5,1.5,1.0,1.0,1.0,0.5],
1739 [2.0,2.5,2.5,3.5,0.5,1.0,1.0,1.0],
1742 [2.0,2.5,2.5,3.5,0.5,1.0,1.0,1.0],
1740 [2.5,2.5,1.0,1.0,0.5,0.5,0.5,0.5],
1743 [2.5,2.5,1.0,1.0,0.5,0.5,0.5,0.5],
1741 [1.0,1.0,1.0,1.0,0.5,0.5,0.5,1.0],
1744 [1.0,1.0,1.0,1.0,0.5,0.5,0.5,1.0],
1742 [0.5,0.5,0.5,0.5,0.5,0.0,0.0,0.0],
1745 [0.5,0.5,0.5,0.5,0.5,0.0,0.0,0.0],
1743 [0.5,0.5,1.0,0.5,0.0,0.0,0.0,0.0],
1746 [0.5,0.5,1.0,0.5,0.0,0.0,0.0,0.0],
1744 [0.5,0.5,0.5,1.0,0.0,0.0,0.0,0.0],
1747 [0.5,0.5,0.5,1.0,0.0,0.0,0.0,0.0],
1745 [0.5,0.5,0.5,0.5,0.0,0.0,0.0,0.0]])
1748 [0.5,0.5,0.5,0.5,0.0,0.0,0.0,0.0]])
1746
1749
1747 gain_tx = numpy.array([[0,0,0,0,0,0,0,0],
1750 gain_tx = numpy.array([[0,0,0,0,0,0,0,0],
1748 [0,0,0,0,0,0,0,0],
1751 [0,0,0,0,0,0,0,0],
1749 [0,0,0,0,0,0,0,0],
1752 [0,0,0,0,0,0,0,0],
1750 [0,0,0,0,0,0,0,0],
1753 [0,0,0,0,0,0,0,0],
1751 [0,0,0,0,1,1,1,1],
1754 [0,0,0,0,1,1,1,1],
1752 [0,0,0,0,0,0,0,0],
1755 [0,0,0,0,0,0,0,0],
1753 [0,0,0,0,0,0,0,0],
1756 [0,0,0,0,0,0,0,0],
1754 [0,0,0,0,0,0,0,0]])
1757 [0,0,0,0,0,0,0,0]])
1755
1758
1756 gain_rx = numpy.array([[0,0,0,0,0,0,0,0],
1759 gain_rx = numpy.array([[0,0,0,0,0,0,0,0],
1757 [0,0,1,0,0,0,0,0],
1760 [0,0,1,0,0,0,0,0],
1758 [0,0,1,0,0,0,0,0],
1761 [0,0,1,0,0,0,0,0],
1759 [0,0,0,0,0,0,0,0],
1762 [0,0,0,0,0,0,0,0],
1760 [0,0,0,0,0,0,0,0],
1763 [0,0,0,0,0,0,0,0],
1761 [0,0,0,0,0,0,0,0],
1764 [0,0,0,0,0,0,0,0],
1762 [0,0,0,0,0,0,0,0],
1765 [0,0,0,0,0,0,0,0],
1763 [0,0,0,0,0,0,0,0]])
1766 [0,0,0,0,0,0,0,0]])
1764
1767
1765 jro = overJroShow()
1768 jro = overJroShow()
1766
1769
1767 fig = jro.plotPattern2(datetime.datetime.today(),
1770 fig = jro.plotPattern2(datetime.datetime.today(),
1768 phases=phases,
1771 phases=phases,
1769 gain_tx=gain_tx,
1772 gain_tx=gain_tx,
1770 gain_rx=gain_rx,
1773 gain_rx=gain_rx,
1771 ues=numpy.array([0.0,0.0,0.0,0.0]),
1774 ues=numpy.array([0.0,0.0,0.0,0.0]),
1772 just_rx=0)
1775 just_rx=0)
1773
1776
1774 fig.savefig('./pat.png')
1777 fig.savefig('./pat.png')
1775
1778
@@ -1,404 +1,411
1 import json
1 import json
2 import requests
2 import requests
3
3
4 from django.db import models
4 from django.db import models
5 from django.core.validators import MinValueValidator, MaxValueValidator
5 from django.core.validators import MinValueValidator, MaxValueValidator
6 from django.urls import reverse
6 from django.urls import reverse
7
7
8 from apps.main.models import Configuration
8 from apps.main.models import Configuration
9 from apps.main.utils import Params
9 from apps.main.utils import Params
10 from .utils import create_jarsfiles
10 from .utils import create_jarsfiles
11
11
12 # Create your models here.
12 # Create your models here.
13
13
14 EXPERIMENT_TYPE = (
14 EXPERIMENT_TYPE = (
15 (0, 'RAW_DATA'),
15 (0, 'RAW_DATA'),
16 (1, 'PDATA'),
16 (1, 'PDATA'),
17 )
17 )
18
18
19 DATA_TYPE = (
19 DATA_TYPE = (
20 (0, 'SHORT'),
20 (0, 'SHORT'),
21 (1, 'FLOAT'),
21 (1, 'FLOAT'),
22 )
22 )
23
23
24 DECODE_TYPE = (
24 DECODE_TYPE = (
25 (0, 'None'),
25 (0, 'None'),
26 (1, 'TimeDomain'),
26 (1, 'TimeDomain'),
27 (2, 'FreqDomain'),
27 (2, 'FreqDomain'),
28 (3, 'InvFreqDomain'),
28 (3, 'InvFreqDomain'),
29 )
29 )
30
30
31 FILTER = '{"id":1, "clock": 60, "multiplier": 5, "frequency": 49.92, "f_decimal": 721554506, "fir": 2, "cic_2": 12, "cic_5": 25}'
31 FILTER = '{"id":1, "clock": 60, "multiplier": 5, "frequency": 49.92, "f_decimal": 721554506, "fir": 2, "cic_2": 12, "cic_5": 25}'
32
32
33 class JARSFilter(models.Model):
33 class JARSFilter(models.Model):
34
34
35 JARS_NBITS = 32
35 JARS_NBITS = 32
36
36
37 name = models.CharField(verbose_name='Name', max_length=60, unique=True, default='')
37 name = models.CharField(verbose_name='Name', max_length=60, unique=True, default='')
38 clock = models.FloatField(verbose_name='Clock In (MHz)', validators=[
38 clock = models.FloatField(verbose_name='Clock In (MHz)', validators=[
39 MinValueValidator(5), MaxValueValidator(75)], null=True, default=60)
39 MinValueValidator(5), MaxValueValidator(75)], null=True, default=60)
40 multiplier = models.PositiveIntegerField(verbose_name='Multiplier', validators=[
40 multiplier = models.PositiveIntegerField(verbose_name='Multiplier', validators=[
41 MinValueValidator(1), MaxValueValidator(20)], default=5)
41 MinValueValidator(1), MaxValueValidator(20)], default=5)
42 frequency = models.FloatField(verbose_name='Frequency (MHz)', validators=[
42 frequency = models.FloatField(verbose_name='Frequency (MHz)', validators=[
43 MaxValueValidator(150)], null=True, default=49.9200)
43 MaxValueValidator(150)], null=True, default=49.9200)
44 f_decimal = models.BigIntegerField(verbose_name='Frequency (Decimal)', validators=[
44 f_decimal = models.BigIntegerField(verbose_name='Frequency (Decimal)', validators=[
45 MinValueValidator(-9223372036854775808), MaxValueValidator(2**JARS_NBITS-1)], null=True, default=721554505)
45 MinValueValidator(-9223372036854775808), MaxValueValidator(2**JARS_NBITS-1)], null=True, default=721554505)
46 cic_2 = models.PositiveIntegerField(verbose_name='CIC2', validators=[
46 cic_2 = models.PositiveIntegerField(verbose_name='CIC2', validators=[
47 MinValueValidator(2), MaxValueValidator(100)], default=10)
47 MinValueValidator(2), MaxValueValidator(100)], default=10)
48 scale_cic_2 = models.PositiveIntegerField(verbose_name='Scale CIC2', validators=[
48 scale_cic_2 = models.PositiveIntegerField(verbose_name='Scale CIC2', validators=[
49 MinValueValidator(0), MaxValueValidator(6)], default=1)
49 MinValueValidator(0), MaxValueValidator(6)], default=1)
50 cic_5 = models.PositiveIntegerField(verbose_name='CIC5', validators=[
50 cic_5 = models.PositiveIntegerField(verbose_name='CIC5', validators=[
51 MinValueValidator(1), MaxValueValidator(100)], default=1)
51 MinValueValidator(1), MaxValueValidator(100)], default=1)
52 scale_cic_5 = models.PositiveIntegerField(verbose_name='Scale CIC5', validators=[
52 scale_cic_5 = models.PositiveIntegerField(verbose_name='Scale CIC5', validators=[
53 MinValueValidator(0), MaxValueValidator(20)], default=5)
53 MinValueValidator(0), MaxValueValidator(20)], default=5)
54 fir = models.PositiveIntegerField(verbose_name='FIR', validators=[
54 fir = models.PositiveIntegerField(verbose_name='FIR', validators=[
55 MinValueValidator(1), MaxValueValidator(100)], default=6)
55 MinValueValidator(1), MaxValueValidator(100)], default=6)
56 scale_fir = models.PositiveIntegerField(verbose_name='Scale FIR', validators=[
56 scale_fir = models.PositiveIntegerField(verbose_name='Scale FIR', validators=[
57 MinValueValidator(0), MaxValueValidator(7)], default=3)
57 MinValueValidator(0), MaxValueValidator(7)], default=3)
58 number_taps = models.PositiveIntegerField(verbose_name='Number of taps', validators=[
58 number_taps = models.PositiveIntegerField(verbose_name='Number of taps', validators=[
59 MinValueValidator(1), MaxValueValidator(256)], default=4)
59 MinValueValidator(1), MaxValueValidator(256)], default=4)
60 taps = models.CharField(verbose_name='Taps', max_length=1600, default='0')
60 taps = models.CharField(verbose_name='Taps', max_length=1600, default='0')
61
61
62 class Meta:
62 class Meta:
63 db_table = 'jars_filters'
63 db_table = 'jars_filters'
64
64
65 def __unicode__(self):
65 def __unicode__(self):
66 return u'%s' % (self.name)
66 return u'%s' % (self.name)
67
67
68 def jsonify(self):
68 def jsonify(self):
69
69
70 data = {}
70 data = {}
71 ignored = ()
71 ignored = ()
72
72
73 for field in self._meta.fields:
73 for field in self._meta.fields:
74 if field.name in ignored:
74 if field.name in ignored:
75 continue
75 continue
76 data[field.name] = field.value_from_object(self)
76 data[field.name] = field.value_from_object(self)
77
77
78 return data
78 return data
79
79
80 def parms_to_dict(self):
80 def parms_to_dict(self):
81
81
82 parameters = {}
82 parameters = {}
83
83
84 parameters['name'] = self.name
84 parameters['name'] = self.name
85 parameters['clock'] = float(self.clock)
85 parameters['clock'] = float(self.clock)
86 parameters['multiplier'] = int(self.multiplier)
86 parameters['multiplier'] = int(self.multiplier)
87 parameters['frequency'] = float(self.frequency)
87 parameters['frequency'] = float(self.frequency)
88 parameters['f_decimal'] = int(self.frequency)
88 parameters['f_decimal'] = int(self.frequency)
89 parameters['fir'] = int(self.fir)
89 parameters['fir'] = int(self.fir)
90 parameters['cic_2'] = int(self.cic_2)
90 parameters['cic_2'] = int(self.cic_2)
91 parameters['cic_5'] = int(self.cic_5)
91 parameters['cic_5'] = int(self.cic_5)
92
92
93 return parameters
93 return parameters
94
94
95 def dict_to_parms(self, parameters):
95 def dict_to_parms(self, parameters):
96
96
97 self.name = parameters['name']
97 self.name = parameters['name']
98 self.clock = parameters['clock']
98 self.clock = parameters['clock']
99 self.multiplier = parameters['multiplier']
99 self.multiplier = parameters['multiplier']
100 self.frequency = parameters['frequency']
100 self.frequency = parameters['frequency']
101 self.f_decimal = parameters['f_decimal']
101 self.f_decimal = parameters['f_decimal']
102 self.fir = parameters['fir']
102 self.fir = parameters['fir']
103 self.cic_2 = parameters['cic_2']
103 self.cic_2 = parameters['cic_2']
104 self.cic_5 = parameters['cic_5']
104 self.cic_5 = parameters['cic_5']
105
105
106 def dict_to_parms_new(self, parameters):
106 def dict_to_parms_new(self, parameters):
107
107
108 self.name = parameters['name']
108 self.name = parameters['name']
109 self.clock = parameters['clock']
109 self.clock = parameters['clock']
110 self.multiplier = parameters['multiplier']
110 self.multiplier = parameters['multiplier']
111 self.frequency = parameters['frequency']
111 self.frequency = parameters['frequency']
112 self.f_decimal = parameters['f_decimal']
112 self.f_decimal = parameters['f_decimal']
113 self.fir = parameters['fir']
113 self.fir = parameters['fir']
114 self.cic_2 = parameters['cic_2']
114 self.cic_2 = parameters['cic_2']
115 self.cic_5 = parameters['cic_5']
115 self.cic_5 = parameters['cic_5']
116 self.scale_fir = parameters['scale_fir']
116 self.scale_fir = parameters['scale_fir']
117 self.scale_cic_2 = parameters['scale_cic_2']
117 self.scale_cic_2 = parameters['scale_cic_2']
118 self.scale_cic_5 = parameters['scale_cic_5']
118 self.scale_cic_5 = parameters['scale_cic_5']
119 self.number_taps = parameters['number_taps']
119 self.number_taps = parameters['number_taps']
120 self.taps = parameters['taps']
120 self.taps = parameters['taps']
121
121
122 class JARSConfiguration(Configuration):
122 class JARSConfiguration(Configuration):
123
123
124 ADC_RESOLUTION = 8
124 ADC_RESOLUTION = 8
125 PCI_DIO_BUSWIDTH = 32
125 PCI_DIO_BUSWIDTH = 32
126 HEADER_VERSION = 1103
126 HEADER_VERSION = 1103
127 BEGIN_ON_START = True
127 BEGIN_ON_START = True
128 REFRESH_RATE = 1
128 REFRESH_RATE = 1
129
129
130 exp_type = models.PositiveIntegerField(
130 exp_type = models.PositiveIntegerField(
131 verbose_name='Experiment Type', choices=EXPERIMENT_TYPE, default=0)
131 verbose_name='Experiment Type', choices=EXPERIMENT_TYPE, default=0)
132 cards_number = models.PositiveIntegerField(verbose_name='Number of Cards', validators=[
132 cards_number = models.PositiveIntegerField(verbose_name='Number of Cards', validators=[
133 MinValueValidator(1), MaxValueValidator(4)], default=1)
133 MinValueValidator(1), MaxValueValidator(4)], default=1)
134 channels_number = models.PositiveIntegerField(verbose_name='Number of Channels', validators=[
134 channels_number = models.PositiveIntegerField(verbose_name='Number of Channels', validators=[
135 MinValueValidator(1), MaxValueValidator(8)], default=5)
135 MinValueValidator(1), MaxValueValidator(8)], default=5)
136 channels = models.CharField(
136 channels = models.CharField(
137 verbose_name='Channels', max_length=15, default='1,2,3,4,5')
137 verbose_name='Channels', max_length=15, default='1,2,3,4,5')
138 data_type = models.PositiveIntegerField(
138 data_type = models.PositiveIntegerField(
139 verbose_name='Data Type', choices=DATA_TYPE, default=0)
139 verbose_name='Data Type', choices=DATA_TYPE, default=0)
140 raw_data_blocks = models.PositiveIntegerField(
140 raw_data_blocks = models.PositiveIntegerField(
141 verbose_name='Raw Data Blocks', validators=[MaxValueValidator(5000)], default=60)
141 verbose_name='Raw Data Blocks', validators=[MaxValueValidator(5000)], default=60)
142 profiles_block = models.PositiveIntegerField(
142 profiles_block = models.PositiveIntegerField(
143 verbose_name='Profiles Per Block', default=400)
143 verbose_name='Profiles Per Block', default=400)
144 acq_profiles = models.PositiveIntegerField(
144 acq_profiles = models.PositiveIntegerField(
145 verbose_name='Acquired Profiles', default=400)
145 verbose_name='Acquired Profiles', default=400)
146 ftp_interval = models.PositiveIntegerField(
146 ftp_interval = models.PositiveIntegerField(
147 verbose_name='FTP Interval', default=60)
147 verbose_name='FTP Interval', default=60)
148 fftpoints = models.PositiveIntegerField(
148 fftpoints = models.PositiveIntegerField(
149 verbose_name='FFT Points', default=16)
149 verbose_name='FFT Points', default=16)
150 cohe_integr_str = models.PositiveIntegerField(
150 cohe_integr_str = models.PositiveIntegerField(
151 verbose_name='Coh. Int. Stride', validators=[MinValueValidator(1)], default=30)
151 verbose_name='Coh. Int. Stride', validators=[MinValueValidator(1)], default=30)
152 cohe_integr = models.PositiveIntegerField(
152 cohe_integr = models.PositiveIntegerField(
153 verbose_name='Coherent Integrations', validators=[MinValueValidator(1)], default=30)
153 verbose_name='Coherent Integrations', validators=[MinValueValidator(1)], default=30)
154 incohe_integr = models.PositiveIntegerField(
154 incohe_integr = models.PositiveIntegerField(
155 verbose_name='Incoherent Integrations', validators=[MinValueValidator(1)], default=30)
155 verbose_name='Incoherent Integrations', validators=[MinValueValidator(1)], default=30)
156 decode_data = models.PositiveIntegerField(
156 decode_data = models.PositiveIntegerField(
157 verbose_name='Decode Data', choices=DECODE_TYPE, default=0)
157 verbose_name='Decode Data', choices=DECODE_TYPE, default=0)
158 post_coh_int = models.BooleanField(
158 post_coh_int = models.BooleanField(
159 verbose_name='Post Coherent Integration', default=False)
159 verbose_name='Post Coherent Integration', default=False)
160 spectral_number = models.PositiveIntegerField(
160 spectral_number = models.PositiveIntegerField(
161 verbose_name='# Spectral Combinations', validators=[MinValueValidator(1)], default=1)
161 verbose_name='# Spectral Combinations', validators=[MinValueValidator(1)], default=1)
162 spectral = models.CharField(
162 spectral = models.CharField(
163 verbose_name='Combinations', max_length=5000, default='[0, 0],')
163 verbose_name='Combinations', max_length=5000, default='[0, 0],')
164 create_directory = models.BooleanField(
164 create_directory = models.BooleanField(
165 verbose_name='Create Directory Per Day', default=True)
165 verbose_name='Create Directory Per Day', default=True)
166 include_expname = models.BooleanField(
166 include_expname = models.BooleanField(
167 verbose_name='Experiment Name in Directory', default=False)
167 verbose_name='Experiment Name in Directory', default=False)
168 #view_raw_data = models.BooleanField(verbose_name='View Raw Data', default=True)
168 #view_raw_data = models.BooleanField(verbose_name='View Raw Data', default=True)
169 save_ch_dc = models.BooleanField(
169 save_ch_dc = models.BooleanField(
170 verbose_name='Save Channels DC', default=True)
170 verbose_name='Save Channels DC', default=True)
171 save_data = models.BooleanField(verbose_name='Save Data', default=True)
171 save_data = models.BooleanField(verbose_name='Save Data', default=True)
172 filter_parms = models.CharField(
172 filter_parms = models.CharField(
173 max_length=10000, default=FILTER)
173 max_length=10000, default=FILTER)
174 filter = models.ForeignKey(
174 filter = models.ForeignKey(
175 'JARSFilter', verbose_name='Filter', null=True, blank=True, on_delete=models.CASCADE)
175 'JARSFilter', verbose_name='Filter', null=True, blank=True, on_delete=models.CASCADE)
176
176
177 class Meta:
177 class Meta:
178 db_table = 'jars_configurations'
178 db_table = 'jars_configurations'
179
179
180 def filter_resolution(self):
180 def filter_resolution(self):
181 filter_parms = json.loads(self.filter_parms)
181 filter_parms = json.loads(self.filter_parms)
182 clock = float(filter_parms['clock'])
182 clock = float(filter_parms['clock'])
183 cic_2 = filter_parms['cic_2']
183 cic_2 = filter_parms['cic_2']
184 cic_5 = filter_parms['cic_5']
184 cic_5 = filter_parms['cic_5']
185 fir = filter_parms['fir']
185 fir = filter_parms['fir']
186 resolution = round((clock/(cic_2*cic_5*fir)), 2)
186 resolution = round((clock/(cic_2*cic_5*fir)), 2)
187 return resolution
187 return resolution
188
188
189 def dict_to_parms(self, params, id=None):
189 def dict_to_parms(self, params, id=None):
190
190
191 if id is not None:
191 if id is not None:
192 data = Params(params).get_conf(id_conf=id)
192 data = Params(params).get_conf(id_conf=id)
193 else:
193 else:
194 data = Params(params).get_conf(dtype='jars')
194 data = Params(params).get_conf(dtype='jars')
195 data['filter_parms'] = params['filter_parms']
195 data['filter_parms'] = params['filter_parms']
196
196
197 # self.name = data['name']
197 # self.name = data['name']
198 self.exp_type = data['exp_type']
198 self.exp_type = data['exp_type']
199 #----PDATA----
199 #----PDATA----
200 if self.exp_type == 1:
200 if self.exp_type == 1:
201 self.incohe_integr = data['incohe_integr']
201 self.incohe_integr = data['incohe_integr']
202 self.spectral_number = data['spectral_number']
202 self.spectral_number = data['spectral_number']
203 self.spectral = data['spectral']
203 self.spectral = data['spectral']
204 self.fftpoints = data['fftpoints']
204 self.fftpoints = data['fftpoints']
205 self.save_ch_dc = data['save_ch_dc']
205 self.save_ch_dc = data['save_ch_dc']
206 else:
206 else:
207 self.raw_data_blocks = data['raw_data_blocks']
207 self.raw_data_blocks = data['raw_data_blocks']
208 #----PDATA----
208 #----PDATA----
209 self.cards_number = data['cards_number']
209 self.cards_number = data['cards_number']
210 self.channels_number = data['channels_number']
210 self.channels_number = data['channels_number']
211 self.channels = data['channels']
211 self.channels = data['channels']
212 self.data_type = data['data_type']
212 self.data_type = data['data_type']
213 self.profiles_block = data['profiles_block']
213 self.profiles_block = data['profiles_block']
214 self.acq_profiles = data['acq_profiles']
214 self.acq_profiles = data['acq_profiles']
215 self.ftp_interval = data['ftp_interval']
215 self.ftp_interval = data['ftp_interval']
216 self.cohe_integr_str = data['cohe_integr_str']
216 self.cohe_integr_str = data['cohe_integr_str']
217 self.cohe_integr = data['cohe_integr']
217 self.cohe_integr = data['cohe_integr']
218 #----DECODE----
218 #----DECODE----
219 self.decode_data = data['decode_data']
219 self.decode_data = data['decode_data']
220 self.post_coh_int = data['post_coh_int']
220 self.post_coh_int = data['post_coh_int']
221 #----DECODE----
221 #----DECODE----
222 self.create_directory = data['create_directory']
222 self.create_directory = data['create_directory']
223 self.include_expname = data['include_expname']
223 self.include_expname = data['include_expname']
224 self.save_data = data['save_data']
224 self.save_data = data['save_data']
225 self.filter_parms = json.dumps(data['filter_parms'])
225 self.filter_parms = json.dumps(data['filter_parms'])
226
226
227 self.save()
227 self.save()
228
228
229 def parms_to_text(self, file_format='jars'):
229 def parms_to_text(self, file_format='jars'):
230
230
231 data = self.experiment.parms_to_dict()
231 data = self.experiment.parms_to_dict()
232
232
233 for key in data['configurations']['allIds']:
233 for key in data['configurations']['allIds']:
234 if data['configurations']['byId'][key]['device_type'] in ('dds', 'cgs'):
234 if data['configurations']['byId'][key]['device_type'] in ('dds', 'cgs'):
235 data['configurations']['allIds'].remove(key)
235 data['configurations']['allIds'].remove(key)
236 data['configurations']['byId'].pop(key)
236 data['configurations']['byId'].pop(key)
237 elif data['configurations']['byId'][key]['device_type'] == 'jars':
237 elif data['configurations']['byId'][key]['device_type'] == 'jars':
238 data['configurations']['byId'][key] = self.parms_to_dict(
238 data['configurations']['byId'][key] = self.parms_to_dict(
239 )['configurations']['byId'][str(self.pk)]
239 )['configurations']['byId'][str(self.pk)]
240 elif data['configurations']['byId'][key]['device_type'] == 'rc':
240 elif data['configurations']['byId'][key]['device_type'] == 'rc':
241 data['configurations']['byId'][key]['pulses'] = ''
241 data['configurations']['byId'][key]['pulses'] = ''
242 data['configurations']['byId'][key]['delays'] = ''
242 data['configurations']['byId'][key]['delays'] = ''
243 rc_ids = [pk for pk in data['configurations']['allIds']
243 rc_ids = [pk for pk in data['configurations']['allIds']
244 if data['configurations']['byId'][pk]['device_type'] == 'rc']
244 if data['configurations']['byId'][pk]['device_type'] == 'rc']
245 mix_ids = [pk for pk in rc_ids if data['configurations']
245 mix_ids = [pk for pk in rc_ids if data['configurations']
246 ['byId'][pk]['mix']]
246 ['byId'][pk]['mix']]
247
247
248 if mix_ids:
248 if mix_ids:
249 params = data['configurations']['byId'][mix_ids[0]]['parameters']
249 params = data['configurations']['byId'][mix_ids[0]]['parameters']
250 rc = data['configurations']['byId'][params.split(
250 rc = data['configurations']['byId'][params.split(
251 '-')[0].split('|')[0]]
251 '-')[0].split('|')[0]]
252 rc['mix'] = True
252 rc['mix'] = True
253 data['configurations']['byId'][rc['id']] = rc
253 data['configurations']['byId'][rc['id']] = rc
254 elif len(rc_ids) == 0:
254 elif len(rc_ids) == 0:
255 self.message = 'File needs RC configuration'
255 self.message = 'File needs RC configuration'
256 return ''
256 return ''
257
257
258 json_data = json.dumps(data)
258 json_data = json.dumps(data)
259 racp_file, filter_file = create_jarsfiles(json_data)
259 racp_file, filter_file = create_jarsfiles(json_data)
260 if file_format == 'racp':
260 if file_format == 'racp':
261 return racp_file
261 return racp_file
262
262
263 return filter_file
263 return filter_file
264
264
265 def request(self, cmd, method='get', **kwargs):
265 def request(self, cmd, method='get', **kwargs):
266
266
267 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
267 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
268 payload = req.json()
268 payload = req.json()
269 return payload
269 return payload
270
270
271 def status_device(self):
271 def status_device(self):
272
272
273 try:
273 try:
274 payload = self.request('status',
274 payload = self.request('status',
275 params={'name': self.experiment.name})
275 params={'name': self.experiment.name})
276 self.device.status = payload['status']
276 self.device.status = payload['status']
277 self.device.save()
277 self.device.save()
278 self.message = payload['message']
278 self.message = payload['message']
279 except Exception as e:
279 except Exception as e:
280 self.device.status = 0
280 self.device.status = 0
281 self.message = str(e)
281 self.message = str(e)
282 self.device.save()
282 self.device.save()
283 return False
283 return False
284
284
285 return True
285 return True
286
286
287 def stop_device(self):
287 def stop_device(self):
288
288
289 try:
289 try:
290 payload = self.request('stop', 'post')
290 payload = self.request('stop', 'post')
291 self.device.status = payload['status']
291 self.device.status = payload['status']
292 self.device.save()
292 self.device.save()
293 self.message = payload['message']
293 self.message = payload['message']
294 print("------STOP JARS------",flush=True)
294 except Exception as e:
295 except Exception as e:
295 self.device.status = 0
296 self.device.status = 0
296 self.message = str(e)
297 self.message = str(e)
297 self.device.save()
298 self.device.save()
298 return False
299 return False
299
300
300 return True
301 return True
301
302
302 def read_device(self):
303 def read_device(self):
303
304
304 try:
305 try:
305 payload = self.request(
306 payload = self.request(
306 'read', params={'name': self.experiment.name})
307 'read', params={'name': self.experiment.name})
307 self.message = 'Configuration loaded'
308 self.message = 'Configuration loaded'
308 except:
309 except:
309 self.device.status = 0
310 self.device.status = 0
310 self.device.save()
311 self.device.save()
311 self.message = 'Could not read JARS configuration.'
312 self.message = 'Could not read JARS configuration.'
312 return False
313 return False
313
314
314 return payload
315 return payload
315
316
316 def write_device(self):
317 def write_device(self):
317
318
318 if self.device.status == 3:
319 if self.device.status == 3:
319 self.message = 'Could not configure device. Software Acquisition is running'
320 self.message = 'Could not configure device. Software Acquisition is running'
320 return False
321 return False
322
323 print("------ JARS WRITING ------",flush=True)
324 self.device.status = 5 #Busy
325 print("STATUS:", self.device.status,flush=True)
321
326
322 data = self.experiment.parms_to_dict()
327 data = self.experiment.parms_to_dict()
323 #print(data)
328 #print(data)
324 for key in data['configurations']['allIds']:
329 for key in data['configurations']['allIds']:
325 if data['configurations']['byId'][key]['device_type'] in ('dds', 'cgs'):
330 if data['configurations']['byId'][key]['device_type'] in ('dds', 'cgs'):
326 data['configurations']['allIds'].remove(key)
331 data['configurations']['allIds'].remove(key)
327 data['configurations']['byId'].pop(key)
332 data['configurations']['byId'].pop(key)
328 elif data['configurations']['byId'][key]['device_type'] == 'rc':
333 elif data['configurations']['byId'][key]['device_type'] == 'rc':
329 data['configurations']['byId'][key]['pulses'] = ''
334 data['configurations']['byId'][key]['pulses'] = ''
330 data['configurations']['byId'][key]['delays'] = ''
335 data['configurations']['byId'][key]['delays'] = ''
331 rc_ids = [pk for pk in data['configurations']['allIds']
336 rc_ids = [pk for pk in data['configurations']['allIds']
332 if data['configurations']['byId'][pk]['device_type'] == 'rc']
337 if data['configurations']['byId'][pk]['device_type'] == 'rc']
333 if len(rc_ids) == 0:
338 if len(rc_ids) == 0:
334 self.message = 'Missing RC configuration'
339 self.message = 'Missing RC configuration'
335 return False
340 return False
336
341
337 json_data = json.dumps(data)
342 json_data = json.dumps(data)
343 print("STATUS:", self.device.status,flush=True)
338
344
339 try:
345 try:
340 payload = self.request('write', 'post', json=json_data)
346 payload = self.request('write', 'post', json=json_data)
341 self.device.status = payload['status']
347 self.device.status = payload['status']
342 self.message = payload['message']
348 self.message = payload['message']
343 self.device.save()
349 self.device.save()
344 if self.device.status == 1:
350 if self.device.status == 1:
345 return False
351 return False
352 print("------ JARS WRITED ------",flush=True)
346
353
347 except Exception as e:
354 except Exception as e:
348 self.device.status = 0
355 self.device.status = 0
349 self.message = str(e)
356 self.message = str(e)
350 self.device.save()
357 self.device.save()
351 return False
358 return False
352
359 print("FINAL STATUS:", self.device.status,flush=True)
353 return True
360 return True
354
361
355 def start_device(self):
362 def start_device(self):
356
363
357 try:
364 try:
358 payload = self.request('start', 'post',
365 payload = self.request('start', 'post',
359 json={'name': self.experiment.name})
366 json={'name': self.experiment.name})
360 self.device.status = payload['status']
367 self.device.status = payload['status']
361 self.message = payload['message']
368 self.message = payload['message']
362 self.device.save()
369 self.device.save()
363 if self.device.status == 1:
370 if self.device.status == 1:
364 return False
371 return False
365
372
366 except Exception as e:
373 except Exception as e:
367 self.device.status = 0
374 self.device.status = 0
368 self.message = str(e)
375 self.message = str(e)
369 self.device.save()
376 self.device.save()
370 return False
377 return False
371
378 print("------START JARS------",flush=True)
372 return True
379 return True
373
380
374 def get_log(self):
381 def get_log(self):
375
382
376 payload = None
383 payload = None
377
384
378 try:
385 try:
379 payload = requests.get(self.device.url('get_log'), params={
386 payload = requests.get(self.device.url('get_log'), params={
380 'name': self.experiment.name})
387 'name': self.experiment.name})
381 except:
388 except:
382 self.device.status = 0
389 self.device.status = 0
383 self.device.save()
390 self.device.save()
384 self.message = 'Jars API is not running.'
391 self.message = 'Jars API is not running.'
385 return False
392 return False
386
393
387 self.message = 'Jars API is running'
394 self.message = 'Jars API is running'
388
395
389 return payload
396 return payload
390
397
391 def update_from_file(self, filename):
398 def update_from_file(self, filename):
392
399
393 f = JARSFile(filename)
400 f = JARSFile(filename)
394 self.dict_to_parms(f.data)
401 self.dict_to_parms(f.data)
395 self.save()
402 self.save()
396
403
397 def get_absolute_url_import(self):
404 def get_absolute_url_import(self):
398 return reverse('url_import_jars_conf', args=[str(self.id)])
405 return reverse('url_import_jars_conf', args=[str(self.id)])
399
406
400 def get_absolute_url_read(self):
407 def get_absolute_url_read(self):
401 return reverse('url_read_jars_conf', args=[str(self.id)])
408 return reverse('url_read_jars_conf', args=[str(self.id)])
402
409
403 def get_absolute_url_log(self):
410 def get_absolute_url_log(self):
404 return reverse('url_get_jars_log', args=[str(self.id)])
411 return reverse('url_get_jars_log', args=[str(self.id)])
@@ -1,87 +1,86
1 from django.core.management.base import BaseCommand
1 from django.core.management.base import BaseCommand
2 from apps.main.models import Campaign, Location
2 from apps.main.models import Campaign, Location
3 from datetime import datetime,timedelta
3 from datetime import datetime,timedelta
4 from apps.main.views import radar_start
4 from apps.main.views import radar_start
5 from django.shortcuts import render, redirect,get_object_or_404, HttpResponse
5 from django.shortcuts import render, redirect,get_object_or_404, HttpResponse
6 from django.urls import reverse
6 from django.urls import reverse
7 from django.utils.timezone import is_aware
7 from django.utils.timezone import is_aware
8 from django.contrib import messages
8 from django.contrib import messages
9 from django.http import HttpResponseRedirect
9 from django.http import HttpResponseRedirect
10 from apps.main.views import experiment_start
10 from apps.main.views import experiment_start
11 from apps.main.models import Experiment, Configuration
11 from apps.main.models import Experiment, Configuration
12
12
13 class Command(BaseCommand):
13 class Command(BaseCommand):
14 """
14 """
15 Restart experiment every night at 05:00 am.
15 Restart experiment every night at 05:00 am.
16 Example:
16 Example:
17 manage.py restart_experiment
17 manage.py restart_experiment
18 """
18 """
19 def handle(self, *args, **options):
19 def handle(self, *args, **options):
20 print("\n\n")
20 print("\n\n")
21 all_campaigns=Campaign.objects.all()
21 all_campaigns=Campaign.objects.all()
22 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
22 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
23 end_date__gte=datetime.now()).order_by('-start_date')
23 end_date__gte=datetime.now()).order_by('-start_date')
24
24
25 for campaign in all_campaigns:
25 for campaign in all_campaigns:
26 if campaign.start_date<datetime.now() and campaign.end_date > datetime.now():
26 if campaign.start_date<datetime.now() and campaign.end_date > datetime.now():
27
27
28 radar=campaign.get_experiments_by_radar(radar=None)
28 radar=campaign.get_experiments_by_radar(radar=None)
29 for rad in radar:
29 for rad in radar:
30 # print("RADR", rad)
30 # print("RADR", rad)
31 radar_id=rad["id"]
31 radar_id=rad["id"]
32 # print("RADR_",radar_id)
32 # print("RADR_",radar_id)
33 radar_start_scheduler(campaign.id,radar_id)
33 radar_write_start_scheduler(campaign.id,radar_id)
34 print(campaign.name, "\t\t Campaign already running")
34 print(campaign.name, "\t\t Campaign already running")
35
35
36 else:
36 else:
37 radar=campaign.get_experiments_by_radar(radar=None)
37 radar=campaign.get_experiments_by_radar(radar=None)
38 radar_id=radar[0]["id"]
38 radar_id=radar[0]["id"]
39 if campaign.experiments.all()[0].status !=1:
39 if campaign.experiments.all()[0].status !=1:
40 print(campaign.name, "\t\t Stopping Campaign...")
40 print(campaign.name, "\t\t Stopping Campaign...")
41 a=radar_stop_scheduler(campaign.id,radar_id,campaign.experiments.all()[0].id)
41 a=radar_stop_scheduler(campaign.id,radar_id,campaign.experiments.all()[0].id)
42 print("New Status: ", a)
42 print("New Status: ", a)
43 else:
43 else:
44 print(campaign.name,"\t\t\t Campaign already stooped")
44 print(campaign.name,"\t\t\t Campaign already stooped")
45
45
46 def radar_start_scheduler(id_camp,id_radar):
46 def radar_write_start_scheduler(id_camp,id_radar):
47 campaign = get_object_or_404(Campaign, pk=id_camp)
47 campaign = get_object_or_404(Campaign, pk=id_camp)
48 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
48 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
49 now = datetime.now()
50 # print(campaign)
49 # print(campaign)
51 # print(experiments)
50 # print(experiments)
52 for exp in experiments:
51 for exp in experiments:
53 exp = get_object_or_404(Experiment, pk=exp.id)
52 exp = get_object_or_404(Experiment, pk=exp.id)
54 # print("---------DEBUGG-------------")
53 # print("---------DEBUGG-------------")
55 # print(exp)
54 # print(exp)
56 if exp.status == 2:
55 if exp.status == 2:
57 print('\t\t\t {} \t\t Experiment already runnnig'.format(exp))
56 print('\t\t\t {} \t\t Experiment already runnnig'.format(exp))
58 else:
57 else:
59 exp.status = exp.start()
58 exp.status = exp.start()
60 if exp.status == 0:
59 if exp.status == 0:
61 print('\t\t\t {} \t\tExperiment not start'.format(exp))
60 print('\t\t\t {} \t\tExperiment not start'.format(exp))
62 if exp.status == 2:
61 if exp.status == 2:
63 print('\t\t\t {} \t\tExperiment started'.format(exp))
62 print('\t\t\t {} \t\tExperiment started'.format(exp))
64 if exp.status == 4:
63 if exp.status == 4:
65 print('\t\t\t {} \t\tExperiment with state uknown, please reset'.format(exp))
64 print('\t\t\t {} \t\tExperiment with state uknown, please reset (Stop and start manually)'.format(exp))
66 exp.save()
65 exp.save()
67
66
68 def radar_stop_scheduler(id_camp,id_radar,id_experiment):
67 def radar_stop_scheduler(id_camp,id_radar,id_experiment):
69 '''
68 '''
70 Stop experiments's devices
69 Stop experiments's devices
71 DDS-JARS-RC-CGS-ABS
70 DDS-JARS-RC-CGS-ABS
72 '''
71 '''
73 exp=get_object_or_404(Experiment,pk=id_experiment)
72 exp=get_object_or_404(Experiment,pk=id_experiment)
74
73
75 if exp.status == 2:
74 if exp.status == 2:
76 confs = Configuration.objects.filter(experiment=id_experiment,type = 0).order_by('device__device_type__sequence')
75 confs = Configuration.objects.filter(experiment=id_experiment,type = 0).order_by('device__device_type__sequence')
77 confs = confs.exclude(device__device_type__name='cgs')
76 confs = confs.exclude(device__device_type__name='cgs')
78 try:
77 try:
79 for conf in confs:
78 for conf in confs:
80 # print(conf)
79 # print(conf)
81 conf.stop_device()
80 conf.stop_device()
82 exp.status= 1
81 exp.status= 1
83 except:
82 except:
84 exp.status= 0
83 exp.status= 0
85 exp.save()
84 exp.save()
86
85
87 return exp.status No newline at end of file
86 return exp.status
@@ -1,828 +1,832
1
1
2 import os
2 import os
3 import json
3 import json
4 import requests
4 import requests
5 import time
5 import time
6 from datetime import datetime
6 from datetime import datetime
7
7
8 try:
8 try:
9 from polymorphic.models import PolymorphicModel
9 from polymorphic.models import PolymorphicModel
10 except:
10 except:
11 from polymorphic import PolymorphicModel
11 from polymorphic import PolymorphicModel
12
12
13 from django.template.base import kwarg_re
13 from django.template.base import kwarg_re
14 from django.db import models
14 from django.db import models
15 from django.urls import reverse
15 from django.urls import reverse
16 from django.core.validators import MinValueValidator, MaxValueValidator
16 from django.core.validators import MinValueValidator, MaxValueValidator
17 from django.shortcuts import get_object_or_404
17 from django.shortcuts import get_object_or_404
18 from django.contrib.auth.models import User
18 from django.contrib.auth.models import User
19 from django.db.models.signals import post_save
19 from django.db.models.signals import post_save
20 from django.dispatch import receiver
20 from django.dispatch import receiver
21
21
22 from apps.main.utils import Params
22 from apps.main.utils import Params
23 from apps.rc.utils import RCFile
23 from apps.rc.utils import RCFile
24 from apps.jars.utils import RacpFile
24 from apps.jars.utils import RacpFile
25 from devices.dds import api as dds_api
25 from devices.dds import api as dds_api
26 from devices.dds import data as dds_data
26 from devices.dds import data as dds_data
27
27
28
28
29 DEV_PORTS = {
29 DEV_PORTS = {
30 'rc' : 2000,
30 'rc' : 2000,
31 'dds' : 2000,
31 'dds' : 2000,
32 'jars' : 2000,
32 'jars' : 2000,
33 'usrp' : 2000,
33 'usrp' : 2000,
34 'cgs' : 8080,
34 'cgs' : 8080,
35 'abs' : 8080,
35 'abs' : 8080,
36 'dds_rest': 80
36 'dds_rest': 80
37 }
37 }
38
38
39 RADAR_STATES = (
39 RADAR_STATES = (
40 (0, 'No connected'),
40 (0, 'No connected'),
41 (1, 'Connected'),
41 (1, 'Connected'),
42 (2, 'Configured'),
42 (2, 'Configured'),
43 (3, 'Running'),
43 (3, 'Running'),
44 (4, 'Scheduled'),
44 (4, 'Scheduled'),
45 )
45 )
46
46
47 EXPERIMENT_TYPE = (
47 EXPERIMENT_TYPE = (
48 (0, 'RAW_DATA'),
48 (0, 'RAW_DATA'),
49 (1, 'PDATA'),
49 (1, 'PDATA'),
50 )
50 )
51
51
52 DECODE_TYPE = (
52 DECODE_TYPE = (
53 (0, 'None'),
53 (0, 'None'),
54 (1, 'TimeDomain'),
54 (1, 'TimeDomain'),
55 (2, 'FreqDomain'),
55 (2, 'FreqDomain'),
56 (3, 'InvFreqDomain'),
56 (3, 'InvFreqDomain'),
57 )
57 )
58
58
59 DEV_STATES = (
59 DEV_STATES = (
60 (0, 'No connected'),
60 (0, 'No connected'),
61 (1, 'Connected'),
61 (1, 'Connected'),
62 (2, 'Configured'),
62 (2, 'Configured'),
63 (3, 'Running'),
63 (3, 'Running'),
64 (4, 'Unknown'),
64 (4, 'Unknown'),
65 (5, 'Busy')
65 )
66 )
66
67
67 DEV_TYPES = (
68 DEV_TYPES = (
68 ('', 'Select a device type'),
69 ('', 'Select a device type'),
69 ('rc', 'Radar Controller'),
70 ('rc', 'Radar Controller'),
70 ('dds', 'Direct Digital Synthesizer'),
71 ('dds', 'Direct Digital Synthesizer'),
71 ('jars', 'Jicamarca Radar Acquisition System'),
72 ('jars', 'Jicamarca Radar Acquisition System'),
72 ('usrp', 'Universal Software Radio Peripheral'),
73 ('usrp', 'Universal Software Radio Peripheral'),
73 ('cgs', 'Clock Generator System'),
74 ('cgs', 'Clock Generator System'),
74 ('abs', 'Automatic Beam Switching'),
75 ('abs', 'Automatic Beam Switching'),
75 ('dds_rest', 'Direct Digital Synthesizer_REST'),
76 ('dds_rest', 'Direct Digital Synthesizer_REST'),
76 ('atrad', 'Transmitter ATRAD'),
77 ('atrad', 'Transmitter ATRAD'),
77 )
78 )
78
79
79 EXP_STATES = (
80 EXP_STATES = (
80 (0,'Error'), #RED
81 (0,'Error'), #RED
81 (1,'Cancelled'), #YELLOW
82 (1,'Cancelled'), #YELLOW
82 (2,'Running'), #GREEN
83 (2,'Running'), #GREEN
83 (3,'Scheduled'), #BLUE
84 (3,'Scheduled'), #BLUE
84 (4,'Unknown'), #WHITE
85 (4,'Unknown'), #WHITE
85 )
86 )
86
87
87 CONF_TYPES = (
88 CONF_TYPES = (
88 (0, 'Active'),
89 (0, 'Active'),
89 (1, 'Historical'),
90 (1, 'Historical'),
90 )
91 )
91
92
92 class Profile(models.Model):
93 class Profile(models.Model):
93 user = models.OneToOneField(User, on_delete=models.CASCADE)
94 user = models.OneToOneField(User, on_delete=models.CASCADE)
94 theme = models.CharField(max_length=30, default='spacelab')
95 theme = models.CharField(max_length=30, default='spacelab')
95
96
96
97
97 @receiver(post_save, sender=User)
98 @receiver(post_save, sender=User)
98 def create_user_profile(sender, instance, created, **kwargs):
99 def create_user_profile(sender, instance, created, **kwargs):
99 if created:
100 if created:
100 Profile.objects.create(user=instance)
101 Profile.objects.create(user=instance)
101
102
102 @receiver(post_save, sender=User)
103 @receiver(post_save, sender=User)
103 def save_user_profile(sender, instance, **kwargs):
104 def save_user_profile(sender, instance, **kwargs):
104 instance.profile.save()
105 instance.profile.save()
105
106
106
107
107 class Location(models.Model):
108 class Location(models.Model):
108
109
109 name = models.CharField(max_length = 30)
110 name = models.CharField(max_length = 30)
110 description = models.TextField(blank=True, null=True)
111 description = models.TextField(blank=True, null=True)
111
112
112 class Meta:
113 class Meta:
113 db_table = 'db_location'
114 db_table = 'db_location'
114
115
115 def __str__(self):
116 def __str__(self):
116 return u'%s' % self.name
117 return u'%s' % self.name
117
118
118 def get_absolute_url(self):
119 def get_absolute_url(self):
119 return reverse('url_location', args=[str(self.id)])
120 return reverse('url_location', args=[str(self.id)])
120
121
121
122
122 class DeviceType(models.Model):
123 class DeviceType(models.Model):
123
124
124 name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'dds_rest')
125 name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'dds_rest')
125 sequence = models.PositiveSmallIntegerField(default=55)
126 sequence = models.PositiveSmallIntegerField(default=55)
126 description = models.TextField(blank=True, null=True)
127 description = models.TextField(blank=True, null=True)
127
128
128 class Meta:
129 class Meta:
129 db_table = 'db_device_types'
130 db_table = 'db_device_types'
130
131
131 def __str__(self):
132 def __str__(self):
132 return u'%s' % self.get_name_display()
133 return u'%s' % self.get_name_display()
133
134
134 class Device(models.Model):
135 class Device(models.Model):
135
136
136 device_type = models.ForeignKey('DeviceType', on_delete=models.CASCADE)
137 device_type = models.ForeignKey('DeviceType', on_delete=models.CASCADE)
137 location = models.ForeignKey('Location', on_delete=models.CASCADE)
138 location = models.ForeignKey('Location', on_delete=models.CASCADE)
138 ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
139 ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
139 port_address = models.PositiveSmallIntegerField(default=2000)
140 port_address = models.PositiveSmallIntegerField(default=2000)
140 description = models.TextField(blank=True, null=True)
141 description = models.TextField(blank=True, null=True)
141 status = models.PositiveSmallIntegerField(default=4, choices=DEV_STATES)
142 status = models.PositiveSmallIntegerField(default=4, choices=DEV_STATES)
142 conf_active = models.PositiveIntegerField(default=0, verbose_name='Current configuration')
143 conf_active = models.PositiveIntegerField(default=0, verbose_name='Current configuration')
143
144
144 class Meta:
145 class Meta:
145 db_table = 'db_devices'
146 db_table = 'db_devices'
146
147
147 def __str__(self):
148 def __str__(self):
148 ret = u'{} [{}]'.format(self.device_type.name.upper(), self.location.name)
149 ret = u'{} [{}]'.format(self.device_type.name.upper(), self.location.name)
149
150
150 return ret
151 return ret
151
152
152 @property
153 @property
153 def name(self):
154 def name(self):
154 return str(self)
155 return str(self)
155
156
156 def get_status(self):
157 def get_status(self):
157 return self.status
158 return self.status
158
159
159 @property
160 @property
160 def status_color(self):
161 def status_color(self):
161 color = 'muted'
162 color = 'muted'
162 if self.status == 0:
163 if self.status == 0:
163 color = "danger"
164 color = "danger"
164 elif self.status == 1:
165 elif self.status == 1:
165 color = "warning"
166 color = "warning"
166 elif self.status == 2:
167 elif self.status == 2:
167 color = "info"
168 color = "info"
168 elif self.status == 3:
169 elif self.status == 3:
169 color = "success"
170 color = "success"
170
171
171 return color
172 return color
172
173
173 def url(self, path=None):
174 def url(self, path=None):
174
175
175 if path:
176 if path:
176 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
177 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
177 else:
178 else:
178 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
179 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
179
180
180 def get_absolute_url(self):
181 def get_absolute_url(self):
181 return reverse('url_device', args=[str(self.id)])
182 return reverse('url_device', args=[str(self.id)])
182
183
183 def get_absolute_url_edit(self):
184 def get_absolute_url_edit(self):
184 return reverse('url_edit_device', args=[str(self.id)])
185 return reverse('url_edit_device', args=[str(self.id)])
185
186
186 def get_absolute_url_delete(self):
187 def get_absolute_url_delete(self):
187 return reverse('url_delete_device', args=[str(self.id)])
188 return reverse('url_delete_device', args=[str(self.id)])
188
189
189 def change_ip(self, ip_address, mask, gateway, dns, **kwargs):
190 def change_ip(self, ip_address, mask, gateway, dns, **kwargs):
190
191
191 if self.device_type.name=='dds':
192 if self.device_type.name=='dds':
192 try:
193 try:
193 answer = dds_api.change_ip(ip = self.ip_address,
194 answer = dds_api.change_ip(ip = self.ip_address,
194 port = self.port_address,
195 port = self.port_address,
195 new_ip = ip_address,
196 new_ip = ip_address,
196 mask = mask,
197 mask = mask,
197 gateway = gateway)
198 gateway = gateway)
198 if answer[0]=='1':
199 if answer[0]=='1':
199 self.message = '25|DDS - {}'.format(answer)
200 self.message = '25|DDS - {}'.format(answer)
200 self.ip_address = ip_address
201 self.ip_address = ip_address
201 self.save()
202 self.save()
202 else:
203 else:
203 self.message = '30|DDS - {}'.format(answer)
204 self.message = '30|DDS - {}'.format(answer)
204 return False
205 return False
205 except Exception as e:
206 except Exception as e:
206 self.message = '40|{}'.format(str(e))
207 self.message = '40|{}'.format(str(e))
207 return False
208 return False
208
209
209 elif self.device_type.name=='rc':
210 elif self.device_type.name=='rc':
210 headers = {'content-type': "application/json",
211 headers = {'content-type': "application/json",
211 'cache-control': "no-cache"}
212 'cache-control': "no-cache"}
212
213
213 ip = [int(x) for x in ip_address.split('.')]
214 ip = [int(x) for x in ip_address.split('.')]
214 dns = [int(x) for x in dns.split('.')]
215 dns = [int(x) for x in dns.split('.')]
215 gateway = [int(x) for x in gateway.split('.')]
216 gateway = [int(x) for x in gateway.split('.')]
216 subnet = [int(x) for x in mask.split('.')]
217 subnet = [int(x) for x in mask.split('.')]
217
218
218 payload = {
219 payload = {
219 "ip": ip,
220 "ip": ip,
220 "dns": dns,
221 "dns": dns,
221 "gateway": gateway,
222 "gateway": gateway,
222 "subnet": subnet
223 "subnet": subnet
223 }
224 }
224
225
225 req = requests.post(self.url('changeip'), data=json.dumps(payload), headers=headers)
226 req = requests.post(self.url('changeip'), data=json.dumps(payload), headers=headers)
226 try:
227 try:
227 answer = req.json()
228 answer = req.json()
228 if answer['changeip']=='ok':
229 if answer['changeip']=='ok':
229 self.message = '25|IP succesfully changed'
230 self.message = '25|IP succesfully changed'
230 self.ip_address = ip_address
231 self.ip_address = ip_address
231 self.save()
232 self.save()
232 else:
233 else:
233 self.message = '30|An error ocuur when changing IP'
234 self.message = '30|An error ocuur when changing IP'
234 except Exception as e:
235 except Exception as e:
235 self.message = '40|{}'.format(str(e))
236 self.message = '40|{}'.format(str(e))
236 else:
237 else:
237 self.message = 'Not implemented'
238 self.message = 'Not implemented'
238 return False
239 return False
239
240
240 return True
241 return True
241
242
242
243
243 class Campaign(models.Model):
244 class Campaign(models.Model):
244
245
245 template = models.BooleanField(default=False)
246 template = models.BooleanField(default=False)
246 name = models.CharField(max_length=60, unique=True)
247 name = models.CharField(max_length=60, unique=True)
247 start_date = models.DateTimeField(blank=True, null=True)
248 start_date = models.DateTimeField(blank=True, null=True)
248 end_date = models.DateTimeField(blank=True, null=True)
249 end_date = models.DateTimeField(blank=True, null=True)
249 tags = models.CharField(max_length=40, blank=True, null=True)
250 tags = models.CharField(max_length=40, blank=True, null=True)
250 description = models.TextField(blank=True, null=True)
251 description = models.TextField(blank=True, null=True)
251 experiments = models.ManyToManyField('Experiment', blank=True)
252 experiments = models.ManyToManyField('Experiment', blank=True)
252 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
253 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
253
254
254 class Meta:
255 class Meta:
255 db_table = 'db_campaigns'
256 db_table = 'db_campaigns'
256 ordering = ('name',)
257 ordering = ('name',)
257
258
258 def __str__(self):
259 def __str__(self):
259 if self.template:
260 if self.template:
260 return u'{} (template)'.format(self.name)
261 return u'{} (template)'.format(self.name)
261 else:
262 else:
262 return u'{}'.format(self.name)
263 return u'{}'.format(self.name)
263
264
264 def jsonify(self):
265 def jsonify(self):
265
266
266 data = {}
267 data = {}
267
268
268 ignored = ('template')
269 ignored = ('template')
269
270
270 for field in self._meta.fields:
271 for field in self._meta.fields:
271 if field.name in ignored:
272 if field.name in ignored:
272 continue
273 continue
273 data[field.name] = field.value_from_object(self)
274 data[field.name] = field.value_from_object(self)
274
275
275 data['start_date'] = data['start_date'].strftime('%Y-%m-%d')
276 data['start_date'] = data['start_date'].strftime('%Y-%m-%d')
276 data['end_date'] = data['end_date'].strftime('%Y-%m-%d')
277 data['end_date'] = data['end_date'].strftime('%Y-%m-%d')
277
278
278 return data
279 return data
279
280
280 def parms_to_dict(self):
281 def parms_to_dict(self):
281
282
282 params = Params({})
283 params = Params({})
283 params.add(self.jsonify(), 'campaigns')
284 params.add(self.jsonify(), 'campaigns')
284
285
285 for exp in Experiment.objects.filter(campaign = self):
286 for exp in Experiment.objects.filter(campaign = self):
286 params.add(exp.jsonify(), 'experiments')
287 params.add(exp.jsonify(), 'experiments')
287 configurations = Configuration.objects.filter(experiment=exp, type=0)
288 configurations = Configuration.objects.filter(experiment=exp, type=0)
288
289
289 for conf in configurations:
290 for conf in configurations:
290 params.add(conf.jsonify(), 'configurations')
291 params.add(conf.jsonify(), 'configurations')
291 if conf.device.device_type.name=='rc':
292 if conf.device.device_type.name=='rc':
292 for line in conf.get_lines():
293 for line in conf.get_lines():
293 params.add(line.jsonify(), 'lines')
294 params.add(line.jsonify(), 'lines')
294
295
295 return params.data
296 return params.data
296
297
297 def dict_to_parms(self, parms, CONF_MODELS):
298 def dict_to_parms(self, parms, CONF_MODELS):
298
299
299 experiments = Experiment.objects.filter(campaign = self)
300 experiments = Experiment.objects.filter(campaign = self)
300
301
301 if experiments:
302 if experiments:
302 for experiment in experiments:
303 for experiment in experiments:
303 experiment.delete()
304 experiment.delete()
304
305
305 for id_exp in parms['experiments']['allIds']:
306 for id_exp in parms['experiments']['allIds']:
306 exp_parms = parms['experiments']['byId'][id_exp]
307 exp_parms = parms['experiments']['byId'][id_exp]
307 dum = (datetime.now() - datetime(1970, 1, 1)).total_seconds()
308 dum = (datetime.now() - datetime(1970, 1, 1)).total_seconds()
308 exp = Experiment(name='{}'.format(dum))
309 exp = Experiment(name='{}'.format(dum))
309 exp.save()
310 exp.save()
310 exp.dict_to_parms(parms, CONF_MODELS, id_exp=id_exp)
311 exp.dict_to_parms(parms, CONF_MODELS, id_exp=id_exp)
311 self.experiments.add(exp)
312 self.experiments.add(exp)
312
313
313 camp_parms = parms['campaigns']['byId'][parms['campaigns']['allIds'][0]]
314 camp_parms = parms['campaigns']['byId'][parms['campaigns']['allIds'][0]]
314
315
315 self.name = '{}-{}'.format(camp_parms['name'], datetime.now().strftime('%y%m%d'))
316 self.name = '{}-{}'.format(camp_parms['name'], datetime.now().strftime('%y%m%d'))
316 self.start_date = camp_parms['start_date']
317 self.start_date = camp_parms['start_date']
317 self.end_date = camp_parms['end_date']
318 self.end_date = camp_parms['end_date']
318 self.tags = camp_parms['tags']
319 self.tags = camp_parms['tags']
319 self.save()
320 self.save()
320
321
321 return self
322 return self
322
323
323 def get_experiments_by_radar(self, radar=None):
324 def get_experiments_by_radar(self, radar=None):
324
325
325 ret = []
326 ret = []
326 if radar:
327 if radar:
327 locations = Location.objects.filter(pk=radar)
328 locations = Location.objects.filter(pk=radar)
328 else:
329 else:
329 locations = set([e.location for e in self.experiments.all()])
330 locations = set([e.location for e in self.experiments.all()])
330
331
331 for loc in locations:
332 for loc in locations:
332 dum = {}
333 dum = {}
333 dum['name'] = loc.name
334 dum['name'] = loc.name
334 dum['id'] = loc.pk
335 dum['id'] = loc.pk
335 dum['experiments'] = [e for e in self.experiments.all() if e.location==loc]
336 dum['experiments'] = [e for e in self.experiments.all() if e.location==loc]
336 ret.append(dum)
337 ret.append(dum)
337 return ret
338 return ret
338
339
339 def get_absolute_url(self):
340 def get_absolute_url(self):
340 return reverse('url_campaign', args=[str(self.id)])
341 return reverse('url_campaign', args=[str(self.id)])
341
342
342 def get_absolute_url_edit(self):
343 def get_absolute_url_edit(self):
343 return reverse('url_edit_campaign', args=[str(self.id)])
344 return reverse('url_edit_campaign', args=[str(self.id)])
344
345
345 def get_absolute_url_delete(self):
346 def get_absolute_url_delete(self):
346 return reverse('url_delete_campaign', args=[str(self.id)])
347 return reverse('url_delete_campaign', args=[str(self.id)])
347
348
348 def get_absolute_url_export(self):
349 def get_absolute_url_export(self):
349 return reverse('url_export_campaign', args=[str(self.id)])
350 return reverse('url_export_campaign', args=[str(self.id)])
350
351
351 def get_absolute_url_import(self):
352 def get_absolute_url_import(self):
352 return reverse('url_import_campaign', args=[str(self.id)])
353 return reverse('url_import_campaign', args=[str(self.id)])
353
354
354
355
355 class RunningExperiment(models.Model):
356 class RunningExperiment(models.Model):
356 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
357 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
357 running_experiment = models.ManyToManyField('Experiment', blank = True)
358 running_experiment = models.ManyToManyField('Experiment', blank = True)
358 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
359 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
359
360
360
361
361 class Experiment(models.Model):
362 class Experiment(models.Model):
362
363
363 template = models.BooleanField(default=False)
364 template = models.BooleanField(default=False)
364 name = models.CharField(max_length=40, default='', unique=True)
365 name = models.CharField(max_length=40, default='', unique=True)
365 location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
366 location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
366 freq = models.FloatField(verbose_name='Operating Freq. (MHz)', validators=[MinValueValidator(1), MaxValueValidator(10000)], default=49.9200)
367 freq = models.FloatField(verbose_name='Operating Freq. (MHz)', validators=[MinValueValidator(1), MaxValueValidator(10000)], default=49.9200)
367 start_time = models.TimeField(default='00:00:00')
368 start_time = models.TimeField(default='00:00:00')
368 end_time = models.TimeField(default='23:59:59')
369 end_time = models.TimeField(default='23:59:59')
369 task = models.CharField(max_length=36, default='', blank=True, null=True)
370 task = models.CharField(max_length=36, default='', blank=True, null=True)
370 status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES)
371 status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES)
371 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
372 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
372 hash = models.CharField(default='', max_length=64, null=True, blank=True)
373 hash = models.CharField(default='', max_length=64, null=True, blank=True)
373
374
374 class Meta:
375 class Meta:
375 db_table = 'db_experiments'
376 db_table = 'db_experiments'
376 ordering = ('template', 'name')
377 ordering = ('template', 'name')
377
378
378 def __str__(self):
379 def __str__(self):
379 if self.template:
380 if self.template:
380 return u'%s (template)' % (self.name)
381 return u'%s (template)' % (self.name)
381 else:
382 else:
382 return u'%s' % (self.name)
383 return u'%s' % (self.name)
383
384
384 def jsonify(self):
385 def jsonify(self):
385
386
386 data = {}
387 data = {}
387
388
388 ignored = ('template')
389 ignored = ('template')
389
390
390 for field in self._meta.fields:
391 for field in self._meta.fields:
391 if field.name in ignored:
392 if field.name in ignored:
392 continue
393 continue
393 data[field.name] = field.value_from_object(self)
394 data[field.name] = field.value_from_object(self)
394
395
395 data['start_time'] = data['start_time'].strftime('%H:%M:%S')
396 data['start_time'] = data['start_time'].strftime('%H:%M:%S')
396 data['end_time'] = data['end_time'].strftime('%H:%M:%S')
397 data['end_time'] = data['end_time'].strftime('%H:%M:%S')
397 data['location'] = self.location.name
398 data['location'] = self.location.name
398 data['configurations'] = ['{}'.format(conf.pk) for
399 data['configurations'] = ['{}'.format(conf.pk) for
399 conf in Configuration.objects.filter(experiment=self, type=0)]
400 conf in Configuration.objects.filter(experiment=self, type=0)]
400
401
401 return data
402 return data
402
403
403 @property
404 @property
404 def radar_system(self):
405 def radar_system(self):
405 return self.location
406 return self.location
406
407
407 def clone(self, **kwargs):
408 def clone(self, **kwargs):
408
409
409 confs = Configuration.objects.filter(experiment=self, type=0)
410 confs = Configuration.objects.filter(experiment=self, type=0)
410 self.pk = None
411 self.pk = None
411 self.name = '{}_{:%y%m%d%H%M%S}'.format(self.name, datetime.now())
412 self.name = '{}_{:%y%m%d%H%M%S}'.format(self.name, datetime.now())
412 for attr, value in kwargs.items():
413 for attr, value in kwargs.items():
413 setattr(self, attr, value)
414 setattr(self, attr, value)
414
415
415 self.save()
416 self.save()
416
417
417 for conf in confs:
418 for conf in confs:
418 conf.clone(experiment=self, template=False)
419 conf.clone(experiment=self, template=False)
419
420
420 return self
421 return self
421
422
422 def start(self):
423 def start(self):
423 '''
424 '''
424 Configure and start experiments's devices
425 Configure and start experiments's devices
425 ABS-CGS-DDS-RC-JARS
426 ABS-CGS-DDS-RC-JARS
426 '''
427 '''
427
428
428 confs = []
429 confs = []
429 allconfs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence')
430 allconfs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence')
430 rc_mix = [conf for conf in allconfs if conf.device.device_type.name=='rc' and conf.mix]
431 rc_mix = [conf for conf in allconfs if conf.device.device_type.name=='rc' and conf.mix]
431 if rc_mix:
432 if rc_mix:
432 for conf in allconfs:
433 for conf in allconfs:
433 if conf.device.device_type.name == 'rc' and not conf.mix:
434 if conf.device.device_type.name == 'rc' and not conf.mix:
434 continue
435 continue
435 confs.append(conf)
436 confs.append(conf)
436 else:
437 else:
437 confs = allconfs
438 confs = allconfs
438
439
439 print("confs: ",confs)
440 print("confs: ",confs)
440 #try:
441 #try:
441 for conf in confs:
442 for conf in confs:
442 print("conf->",conf)
443 print("conf->",conf)
443 conf.stop_device()
444 conf.stop_device()
444 conf.write_device()
445 conf.write_device()
445 conf.device.conf_active = conf.pk
446 conf.device.conf_active = conf.pk
446 conf.device.save()
447 conf.device.save()
447 conf.start_device()
448 conf.start_device()
448 time.sleep(1)
449 time.sleep(1)
449 #except:
450 #except:
450 #return 0
451 #return 0
451 return 2
452 return 2
452
453
453
454
454 def stop(self):
455 def stop(self):
455 '''
456 '''
456 Stop experiments's devices
457 Stop experiments's devices
457 DDS-JARS-RC-CGS-ABS
458 DDS-JARS-RC-CGS-ABS
458 '''
459 '''
459
460
460 confs = Configuration.objects.filter(experiment=self, type = 0).order_by('device__device_type__sequence')
461 confs = Configuration.objects.filter(experiment=self, type = 0).order_by('device__device_type__sequence')
461 confs = confs.exclude(device__device_type__name='cgs')
462 confs = confs.exclude(device__device_type__name='cgs')
462 try:
463 try:
463 for conf in confs:
464 for conf in confs:
464 conf.stop_device()
465 conf.stop_device()
465 except:
466 except:
466 return 0
467 return 0
467 return 1
468 return 1
468
469
469 def get_status(self):
470 def get_status(self):
470
471
471 if self.status == 3:
472 if self.status == 3:
472 return
473 return
473
474
474 confs = Configuration.objects.filter(experiment=self, type=0)
475 confs = Configuration.objects.filter(experiment=self, type=0)
475
476
476 for conf in confs:
477 for conf in confs:
477 conf.status_device()
478 conf.status_device()
478
479
479 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
480 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
480
481
481 if total==2*confs.count():
482 if total==2*confs.count():
482 status = 1
483 status = 1
483 elif total == 3*confs.count():
484 elif total == 3*confs.count():
484 status = 2
485 status = 2
485 else:
486 else:
486 status = 0
487 status = 0
487
488
488 self.status = status
489 self.status = status
489 self.save()
490 self.save()
490
491
491 def status_color(self):
492 def status_color(self):
492 color = 'muted'
493 color = 'muted'
493 if self.status == 0:
494 if self.status == 0:
494 color = "danger"
495 color = "danger"
495 elif self.status == 1:
496 elif self.status == 1:
496 color = "warning"
497 color = "warning"
497 elif self.status == 2:
498 elif self.status == 2:
498 color = "success"
499 color = "success"
499 elif self.status == 3:
500 elif self.status == 3:
500 color = "info"
501 color = "info"
501
502
502 return color
503 return color
503
504
504 def parms_to_dict(self):
505 def parms_to_dict(self):
505
506
506 params = Params({})
507 params = Params({})
507 params.add(self.jsonify(), 'experiments')
508 params.add(self.jsonify(), 'experiments')
508
509
509 configurations = Configuration.objects.filter(experiment=self, type=0)
510 configurations = Configuration.objects.filter(experiment=self, type=0)
510
511
511 for conf in configurations:
512 for conf in configurations:
512 params.add(conf.jsonify(), 'configurations')
513 params.add(conf.jsonify(), 'configurations')
513 if conf.device.device_type.name=='rc':
514 if conf.device.device_type.name=='rc':
514 for line in conf.get_lines():
515 for line in conf.get_lines():
515 params.add(line.jsonify(), 'lines')
516 params.add(line.jsonify(), 'lines')
516
517
517 return params.data
518 return params.data
518
519
519 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
520 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
520
521
521 configurations = Configuration.objects.filter(experiment=self)
522 configurations = Configuration.objects.filter(experiment=self)
522
523
523 if id_exp is not None:
524 if id_exp is not None:
524 exp_parms = parms['experiments']['byId'][id_exp]
525 exp_parms = parms['experiments']['byId'][id_exp]
525 else:
526 else:
526 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
527 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
527
528
528 if configurations:
529 if configurations:
529 for configuration in configurations:
530 for configuration in configurations:
530 configuration.delete()
531 configuration.delete()
531
532
532 for id_conf in exp_parms['configurations']:
533 for id_conf in exp_parms['configurations']:
533 conf_parms = parms['configurations']['byId'][id_conf]
534 conf_parms = parms['configurations']['byId'][id_conf]
534 device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0]
535 device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0]
535 model = CONF_MODELS[conf_parms['device_type']]
536 model = CONF_MODELS[conf_parms['device_type']]
536 conf = model(
537 conf = model(
537 experiment = self,
538 experiment = self,
538 device = device,
539 device = device,
539 )
540 )
540 conf.dict_to_parms(parms, id=id_conf)
541 conf.dict_to_parms(parms, id=id_conf)
541
542
542
543
543 location, created = Location.objects.get_or_create(name=exp_parms['location'])
544 location, created = Location.objects.get_or_create(name=exp_parms['location'])
544 self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d'))
545 self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d'))
545 self.location = location
546 self.location = location
546 self.start_time = exp_parms['start_time']
547 self.start_time = exp_parms['start_time']
547 self.end_time = exp_parms['end_time']
548 self.end_time = exp_parms['end_time']
548 self.save()
549 self.save()
549
550
550 return self
551 return self
551
552
552 def get_absolute_url(self):
553 def get_absolute_url(self):
553 return reverse('url_experiment', args=[str(self.id)])
554 return reverse('url_experiment', args=[str(self.id)])
554
555
555 def get_absolute_url_edit(self):
556 def get_absolute_url_edit(self):
556 return reverse('url_edit_experiment', args=[str(self.id)])
557 return reverse('url_edit_experiment', args=[str(self.id)])
557
558
558 def get_absolute_url_delete(self):
559 def get_absolute_url_delete(self):
559 return reverse('url_delete_experiment', args=[str(self.id)])
560 return reverse('url_delete_experiment', args=[str(self.id)])
560
561
561 def get_absolute_url_import(self):
562 def get_absolute_url_import(self):
562 return reverse('url_import_experiment', args=[str(self.id)])
563 return reverse('url_import_experiment', args=[str(self.id)])
563
564
564 def get_absolute_url_export(self):
565 def get_absolute_url_export(self):
565 return reverse('url_export_experiment', args=[str(self.id)])
566 return reverse('url_export_experiment', args=[str(self.id)])
566
567
567 def get_absolute_url_start(self):
568 def get_absolute_url_start(self):
568 return reverse('url_start_experiment', args=[str(self.id)])
569 return reverse('url_start_experiment', args=[str(self.id)])
569
570
570 def get_absolute_url_stop(self):
571 def get_absolute_url_stop(self):
571 return reverse('url_stop_experiment', args=[str(self.id)])
572 return reverse('url_stop_experiment', args=[str(self.id)])
572
573
573
574
574 class Configuration(PolymorphicModel):
575 class Configuration(PolymorphicModel):
575
576
576 template = models.BooleanField(default=False)
577 template = models.BooleanField(default=False)
577 # name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
578 # name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
578 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
579 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
579 label = models.CharField(verbose_name="Label", max_length=40, default='', blank=True, null=True)
580 label = models.CharField(verbose_name="Label", max_length=40, default='', blank=True, null=True)
580 experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE)
581 experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE)
581 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
582 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
582 created_date = models.DateTimeField(auto_now_add=True)
583 created_date = models.DateTimeField(auto_now_add=True)
583 programmed_date = models.DateTimeField(auto_now=True)
584 programmed_date = models.DateTimeField(auto_now=True)
584 parameters = models.TextField(default='{}')
585 parameters = models.TextField(default='{}')
585 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
586 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
586 hash = models.CharField(default='', max_length=64, null=True, blank=True)
587 hash = models.CharField(default='', max_length=64, null=True, blank=True)
587 message = ""
588 message = ""
588
589
589 class Meta:
590 class Meta:
590 db_table = 'db_configurations'
591 db_table = 'db_configurations'
591 ordering = ('device__device_type__name',)
592 ordering = ('device__device_type__name',)
592
593
593 def __str__(self):
594 def __str__(self):
594
595
595 ret = u'{} '.format(self.device.device_type.name.upper())
596 ret = u'{} '.format(self.device.device_type.name.upper())
596
597
597 if 'mix' in [f.name for f in self._meta.get_fields()]:
598 if 'mix' in [f.name for f in self._meta.get_fields()]:
598 if self.mix:
599 if self.mix:
599 ret = '{} MIX '.format(self.device.device_type.name.upper())
600 ret = '{} MIX '.format(self.device.device_type.name.upper())
600
601
601 if 'label' in [f.name for f in self._meta.get_fields()]:
602 if 'label' in [f.name for f in self._meta.get_fields()]:
602 ret += '{}'.format(self.label)
603 ret += '{}'.format(self.label)
603
604
604 if self.template:
605 if self.template:
605 ret += ' (template)'
606 ret += ' (template)'
606
607
607 return ret
608 return ret
608
609
609 @property
610 @property
610 def name(self):
611 def name(self):
611
612
612 return str(self)
613 return str(self)
613
614
614 def jsonify(self):
615 def jsonify(self):
615
616
616 data = {}
617 data = {}
617
618
618 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
619 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
619 'created_date', 'programmed_date', 'template', 'device',
620 'created_date', 'programmed_date', 'template', 'device',
620 'experiment')
621 'experiment')
621
622
622 for field in self._meta.fields:
623 for field in self._meta.fields:
623 if field.name in ignored:
624 if field.name in ignored:
624 continue
625 continue
625 data[field.name] = field.value_from_object(self)
626 data[field.name] = field.value_from_object(self)
626
627
627 data['device_type'] = self.device.device_type.name
628 data['device_type'] = self.device.device_type.name
628
629
629 if self.device.device_type.name == 'rc':
630 if self.device.device_type.name == 'rc':
630 data['lines'] = ['{}'.format(line.pk) for line in self.get_lines()]
631 data['lines'] = ['{}'.format(line.pk) for line in self.get_lines()]
631 data['delays'] = self.get_delays()
632 data['delays'] = self.get_delays()
632 data['pulses'] = self.get_pulses()
633 data['pulses'] = self.get_pulses()
633
634
634 elif self.device.device_type.name == 'jars':
635 elif self.device.device_type.name == 'jars':
635 data['decode_type'] = DECODE_TYPE[self.decode_data][1]
636 data['decode_type'] = DECODE_TYPE[self.decode_data][1]
636
637
637 elif self.device.device_type.name == 'dds':
638 elif self.device.device_type.name == 'dds':
638 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
639 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
639 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
640 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
640 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
641 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
641 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
642 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
642
643
643 elif self.device.device_type.name == 'dds_rest':
644 elif self.device.device_type.name == 'dds_rest':
644 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
645 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
645 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
646 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
646 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
647 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
647 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
648 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
648 data['delta_frequency_Mhz'] = float(data['delta_frequency_Mhz'] or 0.00)
649 data['delta_frequency_Mhz'] = float(data['delta_frequency_Mhz'] or 0.00)
649 data['update_clock_Mhz'] = float(data['update_clock_Mhz'] or 0.00)
650 data['update_clock_Mhz'] = float(data['update_clock_Mhz'] or 0.00)
650 data['ramp_rate_clock_Mhz'] = float(data['ramp_rate_clock_Mhz'] or 0.0)
651 data['ramp_rate_clock_Mhz'] = float(data['ramp_rate_clock_Mhz'] or 0.0)
651 return data
652 return data
652
653
653 def clone(self, **kwargs):
654 def clone(self, **kwargs):
654
655
655 self.pk = None
656 self.pk = None
656 self.id = None
657 self.id = None
657 for attr, value in kwargs.items():
658 for attr, value in kwargs.items():
658 setattr(self, attr, value)
659 setattr(self, attr, value)
659
660
660 self.save()
661 self.save()
661
662
662 return self
663 return self
663
664
664 def parms_to_dict(self):
665 def parms_to_dict(self):
665
666
666 params = Params({})
667 params = Params({})
667 params.add(self.jsonify(), 'configurations')
668 params.add(self.jsonify(), 'configurations')
668
669
669 if self.device.device_type.name=='rc':
670 if self.device.device_type.name=='rc':
670 for line in self.get_lines():
671 for line in self.get_lines():
671 params.add(line.jsonify(), 'lines')
672 params.add(line.jsonify(), 'lines')
672
673
673 return params.data
674 return params.data
674
675
675 def parms_to_text(self):
676 def parms_to_text(self):
676
677
677 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
678 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
678
679
679
680
680 def parms_to_binary(self):
681 def parms_to_binary(self):
681
682
682 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
683 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
683
684
684
685
685 def dict_to_parms(self, parameters, id=None):
686 def dict_to_parms(self, parameters, id=None):
686
687
687 params = Params(parameters)
688 params = Params(parameters)
688
689
689 if id:
690 if id:
690 data = params.get_conf(id_conf=id)
691 data = params.get_conf(id_conf=id)
691 else:
692 else:
692 data = params.get_conf(dtype=self.device.device_type.name)
693 data = params.get_conf(dtype=self.device.device_type.name)
693
694
694 if data['device_type']=='rc':
695 if data['device_type']=='rc':
695 self.clean_lines()
696 self.clean_lines()
696 lines = data.pop('lines', None)
697 lines = data.pop('lines', None)
697 for line_id in lines:
698 for line_id in lines:
698 pass
699 pass
699
700
700 for key, value in data.items():
701 for key, value in data.items():
701 if key not in ('id', 'device_type'):
702 if key not in ('id', 'device_type'):
702 setattr(self, key, value)
703 setattr(self, key, value)
703
704
704 self.save()
705 self.save()
705
706
706
707
707 def export_to_file(self, format="json"):
708 def export_to_file(self, format="json"):
708
709
709 content_type = ''
710 content_type = ''
710
711
711 if format == 'racp':
712 if format == 'racp':
712 content_type = 'text/plain'
713 content_type = 'text/plain'
713 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, 'racp')
714 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, 'racp')
714 content = self.parms_to_text(file_format = 'racp')
715 content = self.parms_to_text(file_format = 'racp')
715
716
716 if format == 'text':
717 if format == 'text':
717 content_type = 'text/plain'
718 content_type = 'text/plain'
718 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
719 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
719 content = self.parms_to_text()
720 content = self.parms_to_text()
720
721
721 if format == 'binary':
722 if format == 'binary':
722 content_type = 'application/octet-stream'
723 content_type = 'application/octet-stream'
723 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
724 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
724 content = self.parms_to_binary()
725 content = self.parms_to_binary()
725
726
726 if not content_type:
727 if not content_type:
727 content_type = 'application/json'
728 content_type = 'application/json'
728 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
729 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
729 content = json.dumps(self.parms_to_dict(), indent=2)
730 content = json.dumps(self.parms_to_dict(), indent=2)
730
731
731 fields = {'content_type':content_type,
732 fields = {'content_type':content_type,
732 'filename':filename,
733 'filename':filename,
733 'content':content
734 'content':content
734 }
735 }
735
736
736 return fields
737 return fields
737
738
738 def import_from_file(self, fp):
739 def import_from_file(self, fp):
739
740
740 parms = {}
741 parms = {}
741
742
742 path, ext = os.path.splitext(fp.name)
743 path, ext = os.path.splitext(fp.name)
743
744
744 if ext == '.json':
745 if ext == '.json':
745 parms = json.load(fp)
746 parms = json.load(fp)
746
747
747 if ext == '.dds':
748 if ext == '.dds':
748 lines = fp.readlines()
749 lines = fp.readlines()
749 parms = dds_data.text_to_dict(lines)
750 parms = dds_data.text_to_dict(lines)
750
751
751 if ext == '.racp':
752 if ext == '.racp':
752 if self.device.device_type.name == 'jars':
753 if self.device.device_type.name == 'jars':
753 parms = RacpFile(fp).to_dict()
754 parms = RacpFile(fp).to_dict()
754 parms['filter_parms'] = json.loads(self.filter_parms)
755 parms['filter_parms'] = json.loads(self.filter_parms)
755 return parms
756 return parms
756 parms = RCFile(fp).to_dict()
757 parms = RCFile(fp).to_dict()
757
758
758 return parms
759 return parms
759
760
760 def status_device(self):
761 def status_device(self):
761
762
762 self.message = 'Function not implemented'
763 self.message = 'Function not implemented'
763 return False
764 return False
764
765
765
766
766 def stop_device(self):
767 def stop_device(self):
767
768
768 self.message = 'Function not implemented'
769 self.message = 'Function not implemented'
770 print("BUENAS SEÑALES??? NO LO CREO2",flush=True)
769 return False
771 return False
770
772
771
773
772 def start_device(self):
774 def start_device(self):
773
775
774 self.message = 'Function not implemented'
776 self.message = 'Function not implemented'
777 print("BUENAS SEÑALES??? NO LO CREO",flush=True)
775 return False
778 return False
776
779
777
780
778 def write_device(self, parms):
781 def write_device(self, parms):
779
782
780 self.message = 'Function not implemented'
783 self.message = 'Function not implemented'
784 print("BUENAS SEÑALES??? NO LO CREO3",flush=True)
781 return False
785 return False
782
786
783 def write_device_mqtt(self, parms):
787 def write_device_mqtt(self, parms):
784
788
785 self.message = 'Function not implemented'
789 self.message = 'Function not implemented'
786 return False
790 return False
787
791
788 def read_device(self):
792 def read_device(self):
789
793
790 self.message = 'Function not implemented'
794 self.message = 'Function not implemented'
791 return False
795 return False
792
796
793
797
794 def get_absolute_url(self):
798 def get_absolute_url(self):
795 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
799 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
796
800
797 def get_absolute_url_edit(self):
801 def get_absolute_url_edit(self):
798 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
802 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
799
803
800 def get_absolute_url_delete(self):
804 def get_absolute_url_delete(self):
801 return reverse('url_delete_dev_conf', args=[str(self.id)])
805 return reverse('url_delete_dev_conf', args=[str(self.id)])
802
806
803 def get_absolute_url_import(self):
807 def get_absolute_url_import(self):
804 return reverse('url_import_dev_conf', args=[str(self.id)])
808 return reverse('url_import_dev_conf', args=[str(self.id)])
805
809
806 def get_absolute_url_export(self):
810 def get_absolute_url_export(self):
807 return reverse('url_export_dev_conf', args=[str(self.id)])
811 return reverse('url_export_dev_conf', args=[str(self.id)])
808
812
809 def get_absolute_url_write(self):
813 def get_absolute_url_write(self):
810 return reverse('url_write_dev_conf', args=[str(self.id)])
814 return reverse('url_write_dev_conf', args=[str(self.id)])
811
815
812 def get_absolute_url_write_mqtt(self):
816 def get_absolute_url_write_mqtt(self):
813 return reverse('url_write_mqtt_dev_conf', args=[str(self.id)])
817 return reverse('url_write_mqtt_dev_conf', args=[str(self.id)])
814
818
815 def get_absolute_url_read(self):
819 def get_absolute_url_read(self):
816 return reverse('url_read_dev_conf', args=[str(self.id)])
820 return reverse('url_read_dev_conf', args=[str(self.id)])
817
821
818 def get_absolute_url_start(self):
822 def get_absolute_url_start(self):
819 return reverse('url_start_dev_conf', args=[str(self.id)])
823 return reverse('url_start_dev_conf', args=[str(self.id)])
820
824
821 def get_absolute_url_stop(self):
825 def get_absolute_url_stop(self):
822 return reverse('url_stop_dev_conf', args=[str(self.id)])
826 return reverse('url_stop_dev_conf', args=[str(self.id)])
823
827
824 def get_absolute_url_stop_mqtt(self):
828 def get_absolute_url_stop_mqtt(self):
825 return reverse('url_stop_mqtt_dev_conf', args=[str(self.id)])
829 return reverse('url_stop_mqtt_dev_conf', args=[str(self.id)])
826
830
827 def get_absolute_url_status(self):
831 def get_absolute_url_status(self):
828 return reverse('url_status_dev_conf', args=[str(self.id)])
832 return reverse('url_status_dev_conf', args=[str(self.id)])
General Comments 0
You need to be logged in to leave comments. Login now