Cube

Cube is a class to interact with a fully reduced DRP data cube for a galaxy. For a general introduction to Marvin Tools, check out the Galaxy Tools section. Here we will revisit those features and will expand on some specifics of the Cube class.

Initializing a Cube

A Cube can be initialized in several ways, by filename, in which case it will always be in local mode:

cube = Cube(filename='/Users/Brian/Work/Manga/redux/v2_3_1/8485/stack/manga-8485-1901-LOGCUBE.fits.gz')
<Marvin Cube (plateifu='8485-1901', mode='local', data_origin='file')>

by plateifu or mangaid, in which case it attempts to find a local database, otherwise will open it in remote mode:

cube = Cube(plateifu='8485-1901')
<Marvin Cube (plateifu='8485-1901', mode='local', data_origin='db')>

cube = Cube(mangaid='1-209232')
<Marvin Cube (plateifu='8485-1901', mode='local', data_origin='db')>

However you can also initialize a Cube without the keyword argument and Marvin will attempt to figure out what input you mean.

cube = Cube('8485-1901')
<Marvin Cube (plateifu='8485-1901', mode='local', data_origin='db')>

Basic Attributes

Cubes come with some basic attributes attached, like the full header (as an Astropy Header object), cube RA and Dec, the WCS info (as an Astropy WCS object), and the NSA catalog information (as a dictionary).

# access the header
cube.header

CHECKSUM= 'HLO1KLM1HLM1HLM1'   / HDU checksum updated 2017-10-17T06:02:42
DATASUM = '3722061489'         / data unit checksum updated 2017-10-17T06:02:42
EXTNAME = 'FLUX    '
QUALDATA= 'MASK    '           / Mask extension name
ERRDATA = 'IVAR    '           / Error extension name
HDUCLAS2= 'DATA    '
HDUCLAS1= 'CUBE    '
HDUCLASS= 'SDSS    '           / SDSS format class
CUNIT2  = 'deg     '
CUNIT1  = 'deg     '
CTYPE2  = 'DEC--TAN'
CTYPE1  = 'RA---TAN'
...

# the cube RA and Dec (the OBJRA and OBJDEC)
cube.ra, cube.dec
(232.544703894, 48.6902009334)

# the NSA catalog information
cube.nsa['z']
0.0407447

c.nsa['elpetro_ba']
0.87454

The Cube data quality and targeting flags are available as the quality_flag and target_flags attributes, respectively. These are represented as Maskbit objects. A good quality Cube has an empty (0) bit list. If you are not familiar with MaNGA’s maskbits, check the official documentation.

# check the quality and bits
cube.quality_flag
<Maskbit 'MANGA_DRP3QUAL' []>

cube.quality_flag.bits
[]

# check the targeting flags
cube.target_flags
[<Maskbit 'MANGA_TARGET1' ['SECONDARY_v1_1_0', 'SECONDARY_COM2', 'SECONDARY_v1_2_0']>,
 <Maskbit 'MANGA_TARGET2' []>,
 <Maskbit 'MANGA_TARGET3' []>]

The DataModel

The DRP datamodel is attached to Cube as the datamodel attribute. The datamodel describes the contents of the MaNGA DRP Cube, for a given release.

cube.datamodel
<DRPDataModel release='MPL-6', n_datacubes=3, n_spectra=2>>

The DRP datamodel contains both 1-d (Spectra) and 3-d (DataCubes) representations of the data within a DRP Cube.

# see the available Datacubes
cube.datamodel.datacubes
[<DataCube 'flux', release='MPL-6', unit=u'1e-17 erg / (Angstrom cm2 s spaxel)'>,
 <DataCube 'dispersion', release='MPL-6', unit=u'Angstrom'>,
 <DataCube 'dispersion_prepixel', release='MPL-6', unit=u'Angstrom'>]

 # see the available Spectra
[<Spectrum 'spectral_resolution', release='MPL-6', unit=u'Angstrom'>,
 <Spectrum 'spectral_resolution_prepixel', release='MPL-6', unit=u'Angstrom'>]

DataCubes and Spectra

The datamodel provides DataCube and Spectrum objects for each target for a given release. These objects are marvin quantities. For example, in DR15, there are three available DataCubes, the flux, dispersion, and dispersion_prepixel, and two Spectra, the spectral_resolution and spectral_resolution_prepixel.

