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

Setting `.header['blah']` fails #385

Open keflavich opened 7 years ago

keflavich commented 7 years ago

If you have a cube and you try:

cube.header['OBJECT'] = 'blah'

no exception is raised, but no change to the underlying header will happen either. This is because the header object is a copy of the header object.

@astrofrog, @e-koch - any ideas on how to avoid this? I can't think of a way to make this header object unmodifiable or to redirect the __setitem__ of the copied object to the underlying object.

e-koch commented 7 years ago

@low-sky - This is related to what you pointed out last week. Were you setting the whole header in cubes? Or in projections?

low-sky commented 7 years ago

Whole cubes, I think? I was trying to get uvcombine working with a feather.

drtobybrown commented 4 years ago

Is there a way to work around this and update keys and values in the headers? I'm running into this issue when reading fits cubes, updating/modifying, and then writing cubes back to fits - the header is not updated.

e.g., cube.header.__setitem__("VELREF", 1) doesn't update the VELREF value

keflavich commented 4 years ago

Try setting cube.meta['VELREF'].

If you need to modify a WCS parameter, this might not work, but for any other header keyword, this is the correct way to modify it. You should be able to test by doing:

cube.meta['blah'] = 'foo'
assert cube.hdu.header['BLAH'] == 'foo'

though note that this might do some reading-data-into-memory and you might need .hdulist if it's a multibeam cube.

drtobybrown commented 4 years ago

That worked - thanks!

drtobybrown commented 4 years ago

Running into this issue again. I can't seem to update the meta units (or header) when converting cubes in K to Jy/beam.

assert cube_k.hdu.header['BUNIT'] == 'K'
cube_jy = cube_k / cube_k.hdu.header['JTOK']
cube_jy.meta['BUNIT'] = 'Jy/beam'
assert cube_jy.hdu.header['BUNIT'] == 'Jy/beam'

---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-121-42d0da3033f6> in <module>
      2 cube_jy = cube_k / cube_k.hdu.header['JTOK']
      3 cube_jy.meta['BUNIT'] = 'Jy/beam'
----> 4 assert cube_jy.hdu.header['BUNIT'] == 'Jy/beam'

AssertionError: 
keflavich commented 4 years ago

Right, you cannot change the hdu units - that's intentional. Those should be automatically set when you convert the units of the cube. Your calculations should be:

cube_jy = cube_k.to(u.Jy/u.beam)

for example. See https://spectral-cube.readthedocs.io/en/latest/beam_handling.html.