source: trunk/python/asapgrid.py@ 2396

Last change on this file since 2396 was 2396, checked in by Takeshi Nakazato, 13 years ago

New Development: No

JIRA Issue: Yes CAS-2816

Ready for Test: Yes

Interface Changes: No

What Interface Changed: Please list interface changes

Test Programs: List test programs

Put in Release Notes: Yes/No

Module(s): Module Names change impacts.

Description: Describe your changes here...

Added min/max clipping functionality.
Introduced control parameter and methods for clipping.

File size: 13.5 KB
Line 
1import numpy
2from asap import rcParams
3from asap.scantable import scantable
4from asap.selector import selector
5from asap._asap import stgrid
6import pylab as pl
7from logging import asaplog
8
9class asapgrid:
10 """
11 The asapgrid class is defined to convolve data onto regular
12 spatial grid. Typical usage is as follows:
13
14 # create asapgrid instance with two input data
15 g = asapgrid( ['testimage1.asap','testimage2.asap'] )
16 # set IFNO if necessary
17 g.setIF( 0 )
18 # set POLNOs if necessary
19 g.setPolList( [0,1] )
20 # set SCANNOs if necessary
21 g.setScanList( [22,23,24] )
22 # define image with full specification
23 # you can skip some parameters (see help for defineImage)
24 g.defineImage( nx=12, ny=12, cellx='10arcsec', celly='10arcsec',
25 center='J2000 10h10m10s -5d05m05s' )
26 # set convolution function
27 g.setFunc( func='sf', width=3 )
28 # actual gridding
29 g.grid()
30 # save result
31 g.save( outfile='grid.asap' )
32 # plot result
33 g.plot( plotchan=1246, plotpol=-1, plotgrid=True, plotobs=True )
34 """
35 def __init__( self, infile ):
36 """
37 Create asapgrid instance.
38
39 infile -- input data as a string or string list if you want
40 to grid more than one data at once.
41 """
42 self.outfile = None
43 self.ifno = None
44 self.gridder = stgrid()
45 self.setData( infile )
46
47 def setData( self, infile ):
48 """
49 Set data to be processed.
50
51 infile -- input data as a string or string list if you want
52 to grid more than one data at once.
53 """
54 if isinstance( infile, str ):
55 self.gridder._setin( infile )
56 else:
57 self.gridder._setfiles( infile )
58 self.infile = infile
59
60 def setIF( self, ifno ):
61 """
62 Set IFNO to be processed. Currently, asapgrid allows to process
63 only one IFNO for one gridding run even if the data contains
64 multiple IFs. If you didn't specify IFNO, default value, which
65 is IFNO in the first spectrum, will be processed.
66
67 ifno -- IFNO to be processed.
68 """
69 self.ifno = ifno
70 self.gridder._setif( self.ifno )
71
72 def setPolList( self, pollist ):
73 """
74 Set list of polarization components you want to process.
75 If not specified, all POLNOs will be processed.
76
77 pollist -- list of POLNOs.
78 """
79 self.gridder._setpollist( pollist )
80
81 def setScanList( self, scanlist ):
82 """
83 Set list of scans you want to process. If not specified, all
84 scans will be processed.
85
86 scanlist -- list of SCANNOs.
87 """
88 self.gridder._setscanlist( scanlist )
89
90 def defineImage( self, nx=-1, ny=-1, cellx='', celly='', center='' ):
91 """
92 Define spatial grid.
93
94 First two parameters, nx and ny, define number of pixels of
95 the grid. If which of those is not specified, it will be set
96 to the same value as the other. If none of them are specified,
97 it will be determined from map extent and cell size.
98
99 Next two parameters, cellx and celly, define size of pixel.
100 You should set those parameters as string, which is constructed
101 numerical value and unit, e.g. '0.5arcmin', or numerical value.
102 If those values are specified as numerical value, their units
103 will be assumed to 'arcmin'. If which of those is not specified,
104 it will be set to the same value as the other. If none of them
105 are specified, it will be determined from map extent and number
106 of pixels, or set to '1arcmin' if neither nx nor ny is set.
107
108 The last parameter, center, define the central coordinate of
109 the grid. You should specify its value as a string, like,
110
111 'J2000 05h08m50s -16d23m30s'
112
113 or
114
115 'J2000 05:08:50 -16.23.30'
116
117 You can omit equinox when you specify center coordinate. In that
118 case, J2000 is assumed. If center is not specified, it will be
119 determined from the observed positions of input data.
120
121 nx -- number of pixels along x (R.A.) direction.
122 ny -- number of pixels along y (Dec.) direction.
123 cellx -- size of pixel in x (R.A.) direction.
124 celly -- size of pixel in y (Dec.) direction.
125 center -- central position of the grid.
126 """
127 if not isinstance( cellx, str ):
128 cellx = '%sarcmin'%(cellx)
129 if not isinstance( celly, str ):
130 celly = '%sarcmin'%(celly)
131 self.gridder._defineimage( nx, ny, cellx, celly, center )
132
133 def setFunc( self, func='box', width=-1 ):
134 """
135 Set convolution function. Possible options are 'box' (Box-car,
136 default), 'sf' (prolate spheroidal), and 'gauss' (Gaussian).
137 Width of convolution function can be set using width parameter.
138 By default (-1), width is automatically set depending on each
139 convolution function. Default values for width are:
140
141 'box': 1 pixel
142 'sf': 3 pixels
143 'gauss': 3 pixels (width is used as HWHM)
144
145 func -- Function type ('box', 'sf', 'gauss').
146 width -- Width of convolution function. Default (-1) is to
147 choose pre-defined value for each convolution function.
148 """
149 self.gridder._setfunc( func, width )
150
151 def setWeight( self, weightType='uniform' ):
152 """
153 Set weight type. Possible options are 'uniform' (default),
154 'tint' (weight by integration time), 'tsys' (weight by
155 Tsys: 1/Tsys**2), and 'tintsys' (weight by integration time
156 as well as Tsys: tint/Tsys**2).
157
158 weightType -- weight type ('uniform', 'tint', 'tsys', 'tintsys')
159 """
160 self.gridder._setweight( weightType )
161
162 def enableClip( self ):
163 """
164 Enable min/max clipping.
165
166 By default, min/max clipping is disabled so that you should
167 call this method before actual gridding if you want to do
168 clipping.
169 """
170 self.gridder._enableclip()
171
172 def disableClip( self ):
173 """
174 Disable min/max clipping.
175 """
176 self.gridder._disableclip()
177
178 def grid( self ):
179 """
180 Actual gridding which will be done based on several user inputs.
181 """
182 self.gridder._grid()
183
184 def save( self, outfile='' ):
185 """
186 Save result. By default, output data name will be constructed
187 from first element of input data name list (e.g. 'input.asap.grid').
188
189 outfile -- output data name.
190 """
191 self.outfile = self.gridder._save( outfile )
192
193 def plot( self, plotchan=-1, plotpol=-1, plotobs=False, plotgrid=False ):
194 """
195 Plot gridded data.
196
197 plotchan -- Which channel you want to plot. Default (-1) is
198 to average all the channels.
199 plotpol -- Which polarization component you want to plot.
200 Default (-1) is to average all the polarization
201 components.
202 plotobs -- Also plot observed position if True. Default
203 is False. Setting True for large amount of spectra
204 might be time consuming.
205 plotgrid -- Also plot grid center if True. Default is False.
206 Setting True for large number of grids might be
207 time consuming.
208 """
209 import time
210 t0=time.time()
211 # to load scantable on disk
212 storg = rcParams['scantable.storage']
213 rcParams['scantable.storage'] = 'disk'
214 plotter = _SDGridPlotter( self.infile, self.outfile, self.ifno )
215 plotter.plot( chan=plotchan, pol=plotpol, plotobs=plotobs, plotgrid=plotgrid )
216 # back to original setup
217 rcParams['scantable.storage'] = storg
218 t1=time.time()
219 asaplog.push('plot: elapsed time %s sec'%(t1-t0))
220 asaplog.post('DEBUG','asapgrid.plot')
221
222class _SDGridPlotter:
223 def __init__( self, infile, outfile=None, ifno=-1 ):
224 if isinstance( infile, str ):
225 self.infile = [infile]
226 else:
227 self.infile = infile
228 self.outfile = outfile
229 if self.outfile is None:
230 self.outfile = self.infile[0].rstrip('/')+'.grid'
231 self.nx = -1
232 self.ny = -1
233 self.nchan = 0
234 self.npol = 0
235 self.pollist = []
236 self.cellx = 0.0
237 self.celly = 0.0
238 self.center = [0.0,0.0]
239 self.nonzero = [[0.0],[0.0]]
240 self.ifno = ifno
241 self.tablein = None
242 self.nrow = 0
243 self.blc = None
244 self.trc = None
245 self.get()
246
247 def get( self ):
248 s = scantable( self.outfile, average=False )
249 self.nchan = len(s._getspectrum(0))
250 nrow = s.nrow()
251 pols = numpy.ones( nrow, dtype=int )
252 for i in xrange(nrow):
253 pols[i] = s.getpol(i)
254 self.pollist, indices = numpy.unique( pols, return_inverse=True )
255 self.npol = len(self.pollist)
256 self.pollist = self.pollist[indices[:self.npol]]
257 #print 'pollist=',self.pollist
258 #print 'npol=',self.npol
259 #print 'nrow=',nrow
260
261 idx = 0
262 d0 = s.get_direction( 0 ).split()[-1]
263 while ( s.get_direction(self.npol*idx).split()[-1] == d0 ):
264 idx += 1
265
266 self.nx = idx
267 self.ny = nrow / (self.npol * idx )
268 #print 'nx,ny=',self.nx,self.ny
269
270 self.blc = s.get_directionval( 0 )
271 self.trc = s.get_directionval( nrow-self.npol )
272 #print self.blc
273 #print self.trc
274 incrx = s.get_directionval( self.npol )
275 incry = s.get_directionval( self.nx*self.npol )
276 self.cellx = abs( self.blc[0] - incrx[0] )
277 self.celly = abs( self.blc[1] - incry[1] )
278 #print 'cellx,celly=',self.cellx,self.celly
279
280 def plot( self, chan=-1, pol=-1, plotobs=False, plotgrid=False ):
281 if pol < 0:
282 opt = 'averaged over pol'
283 else:
284 opt = 'pol %s'%(pol)
285 if chan < 0:
286 opt += ', averaged over channel'
287 else:
288 opt += ', channel %s'%(chan)
289 data = self.getData( chan, pol )
290 title = 'Gridded Image (%s)'%(opt)
291 pl.figure(10)
292 pl.clf()
293 # plot grid position
294 if plotgrid:
295 x = numpy.arange(self.blc[0],self.trc[0]+0.5*self.cellx,self.cellx,dtype=float)
296 #print 'len(x)=',len(x)
297 #print 'x=',x
298 ybase = numpy.ones(self.nx,dtype=float)*self.blc[1]
299 #print 'len(ybase)=',len(ybase)
300 incr = self.celly
301 for iy in xrange(self.ny):
302 y = ybase + iy * incr
303 #print y
304 pl.plot(x,y,',',color='blue')
305 # plot observed position
306 if plotobs:
307 for i in xrange(len(self.infile)):
308 self.createTableIn( self.infile[i] )
309 irow = 0
310 while ( irow < self.nrow ):
311 chunk = self.getPointingChunk( irow )
312 #print chunk
313 pl.plot(chunk[0],chunk[1],',',color='green')
314 irow += chunk.shape[1]
315 #print irow
316 # show image
317 extent=[self.blc[0]-0.5*self.cellx,
318 self.trc[0]+0.5*self.cellx,
319 self.blc[1]-0.5*self.celly,
320 self.trc[1]+0.5*self.celly]
321 pl.imshow(data,extent=extent,origin='lower',interpolation='nearest')
322 pl.colorbar()
323 pl.xlabel('R.A. [rad]')
324 pl.ylabel('Dec. [rad]')
325 pl.title( title )
326
327 def createTableIn( self, tab ):
328 del self.tablein
329 self.tablein = scantable( tab, average=False )
330 if self.ifno < 0:
331 ifno = self.tablein.getif(0)
332 print 'ifno=',ifno
333 else:
334 ifno = self.ifno
335 sel = selector()
336 sel.set_ifs( ifno )
337 self.tablein.set_selection( sel )
338 self.nchan = len(self.tablein._getspectrum(0))
339 self.nrow = self.tablein.nrow()
340 del sel
341
342
343 def getPointingChunk( self, irow ):
344 numchunk = 1000
345 nrow = min( self.nrow-irow, numchunk )
346 #print 'nrow=',nrow
347 v = numpy.zeros( (2,nrow), dtype=float )
348 idx = 0
349 for i in xrange(irow,irow+nrow):
350 d = self.tablein.get_directionval( i )
351 v[0,idx] = d[0]
352 v[1,idx] = d[1]
353 idx += 1
354 return v
355
356 def getData( self, chan=-1, pol=-1 ):
357 if chan == -1:
358 spectra = self.__chanAverage()
359 else:
360 spectra = self.__chanIndex( chan )
361 data = spectra.reshape( (self.npol,self.ny,self.nx) )
362 if pol == -1:
363 retval = data.mean(axis=0)
364 else:
365 retval = data[pol]
366 return retval
367
368 def __chanAverage( self ):
369 s = scantable( self.outfile, average=False )
370 nrow = s.nrow()
371 spectra = numpy.zeros( (self.npol,nrow/self.npol), dtype=float )
372 irow = 0
373 sp = [0 for i in xrange(self.nchan)]
374 for i in xrange(nrow/self.npol):
375 for ip in xrange(self.npol):
376 sp = s._getspectrum( irow )
377 spectra[ip,i] = numpy.mean( sp )
378 irow += 1
379 return spectra
380
381 def __chanIndex( self, idx ):
382 s = scantable( self.outfile, average=False )
383 nrow = s.nrow()
384 spectra = numpy.zeros( (self.npol,nrow/self.npol), dtype=float )
385 irow = 0
386 sp = [0 for i in xrange(self.nchan)]
387 for i in xrange(nrow/self.npol):
388 for ip in xrange(self.npol):
389 sp = s._getspectrum( irow )
390 spectra[ip,i] = sp[idx]
391 irow += 1
392 return spectra
393
394
Note: See TracBrowser for help on using the repository browser.