Skip to article frontmatterSkip to article content
IRSA Tutorials

Euclid Q1: MER mosaics

Learning Goals

By the end of this tutorial, you will:

Introduction

Euclid launched in July 2023 as a European Space Agency (ESA) mission with involvement by NASA. The primary science goals of Euclid are to better understand the composition and evolution of the dark Universe. The Euclid mission is providing space-based imaging and spectroscopy as well as supporting ground-based imaging to achieve these primary goals. These data will be archived by multiple global repositories, including IRSA, where they will support transformational work in many areas of astrophysics.

Euclid Quick Release 1 (Q1) consists of consists of ~30 TB of imaging, spectroscopy, and catalogs covering four non-contiguous fields: Euclid Deep Field North (22.9 sq deg), Euclid Deep Field Fornax (12.1 sq deg), Euclid Deep Field South (28.1 sq deg), and LDN1641.

Among the data products included in the Q1 release are the Level 2 MER mosaics. These are multiwavelength mosaics created from images taken with the Euclid instruments (VIS and NISP), as well as a variety of ground-based telescopes. All of the mosaics have been created according to a uniform tiling on the sky, and mapped to a common pixel scale. This notebook provides a quick introduction to accessing MER mosaics from IRSA. If you have questions about it, please contact the IRSA helpdesk.

Data volume

Each MER image is approximately 1.47 GB. Downloading can take some time.

Imports

# Uncomment the next line to install dependencies if needed.
# !pip install numpy 'astropy>=5.3' matplotlib 'astroquery>=0.4.10' 'sep>=1.4' fsspec
import re

import numpy as np

import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse

from astropy.coordinates import SkyCoord
from astropy.io import fits
from astropy.nddata import Cutout2D
from astropy.utils.data import download_file
from astropy.visualization import ImageNormalize, PercentileInterval, AsinhStretch,  ZScaleInterval, SquaredStretch
from astropy.wcs import WCS
from astropy import units as u

from astroquery.ipac.irsa import Irsa
import sep

1. Search for multiwavelength Euclid Q1 MER mosaics that cover the star HD 168151

Below we set a search radius of 10 arcsec and convert the name “HD 168151” into coordinates.

search_radius = 10 * u.arcsec
coord = SkyCoord.from_name('HD 168151')

Use IRSA’s Simple Image Access (SIA) API to search for all Euclid MER mosaics that overlap with the search region you have specified. We specify the euclid_DpdMerBksMosaic “collection” because it lists all of the multiwavelength MER mosaics, along with their associated catalogs.

There are currently four collections available:

For more information on the VIS and NIR calibrated frames, please read the IRSA User Guide

In this notebook, we will focus on downloading and visualizing the MER mosaic data.

image_table = Irsa.query_sia(pos=(coord, search_radius), collection='euclid_DpdMerBksMosaic')

This table lists all MER mosaic images available in this search position. These mosaics include the Euclid VIS, Y, J, H images, as well as ground-based telescopes which have been put on the same pixel scale. For more information, see the Euclid documentation at IPAC.

Note that there are various image types are returned as well, we filter out the science images from these:

science_images = image_table[image_table['dataproduct_subtype'] == 'science']
science_images
Loading...

2. Retrieve a Euclid Q1 MER mosaic image in the VIS bandpass

Let’s first look at one example full image, the VIS image

Note that ‘access_estsize’ is in units of kb

filename = science_images[science_images['energy_bandpassname'] == 'VIS']['access_url'][0]
filesize = science_images[science_images['energy_bandpassname'] == 'VIS']['access_estsize'][0] / 1000000
print(filename)

print(f'Please note this image is {filesize} GB. With 230 Mbps internet download speed, it takes about 1 minute to download.')
https://irsa.ipac.caltech.edu/ibe/data/euclid/q1/MER/102158277/VIS/EUC_MER_BGSUB-MOSAIC-VIS_TILE102158277-27C4DD_20241025T124812.358980Z_00.00.fits
Please note this image is 1.474566 GB. With 230 Mbps internet download speed, it takes about 1 minute to download.
science_images
Loading...

Extract the tileID of this image from the filename

tileID = science_images[science_images['energy_bandpassname'] == 'VIS']['obs_id'][0][:9]

print(f'The MER tile ID for this object is : {tileID}')
The MER tile ID for this object is : 102158277

Retrieve the MER image -- note this file is about 1.46 GB

fname = download_file(filename, cache=True)
hdu_mer_irsa = fits.open(fname)
print(hdu_mer_irsa.info())

header_mer_irsa = hdu_mer_irsa[0].header
Filename: /home/runner/.astropy/cache/download/url/57396083c69b787af6e808156a46c70e/contents
No.    Name      Ver    Type      Cards   Dimensions   Format
  0  PRIMARY       1 PrimaryHDU      48   (19200, 19200)   float32   
