casa
$Rev:20696$
|
00001 import sys 00002 import os 00003 import inspect 00004 import string 00005 import time 00006 from taskinit import * 00007 import viewertool 00008 00009 00010 class __imview_class(object): 00011 "imview() task with local state for created viewer tool" 00012 00013 def __init__( self ): 00014 self.local_vi = None 00015 self.local_ving = None 00016 self.__dirstack = [ ] 00017 00018 def __call__( self, raster=None, contour=None, zoom=None, axes=None, out=None ): 00019 """ Old parameters: 00020 infile=None,displaytype=None,channel=None,zoom=None,outfile=None, 00021 outscale=None,outdpi=None,outformat=None,outlandscape=None,gui=None 00022 The imview task will display images in raster, contour, vector or 00023 marker form. Images can be blinked, and movies are available 00024 for spectral-line image cubes. For measurement sets, many 00025 display and editing options are available. 00026 00027 examples of usage: 00028 00029 imview 00030 imview "myimage.im" 00031 imview "myrestorefile.rstr" 00032 00033 imview "myimage.im", "contour" 00034 00035 imview "'myimage1.im' - 2 * 'myimage2.im'", "lel" 00036 00037 Executing imview( ) will bring up a display panel 00038 window, which can be resized. If no data file was specified, 00039 a Load Data window will also appear. Click on the desired data 00040 file and choose the display type; the rendered data should appear 00041 on the display panel. 00042 00043 A Data Display Options window will also appear. It has drop-down 00044 subsections for related options, most of which are self-explanatory. 00045 00046 The state of the imview task -- loaded data and related display 00047 options -- can be saved in a 'restore' file for later use. 00048 You can provide the restore filename on the command line or 00049 select it from the Load Data window. 00050 00051 See the cookbook for more details on using the imview task. 00052 00053 Keyword arguments: 00054 infile -- Name of file to visualize 00055 default: '' 00056 example: infile='ngc5921.image' 00057 If no infile is specified the Load Data window 00058 will appear for selecting data. 00059 displaytype -- (optional): method of rendering data 00060 visually (raster, contour, vector or marker). 00061 You can also set this parameter to 'lel' and 00062 provide an lel expression for infile (advanced). 00063 default: 'raster' 00064 example: displaytype='contour' 00065 00066 Note: the filetype parameter is optional; typing of 00067 data files is now inferred. 00068 example: imview infile='my.im' 00069 implies: imview infile='my.im', filetype='raster' 00070 the filetype is still used to load contours, etc. 00071 00072 00073 """ 00074 a=inspect.stack() 00075 stacklevel=0 00076 for k in range(len(a)): 00077 if a[k][1] == "<string>" or (string.find(a[k][1], 'ipython console') > 0 or string.find(a[k][1],"casapy.py") > 0): 00078 stacklevel=k 00079 00080 myf=sys._getframe(stacklevel).f_globals 00081 00082 if (type(out) == str and len(out) != 0) or \ 00083 (type(out) == dict and len(out) != 0) : 00084 gui = False 00085 (out_file, out_format, out_scale, out_dpi, out_orientation) = self.__extract_outputinfo( out ) 00086 else: 00087 gui = True 00088 00089 if gui and self.local_vi is None or \ 00090 not gui and self.local_ving is None: 00091 try: 00092 ## vi/ving might not be defined in taskinit if 00093 ## loading directly from python via casa.py... 00094 vwr = vi if gui else ving 00095 00096 if type(vwr) == type(None) or type(vwr.cwd( )) != str: 00097 vwr = viewertool.viewertool( gui, True, (type(myf) == dict and myf.has_key('casa') and type(myf['casa']) == type(os)) ) 00098 except: 00099 vwr = None 00100 00101 if gui: 00102 self.local_vi = vwr 00103 else: 00104 self.local_ving = vwr 00105 else: 00106 vwr = self.local_vi if gui else self.local_ving 00107 00108 if type(vwr) == type(None): 00109 raise Exception, "failed to find a viewertool..." 00110 00111 self.__pushd( vwr, os.path.abspath(os.curdir) ) 00112 panel = vwr.panel("viewer") 00113 vwr.freeze( panel ) 00114 self.__load_files( "raster", vwr, panel, raster ) 00115 self.__load_files( "contour", vwr, panel, contour ) 00116 self.__set_axes( vwr, panel, axes ) 00117 self.__zoom( vwr, panel, zoom ) 00118 vwr.unfreeze( panel ) 00119 00120 if not gui: 00121 vwr.output(out,scale=out_scale,dpi=out_dpi,format=out_format,orientation=out_orientation,panel=panel) 00122 vwr.close(panel) 00123 00124 self.__popd( vwr ) 00125 00126 return None 00127 00128 def __load_raster( self, vwr, panel, raster ): 00129 ## here we can assume we have a dictionary 00130 ## that specifies what needs to be done... 00131 data = None 00132 if not raster.has_key('file'): 00133 return 0 00134 00135 if type(raster['file']) != str or not os.path.exists(raster['file']) or \ 00136 vwr.fileinfo(raster['file'])['type'] != 'image': 00137 raise Exception, raster['file'] + " does not exist or is not an image" 00138 00139 scaling = 0.0 00140 if raster.has_key('scaling'): 00141 scaling = self.__checknumeric(raster['scaling'], float, "raster scaling") 00142 00143 data = vwr.load( raster['file'], 'raster', panel=panel, scaling=scaling ) 00144 00145 if raster.has_key('range'): 00146 vwr.datarange( self.__checknumeric(raster['range'], float, "data range", array_size=2), data=data ) 00147 00148 if raster.has_key('colormap'): 00149 if type(raster['colormap']) == str: 00150 vwr.colormap( raster['colormap'], data ) 00151 else: 00152 raise Exception, "raster colormap must be a string" 00153 00154 if raster.has_key('colorwedge'): 00155 if type(raster['colorwedge']) == bool: 00156 vwr.colorwedge( raster['colorwedge'], data ) 00157 else: 00158 raise Exception, "colorwedge must be a boolean" 00159 00160 return data 00161 00162 def __load_contour( self, vwr, panel, contour ): 00163 ## here we can assume we have a dictionary 00164 ## that specifies what needs to be done... 00165 data = None 00166 if not contour.has_key('file'): 00167 return 0 00168 00169 if type(contour['file']) != str or not os.path.exists(contour['file']) or \ 00170 vwr.fileinfo(contour['file'])['type'] != 'image': 00171 raise Exception, contour['file'] + " does not exist or is not an image" 00172 00173 data = vwr.load( contour['file'], 'contour', panel=panel ) 00174 00175 if contour.has_key('levels'): 00176 vwr.contourlevels( self.__checknumeric(contour['levels'], float, "contour levels", array_size=0), data=data ) 00177 if contour.has_key('unit'): 00178 vwr.contourlevels( unitlevel=self.__checknumeric(contour['unit'], float, "contour unitlevel"), data=data ) 00179 if contour.has_key('base'): 00180 vwr.contourlevels( baselevel=self.__checknumeric(contour['base'], float, "contour baselevel"), data=data ) 00181 00182 return data 00183 00184 def __set_axes( self, vwr, panel, axes ): 00185 x='' 00186 y='' 00187 z='' 00188 invoke = False 00189 if type(axes) == list and len(axes) == 3 and \ 00190 all( map( lambda x: type(x) == str, axes ) ) : 00191 x = axes[0] 00192 y = axes[1] 00193 z = axes[2] 00194 invoke = True 00195 elif type(axes) == dict : 00196 if axes.has_key('x'): 00197 if type(axes['x']) != str: 00198 raise Exception, "dimensions of axes must be strings (x is not)" 00199 x = axes['x'] 00200 invoke = True 00201 if axes.has_key('y'): 00202 if type(axes['y']) != str: 00203 raise Exception, "dimensions of axes must be strings (y is not)" 00204 y = axes['y'] 00205 invoke = True 00206 if axes.has_key('z'): 00207 if type(axes['z']) != str: 00208 raise Exception, "dimensions of axes must be strings (z is not)" 00209 z = axes['z'] 00210 invoke = True 00211 else : 00212 raise Exception, "'axes' must either be a string list of 3 dimensions or a dictionary" 00213 00214 result = False 00215 if invoke: 00216 vwr.axes( x, y, z, panel=panel ) 00217 result = True 00218 00219 return result 00220 00221 00222 def __zoom( self, vwr, panel, zoom ) : 00223 00224 channel = -1 00225 if type(zoom) == dict and zoom.has_key('channel') : 00226 channel = self.__checknumeric(zoom['channel'], int, "channel") 00227 00228 if type(zoom) == int : 00229 vwr.zoom(level=zoom,panel=panel) 00230 elif type(zoom) == str and os.path.isfile( zoom ): 00231 vwr.zoom(region=zoom,panel=panel) 00232 elif type(zoom) == dict and zoom.has_key('blc') and zoom.has_key('trc'): 00233 blc = zoom['blc'] 00234 trc = zoom['trc'] 00235 if type(blc) == list and type(trc) == list: 00236 blc = self.__checknumeric( blc, float, "zoom blc", array_size=2 ) 00237 trc = self.__checknumeric( trc, float, "zoom trc", array_size=2 ) 00238 00239 coord = "pixel" 00240 if zoom.has_key('coordinates'): 00241 if zoom.has_key('coord'): 00242 raise Exception, "cannot specify both 'coord' and 'coordinates' for zoom" 00243 if type(zoom['coordinates']) != str: 00244 raise Exception, "zoom coordinates must be a string" 00245 coord = zoom['coordinates'] 00246 if coord != 'world' and coord != 'pixel' : 00247 raise Exception, "zoom coordinates must be either 'world' or 'pixel'" 00248 elif zoom.has_key('coord'): 00249 if type(zoom['coord']) != str: 00250 raise Exception, "zoom coord must be a string" 00251 coord = zoom['coord'] 00252 if coord != 'world' and coord != 'pixel' : 00253 raise Exception, "zoom coord must be either 'world' or 'pixel'" 00254 if channel >= 0: 00255 vwr.channel( channel, panel=panel ) 00256 vwr.zoom(blc=blc,trc=trc, coordinates=coord, panel=panel) 00257 elif type(blc) == dict and type(trc) == dict and \ 00258 blc.has_key( '*1' ) and trc.has_key( '*1' ) : 00259 if channel >= 0: 00260 vwr.channel( channel, panel=panel ) 00261 vwr.zoom(region=zoom,panel=panel) 00262 else: 00263 raise Exception, "zoom blc & trc must be either lists or dictionaries" 00264 00265 elif type(zoom) == dict and zoom.has_key('regions'): 00266 if channel >= 0: 00267 vwr.channel( channel, panel=panel ) 00268 vwr.zoom(region=zoom,panel=panel) 00269 elif type(zoom) == dict and zoom.has_key('file') and type(zoom['file']) == str and os.path.isfile( zoom['file'] ): 00270 if channel >= 0: 00271 vwr.channel( channel, panel=panel ) 00272 vwr.zoom(region=zoom['file'],panel=panel) 00273 else: 00274 if channel < 0: 00275 raise Exception, "invalid zoom parameters" 00276 else: 00277 vwr.channel( channel, panel=panel ) 00278 00279 def __load_files( self, filetype, vwr, panel, files ): 00280 00281 if filetype != "raster" and filetype != "contour": 00282 raise Exception, "internal error __load_files( )..." 00283 00284 if type(files) == str: 00285 self.__load_raster( vwr, panel, { 'file': files } ) if filetype == 'raster' else \ 00286 self.__load_contour( vwr, panel, { 'file': files } ) 00287 elif type(files) == dict: 00288 self.__load_raster( vwr, panel, files ) if filetype == 'raster' else \ 00289 self.__load_contour( vwr, panel, files ) 00290 elif type(files) == list: 00291 if all(map( lambda x: type(x) == dict, files )): 00292 for f in files: 00293 self.__load_raster( vwr, panel, f ) if filetype == 'raster' else \ 00294 self.__load_contour( vwr, panel, f ) 00295 elif all(map( lambda x: type(x) == str, files )): 00296 for f in files: 00297 self.__load_raster( vwr, panel, { 'file': f } ) if filetype == 'raster' else \ 00298 self.__load_contour( vwr, panel, { 'file': f } ) 00299 else: 00300 raise Exception, "multiple " + filetype + " specifications must be either all dictionaries or all strings" 00301 else: 00302 raise Exception, filetype + "s can be a single file path (string), a single specification (dictionary), or a list containing all strings or all dictionaries" 00303 00304 00305 def __extract_outputinfo( self, out ): 00306 output_file=None 00307 output_format=None 00308 output_scale=1.0 00309 output_dpi=300 00310 output_orientation="portrait" 00311 00312 if type(out) == str: 00313 output_format = self.__check_filename(out) 00314 output_file = out 00315 00316 elif type(out) == dict: 00317 if out.has_key('file'): 00318 if type(out['file']) != str: 00319 raise Exception, "output filename must be a string" 00320 if out.has_key('format'): 00321 if type(out['format']) != str: 00322 raise Exception, "output format must be a string" 00323 output_format = self.__check_fileformat( out['format'] ) 00324 self.__check_filename( out['file'], False ) 00325 else: 00326 output_format = self.__check_filename( out['file'] ) 00327 00328 output_file = out['file'] 00329 00330 else: 00331 raise Exception, "an output dictionary must include a 'file' field" 00332 00333 if out.has_key('scale'): 00334 output_scale = self.__checknumeric(out['scale'], float, "output scale") 00335 00336 if out.has_key('dpi'): 00337 output_dpi = self.__checknumeric(out['dpi'], int, "output dpi") 00338 output_dpi = int(out['dpi']) 00339 00340 if out.has_key('orientation'): 00341 if out.has_key('orient'): 00342 raise Exception, "output dictionary cannot have both 'orient' and 'orientation' fields" 00343 if type(out['orientation']) != str: 00344 raise Exception, "output orientation must be a string" 00345 if out['orientation'] != 'portrait' and out['orientation'] != 'landscape': 00346 raise Exception, "output orientation must be either 'portrait' or 'landscape'" 00347 output_orientation = out['orientation'] 00348 00349 if out.has_key('orient'): 00350 if type(out['orient']) != str: 00351 raise Exception, "output orient field must be a string" 00352 if out['orient'] != 'portrait' and out['orient'] != 'landscape': 00353 raise Exception, "output orient field must be either 'portrait' or 'landscape'" 00354 output_orientation = out['orient'] 00355 00356 return (output_file, output_format, output_scale, output_dpi, output_orientation) 00357 00358 def __checknumeric( self, value, otype, error_string, array_size=None ): 00359 if array_size is not None: 00360 if type(array_size) != int: 00361 raise Exception, "internal error: array_size is expected to be of type int" 00362 if type(value) != list: 00363 raise Exception, error_string + " must be a list" 00364 if array_size > 0 and len(value) != array_size: 00365 numbers = { '1': 'one', '2': 'two', '3': 'three' } 00366 raise Exception, error_string + " can only be a " + numbers[str(array_size)] + " element numeric list" 00367 if not all(map( lambda x: type(x) == int or type(x) == float, value )): 00368 raise Exception, error_string + " must be a numeric list" 00369 return map( lambda x: otype(x), value ) 00370 00371 if type(value) != int and type(value) != float: 00372 raise Exception, error_string + " must be numeric" 00373 00374 return otype(value) 00375 00376 def __check_fileformat( self, ext ): 00377 supported_files = [ 'jpg', 'pdf', 'eps', 'ps', 'png', 'xbm', 'xpm', 'ppm' ] 00378 if supported_files.count(ext.lower( )) == 0: 00379 raise Exception, "output format '" + str(ext) + "' not supported; supported types are: " + str(supported_files) 00380 return ext.lower( ) 00381 00382 00383 def __check_filename( self, out, check_extension = True ): 00384 dir = os.path.dirname(out) 00385 if len(dir) > 0 and not os.path.isdir(dir): 00386 raise Exception, "output directory (" + str(dir) + ") does not exist" 00387 file = os.path.basename(out) 00388 if len(file) == 0: 00389 raise Exception, "could not find a valid file name in '" + str(out) + "'" 00390 (base,ext) = os.path.splitext(file) 00391 if len(ext) == 0: 00392 raise Exception, "could not infer the ouput type from file name '" + str(file) + "'" 00393 return self.__check_fileformat(ext[1:]) if check_extension else '' 00394 00395 def __pushd( self, vwr, newdir ): 00396 try: 00397 old_path = vwr.cwd( ) 00398 except: 00399 raise Exception, "imview() failed to get the current working directory [" + str(sys.exc_info()[0]) + ": " + str(sys.exc_info()[1]) + "]" 00400 00401 self.__dirstack.append(old_path) 00402 try: 00403 vwr.cwd(newdir) 00404 except: 00405 raise Exception, "imview() failed to change to the new working directory (" + os.path.abspath(os.curdir) + ") [" + str(sys.exc_info()[0]) + ": " + str(sys.exc_info()[1]) + "]" 00406 00407 00408 def __popd( self, vwr ): 00409 try: 00410 vwr.cwd(self.__dirstack.pop( )) 00411 except: 00412 raise Exception, "imview() failed to restore the old working directory (" + old_path + ") [" + str(sys.exc_info()[0]) + ": " + str(sys.exc_info()[1]) + "]" 00413 00414 00415 imview = __imview_class( )