##// END OF EJS Templates
SIR with docker-compose working
jespinoza -
r299:d18e81484ac8
parent child
Show More
@@ -0,0 +1,4
1 migrations/
2 .vscode/
3 *.pyc
4 .env
@@ -0,0 +1,39
1 # Integrated Radar System (SIR)
2
3 The Integrated Radar System (SIR) is a web application that allows the configuration of the radar devices as required by the experiment,
4 This app allows the creation of Campaigns, Experiment and Device Configurations.
5 For more information visit: http://jro-dev.igp.gob.pe:3000/projects/sistema-integrado-de-radar/wiki
6
7 ## Installation
8
9 We recommend use docker/docker-compose for test/production but you can install the aplication as a normal django app.
10
11 ### 1. Download
12
13 Download the application *radarsys* to your workspace
14
15 $ cd /path/to/your/workspace
16 $ git clone http://jro-dev.igp.gob.pe/rhodecode/radarsys && cd radarsys
17
18 ### 2. Config app
19
20 Create enviroment vars (/path/to/radarsys/.env)
21
22 HOST_REDIS=radarsys-redis
23 POSTGRES_DB_NAME=radarsys
24 POSTGRES_PORT_5432_TCP_ADDR=radarsys-postgres
25 POSTGRES_PORT_5432_TCP_PORT=5432
26 POSTGRES_USER=docker
27 POSTGRES_PASSWORD=****
28 PGDATA=/var/lib/postgresql/data
29 LC_ALL=C.UTF-8
30
31 Set database user/password in /path/to/radarsys/settings.py
32
33 ### 3. Build application
34
35 $ docker-compose build
36
37 ### 4. Run containers
38
39 $ docker-compose up -d No newline at end of file
@@ -0,0 +1,3
1 FROM postgres:10.1-alpine
2
3 RUN mkdir -p "$PGDATA" && chmod 700 "$PGDATA" No newline at end of file
@@ -0,0 +1,3
1 #!/bin/env bash
2 psql -U postgres -c "CREATE USER $POSTGRES_USER PASSWORD '$POSTGRES_PASSWORD'"
3 psql -U postgres -c "CREATE DATABASE $POSTGRES_DB_NAME OWNER $POSTGRES_USER" No newline at end of file
@@ -1,7 +1,8
1 HOST_MYSQL=mysql
2 HOST_REDIS=redis
3 MYSQL_ROOT_PASSWORD=r00tJRO
4 MYSQL_DATABASE=radarsys
5 MYSQL_USER=developer
6 MYSQL_PASSWORD=idi2015
7 HOST_REDIS=redis No newline at end of file
1 HOST_REDIS=radarsys-redis
2 POSTGRES_DB_NAME=radarsys
3 POSTGRES_PORT_5432_TCP_ADDR=radarsys-postgres
4 POSTGRES_PORT_5432_TCP_PORT=5432
5 POSTGRES_USER=docker
6 POSTGRES_PASSWORD=docker
7 PGDATA=/var/lib/postgresql/data
8 LC_ALL=C.UTF-8 No newline at end of file
@@ -1,16 +1,23
1 FROM python:2.7.11
1 FROM python:2.7-slim
2 2
3 3 # set working directory
4 4 RUN mkdir /radarsys
5 5 WORKDIR /radarsys
6 6
7 7 # Install python dependences
8 8 ADD requirements.txt ./requirements.txt
9 RUN pip install -v --timeout 120 -r requirements.txt --no-cache-dir
9 RUN apt-get clean && apt-get update && apt-get install -y --no-install-recommends \
10 gcc \
11 g++ \
12 && pip install -v --timeout 120 -r requirements.txt --no-cache-dir --index-url http://10.10.20.128:8010/simple --trusted-host 10.10.20.128 \
13 && apt-get purge -y --auto-remove gcc g++\
14 && rm -rf /var/lib/apt/lists/*
10 15
11 16 # Copy the main application.
12 17 COPY . ./
13 18
19 EXPOSE 8000
20
14 21 RUN python manage.py collectstatic --noinput
15 22
16 23
@@ -1,621 +1,621
1 1 """
2 2 The module GRAPHICS_OVERJRO.py gathers classes or/and functions to create graphics from OVER-JRO
3 3 project (e.g. antenna patterns, skynoise, ...).
4 4
5 5 MODULES CALLED:
6 6 TIME, NUMPY, MATPLOTLIB, TIMETOOLS
7 7
8 8 MODIFICATION HISTORY:
9 9 Created by Ing. Freddy Galindo (frederickgalindo@gmail.com). ROJ Oct 18, 2009.
10 10 """
11 11
12 12 import time
13 13 import numpy
14 14 import sys
15 15 import os
16 16
17 17 # set HOME environment variable to a directory the httpd server can write to
18 18 #os.environ[ 'HOME' ] = '/usr/local/www/htdocs/overJro/tempReports'
19 19 #os.environ[ 'HOME' ] = '/home/dsuarez/Pictures'
20 20 #os.environ[ 'HOME' ] = '/tmp/'
21 21 import matplotlib
22 22 #if ide==1:
23 23 # matplotlib.use('Qt4Agg')
24 24 #elif ide==2:
25 25 # matplotlib.use("Agg")
26 26 #else:
27 27 # matplotlib.use('TKAgg')
28 #matplotlib.use("Agg")
28 matplotlib.use("Agg")
29 29 #matplotlib.interactive(1)
30 30 import matplotlib.pyplot
31 31 #import Numeric
32 32 #import scipy
33 33 import scipy.interpolate
34 34
35 35 import Astro_Coords
36 36 import TimeTools
37 37 import Graphics_Miscens
38 38
39 39 import Misc_Routines
40 40
41 41 class AntPatternPlot:
42 42 def __init__(self):
43 43 """
44 44 AntPatternPlot creates an object to call methods to plot the antenna pattern.
45 45
46 46 Modification History
47 47 --------------------
48 48 Created by Freddy Galindo, ROJ, 06 October 2009.
49 49 """
50 50
51 51 self.fig = matplotlib.pyplot.figure(figsize=(8,8), facecolor='white')
52 52 self.ax = self.fig.add_subplot(111)
53 53
54 54 def contPattern(self,iplot=0,gpath='',filename='',mesg='',amp=None ,x=None ,y=None ,getCut=None,title='', save=True):
55 55 """
56 56 contPattern plots a contour map of the antenna pattern.
57 57
58 58 Parameters
59 59 ----------
60 60 iplot = A integer to specify if the plot is the first, second, ... The default va-
61 61 lue is 0.
62 62
63 63 Examples
64 64 --------
65 65 >> Over_Jro.JroPattern(pattern=2).contPattern()
66 66
67 67 Modification history
68 68 --------------------
69 69 Converted to Python by Freddy R. Galindo, ROJ, 06 October 2009.
70 70 """
71 71
72 72 if getCut == 1:
73 73 return
74 74
75 75 xmax = numpy.max(x)
76 76 xmin = numpy.min(x)
77 77 ymax = numpy.max(y)
78 78 ymin = numpy.min(y)
79 79
80 80 levels = numpy.array([1e-3,1e-2,1e-1,0.5,1.0])
81 81 tmp = numpy.round(10*numpy.log10(levels),decimals=1)
82 82 labels = range(5)
83 83 for i in numpy.arange(5):labels[i] = str(numpy.int(tmp[i]))
84 84
85 85
86 86 colors = ((0,0,1.),(0,170/255.,0),(127/255.,1.,0),(1.,109/255.,0),(128/255.,0,0))
87 87 CS = self.ax.contour(x,y,amp.transpose(),levels,colors=colors)
88 88 fmt = {}
89 89 for l,s in zip(CS.levels,labels):
90 90 fmt[l] = s
91 91
92 92 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.)
93 93 self.ax.annotate(mesg,xy=(0,0),xytext=(0.01,0.01),xycoords='figure fraction')
94 94 self.ax.clabel(CS,CS.levels,inline=True,fmt=fmt,fontsize=10)
95 95 self.ax.set_xlim(xmin,xmax)
96 96 self.ax.set_ylim(ymin,ymax)
97 97 self.ax.set_title("Total Pattern: " + title)
98 98 self.ax.set_xlabel("West to South")
99 99 self.ax.set_ylabel("West to North")
100 100 self.ax.grid(True)
101 101
102 102 if save:
103 103 save_fig = os.path.join(gpath,filename)
104 104 self.fig.savefig(save_fig,format='png')
105 105
106 106
107 107
108 108 def close(self):
109 109
110 110 matplotlib.pyplot.close(self.fig)
111 111
112 112 def plotRaDec(self,gpath=None,filename=None,jd=2452640.5,ra_obs=None,xg=None,yg=None,x=None,y=None, save=True):
113 113 """
114 114 plotRaDec draws right ascension and declination lines on a JRO plane. This function
115 115 must call after conPattern.
116 116
117 117 Parameters
118 118 ----------
119 119 jd = A scalar giving the Julian date.
120 120 ra_obs = Scalar giving the right ascension of the observatory.
121 121 xg = A 3-element array to specify ..
122 122 yg = A 3-element array to specify ..
123 123
124 124 Examples
125 125 --------
126 126 >> Over_Jro.JroPattern(pattern=2).contPattern()
127 127 >> Over_Jro.JroPattern(pattern=2).plotRaDec(jd=jd,ra_obs=ra_obs,xg=xg,yg=yg)
128 128
129 129 Modification history
130 130 --------------------
131 131 Converted to Python by Freddy R. Galindo, ROJ, 06 October 2009.
132 132 """
133 133
134 134 # Finding RA of observatory for a specific date
135 135 if ra_obs is None:ra_obs = numpy.array([23.37060849])
136 136 if xg is None:xg = numpy.array([0.62918474,-0.77725579,0.])
137 137 if yg is None:yg = numpy.array([0.77700346,0.62898048,0.02547905])
138 138
139 139 # Getting HA and DEC axes
140 140 mindec = -28; maxdec = 4; incdec = 2.
141 141 ndec = numpy.int((maxdec - mindec)/incdec) + 1
142 142
143 143 minha = -20; maxha = 20; incha = 2.
144 144 nha = numpy.int((maxha - minha)/incha) + 1
145 145
146 146 #mcosx = numpy.zeros((nha,ndec))
147 147 #mcosy = numpy.zeros((nha,ndec))
148 148
149 149 ha_axes = numpy.reshape(numpy.arange(nha)*incha + minha,(nha,1))
150 150 ones_dec = numpy.reshape(numpy.zeros(ndec) + 1,(ndec,1))
151 151 ha_axes = numpy.dot(ha_axes,ones_dec.transpose())
152 152 ha_axes2 = numpy.array(ra_obs - ha_axes)
153 153
154 154 dec_axes = numpy.reshape(numpy.arange(ndec)*incdec + mindec,(ndec,1))
155 155 ones_ra = numpy.reshape(numpy.zeros(nha) + 1,(nha,1))
156 156 dec_axes = numpy.dot(ones_ra,dec_axes.transpose())
157 157 dec_axes2 = numpy.array(dec_axes)
158 158
159 159 ObjHor = Astro_Coords.Equatorial(ha_axes2,dec_axes2,jd)
160 160 [alt,az,ha] = ObjHor.change2AltAz()
161 161
162 162 z = numpy.transpose(alt)*Misc_Routines.CoFactors.d2r ; z = z.flatten()
163 163 az = numpy.transpose(az)*Misc_Routines.CoFactors.d2r ; az = az.flatten()
164 164
165 165 vect = numpy.array([numpy.cos(z)*numpy.sin(az),numpy.cos(z)*numpy.cos(az),numpy.sin(z)])
166 166
167 167 xg = numpy.atleast_2d(xg)
168 168 dcosx = numpy.array(numpy.dot(xg,vect))
169 169 yg = numpy.atleast_2d(yg)
170 170 dcosy = numpy.array(numpy.dot(yg,vect))
171 171
172 172 mcosx = dcosx.reshape(ndec,nha)
173 173 mcosy = dcosy.reshape(ndec,nha)
174 174
175 175 # Defining NAN for points outof limits.
176 176 xmax = numpy.max(x)
177 177 xmin = numpy.min(x)
178 178 ymax = numpy.max(y)
179 179 ymin = numpy.min(y)
180 180
181 181 factor = 1.3
182 182 noval = numpy.where((mcosx>(xmax*factor)) | (mcosx<(xmin*factor)))
183 183 if noval[0].size>0:mcosx[noval] = numpy.nan
184 184 noval = numpy.where((mcosy>(ymax*factor)) | (mcosy<(ymin*factor)))
185 185 if noval[0].size>0:mcosy[noval] = numpy.nan
186 186
187 187 # Plotting HA and declination grid.
188 188 iha0 = numpy.int((0 - minha)/incha)
189 189 idec0 = numpy.int((-14 - mindec)/incdec)
190 190
191 191 colorgrid = (1.,109/255.,0)
192 192 self.ax.plot(mcosx.transpose(),mcosy.transpose(),color=colorgrid,linestyle='--')
193 193 for idec in numpy.arange(ndec):
194 194 if idec != idec0:
195 195 valx = (mcosx[idec,iha0]<=xmax) & (mcosx[idec,iha0]>=xmin)
196 196 valy = (mcosy[idec,iha0]<=ymax) & (mcosy[idec,iha0]>=ymin)
197 197 if valx & valy:
198 198 text = str(numpy.int(mindec + incdec*idec))+'$^o$'
199 199 self.ax.text(mcosx[idec,iha0],mcosy[idec,iha0],text)
200 200
201 201 matplotlib.pyplot.plot(mcosx,mcosy,color=colorgrid,linestyle='--')
202 202 for iha in numpy.arange(nha):
203 203 if iha != iha0:
204 204 valx = (mcosx[idec0,iha]<=xmax) & (mcosx[idec0,iha]>=xmin)
205 205 valy = (mcosy[idec0,iha]<=ymax) & (mcosy[idec0,iha]>=ymin)
206 206 if valx & valy:
207 207 text = str(4*numpy.int(minha + incha*iha))+"'"
208 208 self.ax.text(mcosx[idec0,iha],mcosy[idec0,iha],text)
209 209
210 210 if save:
211 211 save_fig = os.path.join(gpath,filename)
212 212 matplotlib.pyplot.savefig(save_fig,format='png')
213 213
214 214
215 215 def plotBField(self,gpath,filename,dcos,alpha, nlon, nlat, dcosxrange, dcosyrange, heights, alpha_i, save=True):
216 216 """
217 217 plotBField draws the magnetic field in a directional cosines plot.
218 218
219 219 Parameters
220 220 ----------
221 221 dcos = An 4-dimensional array giving the directional cosines of the magnetic field
222 222 over the desired place.
223 223 alpha = An 3-dimensional array giving the angle of the magnetic field over the desi-
224 224 red place.
225 225 nlon = An integer to specify the number of elements per longitude.
226 226 nlat = An integer to specify the number of elements per latitude.
227 227 dcosxrange = A 2-element array giving the range of the directional cosines in the
228 228 "x" axis.
229 229 dcosyrange = A 2-element array giving the range of the directional cosines in the
230 230 "y" axis.
231 231 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.
232 232 alpha_i = Angle to interpolate the magnetic field.
233 233 Modification History
234 234 --------------------
235 235 Converted to Python by Freddy R. Galindo, ROJ, 07 October 2009.
236 236 """
237 237
238 238 handles = []
239 239 objects = []
240 240 colors = ['k','m','c','b','g','r','y']
241 241 marker = ['-+','-*','-D','-x','-s','->','-o','-^']
242 242
243 243 alpha_location = numpy.zeros((nlon,2,heights.size))
244 244
245 245 for ih in numpy.arange(heights.size):
246 246 alpha_location[:,0,ih] = dcos[:,0,ih,0]
247 247 for ilon in numpy.arange(nlon):
248 248 myx = (alpha[ilon,:,ih])[::-1]
249 249 myy = (dcos[ilon,:,ih,0])[::-1]
250 250 tck = scipy.interpolate.splrep(myx,myy,s=0)
251 251 mydcosx = scipy.interpolate.splev(alpha_i,tck,der=0)
252 252
253 253 myx = (alpha[ilon,:,ih])[::-1]
254 254 myy = (dcos[ilon,:,ih,1])[::-1]
255 255 tck = scipy.interpolate.splrep(myx,myy,s=0)
256 256 mydcosy = scipy.interpolate.splev(alpha_i,tck,der=0)
257 257 alpha_location[ilon,:,ih] = numpy.array([mydcosx, mydcosy])
258 258
259 259
260 260 ObjFig, = self.ax.plot(alpha_location[:,0,ih],alpha_location[:,1,ih],
261 261 marker[ih % 8],color=colors[numpy.int(ih/8)],ms=4.5,lw=0.5)
262 262 handles.append(ObjFig)
263 263 objects.append(numpy.str(heights[ih]) + ' km')
264 264
265 265 self.ax.legend(handles,objects,loc="lower right", numpoints=1, handlelength=0.3,
266 266 handletextpad=0.02, borderpad=0.3, labelspacing=0.1)
267 267
268 268 if save:
269 269 save_fig = os.path.join(gpath,filename)
270 270 matplotlib.pyplot.savefig(save_fig,format='png')
271 271
272 272
273 273
274 274 class BFieldPlot:
275 275 def __init__(self):
276 276 """
277 277 BFieldPlot creates an object for drawing magnetic Field lines over Jicamarca.
278 278
279 279 Modification History
280 280 --------------------
281 281 Created by Freddy Galindo, ROJ, 07 October 2009.
282 282 """
283 283
284 284 self.alpha_location = 1
285 285 # pass
286 286
287 287 def plotBField(self,gpath,filename,dcos,alpha, nlon, nlat, dcosxrange, dcosyrange, heights, alpha_i):
288 288 """
289 289 plotBField draws the magnetic field in a directional cosines plot.
290 290
291 291 Parameters
292 292 ----------
293 293 dcos = An 4-dimensional array giving the directional cosines of the magnetic field
294 294 over the desired place.
295 295 alpha = An 3-dimensional array giving the angle of the magnetic field over the desi-
296 296 red place.
297 297 nlon = An integer to specify the number of elements per longitude.
298 298 nlat = An integer to specify the number of elements per latitude.
299 299 dcosxrange = A 2-element array giving the range of the directional cosines in the
300 300 "x" axis.
301 301 dcosyrange = A 2-element array giving the range of the directional cosines in the
302 302 "y" axis.
303 303 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.
304 304 alpha_i = Angle to interpolate the magnetic field.
305 305 Modification History
306 306 --------------------
307 307 Converted to Python by Freddy R. Galindo, ROJ, 07 October 2009.
308 308 """
309 309
310 310 handles = []
311 311 objects = []
312 312 colors = ['k','m','c','b','g','r','y']
313 313 marker = ['-+','-*','-D','-x','-s','->','-o','-^']
314 314
315 315 alpha_location = numpy.zeros((nlon,2,heights.size))
316 316
317 317 for ih in numpy.arange(heights.size):
318 318 alpha_location[:,0,ih] = dcos[:,0,ih,0]
319 319 for ilon in numpy.arange(nlon):
320 320 myx = (alpha[ilon,:,ih])[::-1]
321 321 myy = (dcos[ilon,:,ih,0])[::-1]
322 322 tck = scipy.interpolate.splrep(myx,myy,s=0)
323 323 mydcosx = scipy.interpolate.splev(alpha_i,tck,der=0)
324 324
325 325 myx = (alpha[ilon,:,ih])[::-1]
326 326 myy = (dcos[ilon,:,ih,1])[::-1]
327 327 tck = scipy.interpolate.splrep(myx,myy,s=0)
328 328 mydcosy = scipy.interpolate.splev(alpha_i,tck,der=0)
329 329 alpha_location[ilon,:,ih] = numpy.array([mydcosx, mydcosy])
330 330
331 331
332 332 ObjFig, = matplotlib.pyplot.plot(alpha_location[:,0,ih],alpha_location[:,1,ih], \
333 333 marker[ih % 8],color=colors[numpy.int(ih/8)],ms=4.5,lw=0.5)
334 334 handles.append(ObjFig)
335 335 objects.append(numpy.str(heights[ih]) + ' km')
336 336
337 337 matplotlib.pyplot.xlim(dcosxrange[0],dcosxrange[1])
338 338 matplotlib.pyplot.ylim(dcosyrange[0],dcosyrange[1])
339 339
340 340 try:
341 341 ObjlegB = matplotlib.pyplot.legend(handles,objects,loc="lower right", numpoints=1, handlelength=0.3, \
342 342 handletextpad=0.02, borderpad=0.3, labelspacing=0.1)
343 343 except:
344 344 ObjlegB = matplotlib.pyplot.legend(handles,objects,loc=[0.01,0.75], numpoints=1, handlelength=0, \
345 345 pad=0.015, handletextsep=0.02,labelsep=0.01)
346 346
347 347 matplotlib.pyplot.setp(ObjlegB.get_texts(),fontsize='small')
348 348 matplotlib.pyplot.gca().add_artist(ObjlegB)
349 349
350 350 save_fig = os.path.join(gpath,filename)
351 351 matplotlib.pyplot.savefig(save_fig,format='png')
352 352 self.alpha_location = alpha_location
353 353
354 354
355 355 class CelestialObjectsPlot:
356 356 def __init__(self,jd,dec,tod,maxha_min,show_object=None):
357 357
358 358 self.jd = jd
359 359 self.dec = dec
360 360 self.tod = tod
361 361 self.maxha_min = maxha_min
362 362
363 363 if show_object==None:show_object=numpy.zeros(4)+2
364 364 self.show_object = show_object
365 365
366 366 self.dcosx_sun = 1
367 367 self.dcosy_sun = 1
368 368 self.ha_sun = 1
369 369 self.time_sun = 1
370 370
371 371 self.dcosx_moon = 1
372 372 self.dcosy_moon = 1
373 373 self.ha_moon = 1
374 374 self.time_moon = 1
375 375
376 376 self.dcosx_hydra = 1
377 377 self.dcosy_hydra = 1
378 378 self.ha_hydra = 1
379 379 self.time_hydra = 1
380 380
381 381 self.dcosx_galaxy = 1
382 382 self.dcosy_galaxy = 1
383 383 self.ha_galaxy = 1
384 384 self.time_galaxy = 1
385 385
386 386 def drawObject(self,glat,glon,xg,yg,dcosxrange,dcosyrange,gpath='',filename=''):
387 387
388 388 jd = self.jd
389 389 main_dec = self.dec
390 390 tod = self.tod
391 391 maxha_min = self.maxha_min
392 392
393 393 mesg = "Drawing celestial objects over Observatory"
394 394 # print mesg
395 395 # if textid!=None:textid.append(mesg)
396 396
397 397 maxlev = 24; minlev = 0; maxcol = 39; mincol = 10
398 398 handles = []
399 399 objects = ['$Sun$','$Moon$','$Hydra$','$Galaxy$']
400 400 marker = ['--^','--s','--*','--o']
401 401
402 402 # Getting RGB table to plot celestial object over Jicamarca
403 403 colortable = Graphics_Miscens.ColorTable(table=1).readTable()
404 404
405 405 for io in (numpy.arange(4)+1):
406 406 if self.show_object[io]!=0:
407 407 ObjBodies = Astro_Coords.CelestialBodies()
408 408 if io==1:
409 409 [ra,dec,sunlon,sunobliq] = ObjBodies.sunpos(jd)
410 410 elif io==2:
411 411 [ra,dec,dist,moonlon,moonlat] = ObjBodies.moonpos(jd)
412 412 elif io==3:
413 413 [ra,dec] = ObjBodies.hydrapos()
414 414 elif io==4:
415 415 [maxra,ra] = ObjBodies.skynoise_jro(dec_cut=main_dec)
416 416 ra = maxra*15.
417 417 dec = main_dec
418 418
419 419 ObjEq = Astro_Coords.Equatorial(ra,dec,jd,lat=glat,lon=glon)
420 420 [alt, az, ha] = ObjEq.change2AltAz()
421 421 vect = numpy.array([az,alt]).transpose()
422 422 vect = Misc_Routines.Vector(vect,direction=0).Polar2Rect()
423 423
424 424 dcosx = numpy.array(numpy.dot(vect,xg))
425 425 dcosy = numpy.array(numpy.dot(vect,yg))
426 426 wrap = numpy.where(ha>=180.)
427 427 if wrap[0].size>0:ha[wrap] = ha[wrap] - 360.
428 428
429 429 val = numpy.where((numpy.abs(ha))<=(maxha_min*0.25))
430 430 if val[0].size>2:
431 431 tod_1 = tod*1.
432 432 shift_1 = numpy.where(tod>12.)
433 433 tod_1[shift_1] = tod_1[shift_1] - 24.
434 434 tod_2 = tod*1.
435 435 shift_2 = numpy.where(tod<12.)
436 436 tod_2[shift_2] = tod_2[shift_2] + 24.
437 437
438 438 diff0 = numpy.nanmax(tod[val]) - numpy.nanmin(tod[val])
439 439 diff1 = numpy.nanmax(tod_1[val]) - numpy.nanmin(tod_1[val])
440 440 diff2 = numpy.nanmax(tod_2[val]) - numpy.nanmin(tod_2[val])
441 441
442 442 if ((diff0<=diff1) & (diff0<=diff2)):
443 443 tod_0 = tod
444 444 elif ((diff1<diff0) & (diff1<diff2)):
445 445 tod_0 = tod_1
446 446 else:
447 447 tod_0 = tod_2
448 448
449 449 if io==1:
450 450 self.dcosx_sun = dcosx[val]
451 451 self.dcosy_sun = dcosy[val]
452 452 self.ha_sun = ha[val]
453 453 self.time_sun = numpy.median(tod_0[val])
454 454 elif io==2:
455 455 self.dcosx_moon = dcosx[val]
456 456 self.dcosy_moon = dcosy[val]
457 457 self.ha_moon = ha[val]
458 458 self.time_moon = numpy.median(tod_0[val])
459 459 elif io==3:
460 460 self.dcosx_hydra = dcosx[val]
461 461 self.dcosy_hydra = dcosy[val]
462 462 self.ha_hydra = ha[val]
463 463 self.time_hydra = numpy.mean(tod_0[val])
464 464 elif io==4:
465 465 self.dcosx_galaxy = dcosx[val]
466 466 self.dcosy_galaxy = dcosy[val]
467 467 self.ha_galaxy = ha[val]
468 468 self.time_galaxy = numpy.mean(tod_0[val])
469 469
470 470 index = numpy.mean(tod_0[val]) - minlev
471 471 index = (index*(maxcol - mincol)/(maxlev - minlev)) + mincol
472 472 index = numpy.int(index)
473 473 figobjects, = matplotlib.pyplot.plot(dcosx[val],dcosy[val],marker[io-1],\
474 474 lw=1,ms=7,mew=0,color=tuple(colortable[:,index]))
475 475 handles.append(figobjects)
476 476
477 477 xmax = numpy.max(dcosxrange[1])
478 478 xmin = numpy.min(dcosxrange[0])
479 479 ymax = numpy.max(dcosyrange[1])
480 480 ymin = numpy.min(dcosyrange[0])
481 481 matplotlib.pyplot.xlim(xmin,xmax)
482 482 matplotlib.pyplot.ylim(ymin,ymax)
483 483
484 484 val = numpy.where(self.show_object[1:]>0)
485 485 objects = numpy.array(objects)
486 486 objects = list(objects[val])
487 487 try:
488 488 ObjlegC = matplotlib.pyplot.legend(handles,objects,loc="lower left", numpoints=1, handlelength=0.3, \
489 489 borderpad=0.3, handletextpad=0.02,labelspacing=0.1)
490 490 except:
491 491 ObjlegC = matplotlib.pyplot.legend(handles,objects,loc=[0.01,0.75], numpoints=1, handlelength=0, \
492 492 pad=0.015, handletextsep=0.02,labelsep=0.01)
493 493
494 494 matplotlib.pyplot.setp(ObjlegC.get_texts(),fontsize='small')
495 495 ObjlegC.isaxes = False
496 496 save_fig = os.path.join(gpath,filename)
497 497 matplotlib.pyplot.savefig(save_fig,format='png')
498 498
499 499
500 500 class PatternCutPlot:
501 501 def __init__(self,nsubplots):
502 502 self.nsubplots = nsubplots
503 503
504 504 self.fig = None
505 505
506 506 self.__plot_width = 8
507 507
508 508 if self.nsubplots == 5:
509 509 self.__plot_height = 11
510 510
511 511 if self.nsubplots == 4:
512 512 self.__plot_height = 9
513 513
514 514 if self.nsubplots == 3:
515 515 self.__plot_height = 7
516 516
517 517 if self.nsubplots == 2:
518 518 self.__plot_height = 5
519 519
520 520 if self.nsubplots == 1:
521 521 self.__plot_height = 3
522 522
523 523 self.fig = matplotlib.pyplot.figure(num = 4,figsize = (self.__plot_width, self.__plot_height))
524 524
525 525 if self.nsubplots < 5:
526 526 self.__height_inch = 1.1 #altura de los subplots (pulgadas)
527 527 top_inch = 1.5/2.7 #espacio entre el primer subplot y el limite superior del plot
528 528 self.__vspace_plot_inch = 1.0#1.5/2 # espacio vertical entre subplots
529 529 self.__left = 0.1
530 530 else:
531 531 self.__height_inch = 1.1 #altura de los subplots (pulgadas)
532 532 top_inch = 1.5/2.7 #espacio entre el primer subplot y el limite superior del plot
533 533 self.__vspace_plot_inch = 1.0 # espacio vertical entre subplots
534 534 self.__left = 0.1
535 535
536 536 self.__bottom_inch = self.__plot_height - (self.__height_inch + top_inch)
537 537 self.__height = self.__height_inch/self.__plot_height
538 538
539 539 self.__width = 0.8
540 540
541 541
542 542 def drawCut(self,io,patterns,npatterns,ha,otitle,subtitle,ptitle):
543 543
544 544 t_cuts = ['B','Sun','Moon','Hydra','Galaxy']
545 545 self.__bottom = self.__bottom_inch/self.__plot_height
546 546
547 547
548 548 subp = self.fig.add_axes([self.__left,self.__bottom,self.__width,self.__height])
549 549
550 550 on_axis_angle = -4.65562
551 551 for icut in numpy.arange(npatterns):
552 552 # Getting Antenna cut.
553 553 pattern = patterns[icut]
554 554 power = numpy.abs(pattern/numpy.nanmax(pattern))
555 555 max_power_db = numpy.round(10.*numpy.log10(numpy.nanmax(pattern)),2)
556 556
557 557 bval = numpy.where(power[:,0]==numpy.nanmax(power))
558 558 beta = -0.25*(ha[bval[0]] + on_axis_angle)
559 559 # print 'Angle (deg): '+"%f"%(beta)
560 560
561 561 subp.plot(ha,power)
562 562
563 563
564 564 xmax = numpy.max(numpy.nanmin(ha))
565 565 xmin = numpy.min(numpy.nanmax(ha))
566 566 ymax = numpy.max(1)
567 567 ymin = numpy.min(0)
568 568
569 569
570 570 subp.set_xlim(xmin, xmax)
571 571
572 572 subp.set_ylim(ymin, ymax)
573 573
574 574 subp.set_title(otitle + ' ' + ptitle,size="medium")
575 575
576 576 subp.text(0.5, 1.26,subtitle[0],
577 577 horizontalalignment='center',
578 578 verticalalignment='center',
579 579 transform = subp.transAxes)
580 580
581 581 xlabels = subp.get_xticks()
582 582
583 583 subp.set_xticklabels(xlabels,size="small")
584 584
585 585 ylabels = subp.get_yticks()
586 586
587 587 subp.set_yticklabels(ylabels,size="small")
588 588
589 589 subp.set_xlabel('Hour angle (min) (+ve to West)',size="small")
590 590
591 591 subp.set_ylabel("Power [Max: " + str(max_power_db) + ' dB]',size="small")
592 592
593 593 subp.grid()
594 594
595 595
596 596 self.__bottom_inch = self.__bottom_inch - (self.__height_inch + self.__vspace_plot_inch)
597 597
598 598
599 599 class SkyNoisePlot:
600 600 def __init__(self,date,powr,time,time_lst):
601 601 """
602 602 SkyNoisePlot class creates an object which represents the SkyNoise Object to genera-
603 603 te a SkyNoise map.
604 604
605 605 Parameters
606 606 ----------
607 607 date = A List of 3 elements to define the desired date ([year, month, day]).
608 608 powr = An array giving the SkyNoise power for the desired time.
609 609 time = An array giving the number of seconds since 1970 to the desired time.
610 610 time_lst = Set this input to an array to define the Local Sidereal Time of the desi-
611 611 red time.
612 612
613 613 Modification History
614 614 --------------------
615 615 Created by Freddy Galindo, ROJ, 18 October 2009.
616 616 """
617 617
618 618 self.date = date
619 619 self.powr = powr
620 620 self.time = time
621 621 self.time_lst = time_lst
@@ -1,10 +1,10
1 1 {% extends "base.html" %}
2 2 {% load bootstrap3 %}
3 3 {% block content-title %}Integrated Radar System{% endblock %}
4 4 {% block content-suptitle %}at JRO{% endblock %}
5 5
6 6 {% block content %}
7 7
8 {% lorem %}
8 <p>{% lorem %}</p>
9 9
10 10 {% endblock %}
@@ -1,982 +1,1002
1 1
2 2
3 3 import ast
4 4 import json
5 5 import requests
6 6 import numpy as np
7 7 from base64 import b64encode
8 8 from struct import pack
9 9
10 10 from django.db import models
11 11 from django.core.urlresolvers import reverse
12 12 from django.core.validators import MinValueValidator, MaxValueValidator
13 13
14 14 from apps.main.models import Configuration
15 15 from apps.main.utils import Params
16 16 from devices.rc import api
17 17 from apps.rc.utils import RCFile
18 18
19 19
20 20 LINE_TYPES = (
21 21 ('none', 'Not used'),
22 22 ('tr', 'Transmission/reception selector signal'),
23 23 ('tx', 'A modulating signal (Transmission pulse)'),
24 24 ('codes', 'BPSK modulating signal'),
25 25 ('windows', 'Sample window signal'),
26 26 ('sync', 'Synchronizing signal'),
27 27 ('flip', 'IPP related periodic signal'),
28 28 ('prog_pulses', 'Programmable pulse'),
29 29 ('mix', 'Mixed line'),
30 30 )
31 31
32 32
33 33 SAMPLING_REFS = (
34 34 ('none', 'No Reference'),
35 35 ('begin_baud', 'Begin of the first baud'),
36 36 ('first_baud', 'Middle of the first baud'),
37 37 ('sub_baud', 'Middle of the sub-baud')
38 38 )
39 39
40 40 DAT_CMDS = {
41 41 # Pulse Design commands
42 42 'DISABLE' : 0, # Disables pulse generation
43 43 'ENABLE' : 24, # Enables pulse generation
44 44 'DELAY_START' : 40, # Write delay status to memory
45 45 'FLIP_START' : 48, # Write flip status to memory
46 46 'SAMPLING_PERIOD' : 64, # Establish Sampling Period
47 47 'TX_ONE' : 72, # Output '0' in line TX
48 48 'TX_ZERO' : 88, # Output '0' in line TX
49 49 'SW_ONE' : 104, # Output '0' in line SW
50 50 'SW_ZERO' : 112, # Output '1' in line SW
51 51 'RESTART': 120, # Restarts CR8 Firmware
52 52 'CONTINUE' : 253, # Function Unknown
53 53 # Commands available to new controllers
54 54 # In Pulse Design Executable, the clock divisor code is written as 12 at the start, but it should be written as code 22(below) just before the final enable.
55 55 'CLOCK_DIVISOR_INIT' : 12, # Specifies Clock Divisor. Legacy command, ignored in the actual .dat conversion
56 56 'CLOCK_DIVISOR_LAST' : 22, # Specifies Clock Divisor (default 60 if not included) syntax: 255,22 254,N-1.
57 57 'CLOCK_DIVIDER' : 8,
58 58 }
59 59
60 60 MAX_BITS = 8
61 61
62 62 # Rotate left: 0b1001 --> 0b0011
63 63 rol = lambda val, r_bits: \
64 64 (val << r_bits%MAX_BITS) & (2**MAX_BITS-1) | \
65 65 ((val & (2**MAX_BITS-1)) >> (MAX_BITS-(r_bits%MAX_BITS)))
66 66
67 67 # Rotate right: 0b1001 --> 0b1100
68 68 ror = lambda val, r_bits: \
69 69 ((val & (2**MAX_BITS-1)) >> r_bits%MAX_BITS) | \
70 70 (val << (MAX_BITS-(r_bits%MAX_BITS)) & (2**MAX_BITS-1))
71 71
72 72
73 73 class RCConfiguration(Configuration):
74 74
75 ipp = models.FloatField(verbose_name='IPP [Km]', validators=[MinValueValidator(1), MaxValueValidator(9000)], default=300)
76 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1), MaxValueValidator(400)], default=1)
75 ipp = models.FloatField(verbose_name='IPP [Km]', validators=[MinValueValidator(1)], default=300)
76 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1)], default=1)
77 77 clock_in = models.FloatField(verbose_name='Clock in [MHz]', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
78 78 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
79 79 clock = models.FloatField(verbose_name='Clock Master [MHz]', blank=True, default=1)
80 80 time_before = models.PositiveIntegerField(verbose_name='Time before [&mu;S]', default=12)
81 81 time_after = models.PositiveIntegerField(verbose_name='Time after [&mu;S]', default=1)
82 82 sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
83 83 sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40)
84 84 control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False)
85 85 control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
86 86 total_units = models.PositiveIntegerField(default=0)
87 87 mix = models.BooleanField(default=False)
88 88
89 89 class Meta:
90 90 db_table = 'rc_configurations'
91 91
92 92 def get_absolute_url_plot(self):
93 93 return reverse('url_plot_rc_pulses', args=[str(self.id)])
94 94
95 95 @property
96 96 def ipp_unit(self):
97 97
98 98 return '{} ({})'.format(self.ipp, int(self.ipp*self.km2unit))
99 99
100 100 @property
101 101 def us2unit(self):
102 102
103 103 return self.clock_in/self.clock_divider
104 104
105 105 @property
106 106 def km2unit(self):
107 107
108 108 return 20./3*(self.clock_in/self.clock_divider)
109 109
110 110 def clone(self, **kwargs):
111 111
112 lines = self.get_lines()
113 print 'LINES'
114 print lines
112 lines = self.get_lines()
115 113 self.pk = None
116 114 self.id = None
117 115 for attr, value in kwargs.items():
118 116 setattr(self, attr, value)
119 117 self.save()
120 118
121 119 for line in lines:
122 120 line.clone(rc_configuration=self)
123 121
124 122 new_lines = self.get_lines()
125 123 for line in new_lines:
126 124 line_params = json.loads(line.params)
127 if 'TX_ref' in line_params:
125 if 'TX_ref' in line_params and (line_params['TX_ref'] != '0'):
128 126 ref_line = RCLine.objects.get(pk=line_params['TX_ref'])
129 127 line_params['TX_ref'] = ['{}'.format(l.pk) for l in new_lines if l.get_name()==ref_line.get_name()][0]
130 128 line.params = json.dumps(line_params)
131 129 line.save()
132 130
133 131 return self
134 132
135 133 def get_lines(self, **kwargs):
136 134 '''
137 135 Retrieve configuration lines
138 136 '''
139 137
140 138 return RCLine.objects.filter(rc_configuration=self.pk, **kwargs)
141 139
142 140
143 141 def clean_lines(self):
144 142 '''
145 143 '''
146 144
147 145 empty_line = RCLineType.objects.get(name='none')
148 146
149 147 for line in self.get_lines():
150 148 line.line_type = empty_line
151 149 line.params = '{}'
152 150 line.save()
153 151
154 152 def dict_to_parms(self, params, id=None):
155 153 '''
156 154 '''
157 155
158 156 if id:
159 157 data = Params(params).get_conf(id_conf=id)
160 158 else:
161 159 data = Params(params).get_conf(dtype='rc')
162 160
163 161 self.name = data['name']
164 162 self.ipp = data['ipp']
165 163 self.ntx = data['ntx']
166 164 self.clock_in = data['clock_in']
167 165 self.clock_divider = data['clock_divider']
168 166 self.clock = data['clock']
169 167 self.time_before = data['time_before']
170 168 self.time_after = data['time_after']
171 169 self.sync = data['sync']
172 170 self.sampling_reference = data['sampling_reference']
173 171 self.total_units = self.ipp*self.ntx*self.km2unit
174 172 self.save()
175 173 self.clean_lines()
176 174
177 175 positions = {'tx':0, 'tr':0}
178 176 for i, id in enumerate(data['lines']):
179 177 line_data = params['lines']['byId'][id]
180 178 line_type = RCLineType.objects.get(name=line_data['line_type'])
181 179 if line_type.name == 'codes':
182 180 code = RCLineCode.objects.get(name=line_data['params']['code'])
183 181 line_data['params']['code'] = code.pk
184 182 if line_type.name == 'tx':
185 183 position = positions['tx']
186 184 positions['tx'] += 1
187 185 elif line_type.name == 'tr':
188 186 position = positions['tr']
189 187 positions['tr'] += 1
190 188 else:
191 189 position = 0
192 190 line, dum = RCLine.objects.update_or_create(
193 191 rc_configuration=self,
194 192 channel=i,
195 193 position=position,
196 194 defaults={
197 195 'line_type': line_type,
198 196 'params': json.dumps(line_data['params'])
199 197 }
200 198 )
201 199
202 200 for i, line in enumerate(self.get_lines()):
203 201 line_params = json.loads(line.params)
204 202 if 'TX_ref' in line_params:
205 203 if line_params['TX_ref'] in (0, '0'):
206 204 line_params['TX_ref'] = '0'
207 205 else:
208 206 ref_id = '{}'.format(line_params['TX_ref'])
209 207 ref_line = params['lines']['byId'][ref_id]
210 208 line_params['TX_ref'] = RCLine.objects.get(
211 209 rc_configuration=self,
212 210 params=json.dumps(ref_line['params'])
213 211 ).pk
214 212 line.params = json.dumps(line_params)
215 213 line.save()
216 214
217 215
218 216 def get_delays(self):
219 217
220 218 pulses = [line.pulses_as_points() for line in self.get_lines()]
221 219 points = [tup for tups in pulses for tup in tups]
222 220 points = set([x for tup in points for x in tup])
223 221 points = list(points)
224 222 points.sort()
225 223
226 224 if points[0]!=0:
227 225 points.insert(0, 0)
228 226
229 227 return [points[i+1]-points[i] for i in range(len(points)-1)]
230 228
231 229
232 230 def get_pulses(self, binary=True):
233 231
234 232 pulses = [line.pulses_as_points() for line in self.get_lines()]
235 233 tuples = [tup for tups in pulses for tup in tups]
236 234 points = set([x for tup in tuples for x in tup])
237 235 points = list(points)
238 236 points.sort()
239 237 states = []
240 238 last = [0 for x in pulses]
241 239
242 240 for x in points:
243 241 dum = []
244 242 for i, tups in enumerate(pulses):
245 ups = [tup[0] for tup in tups]
246 dws = [tup[1] for tup in tups]
243 ups = [tup[0] for tup in tups if tup!=(0,0)]
244 dws = [tup[1] for tup in tups if tup!=(0,0)]
247 245 if x in ups:
248 246 dum.append(1)
249 247 elif x in dws:
250 248 dum.append(0)
251 249 else:
252 250 dum.append(last[i])
253 states.append(dum)
251 states.append(dum)
254 252 last = dum
255
253
256 254 if binary:
257 255 ret = []
258 256 for flips in states:
259 257 flips.reverse()
260 258 ret.append(int(''.join([str(x) for x in flips]), 2))
261 259 states = ret
262 260
263 261 return states[:-1]
264 262
265 263 def add_cmd(self, cmd):
266 264
267 265 if cmd in DAT_CMDS:
268 266 return (255, DAT_CMDS[cmd])
269 267
270 268 def add_data(self, value):
271 269
272 270 return (254, value-1)
273 271
274 272 def parms_to_binary(self, dat=True):
275 273 '''
276 274 Create "dat" stream to be send to CR
277 275 '''
278 276
279 277 data = bytearray()
280 278 # create header
281 279 data.extend(self.add_cmd('DISABLE'))
282 280 data.extend(self.add_cmd('CONTINUE'))
283 281 data.extend(self.add_cmd('RESTART'))
284 282
285 283 if self.control_sw:
286 284 data.extend(self.add_cmd('SW_ONE'))
287 285 else:
288 286 data.extend(self.add_cmd('SW_ZERO'))
289 287
290 288 if self.control_tx:
291 289 data.extend(self.add_cmd('TX_ONE'))
292 290 else:
293 291 data.extend(self.add_cmd('TX_ZERO'))
294 292
295 293 # write divider
296 294 data.extend(self.add_cmd('CLOCK_DIVIDER'))
297 295 data.extend(self.add_data(self.clock_divider))
298 296
299 297 # write delays
300 298 data.extend(self.add_cmd('DELAY_START'))
301 299 # first delay is always zero
302 300 data.extend(self.add_data(1))
303 301
304 302 delays = self.get_delays()
305 303
306 304 for delay in delays:
307 305 while delay>252:
308 306 data.extend(self.add_data(253))
309 307 delay -= 253
310 308 data.extend(self.add_data(int(delay)))
311 309
312 310 # write flips
313 311 data.extend(self.add_cmd('FLIP_START'))
314 312
315 313 states = self.get_pulses(binary=True)
316 314
317 315
318 316 last = 0
319 317 for flip, delay in zip(states, delays):
320 318 data.extend(self.add_data((flip^last)+1))
321 319 last = flip
322 320 while delay>252:
323 321 data.extend(self.add_data(1))
324 322 delay -= 253
325 323
326 324 # write sampling period
327 325 data.extend(self.add_cmd('SAMPLING_PERIOD'))
328 326 wins = self.get_lines(line_type__name='windows')
329 327 if wins:
330 328 win_params = json.loads(wins[0].params)['params']
331 329 if win_params:
332 330 dh = int(win_params[0]['resolution']*self.km2unit)
333 331 else:
334 332 dh = 1
335 333 else:
336 334 dh = 1
337 335 data.extend(self.add_data(dh))
338 336
339 337 # write enable
340 338 data.extend(self.add_cmd('ENABLE'))
341 339
342 340 if not dat:
343 341 return data
344 342
345 343 return '\n'.join(['{}'.format(x) for x in data])
346 344
347 345 def update_pulses(self):
348 346
349 347 for line in self.get_lines():
350 348 line.update_pulses()
351 349
352 350 def plot_pulses2(self, km=False):
353 351
352 import matplotlib
353 matplotlib.use('Agg')
354 354 import matplotlib.pyplot as plt
355 355 from bokeh.resources import CDN
356 356 from bokeh.embed import components
357 357 from bokeh.mpl import to_bokeh
358 358 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
359 359
360 360 lines = self.get_lines()
361 361
362 362 N = len(lines)
363 363 npoints = self.total_units/self.km2unit if km else self.total_units
364 364 fig = plt.figure(figsize=(12, 2+N*0.5))
365 365 ax = fig.add_subplot(111)
366 366 labels = ['IPP']
367 367
368 368 for i, line in enumerate(lines):
369 369 labels.append(line.get_name(channel=True))
370 370 l = ax.plot((0, npoints),(N-i-1, N-i-1))
371 371 points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
372 372 ax.broken_barh(points, (N-i-1, 0.5),
373 373 edgecolor=l[0].get_color(), facecolor='none')
374 374
375 375 n = 0
376 376 f = ((self.ntx+50)/100)*5 if ((self.ntx+50)/100)*10>0 else 2
377 377 for x in np.arange(0, npoints, self.ipp if km else self.ipp*self.km2unit):
378 378 if n%f==0:
379 379 ax.text(x, N, '%s' % n, size=10)
380 380 n += 1
381 381
382 382 labels.reverse()
383 383 ax.set_yticks(range(len(labels)))
384 384 ax.set_yticklabels(labels)
385 385 ax.set_xlabel = 'Units'
386 386 plot = to_bokeh(fig, use_pandas=False)
387 387 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), SaveTool()]
388 388 plot.toolbar_location="above"
389 389
390 390 return components(plot, CDN)
391 391
392 392 def plot_pulses(self, km=False):
393 393
394 394 from bokeh.plotting import figure
395 395 from bokeh.resources import CDN
396 396 from bokeh.embed import components
397 397 from bokeh.models import FixedTicker, PrintfTickFormatter
398 398 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
399 399 from bokeh.models.sources import ColumnDataSource
400 400
401 401 lines = self.get_lines().reverse()
402 402
403 403 N = len(lines)
404 404 npoints = self.total_units/self.km2unit if km else self.total_units
405 405 ipp = self.ipp if km else self.ipp*self.km2unit
406 406
407 407 hover = HoverTool(tooltips=[("Line", "@name"),
408 408 ("IPP", "@ipp"),
409 409 ("X", "@left")])
410 410
411 411 tools = [PanTool(dimensions=['width']),
412 412 WheelZoomTool(dimensions=['width']),
413 413 hover, SaveTool()]
414 414
415 415 plot = figure(width=1000,
416 416 height=40+N*50,
417 417 y_range = (0, N),
418 418 tools=tools,
419 419 toolbar_location='above',
420 420 toolbar_sticky=False,)
421 421
422 422 plot.xaxis.axis_label = 'Km' if km else 'Units'
423 423 plot.xaxis[0].formatter = PrintfTickFormatter(format='%d')
424 424 plot.yaxis.axis_label = 'Pulses'
425 425 plot.yaxis[0].ticker=FixedTicker(ticks=list(range(N)))
426 426 plot.yaxis[0].formatter = PrintfTickFormatter(format='Line %d')
427 427
428 428 for i, line in enumerate(lines):
429 429
430 430 points = [tup for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
431 431
432 432 source = ColumnDataSource(data = dict(
433 433 bottom = [i for tup in points],
434 434 top = [i+0.5 for tup in points],
435 435 left = [tup[0] for tup in points],
436 436 right = [tup[1] for tup in points],
437 437 ipp = [int(tup[0]/ipp) for tup in points],
438 438 name = [line.get_name() for tup in points]
439 439 ))
440 440
441 441 plot.quad(
442 442 bottom = 'bottom',
443 443 top = 'top',
444 444 left = 'left',
445 445 right = 'right',
446 446 source = source,
447 447 fill_alpha = 0,
448 448 #line_color = 'blue',
449 449 )
450 450
451 451 plot.line([0, npoints], [i, i])#, color='blue')
452 452
453 453 return components(plot, CDN)
454 454
455 455 def request(self, cmd, method='get', **kwargs):
456 456
457 457 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
458 458 payload = req.json()
459 459
460 460 return payload
461 461
462 462 def status_device(self):
463 463
464 464 try:
465 465 self.device.status = 0
466 466 payload = self.request('status')
467 467 if payload['status']=='enable':
468 468 self.device.status = 3
469 469 elif payload['status']=='disable':
470 470 self.device.status = 2
471 471 else:
472 472 self.device.status = 1
473 473 self.device.save()
474 474 self.message = 'RC status: {}'.format(payload['status'])
475 475 return False
476 476 except Exception as e:
477 477 if 'No route to host' not in str(e):
478 478 self.device.status = 4
479 479 self.device.save()
480 480 self.message = 'RC status: {}'.format(str(e))
481 481 return False
482 482
483 483 self.device.save()
484 484 return True
485 485
486 486 def reset_device(self):
487 487
488 488 try:
489 489 payload = self.request('reset', 'post')
490 490 if payload['reset']=='ok':
491 491 self.message = 'RC restarted OK'
492 492 self.device.status = 2
493 493 self.device.save()
494 494 else:
495 495 self.message = 'RC restart fail'
496 496 self.device.status = 4
497 497 self.device.save()
498 498 except Exception as e:
499 499 self.message = 'RC reset: {}'.format(str(e))
500 500 return False
501 501
502 502 return True
503 503
504 504 def stop_device(self):
505 505
506 506 try:
507 507 payload = self.request('stop', 'post')
508 508 self.message = 'RC stop: {}'.format(payload['stop'])
509 509 if payload['stop']=='ok':
510 510 self.device.status = 2
511 511 self.device.save()
512 512 else:
513 513 self.device.status = 4
514 514 self.device.save()
515 515 return False
516 516 except Exception as e:
517 517 if 'No route to host' not in str(e):
518 518 self.device.status = 4
519 519 else:
520 520 self.device.status = 0
521 521 self.message = 'RC stop: {}'.format(str(e))
522 522 self.device.save()
523 523 return False
524 524
525 525 return True
526 526
527 527 def start_device(self):
528 528
529 529 try:
530 530 payload = self.request('start', 'post')
531 531 self.message = 'RC start: {}'.format(payload['start'])
532 532 if payload['start']=='ok':
533 533 self.device.status = 3
534 534 self.device.save()
535 535 else:
536 536 return False
537 537 except Exception as e:
538 538 if 'No route to host' not in str(e):
539 539 self.device.status = 4
540 540 else:
541 541 self.device.status = 0
542 542 self.message = 'RC start: {}'.format(str(e))
543 543 self.device.save()
544 544 return False
545 545
546 546 return True
547 547
548 def write_device(self):
549
550 values = zip(self.get_pulses(),
551 [x-1 for x in self.get_delays()])
552
548 def write_device(self):
549
550 #values = zip(self.get_pulses(), [x-1 for x in self.get_delays()])
551
552 values = []
553 for pulse, delay in zip(self.get_pulses(), self.get_delays()):
554 while delay>65535:
555 values.append((pulse, 65535))
556 delay -= 65535
557 values.append((pulse, delay-1))
558
553 559 data = bytearray()
554 560 #reset
555 561 data.extend((128, 0))
556 562 #disable
557 563 data.extend((129, 0))
558 564 #divider
559 565 data.extend((131, self.clock_divider-1))
560 566 #enable writing
561 567 data.extend((139, 62))
562 568
563 569 last = 0
564 570 for tup in values:
565 571 vals = pack('<HH', last^tup[0], tup[1])
566 572 last = tup[0]
567 573 data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
568 574
569 575 #enable
570 576 data.extend((129, 1))
571 577
572 578 try:
579 payload = self.request('stop', 'post')
580 payload = self.request('reset', 'post')
581 #payload = self.request('divider', 'post', data={'divider': self.clock_divider-1})
582 #payload = self.request('write', 'post', data=b64encode(bytearray((139, 62))), timeout=20)
583 n = len(data)
584 x = 0
585 #while x < n:
573 586 payload = self.request('write', 'post', data=b64encode(data))
574
587 # x += 1024
588
575 589 if payload['write']=='ok':
576 590 self.device.status = 3
577 591 self.device.save()
578 592 self.message = 'RC configured and started'
579 593 else:
580 594 self.device.status = 1
581 595 self.device.save()
582 596 self.message = 'RC write: {}'.format(payload['write'])
583 597 return False
584 598
599 #payload = self.request('start', 'post')
600
585 601 except Exception as e:
586 602 if 'No route to host' not in str(e):
587 603 self.device.status = 4
588 604 else:
589 605 self.device.status = 0
590 606 self.message = 'RC write: {}'.format(str(e))
591 607 self.device.save()
592 608 return False
593 609
594 610 return True
595 611
596 612
597 613 def get_absolute_url_import(self):
598 614 return reverse('url_import_rc_conf', args=[str(self.id)])
599 615
600 616
601 617 class RCLineCode(models.Model):
602 618
603 619 name = models.CharField(max_length=40)
604 620 bits_per_code = models.PositiveIntegerField(default=0)
605 621 number_of_codes = models.PositiveIntegerField(default=0)
606 622 codes = models.TextField(blank=True, null=True)
607 623
608 624 class Meta:
609 625 db_table = 'rc_line_codes'
610 626 ordering = ('name',)
611 627
612 628 def __str__(self):
613 629 return u'%s' % self.name
614 630
615 631
616 632 class RCLineType(models.Model):
617 633
618 634 name = models.CharField(choices=LINE_TYPES, max_length=40)
619 635 description = models.TextField(blank=True, null=True)
620 636 params = models.TextField(default='[]')
621 637
622 638 class Meta:
623 639 db_table = 'rc_line_types'
624 640
625 641 def __str__(self):
626 642 return u'%s - %s' % (self.name.upper(), self.get_name_display())
627 643
628 644
629 645 class RCLine(models.Model):
630 646
631 647 rc_configuration = models.ForeignKey(RCConfiguration, on_delete=models.CASCADE)
632 648 line_type = models.ForeignKey(RCLineType)
633 649 channel = models.PositiveIntegerField(default=0)
634 650 position = models.PositiveIntegerField(default=0)
635 651 params = models.TextField(default='{}')
636 652 pulses = models.TextField(default='')
637 653
638 654 class Meta:
639 655 db_table = 'rc_lines'
640 656 ordering = ['channel']
641 657
642 658 def __str__(self):
643 659 if self.rc_configuration:
644 return u'%s - %s' % (self.rc_configuration, self.get_name())
660 return u'{}|{} - {}'.format(self.pk, self.get_name(), self.rc_configuration.name)
645 661
646 662 def jsonify(self):
647 663
648 664 data = {}
649 665 data['params'] = json.loads(self.params)
650 666 data['id'] = '{}'.format(self.pk)
651 667 data['line_type'] = self.line_type.name
652 668 data['name'] = self.get_name()
653 669 if data['line_type']=='codes':
654 670 data['params']['code'] = RCLineCode.objects.get(pk=data['params']['code']).name
655 671
656 672 return data
657 673
658 674
659 675 def clone(self, **kwargs):
660 676
661 677 self.pk = None
662 678 self.id = None
663 679
664 680 for attr, value in kwargs.items():
665 681 setattr(self, attr, value)
666 682
667 683 self.save()
668 684
669 685 return self
670 686
671 687 def get_name(self, channel=False):
672 688
673 689 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
674 690 s = ''
675 691
676 692 if self.line_type.name in ('tx',):
677 693 s = chars[self.position]
678 694 elif self.line_type.name in ('codes', 'windows', 'tr'):
679 695 if 'TX_ref' in json.loads(self.params):
680 696 pk = json.loads(self.params)['TX_ref']
681 697 if pk in (0, '0'):
682 698 s = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
683 699 else:
684 700 ref = RCLine.objects.get(pk=pk)
685 701 s = chars[ref.position]
686 702 s = '({})'.format(s)
687 703
688 704 s = '{}{}'.format(self.line_type.name.upper(), s)
689 705
690 706 if channel:
691 707 return '{} {}'.format(s, self.channel)
692 708 else:
693 709 return s
694 710
695 711 def get_lines(self, **kwargs):
696 712
697 713 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
698 714
699 715 def pulses_as_array(self):
700 716
701 717 y = np.zeros(self.rc_configuration.total_units)
702 718
703 719 for tup in ast.literal_eval(self.pulses):
704 720 y[tup[0]:tup[1]] = 1
705 721
706 722 return y.astype(np.int8)
707 723
708 724 def pulses_as_points(self, km=False):
709 725
710 726 if km:
711 727 unit2km = 1/self.rc_configuration.km2unit
712 728 return [(tup[0]*unit2km, tup[1]*unit2km) for tup in ast.literal_eval(self.pulses)]
713 729 else:
714 730 return ast.literal_eval(self.pulses)
715 731
716 732 def get_win_ref(self, params, tx_id, km2unit):
717 733
718 734 ref = self.rc_configuration.sampling_reference
719 735 codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
720 736
721 737 if codes:
722 738 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/len(json.loads(codes[0].params)['codes'][0])
723 739 else:
724 740 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
725 741
726 742 if ref=='first_baud':
727 743 return int(1 + round((tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit))
728 744 elif ref=='sub_baud':
729 745 return np.ceil(1 + params['first_height']*km2unit - params['resolution']*km2unit/2)
730 746 else:
731 747 return 0
732 748
733 749 def update_pulses(self):
734 750 '''
735 751 Update pulses field
736 752 '''
737 753
738 754 km2unit = self.rc_configuration.km2unit
739 755 us2unit = self.rc_configuration.us2unit
740 756 ipp = self.rc_configuration.ipp
741 757 ntx = int(self.rc_configuration.ntx)
742 758 ipp_u = int(ipp*km2unit)
743 759 total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units
744 760 y = []
745 761
746 762 if self.line_type.name=='tr':
747 763 tr_params = json.loads(self.params)
748 764
749 765 if tr_params['TX_ref'] in ('0', 0):
750 766 txs = self.get_lines(line_type__name='tx')
751 767 else:
752 768 txs = RCLine.objects.filter(pk=tr_params['TX_ref'])
753 769
754 770 for tx in txs:
755 771 params = json.loads(tx.params)
756 772
757 773 if float(params['pulse_width'])==0:
758 774 continue
759 775 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
760 776 width = float(params['pulse_width'])*km2unit+int(self.rc_configuration.time_before*us2unit)
761 777 before = 0
762 778 after = int(self.rc_configuration.time_after*us2unit)
763 779
764 780 y_tx = self.points(ntx, ipp_u, width,
765 781 delay=delays,
766 782 before=before,
767 783 after=after,
768 784 sync=self.rc_configuration.sync)
769 785
770 786 ranges = params['range'].split(',')
771 787
772 788 if len(ranges)>0 and ranges[0]!='0':
773 789 y_tx = self.mask_ranges(y_tx, ranges)
774 790
775 791 tr_ranges = tr_params['range'].split(',')
776 792
777 793 if len(tr_ranges)>0 and tr_ranges[0]!='0':
778 794 y_tx = self.mask_ranges(y_tx, tr_ranges)
779 795
780 796 y.extend(y_tx)
781 797
782 798 self.pulses = str(y)
783 799 y = self.array_to_points(self.pulses_as_array())
784 800
785 801 elif self.line_type.name=='tx':
786 802 params = json.loads(self.params)
787 803 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
788 804 width = float(params['pulse_width'])*km2unit
789 805
790 806 if width>0:
791 807 before = int(self.rc_configuration.time_before*us2unit)
792 808 after = 0
793 809
794 810 y = self.points(ntx, ipp_u, width,
795 811 delay=delays,
796 812 before=before,
797 813 after=after,
798 814 sync=self.rc_configuration.sync)
799 815
800 816 ranges = params['range'].split(',')
801 817
802 818 if len(ranges)>0 and ranges[0]!='0':
803 819 y = self.mask_ranges(y, ranges)
804 820
805 821 elif self.line_type.name=='flip':
806 822 n = float(json.loads(self.params)['number_of_flips'])
807 823 width = n*ipp*km2unit
808 824 y = self.points(int((ntx+1)/(2*n)), ipp_u*n*2, width)
809 825
810 826 elif self.line_type.name=='codes':
811 827 params = json.loads(self.params)
812 828 tx = RCLine.objects.get(pk=params['TX_ref'])
813 829 tx_params = json.loads(tx.params)
814 830 delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
815 831 f = int(float(tx_params['pulse_width'])*km2unit/len(params['codes'][0]))
816 832 codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in params['codes']]
817 833 codes = [self.array_to_points(code) for code in codes]
818 834 n = len(codes)
819 835
820 836 ranges = tx_params['range'].split(',')
821 837 if len(ranges)>0 and ranges[0]!='0':
822 838 dum = self.mask_ranges(tx.pulses_as_points(), ranges)
823 839 else:
824 840 dum = tx.pulses_as_points()
825 841
826 842 for i, tup in enumerate(dum):
827 843 if tup==(0,0): continue
828 844 code = codes[i%n]
829 845 y.extend([(c[0]+tup[0], c[1]+tup[0]) for c in code])
830 846
831 847 elif self.line_type.name=='sync':
832 848 params = json.loads(self.params)
833 849 n = ipp_u*ntx
834 850 if params['invert'] in ('1', 1):
835 851 y = [(n-1, n)]
836 852 else:
837 853 y = [(0, 1)]
838 854
839 855 elif self.line_type.name=='prog_pulses':
840 856 params = json.loads(self.params)
841 857 if int(params['periodic'])==0:
842 858 nntx = 1
843 859 nipp = ipp_u*ntx
844 860 else:
845 861 nntx = ntx
846 862 nipp = ipp_u
847 863
848 864 if 'params' in params and len(params['params'])>0:
849 865 for p in params['params']:
850 866 y_pp = self.points(nntx, nipp,
851 867 p['end']-p['begin'],
852 868 before=p['begin'])
853 869
854 870 y.extend(y_pp)
855 871
856 872 elif self.line_type.name=='windows':
857 873 params = json.loads(self.params)
858 874 if 'params' in params and len(params['params'])>0:
859 tr_params = json.loads(self.get_lines(line_type__name='tr')[0].params)
860 tr_ranges = tr_params['range'].split(',')
875 tr_lines = self.get_lines(line_type__name='tr')
876 if tr_lines:
877 tr_params = json.loads(self.get_lines(line_type__name='tr')[0].params)
878 tr_ranges = tr_params['range'].split(',')
879 else:
880 tr_ranges = []
861 881 for p in params['params']:
862 882 y_win = self.points(ntx, ipp_u,
863 883 p['resolution']*p['number_of_samples']*km2unit,
864 before=int(self.rc_configuration.time_before*us2unit),
884 before=int(self.rc_configuration.time_before*us2unit)+p['first_height']*km2unit,
865 885 sync=self.rc_configuration.sync+self.get_win_ref(p, params['TX_ref'], km2unit))
866 886
867 887
868 888 if len(tr_ranges)>0 and tr_ranges[0]!='0':
869 889 y_win = self.mask_ranges(y_win, tr_ranges)
870 890
871 891 y.extend(y_win)
872 892
873 893 elif self.line_type.name=='mix':
874 894 values = self.rc_configuration.parameters.split('-')
875 895 confs = [RCConfiguration.objects.get(pk=value.split('|')[0]) for value in values]
876 896 modes = [value.split('|')[1] for value in values]
877 897 ops = [value.split('|')[2] for value in values]
878 898 delays = [value.split('|')[3] for value in values]
879 899 masks = [value.split('|')[4] for value in values]
880 900 mask = list('{:8b}'.format(int(masks[0])))
881 901 mask.reverse()
882 902 if mask[self.channel] in ('0', '', ' '):
883 903 y = np.zeros(confs[0].total_units, dtype=np.int8)
884 904 else:
885 905 y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
886 906
887 907 for i in range(1, len(values)):
888 908 mask = list('{:8b}'.format(int(masks[i])))
889 909 mask.reverse()
890 910
891 911 if mask[self.channel] in ('0', '', ' '):
892 912 continue
893 913 Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
894 914 delay = float(delays[i])*km2unit
895 915
896 916 if modes[i]=='P':
897 917 if delay>0:
898 918 if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y):
899 919 y_temp = np.empty_like(Y)
900 920 y_temp[:delay] = 0
901 921 y_temp[delay:] = Y[:-delay]
902 922 elif delay+len(Y)>len(y):
903 923 y_new = np.zeros(delay+len(Y), dtype=np.int8)
904 924 y_new[:len(y)] = y
905 925 y = y_new
906 926 y_temp = np.zeros(delay+len(Y), dtype=np.int8)
907 927 y_temp[-len(Y):] = Y
908 928 elif delay+len(Y)==len(y):
909 929 y_temp = np.zeros(delay+len(Y))
910 930 y_temp[-len(Y):] = Y
911 931 elif delay+len(Y)<len(y):
912 932 y_temp = np.zeros(len(y), dtype=np.int8)
913 933 y_temp[delay:delay+len(Y)] = Y
914 934 else:
915 935 y_temp = Y.copy()
916 936
917 937 if ops[i]=='OR':
918 938 y = y | y_temp
919 939 elif ops[i]=='XOR':
920 940 y = y ^ y_temp
921 941 elif ops[i]=='AND':
922 942 y = y & y_temp
923 943 elif ops[i]=='NAND':
924 944 y = y & ~y_temp
925 945 else:
926 946 y = np.concatenate([y, Y])
927 947
928 948 total = len(y)
929 949 y = self.array_to_points(y)
930 950
931 951 else:
932 952 y = []
933 953
934 954 if self.rc_configuration.total_units != total:
935 955 self.rc_configuration.total_units = total
936 956 self.rc_configuration.save()
937 957
938 958 self.pulses = str(y)
939 959 self.save()
940 960
941 961 @staticmethod
942 962 def array_to_points(X):
943 963
944 964 if X.size==0:
945 965 return []
946 966
947 967 d = X[1:]-X[:-1]
948 968
949 969 up = np.where(d==1)[0]
950 970 if X[0]==1:
951 971 up = np.concatenate((np.array([-1]), up))
952 972 up += 1
953 973
954 974 dw = np.where(d==-1)[0]
955 975 if X[-1]==1:
956 976 dw = np.concatenate((dw, np.array([len(X)-1])))
957 977 dw += 1
958 978
959 979 return [(tup[0], tup[1]) for tup in zip(up, dw)]
960 980
961 981 @staticmethod
962 982 def mask_ranges(Y, ranges):
963 983
964 984 y = [(0, 0) for __ in Y]
965 985
966 986 for index in ranges:
967 987 if '-' in index:
968 988 args = [int(a) for a in index.split('-')]
969 989 y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
970 990 else:
971 991 y[int(index)-1] = Y[int(index)-1]
972 992
973 993 return y
974 994
975 995 @staticmethod
976 996 def points(ntx, ipp, width, delay=[0], before=0, after=0, sync=0):
977 997
978 998 delays = len(delay)
979 999
980 1000 Y = [(int(ipp*x+before+delay[x%delays]+sync), int(ipp*x+width+before+delay[x%delays]+after+sync)) for x in range(ntx)]
981 1001
982 1002 return Y
@@ -1,98 +1,104
1 1 '''
2 2 API to configure new Radar controller
3 3
4 4
5 5 @author: Juan C. Espinoza
6 6 '''
7 7
8 8 import os
9 9 import json
10 10 import requests
11 11 from struct import pack
12 12 from base64 import b64encode
13 13
14 14 class RCApi(object):
15 15
16 16 def __init__(self, ip, port=80):
17 17
18 18 self.url = 'http://{}:{}/'.format(ip, port)
19 19 self.params = None
20 20
21 21 def load(self, filename):
22 22
23 23 self.params = json.load(open(filename))
24 print 'RC Configuration: {}'.format(self.params['name'])
24 self.pk = self.params['configurations']['allIds'][0]
25 print 'RC Configuration: {}'.format(self.params['configurations']['byId'][self.pk]['name'])
25 26
26 27 def status(self):
27 28
28 29 url = os.path.join(self.url, 'status')
29 30 req = requests.get(url)
30 31 return req.json()
31 32
32 33 def read(self):
33 34
34 35 url = os.path.join(self.url, 'read')
35 36 req = requests.get(url)
36 37 return req.json()
37 38
38 39 def stop(self):
39 40
40 41 url = os.path.join(self.url, 'stop')
41 42 req = requests.post(url)
42 43 return req.json()
43 44
44 45 def reset(self):
45 46
46 47 url = os.path.join(self.url, 'reset')
47 48 req = requests.post(url)
48 49 return req.json()
49 50
50 51 def start(self):
51 52
52 53 url = os.path.join(self.url, 'start')
53 54 req = requests.post(url)
54 55 return req.json()
55 56
56 57 def write(self):
57 58
58 59 url_write = os.path.join(self.url, 'write')
59 url_divider = os.path.join(self.url, 'divisor')
60
61 values = zip(self.params['pulses'],
62 [x-1 for x in self.params['delays']])
60 url_divider = os.path.join(self.url, 'divider')
61
62 values = zip(self.params['configurations']['byId'][self.pk]['pulses'],
63 [x-1 for x in self.params['configurations']['byId'][self.pk]['delays']])
63 64 payload = ''
64 65
65 66 for tup in values:
66 67 vals = pack('<HH', *tup)
67 payload += '\x05'+vals[0]+'\x04'+vals[1]+'\x05'+vals[2]+'\x04'+vals[3]
68 payload += '\x85'+vals[0]+'\x84'+vals[1]+'\x85'+vals[2]+'\x84'+vals[3]
68 69
69 70 req = requests.post(url_divider,
70 data={'divisor':int(self.params['clock_divider'])-1})
71
71 data={'divider':int(self.params['configurations']['byId'][self.pk]['clock_divider'])-1})
72
72 73 if 'ok' not in req.text:
73 74 print 'Error sending divider'
74 75 return False
75
76
76 77 req = requests.post(url_write,
77 78 data=b64encode(payload))
78 79 return req.json()
79 80
80 81 if __name__ == '__main__':
81
82 import time
82 83 ip = '10.10.10.100'
83 filename = '/home/jespinoza/Downloads/rc_150EEJ.json'
84
84
85 filename = './dia.json'
86
85 87 rc = RCApi(ip)
86 88 rc.load(filename)
87 89
88 print rc.status()
89 print rc.reset()
90 print rc.stop()
90 # print rc.status()
91 # time.sleep(1)
92 # print rc.reset()
93 # time.sleep(1)
94 # print rc.stop()
95 # time.sleep(1)
91 96 print rc.write()
92 print rc.start()
97 # time.sleep(1)
98 # print rc.start()
93 99
94 100
95 101
96 102
97 103
98 104
@@ -1,60 +1,67
1 1 version: '2'
2 2 services:
3 # Django app
3 4 web:
4 container_name: 'radarsys_web'
5 container_name: 'radarsys'
5 6 build: .
6 7 restart: always
7 8 image: radarsys
8 command: gunicorn radarsys.wsgi:application -w 2 -b :8080
9 command: gunicorn radarsys.wsgi:application -w 2 -b :8000
9 10 env_file: .env
10 ports:
11 - "8080:8080"
11
12 12 links:
13 13 - redis
14 - mysql
14 - postgres
15 15 volumes:
16 - './:/data'
16 - './:/radarsys'
17 - '/data/dockers/radarsys/static:/radarsys/static'
17 18 depends_on:
18 19 - redis
19 - mysql
20 - postgres
20 21
21 22 redis:
22 container_name: 'redis'
23 container_name: 'radarsys-redis'
23 24 image: 'redis:3.2-alpine'
24 25 ports:
25 26 - '127.0.0.1:6300:6379'
26 27 volumes:
27 28 - '/data/dockers/radarsys/redis:/data'
28 29
29 30 celery_worker:
31 container_name: 'radarsys-celery'
30 32 image: radarsys
31 33 env_file: .env
32 34 command: celery -A radarsys worker -l info
33 35 volumes_from:
34 36 - web
35 37 depends_on:
36 38 - web
37 39
38 mysql:
39 container_name: 'mysql'
40 image: 'mysql:5.6'
41 env_file: .env
40 # PostgreSQL
41 postgres:
42 container_name: 'radarsys-postgres'
43 build: ./postgres/
42 44 ports:
43 - '127.0.0.1:6301:3306'
45 - 5432:5432
44 46 volumes:
45 - '/data/dockers/radarsys/mysql:/var/lib/mysql'
47 - ./postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
48 - pgdata:/var/lib/postgresql/data
49 env_file: .env
46 50
51 # Web Server
47 52 nginx:
48 container_name: 'radarsys_nginx'
53 container_name: 'radarsys-nginx'
49 54 restart: always
50 55 build: ./nginx/
51 56 ports:
52 - "3000:80"
53 volumes:
54 - '/data/dockers/radarsys/nginx:/data/nginx'
57 - '8030:8030'
55 58 volumes_from:
56 59 - web
57 60 links:
58 61 - web:web
59 62 depends_on:
60 63 - web
64
65 volumes:
66 pgdata:
67 driver: local No newline at end of file
@@ -1,5 +1,3
1 FROM tutum/nginx
2
3 RUN rm /etc/nginx/sites-enabled/default
4 ADD sites-enabled/ /etc/nginx/sites-enabled
5 ADD sites-enabled/radarsys /etc/nginx/conf.d/
1 FROM nginx:1.13.8-alpine
2 RUN rm /etc/nginx/conf.d/default.conf
3 ADD sites-enabled/radarsys.conf /etc/nginx/conf.d/
@@ -1,17 +1,17
1 1 server {
2 2
3 listen 80;
4 server_name sir.com;
3 listen 8030;
4 server_name localhost;
5 5
6 6 access_log /dev/stdout;
7 7 error_log /dev/stdout info;
8 8
9 9 location /static {
10 alias /data/media/static;
10 alias /radarsys/static;
11 11 }
12 12
13 13 location / {
14 proxy_pass http://web:8080;
14 proxy_pass http://web:8000;
15 15 }
16 16
17 17 }
@@ -1,156 +1,135
1 1 """
2 2 Django settings for radarsys project.
3 3
4 4 Generated by 'django-admin startproject' using Django 1.8.6.
5 5
6 6 For more information on this file, see
7 7 https://docs.djangoproject.com/en/1.8/topics/settings/
8 8
9 9 For the full list of settings and their values, see
10 10 https://docs.djangoproject.com/en/1.8/ref/settings/
11 11 """
12 12
13 13 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
14 14 import os
15 15
16 BASE_DIR = os.path.dirname(os.path.abspath(__file__))
16 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
17 17
18 18 # Quick-start development settings - unsuitable for production
19 19 # See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
20 20
21 21 # SECURITY WARNING: keep the secret key used in production secret!
22 22 SECRET_KEY = 'xshb$k5fc-+j16)cvyffj&9u__0q3$l!hieh#+tbzqg)*f^km0'
23 23
24 24 # SECURITY WARNING: don't run with debug turned on in production!
25 25 DEBUG = True
26 26
27 27 ALLOWED_HOSTS = ['*']
28 28
29 29 # Application definition
30 30
31 31 INSTALLED_APPS = (
32 32 'django.contrib.admin',
33 33 'django.contrib.auth',
34 34 'django.contrib.contenttypes',
35 35 'django.contrib.sessions',
36 36 'django.contrib.messages',
37 37 'django.contrib.staticfiles',
38 38 'bootstrap3',
39 39 'polymorphic',
40 40 'apps.accounts',
41 41 'apps.main',
42 42 'apps.misc',
43 43 'apps.rc',
44 44 'apps.dds',
45 45 'apps.jars',
46 46 'apps.usrp',
47 47 'apps.abs',
48 48 'apps.cgs',
49 49 )
50 50
51 51 MIDDLEWARE_CLASSES = (
52 52 'django.contrib.sessions.middleware.SessionMiddleware',
53 53 'django.middleware.common.CommonMiddleware',
54 54 'django.middleware.csrf.CsrfViewMiddleware',
55 55 'django.contrib.auth.middleware.AuthenticationMiddleware',
56 56 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
57 57 'django.contrib.messages.middleware.MessageMiddleware',
58 58 'django.middleware.clickjacking.XFrameOptionsMiddleware',
59 59 'django.middleware.security.SecurityMiddleware',
60 60 )
61 61
62 62 ROOT_URLCONF = 'radarsys.urls'
63 63
64 64 TEMPLATES = [
65 65 {
66 66 'BACKEND': 'django.template.backends.django.DjangoTemplates',
67 67 'DIRS': [os.path.join(BASE_DIR, "templates").replace('\\', '/'),],
68 68 'APP_DIRS': True,
69 69 'OPTIONS': {
70 70 'context_processors': [
71 71 'django.template.context_processors.debug',
72 72 'django.template.context_processors.request',
73 73 'django.contrib.auth.context_processors.auth',
74 74 'django.contrib.messages.context_processors.messages',
75 75 ],
76 76 },
77 77 },
78 78 ]
79 79
80 80 WSGI_APPLICATION = 'radarsys.wsgi.application'
81 81
82 82
83 83 # Database
84 84 # https://docs.djangoproject.com/en/1.8/ref/settings/#databases
85 85
86 86 DATABASES = {
87 87 'default': {
88 #'ENGINE': 'django.db.backends.sqlite3',
89 #'NAME': os.path.join(BASE_DIR, 'radarsys.sqlite'),
90 'ENGINE': 'django.db.backends.mysql',
91 'NAME': 'radarsys',
92 'USER': 'developer',
93 #'HOST': 'mysql',
94 'PASSWORD': 'idi2015',
95 'OPTIONS': {
96 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
97 }
88 'ENGINE': 'django.db.backends.postgresql_psycopg2',
89 'NAME': os.environ.get('POSTGRES_DB_NAME', 'radarsys'),
90 'USER': os.environ.get('POSTGRES_USER', 'docker'),
91 'PASSWORD': os.environ.get('POSTGRES_PASSWORD', 'docker'),
92 'HOST': os.environ.get('POSTGRES_PORT_5432_TCP_ADDR', 'postgres'),
93 'PORT': os.environ.get('POSTGRES_PORT_5432_TCP_PORT', ''),
98 94 }
99 95 }
100 96
101
102 97 # Internationalization
103 98 # https://docs.djangoproject.com/en/1.8/topics/i18n/
104 99
105 100 LANGUAGE_CODE = 'en-us'
106 101
107 102 TIME_ZONE = None
108 103
109 104 USE_I18N = True
110 105
111 106 USE_L10N = True
112 107
113 108 USE_TZ = False
114 109
115 110 # Static files (CSS, JavaScript, Images)
116 111 # https://docs.djangoproject.com/en/1.8/howto/static-files/
117 112
118 MEDIA_ROOT = 'media'#os.path.join(BASE_DIR, 'media')
119 MEDIA_URL = '/site_media/'
113 MEDIA_URL = '/media/'
114 MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
120 115
121 116 STATIC_URL = '/static/'
122 #STATIC_ROOT = '/var/www/html/static/'
123 STATIC_ROOT = os.path.join(MEDIA_ROOT, 'static')
124
125 #STATICFILES_DIRS = (
126 # os.path.join(BASE_DIR, 'apps', 'main', 'static'),
127 #
128 #)
129
117 STATIC_ROOT = os.path.join(BASE_DIR, 'static')
130 118
131 119 STATICFILES_FINDERS = (
132 120 'django.contrib.staticfiles.finders.FileSystemFinder',
133 121 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
134 122 )
135 123
136 FIXTURE_DIRS = (
137 os.path.join(BASE_DIR, 'apps', 'rc', 'fixtures'),
138 os.path.join(BASE_DIR, 'apps', 'main', 'fixtures'),
139 os.path.join(BASE_DIR, 'apps', 'jars', 'fixtures'),
140 )
141
142 124 # Celery stuff
143 REDIS_HOST = 'redis'
125 REDIS_HOST = os.environ.get('HOST_REDIS', '127.0.0.1')
126
144 127 BROKER_TRANSPORT = 'redis'
145 #--Development--# (Para Pruebas Locales)
146 BROKER_URL = 'redis://127.0.0.1:6300'
147 CELERY_RESULT_BACKEND = 'redis://localhost:6300'
148 #---------------#
149 #--Production---# (Para Docker)
150 #CELERY_BROKER_TRANSPORT = BROKER_URL = 'redis://%s:6379/0' % REDIS_HOST
151 #CELERY_RESULT_BACKEND = 'redis://%s:6379/0' % REDIS_HOST
152 #---------------#
128 BROKER_URL = 'redis://%s:6379/0' % REDIS_HOST
129
130 CELERY_RESULT_BACKEND = 'redis://%s:6379/0' % REDIS_HOST
131 CELERY_BROKER_TRANSPORT = BROKER_URL
153 132 CELERY_ACCEPT_CONTENT = ['application/json']
154 133 CELERY_TASK_SERIALIZER = 'json'
155 134 CELERY_RESULT_SERIALIZER = 'json'
156 135 CELERY_TIMEZONE = 'America/Lima'
@@ -1,53 +1,8
1 ### Docker de la base de datos ###
2 # 'NAME': 'radarsys',
3 # 'USER': 'developer',
4 # 'PASSWORD': 'idi2015',
5
6 #Preparar Base de Datos para la aplicacion:
7 ## Crear imagen "mysql:5.6"
8 docker create -v /var/lib/mysql --name mysql-radarsys-data mysql:5.6 /bin/true
9 ## Ejecutar Container "mysql-radarsys-server"
10 docker run --name mysql-radarsys-server -d -e MYSQL_ROOT_PASSWORD=r00tJRO -e MYSQL_DATABASE=radarsys \
11 -e MYSQL_USER=developer -e MYSQL_PASSWORD=idi2015 --volumes-from mysql-radarsys-data mysql:5.6
12
13 #Aplicacion Sistema Integrado de Radar
14 ## Debe crearse *Dockerfile*
15 ## Crear la imagen
16 docker build -t radarsys:v01 .
17 # Ejecutar Container
18 docker run -d --name radarsys01 --link mysql-radarsys-server -p 3000:3000 \
19 -v /home/ubuntu/docker_shared/radarsys/media:/radarsys/media \
20 --add-host smtp_server:172.17.0.1 radarsys:v01
21
22 ## Dentro del Container: se debe realizar las siguiente modificaciones
23 ### Para ingresar al container:
24 docker exec -i -t radarsys01 /bin/bash
25 ### Es necesario ejecutar:
26 apt-get update
27 apt-get install nano
28 ### Modificar radarsys.setting.py, HOST debe estar habilitado
29 'HOST': 'mysql-sysinv-server',
30 ### Asegurarse que:
31 MEDIA_ROOT: 'media'
32 ### En el script abs/utils/Graphics_OverJro.py, matplotlib Agg debe estar habilitado
33 matplotlib.use("Agg")
34 ### En el script radarsys/urls.py comentar para que nginx sirva "static":
35 #from django.contrib.staticfiles.urls import staticfiles_urlpatterns
36 #urlpatterns += staticfiles_urlpatterns()
37
38 ### Ejecutar los siguientes comandos (solo si ya se creo mysql-radarsys-server):
39 python manage.py makemigrations \
40 && python manage.py migrate \
41 && python manage.py loaddata apps/main/fixtures/main_initial_data.json \
42 && python manage.py loaddata apps/rc/fixtures/rc_initial_data.json \
43 && python manage.py loaddata apps/jars/fixtures/initial_filters_data.json \
44 && python manage.py collectstatic
45
46 ### Por ultimo reiniciar el docker
47 docker stop radarsys01
48 docker start radarsys01
49
50
51 #### Archivos Compartidos:
52 # /home/ubuntu/docker_shared/radarsys/media
53 # (debe coincidir con la carpeta que se ingresar en "docker run")
1 # Commands after dockers creations
2
3 docker-compose run web python manage.py makemigrations
4 docker-compose run web python manage.py migrate
5 docker-compose run web python manage.py loaddata apps/main/fixtures/main_initial_data.json \
6 docker-compose run web python manage.py loaddata apps/rc/fixtures/rc_initial_data.json \
7 docker-compose run web python manage.py loaddata apps/jars/fixtures/initial_filters_data.json \
8 docker-compose run web python manage.py collectstatic
@@ -1,12 +1,12
1 1 Django==1.10.1
2 2 django-bootstrap3
3 mysqlclient
3 psycopg2
4 4 django-polymorphic
5 bokeh
6 numpy
5 bokeh==0.12.1
6 numpy==1.13.3
7 7 matplotlib
8 8 scipy
9 9 celery
10 10 gunicorn
11 requests==2.11.1
12 redis
11 requests
12 redis No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now