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