Skip to content

Commit

Permalink
Dask core data (#2521)
Browse files Browse the repository at this point in the history
* DataManager.core_data()

* Cube.core_data()

* Fileformats rules core_data()
  • Loading branch information
bjlittle authored and DPeterK committed May 4, 2017
1 parent 3eb4898 commit 2332870
Show file tree
Hide file tree
Showing 15 changed files with 67 additions and 62 deletions.
18 changes: 9 additions & 9 deletions lib/iris/_data_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def __eq__(self, other):
same_realised_dtype = self._realised_dtype == other._realised_dtype
same_dtype = self.dtype == other.dtype
if same_lazy and same_realised_dtype and same_dtype:
result = array_equal(self.core_data, other.core_data)
result = array_equal(self.core_data(), other.core_data())

return result

Expand Down Expand Up @@ -149,13 +149,14 @@ def __repr__(self):
Returns an string representation of the instance.
"""
fmt = '{cls}({self.core_data!r}{dtype})'
fmt = '{cls}({data!r}{dtype})'
dtype = ''

if self._realised_dtype is not None:
dtype = ', realised_dtype={!r}'.format(self._realised_dtype)

result = fmt.format(self=self, cls=type(self).__name__, dtype=dtype)
result = fmt.format(data=self.core_data(), cls=type(self).__name__,
dtype=dtype)

return result

Expand Down Expand Up @@ -217,7 +218,7 @@ def _deepcopy(self, memo, data=None, realised_dtype='none'):
else:
# Check that the replacement data is valid relative to
# the currently managed data.
DataManager(self.core_data).replace(data)
DataManager(self.core_data()).replace(data)
# If the replacement data is valid, then use it but
# without copying it.

Expand Down Expand Up @@ -262,7 +263,6 @@ def _realised_dtype_setter(self, realised_dtype):
# Check the manager contract, as the managed dtype has changed.
self._assert_axioms()

@property
def core_data(self):
"""
If real data is being managed, then return the :class:`~numpy.ndarray`
Expand Down Expand Up @@ -377,7 +377,7 @@ def dtype(self):
if self._realised_dtype is not None:
result = self._realised_dtype
else:
result = self.core_data.dtype
result = self.core_data().dtype

return result

Expand All @@ -387,15 +387,15 @@ def ndim(self):
The number of dimensions covered by the data being managed.
"""
return self.core_data.ndim
return self.core_data().ndim

@property
def shape(self):
"""
The shape of the data being managed.
"""
return self.core_data.shape
return self.core_data().shape

def copy(self, data=None, realised_dtype='none'):
"""
Expand Down Expand Up @@ -471,7 +471,7 @@ def replace(self, data, realised_dtype=None):
"""
# Snapshot the currently managed data.
original_data = self.core_data
original_data = self.core_data()
# Perform in-place data assignment.
self.data = data
try:
Expand Down
2 changes: 1 addition & 1 deletion lib/iris/_merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -1641,7 +1641,7 @@ def _build_signature(self, cube, fill_value=None):
def _add_cube(self, cube, coord_payload):
"""Create and add the source-cube skeleton to the ProtoCube."""
skeleton = _Skeleton(coord_payload.scalar.values,
cube.core_data)
cube.core_data())
# Attempt to do something sensible with mixed scalar dtypes.
for i, metadata in enumerate(coord_payload.scalar.metadata):
if metadata.points_dtype > self._coord_metadata[i].points_dtype:
Expand Down
4 changes: 2 additions & 2 deletions lib/iris/analysis/maths.py
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,7 @@ def _binary_op_common(operation_function, operation_name, cube, other,
broadcast_shapes(cube.shape, other.shape)
except ValueError:
other = iris.util.as_compatible_shape(other, cube)
other = other.core_data
other = other.core_data()
else:
other = np.asanyarray(other)

Expand Down Expand Up @@ -702,7 +702,7 @@ def _math_op_common(cube, operation_function, new_unit, in_place=False):
# Non ufunc function
operation_function(cube.data)
else:
new_cube = cube.copy(data=operation_function(cube.core_data))
new_cube = cube.copy(data=operation_function(cube.core_data()))
iris.analysis.clear_phenomenon_identity(new_cube)
new_cube.units = new_unit
return new_cube
Expand Down
2 changes: 1 addition & 1 deletion lib/iris/coords.py
Original file line number Diff line number Diff line change
Expand Up @@ -1808,7 +1808,7 @@ def __getitem__(self, key):
full_slice = iris.util._build_full_slice_given_keys(key, self.ndim)

# Get the data, all or part of which will become the new data.
data = self._data_manager.core_data
data = self._data_manager.core_data()
# Copy the data to avoid making the new measure a view on the old one.
data = data.copy()

Expand Down
12 changes: 6 additions & 6 deletions lib/iris/cube.py
Original file line number Diff line number Diff line change
Expand Up @@ -1599,7 +1599,6 @@ def cell_methods(self):
def cell_methods(self, cell_methods):
self._cell_methods = tuple(cell_methods) if cell_methods else tuple()

@property
def core_data(self):
"""
The data at the core of this cube.
Expand All @@ -1609,7 +1608,7 @@ def core_data(self):
to be decided: should this be public??
"""
return self._data_manager.core_data
return self._data_manager.core_data()

@property
def shape(self):
Expand Down Expand Up @@ -2173,7 +2172,7 @@ def new_cell_measure_dims(cm_):
except StopIteration:
first_slice = None

cube_data = self._data_manager.core_data
cube_data = self._data_manager.core_data()

if first_slice is not None:
data = cube_data[first_slice]
Expand Down Expand Up @@ -2827,7 +2826,7 @@ def transpose(self, new_order=None):
raise ValueError('Incorrect number of dimensions.')

# Transpose the data payload.
data = self._data_manager.core_data.transpose(new_order)
data = self._data_manager.core_data().transpose(new_order)
self._data_manager = DataManager(data, self._data_manager.dtype)

dim_mapping = {src: dest for dest, src in enumerate(new_order)}
Expand Down Expand Up @@ -2873,7 +2872,8 @@ def _xml_element(self, doc, checksum=False, order=True, byteorder=True):
if self.fill_value is not None:
cube_xml_element.setAttribute('fill_value', str(self.fill_value))
cube_xml_element.setAttribute('dtype', self.dtype.name)
cube_xml_element.setAttribute('core-dtype', self.core_data.dtype.name)
cube_xml_element.setAttribute('core-dtype',
self.core_data().dtype.name)

if self.attributes:
attributes_element = doc.createElement('attributes')
Expand Down Expand Up @@ -3076,7 +3076,7 @@ def _deepcopy(self, memo, data=None, dtype='none', fill_value='none'):
new_aux_coords_and_dims):
coord_mapping[id(old_pair[0])] = new_pair[0]

new_cube = Cube(dm.core_data,
new_cube = Cube(dm.core_data(),
dim_coords_and_dims=new_dim_coords_and_dims,
aux_coords_and_dims=new_aux_coords_and_dims,
fill_value=fill_value,
Expand Down
1 change: 0 additions & 1 deletion lib/iris/fileformats/grib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,6 @@ def bmdi(self):
# Default for fill value is None.
return None

@property
def core_data(self):
try:
data = self._data
Expand Down
1 change: 0 additions & 1 deletion lib/iris/fileformats/grib/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ def bmdi(self):
# Default for fill value is None.
return None

@property
def core_data(self):
return self.data

Expand Down
7 changes: 3 additions & 4 deletions lib/iris/fileformats/pp.py
Original file line number Diff line number Diff line change
Expand Up @@ -1293,7 +1293,6 @@ def data(self):
def data(self, value):
self._data = value

@property
def core_data(self):
return self._data

Expand Down Expand Up @@ -1866,8 +1865,8 @@ def _create_field_data(field, data_shape, land_mask):
* converting LoadedArrayBytes into an actual numpy array.
"""
if isinstance(field.core_data, LoadedArrayBytes):
loaded_bytes = field.core_data
if isinstance(field.core_data(), LoadedArrayBytes):
loaded_bytes = field.core_data()
field.data = _data_bytes_to_shaped_array(loaded_bytes.bytes,
field.lbpack,
field.boundary_packing,
Expand All @@ -1877,7 +1876,7 @@ def _create_field_data(field, data_shape, land_mask):
else:
# Wrap the reference to the data payload within a data proxy
# in order to support deferred data loading.
fname, position, n_bytes, dtype = field.core_data
fname, position, n_bytes, dtype = field.core_data()
proxy = PPDataProxy(data_shape, dtype,
fname, position, n_bytes,
field.raw_lbpack,
Expand Down
4 changes: 2 additions & 2 deletions lib/iris/fileformats/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -901,12 +901,12 @@ def _make_cube(field, converter):
# Convert the field to a Cube.
metadata = converter(field)

cube = iris.cube.Cube(field.core_data,
cube = iris.cube.Cube(field.core_data(),
attributes=metadata.attributes,
cell_methods=metadata.cell_methods,
dim_coords_and_dims=metadata.dim_coords_and_dims,
aux_coords_and_dims=metadata.aux_coords_and_dims,
fill_value=field.bmdi, dtype=field.core_data.dtype)
fill_value=field.bmdi, dtype=field.core_data().dtype)


# Temporary code to deal with invalid standard names in the
Expand Down
1 change: 0 additions & 1 deletion lib/iris/fileformats/um/_fast_load_structured_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ def data(self):
self._data_cache = multidim_lazy_stack(stack)
return self._data_cache

@property
def core_data(self):
return self.data

Expand Down
30 changes: 18 additions & 12 deletions lib/iris/tests/integration/test_pp.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,12 @@ def test_hybrid_pressure_round_trip(self):
# LBCODE, support len().
def field_with_data(scale=1):
x, y = 40, 30
field = mock.MagicMock(
core_data=np.arange(1200).reshape(y, x) * scale, lbcode=[1],
lbnpt=x, lbrow=y, bzx=350, bdx=1.5, bzy=40, bdy=1.5,
lbuser=[0] * 7, lbrsvd=[0] * 4)
return_value = np.arange(1200).reshape(y, x) * scale
core_data = mock.MagicMock(return_value=return_value)
field = mock.MagicMock(core_data=core_data, lbcode=[1],
lbnpt=x, lbrow=y, bzx=350, bdx=1.5,
bzy=40, bdy=1.5, lbuser=[0] * 7,
lbrsvd=[0] * 4)
field._x_coord_name = lambda: 'longitude'
field._y_coord_name = lambda: 'latitude'
field.coord_system = lambda: None
Expand Down Expand Up @@ -233,10 +235,12 @@ def field_with_data(scale=1):
def test_hybrid_pressure_with_duplicate_references(self):
def field_with_data(scale=1):
x, y = 40, 30
field = mock.MagicMock(
core_data=np.arange(1200).reshape(y, x) * scale, lbcode=[1],
lbnpt=x, lbrow=y, bzx=350, bdx=1.5, bzy=40, bdy=1.5,
lbuser=[0] * 7, lbrsvd=[0] * 4)
return_value = np.arange(1200).reshape(y, x) * scale
core_data = mock.MagicMock(return_value=return_value)
field = mock.MagicMock(core_data=core_data, lbcode=[1],
lbnpt=x, lbrow=y, bzx=350, bdx=1.5,
bzy=40, bdy=1.5, lbuser=[0] * 7,
lbrsvd=[0] * 4)
field._x_coord_name = lambda: 'longitude'
field._y_coord_name = lambda: 'latitude'
field.coord_system = lambda: None
Expand Down Expand Up @@ -346,10 +350,12 @@ def test_hybrid_height_round_trip_no_reference(self):
# LBCODE, support len().
def field_with_data(scale=1):
x, y = 40, 30
field = mock.MagicMock(
core_data=np.arange(1200).reshape(y, x) * scale, lbcode=[1],
lbnpt=x, lbrow=y, bzx=350, bdx=1.5, bzy=40, bdy=1.5,
lbuser=[0] * 7, lbrsvd=[0] * 4)
return_value = np.arange(1200).reshape(y, x) * scale
core_data = mock.MagicMock(return_value=return_value)
field = mock.MagicMock(core_data=core_data, lbcode=[1],
lbnpt=x, lbrow=y, bzx=350, bdx=1.5,
bzy=40, bdy=1.5, lbuser=[0] * 7,
lbrsvd=[0] * 4)
field._x_coord_name = lambda: 'longitude'
field._y_coord_name = lambda: 'latitude'
field.coord_system = lambda: None
Expand Down
Loading

0 comments on commit 2332870

Please sign in to comment.