ejeschke / ginga

The Ginga astronomical FITS file viewer
BSD 3-Clause "New" or "Revised" License
121 stars 77 forks source link

New astropy WCS class incompatible with Anaconda #113

Closed pllim closed 5 years ago

pllim commented 9 years ago

The changes done in #108 give the following errors when I use astropy 1.0.3 that is part of Anaconda:

[WARNI]  Bad coordinate conversion: 'AstropyWCS2' object has no attribute 'coordsys'
[ERROR]  Traceback:
  File ".../ginga-2.4.20150603003439-py2.7.egg/ginga/AstroImage.py", line 621, in info_xy
    elif self.wcs.coordsys == 'raw':
pllim commented 9 years ago

Other errors from the same PR as above:

[WARNI]  Can't calculate compass: global name 'astropy' is not defined
[ERROR]  Traceback:
  File ".../ginga-2.4.20150603003439-py2.7.egg/ginga/misc/plugins/Pan.py", line 205, in set_image
    image.add_offset_xy(x, y, 1.0, 1.0)
  File ".../ginga-2.4.20150603003439-py2.7.egg/ginga/AstroImage.py", line 331, in add_offset_xy
    ra_deg, dec_deg = self.pixtoradec(x, y)
  File ".../ginga-2.4.20150603003439-py2.7.egg/ginga/AstroImage.py", line 279, in pixtoradec
    ra_deg, dec_deg = self.wcs.pixtoradec(args, coords=coords)
  File ".../ginga-2.4.20150603003439-py2.7.egg/ginga/util/wcsmod.py", line 316, in pixtoradec
    return self._frametofloats(self.pixtonative(idxs, coords=coords))
  File ".../ginga-2.4.20150603003439-py2.7.egg/ginga/util/wcsmod.py", line 338, in pixtonative
    self.realize_frame(sky)
  File ".../ginga-2.4.20150603003439-py2.7.egg/ginga/util/wcsmod.py", line 275, in realize_frame
    astropy.coordinates.SphericalRepresentation) and

and

[WARNI]  Can't calculate compass: 'NoneType' object has no attribute 'all_pix2world'
[ERROR]  Traceback:
  File ".../ginga-2.4.20150603003439-py2.7.egg/ginga/misc/plugins/Pan.py", line 205, in set_image
    image.add_offset_xy(x, y, 1.0, 1.0)
  File ".../ginga-2.4.20150603003439-py2.7.egg/ginga/AstroImage.py", line 331, in add_offset_xy
    ra_deg, dec_deg = self.pixtoradec(x, y)
  File ".../ginga-2.4.20150603003439-py2.7.egg/ginga/AstroImage.py", line 279, in pixtoradec
    ra_deg, dec_deg = self.wcs.pixtoradec(args, coords=coords)
  File ".../ginga-2.4.20150603003439-py2.7.egg/ginga/util/wcsmod.py", line 316, in pixtoradec
    return self._frametofloats(self.pixtonative(idxs, coords=coords))
  File ".../ginga-2.4.20150603003439-py2.7.egg/ginga/util/wcsmod.py", line 335, in pixtonative
    raise WCSError(e)
ejeschke commented 9 years ago

@Cadair, would you mind taking a look at this? I think this is in your code, and I haven't yet looked through it to see what exactly is going on.

Cadair commented 9 years ago

I will take a look at this, I don't have much time at the moment.

@pllim Is this particularly urgent? You can override the WCS system right?

ejeschke commented 9 years ago

@plim, for the moment you can simply set

WCSpkg = 'astropy'

in your $HOME/.ginga/general.cfg

pllim commented 9 years ago

@ejeschke , changing the setting to 'astropy' works for me. Thanks! @Cadair , since there is a work-around, this issue is not urgent.

Cadair commented 9 years ago

@pllim I don't seem to be able to replicate this. I managed to open an image in native fk5 and after setting the display coordinate system to something sensible it seems to work fine, I get mouse over coords and the compass.

I am using astropy 1.0.3 from conda and installing ginga from master. Can you tell me more about your setup?

pllim commented 9 years ago

