casa
$Rev:20696$
|
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()