Package omero :: Package util :: Module OmeroPopo
[hide private]
[frames] | no frames]

Source Code for Module omero.util.OmeroPopo

   1  """ 
   2   components/tools/OmeroPy/src/omero/util/OmeroPopo.py 
   3   
   4  ----------------------------------------------------------------------------- 
   5    Copyright (C) 2006-2010 University of Dundee. All rights reserved. 
   6   
   7   
   8    This program is free software; you can redistribute it and/or modify 
   9    it under the terms of the GNU General Public License as published by 
  10    the Free Software Foundation; either version 2 of the License, or 
  11    (at your option) any later version. 
  12    This program is distributed in the hope that it will be useful, 
  13    but WITHOUT ANY WARRANTY; without even the implied warranty of 
  14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  15    GNU General Public License for more details. 
  16     
  17    You should have received a copy of the GNU General Public License along 
  18    with this program; if not, write to the Free Software Foundation, Inc., 
  19    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 
  20   
  21  ------------------------------------------------------------------------------ 
  22   
  23  @author Donald MacDonald      
  24  <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a> 
  25  @version 3.0 
  26  <small> 
  27  (<b>Internal version:</b> $Revision: $Date: $) 
  28  </small> 
  29  @since 3.0-Beta4.2 
  30    
  31  """ 
  32  import math; 
  33  import numpy; 
  34  import omero.clients 
  35  from omero.model import ImageI 
  36  from omero.model import RoiI 
  37  from omero.model import EllipseI 
  38  from omero.model import LineI 
  39  from omero.model import RectI 
  40  from omero.model import PointI 
  41  from omero.model import LabelI 
  42  from omero.model import PolylineI 
  43  from omero.model import PolygonI 
  44  from omero.model import PathI 
  45  from omero.model import MaskI 
  46  from omero.model import NamespaceI 
  47  from omero.rtypes import rdouble 
  48  from omero.rtypes import rstring 
  49  from omero.rtypes import rint 
  50  from omero.rtypes import rfloat 
  51  from omero.rtypes import rlist 
  52  from omero.rtypes import rlong 
  53   
  54  ## Popo helpers ## 
  55     
