casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables
cleanhelper.py
Go to the documentation of this file.
00001 from  casac import *
00002 import os
00003 import commands
00004 import math
00005 import pdb
00006 import numpy
00007 import shutil
00008 import string
00009 from numpy import unique
00010 from odict import odict
00011 
00012 ###some helper tools
00013 ms = casac.ms()
00014 tb = casac.table()
00015 qa = casac.quanta()
00016 me = casac.measures()
00017 rg = casac.regionmanager()
00018 ia = casac.image()
00019 
00020 class cleanhelper:
00021     def __init__(self, imtool='', vis='', usescratch=False, casalog=None):
00022         """
00023         Contruct the cleanhelper object with an imager tool
00024         like so:
00025         a=cleanhelper(im, vis)
00026         """
00027         ###fix for assumption that if it is a list of 1 it is sngle ms mode
00028         if((type(vis)==list) and (len(vis)==1)):
00029             vis=vis[0]
00030         ####
00031         if((type(imtool) != str) and (len(vis) !=0)):
00032             # for multi-mses input (not fully implemented yet)
00033             if(type(vis)==list):
00034                 self.initmultims(imtool, vis, usescratch)
00035             else:
00036                 self.initsinglems(imtool, vis, usescratch)
00037         #self.maskimages={}
00038         self.maskimages=odict()
00039         self.finalimages={}
00040         self.usescratch=usescratch
00041         self.dataspecframe='LSRK'
00042         self.usespecframe='' 
00043         self.inframe=False
00044         # to use phasecenter parameter in initChannelizaiton stage
00045         # this is a temporary fix need. 
00046         self.srcdir=''
00047         # for multims handling
00048         self.sortedvislist=[]
00049         if not casalog:  # Not good!
00050             casalog = casac.logsink()
00051             #casalog.setglobal(True)
00052         self._casalog = casalog
00053         
00054     @staticmethod
00055     def getspwtable(visname=''):
00056         tb.open(visname)
00057         spectable=string.split(tb.getkeyword('SPECTRAL_WINDOW'))
00058         if(len(spectable) ==2):
00059             spectable=spectable[1]
00060         else:
00061             spectable=visname+"/SPECTRAL_WINDOW"
00062         return spectable
00063 
00064     def initsinglems(self, imtool, vis, usescratch):
00065         """
00066         initialization for single ms case
00067         """
00068         self.im=imtool
00069         # modified for self.vis to be a list for handling multims
00070         #self.vis=vis
00071         self.vis=[vis]
00072         self.sortedvisindx=[0]
00073         
00074         if ((type(vis)==str) & (os.path.exists(vis))):
00075             self.im.open(vis, usescratch=usescratch)
00076         else:
00077             raise Exception, 'Visibility data set not found - please verify the name'
00078         self.phasecenter=''
00079         self.spwindex=-1
00080         self.fieldindex=-1
00081         self.outputmask=''
00082         self.csys={}
00083 
00084     def initmultims(self, imtool, vislist, usescratch):
00085         """
00086         initialization for multi-mses 
00087         """
00088         self.im=imtool
00089         self.vis=vislist
00090         if type(vislist)==list:
00091             #        self.im.selectvis(vis)
00092             if ((type(self.vis[0])==str) & (os.path.exists(self.vis[0]))):
00093                 pass
00094             else:
00095                 raise Exception, 'Visibility data set not found - please verify the name'
00096         self.phasecenter=''
00097         self.spwindex=-1
00098         self.fieldindex=-1
00099         self.outputmask=''
00100         self.csys={}
00101 
00102     def sortvislist(self,spw,mode,width):
00103         """
00104         sorting user input vis if it is multiple MSes based on
00105         frequencies (spw). So that in sebsequent processing such
00106         as setChannelization() correctly works.
00107         Returns sorted vis. name list
00108         """
00109         import operator
00110         reverse=False
00111         if mode=='velocity':
00112           if qa.quantity(width)['value']>0:
00113             reverse=True
00114         elif mode=='frequency':
00115           if qa.quantity(width)['value']<0:
00116             reverse=True 
00117         minmaxfs = []
00118         # get selection
00119         if len(self.vis) > 1:
00120           for i in range(len(self.vis)):
00121             visname = self.vis[i]
00122             if type(spw)==list and len(spw) > 1:
00123               inspw=spw[i]
00124             else:
00125               inspw=spw
00126             if len(inspw)==0:
00127               # empty string = select all (='*', for msselectindex)
00128               inspw='*'
00129             mssel=ms.msseltoindex(vis=visname,spw=inspw)
00130             spectable=self.getspwtable(visname)
00131             tb.open(spectable)
00132             chanfreqs=tb.getvarcol('CHAN_FREQ')
00133             kys = chanfreqs.keys()
00134             selspws=mssel['spw']
00135             # find extreme freq in each selected spw
00136             minmax0=0.
00137             firstone=True
00138             minmaxallspw=0.
00139             for chansel in mssel['channel']:
00140               if reverse:
00141                 minmaxf = max(chanfreqs[kys[chansel[0]]][chansel[1]:chansel[2]+1])
00142               else:
00143                 minmaxf = min(chanfreqs[kys[chansel[0]]][chansel[1]:chansel[2]+1])
00144               if firstone:
00145                 minmaxf0=minmaxf
00146                 firstone=False
00147               if reverse:
00148                 minmaxallspw=max(minmaxf,minmaxf0) 
00149               else:
00150                 minmaxallspw=min(minmaxf,minmaxf0) 
00151             minmaxfs.append(minmaxallspw)
00152           self.sortedvisindx = [x for x, y in sorted(enumerate(minmaxfs),
00153                                 key=operator.itemgetter(1),reverse=reverse)] 
00154           self.sortedvislist = [self.vis[k] for k in self.sortedvisindx]
00155         else:
00156           self.sortedvisindx=[0]
00157           self.sortedvislist=self.vis
00158         #print "sortedvislist=",self.sortedvislist
00159         #print "sortedvisindx=",self.sortedvisindx
00160         return
00161 
00162 
00163     def defineimages(self, imsize, cell, stokes, mode, spw, nchan, start,
00164                      width, restfreq, field, phasecenter, facets=1, outframe='',
00165                      veltype='radio'):
00166         """
00167         Define image parameters -calls im.defineimage.
00168         for processing a single field 
00169         (also called by definemultiimages for multifield) 
00170         """
00171         if((type(cell)==list) and (len(cell)==1)):
00172             cell.append(cell[0])
00173         elif ((type(cell)==str) or (type(cell)==int) or (type(cell)==float)):
00174             cell=[cell, cell]
00175         elif (type(cell) != list):
00176             raise TypeError, "parameter cell %s is not understood" % str(cell)
00177         cellx=qa.quantity(cell[0], 'arcsec')
00178         celly=qa.quantity(cell[1], 'arcsec')
00179         if(cellx['unit']==''):
00180             #string with no units given
00181             cellx['unit']='arcsec'
00182         if(celly['unit']==''):
00183             #string with no units given
00184             celly['unit']='arcsec'
00185         if((type(imsize)==list) and (len(imsize)==1)):
00186             imsize.append(imsize[0])
00187         elif(type(imsize)==int):
00188             imsize=[imsize, imsize]
00189         elif(type(imsize) != list):
00190             raise TypeError, "parameter imsize %s is not understood" % str(imsize)
00191             
00192         elstart=start
00193         if(mode=='frequency'):
00194         ##check that start and step have units
00195             if(qa.quantity(start)['unit'].find('Hz') < 0):
00196                 raise TypeError, "start parameter %s is not a valid frequency quantity " % str(start)
00197             ###make sure we respect outframe
00198             if(self.usespecframe != ''):
00199                 elstart=me.frequency(self.usespecframe, start)
00200             if(qa.quantity(width)['unit'].find('Hz') < 0):
00201                 raise TypeError, "width parameter %s is not a valid frequency quantity " % str(width)   
00202         elif(mode=='velocity'): 
00203         ##check that start and step have units
00204             if(qa.quantity(start)['unit'].find('m/s') < 0):
00205                 raise TypeError, "start parameter %s is not a valid velocity quantity " % str(start)
00206             ###make sure we respect outframe
00207             if(self.usespecframe != ''):
00208                 elstart=me.radialvelocity(self.usespecframe, start)
00209             if(qa.quantity(width)['unit'].find('m/s') < 0):
00210                 raise TypeError, "width parameter %s is not a valid velocity quantity " % str(width)    
00211         else:
00212             if((type(width) != int) or 
00213                (type(start) != int)):
00214                 raise TypeError, "start (%s), width (%s) have to be integers with mode %s" % (str(start),str(width),mode)
00215 
00216         # changes related multims handling added below (TT)
00217         # multi-mses are sorted internally (stored in self.sortedvislist and
00218         # indices in self.sortedvisindx) in frequency-wise so that first vis
00219         # contains lowest/highest frequency. Note: self.vis is in original user input order.
00220         #####understand phasecenter
00221         if(type(phasecenter)==str):
00222             ### blank means take field[0]
00223             if (phasecenter==''):
00224                 fieldoo=field
00225                 if(fieldoo==''):
00226                     fieldoo='0'
00227                 #phasecenter=int(ms.msseltoindex(self.vis,field=fieldoo)['field'][0])
00228                 phasecenter=int(ms.msseltoindex(self.vis[self.sortedvisindx[0]],field=fieldoo)['field'][0])
00229             else:
00230                 tmppc=phasecenter
00231                 try:
00232                     #if(len(ms.msseltoindex(self.vis, field=phasecenter)['field']) > 0):
00233                     #    tmppc = int(ms.msseltoindex(self.vis,
00234                     #                                field=phasecenter)['field'][0])
00235                     # to handle multims set to the first ms that matches
00236                     for i in self.sortedvisindx:
00237                         try:
00238                             if(len(ms.msseltoindex(self.vis[i], field=phasecenter)['field']) > 0):
00239                                 tmppc = int(ms.msseltoindex(self.vis[i],
00240                                                     field=phasecenter)['field'][0])
00241                                 #print "tmppc,i=", tmppc, i
00242                         except Exception, instance:
00243                              pass
00244 
00245                     ##succesful must be string like '0' or 'NGC*'
00246                 except Exception, instance:
00247                     ##failed must be a string 'J2000 18h00m00 10d00m00'
00248                     tmppc = phasecenter
00249                 phasecenter = tmppc
00250         self.phasecenter = phasecenter
00251         #print 'cell', cellx, celly, restfreq
00252         ####understand spw
00253         if spw in (-1, '-1', '*', '', ' '):
00254             spwindex = -1
00255         else:
00256             # old, single ms case
00257             #spwindex=ms.msseltoindex(self.vis, spw=spw)['spw'].tolist()
00258             #if(len(spwindex) == 0):
00259             #    spwindex = -1
00260         #self.spwindex = spwindex
00261 
00262         # modified for multims hanlding
00263             # multims case
00264             if len(self.vis)>1:
00265                 self.spwindex=[]
00266                 # will set spwindex in datsel
00267                 spwindex=-1
00268                 for i in self.sortedvisindx:
00269                    if type(spw)==list:
00270                       inspw=spw[i]
00271                    else:
00272                       inspw=spw
00273                    if len(inspw)==0: 
00274                       inspw='*'
00275                    self.spwindex.append(ms.msseltoindex(self.vis[i],spw=inspw)['spw'].tolist())
00276             # single ms
00277             else:
00278                 spwindex=ms.msseltoindex(self.vis[0], spw=spw)['spw'].tolist()
00279                 if(len(spwindex) == 0):
00280                     spwindex = -1
00281                 self.spwindex = spwindex
00282 
00283         ##end spwindex
00284 
00285         if self.usespecframe=='': 
00286             useframe=self.dataspecframe
00287         else:
00288             useframe=self.usespecframe
00289 
00290         self.im.defineimage(nx=imsize[0],      ny=imsize[1],
00291                             cellx=cellx,       celly=celly,
00292                             mode=mode,         nchan=nchan,
00293                             start=elstart,       step=width,
00294                             spw=spwindex,      stokes=stokes,
00295                             restfreq=restfreq, outframe=useframe,
00296                             veltype=veltype, phasecenter=phasecenter,
00297                             facets=facets)
00298 
00299     def definemultiimages(self, rootname, imsizes, cell, stokes, mode, spw,
00300                           nchan, start, width, restfreq, field, phasecenters,
00301                           names=[], facets=1, outframe='', veltype='radio',
00302                           makepbim=False, checkpsf=False):
00303         """
00304         Define image parameters - multiple field version
00305         This fucntion set "private" variables (imagelist and imageids),
00306         and then calls defineimages for ecah field. 
00307         """
00308         #will do loop in reverse assuming first image is main field
00309         if not hasattr(imsizes, '__len__'):
00310             imsizes = [imsizes]
00311         self.nimages=len(imsizes)
00312         #if((len(imsizes)<=2) and ((type(imsizes[0])==int) or
00313         #                          (type(imsizes[0])==long))):
00314         if((len(imsizes)<=2) and (numpy.issubdtype(type(imsizes[0]), int))):
00315             self.nimages=1
00316             if(len(imsizes)==2):
00317                 imsizes=[(imsizes[0], imsizes[1])]
00318             else:
00319                 imsizes=[(imsizes[0], imsizes[0])]
00320         self._casalog.post('Number of images: ' + str(self.nimages), 'DEBUG1')
00321 
00322         #imagelist is to have the list of image model names
00323         self.imagelist={}
00324         #imageids is to tag image to mask in aipsbox style file 
00325         self.imageids={}
00326         if(type(phasecenters) == str):
00327             phasecenters=[phasecenters]
00328         if(type(phasecenters) == int):
00329             phasecenters=[phasecenters]
00330         self._casalog.post('Number of phase centers: ' + str(len(phasecenters)),
00331                            'DEBUG1')
00332 
00333         if((self.nimages==1) and (type(names)==str)):
00334             names=[names]
00335         if((len(phasecenters)) != (len(imsizes))):
00336             errmsg = "Mismatch between the number of phasecenters (%d), image sizes (%d) , and images (%d)" % (len(phasecenters), len(imsizes), self.nimages)
00337             self._casalog.post(errmsg, 'SEVERE')
00338             raise ValueError, errmsg
00339         self.skipclean=False
00340         lerange=range(self.nimages)
00341         lerange.reverse()
00342         for n in lerange:
00343             self.defineimages(list(imsizes[n]), cell, stokes, mode, spw, nchan,
00344                               start, width, restfreq, field, phasecenters[n],
00345                               facets,outframe,veltype)
00346             if(len(names)==self.nimages):
00347                 self.imageids[n]=names[n]
00348                 if(rootname != ''):
00349                     self.imagelist[n]=rootname+'_'+names[n]
00350                 else:
00351                     self.imagelist[n]=names[n]
00352             else:
00353                 self.imagelist[n]=rootname+'_'+str(n)
00354             ###make the image only if it does not exits
00355             ###otherwise i guess you want to continue a clean
00356             if(not os.path.exists(self.imagelist[n])):
00357                 self.im.make(self.imagelist[n])
00358             #if(makepbim and n==0):
00359             if(makepbim):
00360                 ##make .flux image 
00361                 # for now just make for a main field 
00362                 ###need to get the pointing so select the fields
00363                 # single ms
00364 #                if len(self.vis)==1:
00365 #                  self.im.selectvis(field=field,spw=spw)
00366 #                # multi-ms
00367 #                else: 
00368 #                  if len(self.vis) > 1:
00369 #                  # multi-mses case: use first vis that has the specified field
00370 #                  # (use unsorted vis list)
00371 #                  nvis=len(self.vis)
00372 #                  for i in range(nvis):
00373 #                    #if type(field)!=list:
00374 #                    #  field=[field]
00375 #                    try:
00376 #                      selparam=self._selectlistinputs(nvis,i,self.paramlist)
00377 #                      self.im.selectvis(vis=self.vis[i],field=selparam['field'],spw=selparam['spw'])
00378 #                    except:
00379 #                      pass
00380 
00381                 # set to default minpb(=0.1), should use input minpb?
00382                 self.im.setmfcontrol()
00383                 self.im.setvp(dovp=True)
00384                 self.im.makeimage(type='pb', image=self.imagelist[n]+'.flux',
00385                                   compleximage="", verbose=False)
00386                 self.im.setvp(dovp=False, verbose=False)
00387 
00388                 
00389     def checkpsf(self,chan):
00390         """
00391         a check to make sure selected channel plane is not entirely flagged
00392         (for chinter=T interactive clean)
00393         """
00394         #lerange=range(self.nimages)
00395         #lerange.reverse()
00396         #for n in lerange:
00397         #    self.getchanimage(self.finalimages[n]+'.psf',self.imagelist[n]+'.test.psf',chan)
00398         #    ia.open(self.imagelist[n]+'.test.psf')
00399         #    imdata=ia.getchunk()
00400         #    print "imagelist[", n, "]=", self.imagelist[n], " imdata.sum()=",imdata.sum()
00401             #if n==0 and imdata.sum()==0.0:
00402             #    self.skipclean=True 
00403         #    if self.skipclean:
00404         #        pass
00405         #    elif imdata.sum()==0.0:
00406         #        self.skipclean=True
00407         
00408         # need to check only for main field
00409         self.getchanimage(self.finalimages[0]+'.psf',self.imagelist[0]+'.test.psf',chan)
00410         ia.open(self.imagelist[0]+'.test.psf')
00411         imdata=ia.getchunk()
00412         if imdata.sum()==0.0:
00413             self.skipclean=True
00414 
00415 
00416     def makeEmptyimages(self):
00417         """
00418         Create empty images (0.0 pixel values) for 
00419         image, residual, psf
00420         must run after definemultiimages()
00421         and it is assumed that definemultiimages creates 
00422         empty images (self.imagelist). 
00423         """ 
00424         lerange=range(self.nimages)
00425         for n in lerange:
00426             os.system('cp -r '+self.imagelist[n]+' '+self.imagelist[n]+'.image')
00427             os.system('cp -r '+self.imagelist[n]+' '+self.imagelist[n]+'.residual')
00428             os.system('cp -r '+self.imagelist[n]+' '+self.imagelist[n]+'.psf')
00429             os.system('cp -r '+self.imagelist[n]+' '+self.imagelist[n]+'.model')
00430             os.system('cp -r '+self.imagelist[n]+' '+self.imagelist[n]+'.mask')
00431 
00432     
00433     def makemultifieldmask(self, maskobject=''):
00434         """
00435         This function assumes that the function definemultiimages has been run and thus
00436         self.imagelist is defined
00437         if single image use the single image version
00438         (this is not up to date for current mask handling but used in task_widefield,
00439          to be removed after task_widefield is gone)
00440         """
00441         if((len(self.maskimages)==(len(self.imagelist)))):
00442             if(not self.maskimages.has_key(self.imagelist[0])):
00443                 self.maskimages={}
00444         else:
00445             self.maskimages={}
00446         masktext=[]
00447         if (not hasattr(maskobject, '__len__')) \
00448            or (len(maskobject) == 0) or (maskobject == ['']):
00449             return
00450         if(type(maskobject)==str):
00451             maskobject=[maskobject]
00452         if(type(maskobject) != list):
00453             ##don't know what to do with this
00454             raise TypeError, 'Dont know how to deal with mask object'
00455         n=0
00456         for masklets in maskobject:
00457             if(type(masklets)==str):
00458                     if(os.path.exists(masklets)):
00459                         if(commands.getoutput('file '+masklets).count('directory')):
00460                             self.maskimages[self.imagelist[n]]=masklets
00461                             n=n+1
00462                         elif(commands.getoutput('file '+masklets).count('text')):
00463                             masktext.append(masklets)
00464                         else:
00465                             raise TypeError, 'Can only read text mask files or mask images'
00466                     else:
00467                        raise TypeError, masklets+' seems to be non-existant' 
00468         if(len(masktext) > 0):
00469             circles, boxes=self.readmultifieldboxfile(masktext)
00470             if(len(self.maskimages)==0):
00471                 for k in range(len(self.imageids)):
00472                     if(not self.maskimages.has_key(self.imagelist[k])):
00473                         self.maskimages[self.imagelist[k]]=self.imagelist[k]+'.mask'
00474             for k in range(len(self.imageids)):
00475                 ###initialize mask if its not there yet
00476                 if(not (os.path.exists(self.maskimages[self.imagelist[k]]))):
00477                     ia.fromimage(outfile=self.maskimages[self.imagelist[k]],
00478                                  infile=self.imagelist[k])
00479                     ia.open(self.maskimages[self.imagelist[k]])
00480                     ia.set(pixels=0.0)
00481                     ia.done(verbose=False)
00482                 if(circles.has_key(self.imageids[k]) and boxes.has_key(self.imageids[k])):
00483                     self.im.regiontoimagemask(mask=self.maskimages[self.imagelist[k]],
00484                                               boxes=boxes[self.imageids[k]],
00485                                               circles=circles[self.imageids[k]])
00486                 elif(circles.has_key(self.imageids[k])):
00487                     self.im.regiontoimagemask(mask=self.maskimages[self.imagelist[k]],
00488                                               circles=circles[self.imageids[k]])
00489                 elif(boxes.has_key(self.imageids[k])):
00490                     self.im.regiontoimagemask(mask=self.maskimages[self.imagelist[k]],
00491                                               boxes=boxes[self.imageids[k]])
00492                 else:
00493                     ###need to make masks that select that whole image
00494                     ia.open(self.maskimages[self.imagelist[k]])
00495                     ia.set(pixels=1.0)
00496                     ia.done(verbose=False)
00497 
00498 
00499     def makemultifieldmask2(self, maskobject='',slice=-1, newformat=True, interactive=False):
00500 
00501         """
00502         Create mask images for multiple fields (flanking fields) 
00503         This new makemultifieldmask to accomodate different kinds of masks supported
00504         in clean with flanking fields.
00505 
00506         Keyword arguments:
00507         maskobject -- input mask, a list (of string or of list(s)) or a string 
00508         slice      -- channel slice (to handle chaniter mode): default = -1 (all)
00509         newformat  -- if mask is read from new format text file: default = True 
00510 
00511         Prerequiste: definemultiimages has already ran so that imagelist is defined 
00512        
00513         Notes: 
00514         * It makes empty mask images at begenning, calls makemaskimage, and if no
00515           mask to be specified, the corresponding empty mask image is removed
00516   
00517         * When clean is executed in commnad line style (e.g. clean(vis='..', ..))
00518           it is possible to have mask parameter consists of a mix of strings and int lists
00519           (i.e. mask=[['newreg.txt',[55,55,65,70]],['outliermask.rgn']]), and this function
00520           should be able to parse these properly. - although this won't work for the task execution
00521           by go() and tends to messed up inp() after such execution 
00522  
00523         * Currently it is made to handle old outlier text file format and boxfile-style
00524           mask box specification for backward compartibility. But it is planned to
00525           be removed for 3.4.
00526 
00527         * This is a refactored version of the previous makemultifieldmask2
00528           and  calls makemaskimage() for each field. 
00529           this was called makemultifieldmask3 in CASA 3.3 release but now renamed 
00530           makemultifieldmask2 as the previous makemultifieldmask2 was removed.
00531         """
00532         #print "Inside makemultifieldmask2"
00533         if((len(self.maskimages)==(len(self.imagelist)))):
00534             if(not self.maskimages.has_key(self.imagelist[0])):
00535                 self.maskimages=odict()
00536         else:
00537             self.maskimages=odict()
00538         # clean up temp mask image 
00539         if os.path.exists('__tmp_mask'):
00540            shutil.rmtree('__tmp_mask')
00541       
00542         if (not hasattr(maskobject, '__len__')) \
00543            or (len(maskobject) == 0) or (maskobject == ['']):
00544             return
00545         # for empty maskobject list 
00546         if all([msk==[''] or msk==[] for msk in maskobject]):
00547             return
00548         # determine number of input elements
00549         if (type(maskobject)==str):
00550             maskobject=[maskobject]
00551         if(type(maskobject) != list):
00552             ##don't know what to do with this
00553             raise TypeError, 'Dont know how to deal with maskobject with type: %s' % type(maskobject)
00554         #if(type(maskobject[0])==int or type(maskobject[0])==float):
00555         if(numpy.issubdtype(type(maskobject[0]),int) or numpy.issubdtype(type(maskobject[0]),float)):
00556             maskobject=[maskobject] 
00557         if(type(maskobject[0][0])==list):
00558             #if(type(maskobject[0][0][0])!=int and type(maskobject[0][0][0])!=float):        
00559             if not (numpy.issubdtype(type(maskobject[0][0][0]),int) or \
00560                     numpy.issubdtype(type(maskobject[0][0][0]),float)):        
00561                 maskobject=maskobject[0]
00562                     
00563         # define maskimages
00564         if(len(self.maskimages)==0):
00565             for k in range(len(self.imageids)):
00566                 if(not self.maskimages.has_key(self.imagelist[k])):
00567                     self.maskimages[self.imagelist[k]]=self.imagelist[k]+'.mask'
00568         # initialize maskimages - create empty maskimages
00569         # --- use outframe or dataframe for mask creation
00570         # * It appears somewhat duplicating with makemaskimage 
00571         #   but it is necessary to create a maskimage for
00572         #   each field at this point...      
00573         if self.usespecframe=='': 
00574             maskframe=self.dataspecframe
00575         else:
00576             maskframe=self.usespecframe
00577         #print "Frame : ", maskframe
00578         #print "dataframe : ", self.dataspecframe , "   useframe : ", self.usespecframe
00579         for k in range(len(self.imagelist)):
00580             if(not (os.path.exists(self.maskimages[self.imagelist[k]]))):
00581                 ia.fromimage(outfile=self.maskimages[self.imagelist[k]],
00582                         infile=self.imagelist[k])
00583                 ia.open(self.maskimages[self.imagelist[k]])
00584                 ia.set(pixels=0.0)
00585                 #mcsys=ia.coordsys().torecord()
00586                 #if mcsys['spectral2']['conversion']['system']!=maskframe:
00587                 #    mcsys['spectral2']['conversion']['system']=maskframe
00588                 #ia.setcoordsys(mcsys)
00589                 #
00590                 ## This code to set the maskframe is copied from makemaskimages()
00591                 mycsys=ia.coordsys()
00592                 if mycsys.torecord()['spectral2']['conversion']['system']!=maskframe:
00593                     mycsys.setreferencecode(maskframe,'spectral',True)
00594                 self.csys=mycsys.torecord()
00595                 if self.csys['spectral2']['conversion']['system']!=maskframe:
00596                     self.csys['spectral2']['conversion']['system']=maskframe
00597                 ia.setcoordsys(self.csys)
00598 
00599                 ia.done(verbose=False)
00600 
00601         # take out extra []'s
00602         maskobject=self.flatten(maskobject)
00603         masktext=[]
00604         # to keep backward compatibility for a mixed outlier file
00605         # look for boxfiles contains multiple boxes with image ids
00606         for maskid in range(len(maskobject)):
00607             if type(maskobject[maskid])==str:
00608                 maskobject[maskid] = [maskobject[maskid]]
00609                   
00610             for masklets in maskobject[maskid]:
00611                 if type(masklets)==str:
00612                     if (os.path.exists(masklets) and 
00613                         (not commands.getoutput('file '+masklets).count('directory')) and
00614                         (not commands.getoutput('file '+masklets).split(':')[-1].count('data'))):
00615                            # extract boxfile name
00616                         masktext.append(masklets)
00617 
00618         # === boxfile handling ===
00619         #extract boxfile mask info only for now the rest is
00620         #processed by makemaskimage. - DEPRECATED and will be removed 
00621         #in 3.4
00622         #
00623         #group circles and boxes in dic for each image field 
00624         circles, boxes, oldfmts=self.readmultifieldboxfile(masktext)
00625 
00626         # Loop over imagename
00627         # take out text file names contain multifield boxes and field info  
00628         # from maskobject and create updated one (updatedmaskobject)
00629         # by adding boxlists to it instead.
00630         # Use readmultifieldboxfile to read old outlier/box text file format
00631         # Note: self.imageids and boxes's key are self.imagelist for new outlier
00632         #       format while for the old format, they are 'index' in string.
00633 
00634         #maskobject_tmp = maskobject 
00635         # need to do a deep copy
00636         import copy
00637         maskobject_tmp=copy.deepcopy(maskobject)
00638         updatedmaskobject = [] 
00639         for maskid in range(len(maskobject_tmp)):
00640             if len(circles)!=0 or len(boxes)!=0:
00641                 # remove the boxfiles from maskobject list
00642                 for txtf in masktext:
00643                     if maskobject_tmp[maskid].count(txtf) and oldfmts[txtf]:
00644                         maskobject_tmp[maskid].remove(txtf)
00645                 updatedmaskobject = maskobject_tmp
00646             else:
00647                 updatedmaskobject = maskobject 
00648         # adjust no. of elements of maskoject list with []
00649         if len(updatedmaskobject)-len(self.imagelist)<0:
00650             for k in range(len(self.imagelist)-len(updatedmaskobject)):
00651                 updatedmaskobject.append([])            
00652         #for maskid in range(len(self.maskimages)):
00653 
00654         # === boxfile handling ====
00655         for maskid in self.maskimages.keys(): 
00656             # for handling old format
00657             #if nmaskobj <= maskid:
00658             # add circles,boxes back
00659             maskindx = self.maskimages.keys().index(maskid)
00660             if len(circles) != 0:
00661                 for key in circles:
00662                     if  (newformat and maskid==key) or \
00663                         (not newformat and maskid.split('_')[-1]==key):
00664                         if len(circles[key])==1:
00665                            incircles=circles[key][0]
00666                         else: 
00667                            incircles=circles[key]
00668                         # put in imagelist order
00669                         if len(incircles)>1 and isinstance(incircles[0],list):
00670                             updatedmaskobject[self.imagelist.values().index(maskid)].extend(incircles)
00671                         else:
00672                             updatedmaskobject[self.imagelist.values().index(maskid)].append(incircles)
00673             if len(boxes) != 0:
00674                 for key in boxes:
00675                     #try: 
00676                     #    keyid=int(key)
00677                     #except:
00678                     #    keyid=key
00679                     if  (newformat and maskid==key) or \
00680                         (not newformat and maskid.split('_')[-1]==key):
00681                         if len(boxes[key])==1:
00682                             inboxes=boxes[key][0]
00683                         else: 
00684                             inboxes=boxes[key]
00685                         # add to maskobject (extra list bracket taken out)
00686                         # put in imagelist order
00687                         # take out extra []
00688                         if len(inboxes)>1 and isinstance(inboxes[0],list):
00689                            updatedmaskobject[self.imagelist.values().index(maskid)].extend(inboxes)
00690                         else:
00691                            updatedmaskobject[self.imagelist.values().index(maskid)].append(inboxes)
00692         # === boxfile handling ====
00693 
00694         # do maskimage creation (call makemaskimage)
00695         for maskid in range(len(self.maskimages)):
00696             if maskid < len(updatedmaskobject):
00697                 self._casalog.post("Matched masks: maskid=%s mask=%s" % (maskid, updatedmaskobject[maskid]), 'DEBUG1')
00698                 self.outputmask=''
00699                 self.makemaskimage(outputmask=self.maskimages[self.imagelist[maskid]],
00700                 imagename=self.imagelist[maskid], maskobject=updatedmaskobject[maskid], slice=slice)
00701 #            self._casalog.post("Matched masks: maskid=%s mask=%s" % (maskid, updatedmaskobject[maskid]), 'DEBUG1')
00702 #            self.outputmask=''
00703 #            self.makemaskimage(outputmask=self.maskimages[self.imagelist[maskid]], 
00704 #            imagename=self.imagelist[maskid], maskobject=updatedmaskobject[maskid], slice=slice)
00705 
00706         for key in self.maskimages.keys():
00707             if(os.path.exists(self.maskimages[key])):
00708                 ia.open(self.maskimages[key])
00709                 fsum=ia.statistics(verbose=False)['sum']
00710                 if(len(fsum)!=0 and fsum[0]==0.0):
00711                     # make an empty mask
00712                     ia.set(pixels=0.0)
00713                     # should not remove empty mask for multifield case
00714                     # interactive=F.
00715                     # Otherwise makemaskimage later does not work
00716                     # remove the empty mask
00717                     if not interactive:
00718                         ia.remove()
00719                 ia.done(verbose=False)
00720 
00721 
00722     def make_mask_from_threshhold(self, imagename, thresh, outputmask=None):
00723         """
00724         Makes a mask image with the same coords as imagename where each
00725         pixel is True if and only if the corresponding pixel in imagename
00726         is >= thresh.
00727 
00728         The mask will be named outputmask (if provided) or imagename +
00729         '.thresh_mask'.  The name is returned on success, or False on failure.
00730         """
00731         if not outputmask:
00732             outputmask = imagename + '.thresh_mask'
00733 
00734         # im.mask would be a lot shorter, but it (unnecessarily) needs im to be
00735         # open with an MS.
00736         # I am not convinced that im.mask should really be using Quantity.
00737         # qa.quantity(quantity) = quantity.
00738         self.im.mask(imagename, outputmask, qa.quantity(thresh))
00739         
00740         ## # Copy imagename to a safe name to avoid problems with /, +, -, and ia.
00741         ## ia.open(imagename)
00742         ## shp = ia.shape()
00743         ## ia.close()
00744         ## self.copymaskimage(imagename, shp, '__temp_mask')
00745         
00746         ## self.copymaskimage(imagename, shp, outputmask)
00747         ## ia.open(outputmask)
00748         ## ###getchunk is a mem hog
00749         ## #arr=ia.getchunk()
00750         ## #arr[arr>0.01]=1
00751         ## #ia.putchunk(arr)
00752         ## #inpix="iif("+"'"+outputmask.replace('/','\/')+"'"+">0.01, 1, 0)"
00753         ## #ia.calc(pixels=inpix)
00754         ## ia.calc(pixels="iif(__temp_mask>" + str(thresh) + ", 1, 0)")
00755         ## ia.close()
00756         ## ia.removefile('__temp_mask')
00757         return outputmask
00758         
00759     def makemaskimage(self, outputmask='', imagename='', maskobject=[], slice=-1):
00760         """
00761         This function is an attempt to convert all the kind of 'masks' that
00762         people want to throw at it and convert it to a mask image to be used
00763         by imager...For now 'masks' include
00764         
00765         a)set of previous mask images
00766         b)lists of blc trc's
00767         c)record output from rg tool for e.g
00768 
00769         * for a single field 
00770         """
00771         if (not hasattr(maskobject, '__len__')) \
00772            or (len(maskobject) == 0) or (maskobject == ['']):
00773             return
00774         maskimage=[]
00775         masklist=[]
00776         textreglist=[]
00777         masktext=[]
00778         maskrecord={}
00779         tablerecord=[]
00780         # clean up any left over temp files from previous clean runs
00781         if os.path.exists("__temp_mask"):
00782           shutil.rmtree("__temp_mask")
00783         if os.path.exists("__temp_mask2"):
00784           shutil.rmtree("__temp_mask2")
00785   
00786         # relax to allow list input for imagename 
00787         if(type(imagename)==list):
00788            imagename=imagename[0] 
00789 
00790         if(type(maskobject)==dict):
00791             maskrecord=maskobject
00792             maskobject=[]
00793         if(type(maskobject)==str):
00794             maskobject=[maskobject]
00795         
00796         if(type(maskobject) != list):
00797             ##don't know what to do with this
00798             raise TypeError, 'Dont know how to deal with maskobject'
00799         if(numpy.issubdtype(type(maskobject[0]),numpy.int) or \
00800             numpy.issubdtype(type(maskobject[0]),numpy.float)):
00801             # check and convert if list consist of python int or float  
00802             maskobject_tmp = convert_numpydtype(maskobject)
00803             masklist.append(maskobject_tmp)
00804         else:
00805             for masklets in maskobject:
00806                 if(type(masklets)==str): ## Can be a file name, or an explicit region-string
00807                     if(os.path.exists(masklets)):
00808                         if(commands.getoutput('file '+masklets).count('directory')):
00809                             maskimage.append(masklets)
00810                         elif(commands.getoutput('file '+masklets).count('text')):
00811                             masktext.append(masklets)
00812                         else:
00813                             tablerecord.append(masklets)
00814                     else:
00815                        textreglist.append(masklets);
00816                        #raise TypeError, masklets+' seems to be non-existant' 
00817                 if(type(masklets)==list):
00818                     masklets_tmp = convert_numpydtype(masklets)
00819                     masklist.append(masklets_tmp)
00820                 if(type(masklets)==dict):
00821                     maskrecord=masklets
00822         if(len(outputmask)==0):
00823             outputmask=imagename+'.mask'
00824         if(os.path.exists(outputmask)):
00825             # for multiple field 
00826             # outputmask is always already defined
00827             # cannot use copymaskiamge since self.csys used in the code
00828             # fixed to that of main field
00829             if len(self.imagelist)>1:
00830               ia.fromimage('__temp_mask',outputmask,overwrite=True)
00831               ia.close()        
00832             else:
00833               self.im.make('__temp_mask')    
00834             ia.open('__temp_mask')
00835             shp=ia.shape()
00836             self.csys=ia.coordsys().torecord()
00837             ia.close()
00838             ia.removefile('__temp_mask')
00839             ia.open(outputmask)
00840             outim = ia.regrid(outfile='__temp_mask',shape=shp,axes=[0,1], csys=self.csys,overwrite=True)
00841             outim.done(verbose=False)
00842             ia.done(verbose=False)
00843             ia.removefile(outputmask)
00844             os.rename('__temp_mask',outputmask)
00845         else:
00846             self.im.make(outputmask)
00847             if len(self.imagelist)>1:
00848                 raise Exception, "Multifield case - requires initial mask images but undefined."   
00849 
00850         ia.open(outputmask)
00851         shp=ia.shape()
00852         self.csys=ia.coordsys().torecord()
00853         # keep this info for reading worldbox
00854         self.csysorder=ia.coordsys().coordinatetype()
00855         # respect dataframe or outframe
00856         if self.usespecframe=='': 
00857             maskframe=self.dataspecframe
00858         else:
00859             maskframe=self.usespecframe
00860         if len(self.vis)!=1:
00861             if  not self.inframe:
00862                 # for multi-ms case default output frame is default to LSRK
00863                 # (set by baseframe in imager_cmt.cc) 
00864                 maskframe='LSRK'
00865         mycsys=ia.coordsys()
00866         if mycsys.torecord()['spectral2']['conversion']['system']!=maskframe:
00867             mycsys.setreferencecode(maskframe,'spectral',True)
00868         self.csys=mycsys.torecord()
00869         if self.csys['spectral2']['conversion']['system']!=maskframe:
00870             self.csys['spectral2']['conversion']['system']=maskframe
00871 
00872 
00873         ia.setcoordsys(self.csys)
00874         #ia.setcoordsys(mycsys.torecord())
00875         ia.close()
00876         if(len(maskimage) > 0):
00877             for ima in maskimage :
00878                 if slice>-1:
00879                     self.getchanimage(ima, ima+'chanim',slice)
00880                     self.copymaskimage(ima+'chanim',shp,'__temp_mask')
00881                     ia.removefile(ima+'chanim')
00882                 else:
00883                     self.copymaskimage(ima, shp, '__temp_mask')
00884                 #ia.open(ima)
00885                 #ia.regrid(outfile='__temp_mask',shape=shp,csys=self.csys,
00886                 #          overwrite=True)
00887                 #ia.done(verbose=False)
00888                 os.rename(outputmask,'__temp_mask2')
00889                 outim = ia.imagecalc(outfile=outputmask,
00890                              pixels='__temp_mask + __temp_mask2',
00891                              overwrite=True)
00892                 outim.done(verbose=False)
00893                 ia.done(verbose=False)
00894                 ia.removefile('__temp_mask')
00895                 ia.removefile('__temp_mask2')
00896             if(not os.path.exists(outputmask)):
00897                 outputmask = self.make_mask_from_threshhold(outputmask, 0.01,
00898                                                                   outputmask)
00899         #pdb.set_trace()
00900         #### This goes when those tablerecord goes
00901         ### Make masks from tablerecords
00902         if(len(tablerecord) > 0):
00903             reg={}
00904             for tabl in tablerecord:
00905                 try:
00906                     reg.update({tabl:rg.fromfiletorecord(filename=tabl, verbose=False)})
00907                 except:
00908                     raise Exception,'Region-file (binary) format not recognized. Please check. If box-file, please start the file with \'#boxfile\' on the first line';
00909             if(len(reg)==1):
00910                 reg=reg[reg.keys()[0]]
00911             else:
00912                 reg=rg.makeunion(reg)
00913             self.im.regiontoimagemask(mask=outputmask, region=reg)
00914         ###############
00915         ### Make masks from region dictionaries
00916         if((type(maskrecord)==dict) and (len(maskrecord) > 0)):
00917             self.im.regiontoimagemask(mask=outputmask, region=maskrecord)
00918         ### Make masks from text files
00919         if(len(masktext) >0):
00920             for textfile in masktext :
00921                 # Read a box file
00922                 polydic,listbox=self.readboxfile(textfile);
00923                 masklist.extend(listbox)
00924                 if(len(polydic) > 0):
00925                     ia.open(outputmask)
00926                     ia.close()
00927                     self.im.regiontoimagemask(mask=outputmask, region=polydic)
00928                 # If box lists are empty, it may be a region format
00929                 if(len(polydic)==0 and len(listbox)==0):
00930                     # Read in a region file
00931                     try:
00932                         ia.open(outputmask);
00933                         mcsys = ia.coordsys();
00934                         mshp = ia.shape();
00935                         ia.close();
00936                         mreg = rg.fromtextfile(filename=textfile,shape=mshp,csys=mcsys.torecord());
00937                         self.im.regiontoimagemask(mask=outputmask, region=mreg);
00938                     except:
00939                         raise Exception,'Region-file (text) format not recognized. Please check. If box-file, please start the file with \'#boxfile\' on the first line, and have at-least one valid box in it';
00940         ### Make masks from inline lists of pixel coordinates
00941         if((type(masklist)==list) and (len(masklist) > 0)):
00942             self.im.regiontoimagemask(mask=outputmask, boxes=masklist)
00943         ### Make masks from inline region-strings
00944         if((type(textreglist)==list) and (len(textreglist)>0)):
00945              ia.open(outputmask);
00946              mcsys = ia.coordsys();
00947              mshp = ia.shape();
00948              ia.close();
00949              for textlet in textreglist:
00950                 try:
00951                     mreg = rg.fromtext(text=textlet,shape=mshp,csys=mcsys.torecord());
00952                     self.im.regiontoimagemask(mask=outputmask, region=mreg);
00953                 except:
00954                     raise Exception,'\''+textlet+'\' is not recognized as a text file on disk or as a region string';
00955         ### Make mask from an image-mask
00956         if(os.path.exists(imagename) and (len(rg.namesintable(imagename)) !=0)):
00957             regs=rg.namesintable(imagename)
00958             if(type(regs)==str):
00959                     regs=[regs]
00960             for reg in regs:
00961                 elrec=rg.fromtabletorecord(imagename, reg)
00962                 self.im.regiontoimagemask(mask=outputmask, region=elrec)
00963 
00964         self.outputmask=outputmask
00965 
00966         #Done with making masks
00967 
00968     def datselweightfilter(self, field, spw, timerange, uvrange, antenna,scan,
00969                            wgttype, robust, noise, npixels, mosweight,
00970                            innertaper, outertaper, usescratch, nchan=-1, start=0, width=1):
00971         """
00972         Make data selection 
00973         (not in use, split into datsel and  datweightfileter)
00974         """  
00975         rmode='none'
00976         weighting='natural';
00977         if(wgttype=='briggsabs'):
00978             weighting='briggs'
00979             rmode='abs'
00980         elif(wgttype=='briggs'):
00981             weighting='briggs'
00982             rmode='norm'
00983         else:
00984             weighting=wgttype
00985             
00986         self.fieldindex=ms.msseltoindex(self.vis,field=field)['field'].tolist()
00987         if(len(self.fieldindex)==0):
00988             tb.open(self.vis+'/FIELD')
00989             self.fieldindex=range(tb.nrows())
00990             tb.close()
00991         #weighting and tapering should be done together
00992         if(weighting=='natural'):
00993             mosweight=False
00994         self.im.selectvis(nchan=nchan,start=start,step=width,field=field,spw=spw,time=timerange,
00995                               baseline=antenna, scan=scan, uvrange=uvrange, usescratch=usescratch)
00996         self.im.weight(type=weighting,rmode=rmode,robust=robust, npixels=npixels, noise=qa.quantity(noise,'Jy'), mosaic=mosweight)
00997         if((type(outertaper)==list) and (len(outertaper) > 0)):
00998             if(len(outertaper)==1):
00999                 outertaper.append(outertaper[0])
01000                 outertaper.append('0deg')
01001             if(qa.quantity(outertaper[0])['value'] > 0.0):    
01002                 self.im.filter(type='gaussian', bmaj=outertaper[0],
01003                                bmin=outertaper[1], bpa=outertaper[2])
01004 
01005     
01006     # split version of datselweightfilter
01007     def datsel(self, field, spw, timerange, uvrange, antenna, scan, observation,
01008                            usescratch, nchan=-1, start=0, width=1):
01009         """
01010         Make selections in visibility data 
01011         """ 
01012 
01013         # for multi-MSes, if field,spw,timerage,uvrange,antenna,scan are not
01014         # lists the same selection is applied to all the MSes.
01015         self.fieldindex=[]
01016         #nvislist=range(len(self.vis))
01017         vislist=self.sortedvisindx
01018         self.paramlist={'field':field,'spw':spw,'timerange':timerange,'antenna':antenna,
01019                         'scan':scan, 'observation': observation, 'uvrange':uvrange}
01020         for i in vislist:
01021           selectedparams=self._selectlistinputs(len(vislist),i,self.paramlist)
01022           tempfield=selectedparams['field']
01023 #         if type(field)==list:
01024 #            if len(field)==nvislist:
01025 #              tempfield=field[i]
01026 #            else:
01027 #              if len(field)==1:
01028 #                 tempfield=field[0]
01029 #              else:
01030 #                 raise Exception, 'The number of field list does not match with the number of vis list'
01031 #         else:
01032 #            tempfield=field
01033               
01034           if len(tempfield)==0:
01035             tempfield='*'
01036           self.fieldindex.append(ms.msseltoindex(self.vis[i],field=tempfield)['field'].tolist())
01037 
01038         ############################################################
01039         # Not sure I need this now.... Nov 15, 2010
01040         vislist.reverse()
01041         for i in vislist:
01042           # select apropriate parameters
01043           selectedparams=self._selectlistinputs(len(vislist),i,self.paramlist)
01044           inspw=selectedparams['spw'] 
01045           intimerange=selectedparams['timerange'] 
01046           inantenna=selectedparams['antenna'] 
01047           inscan=selectedparams['scan']
01048           inobs = selectedparams['observation']
01049           inuvrange=selectedparams['uvrange'] 
01050 
01051           if len(self.vis)==1:
01052             #print "single ms case"
01053             self.im.selectvis(nchan=nchan,start=start,step=width,field=field,
01054                               spw=inspw,time=intimerange, baseline=inantenna,
01055                               scan=inscan, observation=inobs, uvrange=inuvrange,
01056                               usescratch=usescratch)
01057           else:
01058             #print "multims case: selectvis for vis[",i,"]: spw,field=", inspw, self.fieldindex[i]
01059             self.im.selectvis(vis=self.vis[i],nchan=nchan,start=start,step=width,
01060                               field=self.fieldindex[i], spw=inspw,time=intimerange,
01061                               baseline=inantenna, scan=inscan,
01062                               uvrange=inuvrange, usescratch=usescratch)
01063 
01064     # private function for datsel and datweightfilter
01065     def _selectlistinputs(self,nvis,indx,params):
01066         """
01067         A little private function to do selection and checking for a parameter 
01068         given in list of strings.
01069         It checks nelement in each param either match with nvis or nelement=1
01070         (or a string) otherwise exception is thrown. 
01071         """
01072         outparams={}
01073         if type(params)==dict:
01074           for param,val in params.items():
01075             msg = 'The number of %s list given in list does not match with the number of vis list given.' % param
01076             if type(val)==list:
01077               if len(val)==nvis:
01078                 outval=val[indx]
01079               else:
01080                 if len(val)==1:
01081                   outval=val[0]
01082                 else:
01083                   raise Exception, msg
01084               outparams[param]=outval
01085             else:
01086               #has to be a string
01087               outparams[param]=val
01088           return outparams
01089         else:
01090           raise Exception, 'params must be a dictionary'
01091  
01092     # weighting/filtering part of datselweightfilter.
01093     # The scan parameter is not actually used, so observation is not included
01094     # as a parameter.  Both are used via self._selectlistinputs().
01095     def datweightfilter(self, field, spw, timerange, uvrange, antenna,scan,
01096                         wgttype, robust, noise, npixels, mosweight,
01097                         uvtaper,innertaper, outertaper, usescratch, nchan=-1, start=0, width=1):
01098         """
01099         Apply weighting and tapering 
01100         """
01101         rmode='none'
01102         weighting='natural';
01103         if(wgttype=='briggsabs'):
01104             weighting='briggs'
01105             rmode='abs'
01106         elif(wgttype=='briggs'):
01107             weighting='briggs'
01108             rmode='norm'
01109         else:
01110             weighting=wgttype
01111          #weighting and tapering should be done together
01112         if(weighting=='natural'):
01113             mosweight=False
01114 #        vislist=self.sortedvisindx
01115         #nvislist.reverse()
01116 #        for i in vislist:
01117 #          # select apropriate parameters
01118 #          selectedparams=self._selectlistinputs(len(vislist),i,self.paramlist)
01119 #          inspw=selectedparams['spw'] 
01120 #          intimerange=selectedparams['timerange'] 
01121 #          inantenna=selectedparams['antenna'] 
01122 #          inscan=selectedparams['scan'] 
01123 #          inobs=selectedparams['observation'] 
01124 #          inuvrange=selectedparams['uvrange'] 
01125 #          
01126 #          if len(self.vis) > 1:
01127 #            print 'from datwtfilter - multi';
01128 #            self.im.selectvis(vis=self.vis[i], field=self.fieldindex[i],spw=inspw,time=intimerange,
01129 #                              baseline=inantenna, scan=inscan, observation=inobs,
01130 #                              uvrange=inuvrange, usescratch=calready)
01131 #          else: 
01132 #            print 'from datwtfilter - single';
01133 #            self.im.selectvis(field=field,spw=inspw,time=intimerange,
01134 #                              baseline=inantenna, scan=inscan, observation=inobs,
01135 #                              uvrange=inuvrange, usescratch=calready)
01136 #          self.im.weight(type=weighting,rmode=rmode,robust=robust, 
01137 #                         npixels=npixels, noise=qa.quantity(noise,'Jy'), mosaic=mosweight)
01138         self.im.weight(type=weighting,rmode=rmode,robust=robust, 
01139                          npixels=npixels, noise=qa.quantity(noise,'Jy'), mosaic=mosweight)
01140      
01141         if((uvtaper==True) and (type(outertaper) in (str, int, float, long))):
01142             outertaper=[outertaper]
01143         if((uvtaper==True) and (type(outertaper)==list) and (len(outertaper) > 0)):
01144             if(len(outertaper)==1):
01145                 outertaper.append(outertaper[0])
01146             if(len(outertaper)==2):
01147                 outertaper.append('0deg')
01148             if(qa.quantity(outertaper[0])['unit']==''):
01149                 outertaper[0]=qa.quantity(qa.quantity(outertaper[0])['value'],'lambda')
01150             if(qa.quantity(outertaper[1])['unit']==''):
01151                 outertaper[1]=qa.quantity(qa.quantity(outertaper[1])['value'],'lambda')
01152             if(qa.quantity(outertaper[0])['value'] > 0.0):
01153                 self.im.filter(type='gaussian', bmaj=outertaper[0],
01154                                bmin=outertaper[1], bpa=outertaper[2])
01155 
01156 
01157     def setrestoringbeam(self, restoringbeam):
01158         """
01159         Set restoring beam
01160         """
01161         if((restoringbeam == ['']) or (len(restoringbeam) ==0)):
01162             return
01163         resbmaj=''
01164         resbmin=''
01165         resbpa='0deg'
01166         if((type(restoringbeam) == list)  and len(restoringbeam)==1):
01167             restoringbeam=restoringbeam[0]
01168         if((type(restoringbeam)==str)):
01169             if(qa.quantity(restoringbeam)['unit'] == ''):
01170                 restoringbeam=restoringbeam+'arcsec'
01171             resbmaj=qa.quantity(restoringbeam, 'arcsec')
01172             resbmin=qa.quantity(restoringbeam, 'arcsec')
01173         if(type(restoringbeam)==list):                  
01174             resbmaj=qa.quantity(restoringbeam[0], 'arcsec')
01175             resbmin=qa.quantity(restoringbeam[1], 'arcsec')
01176             if(resbmaj['unit']==''):
01177                 resbmaj=restoringbeam[0]+'arcsec'
01178             if(resbmin['unit']==''):
01179                 resbmin=restoringbeam[1]+'arcsec'
01180             if(len(restoringbeam)==3):
01181                 resbpa=qa.quantity(restoringbeam[2], 'deg')
01182                 if(resbpa['unit']==''):
01183                     resbpa=restoringbeam[2]+'deg'
01184         if((resbmaj != '') and (resbmin != '')):
01185            self.im.setbeam(bmaj=resbmaj, bmin=resbmin, bpa=resbpa)
01186         
01187     def convertmodelimage(self, modelimages=[], outputmodel='',imindex=0):
01188         """
01189         Convert model inputs to a model image
01190 
01191         Keyword arguments:
01192         modleimages -- input model list
01193         outputmodel -- outout modelimage name
01194         imindex     -- image name index (corresponding to imagelist) 
01195                        for multi field hanlding
01196         """
01197         modelos=[]
01198         maskelos=[]
01199         if((modelimages=='') or (modelimages==[]) or (modelimages==[''])):
01200         #if((modelimages=='') or (modelimages==[])):
01201             return
01202         if(type(modelimages)==str):
01203             modelimages=[modelimages]
01204         k=0
01205         for modim in modelimages:
01206             if not os.path.exists(modim):
01207                 raise Exception, "Model image file name="+modim+" does not exist."
01208 
01209             ia.open(modim)
01210             modelosname='modelos_'+str(k) 
01211 
01212             # clean up any temp files left from preveous incomplete run
01213             if os.path.exists(modelosname):
01214                 ia.removefile(modelosname)
01215             if os.path.exists('__temp_model2'):
01216                 ia.removefile('__temp_model2')
01217 
01218             modelos.append(modelosname)
01219 
01220             
01221             if( (ia.brightnessunit().count('/beam')) > 0):
01222                 ##single dish-style model
01223                 maskelos.append(modelos[k]+'.sdmask')
01224                 self.im.makemodelfromsd(sdimage=modim,modelimage=modelos[k],maskimage=maskelos[k])
01225                 ia.open(maskelos[k])
01226                 ##sd mask cover whole image...delete it as it is not needed
01227                 if((ia.statistics(verbose=False)['min']) >0):
01228                     ia.remove(done=True, verbose=False)
01229                     maskelos.remove(maskelos[k])
01230                 ia.done()
01231             else:
01232                 ##assuming its a model image already then just regrid it
01233                 #self.im.make(modelos[k])
01234                 shutil.copytree(self.imagelist[imindex],modelos[k])
01235                 ia.open(modelos[k])
01236                 newcsys=ia.coordsys()
01237                 newshape=ia.shape()
01238                 ia.open(modim)
01239                 ib=ia.regrid(outfile=modelos[k], shape=newshape, axes=[0,1,3], csys=newcsys.torecord(), overwrite=True)
01240                 ib.done(verbose=False)
01241                 
01242             k=k+1
01243             if ia.isopen(): ia.close()
01244         #########
01245         if((len(maskelos)==1) and  (self.outputmask == '')):
01246             self.outputmask=modelimages[0]+'.mask'
01247             if(os.path.exists(self.outputmask)):
01248                 ia.removefile(self.outputmask)
01249             os.rename(maskelos[0],self.outputmask)
01250         elif(len(maskelos) > 0):
01251             if(self.outputmask == ''):
01252                 self.outputmask=modelimages[0]+'.mask'
01253                 
01254             else:
01255                 outputmask=self.outputmask
01256             ##okay if outputmask exists then we need to do an "and" with
01257             ##the sdmask one
01258             doAnd=False;
01259             if(os.path.exists(outputmask)):
01260                 ia.open(outputmask)
01261                 if((ia.statistics(verbose=False)['max'].max()) > 0.00001):
01262                     doAnd=True
01263                 ia.close()
01264             if(doAnd):
01265                 tmpomask='__temp_o_mask'
01266                 self.makemaskimage(outputmask=tmpomask, maskobject=maskelos)
01267                 os.rename(outputmask, '__temp_i_mask')
01268                 outim = ia.imagecalc(outfile=outputmask, pixels='__temp_o_mask * __temp_i_mask', overwrite=True)
01269                 outim.done(verbose=False)
01270                 ia.removefile('__temp_o_mask')
01271                 ia.removefile('__temp_i_mask')
01272                 self.outputmask=outputmask
01273             else:
01274                 self.makemaskimage(outputmask=outputmask, maskobject=maskelos)
01275         for ima in maskelos:
01276             if(os.path.exists(ima)):
01277                 ia.removefile(ima)
01278         if(not (os.path.exists(outputmodel))):
01279             # im.make uses the main field coord. so it does
01280             # not make correct coord. for outlier fields
01281             if len(self.imagelist)>1:
01282                ia.fromimage(outputmodel, self.imagelist[imindex])
01283             else:
01284                self.im.make(outputmodel)
01285         #ia.open(outputmodel)
01286         #ia.close()
01287         for k in range(len(modelos)):
01288             # if os.rename() or shutil.move() is used here,
01289             # for k=1 and at image.imagecalc, it seems to cause 
01290             # casapy to crash... 
01291             #os.rename(outputmodel,'__temp_model2')
01292             shutil.copytree(outputmodel,'__temp_model2')
01293             
01294             outim = ia.imagecalc(outfile=outputmodel,
01295                              pixels=modelos[k]+' + '+'__temp_model2',
01296                              overwrite=True)
01297             outim.done(verbose=False)
01298             ia.removefile('__temp_model2')
01299             ia.removefile(modelos[k]);
01300     
01301     def readboxfile(self, boxfile):
01302         """ Read a file containing clean boxes (compliant with AIPS BOXFILE)
01303 
01304         Format is:
01305         #FIELDID BLC-X BLC-Y TRC-X TRC-Y
01306         0       110   110   150   150 
01307         or
01308         0       hh:mm:ss.s dd.mm.ss.s hh:mm:ss.s dd.mm.ss.s
01309         
01310         Note all lines beginning with '#' are ignored.
01311         
01312         """
01313         union=[]
01314         polyg={}
01315         f=open(boxfile)
01316         temprec={}
01317         counter=0
01318         while 1:
01319             try:
01320                 counter=counter+1
01321                 line=f.readline()
01322                 if(len(line)==0):
01323                     raise Exception
01324                 if (line.find('#')!=0):
01325                     if(line.count('[')==2):
01326                         ##its an output from qtclean
01327                         line=line.replace('\n','')
01328                         line=line.replace('\t',' ')
01329                         line=line.replace('[',' ')
01330                         line=line.replace(']',' ')
01331                         line=line.replace(',',' ')
01332                         splitline=line.split()
01333                         if(len(splitline)==5):
01334                             ##its box
01335                             if(int(splitline[4]) > 0):
01336                                 ##it was a "mask" region not "erase"
01337                                 boxlist=[int(splitline[0]),int(splitline[1]),
01338                                          int(splitline[2]),int(splitline[3])]
01339                                 union.append(boxlist)
01340                         else:
01341                             #its a polygon
01342                             x=[]
01343                             y=[]
01344                             if(int(splitline[len(splitline)-1]) > 0):
01345                                 ###ignore erase regions
01346                                 nnodes=(len(splitline)-1)/2
01347                                 for kk in range(nnodes):
01348                                     x.append(splitline[kk]+'pix')
01349                                     y.append(splitline[kk+nnodes]+'pix')
01350                                 elreg=rg.wpolygon(x=x, y=y, csys=self.csys)
01351                                 temprec.update({counter:elreg})
01352                                 
01353                     elif(line.count('worldbox')==1): 
01354                         #ascii box file from viewer or boxit
01355                         # expected foramt: 'worldbox' pos_ref [lat
01356                         line=line.replace('[',' ')
01357                         line=line.replace(']',' ')
01358                         line=line.replace(',',' ')
01359                         line=line.replace('\'',' ')
01360                         splitline=line.split() 
01361                         if len(splitline) != 13:
01362                            raise TypeError, 'Error reading worldbox file'      
01363                         #
01364                         refframe=self.csys['direction0']['conversionSystem']
01365                         if refframe.find('_VLA')>0:
01366                           refframe=refframe[0:refframe.find('_VLA')]
01367                         ra =[splitline[2],splitline[3]]
01368                         dec = [splitline[4],splitline[5]]
01369                         #set frames
01370                         obsdate=self.csys['obsdate']
01371                         me.doframe(me.epoch(obsdate['refer'], str(obsdate['m0']['value'])+obsdate['m0']['unit']))
01372                         me.doframe(me.observatory(self.csys['telescope']))
01373                         #
01374                         if splitline[1]!=refframe: 
01375                             # coversion between different epoch (and to/from AZEL also)
01376                             radec0 = me.measure(me.direction(splitline[1],ra[0],dec[0]), refframe)
01377                             radec1 = me.measure(me.direction(splitline[1],ra[1],dec[1]), refframe) 
01378                             ra=[str(radec0['m0']['value'])+radec0['m0']['unit'],\
01379                                 str(radec1['m0']['value'])+radec1['m0']['unit']]
01380                             dec=[str(radec0['m1']['value'])+radec0['m1']['unit'],\
01381                                  str(radec1['m1']['value'])+radec1['m1']['unit']]
01382                         # check for stokes 
01383                         stokes=[]
01384                         imstokes = self.csys['stokes1']['stokes']
01385                         for st in [splitline[10],splitline[11]]:
01386                             prevlen = len(stokes)
01387                             for i in range(len(imstokes)):
01388                                 if st==imstokes[i]:
01389                                     stokes.append(str(i)+'pix')
01390                                 elif st.count('pix') > 0:
01391                                     stokes.append(st)
01392                             if len(stokes)<=prevlen:
01393                                 #raise TypeError, "Stokes %s for the box boundaries is outside image" % st              
01394                                 self._casalog.post('Stokes %s for the box boundaries is outside image, -ignored' % st, 'WARN')              
01395                         # frequency
01396                         freqs=[splitline[7].replace('s-1','Hz'), splitline[9].replace('s-1','Hz')]
01397                         fframes=[splitline[6],splitline[8]]
01398                         imframe = self.csys['spectral2']['system']
01399                         # the worldbox file created viewer's "box in file"
01400                         # currently says TOPO in frequency axis but seems to
01401                         # wrong (the freuencies look like in the image's base
01402                         # frame). 
01403                         for k in [0,1]:
01404                             if fframes[k]!=imframe and freqs[k].count('pix')==0:
01405                                 #do frame conversion
01406                                 #self._casalog.post('Ignoring the frequency frame of the box for now', 'WARN')              
01407                                 # uncomment the following when box file correctly labeled the frequency frame
01408                                 me.doframe(me.direction(splitline[1],ra[k],dec[k]))
01409                                 mf=me.measure(me.frequency(fframes[k],freqs[k]),imframe)
01410                                 freqs[k]=str(mf['m0']['value'])+mf['m0']['unit']
01411                         coordorder=self.csysorder
01412                         wblc = []
01413                         wtrc = []
01414                         for type in coordorder:
01415                           if type=='Direction':
01416                              wblc.append(ra[0])
01417                              wblc.append(dec[0])
01418                              wtrc.append(ra[1])
01419                              wtrc.append(dec[1])     
01420                           if type=='Stokes':
01421                              wblc.append(stokes[0])
01422                              wtrc.append(stokes[1])
01423                           if type=='Spectral':
01424                              wblc.append(freqs[0])
01425                              wtrc.append(freqs[1])
01426 
01427                         #wblc = [ra[0], dec[0], stokes[0], freqs[0]]
01428                         #wtrc = [ra[1], dec[1], stokes[1], freqs[1]]
01429                         #wblc = ra[0]+" "+dec[0]
01430                         #wtrc = ra[1]+" "+dec[1]
01431                         wboxreg = rg.wbox(blc=wblc,trc=wtrc,csys=self.csys)
01432                         temprec.update({counter:wboxreg})
01433  
01434                     else:
01435                         ### its an AIPS boxfile
01436                         splitline=line.split('\n')
01437                         splitline2=splitline[0].split()
01438                         if (len(splitline2)<6):
01439                             if(int(splitline2[1])<0):
01440                                 ##circle
01441                                 #circlelist=[int(splitline2[2]),
01442                                 #     int(splitline2[3]),int(splitline2[4])]
01443                                 #circles[splitline2[0]].append(circlelist)
01444                                 continue
01445                             else:
01446                                 boxlist=[int(splitline2[1]),int(splitline2[2]),
01447                                          int(splitline2[3]),int(splitline2[4])]
01448                                 union.append(boxlist)
01449                         else:
01450                            ## Don't know what that is
01451                            ## might be a facet definition 
01452                            continue
01453     
01454             except:
01455                 break
01456 
01457         f.close()
01458         if(len(temprec)==1):
01459             polyg=temprec[temprec.keys()[0]]
01460         elif (len(temprec) > 1):
01461             #polyg=rg.dounion(temprec)
01462             polyg=rg.makeunion(temprec)
01463         
01464         return polyg,union
01465 
01466     def readmultifieldboxfile(self, boxfiles):
01467         """ 
01468         Read boxes and circles in text files in the 
01469         AIPS clean boxfile format.
01470 
01471         Keyword arguments:
01472         boxfiles -- text files in boxfile format
01473 
01474         returns:
01475         circles -- dictionary containing circles      
01476         boxes   -- dictionary conatining boxes ([blc, trc])
01477         oldfileformats -- a list of boolean if the input textfiles
01478                    are boxfile format. 
01479         """  
01480         circles={}
01481         boxes={}
01482         oldfilefmts={}
01483         for k in range(len(self.imageids)):
01484             circles[self.imageids[k]]=[]
01485             boxes[self.imageids[k]]=[]
01486         for boxfile in boxfiles:
01487             f=open(boxfile)
01488             setonce=False
01489             oldfilefmts[boxfile]=False
01490             while 1:
01491                 try:
01492                     line=f.readline()
01493                     if(len(line)==0):
01494                         raise Exception
01495                     if line.find('#')==0:
01496                         if not setonce and line.find('boxfile')>0:
01497                             oldfilefmts[boxfile]=True
01498                             setonce=True
01499                             self._casalog.post(boxfile+" is in a deprecated boxfile format,"+\
01500                                 " will not be supported in the future releases","WARN")
01501                             #raise Exception
01502                     else:
01503                         ### its an AIPS boxfile
01504                         splitline=line.split('\n')
01505                         splitline2=splitline[0].split()
01506                         if (len(splitline2)<6):
01507                             ##circles
01508                             if(int(splitline2[1]) <0):
01509                                 circlelist=[int(splitline2[2]),
01510                                             int(splitline2[3]),int(splitline2[4])]
01511                                 #circles[splitline2[0]].append(circlelist)
01512                                 circles[self.imageids[int(splitline2[0])]].append(circlelist)
01513                             else:
01514                                 #boxes
01515                                 if(len(splitline2)==5):
01516                                    boxlist=[int(splitline2[1]),int(splitline2[2]),
01517                                             int(splitline2[3]),int(splitline2[4])]
01518                                    #boxes[splitline2[0]].append(boxlist)
01519                                    boxes[self.imageids[int(splitline2[0])]].append(boxlist)
01520                         else:
01521                            ## Don't know what that is
01522                            ## might be a facet definition 
01523                             continue
01524     
01525                        
01526     
01527                 except:
01528                     break
01529 
01530             f.close()
01531         ###clean up the records
01532         for k in range(len(self.imageids)):
01533             if(circles[self.imageids[k]]==[]):
01534                 circles.pop(self.imageids[k])
01535             if(boxes[self.imageids[k]]==[]):
01536                 boxes.pop(self.imageids[k])
01537                 
01538         return circles,boxes,oldfilefmts
01539 
01540 
01541     def readoutlier(self, outlierfile):
01542         """ Read a file containing clean boxes (kind of
01543         compliant with AIPS FACET FILE)
01544                     
01545         Format is:
01546          col0    col1   col2  col3 col4 col5 col6 col7  col8   col9
01547           C    FIELDID SIZEX SIZEY RAHH RAMM RASS DECDD DECMM DECSS      
01548         why first column has to have C ... because its should
01549         not to be A or B ...now D would be a totally different thing.
01550         
01551         'C' as in AIPS BOXFILE format indicates the file specify the coordiates
01552         for field center(s). 
01553 
01554         Note all lines beginning with '#' are ignored.
01555         (* Lines with first column other than C or c are also ignored)
01556         
01557         """
01558         imsizes=[]
01559         phasecenters=[]
01560         imageids=[]
01561         f=open(outlierfile)
01562         while 1:
01563             try:
01564                 line=f.readline()
01565                     
01566                 if(len(line)==0):
01567                     raise Exception
01568                 if (line.find('#')!=0):
01569                     splitline=line.split('\n')
01570                     splitline2=splitline[0].split()
01571                     if (len(splitline2)==10):
01572                         if(splitline2[0].upper()=='C'):
01573                             imageids.append(splitline2[1])
01574                             imsizes.append((int(splitline2[2]),int(splitline2[3])))
01575                             mydir='J2000  '+splitline2[4]+'h'+splitline2[5]+'m'+splitline2[6]+'  '+splitline2[7]+'d'+splitline2[8]+'m'+splitline2[9]
01576                             phasecenters.append(mydir)
01577     
01578             except:
01579                 break
01580 
01581         f.close()
01582         return imsizes,phasecenters,imageids
01583 
01584     def newreadoutlier(self, outlierfile): 
01585         """
01586         Read a outlier file (both old and new format) 
01587          
01588         The new format consists of a set of task parameter inputs.
01589         imagename="outlier1" imsize=[128,128] phasecenter="J2000 hhmmss.s ddmmss.s" 
01590         imagename="outlier2" imsize=[128,128] phasecenter="J2000 hhmmss.s ddmmss.s"
01591         mask=['viewermask.rgn','box[[50,60],[50,60]]'] ...
01592 
01593         Currently supported paramters are:
01594         imagename (required: used to delinate a paramater set for each field)
01595         imsize (required)
01596         phasecenter (required)
01597         mask (optional)
01598         modelimage (optional) 
01599         * other parameters can be included in the file but not parsed
01600 
01601         For the old format, readoutlier() is called internally currently. But
01602         the support will be removed by CASA3.4. 
01603 
01604         Returns:
01605         lists of imageids, imsizes, phasecenters, masks, 
01606         and modelimages, and a dictionary contains all the parameters,
01607         and a boolean to indicate read file is in the new format. 
01608         """
01609         import ast
01610         import re
01611 
01612         imsizes=[]
01613         phasecenters=[]
01614         imageids=[]
01615         masks=[]
01616         modelimages=[]
01617         keywd = "imagename"
01618         oldformat=False
01619         nchar= len(keywd)
01620         content0=''
01621         # set this to True to disallow old outlier file
01622         noOldOutlierFileSupport=False;
01623 
01624         with open(outlierfile) as f:  
01625             for line in f:
01626                 try:
01627                     if len(line)!=0 and line.split()!=[]:
01628                         if line.split()[0]=='C' or line.split()[0]=='c':
01629                             oldformat=True
01630                         elif line.split()[0]!='#':
01631                             content0+=line     
01632                 except:
01633                     print "Unkown error while reading the file", outlierfile
01634                     break
01635         if oldformat:
01636             if noOldOutlierFileSupport:
01637                 self._casalog.post("You are using the old outlier file format no longer supported. Please use the new format (see help).","SEVERE")
01638                 raise Exception
01639             else:
01640                 self._casalog.post("This file format is deprecated. Use of a new format is encouraged.","WARN")
01641                 # do old to new data format conversion....(watch out for different order of return parameters...)
01642                 (imsizes,phasecenters,imageids)=self.readoutlier(outlierfile)
01643                 for i in range(len(imageids)):
01644                     modelimages.append('')
01645         #f.seek(0)
01646         #content0 = f.read()
01647         #f.close()
01648         content=content0.replace('\n',' ')
01649         last = len(content)
01650         # split the content using imagename as a key 
01651         # and store each parameter set in pars dict
01652         pars={}
01653         initi = content.find(keywd)
01654         if initi > -1:
01655             i = 0
01656             prevstart=initi
01657             while True:
01658                 step = nchar*(i+1)
01659                 start = prevstart+step
01660                 nexti = content[start:].find(keywd)
01661                 #print "look at start=",start, " nexti=",nexti, " step=",step, " prevstart=",prevstart
01662 
01663                 if nexti == -1:
01664                     pars[i]=content[prevstart:]
01665                 #    print "range=",prevstart, " to the end"
01666                     break
01667                 pars[i]=content[prevstart:prevstart+nexti+step]
01668                 #print "range=",prevstart, " to", prevstart+nexti+step-1
01669                 prevstart=prevstart+nexti+step
01670                 i+=1
01671 
01672         # for parsing of indiviual par (per field)
01673         #print "pars=",pars
01674         dparm ={}
01675         indx=0
01676         for key in pars.keys():
01677             # do parsing
01678             parstr = pars[key]
01679             # clean up extra white spaces
01680             parm=' '.join(parstr.split())
01681             # more clean up
01682             parm=parm.replace("[ ","[")
01683             parm=parm.replace(" ]","]")
01684             parm=parm.replace(" ,",",")
01685             parm=parm.replace(", ",",")
01686             parm=parm.replace(" =","=")
01687             parm=parm.replace("= ","=")
01688             #print "parm=",parm
01689             subdic={}
01690             # final parameter sets 
01691             values=re.compile('\w+=').split(parm)
01692             values=values[1:len(values)]
01693            
01694             ipar = 0 
01695             for pv in parm.split():
01696                 if pv.find('=') != -1:
01697                     if ipar >= len(values):
01698                         raise Exception, TypeError("mismath in no. parameters in parsing outlier file.")
01699                     (k,v) = pv.split('=')
01700                     # fix a string to proper litral value
01701                     # take out any commas at end which will
01702                     # confuse literal_eval function
01703                     pat = re.compile(',+$')
01704                     subdic[k]=ast.literal_eval(pat.sub('',values[ipar]))
01705                     ipar += 1
01706             dparm[indx]=subdic
01707             indx+=1
01708         #print "DONE for parsing parm for each field"
01709         # put into list of parameters
01710         # imsizes, phasecenters, imagenames(imageids)
01711         # mask is passed to other function for forther processing
01712         if not oldformat:
01713             #pack them by parameter name
01714             for fld in dparm.keys():
01715                 # before process, check if it contains all required keys
01716                 # namely, imagename, phasecenter, imsize
01717                 #print "dparm[",fld,"]=",dparm[fld]
01718                 if not (dparm[fld].has_key("imagename") and\
01719                         dparm[fld].has_key("phasecenter") and\
01720                         dparm[fld].has_key("imsize")):
01721                     raise Exception, TypeError("Missing one or more of the required parameters: \
01722                      imagename, phasecenter, and imsize in the outlier file. Please check the input outlier file.") 
01723                 for key in dparm[fld].keys():  
01724                     if key == "imagename":
01725                         imageids.append(dparm[fld][key])
01726                     if key == "phasecenter":
01727                         phasecenters.append(dparm[fld][key])
01728                     if key == "imsize":
01729                         imsizes.append(dparm[fld][key])
01730                     if key == "mask":
01731                         if type(dparm[fld][key])==str:
01732                             masks.append([dparm[fld][key]])
01733                         else:
01734                             masks.append(dparm[fld][key])
01735                     if key == "modelimage":
01736                         if type(dparm[fld][key])==str:
01737                             modelimages.append([dparm[fld][key]])
01738                         else:
01739                             modelimages.append(dparm[fld][key])
01740                 if not dparm[fld].has_key("mask"):
01741                     masks.append([])
01742                 if not dparm[fld].has_key("modelimage"):
01743                     modelimages.append('')
01744                 
01745                  
01746         return (imageids,imsizes,phasecenters,masks,modelimages,dparm, not oldformat) 
01747 
01748 
01749     def copymaskimage(self, maskimage, shp, outfile):
01750         """
01751         Copy mask image
01752         
01753         Keyword arguments:
01754         maskimage -- input maskimage 
01755         shp       -- shape of output image 
01756         outfile   -- output image name
01757         """
01758         if outfile == maskimage:     # Make it a no-op,
01759             return                   # this is more than just peace of mind.
01760         #pdb.set_trace() 
01761         ia.open(maskimage)
01762         oldshp=ia.shape()
01763         if((len(oldshp) < 4) or (shp[2] != oldshp[2]) or (shp[3] != oldshp[3])):
01764             #take the first plane of mask
01765             tmpshp=oldshp
01766             tmpshp[0]=shp[0]
01767             tmpshp[1]=shp[1]
01768             if len(oldshp)==4: # include spectral axis for regrid
01769               tmpshp[3]=shp[3]
01770               ib=ia.regrid(outfile='__looloo', shape=tmpshp, axes=[0,1,3], csys=self.csys, overwrite=True)
01771             else:
01772               ib=ia.regrid(outfile='__looloo', shape=tmpshp, axes=[0,1], csys=self.csys, overwrite=True)
01773 
01774             #dat=ib.getchunk()
01775             ib.done(verbose=False)
01776             ia.fromshape(outfile=outfile, shape=shp, csys=self.csys, overwrite=True)
01777             ##getchunk is a massive memory hog
01778             ###so going round in a funny fashion
01779             #arr=ia.getchunk()
01780             #for k in range(shp[2]):
01781             #    for j in range(shp[3]):
01782             #        if(len(dat.shape)==2):
01783             #            arr[:,:,k,j]=dat
01784             #        elif(len(dat.shape)==3):
01785             #            arr[:,:,k,j]=dat[:,:,0]
01786             #        else:
01787             #            arr[:,:,k,j]=dat[:,:,0,0]
01788             #ia.putchunk(arr)
01789             ia.calc(outfile+'[index3 in [0]]+__looloo') 
01790             ia.calcmask('mask(__looloo)')
01791             ia.done(verbose=False)
01792             ia.removefile('__looloo')
01793         else:
01794             ib=ia.regrid(outfile=outfile ,shape=shp, axes=[0,1], csys=self.csys, overwrite=True)
01795             ia.done(verbose=False)
01796             ib.done(verbose=False)
01797 
01798 
01799     def flatten(self,l):
01800         """
01801         A utility function to flatten nested lists 
01802         but allow nesting of [[elm1,elm2,elm3],[elm4,elm5],[elm6,elm7]]
01803         to handle multifield masks.
01804         This does not flatten if an element is a list of int or float. 
01805         And also leave empty list as is.
01806         """ 
01807         retlist = []
01808         l = list(l)
01809         #print 'l=',l
01810         for i in range(len(l)):
01811             #print "ith l=",i, l[i] 
01812             if isinstance(l[i],list) and l[i]:
01813                 # and (not isinstance(l[i][0],(int,float))):
01814                 #print "recursive l=",l
01815                 if isinstance(l[i][0],list) and isinstance(l[i][0][0],list):
01816                    retlist.extend(self.flatten(l[i]))
01817                 else:
01818                    retlist.append(l[i])
01819             else:
01820                 retlist.append(l[i])
01821         return retlist 
01822 
01823     def getchanimage(self,cubeimage,outim,chan):
01824         """
01825         Create a slice of channel image from cubeimage
01826 
01827         Keyword arguments:
01828         cubeimage -- input image cube
01829         outim     -- output sliced image
01830         chan      -- nth channel
01831         """
01832         #pdb.set_trace()
01833         ia.open(cubeimage)
01834         modshape=ia.shape()
01835         if modshape[3]==1:
01836           return False
01837         if modshape[3]-1 < chan:
01838           return False
01839         blc=[0,0,modshape[2]-1,chan]
01840         trc=[modshape[0]-1,modshape[1]-1,modshape[2]-1,chan]
01841         sbim=ia.subimage(outfile=outim, region=rg.box(blc,trc), overwrite=True)
01842         sbim.close()
01843         ia.close()
01844         return True
01845 
01846     def putchanimage(self,cubimage,inim,chan):
01847         """
01848         Put channel image back to a pre-exisiting cubeimage
01849  
01850         Keyword arguments:
01851         cubimage -- image cube
01852         inim     -- input channel image 
01853         chan     -- nth channel
01854         """
01855         ia.open(inim)
01856         inimshape=ia.shape()
01857         imdata=ia.getchunk()
01858         immask=ia.getchunk(getmask=True)
01859         ia.close()
01860         blc=[0,0,inimshape[2]-1,chan]
01861         trc=[inimshape[0]-1,inimshape[1]-1,inimshape[2]-1,chan]
01862         ia.open(cubimage)
01863         cubeshape=ia.shape()
01864         if not (cubeshape[3] > (chan+inimshape[3]-1)):
01865             return False
01866         rg0=ia.setboxregion(blc=blc,trc=trc)
01867         if inimshape[0:3]!=cubeshape[0:3]: 
01868             return False
01869         #ia.putchunk(pixels=imdata,blc=blc)
01870         ia.putregion(pixels=imdata,pixelmask=immask, region=rg0)
01871         ia.close()
01872         return True
01873 
01874     def qatostring(self,q):
01875         """
01876         A utility function to return a quantity in string
01877         (currently only used in setChannelization which is deprecated)
01878         """
01879         if not q.has_key('unit'):
01880             raise TypeError, "Does not seems to be quantity"
01881         return str(q['value'])+q['unit']
01882 
01883     def convertvf(self,vf,frame,field,restf,veltype='radio'):
01884         """
01885         returns doppler(velocity) or frequency in string
01886         currently use first rest frequency
01887         Assume input vf (velocity or fequency in a string) and 
01888         output are the same 'frame'.
01889         """
01890         #pdb.set_trace()
01891         docalcf=False
01892         #if(frame==''): frame='LSRK' 
01893         #Use datasepcframe, it is cleanhelper initialized to set
01894         #to LSRK
01895         if(frame==''): frame=self.dataspecframe
01896         if(qa.quantity(vf)['unit'].find('m/s') > -1):
01897             docalcf=True
01898         elif(qa.quantity(vf)['unit'].find('Hz') > -1):
01899             docalcf=False
01900         else:
01901             if vf !=0:
01902                 raise TypeError, "Unrecognized unit for the velocity or frequency parameter"
01903         ##fldinds=ms.msseltoindex(self.vis, field=field)['field'].tolist()
01904         fldinds=ms.msseltoindex(self.vis[self.sortedvisindx[0]], field=field)['field'].tolist()
01905         if(len(fldinds) == 0):
01906             fldid0=0
01907         else:
01908             fldid0=fldinds[0]
01909         if restf=='':
01910             #tb.open(self.vis+'/FIELD')
01911             tb.open(self.vis[self.sortedvisindx[0]]+'/FIELD')
01912             nfld = tb.nrows()
01913             if nfld >= fldid0:
01914               srcid=tb.getcell('SOURCE_ID',fldid0)
01915             else:
01916               raise TypeError, ("Cannot set REST_FREQUENCY from the data: "+
01917                   "no SOURCE corresponding field ID=%s, please supply restfreq" % fldid0)
01918             tb.close()
01919             # SOUECE_ID in FIELD table = -1 if no SOURCE table
01920             if srcid==-1:
01921                 raise TypeError, "Rest frequency info is not supplied"
01922             #tb.open(self.vis+'/SOURCE')
01923             tb.open(self.vis[self.sortedvisindx[0]]+'/SOURCE')
01924             tb2=tb.query('SOURCE_ID==%s' % srcid)
01925             tb.close()
01926             nsrc = tb2.nrows()
01927             if nsrc > 0:
01928               rfreq=tb2.getcell('REST_FREQUENCY',0)
01929             else:
01930               raise TypeError, ("Cannot set REST_FREQUENCY from the data: "+
01931                    " no SOURCE corresponding field ID=%s, please supply restfreq" % fldid0)
01932             tb2.close()
01933             if(rfreq<=0):
01934                 raise TypeError, "Rest frequency does not seems to be properly set, check the data"
01935         else:
01936             if type(restf)==str: restf=[restf]
01937             if(qa.quantity(restf[0])['unit'].find('Hz') > -1):
01938                 rfreq=[qa.convert(qa.quantity(restf[0]),'Hz')['value']] 
01939                 #print "using user input rest freq=",rfreq
01940             else:
01941                 raise TypeError, "Unrecognized unit or type for restfreq"
01942         if(vf==0):
01943             # assume just want to get a restfrequecy from the data
01944             ret=str(rfreq[0])+'Hz'
01945         else:
01946             if(docalcf):
01947                 dop=me.doppler(veltype, qa.quantity(vf)) 
01948                 rvf=me.tofrequency(frame, dop, qa.quantity(rfreq[0],'Hz'))
01949             else:
01950                 frq=me.frequency(frame, qa.quantity(vf))
01951                 rvf=me.todoppler(veltype, frq, qa.quantity(rfreq[0],'Hz')) 
01952             ret=str(rvf['m0']['value'])+rvf['m0']['unit']
01953         return ret 
01954 
01955 
01956     def getfreqs(self,nchan,spw,start,width, dummy=False):
01957         """
01958         (not in used - currently commented out in its caller, initChaniter()) 
01959         returns a list of frequencies to be used in output clean image
01960         if width = -1, start is actually end (max) freq 
01961         """
01962         #pdb.set_trace()
01963         freqlist=[]
01964         finc=1
01965         loc_nchan=0
01966 
01967         if spw in (-1, '-1', '*', '', ' '):
01968             spwinds = -1
01969         else:
01970             #spwinds=ms.msseltoindex(self.vis, spw=spw)['spw'].tolist()
01971             spwinds=ms.msseltoindex(self.vis[self.sortedvisindx[0]], spw=spw)['spw'].tolist()
01972             if(len(spwinds) == 0):
01973                 spwinds = -1
01974 
01975         if(spwinds==-1):
01976             # first row
01977             spw0=0
01978         else:
01979             spw0=spwinds[0]
01980         #tb.open(self.vis+'/SPECTRAL_WINDOW')
01981         spectable=self.getspwtable(self.vis[self.sortedvisindx[0]])
01982         tb.open(spectable)
01983         chanfreqscol=tb.getvarcol('CHAN_FREQ')
01984         chanwidcol=tb.getvarcol('CHAN_WIDTH')
01985         spwframe=tb.getcol('MEAS_FREQ_REF');
01986         tb.close()
01987         # assume spw[0]  
01988         elspecframe=["REST",
01989                      "LSRK",
01990                      "LSRD",
01991                      "BARY",
01992                      "GEO",         
01993                      "TOPO",
01994                      "GALACTO",
01995                      "LGROUP",
01996                      "CMB"]
01997         self.dataspecframe=elspecframe[spwframe[spw0]];
01998         if(dummy):
01999             return freqlist, finc
02000         #DP extract array from dictionary returned by getvarcol
02001         chanfreqs1dx = numpy.array([])
02002         chanfreqs=chanfreqscol['r'+str(spw0+1)].transpose()
02003         chanfreqs1dx = chanfreqs[0]
02004         if(spwinds!=-1):
02005             for ispw in range(1,len(spwinds)):
02006                 chanfreqs=chanfreqscol['r'+str(spwinds[ispw]+1)].transpose()            
02007                 chanfreqs1dx = numpy.concatenate((chanfreqs1dx, chanfreqs[0]))
02008         chanfreqs1d = chanfreqs1dx.flatten()        
02009         #RI this is woefully inadequate assuming the first chan's width
02010         #applies to everything selected, but we're going to replace all
02011         #this with MSSelect..
02012         chanwids=chanwidcol['r'+str(spw0+1)].transpose()
02013         chanfreqwidth=chanwids[0][0]
02014         
02015         if(type(start)==int or type(start)==float):
02016             if(start > len(chanfreqs1d)):
02017                 raise TypeError, "Start channel is outside the data range"
02018             startf = chanfreqs1d[start]
02019         elif(type(start)==str):
02020             if(qa.quantity(start)['unit'].find('Hz') > -1):
02021                 startf=qa.convert(qa.quantity(start),'Hz')['value']
02022             else:
02023                 raise TypeError, "Unrecognized start parameter"
02024         if(type(width)==int or type(width)==float):
02025             if(type(start)==int or type(start)==float):
02026                 #finc=(chanfreqs1d[start+1]-chanfreqs1d[start])*width
02027                 finc=(chanfreqwidth)*width
02028                 # still need to convert to target reference frame!
02029             elif(type(start)==str):
02030                 if(qa.quantity(start)['unit'].find('Hz') > -1):
02031                    # assume called from setChannelization with local width=1
02032                    # for the default width(of clean task parameter)='' for
02033                    # velocity and frequency modes. This case set width to 
02034                    # first channel width (for freq) and last one (for vel) 
02035                    if width==-1:
02036                        finc=chanfreqs1d[-1]-chanfreqs1d[-2]
02037                    else:
02038                        finc=chanfreqs1d[1]-chanfreqs1d[0]
02039 
02040                    # still need to convert to target reference frame!
02041         elif(type(width)==str):
02042             if(qa.quantity(width)['unit'].find('Hz') > -1):
02043                 finc=qa.convert(qa.quantity(width),'Hz')['value']
02044         if(nchan ==-1):
02045             if(qa.quantity(start)['unit'].find('Hz') > -1):
02046                 if width==-1: # must be in velocity order (i.e. startf is max)
02047                     bw=startf-chanfreqs1d[0]
02048                 else:
02049                     bw=chanfreqs1d[-1]-startf
02050             else:
02051                 bw=chanfreqs1d[-1]-chanfreqs1d[start]
02052             if(bw < 0):
02053                 raise TypeError, "Start parameter is outside the data range"
02054             if(qa.quantity(width)['unit'].find('Hz') > -1):
02055                 qnchan=qa.convert(qa.div(qa.quantity(bw,'Hz'),qa.quantity(width)))
02056                 #DP loc_nchan=int(math.ceil(qnchan['value']))+1
02057                 loc_nchan=int(round(qnchan['value']))+1
02058             else:
02059                 #DP loc_nchan=int(math.ceil(bw/finc))+1
02060                 loc_nchan=int(round(bw/finc))+1
02061         else:
02062             loc_nchan=nchan
02063         for i in range(int(loc_nchan)):
02064             if(i==0): 
02065                 freqlist.append(startf)
02066             else:
02067                 freqlist.append(freqlist[-1]+finc) 
02068         return freqlist, finc
02069 
02070 
02071     def setChannelizeDefault(self,mode,spw,field,nchan,start,width,frame,veltype,phasec, restf,obstime=''):
02072         """
02073         Determine appropriate values for channelization
02074         parameters when default values are used
02075         for mode='velocity' or 'frequency' or 'channel'
02076         This makes use of ms.cvelfreqs.
02077         """
02078         ###############
02079         # for debugging
02080         ###############
02081         debug=False
02082         ###############
02083         spectable=self.getspwtable(self.vis[self.sortedvisindx[0]])
02084         tb.open(spectable)
02085         chanfreqscol=tb.getvarcol('CHAN_FREQ')
02086         chanwidcol=tb.getvarcol('CHAN_WIDTH')
02087         spwframe=tb.getcol('MEAS_FREQ_REF');
02088         tb.close()
02089         # first parse spw parameter:
02090         # use MSSelect if possible
02091         if len(self.sortedvislist) > 0:
02092           invis = self.sortedvislist[0]
02093           inspw = self.vis.index(self.sortedvislist[0])
02094         else:
02095           invis = self.vis[0]
02096           inspw = 0
02097         ms.open(invis)
02098         if type(spw)==list:
02099           spw=spw[inspw]
02100         if spw in ('-1', '*', '', ' '):
02101           spw='*'
02102         if field=='':
02103           field='*'
02104         mssel=ms.msseltoindex(vis=invis, spw=spw, field=field)
02105         selspw=mssel['spw']
02106         selfield=mssel['field']
02107         chaninds=mssel['channel'].tolist()
02108         chanst0 = chaninds[0][1]
02109 
02110         # frame
02111         spw0=selspw[0]
02112         chanfreqs=chanfreqscol['r'+str(spw0+1)].transpose()[0]
02113         chanres = chanwidcol['r'+str(spw0+1)].transpose()[0]
02114 
02115         # ascending or desending data frequencies?
02116         # based on selected first spw's first CHANNEL WIDTH 
02117         # ==> some MS data may have positive chan width
02118         # so changed to look at first two channels of chanfreq (TT)
02119         #if chanres[0] < 0:
02120         descending = False
02121         if len(chanfreqs) > 1 :
02122           if chanfreqs[1]-chanfreqs[0] < 0:
02123             descending = True        
02124         else:
02125           if chanres[0] < 0:
02126             descending = True
02127 
02128         # set dataspecframe:
02129         elspecframe=["REST",
02130                      "LSRK",
02131                      "LSRD",
02132                      "BARY",
02133                      "GEO",
02134                      "TOPO",
02135                      "GALACTO",
02136                      "LGROUP",
02137                      "CMB"]
02138         self.dataspecframe=elspecframe[spwframe[spw0]];
02139 
02140         # set usespecframe:  user's frame if set, otherwise data's frame
02141         if(frame != ''):
02142             self.usespecframe=frame
02143             self.inframe=True
02144         else:
02145             self.usespecframe=self.dataspecframe
02146 
02147         # some start and width default handling
02148         if mode!='channel':
02149           if width==1:
02150              width=''
02151           if start==0:
02152              start=''
02153 
02154         #get restfreq
02155         if restf=='':
02156           tb.open(invis+'/FIELD')
02157           nfld=tb.nrows()
02158           try:
02159             if nfld >= selfield[0]:
02160               srcid=tb.getcell('SOURCE_ID',selfield[0])
02161             else:
02162               if mode=='velocity':
02163                 raise TypeError, ("Cannot set REST_FREQUENCY from the data: "+
02164                   "no SOURCE corresponding field ID=%s, please supply restfreq" % selfield[0])
02165           finally:
02166             tb.close()
02167           #SOUECE_ID in FIELD table = -1 if no SOURCE table
02168           if srcid==-1:
02169             if mode=='velocity':
02170               raise TypeError, "Rest frequency info is not supplied"
02171           try:
02172             tb.open(invis+'/SOURCE')
02173             tb2=tb.query('SOURCE_ID==%s' % srcid)
02174             nsrc = tb2.nrows()
02175             if nsrc > 0 and tb2.iscelldefined('REST_FREQUENCY',0):
02176               rfqs = tb2.getcell('REST_FREQUENCY',0)
02177               if len(rfqs)>0:  
02178                 restf=str(rfqs[0])+'Hz'
02179               else:
02180                 if mode=='velocity':  
02181                   raise TypeError, ("Cannot set REST_FREQUENCY from the data: "+
02182                     "REST_FREQUENCY entry for ID %s in SOURCE table is empty, please supply restfreq" % srcid)    
02183             else:
02184               if mode=='velocity':
02185                 raise TypeError, ("Cannot set REST_FREQUENCY from the data: "+
02186                  "no SOURCE corresponding field ID=%s, please supply restfreq" % selfield[0])
02187           finally:
02188             tb.close()
02189             tb2.close()
02190 
02191         if type(phasec)==list:
02192            inphasec=phasec[0]
02193         else:
02194            inphasec=phasec
02195         if type(inphasec)==str and inphasec.isdigit():
02196           inphasec=int(inphasec)
02197         #if nchan==1:
02198           # use data chan freqs
02199         #  newfreqs=chanfreqs
02200         #else:
02201           # obstime not included here
02202         if debug: print "before ms.cvelfreqs (start,width,nchan)===>",start, width, nchan
02203         newfreqs=ms.cvelfreqs(spwids=selspw,fieldids=selfield,mode=mode,nchan=nchan,
02204                               start=start,width=width,phasec=inphasec, restfreq=restf,
02205                               outframe=self.usespecframe,veltype=veltype).tolist()
02206         #print newfreqs
02207         descendingnewfreqs=False
02208         if len(newfreqs)>1:
02209           if newfreqs[1]-newfreqs[0] < 0:
02210             descendingnewfreqs=True
02211         if debug: print "Mode, Start, width after cvelfreqs =",mode, start,width 
02212         if type(newfreqs)==list and len(newfreqs) ==0:
02213           raise TypeError, ("Output frequency grid cannot be calculated: "+
02214                  " please check start and width parameters")
02215         if debug:
02216           if len(newfreqs)>1:
02217             print "FRAME=",self.usespecframe
02218             print "newfreqs[0]===>",newfreqs[0]
02219             print "newfreqs[1]===>",newfreqs[1]
02220             print "newfreqs[-1]===>",newfreqs[-1]
02221             print "len(newfreqs)===>",len(newfreqs)
02222           else:
02223             print "newfreqs=",newfreqs
02224         ms.close()
02225 
02226         # set output number of channels
02227         if nchan ==1:
02228           retnchan=1
02229         else:
02230           if len(newfreqs)>1:
02231             retnchan=len(newfreqs)
02232           else:
02233             retnchan=nchan
02234             newfreqs=chanfreqs
02235 
02236         # set start parameter
02237         # first analyze data order etc
02238         reverse=False
02239         negativew=False
02240         if descending:
02241           # channel mode case (width always >0) 
02242           if width!="" and (type(width)==int or type(width)==float):
02243             if descendingnewfreqs:
02244               reverse=False 
02245             else:
02246               reverse=True
02247           elif width=="": #default width
02248             if descendingnewfreqs and mode=="frequency":
02249               reverse=False
02250             else:
02251               reverse=True
02252                
02253           elif type(width)==str:
02254             if width.lstrip().find('-')==0:
02255               negativew=True
02256             if descendingnewfreqs:
02257               if negativew: 
02258                 reverse=False
02259               else:
02260                 reverse=True
02261             else:
02262               if negativew:
02263                 reverse=True
02264               else:
02265                 reverse=False
02266         else: #ascending data
02267           # depends on sign of width only
02268           # with CAS-3117 latest change(rev.15179), velocity start
02269           # means lowest velocity for default width
02270           if width=="" and mode=="velocity": #default width
02271               # ms.cvelfreqs returns correct order so no reversing
02272               reverse=False
02273           elif type(width)==str:
02274             if width.lstrip().find('-')==0:
02275                 reverse=True
02276             else:
02277                 reverse=False
02278 
02279         if reverse:
02280            newfreqs.reverse()
02281         #if (start!="" and mode=='channel') or \
02282         #   (start!="" and type(start)!=int and mode!='channel'):
02283         # for now to avoid inconsistency later in imagecoordinates2 call
02284         # user's start parameter is preserved for channel mode only.
02285         # (i.e. the current code may adjust start parameter for other modes but
02286         # this probably needs to be changed, especially for multiple ms handling.)
02287         if (start!="" and mode=='channel'):
02288           retstart=start
02289         else:
02290           # default cases
02291           if mode=="frequency":
02292             retstart=str(newfreqs[0])+'Hz'
02293           elif mode=="velocity":
02294             startfreq=str(newfreqs[-1])+'Hz'
02295             retstart=self.convertvf(startfreq,frame,field,restf,veltype)
02296           elif mode=="channel":
02297             # default start case, use channel selection from spw
02298             retstart=chanst0
02299         
02300         # set width parameter
02301         if width!="":
02302           retwidth=width
02303         else:
02304           if nchan==1:
02305             finc = chanres[0]
02306           else:
02307             finc = newfreqs[1]-newfreqs[0]
02308             if debug: print "finc(newfreqs1-newfreqs0)=",finc
02309           if mode=="frequency":
02310             if descendingnewfreqs:
02311               finc = -finc
02312             retwidth=str(finc)+'Hz'
02313           elif mode=="velocity":
02314             # for default width assume it is vel<0 (incresing in freq)
02315             if descendingnewfreqs:
02316               ind1=-2
02317               ind0=-1
02318             else:
02319               ind1=-1
02320               ind0=-2
02321             v1 = self.convertvf(str(newfreqs[ind1])+'Hz',frame,field,restf,veltype=veltype)
02322             v0 = self.convertvf(str(newfreqs[ind0])+'Hz',frame,field,restf,veltype=veltype)
02323             ##v1 = self.convertvf(str(newfreqs[-1])+'Hz',frame,field,restf,veltype=veltype)
02324             ##v0 = self.convertvf(str(newfreqs[-2])+'Hz',frame,field,restf,veltype=veltype)
02325             #v1 = self.convertvf(str(newfreqs[1])+'Hz',frame,field,restf,veltype=veltype)
02326             #v0 = self.convertvf(str(newfreqs[0])+'Hz',frame,field,restf,veltype=veltype)
02327             retwidth = str(qa.quantity(qa.sub(qa.quantity(v0),qa.quantity(v1)))['value'])+'m/s'
02328           else:
02329             retwidth=1
02330           if debug: print "setChan retwidth=",retwidth
02331         return retnchan, retstart, retwidth
02332 
02333     def setChannelizeNonDefault(self, mode,spw,field,nchan,start,width,frame,
02334                                 veltype,phasec, restf):
02335         """
02336         Determine appropriate values for channelization
02337         parameters when default values are used
02338         for mode='velocity' or 'frequency' or 'channel'
02339         This does not replaces setChannelization and make no use of ms.cvelfreqs.
02340         """
02341     
02342     
02343         #spw='0:1~4^2;10~12, ,1~3:3~10^3,4~6,*:7'
02344         #vis='ngc5921/ngc5921.demo.ms'
02345     
02346         if type(spw)!=str:
02347             spw=''
02348     
02349         if spw.strip()=='':
02350             spw='*'
02351     
02352         freqs=set()
02353         wset=[]
02354         chunk=spw.split(',')
02355         for i in xrange(len(chunk)):
02356             #print chunk[i], '------'
02357             ck=chunk[i].strip()
02358             if len(ck)==0:
02359                 continue
02360     
02361             wc=ck.split(':')
02362             window=wc[0].strip()
02363     
02364             if len(wc)==2:
02365                 sec=wc[1].split(';')
02366                 for k in xrange(len(sec)):
02367                     chans=sec[k].strip()
02368                     sep=chans.split('^')
02369                     se=sep[0].strip()
02370                     t=1
02371                     if len(sep)==2:
02372                         t=sep[1].strip()
02373                     se=se.split('~')
02374                     s=se[0].strip()
02375                     if len(se)==2:
02376                         e=se[1].strip() 
02377                     else:
02378                         e=-1
02379                     wd=window.split('~')
02380                     if len(wd)==2:
02381                         wds=int(wd[0])
02382                         wde=int(wd[1])
02383                         for l in range(wds, wde):
02384                             #print l, s, e, t
02385                             wset.append([l, s, e, t])
02386                     else:
02387                         #print wd[0], s, e, t
02388                         if e==-1:
02389                             try:
02390                                 e=int(s)+1
02391                             except:
02392                                 e=s
02393                         wset.append([wd[0], s, e, t])
02394             else:
02395                 win=window.split('~')
02396                 if len(win)==2:
02397                     wds=int(win[0])
02398                     wde=int(win[1])
02399                     for l in range(wds, wde):
02400                         #print l, 0, -1, 1
02401                         wset.append([l, 0, -1, 1])
02402                 else:
02403                     #print win[0], 0, -1, 1
02404                     wset.append([win[0], 0, -1, 1])
02405     
02406         #print wset
02407         for i in range(len(wset)):
02408             for j in range(4):
02409                 try:
02410                     wset[i][j]=int(wset[i][j])
02411                 except:
02412                     wset[i][j]=-1
02413         #print wset
02414         spectable=self.getspwtable(self.vis[self.sortedvisindx[0]])
02415         tb.open(spectable)
02416         nr=tb.nrows()
02417         for i in range(len(wset)):
02418             if wset[i][0]==-1:
02419                 w=range(nr)
02420             elif wset[i][0]<nr:
02421                 w=[wset[i][0]]
02422             else:
02423                 w=range(0)
02424             for j in w:
02425                 chanfreqs=tb.getcell('CHAN_FREQ', j)
02426                 if wset[i][2]==-1:
02427                     wset[i][2]=len(chanfreqs)
02428                 if wset[i][2]>len(chanfreqs):
02429                     wset[i][2]=len(chanfreqs)
02430                 #print wset[i][1], wset[i][2], len(chanfreqs), wset[i][3]
02431                 for k in range(wset[i][1], wset[i][2], wset[i][3]):
02432                     #print k
02433                     freqs.add(chanfreqs[k]) 
02434         tb.close()
02435         freqs=list(freqs)
02436         freqs.sort()
02437         #print freqs[0], freqs[-1]
02438     
02439         if mode=='channel':
02440             star=0
02441             if type(start)==str:
02442                try:
02443                    star=int(start)
02444                except:
02445                    star=0
02446             if type(start)==int:
02447                 star=start
02448             if star>len(freqs) or star<0:
02449                 star=0
02450  
02451             if nchan==-1:
02452                 nchan=len(freqs)
02453     
02454             widt=1
02455             if type(width)==str:
02456                try:
02457                    widt=int(width)
02458                except:
02459                    widt=1
02460             if type(width)==int:
02461                widt=width
02462             if widt==0:
02463                 widt=1
02464             if widt>0:
02465                 nchan=max(min(int((len(freqs)-star)/widt), nchan), 1)
02466             else:
02467                 nchan=max(min(int((-star)/widt), nchan), 1)
02468                 widt=-widt
02469                 star=max(star-nchan*widt, 0)
02470        
02471         if mode=='frequency':
02472             star=freqs[0]
02473             if type(start)!=str:
02474                 star=freqs[0]
02475             else:
02476                 star=max(qa.quantity(start)['value'], freqs[0])
02477 
02478             if nchan==-1:
02479                 nchan=len(freqs)
02480     
02481             widt=freqs[-1]
02482             if len(freqs)>1:
02483                 for k in range(len(freqs)-1):
02484                     widt=min(widt, freqs[k+1]-freqs[k])
02485             if type(width)==str and width.strip()!='':
02486                 widt=qa.quantity(width)['value']
02487     
02488             if widt>0:
02489                 #print star, widt, (freqs[-1]-star)/widt
02490                 nchan=max(min(int((freqs[-1]-star)/widt), nchan), 1)
02491             else:
02492                 nchan=max(min(int(freqs[0]-star)/widt, nchan), 1)
02493                 widt=-widt
02494                 star=max(star-nchan*widt, freqs[0])
02495     
02496             widt=str(widt)+'Hz'
02497             star=str(star)+'Hz'
02498     
02499         if mode=='velocity':
02500             beg1=self.convertvf(str(freqs[0])+'Hz',frame,field,restf,veltype=veltype)
02501             beg1=qa.quantity(beg1)['value']
02502             end0=self.convertvf(str(freqs[-1])+'Hz',frame,field,restf,veltype=veltype)
02503             end0=qa.quantity(end0)['value']
02504             star=beg1
02505             if type(start)==str and start.strip()!='':
02506                 star=min(qa.quantity(start)['value'], star)
02507                 star=min(star, end0)
02508             
02509             #print beg1, star, end0
02510 
02511             widt=-end0+beg1
02512             if len(freqs)>1:
02513                 for k in range(len(freqs)-1):
02514                     st=self.convertvf(str(freqs[k])+'Hz',frame,field,restf,veltype=veltype)
02515                     en=self.convertvf(str(freqs[k+1])+'Hz',frame,field,restf,veltype=veltype)
02516                     widt=min(widt, qa.quantity(en)['value']-qa.quantity(st)['value'])
02517                 widt=-abs(widt)
02518 
02519             if type(width)==str and width.strip()!='':
02520                 widt=qa.quantity(width)['value']
02521 
02522             #print widt
02523             if widt>0:
02524                 nchan=max(min(int((beg1-star)/widt), nchan), 1)
02525                 #star=0
02526             else:
02527                 nchan=max(min(int((end0-star)/widt), nchan), 1)
02528                 #widt=-widt
02529 
02530             widt=str(widt)+'m/s'
02531             star=str(star)+'m/s'
02532     
02533         return nchan, star, widt
02534 
02535     def convertframe(self,fin,frame,field):
02536         """
02537         (not in use: its caller is setChannelization...)
02538         convert freq frame in dataframe to specfied frame, assume fin in Hz
02539         retruns converted freq in Hz (value only)
02540         """
02541         # assume set to phasecenter before initChanelization is called
02542         pc=self.srcdir
02543         if(type(pc)==str):
02544             if (pc==''):
02545                 fieldused = field
02546                 if (fieldused ==''):
02547                     fieldused ='0'
02548                 #dir = int(ms.msseltoindex(self.vis,field=fieldused)['field'][0])
02549                 dir = int(ms.msseltoindex(self.vis[self.sortedvisindx[0]],field=fieldused)['field'][0])
02550             else:
02551                 tmpdir = phasecenter
02552                 try:
02553                     #if(len(ms.msseltoindex(self.vis, field=pc)['field']) > 0):
02554                     if(len(ms.msseltoindex(self.vis[self.sortedvisindx[0]], field=pc)['field']) > 0):
02555                         #tmpdir  = int(ms.msseltoindex(self.vis,field=pc)['field'][0])
02556                         tmpdir  = int(ms.msseltoindex(self.vis[self.sortedvisindx[0]],field=pc)['field'][0])
02557                 except Exception, instance:
02558                     tmpdir = pc
02559                 dir = tmpdir
02560         if type(dir)==str:
02561             try:
02562                 mrf, ra, dec = dir.split()
02563             except Exception, instance:
02564                 raise TypeError, "Error in a string format  for phasecenter"
02565             mdir = me.direction(mrf, ra, dec)
02566         else:
02567             #tb.open(self.vis+'/FIELD')
02568             tb.open(self.vis[self.sortedvisindx[0]]+'/FIELD')
02569             srcdir=tb.getcell('DELAY_DIR',dir)
02570             mrf=tb.getcolkeywords('DELAY_DIR')['MEASINFO']['Ref']
02571             tb.close()
02572             mdir = me.direction(mrf,str(srcdir[0][0])+'rad',str(srcdir[1][0])+'rad')
02573             #tb.open(self.vis+'/OBSERVATION')
02574             tb.open(self.vis[self.sortedvisindx[0]]+'/OBSERVATION')
02575         telname=tb.getcell('TELESCOPE_NAME',0)
02576         # use time in main table instead?
02577         tmr=tb.getcell('TIME_RANGE',0)
02578         tb.close()
02579         #print "direction=", me.direction(mrf,str(srcdir[0][0])+'rad',str(srcdir[1][0])+'rad')
02580         #print "tmr[1]=",tmr[1]
02581         #print "epoch=", me.epoch('utc',qa.convert(qa.quantity(str(tmr[1])+'s'),'d'))
02582         me.doframe(me.epoch('utc',qa.convert(qa.quantity(str(tmr[0])+'s'),'d')))
02583         me.doframe(me.observatory(telname))
02584         me.doframe(mdir)
02585         f0 = me.frequency(self.dataspecframe, str(fin)+'Hz')
02586         #print "frame=", frame, ' f0=',f0
02587         fout = me.measure(f0,frame)['m0']['value']
02588         return fout
02589 
02590     def setspecframe(self,spw):
02591         """
02592         set spectral frame for mfs to data frame based
02593         on spw selection 
02594         (part copied from setChannelization)
02595         """
02596         #tb.open(self.vis+'/SPECTRAL_WINDOW')
02597         spectable=self.getspwtable(self.vis[self.sortedvisindx[0]])
02598         tb.open(spectable)
02599         spwframe=tb.getcol('MEAS_FREQ_REF');
02600         tb.close()
02601 
02602         # first parse spw parameter:
02603 
02604         # use MSSelect if possible
02605         if type(spw)==list:
02606           spw=spw[self.sortedvisindx[0]]
02607 
02608         if spw in (-1, '-1', '*', '', ' '):
02609             spw="*"
02610 
02611         sel=ms.msseltoindex(self.vis[self.sortedvisindx[0]], spw=spw)
02612         # spw returned by msseletoindex, spw='0:5~10;10~20' 
02613         # will give spw=[0] and len(spw) not equal to len(chanids)
02614         # so get spwids from chaninds instead.
02615         chaninds=sel['channel'].tolist()
02616         spwinds=[]
02617         for k in range(len(chaninds)):
02618             spwinds.append(chaninds[k][0])
02619         if(len(spwinds) == 0):
02620             raise Exception, 'unable to parse spw parameter '+spw;
02621             
02622         # the first selected spw 
02623         spw0=spwinds[0]
02624 
02625         # set dataspecframe:
02626         elspecframe=["REST",
02627                      "LSRK",
02628                      "LSRD",
02629                      "BARY",
02630                      "GEO",         
02631                      "TOPO",
02632                      "GALACTO",
02633                      "LGROUP",
02634                      "CMB"]
02635         self.dataspecframe=elspecframe[spwframe[spw0]];
02636         return 
02637 
02638     def initChaniter(self,nchan,spw,start,width,imagename,mode,tmpdir='_tmpimdir/'):
02639         """
02640         initialize for channel iteration in interactive clean
02641         --- create a temporary directory, get frequencies for
02642         mode='channel'
02643        
02644         Keyword arguments:
02645         nchan -- no. channels
02646         spw   -- spw 
02647         start -- start modified after channelization function 
02648         width -- width modified after channelization function
02649         imagename -- from task input 
02650         mode  -- from task input
02651         tmpdir -- temporary directory name to store channel images
02652         
02653         returns: 
02654         frequencies in a list
02655         frequency increment
02656         newmode -- force to set mode to frequency
02657         tmppath -- path for the temporary directory
02658         """
02659         # create a temporary directory to put channel images
02660         tmppath=[]
02661         freqs=[]
02662         finc=0
02663         newmode=mode
02664         for imname in imagename:
02665             if os.path.dirname(imname)=='':
02666                 tmppath.append(tmpdir)
02667             else:
02668                 tmppath.append(os.path.dirname(imname)+'/'+tmpdir)
02669             # clean up old directory
02670             if os.path.isdir(tmppath[-1]):
02671                 shutil.rmtree(tmppath[-1])
02672             os.mkdir(tmppath[-1])
02673         #internally converted to frequency mode for mode='channel'
02674         #to ensure correct frequency axis for output image
02675         #if mode == 'channel':
02676         #    freqs, finc = self.getfreqs(nchan, spw, start, width)
02677         #    newmode = 'frequency'
02678         if mode == 'channel':
02679             # get spectral axis info from the dirty image
02680             ia.open(imagename[0]+'.image')
02681             imcsys=ia.coordsys().torecord()
02682             ia.close()
02683             # for optical velocity mode, the image will be in tabular form.
02684             if imcsys['spectral2'].has_key('tabular'):
02685               key='tabular'
02686             else:
02687               key='wcs'
02688             cdelt=imcsys['spectral2'][key]['cdelt']
02689             crval=imcsys['spectral2'][key]['crval']
02690             #cdelt=imcsys['spectral2']['wcs']['cdelt']
02691             #crval=imcsys['spectral2']['wcs']['crval']
02692             for i in range(nchan):
02693                 if i==0: freqs.append(crval)
02694                 freqs.append(freqs[-1]+cdelt)
02695             finc = cdelt
02696             newmode = 'frequency'
02697         return freqs,finc,newmode,tmppath
02698 
02699 
02700     def makeTemplateCubes(self, imagename,outlierfile, field, spw, selectdata, timerange,
02701           uvrange, antenna, scan, observation, mode, facets, cfcache, interpolation, 
02702           imagermode, localFTMachine, mosweight, locnchan, locstart, locwidth, outframe,
02703           veltype, imsize, cell, phasecenter, restfreq, stokes, weighting,
02704           robust, uvtaper, outertaper, innertaper, modelimage, restoringbeam,
02705           usescratch, noise, npixels, padding):
02706         """
02707         make template cubes to be used for chaniter=T interactive clean
02708         """
02709         imageids=[]
02710         imsizes=[]
02711         phasecenters=[]
02712         rootname=''
02713         multifield=False
02714         loc_modelimage=modelimage
02715         newformat=False
02716 
02717         if len(outlierfile) != 0:
02718             f_imageids,f_imsizes,f_phasecenters,f_masks,f_modelimages,parms,newformat=self.newreadoutlier(outlierfile)
02719             if type(imagename) == list or newformat:
02720                 rootname = ''
02721             else:
02722                 rootname = imagename
02723 
02724             # combine with the task parameter input
02725             if type(imagename) == str:
02726                 if newformat:
02727                     imageids.append(imagename)
02728                     imsizes.append(imsize)
02729                     phasecenters.append(phasecenter)
02730             else:
02731                 imageids=imagename
02732                 imsizes=imsize
02733                 phasecenters=phasecenter
02734 
02735             #if type(mask) !=  list:
02736             #    mask=[mask]
02737             #elif type(mask[0]) != list:
02738             #    mask=[mask]
02739             if type(loc_modelimage) != list:
02740                 loc_modelimage=[loc_modelimage]
02741 
02742             #elif type(loc_modelimage[0]) != list and type(imagename) != str:
02743             #if type(loc_modelimage[0]) != list and \
02744             #    (type(imagename) != str or (type(imageids)==list and len(imageids)=1)):
02745             #    loc_modelimage=[loc_modelimage]
02746             if type(loc_modelimage[0]) != list:
02747                 loc_modelimage=[loc_modelimage]
02748 
02749             # now append readoutlier content
02750             for indx, name in enumerate(f_imageids):
02751                 imageids.append(name)
02752                 imsizes.append(f_imsizes[indx])
02753                 phasecenters.append(f_phasecenters[indx])
02754                
02755                 if newformat:
02756                     #mask.append(f_masks[indx])
02757                     loc_modelimage.append([f_modelimages[indx]])
02758                 else:
02759                     if indx!=0:
02760                         loc_modelimage.append([f_modelimages[indx]])
02761 
02762             ##if len(imageids) > 1:
02763             #    multifield=True
02764         else:
02765             imsizes=imsize
02766             phasecenters=phasecenter
02767             imageids=imagename
02768                
02769         if len(imageids) > 1:
02770             multifield=True
02771 
02772         self.imageids=imageids
02773         # readoutlier need to be run first....
02774         self.datsel(field=field, spw=spw, timerange=timerange, uvrange=uvrange, 
02775                     antenna=antenna,scan=scan, observation=observation, usescratch=usescratch,
02776                     nchan=-1, start=0, width=1)
02777 
02778         self.definemultiimages(rootname=rootname,imsizes=imsizes,cell=cell,
02779                                 stokes=stokes,mode=mode,
02780                                spw=spw, nchan=locnchan, start=locstart,
02781                                width=locwidth, restfreq=restfreq,
02782                                field=field, phasecenters=phasecenters,
02783                                names=imageids, facets=facets,
02784                                outframe=outframe, veltype=veltype,
02785                                makepbim=False, checkpsf=False)
02786 
02787         self.datweightfilter(field=field, spw=spw, timerange=timerange, 
02788                              uvrange=uvrange, antenna=antenna,scan=scan,
02789                              wgttype=weighting, robust=robust, noise=noise, 
02790                              npixels=npixels, mosweight=mosweight,
02791                              uvtaper=uvtaper, innertaper=innertaper, outertaper=outertaper, 
02792                              usescratch=usescratch, nchan=-1, start=0, width=1)
02793         # split this 
02794         #self.datselweightfilter(field=field, spw=spw,
02795         #                         timerange=timerange, uvrange=uvrange,
02796         #                         antenna=antenna, scan=scan,
02797         #                         wgttype=weighting, robust=robust,
02798         #                         noise=noise, npixels=npixels,
02799         #                         mosweight=mosweight,
02800         #                         innertaper=innertaper,
02801         #                         outertaper=outertaper,
02802         #                         calready=calready, nchan=-1,
02803         #                         start=0, width=1)
02804        
02805         #localAlgorithm = getAlgorithm(psfmode, imagermode, gridmode, mode,
02806         #                             multiscale, multifield, facets, nterms,
02807         #                             'clark');
02808 
02809         #localAlgorithm = 'clark'
02810         #print "localAlogrithm=",localAlgorithm
02811 
02812         #self.im.setoptions(ftmachine=localFTMachine,
02813         #                     wprojplanes=wprojplanes,
02814         #                     freqinterp=interpolation, padding=padding,
02815         #                     cfcachedirname=cfcache, pastep=painc,
02816         #                     epjtablename=epjtable,
02817         #                     applypointingoffsets=False,
02818         #                     dopbgriddingcorrections=True)
02819         self.im.setoptions(ftmachine=localFTMachine,
02820                              freqinterp=interpolation, padding=padding,
02821                              cfcachedirname=cfcache)
02822 
02823         modelimages=[]
02824         restoredimage=[]
02825         residualimage=[]
02826         psfimage=[]
02827         fluximage=[]
02828         for k in range(len(self.imagelist)):
02829             ia.open(self.imagelist[k])
02830             #if (modelimage =='' or modelimage==[]) and multifield:
02831             #    ia.rename(self.imagelist[k]+'.model',overwrite=True)
02832             #else:
02833             #    ia.remove(verbose=False)
02834             if ((loc_modelimage =='' or loc_modelimage==[]) or \
02835                 (type(loc_modelimage)==list and \
02836                  (loc_modelimage[k]=='' or loc_modelimage[k]==[''] or loc_modelimage[k]==[]))) and multifield:
02837                 ia.rename(self.imagelist[k]+'.model',overwrite=True)
02838             else:
02839                 modlist=[]
02840                 if type(modelimage)==str:
02841                     modlist=[modelimage]
02842                 # make sure input model image is not removed
02843                 if (not any([inmodel == self.imagelist[k] for inmodel in modlist])) and \
02844                     (not any([inmodel == self.imagelist[k]+'.model' for inmodel in modlist])):
02845                 #    ia.remove(verbose=False)
02846                      ia.rename(self.imagelist[k]+'.model',overwrite=True)
02847             ia.close()
02848 
02849             modelimages.append(self.imagelist[k]+'.model')
02850             restoredimage.append(self.imagelist[k]+'.image')
02851             residualimage.append(self.imagelist[k]+'.residual')
02852             psfimage.append(self.imagelist[k]+'.psf')
02853             if(imagermode=='mosaic'):
02854                 fluximage.append(self.imagelist[k]+'.flux')
02855 
02856         # make dirty image cube
02857         if multifield:
02858            alg='mfclark'
02859         else:
02860            alg='clark'
02861        
02862         self.im.clean(algorithm=alg, niter=0,
02863                    model=modelimages, residual=residualimage,
02864                    image=restoredimage, psfimage=psfimage,
02865                    mask='', interactive=False)
02866 
02867 
02868     def setChaniterParms(self,finalimagename, spw,chan,start,width,freqs,finc,tmppath):
02869         """
02870         Set parameters for channel by channel iterations
02871         returns:
02872         start and width to define each channel image plane
02873         """
02874         retparms={}
02875         self.maskimages={}
02876         retparms['imagename']=[tmppath[indx]+os.path.basename(imn)+'.ch'+str(chan)
02877                    for indx, imn in enumerate(finalimagename)]
02878 
02879         #print "Processing channel %s " % chan
02880         #self._casalog.post("Processing channel %s "% chan)
02881 
02882         # Select only subset of vis data if possible.
02883         # It does not work well for multi-spw so need
02884         # to select with nchan=-1
02885         retparms['imnchan']=1
02886         retparms['chanslice']=chan
02887         qat=casac.quanta()
02888         q = qat.quantity
02889 
02890         # 2010-08-18 note: disable this. Has the problem 
02891         # getting imaging weights correctly when the beginning 
02892         # channels were flagged.
02893         #if type(spw)==int or len(spw)==1:
02894         #    if width>1:
02895         #        visnchan=width
02896         #    else:
02897         #        visnchan=1
02898         #else:
02899         #    visnchan=-1
02900 
02901         visnchan=-1
02902         retparms['visnchan']=visnchan
02903         visstart=0
02904 
02905         if type(start)==int:
02906             # need to convert to frequencies
02907             # to ensure correct frequencies in
02908             # output images(especially for multi-spw)
02909             # Use freq list instead generated in initChaniter
02910             imstart=q(freqs[chan],'Hz')
02911             width=q(finc,'Hz')
02912         elif start.find('m/s')>0:
02913             imstart=qat.add(q(start),qat.mul(chan,q(width)))
02914         elif start.find('Hz')>0:
02915             imstart=qat.add(q(start),qat.mul(chan,q(width)))
02916         retparms['width']=width
02917         retparms['imstart']=imstart
02918         retparms['visstart']=visstart
02919 
02920         #
02921         return retparms
02922 
02923     def defineChaniterModelimages(self,modelimage,chan,tmppath):
02924         """
02925         chaniter=T specific function to convert input models 
02926         to a model image 
02927         """
02928         chanmodimg=[]
02929         if type(modelimage)==str:
02930             modelimage=[modelimage]
02931         indx=0
02932         for modimg in modelimage:
02933             if modimg=='':
02934                 return 
02935             if type(modimg)==list:
02936                 chanmodimg=[]
02937                 for img in modimg:
02938                     if img!='':
02939                         if os.path.dirname(img) != '':
02940                             chanmodimg.append(tmppath[0] + '_tmp.' +
02941                                               os.path.basename(img))
02942                         else:
02943                             chanmodimg.append(tmppath[0] + '_tmp.' + img)
02944                         self.getchanimage(cubeimage=img, outim=chanmodimg[-1], chan=chan)
02945                 #self.convertmodelimage(modelimages=chanmodimg,
02946                 #                        outputmodel=self.imagelist.values()[0]+'.model')
02947                 self.convertmodelimage(modelimages=chanmodimg,
02948                                         outputmodel=self.imagelist.values()[indx]+'.model', imindex=indx)
02949                 chanmodimg=[]
02950                 indx+=1
02951             else:
02952                 if os.path.dirname(modimg) != '':
02953                     chanmodimg.append(tmppath[0] + '_tmp.' + os.path.basename(modimg))
02954                 else:
02955                     chanmodimg.append(tmppath[0] + '_tmp.' + modimg)
02956                 self.getchanimage(cubeimage=modimg, outim=chanmodimg[-1],chan=chan)
02957 
02958                 #self.convertmodelimage(modelimages=chanmodimg,
02959                 #                        outputmodel=self.imagelist.values()[0]+'.model')
02960                 self.convertmodelimage(modelimages=chanmodimg,
02961                                         outputmodel=self.imagelist.values()[indx]+'.model',imindex=indx)
02962             # clean up temporary channel model image
02963             self.cleanupTempFiles(chanmodimg)
02964 
02965     def convertAllModelImages_old(self,modelimage, mode, nterms, dochaniter, chan, tmppath):
02966         """
02967         wrapper function for convertmodelimage for all different cases
02968         """
02969         if (type(modelimage)!=str and type(modelimage)!=list):
02970                     raise Exception,'modelimage must be a string or a list of strings';
02971         #spectralline modes
02972         if (not mode=='mfs') or (mode=='mfs' and nterms==1):
02973             if (not all(img=='' or img==[] or img==[''] for img in modelimage)):
02974                 if dochaniter:
02975                     self.defineChaniterModelimages(modelimage,chan,tmppath)
02976                 else:
02977                     if type(modelimage)== str or \
02978                        (type(modelimage)==list and len(self.imagelist)==1 and len(modelimage)>1):
02979                         modelimage=[modelimage]
02980                     
02981                     #print "Run convertmodelimage for this list : ", self.imagelist, " with these models : ", modelimage;
02982                     for j in range(len(self.imagelist)):
02983                         self._casalog.post("Use modelimages: "+str(modelimage[j])+" to create a combined modelimage: " \
02984                                            +self.imagelist.values()[j]+".model", 'DEBUG1')
02985                         if modelimage[j] != '' and modelimage[j] != []:
02986                             self.convertmodelimage(modelimages=modelimage[j],
02987                                     outputmodel=self.imagelist.values()[j]+'.model',imindex=j)
02988 
02989         # elif .......
02990         # put mfs with nterms>1 case here
02991 
02992     ##########################################################
02993     # Multiple models for one field : [ [ 'm0', 'm1' ] ]
02994     # Multiple taylor terms and one field : [ [ 't0','t1'] ]
02995     # Multiple models per field : [ [ 'm0f0', 'm1f0' ] ,  [ 'm0f1', 'm1f1' ] ]
02996     # Multiple taylor terms per field : [ [ 't0f0','t1f0' ] , [ 't0f1','t1f1' ] ]
02997     ##########################################################
02998     # Cannot do multiple models per taylor term and per field for now.
02999     # ....... later...  [  [ ['m0t0f0','m1t0f0'],['m0t1f0','m1t1f0'] ] , [ [ ['t0f1'] ],[ ['t1f1'] ] ] ]
03000     ##########################################################
03001     def convertAllModelImages(self,modelimage, mode, nterms, dochaniter, chan, tmppath):
03002         """
03003         wrapper function for convertmodelimage for all different cases
03004         """
03005         if (type(modelimage)!=str and type(modelimage)!=list):
03006                     raise Exception,'modelimage must be a string or a list of strings';
03007         if (not all(img=='' or img==[] or img==[''] for img in modelimage)):
03008              if dochaniter:
03009                     self.defineChaniterModelimages(modelimage,chan,tmppath)
03010              else:
03011                     if type(modelimage)== str or \
03012                        (type(modelimage)==list and len(self.imagelist)==1 and len(modelimage)>1):
03013                         modelimage=[modelimage]
03014 
03015              #print "Run convertmodelimage for this list : ", self.imagelist, " with these models : ", modelimage;
03016              #spectralline modes + basic mfs
03017 #             if (not mode=='mfs') or (mode=='mfs' and nterms==1):
03018 #                    for j in range(len(self.imagelist)):   # = nfield
03019 #                        self._casalog.post("Use modelimages: "+str(modelimage[j])+" to create a combined modelimage: " \
03020 #                                           +self.imagelist.values()[j]+".model", 'DEBUG1')
03021 #                        if modelimage[j] != '' and modelimage[j] != []:
03022 #                            self.convertmodelimage(modelimages=modelimage[j],
03023 #                                    outputmodel=self.imagelist.values()[j]+'.model',imindex=j)
03024 
03025 #             else: # mfs and nterms>1
03026              if 1:
03027                     nfld = len(self.imagelist);
03028                     # if only one field, then modelimage must be a list of strings. convert to list of list of str
03029                     # if multiple fields, then model image : list of list of strings
03030                     if nfld != len(modelimage):
03031                        raise Exception,'Model images must be same length as fields : '+str(nfld) + str(modelimage);
03032 
03033                     for fld in range(nfld):
03034                        modsforfield = modelimage[fld]; # a list
03035                        if type(modsforfield)==str:
03036                             modsforfield = [modsforfield];
03037                        if nterms==1:
03038                             nimages = len(modsforfield);
03039                        else:
03040                             nimages = min( len(modsforfield), nterms ); ## one model per term
03041                        for tt in range(0,nimages):
03042                            if nterms==1:
03043                                modname = self.imagelist[fld]+'.model';
03044                            else:
03045                                modname = self.imagelist[fld]+'.model.tt'+str(tt) ;
03046                            if( os.path.exists(modsforfield[tt]) ):
03047 #                              print "Found user-specified model image : "+modsforfield[tt]+" . Adding to starting model : "+modname;
03048                                self._casalog.post("Found user-specified model image : "+modsforfield[tt]+" . Adding to starting model : "+modname);
03049                                self.convertmodelimage(modelimages=modsforfield[tt],outputmodel=modname, imindex=fld);
03050                            else:
03051                                self._casalog.post("Cannot find user-specified model image : "+modsforfield[tt]+" . Continuing with current model : "+modname);
03052 
03053 
03054 
03055         
03056 
03057     def storeCubeImages(self,cubeimageroot,chanimageroot,chan,imagermode):
03058         """
03059         Put channel images back into CubeImages for chaniter=T mode
03060         
03061         Keyword arguments:
03062         cubeimageroot -- root name for output cube image
03063         chanimageroot -- root name for channel image
03064         chan          -- channel plane index
03065         imagermode    -- imagermode  
03066         """
03067         imagext = ['.image','.model','.flux','.residual','.psf','.mask']
03068         if imagermode=='mosaic':
03069             imagext.append('.flux.pbcoverage')
03070         lerange=range(self.nimages)
03071         for n in lerange:
03072             cubeimagerootname=cubeimageroot[n]
03073             chanimagerootname=chanimageroot[n]
03074         for ext in imagext:
03075             nomaskim=False
03076             cubeimage=cubeimagerootname+ext
03077             chanimage=chanimagerootname+ext
03078             if not os.path.exists(cubeimage):
03079                 if os.path.exists(chanimage):
03080                     outim=ia.newimagefromimage(cubeimagerootname+'.model',cubeimage)
03081                     outim.done(verbose=False)
03082                 elif ext=='.mask':
03083                     # unless mask image is given or in interactive mode
03084                     # there is no mask image
03085                     nomaskim=True
03086             if not nomaskim: 
03087                 self.putchanimage(cubeimage, chanimage,chan)
03088 
03089     def cleanupTempFiles(self, tmppath):
03090         """
03091         Remove the directories listed by tmppath.
03092         """
03093         # Created to deal with temporary dirs created by chaniter=T clean,
03094         # now used elsewhere too.
03095         for dir in tmppath:
03096             if os.path.exists(dir):
03097                shutil.rmtree(dir)
03098 
03099     def convertImageFreqFrame(self,imlist):
03100         """
03101         Convert output images to proper output frame
03102         (after im.clean() executed)
03103         """
03104         if type(imlist)==str:
03105           imlist=[imlist]
03106         if self.usespecframe.lower() != 'lsrk':
03107           if self.usespecframe=='':
03108             inspectral=self.dataspecframe
03109           else: 
03110             inspectral=self.usespecframe
03111           for img in imlist:
03112             if os.path.exists(img):
03113               ia.open(img)
03114               csys=ia.coordsys()
03115               csys.setconversiontype(spectral=inspectral)
03116               #print "csys.torecord spectral2=", csys.torecord()['spectral2']
03117               ia.setcoordsys(csys.torecord())
03118               ia.close()
03119 
03120     @staticmethod
03121     def getOptimumSize(size):
03122         '''
03123         This returns the next largest even composite of 2, 3, 5, 7
03124         '''
03125         def prime_factors(n, douniq=True):
03126             """ Return the prime factors of the given number. """
03127             factors = []
03128             lastresult = n
03129             sqlast=int(numpy.sqrt(n))+1
03130            # 1 pixel must a single dish user
03131             if n == 1:
03132                 return [1]
03133             c=2
03134             while 1:
03135                 if (lastresult == 1) or (c > sqlast):
03136                     break
03137                 sqlast=int(numpy.sqrt(lastresult))+1
03138                 while 1:
03139                     if(c > sqlast):
03140                         c=lastresult
03141                         break
03142                     if lastresult % c == 0:
03143                         break            
03144                     c += 1
03145 
03146                 factors.append(c)
03147                 lastresult /= c
03148             if(factors==[]): factors=[n]
03149             return  numpy.unique(factors).tolist() if douniq else factors 
03150         n=size
03151         if(n%2 != 0):
03152             n+=1
03153         fac=prime_factors(n, False)
03154         for k in range(len(fac)):
03155             if(fac[k] > 7):
03156                 val=fac[k]
03157                 while(numpy.max(prime_factors(val)) > 7):
03158                     val +=1
03159                 fac[k]=val
03160         newlarge=numpy.product(fac)
03161         for k in range(n, newlarge, 2):
03162             if((numpy.max(prime_factors(k)) < 8)):
03163                 return k
03164         return newlarge
03165 
03166 def getFTMachine(gridmode, imagermode, mode, wprojplanes, userftm):
03167     """
03168     A utility function which implements the logic to determine the
03169     ftmachine name to be used in the under-laying tool.
03170     """
03171 #    ftm = userftm;
03172     ftm='ft';
03173     if ((gridmode == 'widefield') and(wprojplanes > 1)): ftm = 'wproject';
03174     elif (gridmode == 'aprojection'):                    ftm = 'awproject';
03175     elif (gridmode == 'advancedaprojection'):            ftm = 'awproject';
03176     elif (imagermode == 'csclean'):                      ftm = 'ft';
03177     elif (imagermode == 'mosaic'):                       ftm = userftm;
03178     return ftm;
03179 
03180 def getAlgorithm(psfmode, imagermode, gridmode, mode, 
03181                  multiscale, multifield, facets, nterms, useralg):
03182     """
03183     A utility function which implements the logic to determine the
03184     deconvolution algorithm to be used in the under-laying tool.
03185     """
03186     alg=useralg
03187     addMultiField=False;
03188 
03189     if((type(multiscale)==list) and 
03190        (len(multiscale) > 0) and
03191        (sum(multiscale) > 0)): alg = 'multiscale';
03192     elif ((psfmode == 'clark') or (psfmode == 'hogbom')): alg=psfmode;
03193 
03194     if ((imagermode == '') and (multifield)): addMultiField=True;
03195     if (imagermode == 'mosaic'):              addMultiField=True;
03196     if (imagermode == 'csclean'):             addMultiField = True; #!!!!
03197 
03198     if ((mode == 'mfs') and (nterms > 1)): 
03199         alg = 'msmfs';
03200         if(imagermode == 'mosaic'): 
03201             ##print 'Multi-Term MFS with a mosaic is experimental'
03202             raise Exception, 'msmfs (nterms>1) not allowed with imagermode=' + imagermode + '. For now, msmfs automatically performs cs-clean type iterations';
03203         if (multifield): 
03204                 addMultiField = True;
03205         if facets > 1:
03206             raise Exception, 'msmfs (nterms>1) with facets>1 is not yet available'
03207     if( (mode=='mfs') and (nterms<1) ):
03208          raise Exception, 'nterms must be > 0';
03209 
03210 #    if (gridmode == 'widefield'): alg='mfclark';
03211 
03212     if (gridmode == 'widefield'):
03213         addMultiField=True;
03214         if (facets > 1):
03215             if(alg.count('multiscale') > 0):
03216                 raise Exception, 'multiscale with facets > 1 not allowed for now';
03217             if (psfmode==''): psfmode='clark';
03218             if((psfmode == 'clark') or (psfmode == 'hogbom')):
03219                 alg='wf'+psfmode;
03220                 addMultiField=False;
03221             else:
03222                 addMultiField=True;
03223 #            addMultiField=False;
03224 
03225 #
03226 # if facets > 1 && mutliscale ==> fail
03227 
03228 
03229     if (addMultiField and (alg[0:2] != 'mf') and (alg != 'msmfs')):  alg = 'mf' + alg;
03230     return alg;
03231 
03232 def convert_numpydtype(listobj):
03233     """
03234     utility function to covert list with elements in numpy.int or
03235     numpy.float types to python int/float
03236     """
03237     import array as pyarr
03238     floatarr=False
03239     intarr=False
03240     for elm in listobj:
03241       if numpy.issubdtype(type(elm), numpy.float):
03242         floatarr = True
03243       elif numpy.issubdtype(type(elm), numpy.int):
03244         intarr = True
03245     if floatarr or (floatarr and intarr):
03246       temparr=pyarr.array('f', listobj)
03247     elif intarr:
03248       temparr=pyarr.array('i', listobj)
03249     else:
03250       temparr = listobj
03251       return temparr
03252     return temparr.tolist()