Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/887.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add new method, `ndcube.NDCube.to_nddata`, which allows easy conversion of an `~ndcube.NDCube` to a subclass of `~astropy.nddata.NDData`. Users have the option of changing attribute values when doing so by designated the new values via kwargs.
53 changes: 53 additions & 0 deletions ndcube/ndcube.py
Original file line number Diff line number Diff line change
Expand Up @@ -1461,6 +1461,59 @@ def fill_masked(self, fill_value, uncertainty_fill_value=None, unmask=False, fil
self.mask = False
return None

def to_nddata(self, *, nddata_type=NDData, **kwargs):
"""
Constructs new type instance with the same attribute values as this `~ndcube.NDCube`.

Any attributes not supported by the new class (``nddata_type``), will be discarded.
Values of supported attributes can be altered on the output object by setting a
kwarg with the new value, e.g. ``data=new_data``.

Parameters
----------
nddata_type:
The type of the returned object. Must be a subclass of `~astropy.nddata.NDData`
or a class that behaves like one. Default=`~astropy.nddata.NDData`.

kwargs:
Attributes to change on output object. For example, to change the data on the
returned object compare to this instance, set a kwarg ``data=new_data``.
Note that kwargs set to ``None`` will not be passed to the constructor
of the ``nddata_type``. Therefore, if that attribute exists on the new type,
it will be given the default value defined by ``nddata_type``'s call signature.

Returns
-------
new_nddata:
A object of class given by ``nddata_type`` with the same attribute values as
this `~ndcube.NDCube` instance, except for any alterations specified by the
kwargs.

Examples
--------
To create an `~astropy.nddata.NDData` instance which is a copy of an `~ndcube.NDCube`
(called ``cube``) without a WCS, do:

>>> nddata_without_coords = cube.to_nddata(wcs=None) # doctest: +SKIP
"""
# Build dictionary of new attribute values from this NDCube instance.
new_kwargs = {key.strip("_"): value for key, value in self.__dict__.items()}
# Remove kwargs set to None and add kwargs that don't correspond to NDCube attrs.
for key, value in kwargs.items():
if value is None:
del new_kwargs[key]
else:
new_kwargs[key] = value
# Inspect call signature of new_nddata class and
# remove unsupported items from new_kwargs.
nddata_sig = inspect.signature(nddata_type).parameters.keys()
new_kwarg_keys = list(new_kwargs.keys())
for key in new_kwarg_keys:
if key not in nddata_sig:
del new_kwargs[key]
# Construct and return new instance.
return nddata_type(**new_kwargs)


def _create_masked_array_for_rebinning(data, mask, operation_ignores_mask):
m = None if (mask is None or mask is False or operation_ignores_mask) else mask
Expand Down
10 changes: 10 additions & 0 deletions ndcube/tests/test_ndcube.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import numpy as np
import pytest

import astropy.nddata
import astropy.units as u
import astropy.wcs
from astropy.wcs.wcsapi import BaseHighLevelWCS
Expand Down Expand Up @@ -238,3 +239,12 @@ def test_fill_masked_ndc_uncertainty_none(ndc, fill_value, uncertainty_fill_valu
uncertainty_fill_value=uncertainty_fill_value,
fill_in_place=True
)


def test_to_nddata(ndcube_2d_ln_lt):
ndc = ndcube_2d_ln_lt
new_data = ndc.data * 2
output = ndc.to_nddata(data=new_data, wcs=None)
assert type(output) is astropy.nddata.NDData
assert output.wcs is None
assert (output.data == new_data).all()
Loading