def ingestImageStack(self): """Ingest a TIF image stack""" # Load a database with closing(ocpcaproj.OCPCAProjectsDB()) as projdb: proj = projdb.loadToken(self.token) with closing(ocpcadb.OCPCADB(proj)) as db: ch = proj.getChannelObj(self.channel) # get the dataset configuration [[ximagesz, yimagesz, zimagesz], (starttime, endtime)] = proj.datasetcfg.imageSize(self.resolution) [xcubedim, ycubedim, zcubedim ] = cubedim = proj.datasetcfg.getCubeDims()[self.resolution] [xoffset, yoffset, zoffset] = proj.datasetcfg.getOffset()[self.resolution] if ch.getChannelType() in TIMESERIES_CHANNELS and ( starttime == 0 and endtime == 0): logger.error("Timeseries Data cannot have timerange (0,0)") raise OCPCAError("Timeseries Data cannot have timerange (0,0)") # Get a list of the files in the directories for timestamp in range(starttime, endtime + 1): for slice_number in range(zoffset, zimagesz, zcubedim): slab = np.zeros([zcubedim, yimagesz, ximagesz], dtype=OCP_dtypetonp.get(ch.getDataType())) # fetch 16 slices at a time if ch.getChannelType() in TIMESERIES_CHANNELS: time_value = timestamp else: time_value = None self.fetchData( range(slice_number, slice_number + zcubedim) if slice_number + zcubedim <= zimagesz else range(slice_number, zimagesz), time_value=time_value) for b in range(zcubedim): if (slice_number + b < zimagesz): try: # reading the raw data file_name = "{}{}".format( self.path, self.generateFileName(slice_number + b)) print "Open filename {}".format(file_name) logger.info( "Open filename {}".format(file_name)) if ch.getDataType() in [ UINT8, UINT16 ] and ch.getChannelType( ) in IMAGE_CHANNELS + TIMESERIES_CHANNELS: image_data = np.asarray( Image.open(file_name, 'r')) slab[b, :, :] = image_data elif ch.getDataType() in [ UINT32 ] and ch.getChannelType( ) in IMAGE_CHANNELS + TIMESERIES_CHANNELS: image_data = np.asarray( Image.open(file_name, 'r').convert('RGBA')) slab[b, :, :] = np.left_shift( image_data[:, :, 3], 24, dtype=np.uint32) | np.left_shift( image_data[:, :, 2], 16, dtype=np.uint32) | np.left_shift( image_data[:, :, 1], 8, dtype=np.uint32) | np.uint32( image_data[:, :, 0]) elif ch.getChannelType( ) in ANNOTATION_CHANNELS: image_data = np.asarray( Image.open(file_name, 'r')) slab[b, :, :] = image_data else: logger.error("Cannot ingest this data yet") raise OCPCAError( "Cannot ingest this data yet") except IOError, e: logger.warning("IOError {}.".format(e)) slab[b, :, :] = np.zeros((yimagesz, ximagesz), dtype=np.uint32) for y in range(0, yimagesz + 1, ycubedim): for x in range(0, ximagesz + 1, xcubedim): # Getting a Cube id and ingesting the data one cube at a time zidx = ocplib.XYZMorton([ x / xcubedim, y / ycubedim, (slice_number - zoffset) / zcubedim ]) cube = Cube.getCube(cubedim, ch.getChannelType(), ch.getDataType()) cube.zeros() xmin, ymin = x, y xmax = min(ximagesz, x + xcubedim) ymax = min(yimagesz, y + ycubedim) zmin = 0 zmax = min(slice_number + zcubedim, zimagesz + 1) cube.data[0:zmax - zmin, 0:ymax - ymin, 0:xmax - xmin] = slab[zmin:zmax, ymin:ymax, xmin:xmax] if cube.isNotZeros(): if ch.getChannelType() in IMAGE_CHANNELS: db.putCube(ch, zidx, self.resolution, cube, update=False) elif ch.getChannelType( ) in TIMESERIES_CHANNELS: db.putTimeCube(ch, zidx, timestamp, self.resolution, cube, update=False) elif ch.getChannelType( ) in ANNOTATION_CHANNELS: corner = map(sub, [x, y, slice_number], [xoffset, yoffset, zoffset]) db.annotateDense(ch, corner, self.resolution, cube.data, 'O') else: logger.error( "Channel type {} not supported".format( ch.getChannelType())) raise OCPCAError( "Channel type {} not supported".format( ch.getChannelType())) # clean up the slices fetched self.cleanData( range(slice_number, slice_number + zcubedim) if slice_number + zcubedim <= zimagesz else range(slice_number, zimagesz))
def buildImageStack(proj, ch, res=None): """Build the hierarchy of images""" with closing(ocpcadb.OCPCADB(proj)) as db: # pick a resolution if res is None: res = 1 high_res = proj.datasetcfg.scalinglevels scaling = proj.datasetcfg.scalingoption for cur_res in range (res, high_res+1): # Get the source database sizes [[ximagesz, yimagesz, zimagesz], timerange] = proj.datasetcfg.imageSize(cur_res) [xcubedim, ycubedim, zcubedim] = cubedim = proj.datasetcfg.getCubeDims()[cur_res] if scaling == ZSLICES: (xscale, yscale, zscale) = (2, 2, 1) elif scaling == ISOTROPIC: (xscale, yscale, zscale) = (2, 2, 2) else: logger.error("Invalid scaling option in project = {}".format(scaling)) raise OCPCAError("Invalid scaling option in project = {}".format(scaling)) biggercubedim = [xcubedim*xscale,ycubedim*yscale,zcubedim*zscale] # Set the limits for iteration on the number of cubes in each dimension xlimit = (ximagesz-1) / xcubedim + 1 ylimit = (yimagesz-1) / ycubedim + 1 zlimit = (zimagesz-1) / zcubedim + 1 # Iterating over time for ts in range(timerange[0], timerange[1]+1, 1): # Iterating over zslice for z in range(zlimit): # Iterating over y for y in range(ylimit): # Iterating over x for x in range(xlimit): # cutout the data at the resolution if ch.getChannelType() not in TIMESERIES_CHANNELS: olddata = db.cutout(ch, [x*xscale*xcubedim, y*yscale*ycubedim, z*zscale*zcubedim ], biggercubedim, cur_res-1).data else: olddata = db.timecutout(ch, [x*xscale*xcubedim, y*yscale*ycubedim, z*zscale*zcubedim ], biggercubedim, cur_res-1, [ts,ts+1]).data olddata = olddata[0,:,:,:] #olddata target array for the new data (z,y,x) order newdata = np.zeros([zcubedim,ycubedim,xcubedim], dtype=OCP_dtypetonp.get(ch.getDataType())) for sl in range(zcubedim): if scaling == ZSLICES: data = olddata[sl,:,:] elif scaling == ISOTROPIC: data = ocplib.isotropicBuild_ctype(olddata[sl*2,:,:], olddata[sl*2+1,:,:]) # Convert each slice to an image # 8-bit int option if olddata.dtype == np.uint8: slimage = Image.frombuffer('L', (xcubedim*2,ycubedim*2), data.flatten(), 'raw', 'L', 0, 1) # 16-bit int option elif olddata.dtype == np.uint16: slimage = Image.frombuffer('I;16', (xcubedim*2,ycubedim*2), data.flatten(), 'raw', 'I;16', 0, 1) # 32-bit float option elif olddata.dtype == np.float32: slimage = Image.frombuffer ( 'F', (xcubedim*2,ycubedim*2), data.flatten(), 'raw', 'F', 0, 1 ) # 32 bit RGBA data elif olddata.dtype == np.uint32: slimage = Image.fromarray( data, "RGBA" ) # KL TODO Add support for 32bit and 64bit RGBA data # Resize the image and put in the new cube array if olddata.dtype != np.uint32: newdata[sl, :, :] = np.asarray(slimage.resize([xcubedim,ycubedim])) else: tempdata = np.asarray(slimage.resize([xcubedim, ycubedim])) newdata[sl,:,:] = np.left_shift(tempdata[:,:,3], 24, dtype=np.uint32) | np.left_shift(tempdata[:,:,2], 16, dtype=np.uint32) | np.left_shift(tempdata[:,:,1], 8, dtype=np.uint32) | np.uint32(tempdata[:,:,0]) zidx = ocplib.XYZMorton ([x,y,z]) cube = Cube.getCube(cubedim, ch.getChannelType(), ch.getDataType()) cube.zeros() cube.data = newdata if ch.getChannelType() not in TIMESERIES_CHANNELS: db.putCube(ch, zidx, cur_res, cube, update=True) else: db.putTimeCube(ch, zidx, ts, cur_res, cube, update=False)
def ingestImageStack(self): """Ingest a TIF image stack""" # Load a database with closing(ocpcaproj.OCPCAProjectsDB()) as projdb: proj = projdb.loadToken(self.token) with closing(ocpcadb.OCPCADB(proj)) as db: ch = proj.getChannelObj(self.channel) # get the dataset configuration [[ximagesz, yimagesz, zimagesz], (starttime, endtime)] = proj.datasetcfg.imageSize(self.resolution) [xcubedim, ycubedim, zcubedim ] = cubedim = proj.datasetcfg.getCubeDims()[self.resolution] [xoffset, yoffset, zoffset] = proj.datasetcfg.getOffset()[self.resolution] if ch.getChannelType() in TIMESERIES_CHANNELS and ( starttime == 0 and endtime == 0): print "Timeseries Data cannot have timerange (0,0)" raise # Get a list of the files in the directories for timestamp in range(starttime, endtime + 1): for slice_number in range(zoffset, zimagesz + 1, zcubedim): slab = np.zeros([zcubedim, yimagesz, ximagesz], dtype=OCP_dtypetonp.get(ch.getDataType())) # fetch 16 slices at a time if ch.getChannelType() in TIMESERIES_CHANNELS: time_value = timestamp else: time_value = None self.fetchData( range(slice_number, slice_number + zcubedim) if slice_number + zcubedim <= zimagesz else range(slice_number, zimagesz), time_value=time_value) for b in range(zcubedim): if (slice_number + b <= zimagesz): try: # reading the raw data file_name = "{}{}".format( self.path, self.generateFileName(slice_number + b)) print "Open filename {}".format(file_name) slab[b, :, :] = np.asarray( Image.open(file_name, 'r')) except IOError, e: print e slab[b, :, :] = np.zeros((yimagesz, ximagesz), dtype=np.uint32) for y in range(0, yimagesz + 1, ycubedim): for x in range(0, ximagesz + 1, xcubedim): # Getting a Cube id and ingesting the data one cube at a time zidx = ocplib.XYZMorton([ x / xcubedim, y / ycubedim, (slice_number - zoffset) / zcubedim ]) cube = Cube.getCube(cubedim, ch.getChannelType(), ch.getDataType()) cube.zeros() xmin, ymin = x, y xmax = min(ximagesz, x + xcubedim) ymax = min(yimagesz, y + ycubedim) zmin = 0 zmax = min(slice_number + zcubedim, zimagesz + 1) cube.data[0:zmax - zmin, 0:ymax - ymin, 0:xmax - xmin] = slab[zmin:zmax, ymin:ymax, xmin:xmax] if cube.isNotZeros(): if ch.getChannelType( ) not in TIMESERIES_CHANNELS: db.putCube(ch, zidx, self.resolution, cube, update=True) else: db.putTimeCube(ch, zidx, timestamp, self.resolution, cube, update=True) # clean up the slices fetched self.cleanData( range(slice_number, slice_number + zcubedim) if slice_number + zcubedim <= zimagesz else range(slice_number, zimagesz))
def buildAnnoStack ( proj, ch, res=None ): """Build the hierarchy for annotations""" with closing(ocpcadb.OCPCADB (proj)) as db: # pick a resolution if res is None: res = 1 high_res = proj.datasetcfg.scalinglevels scaling = proj.datasetcfg.scalingoption for cur_res in range(res, high_res+1): # Get the source database sizes [[ximagesz, yimagesz, zimagesz], timerange] = proj.datasetcfg.imageSize(cur_res-1) [xcubedim, ycubedim, zcubedim] = cubedim = proj.datasetcfg.getCubeDims()[cur_res-1] # Set the limits for iteration on the number of cubes in each dimension xlimit = (ximagesz-1) / xcubedim + 1 ylimit = (yimagesz-1) / ycubedim + 1 zlimit = (zimagesz-1) / zcubedim + 1 # Choose constants that work for all resolutions. recall that cube size changes from 128x128x16 to 64*64*64 if scaling == ZSLICES: outdata = np.zeros ( [ zcubedim*4, ycubedim*2, xcubedim*2 ], dtype=OCP_dtypetonp.get(ch.getDataType())) elif scaling == ISOTROPIC: outdata = np.zeros ( [ zcubedim*2, ycubedim*2, xcubedim*2 ], dtype=OCP_dtypetonp.get(ch.getDataType())) else: logger.error ( "Invalid scaling option in project = {}".format(scaling) ) raise OCPCAError ( "Invalid scaling option in project = {}".format(scaling)) # Round up to the top of the range lastzindex = (ocplib.XYZMorton([xlimit,ylimit,zlimit])/64+1)*64 # Iterate over the cubes in morton order for mortonidx in range(0, lastzindex, 64): # call the range query cuboids = db.getCubes(ch, range(mortonidx,mortonidx+64), cur_res-1) cube = Cube.getCube(cubedim, ch.getChannelType(), ch.getDataType()) # get the first cube for idx, datastring in cuboids: xyz = ocplib.MortonXYZ(idx) cube.fromNPZ(datastring) if scaling == ZSLICES: # Compute the offset in the output data cube # we are placing 4x4x4 input blocks into a 2x2x4 cube offset = [(xyz[0]%4)*(xcubedim/2), (xyz[1]%4)*(ycubedim/2), (xyz[2]%4)*zcubedim] # add the contribution of the cube in the hierarchy ocplib.addDataToZSliceStack_ctype(cube, outdata, offset) elif scaling == ISOTROPIC: # Compute the offset in the output data cube # we are placing 4x4x4 input blocks into a 2x2x2 cube offset = [(xyz[0]%4)*(xcubedim/2), (xyz[1]%4)*(ycubedim/2), (xyz[2]%4)*(zcubedim/2)] # use python version for debugging ocplib.addDataToIsotropicStack_ctype(cube, outdata, offset) # Get the base location of this batch xyzout = ocplib.MortonXYZ (mortonidx) # adjust to output corner for scale. if scaling == ZSLICES: outcorner = [ xyzout[0]*xcubedim/2, xyzout[1]*ycubedim/2, xyzout[2]*zcubedim ] elif scaling == ISOTROPIC: outcorner = [ xyzout[0]*xcubedim/2, xyzout[1]*ycubedim/2, xyzout[2]*zcubedim/2 ] # Data stored in z,y,x order dims in x,y,z outdim = outdata.shape[::-1] # Preserve annotations made at the specified level # KL check that the P option preserves annotations? RB changed from O db.annotateDense(ch, outcorner, cur_res, outdata, 'O') db.conn.commit() # zero the output buffer outdata = np.zeros ([zcubedim*4, ycubedim*2, xcubedim*2], dtype=OCP_dtypetonp.get(ch.getDataType()))
def ingestImageStack(self): """Ingest a TIF image stack""" # Load a database with closing (ocpcaproj.OCPCAProjectsDB()) as projdb: proj = projdb.loadToken(self.token) with closing (ocpcadb.OCPCADB(proj)) as db: ch = proj.getChannelObj(self.channel) # get the dataset configuration [[ximagesz, yimagesz, zimagesz],(starttime,endtime)] = proj.datasetcfg.imageSize(self.resolution) [xcubedim, ycubedim, zcubedim] = cubedim = proj.datasetcfg.getCubeDims()[self.resolution] [xoffset, yoffset, zoffset] = proj.datasetcfg.getOffset()[self.resolution] if ch.getChannelType() in TIMESERIES_CHANNELS and (starttime == 0 and endtime == 0): logger.error("Timeseries Data cannot have timerange (0,0)") raise OCPCAError("Timeseries Data cannot have timerange (0,0)") # Get a list of the files in the directories for timestamp in range(starttime, endtime+1): for slice_number in range (zoffset, zimagesz, zcubedim): slab = np.zeros([zcubedim, yimagesz, ximagesz ], dtype=OCP_dtypetonp.get(ch.getDataType())) # fetch 16 slices at a time if ch.getChannelType() in TIMESERIES_CHANNELS: time_value = timestamp else: time_value = None self.fetchData(range(slice_number,slice_number+zcubedim) if slice_number+zcubedim<=zimagesz else range(slice_number,zimagesz), time_value=time_value) for b in range(zcubedim): if (slice_number + b < zimagesz): try: # reading the raw data file_name = "{}{}".format(self.path, self.generateFileName(slice_number+b)) print "Open filename {}".format(file_name) logger.info("Open filename {}".format(file_name)) if ch.getDataType() in [UINT8, UINT16] and ch.getChannelType() in IMAGE_CHANNELS + TIMESERIES_CHANNELS: image_data = np.asarray(Image.open(file_name, 'r')) slab[b,:,:] = image_data elif ch.getDataType() in [UINT32] and ch.getChannelType() in IMAGE_CHANNELS + TIMESERIES_CHANNELS: image_data = np.asarray(Image.open(file_name, 'r').convert('RGBA')) slab[b,:,:] = np.left_shift(image_data[:,:,3], 24, dtype=np.uint32) | np.left_shift(image_data[:,:,2], 16, dtype=np.uint32) | np.left_shift(image_data[:,:,1], 8, dtype=np.uint32) | np.uint32(image_data[:,:,0]) elif ch.getChannelType() in ANNOTATION_CHANNELS: image_data = np.asarray(Image.open(file_name, 'r')) slab[b,:,:] = image_data else: logger.error("Cannot ingest this data yet") raise OCPCAError("Cannot ingest this data yet") except IOError, e: logger.warning("IOError {}.".format(e)) slab[b,:,:] = np.zeros((yimagesz, ximagesz), dtype=np.uint32) for y in range ( 0, yimagesz+1, ycubedim ): for x in range ( 0, ximagesz+1, xcubedim ): # Getting a Cube id and ingesting the data one cube at a time zidx = ocplib.XYZMorton ( [x/xcubedim, y/ycubedim, (slice_number-zoffset)/zcubedim] ) cube = Cube.getCube(cubedim, ch.getChannelType(), ch.getDataType()) cube.zeros() xmin,ymin = x,y xmax = min ( ximagesz, x+xcubedim ) ymax = min ( yimagesz, y+ycubedim ) zmin = 0 zmax = min(slice_number+zcubedim, zimagesz+1) cube.data[0:zmax-zmin,0:ymax-ymin,0:xmax-xmin] = slab[zmin:zmax, ymin:ymax, xmin:xmax] if cube.isNotZeros(): if ch.getChannelType() in IMAGE_CHANNELS: db.putCube(ch, zidx, self.resolution, cube, update=True) elif ch.getChannelType() in TIMESERIES_CHANNELS: db.putTimeCube(ch, zidx, timestamp, self.resolution, cube, update=True) elif ch.getChannelType() in ANNOTATION_CHANNELS: corner = map(sub, [x,y,slice_number], [xoffset,yoffset,zoffset]) db.annotateDense(ch, corner, self.resolution, cube.data, 'O') else: logger.error("Channel type {} not supported".format(ch.getChannelType())) raise OCPCAError("Channel type {} not supported".format(ch.getChannelType())) # clean up the slices fetched self.cleanData(range(slice_number,slice_number+zcubedim) if slice_number+zcubedim<=zimagesz else range(slice_number,zimagesz))
def ingestImageStack(self): """Ingest a TIF image stack""" # Load a database with closing (ocpcaproj.OCPCAProjectsDB()) as projdb: proj = projdb.loadToken(self.token) with closing (ocpcadb.OCPCADB(proj)) as db: ch = proj.getChannelObj(self.channel) # get the dataset configuration [[ximagesz, yimagesz, zimagesz],(starttime,endtime)] = proj.datasetcfg.imageSize(self.resolution) [xcubedim, ycubedim, zcubedim] = cubedim = proj.datasetcfg.getCubeDims()[self.resolution] [xoffset, yoffset, zoffset] = proj.datasetcfg.getOffset()[self.resolution] if ch.getChannelType() in TIMESERIES_CHANNELS and (starttime == 0 and endtime == 0): print "Timeseries Data cannot have timerange (0,0)" raise # Get a list of the files in the directories for timestamp in range(starttime, endtime+1): for slice_number in range (zoffset, zimagesz+1, zcubedim): slab = np.zeros([zcubedim, yimagesz, ximagesz ], dtype=OCP_dtypetonp.get(ch.getDataType())) # fetch 16 slices at a time if ch.getChannelType() in TIMESERIES_CHANNELS: time_value = timestamp else: time_value = None self.fetchData(range(slice_number,slice_number+zcubedim) if slice_number+zcubedim<=zimagesz else range(slice_number,zimagesz), time_value=time_value) for b in range(zcubedim): if (slice_number + b <= zimagesz): try: # reading the raw data file_name = "{}{}".format(self.path, self.generateFileName(slice_number+b)) print "Open filename {}".format(file_name) slab[b,:,:] = np.asarray(Image.open(file_name, 'r')) except IOError, e: print e slab[b,:,:] = np.zeros((yimagesz, ximagesz), dtype=np.uint32) for y in range ( 0, yimagesz+1, ycubedim ): for x in range ( 0, ximagesz+1, xcubedim ): # Getting a Cube id and ingesting the data one cube at a time zidx = ocplib.XYZMorton ( [x/xcubedim, y/ycubedim, (slice_number-zoffset)/zcubedim] ) cube = Cube.getCube(cubedim, ch.getChannelType(), ch.getDataType()) cube.zeros() xmin,ymin = x,y xmax = min ( ximagesz, x+xcubedim ) ymax = min ( yimagesz, y+ycubedim ) zmin = 0 zmax = min(slice_number+zcubedim, zimagesz+1) cube.data[0:zmax-zmin,0:ymax-ymin,0:xmax-xmin] = slab[zmin:zmax, ymin:ymax, xmin:xmax] if cube.isNotZeros(): if ch.getChannelType() not in TIMESERIES_CHANNELS: db.putCube(ch, zidx, self.resolution, cube, update=True) else: db.putTimeCube(ch, zidx, timestamp, self.resolution, cube, update=True) # clean up the slices fetched self.cleanData(range(slice_number,slice_number+zcubedim) if slice_number+zcubedim<=zimagesz else range(slice_number,zimagesz))
def buildImageStack(proj, ch, res=None): """Build the hierarchy of images""" with closing(ocpcadb.OCPCADB(proj)) as db: # pick a resolution if res is None: res = 1 high_res = proj.datasetcfg.scalinglevels scaling = proj.datasetcfg.scalingoption for cur_res in range(res, high_res + 1): # Get the source database sizes [[ximagesz, yimagesz, zimagesz], timerange] = proj.datasetcfg.imageSize(cur_res) [xcubedim, ycubedim, zcubedim] = cubedim = proj.datasetcfg.getCubeDims()[cur_res] if scaling == ZSLICES: (xscale, yscale, zscale) = (2, 2, 1) elif scaling == ISOTROPIC: (xscale, yscale, zscale) = (2, 2, 2) else: logger.error( "Invalid scaling option in project = {}".format(scaling)) raise OCPCAError( "Invalid scaling option in project = {}".format(scaling)) biggercubedim = [ xcubedim * xscale, ycubedim * yscale, zcubedim * zscale ] # Set the limits for iteration on the number of cubes in each dimension xlimit = (ximagesz - 1) / xcubedim + 1 ylimit = (yimagesz - 1) / ycubedim + 1 zlimit = (zimagesz - 1) / zcubedim + 1 # Iterating over time for ts in range(timerange[0], timerange[1] + 1, 1): # Iterating over zslice for z in range(zlimit): # Iterating over y for y in range(ylimit): # Iterating over x for x in range(xlimit): # cutout the data at the resolution if ch.getChannelType() not in TIMESERIES_CHANNELS: olddata = db.cutout(ch, [ x * xscale * xcubedim, y * yscale * ycubedim, z * zscale * zcubedim ], biggercubedim, cur_res - 1).data else: olddata = db.timecutout( ch, [ x * xscale * xcubedim, y * yscale * ycubedim, z * zscale * zcubedim ], biggercubedim, cur_res - 1, [ts, ts + 1]).data olddata = olddata[0, :, :, :] #olddata target array for the new data (z,y,x) order newdata = np.zeros([zcubedim, ycubedim, xcubedim], dtype=OCP_dtypetonp.get( ch.getDataType())) for sl in range(zcubedim): if scaling == ZSLICES: data = olddata[sl, :, :] elif scaling == ISOTROPIC: data = ocplib.isotropicBuild_ctype( olddata[sl * 2, :, :], olddata[sl * 2 + 1, :, :]) # Convert each slice to an image # 8-bit int option if olddata.dtype == np.uint8: slimage = Image.frombuffer( 'L', (xcubedim * 2, ycubedim * 2), data.flatten(), 'raw', 'L', 0, 1) # 16-bit int option elif olddata.dtype == np.uint16: slimage = Image.frombuffer( 'I;16', (xcubedim * 2, ycubedim * 2), data.flatten(), 'raw', 'I;16', 0, 1) # 32-bit float option elif olddata.dtype == np.float32: slimage = Image.frombuffer( 'F', (xcubedim * 2, ycubedim * 2), data.flatten(), 'raw', 'F', 0, 1) # 32 bit RGBA data elif olddata.dtype == np.uint32: slimage = Image.fromarray(data, "RGBA") # KL TODO Add support for 32bit and 64bit RGBA data # Resize the image and put in the new cube array if olddata.dtype != np.uint32: newdata[sl, :, :] = np.asarray( slimage.resize([xcubedim, ycubedim])) else: tempdata = np.asarray( slimage.resize([xcubedim, ycubedim])) newdata[sl, :, :] = np.left_shift( tempdata[:, :, 3], 24, dtype=np.uint32) | np.left_shift( tempdata[:, :, 2], 16, dtype=np.uint32) | np.left_shift( tempdata[:, :, 1], 8, dtype=np.uint32) | np.uint32( tempdata[:, :, 0]) zidx = ocplib.XYZMorton([x, y, z]) cube = Cube.getCube(cubedim, ch.getChannelType(), ch.getDataType()) cube.zeros() cube.data = newdata if ch.getChannelType() not in TIMESERIES_CHANNELS: db.putCube(ch, zidx, cur_res, cube, update=True) else: db.putTimeCube(ch, zidx, ts, cur_res, cube, update=False)
def buildAnnoStack(proj, ch, res=None): """Build the hierarchy for annotations""" with closing(ocpcadb.OCPCADB(proj)) as db: # pick a resolution if res is None: res = 1 high_res = proj.datasetcfg.scalinglevels scaling = proj.datasetcfg.scalingoption for cur_res in range(res, high_res + 1): # Get the source database sizes [[ximagesz, yimagesz, zimagesz], timerange] = proj.datasetcfg.imageSize(cur_res - 1) [xcubedim, ycubedim, zcubedim] = cubedim = proj.datasetcfg.getCubeDims()[cur_res - 1] # Set the limits for iteration on the number of cubes in each dimension xlimit = (ximagesz - 1) / xcubedim + 1 ylimit = (yimagesz - 1) / ycubedim + 1 zlimit = (zimagesz - 1) / zcubedim + 1 # Choose constants that work for all resolutions. recall that cube size changes from 128x128x16 to 64*64*64 if scaling == ZSLICES: outdata = np.zeros([zcubedim * 4, ycubedim * 2, xcubedim * 2], dtype=OCP_dtypetonp.get(ch.getDataType())) elif scaling == ISOTROPIC: outdata = np.zeros([zcubedim * 2, ycubedim * 2, xcubedim * 2], dtype=OCP_dtypetonp.get(ch.getDataType())) else: logger.error( "Invalid scaling option in project = {}".format(scaling)) raise OCPCAError( "Invalid scaling option in project = {}".format(scaling)) # Round up to the top of the range lastzindex = (ocplib.XYZMorton([xlimit, ylimit, zlimit]) / 64 + 1) * 64 # Iterate over the cubes in morton order for mortonidx in range(0, lastzindex, 64): # call the range query cuboids = db.getCubes(ch, range(mortonidx, mortonidx + 64), cur_res - 1) cube = Cube.getCube(cubedim, ch.getChannelType(), ch.getDataType()) # get the first cube for idx, datastring in cuboids: xyz = ocplib.MortonXYZ(idx) cube.fromNPZ(datastring) if scaling == ZSLICES: # Compute the offset in the output data cube # we are placing 4x4x4 input blocks into a 2x2x4 cube offset = [(xyz[0] % 4) * (xcubedim / 2), (xyz[1] % 4) * (ycubedim / 2), (xyz[2] % 4) * zcubedim] # add the contribution of the cube in the hierarchy ocplib.addDataToZSliceStack_ctype( cube, outdata, offset) elif scaling == ISOTROPIC: # Compute the offset in the output data cube # we are placing 4x4x4 input blocks into a 2x2x2 cube offset = [(xyz[0] % 4) * (xcubedim / 2), (xyz[1] % 4) * (ycubedim / 2), (xyz[2] % 4) * (zcubedim / 2)] # use python version for debugging ocplib.addDataToIsotropicStack_ctype( cube, outdata, offset) # Get the base location of this batch xyzout = ocplib.MortonXYZ(mortonidx) # adjust to output corner for scale. if scaling == ZSLICES: outcorner = [ xyzout[0] * xcubedim / 2, xyzout[1] * ycubedim / 2, xyzout[2] * zcubedim ] elif scaling == ISOTROPIC: outcorner = [ xyzout[0] * xcubedim / 2, xyzout[1] * ycubedim / 2, xyzout[2] * zcubedim / 2 ] # Data stored in z,y,x order dims in x,y,z outdim = outdata.shape[::-1] # Preserve annotations made at the specified level # KL check that the P option preserves annotations? RB changed from O db.annotateDense(ch, outcorner, cur_res, outdata, 'O') db.conn.commit() # zero the output buffer outdata = np.zeros([zcubedim * 4, ycubedim * 2, xcubedim * 2], dtype=OCP_dtypetonp.get(ch.getDataType()))