source: trunk/python/asapgrid.py @ 2679

Last change on this file since 2679 was 2679, checked in by Takeshi Nakazato, 12 years ago

New Development: No

JIRA Issue: Yes CAS-4429

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...

Updated description for asapgrid.setFunc().


File size: 24.9 KB
Line 
1import numpy
2from asap import rcParams
3from asap.scantable import scantable
4from asap.selector import selector
5from asap._asap import stgrid, stgrid2
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', convsupport=3 )
28       # enable min/max clipping
29       g.enableClip()
30       # or, disable min/max clipping
31       #g.disableClip()
32       # actual gridding
33       g.grid()
34       # save result
35       g.save( outfile='grid.asap' )
36       # plot result
37       g.plot( plotchan=1246, plotpol=-1, plotgrid=True, plotobs=True )
38    """
39    def __init__( self, infile ):
40        """
41        Create asapgrid instance.
42
43        infile -- input data as a string or string list if you want
44                  to grid more than one data at once. 
45        """
46        self.outfile = None
47        self.ifno = None
48        self.gridder = stgrid()
49        self.setData( infile )
50
51    def setData( self, infile ):
52        """
53        Set data to be processed.
54
55        infile -- input data as a string or string list if you want
56                  to grid more than one data at once. 
57        """
58        if isinstance( infile, str ):
59            self.gridder._setin( infile )
60        else:
61            self.gridder._setfiles( infile )
62        self.infile = infile
63
64    def setIF( self, ifno ):
65        """
66        Set IFNO to be processed. Currently, asapgrid allows to process
67        only one IFNO for one gridding run even if the data contains
68        multiple IFs. If you didn't specify IFNO, default value, which
69        is IFNO in the first spectrum, will be processed.
70
71        ifno -- IFNO to be processed.
72        """
73        self.ifno = ifno
74        self.gridder._setif( self.ifno )
75
76    def setPolList( self, pollist ):
77        """
78        Set list of polarization components you want to process.
79        If not specified, all POLNOs will be processed.
80
81        pollist -- list of POLNOs.
82        """
83        self.gridder._setpollist( pollist )
84
85    def setScanList( self, scanlist ):
86        """
87        Set list of scans you want to process. If not specified, all
88        scans will be processed.
89
90        scanlist -- list of SCANNOs.
91        """
92        self.gridder._setscanlist( scanlist )
93
94    def defineImage( self, nx=-1, ny=-1, cellx='', celly='', center='' ):
95        """
96        Define spatial grid.
97
98        First two parameters, nx and ny, define number of pixels of
99        the grid. If which of those is not specified, it will be set
100        to the same value as the other. If none of them are specified,
101        it will be determined from map extent and cell size.
102
103        Next two parameters, cellx and celly, define size of pixel.
104        You should set those parameters as string, which is constructed
105        numerical value and unit, e.g. '0.5arcmin', or numerical value.
106        If those values are specified as numerical value, their units
107        will be assumed to 'arcsec'. If which of those is not specified,
108        it will be set to the same value as the other. If none of them
109        are specified, it will be determined from map extent and number
110        of pixels, or set to '1arcmin' if neither nx nor ny is set.
111
112        The last parameter, center, define the central coordinate of
113        the grid. You should specify its value as a string, like,
114
115           'J2000 05h08m50s -16d23m30s'
116
117        or
118
119           'J2000 05:08:50 -16.23.30'
120
121        You can omit equinox when you specify center coordinate. In that
122        case, J2000 is assumed. If center is not specified, it will be
123        determined from the observed positions of input data.
124
125        nx -- number of pixels along x (R.A.) direction.
126        ny -- number of pixels along y (Dec.) direction.
127        cellx -- size of pixel in x (R.A.) direction.
128        celly -- size of pixel in y (Dec.) direction.
129        center -- central position of the grid.
130        """
131        if not isinstance( cellx, str ):
132            cellx = '%sarcsec'%(cellx)
133        if not isinstance( celly, str ):
134            celly = '%sarcsec'%(celly)
135        self.gridder._defineimage( nx, ny, cellx, celly, center )
136
137    def setFunc( self, func='box', convsupport=-1, truncate="-1", gwidth="-1", jwidth="-1" ):
138        """
139        Set convolution function. Possible options are 'box' (Box-car,
140        default), 'sf' (prolate spheroidal), 'gauss' (Gaussian), and
141        'gjinc' (Gaussian * Jinc).
142        Width of convolution function can be set using several parameters.
143        For 'box' and 'sf', we have one parameter, convsupport, that
144        specifies a cut-off radius of the convlolution function. By default
145        (-1), convsupport is automatically set depending on each convolution
146        function. Default values for convsupport are:
147
148           'box': 1 pixel
149           'sf': 3 pixels
150
151        For 'gauss', we have two parameters for convolution function,
152        truncate and gwidth. The truncate is similar to convsupport
153        except that truncate allows to specify its value as float or
154        string consisting of numeric and unit (e.g. '10arcsec' or
155        '3pixel'). Available units are angular units ('arcsec', 'arcmin',
156        'deg', etc.) and 'pixel'. Default unit is 'pixel' so that if
157        you specify numerical value or string without unit to gwidth,
158        the value will be interpreted as 'pixel'. gwidth is an HWHM of
159        gaussian. It also allows string value. Interpretation of the
160        value for gwidth is same as truncate. Default value for 'gauss'
161        is
162
163              gwidth: '-1' ---> sqrt(log(2.0)) pixel
164            truncate: '-1' ---> 3*gwidth pixel
165
166        For 'gjinc', there is an additional parameter jwidth that
167        specifies a width of the jinc function whose functional form is
168
169            jinc(x) = J_1(pi*x/jwidth) / (pi*x/jwidth)
170
171        Default values for 'gjinc' is
172
173              gwidth: '-1' ---> 2.52*sqrt(log(2.0)) pixel
174              jwidth: '-1' ---> 1.55
175            truncate: '-1' ---> automatically truncate at first null
176
177        Default values for gwidth and jwidth are taken from Mangum et al.
178        (2007).
179
180        func -- Function type ('box', 'sf', 'gauss', 'gjinc').
181        convsupport -- Width of convolution function. Default (-1) is
182                       to choose pre-defined value for each convolution
183                       function. Effective only for 'box' and 'sf'.
184        truncate -- Truncation radius of the convolution function.
185                    Acceptable value is an integer or a float in units of
186                    pixel, or a string consisting of numeric plus unit.
187                    Default unit for the string is 'pixel'. Default (-1)
188                    is to choose pre-defined value for each convolution
189                    function. Effective only for 'gauss' and 'gjinc'.
190        gwidth -- The HWHM of the gaussian. Acceptable value is an integer
191                  or a float in units of pixel, or a string consisting of
192                  numeric plus unit. Default unit for the string is 'pixel'.
193                  Default (-1) is to choose pre-defined value for each
194                  convolution function. Effective only for 'gauss' and
195                  'gjinc'.
196        jwidth -- The width of the jinc function. Acceptable value is an
197                  integer or a float in units of pixel, or a string
198                  consisting of numeric plus unit. Default unit for the
199                  string is 'pixel'. Default (-1) is to choose pre-defined
200                  value for each convolution function. Effective only for
201                  'gjinc'.
202        """
203        self.gridder._setfunc(func,
204                              convsupport=convsupport,
205                              truncate=truncate,
206                              gwidth=gwidth,
207                              jwidth=jwidth)
208
209    def setWeight( self, weightType='uniform' ):
210        """
211        Set weight type. Possible options are 'uniform' (default),
212        'tint' (weight by integration time), 'tsys' (weight by
213        Tsys: 1/Tsys**2), and 'tintsys' (weight by integration time
214        as well as Tsys: tint/Tsys**2).
215
216        weightType -- weight type ('uniform', 'tint', 'tsys', 'tintsys')
217        """
218        self.gridder._setweight( weightType )
219
220    def enableClip( self ):
221        """
222        Enable min/max clipping.
223
224        By default, min/max clipping is disabled so that you should
225        call this method before actual gridding if you want to do
226        clipping.
227        """
228        self.gridder._enableclip()
229
230    def disableClip( self ):
231        """
232        Disable min/max clipping.
233        """
234        self.gridder._disableclip()
235
236    def grid( self ):
237        """
238        Actual gridding which will be done based on several user inputs.
239        """
240        self.gridder._grid()
241
242    def save( self, outfile='' ):
243        """
244        Save result. By default, output data name will be constructed
245        from first element of input data name list (e.g. 'input.asap.grid').
246
247        outfile -- output data name.
248        """
249        self.outfile = self.gridder._save( outfile )
250
251    def plot( self, plotchan=-1, plotpol=-1, plotobs=False, plotgrid=False ):
252        """
253        Plot gridded data.
254
255        plotchan -- Which channel you want to plot. Default (-1) is
256                    to average all the channels.
257        plotpol -- Which polarization component you want to plot.
258                   Default (-1) is to average all the polarization
259                   components.
260        plotobs -- Also plot observed position if True. Default
261                   is False. Setting True for large amount of spectra
262                   might be time consuming.
263        plotgrid -- Also plot grid center if True. Default is False.
264                    Setting True for large number of grids might be
265                    time consuming.
266        """
267        import time
268        t0=time.time()
269        # to load scantable on disk
270        storg = rcParams['scantable.storage']
271        rcParams['scantable.storage'] = 'disk'
272        plotter = _SDGridPlotter( self.infile, self.outfile, self.ifno )
273        plotter.plot( chan=plotchan, pol=plotpol, plotobs=plotobs, plotgrid=plotgrid )
274        # back to original setup
275        rcParams['scantable.storage'] = storg
276        t1=time.time()
277        asaplog.push('plot: elapsed time %s sec'%(t1-t0))
278        asaplog.post('DEBUG','asapgrid.plot')
279
280    def plotFunc(self, clear=True):
281        """
282        Support function to see the shape of current grid function.
283
284        clear -- clear panel if True. Default is True.
285        """
286        pl.figure(11)
287        if clear:
288            pl.clf()
289        f = self.gridder._getfunc()
290        convsampling = 100
291        a = numpy.arange(0,len(f)/convsampling,1./convsampling,dtype=float)
292        pl.plot(a,f,'.-')
293        pl.xlabel('pixel')
294        pl.ylabel('convFunc')
295       
296class asapgrid2:
297    """
298    The asapgrid class is defined to convolve data onto regular
299    spatial grid. Typical usage is as follows:
300
301       # create asapgrid instance with input scantable
302       s = scantable( 'testimage1.asap', average=False )
303       g = asapgrid( s )
304       # set IFNO if necessary
305       g.setIF( 0 )
306       # set POLNOs if necessary
307       g.setPolList( [0,1] )
308       # set SCANNOs if necessary
309       g.setScanList( [22,23,24] )
310       # define image with full specification
311       # you can skip some parameters (see help for defineImage)
312       g.defineImage( nx=12, ny=12, cellx='10arcsec', celly='10arcsec',
313                      center='J2000 10h10m10s -5d05m05s' )
314       # set convolution function
315       g.setFunc( func='sf', width=3 )
316       # enable min/max clipping
317       g.enableClip()
318       # or, disable min/max clipping
319       #g.disableClip()
320       # actual gridding
321       g.grid()
322       # get result as scantable
323       sg = g.getResult()
324    """
325    def __init__( self, scantab ):
326        """
327        Create asapgrid instance.
328
329        scantab -- input data as a scantable or a list of scantables
330                   to grid more than one data at once. 
331        """
332        self.outfile = None
333        self.ifno = None
334        self.gridder = stgrid2()
335        self.setData( scantab )
336
337    def setData( self, scantab ):
338        """
339        Set data to be processed.
340
341        scantab -- input data as a scantable or a list of scantables
342                   to grid more than one data at once. 
343        """
344        if isinstance( scantab, scantable ):
345            self.gridder._setin( scantab )
346        else:
347            self.gridder._setfiles( scantab )
348        self.scantab = scantab
349
350    def setIF( self, ifno ):
351        """
352        Set IFNO to be processed. Currently, asapgrid allows to process
353        only one IFNO for one gridding run even if the data contains
354        multiple IFs. If you didn't specify IFNO, default value, which
355        is IFNO in the first spectrum, will be processed.
356
357        ifno -- IFNO to be processed.
358        """
359        self.ifno = ifno
360        self.gridder._setif( self.ifno )
361
362    def setPolList( self, pollist ):
363        """
364        Set list of polarization components you want to process.
365        If not specified, all POLNOs will be processed.
366
367        pollist -- list of POLNOs.
368        """
369        self.gridder._setpollist( pollist )
370
371    def setScanList( self, scanlist ):
372        """
373        Set list of scans you want to process. If not specified, all
374        scans will be processed.
375
376        scanlist -- list of SCANNOs.
377        """
378        self.gridder._setscanlist( scanlist )
379
380    def defineImage( self, nx=-1, ny=-1, cellx='', celly='', center='' ):
381        """
382        Define spatial grid.
383
384        First two parameters, nx and ny, define number of pixels of
385        the grid. If which of those is not specified, it will be set
386        to the same value as the other. If none of them are specified,
387        it will be determined from map extent and cell size.
388
389        Next two parameters, cellx and celly, define size of pixel.
390        You should set those parameters as string, which is constructed
391        numerical value and unit, e.g. '0.5arcmin', or numerical value.
392        If those values are specified as numerical value, their units
393        will be assumed to 'arcsec'. If which of those is not specified,
394        it will be set to the same value as the other. If none of them
395        are specified, it will be determined from map extent and number
396        of pixels, or set to '1arcmin' if neither nx nor ny is set.
397
398        The last parameter, center, define the central coordinate of
399        the grid. You should specify its value as a string, like,
400
401           'J2000 05h08m50s -16d23m30s'
402
403        or
404
405           'J2000 05:08:50 -16.23.30'
406
407        You can omit equinox when you specify center coordinate. In that
408        case, J2000 is assumed. If center is not specified, it will be
409        determined from the observed positions of input data.
410
411        nx -- number of pixels along x (R.A.) direction.
412        ny -- number of pixels along y (Dec.) direction.
413        cellx -- size of pixel in x (R.A.) direction.
414        celly -- size of pixel in y (Dec.) direction.
415        center -- central position of the grid.
416        """
417        if not isinstance( cellx, str ):
418            cellx = '%sarcsec'%(cellx)
419        if not isinstance( celly, str ):
420            celly = '%sarcsec'%(celly)
421        self.gridder._defineimage( nx, ny, cellx, celly, center )
422
423    def setFunc( self, func='box', width=-1 ):
424        """
425        Set convolution function. Possible options are 'box' (Box-car,
426        default), 'sf' (prolate spheroidal), and 'gauss' (Gaussian).
427        Width of convolution function can be set using width parameter.
428        By default (-1), width is automatically set depending on each
429        convolution function. Default values for width are:
430
431           'box': 1 pixel
432           'sf': 3 pixels
433           'gauss': 1 pixel (width is used as HWHM)
434
435        func -- Function type ('box', 'sf', 'gauss').
436        width -- Width of convolution function. Default (-1) is to
437                 choose pre-defined value for each convolution function.
438        """
439        fname = func.upper()
440        if fname == 'GAUSS' or fname == 'GJINC':
441            gw = str(gwidth)
442            jw = str(jwidth)
443            w = str(width)
444            if w[0] == '-': w = ''
445            #self.gridder._setfunc(fname, -1, w, gw, jw)
446            self.gridder._setfunc(fname,convsupport=-1,gwidth=gw,jwidth=jw,truncate=w)
447        else:
448            self.gridder._setfunc( func, convsupport=width )
449
450    def setWeight( self, weightType='uniform' ):
451        """
452        Set weight type. Possible options are 'uniform' (default),
453        'tint' (weight by integration time), 'tsys' (weight by
454        Tsys: 1/Tsys**2), and 'tintsys' (weight by integration time
455        as well as Tsys: tint/Tsys**2).
456
457        weightType -- weight type ('uniform', 'tint', 'tsys', 'tintsys')
458        """
459        self.gridder._setweight( weightType )
460
461    def enableClip( self ):
462        """
463        Enable min/max clipping.
464
465        By default, min/max clipping is disabled so that you should
466        call this method before actual gridding if you want to do
467        clipping.
468        """
469        self.gridder._enableclip()
470
471    def disableClip( self ):
472        """
473        Disable min/max clipping.
474        """
475        self.gridder._disableclip()
476
477    def grid( self ):
478        """
479        Actual gridding which will be done based on several user inputs.
480        """
481        self.gridder._grid()
482
483    def getResult( self ):
484        """
485        Return gridded data as a scantable.
486        """
487        tp = 0 if rcParams['scantable.storage']=='memory' else 1
488        return scantable( self.gridder._get( tp ), average=False )
489   
490    def plotFunc(self, clear=True):
491        """
492        Support function to see the shape of current grid function.
493
494        clear -- clear panel if True. Default is True.
495        """
496        pl.figure(11)
497        if clear:
498            pl.clf()
499        f = self.gridder._getfunc()
500        convsampling = 100
501        a = numpy.arange(0,len(f)/convsampling,1./convsampling,dtype=float)
502        pl.plot(a,f,'.-')
503        pl.xlabel('pixel')
504        pl.ylabel('convFunc')
505
506class _SDGridPlotter:
507    def __init__( self, infile, outfile=None, ifno=-1 ):
508        if isinstance( infile, str ):
509            self.infile = [infile]
510        else:
511            self.infile = infile
512        self.outfile = outfile
513        if self.outfile is None:
514            self.outfile = self.infile[0].rstrip('/')+'.grid'
515        self.nx = -1
516        self.ny = -1
517        self.nchan = 0
518        self.npol = 0
519        self.pollist = []
520        self.cellx = 0.0
521        self.celly = 0.0
522        self.center = [0.0,0.0]
523        self.nonzero = [[0.0],[0.0]]
524        self.ifno = ifno
525        self.tablein = None
526        self.nrow = 0
527        self.blc = None
528        self.trc = None
529        self.get()
530
531    def get( self ):
532        s = scantable( self.outfile, average=False )
533        self.nchan = len(s._getspectrum(0))
534        nrow = s.nrow()
535        pols = numpy.ones( nrow, dtype=int )
536        for i in xrange(nrow):
537            pols[i] = s.getpol(i)
538        self.pollist, indices = numpy.unique( pols, return_inverse=True )
539        self.npol = len(self.pollist)
540        self.pollist = self.pollist[indices[:self.npol]]
541        #print 'pollist=',self.pollist
542        #print 'npol=',self.npol
543        #print 'nrow=',nrow
544
545        idx = 1
546        d0 = s.get_direction( 0 ).split()[-2]
547        d = s.get_direction(self.npol*idx)
548        while( d is not None \
549               and d.split()[-2] != d0):
550            idx += 1
551            d = s.get_direction(self.npol*idx)
552       
553        self.nx = idx
554        self.ny = nrow / (self.npol * idx )
555        #print 'nx,ny=',self.nx,self.ny
556
557        self.blc = s.get_directionval( 0 )
558        self.trc = s.get_directionval( nrow-self.npol )
559        #print self.blc
560        #print self.trc
561        if nrow > 1:
562            incrx = s.get_directionval( self.npol )
563            incry = s.get_directionval( self.nx*self.npol )
564        else:
565            incrx = [0.0,0.0]
566            incry = [0.0,0.0]
567        self.cellx = abs( self.blc[0] - incrx[0] )
568        self.celly = abs( self.blc[1] - incry[1] )
569        #print 'cellx,celly=',self.cellx,self.celly
570
571    def plot( self, chan=-1, pol=-1, plotobs=False, plotgrid=False ):
572        if pol < 0:
573            opt = 'averaged over pol'
574        else:
575            opt = 'pol %s'%(pol)
576        if type(chan) is list:
577            opt += ', averaged over channel %s-%s'%(chan[0],chan[1])
578        elif chan < 0:
579            opt += ', averaged over channel'
580        else:
581            opt += ', channel %s'%(chan)
582        data = self.getData( chan, pol )
583        #data = numpy.fliplr( data )
584        title = 'Gridded Image (%s)'%(opt)
585        pl.figure(10)
586        pl.clf()
587        # plot grid position
588        if plotgrid:
589            x = numpy.arange(self.blc[0],self.trc[0]+0.5*self.cellx,self.cellx,dtype=float)
590            #print 'len(x)=',len(x)
591            #print 'x=',x
592            ybase = numpy.ones(self.nx,dtype=float)*self.blc[1]
593            #print 'len(ybase)=',len(ybase)
594            incr = self.celly
595            for iy in xrange(self.ny):
596                y = ybase + iy * incr
597                #print y
598                pl.plot(x,y,',',color='blue')
599        # plot observed position
600        if plotobs:
601            for i in xrange(len(self.infile)):
602                self.createTableIn( self.infile[i] )
603                irow = 0
604                while ( irow < self.nrow ):
605                    chunk = self.getPointingChunk( irow )
606                    #print chunk
607                    pl.plot(chunk[0],chunk[1],',',color='green')
608                    irow += chunk.shape[1]
609                    #print irow
610        # show image
611        extent=[self.trc[0]+0.5*self.cellx,
612                self.blc[0]-0.5*self.cellx,
613                self.blc[1]-0.5*self.celly,
614                self.trc[1]+0.5*self.celly]
615        deccorr = 1.0/numpy.cos(0.5*(self.blc[1]+self.trc[1]))
616        pl.imshow(data,extent=extent,origin='lower',interpolation='nearest')
617        pl.colorbar()
618        pl.xlabel('R.A. [rad]')
619        pl.ylabel('Dec. [rad]')
620        ax = pl.axes()
621        ax.set_aspect(deccorr)
622        pl.title( title )
623
624    def createTableIn( self, tab ):
625        del self.tablein
626        self.tablein = scantable( tab, average=False )
627        if self.ifno < 0:
628            ifno = self.tablein.getif(0)
629            #print 'ifno=',ifno
630        else:
631            ifno = self.ifno
632        sel = selector()
633        sel.set_ifs( ifno )
634        self.tablein.set_selection( sel )
635        self.nchan = len(self.tablein._getspectrum(0))
636        self.nrow = self.tablein.nrow()
637        del sel
638       
639
640    def getPointingChunk( self, irow ):
641        numchunk = 1000
642        nrow = min( self.nrow-irow, numchunk )
643        #print 'nrow=',nrow
644        v = numpy.zeros( (2,nrow), dtype=float )
645        idx = 0
646        for i in xrange(irow,irow+nrow):
647            d = self.tablein.get_directionval( i )
648            v[0,idx] = d[0]
649            v[1,idx] = d[1]
650            idx += 1
651        return v
652
653    def getData( self, chan=-1, pol=-1 ):
654        if type(chan) == list:
655            spectra = self.__chanAverage(start=chan[0],end=chan[1])
656        elif chan == -1:
657            spectra = self.__chanAverage()
658        else:
659            spectra = self.__chanIndex( chan )
660        data = spectra.reshape( (self.npol,self.ny,self.nx) )
661        if pol == -1:
662            retval = data.mean(axis=0)
663        else:
664            retval = data[pol]
665        return retval
666
667    def __chanAverage( self, start=-1, end=-1 ):
668        s = scantable( self.outfile, average=False )
669        nrow = s.nrow()
670        spectra = numpy.zeros( (self.npol,nrow/self.npol), dtype=float )
671        irow = 0
672        sp = [0 for i in xrange(self.nchan)]
673        if start < 0:
674            start = 0
675        if end < 0:
676            end = self.nchan
677        for i in xrange(nrow/self.npol):
678            for ip in xrange(self.npol):
679                sp = s._getspectrum( irow )[start:end]
680                spectra[ip,i] = numpy.mean( sp )
681                irow += 1
682           
683        return spectra
684
685    def __chanIndex( self, idx ):
686        s = scantable( self.outfile, average=False )
687        nrow = s.nrow()
688        spectra = numpy.zeros( (self.npol,nrow/self.npol), dtype=float )
689        irow = 0
690        sp = [0 for i in xrange(self.nchan)]
691        for i in xrange(nrow/self.npol):
692            for ip in xrange(self.npol):
693                sp = s._getspectrum( irow )
694                spectra[ip,i] = sp[idx]
695                irow += 1
696        return spectra
697       
698           
Note: See TracBrowser for help on using the repository browser.