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

Source Code for Module omero.util.ROI_utils

  1  #!/usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3  # 
  4  # 
  5  #------------------------------------------------------------------------------ 
  6  #  Copyright (C) 2006-2009 University of Dundee. All rights reserved. 
  7  # 
  8  # 
  9  #       This program is free software; you can redistribute it and/or modify 
 10  #  it under the terms of the GNU General Public License as published by 
 11  #  the Free Software Foundation; either version 2 of the License, or 
 12  #  (at your option) any later version. 
 13  #  This program is distributed in the hope that it will be useful, 
 14  #  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 15  #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 16  #  GNU General Public License for more details. 
 17  # 
 18  #  You should have received a copy of the GNU General Public License along 
 19  #  with this program; if not, write to the Free Software Foundation, Inc., 
 20  #  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 
 21  # 
 22  #------------------------------------------------------------------------------ 
 23   
 24  ### 
 25  # 
 26  # ROIUtils allows the mapping of omero.model.ROIDataTypesI to python types 
 27  # and to create ROIDataTypesI from ROIUtil types.  
 28  # These methods also implement the acceptVisitor method linking to the ROIDrawingCanvas. 
 29  # 
 30  # 
 31  # @author  Jean-Marie Burel      
 32  #       <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a> 
 33  # @author       Donald MacDonald &nbsp;&nbsp;&nbsp;&nbsp; 
 34  #       <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a> 
 35  # @version 3.0 
 36  # <small> 
 37  # (<b>Internal version:</b> $Revision: $Date: $) 
 38  # </small> 
 39  # @since 3.0-Beta4 
 40  #/ 
 41  import omero.clients 
 42  from omero.model import RoiI 
 43  from omero.model import EllipseI 
 44  from omero.model import LineI 
 45  from omero.model import RectI 
 46  from omero.model import PointI 
 47  from omero.model import TextI 
 48  from omero.model import PolylineI 
 49  from omero.model import PolygonI 
 50  from omero.model import PathI 
 51  from omero.model import MaskI 
 52  from omero.rtypes import rdouble  
 53  from omero.rtypes import rstring  
 54  from omero.rtypes import rint  
 55  from omero.rtypes import rfloat  
 56   
 57   
 58  ## 
 59  # abstract, defines the method that call it as abstract. 
 60  # 
 61  # 
