def cutout ( self, ch, corner, dim, resolution, zscaling=None, annoids=None ):
    """Extract a cube of arbitrary size.  Need not be aligned."""

    # if cutout is below resolution, get a smaller cube and scaleup
    if ch.getChannelType() in ANNOTATION_CHANNELS and ch.getResolution() > resolution:

      # find the effective dimensions of the cutout (where the data is)
      effcorner, effdim, (xpixeloffset,ypixeloffset) = self._zoominCutout ( ch, corner, dim, resolution )
      [ xcubedim, ycubedim, zcubedim ] = cubedim = self.datasetcfg.cubedim [ ch.getResolution() ] 
      effresolution = ch.getResolution()

    # if cutout is above resolution, get a large cube and scaledown
    elif ch.getChannelType() in ANNOTATION_CHANNELS and ch.getResolution() < resolution and ch.getPropagate() not in [PROPAGATED]:  

      [ xcubedim, ycubedim, zcubedim ] = cubedim = self.datasetcfg.cubedim [ ch.getResolution() ] 
      effcorner, effdim = self._zoomoutCutout ( ch, corner, dim, resolution )
      effresolution = ch.getResolution()

    # this is the default path when not scaling up the resolution
    else:

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

    # Round to the nearest larger cube in all dimensions
    zstart = effcorner[2]/zcubedim
    ystart = effcorner[1]/ycubedim
    xstart = effcorner[0]/xcubedim

    znumcubes = (effcorner[2]+effdim[2]+zcubedim-1)/zcubedim - zstart
    ynumcubes = (effcorner[1]+effdim[1]+ycubedim-1)/ycubedim - ystart
    xnumcubes = (effcorner[0]+effdim[0]+xcubedim-1)/xcubedim - xstart
  
    # use the requested resolution
    if zscaling == 'nearisotropic' and self.datasetcfg.nearisoscaledown[resolution] > 1:
      dbname = ch.getNearIsoTable(resolution)
    else:
      dbname = ch.getTable(effresolution)

    import cube
    incube = Cube.getCube ( cubedim, ch.getChannelType(), ch.getDataType() )
    outcube = Cube.getCube([xnumcubes*xcubedim,ynumcubes*ycubedim,znumcubes*zcubedim], ch.getChannelType(), ch.getDataType())
                                        
    # Build a list of indexes to access
    listofidxs = []
    for z in range ( znumcubes ):
      for y in range ( ynumcubes ):
        for x in range ( xnumcubes ):
          mortonidx = ocplib.XYZMorton ( [x+xstart, y+ystart, z+zstart] )
          listofidxs.append ( mortonidx )

    # Sort the indexes in Morton order
    listofidxs.sort()
    
    # xyz offset stored for later use
    lowxyz = ocplib.MortonXYZ ( listofidxs[0] )
    
    self.kvio.startTxn()

    try:

      if zscaling == 'nearisotropic' and self.datasetcfg.nearisoscaledown[resolution] > 1:
        cuboids = self.getCubes(ch, listofidxs, effresolution, True)
      else:
        cuboids = self.getCubes(ch, listofidxs, effresolution)

      # use the batch generator interface
      for idx, datastring in cuboids:

        #add the query result cube to the bigger cube
        curxyz = ocplib.MortonXYZ(int(idx))
        offset = [ curxyz[0]+lowxyz[0], curxyz[1]-lowxyz[1], curxyz[2]-lowxyz[2] ]
        
        if self.NPZ:
          incube.fromNPZ ( datastring[:] )
        else:
          incube.fromBlosc ( datastring[:] )

        # apply exceptions if it's an annotation project
        if annoids!= None and ch.getChannelType() in ANNOTATION_CHANNELS:
          incube.data = ocplib.filter_ctype_OMP ( incube.data, annoids )
          if ch.getExceptions() == EXCEPTION_TRUE:
            self.applyCubeExceptions ( ch, annoids, effresolution, idx, incube )

        # add it to the output cube
        outcube.addData ( incube, offset ) 

    except:
      self.kvio.rollback()
      raise

    self.kvio.commit()

    # if we fetched a smaller cube to zoom, correct the result
    if ch.getChannelType() in ANNOTATION_CHANNELS and ch.getResolution() > resolution:

      outcube.zoomData ( ch.getResolution()-resolution )

      # need to trim based on the cube cutout at resolution()
      outcube.trim ( corner[0]%(xcubedim*(2**(ch.getResolution()-resolution)))+xpixeloffset,dim[0], corner[1]%(ycubedim*(2**(ch.getResolution()-resolution)))+ypixeloffset,dim[1], corner[2]%zcubedim,dim[2] )

    # if we fetch a larger cube, downscale it and correct
    elif ch.getChannelType() in ANNOTATION_CHANNELS and ch.getResolution() < resolution and ch.getPropagate() not in [PROPAGATED]:

      outcube.downScale (resolution - ch.getResolution())

      # need to trime based on the cube cutout at resolution
      outcube.trim ( corner[0]%(xcubedim*(2**(ch.getResolution()-resolution))),dim[0], corner[1]%(ycubedim*(2**(ch.getResolution()-resolution))),dim[1], corner[2]%zcubedim,dim[2] )
      
    # need to trim down the array to size only if the dimensions are not the same
    elif dim[0] % xcubedim  == 0 and dim[1] % ycubedim  == 0 and dim[2] % zcubedim  == 0 and corner[0] % xcubedim  == 0 and corner[1] % ycubedim  == 0 and corner[2] % zcubedim  == 0:
      pass
    else:
      outcube.trim ( corner[0]%xcubedim,dim[0],corner[1]%ycubedim,dim[1],corner[2]%zcubedim,dim[2] )

    return outcube
dataset/ETHPy150Open neurodata/ndstore/ocpca/ocpcadb.py/OCPCADB.cutout/operator `-` -> `+`