Aligning HST images to an Absolute Reference Catalog#

This notebook requires creating and activating a virtual environment using the requirements file in this notebook's repository. Please also review the README file before using the notebook.

Table of Contents#

Introduction
Import Packages

1. Download the Observations with astroquery
    1.1 Check image header data
    1.2 Inspect the alignment

2. Query the Reference Catalogs
    2.1 Identify Coordinates
    2.2 SDSS Query
    2.3 Gaia Query

3. Align images with TweakReg
    3.1 SDSS Alignment
    3.2 Inspect the shift file and fit residuals
    3.3 Gaia Alignment
    3.4 Inspect the shift file and fit residuals
    3.5 Overplot Matched Sources on the image
    3.6 Update header with optimal parameters

4. Combine the images using AstroDrizzle

Conclusions
About this Notebook

Introduction#

The alignment of HST exposures is a critical step in image stacking or combination performed with software such as AstroDrizzle. Generally, a relative alignment is performed to align one or multiple images to another image that is designated as the reference image. The reference image is generally the deepest exposure and/or that covering the largest area of all the exposures. This process aligns the images to each other, but the pointing error of the observatory can still cause the images to have incorrect absolute astrometry. When absolute astrometry is desired, the images can be aligned to an external catalog with an absolute world coordinate system (WCS). In this example, we will provide a workflow to query catalogs such as SDSS and Gaia using the astroquery package, and then align the images to that catalog using TweakReg.

The workflow in this notebook for aligning images to Gaia is based on WFC3 ISR 2017-19: Aligning HST Images to Gaia: a Faster Mosaicking Workflow and contains a subset of the information and code found in this repository. For more information, see the notebook in that repository titled Gaia_alignment.ipynb.

For more information about TweakReg, see the other notebooks in this repository or the TweakReg Documentation.

For more information on Astroquery, see the other notebooks in this repository or the Astroquery Documentation.

Import Packages#

Table of Contents


The following Python packages are required to run the Jupyter Notebook:

  • os - change and make directories

  • glob - gather lists of filenames

  • shutil - remove directories and files

  • numpy - math and array functions

  • matplotlib - make figures and graphics

  • astropy - file handling, tables, units, WCS, statistics

  • astroquery - download data and query databases

  • drizzlepac - align and combine HST images

import os
import glob
import shutil
import numpy as np
import matplotlib.pyplot as plt
from collections import defaultdict
from IPython.display import Image, clear_output
import astropy.units as u
from astropy.io import ascii, fits
from astropy.table import Table
from astropy.units import Quantity
from astropy.coordinates import SkyCoord
from astropy.visualization import ZScaleInterval
from astroquery.mast import Observations
from astroquery.sdss import SDSS
from astroquery.gaia import Gaia
from drizzlepac import tweakreg, astrodrizzle
from drizzlepac.processInput import getMdriztabPars

%config InlineBackend.figure_format = 'retina' # Improves the resolution of figures rendered in notebooks.
Gaia.MAIN_GAIA_TABLE = 'gaiadr3.gaia_source' # Change this to the desired Gaia data release.
Gaia.ROW_LIMIT = 100000 # Show all of the matched sources in the printed tables.

# Set the locations of reference files and retrieve the MDRIZTAB recommended drizzle parameters.
os.environ['CRDS_SERVER_URL'] = 'https://hst-crds.stsci.edu'
os.environ['CRDS_SERVER'] = 'https://hst-crds.stsci.edu'
os.environ['CRDS_PATH'] = './crds_cache'
os.environ['iref'] = './crds_cache/references/hst/wfc3/'

The following task in the stsci.skypac package can be run with TEAL:
                                    skymatch                                    
The following tasks in the drizzlepac package can be run with TEAL:
    astrodrizzle       config_testbed      imagefindpars           mapreg       
       photeq            pixreplace           pixtopix            pixtosky      
  refimagefindpars       resetbits          runastrodriz          skytopix      
     tweakback            tweakreg           updatenpol

1. Download the Observations with astroquery#

Table of Contents

For this notebook, we will download WFC3/UVIS images of NGC 6791 from program 12692 in the F606W filter acquired in Visit 01. The three FLC images have been processed by the HST WFC3 pipeline (calwf3), which includes bias subtraction, dark current and CTE correction, cosmic-ray rejection, and flat-fielding:

        ibwb01xqq_flc.fits
        ibwb01xrq_flc.fits
        ibwb01xxq_flc.fits

MAST queries may be done using query_criteria, where we specify:

    \(\rightarrow\) obs_id, proposal_id, and filters

MAST data products may be downloaded by using download_products, where we specify:

    \(\rightarrow\) products = calibrated (FLT, FLC) or drizzled (DRZ, DRC) files

    \(\rightarrow\) type = standard products (CALxxx) or advanced products (HAP-SVM)

Depending on your connection speed this cell may take a few minutes to execute.
obs_ids = ['ibwb01*']
props = ['12692']
filts = ['F606W']

obsTable = Observations.query_criteria(obs_id=obs_ids, proposal_id=props, filters=filts)
products = Observations.get_product_list(obsTable)

data_prod = ['FLC']    # ['FLC','FLT','DRC','DRZ']                  
data_type = ['CALWF3'] # ['CALACS','CALWF3','CALWP2','HAP-SVM']    

Observations.download_products(products, productSubGroupDescription=data_prod, project=data_type, cache=True)
Downloading URL https://mast.stsci.edu/api/v0.1/Download/file?uri=mast:HST/product/ibwb01xqq_flc.fits to ./mastDownload/HST/ibwb01xqq/ibwb01xqq_flc.fits ...
 [Done]
Downloading URL https://mast.stsci.edu/api/v0.1/Download/file?uri=mast:HST/product/ibwb01xrq_flc.fits to ./mastDownload/HST/ibwb01xrq/ibwb01xrq_flc.fits ...
 [Done]
Downloading URL https://mast.stsci.edu/api/v0.1/Download/file?uri=mast:HST/product/ibwb01xxq_flc.fits to ./mastDownload/HST/ibwb01xxq/ibwb01xxq_flc.fits ...
 [Done]
Table length=3
Local PathStatusMessageURL
str47str8objectobject
./mastDownload/HST/ibwb01xqq/ibwb01xqq_flc.fitsCOMPLETENoneNone
./mastDownload/HST/ibwb01xrq/ibwb01xrq_flc.fitsCOMPLETENoneNone
./mastDownload/HST/ibwb01xxq/ibwb01xxq_flc.fitsCOMPLETENoneNone

Move to the files to the local working directory:

for flc in glob.glob('./mastDownload/HST/*/*flc.fits'):
    flc_name = os.path.basename(flc)
    os.rename(flc, flc_name)
    
if os.path.exists('mastDownload'):
    shutil.rmtree('mastDownload')

1.1 Check image header data#

The cell below retrieves values for specific keywords from the first and second extensions of the image header. We see that the 1st exposure is 30 seconds and the 2nd and 3rd exposures are 360 seconds in duration. The 3rd exposure is dithered by approximately 82 arcseconds in the y-direction which is approximately the width of one WFC3 UVIS detector chip. A full list of header keywords is available in Section 2.4 of the WFC3 Data Handbook.

paths = sorted(glob.glob('*flc.fits'))
data = []
keywords_ext0 = ["ROOTNAME", "ASN_ID", "TARGNAME", "DETECTOR", "FILTER", "exptime", 
                 "ra_targ", "dec_targ", "postarg1", "postarg2", "DATE-OBS"]
keywords_ext1 = ["orientat"]