62 -def abstract():
63 import inspect 64 caller = inspect.getouterframes(inspect.currentframe())[1][3] 65 raise NotImplementedError(caller + ' must be implemented in subclass')
66 67 ## 68 # ShapeSettingsData contains all the display information about the ROI that aggregates it. 69 #
70 -class ShapeSettingsData:
71 72 ## 73 # Initialises the default values of the ShapeSettings. 74 # Stroke has default colour of darkGrey 75 # StrokeWidth defaults to 1 76 #
77 - def __init__(self):
78 self.WHITE = 16777215 79 self.BLACK = 0 80 self.GREY = 11184810 81 self.strokeColour = rint(self.GREY) 82 self.strokeWidth = rint(1) 83 self.strokeDashArray = rstring('') 84 self.strokeDashOffset = rint(0) 85 self.strokeLineCap = rstring('') 86 self.strokeLineJoin = rstring('') 87 self.strokeMiterLimit = rint(0) 88 self.fillColour = rint(self.GREY) 89 self.fillRule = rstring('')
90 91 ## 92 # Applies the settings in the ShapeSettingsData to the ROITypeI 93 # @param shape the omero.model.ROITypeI that these settings will be applied to 94 #
95 - def setROIShapeSettings(self, shape):
96 shape.setStrokeColor(self.strokeColour); 97 shape.setStrokeWidth(self.strokeWidth); 98 shape.setStrokeDashArray(self.strokeDashArray); 99 shape.setStrokeDashOffset(self.strokeDashOffset); 100 shape.setStrokeLineCap(self.strokeLineCap); 101 shape.setStrokeLineJoin(self.strokeLineJoin); 102 shape.setStrokeMiterLimit(self.strokeMiterLimit); 103 shape.setFillColor(self.fillColour); 104 shape.setFillRule(self.fillRule);
105 106 ## 107 # Set the Stroke settings of the ShapeSettings. 108 # @param colour The colour of the stroke. 109 # @param width The stroke width. 110 #
111 - def setStrokeSettings(self, colour, width = 1):
112 self.strokeColour = rint(colour); 113 self.strokeWidth = rint(width);
114 115 ### 116 # Set the Fill Settings for the ShapeSettings. 117 # @param colour The fill colour of the shape.
118 - def setFillSettings(self, colour):
119 self.fillColour = rstring(colour);
120 121 ## 122 # Get the stroke settings as the tuple (strokeColour, strokeWidth). 123 # @return See above. 124 #
125 - def getStrokeSettings(self):
126 return (self.strokeColour.getValue(), self.strokeWidth.getValue());
127 128 ## 129 # Get the fill setting as a tuple of (fillColour) 130 # @return See above. 131 #
132 - def getFillSettings(self):
133 return (self.fillColour.getValue());
134 135 ## 136 # Get the tuple ((stokeColor, strokeWidth), (fillColour)). 137 # @return see above. 138 #
139 - def getSettings(self):
140 return (self.getStrokeSettings(), self.getFillSettings());
141 142 ## 143 # Set the current shapeSettings from the ROI roi. 144 # @param roi see above. 145 #
146 - def getShapeSettingsFromROI(self, roi):
147 self.strokeColour = roi.getStrokeColor(); 148 self.strokeWidth = roi.getStrokeWidth(); 149 self.strokeDashArray = roi.getStrokeDashArray(); 150 self.strokeDashOffset = roi.getStrokeDashOffset(); 151 self.strokeLineCap = roi.getStrokeLineCap(); 152 self.strokeLineJoin = roi.getStrokeLineJoin(); 153 self.strokeMiterLimit = roi.getStrokeMiterLimit(); 154 self.fillColour = roi.getFillColor(); 155 self.fillRule = roi.getFillRule();
156 157 ## 158 # This class stores the ROI Coordinate (Z,T). 159 #
160 -class ROICoordinate:
161 162 ## 163 # Initialise the ROICoordinate. 164 # @param z The z-section. 165 # @param t The timepoint.
166 - def __init__(self, z = 0, t = 0):
167 self.theZ = rint(z); 168 self.theT = rint(t);
169 170 ## 171 # Set the (z, t) for the roi using the (z, t) of the ROICoordinate. 172 # @param roi The ROI to set the (z, t) on. 173 #
174 - def setROICoord(self, roi):
175 roi.setTheZ(self.theZ); 176 roi.setTheT(self.theT);
177 178 ## 179 # Get the (z, t) from the ROI. 180 # @param See above. 181 #
182 - def setCoordFromROI(self, roi):
183 self.theZ = roi.getTheZ(); 184 self.theT = roi.getTheT();
185 186 ## 187 # Interface to inherit for accepting ROIDrawing as a visitor. 188 # @param visitor The ROIDrawingCompoent. 189 #
190 -class ROIDrawingI:
191 - def acceptVisitor(self, visitor):
192 abstract();
193 194 ## 195 # The base class for all ROIShapeData objects. 196 #
197 -class ShapeData:
198 199 ## 200 # Constructor sets up the coord, shapeSettings and ROI objects. 201 #
202 - def __init__(self):
203 self.coord = ROICoordinate(); 204 self.shapeSettings = ShapeSettingsData(); 205 self.ROI = None;
206 207 ## 208 # Set the coord of the class to coord. 209 # @param See above. 210 #
211 - def setCoord(self, coord):
212 self.coord = coord;
213 214 ## 215 # Set the ROICoordinate of the roi. 216 # @param roi See above. 217 #
218 - def setROICoord(self, roi):
219 self.coord.setROICoord(roi);
220 221 ## 222 # Set the Geometry of the roi from the geometry in ShapeData. 223 # @param roi See above. 224 #
225 - def setROIGeometry(self, roi):
226 abstract();
227 228 ## 229 # Set the Settings of the ShapeDate form the settings object. 230 # @param settings See above. 231 #
232 - def setShapeSettings(self, settings):
233 self.shapeSettings = settings;
234 235 ## 236 # Set the Settings of the roi from the setting in ShapeData. 237 # @param roi See above. 238 #
239 - def setROIShapeSettings(self, roi):
240 self.shapeSettings.setROIShapeSettings(roi);
241 242 ## 243 # Accept visitor. 244 # @param visitor See above. 245 #
246 - def acceptVisitor(self, visitor):
247 abstract();
248 249 ## 250 # Create the base type of ROI for this shape. 251 #
252 - def createBaseType(self):
253 abstract();
254 255 ## 256 # Get the roi from the ShapeData. If the roi already exists return it. 257 # Otherwise create it from the ShapeData and return it. 258 # @return See above. 259 #
260 - def getROI(self):
261 if(self.roi != None): 262 return self.roi; 263 self.roi = self.createBaseType(); 264 self.setROICoord(self.roi); 265 self.setROIGeometry(self.roi); 266 self.setROIShapeSettings(self.roi); 267 return self.roi;
268 269 ## 270 # Set the shape settings object from the roi. 271 # @param roi see above. 272 #
273 - def getShapeSettingsFromROI(self, roi):
274 self.shapeSettings.getShapeSettingsFromROI(roi);
275 276 ## 277 # Set the ROICoordinate from the roi. 278 # @param roi See above. 279 #
280 - def getCoordFromROI(self, roi):
281 self.coord.setCoordFromROI(roi);
282 283 ## 284 # Set the Geometr from the roi. 285 # @param roi See above. 286 #
287 - def getGeometryFromROI(self , roi):
288 abstract();
289 290 ## 291 # Get all settings from the roi, Geomerty, Shapesettins, ROICoordinate. 292 # @param roi See above. 293 #
294 - def fromROI(self, roi):
295 self.roi = roi; 296 self.getShapeSettingsFromROI(roi); 297 self.getCoordFromROI(roi); 298 self.getGeometryFromROI(roi);
299 300 ## 301 # The EllispeData class contains all the manipulation and create of EllipseI 302 # types. 303 # It also accepts the ROIDrawingUtils visitor for drawing ellipses. 304 #
305 -class EllipseData(ShapeData, ROIDrawingI):
306 307 ## 308 # Constructor for EllipseData object. 309 # @param roicoord The ROICoordinate of the object (default: 0,0) 310 # @param cx The centre x coordinate of the ellipse. 311 # @param cy The centre y coordinate of the ellipse. 312 # @param rx The major axis of the ellipse. 313 # @param ry The minor axis of the ellipse.
314 - def __init__(self, roicoord = ROICoordinate(), cx = 0, cy = 0, rx = 0, ry = 0):
315 ShapeData.__init__(self); 316 self.cx = rdouble(cx); 317 self.cy = rdouble(cy); 318 self.rx = rdouble(rx); 319 self.ry = rdouble(ry); 320 self.setCoord(roicoord);
321 322 ## 323 # overridden, @See ShapeData#setROIGeometry 324 #
325 - def setROIGeometry(self, ellipse):
326 ellipse.setTheZ(self.coord.theZ); 327 ellipse.setTheT(self.coord.theZ); 328 ellipse.setCx(self.cx); 329 ellipse.setCy(self.cy); 330 ellipse.setRx(self.rx); 331 ellipse.setRy(self.ry);
332 333 ## 334 # overridden, @See ShapeData#getGeometryFromROI 335 #
336 - def getGeometryFromROI(self, roi):
337 self.cx = roi.getCx(); 338 self.cy = roi.getCy(); 339 self.rx = roi.getRx(); 340 self.ry = roi.getRy();
341 342 ## 343 # overridden, @See ShapeData#createBaseType 344 #
345 - def createBaseType(self):
346 return EllipseI();
347 348 ## 349 # overridden, @See ShapeData#acceptVisitor 350 #
351 - def acceptVisitor(self, visitor):
352 visitor.drawEllipse(self.cx.getValue(), self.cy.getValue(), self.rx.getValue(), self.ry.getValue(), self.shapeSettings.getSettings());
353 354 ## 355 # The RectangleData class contains all the manipulation and create of RectI 356 # types. 357 # It also accepts the ROIDrawingUtils visitor for drawing rectangles. 358 #
359 -class RectangleData(ShapeData, ROIDrawingI):
360 361 ## 362 # Constructor for RectangleData object. 363 # @param roicoord The ROICoordinate of the object (default: 0,0) 364 # @param x The top left x - coordinate of the shape. 365 # @param y The top left y - coordinate of the shape. 366 # @param width The width of the shape. 367 # @param height The height of the shape.
368 - def __init__(self, roicoord = ROICoordinate(), x = 0, y = 0, width = 0, height = 0):
369 ShapeData.__init__(self); 370 self.x = rdouble(x); 371 self.y = rdouble(y); 372 self.width = rdouble(width); 373 self.height = rdouble(height); 374 self.setCoord(roicoord);
375 376 ## 377 # overridden, @See ShapeData#setGeometry 378 #
379 - def setGeometry(self, rectangle):
380 rectangle.setTheZ(self.coord.theZ); 381 rectangle.setTheT(self.coord.theZ); 382 rectangle.setX(self.x); 383 rectangle.setY(self.y); 384 rectangle.setWidth(self.width); 385 rectangle.setHeight(self.height);
386 387 ## 388 # overridden, @See ShapeData#getGeometryFromROI 389 #
390 - def getGeometryFromROI(self, roi):
391 self.x = roi.getX(); 392 self.y = roi.getY(); 393 self.width = roi.getWidth(); 394 self.height = roi.getHeight();
395 396 ## 397 # overridden, @See ShapeData#createBaseType 398 #
399 - def createBaseType(self):
400 return RectI();
401 402 ## 403 # overridden, @See ShapeData#acceptVisitor 404 #
405 - def acceptVisitor(self, visitor):
406 visitor.drawRectangle(self.x, self.y, self.width, self.height, self.shapeSettings.getSettings());
407 ## 408 # The LineData class contains all the manipulation and create of LineI 409 # types. 410 # It also accepts the ROIDrawingUtils visitor for drawing lines. 411 #
412 -class LineData(ShapeData, ROIDrawingI):
413 414 ## 415 # Constructor for LineData object. 416 # @param roicoord The ROICoordinate of the object (default: 0,0) 417 # @param x1 The first x coordinate of the shape. 418 # @param y1 The first y coordinate of the shape. 419 # @param x2 The second x coordinate of the shape. 420 # @param y2 The second y coordinate of the shape.
421 - def __init__(self, roicoord = ROICoordinate(), x1 = 0, y1 = 0, x2 = 0, y2 = 0):
422 ShapeData.__init__(self); 423 self.x1 = rdouble(x1); 424 self.y1 = rdouble(y1); 425 self.x2 = rdouble(x2); 426 self.y2 = rdouble(y2); 427 self.setCoord(roicoord);
428 429 ## 430 # overridden, @See ShapeData#setGeometry 431 #
432 - def setGeometry(self, line):
433 line.setTheZ(self.coord.theZ); 434 line.setTheT(self.coord.theZ); 435 line.setX1(self.x1); 436 line.setY1(self.y1); 437 line.setX2(self.x2); 438 line.setY2(self.y2);
439 440 ## 441 # overridden, @See ShapeData#getGeometryFromROI 442 #
443 - def getGeometryFromROI(self, roi):
444 self.x1 = roi.getX1(); 445 self.y1 = roi.getY1(); 446 self.x2 = roi.getX2(); 447 self.y2 = roi.getY2();
448 449 ## 450 # overridden, @See ShapeData#createBaseType 451 #
452 - def createBaseType(self):
453 return LineI();
454 455 ## 456 # overridden, @See ShapeData#acceptVisitor 457 #
458 - def acceptVisitor(self, visitor):
459 visitor.drawLine(self.x1.getValue(), self.y1.getValue(), self.x2.getValue(), self.y2.getValue(), self.shapeSettings.getSettings());
460 461 ## 462 # The MaskData class contains all the manipulation and create of MaskI 463 # types. 464 # It also accepts the ROIDrawingUtils visitor for drawing masks. 465 #
466 -class MaskData(ShapeData, ROIDrawingI):
467 468 ## 469 # Constructor for MaskData object. 470 # @param roicoord The ROICoordinate of the object (default: 0,0) 471 # @param bytes The mask data. 472 # @param x The top left x - coordinate of the shape. 473 # @param y The top left y - coordinate of the shape. 474 # @param width The width of the shape. 475 # @param height The height of the shape.
476 - def __init__(self, roicoord = ROICoordinate(), bytes = None, x = 0, y = 0, width = 0, height = 0):
477 ShapeData.__init__(self); 478 self.x = rdouble(x); 479 self.y = rdouble(y); 480 self.width = rdouble(width); 481 self.height = rdouble(height); 482 self.bytesdata = bytes; 483 self.setCoord(roicoord);
484 485 ## 486 # overridden, @See ShapeData#setGeometry 487 #
488 - def setGeometry(self, mask):
489 mask.setTheZ(self.coord.theZ); 490 mask.setTheT(self.coord.theZ); 491 mask.setX(self.x); 492 mask.setY(self.y); 493 mask.setWidth(self.width); 494 mask.setHeight(self.height); 495 mask.setBytes(self.bytedata);
496 497 ## 498 # overridden, @See ShapeData#getGeometryFromROI 499 #
500 - def getGeometryFromROI(self, roi):
501 self.x = roi.getX(); 502 self.y = roi.getY(); 503 self.width = roi.getWidth(); 504 self.height = roi.getHeight(); 505 self.bytesdata = roi.getBytes();
506 507 ## 508 # overridden, @See ShapeData#createBaseType 509 #
510 - def createBaseType(self):
511 return MaskI();
512 513 ## 514 # overridden, @See ShapeData#acceptVisitor 515 #
516 - def acceptVisitor(self, visitor):
517 visitor.drawMask(self.x.getValue(), self.y.getValue(), self.width.getValue(), self.height.getValue(), self.bytesdata, self.shapeSettings.getSettings());
518 519 ## 520 # The PointData class contains all the manipulation and create of PointI 521 # types. 522 # It also accepts the ROIDrawingUtils visitor for drawing points. 523 #
524 -class PointData(ShapeData, ROIDrawingI):
525 526 ## 527 # Constructor for PointData object. 528 # @param roicoord The ROICoordinate of the object (default: 0,0) 529 # @param x The x coordinate of the shape. 530 # @param y The y coordinate of the shape.
531 - def __init__(self, roicoord = ROICoordinate(), x = 0, y = 0):
532 ShapeData.__init__(self); 533 self.x = rdouble(x); 534 self.y = rdouble(y); 535 self.setCoord(roicoord);
536 537 ## 538 # overridden, @See ShapeData#setGeometry 539 #
540 - def setGeometry(self, point):
541 point.setTheZ(self.coord.theZ); 542 point.setTheT(self.coord.theZ); 543 point.setX(self.x); 544 point.setY(self.y);
545 546 ## 547 # overridden, @See ShapeData#getGeometryFromROI 548 #
549 - def getGeometryFromROI(self, roi):
550 self.x = roi.getX(); 551 self.y = roi.getY();
552 553 ## 554 # overridden, @See ShapeData#createBaseType 555 #
556 - def createBaseType(self):
557 return PointI();
558 559 ## 560 # overridden, @See ShapeData#acceptVisitor 561 #
562 - def acceptVisitor(self, visitor):
563 visitor.drawEllipse(self.x.getValue(), self.y.getValue(), 3, 3, self.shapeSettings.getSettings());
564 565 ## 566 # The PolygonData class contains all the manipulation and create of PolygonI 567 # types. 568 # It also accepts the ROIDrawingUtils visitor for drawing polygons. 569 #
570 -class PolygonData(ShapeData, ROIDrawingI):
571 572 ## 573 # Constructor for PolygonData object. 574 # @param roicoord The ROICoordinate of the object (default: 0,0) 575 # @param pointList The list of points that make up the polygon, as pairs [x1, y1, x2, y2 ..].
576 - def __init__(self, roicoord = ROICoordinate(), pointsList = (0,0)):
577 ShapeData.__init__(self); 578 self.points = rstring(self.listToString(pointsList)); 579 self.setCoord(roicoord);
580 581 ## 582 # overridden, @See ShapeData#setGeometry 583 #
584 - def setGeometry(self, polygon):
585 polygon.setTheZ(self.coord.theZ); 586 polygon.setTheT(self.coord.theZ); 587 polygon.setPoints(self.points);
588 589 ## 590 # overridden, @See ShapeData#getGeometryFromROI 591 #
592 - def getGeometryFromROI(self, roi):
593 self.points = roi.getPoints();
594 595 ## 596 # Convert a pointsList[x1,y1,x2,y2..] to a string. 597 # @param pointsList The list of points to convert. 598 # @return The pointsList converted to a string.
599 - def listToString(self, pointsList):
600 string = ''; 601 cnt = 0; 602 for element in pointsList: 603 if(cnt!=0): 604 string = string + ','; 605 cnt += 1; 606 string = string + str(element); 607 return string;
608 609 ## 610 # Convert a string of points to a tuple list [(x1,y1),(x2,y2)..]. 611 # @param pointString The string to convert. 612 # @return The tuple list converted from a string.
613 - def stringToTupleList(self, pointString):
614 elements = []; 615 list = pointString.split(','); 616 numTokens = len(list); 617 for tokenPair in range(0,numTokens/2): 618 elements.append((int(list[tokenPair*2]), int(list[tokenPair*2+1]))); 619 return elements;
620 621 ## 622 # overridden, @See ShapeData#createBaseType 623 #
624 - def createBaseType(self):
625 return PolygonI();
626 627 ## 628 # overridden, @See ShapeData#acceptVisitor 629 #
630 - def acceptVisitor(self, visitor):
631 visitor.drawPolygon(self.stringToTupleList(self.points.getValue()), self.shapeSettings.getSettings());
632 633 ## 634 # The PolylineData class contains all the manipulation and create of PolylineI 635 # types. 636 # It also accepts the ROIDrawingUtils visitor for drawing polylines. 637 #
638 -class PolylineData(ShapeData, ROIDrawingI):
639 640 ## 641 # Constructor for PolylineData object. 642 # @param roicoord The ROICoordinate of the object (default: 0,0) 643 # @param pointList The list of points that make up the polygon, as pairs [x1, y1, x2, y2 ..].
644 - def __init__(self, roicoord = ROICoordinate(), pointsList = (0,0)):
645 ShapeData.__init__(self); 646 self.points = rstring(self.listToString(pointsList)); 647 self.setCoord(roicoord);
648 649 ## 650 # overridden, @See ShapeData#setGeometry 651 #
652 - def setGeometry(self, point):
653 point.setTheZ(self.coord.theZ); 654 point.setTheT(self.coord.theZ); 655 point.setPoints(self.points);
656 657 ## 658 # overridden, @See ShapeData#getGeometryFromROI 659 #
660 - def getGeometryFromROI(self, roi):
661 self.points = roi.getPoints();
662 663 ## 664 # Convert a pointsList[x1,y1,x2,y2..] to a string. 665 # @param pointsList The list of points to convert. 666 # @return The pointsList converted to a string.
667 - def listToString(self, pointsList):
668 string = ''; 669 cnt = 0; 670 for element in pointsList: 671 if(cnt > 0): 672 string = string + ','; 673 string = string + str(element); 674 cnt+=1; 675 return string;
676 677 ## 678 # Convert a string of points to a tuple list [(x1,y1),(x2,y2)..]. 679 # @param pointString The string to convert. 680 # @return The tuple list converted from a string.
681 - def stringToTupleList(self, pointString):
682 elements = []; 683 list = pointString.split(','); 684 numTokens = len(list); 685 for tokenPair in range(0,numTokens/2): 686 elements.append((int(list[tokenPair*2]), int(list[tokenPair*2+1]))); 687 return elements;
688 689 ## 690 # overridden, @See ShapeData#createBaseType 691 #
692 - def createBaseType(self):
693 return PolylineI();
694 695 ## 696 # overridden, @See ShapeData#acceptVisitor 697 #
698 - def acceptVisitor(self, visitor):
699 visitor.drawPolyline(self.stringToTupleList(self.points.getValue()), self.shapeSettings.getSettings());
700