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