# Buggy code
def __call__(self, projectables, optional_datasets=None, **info):
    """Get the corrected reflectance when removing Rayleigh scattering. Uses
    pyspectral.
    """
    from pyspectral.rayleigh import Rayleigh

    (vis, red) = projectables
    if vis.shape != red.shape:
        raise IncompatibleAreas
    try:
        (sata, satz, suna, sunz) = optional_datasets
    except ValueError:
        from pyorbital.astronomy import get_alt_az, sun_zenith_angle
        from pyorbital.orbital import get_observer_look

        lons, lats = vis.info["area"].get_lonlats()
        sunalt, suna = get_alt_az(vis.info["start_time"], lons, lats)
        suna = np.rad2deg(suna)
        sunz = sun_zenith_angle(vis.info["start_time"], lons, lats)
        sata, satel = get_observer_look(
            vis.info["satellite_longitude"],
            vis.info["satellite_latitude"],
            vis.info["satellite_altitude"],
            vis.info["start_time"],
            lons,
            lats,
            0,
        )
        satz = 90 - satel
        del satel
    LOG.info("Removing Rayleigh scattering and aerosol absorption")

    # First make sure the two azimuth angles are in the range 0-360:
    sata = np.mod(sata, 360.0)
    suna = np.mod(suna, 360.0)
    ssadiff = np.abs(suna - sata)
    ssadiff = np.where(ssadiff > 180, 360 - ssadiff, ssadiff)
    del sata, suna

    atmosphere = self.info.get("atmosphere", "us-standard")
    aerosol_type = self.info.get("aerosol_type", "marine_clean_aerosol")

    corrector = Rayleigh(
        vis.info["platform_name"],
        vis.info["sensor"],
        atmosphere=atmosphere,
        aerosol_type=aerosol_type,
    )

    try:
        refl_cor_band = corrector.get_reflectance(sunz, satz, ssadiff, vis.id.name, red)
    except KeyError:
        LOG.warning(
            "Could not get the reflectance correction using band name: %s", vis.id.name
        )
        LOG.warning("Will try use the wavelength, however, this may be ambiguous!")
        refl_cor_band = corrector.get_reflectance(
            sunz, satz, ssadiff, vis.id.wavelength[1], red
        )

    proj = Dataset(vis - refl_cor_band, copy=False, **vis.info)
    self.apply_modifier_info(vis, proj)

    return proj


# 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 __call__(self, projectables, optional_datasets=None, **info):
    """Get the corrected reflectance when removing Rayleigh scattering.

    Uses pyspectral.
    """
    from pyspectral.rayleigh import Rayleigh

    (vis, red) = projectables
    if vis.shape != red.shape:
        raise IncompatibleAreas
    try:
        (sata, satz, suna, sunz) = optional_datasets
    except ValueError:
        from pyorbital.astronomy import get_alt_az, sun_zenith_angle
        from pyorbital.orbital import get_observer_look

        lons, lats = vis.attrs["area"].get_lonlats_dask(CHUNK_SIZE)
        sunalt, suna = get_alt_az(vis.attrs["start_time"], lons, lats)
        suna = np.rad2deg(suna)
        sunz = sun_zenith_angle(vis.attrs["start_time"], lons, lats)
        sata, satel = get_observer_look(
            vis.attrs["satellite_longitude"],
            vis.attrs["satellite_latitude"],
            vis.attrs["satellite_altitude"],
            vis.attrs["start_time"],
            lons,
            lats,
            0,
        )
        satz = 90 - satel
        del satel
    LOG.info("Removing Rayleigh scattering and aerosol absorption")

    # First make sure the two azimuth angles are in the range 0-360:
    sata = sata % 360.0
    suna = suna % 360.0
    ssadiff = abs(suna - sata)
    ssadiff = xu.minimum(ssadiff, 360 - ssadiff)
    del sata, suna

    atmosphere = self.attrs.get("atmosphere", "us-standard")
    aerosol_type = self.attrs.get("aerosol_type", "marine_clean_aerosol")

    corrector = Rayleigh(
        vis.attrs["platform_name"],
        vis.attrs["sensor"],
        atmosphere=atmosphere,
        aerosol_type=aerosol_type,
    )

    try:
        refl_cor_band = corrector.get_reflectance(
            sunz.load(), satz.load(), ssadiff, vis.attrs["name"], red.load()
        )
    except KeyError:
        LOG.warning(
            "Could not get the reflectance correction using band name: %s", vis.id.name
        )
        LOG.warning("Will try use the wavelength, however, this may be ambiguous!")
        refl_cor_band = corrector.get_reflectance(
            sunz.load(), satz.load(), ssadiff, vis.attrs["wavelength"][1], red.load()
        )

    proj = vis - refl_cor_band
    proj.attrs = vis.attrs
    self.apply_modifier_info(vis, proj)

    return proj