Coverage for /wheeldirectory/casa-6.7.0-12-py3.10.el8/lib/py/lib/python3.10/site-packages/casatasks/private/task_makemask.py: 4%
711 statements
« prev ^ index » next coverage.py v7.6.4, created at 2024-10-31 18:48 +0000
« prev ^ index » next coverage.py v7.6.4, created at 2024-10-31 18:48 +0000
1################################################
2# Task to make masks.
3# reorganized after diesuccsion on Oct1, 2012
4# with Jeurgen and Urvashi
5#
6# modified by TT
7# based on the original code,
8# v1.0: 2012.03.20, U.Rau
9#
10################################################
11# Notes (to self) - TT
12# 1. expanding one mask to another
13# e.g.) expanding a continuum mask (both image mask/boolean mask)
14# channel mask
15# 2. part of copy mode func.: merging of different types of masks
16# e.g.) inpimage and inpmask are lists of the mask to be merged
17# output mask is written to either outimage or outmask as embedded
18# T/F mask
19# 3. copying mask to another or create a new one
20# regrid if necessary (i.e. if the coords are different)
21# ----------------------------------------------
22# basic rules:
23# for mask image (1/0 mask): as it is
24# for internal mask : parent_imagename:mask_name
25#
26# For input,
27# inpimage is the casa image
28# - mode='list': list internal masks of inpimage
29# - other mode: used as a template for output
30# if region files are specified -> make mask specifeid with the regions on to inpimage
31# output is '' => modified inpimage unless overwrite=F else exception
32#
33# if inpmask='': use inpimage as input mask
34# if inpmask='mask0' or other embedded mask name of the inpimage,
35# use that T/F mask
36#
37# =expand=
38# case1: on the same image (outimage=''), expand mask image from
39# prev. run etc. No regriding. Use nearest chan mask
40# image to expand.
41# 1.a: inpimage is clean image mask (1s and 0s)
42# i) outimage != inpimage and outmask='' => new expanded mask image to outimage
43# ii) outimage != inpimage and outmask!='' => convert expanded mask image to T/F mask to store inside outimage
44# iii) outimage ==inpimage and outmask='' => update input mask image by expanding it
45# iv) outimage ==inpimage and outmask!=''=> update input image with the expanded T/F mask
46# 1.b: if inpmask!='', do T/F mask to 1/0 image mask conversion, then do as in 1.a
48# case2: outimage is in diffirent coords. (need to regrid)
49#
50#################
51# tests
52# 1. for input: mask image
53# 2. for input: mask/or regular image with internal mask
54# 3. for input: mask image; for output: mask image with different spectral grid
55# 4. for input: mask/regular image with internal mask; for output: image with
56# internal mask with different spectral grid
57###################
58import os
59import shutil
60import numpy as np
62from casatools import image, regionmanager, imager, table, quanta
63from casatasks import casalog
64from .imtools import pixelmask2cleanmask
66import subprocess
67subprocess_getoutput = subprocess.getoutput
69_ia = image()
70_rg = regionmanager()
71_qa = quanta()
73pid = str(os.getpid())
74debug = False
75#debug = True
77def makemask(mode,inpimage, inpmask, output, overwrite, inpfreqs, outfreqs):
78 """
79 make /manipulate masks
81 """
82 _ia = image()
83 _rg = regionmanager()
84 _im = imager()
85 casalog.origin('makemask')
86 #casalog.post("params(mode,inpimage,inpmask,output,overwrite)=",mode,inpimage,inpmask,output,overwrite)
88 try:
89 # temp files
90 tmp_maskimage='__tmp_makemaskimage_'+pid
91 tmp_outmaskimage='__tmp_outmakemaskimage_'+pid
92 tmp_regridim='__tmp_regridim_'+pid
94 #intial cleanup to make sure nothing left from previous runs
95 tmplist = [tmp_maskimage,tmp_outmaskimage,tmp_regridim]
96 cleanuptempfiles(tmplist)
98 # do parameter check first
99 # check names of inpimage, inpmask check for existance
100 # inpimage == output (exact match) then check overwrite
101 # => T overwrite inpimage
102 # => F exception
104 # check inpimage
105 if (['list','copy','expand'].count(mode)==1):
106 if inpimage=='': raise ValueError("inpimage is empty")
107 if not os.path.isdir(inpimage):
108 raise RuntimeError("inpimage=%s does not exist" % inpimage)
110 # === list mode ===
111 if mode == 'list':
112 inpOK=checkinput(inpimage)
113 if inpOK:
115 if _ia.isopen(): _ia.close()
116 _ia.open(inpimage)
117 inmasklist=_ia.maskhandler('get')
118 # now ia.maskhandler returns ['T'] if no internal mask is there...
119 if inmasklist.count('T')!=0:
120 inmasklist.remove('T')
121 if len(inmasklist) ==0:
122 casalog.post('No internal (T/F) masks were found in %s' % (inpimage),'INFO')
123 else:
124 defaultmaskname=_ia.maskhandler('default')[0]
125 printinmasks=''
126 for mname in inmasklist:
127 if mname==defaultmaskname:
128 printinmasks+='\''+mname+'\''+'(default)'
129 else:
130 printinmasks+='\''+mname+'\''
131 if mname != inmasklist[-1]:
132 printinmasks+=', '
134 casalog.post('Internal (T/F) masks in %s: %s' % (inpimage, printinmasks),'INFO')
135 _ia.close()
137 # === setdefaultmask mode ===
138 elif mode == 'setdefaultmask':
139 inpOK=checkinput(inpmask)
140 if inpOK:
141 (parentimage,bmask)=extractmaskname(inpmask)
142 if bmask=='':
143 raise RuntimeError("Missing an internal mask name")
144 if _ia.isopen(): _ia.close()
145 _ia.open(parentimage)
146 defaultmaskname=_ia.maskhandler('default')[0]
147 inmasklist=_ia.maskhandler('get')
148 if defaultmaskname==bmask:
149 casalog.post('No change. %s is already a default internal mask' % bmask, 'INFO')
150 else:
151 _ia.maskhandler('set',bmask)
152 casalog.post('Set %s as a default internal mask' % bmask, 'INFO')
153 if len(inmasklist)>1:
154 casalog.post('Current internal masks are %s' % str(inmasklist), 'INFO')
155 _ia.close()
157 # === delete mode ===
158 elif mode == 'delete':
159 inpOK=checkinput(inpmask)
160 if inpOK:
161 (parentimage,bmask)=extractmaskname(inpmask)
162 if bmask=='':
163 raise RuntimeError("Missing an internal mask name")
164 _ia.open(parentimage)
165 casalog.post('Deleting the internal mask, %s ' % bmask, 'INFO')
166 defaultmaskname=_ia.maskhandler('default')[0]
167 _ia.maskhandler('delete',bmask)
168 inmasklist=_ia.maskhandler('get')
169 if inmasklist.count('T')!=0:
170 inmasklist.remove('T')
171 if len(inmasklist) !=0 and defaultmaskname==bmask:
172 _ia.maskhandler('set',inmasklist[0])
173 casalog.post('Set %s as a default internal mask' % inmasklist[0], 'INFO')
174 if len(inmasklist)>1:
175 casalog.post('Current internal masks are %s' % str(inmasklist), 'INFO')
177 _ia.close()
179 else:
180 # PREPROCESS STAGE for mode='copy' and 'expand'
181 #DEBUG
182 #casalog.post("mode=",mode)
183 # copy can have multiple input masks, expand has only one.
184 # check inpimage, inpmask, output, overwrite
185 #
186 storeinmask = False # used to check if output to a new internal mask
187 isNewOutfile = False
189 inpOK=checkinput(inpimage)
190 if inpOK:
191 (immask,inmask)=extractmaskname(inpimage)
193 # seperate text files(region files), images(with full ':'), and direct region
194 # input mask(s)
195 if inpmask=='':
196 raise ValueError("Input errror. The inpmask parameter is not specified.")
197 if type(inpmask)!=list:
198 inpmask=[inpmask]
200 # check if inpmask contains region file or region specification
201 rgfiles=[]
202 imgfiles=[]
203 rglist=[]
204 bmasks=[]
205 for masklet in inpmask:
206 # is text file?
207 if type(masklet)==str: # text file or image
208 if os.path.exists(masklet):
209 # region file or image
210 if (subprocess_getoutput('file '+masklet).count('directory')):
211 if os.path.exists(masklet+'/table.f1'):
212 #casalog.post("%s is not in a recognized format for inpmask, ignored." % masklet, 'WARN')
213 raise ValueError("%s is not in a recognized format for inpmask" % masklet)
214 else:
215 # probably image file (with no mask extension)
216 imgfiles.append(masklet)
217 # text file (CRTF)
218 elif (subprocess_getoutput('file '+masklet).count('text')):
219 rgfiles.append(masklet)
220 else:
221 #casalog.post("%s does not recognized format for inpmask, ignored." % masklet, 'WARN')
222 raise ValueError("%s is not in a recognized format for inpmask" % masklet)
223 else:
224 # direct string specification
225 if masklet.count('[') and masklet.count(']'): # rough check on region specification
226 rglist.append(masklet)
227 # extract internal mask from the input image
228 else:
229 (parentim, mask)=extractmaskname(masklet)
230 if mask!='':
231 bmasks.append(masklet)
232 else:
233 raise ValueError("%s is not an existing file/image or a region format" % masklet)
235 # expand allows only a string for inpmask
236 if mode=='expand':
237 if type(inpmask)==list:
238 inpmask=inpmask[0]
239 # check for overwrite condition
240 if output=='':
241 if overwrite:
242 output=inpimage
243 else:
244 raise ValueError("output is not specified. If you want to overwrite inpimage, please set overwrite=True")
246 if inpimage==output:
247 #if overwrite:
248 # tmp_outmaskimage=tmp_maskimage
249 #else:
250 if not overwrite:
251 raise ValueError("output=inpimage. If you want to overwrite inpimage, please set overwrite=True")
253 outparentim=output
254 outbmask=''
255 if os.path.isdir(output):
256 if not overwrite:
257 raise RuntimeError("output=%s exists. If you want to overwrite it, please set overwrite=True" % output)
258 else:
259 (outparentim, outbmask)=extractmaskname(output)
260 if outbmask!='':
261 (parentimexist,maskexist)=checkinmask(outparentim,outbmask)
262 if parentimexist and maskexist:
263 if not overwrite:
264 raise ValueError("output=%s exists. If you want to overwrite it, please set overwrite=True" % output)
265 else:
266 casalog.post("Will overwrite the existing internal mask, %s in %s" % (outbmask,outparentim))
267 storeinmask=True
269 #if parentimexist and not maskexist:
270 else:
271 storeinmask = True
272 if not parentimexist: isNewOutfile=True
273 else:
274 outparentim=output
276 #casalog.post("param checks before branching out for mode=========="))
277 #casalog.post("storeinmask = ",storeinmask)
278 #casalog.post("output=",output, " is exist?=",os.path.isdir(output))
279 #casalog.post("outparentim=",outparentim, " is exist?=",os.path.isdir(outparentim))
281 # MAIN PROCESS for 'copy' or 'expand' mode
282 # the following code is somewhat duplicated among the modes but keep separated from each mode
283 # for now.... copy now handle merge as well
284 # === old copy mode === NOW combined to 'merge mode'
285# #if mode=='copy':
286# #casalog.post("Copy mode")
287# needregrid=True
288# #if outimage=='':
289# #overwrite
290# # outimage=inpimage
291#
292# if not os.path.isdir(outimage):
293# needregrid=False
294#
295# if inpmask!='':
296# # need to extract the mask and put in tmp_maskimage
297# pixelmask2cleanmask(imagename=inpimage, maskname=inpmask, maskimage=tmp_maskimage, usemasked=True)
298# else:
299# shutil.copytree(inpimage, tmp_maskimage)
300# if needregrid:
301# casalog.post("Regridding...",'DEBUG1')
302# regridmask(tmp_maskimage,outimage,tmp_outmaskimage)
303# # regrid may produce <1.0 pixels for mask so be sure to its all in 1.0
304# #_ia.open(tmp_outmaskimage)
305# #_ia.calc('iif (%s>0.0 && %s<1.0,1,%s)'%(tmp_outmaskimage,tmp_outmaskimage,tmp_outmaskimage))
306# #_ia.close()
307# #casalog.post("Copying regrid output=",tmp_outmaskimage)
308# else:
309# shutil.copytree(tmp_maskimage,tmp_outmaskimage)
310# if outmask!='':
311# #convert the image mask to T/F mask
312# if not os.path.isdir(outimage):
313# shutil.copytree(inpimage,outimage)
314# #
315# _ia.open(outimage)
316# casalog.post("convert the output image mask to T/F mask")
317# _ia.calcmask(mask='%s<0.5' % tmp_outmaskimage,name=outmask,asdefault=True)
318# _ia.done()
319# else:
320# # if regridded - tmp_outmaskimage is created by regridmask
321# # if not, tmp_outmaskimage=outimage
322# _ia.open(tmp_outmaskimage)
323# _ia.rename(outimage,overwrite=True)
324# _ia.done()
327 # === expand mode ===
328 if mode=='expand':
329 _rg = regionmanager()
330 needtoregrid=False
331 bychanindx=False
333 try:
334 # These coordsys objects will need to be closed, if created
335 incsys = None
336 inmaskcsys = None
337 ocsys = None
339 #casalog.post("expand mode main processing blocks...")
340 # do not allow list in this mode (for inpimage and inpmask) - maybe this is redundant now
341 if type(inpmask)==list:
342 raise TypeError('A list for inpmask is not allowed for mode=expand')
344 # input image info, actually this will be output coordinates
345 _ia.open(inpimage)
346 inshp = _ia.shape()
347 incsys = _ia.coordsys()
348 _ia.close()
349 #casalog.post("inpimage=",inpimage," is exist?=",os.path.isdir(inpimage))
350 #casalog.post(" inshp for inpimage=",inshp)
352 # prepare working input mask image (tmp_maskimage)
353 if debug: casalog.post("prepare working input image (tmp_maskimage)...")
354 if inpmask!='': # inpmask is either image mask or T/F mask now
355 # need to extract the mask and put in tmp_maskimage
356 # Note: changed usemasked=F, so that True (unmasked) part to be used. CAS-
357 # ==> tmp_maskimage is an input mask image
358 (parentimage,bmask)=extractmaskname(inpmask)
359 if bmask!='':
360 pixelmask2cleanmask(imagename=parentimage, maskname=bmask, maskimage=tmp_maskimage, usemasked=False)
361 #_ia.open(tmp_maskimage)
362 else:
363 if debug:
364 casalog.post("parentimage=" + parentimage + " exist?=" + os.path.isdir(parentimage))
365 casalog.post("tmp_maskimage=" + tmp_maskimage + " exist?=" + os.path.isdir(tmp_maskimage))
366 # copy of inpimage in tmp_maskimage
367 _ia.fromimage(outfile=tmp_maskimage, infile=parentimage)
368 else:
369 raise ValueError("inpmask must be specified")
370 if _ia.isopen(): _ia.close()
371 #setting up the output image (copy from inpimage or template)
372 if not os.path.isdir(outparentim):
373 #shutil.copytree(inpimage,tmp_outmaskimage)
374 _ia.fromshape(outfile=tmp_outmaskimage,shape=inshp, csys=incsys.torecord())
375 _ia.close()
376 needtoregrid=False
377 else:
378 # if inpimage == output, tmp_outmaskimage is already created...
379 if not os.path.isdir(tmp_outmaskimage):
380 shutil.copytree(outparentim,tmp_outmaskimage)
381 if debug: casalog.post("done setting up the out image=" + tmp_outmaskimage)
382 # if inpfreq/outfreq are channel indices (int) then
383 # regrid in x y coords only and extract specified channel mask
384 # to specified output channels. (no regriding in spectral axis)
385 # if inpfreqs/outfreqs are velocity or freqs,
386 # it assumes it is expressed in the range with minval~maxval
387 # create subimage of the input mask with the range,
388 # do regrid with the subimage to output.
390 # decide to regrid or not
391 # 1. the case all channels are selected for input and output, simply regrid
392 # 2. if inpfreqs and outfreqs are integers (= channel indices), regrid only in
393 # first and second axes (e.g. ra,dec) and no regridding along spectral axis
394 # 3. if inpfreqs and outfreqs are ranges in freq or vel, make subimage and regrid
395 _ia.open(tmp_maskimage)
396 inmaskshp = _ia.shape()
397 inmaskcsys = _ia.coordsys()
398 _ia.close()
399 regridmethod = 'linear'
400 if 'spectral2' in inmaskcsys.torecord():
401 inspecdelt = inmaskcsys.torecord()['spectral2']['wcs']['cdelt']
402 _ia.open(tmp_outmaskimage)
403 ocsys=_ia.coordsys()
404 oshp=_ia.shape()
405 _ia.close()
406 outspecdelt = ocsys.torecord()['spectral2']['wcs']['cdelt']
407 if outspecdelt < inspecdelt:
408 regridmethod='nearest'
410 if inmaskshp[3]!=1 and ((inpfreqs==[] and outfreqs==[]) \
411 or (inpfreqs=='' and outfreqs=='')):
412 # unless inpimage is continuum, skip chan selection part and regrid
413 needtoregrid=True
414 # detach input(tmp) image and open output tmp image
415 # _ia.open(tmp_outmaskimage)
416 else:
417 # if _ia.isopen():
418 # if _ia.name(strippath=True)!=tmp_maskimage:
419 # _ia.close()
420 # _ia.open(tmp_maskimage)
421 # else:
422 # _ia.open(tmp_maskimage)
424 #if inshp[3]!=1: casalog.post("inpmask is continuum..","INFO")
425 if inmaskshp[3]==1: casalog.post("inpmask is continuum..","INFO")
426 # selection by channel indices (number)
427 # if both inpfreqs and outfreqs are int skip regridding
428 # if outfreqs is vel or freq ranges, try regridding
429 if inpfreqs==[[]] or inpfreqs==[]:
430 # select all channels for input
431 inpfreqs=list(range(inmaskshp[3]))
433 # check inpfreqs and outfreqs types
434 # index based
435 selmode='bychan'
436 if type(inpfreqs)==list:
437 if type(inpfreqs[0])==int:
438 if type(outfreqs)==list and (len(outfreqs)==0 or type(outfreqs[0])==int):
439 selmode='bychan'
440 elif type(outfreqs)==str:
441 #if inpfreqs[0]==0: #contintuum -allow index-type specification
442 if len(inpfreqs)==1: #contintuum -allow index-type specification
443 selmode='byvf'
444 else:
445 raise TypeError("Mixed types in infreqs and outfreqs are not allowed")
446 else:
447 raise TypeError("Non-integer in inpfreq is not supported")
448 # by velocity or frequency
449 elif type(inpfreqs)==str:
450 if type(outfreqs)!=str:
451 raise TypeError("Mixed types in infreqs and outfreqs")
452 selmode='byvf'
453 else:
454 raise TypeError("Wrong type for infreqs")
456 # inpfreqs and outfreqs are list of int
457 # match literally without regridding.
458 if selmode=='bychan':
459 casalog.post("selection of input and output ranges by channel")
461 if _ia.isopen():
462 _ia.close()
463 if outfreqs==[] or outfreqs==[[]]:
464 outchans=[]
465 else:
466 outchans=outfreqs
467 expandchanmask(tmp_maskimage,inpfreqs,tmp_outmaskimage,outchans)
468 _ia.open(tmp_outmaskimage)
470 elif selmode=='byvf': # outfreqs are quantities (freq or vel)
471 casalog.post("selection of input/output ranges by frequencies/velocities")
473 # do it for input mask image (not the template )
474 inpfreqlist = translatefreqrange(inpfreqs,inmaskcsys)
475 #casalog.post("inpfreqlist=",inpfreqlist)
476 # close input image
477 if _ia.isopen():
478 _ia.close()
480 #regrid to output image coordinates
481 if len(inpfreqlist)==1: # continuum
482 #do not regrid, use input image
483 shutil.copytree(tmp_maskimage,tmp_regridim)
484 else:
485 if debug: casalog.post("regrid the mask,tmp_maskimage=" + tmp_maskimage + " tmp_regridim=" + tmp_regridim)
486 #shutil.copytree(tmp_maskimage,'before_regrid_tmp_maskimage')
487 regridmask(tmp_maskimage,inpimage,tmp_regridim,chanrange=inpfreqlist,method=regridmethod)
488 #regridmask(tmp_maskimage,inpimage,tmp_regridim,chanrange=inpfreqlist)
489 # find edge masks (nonzero planes)
490 ##shutil.copytree(tmp_regridim,'saved_'+tmp_regridim)
491 if _ia.isopen(): _ia.close()
492 _ia.open(tmp_regridim)
493 sh=_ia.shape()
494 chanlist = list(range(sh[3]))
495 indlo=0
496 indhi=0
497 for i in chanlist:
498 sl1=[0,0,0,i]
499 sl2=[sh[0]-1,sh[1]-1,sh[2]-1,i]
500 psum = _ia.getchunk(sl1,sl2).sum()
501 pmsum = _ia.getchunk(sl1,sl2,getmask=True).sum()
502 if pmsum!=0 and psum>0.0:
503 indlo=i
504 break
505 chanlist.reverse()
506 for i in chanlist:
507 sl1=[0,0,0,i]
508 sl2=[sh[0]-1,sh[1]-1,sh[2]-1,i]
509 psum = _ia.getchunk(sl1,sl2).sum()
510 if psum>0.0:
511 indhi=i
512 break
513 if indhi < indlo:
514 raise RuntimeError("Incorrectly finding edges of input masks! Probably some logic error in the code!!!")
515 else:
516 casalog.post("Determined non-zero channel range to be "+str(indlo)+"~"+str(indhi), 'DEBUG1')
518 # find channel indices for given outfreqs
519 #_ia.open(tmp_outmaskimage)
520 #ocsys=_ia.coordsys()
521 #oshp=_ia.shape()
522 outfreqlist = translatefreqrange(outfreqs,ocsys)
523 rtn=ocsys.findcoordinate('spectral')
524 px=rtn['pixel'][0]
525 wc=rtn['world'][0]
526 world=ocsys.referencevalue()
527 # assume chanrange are in freqs
528 world['numeric'][wc]=_qa.convert(_qa.quantity(outfreqlist[0]),'Hz')['value']
529 p1 = ocsys.topixel(world)['numeric'][px]
530 world['numeric'][wc]=_qa.convert(_qa.quantity(outfreqlist[1]),'Hz')['value']
531 p2 = ocsys.topixel(world)['numeric'][px]
532 casalog.post("translated channel indices:"+_qa.tos(outfreqlist[0])+"->p1="+str(p1)+\
533 " "+_qa.tos(outfreqlist[0])+"-> p2="+str(p2))
534 if len(inpfreqs)==1:
535 inpfreqchans=inpfreqs
536 elif inpfreqs.find('~'):
537 inpfreqchans=list(range(indlo,indhi+1))
538 else:
539 inpfreqchans=[indlo,indhi]
540 outfreqchans=list(range(int(round(p1)),int(round(p2))+1))
541 #casalog.post("inpfreqchans=",inpfreqchans)
542 #casalog.post("outfreqchans=",outfreqchans)
543 expandchanmask(tmp_regridim,inpfreqchans,tmp_outmaskimage,outfreqchans)
544 #shutil.copytree(tmp_regridim,'my_tmp_regrid')
545 #shutil.copytree(tmp_outmaskimage,'my_tmp_outmaskimage')
547# usechanims={} # list of input mask to be use for each outpfreq
548# for i in outfreqchans:
549# nearestch = findnearest(inpfreqchans,i)
550# usechanims[i]=nearestch
551# # put masks from inp image channel by channel
552# for j in outfreqs:
553# pix = refchanchunk[usechanims[j]-refchanst]
554# #_ia.putchunk(pixels=pix,blc=[inshp[0]-1,inshp[1]-1,0,j])
555# _ia.putchunk(pixels=pix.transpose(),blc=[0,0,0,j])
556 needtoregrid=False
558 if _ia.isopen(): _ia.close()
559 _ia.open(tmp_outmaskimage)
560 #
562 if needtoregrid:
563 # closing current output image
564 if _ia.isopen():
565 _ia.close()
566 _ia.open(tmp_maskimage)
567 #os.system('cp -r %s beforeregrid.im' % tmp_maskimage)
568 if os.path.isdir(tmp_outmaskimage):
569 #casalog.post("Removing %s" % tmp_outmaskimage)
570 shutil.rmtree(tmp_outmaskimage)
571 #regridmask(tmp_maskimage,outparentim,tmp_outmaskimage)
572 regridmask(tmp_maskimage,inpimage,tmp_outmaskimage,method=regridmethod)
573 _ia.remove()
574 #casalog.post("closing after regrid")
575 _ia.open(tmp_outmaskimage) # reopen output tmp image
577 # for debugging
578 #os.system('cp -r '+outparentim+" expandmode-copy-"+outparentim)
579 #os.system('cp -r '+tmp_outmaskimage+" expandmode-copy-"+tmp_outmaskimage)
580 if outbmask!='':
581 #convert the image mask to T/F mask
582 casalog.post("Convert the image mask to T/F mask",'INFO')
583 # regions will be masked if == 0.0 for a new outfile, if outfile exists
584 # the pixel values inside specified mask is preserved and the rest is masked
585 if os.path.isdir(outparentim):
586 _ia.calcmask(mask='%s==1.0' % tmp_outmaskimage,name=outbmask,asdefault=True)
587 else:
588 _ia.calcmask(mask='%s!=0.0' % tmp_outmaskimage,name=outbmask,asdefault=True)
589 if storeinmask:
590 isNewFile=False
591 if not os.path.isdir(outparentim):
592 makeEmptyimage(inpimage,outparentim)
593 isNewFile=True
594 _ia.open(outparentim)
595 if isNewFile:
596 _ia.set(1)
597 # if output image exist its image pixel values will not be normalized the region
598 # outside input mask will be masked.
599 #check
600 curinmasks = _ia.maskhandler('get')
601 if outbmask in curinmasks:
602 if not overwrite:
603 raise RuntimeError("Internal mask,"+outbmask+" exists. Please set overwrite=True.")
604 else:
605 _ia.maskhandler('delete',outbmask)
607 _ia.maskhandler('copy',[tmp_outmaskimage+':'+outbmask, outbmask])
608 _ia.maskhandler('set',outbmask)
609 _ia.done()
610 casalog.post("Output the mask to %s in %s" % (outbmask,outparentim) ,"INFO")
611 else:
612 ow = False
613 if inpimage==output:
614 casalog.post("Updating "+output+" with new mask","INFO")
615 ow=True
616 else:
617 if os.path.isdir(outparentim):
618 casalog.post(outparentim+" exists, overwriting","INFO")
619 ow=True
620 else:
621 casalog.post("Output the mask to "+outparentim ,"INFO")
622 _ia.rename(outparentim,ow)
623 _ia.done()
625 except Exception as instance:
626 casalog.post("*** Error (1) *** %s" % instance, 'ERROR')
627 if _ia.isopen():
628 _ia.close()
629 _ia.done()
630 raise
631 finally:
632 if inmaskcsys:
633 inmaskcsys.done()
634 if incsys:
635 incsys.done()
636 if ocsys:
637 ocsys.done()
638 if os.path.exists(tmp_maskimage):
639 shutil.rmtree(tmp_maskimage)
640 if os.path.exists(tmp_regridim):
641 shutil.rmtree(tmp_regridim)
642 if os.path.exists(tmp_outmaskimage):
643 shutil.rmtree(tmp_outmaskimage)
645 # === main process for copy mode: also does merge of masks ===
646 # copy is a just special case of merge mode
647 # CHANGE:
648 # all input masks should be specified in inpmask
649 # type of inpmask accepted: 1/0 mask, T/F mask, region file, and region expression in a string
650 # already stored internally in seperate lists
651 # rgfiles - region files (binary or CRTF-format text file)
652 # imgfiles - 1/0 image masks
653 # rglist - region expression in strings
654 # bmasks - T/F internal masks
655 #
656 # avaialble parameters: inpimage (string) , inpmask (list/string), output(string)
657 # input inpimage as a template or image used for defining regions when it is given in inpmask
658 # inpmask as list of all the masks to be merged (image masks, T/F internal masks, regions)
660 if mode=='copy':
661 sum_tmp_outfile='__tmp_outputmask_'+pid
662 tmp_inmask='__tmp_frominmask_'+pid
663 tmp_allrgmaskim='__tmp_fromAllRgn_'+pid
664 tmp_rgmaskim='__tmp_fromRgn_'+pid
665 # making sure to remove pre-existing temp files
666 cleanuptempfiles([sum_tmp_outfile, tmp_inmask, tmp_allrgmaskim, tmp_rgmaskim])
667 usedimfiles=[]
668 usedbmasks=[]
669 usedrgfiles=[]
670 usedrglist=[]
671 # This coordsys object used in several places below will need to be closed, if created
672 tcsys = None
673 try:
674 # check outparentim - image part of output and set as a template image
675 if not (os.path.isdir(outparentim) or (outparentim==inpimage)):
676 # Output is either a new image or the same as inpimage
678 # figure out which input mask to be used as template
679 # if inpimage is defined use the first one else try the first one
680 # inpmask
681 #if output=='':
682 # if type(inpimage)==list:
683 # raise Exception, "inputimage must be a string"
684 # elif type(inpimage)==str:
685 # outimage=inpimage
686 # casalog.post("No outimage is specified. Will overwrite input image: "+outimage,'INFO')
688 #if type(inpimage)==list and len(inpimage)!=0:
689 # tmp_template=inpimage[0]
690 #elif inpimage!='' and inpimage!=[]:
691 # tmp_template=inpimage # string
692 #tmp_template=inpimage # string
693 #else:
694 # if type(inpmask)==list and len(inpmask)!=0:
695 # fsep=inpmask[0].rfind(':')
696 # if fsep ==-1:
697 # raise IOError, "Cannot resolve inpmask name, check the format"
698 # else:
699 # tmp_template=inpmask[0][:inpmask[0].rfind(':')]
700 # elif inpmask!='' and inpmask!=[]:
701 # # this is equivalent to 'copy' the inpmask
702 # tmp_template=inpmask #string
704 # create an empty image with the coords from inpimage
705 makeEmptyimage(inpimage,sum_tmp_outfile)
706 #casalog.post("making an empty image from inpimage to sum_tmp_outfile")
707 else:
708 #use output image(either the same as the input image or other existing image)
709 # - does not do zeroeing out, so output image is only modified *for outbmask!=''*
710 shutil.copytree(outparentim,sum_tmp_outfile)
711 # temporary clear out the internal masks from the working image
712 if _ia.isopen(): _ia.close()
713 _ia.open(sum_tmp_outfile)
714 if (len(imgfiles) or len(rglist) or len(rgfiles)):
715 # do zeroeing out working base image for masks
716 _ia.set(0)
717 origmasks = _ia.maskhandler('get')
718 _ia.maskhandler('delete',origmasks)
719 _ia.close()
721 if len(imgfiles)>0:
722 # summing all the images
723 casalog.post('Summing all mask images in inpmask and normalized to 1 for mask','INFO')
724 for img in imgfiles:
725 #tmpregrid='__tmp_regrid.'+img
726 dirname = os.path.dirname(img)
727 basename = os.path.basename(img)
728 tmpregrid= dirname+'/'+'__tmp_regrid.'+basename if len(dirname) else '__tmp_regrid.'+basename
729 tmpregrid+='_'+pid
730 if os.path.exists(tmpregrid):
731 shutil.rmtree(tmpregrid)
732 # regrid to output image coords
733 try:
734 regridmask(img,sum_tmp_outfile,tmpregrid)
735 addimagemask(sum_tmp_outfile,tmpregrid)
736 usedimfiles.append(img)
737 finally:
738 shutil.rmtree(tmpregrid)
739 # get boolean masks
740 # will work in image(1/0) masks
742 if debug:
743 casalog.post(("imgfiles=" + imgfiles))
744 shutil.copytree(sum_tmp_outfile,sum_tmp_outfile+"_imagemaskCombined")
746 if len(bmasks)>0:
747 casalog.post('Summing all T/F mask in inpmask and normalized to 1 for mask','INFO')
748 for msk in bmasks:
749 (imname,mskname) = extractmaskname(msk)
750 #if msk.find(':')<0:
751 # # assume default mask
752 # msk=msk+':mask0'
753 #imname=msk[:msk.rfind(':')]
754 if _ia.isopen(): _ia.close()
755 _ia.open(imname)
756 inmasks=_ia.maskhandler('get')
757 _ia.close()
758 if not inmasks.count(mskname):
759 raise TypeError(mskname+" does not exist in "+imname+" -available masks:"+str(inmasks))
760 # move T/F mask to image mask
761 # changed to usemasked=False as of CAS-5443
763 pixelmask2cleanmask(imname, mskname, tmp_inmask, False)
764 cleanuptempfiles(['__tmp_fromTFmask_'+pid])
765 regridmask(tmp_inmask,sum_tmp_outfile,'__tmp_fromTFmask_'+pid)
766 # for T/F mask do AND operation
767 _ia.open(sum_tmp_outfile)
768 if _ia.statistics()['sum'][0] != 0:
769 multiplyimagemask(sum_tmp_outfile,'__tmp_fromTFmask_'+pid)
770 else:
771 addimagemask(sum_tmp_outfile,'__tmp_fromTFmask_'+pid)
772 _ia.close()
773 usedbmasks.append(msk)
774 # need this temp file for the process later
775 ###shutil.rmtree('__tmp_fromTFmask')
776 if os.path.isdir(tmp_inmask):
777 shutil.rmtree(tmp_inmask)
778 # if overwriting to inpimage and if not writing to in-mask, delete the boolean mask
779 if outparentim==inpimage and inpimage==imname:
780 if outbmask=="":
781 _ia.open(imname)
782 _ia.maskhandler('delete',[mskname])
783 _ia.close()
784 _ia.open(imname)
785 _ia.close()
787 if debug: casalog.post("check rgfiles and rglist")
789 if len(rgfiles)>0 or len(rglist)>0:
790 # create an empty image with input image coords.
791 #casalog.post("Using %s as a template for regions" % inpimage )
792 if _ia.isopen(): _ia.close()
793 _ia.open(inpimage)
794 tshp=_ia.shape()
795 tcsys=_ia.coordsys()
796 _ia.fromshape(tmp_allrgmaskim,shape=tshp, csys=tcsys.torecord(),overwrite=True)
797 _ia.done()
798 if os.path.isdir(tmp_rgmaskim):
799 shutil.rmtree(tmp_rgmaskim)
800 shutil.copytree(tmp_allrgmaskim,tmp_rgmaskim)
802 if len(rgfiles)>0:
803 # Here only CRTF format file is expected
804 nrgn=0
805 for rgn in rgfiles:
806 subnrgn=0
807 with open(rgn) as f:
808 # check if it has '#CRTF' in the first line
809 firstline=f.readline()
810 if firstline.count('#CRTF')==0:
811 raise Exception("Input text file does not seems to be in a correct format \
812 (must contains #CRTF in the first line)")
813 else:
814 try:
815 # reset temp mask image
816 if _ia.isopen(): _ia.close()
817 _ia.open(tmp_rgmaskim)
818 _ia.set(pixels=0.0)
819 _ia.close()
820 #casalog.post... "tshp=",tshp
821 #casalog.post... "tcsys.torecord=",tcsys.torecord()
822 inrgn=_rg.fromtextfile(rgn, tshp, tcsys.torecord())
823 #casalog.post... "inrgn=",inrgn
824 _im.regiontoimagemask(tmp_rgmaskim,region=inrgn)
825 addimagemask(tmp_allrgmaskim,tmp_rgmaskim)
826 #shutil.rmtree(tmp_rgmaskim)
827 subnrgn +=1
828 nrgn +=1
829 except:
830 break
831 if subnrgn>0:
832 usedrgfiles.append(rgn)
833 casalog.post("Converted %s regions from %s region files to image mask" % (nrgn,len(rgfiles)),"INFO")
835 if debug: casalog.post("processing rglist...")
836 if len(rglist)>0:
837 #casalog.post( "Has rglist...")
838 nrgn=0
839 for rgn in rglist:
840 # reset temp mask image
841 if _ia.isopen(): _ia.close()
842 _ia.open(tmp_rgmaskim)
843 _ia.set(pixels=0.0)
844 _ia.close()
845 inrgn=_rg.fromtext(rgn, tshp, tcsys.torecord())
846 _im.regiontoimagemask(tmp_rgmaskim,region=inrgn)
847 addimagemask(tmp_allrgmaskim,tmp_rgmaskim)
848 #shutil.rmtree(tmp_rgmaskim)
849 usedrglist.append(rgn)
850 nrgn+=1
851 casalog.post("Converted %s regions to image mask" % (nrgn),"INFO")
854 if debug: casalog.post("Regirdding...")
855 # regrid if necessary
856 regridded_mask='__tmp_regrid_allrgnmask_'+pid
857 regridmask(tmp_allrgmaskim, sum_tmp_outfile,regridded_mask)
858 addimagemask(sum_tmp_outfile,regridded_mask)
859 #shutil.rmtree('__tmp_regridded_allrgnmask')
860 casalog.post("Added mask based on regions to output mask","INFO")
861 #cleanup
862 for tmpfile in [tmp_allrgmaskim,tmp_rgmaskim,regridded_mask]:
863 if os.path.isdir(tmpfile):
864 shutil.rmtree(tmpfile)
866 # merge the bmasks with AND
867 if os.path.exists('__tmp_fromTFmask_'+pid) and len(bmasks)>0:
868 if _ia.isopen(): _ia.close()
869 _ia.open(sum_tmp_outfile)
870 if _ia.statistics()['sum'][0]!=0:
871 multiplyimagemask(sum_tmp_outfile,'__tmp_fromTFmask_'+pid)
872 else:
873 addimagemask(sum_tmp_outfile,'__tmp_fromTFmask_'+pid)
874 _ia.done()
875 shutil.rmtree('__tmp_fromTFmask_'+pid)
876 if outbmask!='':
877 casalog.post('Putting mask in T/F','INFO')
878 if _ia.isopen(): _ia.close()
879 try:
880 _ia.open(sum_tmp_outfile)
881 _ia.calcmask(mask='%s==1.0' % sum_tmp_outfile,name=outbmask,asdefault=True)
882 # mask only pixel == 0.0 (for a new outfile), mask region !=1.0 and preserve
883 # the pixel values if outfile exists
884 #if os.path.isdir(outparentim):
885 # _ia.calcmask(mask='%s==1.0' % sum_tmp_outfile,name=outbmask,asdefault=True)
886 #else:
887 # _ia.calcmask(mask='%s!=0.0' % sum_tmp_outfile,name=outbmask,asdefault=True)
888 finally:
889 _ia.done()
890 if debug: shutil.copytree(sum_tmp_outfile,sum_tmp_outfile+"_afterCoverttoTFmask")
891 # if outfile exists initially outfile is copied to sum_tmp_outfile
892 # if outfile does not exist initially sum_tmp_outfile is a copy of inpimage
893 # so rename it with overwrite=T all the cases
894 #casalog.post("open sum_tmp_outfile=",sum_tmp_outfile)
895 if storeinmask:
896 if debug: casalog.post("Storeinmask......")
897 # by a request in CAS-6912 no setting of 1 for copying mask to the 'in-mask'
898 # (i.e. copy the values of inpimage as well for this mode)
899 # Replace
900 #isNewfile = False
901 #if not os.path.isdir(outparentim):
902 if isNewOutfile:
903 #makeEmptyimage(inpimage,outparentim)
904 #isNewfile=True
906 shutil.copytree(inpimage,outparentim)
907 if _ia.isopen(): _ia.close()
908 _ia.open(outparentim)
909 if isNewOutfile:
910 oldmasklist = _ia.maskhandler('get')
911 if oldmasklist[0]!='T':
912 # clean up existing internal masks for the copied image
913 if outbmask in oldmasklist:
914 _ia.maskhandler('delete',outbmask)
915 if (maskexist and overwrite):
916 if debug: casalog.post("outbmask=" + outbmask + " exists... deleting it")
917 _ia.maskhandler('delete',outbmask)
918 _ia.maskhandler('copy',[sum_tmp_outfile+':'+outbmask, outbmask])
919 _ia.maskhandler('set',outbmask)
920 _ia.done()
921 outputmsg="to create an output mask: %s in %s" % (outbmask,outparentim)
922 else:
923 if debug: casalog.post("store as an image mask......")
924 if _ia.isopen(): _ia.close()
925 _ia.open(sum_tmp_outfile)
926 _ia.rename(outparentim,overwrite=True)
927 _ia.done()
928 outputmsg="to create an output mask: %s " % outparentim
930 casalog.post("Merged masks from:","INFO")
931 if len(usedimfiles)>0:
932 casalog.post("mask image(s): "+str(usedimfiles),"INFO")
933 if len(usedbmasks)>0:
934 casalog.post("internal mask(s): "+str(usedbmasks),"INFO")
935 if len(usedrgfiles)>0:
936 casalog.post("region txt file(s): "+str(usedrgfiles),"INFO")
937 if len(usedrglist)>0:
938 casalog.post("region(s) from direct input: "+str(usedrglist),"INFO")
939 casalog.post(outputmsg,"INFO")
941 except Exception as instance:
942 raise RuntimeError("*** Error (2), in mode copy: *** %s" % instance)
943 finally:
944 if os.path.exists(sum_tmp_outfile):
945 shutil.rmtree(sum_tmp_outfile)
946 if os.path.exists(tmp_inmask):
947 shutil.rmtree(tmp_inmask)
948 if os.path.exists(tmp_allrgmaskim):
949 shutil.rmtree(tmp_allrgmaskim)
950 if os.path.exists(tmp_rgmaskim):
951 shutil.rmtree(tmp_rgmaskim)
952 if tcsys:
953 tcsys.done()
956 if type(inpimage)==list:
957 for im in inpimage:
958 basename = os.path.basename(im)
959 dirname = os.path.dirname(im)
960 tempregridname = dirname+'/__tmp_regrid.'+basename if len(dirname) else '__tmp_regrid.'+basename
961 tempregridname+='_'+pid
962 if os.path.isdir(tempregridname):
963 shutil.rmtree(tempregridname)
967 # === draw mode ===
968 # disabled - drawmaskinimage (working with viewer) a bit flaky
969 # when run in succession.
970 # if mode=='draw':
971 # #call drawmaskinimage
972 # from recipes.drawmaskinimage import drawmaskinimage
973 # drawmaskinimage(inpimage,outmask)
976 finally:
977 # final clean up
978 if os.path.isdir(tmp_maskimage):
979 shutil.rmtree(tmp_maskimage)
980 if os.path.isdir(tmp_outmaskimage):
981 shutil.rmtree(tmp_outmaskimage)
982 if os.path.isdir(tmp_regridim):
983 shutil.rmtree(tmp_regridim)
984 if os.path.exists('__tmp_fromTFmask_'+pid):
985 shutil.rmtree('__tmp_fromTFmask_'+pid)
987def findnearest(arr, val):
988 if type(arr)==list:
989 arr = np.array(arr)
990 indx = np.abs(arr - val).argmin()
991 return arr[indx]
993def regridmask(inputmask,template,outputmask,axes=[3,0,1],method='linear',chanrange=None):
994 '''
995 Regrid input mask (image) to output mask using a template.
996 Currently the template must be a CASA image.
997 The default interpolation method is set to 'linear' (since 'nearest'
998 sometime fails).
999 '''
1000 #casalog.post("Regrid..")
1001 #casalog.post("inputmask=",inputmask," template=",template," outputmask=",outputmask)
1002 if not os.path.isdir(template):
1003 raise OSError("template image %s does not exist" % template)
1005 _ia = image()
1006 try:
1007 _tb = table()
1008 inputmaskcopy = "_tmp_copy_"+os.path.basename(inputmask)
1009 cleanuptempfiles([inputmaskcopy])
1010 shutil.copytree(inputmask,inputmaskcopy)
1011 _ia.open(template)
1012 ocsys = _ia.coordsys()
1013 oshp = _ia.shape()
1014 finally:
1015 _ia.done()
1016 _tb.open(template)
1017 defTelescope = _tb.getkeywords()['coords']['telescope']
1018 _tb.close()
1019 _tb.open(inputmaskcopy, nomodify=False)
1020 keys = _tb.getkeywords()
1021 if keys['coords']['telescope']=="UNKNOWN":
1022 if defTelescope =="UNKNOWN":
1023 raise ValueError("UNKNOWN Telescope for %s " % inputmask)
1024 else:
1025 keys['coords']['telescope']=defTelescope
1026 _tb.putkeywords(keys)
1027 _tb.close()
1029 if _ia.isopen(): _ia.close()
1030 _ia.open(inputmaskcopy)
1031 # check axis order, if necessary re-interprete input axes correctly
1032 # assumed order of axes
1033 reforder=['Right Ascension', 'Declination', 'Stokes', 'Frequency']
1034 axisorder=_ia.summary(list=False)['axisnames'].tolist()
1035 # check if all 4 axes exist
1036 errmsg = ""
1037 for axname in reforder:
1038 if axisorder.count(axname) == 0:
1039 errmsg += axname+" "
1040 if len(errmsg) != 0:
1041 errmsg = "There is no "+errmsg+" axes inpimage. ia.adddegaxis or importfits with defaultaxes=True can solve this problem"
1042 raise Exception(errmsg)
1044 tmp_axes=[]
1045 for axi in axes:
1046 tmp_axes.append(axisorder.index(reforder[axi]))
1047 axes=tmp_axes
1048 if type(chanrange)==list and len(chanrange)==2:
1049 incsys=_ia.coordsys()
1050 spaxis=incsys.findcoordinate('spectral')['world']
1051 # create subimage based on the inpfreqs range
1052 inblc=chanrange[0]
1053 intrc=chanrange[1]
1054 casalog.post("Regridmask: spaxis=%s, inblc=%s, intrc=%s" % (spaxis,inblc,intrc), 'DEBUG1')
1055 rgn = _rg.wbox(blc=inblc,trc=intrc,pixelaxes=spaxis.tolist(),csys=incsys.torecord())
1056 incsys.done()
1057 else:
1058 rgn={}
1059 # for continuum case
1060 ir = None
1061 if oshp[tmp_axes[0]]==1:
1062 axes=[0,1]
1063 try:
1064 #check for an appropriate decimation factor
1065 min_axlen=min(oshp[:2])
1066 if min_axlen < 30:
1067 decfactor=min_axlen//3
1068 if decfactor==0: decfactor=1
1069 else:
1070 decfactor=10
1071 ir=_ia.regrid(outfile=outputmask,shape=oshp,csys=ocsys.torecord(),axes=axes,region=rgn,method=method,decimate=decfactor)
1073 except:
1074 pass
1075 finally:
1076 ocsys.done()
1077 _ia.remove()
1078 _ia.done()
1079 # to ensure to create 1/0 mask image
1080 #ir.calc('iif (%s>0.0 && %s<1.0,1,%s)'%(outputmask,outputmask,outputmask))
1081 # treat everything not = 0.0 to be mask
1082 if (ir):
1083 try:
1084 ir.calc('iif (abs("%s")>0.0,1,"%s")'%(outputmask,outputmask),False)
1085 finally:
1086 ir.done()
1087 if os.path.isdir(inputmaskcopy):
1088 shutil.rmtree(inputmaskcopy)
1090def addimagemask(sumimage, imagetoadd, threshold=0.0):
1091 """
1092 add image masks (assumed the images are already in the same coordinates)
1093 """
1094 _ia = image()
1095 try:
1096 #casalog.post("addimagemask: sumimage=",sumimage," imagetoadd=",imagetoadd)
1097 _ia.open(sumimage)
1098 _ia.calc('iif ("'+imagetoadd+'">'+str(threshold)+',("'+sumimage+'"+"'+imagetoadd+'")/("'+sumimage+'"+"'+imagetoadd+'"),"'+sumimage+'")',False)
1099 # actually should be AND?
1100 #_ia.calc('iif ('+imagetoadd+'>'+str(threshold)+','+sumimage+'*'+imagetoadd+','+sumimage+')')
1101 #_ia.calc('iif ('+imagetoadd+'>'+str(threshold)+',('+sumimage+'*'+imagetoadd+')/('+sumimage+'*'+imagetoadd+'),'+sumimage+')')
1102 finally:
1103 _ia.close()
1105def multiplyimagemask(sumimage, imagetomerge):
1106 """
1107 multiple image masks (do AND operation, assumed the images are already in the same coordinates)
1108 to use for merging of two image masks originated from T/F masks or merging between mask image
1109 and a T/F mask originated mask image
1110 """
1111 _ia = image()
1112 try:
1113 _ia.open(sumimage)
1114 _ia.calc('iif ("'+imagetomerge+'"!=0.0,("'+sumimage+'"*"'+imagetomerge+'"),0.0 )',False)
1115 _ia.calc('iif ("'+sumimage+'"!=0.0,("'+sumimage+'")/("'+sumimage+'"),"'+sumimage+'")',False)
1116 finally:
1117 _ia.close()
1119def expandchanmask(inimage,inchans,outimage,outchans):
1120 """
1121 expand masks in channel direction,and insert then
1122 to output image with the same coordinates (post-regridded)
1123 only differ by channels
1124 """
1125 _ia = image()
1126 # input image
1127 _ia.open(inimage)
1128 inshp=_ia.shape()
1129 refchanst=inchans[0]
1130 refchanen=inchans[-1]
1131 #casalog.post("refchanst=",refchanst," refchanen=",refchanen," inshp=",inshp," inchans=",inchans)
1132 slst = [0,0,0,refchanst]
1133 slen = [inshp[0]-1,inshp[1]-1,0,refchanen]
1134 casalog.post("getting chunk at blc="+str(slst)+" trc="+str(slen),'DEBUG1')
1135 refchanchunk=_ia.getchunk(blc=slst,trc=slen)
1136 refchanchunk=refchanchunk.transpose()
1137 _ia.close()
1138 #casalog.post("refchanchunk:shape=",refchanchunk.shape)
1140 _ia.open(outimage)
1141 # need find nearest inchan
1142 # store by chan indices (no regrid)
1143 outshp=_ia.shape()
1144 if outchans==[]:
1145 #select all channels
1146 outchans=list(range(outshp[3]))
1147 usechanims={} # list of input mask to be use for each outpfreq
1148 for i in outchans:
1149 nearestch = findnearest(inchans,i)
1150 usechanims[i]=nearestch
1151 #casalog.post("usechanims=",usechanims)
1152 casalog.post("Mapping of channels: usechanims="+str(usechanims),'DEBUG1')
1153 for j in outchans:
1154 pix = refchanchunk[usechanims[j]-refchanst]
1155 #casalog.post("pix=",pix)
1156 #casalog.post("pix.shape=",pix.shape)
1157 #casalog.post("inshp=",inshp, ' j=',j)
1158 #_ia.putchunk(pixels=pix,blc=[inshp[0]-1,inshp[1]-1,0,j])
1159 _ia.putchunk(pixels=pix.transpose(),blc=[0,0,0,j])
1160 #casalog.post("DONE putchunk for j=", j)
1161 _ia.done()
1163def translatefreqrange(freqrange,csys):
1164 """
1165 convert the range in list
1166 mainly for frequeny and velocity range determination
1167 """
1168 if type(freqrange)==list and type(freqrange[0])==int:
1169 #do nothing
1170 return freqrange
1171 elif type(freqrange)==str:
1172 freqlist=freqrange.split('~')
1173 for i in list(range(len(freqlist))):
1174 if freqlist[i].find('m/s') > -1:
1175 fq = _qa.quantity(freqlist[i])
1176 vf=csys.velocitytofrequency(value=fq['value'],velunit=fq['unit'])
1177 freqlist[i]=str(vf[0])+'Hz'
1178 return freqlist
1179 else:
1180 raise TypeError("Cannot understand frequency range")
1182def checkinput(inpname):
1183 """
1184 do existance check on image and internal mask
1185 """
1186 _ia = image()
1187 (parentimage,tfmaskname)=extractmaskname(inpname)
1188 (parentimexist,tfmaskexist)=checkinmask(parentimage,tfmaskname)
1189 if parentimexist:
1190 if tfmaskname=='':
1191 return True # only the image
1192 else:
1193 if not tfmaskexist:
1194 _ia.open(parentimage)
1195 inmasklist=_ia.maskhandler('get')
1196 _ia.close()
1197 raise Exception("Cannot find the internal mask, %s. Candidate mask(s) are %s" % (tfmaskname, str(inmasklist)))
1198 else:
1199 return True # image mask and internal mask
1200 else:
1201 raise Exception("Cannot find the image=%s" % parentimage)
1204def checkinmask(parentimage,tfmaskname):
1205 """
1206 check existance of the internal mask
1207 """
1208 _ia = image()
1209 if os.path.isdir(parentimage):
1210 if tfmaskname!='':
1211 _ia.open(parentimage)
1212 inmasks=_ia.maskhandler('get')
1213 _ia.done()
1214 if not any(tfmaskname in msk for msk in inmasks):
1215 return (True, False)
1216 else:
1217 return (True, True) # image mask and internal mask
1218 else:
1219 return (True, False)
1220 else:
1221 return (False,False)
1223def extractmaskname(maskname):
1224 """
1225 split out imagename and maskname from a maskname string
1226 returns (parentimage, internalmask)
1227 """
1228 # the image file name may contains ':' some cases
1229 # take last one in split list as an internal mask name
1231 # Try to avoid issues with ':' included in paths when given absolute paths
1232 dirname = None
1233 if os.path.isabs(maskname):
1234 dirname = os.path.dirname(maskname)
1235 maskname = os.path.basename(maskname)
1237 indx = maskname.find(':')
1238 for i in list(range(len(maskname))):
1239 if indx>-1:
1240 indx += maskname[indx+1:].find(':')
1241 indx +=1
1242 else:
1243 break
1244 if indx != -1:
1245 parentimage = maskname[:indx]
1246 maskn = maskname[indx+1:]
1247 else:
1248 parentimage = maskname
1249 maskn = ''
1251 if dirname:
1252 parentimage = os.path.join(dirname, parentimage)
1254 return (parentimage, maskn)
1256def makeEmptyimage(template,outimage):
1257 """
1258 make an empty image with the coords
1259 from template
1260 """
1262 _ia = image()
1263 _ia.open(template)
1264 inshp=_ia.shape()
1265 incsys=_ia.coordsys()
1266 _ia.fromshape(outimage,shape=inshp,csys=incsys.torecord())
1267 incsys.done()
1268 _ia.done()
1270def cleanuptempfiles(tempfilelist):
1271 """
1272 clean up tempfilelist
1273 """
1274 for fn in tempfilelist:
1275 if os.path.isdir(fn):
1276 shutil.rmtree(fn)
1277 elif os.path.isfile(fn):
1278 os.remove(fn)