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

Source Code for Module omero.util.tiles

  1  #!/usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3  """ 
  4   
  5     Copyright 2011 Glencoe Software, Inc. All rights reserved. 
  6     Use is subject to license terms supplied in LICENSE.txt 
  7   
  8  """ 
  9   
 10   
11 -class TileLoopIteration(object):
12 """ 13 "Interface" which must be passed to forEachTile 14 """
15 - def run(self, rps, z, c, t, x, y, tileWidth, tileHeight, tileCount):
16 raise NotImplemented()
17 18
19 -class TileData(object):
20 """ 21 "Interface" which must be returned by concrete TileLoop 22 implementations. 23 """ 24
25 - def getTile(self, z, c, t, x, y, w, h):
26 """ 27 z: int 28 c: int 29 t: int 30 y: int 31 w: int 32 h: int 33 return: byte[] 34 """ 35 raise NotImplementedError()
36
37 - def setTile(self, buffer, z, c, t, x, y, w, h):
38 """ 39 buffer: byte[] 40 z: int 41 c: int 42 t: int 43 y: int 44 w: int 45 h: int 46 """ 47 raise NotImplementedError();
48
49 - def close(self):
50 raise NotImplementedError();
51 52
53 -class TileLoop(object):
54
55 - def createData(self):
56 """ 57 Subclasses must provide a fresh instance of {@link TileData}. 58 The instance will be closed after the run of forEachTile. 59 60 returns: TileData 61 """ 62 raise NotImplementedError()
63
64 - def forEachTile(self, sizeX, sizeY, sizeZ, sizeC, sizeT,\ 65 tileWidth, tileHeight, iteration):
66 """ 67 Iterates over every tile in a given pixel based on the 68 over arching dimensions and a requested maximum tile width and height. 69 @param iteration Invoker to call for each tile. 70 @param pixel Pixel instance 71 @param tileWidth <b>Maximum</b> width of the tile requested. The tile 72 request itself will be smaller than the original tile width requested if 73 <code>x + tileWidth > sizeX</code>. 74 @param tileHeight <b>Maximum</b> height of the tile requested. The tile 75 request itself will be smaller if <code>y + tileHeight > sizeY</code>. 76 @return The total number of tiles iterated over. 77 """ 78 79 data = self.createData() 80 81 try: 82 tileCount = 0 83 for t in range(0, sizeT): 84 85 for c in range(0, sizeC): 86 87 for z in range(0, sizeZ): 88 89 for tileOffsetY in range(0, ((sizeY + tileHeight - 1) / tileHeight)): 90 91 for tileOffsetX in range(0, ((sizeX + tileWidth - 1) / tileWidth)): 92 93 x = tileOffsetX * tileWidth 94 y = tileOffsetY * tileHeight 95 w = tileWidth 96 97 if (w + x > sizeX): 98 w = sizeX - x; 99 100 h = tileHeight 101 if (h + y > sizeY): 102 h = sizeY - y 103 104 iteration.run(data, z, c, t, x, y, w, h, tileCount) 105 tileCount += 1 106 return tileCount; 107 108 finally: 109 data.close()
110 111
112 -class RPSTileData(TileData):
113 """ 114 """
115 - def __init__(self, loop, rps):
116 self.loop = loop 117 self.rps = rps 118 self.pixels = None
119
120 - def getTile(self, z, c, t, x, y, w, h):
121 return self.rps.getTile(z, c, t, x, y, w, h)
122
123 - def setTile(self, buffer, z, c, t, x, y, w, h):
124 self.rps.setTile(buffer, z, c, t, x, y, w, h)
125
126 - def close(self):
127 pixels = self.rps.save() 128 self.loop.setPixels(pixels) 129 self.rps.close()
130 131
132 -class RPSTileLoop(TileLoop):
133
134 - def __init__(self, session, pixels):
135 self.session = session 136 self.pixels = pixels
137
138 - def getSession(self):
139 return self.session
140
141 - def getPixels(self):
142 """ 143 After saving the binary data, the update event of the 144 {@link Pixels} instance will be updated and therefore 145 need to be reloaded. As a convenience the returned 146 value is accessible here. 147 """ 148 return self.pixels
149
150 - def setPixels(self, pixels):
151 """ 152 Used by RPSTileData to set a reloaded Pixels instance 153 for client use. 154 """ 155 self.pixels = pixels
156
157 - def createData(self):
158 rps = self.getSession().createRawPixelsStore() 159 data = RPSTileData(self, rps) 160 rps.setPixelsId(self.getPixels().getId().getValue(), False) # 'false' is ignored here. 161 return data
162
163 - def forEachTile(self, tileWidth, tileHeight, iteration):
164 """ 165 Iterates over every tile in a given pixel based on the 166 over arching dimensions and a requested maximum tile width and height. 167 @param iteration Invoker to call for each tile. 168 @param pixel Pixel instance 169 @param tileWidth <b>Maximum</b> width of the tile requested. The tile 170 request itself will be smaller than the original tile width requested if 171 <code>x + tileWidth > sizeX</code>. 172 @param tileHeight <b>Maximum</b> height of the tile requested. The tile 173 request itself will be smaller if <code>y + tileHeight > sizeY</code>. 174 @return The total number of tiles iterated over. 175 """ 176 177 if self.pixels is None or self.pixels.id is None: 178 raise omero.ClientError("pixels instance must be managed!") 179 elif not self.pixels.loaded: 180 try: 181 self.pixels = getSession().getPixelsService().retrievePixDescription(self.pixels.id.val) 182 except: 183 raise omero.ClientError("Failed to load %s\n%s" % (self.pixels.id.val, e)) 184 185 sizeX = self.pixels.getSizeX().getValue() 186 sizeY = self.pixels.getSizeY().getValue() 187 sizeZ = self.pixels.getSizeZ().getValue() 188 sizeC = self.pixels.getSizeC().getValue() 189 sizeT = self.pixels.getSizeT().getValue() 190 191 return TileLoop.forEachTile(self, sizeX, sizeY, sizeZ, sizeC, sizeT, tileWidth, tileHeight, iteration);
192