casa
$Rev:20696$
|
00001 # 00002 # This file was generated using xslt from its XML file 00003 # 00004 # Copyright 2008, Associated Universities Inc., Washington DC 00005 # 00006 import sys 00007 import os 00008 #from casac import * 00009 import casac 00010 import string 00011 import time 00012 import inspect 00013 import gc 00014 import numpy 00015 from odict import odict 00016 from taskmanager import tm 00017 from task_immath import immath 00018 class immath_cli_: 00019 __name__ = "immath" 00020 __async__ = {} 00021 rkey = None 00022 i_am_a_casapy_task = None 00023 # The existence of the i_am_a_casapy_task attribute allows help() 00024 # (and other) to treat casapy tasks as a special case. 00025 00026 def __init__(self) : 00027 self.__bases__ = (immath_cli_,) 00028 self.__doc__ = self.__call__.__doc__ 00029 00030 self.parameters={'imagename':None, 'mode':None, 'outfile':None, 'expr':None, 'varnames':None, 'sigma':None, 'polithresh':None, 'mask':None, 'region':None, 'box':None, 'chans':None, 'stokes':None, 'stretch':None, 'async':None} 00031 00032 00033 def result(self, key=None): 00034 #### here we will scan the task-ids in __async__ 00035 #### and add any that have completed... 00036 if key is not None and self.__async__.has_key(key) and self.__async__[key] is not None: 00037 ret = tm.retrieve(self.__async__[key]) 00038 if ret['state'] == "done" : 00039 self.__async__[key] = None 00040 elif ret['state'] == 'crashed' : 00041 self.__async__[key] = None 00042 return ret 00043 return None 00044 00045 00046 def __call__(self, imagename=None, mode=None, outfile=None, expr=None, varnames=None, sigma=None, polithresh=None, mask=None, region=None, box=None, chans=None, stokes=None, stretch=None, async=None): 00047 00048 """Perform math operations on images 00049 00050 This task evaluates mathematical expressions involving existing 00051 image files. The results of the calculations are stored in the 00052 designated output file. Options are available to specify mathematical 00053 expression directly or pre-defined expression for calculation of 00054 spectral index image, and polarization intensity and position angle 00055 images are available. The image file names imbedded in the expression or 00056 specified in the imagename parameter for the pre-defined calculations may 00057 be CASA images or FITS images. 00058 00059 00060 NOTE: Index values start at 0 Use the imhead task to see the range of 00061 index values for each axes. 00062 00063 00064 Keyword arguments: 00065 imagename input image name(s) 00066 Default: none; 00067 Examples: mode='evalexpr'; imagename=['image1.im', 'image2.im' ] 00068 The text 'IM0' is replaced by 'image1.im' in the 00069 expression and 'IM1' is repalced with 'image2.im' 00070 mode='spix'; imagename=['image1.im','image2.im'] will calculate 00071 an image of log(S1/S2)/log(f1/f2), where S1 and S2 are fluxes and 00072 f1 and f2 are frequencies 00073 mode='pola'; imagename='multistokes.im' (where that image contains both Q and U 00074 stokes planes) or imagename=['imageQ.im','imageU.im'] will calculate 00075 an image of polarization angle distribution, where imageQ.im and 00076 imageU.im are Stokes Q and U images, respectively. Calculate 0.5*arctan(U/Q). 00077 mode='poli'; imagename=['imageQ.im','imageU.im','imageV.im'] will calculate 00078 total polarization intensity image, where imageQ.im, imageU.im, imageV.im 00079 are Stokes Q, U, and V images, respectively. Alternatively, with 00080 imagename = ['imageQ.im','imageU.im'] the linear polarization intensity 00081 image will be calculated. In the case where imagename is a single multi-stokes 00082 image, the total polarization image will be calculated if all of the Q, U, and 00083 V stokes planes are present, and the linear polarization intensity image will 00084 be calculated if the Q and U (but not V) planes are present. 00085 00086 mode mode for mathematical operation 00087 Default: evalexpr 00088 Options: 'evalexpr' : evalulate a mathematical expression defined in 'expr' 00089 'spix' : spectalindex image 00090 'pola' : polarization position angle image 00091 'poli' : polarization intesity image 00092 >>> mode expandable parameters 00093 sigma (for mode='poli') standard deviation of noise of Stokes images with unit such as 00094 Jy/beam to correct for bias 00095 Default: '0.0Jy/beam' (= no debiasing) 00096 polithresh (for mode='pola') Quantity (eg '30uJy/beam') describing the linear (not total; 00097 the stokes V contribution is not included) polarization threshold. A mask ('mask0') 00098 is written to the output image and is False for all corresponding linear polarization 00099 values below this threshold. This parameter overrides the mask input parameter 00100 (below). Default ('') means use the value given in mask, or no masking if that 00101 value is empty as well. 00102 expr (for mode='evalexpr') A LEL expression with images. 00103 Image file names are specified in the imagenames paramter, and 00104 the variables IM0, IM1, ... (or optionally via the varnames parameter, see below) 00105 are used to represent these files 00106 in the expression. Explicit notations of file names in the 00107 expression are also supported, in which cases the file names must 00108 be enclosed in double quotes (") and imagename is ignored. 00109 Examples: 00110 Make an image that is image1.im - image2.im 00111 expr=' (IM0 - IM1 )' 00112 or with an explicit notation, 00113 expr='("image1.im" - "image2.im")' 00114 Clip an image below a value (0.5 in this case) 00115 expr = ' iif( IM0 >=0.5, IM0, 0.0) ' 00116 Note: iif (a, b, c) a is the boolean expression 00117 b is the value if true 00118 c is the value if false 00119 Take the rms value of two images 00120 expr = ' sqrt(IM0 * IM0 + IM1 * IM1) ' 00121 Note: No exponentiaion available? 00122 Build an image pixel by pixel from the minimum of (image2.im, 2*image1.im) 00123 expr='min(IM1,2*max(IM0))' 00124 varnames For mode="evalexpr". Instead of the default variable names IM0, IM1, ..., use 00125 the names in this array to represent the input images. 00126 outfile The output image. Overwriting an existing outfile is not permitted. 00127 Default: immath_results.im; Example: outfile='results.im' 00128 mask Mask to use. See help par.mask. Default is none. Also see polithresh. 00129 stretch Stretch the input mask if necessary and possible. See below. 00130 region Name of region file, region text description, or region dictionary. 00131 box A rectangular region on the directional plane expressed in pixels. 00132 Example: box='10,10,50,50' 00133 chans Channel ranges to use, expressed in pixels. Example: chans='3~20' 00134 stokes Stokes parameters. Example: stokes='IQUV'; 00135 Options: 'I','Q','U','V','RR','RL','LR','LL','XX','YX','XY','YY', ... 00136 Not used in for cases of mode='poli' or mode='pola' 00137 00138 Available functions in the expr and mask paramters: 00139 pi(), e(), sin(), sinh(), asinh(), cos(), cosh(), tan(), tanh(), 00140 atan(), exp(), log(), log10(), pow(), sqrt(), complex(), conj() 00141 real(), imag(), abs(), arg(), phase(), aplitude(), min(), max() 00142 round(), isgn(), floor(), ceil(), rebin(), spectralindex(), pa(), 00143 iif(), indexin(), replace(), ... 00144 00145 If the mask has fewer dimensions than the image and if the shape 00146 of the dimensions the mask and image have in common are the same, 00147 the mask will automatically have the missing dimensions added so 00148 it conforms to the image. 00149 00150 For a full description of the allowed syntax see the 00151 Lattice Expression Language (LEL) documentation on the at: 00152 http://aips2.nrao.edu/docs/notes/223/223.html 00153 00154 NOTE: where indexing and axis numbering are used in the above 00155 functions they are 1-based, ie. numbering starts at 1. 00156 00157 If stretch is true and if the number of mask dimensions is less than 00158 or equal to the number of image dimensions and some axes in the 00159 mask are degenerate while the corresponding axes in the image are not, 00160 the mask will be stetched in the degenerate axis dimensions. For example, 00161 if the input image has shape [100, 200, 10] and the input 00162 mask has shape [100, 200, 1] and stretch is true, the mask will be 00163 stretched along the third dimension to shape [100, 200, 10]. However if 00164 the mask is shape [100, 200, 2], stretching is not possible and an 00165 error will result. 00166 00167 CAUTION: Note that when multiple image are used in the expression, there is 00168 no garauntee about which of those images will be used to create the header 00169 of the output image. Therefore, one may have to modify the output header as 00170 needed if the input headers differ. 00171 00172 Examples: 00173 # Double all values in an image. 00174 immath( imagesname='myimage.im', expr='IM0*2', outfile='double.im' ) 00175 # or with an explicit notation, 00176 immath( expr='"myimage.im"*2', outfile='double.im' ) 00177 00178 # Taking the sin of an image and adding it to another 00179 # Note that the images need to be the same size 00180 immath(images=['image1.im', 'image2.im'], expr='sin(IM1)+IM0;',outfile='newImage.im') 00181 00182 # Adding only the plane associated with the 'V' stokes value and 00183 # the 1st channel together in two images 00184 immath(imagename=[image1', 'image2'], expr='IM0+IM1',chans='1',stokes='V') 00185 00186 00187 # Selecting a single plane (5th channel), of the 3-D cube and 00188 # adding it to the original image. In this example the 2-D plane 00189 # gets expanded out and the values are applied to each plane in the 00190 # 3-D cube. 00191 default('immath') 00192 imagename='ngc7538.image' 00193 outfile='chanFive.im' 00194 expr='IM0' 00195 chans='5' 00196 go 00197 default('immath') 00198 imagename=['ngc7538.image', chanFive.im'] 00199 outfile='ngc7538_chanFive.im' 00200 expr='IM0+IM1' 00201 go 00202 00203 # Selecting and saving the inner 3/4 of an image for channels 40,42,44 00204 # as well as channels less than 10 00205 default('immath') 00206 imagename='my_image.im' 00207 expr='IM0' 00208 box='25,25,123,123' 00209 chans='<10;40,42,44' 00210 outfile='my_image_inner.im' ) 00211 go 00212 00213 # Dividing an image by another, making sure we aren't dividing by zero 00214 default('immath') 00215 imagename=['orion.image', 'my.image'] 00216 expr='IM0/iif(IM1==0,1.0,IM1)' 00217 outfile='my_orion.image' 00218 go 00219 00220 # Applying a mask to all of the images in the expression 00221 default('immath') 00222 imagename=['ngc7538.image','ngc7538_clean.image'] 00223 expr='(IM0*10)+IM1' 00224 mask='"ngc7538.mask"' 00225 outfile='really_noisy_ngc7538.image' 00226 go 00227 00228 00229 # Applying a pixel mask contained in the image information 00230 default('immath') 00231 imagename='ngc5921.image' 00232 expr='IM0*10' 00233 mask='mask("ngc5921.mask")' 00234 outfile='ngc5921.masked.image' 00235 go 00236 00237 # Creating a total polarization intensity image from an multi-stokes image 00238 # containing IQUV. 00239 default('immath') 00240 outfile='pol_intensity' 00241 stokes='' 00242 # in imagename, you can also specify a list containing single stokes images 00243 # of Q and U (for linear polarization intensity) and V (for total 00244 # polarization intensity) 00245 imagename='3C138_pcal' 00246 mode='poli' 00247 go 00248 00249 # Creating a polarization position angle image 00250 default('immath') 00251 outfile='pol_angle.im' 00252 mode='pola' 00253 # you can also do imagename=['Q.im','U.im'] for single stokes images, order of 00254 # the two Stokes images does not matter 00255 imagename='3C138_pcal' # multi-stokes image containing at least Q and U stokes 00256 go 00257 00258 # same as before but write a mask with values of False for pixels for which the 00259 # corresponding linear polarization ( sqrt(Q*Q+U*U)) is less than 30 microJy/beam 00260 polithresh='30uJy/beam' 00261 go 00262 00263 # Creating a spectral index image from the images at two different observing frequencies 00264 default('immath') 00265 outfile='mySource_sp.im' 00266 mode='spix' 00267 imagename=['mySource_5GHz.im','mySource_8GHz.im'] 00268 go 00269 00270 TEMPORARY IMAGES 00271 00272 At this time, it is usually necessary for this task to create intermediate, temporary disk images. 00273 The names of these images start with '_immath' and are created in the directory in which the task 00274 is run. The task makes reasonable attempts to remove these images before it exits, but there are 00275 conceivably instances where the temporary images may not be automatically deleted. It is generally 00276 safe to delete them by hand, assuming no immath instance is currently in progress. 00277 00278 The hope and plan is that the necessity of these images will decrease in the future (ie the computations 00279 will require only RAM and not temporary persistent storage of intermediate results). 00280 00281 00282 00283 """ 00284 if not hasattr(self, "__globals__") or self.__globals__ == None : 00285 self.__globals__=sys._getframe(len(inspect.stack())-1).f_globals 00286 #casac = self.__globals__['casac'] 00287 casalog = self.__globals__['casalog'] 00288 #casalog = casac.casac.logsink() 00289 self.__globals__['__last_task'] = 'immath' 00290 self.__globals__['taskname'] = 'immath' 00291 ### 00292 self.__globals__['update_params'](func=self.__globals__['taskname'],printtext=False,ipython_globals=self.__globals__) 00293 ### 00294 ### 00295 #Handle globals or user over-ride of arguments 00296 # 00297 function_signature_defaults=dict(zip(self.__call__.func_code.co_varnames,self.__call__.func_defaults)) 00298 useLocalDefaults = False 00299 00300 for item in function_signature_defaults.iteritems(): 00301 key,val = item 00302 keyVal = eval(key) 00303 if (keyVal == None): 00304 #user hasn't set it - use global/default 00305 pass 00306 else: 00307 #user has set it - use over-ride 00308 if (key != 'self') : 00309 useLocalDefaults = True 00310 00311 myparams = {} 00312 if useLocalDefaults : 00313 for item in function_signature_defaults.iteritems(): 00314 key,val = item 00315 keyVal = eval(key) 00316 exec('myparams[key] = keyVal') 00317 self.parameters[key] = keyVal 00318 if (keyVal == None): 00319 exec('myparams[key] = '+ key + ' = self.itsdefault(key)') 00320 keyVal = eval(key) 00321 if(type(keyVal) == dict) : 00322 if len(keyVal) > 0 : 00323 exec('myparams[key] = ' + key + ' = keyVal[len(keyVal)-1][\'value\']') 00324 else : 00325 exec('myparams[key] = ' + key + ' = {}') 00326 00327 else : 00328 async = self.parameters['async'] 00329 myparams['imagename'] = imagename = self.parameters['imagename'] 00330 myparams['mode'] = mode = self.parameters['mode'] 00331 myparams['outfile'] = outfile = self.parameters['outfile'] 00332 myparams['expr'] = expr = self.parameters['expr'] 00333 myparams['varnames'] = varnames = self.parameters['varnames'] 00334 myparams['sigma'] = sigma = self.parameters['sigma'] 00335 myparams['polithresh'] = polithresh = self.parameters['polithresh'] 00336 myparams['mask'] = mask = self.parameters['mask'] 00337 myparams['region'] = region = self.parameters['region'] 00338 myparams['box'] = box = self.parameters['box'] 00339 myparams['chans'] = chans = self.parameters['chans'] 00340 myparams['stokes'] = stokes = self.parameters['stokes'] 00341 myparams['stretch'] = stretch = self.parameters['stretch'] 00342 00343 00344 result = None 00345 00346 # 00347 # The following is work around to avoid a bug with current python translation 00348 # 00349 mytmp = {} 00350 00351 mytmp['imagename'] = imagename 00352 mytmp['mode'] = mode 00353 mytmp['outfile'] = outfile 00354 mytmp['expr'] = expr 00355 mytmp['varnames'] = varnames 00356 mytmp['sigma'] = sigma 00357 mytmp['polithresh'] = polithresh 00358 mytmp['mask'] = mask 00359 mytmp['region'] = region 00360 mytmp['box'] = box 00361 mytmp['chans'] = chans 00362 mytmp['stokes'] = stokes 00363 mytmp['stretch'] = stretch 00364 pathname='file:///'+os.environ.get('CASAPATH').split()[0]+'/share/xml/' 00365 trec = casac.casac.utils().torecord(pathname+'immath.xml') 00366 00367 casalog.origin('immath') 00368 try : 00369 #if not trec.has_key('immath') or not casac.casac.utils().verify(mytmp, trec['immath']) : 00370 #return False 00371 00372 casac.casac.utils().verify(mytmp, trec['immath'], True) 00373 scriptstr=[''] 00374 saveinputs = self.__globals__['saveinputs'] 00375 saveinputs('immath', 'immath.last', myparams, self.__globals__,scriptstr=scriptstr) 00376 if async : 00377 count = 0 00378 keybase = time.strftime("%y%m%d.%H%M%S") 00379 key = keybase + "_" + str(count) 00380 while self.__async__.has_key(key) : 00381 count += 1 00382 key = keybase + "_" + str(count) 00383 result = tm.execute('immath', imagename, mode, outfile, expr, varnames, sigma, polithresh, mask, region, box, chans, stokes, stretch) 00384 print "Use: " 00385 print " tm.retrieve(return_value) # to retrieve the status" 00386 print 00387 self.rkey = key 00388 self.__async__[key] = result 00389 else : 00390 tname = 'immath' 00391 spaces = ' '*(18-len(tname)) 00392 casalog.post('\n##########################################'+ 00393 '\n##### Begin Task: ' + tname + spaces + ' #####') 00394 casalog.post(scriptstr[1][1:]+'\n', 'INFO') 00395 result = immath(imagename, mode, outfile, expr, varnames, sigma, polithresh, mask, region, box, chans, stokes, stretch) 00396 casalog.post('##### End Task: ' + tname + ' ' + spaces + ' #####'+ 00397 '\n##########################################') 00398 00399 except Exception, instance: 00400 if(self.__globals__.has_key('__rethrow_casa_exceptions') and self.__globals__['__rethrow_casa_exceptions']) : 00401 raise 00402 else : 00403 #print '**** Error **** ',instance 00404 tname = 'immath' 00405 casalog.post('An error occurred running task '+tname+'.', 'ERROR') 00406 pass 00407 00408 gc.collect() 00409 return result 00410 # 00411 # 00412 # 00413 def paramgui(self, useGlobals=True, ipython_globals=None): 00414 """ 00415 Opens a parameter GUI for this task. If useGlobals is true, then any relevant global parameter settings are used. 00416 """ 00417 import paramgui 00418 if not hasattr(self, "__globals__") or self.__globals__ == None : 00419 self.__globals__=sys._getframe(len(inspect.stack())-1).f_globals 00420 00421 if useGlobals: 00422 if ipython_globals == None: 00423 myf=self.__globals__ 00424 else: 00425 myf=ipython_globals 00426 00427 paramgui.setGlobals(myf) 00428 else: 00429 paramgui.setGlobals({}) 00430 00431 paramgui.runTask('immath', myf['_ip']) 00432 paramgui.setGlobals({}) 00433 00434 # 00435 # 00436 # 00437 def defaults(self, param=None, ipython_globals=None, paramvalue=None, subparam=None): 00438 if not hasattr(self, "__globals__") or self.__globals__ == None : 00439 self.__globals__=sys._getframe(len(inspect.stack())-1).f_globals 00440 if ipython_globals == None: 00441 myf=self.__globals__ 00442 else: 00443 myf=ipython_globals 00444 00445 a = odict() 00446 a['imagename'] = '' 00447 a['mode'] = 'evalexpr' 00448 a['outfile'] = 'immath_results.im' 00449 a['mask'] = '' 00450 a['region'] = '' 00451 a['box'] = '' 00452 a['chans'] = '' 00453 a['stokes'] = '' 00454 00455 a['async']=False 00456 a['mode'] = { 00457 0:odict([{'value':'evalexpr'}, {'expr':""}, {'varnames':""}]), 00458 1:odict([{'value':'poli'}, {'sigma':"0.0mJy/beam"}]), 00459 2:odict([{'value':'pola'}, {'polithresh':""}]), 00460 3:{'value':'spix'}} 00461 a['mask'] = { 00462 0:odict([{'notvalue':''}, {'stretch':False}])} 00463 00464 ### This function sets the default values but also will return the list of 00465 ### parameters or the default value of a given parameter 00466 if(param == None): 00467 myf['__set_default_parameters'](a) 00468 elif(param == 'paramkeys'): 00469 return a.keys() 00470 else: 00471 if(paramvalue==None and subparam==None): 00472 if(a.has_key(param)): 00473 return a[param] 00474 else: 00475 return self.itsdefault(param) 00476 else: 00477 retval=a[param] 00478 if(type(a[param])==dict): 00479 for k in range(len(a[param])): 00480 valornotval='value' 00481 if(a[param][k].has_key('notvalue')): 00482 valornotval='notvalue' 00483 if((a[param][k][valornotval])==paramvalue): 00484 retval=a[param][k].copy() 00485 retval.pop(valornotval) 00486 if(subparam != None): 00487 if(retval.has_key(subparam)): 00488 retval=retval[subparam] 00489 else: 00490 retval=self.itsdefault(subparam) 00491 else: 00492 retval=self.itsdefault(subparam) 00493 return retval 00494 00495 00496 # 00497 # 00498 def check_params(self, param=None, value=None, ipython_globals=None): 00499 if ipython_globals == None: 00500 myf=self.__globals__ 00501 else: 00502 myf=ipython_globals 00503 # print 'param:', param, 'value:', value 00504 try : 00505 if str(type(value)) != "<type 'instance'>" : 00506 value0 = value 00507 value = myf['cu'].expandparam(param, value) 00508 matchtype = False 00509 if(type(value) == numpy.ndarray): 00510 if(type(value) == type(value0)): 00511 myf[param] = value.tolist() 00512 else: 00513 #print 'value:', value, 'value0:', value0 00514 #print 'type(value):', type(value), 'type(value0):', type(value0) 00515 myf[param] = value0 00516 if type(value0) != list : 00517 matchtype = True 00518 else : 00519 myf[param] = value 00520 value = myf['cu'].verifyparam({param:value}) 00521 if matchtype: 00522 value = False 00523 except Exception, instance: 00524 #ignore the exception and just return it unchecked 00525 myf[param] = value 00526 return value 00527 # 00528 # 00529 def description(self, key='immath', subkey=None): 00530 desc={'immath': 'Perform math operations on images', 00531 'imagename': 'a list of input images ', 00532 'mode': 'mode for math operation (evalexpr, spix, pola, poli)', 00533 'outfile': 'File where the output is saved', 00534 'expr': 'Mathematical expression using images', 00535 'varnames': 'a list of variable names to use with the image files', 00536 'sigma': 'standard deviation of noise for debiasing', 00537 'polithresh': 'Threshold in linear polarization intensity image below which to mask pixels.', 00538 'mask': 'Mask to use. See help par.mask. Default is none.', 00539 'region': 'File path which contains an Image Region', 00540 'box': 'Select one or more box regions in the input images', 00541 'chans': 'Select the channel(spectral) range', 00542 'stokes': 'Stokes params to image (I,IV,IQU,IQUV)', 00543 'stretch': 'Stretch the mask if necessary and possible? See help stretch.par ', 00544 00545 'async': 'If true the taskname must be started using immath(...)' 00546 } 00547 00548 # 00549 # Set subfields defaults if needed 00550 # 00551 00552 if(desc.has_key(key)) : 00553 return desc[key] 00554 00555 def itsdefault(self, paramname) : 00556 a = {} 00557 a['imagename'] = '' 00558 a['mode'] = 'evalexpr' 00559 a['outfile'] = 'immath_results.im' 00560 a['expr'] = 'IM0' 00561 a['varnames'] = '' 00562 a['sigma'] = '0.0mJy/beam' 00563 a['polithresh'] = '' 00564 a['mask'] = '' 00565 a['region'] = '' 00566 a['box'] = '' 00567 a['chans'] = '' 00568 a['stokes'] = '' 00569 a['stretch'] = False 00570 00571 #a = sys._getframe(len(inspect.stack())-1).f_globals 00572 00573 if self.parameters['mode'] == 'evalexpr': 00574 a['expr'] = "" 00575 a['varnames'] = "" 00576 00577 if self.parameters['mode'] == 'poli': 00578 a['sigma'] = "0.0mJy/beam" 00579 00580 if self.parameters['mode'] == 'pola': 00581 a['polithresh'] = "" 00582 00583 if self.parameters['mask'] != '': 00584 a['stretch'] = False 00585 00586 if a.has_key(paramname) : 00587 return a[paramname] 00588 immath_cli = immath_cli_()