Package Pmv :: Module Grid
[hide private]
[frames] | no frames]

Source Code for Module Pmv.Grid

   1  ############################################################################# 
   2  # 
   3  # Author: Ruth HUEY, Michel F. SANNER 
   4  # 
   5  # Copyright: M. Sanner TSRI 2000 
   6  # 
   7  ############################################################################# 
   8   
   9  # 
  10  # $Header: /opt/cvs/python/packages/share1.5/Pmv/Grid.py,v 1.28 2007/07/23 20:38:58 vareille Exp $ 
  11  # 
  12  # $Id: Grid.py,v 1.28 2007/07/23 20:38:58 vareille Exp $ 
  13  # 
  14   
  15  ###################################################################### 
  16  # 
  17  #In this module, class Grid and AutoGrid were defined by Shanrong Zhao 
  18  # 
  19  #                            Oct. 30, 1998 
  20  # 
  21  ###################################################################### 
  22   
  23  from Numeric import * 
  24  from types import * 
  25  import string, os, math 
  26  #import isocontour 
  27  from UTpackages.UTisocontour import isocontour 
  28  import Tkinter 
  29   
  30  ##  from ViewerFramework.gui import InputFormDescr 
  31  from mglutil.gui.InputForm.Tk.gui import InputFormDescr 
  32   
  33  from mglutil.util.callback import CallBackFunction 
  34   
  35  from mglutil.gui.BasicWidgets.Tk.customizedWidgets import ExtendedSliderWidget 
  36   
  37  ##  from DejaVu.extendedSlider import ExtendedSlider 
  38  from DejaVu.IndexedPolygons import IndexedPolygons 
  39  from DejaVu.bitPatterns import patternList 
  40  from DejaVu.colorTool import Map, RGBRamp, array2DToImage 
  41  from DejaVu import Texture 
  42   
  43  from opengltk.OpenGL import GL 
  44   
  45  #isocontour.setVerboseLevel(1) 
  46  isocontour.setVerboseLevel(0) 
  47   
  48  # six compare object have been defined below 
