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