# access the cube flux
cube.flux
<DataCube [[[ 0., 0., 0.,...,  0., 0., 0.],
            [ 0., 0., 0.,...,  0., 0., 0.],
            [ 0., 0., 0.,...,  0., 0., 0.],
            ...,
            [ 0., 0., 0.,...,  0., 0., 0.],
            [ 0., 0., 0.,...,  0., 0., 0.],
            [ 0., 0., 0.,...,  0., 0., 0.]]] 1e-17 erg / (Angstrom cm2 s spaxel)>

type(cube.flux)
marvin.tools.quantities.datacube.DataCube

You can always get back the numpy array values using the value attribute.

# retrieve the underlying data
cube.flux.value
array([[[ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        ...,
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.]],

       [[ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        ...

DataCubes and Spectra behave as quantities, so may have available wavelength, ivar and mask attached.

# get the wavelength
cube.flux.wavelength
<Quantity [  3621.6 ,  3622.43,  3623.26,...,  10349.  , 10351.4 , 10353.8 ] Angstrom>

# get the flux ivar and mask
cube.flux.ivar
array([[[ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        ...,
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.]],

       [[ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        ...

cube.flux.mask
array([[[1027, 1027, 1027, ..., 1027, 1027, 1027],
        [1027, 1027, 1027, ..., 1027, 1027, 1027],
        [1027, 1027, 1027, ..., 1027, 1027, 1027],
        ...,
        [1027, 1027, 1027, ..., 1027, 1027, 1027],
        [1027, 1027, 1027, ..., 1027, 1027, 1027],
        [1027, 1027, 1027, ..., 1027, 1027, 1027]],

       [[1027, 1027, 1027, ..., 1027, 1027, 1027],
        [1027, 1027, 1027, ..., 1027, 1027, 1027],
        [1027, 1027, 1027, ..., 1027, 1027, 1027],
        ...

You can manipulate the pixel mask using the pixmask attribute.

cube.flux.pixmask
<Maskbit 'MANGA_DRP3PIXMASK' shape=(4563, 34, 34)>

Extracting a Spaxel

From a Cube you can access Marvin objects related to this particular target. To access a Spaxel, you can slice like an array

# slice a cube by i, j
spaxel = cube[17, 17]
<Marvin Spaxel (plateifu=8485-1901, x=17, y=17; x_cen=0, y_cen=0)>

When slicing a Cube, the xy origin is always the lower left corner of the array, xyorig="lower". Remember Numpy arrays are in row-major. You can also use the getSpaxel method, which provides addionional keyword options; cube[i, j] is a shorthand for cube.getSpaxel(x=j, y=i, xyorig='lower').

# get the central spaxel
spaxel = cube.getSpaxel(x=17, y=17, xyorig='lower')
<Marvin Spaxel (plateifu=8485-1901, x=17, y=17; x_cen=0, y_cen=0)>

By default, the xy origin in getSpaxel is the center of the Cube, xyorig="center".

spaxel = cube.getSpaxel(x=1, y=1)
<Marvin Spaxel (plateifu=8485-1901, x=18, y=18; x_cen=1, y_cen=1)>

Accessing Maps

Maps are also available from the Cube object, using the getMaps method. By default, this grabs the Maps with the default bintype. For more information about Maps see Maps.

# grab the Marvin Maps object
cube.getMaps()
<Marvin Maps (plateifu='8485-1901', mode='local', data_origin='db', bintype='HYB10', template='GAU-MILESHC')>

Saving and Restoring

You can save a Cube locally as a Python pickle object, using the save method.

cube.save('mycube.mpf')

as well as restore a Cube pickle object using the restore class method

from marvin.tools.cube.Cube import Cube

cube = Cube.restore('mycube.mpf')

Reference/API

Class Inheritance Diagram

Inheritance diagram of marvin.tools.cube.Cube

Class

marvin.tools.cube.Cube([input, filename, …]) A class to interface with MaNGA DRP data cubes.

Methods

marvin.tools.cube.Cube.getMaps(**kwargs) Retrieves the DAP Maps for this cube.
marvin.tools.cube.Cube.getSpaxel([x, y, ra, …]) Returns the Spaxel matching certain coordinates.
marvin.tools.cube.Cube.download() Downloads the cube using sdss_access - Rsync,
marvin.tools.cube.Cube.save([path, overwrite]) Pickles the object.
marvin.tools.cube.Cube.restore(path[, delete]) Restores a MarvinToolsClass object from a pickled file.