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 string 00010 import time 00011 import inspect 00012 import gc 00013 import numpy 00014 from odict import odict 00015 from task_imfit import imfit 00016 from task_imfit import casalog 00017 00018 class imfit_pg_: 00019 __name__ = "imfit" 00020 00021 def __init__(self) : 00022 self.__bases__ = (imfit_pg_,) 00023 self.__doc__ = self.__call__.__doc__ 00024 00025 00026 def __call__(self, imagename=None, box=None, region=None, chans=None, stokes=None, mask=None, includepix=None, excludepix=None, residual=None, model=None, estimates=None, logfile=None, append=None, newestimates=None, complist=None, overwrite=None, dooff=None, offset=None, fixoffset=None, stretch=None, async=None): 00027 00028 """Fit one or more elliptical Gaussian components on an image region(s) 00029 PARAMETER SUMMARY 00030 imagename Name of the input image 00031 box One or more box regions to use for fitting, 00032 eg "100, 120, 200, 220, 300, 300, 400, 400" 00033 to use two boxes. If both box and region 00034 parameters are specified, box is used. 00035 region Region of interest. See help par.region for specification options. 00036 stokes Stokes parameter to fit. If blank, first polarization plane is used. 00037 mask Mask to use. See help par.mask. Default is none. 00038 includepix Range of pixel values to include for fitting. Array of two numeric 00039 values assumed to have same units as image pixel values. Only one 00040 of includepix or excludepix can be specified. 00041 excludepix Range of pixel values to exclude for fitting. Array of two numeric 00042 values assumed to have same units as image pixel values. Only one 00043 of includepix or excludepix can be specified. 00044 residual Name of the residual image to write. 00045 model Name of the model image to write. 00046 estimates Name of file containing initial estimates of component parameters 00047 (see below for formatting details). 00048 logfile Name of file to write fit results. 00049 append If logfile exists, append to it (True) or overwrite it (False). 00050 newestimates File to write fit results which can be used as initial estimates 00051 for next run. 00052 complist Name of output component list table. 00053 overwrite Overwrite component list table if it exists? 00054 dooff Simultaneously fit a zero-level offset? 00055 offset Initial estimate for the zero-level offset. Only used if dooff is True. 00056 fixoffset Hold zero-level offset constant during fit? Only used if dooff is True. 00057 stretch Stretch the input mask if necessary and possible. Only used if a mask is specified. 00058 See help par.stretch. 00059 00060 OVERVIEW 00061 imfit is used to fit one or more gaussians to sources in an image as 00062 well as an optional zero-level offset. Fitting is limited to a single polarization 00063 but can be performed over several contiguous spectral channels. 00064 If the image has a clean beam, the report will contain both the convolved 00065 and the deconvolved fit results. It is a simple wrapper around the ia.fitcomponents() 00066 tool method. 00067 00068 When dooff is False, the method returns a dictionary with two keys, 'converged' and 'results'. 00069 The value of 'converged' is a boolean array which indicates if the fit converged 00070 on a channel by channel basis. 00071 The value of 'results' is a dictionary representing a component list reflecting the 00072 fit results. In the case of a deconvolved image, the sizes and position angles are those 00073 of the source convolved with the restoring beam. For convenience, the 'results' dictionary can 00074 be read into a compoenent list tool (default tool is named cl) using the fromrecord() method 00075 for easier inspection using tool methods, eg 00076 00077 cl.fromrecord(res['results']) 00078 00079 If dooff is True, in addtion to the specified number of 00080 gaussians, a zero-level offset will also be fit. The initial estimate for this 00081 offset is specified using the offset parameter. Units are assumed to be the 00082 same as the image brightness units.The zero level offset can be held constant during 00083 the fit by specifying fixoffset=True. In the case of dooff=True, the returned 00084 dictionary contains two additional keys, 'zerooff' and 'zeroofferr', which are both 00085 arrays containing the the fitted zero level offset value and its error, respectively, 00086 for each channel. Both sets of values are in image brightness units. 00087 In cases where the fit did not converge, these values are set to NaN. 00088 00089 The region can either be specified by a box(es) or a region (there is no 00090 garauntee which will be used if both are specified, so be certain only one is). 00091 If specified using the box parameter, multiple boxes can be given using the format 00092 box="blcx1, blcy1, trcx1, trcy1, blcx2, blcy2, trcx2, trcy2, ... , blcxN, blcyN, trcxN, trcyN" 00093 where N is the number of boxes. In this case, the union of the specified boxes will be used. 00094 00095 Ranges of pixel values can be included or excluded from the fit via includepix and excludepix. 00096 00097 If specified, the task will write the residual and/or model images for 00098 successful fits. 00099 00100 If an estimates file is not specified, the task will attempt to estimate 00101 initial parameters and fit a single Gaussian. If a multiple Gaussian fit 00102 is desired, the user must specify initial estimates via a text file 00103 (see below for details). 00104 00105 The user has the option of writing the result of the fit to a log file, 00106 and has the option of either appending to or overwriting an existing file. 00107 00108 The user has the option of writing the (convolved) parameters of a successful 00109 fit to a file which can be fed back to imfit as the estimates file for a 00110 subsequent run. 00111 00112 FITTING OVER MULTIPLE CHANNELS 00113 00114 For fitting over multiple channels, the result 00115 of the previous successful fit is used as the estimate for the next channel. The number 00116 of gaussians fit cannot be varied on a channel by channel basis. Thus the variation 00117 of source structure should be reasonably smooth in frequency to produce reliable fit 00118 results. 00119 00120 MASK SPECIFICATION 00121 00122 Mask specification can be done using an LEL expression. For example 00123 00124 mask = '"myimage">5' will use only pixels with values greater than 5. 00125 00126 INCLUDING AND EXCLUDING PIXELS 00127 00128 Pixels can be included or excluded from the fit based on their values 00129 using includepix and excludepix. Note that specifying both is not permitted 00130 and will result in an error. If specified, both take an array of two numeric 00131 values. 00132 00133 ESTIMATES 00134 00135 Initial estimates of fit parameters may be specified via an estimates 00136 text file. Each line of this file should contain a set of parameters for 00137 a single gaussian. Optionally, some of these parameters can be fixed during 00138 the fit. The format of each line is 00139 00140 peak intensity, peak x-pixel value, peak y-pixel value, major axis, minor axis, position angle, fixed 00141 00142 The fixed parameter is optional. The peak intensity is assumed to be in the 00143 same units as the image pixel values (eg Jy/beam). The peak coordinates are specified 00144 by pixel values. The major and minor axes and the position angle are the convolved 00145 parameters if the image has been convolved with a clean beam and are specified as quantities. 00146 The fixed parameter is optional and is a string. It may contain any combination of the 00147 following characters 'f' (peak intensity), 'x' (peak x position), 'y' (peak y position), 00148 'a' (major axis), 'b' (minor axis), 'p' (position angle). 00149 00150 In addition, lines in the file starting with a "#" are considered comments. 00151 00152 An example of such a file is: 00153 00154 # peak intensity must be in map units 00155 120, 150, 110, 23.5arcsec, 18.9arcsec, 120deg 00156 90, 60, 200, 46arcsec, 23arcsec, 140deg, fxp 00157 00158 This is a file which specifies that two gaussians are to be simultaneously fit, 00159 and for the second gaussian the specified peak intensity, x position, and position angle 00160 are to be held fixed during the fit. 00161 00162 ERROR ESTIMATES 00163 00164 The reported estimated errors are the maxima from two methods. In the first method, errors are calculated 00165 according to the description given in AIPS++ Note 224: AIPS++ Least Squares Background available at 00166 http://www.astron.nl/casacore/trunk/casacore/doc/notes/224.html . In the second method (Condon et al 00167 1998AJ.115.1693; Richards et al. 1999MNRAS.306..954), the following algorithms are used to compute the 00168 various errors. 00169 00170 R = rms of residual image 00171 P = fitted peak intensity 00172 S = P/R (signal to noise) 00173 00174 longitude error = (FWHM beam width in longitude direction)/(2*S) 00175 latitude error = (FWHM beam width in latitude direction)/(2*S) 00176 FWHM of major axis error = (FWHM beam along major axis)/S 00177 FWHM of minor axis error = (FWHM beam along minor axis)/S 00178 position angle error is calculated via standard error propogation of the FWHM major and minor axes sizes and errors 00179 flux error is computed via standard error propogation of the peak intensity and its error and the FWHM major 00180 and minor axes sizes and their errors. 00181 00182 In the case where the image has no beam, the pixel width is used as the diameter of the resolution element. 00183 00184 In the vast majority of (and perhaps all) cases, the errors reported come from the second method. 00185 00186 The deconvolved size and position angle errors are computed by taking the maximum of the absolute values of the 00187 differences of the best fit deconvolved value of the given parameter and the deconvolved size of the eight 00188 possible combinations of (FWHM major axis +/- major axis error), (FWHM minor axis +/- minor axis error), 00189 and (position andle +/- position angle error). 00190 00191 CAUTIONARY NOTES ON ERRORS 00192 imfit makes the following implicit assumptions: 00193 00194 1. The noise associated with the pixels it is given to fit is truly random and gaussian 00195 2. There is no offset (constant (unless one is fit), gradient, or more complex function) in pixel values. 00196 3. The things that are trying to be fit are bona-fide gaussians. 00197 00198 If any of these assumptions is not true, the errors reported will in general be lower limits. These 00199 assumptions do not hold if for example, there is structure in the noise of the image (eg the residual map produced 00200 by deconvolution has structure), the area being fit lies in a negative bowl, in extended emission, or on an image 00201 artifact (eg ripple), or the source(s) is nongaussian (eg a disk or more complex function convolved with a gaussian; 00202 just because something looks gaussian to the human image analysis system does not necessarily mean it is). 00203 In addition, in the case of an image produced from interferometric observations, the errors given are appropriate 00204 for good uv plane coverage. They may be a factor of two or more higher for sparse arrays or snapshots. 00205 In short, imfit is not a silver bullet for determining parameters in flawed images and reported errors 00206 should be interpreted cautiously in the vast majority of all "real life" cases. The closer the source being fit is to 00207 fulfilling these assumptions the more realistic reported errors will be. 00208 00209 EXAMPLE: 00210 00211 Here is how one might fit two gaussians to multiple channels of a cube using the fit 00212 from the previous channel as the initial estimate for the next. It also illustrates 00213 how one can specify a region in the associated continuum image as the region to use 00214 as the fit for the channel. 00215 00216 default imfit 00217 imagename = "co_cube.im" 00218 # specify region using region from continuum 00219 region = "continuum.im:source.rgn" 00220 chans = "2~20" 00221 # only use pixels with positive values in the fit 00222 excludepix = [-1e10,0] 00223 # estimates file contains initial parameters for two Gaussians in channel 2 00224 estimates = "initial_estimates.txt" 00225 logfile = "co_fit.log" 00226 # append results to the log file for all the channels 00227 append = "True" 00228 imfit() 00229 00230 00231 """ 00232 a=inspect.stack() 00233 stacklevel=0 00234 for k in range(len(a)): 00235 if (string.find(a[k][1], 'ipython console') > 0) or (string.find(a[k][1], '<string>') >= 0): 00236 stacklevel=k 00237 break 00238 myf=sys._getframe(stacklevel).f_globals 00239 myf['__last_task'] = 'imfit' 00240 myf['taskname'] = 'imfit' 00241 ### 00242 myf['update_params'](func=myf['taskname'],printtext=False) 00243 ### 00244 ### 00245 #Handle globals or user over-ride of arguments 00246 # 00247 function_signature_defaults=dict(zip(self.__call__.func_code.co_varnames,self.__call__.func_defaults)) 00248 useLocalDefaults = False 00249 00250 for item in function_signature_defaults.iteritems(): 00251 key,val = item 00252 keyVal = eval(key) 00253 if (keyVal == None): 00254 #user hasn't set it - use global/default 00255 pass 00256 else: 00257 #user has set it - use over-ride 00258 if (key != 'self') : 00259 useLocalDefaults = True 00260 #myf[key]=keyVal 00261 00262 myparams = {} 00263 if useLocalDefaults : 00264 for item in function_signature_defaults.iteritems(): 00265 key,val = item 00266 keyVal = eval(key) 00267 exec('myparams[key] = keyVal') 00268 if (keyVal == None): 00269 exec('myparams[key] = '+ key + ' = self.itsdefault(key)') 00270 keyVal = eval(key) 00271 if(type(keyVal) == dict) : 00272 exec('myparams[key] = ' + key + ' = keyVal[len(keyVal)-1][\'value\']') 00273 00274 else : 00275 uselessvariable = None 00276 myparams['imagename'] = imagename = myf['imagename'] 00277 myparams['box'] = box = myf['box'] 00278 myparams['region'] = region = myf['region'] 00279 myparams['chans'] = chans = myf['chans'] 00280 myparams['stokes'] = stokes = myf['stokes'] 00281 myparams['mask'] = mask = myf['mask'] 00282 myparams['includepix'] = includepix = myf['includepix'] 00283 myparams['excludepix'] = excludepix = myf['excludepix'] 00284 myparams['residual'] = residual = myf['residual'] 00285 myparams['model'] = model = myf['model'] 00286 myparams['estimates'] = estimates = myf['estimates'] 00287 myparams['logfile'] = logfile = myf['logfile'] 00288 myparams['append'] = append = myf['append'] 00289 myparams['newestimates'] = newestimates = myf['newestimates'] 00290 myparams['complist'] = complist = myf['complist'] 00291 myparams['overwrite'] = overwrite = myf['overwrite'] 00292 myparams['dooff'] = dooff = myf['dooff'] 00293 myparams['offset'] = offset = myf['offset'] 00294 myparams['fixoffset'] = fixoffset = myf['fixoffset'] 00295 myparams['stretch'] = stretch = myf['stretch'] 00296 00297 if type(includepix)==int: includepix=[includepix] 00298 if type(excludepix)==int: excludepix=[excludepix] 00299 00300 result = None 00301 00302 # 00303 # The following is work around to avoid a bug with current python translation 00304 # 00305 mytmp = {} 00306 00307 mytmp['imagename'] = imagename 00308 mytmp['box'] = box 00309 mytmp['region'] = region 00310 mytmp['chans'] = chans 00311 mytmp['stokes'] = stokes 00312 mytmp['mask'] = mask 00313 mytmp['includepix'] = includepix 00314 mytmp['excludepix'] = excludepix 00315 mytmp['residual'] = residual 00316 mytmp['model'] = model 00317 mytmp['estimates'] = estimates 00318 mytmp['logfile'] = logfile 00319 mytmp['append'] = append 00320 mytmp['newestimates'] = newestimates 00321 mytmp['complist'] = complist 00322 mytmp['overwrite'] = overwrite 00323 mytmp['dooff'] = dooff 00324 mytmp['offset'] = offset 00325 mytmp['fixoffset'] = fixoffset 00326 mytmp['stretch'] = stretch 00327 pathname='file:///'+os.environ.get('CASAPATH').split()[0]+'/share/xml/' 00328 trec = casac.utils().torecord(pathname+'imfit.xml') 00329 00330 casalog.origin('imfit') 00331 if not trec.has_key('imfit') or not casac.utils().verify(mytmp, trec['imfit']) : 00332 return False 00333 00334 00335 try : 00336 casalog.post('') 00337 casalog.post('##########################################') 00338 casalog.post('##### Begin Task: imfit #####') 00339 casalog.post('') 00340 result = imfit(imagename, box, region, chans, stokes, mask, includepix, excludepix, residual, model, estimates, logfile, append, newestimates, complist, overwrite, dooff, offset, fixoffset, stretch) 00341 casalog.post('') 00342 casalog.post('##### End Task: imfit #####') 00343 casalog.post('##########################################') 00344 00345 00346 # saveinputs for individule engine has no use 00347 # saveinputs should alos be removed from casa_in_py.py 00348 # 00349 # 00350 # saveinputs = myf['saveinputs'] 00351 # saveinputs('imfit', 'imfit.last', myparams) 00352 # 00353 # 00354 except Exception, instance: 00355 #print '**** Error **** ',instance 00356 pass 00357 00358 gc.collect() 00359 return result 00360 # 00361 # 00362 ## 00363 # def paramgui(self, useGlobals=True): 00364 # """ 00365 # Opens a parameter GUI for this task. If useGlobals is true, then any relevant global parameter settings are used. 00366 # """ 00367 # import paramgui 00368 # 00369 # a=inspect.stack() 00370 # stacklevel=0 00371 # for k in range(len(a)): 00372 # if (string.find(a[k][1], 'ipython console') > 0) or (string.find(a[k][1], '<string>') >= 0): 00373 # stacklevel=k 00374 # break 00375 # myf = sys._getframe(stacklevel).f_globals 00376 # 00377 # if useGlobals: 00378 # paramgui.setGlobals(myf) 00379 # else: 00380 # paramgui.setGlobals({}) 00381 # 00382 # paramgui.runTask('imfit', myf['_ip']) 00383 # paramgui.setGlobals({}) 00384 # 00385 # 00386 # 00387 # 00388 def defaults(self, param=None): 00389 a=inspect.stack() 00390 stacklevel=0 00391 for k in range(len(a)): 00392 if (string.find(a[k][1], 'ipython console') > 0) or (string.find(a[k][1], '<string>') >= 0): 00393 stacklevel=k 00394 break 00395 myf=sys._getframe(stacklevel).f_globals 00396 a = odict() 00397 a['imagename'] = '' 00398 a['box'] = '' 00399 a['region'] = '' 00400 a['chans'] = '' 00401 a['stokes'] = '' 00402 a['mask'] = '' 00403 a['includepix'] = [] 00404 a['excludepix'] = [] 00405 a['residual'] = '' 00406 a['model'] = '' 00407 a['estimates'] = '' 00408 a['logfile'] = '' 00409 a['newestimates'] = '' 00410 a['complist'] = '' 00411 a['dooff'] = False 00412 00413 a['async']=False 00414 a['mask'] = { 00415 0:odict([{'notvalue':''}, {'stretch':False}])} 00416 a['logfile'] = { 00417 0:odict([{'notvalue':''}, {'append':True}])} 00418 a['complist'] = { 00419 0:odict([{'notvalue':''}, {'overwrite':False}])} 00420 a['dooff'] = { 00421 0:odict([{'notvalue':False}, {'offset':0.0}, {'fixoffset':False}])} 00422 00423 ### This function sets the default values but also will return the list of 00424 ### parameters or the default value of a given parameter 00425 if(param == None): 00426 myf['__set_default_parameters'](a) 00427 elif(param == 'paramkeys'): 00428 return a.keys() 00429 else: 00430 if(a.has_key(param)): 00431 #if(type(a[param]) == dict) : 00432 # return a[param][len(a[param])-1]['value'] 00433 #else : 00434 return a[param] 00435 00436 00437 # 00438 # 00439 def check_params(self, param=None, value=None): 00440 a=inspect.stack() 00441 stacklevel=0 00442 for k in range(len(a)): 00443 if (string.find(a[k][1], 'ipython console') > 0) or (string.find(a[k][1], '<string>') >= 0): 00444 stacklevel=k 00445 break 00446 myf=sys._getframe(stacklevel).f_globals 00447 00448 # print 'param:', param, 'value:', value 00449 try : 00450 if str(type(value)) != "<type 'instance'>" : 00451 value0 = value 00452 value = myf['cu'].expandparam(param, value) 00453 matchtype = False 00454 if(type(value) == numpy.ndarray): 00455 if(type(value) == type(value0)): 00456 myf[param] = value.tolist() 00457 else: 00458 #print 'value:', value, 'value0:', value0 00459 #print 'type(value):', type(value), 'type(value0):', type(value0) 00460 myf[param] = value0 00461 if type(value0) != list : 00462 matchtype = True 00463 else : 00464 myf[param] = value 00465 value = myf['cu'].verifyparam({param:value}) 00466 if matchtype: 00467 value = False 00468 except Exception, instance: 00469 #ignore the exception and just return it unchecked 00470 myf[param] = value 00471 return value 00472 00473 # 00474 # 00475 def description(self, key='imfit', subkey=None): 00476 desc={'imfit': 'Fit one or more elliptical Gaussian components on an image region(s)', 00477 'imagename': 'Name of the input image', 00478 'box': 'Specify one or more box regions for the fit.', 00479 'region': 'Region. See help par.region for specs.', 00480 'chans': 'Spectral channels on which to perform fit.', 00481 'stokes': 'Stokes parameter to fit. If blank, first stokes plane is used.', 00482 'mask': 'Mask to use. See help par.mask. Default is none.', 00483 'includepix': 'Range of pixel values to include for fitting.', 00484 'excludepix': 'Range of pixel values to exclude for fitting.', 00485 'residual': 'Name of output residual image.', 00486 'model': 'Name of output model image.', 00487 'estimates': 'Name of file containing initial estimates of component parameters.', 00488 'logfile': 'Name of file to write fit results.', 00489 'append': 'If logfile exists, append to it if True or overwrite it if False', 00490 'newestimates': 'File to write fit results which can be used as initial estimates for next run.', 00491 'complist': 'Name of output component list table.', 00492 'overwrite': 'Overwrite component list table if it exists?', 00493 'dooff': 'Also fit a zero level offset? Default is False', 00494 'offset': 'Initial estimate of zero-level offset. Only used if doff is True. Default is 0.0', 00495 'fixoffset': 'Keep the zero level offset fixed during fit? Default is False ', 00496 'stretch': 'Stretch the mask if necessary and possible? See help par.stretch ', 00497 00498 'async': 'If true the taskname must be started using imfit(...)' 00499 } 00500 00501 # 00502 # Set subfields defaults if needed 00503 # 00504 00505 if(desc.has_key(key)) : 00506 return desc[key] 00507 00508 def itsdefault(self, paramname) : 00509 a = {} 00510 a['imagename'] = '' 00511 a['box'] = '' 00512 a['region'] = '' 00513 a['chans'] = '' 00514 a['stokes'] = '' 00515 a['mask'] = '' 00516 a['includepix'] = [] 00517 a['excludepix'] = [] 00518 a['residual'] = '' 00519 a['model'] = '' 00520 a['estimates'] = '' 00521 a['logfile'] = '' 00522 a['append'] = True 00523 a['newestimates'] = '' 00524 a['complist'] = '' 00525 a['overwrite'] = False 00526 a['dooff'] = False 00527 a['offset'] = 0.0 00528 a['fixoffset'] = False 00529 a['stretch'] = False 00530 00531 if a.has_key(paramname) : 00532 return a[paramname] 00533 imfit_pg = imfit_pg_()