for path in paths:
    path_data = []
    for keyword in keywords_ext0:
        path_data.append(fits.getval(path, keyword, ext=0))
    for keyword in keywords_ext1:
        path_data.append(fits.getval(path, keyword, ext=1))
    data.append(path_data)
    
keywords = keywords_ext0 + keywords_ext1
table = Table(np.array(data), names=keywords, dtype=['str', 'str', 'str', 'str', 'str', 'f8', 'f8', 'f8', 'f8', 'f8', 'str', 'f8'])
table['exptime'].format = '7.1f'
table['ra_targ'].format = table['dec_targ'].format = '7.4f'
table['postarg1'].format = table['postarg2'].format = '7.3f'
table['orientat'].format = '7.2f'
table
Table length=3
ROOTNAMEASN_IDTARGNAMEDETECTORFILTERexptimera_targdec_targpostarg1postarg2DATE-OBSorientat
str32str32str32str32str32float64float64float64float64float64str32float64
ibwb01xqqNONENGC-6791UVISF606W30.0290.224837.80270.0000.0002011-10-20-56.27
ibwb01xrqNONENGC-6791UVISF606W360.0290.224837.80270.0000.0002011-10-20-56.27
ibwb01xxqNONENGC-6791UVISF606W360.0290.224837.80270.00081.6002011-10-20-56.25

1.2 Inspect the Alignment#

Check the active WCS solution in the image header. If the image is aligned to a catalog, the list the number of matches and the fit RMS in milli-arcseconds. Next, convert the fit RMS values to pixels for comparison with the alignment results performed later in this notebook using Tweakreg.

ext_0_keywords = ['DETECTOR', 'EXPTIME'] # extension 0 keywords.
ext_1_keywords = ['WCSNAME', 'NMATCHES', 'RMS_RA', 'RMS_DEC'] # extension 1 keywords.

# Define the detector plate scales in arcsec per pixel.
DETECTOR_SCALES = {
  'IR': 0.1283, 
  'UVIS': 0.0396, 
  'WFC': 0.05
}

formatted_data = {}
column_data = defaultdict(list)

for fits_file in sorted(glob.glob('*flc.fits')):
    column_data['filename'].append(fits_file)
    header0 = fits.getheader(fits_file, 0)
    header1 = fits.getheader(fits_file, 1)
    
    for keyword in ext_0_keywords:
        column_data[keyword].append(header0[keyword])
    for keyword in ext_1_keywords:
        if 'RMS' in keyword:
            value = np.around(header1[keyword], decimals=1)
        else:
            value = header1[keyword]
        column_data[keyword].append(value)
            
    for keyword in ['RMS_RA', 'RMS_DEC']:
        rms_value = header1[keyword] / 1000 / DETECTOR_SCALES[header0['DETECTOR']]
        column_data[f'{keyword}_pix'].append(np.round(rms_value, decimals=2))

wcstable = Table(column_data)
wcstable
Table length=3
filenameDETECTOREXPTIMEWCSNAMENMATCHESRMS_RARMS_DECRMS_RA_pixRMS_DEC_pix
str18str4float64str30int64float64float64float64float64
ibwb01xqq_flc.fitsUVIS30.0IDC_2731450pi-FIT_IMG_GAIAeDR34421.31.50.030.04
ibwb01xrq_flc.fitsUVIS360.0IDC_2731450pi-FIT_IMG_GAIAeDR34624.03.80.10.1
ibwb01xxq_flc.fitsUVIS360.0IDC_2731450pi-FIT_IMG_GAIAeDR34293.93.70.10.09

2. Query the Reference Catalogs#

Table of Contents

Now that we have the FITS images, we will download the reference catalogs from both SDSS and Gaia using astroquery.

2.1 Identify Coordinates#

We will first create a SkyCoord Object to point astroquery to where we are looking on the sky. Since our example uses data from NGC 6791, we will use the ra_targ and dec_targ keywords from the first image to get the coordinates of the object.

RA = table['ra_targ'][0]
Dec = table['dec_targ'][0]

2.2 SDSS Query#

We now give the RA and Dec values to an astropy SkyCoord object, which we will pass to the SDSS query. Additionally, we use an astropy Quantity object to create a radius for the SDSS query in physical units. We set the radius to 5 arcminutes to comfortably cover the area of our images. For reference, the UVIS detector field of view is approximately 2.7’\(\times\)2.7’ and a y-dither of 82 arcseconds covers a total area on the sky of approximately 2.7’\(\times\)4.1’.

coord = SkyCoord(ra=RA, dec=Dec, unit=(u.deg, u.deg))
radius = Quantity(3., u.arcmin)

Next, we perform the query via the SDSS.query_region method of astroquery.sdss. The spectro=False keyword argument means we want to exclude spectroscopic objects, as we are looking for objects to match with an image. In the fields parameter, we specify a list of fields we want returned by the query. In this case we only need the position, as well as a g-band magnitude if we want to remove very dim and/or bright objects from the catalog, as those are likely measured poorly. Details on selecting objects by magnitude may be found in the ‘Gaia_alignment’ notebook. Many other fields are available in the SDSS query and are documented on this webpage.

sdss_query = SDSS.query_region(coord, radius=radius, spectro=False, fields=['ra', 'dec', 'g'])
sdss_query
Table length=2140
radecg
float64float64float64
290.17525748330637.775702374262919.10387
290.17526027081637.8293581828758-9999.0
290.17526844129637.775707693253118.98614
290.17530712163237.754876031386719.49425
290.17531755653737.829330802868618.26527
290.17531878487237.8293349727083-9999.0
290.17532068669837.754874661917319.7736
290.17532812575537.762593621772919.44313
290.17533315201537.829327081247718.38934
.........
290.27470363270837.787787783515518.8502
290.27470460318837.789114106455818.63407
290.27472136138937.787773766692819.01597
290.2747293008837.789065709345118.74797
290.27479478394837.799379749313116.67577
290.27480089191437.799393828457416.11324
290.27480758871537.79939257729116.08992
290.27481515297637.799373630825516.13595
290.2748239154337.799375714545816.16263
290.27483970519237.842349565367820.26493

We then need to save the catalog to use with TweakReg. As the returned value of the query is an astropy.Table, saving the file is straightforward:

sdss_query.write('sdss.cat', format='ascii.commented_header', overwrite=True)

2.3 Gaia Query#

Similarly to SDSS, we can query Gaia catalogs for our target via astroquery.gaia. This may be preferable in many cases because the spaced-based astrometry from Gaia is generally very accurate and precise. We can use the same coord and radius search parameters from our earlier SDSS query.

gaia_query = Gaia.query_object_async(coordinate=coord, radius=radius)
gaia_query
INFO: Query finished. [astroquery.utils.tap.core]
Table length=2331
solution_idDESIGNATIONSOURCE_IDrandom_indexref_epochrara_errordecdec_errorparallaxparallax_errorparallax_over_errorpmpmrapmra_errorpmdecpmdec_errorra_dec_corrra_parallax_corrra_pmra_corrra_pmdec_corrdec_parallax_corrdec_pmra_corrdec_pmdec_corrparallax_pmra_corrparallax_pmdec_corrpmra_pmdec_corrastrometric_n_obs_alastrometric_n_obs_acastrometric_n_good_obs_alastrometric_n_bad_obs_alastrometric_gof_alastrometric_chi2_alastrometric_excess_noiseastrometric_excess_noise_sigastrometric_params_solvedastrometric_primary_flagnu_eff_used_in_astrometrypseudocolourpseudocolour_errorra_pseudocolour_corrdec_pseudocolour_corrparallax_pseudocolour_corrpmra_pseudocolour_corrpmdec_pseudocolour_corrastrometric_matched_transitsvisibility_periods_usedastrometric_sigma5d_maxmatched_transitsnew_matched_transitsmatched_transits_removedipd_gof_harmonic_amplitudeipd_gof_harmonic_phaseipd_frac_multi_peakipd_frac_odd_winruwescan_direction_strength_k1scan_direction_strength_k2scan_direction_strength_k3scan_direction_strength_k4scan_direction_mean_k1scan_direction_mean_k2scan_direction_mean_k3scan_direction_mean_k4duplicated_sourcephot_g_n_obsphot_g_mean_fluxphot_g_mean_flux_errorphot_g_mean_flux_over_errorphot_g_mean_magphot_bp_n_obsphot_bp_mean_fluxphot_bp_mean_flux_errorphot_bp_mean_flux_over_errorphot_bp_mean_magphot_rp_n_obsphot_rp_mean_fluxphot_rp_mean_flux_errorphot_rp_mean_flux_over_errorphot_rp_mean_magphot_bp_rp_excess_factorphot_bp_n_contaminated_transitsphot_bp_n_blended_transitsphot_rp_n_contaminated_transitsphot_rp_n_blended_transitsphot_proc_modebp_rpbp_gg_rpradial_velocityradial_velocity_errorrv_method_usedrv_nb_transitsrv_nb_deblended_transitsrv_visibility_periods_usedrv_expected_sig_to_noiserv_renormalised_gofrv_chisq_pvaluerv_time_durationrv_amplitude_robustrv_template_teffrv_template_loggrv_template_fe_hrv_atm_param_originvbroadvbroad_errorvbroad_nb_transitsgrvs_maggrvs_mag_errorgrvs_mag_nb_transitsrvs_spec_sig_to_noisephot_variable_flaglbecl_lonecl_latin_qso_candidatesin_galaxy_candidatesnon_single_starhas_xp_continuoushas_xp_sampledhas_rvshas_epoch_photometryhas_epoch_rvhas_mcmc_gspphothas_mcmc_mscin_andromeda_surveyclassprob_dsc_combmod_quasarclassprob_dsc_combmod_galaxyclassprob_dsc_combmod_starteff_gspphotteff_gspphot_lowerteff_gspphot_upperlogg_gspphotlogg_gspphot_lowerlogg_gspphot_uppermh_gspphotmh_gspphot_lowermh_gspphot_upperdistance_gspphotdistance_gspphot_lowerdistance_gspphot_upperazero_gspphotazero_gspphot_lowerazero_gspphot_upperag_gspphotag_gspphot_lowerag_gspphot_upperebpminrp_gspphotebpminrp_gspphot_lowerebpminrp_gspphot_upperlibname_gspphotdist
yrdegmasdegmasmasmasmas / yrmas / yrmas / yrmas / yrmas / yrmas1 / um1 / um1 / ummasdegdegdegdegdegelectron / selectron / smagelectron / selectron / smagelectron / selectron / smagmagmagmagkm / skm / sdkm / sKlog(cm.s**-2)dexkm / skm / smagmagdegdegdegdegKKKlog(cm.s**-2)log(cm.s**-2)log(cm.s**-2)dexdexdexpcpcpcmagmagmagmagmagmagmagmagmag
int64objectint64int64float64float64float32float64float32float64float32float32float32float64float32float64float32float32float32float32float32float32float32float32float32float32float32int16int16int16int16float32float32float32float32int16boolfloat32float32float32float32float32float32float32float32int16int16float32int16int16int16float32float32int16int16float32float32float32float32float32float32float32float32float32boolint16float64float32float32float32int16float64float32float32float32int16float64float32float32float32float32int16int16int16int16int16float32float32float32float32float32int16int16int16int16float32float32float32float32float32float32float32float32int16float32float32int16float32float32int16float32objectfloat64float64float64float64boolboolint16boolboolboolboolboolboolboolboolfloat32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32objectfloat64
1636148068921376768Gaia DR3 2051293319932402944205129331993240294417104148122016.0290.22486113562830.1234355137.801929503613590.155340691.24091546330640860.159768727.76694876.0644784-0.62265434076184740.154743726.03242907928795450.18924683-0.0330014680.16417459-0.027278472-0.0201708860.07942047-0.046242356-0.19703287-0.076851850.00517138930.050814763394038950.407836413.483030.02.0511602e-1531False1.3016587--------------45260.26493552492200.0189501614.319122001.01388040.175694810.202403290.102880320.089386284-95.1318277.093792.6807811-30.180996False385492.167884547433860.9903239496.9766818.95708339106.264534883216615.385507619.73157320.27257239549.19942951062547.085240477.5131717.8985711.3317894020202.37400051.31548881.0585117--------------------------------------------NOT_AVAILABLE69.9876189105112910.914199739506339302.0419657477765459.01190915812673FalseFalse0FalseFalseFalseFalseFalseTrueFalseFalse1.4003378e-135.356044e-130.999967753653.5923591.57523744.39924.85524.49924.9965-0.4967-0.7199-0.1315653.0443491.94811283.51120.78120.64990.92020.53050.440.62660.31020.25810.3649MARCS0.0007449136479797354
1636148068921376768Gaia DR3 205129332421826380820512933242182638082149749782016.0290.223279727540841.049147237.802839447959031.4068799-0.60690774600642671.4172788-0.428220453.8347042-0.496949943918527371.433404-3.8023671866937022.183717-0.325595260.440830080.040013984-0.36232764-0.18673699-0.298557550.51452190.16053891-0.3253903-0.32209665133013212.3624072187.533173.49461981.735654495False--1.25838210.3532982-0.10796609-0.06725511-0.030691369-0.22952616-0.1275772916143.268870618610.06122743743.2264185171.14967740.235481130.32430920.357489230.4221966-95.1267274.99657-8.526287-16.614477False13288.73757662943781.199292273.9916220.8170990--------0------------------0--------------------------------------------------NOT_AVAILABLE69.987894390365210.915721621139165302.040099004613159.01311977354264FalseFalse0FalseFalseFalseFalseFalseFalseFalseFalse7.759076e-083.7895185e-090.9999943------------------------------------------0.0012108975043825237
1636148068921376768Gaia DR3 205129332422297228820512933242229722881644563802016.0290.222619948805970.03284164537.802707524747090.0394590.30530948963652580.0411276977.4234522.5961652-0.70126232753246160.041221105-2.49966104338574050.047550496-0.0475552980.165465030.021742897-0.0778674560.066915035-0.08765522-0.26260835-0.059347805-0.087691456-0.001331030738303812-2.1703348333.383270.00.031False1.4413656--------------44250.06704042482100.01503751812.04822000.92104670.138905180.189018130.109005130.0641752-88.3616572.3029565.923747-33.787945False3814179.2546590772062.25175741855.996816.63462431717.78303874708586.2028065276.9364317.251122393494.120407965024210.008291349.122615.8895511.247089302502301.36157040.616500850.7450695--------------------------------------------NOT_AVAILABLE69.9875410099388210.916132432650413302.039054790094259.01313187059839FalseFalse0TrueFalseFalseFalseFalseTrueTrueFalse1.0228448e-139.3310026e-110.99997414770.34474749.60454790.8184.17764.15964.19020.35460.32680.38052185.93162147.36252239.19260.35110.32590.37350.27010.25050.28750.14060.13030.1496PHOENIX0.001721026645501702
1636148068921376768Gaia DR3 2051293324222972416205129332422297241615999055882016.0290.22483097015550.05294129637.800586114058950.0648960550.218370438246445250.0670577663.25645262.3448853-0.58272005397828510.066188715-2.27132660016116360.0787358-0.0768301040.14136231-0.025055349-0.072975410.056257915-0.07904705-0.24559797-0.07446872-0.087429665-0.0335280339503923-0.037620842401.514340.00.031False1.4891585--------------45250.110738866492200.015343606515.8542000.997787240.152932750.214773120.129280220.08397196-94.64999470.080226.0968003-29.722376False3891751.03660763972771.49502251171.244317.57912846817.00652343411046.4622293126.4279718.057978441347.1552304503578.58573156.9063316.924351.235931803202901.13362690.47884940.6547775--------------------------------------------NOT_AVAILABLE69.9863784534824610.913632562752337302.041224263599659.01062093567249FalseFalse0TrueFalseFalseFalseFalseTrueTrueFalse6.110852e-115.145215e-130.99991324831.9014812.9594859.144.6614.64124.6768-0.4447-0.5218-0.37861595.51841545.62231641.48860.00870.00210.0210.00690.00170.01660.00360.00090.0088PHOENIX0.0020867793124382814
1636148068921376768Gaia DR3 205129331993479193620512933199347919361277407952016.0290.22256026388090.09856778437.803978470044570.122381570.186089237607969780.126199871.47455972.3556678-0.205917660343796220.12384657-2.3466506380483370.14836667-0.00343720640.17569284-0.028029243-0.0236887970.0831415-0.04713238-0.21456409-0.08000817-0.0190065170.07798844386038330.34466058403.298740.00.031False1.4745288--------------44260.20897423482100.0252598416.266506001.0116760.164512680.1805770.0794067760.08114059-89.37092680.655790.7836158-30.156015False377665.16671859144721.124127591.7184418.63004140296.016045706441965.845524350.6397819.16025441517.31486865230936.127615584.4235217.9635091.2227474000001.19674490.53021240.6665325--------------------------------------------NOT_AVAILABLE69.9886834952528110.916731652994313302.0396258357147359.014369244472704FalseFalse0FalseFalseFalseFalseFalseTrueFalseFalse1.0210282e-135.259736e-130.999994754590.27834575.7664603.02444.82554.79814.858-1.2317-1.4162-1.10091664.28761569.11961730.9150.01020.00260.02570.0080.0020.020.00430.00110.0107PHOENIX0.0021977590777958536
1636148068921376768Gaia DR3 205129332421654323220512933242165432324969746282016.0290.226819596871960.580043437.801127727705170.85181140.98661196885736370.84873931.1624444.5651155-0.442437662624050151.042491-4.5436251700190051.2715639-0.03034182-0.130354290.099056150.024711896-0.035745695-0.130549790.34666777-0.069062054-0.28526154-0.107861118901890-0.84486425177.74490.01.4856265e-1595False--1.55213480.21582161-0.00621337680.28042490.035700142-0.421011060.1781859222151.815063425800.02325232930.515776000.9543710.208770540.288419070.19270840.43569437-76.916684.362335-3.7503886-19.752798False189100.173459526538440.81711596122.5939320.6854861634.7777430671914948.3456144.167187721.4852891989.512291396926145.523087516.2069319.8681891.2407482000001.61709980.79980280.817297--------------------------------------------NOT_AVAILABLE69.9875754334518210.912457430119012302.044446154287159.01072318960171FalseFalse0FalseFalseFalseFalseFalseFalseFalseFalse1.5372552e-091.1275478e-090.99999505------------------------------------------0.002222460820739603
1636148068921376768Gaia DR3 2051293324222974464205129332422297446417984361052016.0290.22752493081420.2407992537.8034727751390350.30747050.445066524419969630.31342351.42001641.903844-0.77414992477356190.3071843-1.73934298252762920.374548080.0204875150.17073557-0.0363375430.0416509140.12431544-0.0061035734-0.18864702-0.065493080.0605290680.123350315382038020.5945536412.031980.90154610.957877495False--1.31476190.081987195-0.0167665020.1181909740.037860535-0.0898746-0.1086104344250.52942884482100.02776220820.245789041.020920.184008080.17896370.0736982750.10250232-90.67370685.22672-9.854181-30.444962False380207.208736176724160.7419642279.270519.896347991.399500159475617.501483412.1841920.4361829224.2019002106420411.06425320.26362818.8712981.5231086000001.56488420.5398351.0250492--------------------------------------------NOT_AVAILABLE69.9899708940742310.912983986333725302.0467059052208559.01283416072846FalseFalse0FalseFalseFalseFalseFalseFalseFalseFalse1.8206678e-092.9034798e-080.99998796------------------------------------------0.002298594469020544
1636148068921376768Gaia DR3 2051293324216539648205129332421653964816494576092016.0290.22423204098210.527127437.800395107394630.766553341.36327565842414340.67285462.02610732.2253373-0.97086458829061460.6578662-2.00238563025194070.98862535-0.334653530.08556003-0.27351620.26027030.1616140.21899539-0.265428070.0335000120.1458301-0.23663591243024301.2024069273.663820.00.095False--1.68184630.19114311-0.260752350.11348202-0.08333635-0.06321393-0.1521266128181.4304484321410.070790234.3759540151.05430190.245606850.44389820.229683370.165783-110.2577667.430465.994361-23.29821False244109.85521560273350.8030061136.8049620.5853160--------0------------------2--------------------------------------------------NOT_AVAILABLE69.9859924248062710.91397427439119302.040239437952359.01056325889003FalseFalse0FalseFalseFalseFalseFalseFalseFalseFalse------------------------------------------------0.0023210548670645637
1636148068921376768Gaia DR3 205129332422533606420512933242253360643980909602016.0290.223029396664630.4765001837.80034041154940.571635841.04655396175326130.605739831.72772840.34264810.0165256796874195530.6219764-0.342249354474437440.7205138-0.113586160.15291650.07183364-0.1044668260.054135017-0.07860708-0.17583270.10776901-0.16631071-0.164722253730365886.8070312487.4786.598426424.326495False--1.29765440.14454299-0.0576655570.0526744050.0332027340.010857275-0.0792269743251.0361372505000.1981419321.4078086305.61499450.16931350.215803350.101834080.09376588-92.0437770.390440.82470447-23.783632False298836.2066294848865.043918165.7851418.38158243492.858050365895965.083862396.94559518.60673741916.84299006550376.7629867135.5677617.3421571.6858286020201.26457980.225154881.0394249--------------------------------------------NOT_AVAILABLE69.9855183318727510.914804515213548302.038432481796159.01076433315906FalseFalse0FalseFalseFalseFalseFalseFalseFalseFalse9.514203e-111.056036e-050.99998164------------------------------------------0.0027187891427339723
...........................................................................................................................................................................................................................................................................................................................................................................................................................................................................
1636148068921376768Gaia DR3 2051288101537870720205128810153787072014760969012016.0290.16549518385550.0482145237.785447637869870.0576339740.225037240939968130.0606965723.70757752.275607-0.406494637490741660.060702868-2.23900653311607730.069002240.0123343220.13113154-0.11899681-0.0199619890.14481837-0.038124166-0.29374352-0.14935088-0.112530250.0707716441904190-0.67899024410.350370.00.031False1.504531--------------48270.09853348492300.01999590515.846279000.97569780.155984940.121216810.090789510.13566518-107.6315479.535222.3636649-34.418354False4171993.71565776291071.43942381385.07917.4382140950.04588058638586.864714138.3955517.89418391436.02707118447625.677532252.9315616.8549881.196797000101.03919220.455970760.58322144--------------------------------------------NOT_AVAILABLE69.9516043802159810.949157081403966301.9456163949144559.0085358362026FalseFalse0TrueFalseFalseFalseFalseTrueTrueFalse1.0226445e-135.119075e-130.99997635141.58745123.63335158.20564.63264.61944.6433-0.1554-0.2038-0.11211939.211896.90011979.40120.00370.00090.01070.0030.00070.00860.00160.00030.0045PHOENIX0.04992738302391301
1636148068921376768Gaia DR3 205110537645150579220511053764515057928833224662016.0290.257022211637550.1890509437.759722046770770.2666551-0.0399597024672329050.25163692-0.158799042.4071147-0.491445326129921030.24496886-2.35641321655535570.344565750.126976520.14626107-0.19946665-0.04836270.07724031-0.09694064-0.30264643-0.123869210.128719550.22539671336033420.6659974366.435850.538702550.502320895False--1.31679610.06423852-0.0426506960.0161977630.06316402-0.07971905-0.02667346840240.49691302442100.0465288111.265161061.02509030.213100790.286775470.154629080.17873366-106.79698-85.40637-17.572538-26.361528False332290.821825381076340.9811591296.406419.528330191.564207027824187.965888524.04806519.63275730383.742788465535810.283154537.31761618.2877941.978211203003001.34496310.1044578551.2405052--------------------------------------------NOT_AVAILABLE69.9603328723665510.87285183333383302.0676274347689558.96444565627617FalseFalse0FalseFalseFalseFalseFalseFalseFalseFalse1.600451e-096.6841253e-060.9999911------------------------------------------0.04993419538093678
1636148068921376768Gaia DR3 205110571575459353620511057157545935363676490892016.0290.2808046202360.1449245737.7795469166410950.179634230.214689768299775650.189640181.13209017.283765-1.54591991327724140.18082064-7.1178202618136460.2268990.08210180.19335385-0.19755834-0.00732534660.17681892-0.059489112-0.13821003-0.101814020.087074090.12708417339033810.13918142351.195040.00.095False--1.39655030.052453425-0.215976280.046664923-0.146946940.0073276316-0.1084316140250.3193467441800.0257379583.3489754001.00440050.289543540.217890460.101684180.21477832-101.08861-86.16012-9.762876-25.57112False339447.77022961115910.9872021453.5750419.05972940189.715978411171084.77862839.7009319.64328240375.79942488428815.954777763.1088918.3105051.2629589020101.3327770.58355330.7492237--------------------------------------------NOT_AVAILABLE69.9868707375873510.864652528833176302.113052727851658.97852325474902FalseFalse0FalseFalseFalseFalseFalseFalseFalseFalse9.687291e-112.1935703e-100.9999868------------------------------------------0.049937021935667826
1636148068921376768Gaia DR3 205110534209172915220511053420917291529872084622016.0290.24983428483160.1831187537.75681540801750.239199710.332646409614890670.240938831.3806266.841415-3.0395078366690350.23630942-6.12913946837960650.290520940.066486030.18299167-0.13769636-0.059145480.17252389-0.109444715-0.24172258-0.127430720.029753340.1879744378037710.6412554409.29340.00.031False1.5193098--------------44260.4198297472200.0369631727.785712001.02269850.207776190.222007990.127044320.11301937-103.070724-89.776115-15.491943-22.853712False364274.335057197294130.83240443329.5694319.59166320108.427932691982758.140017513.32035620.25068922229.263469469487667.030934332.60782218.847061.2309451000001.40362930.65902520.7446041--------------------------------------------NOT_AVAILABLE69.9551353103771410.876684519101982302.05550000279658.96316234659864FalseFalse0FalseFalseFalseFalseFalseFalseFalseFalse7.055214e-102.4849628e-100.9999974------------------------------------------0.049944646819559776
1636148068921376768Gaia DR3 205129459552863180820512945955286318081327429562016.0290.201596053239260.3187812637.8491395045859560.4108245-0.123915657769207350.4221808-0.293513243.416373-1.24413563337352050.42176288-3.18178100793894370.5004318-0.050365023-0.0008751949-0.171131450.0524337960.131542440.061325245-0.267767820.0703754-0.04012821-0.025681598349034722.601649440.676971.6417072.090848431False1.4571096--------------41240.7057606432100.01886618931.54997001.10010170.24072120.190150620.132489680.1401775-98.9532679.32095-10.734245-22.811646False346162.806300294100340.72370195224.963220.158194088.099421093570754.830718518.23733320.4761139109.633411090580995.663702519.35719919.6480391.2145281000000.82807160.317920680.5101509--------------------------------------------NOT_AVAILABLE70.0226470645821210.951397166233019302.032058261972459.06231257269266FalseFalse0FalseFalseFalseFalseFalseFalseFalseFalse1.8466157e-087.57946e-100.99999225------------------------------------------0.04995017327286985
1636148068921376768Gaia DR3 2051293564734766208205129356473476620811408363952016.0290.2846112152410.1984680937.8189289559597550.258277770.424375177503089060.260234531.63074122.672299-0.368370911181140740.25271687-2.6467874490874770.315719780.0226318110.07644129-0.0386861-0.0274652780.08704854-0.076738395-0.2122061-0.0116577350.073291190.13596117373037120.69725716399.00920.505643370.408365695False--1.45072540.06923322-0.0947986250.12845540.025951082-0.15272623-0.0750119745260.448276492100.0034285483126.74221001.02499640.22425970.19244020.07091990.12980221-98.0092489.90393-16.552565-28.187826False375265.74689470918630.9801038271.1415719.62619619186.7240835547094717.8482810.46174119.66054217322.696542761022418.0070417.92057618.475911.9169391020001.18463130.0343456271.1502857--------------------------------------------NOT_AVAILABLE70.024252084794910.879224379025027302.1391473651770559.01566265745925FalseFalse0FalseFalseFalseFalseFalseFalseFalseFalse2.237545e-091.1975736e-050.999988------------------------------------------0.04997304885611112
1636148068921376768Gaia DR3 205129356044021977620512935604402197764684068162016.0290.28247640036520.067095237.823196701588570.087905150.196099726363975680.088092792.22605872.2592366-0.35040446862828360.08420435-2.23189760448859160.10411392-0.02778220.11649344-0.0013309642-0.00266639470.041511085-0.01673569-0.2758432-0.04604975-0.0346640870.02519941740104001-0.95538807383.926570.00.031False1.495298--------------46270.1470113512200.017714818.017093000.9653680.239837150.213790920.0572092570.11334882-95.9932184.87185-0.7996727-28.648691False4061125.7896951764691.2112837929.418718.05872345517.73988089630945.84148588.6315518.55326344810.51519000444477.3433576110.37392417.4759921.179843010001.07727050.494539260.58273125--------------------------------------------NOT_AVAILABLE70.027404486768110.882611695924751302.138212029756559.02022616662701FalseFalse0FalseFalseFalseFalseFalseTrueTrueFalse1.0224728e-135.244856e-130.9999795021.6584976.74275065.8754.66564.63084.6852-0.2925-0.4153-0.17542265.63062154.79272422.62080.00690.00170.01760.00550.00130.01410.00290.00070.0075PHOENIX0.04997598495418403
1636148068921376768Gaia DR3 205110588756193152020511058875619315204892972152016.0290.287719822162560.1798201837.797530573830140.22851922-0.276370328673275770.23563609-1.17286922.7092662-0.81064798901834710.23371251-2.58514469035561230.293446750.16372470.2333921-0.052740883-0.00143093190.17818415-0.04178299-0.16686740.0306603240.12771360.24382767360035910.45686695382.514770.00.031False1.4419978--------------42260.42486578461900.02402876119.193428001.01627230.230088260.2138760.093165410.14170524-89.87326-80.582855-20.517448-27.920107False364312.15781486530120.8630008361.7120719.45143143106.710677357382955.866486518.18987820.26802342250.006030328899988.70252728.72798218.753021.1427448010101.51500320.816591260.69841194--------------------------------------------NOT_AVAILABLE70.0057677699002510.867630795568862302.132613996214358.99438818311647FalseFalse0FalseFalseFalseFalseFalseFalseFalseFalse3.923956e-106.2316663e-100.9999929------------------------------------------0.04998339321858548
1636148068921376768Gaia DR3 205110537645153408020511053764515340803490057852016.0290.26203068615850.2134581737.762256377555390.284136980.3048471553985990.279891521.08916182.7098396-0.144494937142684580.27666575-2.70598440598217850.34065380.1112984050.07204159-0.12538862-0.0552073420.13312708-0.1043947-0.21191615-0.169841960.0554609370.213843934803444-0.37459254341.677220.00.095False--1.44680510.07294632-0.0622924640.067121990.040067807-0.10036108-0.0895837441250.49400654441900.0245677833.541193100.984645960.25421770.22835790.126112420.1156371-111.30088-87.94184-12.496002-21.521162False334235.456632599911870.7688483306.245919.757593685.926251067575756.026134514.25893320.50322735175.133212534436845.921056329.57803519.1394751.1087369010001.36375240.74563790.6181145--------------------------------------------NOT_AVAILABLE69.964420327556610.870404794991602302.076341691821858.96583000941361FalseFalse0FalseFalseFalseFalseFalseFalseFalseFalse3.0029546e-107.6057516e-100.9999992------------------------------------------0.04999419931408359

