Welcome to the JWST/HST Alignment Tool (JHAT)

Installation

jhat works on Python 3+ and requires the following Python packages (these should install automatically when you install jhat):

Install using pip

Using pip:

pip install jhat

Install Development Version

Using git:

git clone https://github.com/arminrest/jhat.git
cd jhat
python setup.py install

Interpreting Plots

This is the initial plot to check if things are going the right direction. Here each point is a source detected in the image. Blue points have passed the initial cuts, gray points fail cuts are are not used. If there is a locus in both dx and dy, then the code will be able to find the correct alignment parameters. The second row just shows the same sources as a function of some photometric parameters.

alternate text

This is an example of the same set of plots for a case where the alignment has failed. No locus is apparent in dx or dy. If there is no relation to be seen in this initial plot, then cuts and params need to be changed/loosened (see Useful Parameters), in this case d2d_max should be increased.

alternate text

The second important set of plots comes from the selection of good matches between reference catalog and target image source catalog. First the best rotation and offset is chosen for dx, which is successful if there is a clear peak in the upper left panel (histogram peak value versus slope). In the second row, blue dots are sources that are kept after rotation, and red are the original unrotated dx residuals (lower left panel). Then a 3sigma cut is done on the sources in the dx parameter space, and red indicates the cut values in the far right center row. Finally, the the same is done for dy, but ONLY with sources that already passed the dx cut.

alternate text alternate text

Finally, we can check what the alignment did by observing the pre and post wcs-correction plots.

alternate text alternate text

Useful Parameters

Here we describe the most useful parameters and what changing them does inside of the code.

  • d2d_max

  • sharpness_lim

  • roundness1_lim

  • delta_mag_lim

  • objmag_lim

  • refmag_lim

  • slope_min

  • Nbright4match

  • Nbright

  • xshift/yshift

  • rough_cut_px_min/max

  • d_rotated_Nsigma

Command Line Commands

Here we have a directory called “miri_example” that has some MIRI cals. JHAT can also be run from the command line in the following way:

run_st_wcs_align.py miri_example/jw02666001001_02101_00001_mirimage_cal.fits --outrootdir '.'
        --outsubdir aligned  --overwr -v --refcat gaia --saveplots -tt -pp --histocut_order dxdy

Which produces the following plots:

alternate text alternate text alternate text alternate text alternate text

Improving Alignment

Sometimes, in particular if there are not enough sources or the images are particularly poorly aligned, JHAT has a difficult time finding a good alignment (or it can be improved). Here are a few methods for improving the results. First we add cuts on sharpness, roundness, and brightness:

run_st_wcs_align.py miri_example/jw02666001001_02101_00001_mirimage_cal.fits --outrootdir '.'
        --outsubdir aligned  --overwr -v --refcat gaia --saveplots -tt -pp --histocut_order dxdy
        --roundness1_lim -0.5 0.5 --objmag_lim 14 21.5 --sharpness_lim 0.6 0.85 --refmag_lim 16 25
alternate text alternate text alternate text alternate text alternate text

Next we increase the allowed distance between matches between the reference and target catalogs (d2d_max), and limit the difference between measured magnitudes between the catalogs.

run_st_wcs_align.py miri_example/jw02666001001_02101_00001_mirimage_cal.fits --outrootdir '.'
        --outsubdir aligned  --overwr -v --refcat gaia --saveplots -tt -pp --histocut_order dxdy
        --roundness1_lim -0.5 0.5 --objmag_lim 14 21.5 --refmag_lim 16 25 --delta_mag_lim -2 2 --d2d_max 1.5
alternate text alternate text alternate text alternate text alternate text

Finally, we might use the previous results to guess the rough needed offset, and apply it directly before the matching begins:

run_st_wcs_align.py miri_example/jw02666001001_02101_00001_mirimage_cal.fits --outrootdir '.'
        --outsubdir aligned  --overwr -v --refcat gaia --saveplots -tt -pp --histocut_order dxdy
        --roundness1_lim -0.5 0.5 --objmag_lim 14 21.5 --refmag_lim 16 25 --delta_mag_lim -2 2
        --d2d_max 1.5 --xshift 3 --yshift -4
alternate text alternate text alternate text alternate text alternate text

Level 3 From Aligned Cals

We run F560W with the best options determined from the Improving Alignment example:

run_st_wcs_align_batch.py --input_dir '.' --input_files 'miri_example/*_cal.fits' --outrootdir aligned
        --outsubdir F560W_level2_gaia  --overwr -v --refcat gaia --saveplots -tt -pp --histocut_order dxdy
        --roundness1_lim -0.5 0.5 --objmag_lim 14 21.5  --refmag_lim 16 25 --delta_mag_lim -2 2
        --d2d_max 1.5 --xshift 3 --yshift -4 --filter F560W

Now we run the notebook that runs level3 and creates the mosaic and the corresponding catalog (On GitHub here). That notebook produces a catalog (F560W_snr3_npix10_cat.ecsv), which we choose as our secondary astrometric catalog.

Now we run the rest of the filters. However, we remove –delta_mag_lim, since this cut depends on the filter!!! Note that we define the necessary column names from the catalog, which are different from the defaults.

run_st_wcs_align_batch.py --input_dir '.' --input_files 'miri_example/*_cal.fits' --outrootdir miri_example
        --outsubdir ALL_level2_catF560W  --overwr -v --refcat F560W_snr3_npix10_cat.ecsv --saveplots -tt -pp
        --histocut_order dxdy --roundness1_lim -0.5 0.5 --objmag_lim 14 21.5  --refmag_lim 16 25 --d2d_max 1.5
        --xshift 3 --yshift -4 --iterate_with_xyshifts --refcat_racol sky_centroid.ra
        --refcat_deccol sky_centroid.dec --refcat_magcol aper50_abmag  --refcat_magerrcol aper50_abmag_err
        --filters F560W F1000W F1280W F1130W F1500W F1800W

We find that F1500W F1800W mostly work, but don’t have many stars. Therefore we run it with –d_rotated_Nsigma 0.0: Too few stars to do a 3-sigma cut.

run_st_wcs_align_batch.py --input_dir '.' --input_files 'miri_example/*_cal.fits' --outrootdir miri_example
        --outsubdir ALLRED_level2_catF560W  --overwr -vvv --refcat F560W_snr3_npix10_cat.ecsv --saveplots -tt -pp
        --histocut_order dxdy --roundness1_lim -0.5 0.5 --objmag_lim 14 21.5  --refmag_lim 16 25 --d2d_max 1.5 --xshift 3
        --yshift -4 --iterate_with_xyshifts --refcat_racol sky_centroid.ra --refcat_deccol sky_centroid.dec --refcat_magcol
        aper50_abmag  --refcat_magerrcol aper50_abmag_err  --filters F1500W F1800W F2100W --d_rotated_Nsigma 0.0

Examples

JWST MIRI

JWST MIRI

JWST NIRCAM

JWST NIRCAM

Hubble

Hubble

JWST MIRI

Aligning JWST/MIRI images with JHAT.

An example MIRI Dataset is downloaded, and then a series of alignment methods are used. For more information on the key parameters used for alignment see Useful Parameters.

import sys,os,glob
from astropy.io import fits
from astropy.table import Table
from astropy.nddata import extract_array
from astropy.coordinates import SkyCoord
from astropy import wcs
from astropy.wcs.utils import skycoord_to_pixel
from astropy import units as u
import numpy as np
import matplotlib.pyplot as plt
from astroquery.mast import Observations
from astropy.visualization import (simple_norm,LinearStretch)

import jhat
from jhat import jwst_photclass,st_wcs_align

Relative Alignment

Download some Data

For this example we download 2 MIRI cal images from MAST. They’re the same field and different filters. Note that the code will also work for level 3 images.

obs_table1 = Observations.query_criteria(obs_id='jw02107-o038_t019_miri_f770w')
data_products_by_obs = Observations.get_product_list(obs_table1)
data_products_by_obs = data_products_by_obs[data_products_by_obs['calib_level']==2]
data_products_by_obs = data_products_by_obs[data_products_by_obs['productSubGroupDescription']=='CAL'][0]
Observations.download_products(data_products_by_obs,extension='fits')

obs_table2 = Observations.query_criteria(obs_id='jw02107-c1018_t019_miri_f1130w')
data_products_by_obs = Observations.get_product_list(obs_table2)
data_products_by_obs = data_products_by_obs[data_products_by_obs['calib_level']==2]
data_products_by_obs = data_products_by_obs[data_products_by_obs['productSubGroupDescription']=='CAL'][0]
Observations.download_products(data_products_by_obs,extension='fits')
Downloading URL https://mast.stsci.edu/api/v0.1/Download/file?uri=mast:JWST/product/jw02107038001_02101_00001_mirimage_cal.fits to ./mastDownload/JWST/jw02107038001_02101_00001_mirimage/jw02107038001_02101_00001_mirimage_cal.fits ... [Done]
Downloading URL https://mast.stsci.edu/api/v0.1/Download/file?uri=mast:JWST/product/jw02107038001_02105_00001_mirimage_cal.fits to ./mastDownload/JWST/jw02107038001_02105_00001_mirimage/jw02107038001_02105_00001_mirimage_cal.fits ... [Done]
Table length=1
Local PathStatusMessageURL
str98str8objectobject
./mastDownload/JWST/jw02107038001_02105_00001_mirimage/jw02107038001_02105_00001_mirimage_cal.fitsCOMPLETENoneNone


Examine the Reference Image

files = glob.glob('mastDownload/JWST/*miri*/*cal.fits')
ref_image = files[0]
print(ref_image)
ref_fits = fits.open(ref_image)
ref_data = fits.open(ref_image)['SCI',1].data
norm1 = simple_norm(ref_data,stretch='log',min_cut=5,max_cut=25)

plt.imshow(ref_data, origin='lower',
                      norm=norm1,cmap='gray')
plt.gca().tick_params(labelcolor='none',axis='both',color='none')
plt.show()
plot c miri
mastDownload/JWST/jw02107038001_02101_00001_mirimage/jw02107038001_02101_00001_mirimage_cal.fits

Zoom in to see the offset

Here add an artificial offset to the wcs, and then we see the same star in both images at the same ra/dec location, demonstrating a large offset between the images.

star_location = SkyCoord('23:09:44.0809','-43:26:05.613',unit=(u.hourangle,u.deg))
align_image = files[1]
align_fits = fits.open(align_image)
align_fits['SCI',1].header['CRPIX1']+=2
align_fits['SCI',1].header['CRPIX2']+=2
align_fits.writeto(align_image,overwrite=True)

align_data = fits.open(align_image)['SCI',1].data
ref_y,ref_x = skycoord_to_pixel(star_location,wcs.WCS(ref_fits['SCI',1],ref_fits))
align_y,align_x = skycoord_to_pixel(star_location,wcs.WCS(align_fits['SCI',1],align_fits))

ref_cutout = extract_array(ref_data,(11,11),(ref_x,ref_y))
align_cutout = extract_array(align_data,(11,11),(align_x,align_y))
norm1 = simple_norm(ref_cutout,stretch='log',min_cut=-1,max_cut=200)
norm2 = simple_norm(align_cutout,stretch='log',min_cut=-1,max_cut=200)
fig,axes = plt.subplots(1,2)
axes[0].imshow(ref_cutout, origin='lower',
                      norm=norm1,cmap='gray')
axes[1].imshow(align_cutout, origin='lower',
                      norm=norm2,cmap='gray')
axes[0].set_title('Reference')
axes[1].set_title('To Align')
axes[0].tick_params(labelcolor='none',axis='both',color='none')
axes[1].tick_params(labelcolor='none',axis='both',color='none')

plt.show()
Reference, To Align
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/wcs/wcs.py:725: FITSFixedWarning: 'datfix' made the change 'Set DATE-BEG to '2022-07-06T17:29:42.548' from MJD-BEG.
Set DATE-AVG to '2022-07-06T17:29:53.648' from MJD-AVG.
Set DATE-END to '2022-07-06T17:30:04.748' from MJD-END'.
  warnings.warn(
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/wcs/wcs.py:725: FITSFixedWarning: 'obsfix' made the change 'Set OBSGEO-L to   -72.176807 from OBSGEO-[XYZ].
Set OBSGEO-B to   -38.353152 from OBSGEO-[XYZ].
Set OBSGEO-H to 1740801417.596 from OBSGEO-[XYZ]'.
  warnings.warn(
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/wcs/wcs.py:725: FITSFixedWarning: 'datfix' made the change 'Set DATE-BEG to '2022-07-06T17:47:53.158' from MJD-BEG.
Set DATE-AVG to '2022-07-06T17:48:32.008' from MJD-AVG.
Set DATE-END to '2022-07-06T17:49:10.859' from MJD-END'.
  warnings.warn(
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/wcs/wcs.py:725: FITSFixedWarning: 'obsfix' made the change 'Set OBSGEO-L to   -72.174733 from OBSGEO-[XYZ].
Set OBSGEO-B to   -38.353284 from OBSGEO-[XYZ].
Set OBSGEO-H to 1740817774.322 from OBSGEO-[XYZ]'.
  warnings.warn(

Create a Photometric Catalog for Relative Alignment

We choose one of the images to be the reference image, and then create a catalog that we will use to align the other image.

jwst_phot = jwst_photclass()
jwst_phot.run_phot(imagename=ref_image,photfilename='auto',overwrite=True)
ref_catname = ref_image.replace('.fits','.phot.txt') # the default
refcat = Table.read(ref_catname,format='ascii')
print(refcat)
0 mastDownload/JWST/jw02107038001_02101_00001_mirimage/jw02107038001_02101_00001_mirimage_cal.phot.txt
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/wcs/wcs.py:725: FITSFixedWarning: 'datfix' made the change 'Set DATE-BEG to '2022-07-06T17:29:42.548' from MJD-BEG.
Set DATE-AVG to '2022-07-06T17:29:53.648' from MJD-AVG.
Set DATE-END to '2022-07-06T17:30:04.748' from MJD-END'.
  warnings.warn(
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/wcs/wcs.py:725: FITSFixedWarning: 'obsfix' made the change 'Set OBSGEO-L to   -72.176807 from OBSGEO-[XYZ].
Set OBSGEO-B to   -38.353152 from OBSGEO-[XYZ].
Set OBSGEO-H to 1740801417.596 from OBSGEO-[XYZ]'.
  warnings.warn(
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/stats/sigma_clipping.py:411: AstropyUserWarning: Input data contains invalid values (NaNs or infs), which were automatically clipped.
  warnings.warn('Input data contains invalid values (NaNs or '
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/stats/sigma_clipping.py:411: AstropyUserWarning: Input data contains invalid values (NaNs or infs), which were automatically clipped.
  warnings.warn('Input data contains invalid values (NaNs or '
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/units/function/logarithmic.py:47: RuntimeWarning: invalid value encountered in log10
  return dex.to(self._function_unit, np.log10(x))
/Users/jpierel/CodeBase/jhat/jhat/simple_jwst_phot.py:897: RuntimeWarning: invalid value encountered in log10
  phot['magerr'] = 2.5 * np.log10(1.0 + (fluxerr/flux))
aper_sum_4.1px annulus_median_4.1px aper_bkg_4.1px ...   x_idl      y_idl
-------------- -------------------- -------------- ... ---------- ----------
    297.650667               -99.99   -5238.189153 ...  37.152004 -55.873059
    378.648855             5.548146     290.651448 ...  30.043803 -54.923731
    115.583682               -99.99   -5238.189153 ... -76.001952 -54.071845
    294.794123             0.126702        6.63754 ... -76.013673 -51.700329
    234.943054             0.218582      11.450907 ... -76.018672 -50.556787
    467.419303              6.36806     333.604394 ...  -3.833359  -48.74132
    342.922546             0.173903       9.110269 ... -76.032743 -47.064001
    371.015027             0.207516      10.871191 ... -76.037395 -45.257877
    173.426586             0.099091       5.191109 ...  -76.03994 -44.794514
    838.584206             7.751832     406.096233 ...  -9.072841 -43.561009
           ...                  ...            ... ...        ...        ...
    133.430719               0.1092       5.720696 ... -75.754248  30.346453
    245.152683             0.405534      21.244786 ... -75.721452  34.663273
    233.690538             0.556301      29.143019 ... -75.716036  35.792661
    445.263408              0.72363      37.908921 ... -75.646588   46.09179
       176.538             0.783822      41.062174 ... -75.634492  47.785745
    617.329614             4.899353     256.663045 ...  36.555135   50.32043
    622.234759             4.964599     260.081101 ...   36.55006  51.069329
    330.330828             0.707696      37.074164 ... -75.607653  52.275188
    378.108748             0.679931      35.619658 ... -75.600128  53.678531
    547.845954               -99.99   -5238.189153 ... -75.589207  55.779377
    459.438067               -99.99   -5238.189153 ...  36.520526  55.674128
Length = 211 rows

Align the second image

The plots outputted here show the various steps used by jhat to determine the true matching sources in the image, and the subsequent correction needed for optimal alignment.

wcs_align = st_wcs_align()


wcs_align.run_all(align_image,
              telescope='jwst',
              outsubdir='mastDownload',
          refcat_racol='ra',
          refcat_deccol='dec',
          refcat_magcol='mag',
          refcat_magerrcol='dmag',
          overwrite=True,
          d2d_max=1,
          showplots=2,
          refcatname=ref_catname,
          histocut_order='dxdy',
              sharpness_lim=(0.3,0.9),
              roundness1_lim=(-0.7, 0.7),
              SNR_min= 3,
              dmag_max=1.0,
              objmag_lim =(14,24))
  • Initial cut: d2d_max=1, dmag_max=None, Nbright=None, delta_mag_lim=(None, None)
  • dx, dx, dx, slope:4.882812499998248e-05, 3-sigma cut: 72 out of 75 left mean = -0.158 px, stdev = 0.191 px
  • dy, dy, dy, slope:4.882812499998248e-05, 3-sigma cut: 61 out of 61 left mean = 0.127 px, stdev = 0.257 px
0 ./mastDownload/jw02107038001_02105_00001_mirimage.phot.txt
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/wcs/wcs.py:725: FITSFixedWarning: 'datfix' made the change 'Set DATE-BEG to '2022-07-06T17:47:53.158' from MJD-BEG.
Set DATE-AVG to '2022-07-06T17:48:32.008' from MJD-AVG.
Set DATE-END to '2022-07-06T17:49:10.859' from MJD-END'.
  warnings.warn(
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/wcs/wcs.py:725: FITSFixedWarning: 'obsfix' made the change 'Set OBSGEO-L to   -72.174733 from OBSGEO-[XYZ].
Set OBSGEO-B to   -38.353284 from OBSGEO-[XYZ].
Set OBSGEO-H to 1740817774.322 from OBSGEO-[XYZ]'.
  warnings.warn(
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/stats/sigma_clipping.py:411: AstropyUserWarning: Input data contains invalid values (NaNs or infs), which were automatically clipped.
  warnings.warn('Input data contains invalid values (NaNs or '
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/stats/sigma_clipping.py:411: AstropyUserWarning: Input data contains invalid values (NaNs or infs), which were automatically clipped.
  warnings.warn('Input data contains invalid values (NaNs or '
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/units/function/logarithmic.py:47: RuntimeWarning: invalid value encountered in log10
  return dex.to(self._function_unit, np.log10(x))
/Users/jpierel/CodeBase/jhat/jhat/simple_jwst_phot.py:897: RuntimeWarning: invalid value encountered in log10
  phot['magerr'] = 2.5 * np.log10(1.0 + (fluxerr/flux))
*** Note: close plot to continue!
   slope  intercept    maxval  index  d_bestguess  fwhm  multimax
0.000049     -0.025 54.211365     28    -0.241148   1.0     False
Keeping 75 out of 75, skippin 0 because of null values in columns d_rot_tmp
median: -0.161845
75.000000 percentile cut: max residual for cut: 0.212953
median: -0.162629
i:00 mean:-0.162629(0.014451) stdev:0.107171(0.010127) X2norm:0.99 Nchanged:0 Ngood:56 Nclip:19

mean: -0.144962
i:01 mean:-0.144962(0.017233) stdev:0.136786(0.012090) X2norm:1.00 Nchanged:8 Ngood:64 Nclip:11

mean: -0.145593
i:02 mean:-0.145593(0.019481) stdev:0.159460(0.013674) X2norm:1.00 Nchanged:4 Ngood:68 Nclip:7

mean: -0.158406
i:03 mean:-0.158406(0.020980) stdev:0.174271(0.014729) X2norm:1.00 Nchanged:2 Ngood:70 Nclip:5

mean: -0.158419
i:04 mean:-0.158419(0.022668) stdev:0.191002(0.015917) X2norm:1.00 Nchanged:2 Ngood:72 Nclip:3

mean: -0.158419
i:05 mean:-0.158419(0.022668) stdev:0.191002(0.015917) X2norm:1.00 Nchanged:0 Ngood:72 Nclip:3
   slope  intercept    maxval  index  d_bestguess  fwhm  multimax
0.000049  -0.025195 41.262524     36     0.051438   1.0     False
Keeping 61 out of 61, skippin 0 because of null values in columns d_rot_tmp
median: 0.109562
75.000000 percentile cut: max residual for cut: 0.288823
median: 0.102123
i:00 mean:0.102123(0.021089) stdev:0.139885(0.014745) X2norm:0.99 Nchanged:0 Ngood:45 Nclip:16

mean: 0.114686
i:01 mean:0.114686(0.024837) stdev:0.177373(0.017393) X2norm:1.00 Nchanged:7 Ngood:52 Nclip:9

mean: 0.105753
i:02 mean:0.105753(0.028650) stdev:0.214397(0.020080) X2norm:1.00 Nchanged:5 Ngood:57 Nclip:4

mean: 0.126734
i:03 mean:0.126734(0.033214) stdev:0.257275(0.023293) X2norm:1.00 Nchanged:4 Ngood:61 Nclip:0

mean: 0.126734
i:04 mean:0.126734(0.033214) stdev:0.257275(0.023293) X2norm:1.00 Nchanged:0 Ngood:61 Nclip:0
*** Note: close plots to continue!
/Users/jpierel/CodeBase/tweakreg_hack/tweakreg_hack/tweakreg_step_hack.py:540: AstropyDeprecationWarning: The JWSTgWCS class is deprecated and may be removed in a future version.
        Use JWSTWCSCorrector instead.
  im = JWSTgWCS(
replacing SIP ./mastDownload/jw02107038001_02105_00001_mirimage_jhat.fits
./mastDownload/jw02107038001_02105_00001_mirimage_jhat.fits
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/wcs/wcs.py:725: FITSFixedWarning: 'obsfix' made the change 'Set OBSGEO-L to   -72.174733 from OBSGEO-[XYZ].
Set OBSGEO-B to   -38.353284 from OBSGEO-[XYZ].
Set OBSGEO-H to 1740817774.322 from OBSGEO-[XYZ]'.
  warnings.warn(
*** Note: close plots to continue!

0

Check the Output

The reference image has not changed, but let’s read in the newly aligned image and compare with the original. subsequent correction needed for optimal alignment.

aligned_image = os.path.join('mastDownload',os.path.basename(align_image).replace('cal.fits','jhat.fits'))
aligned_fits = fits.open(aligned_image)
aligned_data = fits.open(aligned_image)['SCI',1].data
aligned_y,aligned_x = skycoord_to_pixel(star_location,wcs.WCS(aligned_fits['SCI',1],aligned_fits))
aligned_cutout = extract_array(aligned_data,(11,11),(aligned_x,aligned_y))

norm3 = simple_norm(aligned_cutout,stretch='log',min_cut=-1,max_cut=200)
fig,axes = plt.subplots(1,3)
axes[0].imshow(ref_cutout, origin='lower',
                      norm=norm1,cmap='gray')
axes[1].imshow(align_cutout, origin='lower',
                      norm=norm2,cmap='gray')
axes[2].imshow(aligned_cutout, origin='lower',
                      norm=norm3,cmap='gray')
axes[0].set_title('Reference')
axes[1].set_title('To Align')
axes[2].set_title('Aligned')
for i in range(3):
    axes[i].tick_params(labelcolor='none',axis='both',color='none')


plt.show()
Reference, To Align, Aligned
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/wcs/wcs.py:725: FITSFixedWarning: 'obsfix' made the change 'Set OBSGEO-L to   -72.174733 from OBSGEO-[XYZ].
Set OBSGEO-B to   -38.353284 from OBSGEO-[XYZ].
Set OBSGEO-H to 1740817774.322 from OBSGEO-[XYZ]'.
  warnings.warn(

Total running time of the script: ( 0 minutes 32.073 seconds)

Gallery generated by Sphinx-Gallery

JWST NIRCAM

Aligning JWST/NIRCAM images with JHAT.

An example NIRCam Dataset is downloaded, and then a series of alignment methods are used. For more information on the key parameters used for alignment see Useful Parameters.

import sys,os,glob
from astropy.io import fits
from astropy.table import Table
from astropy.nddata import extract_array
from astropy.coordinates import SkyCoord
from astropy import wcs
from astropy.wcs.utils import skycoord_to_pixel
from astropy import units as u
import numpy as np
import matplotlib.pyplot as plt
from astroquery.mast import Observations
from astropy.visualization import (simple_norm,LinearStretch)

import jhat
from jhat import jwst_photclass,st_wcs_align

Relative Alignment

Download some Data

For this example we download 2 JWST NIRCam images from MAST. They’re the same field but different filters. Note that the code will also work for level 3 data images.

obs_table1 = Observations.query_criteria(obs_id='jw02107-o041_t019_nircam_clear-f200w')
data_products_by_obs = Observations.get_product_list(obs_table1)
data_products_by_obs = data_products_by_obs[data_products_by_obs['calib_level']==2]
data_products_by_obs = data_products_by_obs[data_products_by_obs['productSubGroupDescription']=='CAL'][0]
Observations.download_products(data_products_by_obs,extension='fits')

obs_table2 = Observations.query_criteria(obs_id='jw02107-o041_t019_nircam_clear-f360m')
data_products_by_obs = Observations.get_product_list(obs_table2)
data_products_by_obs = data_products_by_obs[data_products_by_obs['calib_level']==2]
data_products_by_obs = data_products_by_obs[data_products_by_obs['productSubGroupDescription']=='CAL'][0]
Observations.download_products(data_products_by_obs,extension='fits')
Downloading URL https://mast.stsci.edu/api/v0.1/Download/file?uri=mast:JWST/product/jw02107041001_02101_00001_nrcb1_cal.fits to ./mastDownload/JWST/jw02107041001_02101_00001_nrcb1/jw02107041001_02101_00001_nrcb1_cal.fits ... [Done]
Downloading URL https://mast.stsci.edu/api/v0.1/Download/file?uri=mast:JWST/product/jw02107041001_02101_00001_nrcblong_cal.fits to ./mastDownload/JWST/jw02107041001_02101_00001_nrcblong/jw02107041001_02101_00001_nrcblong_cal.fits ... [Done]
Table length=1
Local PathStatusMessageURL
str98str8objectobject
./mastDownload/JWST/jw02107041001_02101_00001_nrcblong/jw02107041001_02101_00001_nrcblong_cal.fitsCOMPLETENoneNone


Examine the Reference Image

ref_image = glob.glob('mastDownload/JWST/*nrcb1*/*cal.fits')[0]

ref_fits = fits.open(ref_image)
ref_data = fits.open(ref_image)['SCI',1].data
norm1 = simple_norm(ref_data,stretch='linear',min_cut=-.5,max_cut=3)

plt.imshow(ref_data, origin='lower',
                      norm=norm1,cmap='gray')
plt.gca().tick_params(labelcolor='none',axis='both',color='none')
plt.show()
plot b nircam

Zoom in to see the offset

Here add an artificial offset to the wcs, and then we see the same star in both images at the same ra/dec location, demonstrating a large offset between the images.

star_location = SkyCoord('23:09:41.0532','-43:26:41.128',unit=(u.hourangle,u.deg))
align_image = glob.glob('mastDownload/JWST/*long*/*cal.fits')[0]
align_fits = fits.open(align_image)
align_fits['SCI',1].header['CRPIX1']+=1
align_fits['SCI',1].header['CRPIX2']+=1
align_fits.writeto(align_image,overwrite=True)

align_data = fits.open(align_image)['SCI',1].data
ref_y,ref_x = skycoord_to_pixel(star_location,wcs.WCS(ref_fits['SCI',1],ref_fits))
align_y,align_x = skycoord_to_pixel(star_location,wcs.WCS(align_fits['SCI',1],align_fits))

ref_cutout = extract_array(ref_data,(11,11),(ref_x,ref_y))
align_cutout = extract_array(align_data,(11,11),(align_x,align_y))
norm1 = simple_norm(ref_cutout,stretch='linear',min_cut=-.5,max_cut=3)
norm2 = simple_norm(align_cutout,stretch='linear',min_cut=-.5,max_cut=3)
fig,axes = plt.subplots(1,2)
axes[0].imshow(ref_cutout, origin='lower',
                      norm=norm1,cmap='gray')
axes[1].imshow(align_cutout, origin='lower',
                      norm=norm2,cmap='gray')
axes[0].set_title('Reference')
axes[1].set_title('To Align')
axes[0].tick_params(labelcolor='none',axis='both',color='none')
axes[1].tick_params(labelcolor='none',axis='both',color='none')

plt.show()
Reference, To Align
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/wcs/wcs.py:725: FITSFixedWarning: 'datfix' made the change 'Set DATE-BEG to '2022-07-06T19:16:42.721' from MJD-BEG.
Set DATE-AVG to '2022-07-06T19:17:14.932' from MJD-AVG.
Set DATE-END to '2022-07-06T19:17:47.142' from MJD-END'.
  warnings.warn(
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/wcs/wcs.py:725: FITSFixedWarning: 'obsfix' made the change 'Set OBSGEO-L to   -72.164999 from OBSGEO-[XYZ].
Set OBSGEO-B to   -38.353872 from OBSGEO-[XYZ].
Set OBSGEO-H to 1740894174.999 from OBSGEO-[XYZ]'.
  warnings.warn(
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/wcs/wcs.py:725: FITSFixedWarning: 'datfix' made the change 'Set DATE-BEG to '2022-07-06T19:16:42.721' from MJD-BEG.
Set DATE-AVG to '2022-07-06T19:17:14.932' from MJD-AVG.
Set DATE-END to '2022-07-06T19:17:47.142' from MJD-END'.
  warnings.warn(
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/wcs/wcs.py:725: FITSFixedWarning: 'obsfix' made the change 'Set OBSGEO-L to   -72.164999 from OBSGEO-[XYZ].
Set OBSGEO-B to   -38.353872 from OBSGEO-[XYZ].
Set OBSGEO-H to 1740894174.999 from OBSGEO-[XYZ]'.
  warnings.warn(

Create a Photometric Catalog for Relative Alignment

We choose one of the images to be the reference image, and then create a catalog that we will use to align the other image.

jwst_phot = jwst_photclass()
jwst_phot.run_phot(imagename=ref_image,photfilename='auto',overwrite=True,ee_radius=80)
ref_catname = ref_image.replace('.fits','.phot.txt') # the default
refcat = Table.read(ref_catname,format='ascii')
print(refcat)
0 mastDownload/JWST/jw02107041001_02101_00001_nrcb1/jw02107041001_02101_00001_nrcb1_cal.phot.txt
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/wcs/wcs.py:725: FITSFixedWarning: 'datfix' made the change 'Set DATE-BEG to '2022-07-06T19:16:42.721' from MJD-BEG.
Set DATE-AVG to '2022-07-06T19:17:14.932' from MJD-AVG.
Set DATE-END to '2022-07-06T19:17:47.142' from MJD-END'.
  warnings.warn(
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/wcs/wcs.py:725: FITSFixedWarning: 'obsfix' made the change 'Set OBSGEO-L to   -72.164999 from OBSGEO-[XYZ].
Set OBSGEO-B to   -38.353872 from OBSGEO-[XYZ].
Set OBSGEO-H to 1740894174.999 from OBSGEO-[XYZ]'.
  warnings.warn(
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/stats/sigma_clipping.py:411: AstropyUserWarning: Input data contains invalid values (NaNs or infs), which were automatically clipped.
  warnings.warn('Input data contains invalid values (NaNs or '
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/stats/sigma_clipping.py:411: AstropyUserWarning: Input data contains invalid values (NaNs or infs), which were automatically clipped.
  warnings.warn('Input data contains invalid values (NaNs or '
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/units/function/logarithmic.py:47: RuntimeWarning: invalid value encountered in log10
  return dex.to(self._function_unit, np.log10(x))
/Users/jpierel/CodeBase/jhat/jhat/simple_jwst_phot.py:897: RuntimeWarning: invalid value encountered in log10
  phot['magerr'] = 2.5 * np.log10(1.0 + (fluxerr/flux))
aper_sum_5.7px annulus_median_5.7px aper_bkg_5.7px ...   x_idl      y_idl
-------------- -------------------- -------------- ... ---------- ----------
    105.310801             0.910453       92.21433 ... -11.710449 -31.373861
     121.56116             0.960956      97.329433 ...   1.390701 -31.374766
     60.232352             0.498815      50.521961 ...  18.604013  -31.26976
    126.737312             1.019729     103.282174 ... -31.055244  -31.32962
    113.529229             0.802048      81.234601 ... -18.547597  -31.34987
    105.370409             0.767367      77.721958 ... -13.204667 -31.345555
     89.411974             0.648643      65.697099 ...  11.290307 -31.300338
    110.788413             0.861123      87.217932 ...   -0.18106 -31.287703
    124.473601             0.862357      87.342937 ...   6.266814 -31.255725
    108.728849             0.849587       86.04952 ...  10.634677 -31.259596
           ...                  ...            ... ...        ...        ...
     33.278942             0.200456      20.302942 ... -18.177622  29.366304
       23.6942              0.04802       4.863676 ... -17.540134  29.519926
     18.277825             0.013074       1.324192 ...   -9.43527   29.52744
       0.06818               -99.99  -10127.382506 ...  -2.732965  29.758751
     14.784146               -99.99  -10127.382506 ...  20.030247  29.877627
     47.576291             0.323802      32.795919 ...   8.796703  31.023101
     36.125728             0.251559      25.478925 ...  26.612871  31.127561
     39.783969             0.184818      18.719089 ... -15.095758    31.1144
    341.811179              0.27702        28.0577 ...  -9.937289  31.082671
     53.600708             0.336015      34.032935 ...   8.547109  31.138805
     50.031236             0.275069      27.860125 ...  13.180869  31.166268
Length = 2756 rows

Align the second image

The plots outputted here show the various steps used by jhat to determine the true matching sources in the image, and the subsequent correction needed for optimal alignment.

wcs_align = st_wcs_align()


wcs_align.run_all(align_image,
              telescope='jwst',
              outsubdir='mastDownload',
          refcat_racol='ra',
          refcat_deccol='dec',
          refcat_magcol='mag',
          refcat_magerrcol='dmag',
          overwrite=True,
          d2d_max=1,
          showplots=2,
          refcatname=ref_catname,
          histocut_order='dxdy',
              sharpness_lim=(0.3,0.9),
              roundness1_lim=(-0.7, 0.7),
              SNR_min= 3,
              dmag_max=1.0,
              objmag_lim =(14,24))
  • Initial cut: d2d_max=1, dmag_max=None, Nbright=None, delta_mag_lim=(None, None)
  • dx, dx, dx, slope:0.00014648437499998213, 3-sigma cut: 105 out of 109 left mean = -0.554 px, stdev = 0.158 px
  • dy, dy, dy, slope:-1.734723475976807e-17, 3-sigma cut: 100 out of 103 left mean = -0.570 px, stdev = 0.164 px
0 ./mastDownload/jw02107041001_02101_00001_nrcblong.phot.txt
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/wcs/wcs.py:725: FITSFixedWarning: 'datfix' made the change 'Set DATE-BEG to '2022-07-06T19:16:42.721' from MJD-BEG.
Set DATE-AVG to '2022-07-06T19:17:14.932' from MJD-AVG.
Set DATE-END to '2022-07-06T19:17:47.142' from MJD-END'.
  warnings.warn(
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/wcs/wcs.py:725: FITSFixedWarning: 'obsfix' made the change 'Set OBSGEO-L to   -72.164999 from OBSGEO-[XYZ].
Set OBSGEO-B to   -38.353872 from OBSGEO-[XYZ].
Set OBSGEO-H to 1740894174.999 from OBSGEO-[XYZ]'.
  warnings.warn(
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/stats/sigma_clipping.py:411: AstropyUserWarning: Input data contains invalid values (NaNs or infs), which were automatically clipped.
  warnings.warn('Input data contains invalid values (NaNs or '
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/stats/sigma_clipping.py:411: AstropyUserWarning: Input data contains invalid values (NaNs or infs), which were automatically clipped.
  warnings.warn('Input data contains invalid values (NaNs or '
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/units/function/logarithmic.py:47: RuntimeWarning: invalid value encountered in log10
  return dex.to(self._function_unit, np.log10(x))
/Users/jpierel/CodeBase/jhat/jhat/simple_jwst_phot.py:897: RuntimeWarning: invalid value encountered in log10
  phot['magerr'] = 2.5 * np.log10(1.0 + (fluxerr/flux))
*** Note: close plot to continue!
   slope  intercept    maxval  index  d_bestguess  fwhm  multimax
0.000146      -0.15 83.958993     76     -0.50978   0.8     False
Keeping 109 out of 109, skippin 0 because of null values in columns d_rot_tmp
median: -0.572386
75.000000 percentile cut: max residual for cut: 0.188131
median: -0.587588
i:00 mean:-0.587588(0.010388) stdev:0.092914(0.007300) X2norm:0.99 Nchanged:0 Ngood:81 Nclip:28

mean: -0.580012
i:01 mean:-0.580012(0.012575) stdev:0.121920(0.008845) X2norm:1.00 Nchanged:14 Ngood:95 Nclip:14

mean: -0.557890
i:02 mean:-0.557890(0.014267) stdev:0.143378(0.010038) X2norm:1.00 Nchanged:7 Ngood:102 Nclip:7

mean: -0.554064
i:03 mean:-0.554064(0.015446) stdev:0.157514(0.010870) X2norm:1.00 Nchanged:3 Ngood:105 Nclip:4

mean: -0.554064
i:04 mean:-0.554064(0.015446) stdev:0.157514(0.010870) X2norm:1.00 Nchanged:0 Ngood:105 Nclip:4
        slope    intercept    maxval  index  d_bestguess  fwhm  multimax
-1.734723e-17 1.776357e-14 79.085569      6    -0.534655   0.8     False
Keeping 103 out of 103, skippin 0 because of null values in columns d_rot_tmp
median: -0.559999
75.000000 percentile cut: max residual for cut: 0.191320
median: -0.559999
i:00 mean:-0.559999(0.010883) stdev:0.094879(0.007646) X2norm:0.99 Nchanged:0 Ngood:77 Nclip:26

mean: -0.554858
i:01 mean:-0.554858(0.013144) stdev:0.124003(0.009243) X2norm:1.00 Nchanged:13 Ngood:90 Nclip:13

mean: -0.565181
i:02 mean:-0.565181(0.015176) stdev:0.148691(0.010675) X2norm:1.00 Nchanged:7 Ngood:97 Nclip:6

mean: -0.564816
i:03 mean:-0.564816(0.016002) stdev:0.158407(0.011258) X2norm:1.00 Nchanged:2 Ngood:99 Nclip:4

mean: -0.569514
i:04 mean:-0.569514(0.016529) stdev:0.164459(0.011629) X2norm:1.00 Nchanged:1 Ngood:100 Nclip:3

mean: -0.569514
i:05 mean:-0.569514(0.016529) stdev:0.164459(0.011629) X2norm:1.00 Nchanged:0 Ngood:100 Nclip:3
*** Note: close plots to continue!
/Users/jpierel/CodeBase/tweakreg_hack/tweakreg_hack/tweakreg_step_hack.py:540: AstropyDeprecationWarning: The JWSTgWCS class is deprecated and may be removed in a future version.
        Use JWSTWCSCorrector instead.
  im = JWSTgWCS(
replacing SIP ./mastDownload/jw02107041001_02101_00001_nrcblong_jhat.fits
./mastDownload/jw02107041001_02101_00001_nrcblong_jhat.fits
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/wcs/wcs.py:725: FITSFixedWarning: 'obsfix' made the change 'Set OBSGEO-L to   -72.164999 from OBSGEO-[XYZ].
Set OBSGEO-B to   -38.353872 from OBSGEO-[XYZ].
Set OBSGEO-H to 1740894174.999 from OBSGEO-[XYZ]'.
  warnings.warn(
*** Note: close plots to continue!

0

Check the Output

The reference image has not changed, but let’s read in the newly aligned image and compare with the original. subsequent correction needed for optimal alignment.

aligned_image = os.path.join('mastDownload',os.path.basename(align_image).replace('cal.fits','jhat.fits'))
aligned_fits = fits.open(aligned_image)
aligned_data = fits.open(aligned_image)['SCI',1].data
aligned_y,aligned_x = skycoord_to_pixel(star_location,wcs.WCS(aligned_fits['SCI',1],aligned_fits))
aligned_cutout = extract_array(aligned_data,(11,11),(aligned_x,aligned_y))

norm3 = simple_norm(aligned_cutout,stretch='linear',min_cut=-.5,max_cut=3)
fig,axes = plt.subplots(1,3)
axes[0].imshow(ref_cutout, origin='lower',
                      norm=norm1,cmap='gray')
axes[1].imshow(align_cutout, origin='lower',
                      norm=norm2,cmap='gray')
axes[2].imshow(aligned_cutout, origin='lower',
                      norm=norm3,cmap='gray')
axes[0].set_title('Reference')
axes[1].set_title('To Align')
axes[2].set_title('Aligned')
for i in range(3):
    axes[i].tick_params(labelcolor='none',axis='both',color='none')


plt.show()
Reference, To Align, Aligned
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/wcs/wcs.py:725: FITSFixedWarning: 'obsfix' made the change 'Set OBSGEO-L to   -72.164999 from OBSGEO-[XYZ].
Set OBSGEO-B to   -38.353872 from OBSGEO-[XYZ].
Set OBSGEO-H to 1740894174.999 from OBSGEO-[XYZ]'.
  warnings.warn(

Align to Catalog

You can also align each image to the Gaia DR3 catalog, or you could replace the catalog created in step one with your own catalog of the field.

wcs_align.run_all(align_image,
              telescope='jwst',
              outsubdir='mastDownload',
          overwrite=True,
          d2d_max=.5,
          showplots=0,
          refcatname='Gaia',
          histocut_order='dxdy',
              sharpness_lim=(0.3,0.9),
              roundness1_lim=(-0.7, 0.7),
              SNR_min= 3,
              dmag_max=1.0,
              objmag_lim =(14,24))

aligned_image = os.path.join('mastDownload',os.path.basename(align_image).replace('cal.fits','jhat.fits'))
aligned_fits = fits.open(aligned_image)
aligned_data = fits.open(aligned_image)['SCI',1].data
aligned_y,aligned_x = skycoord_to_pixel(star_location,wcs.WCS(aligned_fits['SCI',1],aligned_fits))
aligned_cutout = extract_array(aligned_data,(11,11),(aligned_x,aligned_y))

norm3 = simple_norm(aligned_cutout,stretch='linear',min_cut=-.5,max_cut=3)
fig,axes = plt.subplots(1,2)
axes[0].imshow(align_cutout, origin='lower',
                      norm=norm2,cmap='gray')
axes[1].imshow(aligned_cutout, origin='lower',
                      norm=norm3,cmap='gray')
axes[0].set_title('To Align')
axes[1].set_title('Aligned')
for i in range(2):
    axes[i].tick_params(labelcolor='none',axis='both',color='none')


plt.show()
To Align, Aligned
0 ./mastDownload/jw02107041001_02101_00001_nrcblong.phot.txt
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/wcs/wcs.py:725: FITSFixedWarning: 'datfix' made the change 'Set DATE-BEG to '2022-07-06T19:16:42.721' from MJD-BEG.
Set DATE-AVG to '2022-07-06T19:17:14.932' from MJD-AVG.
Set DATE-END to '2022-07-06T19:17:47.142' from MJD-END'.
  warnings.warn(
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/wcs/wcs.py:725: FITSFixedWarning: 'obsfix' made the change 'Set OBSGEO-L to   -72.164999 from OBSGEO-[XYZ].
Set OBSGEO-B to   -38.353872 from OBSGEO-[XYZ].
Set OBSGEO-H to 1740894174.999 from OBSGEO-[XYZ]'.
  warnings.warn(
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/stats/sigma_clipping.py:411: AstropyUserWarning: Input data contains invalid values (NaNs or infs), which were automatically clipped.
  warnings.warn('Input data contains invalid values (NaNs or '
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/stats/sigma_clipping.py:411: AstropyUserWarning: Input data contains invalid values (NaNs or infs), which were automatically clipped.
  warnings.warn('Input data contains invalid values (NaNs or '
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/units/function/logarithmic.py:47: RuntimeWarning: invalid value encountered in log10
  return dex.to(self._function_unit, np.log10(x))
/Users/jpierel/CodeBase/jhat/jhat/simple_jwst_phot.py:897: RuntimeWarning: invalid value encountered in log10
  phot['magerr'] = 2.5 * np.log10(1.0 + (fluxerr/flux))
INFO: Query finished. [astroquery.utils.tap.core]
Number of stars: 21
### NO propoer motion correction!!!
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/pandas/core/arraylike.py:402: RuntimeWarning: invalid value encountered in sqrt
  result = getattr(ufunc, method)(*inputs, **kwargs)
Number of stars after removing nan's: 21
   slope  intercept   maxval  index  d_bestguess  fwhm  multimax
0.001367       -1.4 3.661515     35     0.706414   0.8     False
Keeping 5 out of 5, skippin 0 because of null values in columns d_rot_tmp
median: 0.644163
75.000000 percentile cut: max residual for cut: 0.071771
median: 0.646769
i:00 mean:0.646769(0.001950) stdev:0.002758(0.001126) X2norm:0.79 Nchanged:0 Ngood:3 Nclip:2

mean: 0.646657
i:01 mean:0.646657(0.001725) stdev:0.002440(0.000996) X2norm:1.00 Nchanged:0 Ngood:3 Nclip:2
   slope  intercept  maxval  index  d_bestguess  fwhm  multimax
0.000537      -0.55     3.0      4    -1.643322   0.8     False
Keeping 3 out of 3, skippin 0 because of null values in columns d_rot_tmp
median: -1.609357
i:00 mean:-1.609357(0.083353) stdev:0.117879(0.048124) X2norm:0.79 Nchanged:0 Ngood:3 Nclip:0

mean: -1.633248
i:01 mean:-1.633248(0.070913) stdev:0.100286(0.040942) X2norm:1.00 Nchanged:0 Ngood:3 Nclip:0
/Users/jpierel/CodeBase/tweakreg_hack/tweakreg_hack/tweakreg_step_hack.py:540: AstropyDeprecationWarning: The JWSTgWCS class is deprecated and may be removed in a future version.
        Use JWSTWCSCorrector instead.
  im = JWSTgWCS(
replacing SIP ./mastDownload/jw02107041001_02101_00001_nrcblong_jhat.fits
./mastDownload/jw02107041001_02101_00001_nrcblong_jhat.fits
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/wcs/wcs.py:725: FITSFixedWarning: 'obsfix' made the change 'Set OBSGEO-L to   -72.164999 from OBSGEO-[XYZ].
Set OBSGEO-B to   -38.353872 from OBSGEO-[XYZ].
Set OBSGEO-H to 1740894174.999 from OBSGEO-[XYZ]'.
  warnings.warn(
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/wcs/wcs.py:725: FITSFixedWarning: 'obsfix' made the change 'Set OBSGEO-L to   -72.164999 from OBSGEO-[XYZ].
Set OBSGEO-B to   -38.353872 from OBSGEO-[XYZ].
Set OBSGEO-H to 1740894174.999 from OBSGEO-[XYZ]'.
  warnings.warn(

Total running time of the script: ( 1 minutes 42.234 seconds)

Gallery generated by Sphinx-Gallery

Hubble

Aligning HST images with JHAT.

An example HST Dataset is downloaded, and then a series of alignment methods are used. For more information on the key parameters used for alignment see Useful Parameters.

import sys,os,glob
from astropy.io import fits
from astropy.table import Table
from astropy.nddata import extract_array
from astropy.coordinates import SkyCoord
from astropy import wcs
from astropy.wcs.utils import skycoord_to_pixel
from astropy import units as u
import numpy as np
import matplotlib.pyplot as plt
from astroquery.mast import Observations
from astropy.visualization import (simple_norm,LinearStretch)

import jhat
from jhat import hst_photclass,st_wcs_align

Relative Alignment

Download some Data

For this example we download 2 HST DRZ images from MAST. They’re the same filter and same field, just separated in time.

obs_table = Observations.query_criteria(obs_id='hst_16264_12_wfc3_ir_f110w_iebc12')
obs_table1 = obs_table[obs_table['filters']=='F110W']

obs_table = Observations.query_criteria(obs_id='hst_16264_15_wfc3_ir_f110w_iebc15')
obs_table2 = obs_table[obs_table['filters']=='F110W']

data_products_by_obs = Observations.get_product_list(obs_table1)
data_products_by_obs = data_products_by_obs[data_products_by_obs['calib_level']==3]
data_products_by_obs = data_products_by_obs[data_products_by_obs['productSubGroupDescription']=='DRZ'][0]
Observations.download_products(data_products_by_obs,extension='fits')

data_products_by_obs = Observations.get_product_list(obs_table2)
data_products_by_obs = data_products_by_obs[data_products_by_obs['calib_level']==3]
data_products_by_obs = data_products_by_obs[data_products_by_obs['productSubGroupDescription']=='DRZ'][0]
Observations.download_products(data_products_by_obs,extension='fits')
Downloading URL https://mast.stsci.edu/api/v0.1/Download/file?uri=mast:HST/product/hst_16264_12_wfc3_ir_f110w_iebc12_drz.fits to ./mastDownload/HST/hst_16264_12_wfc3_ir_f110w_iebc12/hst_16264_12_wfc3_ir_f110w_iebc12_drz.fits ... [Done]
Downloading URL https://mast.stsci.edu/api/v0.1/Download/file?uri=mast:HST/product/hst_16264_15_wfc3_ir_f110w_iebc15_drz.fits to ./mastDownload/HST/hst_16264_15_wfc3_ir_f110w_iebc15/hst_16264_15_wfc3_ir_f110w_iebc15_drz.fits ... [Done]
Table length=1
Local PathStatusMessageURL
str95str8objectobject
./mastDownload/HST/hst_16264_15_wfc3_ir_f110w_iebc15/hst_16264_15_wfc3_ir_f110w_iebc15_drz.fitsCOMPLETENoneNone


Examine the Reference Image

files = glob.glob('mastDownload/HST/*/*drz.fits')
ref_image = files[0]
ref_fits = fits.open(ref_image)
ref_data = fits.open(ref_image)['SCI',1].data
norm1 = simple_norm(ref_data,stretch='log',min_cut=-1,max_cut=15)

plt.imshow(ref_data, origin='lower',
                      norm=norm1,cmap='gray')
plt.gca().tick_params(labelcolor='none',axis='both',color='none')
plt.show()
plot a hst

Zoom in to see the offset

Here add an artificial offset to the wcs, and then we see the same star in both images at the same ra/dec location, demonstrating a large offset between the images.

star_location = SkyCoord('21:29:40.5351','+0:04:42.697',unit=(u.hourangle,u.deg))
align_image = files[1]
align_fits = fits.open(align_image)
align_fits['SCI',1].header['CRPIX1']+=2
align_fits['SCI',1].header['CRPIX2']+=2
align_fits.writeto(align_image,overwrite=True)

align_data = fits.open(align_image)['SCI',1].data
ref_y,ref_x = skycoord_to_pixel(star_location,wcs.WCS(ref_fits['SCI',1],ref_fits))
align_y,align_x = skycoord_to_pixel(star_location,wcs.WCS(align_fits['SCI',1],align_fits))

ref_cutout = extract_array(ref_data,(11,11),(ref_x,ref_y))
align_cutout = extract_array(align_data,(11,11),(align_x,align_y))
norm1 = simple_norm(ref_cutout,stretch='log',min_cut=-1,max_cut=200)
norm2 = simple_norm(align_cutout,stretch='log',min_cut=-1,max_cut=200)
fig,axes = plt.subplots(1,2)
axes[0].imshow(ref_cutout, origin='lower',
                      norm=norm1,cmap='gray')
axes[1].imshow(align_cutout, origin='lower',
                      norm=norm2,cmap='gray')
axes[0].set_title('Reference')
axes[1].set_title('To Align')
axes[0].tick_params(labelcolor='none',axis='both',color='none')
axes[1].tick_params(labelcolor='none',axis='both',color='none')

plt.show()
Reference, To Align

Create a Photometric Catalog for Relative Alignment

We choose one of the images to be the reference image, and then create a catalog that we will use to align the other image.

hst_phot = hst_photclass(psf_fwhm=1.8,aperture_radius=5)
hst_phot.run_phot(imagename=ref_image,photfilename='auto',overwrite=True)
ref_catname = ref_image.replace('.fits','.phot.txt') # the default
refcat = Table.read(ref_catname,format='ascii')
print(refcat)
0 mastDownload/HST/hst_16264_15_wfc3_ir_f110w_iebc15/hst_16264_15_wfc3_ir_f110w_iebc15_drz.phot.txt
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/stats/sigma_clipping.py:411: AstropyUserWarning: Input data contains invalid values (NaNs or infs), which were automatically clipped.
  warnings.warn('Input data contains invalid values (NaNs or '
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/stats/sigma_clipping.py:411: AstropyUserWarning: Input data contains invalid values (NaNs or infs), which were automatically clipped.
  warnings.warn('Input data contains invalid values (NaNs or '
/Users/jpierel/CodeBase/jhat/jhat/simple_jwst_phot.py:1942: RuntimeWarning: invalid value encountered in log10
  phot['mag'] = -2.5*np.log10(phot['aper_sum_bkgsub'])+ee_corr+zp
/Users/jpierel/CodeBase/jhat/jhat/simple_jwst_phot.py:1945: RuntimeWarning: invalid value encountered in log10
  phot['magerr'] = 2.5 * np.log10(1.0 + (fluxerr/phot['aper_sum_bkgsub']))
aper_sum_5.0px annulus_median_5.0px aper_bkg_5.0px ...   x_idl     y_idl
-------------- -------------------- -------------- ... --------- ----------
     98.701908             1.222414      96.008154 ... 10.282901 -58.751291
    112.858933             1.215701      95.480899 ...  0.099716 -56.988332
    101.387021             1.221539      95.939432 ... 11.171638 -55.244084
    103.395491             1.223192       96.06924 ... 12.050499 -54.702786
     98.175518             1.216526      95.545731 ...   18.3728 -52.885932
    105.185721              1.21896      95.736903 ... 20.125268 -52.409859
     98.467777             1.222879      96.044673 ...  8.878883 -51.562419
    101.178176             1.223382      96.084188 ...  9.447841 -51.376254
    100.858931             1.222232      95.993843 ...  9.589212 -51.288441
     97.386204             1.211678      95.164984 ... -1.323612 -51.067408
           ...                  ...            ... ...       ...        ...
    106.700574             1.228211      96.463442 ... 38.894969  98.502383
    100.028718             1.227917      96.440353 ... 38.374139   99.52547
     97.812416             1.220746      95.877198 ... 26.977886  99.641609
     97.602401             1.223992      96.132097 ... 37.761718 100.233421
    105.374585             1.219728      95.797236 ... 33.155942 100.494187
     97.821326             1.222629      96.025086 ... 36.519167 101.346028
    102.604081             1.224514      96.173087 ... 22.996227 101.696774
     97.176703             1.223466      96.090817 ... 29.490227 101.683135
    106.491719             1.221887      95.966789 ... 28.696314 105.056795
    136.421682             1.214225      95.364994 ... 36.206768 105.813417
    105.467064             1.229289      96.548109 ... 30.779631 106.393258
Length = 769 rows

Align the second image

The plots outputted here show the various steps used by jhat to determine the true matching sources in the image, and the subsequent correction needed for optimal alignment.

wcs_align = st_wcs_align()


wcs_align.run_all(align_image,
              telescope='hst',
              outsubdir='mastDownload',
          refcat_racol='ra',
          refcat_deccol='dec',
          refcat_magcol='mag',
          refcat_magerrcol='dmag',
          overwrite=True,
          d2d_max=.5,
          showplots=2,
          refcatname=ref_catname,
          histocut_order='dxdy',
              sharpness_lim=(0.3,0.9),
              roundness1_lim=(-0.7, 0.7),
              SNR_min= 3,
              dmag_max=1.0,
              objmag_lim =(14,24))
  • Initial cut: d2d_max=0.5, dmag_max=None, Nbright=None, delta_mag_lim=(None, None)
  • dx, dx, dx, slope:-9.7656250000017e-05, 3-sigma cut: 198 out of 222 left mean = 2.108 px, stdev = 0.055 px
  • dy, dy, dy, slope:0.00014648437499998213, 3-sigma cut: 189 out of 198 left mean = 1.941 px, stdev = 0.058 px
Warning: Setting aperture radius to twice the psf_fwhm (4.000000)
0 ./mastDownload/hst_16264_12_wfc3_ir_f110w_iebc12.phot.txt
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/stats/sigma_clipping.py:411: AstropyUserWarning: Input data contains invalid values (NaNs or infs), which were automatically clipped.
  warnings.warn('Input data contains invalid values (NaNs or '
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/stats/sigma_clipping.py:411: AstropyUserWarning: Input data contains invalid values (NaNs or infs), which were automatically clipped.
  warnings.warn('Input data contains invalid values (NaNs or '
/Users/jpierel/CodeBase/jhat/jhat/simple_jwst_phot.py:1942: RuntimeWarning: invalid value encountered in log10
  phot['mag'] = -2.5*np.log10(phot['aper_sum_bkgsub'])+ee_corr+zp
/Users/jpierel/CodeBase/jhat/jhat/simple_jwst_phot.py:1945: RuntimeWarning: invalid value encountered in log10
  phot['magerr'] = 2.5 * np.log10(1.0 + (fluxerr/phot['aper_sum_bkgsub']))
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.instrument.name the following error occurred:
'WFC3' is not one of ['NIRCAM', 'NIRSPEC', 'MIRI', 'TFI', 'FGS', 'NIRISS', 'ANY', 'N/A']

Failed validating 'enum' in schema:
    OrderedDict([('title', 'Instrument used to acquire the data'),
                 ('type', 'string'),
                 ('enum',
                  ['NIRCAM',
                   'NIRSPEC',
                   'MIRI',
                   'TFI',
                   'FGS',
                   'NIRISS',
                   'ANY',
                   'N/A']),
                 ('fits_keyword', 'INSTRUME'),
                 ('blend_table', True)])

On instance:
    'WFC3'
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.instrument.detector the following error occurred:
'IR' is not one of ['NRCA1', 'NRCA2', 'NRCA3', 'NRCA4', 'NRCALONG', 'NRCB1', 'NRCB2', 'NRCB3', 'NRCB4', 'NRCBLONG', 'NRS1', 'NRS2', 'ANY', 'MIRIMAGE', 'MIRIFULONG', 'MIRIFUSHORT', 'NIS', 'GUIDER1', 'GUIDER2', 'N/A', 'MULTIPLE']

Failed validating 'enum' in schema:
    OrderedDict([('title', 'Name of detector used to acquire the data'),
                 ('type', 'string'),
                 ('enum',
                  ['NRCA1',
                   'NRCA2',
                   'NRCA3',
                   'NRCA4',
                   'NRCALONG',
                   'NRCB1',
                   'NRCB2',
                   'NRCB3',
                   'NRCB4',
                   'NRCBLONG',
                   'NRS1',
                   'NRS2',
                   'ANY',
                   'MIRIMAGE',
                   'MIRIFULONG',
                   'MIRIFUSHORT',
                   'NIS',
                   'GUIDER1',
                   'GUIDER2',
                   'N/A',
                   'MULTIPLE']),
                 ('fits_keyword', 'DETECTOR'),
                 ('blend_table', True),
                 ('blend_rule', 'multi')])

On instance:
    'IR'
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.subarray.name the following error occurred:
False is not of type 'string'

Failed validating 'type' in schema:
    OrderedDict([('title', 'Subarray used'),
                 ('type', 'string'),
                 ('anyOf',
                  [{'enum': ['8X8',
                             '32X32',
                             '128X128',
                             '2048X64',
                             'SUB128CNTR',
                             'SUB128DIAG',
                             'SUB128LL',
                             'SUB32CNTR',
                             'SUB32DIAG',
                             'SUB32LL',
                             'SUB8CNTR',
                             'SUB8DIAG',
                             'SUB8LL',
                             'SUBIDSTRIPCENTER',
                             'SUBIDSTRIPLL',
                             'SUBTUNE32CENTERG1',
                             'SUBTUNE32CENTERG2',
                             'SUBTUNE32LLG1',
                             'SUBTUNE32LLG2']},
                   {'enum': ['BRIGHTSKY',
                             'MASK1065',
                             'MASK1140',
                             'MASK1550',
                             'MASKLYOT',
                             'SLITLESSPRISM',
                             'SUB128',
                             'SUB256',
                             'SUB64',
                             'SUBPRISM']},
                   {'enum': ['FULLP',
                             'MASK210R',
                             'MASK335R',
                             'MASK430R',
                             'MASKLWB',
                             'MASKSWB',
                             'SUB160',
                             'SUB160P',
                             'SUB320',
                             'SUB320A335R',
                             'SUB320A430R',
                             'SUB320ALWB',
                             'SUB320B335R',
                             'SUB320B430R',
                  ...
  warnings.warn(errmsg, ValidationWarning)
*** Note: close plot to continue!
    slope  intercept     maxval  index  d_bestguess  fwhm  multimax
-0.000098   0.071191 183.673678     28     2.022576   0.8     False
Keeping 222 out of 222, skippin 0 because of null values in columns d_rot_tmp
median: 2.110833
75.000000 percentile cut: max residual for cut: 0.076543
median: 2.112779
i:00 mean:2.112779(0.002520) stdev:0.032375(0.001777) X2norm:1.00 Nchanged:0 Ngood:166 Nclip:56

mean: 2.114075
i:01 mean:2.114075(0.002887) stdev:0.038415(0.002036) X2norm:1.00 Nchanged:12 Ngood:178 Nclip:44

mean: 2.113588
i:02 mean:2.113588(0.003081) stdev:0.041561(0.002172) X2norm:1.00 Nchanged:5 Ngood:183 Nclip:39

mean: 2.113580
i:03 mean:2.113580(0.003189) stdev:0.043262(0.002249) X2norm:1.00 Nchanged:2 Ngood:185 Nclip:37

mean: 2.110885
i:04 mean:2.110885(0.003397) stdev:0.046577(0.002396) X2norm:1.00 Nchanged:4 Ngood:189 Nclip:33

mean: 2.111600
i:05 mean:2.111600(0.003454) stdev:0.047488(0.002436) X2norm:1.00 Nchanged:1 Ngood:190 Nclip:32

mean: 2.112334
i:06 mean:2.112334(0.003631) stdev:0.050314(0.002561) X2norm:1.00 Nchanged:3 Ngood:193 Nclip:29

mean: 2.110830
i:07 mean:2.110830(0.003748) stdev:0.052203(0.002643) X2norm:1.00 Nchanged:2 Ngood:195 Nclip:27

mean: 2.109305
i:08 mean:2.109305(0.003863) stdev:0.054084(0.002725) X2norm:1.00 Nchanged:2 Ngood:197 Nclip:25

mean: 2.108492
i:09 mean:2.108492(0.003929) stdev:0.055147(0.002771) X2norm:1.00 Nchanged:1 Ngood:198 Nclip:24

   slope  intercept    maxval  index  d_bestguess  fwhm  multimax
0.000146   -0.10686 185.08144      5     1.964436   0.8     False
Keeping 198 out of 198, skippin 0 because of null values in columns d_rot_tmp
median: 1.946136
75.000000 percentile cut: max residual for cut: 0.064640
median: 1.947841
i:00 mean:1.947841(0.002509) stdev:0.030420(0.001768) X2norm:1.00 Nchanged:0 Ngood:148 Nclip:50

mean: 1.939984
i:01 mean:1.939984(0.002941) stdev:0.037665(0.002073) X2norm:1.00 Nchanged:17 Ngood:165 Nclip:33

mean: 1.938798
i:02 mean:1.938798(0.003106) stdev:0.040264(0.002190) X2norm:1.00 Nchanged:4 Ngood:169 Nclip:29

mean: 1.937518
i:03 mean:1.937518(0.003415) stdev:0.045050(0.002408) X2norm:1.00 Nchanged:6 Ngood:175 Nclip:23

mean: 1.938289
i:04 mean:1.938289(0.003692) stdev:0.049402(0.002604) X2norm:1.00 Nchanged:5 Ngood:180 Nclip:18

mean: 1.939838
i:05 mean:1.939838(0.004048) stdev:0.055060(0.002855) X2norm:1.00 Nchanged:6 Ngood:186 Nclip:12

mean: 1.939851
i:06 mean:1.939851(0.004173) stdev:0.057063(0.002943) X2norm:1.00 Nchanged:2 Ngood:188 Nclip:10

mean: 1.940734
i:07 mean:1.940734(0.004244) stdev:0.058191(0.002993) X2norm:1.00 Nchanged:1 Ngood:189 Nclip:9

mean: 1.940734
i:08 mean:1.940734(0.004244) stdev:0.058191(0.002993) X2norm:1.00 Nchanged:0 Ngood:189 Nclip:9
*** Note: close plots to continue!
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.instrument.name the following error occurred:
'WFC3' is not one of ['NIRCAM', 'NIRSPEC', 'MIRI', 'TFI', 'FGS', 'NIRISS', 'ANY', 'N/A']

Failed validating 'enum' in schema:
    OrderedDict([('title', 'Instrument used to acquire the data'),
                 ('type', 'string'),
                 ('enum',
                  ['NIRCAM',
                   'NIRSPEC',
                   'MIRI',
                   'TFI',
                   'FGS',
                   'NIRISS',
                   'ANY',
                   'N/A']),
                 ('fits_keyword', 'INSTRUME'),
                 ('blend_table', True)])

On instance:
    'WFC3'
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.instrument.detector the following error occurred:
'IR' is not one of ['NRCA1', 'NRCA2', 'NRCA3', 'NRCA4', 'NRCALONG', 'NRCB1', 'NRCB2', 'NRCB3', 'NRCB4', 'NRCBLONG', 'NRS1', 'NRS2', 'ANY', 'MIRIMAGE', 'MIRIFULONG', 'MIRIFUSHORT', 'NIS', 'GUIDER1', 'GUIDER2', 'N/A', 'MULTIPLE']

Failed validating 'enum' in schema:
    OrderedDict([('title', 'Name of detector used to acquire the data'),
                 ('type', 'string'),
                 ('enum',
                  ['NRCA1',
                   'NRCA2',
                   'NRCA3',
                   'NRCA4',
                   'NRCALONG',
                   'NRCB1',
                   'NRCB2',
                   'NRCB3',
                   'NRCB4',
                   'NRCBLONG',
                   'NRS1',
                   'NRS2',
                   'ANY',
                   'MIRIMAGE',
                   'MIRIFULONG',
                   'MIRIFUSHORT',
                   'NIS',
                   'GUIDER1',
                   'GUIDER2',
                   'N/A',
                   'MULTIPLE']),
                 ('fits_keyword', 'DETECTOR'),
                 ('blend_table', True),
                 ('blend_rule', 'multi')])

On instance:
    'IR'
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.subarray.name the following error occurred:
False is not of type 'string'

Failed validating 'type' in schema:
    OrderedDict([('title', 'Subarray used'),
                 ('type', 'string'),
                 ('anyOf',
                  [{'enum': ['8X8',
                             '32X32',
                             '128X128',
                             '2048X64',
                             'SUB128CNTR',
                             'SUB128DIAG',
                             'SUB128LL',
                             'SUB32CNTR',
                             'SUB32DIAG',
                             'SUB32LL',
                             'SUB8CNTR',
                             'SUB8DIAG',
                             'SUB8LL',
                             'SUBIDSTRIPCENTER',
                             'SUBIDSTRIPLL',
                             'SUBTUNE32CENTERG1',
                             'SUBTUNE32CENTERG2',
                             'SUBTUNE32LLG1',
                             'SUBTUNE32LLG2']},
                   {'enum': ['BRIGHTSKY',
                             'MASK1065',
                             'MASK1140',
                             'MASK1550',
                             'MASKLYOT',
                             'SLITLESSPRISM',
                             'SUB128',
                             'SUB256',
                             'SUB64',
                             'SUBPRISM']},
                   {'enum': ['FULLP',
                             'MASK210R',
                             'MASK335R',
                             'MASK430R',
                             'MASKLWB',
                             'MASKSWB',
                             'SUB160',
                             'SUB160P',
                             'SUB320',
                             'SUB320A335R',
                             'SUB320A430R',
                             'SUB320ALWB',
                             'SUB320B335R',
                             'SUB320B430R',
                  ...
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/jwst/datamodels/util.py:234: NoTypeWarning: model_type not found. Opening mastDownload/HST/hst_16264_12_wfc3_ir_f110w_iebc12/hst_16264_12_wfc3_ir_f110w_iebc12_drz.fits as a ImageModel
  warnings.warn(f"model_type not found. Opening {file_name} as a {class_name}",
*** Note: close plots to continue!

0

Check the Output

The reference image has not changed, but let’s read in the newly aligned image and compare with the original. subsequent correction needed for optimal alignment.

aligned_image = os.path.join('mastDownload',os.path.basename(align_image).replace('drz.fits','jhat.fits'))
aligned_fits = fits.open(aligned_image)
aligned_data = fits.open(aligned_image)['SCI',1].data
aligned_y,aligned_x = skycoord_to_pixel(star_location,wcs.WCS(aligned_fits['SCI',1],aligned_fits))
aligned_cutout = extract_array(aligned_data,(11,11),(aligned_x,aligned_y))

norm3 = simple_norm(aligned_cutout,stretch='log',min_cut=-1,max_cut=200)
fig,axes = plt.subplots(1,3)
axes[0].imshow(ref_cutout, origin='lower',
                      norm=norm1,cmap='gray')
axes[1].imshow(align_cutout, origin='lower',
                      norm=norm2,cmap='gray')
axes[2].imshow(aligned_cutout, origin='lower',
                      norm=norm3,cmap='gray')
axes[0].set_title('Reference')
axes[1].set_title('To Align')
axes[2].set_title('Aligned')
for i in range(3):
    axes[i].tick_params(labelcolor='none',axis='both',color='none')


plt.show()
Reference, To Align, Aligned

Align to Gaia

You can also align each image to the Gaia DR3 catalog, or you could replace the catalog created in step one with your own catalog of the field.

wcs_align.run_all(align_image,
              telescope='hst',
              outsubdir='mastDownload',
          overwrite=True,
          d2d_max=.5,
          showplots=0,
          refcatname='Gaia',
          histocut_order='dxdy',
              sharpness_lim=(0.3,0.9),
              roundness1_lim=(-0.7, 0.7),
              SNR_min= 3,
              dmag_max=1.0,
              objmag_lim =(14,24))

aligned_image = os.path.join('mastDownload',os.path.basename(align_image).replace('drz.fits','jhat.fits'))
aligned_fits = fits.open(aligned_image)
aligned_data = fits.open(aligned_image)['SCI',1].data
aligned_y,aligned_x = skycoord_to_pixel(star_location,wcs.WCS(aligned_fits['SCI',1],aligned_fits))
aligned_cutout = extract_array(aligned_data,(11,11),(aligned_x,aligned_y))

norm3 = simple_norm(aligned_cutout,stretch='log',min_cut=-1,max_cut=200)
fig,axes = plt.subplots(1,2)
axes[0].imshow(align_cutout, origin='lower',
                      norm=norm2,cmap='gray')
axes[1].imshow(aligned_cutout, origin='lower',
                      norm=norm3,cmap='gray')
axes[0].set_title('To Align')
axes[1].set_title('Aligned')
for i in range(2):
    axes[i].tick_params(labelcolor='none',axis='both',color='none')


plt.show()
To Align, Aligned
Warning: Setting aperture radius to twice the psf_fwhm (4.000000)
0 ./mastDownload/hst_16264_12_wfc3_ir_f110w_iebc12.phot.txt
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/stats/sigma_clipping.py:411: AstropyUserWarning: Input data contains invalid values (NaNs or infs), which were automatically clipped.
  warnings.warn('Input data contains invalid values (NaNs or '
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/stats/sigma_clipping.py:411: AstropyUserWarning: Input data contains invalid values (NaNs or infs), which were automatically clipped.
  warnings.warn('Input data contains invalid values (NaNs or '
/Users/jpierel/CodeBase/jhat/jhat/simple_jwst_phot.py:1942: RuntimeWarning: invalid value encountered in log10
  phot['mag'] = -2.5*np.log10(phot['aper_sum_bkgsub'])+ee_corr+zp
/Users/jpierel/CodeBase/jhat/jhat/simple_jwst_phot.py:1945: RuntimeWarning: invalid value encountered in log10
  phot['magerr'] = 2.5 * np.log10(1.0 + (fluxerr/phot['aper_sum_bkgsub']))
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.instrument.name the following error occurred:
'WFC3' is not one of ['NIRCAM', 'NIRSPEC', 'MIRI', 'TFI', 'FGS', 'NIRISS', 'ANY', 'N/A']

Failed validating 'enum' in schema:
    OrderedDict([('title', 'Instrument used to acquire the data'),
                 ('type', 'string'),
                 ('enum',
                  ['NIRCAM',
                   'NIRSPEC',
                   'MIRI',
                   'TFI',
                   'FGS',
                   'NIRISS',
                   'ANY',
                   'N/A']),
                 ('fits_keyword', 'INSTRUME'),
                 ('blend_table', True)])

On instance:
    'WFC3'
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.instrument.detector the following error occurred:
'IR' is not one of ['NRCA1', 'NRCA2', 'NRCA3', 'NRCA4', 'NRCALONG', 'NRCB1', 'NRCB2', 'NRCB3', 'NRCB4', 'NRCBLONG', 'NRS1', 'NRS2', 'ANY', 'MIRIMAGE', 'MIRIFULONG', 'MIRIFUSHORT', 'NIS', 'GUIDER1', 'GUIDER2', 'N/A', 'MULTIPLE']

Failed validating 'enum' in schema:
    OrderedDict([('title', 'Name of detector used to acquire the data'),
                 ('type', 'string'),
                 ('enum',
                  ['NRCA1',
                   'NRCA2',
                   'NRCA3',
                   'NRCA4',
                   'NRCALONG',
                   'NRCB1',
                   'NRCB2',
                   'NRCB3',
                   'NRCB4',
                   'NRCBLONG',
                   'NRS1',
                   'NRS2',
                   'ANY',
                   'MIRIMAGE',
                   'MIRIFULONG',
                   'MIRIFUSHORT',
                   'NIS',
                   'GUIDER1',
                   'GUIDER2',
                   'N/A',
                   'MULTIPLE']),
                 ('fits_keyword', 'DETECTOR'),
                 ('blend_table', True),
                 ('blend_rule', 'multi')])

On instance:
    'IR'
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.subarray.name the following error occurred:
False is not of type 'string'

Failed validating 'type' in schema:
    OrderedDict([('title', 'Subarray used'),
                 ('type', 'string'),
                 ('anyOf',
                  [{'enum': ['8X8',
                             '32X32',
                             '128X128',
                             '2048X64',
                             'SUB128CNTR',
                             'SUB128DIAG',
                             'SUB128LL',
                             'SUB32CNTR',
                             'SUB32DIAG',
                             'SUB32LL',
                             'SUB8CNTR',
                             'SUB8DIAG',
                             'SUB8LL',
                             'SUBIDSTRIPCENTER',
                             'SUBIDSTRIPLL',
                             'SUBTUNE32CENTERG1',
                             'SUBTUNE32CENTERG2',
                             'SUBTUNE32LLG1',
                             'SUBTUNE32LLG2']},
                   {'enum': ['BRIGHTSKY',
                             'MASK1065',
                             'MASK1140',
                             'MASK1550',
                             'MASKLYOT',
                             'SLITLESSPRISM',
                             'SUB128',
                             'SUB256',
                             'SUB64',
                             'SUBPRISM']},
                   {'enum': ['FULLP',
                             'MASK210R',
                             'MASK335R',
                             'MASK430R',
                             'MASKLWB',
                             'MASKSWB',
                             'SUB160',
                             'SUB160P',
                             'SUB320',
                             'SUB320A335R',
                             'SUB320A430R',
                             'SUB320ALWB',
                             'SUB320B335R',
                             'SUB320B430R',
                  ...
  warnings.warn(errmsg, ValidationWarning)
INFO: Query finished. [astroquery.utils.tap.core]
Number of stars: 81
### NO propoer motion correction!!!
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/pandas/core/arraylike.py:402: RuntimeWarning: invalid value encountered in sqrt
  result = getattr(ufunc, method)(*inputs, **kwargs)
Number of stars after removing nan's: 81
   slope  intercept   maxval  index  d_bestguess  fwhm  multimax
0.000537  -0.391553 6.837554      6     1.974222   0.8     False
Keeping 9 out of 9, skippin 0 because of null values in columns d_rot_tmp
median: 1.981504
75.000000 percentile cut: max residual for cut: 0.180525
median: 2.017531
i:00 mean:2.017531(0.051121) stdev:0.114310(0.032998) X2norm:0.91 Nchanged:0 Ngood:6 Nclip:3

mean: 2.001886
i:01 mean:2.001886(0.055165) stdev:0.145953(0.036488) X2norm:1.00 Nchanged:2 Ngood:8 Nclip:1

mean: 2.001886
i:02 mean:2.001886(0.055165) stdev:0.145953(0.036488) X2norm:1.00 Nchanged:0 Ngood:8 Nclip:1
   slope  intercept  maxval  index  d_bestguess  fwhm  multimax
0.000146   -0.10686   5.236      6     2.360891   1.0     False
Keeping 8 out of 8, skippin 0 because of null values in columns d_rot_tmp
median: 2.342233
75.000000 percentile cut: max residual for cut: 0.358199
median: 2.342233
i:00 mean:2.342233(0.100460) stdev:0.224635(0.064847) X2norm:0.91 Nchanged:0 Ngood:6 Nclip:2

mean: 2.331019
i:01 mean:2.331019(0.114384) stdev:0.302631(0.075658) X2norm:1.00 Nchanged:2 Ngood:8 Nclip:0

mean: 2.331019
i:02 mean:2.331019(0.114384) stdev:0.302631(0.075658) X2norm:1.00 Nchanged:0 Ngood:8 Nclip:0
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.instrument.name the following error occurred:
'WFC3' is not one of ['NIRCAM', 'NIRSPEC', 'MIRI', 'TFI', 'FGS', 'NIRISS', 'ANY', 'N/A']

Failed validating 'enum' in schema:
    OrderedDict([('title', 'Instrument used to acquire the data'),
                 ('type', 'string'),
                 ('enum',
                  ['NIRCAM',
                   'NIRSPEC',
                   'MIRI',
                   'TFI',
                   'FGS',
                   'NIRISS',
                   'ANY',
                   'N/A']),
                 ('fits_keyword', 'INSTRUME'),
                 ('blend_table', True)])

On instance:
    'WFC3'
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.instrument.detector the following error occurred:
'IR' is not one of ['NRCA1', 'NRCA2', 'NRCA3', 'NRCA4', 'NRCALONG', 'NRCB1', 'NRCB2', 'NRCB3', 'NRCB4', 'NRCBLONG', 'NRS1', 'NRS2', 'ANY', 'MIRIMAGE', 'MIRIFULONG', 'MIRIFUSHORT', 'NIS', 'GUIDER1', 'GUIDER2', 'N/A', 'MULTIPLE']

Failed validating 'enum' in schema:
    OrderedDict([('title', 'Name of detector used to acquire the data'),
                 ('type', 'string'),
                 ('enum',
                  ['NRCA1',
                   'NRCA2',
                   'NRCA3',
                   'NRCA4',
                   'NRCALONG',
                   'NRCB1',
                   'NRCB2',
                   'NRCB3',
                   'NRCB4',
                   'NRCBLONG',
                   'NRS1',
                   'NRS2',
                   'ANY',
                   'MIRIMAGE',
                   'MIRIFULONG',
                   'MIRIFUSHORT',
                   'NIS',
                   'GUIDER1',
                   'GUIDER2',
                   'N/A',
                   'MULTIPLE']),
                 ('fits_keyword', 'DETECTOR'),
                 ('blend_table', True),
                 ('blend_rule', 'multi')])

On instance:
    'IR'
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.subarray.name the following error occurred:
False is not of type 'string'

Failed validating 'type' in schema:
    OrderedDict([('title', 'Subarray used'),
                 ('type', 'string'),
                 ('anyOf',
                  [{'enum': ['8X8',
                             '32X32',
                             '128X128',
                             '2048X64',
                             'SUB128CNTR',
                             'SUB128DIAG',
                             'SUB128LL',
                             'SUB32CNTR',
                             'SUB32DIAG',
                             'SUB32LL',
                             'SUB8CNTR',
                             'SUB8DIAG',
                             'SUB8LL',
                             'SUBIDSTRIPCENTER',
                             'SUBIDSTRIPLL',
                             'SUBTUNE32CENTERG1',
                             'SUBTUNE32CENTERG2',
                             'SUBTUNE32LLG1',
                             'SUBTUNE32LLG2']},
                   {'enum': ['BRIGHTSKY',
                             'MASK1065',
                             'MASK1140',
                             'MASK1550',
                             'MASKLYOT',
                             'SLITLESSPRISM',
                             'SUB128',
                             'SUB256',
                             'SUB64',
                             'SUBPRISM']},
                   {'enum': ['FULLP',
                             'MASK210R',
                             'MASK335R',
                             'MASK430R',
                             'MASKLWB',
                             'MASKSWB',
                             'SUB160',
                             'SUB160P',
                             'SUB320',
                             'SUB320A335R',
                             'SUB320A430R',
                             'SUB320ALWB',
                             'SUB320B335R',
                             'SUB320B430R',
                  ...
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/jwst/datamodels/util.py:234: NoTypeWarning: model_type not found. Opening mastDownload/HST/hst_16264_12_wfc3_ir_f110w_iebc12/hst_16264_12_wfc3_ir_f110w_iebc12_drz.fits as a ImageModel
  warnings.warn(f"model_type not found. Opening {file_name} as a {class_name}",

Large Offsets

Sometimes the initial images are so poorly aligned, that the code fails. Here we read in the same image as in the first example, and add an additional 3 pixel offset in the wcs.

files = glob.glob('mastDownload/HST/*/*drz.fits')
align_image = files[1]
align_fits = fits.open(align_image)
align_fits['SCI',1].header['CRPIX1']+=3
align_fits['SCI',1].header['CRPIX2']+=3
align_fits.writeto(align_image,overwrite=True)

align_data = fits.open(align_image)['SCI',1].data
ref_y,ref_x = skycoord_to_pixel(star_location,wcs.WCS(ref_fits['SCI',1],ref_fits))
align_y,align_x = skycoord_to_pixel(star_location,wcs.WCS(align_fits['SCI',1],align_fits))

ref_cutout = extract_array(ref_data,(11,11),(ref_x,ref_y))
align_cutout = extract_array(align_data,(11,11),(align_x,align_y))
norm1 = simple_norm(ref_cutout,stretch='log',min_cut=-1,max_cut=200)
norm2 = simple_norm(align_cutout,stretch='log',min_cut=-1,max_cut=200)
fig,axes = plt.subplots(1,2)
axes[0].imshow(ref_cutout, origin='lower',
                      norm=norm1,cmap='gray')
axes[1].imshow(align_cutout, origin='lower',
                      norm=norm2,cmap='gray')
axes[0].set_title('Reference')
axes[1].set_title('To Align')
axes[0].tick_params(labelcolor='none',axis='both',color='none')
axes[1].tick_params(labelcolor='none',axis='both',color='none')

plt.show()

wcs_align = st_wcs_align()

try:
    wcs_align.run_all(align_image,
              telescope='hst',
              outsubdir='mastDownload',
          refcat_racol='ra',
          refcat_deccol='dec',
          refcat_magcol='mag',
          refcat_magerrcol='dmag',
          overwrite=True,
          d2d_max=.5,
          showplots=2,
          refcatname=ref_catname,
          histocut_order='dxdy',
              sharpness_lim=(0.3,0.9),
              roundness1_lim=(-0.7, 0.7),
              SNR_min= 3,
              dmag_max=1.0,
              objmag_lim =(14,24))

except:
    print('Failed for not enough matches!')
  • Reference, To Align
  • Initial cut: d2d_max=0.5, dmag_max=None, Nbright=None, delta_mag_lim=(None, None)
  • dx, dx, dx, slope:0.0020507812499999754, 3-sigma cut: 9 out of 13 left mean = 1.129 px, stdev = 0.094 px
  • dy, dy, dy, slope:-0.0011230468750000134, 3-sigma cut: 3 out of 4 left mean = 1.080 px, stdev = 0.078 px
Warning: Setting aperture radius to twice the psf_fwhm (4.000000)
0 ./mastDownload/hst_16264_12_wfc3_ir_f110w_iebc12.phot.txt
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/stats/sigma_clipping.py:411: AstropyUserWarning: Input data contains invalid values (NaNs or infs), which were automatically clipped.
  warnings.warn('Input data contains invalid values (NaNs or '
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/stats/sigma_clipping.py:411: AstropyUserWarning: Input data contains invalid values (NaNs or infs), which were automatically clipped.
  warnings.warn('Input data contains invalid values (NaNs or '
/Users/jpierel/CodeBase/jhat/jhat/simple_jwst_phot.py:1942: RuntimeWarning: invalid value encountered in log10
  phot['mag'] = -2.5*np.log10(phot['aper_sum_bkgsub'])+ee_corr+zp
/Users/jpierel/CodeBase/jhat/jhat/simple_jwst_phot.py:1945: RuntimeWarning: invalid value encountered in log10
  phot['magerr'] = 2.5 * np.log10(1.0 + (fluxerr/phot['aper_sum_bkgsub']))
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.instrument.name the following error occurred:
'WFC3' is not one of ['NIRCAM', 'NIRSPEC', 'MIRI', 'TFI', 'FGS', 'NIRISS', 'ANY', 'N/A']

Failed validating 'enum' in schema:
    OrderedDict([('title', 'Instrument used to acquire the data'),
                 ('type', 'string'),
                 ('enum',
                  ['NIRCAM',
                   'NIRSPEC',
                   'MIRI',
                   'TFI',
                   'FGS',
                   'NIRISS',
                   'ANY',
                   'N/A']),
                 ('fits_keyword', 'INSTRUME'),
                 ('blend_table', True)])

On instance:
    'WFC3'
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.instrument.detector the following error occurred:
'IR' is not one of ['NRCA1', 'NRCA2', 'NRCA3', 'NRCA4', 'NRCALONG', 'NRCB1', 'NRCB2', 'NRCB3', 'NRCB4', 'NRCBLONG', 'NRS1', 'NRS2', 'ANY', 'MIRIMAGE', 'MIRIFULONG', 'MIRIFUSHORT', 'NIS', 'GUIDER1', 'GUIDER2', 'N/A', 'MULTIPLE']

Failed validating 'enum' in schema:
    OrderedDict([('title', 'Name of detector used to acquire the data'),
                 ('type', 'string'),
                 ('enum',
                  ['NRCA1',
                   'NRCA2',
                   'NRCA3',
                   'NRCA4',
                   'NRCALONG',
                   'NRCB1',
                   'NRCB2',
                   'NRCB3',
                   'NRCB4',
                   'NRCBLONG',
                   'NRS1',
                   'NRS2',
                   'ANY',
                   'MIRIMAGE',
                   'MIRIFULONG',
                   'MIRIFUSHORT',
                   'NIS',
                   'GUIDER1',
                   'GUIDER2',
                   'N/A',
                   'MULTIPLE']),
                 ('fits_keyword', 'DETECTOR'),
                 ('blend_table', True),
                 ('blend_rule', 'multi')])

On instance:
    'IR'
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.subarray.name the following error occurred:
False is not of type 'string'

Failed validating 'type' in schema:
    OrderedDict([('title', 'Subarray used'),
                 ('type', 'string'),
                 ('anyOf',
                  [{'enum': ['8X8',
                             '32X32',
                             '128X128',
                             '2048X64',
                             'SUB128CNTR',
                             'SUB128DIAG',
                             'SUB128LL',
                             'SUB32CNTR',
                             'SUB32DIAG',
                             'SUB32LL',
                             'SUB8CNTR',
                             'SUB8DIAG',
                             'SUB8LL',
                             'SUBIDSTRIPCENTER',
                             'SUBIDSTRIPLL',
                             'SUBTUNE32CENTERG1',
                             'SUBTUNE32CENTERG2',
                             'SUBTUNE32LLG1',
                             'SUBTUNE32LLG2']},
                   {'enum': ['BRIGHTSKY',
                             'MASK1065',
                             'MASK1140',
                             'MASK1550',
                             'MASKLYOT',
                             'SLITLESSPRISM',
                             'SUB128',
                             'SUB256',
                             'SUB64',
                             'SUBPRISM']},
                   {'enum': ['FULLP',
                             'MASK210R',
                             'MASK335R',
                             'MASK430R',
                             'MASKLWB',
                             'MASKSWB',
                             'SUB160',
                             'SUB160P',
                             'SUB320',
                             'SUB320A335R',
                             'SUB320A430R',
                             'SUB320ALWB',
                             'SUB320B335R',
                             'SUB320B430R',
                  ...
  warnings.warn(errmsg, ValidationWarning)
*** Note: close plot to continue!
   slope  intercept   maxval  index  d_bestguess  fwhm  multimax
0.002051   -1.49502 8.877268     34     1.149103   0.8     False
Keeping 13 out of 13, skippin 0 because of null values in columns d_rot_tmp
median: 1.142187
75.000000 percentile cut: max residual for cut: 0.473790
median: 1.142187
i:00 mean:1.142187(0.034755) stdev:0.098302(0.023170) X2norm:0.94 Nchanged:0 Ngood:9 Nclip:4

mean: 1.128891
i:01 mean:1.128891(0.033318) stdev:0.094236(0.022212) X2norm:1.00 Nchanged:0 Ngood:9 Nclip:4
    slope  intercept   maxval  index  d_bestguess  fwhm  multimax
-0.001123   0.819263 3.661515     19     1.083046   0.8     False
Keeping 4 out of 4, skippin 0 because of null values in columns d_rot_tmp
median: 1.045332
75.000000 percentile cut: max residual for cut: 0.138967
median: 1.095192
i:00 mean:1.095192(0.064008) stdev:0.090521(0.036955) X2norm:0.79 Nchanged:0 Ngood:3 Nclip:1

mean: 1.079986
i:01 mean:1.079986(0.055176) stdev:0.078030(0.031856) X2norm:1.00 Nchanged:0 Ngood:3 Nclip:1
*** Note: close plots to continue!
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.instrument.name the following error occurred:
'WFC3' is not one of ['NIRCAM', 'NIRSPEC', 'MIRI', 'TFI', 'FGS', 'NIRISS', 'ANY', 'N/A']

Failed validating 'enum' in schema:
    OrderedDict([('title', 'Instrument used to acquire the data'),
                 ('type', 'string'),
                 ('enum',
                  ['NIRCAM',
                   'NIRSPEC',
                   'MIRI',
                   'TFI',
                   'FGS',
                   'NIRISS',
                   'ANY',
                   'N/A']),
                 ('fits_keyword', 'INSTRUME'),
                 ('blend_table', True)])

On instance:
    'WFC3'
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.instrument.detector the following error occurred:
'IR' is not one of ['NRCA1', 'NRCA2', 'NRCA3', 'NRCA4', 'NRCALONG', 'NRCB1', 'NRCB2', 'NRCB3', 'NRCB4', 'NRCBLONG', 'NRS1', 'NRS2', 'ANY', 'MIRIMAGE', 'MIRIFULONG', 'MIRIFUSHORT', 'NIS', 'GUIDER1', 'GUIDER2', 'N/A', 'MULTIPLE']

Failed validating 'enum' in schema:
    OrderedDict([('title', 'Name of detector used to acquire the data'),
                 ('type', 'string'),
                 ('enum',
                  ['NRCA1',
                   'NRCA2',
                   'NRCA3',
                   'NRCA4',
                   'NRCALONG',
                   'NRCB1',
                   'NRCB2',
                   'NRCB3',
                   'NRCB4',
                   'NRCBLONG',
                   'NRS1',
                   'NRS2',
                   'ANY',
                   'MIRIMAGE',
                   'MIRIFULONG',
                   'MIRIFUSHORT',
                   'NIS',
                   'GUIDER1',
                   'GUIDER2',
                   'N/A',
                   'MULTIPLE']),
                 ('fits_keyword', 'DETECTOR'),
                 ('blend_table', True),
                 ('blend_rule', 'multi')])

On instance:
    'IR'
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.subarray.name the following error occurred:
False is not of type 'string'

Failed validating 'type' in schema:
    OrderedDict([('title', 'Subarray used'),
                 ('type', 'string'),
                 ('anyOf',
                  [{'enum': ['8X8',
                             '32X32',
                             '128X128',
                             '2048X64',
                             'SUB128CNTR',
                             'SUB128DIAG',
                             'SUB128LL',
                             'SUB32CNTR',
                             'SUB32DIAG',
                             'SUB32LL',
                             'SUB8CNTR',
                             'SUB8DIAG',
                             'SUB8LL',
                             'SUBIDSTRIPCENTER',
                             'SUBIDSTRIPLL',
                             'SUBTUNE32CENTERG1',
                             'SUBTUNE32CENTERG2',
                             'SUBTUNE32LLG1',
                             'SUBTUNE32LLG2']},
                   {'enum': ['BRIGHTSKY',
                             'MASK1065',
                             'MASK1140',
                             'MASK1550',
                             'MASKLYOT',
                             'SLITLESSPRISM',
                             'SUB128',
                             'SUB256',
                             'SUB64',
                             'SUBPRISM']},
                   {'enum': ['FULLP',
                             'MASK210R',
                             'MASK335R',
                             'MASK430R',
                             'MASKLWB',
                             'MASKSWB',
                             'SUB160',
                             'SUB160P',
                             'SUB320',
                             'SUB320A335R',
                             'SUB320A430R',
                             'SUB320ALWB',
                             'SUB320B335R',
                             'SUB320B430R',
                  ...
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/jwst/datamodels/util.py:234: NoTypeWarning: model_type not found. Opening mastDownload/HST/hst_16264_12_wfc3_ir_f110w_iebc12/hst_16264_12_wfc3_ir_f110w_iebc12_drz.fits as a ImageModel
  warnings.warn(f"model_type not found. Opening {file_name} as a {class_name}",
Failed for not enough matches!

This is what a failure looks like (compare to the plots above). There are now a couple of options here. You can increase the d2d_max parameter, which increases the allowed distance between sources being matched in the reference and target images:

wcs_align = st_wcs_align()


wcs_align.run_all(align_image,
              telescope='hst',
              outsubdir='mastDownload',
          refcat_racol='ra',
          refcat_deccol='dec',
          refcat_magcol='mag',
          refcat_magerrcol='dmag',
          overwrite=True,
          d2d_max=1,
          showplots=2,
          refcatname=ref_catname,
          histocut_order='dxdy',
              sharpness_lim=(0.3,0.9),
              roundness1_lim=(-0.7, 0.7),
              SNR_min= 3,
              dmag_max=1.0,
              objmag_lim =(14,24))

aligned_image = os.path.join('mastDownload',os.path.basename(align_image).replace('drz.fits','jhat.fits'))
aligned_fits = fits.open(aligned_image)
aligned_data = fits.open(aligned_image)['SCI',1].data
aligned_y,aligned_x = skycoord_to_pixel(star_location,wcs.WCS(aligned_fits['SCI',1],aligned_fits))
aligned_cutout = extract_array(aligned_data,(11,11),(aligned_x,aligned_y))

norm3 = simple_norm(aligned_cutout,stretch='log',min_cut=-1,max_cut=200)
fig,axes = plt.subplots(1,3)
axes[0].imshow(ref_cutout, origin='lower',
                      norm=norm1,cmap='gray')
axes[1].imshow(align_cutout, origin='lower',
                      norm=norm2,cmap='gray')
axes[2].imshow(aligned_cutout, origin='lower',
                      norm=norm3,cmap='gray')
axes[0].set_title('Reference')
axes[1].set_title('To Align')
axes[2].set_title('Aligned')
for i in range(3):
    axes[i].tick_params(labelcolor='none',axis='both',color='none')


plt.show()
  • Initial cut: d2d_max=1, dmag_max=None, Nbright=None, delta_mag_lim=(None, None)
  • dx, dx, dx, slope:-0.0002929687500000163, 3-sigma cut: 163 out of 177 left mean = 5.103 px, stdev = 0.076 px
  • dy, dy, dy, slope:9.76562499999823e-05, 3-sigma cut: 152 out of 162 left mean = 4.944 px, stdev = 0.053 px
  • Reference, To Align, Aligned
Warning: Setting aperture radius to twice the psf_fwhm (4.000000)
0 ./mastDownload/hst_16264_12_wfc3_ir_f110w_iebc12.phot.txt
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/stats/sigma_clipping.py:411: AstropyUserWarning: Input data contains invalid values (NaNs or infs), which were automatically clipped.
  warnings.warn('Input data contains invalid values (NaNs or '
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/stats/sigma_clipping.py:411: AstropyUserWarning: Input data contains invalid values (NaNs or infs), which were automatically clipped.
  warnings.warn('Input data contains invalid values (NaNs or '
/Users/jpierel/CodeBase/jhat/jhat/simple_jwst_phot.py:1942: RuntimeWarning: invalid value encountered in log10
  phot['mag'] = -2.5*np.log10(phot['aper_sum_bkgsub'])+ee_corr+zp
/Users/jpierel/CodeBase/jhat/jhat/simple_jwst_phot.py:1945: RuntimeWarning: invalid value encountered in log10
  phot['magerr'] = 2.5 * np.log10(1.0 + (fluxerr/phot['aper_sum_bkgsub']))
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.instrument.name the following error occurred:
'WFC3' is not one of ['NIRCAM', 'NIRSPEC', 'MIRI', 'TFI', 'FGS', 'NIRISS', 'ANY', 'N/A']

Failed validating 'enum' in schema:
    OrderedDict([('title', 'Instrument used to acquire the data'),
                 ('type', 'string'),
                 ('enum',
                  ['NIRCAM',
                   'NIRSPEC',
                   'MIRI',
                   'TFI',
                   'FGS',
                   'NIRISS',
                   'ANY',
                   'N/A']),
                 ('fits_keyword', 'INSTRUME'),
                 ('blend_table', True)])

On instance:
    'WFC3'
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.instrument.detector the following error occurred:
'IR' is not one of ['NRCA1', 'NRCA2', 'NRCA3', 'NRCA4', 'NRCALONG', 'NRCB1', 'NRCB2', 'NRCB3', 'NRCB4', 'NRCBLONG', 'NRS1', 'NRS2', 'ANY', 'MIRIMAGE', 'MIRIFULONG', 'MIRIFUSHORT', 'NIS', 'GUIDER1', 'GUIDER2', 'N/A', 'MULTIPLE']

Failed validating 'enum' in schema:
    OrderedDict([('title', 'Name of detector used to acquire the data'),
                 ('type', 'string'),
                 ('enum',
                  ['NRCA1',
                   'NRCA2',
                   'NRCA3',
                   'NRCA4',
                   'NRCALONG',
                   'NRCB1',
                   'NRCB2',
                   'NRCB3',
                   'NRCB4',
                   'NRCBLONG',
                   'NRS1',
                   'NRS2',
                   'ANY',
                   'MIRIMAGE',
                   'MIRIFULONG',
                   'MIRIFUSHORT',
                   'NIS',
                   'GUIDER1',
                   'GUIDER2',
                   'N/A',
                   'MULTIPLE']),
                 ('fits_keyword', 'DETECTOR'),
                 ('blend_table', True),
                 ('blend_rule', 'multi')])

On instance:
    'IR'
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.subarray.name the following error occurred:
False is not of type 'string'

Failed validating 'type' in schema:
    OrderedDict([('title', 'Subarray used'),
                 ('type', 'string'),
                 ('anyOf',
                  [{'enum': ['8X8',
                             '32X32',
                             '128X128',
                             '2048X64',
                             'SUB128CNTR',
                             'SUB128DIAG',
                             'SUB128LL',
                             'SUB32CNTR',
                             'SUB32DIAG',
                             'SUB32LL',
                             'SUB8CNTR',
                             'SUB8DIAG',
                             'SUB8LL',
                             'SUBIDSTRIPCENTER',
                             'SUBIDSTRIPLL',
                             'SUBTUNE32CENTERG1',
                             'SUBTUNE32CENTERG2',
                             'SUBTUNE32LLG1',
                             'SUBTUNE32LLG2']},
                   {'enum': ['BRIGHTSKY',
                             'MASK1065',
                             'MASK1140',
                             'MASK1550',
                             'MASKLYOT',
                             'SLITLESSPRISM',
                             'SUB128',
                             'SUB256',
                             'SUB64',
                             'SUBPRISM']},
                   {'enum': ['FULLP',
                             'MASK210R',
                             'MASK335R',
                             'MASK430R',
                             'MASKLWB',
                             'MASKSWB',
                             'SUB160',
                             'SUB160P',
                             'SUB320',
                             'SUB320A335R',
                             'SUB320A430R',
                             'SUB320ALWB',
                             'SUB320B335R',
                             'SUB320B430R',
                  ...
  warnings.warn(errmsg, ValidationWarning)
*** Note: close plot to continue!
    slope  intercept     maxval  index  d_bestguess  fwhm  multimax
-0.000293   0.213574 151.767497     58     5.058877   0.8     False
Keeping 177 out of 177, skippin 0 because of null values in columns d_rot_tmp
median: 5.100640
75.000000 percentile cut: max residual for cut: 0.091924
median: 5.091393
i:00 mean:5.091393(0.004565) stdev:0.052249(0.003216) X2norm:1.00 Nchanged:0 Ngood:132 Nclip:45

mean: 5.101872
i:01 mean:5.101872(0.005427) stdev:0.067565(0.003825) X2norm:1.00 Nchanged:24 Ngood:156 Nclip:21

mean: 5.103992
i:02 mean:5.103992(0.005907) stdev:0.074955(0.004164) X2norm:1.00 Nchanged:6 Ngood:162 Nclip:15

mean: 5.102721
i:03 mean:5.102721(0.006008) stdev:0.076467(0.004235) X2norm:1.00 Nchanged:1 Ngood:163 Nclip:14

mean: 5.102721
i:04 mean:5.102721(0.006008) stdev:0.076467(0.004235) X2norm:1.00 Nchanged:0 Ngood:163 Nclip:14
   slope  intercept     maxval  index  d_bestguess  fwhm  multimax
0.000098   -0.07124 153.147275     54     4.948694   0.8     False
Keeping 162 out of 162, skippin 0 because of null values in columns d_rot_tmp
median: 4.942136
75.000000 percentile cut: max residual for cut: 0.062217
median: 4.946718
i:00 mean:4.946718(0.002966) stdev:0.032492(0.002089) X2norm:1.00 Nchanged:0 Ngood:121 Nclip:41

mean: 4.942254
i:01 mean:4.942254(0.003583) stdev:0.042396(0.002525) X2norm:1.00 Nchanged:20 Ngood:141 Nclip:21

mean: 4.941777
i:02 mean:4.941777(0.003869) stdev:0.046592(0.002727) X2norm:1.00 Nchanged:5 Ngood:146 Nclip:16

mean: 4.942611
i:03 mean:4.942611(0.004236) stdev:0.051878(0.002985) X2norm:1.00 Nchanged:5 Ngood:151 Nclip:11

mean: 4.943574
i:04 mean:4.943574(0.004317) stdev:0.053053(0.003043) X2norm:1.00 Nchanged:1 Ngood:152 Nclip:10

mean: 4.943574
i:05 mean:4.943574(0.004317) stdev:0.053053(0.003043) X2norm:1.00 Nchanged:0 Ngood:152 Nclip:10
*** Note: close plots to continue!
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.instrument.name the following error occurred:
'WFC3' is not one of ['NIRCAM', 'NIRSPEC', 'MIRI', 'TFI', 'FGS', 'NIRISS', 'ANY', 'N/A']

Failed validating 'enum' in schema:
    OrderedDict([('title', 'Instrument used to acquire the data'),
                 ('type', 'string'),
                 ('enum',
                  ['NIRCAM',
                   'NIRSPEC',
                   'MIRI',
                   'TFI',
                   'FGS',
                   'NIRISS',
                   'ANY',
                   'N/A']),
                 ('fits_keyword', 'INSTRUME'),
                 ('blend_table', True)])

On instance:
    'WFC3'
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.instrument.detector the following error occurred:
'IR' is not one of ['NRCA1', 'NRCA2', 'NRCA3', 'NRCA4', 'NRCALONG', 'NRCB1', 'NRCB2', 'NRCB3', 'NRCB4', 'NRCBLONG', 'NRS1', 'NRS2', 'ANY', 'MIRIMAGE', 'MIRIFULONG', 'MIRIFUSHORT', 'NIS', 'GUIDER1', 'GUIDER2', 'N/A', 'MULTIPLE']

Failed validating 'enum' in schema:
    OrderedDict([('title', 'Name of detector used to acquire the data'),
                 ('type', 'string'),
                 ('enum',
                  ['NRCA1',
                   'NRCA2',
                   'NRCA3',
                   'NRCA4',
                   'NRCALONG',
                   'NRCB1',
                   'NRCB2',
                   'NRCB3',
                   'NRCB4',
                   'NRCBLONG',
                   'NRS1',
                   'NRS2',
                   'ANY',
                   'MIRIMAGE',
                   'MIRIFULONG',
                   'MIRIFUSHORT',
                   'NIS',
                   'GUIDER1',
                   'GUIDER2',
                   'N/A',
                   'MULTIPLE']),
                 ('fits_keyword', 'DETECTOR'),
                 ('blend_table', True),
                 ('blend_rule', 'multi')])

On instance:
    'IR'
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.subarray.name the following error occurred:
False is not of type 'string'

Failed validating 'type' in schema:
    OrderedDict([('title', 'Subarray used'),
                 ('type', 'string'),
                 ('anyOf',
                  [{'enum': ['8X8',
                             '32X32',
                             '128X128',
                             '2048X64',
                             'SUB128CNTR',
                             'SUB128DIAG',
                             'SUB128LL',
                             'SUB32CNTR',
                             'SUB32DIAG',
                             'SUB32LL',
                             'SUB8CNTR',
                             'SUB8DIAG',
                             'SUB8LL',
                             'SUBIDSTRIPCENTER',
                             'SUBIDSTRIPLL',
                             'SUBTUNE32CENTERG1',
                             'SUBTUNE32CENTERG2',
                             'SUBTUNE32LLG1',
                             'SUBTUNE32LLG2']},
                   {'enum': ['BRIGHTSKY',
                             'MASK1065',
                             'MASK1140',
                             'MASK1550',
                             'MASKLYOT',
                             'SLITLESSPRISM',
                             'SUB128',
                             'SUB256',
                             'SUB64',
                             'SUBPRISM']},
                   {'enum': ['FULLP',
                             'MASK210R',
                             'MASK335R',
                             'MASK430R',
                             'MASKLWB',
                             'MASKSWB',
                             'SUB160',
                             'SUB160P',
                             'SUB320',
                             'SUB320A335R',
                             'SUB320A430R',
                             'SUB320ALWB',
                             'SUB320B335R',
                             'SUB320B430R',
                  ...
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/jwst/datamodels/util.py:234: NoTypeWarning: model_type not found. Opening mastDownload/HST/hst_16264_12_wfc3_ir_f110w_iebc12/hst_16264_12_wfc3_ir_f110w_iebc12_drz.fits as a ImageModel
  warnings.warn(f"model_type not found. Opening {file_name} as a {class_name}",
*** Note: close plots to continue!

Or you can apply a rough guess for the offset, and then use a smaller d2d_max for matching:

wcs_align = st_wcs_align()


wcs_align.run_all(align_image,
              telescope='hst',
              outsubdir='mastDownload',
          refcat_racol='ra',
          refcat_deccol='dec',
          refcat_magcol='mag',
          refcat_magerrcol='dmag',
          overwrite=True,
          d2d_max=.25,
          xshift=5,
          yshift=5,
          showplots=2,
          refcatname=ref_catname,
          histocut_order='dxdy',
              sharpness_lim=(0.3,0.9),
              roundness1_lim=(-0.7, 0.7),
              SNR_min= 3,
              dmag_max=1.0,
              objmag_lim =(14,24))

aligned_image = os.path.join('mastDownload',os.path.basename(align_image).replace('drz.fits','jhat.fits'))
aligned_fits = fits.open(aligned_image)
aligned_data = fits.open(aligned_image)['SCI',1].data
aligned_y,aligned_x = skycoord_to_pixel(star_location,wcs.WCS(aligned_fits['SCI',1],aligned_fits))
aligned_cutout = extract_array(aligned_data,(11,11),(aligned_x,aligned_y))

norm3 = simple_norm(aligned_cutout,stretch='log',min_cut=-1,max_cut=200)
fig,axes = plt.subplots(1,3)
axes[0].imshow(ref_cutout, origin='lower',
                      norm=norm1,cmap='gray')
axes[1].imshow(align_cutout, origin='lower',
                      norm=norm2,cmap='gray')
axes[2].imshow(aligned_cutout, origin='lower',
                      norm=norm3,cmap='gray')
axes[0].set_title('Reference')
axes[1].set_title('To Align')
axes[2].set_title('Aligned')
for i in range(3):
    axes[i].tick_params(labelcolor='none',axis='both',color='none')


plt.show()
  • Initial cut: d2d_max=0.25, dmag_max=None, Nbright=None, delta_mag_lim=(None, None)
  • dx, dx, dx, slope:-4.8828125000017174e-05, 3-sigma cut: 203 out of 228 left mean = 5.109 px, stdev = 0.055 px
  • dy, dy, dy, slope:0.00014648437499998213, 3-sigma cut: 191 out of 203 left mean = 4.941 px, stdev = 0.058 px
  • Reference, To Align, Aligned
Warning: Setting aperture radius to twice the psf_fwhm (4.000000)
0 ./mastDownload/hst_16264_12_wfc3_ir_f110w_iebc12.phot.txt
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/stats/sigma_clipping.py:411: AstropyUserWarning: Input data contains invalid values (NaNs or infs), which were automatically clipped.
  warnings.warn('Input data contains invalid values (NaNs or '
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/astropy/stats/sigma_clipping.py:411: AstropyUserWarning: Input data contains invalid values (NaNs or infs), which were automatically clipped.
  warnings.warn('Input data contains invalid values (NaNs or '
/Users/jpierel/CodeBase/jhat/jhat/simple_jwst_phot.py:1942: RuntimeWarning: invalid value encountered in log10
  phot['mag'] = -2.5*np.log10(phot['aper_sum_bkgsub'])+ee_corr+zp
/Users/jpierel/CodeBase/jhat/jhat/simple_jwst_phot.py:1945: RuntimeWarning: invalid value encountered in log10
  phot['magerr'] = 2.5 * np.log10(1.0 + (fluxerr/phot['aper_sum_bkgsub']))
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.instrument.name the following error occurred:
'WFC3' is not one of ['NIRCAM', 'NIRSPEC', 'MIRI', 'TFI', 'FGS', 'NIRISS', 'ANY', 'N/A']

Failed validating 'enum' in schema:
    OrderedDict([('title', 'Instrument used to acquire the data'),
                 ('type', 'string'),
                 ('enum',
                  ['NIRCAM',
                   'NIRSPEC',
                   'MIRI',
                   'TFI',
                   'FGS',
                   'NIRISS',
                   'ANY',
                   'N/A']),
                 ('fits_keyword', 'INSTRUME'),
                 ('blend_table', True)])

On instance:
    'WFC3'
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.instrument.detector the following error occurred:
'IR' is not one of ['NRCA1', 'NRCA2', 'NRCA3', 'NRCA4', 'NRCALONG', 'NRCB1', 'NRCB2', 'NRCB3', 'NRCB4', 'NRCBLONG', 'NRS1', 'NRS2', 'ANY', 'MIRIMAGE', 'MIRIFULONG', 'MIRIFUSHORT', 'NIS', 'GUIDER1', 'GUIDER2', 'N/A', 'MULTIPLE']

Failed validating 'enum' in schema:
    OrderedDict([('title', 'Name of detector used to acquire the data'),
                 ('type', 'string'),
                 ('enum',
                  ['NRCA1',
                   'NRCA2',
                   'NRCA3',
                   'NRCA4',
                   'NRCALONG',
                   'NRCB1',
                   'NRCB2',
                   'NRCB3',
                   'NRCB4',
                   'NRCBLONG',
                   'NRS1',
                   'NRS2',
                   'ANY',
                   'MIRIMAGE',
                   'MIRIFULONG',
                   'MIRIFUSHORT',
                   'NIS',
                   'GUIDER1',
                   'GUIDER2',
                   'N/A',
                   'MULTIPLE']),
                 ('fits_keyword', 'DETECTOR'),
                 ('blend_table', True),
                 ('blend_rule', 'multi')])

On instance:
    'IR'
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.subarray.name the following error occurred:
False is not of type 'string'

Failed validating 'type' in schema:
    OrderedDict([('title', 'Subarray used'),
                 ('type', 'string'),
                 ('anyOf',
                  [{'enum': ['8X8',
                             '32X32',
                             '128X128',
                             '2048X64',
                             'SUB128CNTR',
                             'SUB128DIAG',
                             'SUB128LL',
                             'SUB32CNTR',
                             'SUB32DIAG',
                             'SUB32LL',
                             'SUB8CNTR',
                             'SUB8DIAG',
                             'SUB8LL',
                             'SUBIDSTRIPCENTER',
                             'SUBIDSTRIPLL',
                             'SUBTUNE32CENTERG1',
                             'SUBTUNE32CENTERG2',
                             'SUBTUNE32LLG1',
                             'SUBTUNE32LLG2']},
                   {'enum': ['BRIGHTSKY',
                             'MASK1065',
                             'MASK1140',
                             'MASK1550',
                             'MASKLYOT',
                             'SLITLESSPRISM',
                             'SUB128',
                             'SUB256',
                             'SUB64',
                             'SUBPRISM']},
                   {'enum': ['FULLP',
                             'MASK210R',
                             'MASK335R',
                             'MASK430R',
                             'MASKLWB',
                             'MASKSWB',
                             'SUB160',
                             'SUB160P',
                             'SUB320',
                             'SUB320A335R',
                             'SUB320A430R',
                             'SUB320ALWB',
                             'SUB320B335R',
                             'SUB320B430R',
                  ...
  warnings.warn(errmsg, ValidationWarning)
*** Note: close plot to continue!
    slope  intercept     maxval  index  d_bestguess  fwhm  multimax
-0.000049   0.035596 210.533193     11     5.118499   0.8     False
Keeping 228 out of 228, skippin 0 because of null values in columns d_rot_tmp
median: 5.108273
75.000000 percentile cut: max residual for cut: 0.073336
median: 5.111246
i:00 mean:5.111246(0.002647) stdev:0.034510(0.001866) X2norm:1.00 Nchanged:0 Ngood:171 Nclip:57

mean: 5.113886
i:01 mean:5.113886(0.003071) stdev:0.041878(0.002165) X2norm:1.00 Nchanged:16 Ngood:187 Nclip:41

mean: 5.113807
i:02 mean:5.113807(0.003391) stdev:0.047237(0.002392) X2norm:1.00 Nchanged:8 Ngood:195 Nclip:33

mean: 5.113819
i:03 mean:5.113819(0.003501) stdev:0.049019(0.002470) X2norm:1.00 Nchanged:2 Ngood:197 Nclip:31

mean: 5.113098
i:04 mean:5.113098(0.003558) stdev:0.049936(0.002509) X2norm:1.00 Nchanged:1 Ngood:198 Nclip:30

mean: 5.111626
i:05 mean:5.111626(0.003673) stdev:0.051807(0.002590) X2norm:1.00 Nchanged:2 Ngood:200 Nclip:28

mean: 5.110125
i:06 mean:5.110125(0.003788) stdev:0.053702(0.002672) X2norm:1.00 Nchanged:2 Ngood:202 Nclip:26

mean: 5.109359
i:07 mean:5.109359(0.003846) stdev:0.054669(0.002713) X2norm:1.00 Nchanged:1 Ngood:203 Nclip:25

mean: 5.109359
i:08 mean:5.109359(0.003846) stdev:0.054669(0.002713) X2norm:1.00 Nchanged:0 Ngood:203 Nclip:25
   slope  intercept     maxval  index  d_bestguess  fwhm  multimax
0.000146   -0.10686 187.297193      5     4.964436   0.8     False
Keeping 203 out of 203, skippin 0 because of null values in columns d_rot_tmp
median: 4.946334
75.000000 percentile cut: max residual for cut: 0.066828
median: 4.947336
i:00 mean:4.947336(0.002530) stdev:0.031086(0.001783) X2norm:1.00 Nchanged:0 Ngood:152 Nclip:51

mean: 4.940657
i:01 mean:4.940657(0.002958) stdev:0.038228(0.002086) X2norm:1.00 Nchanged:16 Ngood:168 Nclip:35

mean: 4.938915
i:02 mean:4.938915(0.003185) stdev:0.041767(0.002245) X2norm:1.00 Nchanged:5 Ngood:173 Nclip:30

mean: 4.937633
i:03 mean:4.937633(0.003487) stdev:0.046521(0.002459) X2norm:1.00 Nchanged:6 Ngood:179 Nclip:24

mean: 4.939127
i:04 mean:4.939127(0.003714) stdev:0.050106(0.002619) X2norm:1.00 Nchanged:4 Ngood:183 Nclip:20

mean: 4.939913
i:05 mean:4.939913(0.004011) stdev:0.054843(0.002828) X2norm:1.00 Nchanged:5 Ngood:188 Nclip:15

mean: 4.939926
i:06 mean:4.939926(0.004134) stdev:0.056835(0.002916) X2norm:1.00 Nchanged:2 Ngood:190 Nclip:13

mean: 4.940799
i:07 mean:4.940799(0.004205) stdev:0.057955(0.002965) X2norm:1.00 Nchanged:1 Ngood:191 Nclip:12

mean: 4.940799
i:08 mean:4.940799(0.004205) stdev:0.057955(0.002965) X2norm:1.00 Nchanged:0 Ngood:191 Nclip:12
*** Note: close plots to continue!
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.instrument.name the following error occurred:
'WFC3' is not one of ['NIRCAM', 'NIRSPEC', 'MIRI', 'TFI', 'FGS', 'NIRISS', 'ANY', 'N/A']

Failed validating 'enum' in schema:
    OrderedDict([('title', 'Instrument used to acquire the data'),
                 ('type', 'string'),
                 ('enum',
                  ['NIRCAM',
                   'NIRSPEC',
                   'MIRI',
                   'TFI',
                   'FGS',
                   'NIRISS',
                   'ANY',
                   'N/A']),
                 ('fits_keyword', 'INSTRUME'),
                 ('blend_table', True)])

On instance:
    'WFC3'
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.instrument.detector the following error occurred:
'IR' is not one of ['NRCA1', 'NRCA2', 'NRCA3', 'NRCA4', 'NRCALONG', 'NRCB1', 'NRCB2', 'NRCB3', 'NRCB4', 'NRCBLONG', 'NRS1', 'NRS2', 'ANY', 'MIRIMAGE', 'MIRIFULONG', 'MIRIFUSHORT', 'NIS', 'GUIDER1', 'GUIDER2', 'N/A', 'MULTIPLE']

Failed validating 'enum' in schema:
    OrderedDict([('title', 'Name of detector used to acquire the data'),
                 ('type', 'string'),
                 ('enum',
                  ['NRCA1',
                   'NRCA2',
                   'NRCA3',
                   'NRCA4',
                   'NRCALONG',
                   'NRCB1',
                   'NRCB2',
                   'NRCB3',
                   'NRCB4',
                   'NRCBLONG',
                   'NRS1',
                   'NRS2',
                   'ANY',
                   'MIRIMAGE',
                   'MIRIFULONG',
                   'MIRIFUSHORT',
                   'NIS',
                   'GUIDER1',
                   'GUIDER2',
                   'N/A',
                   'MULTIPLE']),
                 ('fits_keyword', 'DETECTOR'),
                 ('blend_table', True),
                 ('blend_rule', 'multi')])

On instance:
    'IR'
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/stdatamodels/validate.py:38: ValidationWarning: While validating meta.subarray.name the following error occurred:
False is not of type 'string'

Failed validating 'type' in schema:
    OrderedDict([('title', 'Subarray used'),
                 ('type', 'string'),
                 ('anyOf',
                  [{'enum': ['8X8',
                             '32X32',
                             '128X128',
                             '2048X64',
                             'SUB128CNTR',
                             'SUB128DIAG',
                             'SUB128LL',
                             'SUB32CNTR',
                             'SUB32DIAG',
                             'SUB32LL',
                             'SUB8CNTR',
                             'SUB8DIAG',
                             'SUB8LL',
                             'SUBIDSTRIPCENTER',
                             'SUBIDSTRIPLL',
                             'SUBTUNE32CENTERG1',
                             'SUBTUNE32CENTERG2',
                             'SUBTUNE32LLG1',
                             'SUBTUNE32LLG2']},
                   {'enum': ['BRIGHTSKY',
                             'MASK1065',
                             'MASK1140',
                             'MASK1550',
                             'MASKLYOT',
                             'SLITLESSPRISM',
                             'SUB128',
                             'SUB256',
                             'SUB64',
                             'SUBPRISM']},
                   {'enum': ['FULLP',
                             'MASK210R',
                             'MASK335R',
                             'MASK430R',
                             'MASKLWB',
                             'MASKSWB',
                             'SUB160',
                             'SUB160P',
                             'SUB320',
                             'SUB320A335R',
                             'SUB320A430R',
                             'SUB320ALWB',
                             'SUB320B335R',
                             'SUB320B430R',
                  ...
  warnings.warn(errmsg, ValidationWarning)
/Users/jpierel/miniconda3/envs/tweakreg/lib/python3.10/site-packages/jwst/datamodels/util.py:234: NoTypeWarning: model_type not found. Opening mastDownload/HST/hst_16264_12_wfc3_ir_f110w_iebc12/hst_16264_12_wfc3_ir_f110w_iebc12_drz.fits as a ImageModel
  warnings.warn(f"model_type not found. Opening {file_name} as a {class_name}",
*** Note: close plots to continue!

Total running time of the script: ( 0 minutes 57.951 seconds)

Gallery generated by Sphinx-Gallery

Gallery generated by Sphinx-Gallery

API Documentation


jhat

st_wcs_align

Created on Thu Apr 21 14:32:42 2022

@author: arest, bhilbert, mcorrenti, acanipe, jpierel

class jhat.st_wcs_align.st_wcs_align[source]

Main class for alignment.

outrootdir

output root directory. The output directoy is the output root directory + the outsubdir if not None

Type:

str

outsubdir

outsubdir added to output root directory

Type:

str

overwrite

overwrite files if they exist.

Type:

bool

telescope

If None, then telescope is determined automatically from the filename (“jw*” and “hst*” for JWST and HST, respectively)

Type:

str

skip_if_exists

Skip doing the analysis of a given input image if the cal file already exists, assuming the full analysis has been already done

Type:

bool

verbose

verbosity count (lower is less verbose)

Type:

int

SNR_min

mininum SNR for objects in image to be used for analysis

Type:

float

use_dq

use the DQ extensions for masking

Type:

bool

refcat

reference catalog. Can be a filename or Gaia

Type:

str

refcat_racol

RA column of reference catalog. If None, then automatically determined

Type:

str

refcat_deccol

Dec column of reference catalog. If None, then automatically determined

Type:

str

refcat_magcol

mag column of reference catalog. If None and not one of the default refcats like gaia, then 3rd column is used

Type:

str

refcat_magerrcol

magerr column of reference catalog. If None, then not used

Type:

str

refcat_colorcol

color column of reference catalog. If None, then not used

Type:

str:

refcat_pmflag

Apply the proper motion correction (only for catalogs it is applicable, e.g., gaia

Type:

bool

refcat_pmmedian

Apply the MEDIAN proper motion correction (only for catalogs it is applicable, e.g., gaia

Type:

bool

photfilename

photometry output filename. if “auto”, the fits in the image filename is substituted with phot.txt

Type:

str

load_photcat_if_exists

If the photometric catalog file already exists, skip recreating it.

Type:

bool

rematch_refcat

if –load_photcat_if_exists and the photcat already exists, load the photcat, but rematch with refcat

Type:

bool

d2d_max

maximum distance between source in image and refcat object, in arcsec

Type:

float

dmag_max

maximum uncertainty of sources in image

Type:

float

sharpness_lim

sharpness limits of sources in image (iterable of length 2)

Type:

list of float

roundness1_lim

roundness1 limits of sources in image (iterable of length 2)

Type:

list of float

delta_mag_lim

limits on mag - refcat_mainfilter (iterable of length 2)

Type:

list of float

objmag_lim

limits on mag, the magnitude of the objects in the image (iterable of length 2)

Type:

list of float

refmag_lim

limits on refcat_mainfilter, the magnitude of the reference catalog (iterable of length 2)

Type:

list of float

slope_min

minimum slope for linear correction applied to dx/dy. This effectively accounts for rotation. slopes go from slopemin to -slopemin

Type:

float

Nbright4match

Use only Nbright brightest objects for matching to the ref cat

Type:

int

Nbright

Use only Nbright brightest objects in image that are matched to refcat for alignment

Type:

int

histocut_order

histocut_order defines whether the histogram cut is first done for dx or first for dy (choices are ‘dxdy’ or ‘dydx’)

Type:

str

xshift

added to the x coordinate before calculating ra,dec (only impacts ra,dec, not x). This can be used to correct for large shifts before matching!

Type:

float

yshift

added to the y coordinate before calculating ra,dec (only impacts ra,dec, not y). This can be used to correct for large shifts before matching!

Type:

float

iterate_with_xyshifts

After the first histogram fit, redo the match with refcat with x/yshift=median(dx/dy) and redo histofit. Use this if the offsets are big, since the second iteration will give you better matching with the refcat

Type:

bool

showplots

showplots=1: most important plots. showplots=2: all plots (debug/test/finetune)

Type:

int

saveplots

saveplots=1: most important plots. saveplots=2: all plots (debug/test/finetune)

Type:

int

savephottable

Save the final photometry table

Type:

bool

replace_sip

Replace the tweaked fits image wcs with the SIP representation.

Type:

bool

sip_err

max_pix_error for SIP transformation.

Type:

float

sip_degree

degree for SIP transformation.

Type:

int

sip_points

npoints for SIP transformation.

Type:

int

ee_radius

encircled energy percentage (multiples of 10) for photometry

Type:

int

rough_cut_px_min

first rough cut: best d_rotated+-rough_cut_pix. This is the lower limit for rough_cut

Type:

float

rough_cut_px_max

first rough cut: best d_rotated+-rough_cut_pix. This is the upper limit for rough_cut

Type:

float

d_rotated_Nsigma

Nsigma for sigma cut of d_rotated. If 0.0, then 3-sigma cut is skipped

Type:

float

set_telescope(telescope=None, imname=None)[source]

Figuring out which telescope your data come from (HST or JWST). Note that if your filename is non-standard, then you MUST set


simple_jwst_phot

Created on Wed Apr 27 09:21:15 2022

@author: arest, jpierel, mcorrenti

This is class wrapper around doing simple photometry on a single JWST image

class jhat.simple_jwst_phot.hst_photclass(psf_fwhm=2, aperture_radius=None, verbose=0)[source]

The photometry class for HST images.

aperture_phot(filt=None, pupil=None, radii_Nfwhm=None, radius_Nfwhm_sky_in=None, radius_Nfwhm_sky_out=None, radius_Nfwhm_for_mag=None, primaryhdr=None, scihdr=None)[source]

Aperture photometry routine for HST.

Returns:

table_aper

Return type:

astropy.table.Table

match_refcat(max_sep=1.0, borderpadding=40, refcatshort=None, ixs_obj=None, ixs_refcat=None)[source]

Matches the photometry catalog to the reference catalog.

Parameters:
  • max_sep (float) – Maximum separation between sources in arcseconds

  • borderpadding (float) – Pixel separation required from border of image

  • refcatshort (string, optional) – Short name of reference catalog that is used as prefix for the column names. The default is None. If None, then refcatshort is set to self.refcat.short

  • indices (list) – The indices to access the photometry catalog, default None (use the full catalog)

Return type:

None.

class jhat.simple_jwst_phot.jwst_photclass(verbose=0)[source]

The photometry class for JWST images.

aperture_phot(filt=None, pupil=None, radii_Nfwhm=None, radius_Nfwhm_sky_in=None, radius_Nfwhm_sky_out=None, radius_Nfwhm_for_mag=None, primaryhdr=None, scihdr=None)[source]

Aperture photometry routine for HST.

Returns:

table_aper

Return type:

astropy.table.Table

find_stars(threshold=3, var_bkg=False, primaryhdr=None, scihdr=None)[source]
Parameters:
  • threshold (float) – The absolute image value above which to select sources.

  • fwhm (float) – The full-width half-maximum (FWHM) of the major axis of the Gaussian kernel in units of pixels.

  • var_bkg (bool) – Use Background2D (see description above)

match_refcat(max_sep=1.0, borderpadding=40, refcatshort=None, ixs_obj=None, ixs_refcat=None)[source]

Matches the photometry catalog to the reference catalog.

Parameters:
  • max_sep (float) – Maximum separation between sources in arcseconds

  • borderpadding (float) – Pixel separation required from border of image

  • refcatshort (string, optional) – Short name of reference catalog that is used as prefix for the column names. The default is None. If None, then refcatshort is set to self.refcat.short

  • indices (list) – The indices to access the photometry catalog, default None (use the full catalog)

Return type:

None.


st_wcs_align_batch

Created on Mon Apr 25 09:39:07 2022

@author: arest


Citing JHAT

Please use the following bibcode citation for JHAT:

    @MISC{Rest2023_jhat,
   author = {{Rest}, Armin and {Pierel}, Justin and {Correnti}, Matteo and {Hilbert}, Bryan and {Canipe}, Alicia and {Sunnquist}, Ben and {Fox}, Ori,
    title = "{The JWST HST Alignment Tool (JHAT)}",
            howpublished = {Zenodo},
     year = 2023,
    month = may,
      eid = {10.5281/zenodo.7892935},
      doi = {10.5281/zenodo.7892935},
  version = {v2},
publisher = {Zenodo},
}

Primary Contributors

alternate text

Armin Rest

alternate text

Justin Pierel

alternate text

Matteo Correnti

alternate text

Alicia Canipe

alternate text

Bryan Hilbert

alternate text

Ben Sunnquist

API Documentation

Indices and tables