Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

convert a FITS WCS object to a GWCS object #99

Open
nden opened this issue Sep 6, 2017 · 14 comments
Open

convert a FITS WCS object to a GWCS object #99

nden opened this issue Sep 6, 2017 · 14 comments
Milestone

Comments

@nden
Copy link
Collaborator

nden commented Sep 6, 2017

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 nden added this to the 1.0 milestone Sep 6, 2017
@astrofrog
Copy link

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.

@jdavies-st
Copy link
Contributor

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.

@pllim
Copy link
Contributor

pllim commented Mar 13, 2018

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
Copy link
Contributor

pllim commented Mar 20, 2018

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.

@nden
Copy link
Collaborator Author

nden commented Mar 21, 2018

@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.

@pllim
Copy link
Contributor

pllim commented Mar 21, 2018

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).

@nden
Copy link
Collaborator Author

nden commented Mar 21, 2018

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

@stscijgbot
Copy link

This ticket is now being tracked at AL-56

@jehturner
Copy link

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.

@pllim
Copy link
Contributor

pllim commented Sep 1, 2021

@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?

@jehturner
Copy link

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.

@chris-simpson
Copy link
Contributor

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 astropy/astropy#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.

@pllim
Copy link
Contributor

pllim commented Sep 3, 2021

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

@pllim
Copy link
Contributor

pllim commented Sep 3, 2021

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants