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

Source Code for Module omero.util.tiles

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