1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
33 INSIGHT_POINT_LIST_RE = re.compile(r'points\[([^\]]+)\]')
34
35
36 OME_MODEL_POINT_LIST_RE = re.compile(r'([\d.]+),([\d.]+)')
37
54
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
72
73
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
84
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:
118 rv['Exception'] = ex.message
119 logger.error(traceback.format_exc())
120 return rv
121
122
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
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
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
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"
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
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
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
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