Initialise a spectrum interpolator.

def _initialise_approximator(self, closest_point=None,
        wavelengths_required=None, rescale=True, **kwargs):
        """
        Initialise a spectrum interpolator.
        """

        if self._initialised and not kwargs.get("force", False):
            logger.debug("Ignoring call to re-initialise approximator because "
                "we already have.")
            return self._subset_bounds


        logger.info("Initialising approximator near {0}".format(closest_point))

        N = self.grid_points.size
        dtype = [(name, '<f8') for name in self.grid_points.dtype.names]
        grid_points = self.grid_points.astype(dtype).view(float).reshape(N, -1)

        # If closest_point is given then we will slice a small part of the grid.
        if closest_point is not None:

            default = 1.0
            grid_subset = self._configuration.get("settings", 
                { "grid_subset": default }).get("grid_subset", default)

            # Use nearest N points in interpolator.
            # If grid subset is a fraction, scale it to real numbers.
            if 1 >= grid_subset > 0:
                grid_subset = int(np.round(grid_subset * N))

            logger.debug("Using {0} nearest points for interpolator".format(
                grid_subset))

            # Use closest N points.
            distance = np.sum(np.abs(grid_points - closest_point)/
                np.ptp(grid_points, axis=0), axis=1)
            grid_indices = np.argsort(distance)[:grid_subset]

        else:
            grid_indices = np.ones(N, dtype=bool)

        # What wavelengths will be required? Assume all if not specified.
        if wavelengths_required is not None:
            mask = np.zeros(self.wavelengths.size, dtype=bool)
            for start, end in wavelengths_required:
                idx = np.clip(
                    self.wavelengths.searchsorted([start, end]) + [0, 1],
                    0, self.wavelengths.size)
                mask[idx[0]:idx[1]] = True
        else:
            mask = np.ones(self.wavelengths.size, dtype=bool)

        # Apply model masks.
        mask *= self._model_mask()

        # Slice small part of the intensities grid.
        intensities = np.memmap(
            self._configuration["model_grid"]["intensities"],
            dtype="float32", mode="r", shape=(N, self.wavelengths.size))
        subset = np.copy(intensities[grid_indices, :])
        subset[:, ~mask] = np.nan
        del intensities

        # Create an interpolator.
        try:
            interpolator = interpolate.LinearNDInterpolator(
                grid_points[grid_indices], subset, rescale=rescale)

        except TypeError:
            logger.warn("Could not rescale the LinearNDInterpolator because "\
                "you need a newer version of scipy")
            interpolator = interpolate.LinearNDInterpolator(
                grid_points[grid_indices], subset)

        generate.init()
        generate.wavelengths.append(self.wavelengths)
        generate.intensities.append(interpolator)
        
        self._initialised = True

        # Return the subset boundaries of the grid.
        self._subset_bounds = {}
        for name in self.grid_points.dtype.names:
            points = self.grid_points[name][grid_indices]
            self._subset_bounds[name] = (min(points), max(points))

        return self._subset_bounds