This query has returned very large number of columns, so we select the most useful columns to make the catalog easier to use with TweakReg.

reduced_query = gaia_query['ra', 'dec', 'phot_g_mean_mag']
reduced_query
Table length=2331
radecphot_g_mean_mag
degdegmag
float64float64float32
290.224861135628337.8019295036135918.957083
290.2232797275408437.8028394479590320.817099
290.2226199488059737.8027075247470916.63462
290.224830970155537.8005861140589517.579128
290.222560263880937.8039784700445718.630041
290.2268195968719637.8011277277051720.685486
290.227524930814237.80347277513903519.896347
290.224232040982137.8003951073946320.585316
290.2230293966646337.800340411549418.381582
.........
290.165495183855537.7854476378698717.43821
290.2570222116375537.7597220467707719.5283
290.28080462023637.77954691664109519.059729
290.249834284831637.756815408017519.591663
290.2015960532392637.84913950458595620.15819
290.28461121524137.81892895595975519.626196
290.282476400365237.8231967015885718.058723
290.2877198221625637.7975305738301419.451431
290.262030686158537.7622563775553919.75759

Then we write this catalog to an ascii file for use with TweakReg.

reduced_query.write('gaia.cat', format='ascii.commented_header', overwrite=True)

3. Align with TweakReg#

