def annotateDense ( self, ch, corner, resolution, annodata, conflictopt ):
   
    index_dict = defaultdict(set)

    # dim is in xyz, data is in zyxj
    dim = annodata.shape[::-1]

    # get the size of the image and cube
    [xcubedim, ycubedim, zcubedim] = cubedim = self.datasetcfg.cubedim [ resolution ] 

    # Round to the nearest larger cube in all dimensions
    start = [xstart, ystart, zstart] = map(div, corner, cubedim)

    znumcubes = (corner[2]+dim[2]+zcubedim-1)/zcubedim - zstart
    ynumcubes = (corner[1]+dim[1]+ycubedim-1)/ycubedim - ystart
    xnumcubes = (corner[0]+dim[0]+xcubedim-1)/xcubedim - xstart

    offset = [xoffset, yoffset, zoffset] = map(mod, corner, cubedim)

    databuffer = np.zeros ([znumcubes*zcubedim, ynumcubes*ycubedim, xnumcubes*xcubedim], dtype=np.uint32 )
    databuffer [ zoffset:zoffset+dim[2], yoffset:yoffset+dim[1], xoffset:xoffset+dim[0] ] = annodata 

    # start a transaction if supported
    self.kvio.startTxn()

    try:

      for z in range(znumcubes):
        for y in range(ynumcubes):
          for x in range(xnumcubes):

            key = ocplib.XYZMorton ([x+xstart,y+ystart,z+zstart])
            cube = self.getCube (ch, key, resolution, True)
            
            if conflictopt == 'O':
              cube.overwrite ( databuffer [ z*zcubedim:(z+1)*zcubedim, y*ycubedim:(y+1)*ycubedim, x*xcubedim:(x+1)*xcubedim ] )
            elif conflictopt == 'P':
              cube.preserve ( databuffer [ z*zcubedim:(z+1)*zcubedim, y*ycubedim:(y+1)*ycubedim, x*xcubedim:(x+1)*xcubedim ] )
            elif conflictopt == 'E': 
              if ch.getExceptions() == EXCEPTION_TRUE:
                exdata = cube.exception ( databuffer [ z*zcubedim:(z+1)*zcubedim, y*ycubedim:(y+1)*ycubedim, x*xcubedim:(x+1)*xcubedim ] )
                for exid in np.unique ( exdata ):
                  if exid != 0:
                    # get the offsets
                    exoffsets = np.nonzero ( exdata==exid )
                    # assemble into 3-tuples zyx->xyz
                    exceptions = np.array ( zip(exoffsets[2], exoffsets[1], exoffsets[0]), dtype=np.uint32 )
                    # update the exceptions
                    self.updateExceptions ( ch, key, resolution, exid, exceptions )
                    # add to the index
                    index_dict[exid].add(key)
              else:
                logger.error("No exceptions for this project.")
                raise OCPCAError ( "No exceptions for this project.")
            else:
              logger.error ( "Unsupported conflict option %s" % conflictopt )
              raise OCPCAError ( "Unsupported conflict option %s" % conflictopt )
            
            self.putCube (ch, key, resolution, cube)

            # update the index for the cube
            # get the unique elements that are being added to the data
            uniqueels = np.unique ( databuffer [ z*zcubedim:(z+1)*zcubedim, y*ycubedim:(y+1)*ycubedim, x*xcubedim:(x+1)*xcubedim ] )
            for el in uniqueels:
              index_dict[el].add(key) 

            # remove 0 no reason to index that
            if 0 in index_dict:
              del(index_dict[0])

      # Update all indexes
      self.annoIdx.updateIndexDense(ch, index_dict, resolution)
      # commit cubes.  not commit controlled with metadata

    except:
      self.kvio.rollback()
      raise
    
    self.kvio.commit()


  #
  #  Called when labeling an entity
  #
Process all the annotations in the dense volume
dataset/ETHPy150Open neurodata/ndstore/ocpca/ocpcadb.py/OCPCADB.annotateDense