flint.coadd.linmos ================== .. py:module:: flint.coadd.linmos .. autoapi-nested-parse:: This is an interface into the yandasoft linmos task. Attributes ---------- .. autoapisummary:: flint.coadd.linmos.EXPECTED_HOLOGRAPHY_ROTATION_CONSTANT_RADIANS Classes ------- .. autoapisummary:: flint.coadd.linmos.BoundingBox flint.coadd.linmos.LinmosOptions flint.coadd.linmos.LinmosParsetSummary flint.coadd.linmos.LinmosResult flint.coadd.linmos.TrimImageResult Functions --------- .. autoapisummary:: flint.coadd.linmos._create_bound_box_plane flint.coadd.linmos._file_list_to_string flint.coadd.linmos._get_alpha_linmos_option flint.coadd.linmos._get_holography_linmos_options flint.coadd.linmos._get_image_weight_plane flint.coadd.linmos._linmos_cleanup flint.coadd.linmos.cli flint.coadd.linmos.create_bound_box flint.coadd.linmos.generate_linmos_parameter_set flint.coadd.linmos.generate_weights_list_and_files flint.coadd.linmos.get_image_weight flint.coadd.linmos.get_parser flint.coadd.linmos.linmos_images flint.coadd.linmos.trim_fits_image Module Contents --------------- .. py:class:: BoundingBox Bases: :py:obj:`NamedTuple` Simple container to represent a bounding box .. py:attribute:: original_shape :type: tuple[int, int] The original shape of the image. If constructed against a cube this is the shape of a single plane. .. py:attribute:: xmax :type: int Maximum x pixel .. py:attribute:: xmin :type: int Minimum x pixel .. py:attribute:: ymax :type: int Maximum y pixel .. py:attribute:: ymin :type: int Minimum y pixel .. py:class:: LinmosOptions(/, **data: Any) Bases: :py:obj:`flint.options.BaseOptions` Container for options that direct linmos processing .. py:attribute:: base_output_name :type: pathlib.Path Base name path of the output linmos produces, including parent path. This is provided to form ``LinmosNames``. Defaults to 'linmos_field'. .. py:attribute:: cleanup :type: bool :value: False Remove files generated throughout linmos, including the text files with the channel weights. Defaults to False. .. py:attribute:: cutoff :type: float :value: 0.001 Pixels whose primary beam attenuation is below this cutoff value are blanked. Defaults to 0.001. .. py:attribute:: force_remove_leakage :type: bool | None :value: None Overwrite the ``removeLeakage`` option to ``linmos``. Defaults to None. .. py:attribute:: holofile :type: pathlib.Path | None :value: None Path to a FITS cube produced by the holography processing pipeline. Used by linmos to appropriate primary-beam correct the images. Defaults to None. .. py:attribute:: overwrite :type: bool :value: False Overwrite the linmos parset file generated if it exists. Defaults to False. .. py:attribute:: pol_axis :type: float | None :value: None The physical oritentation of the ASKAP third-axis in radians. Defaults to None. .. py:attribute:: remove_original_images :type: bool :value: False Delete the images that were coaddede together. Defaults to False. .. py:attribute:: stokesi_images :type: list[pathlib.Path] | None :value: None Collection of Stokes-I images used to correct widefield leakage when input images are Stokes Q or U. If None ``linmos`` will attempt to find them. Defaults to None. .. py:attribute:: trim_linmos_fits :type: bool :value: True Attempt to trim the output linmos files of as much empty space as possible. Defaults to True. .. py:class:: LinmosParsetSummary Bases: :py:obj:`NamedTuple` Container for key components around a linmos parset file .. py:attribute:: image_paths :type: tuple[pathlib.Path, Ellipsis] The set of paths to the fits images that were coadded together .. py:attribute:: parset_path :type: pathlib.Path Path to the parset text file created .. py:attribute:: weight_text_paths :type: tuple[pathlib.Path, Ellipsis] | None :value: None The set of Paths to the text files with per channel weights used by linmos .. py:class:: LinmosResult(/, **data: Any) Bases: :py:obj:`flint.options.BaseOptions` A base class that Options style flint classes can inherit from. This is derived from ``pydantic.BaseModel``, and can be used for validation of supplied values. Class derived from ``BaseOptions`` are immutable by default, and have the docstrings of attributes extracted. .. py:attribute:: cmd :type: str The yandasoft linmos task that will be executed .. py:attribute:: image_fits :type: pathlib.Path Path to the output linmos image created (or will be). .. py:attribute:: parset :type: pathlib.Path The output location that the generated linmos parset has been written to .. py:attribute:: weight_fits :type: pathlib.Path Path to the output weight image formed through the linmos process .. py:class:: TrimImageResult Bases: :py:obj:`NamedTuple` The constructed path and the bounding box .. py:attribute:: bounding_box :type: BoundingBox The bounding box that was applied to the image .. py:attribute:: path :type: pathlib.Path The path to the trimmed image .. py:function:: _create_bound_box_plane(image_data: numpy.ndarray, is_masked: bool = False) -> BoundingBox | None Create a bounding box around pixels in a 2D image. If all pixels are not valid, then ``None`` is returned. :param image_data: The 2D image to construct a bounding box around :type image_data: np.ndarray :param is_masked: Whether to treat the image as booleans or values. Defaults to False. :type is_masked: bool, optional :returns: None if no valid pixels, a bounding box with the (xmin,xmax,ymin,ymax) of valid pixels :rtype: Optional[BoundingBox] .. py:function:: _file_list_to_string(file_list: Collection[pathlib.Path]) -> str .. py:function:: _get_alpha_linmos_option(pol_axis: float | None = None) -> str Compute the appropriate alpha term for linmos that is used to describe the differential rotation of the ASKAP third-axis and the footprint layout. The typical holography rotation is -45 degs. Internally the `alpha` term is computed as: >>> pol_axis - EXPECTED_HOLOGRAPHY_ROTATION_CONSTANT_RADIANS :param pol_axis: The prescribed polarisation axis value described in a MS. Defaults to None. :type pol_axis: Optional[float], optional :returns: Yandasoft linmos option to rotation the holography cubes :rtype: str .. py:function:: _get_holography_linmos_options(holofile: pathlib.Path | None = None, pol_axis: float | None = None, remove_leakage: bool = False, stokesi_images: Collection[pathlib.Path] | None = None) -> str Construct the appropriate set of linmos options that describe the use of the holography cube file to primary beam correct the input images. This includes appropriately rotating the holography (see `_get_alpha_linmos_options`). :param holofile: Path to the holography cube file to primary beam correct with. Defaults to None. :type holofile: Optional[Path], optional :param pol_axis: The rotation of the third axis as described in an ASAKP MS. Defaults to None. :type pol_axis: Optional[float], optional :param remove_leakage: Add the directive to remove leakage. Defaults to False. :type remove_leakage: bool, optional :returns: Set of linmos options to add to a parset file :rtype: str .. py:function:: _get_image_weight_plane(image_data: numpy.ndarray, mode: Literal['std', 'mad'] = 'mad', stride: int = 4) -> float Extract the inverse variance weight for an input plane of data Modes are 'std' or 'mad'. :param image_data: Data to consider :type image_data: np.ndarray :param mode: Statistic computation mode. Defaults to "mad". :type mode: str, optional :param stride: Include every n'th pixel when computing the weight. '1' includes all pixels. Defaults to 1. :type stride: int, optional :raises ValueError: Raised when modes unknown :returns: The inverse variance weight computerd :rtype: float .. py:function:: _linmos_cleanup(linmos_parset_summary: LinmosParsetSummary) -> tuple[pathlib.Path, Ellipsis] Clean up linmos files if requested. :param linmos_parset_summary: Parset summary from which the text file weights are gathered for deletion from :type linmos_parset_summary: LinmosParsetSummary :returns: Set of files removed :rtype: Tuple[Path, ...] .. py:function:: cli() -> None .. py:function:: create_bound_box(image_data: numpy.ndarray, is_masked: bool = False) -> BoundingBox Construct a bounding box around finite pixels for a 2D image. If a cube ids provided, the bounding box is constructed from pixels as broadcast across all of the non-spatial dimensions. That is to say the single bounding box can be projected across all channel/stokes channels If ``is_mask` is ``False``, the ``image_data`` will be masked internally using ``numpy.isfinite``. :param image_data: The image data that will have a bounding box constructed for. :type image_data: np.ndarray :param is_masked: if this is ``True`` the ``image_data`` are treated as a boolean mask array. Defaults to False. :type is_masked: bool, optional :returns: The tight bounding box around pixels. :rtype: BoundingBox .. py:function:: generate_linmos_parameter_set(images: Collection[pathlib.Path], linmos_names: flint.naming.LinmosNames, linmos_options: LinmosOptions, weight_list: str | None = None) -> LinmosParsetSummary Generate a parset file that will be used with the yandasoft linmos task. :param images: The images that will be coadded into a single field image. :type images: Collection[Path] :param linmos_names: Names of the output image and weights that linmos will produces. The weight image will have a similar name. Defaults to "linmos_field". :type linmos_names: LinmosNames :param linmos_options: Options that are passed through to the yandasoft linmos application. :type linmos_options: LinmosOptions :param weight_list: If not None, this string will be embedded into the yandasoft linmos parset as-is. It should represent the formatted string pointing to weight files, and should be equal length of the input images. If None it is internally generated. Defaults to None. :type weight_list: str, optional :returns: Important components around the generated parset file. :rtype: LinmosParsetSummary .. py:function:: generate_weights_list_and_files(image_paths: Collection[pathlib.Path], mode: str = 'mad', stride: int = 1) -> tuple[pathlib.Path, Ellipsis] Generate the expected linmos weight files, and construct an appropriate string that can be embedded into a linmos partset. These weights files will appear as: >>> #Channel Weight >>> 0 1234.5 >>> 1 6789.0 The weights should be correct relative to the entire set of input images. They do not necessarily have to correspond to an accurate measure of the RMS. This function will create a corresponding text file for each input image. At the moment it is only intended to work on MFS images. It *is not* currently intended to be used on image cubes. The stride parameter will only include every N'th pixel when computing the weights. A smaller set of pixels will reduce the time required to calculate the weights, but may come at the cost of accuracy with large values. :param image_paths: Images to iterate over to create a corresponding weights.txt file. :type image_paths: Collection[Path] :param mode: The mode to use when calling get_image_weight :type mode: str, optional :returns: A list of paths pointing to the weights for each input image :rtype: Tuple[Path, ...] .. py:function:: get_image_weight(image_path: pathlib.Path, mode: str = 'mad', stride: int = 1, image_slice: int = 0) -> list[float] Compute an image weight supplied to linmos, which is used for optimally weighting overlapping images. Supported modes are 'mad' and 'mtd', which simply resolve to their numpy equivalents. This weight is really a relative weight to used between all images in a set of images being co-added together. So long as these are all calculated in the same way, it does not necessarily have to correspond to an optimatelly calculated RMS. The stride parameter will only include every N'th pixel when computing the weights. A smaller set of pixels will reduce the time required to calculate the weights, but may come at the cost of accuracy with large values. :param image: The path to the image fits file to inspect. :type image: Path :param mode: Which mode should be used when calculating the weight. Defaults to 'mad'. :type mode: str, optional :param stride: Include every n'th pixel when computing the weight. '1' includes all pixels. Defaults to 1. :type stride: int, optional :param image_slice: The image slice in the HDU list of the `image` fits file to inspect. Defaults to 0. :type image_slice: int, optional :raises ValueError: Raised when a mode is requested but does not exist :returns: The weight per channel to supply to linmos :rtype: List[float] .. py:function:: get_parser() -> argparse.ArgumentParser .. py:function:: linmos_images(images: Collection[pathlib.Path], linmos_options: LinmosOptions, parset_output_path: pathlib.Path | None = None, weight_list: str | None = None, container: pathlib.Path = Path('yandasoft.sif')) -> LinmosResult Create a linmos parset file and execute it. :param images: The images that will be coadded into a single field image. :type images: Collection[Path] :param linmos_options: Options to control the yandasott linmos program and related features. :type linmos_options: LinmosOptions :param parset_output_path: Path of the output linmos parset file. If None it is derived from common input fields. Defaults to None. :type parset_output_path: Path | None, optional :param weight_list: If not None, this string will be embedded into the yandasoft linmos parset as-is. It should represent the formatted string pointing to weight files, and should be equal length of the input images. If None it is internally generated. Defaults to None. :type weight_list: str, optional :returns: The linmos command executed and the associated parset file :rtype: LinmosResult .. py:function:: trim_fits_image(image_path: pathlib.Path, bounding_box: BoundingBox | None = None) -> TrimImageResult Trim the FITS image produces by linmos to remove as many empty pixels around the border of the image as possible. This is an inplace operation. Pixels that have a value of 0.0 are first filled with nan values before trimming. :param image_path: The FITS image that will have its border trimmed :type image_path: Path :param bounding_box: The bounding box that will be applied to the image. If None it is computed. Defaults to None. :type bounding_box: Optional[BoundingBox], optional :returns: Path of the FITS image that had its border trimmed :rtype: Path .. py:data:: EXPECTED_HOLOGRAPHY_ROTATION_CONSTANT_RADIANS