49 -class greatObj:
50 - def __call__(self,a,b):
51 return a > b
52
53 -class notgreatObj:
54 - def __call__(self,a,b):
55 return a <= b
56
57 -class lessObj:
58 - def __call__(self,a,b):
59 return a < b
60
61 -class notlessObj:
62 - def __call__(self,a,b):
63 return a >= b
64
65 -class equalObj:
66 - def __call__(self,a,b):
67 return a == b
68
69 -class notequalObj:
70 - def __call__(self,a,b):
71 return a != b
72
73 -def uniqueSort(lst, func=None):
74 assert type(lst) in [ListType, TupleType] 75 if lst == []: return [] 76 res = {} 77 def add__to__dict(value, d = res): 78 d[value] = None
79 map(add__to__dict , lst) 80 lst2 = res.keys() 81 if func: lst2.sort(func) 82 else: lst2.sort() 83 return lst2 84 85 ####################################################################### 86 # 87 # class tupleElement, group data as a pseudo SINGLE element 88 # for example, tupleElement can be used to represent coordinate 89 # (x,y,z), or the (key,value), or (key,index) pairs. The best 90 # advantage is: group data act as an object 91 92 # The present class tupleElement is not so powerful, but which will be 93 # enhanced in the future so that we can manipulate COMPLEX array 94 # elements in addition to number.
95 -class tupleElement:
96 - def __init__(self, elements = None):
97 if elements: 98 self.data = tuple(elements) 99 else: 100 self.data = tuple(())
101
102 - def __repr__(self):
103 return repr(self.data)
104
105 - def __len__(self): return len(self.data)
106
107 - def __getitem__(self, index):
108 return self._rc(self.data[index])
109
110 - def __getslice__(self, i, j):
111 return self._rc(self.data[i:j]) 112
113 - def __cmp__(self, other):
114 if isinstance(other,self.__class__): 115 return cmp(self.data, other.data) 116 else: 117 return cmp(self.data, self.__class__(other).data)
118
119 - def _rc(self, a):
120 if len(shape(a)) == 0: return a 121 return self.__class__(a)
122 123 124 ##################################################################### 125 # 126 # In essense, a template class Set is a binary tree. The advantage of 127 # of Set is that you could easily to add and delete an element from the 128 # the set. The disadvatage is that you cannot manipulate those data in 129 # in a set as a whole. 130 # 131 # ATTENTION: set is ABSOLUTELY not a list. If your data behave like a 132 # list and you want to treat them as a set, please use VECTOR. 133 # For more information. please have a look at STL (Standard Template 134 # Library) head file set.h 135 # 136 # The Set class below employs LIST to store data, which would be updated 137 # in the future for both speed and memory management 138 # 139 #######################################################################
140 -class Set:
141 """ 142 Base class for sets of objects. The objects are stored in a list. 143 For the sake of simplicity, the set is assumed to be homogenous 144 Functios below are provided: 145 add (+), sub (-), and (&), or (|), xor (^) 146 """
147 - def __init__(self, objects=None, CompFunc= None):
148 149 self.CompObj = CompFunc 150 if objects: 151 self.DataObj = uniqueSort(objects, self.CompObj) 152 else: 153 self.DataObj = []
154
155 - def __getitem__(self,key):
156 return self.DataObj[key]
157
158 - def __getslice__(self,i,j):
159 return self._rc(self.DataObj[i:j])
160
161 - def __repr__(self):
162 if self.DataObj: return '<instance of %s> %d object: ' % \ 163 (self.__class__,len(self.DataObj))+ repr(self.DataObj)
164
165 - def __len__(self):
166 return len(self.DataObj)
167
168 - def __cmp__(self, right):
169 if type(right) == ListType: 170 return cmp( self.DataObj, right) 171 else: 172 assert isinstance(right, self.__class__) 173 return cmp( self.DataObj, right.DataObj)
174
175 - def filter(self, func):
176 assert callable(func) 177 newlist = filter(func, self.DataObj) 178 return self._rc(newlist)
179
180 - def __add__(self, right):
181 if type(right) == ListType: 182 return self._rc( self.DataObj + right, self.CompObj ) 183 if type(right) == TupleType: 184 return self._rc( self.DataObj + list(right), self.CompObj ) 185 assert isinstance(right, self.__class__) 186 return self._rc( self.DataObj+right.DataObj, self.CompObj )
187
188 - def __sub__(self, right):
189 if type(right) not in [ListType,TupleType]: 190 assert isinstance(right, self.__class__) 191 rlist = right.DataObj 192 else: 193 rlist = right 194 195 data = {} 196 for item in self.DataObj: data[item] = None 197 for ritem in rlist: 198 if data.has_key(ritem): del data[ritem] 199 return self._rc(data.keys(),self.CompObj)
200 201 # for logical operation, the two operands are required to be sets 202 # Since both sets are ordered, it would be better to perform logical 203 # operation by 'overlap' method. e.g. 204 # set1 ---------------------- 205 # i| |j 206 # set2 ===================== 207 # Only for overlap regions (i,j), special comparision are required. It 208 # seems that this would speed logical operation.
209 - def __and__(self, right):
210 assert isinstance(right, self.__class__) 211 if len(self.DataObj) < len(right.DataObj): 212 l1 = right.DataObj 213 l2 = self.DataObj 214 else: 215 l1 = self.DataObj 216 l2 = right.DataObj 217 218 data = {} 219 for item in l1: data[item] = None 220 res = {} 221 for item in l2: 222 if data.has_key(item): res[item] = None 223 224 return self._rc(res.keys(),self.CompObj)
225 226 # !!! In a sense, __or__ is nearly identical to __add__.
227 - def __or__(self, right):
228 assert isinstance(right, self.__class__) 229 return self._rc( self.DataObj+right.DataObj, self.CompObj )
230
231 - def __xor__(self, right):
232 assert isinstance(right, self.__class__) 233 if len(self.DataObj) < len(right.DataObj): 234 l1 = right.DataObj 235 l2 = self.DataObj 236 else: 237 l1 = self.DataObj 238 l2 = right.DataObj 239 240 data = {} 241 for item in l1: data[item] = None 242 for item in l2: 243 if data.has_key(item): del data[item] 244 else: data[item] = None 245 246 return self._rc(data.keys(), self.CompObj)
247
248 - def _rc(self,objlst,func):
249 return self.__class__(objlst,func)
250 251 252 ##################################################################### 253 # function tupleArrayList flat all the arrays first, and then 254 # combine them. At last, output list 255 #
256 -def tupleArrayList( arrays ):
257 num = len(arrays) 258 dimensions = arrays[1].shape 259 size = multiply.reduce(dimensions) 260 261 larray = zeros((num,size)) 262 for i in range(num): 263 larray[i] = arrays[i].flat 264 265 carray = transpose ( array (tuple(larray)) ) 266 return map(lambda x: tupleElement(x), carray.tolist())
267 268 269 # associate an list order to each element in the array
270 -def tupleArrayOrderList( arr ):
271 size = multiply.reduce( arr.shape ) 272 orderarr = arange(size) 273 newarray = array([arr.flat,orderarr]) 274 carray = transpose(newarray) 275 return map(lambda x: tupleElement(x), carray.tolist())
276 277 # the list in extractOrderList must be in format: [(a1,r1),(a2,r2)...(an,rn)]
278 -def extractOrderList ( lst ):
279 arrlist = transpose( array(lst) ) 280 return arrlist[1].tolist()
281 282 # select non zero grid points from an array
283 -def selectNonZeroGrids ( arr ):
284 return nonzero( arr.flat)
285 286 # associate an order list to an array to form a new array
287 -def tupleArrayOrder( arr ):
288 dimensions = list(arr.shape) 289 dimensions.append(2) 290 lst = tupleArrayOrderList(arr) 291 return reshape( lst, dimensions)
292 293 ### 294 # Function tupleArrayElement : Tuple array elements 295 # Attention: these array must be of the same dimensions. 296 # It is you who are responsible for any failures due to 297 # improper function call 298 #
299 -def tupleArrayElement( arrays ):
300 dimensions = list(arrays[1].shape) 301 dimensions.append(len(arrays)) 302 # combined list 303 clist = tupleArrayList( arrays ) 304 return reshape( clist,dimensions)
305 306 307 ### 308 # find those points that are adjactant with the seed element 309 # Typically, the list is a point list [ point1, point2, ... ] 310 # eg. [(3,4,5), (3,2,6), (5,2,1) ...] 311 # 312 # Input: list ( tuple, or array), seed 313 # output: ( group, rest ), both group and rest are lists 314 #
315 -def findNeighbours ( lst, seed = None ):
316 assert type(lst) in [ListType, TupleType, ArrayType] 317 length = len(lst) 318 if length == 0: return ([],[]) 319 arrlst = array(lst) 320 321 if seed == None: firstEle = lst[0] 322 else: firstEle = seed 323 size = len( firstEle ) 324 325 result = abs( arrlst - array(firstEle)) 326 compones = ones((size)) 327 compresult = less_equal ( result, compones ) 328 329 resultpositive = product(compresult,1) 330 resultnegative = equal(resultpositive,0) 331 selectindex = nonzero( resultpositive ) 332 nonselectindex = nonzero( resultnegative) 333 334 #get and extract the adjactent elements 335 #Attention: array([0]) is FALSE condition !!!!! 336 point_1s = take( arrlst, selectindex).tolist() 337 point_rest = take(arrlst,nonselectindex).tolist() 338 return (point_1s, point_rest)
339 340 ### 341 # find a continous region starting from a seed point 342 # Attention: function below is not suitable for large 343 # groups since it use list to perform the task. 344 #
345 -def findOneGroup ( lst, seed = None ):
346 res = findNeighbours(lst, seed) 347 neighbours = res[0] 348 environ = res[1] 349 350 # Below is a tricky loop 351 for ele in neighbours: 352 res2 = findNeighbours(environ, ele) 353 neighbour2 = res2[0] 354 environ = res2[1] 355 length = len(neighbours) 356 neighbours[length:] = neighbour2 357 # trick again: return [(x,y,z) ...], instead of [[x,y,z] ...] 358 group = map(tuple,neighbours) 359 environment = map(tuple, environ) 360 return [group, environment]
361 362 ### 363 # Clutering a list of points into groups baset upon their spacial 364 # location. return [ group1, group2, ... ]. for each group, the 365 # data structure looks like [ (x1,y1,z1), (x2,y2,z2), ... ] 366 #
367 -def findGroups ( lst ):
368 groups = [] 369 res = findOneGroup(lst) 370 grp = res[0] 371 enviro = res[1] 372 groups.append( grp ) 373 374 while enviro: 375 res = findOneGroup( enviro) 376 grp = res[0] 377 enviro = res[1] 378 groups.append( grp ) 379 return groups
380 381 382 ##################################################################### 383 # Class GridPointSet contains a set of grid points. Typically, this 384 # set is generated by AutoGrid search functions. 385 #
386 -class GridPointSet(Set):
387 - def __init__(self, gridobj, pointset, compobj = None):
388 self.GridObj = gridobj 389 Set.__init__(self, pointset, compobj) 390 self.viewer = None 391 self.geom = None
392
393 - def _rc(self,objlst,func):
394 return self.__class__(self.GridObj, objlst, func)
395
396 - def index2coordinate(self):
397 # coor = ( index - centerIndex) * spacing + center 398 CI =array(self.GridObj.shape) 399 CI = (CI - 1)/2 400 center = array(self.GridObj.CENTER) 401 return (array(self.DataObj)-CI)*self.GridObj.SPACING+center
402 403 # group grid points, loci is the miminum loci size
404 - def findGroups(self):
405 return findGroups (self.DataObj)
406 407 # color grids. color means "red, blue, yellow" or RGB color(,,) 408 # self.color("red"); self.color((1,0,0))
409 - def color(self, color):
410 colortable = {'GREEN': ( 0.0, 1.0, 0.0), 411 'BLUE' : ( 0.0, 0.0, 1.0), 412 'WHITE': ( 1.0, 1.0, 1.0), 413 'RED' : ( 1.0, 0.0, 0.0), 414 'YELLOW': ( 1.0, 1.0, 0.0), 415 'CYAN' : ( 0.0, 1.0, 1.0), 416 'MAGENTA':( 1.0, 0.0, 1.0), 417 'BLACK' : ( 0.0, 0.0, 0.0) } 418 if type(color) == StringType: 419 colorname = string.upper(color) 420 if colortable.has_key(colorname): 421 color = colortable[colorname] 422 else: 423 raise ValueError('bad color name') 424 else: 425 assert type(color) == TupleType 426 self.geom.Set(materials=(color,), inheritMaterial=0)
427
428 - def colorByValue(self):
429 from DejaVu import colorTool 430 cmap = colorTool.RGBRamp() 431 val = self.getValue() 432 color = colorTool.Map(val, cmap) 433 self.geom.Set(materials=color, inheritMaterial=0)
434
435 - def getValue(self):
436 lst = self.GridObj.To1Ds(self.DataObj) 437 return( take(self.GridObj.array.flat, lst) )
438
439 - def display(self, viewer = None):
440 from DejaVu.Spheres import Spheres 441 from DejaVu import Viewer 442 443 if viewer==None: 444 raise None 445 else: 446 assert isinstance(viewer, Viewer) 447 self.viewer = viewer 448 449 if not self.geom: 450 pts = self.index2coordinate() 451 self.geom = Spheres('GridPoints', centers = pts, 452 radii = 0.2, protected=True) 453 self.viewer.AddObject(self.geom)
454 455 456 ##################################################################### 457 # In essence, class Grid is an adaptor to Numeric Array so 458 # that user can manipulate Grid just like it's an array. 459 #
460 -class Grid:
461 - def __init__(self, data, typecode = None):
462 if typecode == None: 463 self.array = asarray(data) 464 else: 465 self.array = array(data, typecode) 466 467 self.shape = self.array.shape 468 self.base = self._base() 469 self.flat = self.array.flat 470 self.min = minimum.reduce(self.array.flat) 471 self.max = maximum.reduce(self.array.flat) 472 self.typecode = self.array.typecode() 473 self.name = string.split(str(self.__class__))[0] 474 # data below are for viewer 475 self.viewer = None 476 self.geom = None 477 if not hasattr(self, 'SPACING'): self.SPACING=1.0 478 if not hasattr(self, 'CENTER'): self.CENTER=(0.,0.,0.)
479 480
481 - def doSlice(self, isovar=0, timestep=0, axis='x', sliceNum=10):
482 #in this case have to recalculate self.the_data 483 #from swig import swig 484 if not hasattr(self, 'the_data'): 485 self.initIsoContour(step=1) 486 #sl = isocontour.getSlice(self.the_data, isovar, timestep, axis,sliceNum) 487 #print sl.width 488 #print sl.height 489 #print sl.datatype 490 #print sl.fdata 491 #sld = swig.getfloatarray(sl.fdata,(sl.width,sl.height)) 492 sld = isocontour.getSliceArray(self.the_data, isovar, 493 timestep, axis,sliceNum) 494 #print sld.shape 495 #return sl,sld 496 return sld
497
498 - def doSlice2(self, isovar=0, timestep=0, axis='x', sliceNum=10):
499 if not hasattr(self, 'da'): 500 sh = (1,1,self.shape[0],self.shape[1],self.shape[2]) 501 self.da = zeros(sh).astype('f') 502 self.da[0][0] = array(reshape(swapaxes(self.array,0,2),self.shape)).astype('f') 503 d = swapaxes(self.da, 2, 4) 504 if axis=='x': 505 sld = array(transpose(d[isovar,timestep,sliceNum])) 506 elif axis=='y': 507 sld = array(transpose(d[isovar,timestep,:,sliceNum])) 508 elif axis=='z': 509 sld = array(transpose(d[isovar,timestep,:,:,sliceNum])) 510 return sld.shape, sld
511
512 - def buildSliceVertices(self, width, height, axis, sliceNum):
513 cen = array(self.CENTER).astype('f') 514 dim = array(self.NELEMENTS).astype('f') 515 span = array(self.SPACING).astype('f') 516 orig = cen -((dim-1)/2)*span 517 518 #NB: 519 #for x-perpendicular slice, 520 #coords for y and z corners are origin PLUS whole extent 521 #for x-perpendicular slice, 522 #coord for x corners is origin +sliceNum/totalNum * extent 523 # for y- or z- perpendicular slice, 524 #coords found in same fashion 525 nelements = array(self.NELEMENTS) 526 nelements = nelements -1 527 #NB: self.step is ALWAYS one for these slices 528 extent = span*nelements 529 axisList=['x','y','z'] 530 axisInd=axisList.index(axis) 531 partialExtent=(float(sliceNum)/float(nelements[axisInd]))*extent 532 self.pE=partialExtent 533 #partialExtent = extent * (sliceNum/(height-1.)) 534 #NB the order of visiting the corner pts of slice are probably wrong... 535 #keep order x->y->z->x 536 #so that for each axis, next point has delta in next axis 537 if axis == 'x': 538 v = array([orig + (partialExtent[0], 0, 0), 539 orig + (partialExtent[0], extent[1],0), 540 orig + (partialExtent[0], extent[1],extent[2]), 541 orig + (partialExtent[0], 0,extent[2]) 542 ] ) 543 elif axis == 'y': 544 v = array([ 545 orig + (0,partialExtent[1], 0), 546 ##orig + (extent[0], partialExtent[1], 0), 547 orig + (0, partialExtent[1], extent[2]), 548 orig + (extent[0], partialExtent[1], extent[2]), 549 ##orig + (0, partialExtent[1], extent[2]) 550 orig + (extent[0], partialExtent[1], 0) 551 ] ) 552 elif axis == 'z': 553 v = array([orig + (0,0,partialExtent[2]), 554 orig + (extent[0], 0, partialExtent[2]), 555 orig + (extent[0], extent[1],partialExtent[2]), 556 orig + (0, extent[1], partialExtent[2]) 557 ] ) 558 return v
559
560 - def buildTextureCoords(self, width, height, axis, sliceNum):
561 dim1=dim2=1 562 while dim1<width: dim1 = dim1<<1 563 while dim2<height: dim2 = dim2<<1 564 maxI=float(width)/float(dim1) 565 max2=float(height)/float(dim2) 566 return ((0,0), (maxI,0), (maxI, max2), (0, max2))
567 568 #def initIso2DContour(self, step=1): 569 #notes from 6/30: 570 #d = swapaxes(self.da, 2,4) 571 #sld = array(transpose(d[0,0,30])) 572 #sld.shape=(1,1,61,61) 573 #first arg is slice data, then origin, then spacing of data... 574 #data = isocontour.newDatasetRegFloat2D(sld,(0,0),(.1,.1)) 575 #isoc = isocontour.getContour2d(data,0,0,-.71) 576 #center = array(self.CENTER).astype('f') 577 #dim = array(self.shape).astype('f') 578 #span = array(self.SPACING).astype('f') 579 #orig = center - ((dim-1)/2)*span 580 #nb: this is wrong->error message is that daSmallhas wrong shape... 581 #self.the_data2D = isocontour.newDatasetRegFloat2D(self.daSmall[1:], 582 #orig[:2].astype('f'), (span*step,)*2 ) 583 #self.info2D = isocontour.getDatasetInfo(self.the_data2D) 584
585 - def initIsoContour(self, step=3):
586 self.step=step 587 sh = (1,1,self.shape[0],self.shape[1],self.shape[2]) 588 self.da = zeros(sh).astype('f') 589 self.da[0][0] = array( reshape( swapaxes( self.array, 0, 2), self.shape ) ).astype('f') 590 #to gain control over sampling step(s) 591 try: 592 self.daSmall = array(self.da[:,:,::step[0],::step[1],::step[2]]).astype('f') 593 stepthree=1 594 except: 595 self.daSmall = array(self.da[:,:,::step,::step,::step]).astype('f') 596 stepthree=0 597 center = array(self.CENTER).astype('f') 598 dim = array(self.shape).astype('f') 599 span = array(self.SPACING).astype('f') 600 orig = center - ((dim-1)/2)*span 601 #print 'span*step,)*3=', (span*step,)*3 602 if stepthree: 603 self.the_data = isocontour.newDatasetRegFloat3D(self.daSmall, 604 orig.astype('f'), (span*step[0],span*step[1],span*step[2]) ) 605 else: 606 self.the_data = isocontour.newDatasetRegFloat3D(self.daSmall, 607 orig.astype('f'), (span*step,)*3 ) 608 self.info = isocontour.getDatasetInfo(self.the_data)
609 610 #isovar is 0, timestep = 0
611 - def getIsoContour(self, val=-0.71):
612 isoc = isocontour.getContour3d(self.the_data, 0, 0, val, 613 isocontour.NO_COLOR_VARIABLE) 614 vert = zeros((isoc.nvert,3)).astype('f') 615 norm = zeros((isoc.nvert,3)).astype('f') 616 col = zeros((isoc.nvert)).astype('f') 617 tri = zeros((isoc.ntri,3)).astype('i') 618 isocontour.getContour3dData(isoc, vert, norm, col, tri, 1) 619 #print 'vert.shape=', vert.shape 620 #print 'vert=', vert 621 #if len(vert)<20: 622 #print 'vert=', vert 623 #else: 624 #print 'vert[:3]=', vert[:3] 625 #print 'tri.shape=', tri.shape 626 #print 'tri[:3]=', tri[:3] 627 #print 'col.shape=', col.shape 628 #print 'col[:3]=', col[:3] 629 return vert, norm, col, tri
630 631 632 633 # calculate the base for each dimension, which will be used 634 # when we convert linear index into an array index
635 - def _base(self):
636 dimensions = self.shape 637 base = [] 638 length = len(dimensions) 639 for i in range(length): 640 b = 1 641 # base size = dimension[i+1]* ... * dimension[length] 642 for j in range( i+1, length ): 643 b = b*dimensions[j] 644 base.append(b) 645 return tuple(base)
646 647 # convert an flat index into an array index. For example, for 648 # array(3,2,4), the tenth element corresponds to (1,0,2). i.e. 649 # (1* 8 + 0* 4 + 2* 1), (8,4,1) is the base for array(3,2,4)
650 - def To3D(self, index):
651 res = [] 652 index = int(index) 653 length = len(self.shape) 654 base = self.base 655 Index = [] 656 for i in range(length): 657 xyz = index / base[i] 658 index = index - xyz*base[i] 659 Index.append(xyz) 660 res.append(tuple(Index)) 661 return res
662 663 # for the sake of efficiency, another similar functions 664 # is also provided, which is a loop of 1DTo3D(...)
665 - def To3Ds(self, indices):
666 length = len(self.shape) 667 base = self.base 668 Indices = [] 669 for index in indices: 670 index = int(index) 671 Index = [] 672 for i in range(length): 673 xyz = index / base[i] 674 index = index - xyz*base[i] 675 Index.append(xyz) 676 Indices.append(tuple(Index)) 677 return Indices
678 679 # Attention: the return index is an array, not a list
680 - def To1Ds(self, indices):
681 length = len(self.shape) 682 base = array(self.base) 683 arrIndex = array(indices) 684 return sum( arrIndex*base, -1)
685 686
687 - def __repr__(self):
688 return self.name+repr(self.array.shape)
689
690 - def __array__(self,t=None):
691 if t: return asarray(self.array,t) 692 return asarray(self.array)
693 694 # bugs found in float function 695 #def __float__(self): 696 #return float(asarray(self.array)) 697 698 # Grid get and set functions (both attribute and slices)
699 - def __len__(self): return len(self.array)
700
701 - def __getitem__(self, index):
702 return self._rc(self.array[index])
703
704 - def __getslice__(self, i, j):
705 return self._rc(self.array[i:j]) 706
707 - def __setitem__(self, index, value): self.array[index] = \ 708 asarray(value,self.typecode)
709 - def __setslice__(self, i, j, value): self.array[i:j] = asarray(value)
710 711 # Arithematic operation, add, sub, mul, div and the like
712 - def __abs__(self): return self._rc(absolute(self.array))
713 - def __neg__(self): return self._rc(-self.array)
714
715 - def __add__(self, other):
716 return self._rc(self.array+asarray(other)) 717 __radd__ = __add__ 718
719 - def __sub__(self, other):
720 return self._rc(self.array-asarray(other))
721 - def __rsub__(self, other):
722 return self._rc(asarray(other)-self.array) 723
724 - def __mul__(self, other):
725 return self._rc(multiply(self.array,asarray(other))) 726 __rmul__ = __mul__ 727
728 - def __div__(self, other):
729 return self._rc(divide(self.array,asarray(other)))
730 - def __rdiv__(self, other):
731 return self._rc(divide(asarray(other),self.array)) 732
733 - def __pow__(self,other):
734 return self._rc(power(self.array,asarray(other)))
735 - def __rpow__(self,other):
736 return self._rc(power(asarray(other),self.array)) 737
738 - def __sqrt__(self):
739 return self._rc(sqrt(self.array)) 740
741 - def tostring(self): return self.array.tostring()
742
743 - def byteswapped(self): return self._rc(self.array.byteswapped())
744 - def astype(self,typecode): return self._rc(self.array.astype(typecode))
745 - def typecode(self): return self.array.typecode()
746
747 - def itemsize(self): return self.array.itemsize()
748 - def iscontiguous(self): return self.array.iscontiguous()
749 750 # Attention: the function below is very import, especially 751 # for drived class. You could overload this function.
752 - def _rc(self, a):
753 if len(shape(a)) == 0: return a 754 else: return self.__class__(a)
755 756 # An interface function to class GridPointSet
757 - def _GridPoint(self,index):
758 return GridPointSet (self, self.To3D(index))
759
760 - def _GridPointSet(self, data):
761 #return self.1DTo3Ds(data), 3d coordinate list 762 return GridPointSet (self, self.To3Ds(data))
763
764 - def findMaxGrid(self):
765 return self._GridPoint( argmax(self.array.flat))
766
767 - def findMaxValue(self):
768 return max(self.array.flat)
769
770 - def findMinGrid(self):
771 return self._GridPoint( argmin(self.array.flat))
772
773 - def findMinValue(self):
774 return min(self.array.flat)
775
776 - def findTopGrids(self,n):
777 sortarrIndex1D = argsort(self.array.flat) 778 return self._GridPointSet( sortarrIndex1D[-n:] )
779
780 - def findTopValues(self,n):
781 sortarr1D = sort(self.array.flat) 782 return sortarr1D[-n:]
783
784 - def findBottomGrids(self,n):
785 sortarrIndex1D = argsort(self.array.flat) 786 return self._GridPointSet( sortarrIndex1D[:n] )
787
788 - def findBottomValues(self,n):
789 sortarr1D = sort(self.array.flat) 790 return sortarr1D[:n]
791 792 # find the grids which is above,equal ot below specified value
793 - def _findGrid(self, arr):
794 indices = nonzero(arr.flat) 795 return self._GridPointSet( indices)
796
797 - def findAboveGrids(self,value):
798 result = greater(self.array, value) 799 return self._findGrid ( result )
800
801 - def findAboveEqualGrids(self,value):
802 result = greater_equal(self.array,value) 803 return self._findGrid ( result )
804
805 - def findBelowGrids(self,value):
806 result = less(self.array,value) 807 return self._findGrid ( result )
808
809 - def findBelowEqualGrids(self,value):
810 result = less_equal(self.array,value) 811 return self._findGrid ( result )
812
813 - def findBetweenGrids(self,low,hi):
814 result= greater(self.array,low)*less(self.array,hi) 815 return self._findGrid ( result )
816
817 - def findBetweenEqualGrids(self,low,hi):
818 result= greater_equal(self.array,low)*less_equal(self.array,hi) 819 return self._findGrid ( result )
820 821 # find the value which satisfying conditions. return list
822 - def _findValue( self,arr):
823 indices = nonzero(arr.flat) 824 result = take(self.array.flat, indices) 825 return result.tolist()
826
827 - def findAboveValues(self,value):
828 result = greater(self.array, value) 829 return self._findValue ( result )
830
831 - def findAboveEqualValues(self,value):
832 result = greater_equal(self.array,value) 833 return self._findValue ( result )
834
835 - def findBelowValues(self,value):
836 result = less(self.array,value) 837 return self._findValue ( result )
838
839 - def findBelowEqualValues(self,value):
840 result = less_equal(self.array,value) 841 return self._findValue( result )
842
843 - def findBetweenValues(self,low,hi):
844 result= greater(self.array,low)*less(self.array,hi) 845 return self._findValue ( result )
846
847 - def findBetweenEqualValues(self,low,hi):
848 result= greater_equal(self.array,low)*less_equal(self.array,hi) 849 return self._findValue ( result )
850 851 # find order (or index) of a value in a grid object
852 - def findOrder(self, value):
853 sortIndex = argsort(self.array.flat) 854 length = len(sortIndex) 855 begin = 0 856 end = length -1 857 858 # initial comparision 859 MIN = self.array.flat[sortIndex[0]] 860 MAX = self.array.flat[sortIndex[-1]] 861 if value <= MIN: return 0 862 if value == MAX: return end 863 if value > MAX: return length 864 865 # determine the order of value 866 middle = ( begin + end ) /2 867 while begin < end: 868 pos = sortIndex[middle] 869 if self.array.flat[pos] == value: 870 return middle 871 elif self.array.flat[pos] > value: 872 end = middle 873 else: 874 begin = middle + 1 875 middle = ( begin + end ) /2 876 return middle
877 878 # get the value of the ith element
879 - def get_ith_element ( self, i):
880 sortIndex = argsort(self.array.flat) 881 return self.array.flat[ sortIndex[i] ]
882 883 # statistical information on Grid values
884 - def findGridNumbers ( self, low, hi):
885 result= greater_equal(self.array,low)*less(self.array,hi) 886 return len(nonzero(result.flat))
887 888 # call: (intervals, MIN, MAX, tick)
889 - def distribution(self,intervals = 100,MIN=None,MAX = None,tick =0):
890 if MIN == None: MIN = self.findMinValue() 891 if MAX == None: MAX = self.findMaxValue() 892 step = ( MAX - MIN) / intervals 893 varray1 = arange(intervals)* step + MIN 894 varray2 = arange(1,intervals+1)* step + MIN 895 result = map( self.findGridNumbers, varray1, varray2 ) 896 if tick == 0 : 897 return result 898 else: 899 return map(None, result, varray1,varray2)
900 901 # display Gridbox
902 - def displayBox(self,viewer=None, materials=None):
903 from DejaVu.Box import Box 904 from DejaVu.Viewer import Viewer 905 #print 'materials = ', materials 906 if viewer==None: 907 print "must specify viewer" 908 return 909 if hasattr(self, 'box'): 910 return 911 sh=array(self.shape) 912 sh2=(sh-1)/2 913 pt1=(sh-1)/2*self.SPACING 914 pt2=0.0-pt1 915 if hasattr(self, 'GRID_DATA_FILE'): 916 nstr=string.split(self.GRID_DATA_FILE,'.')[0]+'_box' 917 else: 918 nstr='box' 919 if not materials: 920 materials = ((0,0,1),(0,1,0),(0,0,1),(0,1,0),(1,0,0),(1,0,0),) 921 #print 'calling Box constructor with materials = ', materials 922 self.box=Box(nstr,cornerPoints=(pt2,pt1), materials=materials, 923 inheritMaterial=0, inheritLineWidth=0) 924 viewer.AddObject(self.box) 925 if hasattr(self, 'CENTER'): 926 self.box.Set(center=self.CENTER) 927 self.box.RedoDisplayList()
928 929
930 - def display(self, viewer=None):
931 """Draws the Grid box""" 932 from DejaVu.IndexedPolylines import IndexedPolylines 933 from DejaVu import Viewer 934 935 if viewer==None: 936 raise None 937 #self.viewer = self.GetViewer() 938 else: 939 assert isinstance(viewer, Viewer) 940 self.viewer = viewer 941 942 if not self.geom: 943 x, y, z = self.shape 944 (rx,ry,rz)=( (x-1)/2 , (y-1)/2, (z-1)/2 ) 945 #self.corners = ((0,0,0), (x,0,0), (0, y, 0), (x,y,0), 946 #(0,0,z), (x,0,z), (0, y, z), (x,y,z)) 947 self.corners = ((-rx,ry,rz),(rx,ry,rz),(-rx,-ry,rz), 948 (rx,-ry,rz), (-rx,ry,-rz),(rx,ry,-rz), 949 (-rx,-ry,-rz), (rx,-ry,-rz)) 950 self.indices = ( (0,2,3,1), (1,3,7,5), (5,7,6,4), 951 (0,4,6,2), (0,1,5,4), (2,6,7,3) ) 952 self.geom = IndexedPolylines('Grid', 953 vertices = self.corners, 954 faces = self.indices, protected=True) 955 self.viewer.AddObject(self.geom)
956 957 ################################################################### 958
959 -def ReadAutoGridMap(file):
960 f = open(file, 'r') 961 962 try: 963 GRID_PARAMETER_FILE = string.split(f.readline())[1] 964 except: 965 GRID_PARAMETER_FILE = '' 966 GRID_DATA_FILE = string.split(f.readline())[1] 967 MACROMOLECULE = string.split(f.readline())[1] 968 969 # spacing 970 SPACING = float(string.split(f.readline())[1]) 971 972 # number of points and center 973 (nx,ny,nz) = string.split(f.readline())[1:4] 974 NELEMENTS = (nx,ny,nz) = (int(nx)+1, int(ny)+1, int(nz)+1) 975 (cx,cy,cz) = string.split(f.readline())[1:4] 976 CENTER = ( float(cx),float(cy), float(cz)) 977 978 # read grid points 979 points = map( lambda x: float(x), f.readlines()) 980 TMPGRIDS = swapaxes(reshape( points,(nz,ny,nx)), 0, 2) 981 GRIDS = array(TMPGRIDS) 982 f.close() 983 return (GRID_PARAMETER_FILE, GRID_DATA_FILE,MACROMOLECULE, 984 SPACING, NELEMENTS, CENTER, GRIDS)
985 986 from Volume.IO.dxReader import ReadDX 987
988 -class DX(Grid):
989 - def __init__(self, file, typecode = None,gui=None, viewer=None):
990 991 # type - dependent initialization maybe unsafe 992 # Obviously, only original AutoGrid Object has 993 # additional attributes 994 reader = ReadDX() 995 grid = reader.read(file,True) 996 #Grid.__init__(self, results[6], typecode) 997 self.GRID_PARAMETER_FILE = file 998 self.GRID_DATA_FILE = file 999 self.MACROMOLECULE = None 1000 self.SPACING = grid.stepSize[0] 1001 self.NELEMENTS = grid.dimensions 1002 self.CENTER = grid.centerPoint() 1003 Grid.__init__(self, grid.data, typecode) 1004 self.gui=gui 1005 self.viewer=viewer
1006 1007
1008 -class AutoGrid(Grid):
1009 - def __init__(self, data, typecode = None,gui=None, viewer=None):
1010 1011 if ( type(data) == StringType): 1012 # type - dependent initialization maybe unsafe 1013 # Obviously, only original AutoGrid Object has 1014 # additional attributes 1015 results = ReadAutoGridMap(data) 1016 #Grid.__init__(self, results[6], typecode) 1017 self.GRID_PARAMETER_FILE = results[0] 1018 self.GRID_DATA_FILE = results[1] 1019 self.MACROMOLECULE = results[2] 1020 self.SPACING = results[3] 1021 self.NELEMENTS = results[4] 1022 self.CENTER = results[5] 1023 Grid.__init__(self, results[6], typecode) 1024 self.SPACING = results[3] 1025 self.CENTER = results[5] 1026 self.gui=gui 1027 self.viewer=viewer 1028 else: 1029 Grid.__init__(self, data, typecode)
1030
1031 - def index2coordinate(self, index):
1032 # coor = ( index - centerIndex) * spacing + center 1033 CI =array(self.shape) 1034 CI = (CI - 1)/2 1035 center = array(self.CENTER) 1036 return tuple ((array(index)-CI)*self.SPACING+center)
1037
1038 - def coordinate2index( self, coordinate):
1039 c = array(self.CENTER) 1040 CI =array(self.shape) 1041 CI = (CI - 1)/2 1042 return tuple( map(int,(array(coordinate)-c)/self.SPACING+CI) )
1043
1044 - def display(self, viewer=None):
1045 Grid.display(self) 1046 scale = self.SPACING 1047 GL.glPushMatrix() 1048 GL.glLoadIdentity() 1049 GL.glScalef( float(scale), float(scale), float(scale)) 1050 center = array( self.CENTER ) / scale 1051 GL.glTranslatef(float(center[0]), float(center[1]), float(center[2])) 1052 GL.glMultMatrixf(self.geom.Matrix) 1053 self.geom.Matrix = GL.glGetDoublev(GL.GL_MODELVIEW_MATRIX) 1054 self.geom.Matrix.shape = (16,) 1055 GL.glPopMatrix()
1056 1057 1058
1059 -class AutoGridSurfaceGui:
1060
1061 - def __init__(self,grid,vf):
1062 self.grid=grid 1063 self.vf = vf 1064 self.master=vf.GUI.ROOT 1065 #for Surface visibility: 1066 self.vVar=Tkinter.IntVar(self.master) 1067 self.vVar.set(0) 1068 #for isovalue 1069 self.isovalueVar=Tkinter.StringVar(self.master) 1070 self.isovalueVar.set('-0.071') 1071 #for sampling 1072 self.setVar=Tkinter.StringVar(self.master) 1073 ne=grid.NELEMENTS 1074 if ne[0]==ne[1]==ne[2]: 1075 self.setVar.set(3) 1076 else: 1077 self.setVar.set(1) 1078 #for rendermode 1079 self.renderModeVar=Tkinter.IntVar(self.master) 1080 #for box visibility 1081 self.boxvVar=Tkinter.IntVar(self.master) 1082 #for box 1083 self.box=None 1084 self.oldVals=[] 1085 grid.color = self.getColor() 1086 grid.surfaceGUI=self 1087 #keep a list of entry widgets to forget for cleanup 1088 self.entry_widgets = []
1089
1090 - def delete_all_widgets(self, event=None):
1091 for widget in self.entry_widgets: 1092 widget.grid_forget()
1093 1094
1095 - def initColorVars(self):
1096 self.colorVars={} 1097 keyList=['C','N','n','O','S','H','A','f','c','b','I','F','M','X','e','NA','OA','SA','HD'] 1098 colorList=[((1,1,1),),((0,0,1),),((0,.2,1),),((1,0,0),),((1,1,0),), 1099 ((0,1.0,1.0),),((0,1,0),),((0,.5,.5,),),((0.5,0.5,0,),), 1100 ((.5,0,.5,),),((.2,.2,.6,),),((.6,.4,0),),((0.2,1,0.2),), 1101 ((0.2,0.2,1),),((0.1,0.1,0.1),), ((0,0,1),), ((1,0,0),),((1,1,0),),((0,1,1),)] 1102 for i in range(len(keyList)): 1103 self.colorVars[keyList[i]]=colorList[i]
1104
1105 - def getColor(self):
1106 if not hasattr(self,'colorVars'): self.initColorVars() 1107 if self.grid.atType in self.colorVars.keys(): 1108 return self.colorVars[self.grid.atType] 1109 else: 1110 return ((1,1,1),)
1111
1112 - def makeIfdEntry(self,ifd,bButtons,box=1,visibility=1,set=1,slider=1,rendermode=1):
1113 #NB: it could be more flexible if other functions +/or gridcfgs etc passed 1114 if not hasattr(ifd,'form'): 1115 t="Error: form not initialized" 1116 self.vf.warningMsg(t, title="AutoGridSurfaceGui WARNING") 1117 return 1118 form=ifd.form 1119 #before making new entries, forget the bottom ones: 1120 for item in bButtons: 1121 ifd.entryByName[item]['widget'].grid_forget() 1122 columnctr=0 1123 gridname = os.path.basename(self.grid.name) 1124 if visibility: 1125 entry={'name':'%sVisBut'%self.grid.name, 1126 'widgetType':Tkinter.Checkbutton, 1127 'text':gridname, 1128 'variable':self.vVar, 1129 'gridcfg':{'sticky':Tkinter.W}, 1130 'command': self.changeVisibility} 1131 ifd.entryByName[entry['name']]=entry 1132 form.addEntry(entry) 1133 columnctr=columnctr+1 1134 self.entry_widgets.append(ifd.entryByName[entry['name']]['widget']) 1135 if set: 1136 entry={'name':'%ssetEnt'%self.grid.name, 1137 'widgetType':Tkinter.Entry, 1138 'wcfg':{'width':5, 1139 'textvariable':self.setVar}, 1140 'gridcfg':{'sticky':Tkinter.W,'row':-1, 1141 'column':1}} 1142 ## entry={'name':'%ssetEnt'%self.grid.name, 1143 ## 'widgetType':Tkinter.Entry, 1144 ## 'wcfg':{'width':5}, 1145 ## 'textvariable':self.setVar, 1146 ## 'gridcfg':{'sticky':Tkinter.W,'row':-1,'column':1}} 1147 #'commandArgs':form, 1148 #'command': self.updateSetVal} 1149 form.addEntry(entry) 1150 ifd.entryByName[entry['name']]=entry 1151 self.setWidget=ifd.entryByName[entry['name']]['widget'] 1152 ###setting command and commandArgs in entry didn't work!!!?!!! 1153 self.setWidget.bind('<Return>',self.updateSetVal) 1154 #add to list to delete: 1155 self.entry_widgets.append(self.setWidget) 1156 self.form=form 1157 columnctr=columnctr+1 1158 if slider: 1159 if self.grid.atType!='e': 1160 minval = self.grid.min 1161 if minval<0: 1162 maxval = -minval 1163 elif minval<1: 1164 maxval = 2. 1165 else: 1166 maxval=2.*minval 1167 else: 1168 minval = -3.0 1169 maxval = 3.0 1170 1171 ## entry = {'name':'%sSlider'%self.grid.name, 1172 ## 'widgetType':ExtendedSlider, 1173 ## 'command': self.CallBack, 1174 ## 'type':float, 1175 ## 'wcfg':{'label': " ",'minval':minval,'immediate':1, 1176 ## 'maxval':maxval,'init':-0.071, 'sd':'right'}, 1177 ## 'gridcfg':{'sticky':Tkinter.W,'row':-1, 1178 ## 'column':2, 'columnspan':2} } 1179 1180 entry = {'name':'%sSlider'%self.grid.name, 1181 'widgetType': ExtendedSliderWidget, 1182 'wcfg':{'label':" ", 1183 'minval':minval, 'maxval':maxval, 1184 'immediate':1, 1185 'init':-0.071, 1186 'labelsCursorFormat':'%4.4f', 1187 'command':self.CallBack, 1188 'sliderType':'float', 1189 'entrypackcfg':{'side':'right'}}, 1190 'gridcfg':{'sticky':Tkinter.W, 1191 'row':-1, 'column':2,'columnspan':2}} 1192 form.addEntry(entry) 1193 ifd.entryByName[entry['name']]=entry 1194 newslider=ifd.entryByName[entry['name']]['widget'] 1195 self.slider=newslider 1196 self.entry_widgets.append(self.slider) 1197 columnctr=columnctr+2 1198 if rendermode: 1199 entry={'name':'%sRenderBut'%self.grid.name, 1200 'widgetType':Tkinter.Checkbutton, 1201 'text':'LINE', 1202 'variable':self.renderModeVar, 1203 'gridcfg':{'sticky':Tkinter.W,'row':-1,'column':4}, 1204 'command': CallBackFunction(self.changeRenderMode,ifd)} 1205 ifd.entryByName[entry['name']]=entry 1206 form.addEntry(entry) 1207 self.entry_widgets.append(ifd.entryByName[entry['name']]['widget']) 1208 columnctr=columnctr+1 1209 if box: 1210 #print 'called grid.displayBox with materials= blue' 1211 self.grid.displayBox(self.vf.GUI.VIEWER, materials=((0.,0.,1.),)) 1212 self.boxvVar.set(1) 1213 entry={'name':'%sBoxBut'%self.grid.name, 1214 'widgetType':Tkinter.Checkbutton, 1215 'text':'ShowBox', 1216 'variable':self.boxvVar, 1217 'gridcfg':{'sticky':Tkinter.W,'row':-1,'column':5}, 1218 'command': self.changeBox} 1219 ifd.entryByName[entry['name']]=entry 1220 form.addEntry(entry) 1221 self.entry_widgets.append(ifd.entryByName[entry['name']]['widget']) 1222 columnctr=columnctr+1 1223 rowctr=2 1224 for item in bButtons: 1225 #better to increment row and column + use newvalues here 1226 #THIS ISN'T GENERAL!! 1227 gridcfg=ifd.entryByName[item]['gridcfg'] 1228 gridcfg['row']=gridcfg['row']+rowctr 1229 gridcfg['column']=gridcfg['column'] 1230 gridcfg=ifd.entryByName[item]['widget'].grid(gridcfg) 1231 #4/1: should srf be displayed when added (?) 1232 self.vVar.set(1) 1233 self.changeVisibility()
1234 1235
1236 - def changeVisibility(self,event=None):
1237 if self.vVar.get(): 1238 if self.grid.srf: 1239 self.grid.srf.Set(visible=1) 1240 else: 1241 self.getMap() 1242 self.grid.srf.Set(visible=1) 1243 else: 1244 if self.grid.srf: self.grid.srf.Set(visible=0) 1245 self.vf.GUI.VIEWER.Redraw()
1246 1247
1248 - def changeBox(self,event=None):
1249 if self.boxvVar.get(): 1250 self.grid.box.Set(visible=1) 1251 else: 1252 self.grid.box.Set(visible=0) 1253 self.vf.GUI.VIEWER.Redraw()
1254 1255
1256 - def changeRenderMode(self,ifd,event=None):
1257 if not self.grid.srf: 1258 #in this case build the surface AND display it 1259 self.getMap() 1260 #also need to set visibility check button 1261 self.vVar.set(1) 1262 if self.renderModeVar.get(): 1263 self.grid.srf.Set(frontPolyMode=GL.GL_LINE) 1264 #self.grid.srf.RenderMode(mode=GL.GL_LINE,face=GL.GL_FRONT) 1265 ifd.entryByName['%sRenderBut'%self.grid.name]['widget'].config(text='LINE') 1266 else: 1267 self.grid.srf.Set(frontPolyMode=GL.GL_FILL) 1268 #self.grid.srf.RenderMode(mode=GL.GL_FILL,face=GL.GL_FRONT) 1269 ifd.entryByName['%sRenderBut'%self.grid.name]['widget'].config(text='FILL') 1270 ifd.form.lift() 1271 self.vf.GUI.VIEWER.Redraw()
1272 1273
1274 - def CallBack(self,event=None):
1275 val=round(self.slider.get(),3) 1276 self.isovalueVar.set(str(val)) 1277 g=self.grid 1278 if not hasattr(g, 'the_data'): 1279 atSet=int(self.setVar.get()) 1280 g.initIsoContour(atSet) 1281 g.vert,g.norm,g.col,g.tri=g.getIsoContour(val) 1282 if g.srf: g.srf.Set(vertices=g.vert,vnormals=g.norm,faces=g.tri) 1283 self.vf.GUI.VIEWER.Redraw()
1284 1285
1286 - def updateSetVal(self, event=None):
1287 val=event.widget.get() 1288 intVal=int(val) 1289 if intVal>5 or intVal<1: 1290 self.vf.warningMsg('Only1,2,3,4 or 5 valid', title="AutoGridSurfaceGui WARNING:") 1291 ne=self.grid.NELEMENTS 1292 if ne[0]==ne[1]==ne[2]: 1293 self.setVar.set(3) 1294 else: 1295 self.setVar.set(1) 1296 self.getMap()
1297 1298
1299 - def initMap(self):
1300 grid=self.grid 1301 atType=grid.atType 1302 atSet=int(self.setVar.get()) 1303 atIsovalue=float(self.isovalueVar.get()) 1304 atColor=grid.color 1305 var=self.vVar 1306 1307 grid.initIsoContour(atSet) 1308 vert,norm,col,tri=grid.getIsoContour(atIsovalue) 1309 grid.srf=IndexedPolygons('iso_%s'%grid.name,vertices=vert, 1310 vnormals=norm, faces=tri, materials=atColor, inheritMaterial=0, 1311 inheritLineWidth=0, protected=True,) 1312 1313 if self.vf.userpref['sharpColorBoundariesForMsms']['value'] == 'blur': 1314 grid.srf.Set(inheritSharpColorBoundaries=False, sharpColorBoundaries=False,) 1315 1316 #THINK ABOUT THIS!!! 1317 grid.srf.pickable=1 1318 #grid.srf.pickable=0 1319 grid.srf.atType=atType 1320 grid.srf.Set(frontPolyMode=GL.GL_LINE) 1321 #grid.srf.RenderMode(mode=GL.GL_LINE,face=GL.GL_FRONT) 1322 grid.srf.grid=grid 1323 self.vf.GUI.VIEWER.AddObject(grid.srf) 1324 #is this necessary??? 1325 grid.srf.RedoDisplayList() 1326 #checkOnAddMoleculeRNC(self.vf) 1327 #oldVals keys are types, values lists 1328 self.oldVals=[atSet,atIsovalue,atColor] 1329 self.renderModeVar.set(1) 1330 grid.srf.RedoDisplayList()
1331
1332 - def updateMap(self):
1333 grid=self.grid 1334 atType=grid.atType 1335 atSet=int(self.setVar.get()) 1336 atIsovalue=float(self.isovalueVar.get()) 1337 atColor=grid.color 1338 var=self.vVar 1339 1340 grid.srf.pickable=1 1341 #grid.srf.pickable=0 1342 if not var.get(): 1343 grid.srf.Set(visible=0) 1344 else: 1345 grid.srf.Set(visible=1) 1346 #do possible update here: 1347 #CHECK FOR CHANGES? 1348 if atSet!=self.oldVals[0]: 1349 grid.initIsoContour(atSet) 1350 self.oldVals[0]=atSet 1351 grid.vert,grid.norm,grid.col,grid.tri=grid.getIsoContour(atIsovalue) 1352 grid.srf.Set(vertices=grid.vert, vnormals=grid.norm, 1353 faces=grid.tri, materials=atColor, visible=1, 1354 inheritMaterial=0) 1355 elif atIsovalue!=self.oldVals[1]: 1356 self.oldVals[1]=atIsovalue 1357 grid.vert,grid.norm,grid.col,grid.tri=grid.getIsoContour(atIsovalue) 1358 grid.srf.Set(vertices=grid.vert, vnormals=grid.norm, 1359 faces=grid.tri, materials=atColor,visible=1, 1360 inheritMaterial=0) 1361 elif atColor!=self.oldVals[2]: 1362 grid.srf.Set(materials=atColor, visible=1, inheritMaterial=0) 1363 self.oldVals=[atSet,atIsovalue,atColor] 1364 grid.srf.RedoDisplayList()
1365
1366 - def getMap(self):
1367 grid=self.grid 1368 atType=grid.atType 1369 atSet=int(self.setVar.get()) 1370 atIsovalue=float(self.isovalueVar.get()) 1371 atColor=grid.color 1372 var=self.vVar 1373 1374 if not grid.srf: 1375 #this is initialization 1376 self.initMap() 1377 else: 1378 #grid has been initialized: 1379 #update visibility,atSet,atIsovalue,atColor 1380 self.updateMap() 1381 self.vf.GUI.VIEWER.Redraw()
1382 1383
1384 -class AutoGridSliceGui:
1385
1386 - def __init__(self,grid,vf):
1387 self.grd=grid 1388 self.vf = vf 1389 self.master=vf.GUI.ROOT 1390 if not hasattr(self.grd,'initminmax'): 1391 self.grd.initminmax = 0 1392 self.grd.slices={} 1393 self.grd.slices['x']=[] 1394 self.grd.slices['y']=[] 1395 self.grd.slices['z']=[] 1396 self.axisVars={} 1397 self.vVars={} 1398 self.scaleWidgets={} 1399 grid.sliceGUI=self 1400 self.axisList=['x','y','z'] 1401 #for now, self.grd.step has to be 1 1402 assert hasattr(self.grd, 'srf') 1403 assert hasattr(self.grd, 'surfaceGUI') 1404 if self.grd.step!=1: 1405 self.grd.surfaceGUI.setVar.set('1') 1406 self.grd.surfaceGUI.updateMap() 1407 self.entry_widgets = []
1408 1409 1410
1411 - def delete_all_widgets(self, event=None):
1412 for widget in self.entry_widgets: 1413 widget.grid_forget()
1414 1415
1416 - def makeIfdEntry(self,axis,ifd,bButtons,visibility=1,scaleWidget=1):
1417 #NB: it could be more flexible if other functions +/or gridcfgs etc passed 1418 if not hasattr(ifd,'form'): 1419 t="Error: form not initialized" 1420 self.vf.warningMsg(t, title="AutoGridSliceGui WARNING:") 1421 return 1422 1423 form=ifd.form 1424 snum=len(self.grd.slices[axis]) 1425 #on first call: snum=0 1426 key = axis + str(snum) 1427 gridname = os.path.basename(self.grd.name) 1428 extKey=gridname+'_'+key 1429 self.vVars[key]=Tkinter.IntVar(self.master) 1430 self.vVars[key].set(1) 1431 if not hasattr(self.grd, 'widgets'): 1432 self.grd.widgets=[] 1433 self.grd.gcfgs=[] 1434 #before making new entries, forget the bottom ones: 1435 for itemList in bButtons: 1436 for item in itemList: 1437 ifd.entryByName[item]['widget'].grid_forget() 1438 1439 columnctr=0 1440 if visibility: 1441 #this needs local key for ifd name + extKey for text 1442 entry={'name':'%sVisBut'%key, 1443 'widgetType':Tkinter.Checkbutton, 1444 'text':extKey, 1445 'variable':self.vVars[key], 1446 'gridcfg':{'sticky':Tkinter.W}, 1447 'command': CallBackFunction(self.changeSliceVisibility,extKey,form)} 1448 ifd.entryByName[entry['name']]=entry 1449 form.addEntry(entry) 1450 self.grd.widgets.append(ifd.entryByName[entry['name']]['widget']) 1451 self.grd.gcfgs.append(ifd.entryByName[entry['name']]['gridcfg']) 1452 self.entry_widgets.append(ifd.entryByName[entry['name']]['widget']) 1453 columnctr=columnctr+1 1454 axisIndex=self.axisList.index(axis) 1455 tcolors=['red','green','blue'] 1456 minval = 0 1457 maxval = (self.grd.NELEMENTS[axisIndex]-1)/(self.grd.step*1.0) 1458 entry={'name':'%sScale'%key, 1459 'widgetType':Tkinter.Scale, 1460 'wcfg':{'from':minval,'orient':'horizontal','sliderrelief':'sunken', 1461 'sliderlength':'6','length':'2.5i', 1462 'tickinterval':maxval/2, 1463 'troughcolor':tcolors[axisIndex], 1464 'to':maxval,'command':CallBackFunction(self.CallBack,extKey,axis)}, 1465 'gridcfg':{'sticky':'we','row':-1,'column':1, 'columnspan':4} } 1466 form.addEntry(entry) 1467 ifd.entryByName[entry['name']]=entry 1468 newscale=ifd.entryByName[entry['name']]['widget'] 1469 newscale.grd=self.grd 1470 newscale.axis=axis 1471 newscale.nm=snum 1472 newscale.ky=key 1473 self.grd.widgets.append(ifd.entryByName[entry['name']]['widget']) 1474 self.grd.gcfgs.append(ifd.entryByName[entry['name']]['gridcfg']) 1475 self.entry_widgets.append(ifd.entryByName[entry['name']]['widget']) 1476 self.scaleWidgets[key]=newscale 1477 1478 1479 if not self.grd.initminmax: 1480 #add the label entry for max/min of grd 1481 #add two entries for max and min of colormap of slices here 1482 labStr = gridname[:-4] + '_colormap\nmin/max:' 1483 entry={'name':'%sLab'%gridname, 1484 'widgetType':Tkinter.Label, 1485 'wcfg':{ 'text':labStr }, 1486 'gridcfg':{'sticky':'w'} } 1487 form.addEntry(entry) 1488 ifd.entryByName[entry['name']]=entry 1489 newentry=ifd.entryByName[entry['name']]['widget'] 1490 self.entry_widgets.append(newentry) 1491 newentry.grd=self.grd 1492 self.grd.widgets.append(newentry) 1493 self.grd.gcfgs.append(ifd.entryByName[entry['name']]['gridcfg']) 1494 self.grd.cmapMin = self.grd.min 1495 if self.grd.max > 0.0: 1496 self.grd.cmapMax = 0.0 1497 else: 1498 self.grd.cmapMax = self.grd.max 1499 1500 newMinVar = Tkinter.StringVar(); 1501 newMinVar.set(self.grd.cmapMin) 1502 entry={'name':'%sMinEnt'%key, 1503 'widgetType':Tkinter.Entry, 1504 'wcfg':{'textvariable':newMinVar, 1505 'width':6, 1506 }, 1507 'gridcfg':{'sticky':'we','row':-1,'column':1} } 1508 form.addEntry(entry) 1509 ifd.entryByName[entry['name']]=entry 1510 newentry=ifd.entryByName[entry['name']]['widget'] 1511 newentry.bind('<Return>', CallBackFunction(self.setMin, newMinVar)) 1512 newentry.grd=self.grd 1513 self.grd.widgets.append(ifd.entryByName[entry['name']]['widget']) 1514 self.grd.gcfgs.append(ifd.entryByName[entry['name']]['gridcfg']) 1515 self.entry_widgets.append(ifd.entryByName[entry['name']]['widget']) 1516 1517 newMaxVar = Tkinter.StringVar(); 1518 newMaxVar.set(self.grd.cmapMax) 1519 entry={'name':'%sMaxEnt'%key, 1520 'widgetType':Tkinter.Entry, 1521 'wcfg':{'textvariable':newMaxVar, 1522 'width':6, 1523 }, 1524 'gridcfg':{'sticky':'w','row':-1,'column':2} } 1525 form.addEntry(entry) 1526 ifd.entryByName[entry['name']]=entry 1527 newentry=ifd.entryByName[entry['name']]['widget'] 1528 newentry.bind('<Return>', CallBackFunction(self.setMax, newMaxVar)) 1529 newentry.grd=self.grd 1530 self.grd.widgets.append(ifd.entryByName[entry['name']]['widget']) 1531 self.grd.gcfgs.append(ifd.entryByName[entry['name']]['gridcfg']) 1532 self.entry_widgets.append(ifd.entryByName[entry['name']]['widget']) 1533 self.grd.initminmax = 1 1534 1535 columnctr=columnctr+1 1536 rowctr=2 1537 for itemList in bButtons: 1538 #better to increment row and column + use newvalues here 1539 #THIS ISN'T GENERAL!! 1540 columnctr=0 1541 for item in itemList: 1542 gridcfg=ifd.entryByName[item]['gridcfg'] 1543 gridcfg['row']=gridcfg['row']+rowctr+2 1544 gridcfg['column']=columnctr 1545 #gridcfg['column']=gridcfg['column']+columnctr 1546 gridcfg=ifd.entryByName[item]['widget'].grid(gridcfg) 1547 columnctr=columnctr+1 1548 rowctr=rowctr+1 1549 form.lift()
1550 1551
1552 - def setMin(self, var, event=None):
1553 self.grd.cmapMin = float(var.get())
1554 1555
1556 - def setMax(self, var, event=None):
1557 self.grd.cmapMax = float(var.get())
1558 1559
1560 - def changeSliceVisibility(self, extKey, event=None):
1561 key=string.split(extKey,'_')[-1] 1562 axis=key[0] 1563 num=int(key[1:]) 1564 if self.vVars[key].get(): 1565 #slices entries are geometries: 1566 if self.grd.slices[axis][num]: 1567 self.grd.slices[axis][num].Set(visible=1) 1568 else: 1569 newVal = int(self.scaleWidgets[key].get()) 1570 self.addSlice(axis) 1571 else: 1572 if self.grd.slices[axis][num]: 1573 self.grd.slices[axis][num].Set(visible=0) 1574 self.vf.GUI.VIEWER.Redraw()
1575 1576
1577 - def CallBack(self, extKey, axis, event=None):
1578 #print "plist=",self.grd.slices[axis] 1579 if not len(self.grd.slices[axis]):return 1580 key=string.split(extKey,'_')[-1] 1581 num=int(key[1:]) 1582 if len(self.grd.slices[axis])<num: return 1583 scale=self.scaleWidgets[key] 1584 val=scale.get() 1585 ival = int(val) 1586 #fix this someday 1587 #ival = int(math.floor(ival/self.grd.step)) 1588 g=scale.grd 1589 axis= scale.axis 1590 plist=self.grd.slices[axis] 1591 #if just built scale, don't try to move it 1592 if scale.nm >= len(plist): return 1593 p=plist[scale.nm] 1594 self.moveSlice(axis,p,ival) 1595 self.vf.GUI.VIEWER.Redraw()
1596 1597
1598 - def addSlice(self,axis):
1599 snum = len(self.grd.slices[axis]) 1600 key = axis + str(snum) 1601 extKey = self.grd.name+'_'+key 1602 ###THIS IS THE CHANGE! 1603 min = self.grd.cmapMin 1604 max = self.grd.cmapMax 1605 #if self.grd.min<-3: min=-3 1606 #else: min=self.grd.min 1607 #if self.grd.max>0:max=0 1608 #else:max=self.grd.max 1609 ind = self.axisList.index(axis) 1610 pat = patternList[2+ind] 1611 #all slices are initialized at len(slices) (?) 1612 v,tx,t2 = self.calcSlice(axis,snum,min,max) 1613 #p = IndexedPolygons(extKey, vertices=v, faces=((0,1,2,3),), 1614 # textureCoords=tx, inheritMaterial=0, 1615 # culling=GL.GL_NONE) 1616 p = IndexedPolygons(extKey, protected=True,) 1617 if self.vf.userpref['sharpColorBoundariesForMsms']['value'] == 'blur': 1618 p.Set(inheritSharpColorBoundaries=False, sharpColorBoundaries=False,) 1619 p.Set(vertices=v, faces=((0,1,2,3),), 1620 texture=t2, textureCoords=tx, 1621 inheritMaterial=0, culling=GL.GL_NONE, blendFunctions=(1,1), 1622 frontPolyMode=GL.GL_FILL, backPolyMode=GL.GL_FILL) 1623 #p.RenderMode(GL.GL_FILL,face=GL.GL_BACK) 1624 #p.RenderMode(GL.GL_FILL,face=GL.GL_FRONT) 1625 self.vf.GUI.VIEWER.AddObject(p) 1626 #p.texture = t2 1627 p.polygonstipple.Set(pattern=pat) 1628 p.Set(stipplePolygons=1) 1629 self.grd.slices[axis].append(p) 1630 p.num = snum 1631 p.scaleWidget = self.scaleWidgets[key] 1632 p.RedoDisplayList() 1633 self.vf.GUI.VIEWER.Redraw()
1634
1635 - def calcSlice(self,axis,newVal,min,max):
1636 # MS getSliceArray 1637 ## sl,sld=self.grd.doSlice(0,0,axis,newVal) 1638 ## width=sl.width 1639 ## height=sl.height 1640 sld = self.grd.doSlice(0,0,axis,newVal) 1641 width = sld.shape[0] 1642 height = sld.shape[1] 1643 v = self.grd.buildSliceVertices(width,height,axis,newVal) 1644 #build the image 1645 val = minimum(sld.flat,0) 1646 cmap = RGBRamp() 1647 #FIX THIS 1648 tex2Dimage = array2DToImage(val,cmap,width,height,mini=min,maxi=max) 1649 dim1 = dim2 = 1 1650 while dim1<width: dim1=dim1<<1 1651 while dim2<height: dim2=dim2<<1 1652 t2 = Texture.Texture() 1653 t2.Set(enable=1, image=tex2Dimage, auto=0) 1654 #t2=Texture.Texture(enable=1,image=tex2Dimage, auto=0) 1655 t2.width = dim1 1656 t2.height = dim2 1657 tx = self.grd.buildTextureCoords(width,height,axis,newVal) 1658 return v, tx, t2
1659
1660 - def moveSlice(self, axis, p, newVal):
1661 ##THIS IS CHANGE #@ 1662 min = self.grd.cmapMin 1663 max = self.grd.cmapMax 1664 #if self.grd.min<-3: min=-3 1665 #else: min=self.grd.min 1666 #if self.grd.max>0:max=0 1667 #else:max=self.grd.max 1668 v, tx, t2=self.calcSlice(axis,newVal,min,max) 1669 #p=self.grd.slices[axis][num] 1670 p.Set(vertices=v, textureCoords=tx) 1671 p.texture=t2 1672 ind=self.axisList.index(axis) 1673 pat= patternList[2+ind] 1674 p.polygonstipple.Set(pattern=pat) 1675 p.RedoDisplayList()
1676