casa
$Rev:20696$
|
00001 import os 00002 from taskinit import * 00003 from odict import odict 00004 import numpy 00005 00006 # The function that handles the imval task. 00007 def imval(imagename=None,region=None,box=None,chans=None,stokes=None): 00008 # Blank return value. 00009 retValue = { 'blc':[], 'trc':[], 'unit': '', 'data': [], 'mask': []} 00010 casalog.origin('imval') 00011 00012 try: 00013 axes=getimaxes(imagename) 00014 except: 00015 raise Exception, "Unable to determine the axes of image: "+imagename 00016 00017 00018 # Get rid of any white space in the parameters 00019 region = region.replace(' ', '' ) 00020 box = box.replace( ' ', '' ) 00021 chans = chans.replace( ' ', '' ) 00022 stokes = stokes.replace( ' ','' ) 00023 00024 # Default for the chans and stokes parameter is all when the 00025 # aren't given. The easy way is to set them to -1, and let 00026 # the imageregion.py code handle it. 00027 if ( len(chans) < 1 ): 00028 chans='-1' 00029 00030 if ( len(stokes) < 1 ): 00031 stokes='-1' 00032 00033 00034 # If the user hasn't specified any region information then 00035 # find the very last data point -- what ia.getpixelvalue 00036 # defaults too. 00037 myia = iatool() 00038 if ( len(box)<1 and len(chans)<1 and len(stokes)<1 and len(region)<1 ): 00039 try: 00040 #print "GETTING SINGLE PIXEL VALUE" 00041 # Open the image for processing! 00042 myia.open(imagename) 00043 00044 # Get the default pixelvalue() at the referencepixel pos. 00045 csys=myia.coordsys() 00046 ref_values = csys.referencepixel()['numeric'] 00047 point=[] 00048 for val in ref_values.tolist(): 00049 point.append( int(round(val) ) ) 00050 casalog.post( 'Getting data value at point '+str(point), 'NORMAL' ) 00051 results = myia.pixelvalue(point) 00052 00053 retValue = _imval_process_pixel( results, point ) 00054 retValue['axes']=axes 00055 casalog.post( 'imval task complete for point'+str(point), 'NORMAL1' ) 00056 myia.done() 00057 return retValue 00058 except Exception, instance: 00059 myia.done() 00060 raise Exception, instance 00061 00062 # If the box parameter only has two value then we copy 00063 # them. 00064 if ( box.count(',') == 1 ): 00065 box = box + ','+ box 00066 00067 # If we are finding the value at a single point this 00068 # is a special case and we use ia.getpixelvalue() 00069 00070 singlePt = _imval_get_single( box, chans, stokes, axes ) 00071 #print "Single point is: ", singlePt, " ", len(singlePt) 00072 if ( len( singlePt ) == 4 and singlePt.count( -1 ) < 1 ): 00073 try: 00074 casalog.post( 'Getting data value at point '+str(singlePt), 'NORMAL' ) 00075 myia.open( imagename ) 00076 results = myia.pixelvalue( singlePt ) 00077 retValue = _imval_process_pixel( results, singlePt ) 00078 myia.done() 00079 retValue['axes']=axes 00080 casalog.post( 'imval task complete for point '+str(singlePt), 'NORMAL1' ) 00081 return retValue 00082 except Exception, instance: 00083 myia.done() 00084 raise Exception, instance 00085 00086 00087 # If we've made it here then we are finding the stats 00088 # of a region, which could be a set of single points. 00089 axes=getimaxes(imagename) 00090 statAxes=[] 00091 if ( len(box)>0 ): 00092 statAxes.append(axes[0][0]) 00093 statAxes.append(axes[1][0]) 00094 if ( len(chans)>0 ): 00095 statAxes.append(axes[2][0]) 00096 00097 # If we get to this point and find that nothing was 00098 # given for the box parameter we use the reference 00099 # pixel values. 00100 myia.open(imagename) 00101 mycsys = myia.coordsys() 00102 00103 if ( len(box) == 0 and len(region) == 0): 00104 try: 00105 # Open the image for processing! 00106 ref_values = mycsys.referencepixel()['numeric'] 00107 values = ref_values.tolist() 00108 box = str(int(round(values[axes[0][0]])))+','\ 00109 + str(int(round(values[axes[1][0]])))+',' \ 00110 + str(int(round(values[axes[0][0]])))+','\ 00111 +str(int(round(values[axes[1][0]]))) 00112 except: 00113 myia.done() 00114 raise Exception, "Unable to find the size of the input image." 00115 00116 # Because the help file says -1 is valid, apparently that's supported functionality, good grief 00117 00118 if box.startswith("-1"): 00119 box = "" 00120 if chans.startswith("-1"): 00121 chans = "" 00122 if stokes.startswith("-1"): 00123 stokes = "" 00124 reg = rg.frombcs( 00125 mycsys.torecord(), myia.shape(), box, chans, 00126 stokes, "a", region 00127 ) 00128 myia.done() 00129 00130 # Now that we know which axes we are using, and have the region 00131 # selected, lets get that stats! NOTE: if you have axes size 00132 # greater then 0 then the maxpos and minpos will not be displayed 00133 if ( reg.has_key( 'regions' ) ): 00134 casalog.post( "Complex region found, only processing the first"\ 00135 " SIMPLE region found", "WARN" ) 00136 reg=reg['regions']['*1'] 00137 00138 # Make sure they are sorted first. 00139 reg['blc'].keys().sort() 00140 reg['trc'].keys().sort() 00141 00142 zeroblc=[] 00143 blc_keys=reg['blc'].keys() 00144 blc_keys.sort() 00145 00146 for key in blc_keys: 00147 value=reg['blc'][key]['value'] 00148 if ( reg['oneRel'] ): 00149 #We need to conver to 0 relative! 00150 value=value-1 00151 if ( len( zeroblc ) > 0 ): 00152 zeroblc.append(str(value)+str(reg['blc'][key]['unit'])+',' ) 00153 else: 00154 zeroblc.append(str(value)+str(reg['blc'][key]['unit']) ) 00155 00156 zerotrc=[] 00157 trc_keys=reg['trc'].keys() 00158 trc_keys.sort() 00159 for key in trc_keys: 00160 value=reg['trc'][key]['value'] 00161 if ( reg['oneRel'] ): 00162 #We need to conver to 0 relative! 00163 value=value-1 00164 if ( len( zerotrc ) > 0 ): 00165 zerotrc.append(str(value)+str(reg['trc'][key]['unit'])+',' ) 00166 else: 00167 zerotrc.append(str(value)+str(reg['trc'][key]['unit']) ) 00168 00169 casalog.post( 'Getting data values in region in blc='+str(zeroblc)+' trc='+str(zerotrc), 'NORMAL' ) 00170 casalog.post( "Getting data values for region: "+str(reg), 'NORMAL2' ) 00171 00172 retValue = _imval_getregion( imagename, reg ) 00173 retValue['axes']=axes 00174 00175 casalog.post( 'imval task complete for region bound by blc='+str(retValue['blc'])+' and trc='+str(retValue['trc']), 'NORMAL1' ) 00176 return retValue 00177 00178 00179 # 00180 # Print out the returned results. 00181 # TODO -- finish this function 00182 def _imval_print( values, name ) : 00183 print 'Results of imval task on ', name 00184 print '' 00185 print 'Region ---' 00186 print '\t --\x1B[94m bottom-left corner (pixel) [blc]: \x1B[0m', list(values['blc']) 00187 print '\t --\x1B[94m top-right corner (pixel) [trc]: \x1B[0m', list(values['trc']) 00188 00189 # 00190 # Take the results from the ia.pixelvalue() function and 00191 # the position given to the function and turn the results 00192 # into the desired values; blc, trc, data, and mask 00193 # 00194 def _imval_process_pixel( results, point ): 00195 retvalue={} 00196 # First check that the results are a dictionary type and that 00197 # it contains the key/value pairs we expect. 00198 if ( not isinstance( results, dict ) ): 00199 casalog.post( "ia.pixelvalue() has returned erroneous data, Python dictionary type expectd.", "WARN" ) 00200 casalog.post( "Value returned is: "+str(results), "SEVERE" ) 00201 return retvalue 00202 00203 if ( not results.has_key('mask') ): 00204 casalog.post( "ia.pixelvalue() has returned unexpected results, no mask value present.", "SEVERE" ) 00205 return retvalue 00206 00207 if ( not results.has_key('value') or not results['value'].has_key('unit') or not results['value'].has_key('value') ): 00208 casalog.post( "ia.pixelvalue() has returned unexpected results, data value absent or ill-formed.", "SEVERE" ) 00209 return retvalue 00210 00211 retValue={ 00212 'blc':point, 'trc': point, 'unit':results['value']['unit'], 00213 'data': numpy.array([results['value']['value']]), 00214 'mask': numpy.array([results['mask']]) 00215 } 00216 return retValue 00217 00218 # 00219 # Give the box, channel, and stokes values find out 00220 # if we are getting the data from a single point in the 00221 # image, if so then return that point. 00222 def _imval_get_single( box, chans, stokes, axes ): 00223 # If we have more then one point then return an empty list. 00224 try: 00225 junk=int(chans) 00226 junk=int(stokes) 00227 except: 00228 return [] 00229 if ( box.count(';')>0 ): 00230 return [] 00231 00232 # If the channel wasn't specified use the first one only. 00233 if ( len( chans ) < 1 ): 00234 #chans=0 00235 return [] 00236 00237 # If the stokes values weren't specified use the first one only. 00238 if ( len( stokes ) < 1 ): 00239 #stokes=0 00240 return[] 00241 00242 # The two x values and two y values need to be the same if its 00243 # a single point. There may be only two value if its a single 00244 # point too. 00245 x=-1 00246 y=-1 00247 box=box.split(',') 00248 if ( len(box) == 2 ): 00249 x=int(box[0]) 00250 y=int(box[1]) 00251 elif ( len(box) == 4 and box[0]==box[2] and box[1]==box[3]): 00252 x=int(box[0]) 00253 y=int(box[1]) 00254 else: 00255 # We have more then one point, return empty list. 00256 return [] 00257 00258 retvalue=[-1,-1,-1,-1] 00259 00260 retvalue[axes[0][0]]=x 00261 retvalue[axes[1][0]]=y 00262 retvalue[axes[2][0]]=int(chans) 00263 retvalue[axes[3][0]]=int(stokes) 00264 return retvalue 00265 00266 # 00267 # Use the ia.getregion() function to construct the requested data. 00268 def _imval_getregion( imagename="", region={} ): 00269 retvalue= {} 00270 myia = iatool() 00271 try: 00272 # Open the image for processing! 00273 myia.open(imagename) 00274 00275 # Find the array of data and mask values. 00276 data_results=myia.getregion( region=region, dropdeg=True, getmask=False ) 00277 mask_results=myia.getregion( region=region, dropdeg=True, getmask=True ) 00278 00279 # Find the bounding box of the region so we can report it back to 00280 # the user. 00281 bbox = myia.boundingbox( region=region ) 00282 00283 if ( not bbox.has_key( 'blc' ) ): 00284 casalog.post( "ia.boundingbox() has returned unexpected results, blc value absent.", "SEVERE" ) 00285 myia.done() 00286 return retvalue 00287 if ( not bbox.has_key( 'blc' ) ): 00288 casalog.post( "ia.boundingbox() has returned unexpected results, blc value absent.", "SEVERE" ) 00289 myia.done() 00290 return retvalue 00291 00292 # get the pixel coords 00293 mycsys = myia.coordsys() 00294 myarrays = _imval_iterate(bbox['blc'], bbox['trc']) 00295 mycoords = mycsys.toworldmany(myarrays) 00296 outcoords = _imval_redo(data_results.shape, mycoords['numeric']) 00297 00298 # Find what units the data values are stored in. 00299 avalue = myia.pixelvalue( bbox['blc'].tolist() ) 00300 #print "A VALUE IS: ", avalue 00301 if ( not avalue.has_key('value') or not avalue['value'].has_key('unit') ): 00302 casalog.post( "ia.pixelvalue() has returned unexpected results, data value absent or ill-formed.", "SEVERE" ) 00303 myia.done() 00304 return retvalue 00305 00306 retvalue={ 00307 'blc':bbox['blc'].tolist(),'trc':bbox['trc'].tolist(), 00308 'unit':avalue['value']['unit'], 'data':data_results, 00309 'mask': mask_results, 'coords': outcoords 00310 } 00311 except Exception, instance: 00312 myia.done() 00313 raise instance 00314 myia.done() 00315 return retvalue 00316 00317 def _imval_iterate(begins, ends, arrays=None, place=None, depth=0, count=None): 00318 if (depth == 0): 00319 count = [0] 00320 mylist = [] 00321 diff = numpy.array(ends) - numpy.array(begins) + 1 00322 prod = diff.prod() 00323 for i in range(len(begins)): 00324 mylist.append(numpy.zeros([prod])) 00325 arrays = numpy.array(mylist) 00326 for i in range(begins[depth], ends[depth] + 1): 00327 if (depth == 0): 00328 tmpplace = [] 00329 for j in range(len(begins)): 00330 tmpplace.append(0) 00331 place = numpy.array(tmpplace) 00332 place[depth] = i 00333 if (depth == len(begins) - 1): 00334 for k in range(depth + 1): 00335 arrays[k][count[0]] = place[k] 00336 count[0] = count[0] + 1 00337 else: 00338 mydepth = depth + 1 00339 _imval_iterate(begins, ends, arrays, place, mydepth, count) 00340 return arrays 00341 00342 def _imval_redo(shape, arrays): 00343 list_of_arrays = [] 00344 for x in range(arrays[0].size): 00345 mylist = [] 00346 for arr in arrays: 00347 mylist.append(arr[x]) 00348 list_of_arrays.append(numpy.array(mylist)) 00349 array_of_arrays = numpy.array(list_of_arrays) 00350 # because shape is an immutable tuple 00351 newshape = list(shape) 00352 newshape.append(array_of_arrays.shape[1]) 00353 return array_of_arrays.reshape(newshape) 00354