Repository: pydata/xarray

Issue:
Should the transform attribute be a six-element or nine-element tuple when reading from rasterio?
My basic question is whether XArray should be storing the rasterio transform as a 6-element tuple or a 9-element tuple - as there seems to be a mismatch between the documentation and the actual code.

The documentation at https://github.com/pydata/xarray/blob/7cd3442fc61e94601c3bfb20377f4f795cde584d/xarray/backends/rasterio_.py#L164-L170 says you can run the following code:

```
from affine import Affine
da = xr.open_rasterio('path_to_file.tif')
transform = Affine(*da.attrs['transform'])
```

This takes the tuple stored in the `transform` attribute and uses it as the arguments to the `Affine` class. However, running this gives an error: `TypeError: Expected 6 coefficients, found 9`.

If you look at the code, then this line in the `open_rasterio` function sets the `transform` attribute to be a 6-element tuple - the first 6 elements of the full Affine tuple: https://github.com/pydata/xarray/blob/7cd3442fc61e94601c3bfb20377f4f795cde584d/xarray/backends/rasterio_.py#L249. However, about twenty lines later, another chunk of code looks to see if there is a transform attribute on the rasterio dataset and if so, sets the `transform` attribute to be the full Affine tuple (that is, a 9-element tuple): https://github.com/pydata/xarray/blob/7cd3442fc61e94601c3bfb20377f4f795cde584d/xarray/backends/rasterio_.py#L262-L268

Thus there seems to be confusion both within the code and the documentation as to whether the transform should be a six-element or nine-element tuple.

Which is the intended behaviour? I am happy to submit a PR to fix either the code or the docs or both.

#### Output of ``xr.show_versions()``

<details>
INSTALLED VERSIONS
------------------
commit: None
python: 3.6.6.final.0
python-bits: 64
OS: Darwin
OS-release: 16.7.0
machine: x86_64
processor: i386
byteorder: little
LC_ALL: None
LANG: en_GB.UTF-8
LOCALE: en_GB.UTF-8

xarray: 0.10.8
pandas: 0.23.4
numpy: 1.14.2
scipy: 1.1.0
netCDF4: 1.4.0
h5netcdf: 0.6.1
h5py: 2.8.0
Nio: None
zarr: None
bottleneck: 1.2.1
cyordereddict: None
dask: 0.18.2
distributed: 1.22.1
matplotlib: 2.2.2
cartopy: None
seaborn: None
setuptools: 40.0.0
pip: 18.0
conda: None
pytest: None
IPython: 6.5.0
sphinx: None
</details>


Discussion:
robintw: Strangely, the Travis-CI build seems to have failed with some errors unrelated to this PR. The two errors are on:

- Python 3.6 with the development version of dask, giving an error of `AttributeError: module 'dask.array' has no attribute 'ghost'`
- Python 2.7 with cdat, iris and pynio which gives various errors of arrays not being equal for `test_to_and_from_cdms2_sgrid` and `test_to_and_from_cdms2_ugrid`

For what it's worth, all of the tests related to this PR passed.

Patch:
diff --git a/doc/faq.rst b/doc/faq.rst
index 3cc395b4..9313481f 100644
--- a/doc/faq.rst
+++ b/doc/faq.rst
@@ -160,71 +160,10 @@ methods for converting back and forth between xarray and these libraries. See
 :py:meth:`~xarray.DataArray.to_iris` and :py:meth:`~xarray.DataArray.to_cdms2`
 for more details.
 
-.. _faq.other_projects:
-
 What other projects leverage xarray?
 ------------------------------------
 
-Here are several existing libraries that build functionality upon xarray.
-
-Geosciences
-~~~~~~~~~~~
-
-- `aospy <https://aospy.readthedocs.io>`_: Automated analysis and management of gridded climate data.
-- `infinite-diff <https://github.com/spencerahill/infinite-diff>`_: xarray-based finite-differencing, focused on gridded climate/meterology data
-- `marc_analysis <https://github.com/darothen/marc_analysis>`_: Analysis package for CESM/MARC experiments and output.
-- `MPAS-Analysis <http://mpas-analysis.readthedocs.io>`_: Analysis for simulations produced with Model for Prediction Across Scales (MPAS) components and the Accelerated Climate Model for Energy (ACME).
-- `OGGM <http://oggm.org/>`_: Open Global Glacier Model
-- `Oocgcm <https://oocgcm.readthedocs.io/>`_: Analysis of large gridded geophysical datasets
-- `Open Data Cube <https://www.opendatacube.org/>`_: Analysis toolkit of continental scale Earth Observation data from satellites.
-- `Pangaea: <https://pangaea.readthedocs.io/en/latest/>`_: xarray extension for gridded land surface & weather model output).
-- `Pangeo <https://pangeo-data.github.io>`_: A community effort for big data geoscience in the cloud.
-- `PyGDX <https://pygdx.readthedocs.io/en/latest/>`_: Python 3 package for
-  accessing data stored in GAMS Data eXchange (GDX) files. Also uses a custom
-  subclass.
-- `Regionmask <https://regionmask.readthedocs.io/>`_: plotting and creation of masks of spatial regions
-- `salem <https://salem.readthedocs.io>`_: Adds geolocalised subsetting, masking, and plotting operations to xarray's data structures via accessors.
-- `Spyfit <https://spyfit.readthedocs.io/en/master/>`_: FTIR spectroscopy of the atmosphere
-- `windspharm <https://ajdawson.github.io/windspharm/index.html>`_: Spherical
-  harmonic wind analysis in Python.
-- `wrf-python <https://wrf-python.readthedocs.io/>`_: A collection of diagnostic and interpolation routines for use with output of the Weather Research and Forecasting (WRF-ARW) Model.
-- `xarray-simlab <https://xarray-simlab.readthedocs.io>`_: xarray extension for computer model simulations.
-- `xarray-topo <https://gitext.gfz-potsdam.de/sec55-public/xarray-topo>`_: xarray extension for topographic analysis and modelling.
-- `xbpch <https://github.com/darothen/xbpch>`_: xarray interface for bpch files.
-- `xESMF <https://xesmf.readthedocs.io>`_: Universal Regridder for Geospatial Data.
-- `xgcm <https://xgcm.readthedocs.io/>`_: Extends the xarray data model to understand finite volume grid cells (common in General Circulation Models) and provides interpolation and difference operations for such grids.
-- `xmitgcm <http://xgcm.readthedocs.io/>`_: a python package for reading `MITgcm <http://mitgcm.org/>`_ binary MDS files into xarray data structures.
-- `xshape <https://xshape.readthedocs.io/>`_: Tools for working with shapefiles, topographies, and polygons in xarray.
-- `xskillscore <https://github.com/raybellwaves/xskillscore>`_: Metrics for verifying forecasts.
-
-Machine Learning
-~~~~~~~~~~~~~~~~
-- `cesium <http://cesium-ml.org/>`_: machine learning for time series analysis
-- `Elm <https://ensemble-learning-models.readthedocs.io>`_: Parallel machine learning on xarray data structures
-- `sklearn-xarray (1) <https://phausamann.github.io/sklearn-xarray>`_: Combines scikit-learn and xarray (1).
-- `sklearn-xarray (2) <https://sklearn-xarray.readthedocs.io/en/latest/>`_: Combines scikit-learn and xarray (2).
-
-Extend xarray capabilities
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-- `Collocate <https://github.com/cistools/collocate>`_: Collocate xarray trajectories in arbitrary physical dimensions
-- `eofs <https://ajdawson.github.io/eofs/>`_: EOF analysis in Python.
-- `xarray_extras <https://github.com/crusaderky/xarray_extras>`_: Advanced algorithms for xarray objects (e.g. intergrations/interpolations).
-- `xrft <https://github.com/rabernat/xrft>`_: Fourier transforms for xarray data.
-- `xr-scipy <https://xr-scipy.readthedocs.io>`_: A lightweight scipy wrapper for xarray.
-- `X-regression <https://github.com/kuchaale/X-regression>`_: Multiple linear regression from Statsmodels library coupled with Xarray library.
-- `xyzpy <http://xyzpy.readthedocs.io>`_: Easily generate high dimensional data, including parallelization.
-
-Visualization
-~~~~~~~~~~~~~
-- `Datashader <https://datashader.org>`_, `geoviews <http://geo.holoviews.org>`_, `holoviews <http://holoviews.org/>`_, : visualization packages for large data
-- `psyplot <https://psyplot.readthedocs.io>`_: Interactive data visualization with python.
-
-Other
-~~~~~
-- `ptsa <https://pennmem.github.io/ptsa_new/html/index.html>`_: EEG Time Series Analysis
-- `pycalphad <https://pycalphad.org/docs/latest/>`_: Computational Thermodynamics in Python
-
-More projects can be found at the `"xarray" Github topic <https://github.com/topics/xarray>`_.
+See section :ref:`related-projects`.
 
 How should I cite xarray?
 -------------------------
diff --git a/doc/index.rst b/doc/index.rst
index 6cd942f9..e66c448f 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -76,6 +76,7 @@ Documentation
 * :doc:`internals`
 * :doc:`roadmap`
 * :doc:`contributing`
+* :doc:`related-projects`
 
 .. toctree::
    :maxdepth: 1
@@ -87,6 +88,7 @@ Documentation
    internals
    roadmap
    contributing
+   related-projects
 
 See also
 --------
diff --git a/doc/related-projects.rst b/doc/related-projects.rst
new file mode 100644
index 00000000..9b75d0e1
--- /dev/null
+++ b/doc/related-projects.rst
@@ -0,0 +1,68 @@
+.. _related-projects:
+
+Xarray related projects
+-----------------------
+
+Here below is a list of several existing libraries that build
+functionality upon xarray. See also section :ref:`internals` for more
+details on how to build xarray extensions.
+
+Geosciences
+~~~~~~~~~~~
+
+- `aospy <https://aospy.readthedocs.io>`_: Automated analysis and management of gridded climate data.
+- `infinite-diff <https://github.com/spencerahill/infinite-diff>`_: xarray-based finite-differencing, focused on gridded climate/meterology data
+- `marc_analysis <https://github.com/darothen/marc_analysis>`_: Analysis package for CESM/MARC experiments and output.
+- `MPAS-Analysis <http://mpas-analysis.readthedocs.io>`_: Analysis for simulations produced with Model for Prediction Across Scales (MPAS) components and the Accelerated Climate Model for Energy (ACME).
+- `OGGM <http://oggm.org/>`_: Open Global Glacier Model
+- `Oocgcm <https://oocgcm.readthedocs.io/>`_: Analysis of large gridded geophysical datasets
+- `Open Data Cube <https://www.opendatacube.org/>`_: Analysis toolkit of continental scale Earth Observation data from satellites.
+- `Pangaea: <https://pangaea.readthedocs.io/en/latest/>`_: xarray extension for gridded land surface & weather model output).
+- `Pangeo <https://pangeo-data.github.io>`_: A community effort for big data geoscience in the cloud.
+- `PyGDX <https://pygdx.readthedocs.io/en/latest/>`_: Python 3 package for
+  accessing data stored in GAMS Data eXchange (GDX) files. Also uses a custom
+  subclass.
+- `Regionmask <https://regionmask.readthedocs.io/>`_: plotting and creation of masks of spatial regions
+- `salem <https://salem.readthedocs.io>`_: Adds geolocalised subsetting, masking, and plotting operations to xarray's data structures via accessors.
+- `Spyfit <https://spyfit.readthedocs.io/en/master/>`_: FTIR spectroscopy of the atmosphere
+- `windspharm <https://ajdawson.github.io/windspharm/index.html>`_: Spherical
+  harmonic wind analysis in Python.
+- `wrf-python <https://wrf-python.readthedocs.io/>`_: A collection of diagnostic and interpolation routines for use with output of the Weather Research and Forecasting (WRF-ARW) Model.
+- `xarray-simlab <https://xarray-simlab.readthedocs.io>`_: xarray extension for computer model simulations.
+- `xarray-topo <https://gitext.gfz-potsdam.de/sec55-public/xarray-topo>`_: xarray extension for topographic analysis and modelling.
+- `xbpch <https://github.com/darothen/xbpch>`_: xarray interface for bpch files.
+- `xESMF <https://xesmf.readthedocs.io>`_: Universal Regridder for Geospatial Data.
+- `xgcm <https://xgcm.readthedocs.io/>`_: Extends the xarray data model to understand finite volume grid cells (common in General Circulation Models) and provides interpolation and difference operations for such grids.
+- `xmitgcm <http://xgcm.readthedocs.io/>`_: a python package for reading `MITgcm <http://mitgcm.org/>`_ binary MDS files into xarray data structures.
+- `xshape <https://xshape.readthedocs.io/>`_: Tools for working with shapefiles, topographies, and polygons in xarray.
+- `xskillscore <https://github.com/raybellwaves/xskillscore>`_: Metrics for verifying forecasts.
+
+Machine Learning
+~~~~~~~~~~~~~~~~
+- `cesium <http://cesium-ml.org/>`_: machine learning for time series analysis
+- `Elm <https://ensemble-learning-models.readthedocs.io>`_: Parallel machine learning on xarray data structures
+- `sklearn-xarray (1) <https://phausamann.github.io/sklearn-xarray>`_: Combines scikit-learn and xarray (1).
+- `sklearn-xarray (2) <https://sklearn-xarray.readthedocs.io/en/latest/>`_: Combines scikit-learn and xarray (2).
+
+Extend xarray capabilities
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+- `Collocate <https://github.com/cistools/collocate>`_: Collocate xarray trajectories in arbitrary physical dimensions
+- `eofs <https://ajdawson.github.io/eofs/>`_: EOF analysis in Python.
+- `xarray_extras <https://github.com/crusaderky/xarray_extras>`_: Advanced algorithms for xarray objects (e.g. intergrations/interpolations).
+- `xrft <https://github.com/rabernat/xrft>`_: Fourier transforms for xarray data.
+- `xr-scipy <https://xr-scipy.readthedocs.io>`_: A lightweight scipy wrapper for xarray.
+- `X-regression <https://github.com/kuchaale/X-regression>`_: Multiple linear regression from Statsmodels library coupled with Xarray library.
+- `xyzpy <http://xyzpy.readthedocs.io>`_: Easily generate high dimensional data, including parallelization.
+
+Visualization
+~~~~~~~~~~~~~
+- `Datashader <https://datashader.org>`_, `geoviews <http://geo.holoviews.org>`_, `holoviews <http://holoviews.org/>`_, : visualization packages for large data.
+- `hvplot <https://hvplot.pyviz.org/>`_ : A high-level plotting API for the PyData ecosystem built on HoloViews.
+- `psyplot <https://psyplot.readthedocs.io>`_: Interactive data visualization with python.
+
+Other
+~~~~~
+- `ptsa <https://pennmem.github.io/ptsa_new/html/index.html>`_: EEG Time Series Analysis
+- `pycalphad <https://pycalphad.org/docs/latest/>`_: Computational Thermodynamics in Python
+
+More projects can be found at the `"xarray" Github topic <https://github.com/topics/xarray>`_.
diff --git a/doc/whats-new.rst b/doc/whats-new.rst
index fd359ee1..0c62cca6 100644
--- a/doc/whats-new.rst
+++ b/doc/whats-new.rst
@@ -61,7 +61,16 @@ Bug fixes
   attribute being set.
   (:issue:`2201`)
   By `Thomas Voigt <https://github.com/tv3141>`_.
+
 - Tests can be run in parallel with pytest-xdist
+  By `Tony Tung <https://github.com/ttung>`_.
+
+- Now raises a ValueError when there is a conflict between dimension names and
+  level names of MultiIndex. (:issue:`2299`)
+  By `Keisuke Fujii <https://github.com/fujiisoup>`_.
+
+- Follow up the renamings in dask; from dask.ghost to dask.overlap
+  By `Keisuke Fujii <https://github.com/fujiisoup>`_.
 
 - Now :py:func:`xr.apply_ufunc` raises a ValueError when the size of
 ``input_core_dims`` is inconsistent with the number of arguments.
diff --git a/xarray/backends/rasterio_.py b/xarray/backends/rasterio_.py
index e576435f..5221cf0e 100644
--- a/xarray/backends/rasterio_.py
+++ b/xarray/backends/rasterio_.py
@@ -259,13 +259,6 @@ def open_rasterio(filename, parse_coordinates=None, chunks=None, cache=None,
         # Is the TIF tiled? (bool)
         # We cast it to an int for netCDF compatibility
         attrs['is_tiled'] = np.uint8(riods.value.is_tiled)
-    with warnings.catch_warnings():
-        # casting riods.value.transform to a tuple makes this future proof
-        warnings.simplefilter('ignore', FutureWarning)
-        if hasattr(riods.value, 'transform'):
-            # Affine transformation matrix (tuple of floats)
-            # Describes coefficients mapping pixel coordinates to CRS
-            attrs['transform'] = tuple(riods.value.transform)
     if hasattr(riods.value, 'nodatavals'):
         # The nodata values for the raster bands
         attrs['nodatavals'] = tuple([np.nan if nodataval is None else nodataval
diff --git a/xarray/core/dask_array_ops.py b/xarray/core/dask_array_ops.py
index 55ba1c1c..423a65aa 100644
--- a/xarray/core/dask_array_ops.py
+++ b/xarray/core/dask_array_ops.py
@@ -1,4 +1,5 @@
 from __future__ import absolute_import, division, print_function
+from distutils.version import LooseVersion
 
 import numpy as np
 
@@ -6,7 +7,15 @@ from . import nputils
 from . import dtypes
 
 try:
+    import dask
     import dask.array as da
+    # Note: dask has used `ghost` before 0.18.2
+    if LooseVersion(dask.__version__) <= LooseVersion('0.18.2'):
+        overlap = da.ghost.ghost
+        trim_internal = da.ghost.trim_internal
+    else:
+        overlap = da.overlap.overlap
+        trim_internal = da.overlap.trim_internal
 except ImportError:
     pass
 
@@ -15,26 +24,25 @@ def dask_rolling_wrapper(moving_func, a, window, min_count=None, axis=-1):
     '''wrapper to apply bottleneck moving window funcs on dask arrays'''
     dtype, fill_value = dtypes.maybe_promote(a.dtype)
     a = a.astype(dtype)
-    # inputs for ghost
+    # inputs for overlap
     if axis < 0:
         axis = a.ndim + axis
     depth = {d: 0 for d in range(a.ndim)}
     depth[axis] = (window + 1) // 2
     boundary = {d: fill_value for d in range(a.ndim)}
-    # create ghosted arrays
-    ag = da.ghost.ghost(a, depth=depth, boundary=boundary)
+    # Create overlap array.
+    ag = overlap(a, depth=depth, boundary=boundary)
     # apply rolling func
     out = ag.map_blocks(moving_func, window, min_count=min_count,
                         axis=axis, dtype=a.dtype)
     # trim array
-    result = da.ghost.trim_internal(out, depth)
+    result = trim_internal(out, depth)
     return result
 
 
 def rolling_window(a, axis, window, center, fill_value):
     """ Dask's equivalence to np.utils.rolling_window """
     orig_shape = a.shape
-    # inputs for ghost
     if axis < 0:
         axis = a.ndim + axis
     depth = {d: 0 for d in range(a.ndim)}
@@ -50,7 +58,7 @@ def rolling_window(a, axis, window, center, fill_value):
             "more evenly divides the shape of your array." %
             (window, depth[axis], min(a.chunks[axis])))
 
-    # Although dask.ghost pads values to boundaries of the array,
+    # Although dask.overlap pads values to boundaries of the array,
     # the size of the generated array is smaller than what we want
     # if center == False.
     if center:
@@ -60,12 +68,12 @@ def rolling_window(a, axis, window, center, fill_value):
         start, end = window - 1, 0
     pad_size = max(start, end) + offset - depth[axis]
     drop_size = 0
-    # pad_size becomes more than 0 when the ghosted array is smaller than
+    # pad_size becomes more than 0 when the overlapped array is smaller than
     # needed. In this case, we need to enlarge the original array by padding
-    # before ghosting.
+    # before overlapping.
     if pad_size > 0:
         if pad_size < depth[axis]:
-            # Ghosting requires each chunk larger than depth. If pad_size is
+            # overlapping requires each chunk larger than depth. If pad_size is
             # smaller than the depth, we enlarge this and truncate it later.
             drop_size = depth[axis] - pad_size
             pad_size = depth[axis]
@@ -78,8 +86,8 @@ def rolling_window(a, axis, window, center, fill_value):
 
     boundary = {d: fill_value for d in range(a.ndim)}
 
-    # create ghosted arrays
-    ag = da.ghost.ghost(a, depth=depth, boundary=boundary)
+    # create overlap arrays
+    ag = overlap(a, depth=depth, boundary=boundary)
 
     # apply rolling func
     def func(x, window, axis=-1):
diff --git a/xarray/core/variable.py b/xarray/core/variable.py
index 8b6a3d3b..d9772407 100644
--- a/xarray/core/variable.py
+++ b/xarray/core/variable.py
@@ -1876,12 +1876,15 @@ def assert_unique_multiindex_level_names(variables):
     objects.
     """
     level_names = defaultdict(list)
+    all_level_names = set()
     for var_name, var in variables.items():
         if isinstance(var._data, PandasIndexAdapter):
             idx_level_names = var.to_index_variable().level_names
             if idx_level_names is not None:
                 for n in idx_level_names:
                     level_names[n].append('%r (%s)' % (n, var_name))
+            if idx_level_names:
+                all_level_names.update(idx_level_names)
 
     for k, v in level_names.items():
         if k in variables:
@@ -1892,3 +1895,9 @@ def assert_unique_multiindex_level_names(variables):
         conflict_str = '\n'.join([', '.join(v) for v in duplicate_names])
         raise ValueError('conflicting MultiIndex level name(s):\n%s'
                          % conflict_str)
+    # Check confliction between level names and dimensions GH:2299
+    for k, v in variables.items():
+        for d in v.dims:
+            if d in all_level_names:
+                raise ValueError('conflicting level / dimension names. {} '
+                                 'already exists as a level name.'.format(d))


Test patch:
diff --git a/xarray/tests/test_backends.py b/xarray/tests/test_backends.py
index c90ca01c..a3d56b90 100644
--- a/xarray/tests/test_backends.py
+++ b/xarray/tests/test_backends.py
@@ -2809,6 +2809,7 @@ class TestRasterio(TestCase):
                 assert isinstance(rioda.attrs['res'], tuple)
                 assert isinstance(rioda.attrs['is_tiled'], np.uint8)
                 assert isinstance(rioda.attrs['transform'], tuple)
+                assert len(rioda.attrs['transform']) == 6
                 np.testing.assert_array_equal(rioda.attrs['nodatavals'],
                                               [np.NaN, np.NaN, np.NaN])
 
@@ -2830,6 +2831,7 @@ class TestRasterio(TestCase):
                 assert isinstance(rioda.attrs['res'], tuple)
                 assert isinstance(rioda.attrs['is_tiled'], np.uint8)
                 assert isinstance(rioda.attrs['transform'], tuple)
+                assert len(rioda.attrs['transform']) == 6
 
             # See if a warning is raised if we force it
             with self.assertWarns("transformation isn't rectilinear"):
@@ -2849,6 +2851,7 @@ class TestRasterio(TestCase):
                 assert isinstance(rioda.attrs['res'], tuple)
                 assert isinstance(rioda.attrs['is_tiled'], np.uint8)
                 assert isinstance(rioda.attrs['transform'], tuple)
+                assert len(rioda.attrs['transform']) == 6
                 np.testing.assert_array_equal(rioda.attrs['nodatavals'],
                                               [-9765.])
 
@@ -2886,6 +2889,7 @@ class TestRasterio(TestCase):
                     assert isinstance(rioda.attrs['res'], tuple)
                     assert isinstance(rioda.attrs['is_tiled'], np.uint8)
                     assert isinstance(rioda.attrs['transform'], tuple)
+                    assert len(rioda.attrs['transform']) == 6
 
     def test_indexing(self):
         with create_tmp_geotiff(8, 10, 3, transform_args=[1, 2, 0.5, 2.],
@@ -3080,6 +3084,7 @@ class TestRasterio(TestCase):
                 assert isinstance(rioda.attrs['res'], tuple)
                 assert isinstance(rioda.attrs['is_tiled'], np.uint8)
                 assert isinstance(rioda.attrs['transform'], tuple)
+                assert len(rioda.attrs['transform']) == 6
                 # from ENVI tags
                 assert isinstance(rioda.attrs['description'], basestring)
                 assert isinstance(rioda.attrs['map_info'], basestring)
diff --git a/xarray/tests/test_dataarray.py b/xarray/tests/test_dataarray.py
index fdca3fd8..2950e97c 100644
--- a/xarray/tests/test_dataarray.py
+++ b/xarray/tests/test_dataarray.py
@@ -2915,6 +2915,7 @@ class TestDataArray(TestCase):
         ma = da.to_masked_array()
         assert len(ma.mask) == N
 
+    @pytest.mark.xfail  # GH:2332 TODO fix this in upstream?
     def test_to_and_from_cdms2_classic(self):
         """Classic with 1D axes"""
         pytest.importorskip('cdms2')
@@ -2949,6 +2950,7 @@ class TestDataArray(TestCase):
             assert_array_equal(original.coords[coord_name],
                                back.coords[coord_name])
 
+    @pytest.mark.xfail  # GH:2332 TODO fix this in upstream?
     def test_to_and_from_cdms2_sgrid(self):
         """Curvilinear (structured) grid
 
@@ -2975,6 +2977,7 @@ class TestDataArray(TestCase):
         assert_array_equal(original.coords['lat'], back.coords['lat'])
         assert_array_equal(original.coords['lon'], back.coords['lon'])
 
+    @pytest.mark.xfail  # GH:2332 TODO fix this in upstream?
     def test_to_and_from_cdms2_ugrid(self):
         """Unstructured grid"""
         pytest.importorskip('cdms2')
diff --git a/xarray/tests/test_dataset.py b/xarray/tests/test_dataset.py
index c0516ed7..08d71d46 100644
--- a/xarray/tests/test_dataset.py
+++ b/xarray/tests/test_dataset.py
@@ -2456,6 +2456,18 @@ class TestDataset(TestCase):
         with raises_regex(ValueError, 'conflicting MultiIndex'):
             data.assign(level_1=range(4))
             data.assign_coords(level_1=range(4))
+        # raise an Error when any level name is used as dimension GH:2299
+        with pytest.raises(ValueError):
+            data['y'] = ('level_1', [0, 1])
+
+    def test_merge_multiindex_level(self):
+        data = create_test_multiindex()
+        other = Dataset({'z': ('level_1', [0, 1])})  # conflict dimension
+        with pytest.raises(ValueError):
+            data.merge(other)
+        other = Dataset({'level_1': ('x', [0, 1])})  # conflict variable name
+        with pytest.raises(ValueError):
+            data.merge(other)
 
     def test_setitem_original_non_unique_index(self):
         # regression test for GH943