gwcs icon indicating copy to clipboard operation
gwcs copied to clipboard

convert a FITS WCS object to a GWCS object

Open nden opened this issue 8 years ago • 14 comments

Provide a way to convert an astropy.wcs object to a gwcs.WCS object. I'm not sure we need to go the opposite direction even when it's possible. Comments on this welcome.

nden avatar Sep 06 '17 17:09 nden

This would be great. I do think there would be value in saying 'give me the closest approximation to this transform as an astropy.wcs object' for cases where a file has to be written with 'FITS' WCS for backward-compatibility with specific viewers.

astrofrog avatar Sep 07 '17 19:09 astrofrog

A lot of the code to implement this already exists in gwcs in some form. The utils.make_fitswcs_transform() method does most of the heavy lifting I think.

jdavies-st avatar Sep 07 '17 20:09 jdavies-st

I am just looking for this. I have the following "header" (from a Ginga test). I have no idea how to turn it into a GWCS object.

             header = {'ADC-END': 6.28,
                       'ADC-STR': 6.16,
                       'ADC-TYPE': 'IN',
                       'AIRMASS': 1.0526,
                       'ALTITUDE': 72.142,
                       'AUTOGUID': 'ON',
                       'AZIMUTH': 282.679,
                       'BIN-FCT1': 1,
                       'BIN-FCT2': 1,
                       'BITPIX': -32,
                       'BLANK': -32768,
                       'BUNIT': 'ADU',
                       'CD1_1': -5.611e-05,
                       'CD1_2': 0.0,
                       'CD2_1': 0.0,
                       'CD2_2': 5.611e-05,
                       'CDELT1': -5.611e-05,
                       'CDELT2': 5.611e-05,
                       'COADD': 1,
                       'CRPIX1': 5276.0,
                       'CRPIX2': 25.0,
                       'CRVAL1': 299.91736667,
                       'CRVAL2': 22.68769444,
                       'CTYPE1': 'RA---TAN',
                       'CTYPE2': 'DEC--TAN',
                       'CUNIT1': 'degree',
                       'CUNIT2': 'degree',
                       'DATA-TYP': 'OBJECT',
                       'DATASET': 'DS000',
                       'DATE-OBS': '2009-08-22',
                       'DEC': '+22:41:15.70',
                       'DEC2000': '+22:41:15.70',
                       'DET-A01': 90.0,
                       'DET-ID': 6,
                       'DET-P101': -79.14,
                       'DET-P201': -0.375,
                       'DET-TMAX': 0.0,
                       'DET-TMED': 0.0,
                       'DET-TMIN': 0.0,
                       'DET-TMP': 172.74,
                       'DET-VER': 'spcam20080721',
                       'DETECTOR': 'chihiro',
                       'DOM-HUM': 12.4,
                       'DOM-PRS': 622.3,
                       'DOM-TMP': 276.35,
                       'DOM-WND': 0.6,
                       'EFP-MIN1': 9,
                       'EFP-MIN2': 49,
                       'EFP-RNG1': 2256,
                       'EFP-RNG2': 4177,
                       'EQUINOX': 2000.0,
                       'EXP-ID': 'SUPE01118760',
                       'EXP1TIME': 90.0,
                       'EXPTIME': 90.0,
                       'EXTEND': False,
                       'FILTER01': 'W-J-B',
                       'FOC-POS': 'Prime',
                       'FOC-VAL': 7.14,
                       'FRAMEID': 'SUPA01118766',
                       'GAIN': 3.73,
                       'HST': '23:34:25.911',
                       'HST-END': '23:35:55.010',
                       'HST-STR': '23:34:25.911',
                       'INR-END': -174.487,
                       'INR-STR': -174.239,
                       'INS-VER': 'Messia5/sup080721',
                       'INST-PA': 90.0,
                       'INSTRUME': 'SuprimeCam',
                       'LONGPOLE': 180.0,
                       'LST': '21:15:48.968',
                       'LST-END': '21:17:18.311',
                       'LST-STR': '21:15:48.968',
                       'M2-ANG1': 1.5,
                       'M2-ANG2': -0.0,
                       'M2-ANG3': 0.0,
                       'M2-POS1': -0.753,
                       'M2-POS2': -2.1,
                       'M2-POS3': 8.205,
                       'MJD': 55065.398914,
                       'MJD-END': 55065.399945,
                       'MJD-STR': 55065.398914,
                       'NAXIS': 2,
                       'NAXIS1': 2272,
                       'NAXIS2': 4273,
                       'OBJECT': 'M27',
                       'OBS-ALOC': 'Observation',
                       'OBS-MOD': 'IMAG_N_VGW',
                       'OBSERVAT': 'NAOJ',
                       'OBSERVER': 'Jeschke, Inagaki, Streeper, Yagi, Nakata',
                       'OUT-HUM': 13.1,
                       'OUT-PRS': 622.3,
                       'OUT-TMP': 275.95,
                       'OUT-WND': 6.0,
                       'PRD-MIN1': 1,
                       'PRD-MIN2': 1,
                       'PRD-RNG1': 2272,
                       'PRD-RNG2': 4273,
                       'PROP-ID': 'o99005',
                       'RA': '19:59:40.168',
                       'RA2000': '19:59:40.168',
                       'RADECSYS': 'FK5',
                       'SECZ-END': 1.053,
                       'SECZ-STR': 1.051,
                       'SEEING': 0.29,
                       'SIMPLE': True,
                       'S_AG-DEC': 'N/A',
                       'S_AG-EQN': 2000.0,
                       'S_AG-OBJ': 'N/A',
                       'S_AG-R': 999.99,
                       'S_AG-RA': 'N/A',
                       'S_AG-TH': 999.99,
                       'S_AG-X': 109.97,
                       'S_AG-Y': 19.3,
                       'S_BCTAVE': 999.999,
                       'S_BCTSD': 999.999,
                       'S_DELTAD': 0.0,
                       'S_DELTAZ': 0.0,
                       'S_EFMN11': 9,
                       'S_EFMN12': 49,
                       'S_EFMN21': 617,
                       'S_EFMN22': 49,
                       'S_EFMN31': 1145,
                       'S_EFMN32': 49,
                       'S_EFMN41': 1753,
                       'S_EFMN42': 49,
                       'S_EFMX11': 520,
                       'S_EFMX12': 4225,
                       'S_EFMX21': 1128,
                       'S_EFMX22': 4225,
                       'S_EFMX31': 1656,
                       'S_EFMX32': 4225,
                       'S_EFMX41': 2264,
                       'S_EFMX42': 4225,
                       'S_ETMAX': 0.0,
                       'S_ETMED': 273.15,
                       'S_ETMIN': 0.0,
                       'S_FRMPOS': '0001',
                       'S_GAIN1': 3.73,
                       'S_GAIN2': 2.95,
                       'S_GAIN3': 3.1,
                       'S_GAIN4': 3.17,
                       'S_M2OFF1': 0.0,
                       'S_M2OFF2': 0.0,
                       'S_M2OFF3': 7.14,
                       'S_OSMN11': 521,
                       'S_OSMN12': 1,
                       'S_OSMN21': 569,
                       'S_OSMN22': 1,
                       'S_OSMN31': 1657,
                       'S_OSMN32': 1,
                       'S_OSMN41': 1705,
                       'S_OSMN42': 1,
                       'S_OSMX11': 568,
                       'S_OSMX12': 48,
                       'S_OSMX21': 616,
                       'S_OSMX22': 48,
                       'S_OSMX31': 1704,
                       'S_OSMX32': 48,
                       'S_OSMX41': 1752,
                       'S_OSMX42': 48,
                       'S_SENT': False,
                       'S_UFNAME': 'object060_chihiro.fits',
                       'S_XFLIP': False,
                       'S_YFLIP': True,
                       'TELESCOP': 'Subaru',
                       'TELFOCUS': 'P_OPT',
                       'TIMESYS': 'UTC',
                       'UT': '09:34:25.911',
                       'UT-END': '09:35:55.010',
                       'UT-STR': '09:34:25.911',
                       'WCS-ORIG': 'SUBARU Toolkit',
                       'WEATHER': 'Fine',
                       'ZD-END': 18.2,
                       'ZD-STR': 17.858}

