def make_mosaic(self, block_selector=None, target_fits=None,
            mosaic_key='image_path', weight_key='weight_path'):
        """Swarp a mosaic using the optimal sky offsets.
        
        The mosaic can be made anytime once entries are added
        to the solver's collection. This is because we initialize
        a SimplexScalarOffsetSolver that re-generates the list of best
        offsets from the collection of solver documents.

        Parameters
        ----------
        block_selector : dict
            An alternative MongoDB block selector (used instead of the one
            specific during instance initialization). This can be useful
            for building a mosaic with a subset of the blocks.
        target_fits : str
            Set to the path of a FITS file that will be used to define the
            output frame of the block. The output blocks will then correspond
            pixel-to-pixel. Note that both blocks should already be resampled
            into the same pixel space.
        mosaic_key : str
            MosaicDB key to save the mosaic's FITS path.
        weight_key : str
            MosaicDB key to save the mosaic weightmap's FITS path.
        """
        mosaicDoc = self.mosaicdb.c.find_one({"_id": self.mosaic_name})
        solver_cname = mosaicDoc['solver_cname']
        solver_dbname = mosaicDoc['solver_dbname']

        if block_selector:
            block_sel = dict(block_selector)
        else:
            block_sel = dict(self.block_sel)
        bloc_docs = self.blockdb.find_dict(block_sel)
        solver = SimplexScalarOffsetSolver(dbname=solver_dbname,
                cname=solver_cname,
                url=self.mosaicdb.url, port=self.mosaicdb.port)
        offsets = solver.find_best_offsets()
        
        mosaic_path, mosaic_weight_path = blockmosaic.block_mosaic(bloc_docs,
                offsets, self.mosaic_name, self._swarp_configs, self.workdir,
                target_fits=target_fits,
                delete_offset_images=True,
                offset_fcn=offsettools.apply_offset,
                path_key=self._image_key,
                weight_key=self._weight_key)

        self.mosaicdb.c.update({"_id": self.mosaic_name},
                {"$set": {mosaic_key: mosaic_path,
                          weight_key: mosaic_weight_path}})
    def _solve_offsets(self, mosaicName, solverDBName, couplings,
            blockWCSs, mosaicWCS, initScale, restartScale,
            fresh_start=True, n_runs=1000):
        """Use SimplexScalarOffsetSolver to derive offsets for this block."""
        logPath = os.path.join(self.workdir, "%s.log" % mosaicName)
        solver = SimplexScalarOffsetSolver(dbname=solverDBName,
                cname=mosaicName,
                url=self.mosaicdb.url, port=self.mosaicdb.port)

        if fresh_start:
            solver.resetdb()
        initSigma, resetSigma = self._simplex_dispersion(initScale,
                restartScale, couplings)
        solver.multi_start(couplings, n_runs, logPath, cython=True, mp=True,
                initSigma=initSigma,
                restartSigma=resetSigma)

        offsets = solver.find_best_offsets()

        # Estimate uncertainty in the zeropoint of the sky offsets
        zp_sigma = self._compute_offset_zp_sigma(offsets)

        self.mosaicdb.c.update({"_id": mosaicName},
                {"$set": {"offsets": offsets,
                    "offset_zp_sigma": zp_sigma,
                    "solver_cname": mosaicName,
                    "solver_dbname": solverDBName}})
        return solver