diff --git a/docs/conf.py b/docs/conf.py index f27d86d5b..48999db06 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -221,6 +221,8 @@ def check_sphinx_version(expected_version): "-Gfontname=Helvetica Neue, Helvetica, Arial, sans-serif", ] +# activate figure numbering +numfig = True # If true, '()' will be appended to :func: etc. cross-reference text. # add_function_parentheses = True diff --git a/docs/roman/pipeline/graphics/mosaic4_regular_grid.png b/docs/roman/pipeline/graphics/mosaic4_regular_grid.png new file mode 100644 index 000000000..299f66fa1 Binary files /dev/null and b/docs/roman/pipeline/graphics/mosaic4_regular_grid.png differ diff --git a/docs/roman/pipeline/graphics/mosaic_regular_grid.png b/docs/roman/pipeline/graphics/mosaic_regular_grid.png new file mode 100644 index 000000000..46b9d65c4 Binary files /dev/null and b/docs/roman/pipeline/graphics/mosaic_regular_grid.png differ diff --git a/docs/roman/pipeline/graphics/wfi_4sca_skycell.png b/docs/roman/pipeline/graphics/wfi_4sca_skycell.png new file mode 100644 index 000000000..60ebbe2e0 Binary files /dev/null and b/docs/roman/pipeline/graphics/wfi_4sca_skycell.png differ diff --git a/docs/roman/pipeline/mosaic_pipeline.rst b/docs/roman/pipeline/mosaic_pipeline.rst index 262373a33..752e46bf9 100644 --- a/docs/roman/pipeline/mosaic_pipeline.rst +++ b/docs/roman/pipeline/mosaic_pipeline.rst @@ -59,6 +59,63 @@ calibrated data for the the exposures. The most convenient way to pass the list exposures to be processed with the mosaic level pipeline is to use an association. Instructions on how to create an input association an be found at :ref:`asn-from-list`. +The mosaic pipeline can create different types of products. In one +mode you give it a list of calibrated images and the pipeline will run +the above steps and the final product is a mosaic of the input images +resampled to a regular grid. The mode is selected based on the target +field in the association header. If the input association contains a +target field which matches a skycell name (see TBD) then the mosaic +pipeline will resample the final product onto the skycell grid. + +If the association has been generated with :ref:`skycell_asn` the +skycell name and projection coordinates should be available in the +association header. If the skycell name is available and corresponds +to a valid name in the database and the projection cell coordinates +are not available in the association header then the pipeline will +read the needed information from the data file containing the skycell +information. + +.. _figure-skycell-mosaic: + +.. figure:: graphics/wfi_4sca_skycell.png + :scale: 60 % + + Image showing the four SCA's that overlap a given skycell. + + +The projection of the single WFI exposure resampled to a skycell is shown in :numref:`figure-skycell-mosaic`. +The image has the portion of the four SCAs that overlap +the given skycell resampled to a regular grid on the WCS of the skycell. The gaps +between the images show the placement of the SCAs in the detector. In general +these gaps will be filled in by additional exposures in the visit. + +If the target field does not contain a valid skycell name then the +image or images will be resampled to a regular grid. To resample a +single image the input will need to be an association with a single +member. + +.. list-table:: + + * - .. figure:: graphics/mosaic_regular_grid.png + :name: figure-mosaic-regular-grid + :scale: 25 % + :align: left + + An SCA resampled to a regular grid. + + - .. figure:: graphics/mosaic4_regular_grid.png + :name: figure-mosaic4-regular-grid + :scale: 25 % + + Four SCAs resampled to a regular grid. + +.. labels in list-tables do no appear to be used outside the list-table structure, hard codeing for now. +.. :numref:`figure-mosaic-regular-grid` and :numref:`figure-mosaic4-regular-grid` show + +Figures 2 & 3 show the results of the mosaic pipeline on a single SCA and on four SCA's in the WFI array. +Using the code to mosaic large areas of the sky may result on the code needing large amounts of memory, +so care is needed not to exceed your local memory limits when constructing mosaics in this manner. + Outputs ---------- diff --git a/romancal/associations/skycell_asn.py b/romancal/associations/skycell_asn.py index 50f66bec1..cd0dbe813 100644 --- a/romancal/associations/skycell_asn.py +++ b/romancal/associations/skycell_asn.py @@ -63,14 +63,17 @@ def skycell_asn(filelist, output_file_root, product_type, release_product): # grab all the wcs parameters needed for generate_tan_wcs projcell_info = dict( [ + ("name", pm.PATCH_TABLE[item]["name"]), ("pixel_scale", float(pm.PATCH_TABLE[item]["pixel_scale"])), - ("ra_cent", float(pm.PATCH_TABLE[item]["ra_projection_center"])), - ("dec_cent", float(pm.PATCH_TABLE[item]["dec_projection_center"])), - ("shiftx", float(pm.PATCH_TABLE[item]["x0_projection"])), - ("shifty", float(pm.PATCH_TABLE[item]["y0_projection"])), + ("ra_projection_center", float(pm.PATCH_TABLE[item]["ra_projection_center"])), + ("dec_projection_center", float(pm.PATCH_TABLE[item]["dec_projection_center"])), + ("x0_projection", float(pm.PATCH_TABLE[item]["x0_projection"])), + ("y0_projection", float(pm.PATCH_TABLE[item]["y0_projection"])), + ("ra_center", float(pm.PATCH_TABLE[item]["ra_center"])), + ("dec_center", float(pm.PATCH_TABLE[item]["dec_center"])), ("nx", int(pm.PATCH_TABLE[item]["nx"])), ("ny", int(pm.PATCH_TABLE[item]["ny"])), - ("orient", float(pm.PATCH_TABLE[item]["orientat"])), + ("orientat", float(pm.PATCH_TABLE[item]["orientat"])), ( "orientat_projection_center", float(pm.PATCH_TABLE[item]["orientat_projection_center"]), diff --git a/romancal/pipeline/mosaic_pipeline.py b/romancal/pipeline/mosaic_pipeline.py index a155c68b0..24e89f08f 100644 --- a/romancal/pipeline/mosaic_pipeline.py +++ b/romancal/pipeline/mosaic_pipeline.py @@ -5,6 +5,7 @@ import re from os.path import basename, isfile from typing import TYPE_CHECKING +import json import asdf import numpy as np @@ -86,19 +87,24 @@ def process(self, input): product_name = input.asn["products"][0]["name"] try: skycell_name = input.asn["target"] - except IndexError: + except KeyError: skycell_name = "" skycell_record = [] - # if this is a valid skycell name load the database and get the skycell record + # if this is a valid skycell name get the skycell record if re.match(r"r\d{3}\w{2}\d{2}x\d{2}y\d{2}", skycell_name): - if patch_match.PATCH_TABLE is None: - patch_match.load_patch_table() - if patch_match.PATCH_TABLE is None: - raise RuntimeError("No patch table has been loaded") - skycell_record = patch_match.PATCH_TABLE[ - np.where(patch_match.PATCH_TABLE["name"][:] == skycell_name)[0][0] - ] + # check to see if the skycell coords are in the asn header if + # so read the string and convert to a dictionary to match the patch table + try: + skycell_record = json.loads(input.asn["skycell_wcs_info"]) + except (KeyError, json.JSONDecodeError): + if patch_match.PATCH_TABLE is None: + patch_match.load_patch_table() + if patch_match.PATCH_TABLE is None: + raise RuntimeError("No patch table has been loaded") + skycell_record = patch_match.PATCH_TABLE[ + np.where(patch_match.PATCH_TABLE["name"][:] == skycell_name)[0][0] + ] log.info("Skycell record %s:", skycell_record) if skycell_name in skycell_record["name"]: @@ -140,7 +146,7 @@ def process(self, input): result_catalog = self.sourcecatalog.run(result) else: raise NotImplementedError( - "resampling a mosaic file is not yet supported" + "Overwriting an exisiting file or resampling a mosaic file is not yet supported" ) else: