Git Product home page Git Product logo

cf-units's Introduction

Units of measure as defined by the Climate and Forecast (CF) Metadata Conventions.

⚙️ CI ci-locks ci-manifest ci-tests ci-wheels pre-commit.ci status
💬 Community GH Discussions
📖 Documentation Documentation Status
📈 Health Coverage Status
✨ Meta code style - black isort Flake8 license - bds-3-clause
📦 Package conda-forge downloads pypi pypi - python version DOI
🧰 Repo Commits since last release contributors Latest version

Table of Contents

Overview

Units of measure as required by the Climate and Forecast (CF) metadata conventions.

Provision of a wrapper class to support Unidata/UCAR UDUNITS-2 library, and the cftime calendar functionality.

Documentation can be found at https://cf-units.readthedocs.io/en/latest/.

Example

>>> from cf_units import Unit
>>> km = Unit('kilometers')
>>> m = Unit('meters')
>>> m.convert(1500, km)
1.5

Get in Touch

Credits, Copyright and License

cf-units is developed collaboratively under the SciTools umbrella.

A full list of code contributors ("cf-units contributors") can be found at https://github.com/SciTools/cf-units/graphs/contributors.

Code is just one of many ways of positively contributing to cf-units, please see our contributing guide for more details on how you can get involved.

cf-units is released under a BSD-3 license. See LICENSE for full terms.

The Met Office has made a significant contribution to the development, maintenance and support of this library. All Met Office contributions are copyright on behalf of the British Crown.

cf-units's People

Contributors

ajdawson avatar bekozi avatar bjlittle avatar corinnebosley avatar dependabot[bot] avatar djkirkham avatar dpeterk avatar github-actions[bot] avatar hgwright avatar kaedonkers avatar larsbarring avatar lbdreyer avatar lwgordonimos avatar marqh avatar mrshannon avatar ocefpaf avatar pelson avatar pp-mo avatar pre-commit-ci[bot] avatar qulogic avatar rcomer avatar rhattersley avatar scitools-ci[bot] avatar trexfeathers avatar tv3141 avatar wjbenfold avatar znicholls avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cf-units's Issues

Segfault on exit

The following code, on OSX & master, Seg Faults on exiting python. Need to double check the new cython clearup code:

from cf_units import CALENDARS as calendars
from cf_units import Unit
import numpy as np

from iris.coord_categorisation import add_categorised_coord
from iris.coord_categorisation import add_day_of_year
from iris.cube import Cube
from iris.coords import DimCoord
from iris.tests import mock


def make_cube(calendar):
    n_times = 10
    cube = Cube(np.arange(n_times))
    time_coord = DimCoord(np.arange(n_times), standard_name='time',
                          units=Unit('days since 1980-12-25',
                                     calendar=calendar))
    cube.add_dim_coord(time_coord, 0)
    return cube


calendar = 'all_leap'
#calendar = '366_day'

cube = make_cube(calendar)
add_day_of_year(cube, 'time')
points = cube.coord('day_of_year').points
expected_points = np.array(list(range(360, 367)) + list(range(1, 4)))
print(points)
print(points == expected_points)

Representing measurement conditions

When considering many atmospheric measurements it is important to know if it was made in 'ambient conditions' or 'standard temperature and pressure' conditions.

I've seen many ways these might be represented in the units of a measurement, for example: 'per std cc' or 'cm-3 at stp'. I think I'm right in saying that the CF-conventions don't have anything to say on the matter, but I wonder if this is something that this library could help take care of?

Even if it's just in the form of a flag to indicate if the measurement represents ambient conditions or not. If you think it would be in the scope of cf_units I could try and propose something more concrete in a pull request.

Problem with unit convertion with calendar='360_day'

Python 2.7.12 | Met Office - SciTools | (default, Sep 22 2016, 17:01:57) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cf_units
>>> my_unit = cf_units.Unit('years', calendar='360_day')
>>> print my_unit.convert(1, 'seconds')
31556925.9747
>>> 

Shouldn't this be 60 * 60 * 24 * 360 = 31104000?

setup.py imports numpy, but numpy is an install time dependency

The setup.py file imports numpy which is an installation dependency. Because installation order cannot be specified (in order to ensure numpy is installed first), any package that depends on cf-units may also fail to install because numpy may not exist.

To reproduce the problem create a fresh virtualenv and run pip install cf-units which will result in:

pip install cf-units
Collecting cf-units
  Using cached https://files.pythonhosted.org/packages/ae/31/d803fd21a960db0cd9d03fd134e3551dfc96a8536956d8309caa4f44db90/cf-units-2.0.2.tar.gz
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-build-1f2to47t/cf-units/setup.py", line 7, in <module>
        import numpy as np
    ModuleNotFoundError: No module named 'numpy'
    
    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-1f2to47t/cf-units/

Therefore, cf-units is effectively broken for the standard python tool chain.

Tarball MD5 Checksums are Unstable

@pelson At Spack (an auto-installer), we use MD5 checksums to verify the integrity of downloaded tarballs before we installed. We're having trouble with cf_units because its MD5 checksums are not stable. Would you be able to please take a look at spack/spack#7937 and see if there' something that could be done about it on the cf_units end?

Rounding error in julian_day2date

Giving a minimal example,

from cf_units import julian_day2date
julian_day2date(2450022.5, "standard")

gives output,

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/povey/bin/anaconda3/lib/python3.5/site-packages/cf_units/__init__.py", line 593, in julian_day2date
    return netcdftime.DateFromJulianDay(julian_day, calendar)
  File "/home/povey/bin/anaconda3/lib/python3.5/site-packages/netcdftime/netcdftime.py", line 371, in DateFromJulianDay
    minute[0], second[0], microsecond[0])
ValueError: day is out of range for month

I'm using cf_units 1.1.3 for python 3.5 through conda-forge.

Cython?

It might tidy things up a bit to use Cython for the bindings to UDUNITS.

It might also enable the path to UDUNITS to be baked in at compile time, thus avoiding the need for configuration when using conda.

I believe @marqh has done some prior experimenting in this space.

Unicode character issue with unicode units (e.g. cm²)

According to the udunits grammar, superscript characters are supported (who knew!).

$ udunits2 -H m*m -W cm²
    1 m*m = 10000 cm²
    x/cm² = 10000*(x/m*m)

Looks like this isn't supported in cf_units though:

>>> cf_units.Unit('cm²').symbol
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/pelson/dev/scitools/cf-units/cf_units/__init__.py", line 844, in __init__
    ut_unit = _ud.parse(_ud_system, unit.encode('ascii'), UT_ASCII)
UnicodeEncodeError: 'ascii' codec can't encode character '\xb2' in position 2: ordinal not in range(128)

That encode('ascii') is looking pretty shaky here...

FWIW, this is quite an esoteric issue - I only found this by studying the UDUNITS grammar carefully - I haven't found this in the wild.

netcdf4 1.2.7 breaks date comparison for some calendars

SciTools/Iris has cf_units as dependency. The versions 1.9.2, 1.10, 1.11 on the conda-forge channel use netcdf4 1.2.7 and date comparison is broken for some calendars, see below.

Iris 1.12 uses netcdt4 1.2.4 and the tests below succeed.

"""test_netcdf4_date_comparisons.py """
from datetime import datetime

from iris.time import PartialDateTime
import cf_units
import pytest


class Test_comparison_with_netcdftime():

    @pytest.mark.parametrize(
        'calendar',
        ['gregorian', 'standard', 'proleptic_gregorian', '360_day', 'julian',
         'noleap', '365_day', 'all_leap', '366_day']
    )
    def test_datetime(self, calendar):
        unit = 'days since 2000-01-01 00:00'
        time_unit = cf_units.Unit(unit, calendar)
        assert time_unit.num2date(10) < datetime(2001, 1, 1)


    @pytest.mark.parametrize(
        'calendar',
        ['gregorian', 'standard', 'proleptic_gregorian', '360_day', 'julian',
         'noleap', '365_day', 'all_leap', '366_day']
    )
    def test_partialdatetime(self, calendar):
        unit = 'days since 2000-01-01 00:00'
        time_unit = cf_units.Unit(unit, calendar)
        assert time_unit.num2date(10) < PartialDateTime(year=2001, month=1, day=1)
> py.test --tb=native test_netcdf4_date_comparisons.py 
============================================================================================== test session starts ===============================================================================================
platform linux2 -- Python 2.7.13, pytest-2.9.2, py-1.4.32, pluggy-0.3.1
rootdir: /data/local/tvoigt/autoassess_upgrade, inifile: 
plugins: xdist-1.15.0, cov-2.4.0
collected 18 items 

tests/test_netcdf4_date_comparisons.py ...FFFFFF...FFFFFF

==================================================================================================== FAILURES ====================================================================================================
_____________________________________________________________________________ Test_comparison_with_netcdftime.test_datetime[360_day] _____________________________________________________________________________
Traceback (most recent call last):
  File "/data/local/tvoigt/autoassess_upgrade/tests/test_netcdf4_date_comparisons.py", line 18, in test_datetime
    assert time_unit.num2date(10) < datetime(2001, 1, 1)
  File "netcdftime/_netcdftime.pyx", line 1292, in netcdftime._netcdftime.datetime.__richcmp__ (netcdftime/_netcdftime.c:23305)
TypeError: cannot compare netcdftime._netcdftime.Datetime360Day(2000, 1, 11, 0, 0, 0, 0, -1, 11) and datetime.datetime(2001, 1, 1, 0, 0) (different calendars)
_____________________________________________________________________________ Test_comparison_with_netcdftime.test_datetime[julian] ______________________________________________________________________________
Traceback (most recent call last):
  File "/data/local/tvoigt/autoassess_upgrade/tests/test_netcdf4_date_comparisons.py", line 18, in test_datetime
    assert time_unit.num2date(10) < datetime(2001, 1, 1)
  File "netcdftime/_netcdftime.pyx", line 1292, in netcdftime._netcdftime.datetime.__richcmp__ (netcdftime/_netcdftime.c:23305)
TypeError: cannot compare netcdftime._netcdftime.DatetimeJulian(2000, 1, 11, 0, 0, 0, 0, -1, 1) and datetime.datetime(2001, 1, 1, 0, 0) (different calendars)
_____________________________________________________________________________ Test_comparison_with_netcdftime.test_datetime[noleap] ______________________________________________________________________________
Traceback (most recent call last):
  File "/data/local/tvoigt/autoassess_upgrade/tests/test_netcdf4_date_comparisons.py", line 18, in test_datetime
    assert time_unit.num2date(10) < datetime(2001, 1, 1)
  File "netcdftime/_netcdftime.pyx", line 1292, in netcdftime._netcdftime.datetime.__richcmp__ (netcdftime/_netcdftime.c:23305)
TypeError: cannot compare netcdftime._netcdftime.DatetimeNoLeap(2000, 1, 11, 0, 0, 0, 0, 3, 11) and datetime.datetime(2001, 1, 1, 0, 0) (different calendars)
_____________________________________________________________________________ Test_comparison_with_netcdftime.test_datetime[365_day] _____________________________________________________________________________
Traceback (most recent call last):
  File "/data/local/tvoigt/autoassess_upgrade/tests/test_netcdf4_date_comparisons.py", line 18, in test_datetime
    assert time_unit.num2date(10) < datetime(2001, 1, 1)
  File "netcdftime/_netcdftime.pyx", line 1292, in netcdftime._netcdftime.datetime.__richcmp__ (netcdftime/_netcdftime.c:23305)
TypeError: cannot compare netcdftime._netcdftime.DatetimeNoLeap(2000, 1, 11, 0, 0, 0, 0, 3, 11) and datetime.datetime(2001, 1, 1, 0, 0) (different calendars)
____________________________________________________________________________ Test_comparison_with_netcdftime.test_datetime[all_leap] _____________________________________________________________________________
Traceback (most recent call last):
  File "/data/local/tvoigt/autoassess_upgrade/tests/test_netcdf4_date_comparisons.py", line 18, in test_datetime
    assert time_unit.num2date(10) < datetime(2001, 1, 1)
  File "netcdftime/_netcdftime.pyx", line 1292, in netcdftime._netcdftime.datetime.__richcmp__ (netcdftime/_netcdftime.c:23305)
TypeError: cannot compare netcdftime._netcdftime.DatetimeAllLeap(2000, 1, 11, 0, 0, 0, 0, 5, 11) and datetime.datetime(2001, 1, 1, 0, 0) (different calendars)
_____________________________________________________________________________ Test_comparison_with_netcdftime.test_datetime[366_day] _____________________________________________________________________________
Traceback (most recent call last):
  File "/data/local/tvoigt/autoassess_upgrade/tests/test_netcdf4_date_comparisons.py", line 18, in test_datetime
    assert time_unit.num2date(10) < datetime(2001, 1, 1)
  File "netcdftime/_netcdftime.pyx", line 1292, in netcdftime._netcdftime.datetime.__richcmp__ (netcdftime/_netcdftime.c:23305)
TypeError: cannot compare netcdftime._netcdftime.DatetimeAllLeap(2000, 1, 11, 0, 0, 0, 0, 5, 11) and datetime.datetime(2001, 1, 1, 0, 0) (different calendars)
_________________________________________________________________________ Test_comparison_with_netcdftime.test_partialdatetime[360_day] __________________________________________________________________________
Traceback (most recent call last):
  File "/data/local/tvoigt/autoassess_upgrade/tests/test_netcdf4_date_comparisons.py", line 29, in test_partialdatetime
    assert time_unit.num2date(10) < PartialDateTime(year=2001, month=1, day=1)
  File "netcdftime/_netcdftime.pyx", line 1295, in netcdftime._netcdftime.datetime.__richcmp__ (netcdftime/_netcdftime.c:23410)
TypeError: cannot compare netcdftime._netcdftime.Datetime360Day(2000, 1, 11, 0, 0, 0, 0, -1, 11) and PartialDateTime(year=2001, month=1, day=1)
__________________________________________________________________________ Test_comparison_with_netcdftime.test_partialdatetime[julian] __________________________________________________________________________
Traceback (most recent call last):
  File "/data/local/tvoigt/autoassess_upgrade/tests/test_netcdf4_date_comparisons.py", line 29, in test_partialdatetime
    assert time_unit.num2date(10) < PartialDateTime(year=2001, month=1, day=1)
  File "netcdftime/_netcdftime.pyx", line 1295, in netcdftime._netcdftime.datetime.__richcmp__ (netcdftime/_netcdftime.c:23410)
TypeError: cannot compare netcdftime._netcdftime.DatetimeJulian(2000, 1, 11, 0, 0, 0, 0, -1, 1) and PartialDateTime(year=2001, month=1, day=1)
__________________________________________________________________________ Test_comparison_with_netcdftime.test_partialdatetime[noleap] __________________________________________________________________________
Traceback (most recent call last):
  File "/data/local/tvoigt/autoassess_upgrade/tests/test_netcdf4_date_comparisons.py", line 29, in test_partialdatetime
    assert time_unit.num2date(10) < PartialDateTime(year=2001, month=1, day=1)
  File "netcdftime/_netcdftime.pyx", line 1295, in netcdftime._netcdftime.datetime.__richcmp__ (netcdftime/_netcdftime.c:23410)
TypeError: cannot compare netcdftime._netcdftime.DatetimeNoLeap(2000, 1, 11, 0, 0, 0, 0, 3, 11) and PartialDateTime(year=2001, month=1, day=1)
_________________________________________________________________________ Test_comparison_with_netcdftime.test_partialdatetime[365_day] __________________________________________________________________________
Traceback (most recent call last):
  File "/data/local/tvoigt/autoassess_upgrade/tests/test_netcdf4_date_comparisons.py", line 29, in test_partialdatetime
    assert time_unit.num2date(10) < PartialDateTime(year=2001, month=1, day=1)
  File "netcdftime/_netcdftime.pyx", line 1295, in netcdftime._netcdftime.datetime.__richcmp__ (netcdftime/_netcdftime.c:23410)
TypeError: cannot compare netcdftime._netcdftime.DatetimeNoLeap(2000, 1, 11, 0, 0, 0, 0, 3, 11) and PartialDateTime(year=2001, month=1, day=1)
_________________________________________________________________________ Test_comparison_with_netcdftime.test_partialdatetime[all_leap] _________________________________________________________________________
Traceback (most recent call last):
  File "/data/local/tvoigt/autoassess_upgrade/tests/test_netcdf4_date_comparisons.py", line 29, in test_partialdatetime
    assert time_unit.num2date(10) < PartialDateTime(year=2001, month=1, day=1)
  File "netcdftime/_netcdftime.pyx", line 1295, in netcdftime._netcdftime.datetime.__richcmp__ (netcdftime/_netcdftime.c:23410)
TypeError: cannot compare netcdftime._netcdftime.DatetimeAllLeap(2000, 1, 11, 0, 0, 0, 0, 5, 11) and PartialDateTime(year=2001, month=1, day=1)
_________________________________________________________________________ Test_comparison_with_netcdftime.test_partialdatetime[366_day] __________________________________________________________________________
Traceback (most recent call last):
  File "/data/local/tvoigt/autoassess_upgrade/tests/test_netcdf4_date_comparisons.py", line 29, in test_partialdatetime
    assert time_unit.num2date(10) < PartialDateTime(year=2001, month=1, day=1)
  File "netcdftime/_netcdftime.pyx", line 1295, in netcdftime._netcdftime.datetime.__richcmp__ (netcdftime/_netcdftime.c:23410)
TypeError: cannot compare netcdftime._netcdftime.DatetimeAllLeap(2000, 1, 11, 0, 0, 0, 0, 5, 11) and PartialDateTime(year=2001, month=1, day=1)
====================================================================================== 12 failed, 6 passed in 0.47 seconds =======================================================================================


>   ???
E   TypeError: cannot compare netcdftime._netcdftime.DatetimeAllLeap(2000, 1, 11, 0, 0, 0, 0, 5, 11) and datetime.datetime(2001, 1, 1, 0, 0) (different calendars)

New CLA and relicensing cf-units from LGPL to BSD-3

I've been working through the details of relicensing cf-units (see also SciTools/scitools.org.uk#209) from LGPL to BSD-3. The biggest driver for this comes from (often ill-informed) comments regarding the L in [L]GPL - I don't want to dwell on the accuracy the comments... it is what it is.

At the same time, re-licensing cf-units requires an update to the SciTools CLA (it explicitly names LGPL, as was the style in 2010...). Fortunately, I've also streamlined the CLA signing process (which used to be horribly clunky and manual, and is now replaced with a single web form).

I'm not a lawyer™️ , but my synopsis of the new CLA reads:

  • All contributions you make to cf-units remain your own (but you grant an irrevocable license for cf-units to use your contribution)
  • At any point in the future cf-units (and therefore your contributions) can be re-licensed to any other OSI approved license