Table of Contents

With the catalogs downloaded and the headers populated, we now need to run TweakReg with each catalog passed into the refcat parameter. The steps below compare the astrometric residuals obtained from aligning to each refcat. In each case, we set the updatehdr parameter to False to avoid altering the WCS of the images until we are satisfied with the alignment by inspecting both the TweakReg shift file and the astrometric residual plots.

3.1 SDSS Alignment#

refcat = 'sdss.cat'
wcsname = 'SDSS' # Specify the WCS name for this alignment.
cw = 3.5         # 2x the FWHM of the PSF = 3.5 pixels for ACS/WFC, WFC3/UVIS or 2.5 for WFC3/IR.

tweakreg.TweakReg('*flc.fits', # Pass the input images to tweakreg.
                  imagefindcfg={'threshold': 500., 'conv_width': cw},  # Detection parameters that vary for different datasets.
                  refcat=refcat,                # Use user supplied catalog (Gaia).
                  interactive=False,            # Don't show the interactive interface.
                  see2dplot=False,              # Suppress additional figures in this test.
                  shiftfile=True,               # Save output shift file to examine shifts later.
                  outshifts='SDSS_shifts.txt',  # Name of the shift file that will be saved.
                  wcsname=wcsname,              # Give our WCS a new name defined above.
                  reusename=True,               # Overwrite the WCS if it exists.
                  ylimit=1.5,
                  fitgeometry='rscale',         # Allow for translation, rotation, and plate scaling.
                  updatehdr=False)              # Don't update the header with new WCS until later.