None

If you would like to save the MER mosaic to disk, uncomment the following cell. Please also define a suitable download directory; by default it will be data at the same location as your notebook.

# download_path = 'data'
# hdu_mer_irsa.writeto(os.path.join(download_path, 'MER_image_VIS.fits'), overwrite=True)

Have a look at the header information for this image.

header_mer_irsa
SIMPLE = T / conforms to FITS standard BITPIX = -32 / array data type NAXIS = 2 / number of array dimensions NAXIS1 = 19200 NAXIS2 = 19200 EQUINOX = 2000.00000000 / Mean equinox RADESYS = 'ICRS ' / Astrometric system CTYPE1 = 'RA---TAN' / WCS projection type for this axis CUNIT1 = 'deg ' / Axis unit CRVAL1 = 2.737406439000E+02 / World coordinate on this axis CRPIX1 = 9600 / Reference pixel on this axis CD1_1 = -2.777777777778E-05 / Linear projection matrix CD1_2 = 0.000000000000E+00 / Linear projection matrix CTYPE2 = 'DEC--TAN' / WCS projection type for this axis CUNIT2 = 'deg ' / Axis unit CRVAL2 = 6.450000000000E+01 / World coordinate on this axis CRPIX2 = 9600 / Reference pixel on this axis CD2_1 = 0.000000000000E+00 / Linear projection matrix CD2_2 = 2.777777777778E-05 / Linear projection matrix COMMENT SOFTNAME= 'CT_SWarp' / The software that processed those data SOFTVERS= '10.2 ' / Version of the software SOFTDATE= '2024-03-18' / Release date of the software SOFTAUTH= '2020-2024 Euclid Consortium' / Maintainer of the software SOFTINST= 'Euclid Consortium https://www.euclid-ec.org/' / Institute COMMENT AUTHOR = 'ial ' / Who ran the software ORIGIN = 'pr-02.sdcit-prod-ops.altecspace.it' / Where it was done DATE = '2024-10-25T12:31:02' / When it was started (GMT) COMBINET= 'MEDIAN ' / COMBINE_TYPE config parameter for CT_SWarp COMMENT COMMENT Propagated FITS keywords COMMENT COMMENT Axis-dependent config parameters RESAMPT1= 'BILINEAR' / RESAMPLING_TYPE config parameter CENTERT1= 'ALL ' / CENTER_TYPE config parameter PSCALET1= 'MEDIAN ' / PIXELSCALE_TYPE config parameter RESAMPT2= 'BILINEAR' / RESAMPLING_TYPE config parameter CENTERT2= 'ALL ' / CENTER_TYPE config parameter PSCALET2= 'MEDIAN ' / PIXELSCALE_TYPE config parameter MAGZERO = 24.6 / AB zeropoint FILTER = 'VIS ' / the filter name PPOID = 'MER_ProcessTile_EUCLID_2.0.2-QUICK_RELEASE-glibet-PLAN-000003-0VAPS&' CONTINUE '1GC-20241024-174435-29-RETRY-241025112601&' CONTINUE '' / pipeline PPOID DATASETR= 'Q1_R1 ' / pipeline DATASETRELEASE PIPDEFID= 'MER_ProcessTile_EUCLID_2.0.2' / the pipeline definition ID PPLANID = 'MER_ProcessTile_EUCLID_2.0.2-QUICK_RELEASE-glibet-PLAN-000003' / the PSWNAME = 'MER_ProcessTile' / the pipeline software name PSWREL = '11.0.1 ' / the pipeline software release

Lets extract just the primary image.

im_mer_irsa = hdu_mer_irsa[0].data

print(im_mer_irsa.shape)
(19200, 19200)

Due to the large field of view of the MER mosaic, let’s cut out a smaller section (2"x2")of the MER mosaic to inspect the image

plt.imshow(im_mer_irsa[0:1200,0:1200], cmap='gray', origin='lower',
           norm=ImageNormalize(im_mer_irsa[0:1200,0:1200], interval=PercentileInterval(99.9), stretch=AsinhStretch()))
colorbar = plt.colorbar()
<Figure size 640x480 with 2 Axes>

Uncomment the code below to plot an image of the entire field of view of the MER mosaic.

# # Full MER mosaic, may take a minute for python to create this image
# plt.imshow(im_mer_irsa, cmap='gray', origin='lower', norm=ImageNormalize(im_mer_irsa, interval=PercentileInterval(99.9), stretch=AsinhStretch()))
# colorbar = plt.colorbar()