(Please feel free to comment here if you believe I may be miss-representing it, it wasn't intentional!)

So with all of this said, please may I ask you to consider signing v4 of the SciTools CLA at https://scitools.org.uk/cla/v4/form:

Inevitably there will be some who have contributed to cf-units who are no longer contactable, or who are not prepared to sign the CLA. In this situation, we will have to asses the impact of either carrying the risk of having unlicensed contributions vs reverting those contributions from cf-units.

FWIW All Met Office contributions are already made under the terms of the v4 CLA, but it would significantly help with transparency if all Met Office contributors could sign the new CLA also (please).

cfunits package confusion

The cfunits package is extremely similarly named to this one, and apparently has a purpose in common.

In particular, one major difference is cfunits' changes to the standard udunits definitions:

find *.nonCF -exec sh -c 'echo $0; diff -u "$0" "${0:0:${#0}-6}"' {} \; 
udunits2-accepted.xml.nonCF
--- udunits2-accepted.xml.nonCF	2018-04-30 17:22:48.171105000 +0100
+++ udunits2-accepted.xml	2018-04-30 17:22:48.168105000 +0100
@@ -188,9 +188,11 @@
             <def>cGy</def>
             <aliases> <name><singular>rad</singular></name> </aliases>
         </unit>
-        -->
+        --> 
+        <!-- 'rem' is changed from 'cSv' since 'Sv' has been reassigned to sverdrup for CF
+	-->
         <unit>
-            <def>cSv</def>
+            <def>0.01 sievert</def>
             <aliases>
                 <name><singular>rem</singular></name>
             </aliases>
udunits2-common.xml.nonCF
--- udunits2-common.xml.nonCF	2018-04-30 17:22:48.177098000 +0100
+++ udunits2-common.xml	2018-04-30 17:22:48.175099000 +0100
@@ -877,10 +877,10 @@
             <def>1e6 m^3/s</def>			<!-- exact -->
             <aliases>
                 <name> <singular>sverdrup</singular> </name>
-                <!-- The following is commented-out because "Sv" means
-                     "sievert" in the SI unit-system.
-                <symbol>Sv</symbol>
+                <!-- The following is not commented-out, thereby overriding "Sv" meaning
+                     "sievert" in the SI unit-system, more useful to CF.
                 -->
+                <symbol>Sv</symbol>
             </aliases>
         </unit>
 
@@ -1637,4 +1637,71 @@
                 <symbol>DU</symbol>
             </aliases>
         </unit>
+    <!-- Units useful to CF -->
+       <unit>
+            <def>1e-3</def>		<!-- exact -->
+            <aliases>
+                <name>
+                    <singular>practical_salinity_unit</singular>
+                    <plural>practical_salinity_units</plural>
+                </name>
+                <symbol>psu</symbol>
+            </aliases>
+        </unit>
+        <unit>
+            <def>calendar_year/12</def>		<!-- exact -->
+            <aliases>
+                <name>
+                    <singular>calendar_month</singular>
+                </name>
+                <symbol>cM</symbol>
+            </aliases>
+        </unit>
+        <unit>
+            <def>1</def>		<!-- exact -->
+            <aliases>
+                <name>
+                    <singular>level</singular>
+                    <plural>levels</plural>
+                </name>
+            </aliases>
+        </unit>
+       <unit>
+            <def>1</def>		<!-- exact -->
+            <aliases>
+                <name>
+                    <singular>layer</singular>
+                    <plural>layers</plural>
+                </name>
+            </aliases>
+        </unit>
+        <unit>
+            <def>1</def>		<!-- exact -->
+            <aliases>
+                <name>
+                    <singular>sigma_level</singular>
+                    <plural>sigma_levels</plural>
+                </name>
+            </aliases>
+        </unit>
+        <unit>
+            <def>1</def>		<!-- exact -->
+            <aliases>
+                <name>
+                    <singular>decibel</singular>
+                    <plural>decibels</plural>
+                </name>
+		<symbol>dB</symbol>
+            </aliases>
+        </unit>
+        <unit>
+            <def>10 dB</def>		<!-- exact -->
+            <aliases>
+                <name>
+                    <singular>bel</singular>
+                    <plural>bels</plural>
+                </name>
+            </aliases>
+        </unit>
+
 </unit-system>
udunits2-derived.xml.nonCF
--- udunits2-derived.xml.nonCF	2018-04-30 17:22:48.181097000 +0100
+++ udunits2-derived.xml	2018-04-30 17:22:48.179100000 +0100
@@ -137,7 +137,10 @@
             <def>J/kg</def>
             <aliases>
                 <name><singular>sievert</singular></name>
+		<!-- The following is commented-out, allowing "Sv" to mean
+                     "sverdrup", more useful to CF.
                 <symbol>Sv</symbol>
+		-->
             </aliases>
         </unit>
 </unit-system>

Creating a cf_units.Array

Given how much better numpy is at allowing arrays to be subclassed than it used to be, I wonder if we should consider doing so for this package...

Proposed API:

>>> import numpy as np
>>> import cf_units

# Unit is a *mandatory* keyword only kwarg.
>>> x = cf_units.Array(np.arange(10), unit='meters')
>>> y = cf_units.Array(np.arange(10), unit='meters')

>>> print(x)
[0 1 2 3 4 5 6 7 8 9] m

>>> print(repr(x))
cf_units.Array([0 1 2 3 4 5 6 7 8 9], unit='meters')

>>> print(f'{x.mean()}{x.units}')
4.5m

>>> print(x * y)
[ 0,  1,  4,  9, 16, 25, 36, 49, 64, 81] m2

>>> print(type(x*y))
cf_units.Array

The challenge with implementing this appears to be in figuring out a scheme that works for both np.ndarray and da.ndarray.

cc @dopplershift as somebody with history here 😉

dummy_issue

Just for testing project + teams permissions ..

Release v1.1.0

There are a few commits since v1.0.0: v1.0.0...master
I've created a v1.1.0 milestone. All we need to do is tag the release (we have versioneer on our side now) and push some docs somewhere(?).

conda-forge cf-units 2.0.2

We need to push cf-units version 2.0.2 to conda-forge and deal with the name change.

This will impact iris.

Custom html in README

I'm concerned at the nature of the custom html added to the README. As per my review of the iris-grib README update, the changes have introduced accessibility problems and some questionable stylistic changes, arguably without adding anything beneficial to the README as was.

For the sake of having everything left-aligned, we could have an equivalent README written in pure markdown with no custom html. We should also drop the title-masquerading-as-hyperlink business and just include an explicit link to the cf-units docs in the README body - doing so will be much more accessible and clear.

Note: I do not disagree with updating the README to use markdown - that's definitely a positive step 👍

Docs

Copy all documentation related to units here.

CF valid units that are not in UDUNITS

The CF FAQ page says:

There are two units acceptable to CF that are not in the UDUNITS library: sverdrup, and decibel or dB. These have been requested for inclusion in future versions of the UDUNITS library.

Looks like "sverdrup" is already in UDUNITS-2. "decibel" and "dB" are not. There is an open request to add it (Unidata/UDUNITS-2#33), but the discussion there suggests this may not be possible in a generic way, i.e. without specifying a reference value.

Would it be possible to get cf_units to recognise "dB" and "decibel" (as effectively dimensionless units), independently of UDUNITS?

360 day calendar converting 1 hour to 59 minutes and 59 seconds

Converting 1 hour to a date using num2date gives different results depending on the calendar:

>>> import cf_units
>>> unit_gregorian = cf_units.Unit('hours since 1970-01-01 00:00:00', calendar='gregorian')
>>> print(unit_gregorian.num2date(1))
1970-01-01 01:00:00
>>> unit_360 = cf_units.Unit('hours since 1970-01-01 00:00:00', calendar='360_day')
>>> print(unit_360.num2date(1))
1970-01-01 00:59:59

I'd expect the behaviour from the 360 day calendar to be consistent with that of the gregorian calendar.

Update: I see the correct behaviour with netCDF4-python v1.0.2, but the incorrect behaviour with netCDF4-python v1.2.1, so this may be an issue with the underlying library.

In-place conversions

The documentation for convert states conversions are done in-place: https://github.com/SciTools/cf_units/blob/514872eaeafc4bfc884717d5914defe4776218f1/cf_units/__init__.py#L1896.

However, this is not the case following from TestInPlace: https://github.com/SciTools/cf_units/blob/3719aaff799f281573879e03d2b23fbef60af356/cf_units/tests/test_unit.py#L885.

Does "in-place" refer to the array manipulations inside of convert? Is there an interest in adding an inplace=True argument to convert?

Thanks!

Install documentation and Python 3 support

Currently INSTALL says that cf-units is not compatible with Python 3. Looking at the code and travis builds, it looks like that's no longer the case, and that the install documentation should be updated.

Can cf-units be installed with conda-forge on Python 3? I tried and it looks like it's unavailable there.

Rename the package

@ChrisBarker-NOAA let s move the discussion here.

Maybe "cf_units" it's all about CF, but theoretically only used by Iris, rather than the other way around. But I don't care, really. Good to have "units" in the name, so people will find it.

I like cf_units. @rsignell-usgs what do you think? However, it has to be a name that iris devs are fine with. The goal is to aggregate efforts in one package instead of fragmenting it.

@ocefpaf : maybe udinits2 could be built-in, rather then kept as a separate package. It would make it harder to build, but then it would be only one package to manage.

Right now, we have udunits2 on conda for Linux, Windows and Mac (thanks to you 😄 ), so that is not a big issue. Also, my Linux packager side is biased against it... I like to see small packages with proper dependencies 😁

cf_units breaks day_of_year for 360_day calendars

Here's the problem :

>>> import cf_units
>>> import netcdftime
>>> nc_calendar_360day = netcdftime.utime('hours since 1970-01-01', calendar='360_day')
>>> cf_unit_360day = cf_units.Unit('hours since 1970-01-01', calendar='360_day')
>>> print nc_calendar_360day.num2date(232560.5).timetuple()
(1996, 12, 1, 0, 30, 0, -1, 331, -1)
>>> print cf_unit_360day.num2date(232560.5).timetuple()
(1996, 12, 1, 0, 30, 0, -1, 1, -1)
>>> 

Those two answers ought to be the same,
( especially as the time-of-day is nowhere near midnight )

The basic problem is that this call is not in fact a suitable object constructor call : the netcdftime.datetime.__init__() interface seems designed only for object copying, and an unspecified day-of-year defaults to 1 rather than being calculated from date + calendar as you might reasonably expect.

It's a wee bit awkward because there is no real API specced for these classes :-(
It's a live issue : Unidata/cftime#3

Testing with Iris 2.0

We need to dig into the following before cutting cf-units version 2.0.0...

======================================================================
ERROR: test_circular_subset (iris.tests.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestAreaWeightedRegrid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 532, in test_circular_subset
    res = regrid_area_weighted(src, dest)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_cross_section (iris.tests.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestAreaWeightedRegrid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 438, in test_cross_section
    res = regrid_area_weighted(src, dest)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_global_data_increase_res (iris.tests.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestAreaWeightedRegrid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 484, in test_global_data_increase_res
    res = regrid_area_weighted(src, dest)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_global_data_reduce_res (iris.tests.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestAreaWeightedRegrid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 475, in test_global_data_reduce_res
    res = regrid_area_weighted(src, dest)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_global_data_same_res (iris.tests.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestAreaWeightedRegrid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 492, in test_global_data_same_res
    res = regrid_area_weighted(src, src)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_global_data_subset (iris.tests.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestAreaWeightedRegrid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 512, in test_global_data_subset
    res = regrid_area_weighted(src, dest)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_hybrid_height (iris.tests.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestAreaWeightedRegrid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 368, in test_hybrid_height
    res = regrid_area_weighted(src, dest)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_missing_data (iris.tests.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestAreaWeightedRegrid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 376, in test_missing_data
    res = regrid_area_weighted(src, dest)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_no_x_overlap (iris.tests.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestAreaWeightedRegrid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 387, in test_no_x_overlap
    res = regrid_area_weighted(src, dest)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_no_y_overlap (iris.tests.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestAreaWeightedRegrid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 396, in test_no_y_overlap
    res = regrid_area_weighted(src, dest)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_non_circular_subset (iris.tests.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestAreaWeightedRegrid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 553, in test_non_circular_subset
    res = regrid_area_weighted(src, dest)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_one_point (iris.tests.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestAreaWeightedRegrid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 414, in test_one_point
    res = regrid_area_weighted(src, dest)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_regrid_latlon_reduced_res (iris.tests.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestAreaWeightedRegrid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 327, in test_regrid_latlon_reduced_res
    res = regrid_area_weighted(src, dest)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_regrid_lon_to_half_res (iris.tests.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestAreaWeightedRegrid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 347, in test_regrid_lon_to_half_res
    res = regrid_area_weighted(src, dest)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_regrid_to_higher_res (iris.tests.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestAreaWeightedRegrid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 362, in test_regrid_to_higher_res
    res = regrid_area_weighted(src, dest)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_regrid_to_non_int_frac (iris.tests.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestAreaWeightedRegrid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 355, in test_regrid_to_non_int_frac
    res = regrid_area_weighted(src, dest)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_regrid_to_same_grid (iris.tests.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestAreaWeightedRegrid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 249, in test_regrid_to_same_grid
    res = regrid_area_weighted(src, src)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_regrid_transposed (iris.tests.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestAreaWeightedRegrid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 335, in test_regrid_transposed
    res = regrid_area_weighted(src, dest)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_scalar (iris.tests.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestAreaWeightedRegrid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 404, in test_scalar
    res = regrid_area_weighted(src, dest)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_scalar_source_cube (iris.tests.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestAreaWeightedRegrid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 460, in test_scalar_source_cube
    res = regrid_area_weighted(src, dest)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_ten_by_ten_subset (iris.tests.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestAreaWeightedRegrid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 424, in test_ten_by_ten_subset
    res = regrid_area_weighted(src, dest)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_area_in_far_north (iris.tests.unit.analysis.cartography.test__quadrant_area.TestExampleCases)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test__quadrant_area.py", line 55, in test_area_in_far_north
    lats, lons = self._as_bounded_coords([70, 80], [0, 10])
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test__quadrant_area.py", line 46, in _as_bounded_coords
    return (self._radian_bounds(lats, dtype=dtype),
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test__quadrant_area.py", line 43, in _radian_bounds
    return degrees.convert(bound_deg, radians)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_area_in_far_south (iris.tests.unit.analysis.cartography.test__quadrant_area.TestExampleCases)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test__quadrant_area.py", line 60, in test_area_in_far_south
    lats, lons = self._as_bounded_coords([-80, -70], [0, 10])
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test__quadrant_area.py", line 46, in _as_bounded_coords
    return (self._radian_bounds(lats, dtype=dtype),
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test__quadrant_area.py", line 43, in _radian_bounds
    return degrees.convert(bound_deg, radians)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_area_in_north (iris.tests.unit.analysis.cartography.test__quadrant_area.TestExampleCases)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test__quadrant_area.py", line 50, in test_area_in_north
    lats, lons = self._as_bounded_coords([0, 10], [0, 10])
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test__quadrant_area.py", line 46, in _as_bounded_coords
    return (self._radian_bounds(lats, dtype=dtype),
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test__quadrant_area.py", line 43, in _radian_bounds
    return degrees.convert(bound_deg, radians)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_area_in_north_with_reversed_lats (iris.tests.unit.analysis.cartography.test__quadrant_area.TestExampleCases)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test__quadrant_area.py", line 65, in test_area_in_north_with_reversed_lats
    lats, lons = self._as_bounded_coords([10, 0], [0, 10])
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test__quadrant_area.py", line 46, in _as_bounded_coords
    return (self._radian_bounds(lats, dtype=dtype),
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test__quadrant_area.py", line 43, in _radian_bounds
    return degrees.convert(bound_deg, radians)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_area_multiple_lats (iris.tests.unit.analysis.cartography.test__quadrant_area.TestExampleCases)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test__quadrant_area.py", line 71, in test_area_multiple_lats
    [0, 10])
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test__quadrant_area.py", line 46, in _as_bounded_coords
    return (self._radian_bounds(lats, dtype=dtype),
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test__quadrant_area.py", line 43, in _radian_bounds
    return degrees.convert(bound_deg, radians)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_area_multiple_lats_and_lons (iris.tests.unit.analysis.cartography.test__quadrant_area.TestExampleCases)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test__quadrant_area.py", line 80, in test_area_multiple_lats_and_lons
    [[0, 10], [10, 30]])
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test__quadrant_area.py", line 46, in _as_bounded_coords
    return (self._radian_bounds(lats, dtype=dtype),
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test__quadrant_area.py", line 43, in _radian_bounds
    return degrees.convert(bound_deg, radians)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_symmetric_32_bit (iris.tests.unit.analysis.cartography.test__quadrant_area.TestExampleCases)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test__quadrant_area.py", line 99, in test_symmetric_32_bit
    dtype=np.float32)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test__quadrant_area.py", line 46, in _as_bounded_coords
    return (self._radian_bounds(lats, dtype=dtype),
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test__quadrant_area.py", line 43, in _radian_bounds
    return degrees.convert(bound_deg, radians)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_symmetric_64_bit (iris.tests.unit.analysis.cartography.test__quadrant_area.TestExampleCases)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test__quadrant_area.py", line 91, in test_symmetric_64_bit
    dtype=np.float64)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test__quadrant_area.py", line 46, in _as_bounded_coords
    return (self._radian_bounds(lats, dtype=dtype),
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test__quadrant_area.py", line 43, in _radian_bounds
    return degrees.convert(bound_deg, radians)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_broadcast_cubes (iris.tests.unit.analysis.stats.test_pearsonr.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/stats/test_pearsonr.py", line 46, in setUp
    self.weights = iris.analysis.cartography.area_weights(cube_temp)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_broadcast_cubes_weighted (iris.tests.unit.analysis.stats.test_pearsonr.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/stats/test_pearsonr.py", line 46, in setUp
    self.weights = iris.analysis.cartography.area_weights(cube_temp)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_common_mask_broadcast (iris.tests.unit.analysis.stats.test_pearsonr.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/stats/test_pearsonr.py", line 46, in setUp
    self.weights = iris.analysis.cartography.area_weights(cube_temp)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_common_mask_simple (iris.tests.unit.analysis.stats.test_pearsonr.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/stats/test_pearsonr.py", line 46, in setUp
    self.weights = iris.analysis.cartography.area_weights(cube_temp)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_compatible_cubes (iris.tests.unit.analysis.stats.test_pearsonr.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/stats/test_pearsonr.py", line 46, in setUp
    self.weights = iris.analysis.cartography.area_weights(cube_temp)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_compatible_cubes_weighted (iris.tests.unit.analysis.stats.test_pearsonr.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/stats/test_pearsonr.py", line 46, in setUp
    self.weights = iris.analysis.cartography.area_weights(cube_temp)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_incompatible_cubes (iris.tests.unit.analysis.stats.test_pearsonr.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/stats/test_pearsonr.py", line 46, in setUp
    self.weights = iris.analysis.cartography.area_weights(cube_temp)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_mdtol (iris.tests.unit.analysis.stats.test_pearsonr.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/stats/test_pearsonr.py", line 46, in setUp
    self.weights = iris.analysis.cartography.area_weights(cube_temp)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_non_existent_coord (iris.tests.unit.analysis.stats.test_pearsonr.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/stats/test_pearsonr.py", line 46, in setUp
    self.weights = iris.analysis.cartography.area_weights(cube_temp)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_perfect_corr (iris.tests.unit.analysis.stats.test_pearsonr.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/stats/test_pearsonr.py", line 46, in setUp
    self.weights = iris.analysis.cartography.area_weights(cube_temp)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_perfect_corr_all_dims (iris.tests.unit.analysis.stats.test_pearsonr.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/stats/test_pearsonr.py", line 46, in setUp
    self.weights = iris.analysis.cartography.area_weights(cube_temp)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_weight_error (iris.tests.unit.analysis.stats.test_pearsonr.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/stats/test_pearsonr.py", line 46, in setUp
    self.weights = iris.analysis.cartography.area_weights(cube_temp)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_preserves_lazy (iris.tests.unit.coords.test_AuxCoord.Test_convert_units)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/coords/test_AuxCoord.py", line 621, in test_preserves_lazy
    test_points_ft = Unit('m').convert(test_points, 'ft')
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_preserves_lazy (iris.tests.unit.cube.test_Cube.Test_convert_units)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/cube/test_Cube.py", line 1719, in test_preserves_lazy
    real_data_ft = Unit('m').convert(real_data, 'ft')
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_boolean_mask (iris.tests.unit.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestMdtol)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 123, in test_boolean_mask
    res = regrid(self.src_cube, self.grid_cube, mdtol=0.9)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_default (iris.tests.unit.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestMdtol)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 67, in test_default
    res = regrid(self.src_cube, self.grid_cube)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_fraction_below_min (iris.tests.unit.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestMdtol)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 100, in test_fraction_below_min
    res = regrid(self.src_cube, self.grid_cube, mdtol=mdtol)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_fraction_between_min_and_max (iris.tests.unit.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestMdtol)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 110, in test_fraction_between_min_and_max
    res = regrid(self.src_cube, self.grid_cube, mdtol=mdtol)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_one (iris.tests.unit.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestMdtol)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 79, in test_one
    res = regrid(self.src_cube, self.grid_cube, mdtol=1)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_scalar_no_overlap (iris.tests.unit.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestMdtol)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 131, in test_scalar_no_overlap
    res = regrid(src_cube, grid_cube, mdtol=0.8)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_scalar_with_overlap_above_mdtol (iris.tests.unit.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestMdtol)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 149, in test_scalar_with_overlap_above_mdtol
    res = regrid(src_cube, grid_cube, mdtol=0.4)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_scalar_with_overlap_below_mdtol (iris.tests.unit.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestMdtol)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 140, in test_scalar_with_overlap_below_mdtol
    res = regrid(src_cube, grid_cube, mdtol=0.6)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_src_not_masked_array (iris.tests.unit.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestMdtol)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 118, in test_src_not_masked_array
    res = regrid(self.src_cube, self.grid_cube, mdtol=0.9)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_zero (iris.tests.unit.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestMdtol)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 73, in test_zero
    res = regrid(self.src_cube, self.grid_cube, mdtol=0)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_float_tolerant_equality (iris.tests.unit.experimental.regrid.test_regrid_area_weighted_rectilinear_src_and_grid.TestWrapAround)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/experimental/regrid/test_regrid_area_weighted_rectilinear_src_and_grid.py", line 180, in test_float_tolerant_equality
    res = regrid(source, grid)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 722, in regrid_area_weighted_rectilinear_src_and_grid
    src_x_bounds = _get_bounds_in_units(src_x, x_units, dtype)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/experimental/regrid.py", line 349, in _get_bounds_in_units
    return coord.units.convert(coord.bounds.astype(dtype), units).astype(dtype)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_weighted_mean (iris.tests.test_analysis.TestAnalysisWeights)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_analysis.py", line 188, in test_weighted_mean
    area_weights = iris.analysis.cartography.area_weights(e)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_area_weights_non_adjacent (iris.tests.test_analysis.TestAreaWeightGeneration)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_analysis.py", line 763, in test_area_weights_non_adjacent
    weights = iris.analysis.cartography.area_weights(self.cube)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_area_weights_non_contiguous (iris.tests.test_analysis.TestAreaWeightGeneration)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_analysis.py", line 814, in test_area_weights_non_contiguous
    weights = iris.analysis.cartography.area_weights(cube)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_area_weights_normalized (iris.tests.test_analysis.TestAreaWeightGeneration)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_analysis.py", line 805, in test_area_weights_normalized
    normalize=True)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_area_weights_order (iris.tests.test_analysis.TestAreaWeightGeneration)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_analysis.py", line 756, in test_area_weights_order
    weights = iris.analysis.cartography.area_weights(self.cube)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_area_weights_scalar (iris.tests.test_analysis.TestAreaWeightGeneration)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_analysis.py", line 781, in test_area_weights_scalar
    weights = iris.analysis.cartography.area_weights(cube)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_area_weights_scalar_latitude (iris.tests.test_analysis.TestAreaWeightGeneration)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_analysis.py", line 769, in test_area_weights_scalar_latitude
    weights = iris.analysis.cartography.area_weights(cube)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_area_weights_scalar_longitude (iris.tests.test_analysis.TestAreaWeightGeneration)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_analysis.py", line 775, in test_area_weights_scalar_longitude
    weights = iris.analysis.cartography.area_weights(cube)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_area_weights_singleton_latitude (iris.tests.test_analysis.TestAreaWeightGeneration)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_analysis.py", line 787, in test_area_weights_singleton_latitude
    weights = iris.analysis.cartography.area_weights(cube)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_area_weights_singleton_longitude (iris.tests.test_analysis.TestAreaWeightGeneration)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_analysis.py", line 793, in test_area_weights_singleton_longitude
    weights = iris.analysis.cartography.area_weights(cube)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_area_weights_singletons (iris.tests.test_analysis.TestAreaWeightGeneration)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_analysis.py", line 799, in test_area_weights_singletons
    weights = iris.analysis.cartography.area_weights(cube)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_area_weights_std (iris.tests.test_analysis.TestAreaWeightGeneration)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_analysis.py", line 749, in test_area_weights_std
    weights = iris.analysis.cartography.area_weights(self.cube)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_area_weights (iris.tests.test_analysis.TestAreaWeights)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_analysis.py", line 726, in test_area_weights
    area_weights = iris.analysis.cartography.area_weights(small_cube)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 410, in area_weights
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_cosine_latitude_weights_2d (iris.tests.test_analysis.TestLatitudeWeightGeneration)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_analysis.py", line 933, in test_cosine_latitude_weights_2d
    self.cube_aux_lat)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 502, in cosine_latitude_weights
    if np.any(lat.points < -np.pi / 2. - threshold) or \
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 580, in _points_getter
    return self._points_dm.data.view()
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/_data_manager.py", line 216, in data
    result = as_concrete_data(self._lazy_array)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/_lazy_data.py", line 156, in as_concrete_data
    data, = _co_realise_lazy_arrays([data])
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/_lazy_data.py", line 120, in _co_realise_lazy_arrays
    computed_arrays = da.compute(*arrays)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/base.py", line 407, in compute
    results = get(dsk, keys, **kwargs)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/threaded.py", line 75, in get
    pack_exception=pack_exception, **kwargs)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/local.py", line 521, in get_async
    raise_exception(exc, tb)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/local.py", line 290, in execute_task
    result = _execute_task(task, data)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/local.py", line 271, in _execute_task
    return func(*args2)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 925, in pointwise_convert
    return old_unit.convert(values, new_unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_cosine_latitude_weights_2d_latitude_first (iris.tests.test_analysis.TestLatitudeWeightGeneration)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_analysis.py", line 943, in test_cosine_latitude_weights_2d_latitude_first
    self.cube_aux_lat)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 502, in cosine_latitude_weights
    if np.any(lat.points < -np.pi / 2. - threshold) or \
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 580, in _points_getter
    return self._points_dm.data.view()
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/_data_manager.py", line 216, in data
    result = as_concrete_data(self._lazy_array)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/_lazy_data.py", line 156, in as_concrete_data
    data, = _co_realise_lazy_arrays([data])
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/_lazy_data.py", line 120, in _co_realise_lazy_arrays
    computed_arrays = da.compute(*arrays)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/base.py", line 407, in compute
    results = get(dsk, keys, **kwargs)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/threaded.py", line 75, in get
    pack_exception=pack_exception, **kwargs)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/local.py", line 521, in get_async
    raise_exception(exc, tb)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/local.py", line 290, in execute_task
    result = _execute_task(task, data)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/local.py", line 271, in _execute_task
    return func(*args2)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 925, in pointwise_convert
    return old_unit.convert(values, new_unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_cosine_latitude_weights_2d_latitude_last (iris.tests.test_analysis.TestLatitudeWeightGeneration)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_analysis.py", line 953, in test_cosine_latitude_weights_2d_latitude_last
    self.cube_aux_lat)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 502, in cosine_latitude_weights
    if np.any(lat.points < -np.pi / 2. - threshold) or \
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 580, in _points_getter
    return self._points_dm.data.view()
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/_data_manager.py", line 216, in data
    result = as_concrete_data(self._lazy_array)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/_lazy_data.py", line 156, in as_concrete_data
    data, = _co_realise_lazy_arrays([data])
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/_lazy_data.py", line 120, in _co_realise_lazy_arrays
    computed_arrays = da.compute(*arrays)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/base.py", line 407, in compute
    results = get(dsk, keys, **kwargs)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/threaded.py", line 75, in get
    pack_exception=pack_exception, **kwargs)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/local.py", line 521, in get_async
    raise_exception(exc, tb)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/local.py", line 290, in execute_task
    result = _execute_task(task, data)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/local.py", line 271, in _execute_task
    return func(*args2)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 925, in pointwise_convert
    return old_unit.convert(values, new_unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_cosine_latitude_weights_2d_singleton1 (iris.tests.test_analysis.TestLatitudeWeightGeneration)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_analysis.py", line 909, in test_cosine_latitude_weights_2d_singleton1
    weights = iris.analysis.cartography.cosine_latitude_weights(cube)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 502, in cosine_latitude_weights
    if np.any(lat.points < -np.pi / 2. - threshold) or \
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 580, in _points_getter
    return self._points_dm.data.view()
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/_data_manager.py", line 216, in data
    result = as_concrete_data(self._lazy_array)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/_lazy_data.py", line 156, in as_concrete_data
    data, = _co_realise_lazy_arrays([data])
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/_lazy_data.py", line 120, in _co_realise_lazy_arrays
    computed_arrays = da.compute(*arrays)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/base.py", line 407, in compute
    results = get(dsk, keys, **kwargs)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/threaded.py", line 75, in get
    pack_exception=pack_exception, **kwargs)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/local.py", line 521, in get_async
    raise_exception(exc, tb)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/local.py", line 290, in execute_task
    result = _execute_task(task, data)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/local.py", line 271, in _execute_task
    return func(*args2)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 925, in pointwise_convert
    return old_unit.convert(values, new_unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_cosine_latitude_weights_2d_singleton2 (iris.tests.test_analysis.TestLatitudeWeightGeneration)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_analysis.py", line 917, in test_cosine_latitude_weights_2d_singleton2
    weights = iris.analysis.cartography.cosine_latitude_weights(cube)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 502, in cosine_latitude_weights
    if np.any(lat.points < -np.pi / 2. - threshold) or \
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 580, in _points_getter
    return self._points_dm.data.view()
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/_data_manager.py", line 216, in data
    result = as_concrete_data(self._lazy_array)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/_lazy_data.py", line 156, in as_concrete_data
    data, = _co_realise_lazy_arrays([data])
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/_lazy_data.py", line 120, in _co_realise_lazy_arrays
    computed_arrays = da.compute(*arrays)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/base.py", line 407, in compute
    results = get(dsk, keys, **kwargs)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/threaded.py", line 75, in get
    pack_exception=pack_exception, **kwargs)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/local.py", line 521, in get_async
    raise_exception(exc, tb)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/local.py", line 290, in execute_task
    result = _execute_task(task, data)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/local.py", line 271, in _execute_task
    return func(*args2)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 925, in pointwise_convert
    return old_unit.convert(values, new_unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_cosine_latitude_weights_2d_singleton3 (iris.tests.test_analysis.TestLatitudeWeightGeneration)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_analysis.py", line 925, in test_cosine_latitude_weights_2d_singleton3
    weights = iris.analysis.cartography.cosine_latitude_weights(cube)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/cartography.py", line 502, in cosine_latitude_weights
    if np.any(lat.points < -np.pi / 2. - threshold) or \
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 580, in _points_getter
    return self._points_dm.data.view()
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/_data_manager.py", line 216, in data
    result = as_concrete_data(self._lazy_array)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/_lazy_data.py", line 156, in as_concrete_data
    data, = _co_realise_lazy_arrays([data])
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/_lazy_data.py", line 120, in _co_realise_lazy_arrays
    computed_arrays = da.compute(*arrays)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/base.py", line 407, in compute
    results = get(dsk, keys, **kwargs)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/threaded.py", line 75, in get
    pack_exception=pack_exception, **kwargs)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/local.py", line 521, in get_async
    raise_exception(exc, tb)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/local.py", line 290, in execute_task
    result = _execute_task(task, data)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/dask/local.py", line 271, in _execute_task
    return func(*args2)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 925, in pointwise_convert
    return old_unit.convert(values, new_unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_cos (iris.tests.test_analysis_calculus.TestCoordTrig)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_analysis_calculus.py", line 183, in test_cos
    cos_of_coord = iris.analysis.calculus._coord_cos(self.lat)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/calculus.py", line 416, in _coord_cos
    return _trig_method(coord, np.cos)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/calculus.py", line 434, in _trig_method
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_sin (iris.tests.test_analysis_calculus.TestCoordTrig)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_analysis_calculus.py", line 168, in test_sin
    sin_of_coord = iris.analysis.calculus._coord_sin(self.lat)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/calculus.py", line 403, in _coord_sin
    return _trig_method(coord, np.sin)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/analysis/calculus.py", line 434, in _trig_method
    coord.convert_units('radians')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/coords.py", line 938, in convert_units
    new_bounds = self.units.convert(self.bounds, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 301, in cf_units._udunits2.convert_floats
    def convert_floats(Converter converter, np.ndarray[np.float32_t] in_, np.ndarray[np.float32_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
ERROR: test_convert_units (iris.tests.test_cdm.TestCubeAPI)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_cdm.py", line 775, in test_convert_units
    self.t.convert_units('kV')
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/cube.py", line 888, in convert_units
    new_data = self.units.convert(self.data, unit)
  File "/home/h05/itwl/projects/git/cf_units/cf_units/__init__.py", line 1840, in convert
    _cv_convert_array[ctype](ut_converter, result, result)
  File "cf_units/_udunits2.pyx", line 308, in cf_units._udunits2.convert_doubles
    def convert_doubles(Converter converter, np.ndarray[np.float64_t] in_, np.ndarray[np.float64_t] out):
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

======================================================================
FAIL: test_longitude_no_units (iris.tests.unit.analysis.cartography.test_area_weights.TestInvalidUnits)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/analysis/cartography/test_area_weights.py", line 47, in test_longitude_no_units
    iris.analysis.cartography.area_weights(cube)
AssertionError: "Units of degrees or radians required" does not match "Buffer has wrong number of dimensions (expected 1, got 2)"

======================================================================
FAIL: test_calendars (iris.tests.unit.coord_categorisation.test_add_categorised_coord.Test_add_day_of_year)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/unit/coord_categorisation/test_add_categorised_coord.py", line 130, in test_calendars
    err_msg=msg.format(calendar))
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/__init__.py", line 517, in assertArrayEqual
    np.testing.assert_array_equal(a, b, err_msg=err_msg)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/numpy/testing/utils.py", line 854, in assert_array_equal
    verbose=verbose, header='Arrays are not equal')
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/numpy/testing/utils.py", line 778, in assert_array_compare
    raise AssertionError(msg)
AssertionError: 
Arrays are not equal
Test failed for the following calendar: all_leap.
(mismatch 100.0%)
 x: array([355, 356, 357, 358, 359, 360,   1,   2,   3,   4])
 y: array([360, 361, 362, 363, 364, 365, 366,   1,   2,   3])

======================================================================
FAIL: test_load_lcc_grid (iris.tests.test_netcdf.TestNetCDFLoad)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_netcdf.py", line 161, in test_load_lcc_grid
    self.assertCML(cube, ('netcdf', 'netcdf_lcc.cml'))
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/__init__.py", line 406, in assertCML
    self._check_same(xml, reference_path)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/__init__.py", line 496, in _check_same
    type_comparison_name)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/__init__.py", line 235, in _assert_str_same
    self.fail("%s do not match: %s\n%s" % (type_comparison_name, reference_filename, diff))
AssertionError: CML do not match: /net/home/h05/itwl/projects/git/iris/lib/iris/tests/results/netcdf/netcdf_lcc.cml
--- Reference
+++ Test result
@@ -91 +91 @@
-		227.0, 257.5, 288.0, 318.5, 349.0]" shape="(12,)" standard_name="time" units="Unit('days since 2010-01-01 12:00:00', calendar='standard')" value_type="float64" var_name="time"/>
+		227.0, 257.5, 288.0, 318.5, 349.0]" shape="(12,)" standard_name="time" units="Unit('days since 2010-01-01 12:00:00', calendar='gregorian')" value_type="float64" var_name="time"/>


======================================================================
FAIL: test_multi_field_load (iris.tests.test_nimrod.TestLoad)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_nimrod.py", line 45, in test_multi_field_load
    self.assertCML(cube, ("nimrod", "load_2flds.cml"))
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/__init__.py", line 406, in assertCML
    self._check_same(xml, reference_path)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/__init__.py", line 496, in _check_same
    type_comparison_name)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/__init__.py", line 235, in _assert_str_same
    self.fail("%s do not match: %s\n%s" % (type_comparison_name, reference_filename, diff))
AssertionError: CML do not match: /net/home/h05/itwl/projects/git/iris/lib/iris/tests/results/nimrod/load_2flds.cml
--- Reference
+++ Test result
@@ -13 +13 @@
-        <dimCoord id="9c8bdf81" points="[355014.0]" shape="(1,)" standard_name="forecast_reference_time" units="Unit('hours since 1970-01-01 00:00:00', calendar='standard')" value_type="float64"/>
+        <dimCoord id="9c8bdf81" points="[355014.0]" shape="(1,)" standard_name="forecast_reference_time" units="Unit('hours since 1970-01-01 00:00:00', calendar='gregorian')" value_type="float64"/>
@@ -35 +35 @@
-        <dimCoord id="cb784457" points="[355017.0, 363777.0]" shape="(2,)" standard_name="time" units="Unit('hours since 1970-01-01 00:00:00', calendar='standard')" value_type="float64"/>
+        <dimCoord id="cb784457" points="[355017.0, 363777.0]" shape="(2,)" standard_name="time" units="Unit('hours since 1970-01-01 00:00:00', calendar='gregorian')" value_type="float64"/>


======================================================================
FAIL: test_period_of_interest (iris.tests.test_nimrod.TestLoad)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_nimrod.py", line 107, in test_period_of_interest
    self.assertCML(cube, ("nimrod", "period_of_interest.cml"))
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/__init__.py", line 406, in assertCML
    self._check_same(xml, reference_path)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/__init__.py", line 496, in _check_same
    type_comparison_name)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/__init__.py", line 235, in _assert_str_same
    self.fail("%s do not match: %s\n%s" % (type_comparison_name, reference_filename, diff))
AssertionError: CML do not match: /net/home/h05/itwl/projects/git/iris/lib/iris/tests/results/nimrod/period_of_interest.cml
--- Reference
+++ Test result
@@ -6 +6 @@
-        <dimCoord bounds="[[379973.0, 379974.0]]" id="cb784457" points="[379974.0]" shape="(1,)" standard_name="time" units="Unit('hours since 1970-01-01 00:00:00', calendar='standard')" value_type="float64"/>
+        <dimCoord bounds="[[379973.0, 379974.0]]" id="cb784457" points="[379974.0]" shape="(1,)" standard_name="time" units="Unit('hours since 1970-01-01 00:00:00', calendar='gregorian')" value_type="float64"/>


======================================================================
FAIL: test_time_360 (iris.tests.test_pandas.TestAsDataFrame)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_pandas.py", line 256, in test_time_360
    self.assertArrayEqual(data_frame.index, expected_index)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/__init__.py", line 517, in assertArrayEqual
    np.testing.assert_array_equal(a, b, err_msg=err_msg)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/numpy/testing/utils.py", line 854, in assert_array_equal
    verbose=verbose, header='Arrays are not equal')
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/numpy/testing/utils.py", line 778, in assert_array_compare
    raise AssertionError(msg)
AssertionError: 
Arrays are not equal

(mismatch 100.0%)
 x: array([cftime._cftime.Datetime360Day(2000, 4, 11, 2, 24, 0, 0, -1, 1),
       cftime._cftime.Datetime360Day(2000, 7, 21, 4, 48, 0, 0, -1, 1)], dtype=object)
 y: array([netcdftime._netcdftime.Datetime360Day(2000, 4, 11, 2, 24, 0, 0, -1, 1),
       netcdftime._netcdftime.Datetime360Day(2000, 7, 21, 4, 48, 0, 0, -1, 1)], dtype=object)

======================================================================
FAIL: test_time_360 (iris.tests.test_pandas.TestAsSeries)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_pandas.py", line 118, in test_time_360
    self.assertArrayEqual(series.index, expected_index)
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/__init__.py", line 517, in assertArrayEqual
    np.testing.assert_array_equal(a, b, err_msg=err_msg)
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/numpy/testing/utils.py", line 854, in assert_array_equal
    verbose=verbose, header='Arrays are not equal')
  File "/data/local/itwl/miniconda2/envs/delme-iris/lib/python2.7/site-packages/numpy/testing/utils.py", line 778, in assert_array_compare
    raise AssertionError(msg)
AssertionError: 
Arrays are not equal

(mismatch 100.0%)
 x: array([cftime._cftime.Datetime360Day(2000, 1, 1, 0, 0, 0, 0, -1, 1),
       cftime._cftime.Datetime360Day(2000, 4, 11, 2, 24, 0, 0, -1, 1),
       cftime._cftime.Datetime360Day(2000, 7, 21, 4, 48, 0, 0, -1, 1),...
 y: array([netcdftime._netcdftime.Datetime360Day(2000, 1, 1, 0, 0, 0, 0, -1, 1),
       netcdftime._netcdftime.Datetime360Day(2000, 4, 11, 2, 24, 0, 0, -1, 1),
       netcdftime._netcdftime.Datetime360Day(2000, 7, 21, 4, 48, 0, 0, -1, 1),...

======================================================================
FAIL: test_repr_pass_1 (iris.tests.test_unit.TestStringify)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/net/home/h05/itwl/projects/git/iris/lib/iris/tests/test_unit.py", line 502, in test_repr_pass_1
    self.assertEqual(repr(u), "Unit('hours since 2007-01-15 12:06:00', calendar='standard')")
AssertionError: "Unit('hours since 2007-01-15 12:06:00', calendar='gregorian')" != "Unit('hours since 2007-01-15 12:06:00', calendar='standard')"

----------------------------------------------------------------------
Ran 3861 tests in 140.531s

FAILED (SKIP=114, errors=77, failures=8)

Converting between equivalent calendars failed

Hi

CF_units is failing when trying to convert from a time reference using a gregorian calendar to a time reference using a standard calendar:

  File "/anaconda/envs/esmval/lib/python2.7/site-packages/cf_units/__init__.py", line 2046, in convert
    (self, other))
ValueError: Unable to convert from 'Unit('days since 1850-1-1', calendar='gregorian')' to 'Unit('days since 1950-01-01 00:00:00', calendar='standard')'.

Those calendar are just different aliases for the same calendar, by CF-conventions:

http://cfconventions.org/Data/cf-conventions/cf-conventions-1.7/build/ch04s04.html

It will be nice if this equivalencies are handled directly by cf_units not only for those two, but also for all the other cases (noleap and 365_day, for example)

Thanks,
Javi

assert(0 == _ut_unmap_symbol_to_unit(_ut_system, _c_char_p('Sv'), _UT_ASCII))

After importing cf

from cf.units import Units
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/pau/glorious/packages/mynotebooks/mypy2venv/local/lib/python2.7/site-packages/cf/__init__.py", line 80, in <module>
    from .variable             import Variable
  File "/home/pau/glorious/packages/mynotebooks/mypy2venv/local/lib/python2.7/site-packages/cf/variable.py", line 19, in <module>
    from .cfdatetime   import dt
  File "/home/pau/glorious/packages/mynotebooks/mypy2venv/local/lib/python2.7/site-packages/cf/cfdatetime.py", line 25, in <module>
    from .units     import Units
  File "/home/pau/glorious/packages/mynotebooks/mypy2venv/local/lib/python2.7/site-packages/cf/units.py", line 218, in <module>
    assert(0 == _ut_unmap_symbol_to_unit(_ut_system, _c_char_p('Sv'), _UT_ASCII))
AssertionError

I have these packages installed in a encapsulated virtual environment

backports.functools-lru-cache==1.5
cf-python==2.1.6
cycler==0.10.0
kiwisolver==1.0.1
matplotlib==2.2.2
netCDF4==1.3.1
numpy==1.14.2
psutil==5.4.3
pyparsing==2.2.0
python-dateutil==2.7.0
pytz==2018.3
scipy==1.0.0
six==1.11.0
subprocess32==3.2.7

I am wondering if you could deliver a compatible full virtual portable environment with all the dependencies installed? maybe that would make the whole thing easier...

`is_vertical`?

is_vertical returns True for distances. That is the correct behavior, but the name is not all that intuitive.

Copyright and License

What is the license on this project? I see GPL v3 but I also see a Crown Copyright which is all rights reserved, I believe.

Is there anyway that this project could be licensed under LGPL or something less restrictive than GPL?

Package dependencies

I've been troubleshooting a bunch of tox issues for a project that uses cf_units and I found where the source of the trouble is. cf_units defines the project dependencies in a conda requirements file but not in the setup.py file

Specifically the dependency that's giving me grief is six.

Could you also include the project dependencies in the setup.py file? It might be as simple as

install_requires = [line.strip() for line in open('conda_requirements.txt')]

Hash (#) as a dimensionless unit

@duncanwp has suggested it would be useful to support units of the form # cm-3. This would basically be a simple unit.replace('#', '1').

I somewhat support the suggestion, though wouldn't expect cf_units to preserve the fact that it encountered a hash (aka Postel's law).

Tests

Copy all tests that are related to the units module and run then here.

Windows test failures UT_OPEN_DEFAULT

Test failures on Windows as seen in conda-forge/cf_units-feedstock#14 (comment). An example:

________________________ Test_get_system.test_read_xml ________________________
self = <tests.unit.test__udunits2.Test_get_system testMethod=test_read_xml>
    def test_read_xml(self):
>       system = _ud.read_xml()
tests\unit\test__udunits2.py:43: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cf_units\_udunits2.pyx:206: in cf_units._udunits2.read_xml
    ???
cf_units\_udunits2.pyx:116: in cf_units._udunits2.wrap_system
    ???
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>   ???
E   UdunitsError: UT_OPEN_DEFAULT
cf_units\_udunits2.pyx:196: UdunitsError

Pip install fails with ImportError: No module named Cython.Distutils

pip doesn't seem able to install cf-units 2.0.1:

$ pip install cf-units
Collecting cf-units
  Using cached https://files.pythonhosted.org/packages/0c/01/32ac56ae9977baf05dca9b3c563c96118b4204dff5161ce5ec58113b649c/cf_units-2.0.1.tar.gz
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-hajt1m/cf-units/setup.py", line 6, in <module>
        from Cython.Distutils import build_ext
    ImportError: No module named Cython.Distutils

Python 3?

I tried to install this with python 3.4. It installed fine, but I got the following runtime error after calling import cf_units

ImportError: No module named 'ConfigParser

Am I correct in assuming that the package is python 2 only?

Odd behaviour of 'mm day-1' units.

I found some odd behaviour when manipulating units of mm day-1. The correlation_units function below mimics what happens to the units of iris cubes with the same unit when they are passed to iris.analysis.stats.pearsonr.

import cf_units
print cf_units.__version__

def correlation_units(unit_string):
    unit = cf_units.Unit(unit_string)
    unit_squared = unit * unit

    return unit_squared / unit_squared
    
for unit_string in ['K', 'm/s', 'mm day-1', 'm', 'hPa']:
    print unit_string, ': ', correlation_units(unit_string)

For most of the units, the function produces cf_units.Unit('1'), as expected, but for 'mm day-1', I get a strange unit of cf_units.Unit('1 1').

1.1.3
K :  1
m/s :  1
mm day-1 :  1 1
m :  1
hPa :  1

ValueError: 'gregorian_proleptic' is an unsupported calendar.

Several of our datasets are now failing to load with iris with ValueError: 'gregorian_proleptic' is an unsupported calendar. One can reproduce it with:

import iris
url = "http://tds.marine.rutgers.edu/thredds/dodsC/roms/doppio/2017_da/avg/Averages_Best"
cubes = iris.load_raw(url)

The versions are iris 2.2.0 and cf_units 2.0.2. The full traceback is:

ValueError                                Traceback (most recent call last)
<ipython-input-1-e08eaa4e3e58> in <module>
      1 import iris
      2 url = "http://tds.marine.rutgers.edu/thredds/dodsC/roms/doppio/2017_da/avg/Averages_Best"
----> 3 cubes = iris.load_raw(url)

~/miniconda3/envs/IOOS/lib/python3.7/site-packages/iris/__init__.py in load_raw(uris, constraints, callback)
    452     from iris.fileformats.um._fast_load import _raw_structured_loading
    453     with _raw_structured_loading():
--> 454         return _load_collection(uris, constraints, callback).cubes()
    455 
    456 

~/miniconda3/envs/IOOS/lib/python3.7/site-packages/iris/__init__.py in _load_collection(uris, constraints, callback)
    311     try:
    312         cubes = _generate_cubes(uris, callback, constraints)
--> 313         result = iris.cube._CubeFilterCollection.from_cubes(cubes, constraints)
    314     except EOFError as e:
    315         raise iris.exceptions.TranslationError(

~/miniconda3/envs/IOOS/lib/python3.7/site-packages/iris/cube.py in from_cubes(cubes, constraints)
    143         pairs = [_CubeFilter(constraint) for constraint in constraints]
    144         collection = _CubeFilterCollection(pairs)
--> 145         for cube in cubes:
    146             collection.add_cube(cube)
    147         return collection

~/miniconda3/envs/IOOS/lib/python3.7/site-packages/iris/__init__.py in _generate_cubes(uris, callback, constraints)
    302         elif scheme in ['http', 'https']:
    303             urls = [':'.join(x) for x in groups]
--> 304             for cube in iris.io.load_http(urls, callback):
    305                 yield cube
    306         else:

~/miniconda3/envs/IOOS/lib/python3.7/site-packages/iris/io/__init__.py in load_http(urls, callback)
    232     for handling_format_spec in sorted(handler_map):
    233         fnames = handler_map[handling_format_spec]
--> 234         for cube in handling_format_spec.handler(fnames, callback):
    235             yield cube
    236 

~/miniconda3/envs/IOOS/lib/python3.7/site-packages/iris/fileformats/netcdf.py in load_cubes(filenames, callback)
    710                           list(cf.cf_group.promoted.values()))
    711         for cf_var in data_variables:
--> 712             cube = _load_cube(engine, cf, cf_var, filename)
    713 
    714             # Process any associated formula terms and attach

~/miniconda3/envs/IOOS/lib/python3.7/site-packages/iris/fileformats/netcdf.py in _load_cube(engine, cf, cf_var, filename)
    538 
    539     # Run pyke inference engine with forward chaining rules.
--> 540     engine.activate(_PYKE_RULE_BASE)
    541 
    542     # Populate coordinate attributes with the untouched attributes from the

~/miniconda3/envs/IOOS/lib/python3.7/site-packages/pyke/knowledge_engine.py in activate(self, *rb_names)
    295         add your facts before doing this!
    296         '''
--> 297         for rb_name in rb_names: self.get_rb(rb_name).activate()
    298 
    299     def lookup(self, kb_name, entity_name, pat_context, patterns):

~/miniconda3/envs/IOOS/lib/python3.7/site-packages/pyke/rule_base.py in activate(self)
    157         self.engine.knowledge_bases[self.root_name] = self
    158         self.register_fc_rules(current_rb)
--> 159         self.run_fc_rules(current_rb)
    160 
    161     def reset(self):

~/miniconda3/envs/IOOS/lib/python3.7/site-packages/pyke/rule_base.py in run_fc_rules(self, stop_at_rb)
    145         rb = self
    146         while rb is not stop_at_rb:
--> 147             for fc_rule in rb.fc_rules: fc_rule.run()
    148             if not rb.parent: break
    149             rb = rb.parent

~/miniconda3/envs/IOOS/lib/python3.7/site-packages/pyke/fc_rule.py in run(self)
     88     def run(self):
     89         self.ran = True
---> 90         self.rule_fn(self)
     91 
     92     def new_fact(self, fact_args, n):

~/miniconda3/envs/IOOS/lib/python3.7/site-packages/iris/fileformats/_pyke_rules/compiled_krb/fc_rules_cf_fc.py in fc_default(rule, context, index)
     10   if context is None: context = contexts.simple_context()
     11   try:
---> 12     build_cube_metadata(engine)
     13     engine.rule_triggered.add(rule.name)
     14     rule.rule_base.num_fc_rules_triggered += 1

~/miniconda3/envs/IOOS/lib/python3.7/site-packages/iris/fileformats/_pyke_rules/compiled_krb/fc_rules_cf_fc.py in build_cube_metadata(engine)
   1711             else:
   1712                 cube.long_name = standard_name
-> 1713     attr_units = get_attr_units(cf_var, cube.attributes)
   1714     cube.units = attr_units
   1715     nc_att_cell_methods = getattr(cf_var, CF_ATTR_CELL_METHODS, None)

~/miniconda3/envs/IOOS/lib/python3.7/site-packages/iris/fileformats/_pyke_rules/compiled_krb/fc_rules_cf_fc.py in get_attr_units(cf_var, attributes)
   1940         attr_calendar = getattr(cf_var, CF_ATTR_CALENDAR, None)
   1941         if attr_calendar:
-> 1942             attr_units = cf_units.Unit(attr_units, calendar=attr_calendar)
   1943     return attr_units
   1944 def get_names(cf_coord_var, coord_name, attributes):

~/miniconda3/envs/IOOS/lib/python3.7/site-packages/cf_units/__init__.py in __init__(self, unit, calendar)
    859                     if calendar_ not in CALENDARS:
    860                         msg = '{!r} is an unsupported calendar.'
--> 861                         raise ValueError(msg.format(calendar))
    862                 else:
    863                     msg = 'Expected string-like calendar argument, got {!r}.'

ValueError: 'gregorian_proleptic' is an unsupported calendar.

Package name rebrand

Proposing that we rebrand the package name to be cf-units, in light of the nc-time-axis rebrand.

Test failures with netcdf4-python 1.2.7

See this build:

=================================== FAILURES ===================================
_________________________ Test.test_fractional_360_day _________________________
self = <cf_units.tests.integration.test__num2date_to_nearest_second.Test testMethod=test_fractional_360_day>
    def test_fractional_360_day(self):
        self.setup_units('360_day')
        nums = [5./60., 10./60.,
                15./60., 30./60.,
                8./24., 16./24.]
        utimes = [self.uminutes, self.uminutes,
                  self.uhours, self.uhours,
                  self.udays, self.udays]
        expected = [netcdftime.datetime(1970, 1, 1, 0, 0, 5),
                    netcdftime.datetime(1970, 1, 1, 0, 0, 10),
                    netcdftime.datetime(1970, 1, 1, 0, 15),
                    netcdftime.datetime(1970, 1, 1, 0, 30),
                    netcdftime.datetime(1970, 1, 1, 8),
                    netcdftime.datetime(1970, 1, 1, 16)]
    
>       self.check_dates(nums, utimes, expected)
cf_units/tests/integration/test__num2date_to_nearest_second.py:172: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cf_units/tests/integration/test__num2date_to_nearest_second.py:42: in check_dates
    self.assertEqual(exp, res)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
>   ???
E   TypeError: cannot compare netcdftime._netcdftime.DatetimeProlepticGregorian(1970, 1, 1, 0, 0, 5, 0, -1, 1) and netcdftime._netcdftime.Datetime360Day(1970, 1, 1, 0, 0, 5, 0, -1, 1) (different calendars)
netcdftime/_netcdftime.pyx:1288: TypeError
_________________________ Test.test_fractional_365_day _________________________
self = <cf_units.tests.integration.test__num2date_to_nearest_second.Test testMethod=test_fractional_365_day>
    def test_fractional_365_day(self):
        self.setup_units('365_day')
        nums = [5./60., 10./60.,
                15./60., 30./60.,
                8./24., 16./24.]
        utimes = [self.uminutes, self.uminutes,
                  self.uhours, self.uhours,
                  self.udays, self.udays]
    
        expected = [netcdftime.datetime(1970, 1, 1, 0, 0, 5),
                    netcdftime.datetime(1970, 1, 1, 0, 0, 10),
                    netcdftime.datetime(1970, 1, 1, 0, 15),
                    netcdftime.datetime(1970, 1, 1, 0, 30),
                    netcdftime.datetime(1970, 1, 1, 8),
                    netcdftime.datetime(1970, 1, 1, 16)]
    
>       self.check_dates(nums, utimes, expected)
cf_units/tests/integration/test__num2date_to_nearest_second.py:228: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cf_units/tests/integration/test__num2date_to_nearest_second.py:42: in check_dates
    self.assertEqual(exp, res)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
>   ???
E   TypeError: cannot compare netcdftime._netcdftime.DatetimeProlepticGregorian(1970, 1, 1, 0, 0, 5, 0, -1, 1) and netcdftime._netcdftime.DatetimeNoLeap(1970, 1, 1, 0, 0, 5, 0, -1, 1) (different calendars)
netcdftime/_netcdftime.pyx:1288: TypeError
_____________________ Test.test_fractional_second_360_day ______________________
self = <cf_units.tests.integration.test__num2date_to_nearest_second.Test testMethod=test_fractional_second_360_day>
    def test_fractional_second_360_day(self):
        self.setup_units('360_day')
        nums = [0.25, 0.5, 0.75,
                1.5, 2.5, 3.5, 4.5]
        utimes = [self.useconds] * 7
        expected = [netcdftime.datetime(1970, 1, 1, 0, 0, 0),
                    netcdftime.datetime(1970, 1, 1, 0, 0, 1),
                    netcdftime.datetime(1970, 1, 1, 0, 0, 1),
                    netcdftime.datetime(1970, 1, 1, 0, 0, 2),
                    netcdftime.datetime(1970, 1, 1, 0, 0, 3),
                    netcdftime.datetime(1970, 1, 1, 0, 0, 4),
                    netcdftime.datetime(1970, 1, 1, 0, 0, 5)]
    
>       self.check_dates(nums, utimes, expected)
cf_units/tests/integration/test__num2date_to_nearest_second.py:187: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cf_units/tests/integration/test__num2date_to_nearest_second.py:42: in check_dates
    self.assertEqual(exp, res)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
>   ???
E   TypeError: cannot compare netcdftime._netcdftime.DatetimeProlepticGregorian(1970, 1, 1, 0, 0, 0, 0, -1, 1) and netcdftime._netcdftime.Datetime360Day(1970, 1, 1, 0, 0, 0, 0, -1, 1) (different calendars)
netcdftime/_netcdftime.pyx:1288: TypeError
_____________________ Test.test_fractional_second_365_day ______________________
self = <cf_units.tests.integration.test__num2date_to_nearest_second.Test testMethod=test_fractional_second_365_day>
    def test_fractional_second_365_day(self):
        self.setup_units('365_day')
        nums = [0.25, 0.5, 0.75,
                1.5, 2.5, 3.5, 4.5]
        utimes = [self.useconds] * 7
        expected = [netcdftime.datetime(1970, 1, 1, 0, 0, 0),
                    netcdftime.datetime(1970, 1, 1, 0, 0, 1),
                    netcdftime.datetime(1970, 1, 1, 0, 0, 1),
                    netcdftime.datetime(1970, 1, 1, 0, 0, 2),
                    netcdftime.datetime(1970, 1, 1, 0, 0, 3),
                    netcdftime.datetime(1970, 1, 1, 0, 0, 4),
                    netcdftime.datetime(1970, 1, 1, 0, 0, 5)]
    
>       self.check_dates(nums, utimes, expected)
cf_units/tests/integration/test__num2date_to_nearest_second.py:243: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cf_units/tests/integration/test__num2date_to_nearest_second.py:42: in check_dates
    self.assertEqual(exp, res)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
>   ???
E   TypeError: cannot compare netcdftime._netcdftime.DatetimeProlepticGregorian(1970, 1, 1, 0, 0, 0, 0, -1, 1) and netcdftime._netcdftime.DatetimeNoLeap(1970, 1, 1, 0, 0, 0, 0, -1, 1) (different calendars)
netcdftime/_netcdftime.pyx:1288: TypeError
___________________________ Test.test_simple_360_day ___________________________
self = <cf_units.tests.integration.test__num2date_to_nearest_second.Test testMethod=test_simple_360_day>
    def test_simple_360_day(self):
        self.setup_units('360_day')
        nums = [20., 40.,
                75., 150.,
                8., 16.,
                300., 600.]
        utimes = [self.useconds, self.useconds,
                  self.uminutes, self.uminutes,
                  self.uhours, self.uhours,
                  self.udays, self.udays]
        expected = [netcdftime.datetime(1970, 1, 1, 0, 0, 20),
                    netcdftime.datetime(1970, 1, 1, 0, 0, 40),
                    netcdftime.datetime(1970, 1, 1, 1, 15),
                    netcdftime.datetime(1970, 1, 1, 2, 30),
                    netcdftime.datetime(1970, 1, 1, 8),
                    netcdftime.datetime(1970, 1, 1, 16),
                    netcdftime.datetime(1970, 11, 1),
                    netcdftime.datetime(1971, 9, 1)]
    
>       self.check_dates(nums, utimes, expected)
cf_units/tests/integration/test__num2date_to_nearest_second.py:155: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cf_units/tests/integration/test__num2date_to_nearest_second.py:42: in check_dates
    self.assertEqual(exp, res)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
>   ???
E   TypeError: cannot compare netcdftime._netcdftime.DatetimeProlepticGregorian(1970, 1, 1, 0, 0, 20, 0, -1, 1) and netcdftime._netcdftime.Datetime360Day(1970, 1, 1, 0, 0, 20, 0, -1, 1) (different calendars)
netcdftime/_netcdftime.pyx:1288: TypeError
___________________________ Test.test_simple_365_day ___________________________
self = <cf_units.tests.integration.test__num2date_to_nearest_second.Test testMethod=test_simple_365_day>
    def test_simple_365_day(self):
        self.setup_units('365_day')
        nums = [20., 40.,
                75., 150.,
                8., 16.,
                300., 600.]
        utimes = [self.useconds, self.useconds,
                  self.uminutes, self.uminutes,
                  self.uhours, self.uhours,
                  self.udays, self.udays]
        expected = [netcdftime.datetime(1970, 1, 1, 0, 0, 20),
                    netcdftime.datetime(1970, 1, 1, 0, 0, 40),
                    netcdftime.datetime(1970, 1, 1, 1, 15),
                    netcdftime.datetime(1970, 1, 1, 2, 30),
                    netcdftime.datetime(1970, 1, 1, 8),
                    netcdftime.datetime(1970, 1, 1, 16),
                    netcdftime.datetime(1970, 10, 28),
                    netcdftime.datetime(1971, 8, 24)]
    
>       self.check_dates(nums, utimes, expected)
cf_units/tests/integration/test__num2date_to_nearest_second.py:210: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cf_units/tests/integration/test__num2date_to_nearest_second.py:42: in check_dates
    self.assertEqual(exp, res)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
>   ???
E   TypeError: cannot compare netcdftime._netcdftime.DatetimeProlepticGregorian(1970, 1, 1, 0, 0, 20, 0, -1, 1) and netcdftime._netcdftime.DatetimeNoLeap(1970, 1, 1, 0, 0, 20, 0, -1, 1) (different calendars)
netcdftime/_netcdftime.pyx:1288: TypeError

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.