clear_output()
../../../_images/6dca7e7a672cbe89c59d1e7549416314e1b7f9d7ac8b6f7299c46db51ea1745d.png ../../../_images/b751f05d254e4bcfc3dac94dadd3b8f72ee98df14dfe0f3e5626d6e218808e1d.png
# If the alignment is unsuccessful then stop the notebook.

with open('SDSS_shifts.txt', 'r') as shift:
    for line_number, line in enumerate(shift, start=1):
        if "nan" in line:
            raise ValueError('nan found in line {} in shift file'.format(line_number))
        else:
            continue

3.2 Inspect the shift file and fit residuals#

We can look at the shift file to see how well the fit did (or we could open the output png images for more information). The columns are:

  • Filename, X Shift [pixels], Y Shift [pixels], Rotation [degrees], Scale, X RMS [pixels], Y RMS [pixels]

shift_table = Table.read('SDSS_shifts.txt',
                         format='ascii.no_header', 
                         names=['file', 'dx', 'dy', 'rot', 'scale', 'xrms', 'yrms'])

formats = ['.2f', '.2f', '.3f', '.5f', '.2f', '.2f']
for i, col in enumerate(shift_table.colnames[1:]):
    shift_table[col].format = formats[i]
shift_table
Table length=3
filedxdyrotscalexrmsyrms
str18float64float64float64float64float64float64
ibwb01xqq_flc.fits1.470.690.0030.999930.370.34
ibwb01xxq_flc.fits1.57-0.14360.0001.000100.380.54
ibwb01xrq_flc.fits1.480.560.0020.999950.370.36

Show the astrometric residual plots.

Image(filename='residuals_ibwb01xqq_flc.png', width=500, height=300)
../../../_images/475a48013a8a09241ed9c3d58f029eec7164df8936a3ba12b6a2e1f5d93ae980.png
Image(filename='residuals_ibwb01xrq_flc.png', width=500, height=300)
../../../_images/9d0bfcf6c13b789289911febe9abea6ff17d67fb967f0488ce0694dc2c8bffcf.png
Image(filename='residuals_ibwb01xxq_flc.png', width=500, height=300)
../../../_images/e3c953fc317016e91f3eea1eaa2dca9f4c41ed44ae07fc54405d0547a6224710.png

We can see in the plots above that the RMS is fairly large at about 0.5 pixels. This is generally considered a poor fit, with the desired RMS being < 0.1 pixels depending on the number of sources. This is likely because the SDSS astrometric precision is insufficient for a high-quality HST alignment. One approach would be to align the first image to SDSS and then align the remaining HST images to one another. This would improve both the absolute and relative alignment of the individual frames.

3.3 Gaia Alignment#