3. Create multiwavelength Euclid Q1 MER cutouts of a region of interest

urls = science_images['access_url']

urls
Loading...

Create an array with the instrument and filter name so we can add this to the plots.

science_images['filters'] = science_images['instrument_name'] + "_" + science_images['energy_bandpassname']

# VIS_VIS appears in the filters, so update that filter to just say VIS
science_images['filters'][science_images['filters']== 'VIS_VIS'] = "VIS"

science_images['filters']
Loading...

The image above is very large, so let’s cut out a smaller image to inspect these data.

######################## User defined section ############################
## How large do you want the image cutout to be?
im_cutout = 1.0 * u.arcmin

## What is the center of the cutout?
## For now choosing a random location on the image
## because the star itself is saturated
ra = 273.8667
dec =  64.525

## Bright star position
# ra = 273.474451
# dec = 64.397273

coords_cutout = SkyCoord(ra, dec, unit='deg', frame='icrs')

##########################################################################

## Iterate through each filter

cutout_list = []

for url in urls:
    ## Use fsspec to interact with the fits file without downloading the full file
    hdu = fits.open(url, use_fsspec=True)
    print(f"Opened {url}")

    ## Store the header
    header = hdu[0].header

    ## Read in the cutout of the image that you want
    cutout_data = Cutout2D(hdu[0].section, position=coords_cutout, size=im_cutout, wcs=WCS(hdu[0].header))

    ## Close the file
    # hdu.close()

    ## Define a new fits file based on this smaller cutout, with accurate WCS based on the cutout size
    new_hdu = fits.PrimaryHDU(data=cutout_data.data, header=header)
    new_hdu.header.update(cutout_data.wcs.to_header())

    ## Append the cutout to the list
    cutout_list.append(new_hdu)

## Combine all cutouts into a single HDUList and display information
final_hdulist = fits.HDUList(cutout_list)
final_hdulist.info()
Opened https://irsa.ipac.caltech.edu/ibe/data/euclid/q1/MER/102158277/NISP/EUC_MER_BGSUB-MOSAIC-NIR-Y_TILE102158277-1FE0D9_20241025T122512.777703Z_00.00.fits
Opened https://irsa.ipac.caltech.edu/ibe/data/euclid/q1/MER/102158277/NISP/EUC_MER_BGSUB-MOSAIC-NIR-J_TILE102158277-DA51EA_20241025T122533.612365Z_00.00.fits
Opened https://irsa.ipac.caltech.edu/ibe/data/euclid/q1/MER/102158277/NISP/EUC_MER_BGSUB-MOSAIC-NIR-H_TILE102158277-797A7D_20241025T122514.635323Z_00.00.fits
Opened https://irsa.ipac.caltech.edu/ibe/data/euclid/q1/MER/102158277/GPC/EUC_MER_BGSUB-MOSAIC-PANSTARRS-I_TILE102158277-C2B970_20241025T120200.727193Z_00.00.fits
Opened https://irsa.ipac.caltech.edu/ibe/data/euclid/q1/MER/102158277/VIS/EUC_MER_BGSUB-MOSAIC-VIS_TILE102158277-27C4DD_20241025T124812.358980Z_00.00.fits
Opened https://irsa.ipac.caltech.edu/ibe/data/euclid/q1/MER/102158277/MEGACAM/EUC_MER_BGSUB-MOSAIC-CFIS-U_TILE102158277-DB8920_20241025T120138.608462Z_00.00.fits
Opened https://irsa.ipac.caltech.edu/ibe/data/euclid/q1/MER/102158277/MEGACAM/EUC_MER_BGSUB-MOSAIC-CFIS-R_TILE102158277-CA7AB3_20241025T120300.417407Z_00.00.fits
Opened https://irsa.ipac.caltech.edu/ibe/data/euclid/q1/MER/102158277/HSC/EUC_MER_BGSUB-MOSAIC-WISHES-G_TILE102158277-76C6DB_20241025T120401.488065Z_00.00.fits
Opened https://irsa.ipac.caltech.edu/ibe/data/euclid/q1/MER/102158277/HSC/EUC_MER_BGSUB-MOSAIC-WISHES-Z_TILE102158277-E3133D_20241025T120342.580582Z_00.00.fits
Filename: (No file associated with this HDUList)
No.    Name      Ver    Type      Cards   Dimensions   Format
  0  PRIMARY       1 PrimaryHDU      57   (600, 600)   float32   
  1  PRIMARY       1 PrimaryHDU      56   (600, 600)   float32   
  2  PRIMARY       1 PrimaryHDU      56   (600, 600)   float32   
  3  PRIMARY       1 PrimaryHDU      56   (600, 600)   float32   
  4  PRIMARY       1 PrimaryHDU      56   (600, 600)   float32   
  5  PRIMARY       1 PrimaryHDU      56   (600, 600)   float32   
  6  PRIMARY       1 PrimaryHDU      56   (600, 600)   float32   
  7  PRIMARY       1 PrimaryHDU      56   (600, 600)   float32   
  8  PRIMARY       1 PrimaryHDU      56   (600, 600)   float32   

