radio-astro-tools / spectral-cube

Library for reading and analyzing astrophysical spectral data cubes
http://spectral-cube.rtfd.org
BSD 3-Clause "New" or "Revised" License
98 stars 65 forks source link

cube is dimensionless after smoothing #527

Closed elehcim closed 5 years ago

elehcim commented 5 years ago
In [1]: cube
Out[1]: 
SpectralCube with shape=(8079, 80, 80) and unit=1e-20 erg / (Angstrom cm2 s):
 n_x:     80  type_x: RA---TAN  unit_x: deg    range:    55.028683 deg:   55.034083 deg
 n_y:     80  type_y: DEC--TAN  unit_y: deg    range:   -35.628307 deg:  -35.623918 deg
 n_s:   8079  type_s: AWAV      unit_s: Angstrom  range:     1680.311 Angstrom:    8951.124 Angstrom

In [2]: cube.units
Out[2]: Unit("1e-20 erg / (Angstrom cm2 s)")

In [3]: spatial_kernel                                                                                                                   
Out[3]: <astropy.convolution.kernels.Gaussian2DKernel at 0x7fb1eeade198> 

In [4]: spatial_sm = cube.spatial_smooth(spatial_kernel)

In [5]: spatial_sm
Out[5]: 
SpectralCube with shape=(8079, 80, 80):
 n_x:     80  type_x: RA---TAN  unit_x: deg    range:    55.028683 deg:   55.034083 deg
 n_y:     80  type_y: DEC--TAN  unit_y: deg    range:   -35.628307 deg:  -35.623918 deg
 n_s:   8079  type_s: AWAV      unit_s: Angstrom  range:     1680.311 Angstrom:    8951.124 Angstrom

In [6]: spatial_sm.unit
Out[6]: Unit(dimensionless)                                                                                                         

Same behaviour with spectral smoothing:

In [2]: spectral_kernel                                                                                                                  
Out[2]: <astropy.convolution.kernels.Gaussian1DKernel at 0x7fb1fd538080>

In [3]: spec_sm = cube.spectral_smooth(spectral_kernel) 

In [4]: spec_sm
Out[4]: 
SpectralCube with shape=(8079, 80, 80):
 n_x:     80  type_x: RA---TAN  unit_x: deg    range:    55.028683 deg:   55.034083 deg
 n_y:     80  type_y: DEC--TAN  unit_y: deg    range:   -35.628307 deg:  -35.623918 deg
 n_s:   8079  type_s: AWAV      unit_s: Angstrom  range:     1680.311 Angstrom:    8951.124 Angstrom

In [5]: spec_sm.unit                                                                                                                      
Out[5]: Unit(dimensionless)

I'm using

spectral_cube.__version__   =  '0.4.4.dev2011'
elehcim commented 5 years ago

I'm working with mock data, and I'm building the cube from the initializer. I found that my cube.meta dictionary was empty. Filling it with header['BUNIT'], is a workaround to the problem.

I was puzzled because the header instead is propagated. That's done implicitly in the _new_cube_with method.

So I'm going to suggest (a PR when I have time) to add the header itself as a source for getting the "BUNIT" card in BaseSpectralCube.__init__. In fact, the cube tested in test_regrid.py is read from fits and in that reader there is the line:

if 'BUNIT' in header:
    meta['BUNIT'] = header['BUNIT']

The duplication between meta dict and header is a bit confusing.

keflavich commented 5 years ago

Thanks, this looks like a real error and I'll find a fix for it.

The header and meta dict are intentionally distinct, because the header contains both WCS information (which is stored in the cube.wcs attribute and replaced by that attribute when the header is accessed) and metadata information. If these are getting desynced, we need to fix that.