refcat = 'gaia.cat'
wcsname = 'Gaia' # Specify the WCS name for this alignment.
cw = 3.5         # 2x the FWHM of the PSF = 3.5 pixels for ACS/WFC, WFC3/UVIS or 2.5 for WFC3/IR.

tweakreg.TweakReg('*flc.fits', # Pass the input images to tweakreg.
                  imagefindcfg={'threshold': 500., 'conv_width': cw},  # Detection parameters that vary for different datasets.
                  refcat=refcat,                # Use user supplied catalog (Gaia).
                  interactive=False,            # Don't show the interactive interface.
                  see2dplot=False,              # Suppress additional figures in this test.
                  shiftfile=True,               # Save output shift file to examine shifts later.
                  outshifts='Gaia_shifts.txt',  # Name of the shift file that will be saved.
                  wcsname=wcsname,              # Give our WCS a new name defined above.
                  reusename=True,               # Overwrite the WCS if it exists.
                  ylimit=0.3,                   # The ylimit for the residuals plot.
                  fitgeometry='rscale',         # Allow for translation, rotation, and plate scaling.
                  searchrad=0.1,                # With many sources use a smaller search radius for convergence.
                  updatehdr=False)              # Don't update the header with new WCS until later.
clear_output()
../../../_images/eb09805838ad3e3d6568c2f8e13c25d315d9b298f275c7db3270fd28464c936b.png ../../../_images/1259f76fcd2e5762d1d6ea5a274a3c4758905d25aeae00ad5ed98c6948866ead.png
# If the alignment is unsuccessful then stop the notebook.

with open('Gaia_shifts.txt', 'r') as shift:
    for line_number, line in enumerate(shift, start=1):
        if "nan" in line:
            raise ValueError('nan found in line {} in shift file'.format(line_number))
        else:
            continue

3.4 Inspect the shift file and fit residuals#

We can similarly look at the shift file from alignment to the Gaia catalog. As expected, the Gaia catalog does quite a bit better, with rms residuals ~0.05 pixels.

The columns are: Filename, X Shift [pixels], Y Shift [pixels], Rotation [degrees], Scale, X RMS [pixels], Y RMS [pixels]

shift_table = Table.read('Gaia_shifts.txt',
                         format='ascii.no_header', 
                         names=['file', 'dx', 'dy', 'rot', 'scale', 'xrms', 'yrms'])

formats = ['.2f', '.2f', '.3f', '.5f', '.2f', '.2f']
for i, col in enumerate(shift_table.colnames[1:]):
    shift_table[col].format = formats[i]
shift_table
Table length=3
filedxdyrotscalexrmsyrms
str18float64float64float64float64float64float64
ibwb01xqq_flc.fits-0.220.10360.0001.000000.030.03
ibwb01xxq_flc.fits-0.210.100.0001.000000.030.05
ibwb01xrq_flc.fits-0.220.100.0001.000000.030.05

Print the Number of Gaia Matches per image from the TweakReg output.

rootname1 = 'ibwb01xqq'
rootname2 = 'ibwb01xrq'
rootname3 = 'ibwb01xxq'
match_tab1 = ascii.read(rootname1+'_flc_catalog_fit.match')  # load match file in astropy table
match_tab2 = ascii.read(rootname2+'_flc_catalog_fit.match')  # load match file in astropy table
match_tab3 = ascii.read(rootname3+'_flc_catalog_fit.match')  # load match file in astropy table
print(rootname1+': Number of Gaia Matches =', len(match_tab1))
print(rootname2+': Number of Gaia Matches =', len(match_tab2))
print(rootname3+': Number of Gaia Matches =', len(match_tab3))
ibwb01xqq: Number of Gaia Matches = 565
ibwb01xrq: Number of Gaia Matches = 567
ibwb01xxq: Number of Gaia Matches = 538

Compare the RMS and number of matches from TweakReg with the MAST alignment results.

wcstable
Table length=3
filenameDETECTOREXPTIMEWCSNAMENMATCHESRMS_RARMS_DECRMS_RA_pixRMS_DEC_pix
str18str4float64str30int64float64float64float64float64
ibwb01xqq_flc.fitsUVIS30.0IDC_2731450pi-FIT_IMG_GAIAeDR34421.31.50.030.04
ibwb01xrq_flc.fitsUVIS360.0IDC_2731450pi-FIT_IMG_GAIAeDR34624.03.80.10.1
ibwb01xxq_flc.fitsUVIS360.0IDC_2731450pi-FIT_IMG_GAIAeDR34293.93.70.10.09

The new Gaia solution looks better than the MAST solution, so we rerun TweakReg below and update the image headers with the new WCS solution.

For more details on absolute astrometry in HST images, see Section 4.5 in the DrizzlePac Handbook. Show the astrometric residual plots:

Image(filename='residuals_ibwb01xqq_flc.png', width=500, height=300)
../../../_images/67ec83f08005d981bd9b6c1fa24b98cf819fa628d6fb7a4dc05c0f3bbb36defb.png
Image(filename='residuals_ibwb01xrq_flc.png', width=500, height=300)
../../../_images/bf4622ae2733ab0024a326f84935f46d0bfa6664940757f188aac3b1cb6485a1.png
Image(filename='residuals_ibwb01xxq_flc.png', width=500, height=300)
../../../_images/afdd713b8681bf88091161446f65d3a970e285c697ce9e0b984bab9a732ecdea.png

3.5 Overplot Matched Sources on the Image#

Now, let’s plot the sources that were matched between all images on the “bottom” UVIS chip. This is referred to as chip 2 or SCI, 1 or extension 1. The cell below reads in the *_fit.match file as an astropy table. Unfortunately, it doesn’t automatically name columns so we look at the header to grab the columns.

To verify that TweakReg obtained an acceptable fit between matched source catalogs, it is useful to inspect the results before updating the image header WCS. In the figure below, sources that are matched with Gaia are overplotted on one of the input FLC frames with the two chips merged together.

It can be useful to check that TweakReg locked onto stars and not hot pixels or other detector artifacts before proceeding to update the image header.

# Choose one of the files to view.
# rootname = 'ibwb01xqq'
rootname = 'ibwb01xrq'
# rootname = 'ibwb01xxq'

plt.figure(figsize=(7, 7), dpi=140)
chip1_data = fits.open(rootname+'_flc.fits')['SCI', 2].data
chip2_data = fits.open(rootname+'_flc.fits')['SCI', 1].data
fullsci = np.concatenate([chip2_data, chip1_data])
z1, z2 = ZScaleInterval().get_limits(fullsci)
plt.imshow(fullsci, cmap='Greys', origin='lower', vmin=z1, vmax=z2)

match_tab = ascii.read(rootname+'_flc_catalog_fit.match')  # Load the match file in astropy table.
match_tab_chip1 = match_tab[match_tab['col15'] == 2]  # Filter the table for sources on chip 1.
match_tab_chip2 = match_tab[match_tab['col15'] == 1]  # Filter the table for sources on chip 2.
x_cord1, y_cord1 = match_tab_chip1['col11'], match_tab_chip1['col12']
x_cord2, y_cord2 = match_tab_chip2['col11'], match_tab_chip2['col12']

plt.scatter(x_cord1, y_cord1+2051, s=50, edgecolor='r', facecolor='None', label='Matched Sources')
plt.scatter(x_cord2, y_cord2, s=50, edgecolor='r', facecolor='None')
plt.title(f'Matched sources UVIS to Gaia: N = {len(match_tab)}', fontsize=14)
plt.show()
../../../_images/099ce69bad631668523271c1595435eb266f89c8b67c09423c274a1a4a6fb10d.png