3. Visualize multiwavelength Euclid Q1 MER cutouts

We need to determine the number of images for the grid layout, and then plot each cutout.

num_images = len(final_hdulist)
columns = 4
rows = -(-num_images // columns)

fig, axes = plt.subplots(rows, columns, figsize=(4 * columns, 4 * rows), subplot_kw={'projection': WCS(final_hdulist[0].header)})
axes = axes.flatten()

for idx, (ax, filt) in enumerate(zip(axes, science_images['filters'])):
    image_data = final_hdulist[idx].data
    norm = ImageNormalize(image_data, interval=PercentileInterval(99.9), stretch=AsinhStretch())
    ax.imshow(image_data, cmap='gray', origin='lower', norm=norm)
    ax.set_xlabel('RA')
    ax.set_ylabel('Dec')
    ax.text(0.05, 0.05, filt, color='white', fontsize=14, transform=ax.transAxes, va='bottom', ha='left')

## Remove empty subplots if any
for ax in axes[num_images:]:
    fig.delaxes(ax)

plt.tight_layout()
plt.show()
<Figure size 1600x1200 with 9 Axes>

4. Use the Python package sep to identify and measure sources in the Euclid Q1 MER cutouts

First we list all the filters so you can choose which cutout you want to extract sources on. We will choose VIS.

filt_index = np.where(science_images['filters'] == 'VIS')[0][0]

img1 = final_hdulist[filt_index].data

Extract some sources from the cutout using sep (python package based on source extractor)

Following the sep tutorial, first create a background for the cutout https://sep.readthedocs.io/en/stable/tutorial.html

Need to do some initial steps (swap byte order) with the cutout to prevent sep from crashing. Then create a background model with sep.

img2 = img1.byteswap().view(img1.dtype.newbyteorder())
c_contiguous_data = np.array(img2, dtype=np.float32)

bkg = sep.Background(c_contiguous_data)

bkg_image = bkg.back()

plt.imshow(bkg_image, interpolation='nearest', cmap='gray', origin='lower')
plt.colorbar()
<Figure size 640x480 with 2 Axes>

Inspect the background rms as well

bkg_rms = bkg.rms()

plt.imshow(bkg_rms, interpolation='nearest', cmap='gray', origin='lower')
plt.colorbar();
<Figure size 640x480 with 2 Axes>

Subtract the background

data_sub = img2 - bkg

Source extraction via sep

######################## User defined section ############################

## Sigma threshold to consider this a detection above the global RMS
threshold= 3

## Minimum number of pixels required for an object. Default is 5.
minarea_0=2

## Minimum contrast ratio used for object deblending. Default is 0.005. To entirely disable deblending, set to 1.0.
deblend_cont_0= 0.005

flux_threshold= 0.01
##########################################################################


sources = sep.extract(data_sub, threshold, err=bkg.globalrms, minarea=minarea_0, deblend_cont=deblend_cont_0)
sources_thr = sources[sources['flux'] > flux_threshold]
print("Found", len(sources_thr), "objects above flux threshold")
Found 114 objects above flux threshold

Lets have a look at the objects that were detected with sep in the cutout

We plot the VIS cutout with the sources detected overplotted with a red ellipse

fig, ax = plt.subplots()
m, s = np.mean(data_sub), np.std(data_sub)
im = ax.imshow(data_sub, cmap='gray', origin='lower', norm=ImageNormalize(img2, interval=ZScaleInterval(), stretch=SquaredStretch()))

## Plot an ellipse for each object detected with sep

for i in range(len(sources_thr)):
    e = Ellipse(xy=(sources_thr['x'][i], sources_thr['y'][i]),
                width=6*sources_thr['a'][i],
                height=6*sources_thr['b'][i],
                angle=sources_thr['theta'][i] * 180. / np.pi)
    e.set_facecolor('none')
    e.set_edgecolor('red')
    ax.add_artist(e)
<Figure size 640x480 with 1 Axes>

About this Notebook

Author: Tiffany Meshkat, Anahita Alavi, Anastasia Laity, Andreas Faisst, Brigitta Sipőcz, Dan Masters, Harry Teplitz, Jaladh Singhal, Shoubaneh Hemmati, Vandana Desai

Updated: 2025-03-31

Contact: the IRSA Helpdesk with questions or reporting problems.