Package omero :: Module columns
[hide private]
[frames] | no frames]

Source Code for Module omero.columns

  1  """
 
  2  ::
 
  3      /*
 
  4       *   $Id$
 
  5       *
 
  6       *   Copyright 2009 Glencoe Software, Inc. All rights reserved.
 
  7       *   Use is subject to license terms supplied in LICENSE.txt
 
  8       *
 
  9       */
 
 10  """ 
 11  
 
 12  """
 
 13  Concrete implementations of the omero.grid.Column
 
 14  type hierarchy which know how to convert themselves
 
 15  to PyTables types.
 
 16  """ 
 17  
 
 18  import omero, Ice 
 19  import omero_Tables_ice 
 20  
 
 21  try: 
 22      import numpy 
 23      tables = __import__("tables") # Pytables 
 24      has_pytables = True 
 25  except ImportError: 
 26      has_pytables = False 
 27  
 
 28  
 
29 -def columns2definition(cols):
30 """ 31 Takes a list of columns and converts them into a map 32 from names to tables.* column descriptors 33 """ 34 definition = {} 35 for i in range(len(cols)): 36 column = cols[i] 37 instance = column.descriptor(pos=i) 38 definition[column.name] = instance 39 # Descriptions are handled separately 40 return definition
41
42 -class AbstractColumn(object):
43 """ 44 Base logic for all columns 45 """ 46
47 - def __init__(self):
48 d = self.descriptor(0) 49 if isinstance(d, tables.IsDescription): 50 cols = d.columns 51 try: 52 del cols["_v_pos"] 53 except KeyError: 54 pass 55 self.recarrtypes = [None for x in range(len(cols))] 56 for k, v in cols.items(): 57 self.recarrtypes[v._v_pos] = ("%s/%s" % (self.name, k), v.recarrtype) 58 else: 59 self.recarrtypes = [(self.name, d.recarrtype)]
60
61 - def settable(self, tbl):
62 """ 63 Called by tables.py when first initializing columns. 64 Can be used to complete further initialization. 65 """ 66 self.__table = tbl
67
68 - def append(self, tbl):
69 """ 70 Called by tables.py to give columns. By default, does nothing. 71 """ 72 pass
73
74 - def readCoordinates(self, tbl, rowNumbers):
75 if rowNumbers is None or len(rowNumbers) == 0: 76 rows = tbl.read() 77 else: 78 rows = tbl.readCoordinates(rowNumbers) 79 self.fromrows(rows)
80
81 - def read(self, tbl, start, stop):
82 rows = tbl.read(start, stop) 83 self.fromrows(rows)
84
85 - def getsize(self):
86 """ 87 Any method which does not use the "values" field 88 will need to override this method. 89 """ 90 if self.values is None: 91 return None 92 else: 93 return len(self.values)
94
95 - def setsize(self, size):
96 """ 97 Any method which does not use the "values" field 98 will need to override this method. 99 """ 100 if size is None: 101 self.values = None 102 else: 103 self.values = [None for x in range(size)]
104
105 - def names(self):
106 """ 107 Any method which does not use the "values" field 108 will need to override this method. 109 """ 110 return [self.name]
111
112 - def arrays(self):
113 """ 114 Any method which does not use the "values" field 115 will need to override this method. 116 """ 117 return [numpy.array(self.values, dtype=self.recarrtypes[0][1])]
118
119 - def fromrows(self, rows):
120 """ 121 Any method which does not use the "values" field 122 will need to override this method. 123 """ 124 self.values = rows[self.name] 125 # WORKAROUND: http://www.zeroc.com/forums/bug-reports/4165-icepy-can-not-handle-buffers-longs-i64.html#post20468 126 # see ticket:1951 and #2160 127 ## d = self.recarrtypes[0][1] 128 ## Disabled until Ice 3.4 129 ## if isinstance(d, str): 130 ## d = numpy.dtype(d) 131 ## if d.kind == "S" or (d.kind == "i" and d.itemsize == "8"): 132 self.values = self.values.tolist()
133
134 -class FileColumnI(AbstractColumn, omero.grid.FileColumn):
135
136 - def __init__(self, name = "Unknown", *args):
137 omero.grid.FileColumn.__init__(self, name, *args) 138 AbstractColumn.__init__(self)
139
140 - def descriptor(self, pos):
141 return tables.Int64Col(pos=pos)
142
143 -class ImageColumnI(AbstractColumn, omero.grid.ImageColumn):
144
145 - def __init__(self, name = "Unknown", *args):
146 omero.grid.ImageColumn.__init__(self, name, *args) 147 AbstractColumn.__init__(self)
148
149 - def descriptor(self, pos):
150 return tables.Int64Col(pos=pos)
151
152 -class WellColumnI(AbstractColumn, omero.grid.WellColumn):
153
154 - def __init__(self, name = "Unknown", *args):
155 omero.grid.WellColumn.__init__(self, name, *args) 156 AbstractColumn.__init__(self)
157
158 - def descriptor(self, pos):
159 return tables.Int64Col(pos=pos)
160
161 -class RoiColumnI(AbstractColumn, omero.grid.RoiColumn):
162
163 - def __init__(self, name = "Unknown", *args):
164 omero.grid.RoiColumn.__init__(self, name, *args) 165 AbstractColumn.__init__(self)
166
167 - def descriptor(self, pos):
168 return tables.Int64Col(pos=pos)
169
170 -class ImageColumnI(AbstractColumn, omero.grid.ImageColumn):
171
172 - def __init__(self, name = "Unknown", *args):
173 omero.grid.ImageColumn.__init__(self, name, *args) 174 AbstractColumn.__init__(self)
175
176 - def descriptor(self, pos):
177 return tables.Int64Col(pos=pos)
178
179 -class BoolColumnI(AbstractColumn, omero.grid.BoolColumn):
180
181 - def __init__(self, name = "Unknown", *args):
182 omero.grid.BoolColumn.__init__(self, name, *args) 183 AbstractColumn.__init__(self)
184
185 - def descriptor(self, pos):
186 return tables.BoolCol(pos=pos)
187
188 -class DoubleColumnI(AbstractColumn, omero.grid.DoubleColumn):
189
190 - def __init__(self, name = "Unknown", *args):
191 omero.grid.DoubleColumn.__init__(self, name, *args) 192 AbstractColumn.__init__(self)
193
194 - def descriptor(self, pos):
195 return tables.Float64Col(pos=pos)
196
197 -class LongColumnI(AbstractColumn, omero.grid.LongColumn):
198
199 - def __init__(self, name = "Unknown", *args):
200 omero.grid.LongColumn.__init__(self, name, *args) 201 AbstractColumn.__init__(self)
202
203 - def descriptor(self, pos):
204 return tables.Int64Col(pos=pos)
205
206 -class StringColumnI(AbstractColumn, omero.grid.StringColumn):
207
208 - def __init__(self, name = "Unknown", *args):
209 omero.grid.StringColumn.__init__(self, name, *args) 210 AbstractColumn.__init__(self)
211
212 - def settable(self, tbl):
213 AbstractColumn.settable(self, tbl) 214 self.size = getattr(tbl.cols, self.name).dtype.itemsize
215
216 - def arrays(self):
217 """ 218 Overriding to correct for size. 219 """ 220 sz = self.size 221 return [numpy.array(self.values, dtype="S%s"%sz)]
222
223 - def descriptor(self, pos):
224 # During initialization, size might be zero 225 # to prevent exceptions we set it to 1 226 if not self.size or self.size < 0: 227 self.size = 1 228 return tables.StringCol(pos=pos, itemsize=self.size)
229
230 -class MaskColumnI(AbstractColumn, omero.grid.MaskColumn):
231
232 - def __init__(self, name = "Unknown", *args):
233 omero.grid.MaskColumn.__init__(self, name, *args) 234 AbstractColumn.__init__(self)
235
236 - def __noneorsame(self, a, b):
237 if a is None: 238 if b is None: 239 return 240 # a not none 241 if b is not None: 242 if len(a) == len(b): 243 return 244 raise omero.ValidationException(None, None, "Columns don't match")
245
246 - def __sanitycheck(self):
247 self.__noneorsame(self.imageId, self.theZ) 248 self.__noneorsame(self.imageId, self.theT) 249 self.__noneorsame(self.imageId, self.x) 250 self.__noneorsame(self.imageId, self.y) 251 self.__noneorsame(self.imageId, self.w) 252 self.__noneorsame(self.imageId, self.h) 253 self.__noneorsame(self.imageId, self.bytes)
254
255 - def descriptor(self, pos):
256 class MaskDescription(tables.IsDescription): 257 _v_pos = pos 258 i = tables.Int64Col(pos=0) 259 z = tables.Int32Col(pos=1) 260 t = tables.Int32Col(pos=2) 261 x = tables.Float64Col(pos=3) 262 y = tables.Float64Col(pos=4) 263 w = tables.Float64Col(pos=5) 264 h = tables.Float64Col(pos=6)
265 return MaskDescription()
266
267 - def names(self):
268 return [x[0] for x in self.recarrtypes]
269
270 - def arrays(self):
271 self.__sanitycheck() 272 a = [ 273 numpy.array(self.imageId, dtype=self.recarrtypes[0][1]), 274 numpy.array(self.theZ, dtype=self.recarrtypes[1][1]), 275 numpy.array(self.theT, dtype=self.recarrtypes[2][1]), 276 numpy.array(self.x, dtype=self.recarrtypes[3][1]), 277 numpy.array(self.y, dtype=self.recarrtypes[4][1]), 278 numpy.array(self.w, dtype=self.recarrtypes[5][1]), 279 numpy.array(self.h, dtype=self.recarrtypes[6][1]), 280 ] 281 return a
282
283 - def getsize(self):
284 self.__sanitycheck() 285 if self.imageId is None: 286 return None 287 else: 288 return len(self.imageId)
289
290 - def setsize(self, size):
291 if size is None: 292 self.imageId = None 293 self.theZ = None 294 self.theT = None 295 self.x = None 296 self.y = None 297 self.w = None 298 self.h = None 299 else: 300 self.imageId = numpy.zeroes(size, dtype = self.recarrtypes[0][1]) 301 self.theZ = numpy.zeroes(size, dtype = self.recarrtypes[1][1]) 302 self.theT = numpy.zeroes(size, dtype = self.recarrtypes[2][1]) 303 self.x = numpy.zeroes(size, dtype = self.recarrtypes[3][1]) 304 self.y = numpy.zeroes(size, dtype = self.recarrtypes[4][1]) 305 self.w = numpy.zeroes(size, dtype = self.recarrtypes[5][1]) 306 self.h = numpy.zeroes(size, dtype = self.recarrtypes[6][1])
307
308 - def readCoordinates(self, tbl, rowNumbers):
309 self.__sanitycheck() 310 AbstractColumn.readCoordinates(self, tbl, rowNumbers) # calls fromrows 311 masks = self._getmasks(tbl) 312 if rowNumbers is None or len(rowNumbers) == 0: 313 rowNumbers = range(masks.nrows) 314 self.getbytes(masks, rowNumbers)
315
316 - def read(self, tbl, start, stop):
317 self.__sanitycheck() 318 AbstractColumn.read(self, tbl, start, stop) # calls fromrows 319 masks = self._getmasks(tbl) 320 rowNumbers = range(start, stop) 321 self.getbytes(masks, rowNumbers)
322
323 - def getbytes(self, masks, rowNumbers):
324 self.bytes = [] 325 for idx in rowNumbers: 326 self.bytes.append(masks[idx].tolist())
327
328 - def fromrows(self, all_rows):
329 rows = all_rows[self.name] 330 # WORKAROUND: http://www.zeroc.com/forums/bug-reports/4165-icepy-can-not-handle-buffers-longs-i64.html#post20468 331 self.imageId = rows["i"].tolist() 332 self.theZ = rows["z"].tolist() # ticket:1665 333 self.theT = rows["t"].tolist() # ticket:1665 334 self.x = rows["x"] 335 self.y = rows["y"] 336 self.w = rows["w"] 337 self.h = rows["h"]
338
339 - def append(self, tbl):
340 self.__sanitycheck() 341 masks = self._getmasks(tbl) 342 for x in self.bytes: 343 masks.append(numpy.fromstring(x, count=len(x), dtype=tables.UInt8Atom()))
344
345 - def _getmasks(self, tbl):
346 n = tbl._v_name 347 f = tbl._v_file 348 p = tbl._v_parent 349 # http://www.zeroc.com/doc/Ice-3.3.1/manual/Slice.5.8.html#200 350 # Ice::Byte can be -128 to 127 OR 0 to 255, but using UInt8 for the moment 351 try: 352 masks = getattr(p, "%s_masks" % n) 353 except tables.NoSuchNodeError: 354 masks = f.createVLArray(p, "%s_masks" % n, tables.UInt8Atom()) 355 return masks
356 357 # Helpers 358 # ======================================================================== 359 360 # Conversion classes are for omero.model <--> ome.model only (no python) 361
362 -class ObjectFactory(Ice.ObjectFactory):
363
364 - def __init__(self, cls, f):
365 self.id = cls.ice_staticId() 366 self.f = f
367
368 - def create(self, string):
369 return self.f()
370
371 - def destroy(self):
372 pass
373
374 - def register(self, ic):
375 ic.addObjectFactory(self, self.id)
376 377 378 # Object factories 379 # ========================================================================= 380 381 ObjectFactories = { 382 FileColumnI: ObjectFactory(FileColumnI, lambda: FileColumnI()), 383 ImageColumnI: ObjectFactory(ImageColumnI, lambda: ImageColumnI()), 384 RoiColumnI: ObjectFactory(RoiColumnI, lambda: RoiColumnI()), 385 WellColumnI: ObjectFactory(WellColumnI, lambda: WellColumnI()), 386 BoolColumnI: ObjectFactory(BoolColumnI, lambda: BoolColumnI()), 387 DoubleColumnI: ObjectFactory(DoubleColumnI, lambda: DoubleColumnI()), 388 LongColumnI: ObjectFactory(LongColumnI, lambda: LongColumnI()), 389 StringColumnI: ObjectFactory(StringColumnI, lambda: StringColumnI()), 390 MaskColumnI: ObjectFactory(MaskColumnI, lambda: MaskColumnI()) 391 } 392