# Buggy code
def precompute(
    self,
    mask=None,
    radius_of_influence=10000,
    epsilon=0,
    reduce_data=True,
    nprocs=1,
    segments=None,
    cache_dir=False,
    **kwargs,
):
    """Create a KDTree structure and store it for later use.

    Note: The `mask` keyword should be provided if geolocation may be valid where data points are invalid.
    This defaults to the `mask` attribute of the `data` numpy masked array passed to the `resample` method.
    """

    del kwargs

    source_geo_def = mask_source_lonlats(self.source_geo_def, mask)

    kd_hash = self.get_hash(
        source_geo_def=source_geo_def,
        radius_of_influence=radius_of_influence,
        epsilon=epsilon,
    )

    filename = self._create_cache_filename(cache_dir, kd_hash)
    self._read_params_from_cache(cache_dir, kd_hash, filename)

    if self.cache is not None:
        LOG.debug("Loaded kd-tree parameters")
        return self.cache
    else:
        LOG.debug("Computing kd-tree parameters")

    valid_input_index, valid_output_index, index_array, distance_array = (
        get_neighbour_info(
            source_geo_def,
            self.target_geo_def,
            radius_of_influence,
            neighbours=1,
            epsilon=epsilon,
            reduce_data=reduce_data,
            nprocs=nprocs,
            segments=segments,
        )
    )

    # it's important here not to modify the existing cache dictionary.
    self.cache = {
        "valid_input_index": valid_input_index,
        "valid_output_index": valid_output_index,
        "index_array": index_array,
        "distance_array": distance_array,
        "source_geo_def": source_geo_def,
    }

    self._update_caches(kd_hash, cache_dir, filename)

    return self.cache


# Traceback (AttributeError)
[INFO: 2017-12-12 08:14:04 : satpy.writers.cf_writer] Saving datasets to NetCDF4/CF.
[INFO: 2017-12-12 08:14:04 : satpy.writers.cf_writer] No longitude and latitude data to save.
[INFO: 2017-12-12 08:14:04 : satpy.writers.cf_writer] No grid mapping to save.
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-24-58ece08c15f3> in <module>()
----> 1 lcl.save_datasets(writer='cf', filename='/tmp/foo.nc')

/home/lahtinep/Software/pytroll/packages/satpy/satpy/scene.pyc in save_datasets(self, writer, datasets, **kwargs)
632             datasets = self.datasets.values()
633         writer = self.get_writer(writer, **kwargs)
--> 634         writer.save_datasets(datasets, **kwargs)
635
636     def get_writer(self, writer="geotiff", **kwargs):

/home/lahtinep/Software/pytroll/packages/satpy/satpy/writers/cf_writer.pyc in save_datasets(self, datasets, filename, **kwargs)
176                     coords = [line_coord, pixel_coord]
177
--> 178                 domain = cf.Domain(dim=coords,
179                                    aux=aux,
180                                    ref=grid_mapping)

AttributeError: 'module' object has no attribute 'Domain'

# Fixed code
def precompute(
    self,
    mask=None,
    radius_of_influence=10000,
    epsilon=0,
    reduce_data=True,
    nprocs=1,
    segments=None,
    cache_dir=False,
    **kwargs,
):
    """Create a KDTree structure and store it for later use.

    Note: The `mask` keyword should be provided if geolocation may be valid
    where data points are invalid. This defaults to the `mask` attribute of
    the `data` numpy masked array passed to the `resample` method.
    """

    del kwargs
    source_geo_def = mask_source_lonlats(self.source_geo_def, mask)

    kd_hash = self.get_hash(
        source_geo_def=source_geo_def,
        radius_of_influence=radius_of_influence,
        epsilon=epsilon,
    )

    filename = self._create_cache_filename(cache_dir, kd_hash)
    self._read_params_from_cache(cache_dir, kd_hash, filename)

    if self.resampler is None:
        if self.cache is not None:
            LOG.debug("Loaded kd-tree parameters")
            return self.cache

        LOG.debug("Computing kd-tree parameters")

        self.resampler = XArrayResamplerNN(
            source_geo_def,
            self.target_geo_def,
            radius_of_influence,
            neighbours=1,
            epsilon=epsilon,
            reduce_data=reduce_data,
            nprocs=nprocs,
            segments=segments,
        )

        valid_input_index, valid_output_index, index_array, distance_array = (
            self.resampler.get_neighbour_info()
        )
        # reference call to pristine pyresample
        # vii, voi, ia, da = get_neighbour_info(source_geo_def,
        #                                       self.target_geo_def,
        #                                       radius_of_influence,
        #                                       neighbours=1,
        #                                       epsilon=epsilon,
        #                                       reduce_data=reduce_data,
        #                                       nprocs=nprocs,
        #                                       segments=segments)

        # it's important here not to modify the existing cache dictionary.
        if cache_dir:
            self.cache = {
                "valid_input_index": valid_input_index,
                "valid_output_index": valid_output_index,
                "index_array": index_array,
                "distance_array": distance_array,
                "source_geo_def": source_geo_def,
            }

            self._update_caches(kd_hash, cache_dir, filename)

            return self.cache