Package omeroweb :: Package webgateway :: Module marshal
[hide private]
[frames] | no frames]

Source Code for Module omeroweb.webgateway.marshal

  1  #!/usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3   
  4  # 
  5  # Copyright (C) 2012 University of Dundee & Open Microscopy Environment. 
  6  # All rights reserved. 
  7  # 
  8  # This program is free software: you can redistribute it and/or modify 
  9  # it under the terms of the GNU Affero General Public License as 
 10  # published by the Free Software Foundation, either version 3 of the 
 11  # License, or (at your option) any later version. 
 12  # 
 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 Affero General Public License for more details. 
 17  # 
 18  # You should have received a copy of the GNU Affero General Public License 
 19  # along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 20  # 
 21  import omero 
 22  import time 
 23  import re 
 24  import logging 
 25  import traceback 
 26   
 27  logger = logging.getLogger(__name__) 
 28   
 29  from django.conf import settings 
 30  from omero.rtypes import unwrap 
 31   
 32  # OMERO.insight point list regular expression 
 33  INSIGHT_POINT_LIST_RE = re.compile(r'points\[([^\]]+)\]') 
 34   
 35  # OME model point list regular expression 
 36  OME_MODEL_POINT_LIST_RE = re.compile(r'([\d.]+),([\d.]+)') 
 37   
38 -def channelMarshal (channel):
39 """ 40 return a dict with all there is to know about a channel 41 42 @param channel: L{omero.gateway.ChannelWrapper} 43 @return: Dict 44 """ 45 46 return {'emissionWave': channel.getEmissionWave(), 47 'label': channel.getLabel(), 48 'color': channel.getColor().getHtml(), 49 'window': {'min': channel.getWindowMin(), 50 'max': channel.getWindowMax(), 51 'start': channel.getWindowStart(), 52 'end': channel.getWindowEnd(),}, 53 'active': channel.isActive()}
54
55 -def imageMarshal (image, key=None):
56 """ 57 return a dict with pretty much everything we know and care about an image, 58 all wrapped in a pretty structure. 59 60 @param image: L{omero.gateway.ImageWrapper} 61 @param key: key of specific attributes to select 62 @return: Dict 63 """ 64 65 image.loadRenderOptions() 66 pr = image.getProject() 67 ds = None 68 wellsample = None 69 well = None 70 try: 71 # Replicating the functionality of the deprecated 72 # ImageWrapper.getDataset() with shares in mind. 73 # -- Tue Sep 6 10:48:47 BST 2011 (See #6660) 74 parents = image.listParents() 75 if parents is not None and len(parents) == 1: 76 if parents[0].OMERO_CLASS == 'Dataset': 77 ds = parents[0] 78 elif parents[0].OMERO_CLASS == 'WellSample': 79 wellsample = parents[0] 80 if wellsample.well is not None: 81 well = wellsample.well 82 except omero.SecurityViolation, e: 83 # We're in a share so the Image's parent Dataset cannot be loaded 84 # or some other permissions related issue has tripped us up. 85 logger.warn('Security violation while retrieving Dataset when ' \ 86 'marshaling image metadata: %s' % e.message) 87 88 rv = { 89 'id': image.id, 90 'meta': {'imageName': image.name or '', 91 'imageDescription': image.description or '', 92 'imageAuthor': image.getAuthor(), 93 'projectName': pr and pr.name or 'Multiple', 94 'projectId': pr and pr.id or None, 95 'projectDescription':pr and pr.description or '', 96 'datasetName': ds and ds.name or 'Multiple', 97 'datasetId': ds and ds.id or '', 98 'datasetDescription': ds and ds.description or '', 99 'wellSampleId': wellsample and wellsample.id or '', 100 'wellId': well and well.id.val or '', 101 'imageTimestamp': time.mktime(image.getDate().timetuple()), 102 'imageId': image.id,}, 103 } 104 try: 105 reOK = image._prepareRenderingEngine() 106 if not reOK: 107 logger.debug("Failed to prepare Rendering Engine for imageMarshal") 108 return rv 109 except omero.ConcurrencyException, ce: 110 backOff = ce.backOff 111 rv = { 112 'ConcurrencyException': { 113 'backOff': backOff 114 } 115 } 116 return rv 117 except Exception, ex: # Handle everything else. 118 rv['Exception'] = ex.message 119 logger.error(traceback.format_exc()) 120 return rv # Return what we have already, in case it's useful 121 122 #big images 123 tiles = image._re.requiresPixelsPyramid() 124 width, height = image._re.getTileSize() 125 levels = image._re.getResolutionLevels() 126 zoomLevelScaling = image.getZoomLevelScaling() 127 init_zoom = None 128 if hasattr(settings, 'VIEWER_INITIAL_ZOOM_LEVEL'): 129 init_zoom = settings.VIEWER_INITIAL_ZOOM_LEVEL 130 if init_zoom < 0: 131 init_zoom = levels + init_zoom 132 133 try: 134 rv.update({ 135 'tiles': tiles, 136 'tile_size': {'width': width, 137 'height': height}, 138 'levels': levels, 139 'size': {'width': image.getSizeX(), 140 'height': image.getSizeY(), 141 'z': image.getSizeZ(), 142 't': image.getSizeT(), 143 'c': image.getSizeC(),}, 144 'pixel_size': {'x': image.getPixelSizeX(), 145 'y': image.getPixelSizeY(), 146 'z': image.getPixelSizeZ(),}, 147 }) 148 if init_zoom is not None: 149 rv['init_zoom'] = init_zoom 150 if zoomLevelScaling is not None: 151 rv.update({'zoomLevelScaling': zoomLevelScaling}) 152 try: 153 rv['pixel_range'] = image.getPixelRange() 154 rv['channels'] = map(lambda x: channelMarshal(x), image.getChannels()) 155 rv['split_channel'] = image.splitChannelDims() 156 rv['rdefs'] = {'model': image.isGreyscaleRenderingModel() and 'greyscale' or 'color', 157 'projection': image.getProjection(), 158 'defaultZ': image._re.getDefaultZ(), 159 'defaultT': image._re.getDefaultT(), 160 'invertAxis': image.isInvertedAxis()} 161 except TypeError: 162 # Will happen if an image has bad or missing pixel data 163 logger.error('imageMarshal', exc_info=True) 164 rv['pixel_range'] = (0, 0) 165 rv['channels'] = () 166 rv['split_channel'] = () 167 rv['rdefs'] = {'model': 'color', 168 'projection': image.getProjection(), 169 'defaultZ': 0, 170 'defaultT': 0, 171 'invertAxis': image.isInvertedAxis()} 172 except AttributeError: 173 rv = None 174 raise 175 if key is not None and rv is not None: 176 for k in key.split('.'): 177 rv = rv.get(k, {}) 178 if rv == {}: 179 rv = None 180 return rv
181
182 -def shapeMarshal(shape):
183 """ 184 return a dict with all there is to know about a shape 185 186 @param channel: L{omero.model.ShapeI} 187 @return: Dict 188 """ 189 rv = {} 190 191 def set_if(k, v, func=lambda a: a is not None): 192 """ 193 Sets the key L{k} with the value of L{v} if the unwrapped value L{v} 194 passed to L{func} evaluates to True. In the default case this is 195 True if the unwrapped value L{v} is not None. 196 """ 197 v = unwrap(v) 198 if func(v): 199 rv[k] = v
200 201 rv['id'] = shape.getId().getValue() 202 set_if('theT', shape.getTheT()) 203 set_if('theZ', shape.getTheZ()) 204 shape_type = type(shape) 205 if shape_type == omero.model.RectI: 206 rv['type'] = 'Rectangle' 207 rv['x'] = shape.getX().getValue() 208 rv['y'] = shape.getY().getValue() 209 rv['width'] = shape.getWidth().getValue() 210 rv['height'] = shape.getHeight().getValue() 211 elif shape_type == omero.model.MaskI: 212 rv['type'] = 'Mask' 213 rv['x'] = shape.getX().getValue() 214 rv['y'] = shape.getY().getValue() 215 rv['width'] = shape.getWidth().getValue() 216 rv['height'] = shape.getHeight().getValue() 217 # TODO: support for mask 218 elif shape_type == omero.model.EllipseI: 219 rv['type'] = 'Ellipse' 220 rv['cx'] = shape.getCx().getValue() 221 rv['cy'] = shape.getCy().getValue() 222 rv['rx'] = shape.getRx().getValue() 223 rv['ry'] = shape.getRy().getValue() 224 elif shape_type == omero.model.PolylineI: 225 rv['type'] = 'PolyLine' 226 rv['points'] = stringToSvg(shape.getPoints().getValue()) 227 elif shape_type == omero.model.LineI: 228 rv['type'] = 'Line' 229 rv['x1'] = shape.getX1().getValue() 230 rv['x2'] = shape.getX2().getValue() 231 rv['y1'] = shape.getY1().getValue() 232 rv['y2'] = shape.getY2().getValue() 233 elif shape_type == omero.model.PointI: 234 rv['type'] = 'Point' 235 rv['cx'] = shape.getCx().getValue() 236 rv['cy'] = shape.getCy().getValue() 237 elif shape_type == omero.model.PolygonI: 238 rv['type'] = 'Polygon' 239 rv['points'] = stringToSvg(shape.getPoints().getValue()) + " z" # z = closed line 240 elif shape_type == omero.model.LabelI: 241 rv['type'] = 'Label' 242 rv['x'] = shape.getX().getValue() 243 rv['y'] = shape.getY().getValue() 244 else: 245 logger.debug("Shape type not supported: %s" % str(shape_type)) 246 247 text_value = unwrap(shape.getTextValue()) 248 if text_value is not None: 249 # only populate json with font styles if we have some text 250 rv['textValue'] = text_value 251 set_if('fontSize', shape.getFontSize()) 252 set_if('fontStyle', shape.getFontStyle()) 253 set_if('fontFamily', shape.getFontFamily()) 254 255 set_if('transform', shape.getTransform(), 256 func=lambda a: a is not None and a != 'None') 257 fill_color = unwrap(shape.getFillColor()) 258 if fill_color is not None: 259 rv['fillColor'], rv['fillAlpha'] = rgb_int2css(fill_color) 260 stroke_color = unwrap(shape.getStrokeColor()) 261 if stroke_color is not None: 262 rv['strokeColor'], rv['strokeAlpha'] = rgb_int2css(stroke_color) 263 set_if('strokeWidth', shape.getStrokeWidth()) 264 return rv 265
266 -def stringToSvg(string):
267 """ 268 Method for converting the string returned from omero.model.ShapeI.getPoints() 269 into an SVG for display on web. 270 E.g: "points[309,427, 366,503, 190,491] points1[309,427, 366,503, 190,491] points2[309,427, 366,503, 190,491]" 271 To: M 309 427 L 366 503 L 190 491 z 272 """ 273 point_list = string.strip() 274 match = INSIGHT_POINT_LIST_RE.search(point_list) 275 if match is not None: 276 point_list = match.group(1) 277 point_list = OME_MODEL_POINT_LIST_RE.findall(point_list) 278 if len(point_list) == 0: 279 logger.error("Unrecognised ROI shape 'points' string: %r" % string) 280 return "" 281 point_list = ' L '.join([' '.join(point) for point in point_list]) 282 return "M %s" % point_list
283
284 -def rgb_int2css(rgbint):
285 """ 286 converts a bin int number into css colour, E.g. -1006567680 to '#00ff00' 287 """ 288 alpha = rgbint // 256 // 256 // 256 % 256 289 alpha = float(alpha) / 256 290 r,g,b = (rgbint // 256 // 256 % 256, rgbint // 256 % 256, rgbint % 256) 291 return "#%02x%02x%02x" % (r,g,b) , alpha
292