casa
$Rev:20696$
|
00001 ########################################################################3 00002 # task_immath.py 00003 # 00004 # Copyright (C) 2008, 2009 00005 # Associated Universities, Inc. Washington DC, USA. 00006 # 00007 # This script is free software; you can redistribute it and/or modify it 00008 # under the terms of the GNU Library General Public License as published by 00009 # the Free Software Foundation; either version 2 of the License, or (at your 00010 # option) any later version. 00011 # 00012 # This library is distributed in the hope that it will be useful, but WITHOUT 00013 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00014 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00015 # License for more details. 00016 # 00017 # You should have received a copy of the GNU Library General Public License 00018 # along with this library; if not, write to the Free Software Foundation, 00019 # Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 00020 # 00021 # Correspondence concerning AIPS++ should be adressed as follows: 00022 # Internet email: aips2-request@nrao.edu. 00023 # Postal address: AIPS++ Project Office 00024 # National Radio Astronomy Observatory 00025 # 520 Edgemont Road 00026 # Charlottesville, VA 22903-2475 USA 00027 # 00028 # <summary> 00029 # CASA task for smoothing an image, by doing Forier-based convolution 00030 # on a CASA image file. 00031 # </summary> 00032 # 00033 # <reviewed reviwer="" date="" tests="" demos=""> 00034 # </reviewed 00035 # 00036 # <author> 00037 # Shannon Jaeger, University of Calgary (image math) 00038 # Takeshi Nakazato, National Radio Astronomy Obaservatory (polarization) 00039 # </author> 00040 # 00041 # <prerequisite> 00042 # </prerequisite> 00043 # 00044 # <etymology> 00045 # immath stands for image mathematics 00046 # </etymology> 00047 # 00048 # <synopsis> 00049 # This task evaluates mathematical expressions involving existing 00050 # image files. The results of the calculations are stored in the 00051 # designated output file. Options are available to specify mathematical 00052 # expression directly or pre-defined expression for calculation of 00053 # spectral index image, and polarization intensity and position angle 00054 # images are available. The image file names imbedded in the expression or 00055 # specified in the imagename parameter for the pre-defined calculations may 00056 # be CASA images or FITS images. 00057 # 00058 # 00059 # NOTE: Index values for axes start at 0 for the box and chans 00060 # parameters, but at 1 when used with the indexin function 00061 # in expression. Use the imhead task to see the range of 00062 # values for each axes. 00063 # 00064 # 00065 # Keyword arguments: 00066 # outfile -- The file where the results of the image calculations 00067 # are stored. Overwriting an existing outfile is not permitted. 00068 # Default: none; Example: outfile='results.im' 00069 # mode -- mode for mathematical operation 00070 # Default: evalexpr 00071 # Options: 'evalexpr' : evalulate a mathematical expression defined in 'expr' 00072 # 'spix' : spectalindex image 00073 # 'pola' : polarization position angle image 00074 # 'poli' : polarization intesity image 00075 # mode expandable parameters 00076 # expr -- (for mode='evalexpr') A mathematical expression, with image file names. 00077 # Image file names MUST be enclosed in double quotes (") 00078 # Default: none 00079 # Examples: 00080 # Make an image that is image1.im - image2.im 00081 # expr=' ("image1.im" - "image2.im" )' 00082 # Clip an image below a value (0.5 in this case) 00083 # expr = ' iif("image1.im">=0.5, "image1.im", 0.0) ' 00084 # Note: iif (a, b, c) a is the boolian expression 00085 # b is the value if true 00086 # c is the value if false 00087 # Take the rms value of two images 00088 # expr = ' sqrt("image1.im" * "image1.im" + "image2.im" * "image2.im") ' 00089 # Note: No exponentiaion available? 00090 # Build an image pixel by pixel from the minimum of (image2.im, 2*image1.im) 00091 # expr='min("image2.im",2*max("image1.im"))' 00092 # imagename -- (for mode='spix','pola','poli') input image names 00093 # Default: none; 00094 # Examples: mode='spix'; imagename=['image1.im','image2.im'] will calculate 00095 # an image of log(S1/S2)/log(f1/f2), where S1 and S2 are fluxes and 00096 # f1 and f2 are frequencies 00097 # mode='pola'; imagename=['imageQ.im','imageU.im'] will calculate 00098 # an image of polarization angle distribution, where imageQ.im and 00099 # imageU.im are Stokes Q and U images, respectively. Calculate 0.5*arctan(U/Q). 00100 # mode='poli'; imagename=['imageQ.im','imageU.im','imageV.im'] will calculate 00101 # total polarization intensity image, where imageQ.im, imageU.im, imageV.im 00102 # are Stokes Q, U, and V images, respectively. 00103 # sigma - (for mode='poli') standard deviation of noise of Stokes images with unit such as 00104 # Jy/beam to correct for bias 00105 # Default: '0.0Jy/beam' (= no debiasing) 00106 # mask -- Name of mask applied to each image in the calculation 00107 # Default '' means no mask; Example: mask='orion.mask'. 00108 # region -- File path to an ImageRegion file. 00109 # An ImageRegion file can be created with the CASA 00110 # viewer's region manager. Typically ImageRegion files 00111 # will have the suffix '.rgn'. If a region file is given 00112 # then the box, chans, and stokes selections whill be 00113 # ignored. 00114 # Default: none 00115 # Example: region='myimage.im.rgn' 00116 # box -- A box region on the directional plane 00117 # Only pixel values acceptable at this time. 00118 # Default: none (whole 2-D plane); Example: box='10,10,50,50' 00119 # chans -- channel numbers, velocity, and/or frequency 00120 # Only channel numbers acceptable at this time. 00121 # Default: none (all); Example: chans='3~20' 00122 # stokes -- Stokes parameters to image, may or may not be separated 00123 # by commas but best if you use commas. 00124 # Default: none (all); Example: stokes='IQUV'; 00125 # Options: 'I','Q','U','V','RR','RL','LR','LL','XX','YX','XY','YY', ... 00126 # 00127 # Available functions in the <i>expr</i> and <i>mask</i> paramters: 00128 # pi(), e(), sin(), sinh(), asinh(), cos(), cosh(), tan(), tanh(), 00129 # atan(), exp(), log(), log10(), pow(), sqrt(), complex(), conj() 00130 # real(), imag(), abs(), arg(), phase(), aplitude(), min(), max() 00131 # round(), isgn(), floor(), ceil(), rebin(), spectralindex(), pa(), 00132 # iif(), indexin(), replace(), ... 00133 # 00134 # For a full description of the allowed syntax see the 00135 # Lattice Expression Language (LEL) documentation on the at: 00136 # http://aips2.nrao.edu/docs/notes/223/223.html 00137 # 00138 # NOTE: where indexing and axis numbering are used in the above 00139 # functions they are 1-based, ie. numbering starts at 1. 00140 # 00141 # </synopsis> 00142 # 00143 # <example> 00144 # <srcblock> 00145 # </srcblock 00146 # 00147 # </example> 00148 # 00149 # <motivation> 00150 # To provide a user-friendly task interface to imagecalc and ??? 00151 # as well as an more user-friendling math syntax then what is 00152 # provided by the CASA Lattice Exprssion Language. 00153 # </motivation> 00154 # 00155 # <todo> 00156 # Crystal wanted different masks for different inputs 00157 # but unlikely that its really needed. 00158 # 00159 # Add an "overwrite" output file parameter 00160 # 00161 # Add polygon and circle region selection 00162 # </todo> 00163 ########################################################################3 00164 00165 00166 import os 00167 import shutil 00168 from taskinit import * 00169 00170 def immath( 00171 imagename, mode, outfile, expr, varnames, sigma, 00172 polithresh, mask, region, box, chans, stokes, stretch 00173 ): 00174 # Tell CASA who will be reporting 00175 casalog.origin('immath') 00176 retValue = False 00177 # NOTE: This step likely be eliminated 00178 # 00179 # Remove any old tmp files that may be left from 00180 # a previous run of immath 00181 tb.clearlocks() 00182 tmpFilePrefix='_immath_tmp' 00183 try: 00184 _immath_cleanup( tmpFilePrefix ) 00185 except Exception, e: 00186 casalog.post( 'Unable to cleanup working directory '+os.getcwd()+'\n'+str(e), 'SEVERE' ) 00187 raise Exception, str(e) 00188 00189 00190 # Keep track of which LEL functions are upper-case and 00191 # which are lower-case. For some reason LEL was written 00192 # to be case sensitive! 00193 # 00194 # The values stored are in the opposite case of what we want, 00195 # because we want to search for the invalid case. 00196 # 00197 # Note these were found in the various LEL*Enums.h files. 00198 lower_case=[ 'SIN(', 'SINH(', 'ASIN(', 'COS(', 'COSH(', 'ACOS(', 'TAN(', \ 00199 'TANH(', 'ATAN(', 'ATAN2(', 'EXP(', 'LOG(', 'LOG10(', 'POW(',\ 00200 'SQRT(', 'ROUND(', 'SIGN(', 'CEIL(', 'FLOOR(', 'ABS(', \ 00201 'ARG(', 'REAL(', 'IMAG(', 'CONJ(', 'COMPLEX(', 'FMOD(' \ 00202 'MIN(', 'MAX(', 'MIN1D(', 'MAX1D(', 'MEAN1D(', 'MEDIAN1D('\ 00203 'FRACTILE1D(', 'FRACTILERANGE1D(', 'SUM(', 'NELEM(', 'ALL('\ 00204 'ANY(', 'IIF(', 'REPLACE(', 'LENGTH(', 'INDEXIN(', 'NDIM' ] 00205 upper_case=[ ] 00206 00207 # First check to see if the output file exists. If it 00208 # does then we abort. CASA doesn't allow files to be 00209 # over-written, just a policy. 00210 if ( len( outfile ) < 1 ): 00211 outfile = 'immath_results.im' 00212 casalog.post( "The outfile paramter is empty, consequently the" \ 00213 +" resultant image will be\nsaved on disk in file, " \ 00214 + outfile, 'WARN' ) 00215 if ( len( outfile ) > 0 and os.path.exists( outfile ) ): 00216 raise Exception, 'Output file, '+outfile+\ 00217 ' exists. immath can not proceed, please\n'+\ 00218 'remove it or change the output file name.' 00219 00220 # Find the list of filenames in the expression 00221 # also do a quick check to see if all of the files 00222 # exist 00223 # 00224 # TODO add a size check to make sure all images are the 00225 # same size. Is this 00226 tmpfilenames='' 00227 if mode=='evalexpr': 00228 tmpfilenames=_immath_parse( expr ) 00229 filenames=imagename 00230 else: 00231 filenames=imagename 00232 if ( isinstance( filenames, str ) ): 00233 filenames= [ filenames ] 00234 casalog.post( 'List of input files is: '+str(filenames), 'DEBUG1' ) 00235 #for i in range( len(filenames) ): 00236 # if ( not os.path.exists(filenames[i]) ): 00237 # raise Exception, 'Image data set not found - please verify '+filenames[i] 00238 00239 # Construct the variable name list. We append to the list the 00240 # default variable names if the user hasn't supplied a full suite. 00241 if ( not isinstance( varnames, list ) ): 00242 name0=varnames 00243 varnames=[] 00244 if ( len(name0 ) > 0 ): 00245 varnames.append( name0 ) 00246 nfile=max(len(filenames),len(tmpfilenames)) 00247 #for i in range( len(varnames), len(filenames) ): 00248 for i in range( len(varnames), nfile ): 00249 varnames.append( 'IM'+str(i) ) 00250 casalog.post( 'Variable name list is: '+str(varnames), 'DEBUG1' ) 00251 00252 _myia = iatool() 00253 00254 #file existance check 00255 ignoreimagename=False 00256 if mode=='evalexpr': 00257 varnamesSet=set(varnames) 00258 count = 0 00259 for imname in tmpfilenames: 00260 # check if it is one of varnames, if not check the files in expr exist 00261 if(not varnamesSet.issuperset(imname)): 00262 if( not os.path.exists(imname)): 00263 raise Exception, 'Image data set not found - please verify '+imname 00264 else: 00265 count=count+1 00266 if len(tmpfilenames)==count: 00267 ignoreimagename=True 00268 filenames=tmpfilenames 00269 #if(tmpfilenames==['']): 00270 # for i in range(len(varnames)): 00271 # if(expr.count(varnames[i])==0): 00272 # casalog.post('Variable name '+varnames[i]+' not found in the expression.','WARN') 00273 if not ignoreimagename: 00274 for i in range( len(filenames) ): 00275 if ( not os.path.exists(filenames[i]) ): 00276 raise Exception, 'Image data set not found - please verify '+filenames[i] 00277 00278 00279 # Remove spaces from the expression. 00280 expr=expr.replace( ' ', '' ) 00281 00282 doPolThresh = False 00283 00284 # Construct expressions for the spectral and polarization modes. 00285 # These are common, repetitive calculations that are handled for 00286 # the user. 00287 if mode=='spix': 00288 # calculate a spectral index distribution image 00289 if len(filenames) != 2: 00290 raise Exception, 'Requires two images at different frequencies' 00291 #expr = 'spectralindex("%s","%s")' % (filenames[0],filenames[1]) 00292 00293 expr = 'spectralindex('+varnames[0]+', '+varnames[1]+')' 00294 elif mode=='pola': 00295 expr = _doPolA(filenames, varnames, tmpFilePrefix) 00296 if (polithresh): 00297 if (mask != ""): 00298 mask = "" 00299 casalog.post("Ignoring mask parameter in favor of polithresh parameter", 'WARN') 00300 if (qa.getunit(polithresh) != ""): 00301 initUnit = qa.getunit(polithresh) 00302 _myia.open(filenames[0]) 00303 bunit = _myia.brightnessunit() 00304 polithresh = qa.convert(polithresh, bunit) 00305 _myia.done() 00306 if (qa.getunit(polithresh) != bunit): 00307 raise Exception, "Units of polithresh " + initUnit \ 00308 + " do not conform to input image units of " + bunit \ 00309 + " so cannot perform thresholding. Please correct units and try again." 00310 polithresh = qa.getvalue(polithresh)[0] 00311 doPolThresh = True 00312 [lpolexpr, isLPol, isTPol] = _doPolI(filenames, varnames, tmpFilePrefix, False, False) 00313 lpolexpr = _immath_expr_from_varnames(lpolexpr, varnames, filenames) 00314 lpolexpr = lpolexpr + ")" 00315 lpol = tmpFilePrefix + "_lpol.im" 00316 res = _myia.imagecalc(pixels=lpolexpr, outfile=lpol) 00317 res.done() 00318 elif mode=='poli': 00319 [expr, isLPol, isTPol] = _doPolI(filenames, varnames, tmpFilePrefix, True, True) 00320 sigsq=0 00321 if len(sigma)>0: 00322 qsigma=qa.quantity(sigma) 00323 if qa.getvalue(qsigma)[0] >0: 00324 sigmaunit=qa.getunit(qsigma) 00325 try: 00326 _myia.open(filenames[0]) 00327 iunit = _myia.brightnessunit() 00328 _myia.done() 00329 except: 00330 raise Exception, 'Unable to get brightness unit from image file '+filenames[0] 00331 if sigmaunit!=iunit: 00332 newsigma=qa.convert(qsigma,iunit) 00333 else: 00334 newsigma=sigma 00335 sigsq=(qa.getvalue(newsigma)[0])**2 00336 expr+='-%s' % sigsq 00337 expr+=')' 00338 # reset stokes selection for pola and poli 00339 if (mode=='pola' or mode=='poli') and len(stokes)!=0: 00340 casalog.post( "Ignoring stokes parameters selection." ,'WARN' ); 00341 stokes='' 00342 00343 # PUT TRY BLOCK AROUND THIS PART 00344 # 00345 # NEED TO DO EXPRESSION FOR EXPR MODE 00346 00347 00348 # If the user didn't give any region or mask information 00349 # then just evaluated the expression with the filenames in it. 00350 if ( len(box)<1 and len(chans)<1 and len(stokes)<1 and len(region)<1 and len(mask)<1): 00351 expr = _immath_expr_from_varnames(expr, varnames, filenames) 00352 casalog.post( 'Will evaluate expression: '+expr, 'DEBUG1' ) 00353 try: 00354 res = _myia.imagecalc(pixels=expr, outfile=outfile) 00355 # need to modify stokes type of output image for pol. intensity image 00356 if ( mode =="poli" ): 00357 csys = res.coordsys() 00358 if isTPol: 00359 csys.setstokes('Ptotal') 00360 elif isLPol: 00361 csys.setstokes('Plinear') 00362 res.setcoordsys(csys.torecord()) 00363 res.done() 00364 if (doPolThresh): 00365 _immath_createPolMask(polithresh, lpol, outfile) 00366 return True 00367 except Exception, error: 00368 try: 00369 _myia.done() 00370 except: 00371 pass 00372 casalog.post( 'Unable to do mathematical expression: '\ 00373 +expr+'\n'+str(error), 'SEVERE' ) 00374 return False 00375 00376 # If we've made it here we need to apply masks or extract 00377 # regions from the images before doing the calculations first. 00378 # Warning if user has given a region file plus other region 00379 # selection information 00380 00381 # For each file in the list of files, creat a subimage 00382 # of it and store it. We need to do this only if the user 00383 # specified a region or mask information. 00384 subImages=[] 00385 casalog.post( "SUBIMAGES: "+str(subImages), 'DEBUG2' ) 00386 file_map = {} 00387 00388 i = 0 00389 for image in filenames: 00390 casalog.post( 'Creating tmp image for image ' + image, 'DEBUG2') 00391 00392 _myia.open(image) 00393 reg = rg.frombcs(csys=_myia.coordsys().torecord(), 00394 shape=_myia.shape(), box=box, chans=chans, stokes=stokes, 00395 stokescontrol="a", region=region 00396 ) 00397 _myia.close() 00398 00399 # TODO see if there are issues when NO region given by user 00400 try: 00401 _myia.open(image) 00402 tmpFile=tmpFilePrefix+str(i) 00403 _myia.subimage( region=reg, mask=mask, outfile=tmpFile, stretch=stretch ) 00404 file_map[image] = tmpFile 00405 subImages.append( tmpFile ) 00406 _myia.done() 00407 casalog.post( 'Created temporary image '+tmpFile+' from '+\ 00408 image, 'DEBUG1' ) 00409 i = i + 1 00410 00411 except Exception, e: 00412 try: 00413 _mia.done() 00414 except: 00415 pass 00416 casalog.post( 'Exception caught is: '+str(e), 'DEBUG2' ) 00417 casalog.post( 'Unable to apply region to file: '\ 00418 + image\ 00419 +'.\nUsed region: '+str(reg), 'DEBUG2' ) 00420 #raise Exception, 'Unable to apply region to file: '\ 00421 # +filenames[i] 00422 casalog.post( 'Unable to apply region to file: '\ 00423 + image, 'SEVERE' ) 00424 return False 00425 # Make sure no problems happened 00426 00427 00428 if ( len(filenames) != len(subImages) ) : 00429 #raise Exception, 'Unable to create subimages for all image names given' 00430 casalog.post( 'Unable to create subimages for all image names given',\ 00431 'SEVERE' ) 00432 return False 00433 00434 # because real file names also have to be mapped to a corresponding subimage, CAS-1830 00435 for k in file_map.keys(): 00436 # we require actual image names to be in quotes when used in the expression 00437 varnames.extend(["'" + k + "'", '"' + k + '"']) 00438 subImages.extend(2 * [file_map[k]]) 00439 00440 00441 # Put the subimage names into the expression 00442 try: 00443 expr = _immath_expr_from_varnames(expr, varnames, subImages) 00444 00445 except Exception, e: 00446 casalog.post( 00447 "Unable to construct pixel expression aborting immath: " + str(e), 00448 'SEVERE' 00449 ) 00450 return False 00451 casalog.post( 'Will evaluate expression of subimages: '+expr, 'DEBUG1' ) 00452 00453 try: 00454 # Do the calculation 00455 res = _myia.imagecalc(pixels=expr, outfile=outfile ) 00456 00457 # modify stokes type for polarization intensity image 00458 if ( mode=="poli" ): 00459 csys=retValue.coordsys() 00460 if isTPol: 00461 csys.setstokes('Ptotal') 00462 elif isLPol: 00463 csys.setstokes('Plinear') 00464 res.setcoordsys(csys.torecord()) 00465 res.done() 00466 if (doPolThresh): 00467 _immath_createPolMask(polithresh, lpol, outfile) 00468 00469 #cleanup 00470 _myia.done() 00471 _immath_cleanup( tmpFilePrefix ) 00472 00473 return True 00474 except Exception, error: 00475 try: 00476 _myia.done() 00477 _immath_cleanup( tmpFilePrefix ) 00478 except: 00479 pass 00480 casalog.post( "Exception caught was: "+str(error), 'DEBUG2') 00481 #raise Exception, 'Unable to evaluate math expression: '\ 00482 # +expr+' on file(s) '+str(filenames) 00483 casalog.post( 'Unable to evaluate math expression: '\ 00484 +expr+' on file(s) '+str(filenames), 'SEVERE' ) 00485 return False 00486 00487 00488 # Remove any temporary files 00489 try: 00490 _immath_cleanup( tmpFilePrefix ) 00491 except: 00492 casalog.post( 'immath was unable to cleanup temporary files','SEVERE' ) 00493 return False 00494 return True 00495 00496 def _immath_cleanup( filePrefix ): 00497 # Remove any old tmp files that may be left from 00498 # a previous run of immath 00499 fileList=os.listdir( os.getcwd() ) 00500 for file in fileList: 00501 if ( file.startswith( filePrefix ) ): 00502 #recursivermdir( file ) 00503 shutil.rmtree( file ) 00504 00505 00506 def _immath_parse( expr='' ): 00507 retValue=[] 00508 00509 # Find out if the names are surrounded by single or double quotes 00510 quote='' 00511 if ( expr.find('"') > -1 ): 00512 quote='"' 00513 if ( expr.find("'") > -1 ): 00514 quote="'" 00515 00516 current=expr; 00517 while( current.count(quote) > 1 ): 00518 start = current.index(quote)+1 00519 end = current[start:].index(quote)+start 00520 if ( retValue.count( current[start:end] ) > 0 ) : 00521 # We already have this file name so we won't add it 00522 # to the list again. This saves us work and disk space. 00523 current=current[end+1:] 00524 continue; 00525 00526 retValue.append( current[start:end] ) 00527 current=current[end+1:] 00528 00529 return retValue 00530 00531 # check stokes type for the list of images 00532 def __check_stokes(images): 00533 _myia = iatool() 00534 retValue=[] 00535 for fname in images: 00536 _myia.open(fname) 00537 csys = _myia.coordsys() 00538 stks=csys.stokes() 00539 _myia.close() 00540 retValue.extend(stks) 00541 return retValue 00542 00543 # it is important to sort the varnames in reverse order before doing 00544 # the substitutions to assure the substitution set is performed correctly 00545 # CAS-1678 00546 def _immath_expr_from_varnames(expr, varnames, filenames): 00547 tmpfiles = {} 00548 for i in range(len(filenames)): 00549 tmpfiles[varnames[i]] = filenames[i] 00550 tmpvars = tmpfiles.keys() 00551 00552 tmpvars.sort() 00553 tmpvars.reverse() 00554 for varname in tmpvars: 00555 expr = expr.replace(varname, '"' + tmpfiles[varname] + '"') 00556 return(expr) 00557 00558 def _doPolA(filenames, varnames, tmpFilePrefix): 00559 # calculate a polarization position angle image 00560 stkslist = __check_stokes(filenames) 00561 Uimage = Qimage = '' 00562 _myia = iatool() 00563 if len(filenames) == 1: 00564 # FIXME I really hate creating subimages like this, the poli and pola routines really belong in the as of now non-existant squah task 00565 if (type(stkslist) != list): 00566 raise Exception, filenames[0] + " is the only image specified but it is not multi-stokes so cannot do pola calculation" 00567 _myia.open(filenames[0]) 00568 spixels = _myia.coordsys().findcoordinate('stokes')[1] 00569 if (len(spixels) != 1): 00570 raise Exception, filenames[i] + "does not have exactly one stokes axis, cannot do pola calculation" 00571 stokesPixel = spixels[0] 00572 trc = _myia.shape() 00573 blc = [] 00574 for i in range(len(trc)): 00575 blc.append(0) 00576 trc[i] = trc[i] - 1 00577 for stokes in (['Q', 'U']): 00578 if (stkslist.count(stokes) == 0): 00579 raise Exception, filenames[0] + " is the only image specified but it does not contain stokes " + stokes \ 00580 + " so pola calculation cannot be done" 00581 pixNum = stkslist.index(stokes) 00582 blc[stokesPixel] = pixNum 00583 trc[stokesPixel] = pixNum 00584 myfile = tmpFilePrefix + '_' + stokes 00585 _myia.subimage(outfile=myfile, region=rg.box(blc=blc, trc=trc)) 00586 if (stokes == 'Q'): 00587 Qimage = myfile 00588 elif (stokes == 'U'): 00589 Uimage = myfile 00590 _myia.done() 00591 # to use pass by reference semantics correctly, we have to use the same objects passed in 00592 # rather than create new objects with the same names 00593 filenames[0:1] = [Qimage, Uimage] 00594 varnames[0:1] = ["IM0", "IM1"] 00595 else: 00596 if len(filenames) > 2: 00597 casalog.post( "More than two images. Take first two and ignore the rest. " ,'WARN' ); 00598 for i in range(2): 00599 if type(stkslist[i]) == list: 00600 raise Exception, filenames[i] + " is a mult-stokes image but multiple images are given for pola calculation. " \ 00601 + "Only a single multi-stokes image *or* multiple single stokes images can be specified for pola calculation" 00602 else: 00603 if stkslist[i] == 'U': 00604 Uimage = varnames[i] 00605 if stkslist[i] == 'Q': 00606 Qimage = varnames[i] 00607 if len(Uimage)<1 or len(Qimage)<1: 00608 missing = [] 00609 if len(Qimage)<1: missing.append('Q') 00610 if len(Uimage)<1: missing.append('U') 00611 raise Exception, 'Missing Stokes %s image(s)' % missing 00612 expr = 'pa(%s,%s)' % (Uimage, Qimage) 00613 return expr 00614 00615 def _doPolI(filenames, varnames, tmpFilePrefix, createSubims, tpol): 00616 # FIXME good grief, I question that these opcodes should even exist in immath 00617 # there is a polarization image tool (po) that does all of this much more nicely 00618 # calculate a polarization intensity image 00619 # if 3 files (or 1 file with Q, U, V) total pol intensity image 00620 # if 2 files (or file file with Q, U) given linear pol intensity image 00621 # FIXME I really hate creating subimages like this, the poli and pola routines really belong in the as of now non-existant squah task 00622 if len(filenames) < 1 or len(filenames) > 3: 00623 raise Exception, 'poli requires one multistokes with Q, U, and optionally V stokes or two single stokes (Q, U) images or three single Stokes (Q,U,V) images' 00624 isQim = False 00625 isUim = False 00626 isVim = False 00627 isLPol = False 00628 isTPol = False 00629 00630 stkslist=__check_stokes(filenames) 00631 if len(filenames) == 1: 00632 # do multistokes image 00633 if (len(stkslist) < 2): 00634 raise Exception, filenames[0] + " is the only image specified but it is not multi-stokes so cannot do poli calculation" 00635 _myia = iatool() 00636 _myia.open(filenames[0]) 00637 spixels = _myia.coordsys().findcoordinate('stokes')[1] 00638 if (len(spixels) != 1): 00639 _myia.close() 00640 raise Exception, filenames[i] + "does not have exactly one stokes axis, cannot do pola calculation" 00641 00642 stokesPixel = spixels[0] 00643 trc = _myia.shape() 00644 blc = [] 00645 00646 for i in range(len(trc)): 00647 blc.append(0) 00648 trc[i] = trc[i] - 1 00649 neededStokes = ['Q', 'U'] 00650 if (stkslist.count('V')): 00651 neededStokes.append('V') 00652 Qimage = Uimage = Vimage = '' 00653 for stokes in (neededStokes): 00654 if ((stokes == 'Q' or stokes == 'U') and stkslist.count(stokes) == 0): 00655 _myia.close() 00656 raise Exception, filenames[0] + " is the only image specified but it does not contain stokes " + stokes \ 00657 + " so poli calculation cannot be done" 00658 myfile = tmpFilePrefix + '_' + stokes 00659 if (stokes == 'Q'): 00660 Qimage = myfile 00661 elif (stokes == 'U'): 00662 Uimage = myfile 00663 elif (stokes == 'V' and tpol): 00664 Vimage = myfile 00665 if createSubims: 00666 pixNum = stkslist.index(stokes) 00667 blc[stokesPixel] = pixNum 00668 trc[stokesPixel] = pixNum 00669 _myia.subimage(outfile=myfile, region=rg.box(blc=blc, trc=trc)) 00670 _myia.done() 00671 isTPol = bool(Vimage) 00672 isLPol = not isTPol 00673 filenames = [Qimage, Uimage] 00674 sum = Qimage + '*' + Qimage + " + " + Uimage + '*' + Uimage 00675 if isTPol: 00676 sum = sum + " + " + Vimage + '*' + Vimage 00677 filenames.append(Vimage) 00678 # close paren gets added after this method has been called. 00679 expr = 'sqrt(' + sum 00680 00681 elif len(filenames) == 3: 00682 for i in range(len(stkslist)): 00683 if type(stkslist[i])==list: 00684 casalog.post("stokes " + str(stkslist[i]),'SEVERE') 00685 raise Exception, 'Cannot handle %s, a multi-Stokes image when more than one image supplied.' % filenames[i] 00686 else: 00687 if stkslist[i]=='Q':isQim=True 00688 if stkslist[i]=='U':isUim=True 00689 if stkslist[i]=='V':isVim=True 00690 if not (isUim and isQim and isVim): 00691 missing = [] 00692 if not isQim: missing.append('Q') 00693 if not isUim: missing.append('U') 00694 if not isVim: missing.append('V') 00695 raise Exception, 'Missing Stokes %s image(s)' % missing 00696 expr='sqrt('+varnames[0]+'*'+varnames[0]\ 00697 +'+'+varnames[1]+'*'+varnames[1]\ 00698 +'+'+varnames[2]+'*'+varnames[2] 00699 isTPol = True 00700 elif len(filenames) == 2: 00701 for i in range(len(stkslist)): 00702 if type(stkslist[i])==list: 00703 raise Exception, 'Cannot handle %s, a multi-Stokes image when multiple images supplied.' % filenames[i] 00704 else: 00705 if stkslist[i]=='Q':isQim=True 00706 if stkslist[i]=='U':isUim=True 00707 if not (isUim and isQim): 00708 missing = [] 00709 if not isQim: missing.append('Q') 00710 if not isUim: missing.append('U') 00711 raise Exception, 'Missing Stokes %s image(s)' % missing 00712 expr='sqrt('+varnames[0]+'*'+varnames[0]\ 00713 +'+'+varnames[1]+'*'+varnames[1] 00714 isLPol = True 00715 return [expr, isLPol, isTPol] 00716 00717 def _immath_createPolMask(polithresh, lpol, outfile): 00718 # make the linear polarization threshhold mask CAS-2120 00719 myexpr = "'" + lpol + "' >= " + str(qa.getvalue(polithresh)[0]) 00720 _myia = iatool() 00721 _myia.open(outfile) 00722 _myia.calcmask(name='mask0', mask=myexpr) 00723 casalog.post('Calculated mask based on linear polarization threshold ' + str(polithresh), 00724 'INFO') 00725 _myia.done() 00726