Following suggestion from @jdavies-st above, I get error using GWCS 0.8.0:

>>> from gwcs.utils import make_fitswcs_transform
>>> w = make_fitswcs_transform(header)
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
----> 1 w = make_fitswcs_transform(header)

.../gwcs/utils.py in make_fitswcs_transform(header)
    386         raise TypeError("Expected a FITS Header or a dict.")
    387     transforms = []
--> 388     wcs_linear = fitswcs_linear(wcs_info)
    389     transforms.append(wcs_linear)
    390     wcs_nonlinear = fitswcs_nonlinear(wcs_info)

.../gwcs/utils.py in fitswcs_linear(header)
    411         raise TypeError("Expected a FITS Header or a dict.")
    412 
--> 413     pc = wcs_info['PC']
    414     # get the part of the PC matrix corresponding to the imaging axes
    415     sky_axes, spec_axes, unknown = get_axes(wcs_info)

KeyError: 'PC'

This same header goes through tests with Kapteyn, Starlink, Astlib, and astropy.wcs with no problem.

pllim avatar Mar 13 '18 20:03 pllim

Update: Despite the fix in #142 , the furthest I get is converting FITS header into some compound model. I don't know how to then create a proper GWCS object from that compound model. I tried using something like http://gwcs.readthedocs.io/en/latest/gwcs/wcstools.html but that wcsobj gave me wrong answers. So, my conclusion is that while make_fitswcs_transform() does heavy lifting, it is still insufficient.

