docs: def plant(expnums, ccd, rmin, rmax, ang, width, number=10, mmin=21.0, mmax=25.5, version='s', dry_run=False):
      """Plant artificial sources into the list of images provided.
  
      :param expnums: list of MegaPrime exposure numbers to add artificial KBOs to
      :param ccd: which ccd to work on.
      :param rmin: The minimum rate of motion to add sources at (''/hour)
      :param rmax: The maximum rate of motion to add sources at (''/hour)
      :param ang: The mean angle of motion to add sources
      :param width: The +/- range of angles of motion
      :param version: Add sources to the 'o', 'p' or 's' images
      :param dry_run: don't push results to VOSpace.
      """
  
      # Construct a list of artificial KBOs with positions in the image
      # and rates of motion within the bounds given by the caller.
      filename = storage.get_image(expnums[0],
                                   ccd=ccd,
                                   version=version)
      header = fits.open(filename)[0].header
      bounds = util.get_pixel_bounds_from_datasec_keyword(header.get('DATASEC', '[33:2080,1:4612]'))
  
      # generate a set of artificial KBOs to add to the image.
      kbos = KBOGenerator.get_kbos(n=number,
                                   rate=(rmin, rmax),
                                   angle=(ang - width, ang + width),
                                   mag=(mmin, mmax),
                                   x=(bounds[0][0], bounds[0][1]),
                                   y=(bounds[1][0], bounds[1][1]),
                                   filename='Object.planted')
  
      for expnum in expnums:
          filename = storage.get_image(expnum, ccd, version)
          psf = storage.get_file(expnum, ccd, version, ext='psf.fits')
          plant_kbos(filename, psf, kbos, get_shifts(expnum, ccd, version), "fk")
  
      if dry_run:
          return
  
      uri = storage.get_uri('Object', ext='planted', version='',
                            subdir=str(
                                expnums[0]) + "/ccd%s" % (str(ccd).zfill(2)))
  
      storage.copy('Object.planted', uri)
      for expnum in expnums:
          uri = storage.get_uri(expnum,
                                ccd=ccd,
                                version=version,
                                ext='fits', prefix='fk')
          filename = os.path.basename(uri)
          storage.copy(filename, uri)
  
      return