def listIds(imageargs, dbcfg, proj): """Return the list of annotation identifiers in a region""" # Perform argument processing try: args = restargs.BrainRestArgs() args.cutoutArgs(imageargs, dbcfg) except restargs.RESTArgsError, e: logger.warning("REST Arguments failed: %s" % (e)) raise ANNError(e)
def cutout(imageargs, dbcfg, proj, channel=None): """Build the returned cube of data. This method is called by all of the more basic services to build the data. They then format and refine the output.""" # Perform argument processing try: args = restargs.BrainRestArgs() args.cutoutArgs(imageargs, dbcfg) except restargs.RESTArgsError, e: logger.warning("REST Arguments failed: %s" % (e)) raise ANNError(e)
def yzAnno(imageargs, dbcfg, proj): """Return an yz plane fileobj.read()""" [annoidstr, sym, imageargs] = imageargs.partition('/') annoid = int(annoidstr) # Perform argument processing try: args = restargs.BrainRestArgs() args.yzArgs(imageargs, dbcfg) except restargs.RESTArgsError, e: logger.warning("REST Arguments failed: %s" % (e)) raise ANNError(e)
def __init__(self, token, cutout): """Load the annotation database and project""" projdb = ocpcaproj.OCPCAProjectsDB() self.proj = projdb.loadProject(token) # Bind the annotation database self.annoDB = ocpcadb.OCPCADB(self.proj) # Perform argument processing try: args = restargs.BrainRestArgs() args.cutoutArgs(cutout + "/", self.proj.datasetcfg) except restargs.RESTArgsError, e: raise OCPCAError(e.value)
def yzSlice(imageargs, dbcfg, proj): """Return an yz plane as a cube""" if proj.getDBType() == emcaproj.CHANNELS: [channel, sym, imageargs] = imageargs.partition('/') else: channel = None # Perform argument processing try: args = restargs.BrainRestArgs() args.yzArgs(imageargs, dbcfg) except restargs.RESTArgsError, e: logger.warning("REST Arguments failed: %s" % (e)) raise ANNError(e)
def getAnnotations(webargs, postdata): """Get multiple annotations. Takes an HDF5 that lists ids in the post.""" [token, objectsliteral, otherargs] = webargs.split('/', 2) # Get the annotation database projdb = emcaproj.EMCAProjectsDB() proj = projdb.getProj(token) dbcfg = dbconfig.switchDataset(proj.getDataset()) db = emcadb.EMCADB(dbcfg, proj) # Read the post data HDF5 and get a list of identifiers tmpinfile = tempfile.NamedTemporaryFile() tmpinfile.write(postdata) tmpinfile.seek(0) h5in = h5py.File(tmpinfile.name) # IDENTIFIERS if not h5in.get('ANNOIDS'): logger.warning( "Requesting multiple annotations. But no HDF5 \'ANNOIDS\' field specified." ) raise ANNError( "Requesting multiple annotations. But no HDF5 \'ANNOIDS\' field specified." ) # GET the data out of the HDF5 file. Never operate on the data in place. annoids = h5in['ANNOIDS'][:] # set variables to None: need them in call to getAnnoByID, but not all paths set all corner = None dim = None resolution = None dataarg = '' # process options # Split the URL and get the args if otherargs != '': (dataarg, cutout) = otherargs.split('/', 1) if dataarg == '' or dataarg == 'nodata': dataoption = AR_NODATA elif dataarg == 'voxels': dataoption = AR_VOXELS # only arg to voxels is resolution [resstr, sym, rest] = cutout.partition('/') resolution = int(resstr) if resstr != '' else proj.getResolution() elif dataarg == 'cutout': # if blank of just resolution then a tightcutout if cutout == '' or re.match('^\d+[\/]*$', cutout): dataoption = AR_TIGHTCUTOUT [resstr, sym, rest] = cutout.partition('/') resolution = int(resstr) if resstr != '' else proj.getResolution() else: dataoption = AR_CUTOUT # Perform argument processing brargs = restargs.BrainRestArgs() brargs.cutoutArgs(cutout, dbcfg) # Extract the relevant values corner = brargs.getCorner() dim = brargs.getDim() resolution = brargs.getResolution() # RBTODO test this interface elif dataarg == 'boundingbox': # if blank of just resolution then a tightcutout if cutout == '' or re.match('^\d+[\/]*$', cutout): dataoption = AR_BOUNDINGBOX [resstr, sym, rest] = cutout.partition('/') resolution = int(resstr) if resstr != '' else proj.getResolution() else: logger.warning("In getAnnotations: Error: no such data option %s " % (dataarg)) raise ANNError("In getAnnotations: Error: no such data option %s " % (dataarg)) # Make the HDF5 output file # Create an in-memory HDF5 file tmpoutfile = tempfile.NamedTemporaryFile() h5fout = h5py.File(tmpoutfile.name) # get annotations for each identifier for annoid in annoids: # the int here is to prevent using a numpy value in an inner loop. This is a 10x performance gain. getAnnoById(int(annoid), h5fout, db, dbcfg, dataoption, resolution, corner, dim) # close temporary file h5in.close() tmpinfile.close() # Transmit back the populated HDF5 file h5fout.flush() tmpoutfile.seek(0) return tmpoutfile.read()
def getAnnotation(webargs): """Fetch a RAMON object as HDF5 by object identifier""" [token, sym, otherargs] = webargs.partition('/') # Get the annotation database projdb = emcaproj.EMCAProjectsDB() proj = projdb.getProj(token) dbcfg = dbconfig.switchDataset(proj.getDataset()) db = emcadb.EMCADB(dbcfg, proj) # Split the URL and get the args args = otherargs.split('/', 2) # Make the HDF5 file # Create an in-memory HDF5 file tmpfile = tempfile.NamedTemporaryFile() h5f = h5py.File(tmpfile.name) # if the first argument is numeric. it is an annoid if re.match('^[\d,]+$', args[0]): annoids = map(int, args[0].split(',')) for annoid in annoids: # default is no data if args[1] == '' or args[1] == 'nodata': dataoption = AR_NODATA getAnnoById(annoid, h5f, db, dbcfg, dataoption) # if you want voxels you either requested the resolution id/voxels/resolution # or you get data from the default resolution elif args[1] == 'voxels': dataoption = AR_VOXELS [resstr, sym, rest] = args[2].partition('/') resolution = int( resstr) if resstr != '' else proj.getResolution() getAnnoById(annoid, h5f, db, dbcfg, dataoption, resolution) elif args[1] == 'cutout': # if there are no args or only resolution, it's a tight cutout request if args[2] == '' or re.match('^\d+[\/]*$', args[2]): dataoption = AR_TIGHTCUTOUT [resstr, sym, rest] = args[2].partition('/') resolution = int( resstr) if resstr != '' else proj.getResolution() getAnnoById(annoid, h5f, db, dbcfg, dataoption, resolution) else: dataoption = AR_CUTOUT # Perform argument processing brargs = restargs.BrainRestArgs() brargs.cutoutArgs(args[2], dbcfg) # Extract the relevant values corner = brargs.getCorner() dim = brargs.getDim() resolution = brargs.getResolution() getAnnoById(annoid, h5f, db, dbcfg, dataoption, resolution, corner, dim) elif args[1] == 'boundingbox': dataoption = AR_BOUNDINGBOX [resstr, sym, rest] = args[2].partition('/') resolution = int( resstr) if resstr != '' else proj.getResolution() getAnnoById(annoid, h5f, db, dbcfg, dataoption, resolution) else: logger.warning( "Fetch identifier %s. Error: no such data option %s " % (annoid, args[1])) raise ANNError( "Fetch identifier %s. Error: no such data option %s " % (annoid, args[1])) # the first argument is not numeric. it is a service other than getAnnotation else: logger.warning( "Get interface %s requested. Illegal or not implemented. Args: %s" % (args[0], webargs)) raise ANNError( "Get interface %s requested. Illegal or not implemented" % (args[0])) h5f.flush() tmpfile.seek(0) return tmpfile.read()
def selectPost(webargs, dbcfg, proj, postdata): """Parse the first arg and call the right post service""" [service, sym, postargs] = webargs.partition('/') # Don't write to readonly projects if proj.getReadOnly() == 1: logger.warning("Attempt to write to read only project. %s: %s" % (proj.getDBName(), webargs)) raise ANNError("Attempt to write to read only project. %s: %s" % (proj.getDBName(), webargs)) # choose to overwrite (default), preserve, or make exception lists # when voxels conflict # Perform argument processing # Bind the annotation database db = emcadb.EMCADB(dbcfg, proj) db.startTxn() tries = 0 done = False while not done and tries < 5: try: if service == 'npvoxels': # get the resolution [entity, resolution, conflictargs] = postargs.split('/', 2) # Grab the voxel list fileobj = cStringIO.StringIO(postdata) voxlist = np.load(fileobj) conflictopt = restargs.conflictOption(conflictargs) entityid = db.annotate(int(entity), int(resolution), voxlist, conflictopt) elif service == 'npdense': # Process the arguments try: args = restargs.BrainRestArgs() args.cutoutArgs(postargs, dbcfg) except restargs.RESTArgsError, e: logger.warning("REST Arguments failed: %s" % (e)) raise ANNError(e) corner = args.getCorner() resolution = args.getResolution() # This is used for ingest only now. So, overwrite conflict option. conflictopt = restargs.conflictOption("") # get the data out of the compressed blob rawdata = zlib.decompress(postdata) fileobj = cStringIO.StringIO(rawdata) voxarray = np.load(fileobj) # Get the annotation database db = emcadb.EMCADB(dbcfg, proj) if proj.getDBType() == emcaproj.IMAGES: db.writeImageCuboid(corner, resolution, voxarray) # this is just a status entityid = 0 # Choose the verb, get the entity (as needed), and annotate # Translates the values directly else: entityid = db.annotateDense(corner, resolution, voxarray, conflictopt) db.conn.commit() else: logger.warning( "An illegal Web POST service was requested: %s. Args %s" % (service, webargs)) raise ANNError("No such Web service: %s" % service) db.commit() done = True