Motivation: Having this feature would make testing ejeschke/ginga#327 so much easier.

pllim avatar Mar 20 '18 19:03 pllim

@pllim make_fitswcs_transform was a "proof-of-concept" type code and as such covers only limited FITS WCS options. This issue is about writing astropy.modeling.Model class which can represent a FITS WCS object. If you are interested in doing this we can talk offline.

I guess I don't understand why a FITS WCS object should be converted to a gwcs object in order to support gwcs in stginga. But this is also off topic for thsi issue.

nden avatar Mar 21 '18 12:03 nden

I don't understand why a FITS WCS object should be converted to a gwcs object in order to support gwcs in stginga

This is not about stginga. This is about Ginga itself and perhaps more generally, GWCS beyond JWST. Currently (JWST aside), WCS are in FITS headers. Is your plan to simply ask those users to use astropy.wcs and never GWCS? I guess I need to understand a little where this package is going.

If your answer is "we only care about GWCS that uses JWST models", then perhaps I need to move GWCS support to stginga as well (not just ASDF reader for Ginga). Unfortunately, in this situation, other institutions using GWCS (e.g., SunPy in the near future) would write their own hooks to Ginga (i.e., no universal GWCS support in Ginga).

pllim avatar Mar 21 '18 15:03 pllim

I am not following. It's best to talk in person.

nden avatar Mar 21 '18 15:03 nden

This ticket is now being tracked at AL-56

stscijgbot avatar Jul 12 '19 16:07 stscijgbot

Since I spotted this issue in passing, @chris-simpson has done a bit of related work at https://github.com/GeminiDRSoftware/DRAGONS/blob/master/astrodata/wcs.py.

jehturner avatar Apr 20 '21 21:04 jehturner

@jehturner , I still wish I can use such functionality but I cannot introduce dependency to Gemini pipeline. Any plans to port the translation function upstream?

pllim avatar Sep 01 '21 21:09 pllim

I don't think there's a plan to, but perhaps we could do so if it's general-purpose enough and/or not too much work to make it so. But @chris-simpson is out for I think the next couple of weeks, so we probably won't be able to discuss that until he's back. Does this look useful to you and @nden as-is? My quick impression is that it's somewhat general, but I'd be surprised if it can cover everyone's use cases.

jehturner avatar Sep 02 '21 22:09 jehturner

It was always my intention to submit a PR once we had something that works for us (the priority of course), which is now nearly the case (after much detailed reading of the FITS documentation). One of the outstanding issues is the incorrect broadcasting of fix_inputs in astropy.modeling https://github.com/astropy/astropy/issues/12021 which causes problems if, for example, one is doing a 2D->3D transformation (longslit to RA, Dec, wavelength) which we've had to work around in a rather hacky way with Mapping.

chris-simpson avatar Sep 02 '21 23:09 chris-simpson

I cannot speak for @nden but my immediate use case only covers 2D imager, which should be pretty simple, I hope.

pllim avatar Sep 03 '21 00:09 pllim

Anyways, there is no rush on my side. I'll just continue to wait and see where things go. Thanks for the update!

pllim avatar Sep 03 '21 13:09 pllim