code: function(V, crop, dx, dy, fliplr) {
      // note assumes square outputs of size crop x crop
      if(typeof(fliplr)==='undefined') var fliplr = false;
      if(typeof(dx)==='undefined') var dx = global.randi(0, V.sx - crop);
      if(typeof(dy)==='undefined') var dy = global.randi(0, V.sy - crop);
      
      // randomly sample a crop in the input volume
      var W;
      if(crop !== V.sx || dx!==0 || dy!==0) {
        W = new Vol(crop, crop, V.depth, 0.0);
        for(var x=0;x<crop;x++) {
          for(var y=0;y<crop;y++) {
            if(x+dx<0 || x+dx>=V.sx || y+dy<0 || y+dy>=V.sy) continue; // oob
            for(var d=0;d<V.depth;d++) {
             W.set(x,y,d,V.get(x+dx,y+dy,d)); // copy data over
            }
          }
        }
      } else {
        W = V;
      }
  
      if(fliplr) {
        // flip volume horziontally
        var W2 = W.cloneAndZero();
        for(var x=0;x<W.sx;x++) {
          for(var y=0;y<W.sy;y++) {
            for(var d=0;d<W.depth;d++) {
             W2.set(x,y,d,W.get(W.sx - x - 1,y,d)); // copy data over
            }
          }
        }
        W = W2; //swap
      }
      return W;
    }
docs: Volume utilities intended for use with data augmentation crop is the size of output dx,dy are offset wrt incoming volume, of the shift fliplr is boolean on whether we also want to flip left<->right