Using ginga.util.wcsmod.AstropyWCS, I get the following when I access its wcs.wcs attribute:

       flag: 137
      naxis: 2
      crpix: 0x2404ae0
               0            0         
         pc: 0x2023890
    pc[0][]:   1            0         
    pc[1][]:   0            1         
      cdelt: 0x20c40b0
               1            1         
      crval: 0x22c2650
               0            0         
      cunit: 0x20238c0
             ""
             ""
      ctype: 0x20d6170
             ""
             ""
    lonpole: UNDEFINED
    latpole: 90.000000
    restfrq: 0.000000
    restwav: 0.000000
        npv: 0
     npvmax: 64
         pv: 0x23160b0
        nps: 0
     npsmax: 8
         ps: 0x22038c0
         cd: 0x2023960
    cd[0][]:   0            0         
    cd[1][]:   0            0         
      crota: 0x20d4810
               0            0         
     altlin: 0
     velref: 0
        alt: ' '
     colnum: 0
      colax: 0x2363a40
                 0      0
    wcsname: UNDEFINED
      cname: 0x20df400
             UNDEFINED
             UNDEFINED
      crder: 0x2382630
             UNDEFINED     UNDEFINED   
      csyer: 0x20b6fc0
             UNDEFINED     UNDEFINED   
    radesys: UNDEFINED
    equinox: UNDEFINED
    specsys: UNDEFINED
    ssysobs: UNDEFINED
    velosys: UNDEFINED
    ssyssrc: UNDEFINED
    zsource: UNDEFINED
     obsgeo: UNDEFINED     UNDEFINED     UNDEFINED
    dateobs: UNDEFINED
    dateavg: UNDEFINED
     mjdobs: UNDEFINED
     mjdavg: UNDEFINED
       ntab: 0
        tab: 0x0
       nwtb: 0
        wtb: 0x0
      types: 0x20f2ed0
               0    0
     lngtyp: "    "
     lattyp: "    "
        lng: -1
        lat: -1
       spec: -1
   cubeface: -1
        err: 0x0
        lin: (see below)
        cel: (see below)
        spc: (see below)
     m_flag: 137
    m_naxis: 2
    m_crpix: 0x2404ae0  (= crpix)
       m_pc: 0x2023890  (= pc)
    m_cdelt: 0x20c40b0  (= cdelt)
    m_crval: 0x22c2650  (= crval)
    m_cunit: 0x20238c0  (= cunit)
    m_ctype: 0x20d6170  (= ctype)
       m_pv: 0x23160b0  (= pv)
       m_ps: 0x22038c0  (= ps)
       m_cd: 0x2023960  (= cd)
    m_crota: 0x20d4810  (= crota)

    m_colax: 0x2363a40  (= colax)
    m_cname: 0x20df400  (= cname)
    m_crder: 0x2382630  (= crder)
    m_csyer: 0x20b6fc0  (= csyer)
      m_tab: 0x0  (= tab)
      m_wtb: 0x0  (= wtb)

   lin.*
       flag: 137
      naxis: 2
      crpix: 0x2404ae0
               0            0         
         pc: 0x2023890
    pc[0][]:   1            0         
    pc[1][]:   0            1         
      cdelt: 0x20c40b0
               1            1         
      unity: 1
        err: 0x0
     piximg: (nil)
     imgpix: (nil)
     m_flag: 0
    m_naxis: 0
    m_crpix: 0x0
       m_pc: 0x0
    m_cdelt: 0x0

   cel.*
      flag: 0
     offset: 0
       phi0: UNDEFINED
     theta0: UNDEFINED
       ref:   0            0            9.8765e+107   90        
       prj: (see below)
     euler:   0            0            0            0            0         
    latpreq: -1 (UNDEFINED)
     isolat: 0
        err: 0x0

   prj.*
       flag: 0
       code: "   "
         r0:  0.000000
         pv: (not used)
       phi0: UNDEFINED
     theta0: UNDEFINED
     bounds: 7

       name: "undefined"
   category: 0 (undefined)
    pvrange: 0
  simplezen: 0
  equiareal: 0
  conformal: 0
     global: 0
  divergent: 0
         x0: 0.000000
         y0: 0.000000
        err: 0x0
        w[]:   0            0            0            0            0         
               0            0            0            0            0         
          m: 0
          n: 0
     prjx2s: 0x0
     prjs2x: 0x0

   spc.*
       flag: 0
       type: "    "
       code: "   "
      crval: UNDEFINED
    restfrq: 0.000000
    restwav: 0.000000
         pv: (not used)
          w:   0            0            0           (remainder unused)
    isGrism: 0
        err: 0x0
     spxX2P: 0x0
     spxP2S: 0x0
     spxS2P: 0x0
     spxP2X: 0x0

I cannot load the header at all with AstropyWCS2.

Admittedly, the WCS information is bogus (someone else made it up, not me!). With AstropyWCS, the compass looks all weird on Ginga, i.e., N and E are not perpendicular. For my purpose, I don't care. But I don't understand why AstropyWCS works but not AstropyWCS2.

pllim commented 9 years ago

I cannot share the image nor its full header, but if you need certain header keywords, please let me know and I'll post the values here. Thanks!

Cadair commented 9 years ago

@pllim hmmm, is it in a coordinate system supported by astropy coordinates?

pllim commented 9 years ago

How do I find out? Like I said, AstropyWCS works.

Cadair commented 9 years ago

what do you get when you run the WCS object through this: http://docs.astropy.org/en/stable/api/astropy.wcs.utils.wcs_to_celestial_frame.html#astropy.wcs.utils.wcs_to_celestial_frame

pllim commented 9 years ago
>>> wcs1 = wcsmod.AstropyWCS(logging)
>>> wcs1.load_header(hdr)
WARNING: FITSFixedWarning: The WCS transformation has more axes (2) than the image it is associated with (0) [astropy.wcs.wcs]
WARNING:astropy:FITSFixedWarning: The WCS transformation has more axes (2) than the image it is associated with (0)
>>> wcs_to_celestial_frame(wcs1.wcs)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File ".../astropy/wcs/utils.py", line 149, in wcs_to_celestial_frame
    raise ValueError("Could not determine celestial frame corresponding to "
ValueError: Could not determine celestial frame corresponding to the specified WCS object
Cadair commented 9 years ago

Interesting. What coordinate system is the WCS describing?

I a test file with an unknown WCS. Could you make a derivative of your file that still reproduces that error?

pllim commented 9 years ago

After carefully combing through the header, I realized that it might not have any WCS keywords at all. I can reproduce the same thing by replacing the input header with empty FITS header:

    hdr = fits.header.Header()

:scream:

Cadair commented 9 years ago

haha nice! Thanks.

Ok I will try and give this a go, but as I say might not be for a while, hard to know at the moment.

pllim commented 9 years ago

No problem, there is no rush on my end. Whatever the solution is, would be nice for AstropyWCS and AstropyWCS2 to at least behave consistently. Thanks for looking into this!

ejeschke commented 8 years ago

I believe this is fixed by PR #206. Feel free to reopen if see otherwise, @pllim.

pllim commented 8 years ago

Nope, still getting the same errors. I am using astropy 1.1rc2. You can probably recreate the traceback yourself by using an image without any WCS information.

ejeschke commented 8 years ago

Hmm, I think the problems may go a little further. When I use a file that has WCS keywords, but with a CUNIT{1,2} of type 'pixel', with the original astropy wcs wrapper it succeeds to create the WCS and resolves to reporting pixels. I get this with the new version of the astropy2 wrapper:

2015-12-09 08:48:58,060 | W | AstroImage.py:702 (info_xy) | Bad coordinate conversion: 'str' object has no attribute 'representation'
2015-12-09 08:48:58,060 | E | AstroImage.py:709 (info_xy) | Traceback:
  File "/home/eric/Git/Ginga/ginga/AstroImage.py", line 660, in info_xy
    args, system=system, coords='data')
  File "/home/eric/Git/Ginga/ginga/util/wcsmod.py", line 421, in pixtosystem
    x, y = self.pixtoradec(idxs, coords=coords)
  File "/home/eric/Git/Ginga/ginga/util/wcsmod.py", line 335, in pixtoradec
    return self._frametofloats(self.pixtonative(idxs, coords=coords))
  File "/home/eric/Git/Ginga/ginga/util/wcsmod.py", line 357, in pixtonative
    self.realize_frame_inplace(sky)
  File "/home/eric/Git/Ginga/ginga/util/wcsmod.py", line 295, in realize_frame_inplace
    if (issubclass(self.coordframe.representation,

@eteq just pinging you as you and @Cadair are the authors/editors of this wrapper.

eteq commented 8 years ago

@ejeschke - hmm, I think this was just a mistake in #206, which I can try to fix.

The basic issue here is that in the new AstropyWCS2 implementation, coordsys (which is renamed coordframe to be more clear- see this docstring) is usually an astropy coordinate frame object, but occasionally is a string. This may be entirely do to my confusion, though: sometimes the ginga WCS machinery wants it to be "raw" or "pixel", and it's not clear to me what these are supposed to mean (or are they the same?). It's also not clear to me which methods are actually used outside of the class itself, so I'm not sure where the best place is to implement overrides that catch the "string" cases. Can you clarify this for me? If so I think I can craft a PR to fix this.

ejeschke commented 8 years ago

I think the problem is that that coordsys attribute, which is exposed (and used) outside the wrapper, needs to be a string. The string is examined to decide how to interpret the output of the wcs. For example, if the type is 'pixel', then the result of running the data coordinate through the wrapper is a pixel coordinate, and it shouldn't be further transformed (e.g. ICRS->galactic).

So I think in astropy2 this needs to revert to a string and simply use a different (internal) variable to hold any coordinates/frames used in the transformation.

ejeschke commented 8 years ago

To be more specific, coordsys should be determined by the wcsmod.get_coord_system_name module level function, unless some of the types cannot be supported by astropy. But I believe all of the ones returned by that function can be supported by astropy2. 'raw' means no sensible WCS keywords could be detected, and so the wrapper functions won't even be called, and 'pixel' will only incur a single wcs transform (data->pixel) and so it won't have to map one frame type to another frame type.

eteq commented 8 years ago

Ohh, gotcha - I didn't realize coordsys was used outside of the wcs class itself. So indeed that's probably the issue. Will try to get in a fix for that.