56 -def toCSV(list):
57 """ 58 Convert a list to a Comma Separated Value string. 59 @param list The list to convert. 60 @return See above. 61 """ 62 lenList = len(list); 63 cnt = 0; 64 str = ""; 65 for item in list: 66 str = str + item; 67 if(cnt < lenList-1): 68 str = str + ","; 69 cnt = cnt +1; 70 return str;
71
72 -def toList(csvString):
73 """ 74 Convert a csv string to a list of strings 75 @param csvString The CSV string to convert. 76 @return See above. 77 """ 78 list = csvString.split(','); 79 for index in range(len(list)): 80 list[index] = list[index].strip(); 81 return list;
82 83 ## 84 # Create instance of data object this object wraps the basic OMERO types. 85 #
86 -class DataObject(object):
87 88 ## 89 # Create instance. 90 #
91 - def __init__(self):
92 self.value = None; 93 self.dirty = False;
94 95 ## 96 # Sets the {@link IObject}. 97 # 98 # @param value The value to set. 99 #
100 - def setValue(self, value):
101 if(value==None): 102 raise Exception("IObject delegate for DataObject cannot be null."); 103 self.value = value;
104 105 ## 106 # get the id of the Dataobject. 107 # @return See above. 108 #
109 - def getId(self):
110 if(self.value.getId()==None): 111 return -1; 112 return self.value.getId().getValue();
113 114 ## 115 # Set the id of the data object 116 # @param id See above.
117 - def setId(self, id):
118 self.setDirty(True); 119 self.value.setId(rlong(id));
120 121 ## 122 # Get the current object. 123 # @return See above. 124 #
125 - def asIObject(self):
126 return self.value;
127 128 ## 129 # The object has been changed and is now dirty. 130 # @param boolean See above. 131 #
132 - def setDirty(self, boolean):
133 self.dirty = boolean;
134 135 ## 136 # Has the object has been changed. 137 # @return See above. 138 #
139 - def getDirty(self):
140 return self.dirty;
141 142 ## 143 # Is the object loaded 144 # @return see above.
145 - def isLoaded(self):
146 return self.value.isLoaded();
147 148 ## 149 # Get the user details for the object. 150 # @return see above.
151 - def getDetails(self):
152 return self.asIObject().getDetails();
153
154 -class ImageData(DataObject):
155 156 ## 157 # Create Instance 158 #
159 - def __init__(self, image = None):
160 DataObject.__init__(self) 161 if(image==None): 162 self.setValue(ImageI()); 163 else: 164 self.setValue(image);
165 166 ## 167 # Sets the name of the image. 168 # 169 # @param name 170 # The name of the image. Mustn't be <code>null</code>. 171 #
172 - def setName(self, name):
173 image = self.asIObject(); 174 if(image==None): 175 raise Exception("No Image specified."); 176 image.setName(rstring(name)); 177 self.setDirty(True);
178 179 ## 180 # Returns the name of the image. 181 # 182 # @return See above. 183 #
184 - def getName(self):
185 image = self.asIObject(); 186 if(image==None): 187 raise Exception("No Image specified."); 188 name = image.getName(); 189 if(name==None): 190 return ""; 191 return name.getValue();
192 193 ## 194 # Sets the description of the image. 195 # 196 # @param description 197 # The description of the image. 198 #
199 - def setDescription(self, description):
200 image = self.asIObject(); 201 if(image==None): 202 raise Exception("No Image specified."); 203 image.setDescription(rstring(description)); 204 self.setDirty(True);
205 206 ## 207 # Returns the description of the image. 208 # 209 # @return See above. 210 #
211 - def getDescription(self):
212 image = self.asIObject(); 213 if(image==None): 214 raise Exception("No Image specified."); 215 description = image.getDescription(); 216 if(description==None): 217 return ""; 218 return description.getValue();
219 220 ## 221 # This class stores the ROI Coordinate (Z,T). 222 #
223 -class ROICoordinate:
224 225 ## 226 # Initialise the ROICoordinate. 227 # @param z The z-section. 228 # @param t The timepoint.
229 - def __init__(self, z = 0, t = 0):
230 self.theZ = z; 231 self.theT = t; 232 self.ZBITSPLIT = 18;
233 234 ## 235 # Overload the equals operator 236 #
237 - def __eq__(self, obj):
238 if(self.theZ == obj.theZ and self.theT == obj.theT): 239 return True; 240 return False;
241 242 ## 243 # Overload the equals operator 244 #
245 - def __ne__(self, obj):
246 if(self.theZ != obj.theZ or self.theT != obj.theT): 247 return True; 248 return False;
249 250 ## 251 # Overload the lessthan or equals operator 252 #
253 - def __lt__(self, obj):
254 if(self.theT >= obj.theT): 255 return False; 256 if(self.theZ >= obj.theZ): 257 return False; 258 return True;
259 260 ## 261 # Overload the lessthan or equals operator 262 #
263 - def __le__(self, obj):
264 if(self.theT < obj.theT): 265 return False; 266 if(self.theZ < obj.theZ): 267 return False; 268 return True;
269 270 ## 271 # Overload the greater than equals operator 272 #
273 - def __gt__(self, obj):
274 if(self.theT <= obj.theT): 275 return False; 276 if(self.theZ <= obj.theZ): 277 return False; 278 return True;
279 280 ## 281 # Overload the greater than or equals operator 282 #
283 - def __ge__(self, obj):
284 if(self.theT < obj.theT): 285 return False; 286 if(self.theZ < obj.theZ): 287 return False; 288 return True;
289 290 ## 291 # Overload the hash operator 292 #
293 - def __hash__(self):
294 return self.theZ<<self.ZBITSPLIT+self.theT;
295 296 ## 297 # Returns the timepoint. 298 # 299 # @return See above. 300 #
301 - def getTimepoint(self):
302 return self.theT;
303 304 ## 305 # Returns the Z-Section. 306 # 307 # @return See above. 308 #
309 - def getZSection(self):
310 return self.theZ;
311 312 ## 313 # Set the Z-Section of the Coordinate 314 # @param z See above. 315 #
316 - def setZSection(self, z):
317 self.z = z;
318 319 ## 320 # Set the Timepoint of the Coordinate 321 # @param t See above. 322 #
323 - def setTimepoint(self, t):
324 self.t = t;
325 326 327 ### 328 # Shape wrapper. 329 #
330 -def shapeWrapper(serverSideShape):
331 """ 332 Wrap the serverSide shape as the appropriate OmeroPopos 333 @param serverSideShape The shape object to wrap. 334 @return See above. 335 """ 336 print "ServerSideShape" 337 print serverSideShape.__class__.__name__ 338 if serverSideShape.__class__.__name__=='EllipseI': 339 return EllipseData(serverSideShape); 340 if serverSideShape.__class__.__name__=='RectI': 341 return RectData(serverSideShape); 342 if serverSideShape.__class__.__name__=='MaskI': 343 return MaskData(serverSideShape); 344 if serverSideShape.__class__.__name__=='PolygonI': 345 return PolygonData(serverSideShape); 346 return None;
347 348 ## 349 # This class defines the python mapping of the ROIData object {See Pojos#ROIData} 350 #
351 -class ROIData(DataObject):
352 353 ## 354 # Create a new instance of an ROIData object. 355 #
356 - def __init__(self, roi = None):
357 DataObject.__init__(self); 358 if(roi==None): 359 self.setValue(RoiI()); 360 else: 361 self.setValue(roi); 362 self.roiShapes = dict(); 363 if(roi!=None): 364 self.initialise();
365 ## 366 # Initialise the shape map of the ROIData object. 367 #
368 - def initialise(self):
369 self.roiShapes = dict(); 370 roi = self.asIObject(); 371 shapes = roi.copyShapes(); 372 s = None; 373 for shape in shapes: 374 s = shapeWrapper(shape); 375 if(s!=None): 376 coord = ROICoordinate(s.getZ(), s.getT()); 377 if(not self.roiShapes.has_key(coord)): 378 self.roiShapes[coord] = list(); 379 data = self.roiShapes[coord]; 380 data.append(s);
381 382 ## 383 # Set the imageId for the ROI. 384 # @param imageId See above. 385 #
386 - def setImage(self, image):
387 roi = self.asIObject(); 388 if(roi==None): 389 raise Exception("No Roi specified."); 390 roi.setImage(image); 391 self.setDirty(True);
392 393 ## 394 # Get the image for the ROI. 395 # @return See above. 396 #
397 - def getImage(self):
398 roi = self.asIObject(); 399 if(roi==None): 400 raise Exception("No Roi specified."); 401 return roi.getImage();
402 403 ## 404 # Add ShapeData object to ROIData. 405 # @param shape See above. 406 #
407 - def addShapeData(self, shape):
408 roi = self.asIObject(); 409 if(roi==None): 410 raise Exception("No Roi specified."); 411 coord = shape.getROICoordinate(); 412 shapeList = None; 413 if(self.roiShapes.has_key(coord) == False): 414 shapeList = list(); 415 self.roiShapes[coord] = shapeList; 416 else: 417 shapeList = self.roiShapes[coord]; 418 shapeList.append(shape); 419 roi.addShape(shape.asIObject()); 420 self.setDirty(True);
421 422 ## 423 # Remove ShapeData object from ROIData. 424 # @param shape See above. 425 #
426 - def removeShapeData(self, shape):
427 roi = self.asIObject(); 428 if(roi==None): 429 raise Exception("No Roi specified."); 430 coord = shape.getROICoordinate(); 431 shapeList = self.roiShapes[coord]; 432 shapeList.remove(shape); 433 roi.removeShape(shape.asIObject()); 434 self.setDirty(True);
435 436 ## 437 # Get the number of planes occupied by the ROI. 438 # @return See above. 439 #
440 - def getPlaneCount(self):
441 return len(self.roiShapes)
442 443 ## 444 # Get the number of shapes in the ROI. 445 # @return See above. 446 #
447 - def getShapeCount(self):
448 count = 0; 449 for coord in self.roiShapes: 450 list = self.roiShapes[coord]; 451 count = count + len(list); 452 return count;
453 454 ## 455 # Returns the list of shapes on a given plane. 456 # 457 # @param z The z-section. 458 # @param t The timepoint. 459 # @return See above. 460 #
461 - def getShapes(self, z, t):
462 return self.roiShapes[ROICoordinate(z,t)];
463 464 ## 465 # Returns the iterator of the collection of the map. 466 # 467 # @return See above. 468 #
469 - def getIterator(self):
470 return self.roiShapes.iteritems();
471 472 ## 473 # Returns an iterator of the Shapes in the ROI in the range [start, end]. 474 # 475 # @param start The starting plane where the Shapes should reside. 476 # @param end The final plane where the Shapes should reside. 477 # @return See above. 478 #
479 - def getShapesInRange(self, start, end):
480 coordList = self.roiShapes.keys(); 481 coordList.sort(); 482 keyList = []; 483 for coord in coordList: 484 if(coord>=start and coord <= end): 485 keyList.append(coord); 486 return self.roiShapes.from_keys(keyList);
487 488 ## 489 # Returns the namespace of the ROI. 490 # 491 # @return see above. 492 #
493 - def setNamespaceKeywords(self, namespace, keywords):
494 roi = self.asIObject(); 495 if(roi==None): 496 raise Exception("No Roi specified."); 497 if(len(keywords)==0): 498 self.removeNamespace(namespace); 499 else: 500 map = self.getNamespaceKeywords(); 501 map[namespace] = keywords; 502 self.setNamespaceMap(map); 503 self.setDirty(True);
504 505 ## 506 # Remove the namespace from the ROI 507 # @param namespace See above. 508 #
509 - def removeNamespace(self, namespace):
510 roi = self.asIObject(); 511 if(roi==None): 512 raise Exception("No Roi specified."); 513 map = self.getNamespaceKeywords(); 514 if(map.has_key(namespace)): 515 del map[namespace]; 516 self.setNamespaceMap(map); 517 self.setDirty(True);
518 519 ## 520 # Update the ROIData object to have the namespaces of the 521 # map, and the keywords of the map. 522 # @param map See above. 523 #
524 - def setNamespaceMap(self, map):
525 roi = self.asIObject(); 526 if(roi==None): 527 raise Exception("No Roi specified."); 528 roi.setNamespaces(map.keys); 529 keywords = []; 530 for namespace in map.keys: 531 keywords.append(map[namespace]); 532 roi.setKeywords(keywords); 533 self.setDirty(True);
534 535 ## 536 # Retrieve the namespaces of the ROI 537 # @return See above. 538 #
539 - def getNamespaces(self):
540 roi = self.asIObject(); 541 if(roi==None): 542 raise Exception("No Roi specified."); 543 namespaces = roi.getNamespaces(); 544 if(namespaces==None): 545 return []; 546 return namespaces;
547 548 ## 549 # Get the keywords and namespaces as a map<namespace, keywords> 550 # @return See above. 551 #
552 - def getNamespaceKeywords(self):
553 roi = self.asIObject(); 554 if (roi == None): 555 raise Exception("No Roi specified."); 556 namespaces = self.getNamespaces(); 557 namespaceKeywords = roi.getKeywords(); 558 if(len(namespaces) != len(namespaceKeywords)): 559 raise Exception("Namespaces length does not match keywords namespace length."); 560 map = {}; 561 for i in range(len(namespaces)): 562 map[namespaces[i]] = namespaceKeywords[i]; 563 return map;
564
565 -class ShapeData(DataObject):
566
567 - def __init__(self):
568 DataObject.__init__(self) 569 self.text = None; 570 self.coord = ROICoordinate();
571 572 ## 573 # Returns the z-section. 574 # 575 # @return See above. 576 #
577 - def getZ(self):
578 shape = self.asIObject(); 579 if(shape==None): 580 raise Exception("No Shape specified."); 581 z = shape.getTheZ(); 582 if(z==None): 583 return 0; 584 else: 585 return z.getValue();
586 587 ## 588 # Set the z-section. 589 # @param theZ See above. 590 #
591 - def setZ(self, theZ):
592 shape = self.asIObject(); 593 if(shape==None): 594 raise Exception("No Shape specified."); 595 shape.setTheZ(rint(theZ)); 596 self.coord.setZSection(theZ); 597 self.setDirty(True);
598 599 ## 600 # Returns the timepoint. 601 # 602 # @return See above. 603 #
604 - def getT(self):
605 shape = self.asIObject(); 606 if(shape==None): 607 raise Exception("No Shape specified."); 608 t = shape.getTheT(); 609 if(t==None): 610 return 0; 611 else: 612 return t.getValue();
613 614 ## 615 # Set the timepoint. 616 # @param See above. 617 #
618 - def setT(self, theT):
619 shape = self.asIObject(); 620 if(shape==None): 621 raise Exception("No Shape specified."); 622 shape.setTheT(rint(theT)); 623 self.coord.setTimePoint(theT); 624 self.setDirty(True); 625 626 ## 627 # Set the ROICoordinate for the ShapeData 628 # @param roiCoordinate See above. 629 #
630 - def setROICoordinate(self, coord):
631 shape = self.asIObject(); 632 if(shape==None): 633 raise Exception("No Shape specified."); 634 self.setZ(coord.getZSection()); 635 self.setT(coord.getTimePoint()); 636 self.coord.setZSection(coord.getZSection()); 637 self.coord.setTimePoint(coord.getTimePoint()); 638 self.setDirty(True);
639 640 ## 641 # Get the ROICoordinate for the ShapeData 642 # @return See above. 643 #
644 - def getROICoordinate(self):
645 shape = self.asIObject(); 646 if(shape==None): 647 raise Exception("No Shape specified."); 648 return self.coord;
649 650 ## 651 # Get the text for the Object 652 # @return See above.
653 - def getText(self):
654 shape = self.asIObject(); 655 if(shape==None): 656 raise Exception("No Shape specified."); 657 text = shape.getTextValue(); 658 if(text==None): 659 return ""; 660 else: 661 return text.getValue();
662 663 ## 664 # Set the text for the Obect. 665 # @param See above.
666 - def setText(self, text):
667 shape = self.asIObject(); 668 if(shape==None): 669 raise Exception("No Shape specified."); 670 shape.setTextValue(rstring(text)); 671 self.setDirty(True)
672 673 ## 674 # Get the affinetransform from the object, returned as a string matrix(m00 m01 m10 m11 m02 m12) 675 # see Java affinetransform toMatrix. 676 # @return see above. 677 #
678 - def getTransform(self):
679 shape = self.asIObject(); 680 if(shape==None): 681 raise Exception("No Shape specified."); 682 transform = shape.getTransform(); 683 if(transform!=None): 684 transformValue = transform.getValue(); 685 if(transformValue=="none"): 686 return ""; 687 else: 688 return transformValue; 689 return "";
690
691 - def setTransform(self, transform):
692 shape = self.asIObject(); 693 if(shape==None): 694 raise Exception("No Shape specified."); 695 shape.setTransform(rstring(transform)); 696 self.setDirty(True);
697 698 ## 699 # Transform the affine transform matrix from the string 'matrix(m00 m01 m10 m 11 m02 m12)' to a 700 # more appropriate numpy.array([m00 m01 m02], [m10 m11 m12]). 701 #
702 - def transformToMatrix(self, str):
703 if (str == ""): 704 return numpy.matrix([[1,0,0],[0,1,0]]) 705 transformstr = str[str.find('(')+1:len(str)-1]; 706 values = transformstr.split(' '); 707 b = numpy.matrix(numpy.array(values, dtype='double')); 708 t = numpy.matrix(numpy.zeros((3,3))); 709 t[0,0] = b[0,0]; 710 t[0,1] = b[0,2]; 711 t[1,0] = b[0,1]; 712 t[1,1] = b[0,3]; 713 t[0,2] = b[0,4]; 714 t[1,2] = b[0,5]; 715 t[2,2] = 1; 716 return t;
717 718 ## 719 # does the shape contain the point 720 # @return see above. 721 #
722 - def contains(self, point):
723 return False;
724 725 ## 726 # 727 #
728 - def containsPoints(self):
729 return [];
730 731 ## 732 # Instance of the EllipseData Object 733 #
734 -class EllipseData(ShapeData):
735 736 ## 737 # Create instance of EllipseData Object 738 #
739 - def __init__(self, shape = None):
740 ShapeData.__init__(self); 741 if(shape==None): 742 self.setValue(EllipseI()); 743 self.setCx(0); 744 self.setCy(0); 745 self.setRx(0); 746 self.setRy(0); 747 else: 748 self.setValue(shape);
749 750 ## 751 # Set the centre x coord of the Ellipse 752 # @param cx See above.
753 - def setCx(self, cx):
754 shape = self.asIObject(); 755 if(shape==None): 756 raise Exception("No Shape specified."); 757 shape.setCx(rdouble(cx));
758 759 ## 760 # Get the centre x coord of the Ellipse 761 # @return See Above.
762 - def getCx(self):
763 shape = self.asIObject(); 764 if(shape==None): 765 raise Exception("No Shape specified."); 766 cx = shape.getCx(); 767 if(cx==None): 768 return 0; 769 return cx.getValue();
770 771 ## 772 # Set the centre y coord of the Ellipse 773 # @param cy See above.
774 - def setCy(self, cy):
775 shape = self.asIObject(); 776 if(shape==None): 777 raise Exception("No Shape specified."); 778 shape.setCy(rdouble(cy));
779 780 ## 781 # Get the centre y coord of the Ellipse 782 # @return See Above.
783 - def getCy(self):
784 shape = self.asIObject(); 785 if(shape==None): 786 raise Exception("No Shape specified."); 787 cy = shape.getCy(); 788 if(cy==None): 789 return 0; 790 return cy.getValue();
791 792 ## 793 # Set the radius on the x-axis of the Ellipse 794 # @param rx See above.
795 - def setRx(self, rx):
796 shape = self.asIObject(); 797 if(shape==None): 798 raise Exception("No Shape specified."); 799 shape.setRx(rdouble(rx));
800 801 ## 802 # Get the radius of the x-axis of the Ellipse 803 # @return See Above.
804 - def getRx(self):
805 shape = self.asIObject(); 806 if(shape==None): 807 raise Exception("No Shape specified."); 808 rx = shape.getRx(); 809 if(rx==None): 810 return 0; 811 return rx.getValue();
812 813 ## 814 # Set the radius on the y-axis of the Ellipse 815 # @param rx See above.
816 - def setRy(self, ry):
817 shape = self.asIObject(); 818 if(shape==None): 819 raise Exception("No Shape specified."); 820 shape.setRy(rdouble(ry));
821 822 ## 823 # Get the radius of the y-axis of the Ellipse 824 # @return See Above.
825 - def getRy(self):
826 shape = self.asIObject(); 827 if(shape==None): 828 raise Exception("No Shape specified."); 829 ry = shape.getRy(); 830 if(ry==None): 831 return 0; 832 return ry.getValue();
833 834 ## 835 # Transform the point by the affineTransform transform. 836 # @param transform See above. 837 # @param point See above. 838 # @return See above. 839 #
840 - def transformPoint(self, transform, point):
841 p = numpy.matrix(point).transpose(); 842 return transform*p;
843 844 ## 845 # Return a map of points(x,y) contained within the Shape 846 # @return See above. 847 #
848 - def containsPoints(self):
849 cx = self.getCx(); 850 cy = self.getCy(); 851 rx = self.getRx(); 852 ry = self.getRy(); 853 transform = self.transformToMatrix(self.getTransform()); 854 point = numpy.matrix((cx, cy, 1)).transpose(); 855 centre = transform*point; 856 BL = numpy.matrix((cx-rx, cy+ry, 1)).transpose(); 857 BR = numpy.matrix((cx+rx, cy+ry, 1)).transpose(); 858 TL = numpy.matrix((cx-rx, cy-ry, 1)).transpose(); 859 TR = numpy.matrix((cx+rx, cy-ry, 1)).transpose(); 860 MajorAxisLeft = numpy.matrix((cx-rx, cy, 1)).transpose(); 861 MajorAxisRight = numpy.matrix((cx+rx, cy, 1)).transpose(); 862 MinorAxisTop = numpy.matrix((cx, cy-ry, 1)).transpose(); 863 MinorAxisBottom = numpy.matrix((cx, cy+ry, 1)).transpose(); 864 lb = transform*BL; 865 rb = transform*BR; 866 lt = transform*TL; 867 rt = transform*TR; 868 majl = transform*MajorAxisLeft; 869 majr = transform*MajorAxisRight; 870 mint = transform*MinorAxisTop; 871 minb = transform*MinorAxisBottom; 872 o = (majr[1]-majl[1]); 873 a = (majr[0]-majl[0]); 874 h = math.sqrt(o*o+a*a); 875 majorAxisAngle = math.asin(o/h); 876 boundingBoxMinX = min(lt[0], rt[0],lb[0], rb[0]); 877 boundingBoxMaxX = max(lt[0], rt[0], lb[0], rb[0]); 878 boundingBoxMinY = min(lt[1], rt[1], lb[1], rb[1]); 879 boundingBoxMaxY = max(lt[1], rt[1], lb[1], rb[1]); 880 boundingBox = ((boundingBoxMinX, boundingBoxMinY), (boundingBoxMaxX, boundingBoxMaxY)); 881 centredBoundingBox = ((boundingBox[0][0]-centre[0],boundingBox[0][1]-centre[1]),(boundingBox[1][0]-centre[0],boundingBox[1][1]-centre[1])) 882 points = {}; 883 cx = float(centre[0]); 884 cy = float(centre[1]); 885 xrange = range(centredBoundingBox[0][0], centredBoundingBox[1][0]) 886 yrange = range(centredBoundingBox[0][1], centredBoundingBox[1][1]) 887 for x in xrange: 888 for y in yrange: 889 newX = x*math.cos(majorAxisAngle)+y*math.sin(majorAxisAngle); 890 newY = -x*math.sin(majorAxisAngle)+y*math.cos(majorAxisAngle); 891 val = (newX*newX)/(rx*rx)+ (newY*newY)/(ry*ry); 892 if(val <= 1): 893 points[(int(x+cx), int(y+cy))]=1; 894 return points;
895 896 ## 897 # Instance of Polygon object. 898 #
899 -class PolygonData(ShapeData):
900 901 ### 902 # Create instance of PolygonData Object 903 #
904 - def __init__(self, shape = None):
905 ShapeData.__init__(self); 906 self.NUMREGEX = "\\[.*\\]"; # Regex for a data in block. 907 if(shape==None): 908 self.setValue(PolygonI()); 909 self.points = []; 910 self.points1 = []; 911 self.points2 = []; 912 self.mask = []; 913 else: 914 self.setValue(shape); 915 self.parseShapeStringToPoints();
916 917 ## 918 # Get the points from the points String 919 # @return See above. 920 #
921 - def getPoints(self):
922 pts = self.fromPoints("points"); 923 return self.parsePointsToList(pts);
924 925 ## 926 # Get the points1 from the points String 927 # @return See above. 928 #
929 - def getPoints1(self):
930 pts = self.fromPoints("points1"); 931 return self.parsePointsToList(pts);
932 933 ## 934 # Get the points2 from the points String 935 # @return See above. 936 #
937 - def getPoints2(self):
938 pts = self.fromPoints("points2"); 939 return self.parsePointsToList(pts);
940 941 ## 942 # Get the mask type from the points String 943 # @return See above. 944 #
945 - def getMaskPoints(self):
946 pts = self.fromPoints("mask"); 947 return self.parsePointsToList(pts);
948 949 ## 950 # Set the points from the original PolygonI type. 951 # @param pts The points values. 952 #
953 - def setPointsString(self, pts):
954 shape = self.asIObject(); 955 if(shape==None): 956 raise Exception("No Shape specified."); 957 shape.setPoints(pts); 958 self.setDirty(True); 959 self.parseShapeStringToPoints();
960 961 ## 962 # Set the points from a series of lists, and also set the points string. 963 # @param points The points list. 964 # @param points1 The points1 list. 965 # @param points2 The points2 list. 966 # @param mask The mask represents the curve type, lineTo, ArcTo..
967 - def setPointsFromList(self, points, points1, point2, mask):
968 pts = self.toString(points); 969 pts1 = self.toString(points); 970 pts2 = self.toString(points); 971 mask = self.toString(points); 972 str = "points["+pts+"] "; 973 str = str + "points1["+pts1+"] "; 974 str = str + "points2["+pts2+"] "; 975 str = str + "mask["+mask+"]"; 976 self.setPointsString(str);
977 978 ## 979 # Get the points string from the IObject 980 # @return See above.
981 - def getPointsString(self):
982 shape = self.asIObject(); 983 if(shape==None): 984 raise Exception("No Shape specified."); 985 pts = shape.getPoints(); 986 if(pts==None): 987 return ""; 988 else: 989 return pts.getValue();
990 991 ## 992 # Get the points of type from the point string. 993 # @param type The points type to return, points, point1, point2, mask 994 # @return See above. 995 #
996 - def fromPoints(self, type):
997 return self.getContents(self.getPointsString(), type+"[","]");
998 999 ## 1000 # Helper method to get the contents of the values from the string of form type[values]. 1001 # @param string The string to parse. 1002 # @param start the first part of the string to break apart on. "type[" 1003 # @param end the last part of the string to break apart "]". 1004 # @return The contents of the string between start ReturnValues end 1005 #
1006 - def getContents(self, string, start, end):
1007 lIndex = string.find(start); 1008 if(lIndex == -1): 1009 return ""; 1010 strFragment = string[lIndex:]; 1011 rIndex = strFragment.find(']'); 1012 if(rIndex == -1): 1013 return ""; 1014 return string[lIndex+len(start):rIndex];
1015 1016 ## 1017 # Convert the pts string to a list 1018 # @return See above. 1019 #
1020 - def parsePointsToList(self, pts):
1021 numberList = pts.split(','); 1022 return numberList;
1023 1024 ## 1025 # Convert the pointsList to a string, of CSV 1026 # @return See above. 1027 #
1028 - def toString(self, pointsList):
1029 str = ""; 1030 for index, pt in enumerate(pointsList): 1031 str = str + pt; 1032 if(index<len(pointsList)-1): 1033 str = str + ","; 1034 return str;
1035 1036 ## 1037 # Convert the points string to the points lists, points, point1, point2 and mask. 1038 #
1039 - def parseShapeStringToPoints(self):
1040 self.points = self.fromPoints("points"); 1041 self.points1 = self.fromPoints("points1"); 1042 self.points2 = self.fromPoints("points2"); 1043 self.mask = self.fromPoints("mask");
1044 1045 ## 1046 # Returns the bounding rectangle of the polygon, as a list of coords [(x1,y1), (x2,y2)] 1047 # @return See above. 1048 #
1049 - def getBoundingRectangle(self):
1050 pts = self.toCoords(self.getPoints()); 1051 minx = pts[0][0]; 1052 maxx = minx; 1053 miny = pts[0][1]; 1054 maxy = miny; 1055 1056 for pt in pts: 1057 minx = min(pt[0],minx); 1058 miny = min(pt[1],miny); 1059 maxx = max(pt[0],maxx); 1060 maxy = max(pt[1],maxy); 1061 return [(minx,miny), (maxx, maxy)];
1062 1063 ## 1064 # Convert the points list to a coord list. 1065 # @param ptsList The list of points. 1066 # @return See above.
1067 - def toCoords(self, ptsList):
1068 coords = []; 1069 for index in range(len(ptsList)/2): 1070 coords.append((int(ptsList[index*2]), int(ptsList[index*2+1]))); 1071 return coords;
1072 1073 1074 ## 1075 # Return a map of points(x,y) contained within the Shape 1076 # @return See above. 1077 #
1078 - def containsPoints(self):
1079 points = {}; 1080 boundingRectangle = self.getBoundingRectangle(); 1081 xrange = range(boundingRectangle[0][0], boundingRectangle[1][0]) 1082 yrange = range(boundingRectangle[0][1], boundingRectangle[1][1]) 1083 for xx in xrange: 1084 for yy in yrange: 1085 if(self.inPolygon((xx,yy))): 1086 points[(xx,yy)]=1; 1087 return points;
1088 1089 ## 1090 # Return true if the point p is inside the polygon, defined by the vertexes in points. 1091 # @param p The point (x,y) 1092 # @return See above. 1093 #
1094 - def inPolygon(self, p):
1095 angle = 0.0 1096 polypoints = self.getPoints(); 1097 cnt = 0; 1098 polygon = []; 1099 for index in range(0,len(polypoints)/2): 1100 polygon.append((int(polypoints[index*2]), int(polypoints[index*2+1]))); 1101 1102 n = len(polygon) 1103 1104 for i, (h, v) in enumerate(polygon): 1105 p1 = (h - p[0], v - p[1]) 1106 h, v = polygon[(i + 1) % n] 1107 p2 = (h - p[0], v - p[1]) 1108 angle += self.Angle2D(p1[0], p1[1], p2[0], p2[1]); 1109 1110 if abs(angle) < math.pi: 1111 return False 1112 return True
1113 1114 ## 1115 # Return the angle(in radians) between the two vectors (x1,y1), (x2,y2) 1116 # @param x1 The x of the first vector 1117 # @param y1 The y of the first vector 1118 # @param x2 The x of the second vector 1119 # @param y2 The y of the second vector 1120 # @return see above. 1121 #
1122 - def Angle2D(self, x1, y1, x2, y2):
1123 theta1 = math.atan2(y1, x1) 1124 theta2 = math.atan2(y2, x2) 1125 dtheta = theta2 - theta1 1126 while dtheta > math.pi: 1127 dtheta -= 2.0 * math.pi 1128 while dtheta < -math.pi: 1129 dtheta += 2.0 * math.pi 1130 return dtheta
1131 1132 ## 1133 # Instance of the Mask Object 1134 #
1135 -class MaskData(ShapeData):
1136 1137 ## 1138 # Create instance of MaskData Object 1139 #
1140 - def __init__(self, maskShape=None):
1141 ShapeData.__init__(self); 1142 if(maskShape==None): 1143 self.setValue(MaskI()); 1144 self.setX(0); 1145 self.setY(0); 1146 self.setWidth(0); 1147 self.setHeight(0); 1148 self.setBytes(None); 1149 else: 1150 self.setValue(maskShape);
1151 1152 ## 1153 # Set the x coord of the Mask 1154 # @param x See above.
1155 - def setX(self, x):
1156 shape = self.asIObject(); 1157 if(shape==None): 1158 raise Exception("No Shape specified."); 1159 shape.setX(rdouble(x));
1160 1161 ## 1162 # Get the x coord of the Mask 1163 # @return See Above.
1164 - def getX(self):
1165 shape = self.asIObject(); 1166 if(shape==None): 1167 raise Exception("No Shape specified."); 1168 x = shape.getX(); 1169 if(x==None): 1170 return 0; 1171 return x.getValue();
1172 1173 ## 1174 # Set the y coord of the Mask 1175 # @param y See above.
1176 - def setY(self, y):
1177 shape = self.asIObject(); 1178 if(shape==None): 1179 raise Exception("No Shape specified."); 1180 shape.setY(rdouble(y));
1181 1182 ## 1183 # Get the y coord of the Mask 1184 # @return See Above.
1185 - def getY(self):
1186 shape = self.asIObject(); 1187 if(shape==None): 1188 raise Exception("No Shape specified."); 1189 y = shape.getY(); 1190 if(y==None): 1191 return 0; 1192 return y.getValue();
1193 ## 1194 # Set the width the Mask 1195 # @param width See above.
1196 - def setWidth(self, width):
1197 shape = self.asIObject(); 1198 if(shape==None): 1199 raise Exception("No Shape specified."); 1200 shape.setWidth(rdouble(width));
1201 1202 ## 1203 # Get the width of the Mask 1204 # @return See Above.
1205 - def getWidth(self):
1206 shape = self.asIObject(); 1207 if(shape==None): 1208 raise Exception("No Shape specified."); 1209 width = shape.getWidth(); 1210 if(width==None): 1211 return 0; 1212 return width.getValue();
1213 ## 1214 # Set the height of the Mask 1215 # @param height See above.
1216 - def setHeight(self, height):
1217 shape = self.asIObject(); 1218 if(shape==None): 1219 raise Exception("No Shape specified."); 1220 shape.setHeight(rdouble(height));
1221 1222 ## 1223 # Get the height of the Mask 1224 # @return See Above.
1225 - def getHeight(self):
1226 shape = self.asIObject(); 1227 if(shape==None): 1228 raise Exception("No Shape specified."); 1229 height = shape.getHeight(); 1230 if(height==None): 1231 return 0; 1232 return height.getValue();
1233 ## 1234 # Set the bitmask of the Mask 1235 # @param See Above.
1236 - def setMask(self, mask):
1237 shape = self.asIObject(); 1238 if(shape==None): 1239 raise Exception("No Shape specified."); 1240 shape.setBytes(mask);
1241 1242 ## 1243 # Get the bitmask of the Mask 1244 # @return See Above.
1245 - def getMask(self):
1246 shape = self.asIObject(); 1247 if(shape==None): 1248 raise Exception("No Shape specified."); 1249 mask = shape.getBytes(); 1250 if(mask==None): # ?? 1251 return 0; 1252 return mask.getValue();
1253 1254 1255 ## 1256 # Instance of the RectangleData object 1257 #
1258 -class RectData(ShapeData):
1259 1260 ## 1261 # Create instance of MaskData Object 1262 #
1263 - def __init__(self, rectShape=None):
1264 ShapeData.__init__(self); 1265 if (rectShape == None): 1266 self.setValue(RectI()); 1267 self.setX(0); 1268 self.setY(0); 1269 self.setWidth(0); 1270 self.setHeight(0); 1271 else: 1272 self.setValue(rectShape);
1273 1274 ## 1275 # Set the x coord of the Rectangle 1276 # @param x See above.
1277 - def setX(self, x):
1278 shape = self.asIObject(); 1279 if (shape == None): 1280 raise Exception("No Shape specified."); 1281 shape.setX(rdouble(x));
1282 1283 ## 1284 # Get the x coord of the Rectangle 1285 # @return See Above.
1286 - def getX(self):
1287 shape = self.asIObject(); 1288 if (shape == None): 1289 raise Exception("No Shape specified."); 1290 x = shape.getX(); 1291 if (x == None): 1292 return 0; 1293 return x.getValue();
1294 1295 ## 1296 # Set the y coord of the Rectangle 1297 # @param y See above.
1298 - def setY(self, y):
1299 shape = self.asIObject(); 1300 if(shape==None): 1301 raise Exception("No Shape specified."); 1302 shape.setY(rdouble(y));
1303 1304 ## 1305 # Get the y coord of the Rectangle 1306 # @return See Above.
1307 - def getY(self):
1308 shape = self.asIObject(); 1309 if(shape==None): 1310 raise Exception("No Shape specified."); 1311 y = shape.getY(); 1312 if(y==None): 1313 return 0; 1314 return y.getValue();
1315 ## 1316 # Set the width the Rectangle 1317 # @param width See above.
1318 - def setWidth(self, width):
1319 shape = self.asIObject(); 1320 if(shape==None): 1321 raise Exception("No Shape specified."); 1322 shape.setWidth(rdouble(width));
1323 1324 ## 1325 # Get the width of the Rectangle 1326 # @return See Above.
1327 - def getWidth(self):
1328 shape = self.asIObject(); 1329 if(shape==None): 1330 raise Exception("No Shape specified."); 1331 width = shape.getWidth(); 1332 if(width==None): 1333 return 0; 1334 return width.getValue();
1335 ## 1336 # Set the height of the Rectangle 1337 # @param height See above.
1338 - def setHeight(self, height):
1339 shape = self.asIObject(); 1340 if(shape==None): 1341 raise Exception("No Shape specified."); 1342 shape.setHeight(rdouble(height));
1343 1344 ## 1345 # Get the height of the Rectangle 1346 # @return See Above.
1347 - def getHeight(self):
1348 shape = self.asIObject(); 1349 if(shape==None): 1350 raise Exception("No Shape specified."); 1351 height = shape.getHeight(); 1352 if(height==None): 1353 return 0; 1354 return height.getValue();
1355 1356 ## 1357 # Transform the point by the affineTransform transform. 1358 # @param transform See above. 1359 # @param point See above. 1360 # @return See above. 1361 #
1362 - def transformPoint(self, transform, point):
1363 p = numpy.matrix(point).transpose(); 1364 return transform*p;
1365 1366 ## 1367 # Return a map of points(x,y) contained within the Shape 1368 # @return See above. 1369 #
1370 - def containsPoints(self):
1371 transform = self.transformToMatrix(self.getTransform()); 1372 x = self.getX(); 1373 y = self.getY(); 1374 width = self.getWidth(); 1375 height = self.getHeight(); 1376 point = numpy.matrix((x, y, 1)).transpose(); 1377 centre = transform*point; 1378 BL = numpy.matrix((x, y+height, 1)).transpose(); 1379 BR = numpy.matrix((x+width, y+height, 1)).transpose(); 1380 TL = numpy.matrix((x, y, 1)).transpose(); 1381 TR = numpy.matrix((x+width, y, 1)).transpose(); 1382 lb = transform*BL; 1383 rb = transform*BR; 1384 lt = transform*TL; 1385 rt = transform*TR; 1386 majl = lb 1387 majr = rb 1388 o = (majr[1]-majl[1]); 1389 a = (majr[0]-majl[0]); 1390 h = math.sqrt(o*o+a*a); 1391 angle = math.asin(o/h); 1392 boundingBoxMinX = min(lt[0], rt[0], lb[0], rb[0]); 1393 boundingBoxMaxX = max(lt[0], rt[0], lb[0], rb[0]); 1394 boundingBoxMinY = min(lt[1], rt[1], lb[1], rb[1]); 1395 boundingBoxMaxY = max(lt[1], rt[1], lb[1], rb[1]); 1396 boundingBox = ((boundingBoxMinX, boundingBoxMinY), (boundingBoxMaxX, boundingBoxMaxY)); 1397 points = {}; 1398 xrange = range(boundingBox[0][0], boundingBox[1][0]) 1399 yrange = range(boundingBox[0][1], boundingBox[1][1]) 1400 transformedX = float(centre[0]); 1401 transformedY = float(centre[1]); 1402 cx = float(centre[0]); 1403 cy = float(centre[1]); 1404 for xx in xrange: 1405 for yy in yrange: 1406 newX = xx*math.cos(angle)+yy*math.sin(angle); 1407 newY = -xx*math.sin(angle)+yy*math.cos(angle); 1408 1409 if (newX-transformedX < width and newY-transformedY < height and newX-transformedX > 0 and newY-transformedY > 0): 1410 points[(int(x+cx), int(y+cy))]=1; 1411 return points;
1412 1413 ## 1414 # The workflow data object, which wraps the omero.mdoel.NamespaceI class 1415 #
1416 -class WorkflowData(DataObject):
1417 - def __init__(self, workflow=None):
1418 DataObject.__init__(self); 1419 if(workflow==None): 1420 self.setValue(NamespaceI()); 1421 self.setNamespace(""); 1422 self.setKeywords([]); 1423 self.setDirty(True); 1424 else: 1425 self.setValue(workflow);
1426 1427 ## 1428 # Set the namespace of the workflow. 1429 # @param namespace See above.
1430 - def setNamespace(self, namespace):
1431 workflow = self.asIObject(); 1432 if(workflow==None): 1433 raise Exception("No workflow specified."); 1434 workflow.setName(rstring(namespace)); 1435 self.setDirty(True);
1436 1437 ## 1438 # Get the namespace of the workflow 1439 # @return See Above.
1440 - def getNamespace(self):
1441 workflow = self.asIObject(); 1442 if(workflow==None): 1443 raise Exception("No Workflow specified."); 1444 namespace = workflow.getName(); 1445 if(namespace==None): 1446 return ""; 1447 return namespace.getValue();
1448 1449 ## 1450 # Set the keywords of the workflow. 1451 # @param namespace See above.
1452 - def setKeywords(self, keywords):
1453 workflow = self.asIObject(); 1454 if(workflow==None): 1455 raise Exception("No workflow specified."); 1456 workflow.setKeywords(keywords); 1457 self.setDirty(True);
1458 1459 ## 1460 # Set the keywords of the workflow. 1461 # @param namespace See above.
1462 - def setKeywordsFromString(self, keywords):
1463 workflow = self.asIObject(); 1464 if(workflow==None): 1465 raise Exception("No workflow specified."); 1466 workflow.setKeywords(toList(keywords)); 1467 self.setDirty(True);
1468 1469 ## 1470 # Get the keywords of the workflow 1471 # @return See Above.
1472 - def getKeywords(self):
1473 workflow = self.asIObject(); 1474 if(workflow==None): 1475 raise Exception("No Workflow specified."); 1476 keywords = workflow.getKeywords(); 1477 if(keywords==None): 1478 return []; 1479 return keywords;
1480 1481 ## 1482 # Add a keyword to the workflow 1483 # @param keyword See Above.
1484 - def addKeyword(self, keyword):
1485 if(self.containsKeyword(keyword)): 1486 return; 1487 keywords = self.getKeywords(); 1488 keywords.append(keyword); 1489 self.setKeywords(keywords);
1490 1491 ## 1492 # Return <code>True</code> if the keyword is part of workflow 1493 # @return See Above.
1494 - def containsKeyword(self, keyword):
1495 keywords = self.getKeywords(); 1496 return (keyword in keywords);
1497 1498 ## 1499 # Remove the keyword from the workflow 1500 # @param keyword See Above.
1501 - def removeKeyword(self, keyword):
1502 if(not self.containsKeyword(keyword)): 1503 return; 1504 newList = self.getKeywords(); 1505 newList.remove(keyword); 1506 self.setKeywords(newList);
1507