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

Source Code for Module omero.util.OmeroPopo

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