3.6 Update header with optimal parameters#

Once you’ve decided on the optimal set of parameters for your alignment, it is safe to update the header of the input data, (assuming that the new solution is better than the MAST alignment.) To apply these transformations to the image, we simply need to run TweakReg the same as before, but set the parameter updatehdr equal to True:

refcat = 'gaia.cat'
wcsname = 'Gaia'                   # Specify the WCS name for this alignment
cw = 3.5                           # 2x the FWHM of the PSF = 3.5 for ACS/WFC, WFC3/UVIS or 2.5 for WFC3/IR 

tweakreg.TweakReg('*flc.fits', # Pass the input images to tweakreg.
                  imagefindcfg={'threshold': 500., 'conv_width': cw},  # Detection parameters that vary for different datasets.
                  refcat=refcat,                # Use user supplied catalog (Gaia).
                  interactive=False,            # Don't show the interactive interface.
                  see2dplot=False,              # Suppress additional figures in this test.
                  shiftfile=True,               # Save output shift file to examine shifts later.
                  outshifts='Gaia_shifts.txt',  # Name of the shift file that will be saved.
                  wcsname=wcsname,              # Give our WCS a new name defined above.
                  reusename=True,               # Overwrite the WCS if it exists.
                  ylimit=0.3,                   # The ylimit for the residuals plot.
                  fitgeometry='rscale',         # Allow for translation, rotation, and plate scaling.
                  searchrad=0.1,                # With many sources use a smaller search radius for convergence.
                  updatehdr=True)               # Update the header with new WCS solution.

clear_output()
../../../_images/eb09805838ad3e3d6568c2f8e13c25d315d9b298f275c7db3270fd28464c936b.png ../../../_images/1259f76fcd2e5762d1d6ea5a274a3c4758905d25aeae00ad5ed98c6948866ead.png

4. Combine the Images using AstroDrizzle#

Table of Contents

While the three sets of FLC files are now aligned, in this example we drizzle together only the two long exposures. When exposures are very different lengths, drizzling them together doesn’t work well when ‘EXP’ weighting is used. For objects that saturate in the long exposures, the problem occurs at the boundary where the signal transitions from only being present in short exposures near the core to being present at larger radii in the longer exposures. The result is a discontinuity in the PSF radial profile and a resulting flux that is too low in some regions. For photometry of saturated objects, the short exposures should be drizzled separately from the long exposures.

Next, we combine the images through drizzling, and retrieve some recommended values for this process from the MDRIZTAB reference file. The parameters in this file are different for each detector and are based on the number of input frames. These are a good starting point for drizzling and may be adjusted based on your science goals.

input_images = sorted(glob.glob('ibwb01x[rx]q_flc.fits'))

mdz = fits.getval(input_images[0], 'MDRIZTAB', ext=0).split('$')[1]

print('Searching for the MDRIZTAB file:', mdz)

!crds sync --hst --files {mdz} --output-dir {os.environ['iref']}
Searching for the MDRIZTAB file: ubi1853qi_mdz.fits
CRDS - INFO -  Symbolic context 'hst-latest' resolves to 'hst_1192.pmap'
CRDS - INFO -  Reorganizing 0 references from 'instrument' to 'flat'
CRDS - INFO -  Reorganizing from 'instrument' to 'flat' cache,  removing instrument directories.
CRDS - INFO -  Syncing explicitly listed files.
CRDS - INFO -  Fetching  ./crds_cache/references/hst/wfc3/ubi1853qi_mdz.fits       95.0 K bytes  (1 / 1 files) (0 / 95.0 K bytes)
CRDS - INFO -  0 errors
CRDS - INFO -  0 warnings
CRDS - INFO -  5 infos
def get_vals_from_mdriztab(input_images, 
                           kw_list=[
                               'driz_sep_bits', 
                               'combine_type', 
                               'driz_cr_snr', 
                               'driz_cr_scale', 
                               'final_bits']):
    
    'Get only selected parameters from the MDRIZTAB.'
    mdriz_dict = getMdriztabPars(input_images)
    
    requested_params = {}
    
    print('Outputting the following parameters:')
    for k in kw_list:
        requested_params[k] = mdriz_dict[k]
        print(k, mdriz_dict[k])
    
    return requested_params
selected_params = get_vals_from_mdriztab(input_images)
- MDRIZTAB: AstroDrizzle parameters read from row 2.
Outputting the following parameters:
driz_sep_bits 96
combine_type minmed
driz_cr_snr 3.5 3.0
driz_cr_scale 1.2 0.7
final_bits 96

Note that the parameter final_bits= ‘96’ is equivalent to final_bits= ‘64, 32’ because they are added in a bit-wise manner.

# To override any of the above values:
selected_params['driz_sep_bits'] = '256, 64, 32'
selected_params['final_bits'] = '256, 64, 32'
# selected_params['combine_type']  = 'median'
# selected_params['driz_cr_snr']   = '4.0 3.5'
# selected_params['driz_cr_scale'] = '1.5 1.2'

astrodrizzle.AstroDrizzle(input_images, 
                          output='f606w',
                          preserve=False,
                          clean=True, 
                          build=False,
                          context=False,
                          skymethod='match',
                          **selected_params)

clear_output()

Display the combined science and weight images. In this example there appear to be three detector chips due to the large dither that was used in the observations. We note that the exposures overlapped in the center region, as evidenced by the increased value of the weight map corresponding to a longer effective exposure time. In addition, the resulting mosaic is better cleaned of artifacts and cosmic rays in this region due to the multiple exposures, as seen by the uniform background in the science mosaic.

sci = fits.getdata('f606w_drc_sci.fits')
wht = fits.getdata('f606w_drc_wht.fits')

fig = plt.figure(figsize=(20, 20))
ax1 = fig.add_subplot(1, 2, 1)
ax2 = fig.add_subplot(1, 2, 2)

ax1.imshow(sci, vmin=-0.05, vmax=0.4, cmap='Greys_r', origin='lower')
ax2.imshow(wht, vmin=0.0, vmax=1000, cmap='Greys_r', origin='lower')

ax1.title.set_text('Science Image')
ax2.title.set_text('Weight Image')
ax1.set_xlabel('X (pixels)')
ax1.set_ylabel('Y (pixels)')
ax2.set_xlabel('X (pixels)')
ax2.set_ylabel('Y (pixels)')
Text(0, 0.5, 'Y (pixels)')
../../../_images/5f1597a1a8e67a37616cc0b339f76bcbfd8931ee3f18efba0b92b97001a2337b.png

For more details on inspecting the drizzled products after reprocessing, see Section 7.3 in the DrizzlePac Handbook.

Conclusions#

Table of Contents

Many other services have interfaces for querying catalogs that can also be used to align HST images. In general, Gaia works very well for HST due to its high precision, but can have a low number of sources in some regions, especially at high galactic latitudes. Aligning images to an absolute frame provides a way to make data comparable across many epochs/detectors/observatories, and in many cases, makes the alignment easier to complete.

About this Notebook#

Created: 14 Dec 2018;     V. Bajaj
Updated: 03 Jul 2024;     M. Revalski, V. Bajaj, & J. Mack

Source: GitHub spacetelescope/hst_notebooks

Additional Resources#

Below are some additional resources that may be helpful. Please send any questions through the HST Help Desk, selecting the DrizzlePac category.

Citations#

If you use Python packages such as astropy, astroquery, drizzlepac, matplotlib, or numpy for published research, please cite the authors.

Follow these links for more information about citing various packages:


Top of Page Space Telescope Logo