Source code for httm.transformations.raw_converters_to_calibrated

# HTTM: A transformation library for RAW and Electron Flux TESS Images
# Copyright (C) 2016, 2017 John Doty and Matthew Wampler-Doty of Noqsi Aerospace, Ltd.
# 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


"""
``httm.transformations.raw_converters_to_calibrated``
=====================================================

Transformation functions for processing
:py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` objects so that
they are suitable for writing to a calibrated FITS file.

"""
from collections import OrderedDict

from .common import derive_transformation_function_list
from .raw_slices_to_calibrated import convert_slice_adu_to_electrons, remove_pattern_noise_from_slice, \
    remove_undershoot_from_slice, remove_smear_from_slice, remove_baseline_from_slice, \
    remove_start_of_line_ringing_from_slice
from ..data_structures.raw_converter import SingleCCDRawConverter


[docs]def convert_adu_to_electrons(raw_converter): # type: (SingleCCDRawConverter) -> SingleCCDRawConverter """ Converts a :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` from having *Analogue to Digital Converter Units* (ADU) to estimated electron counts by calling :py:func:`~httm.transformations.raw_slices_to_calibrated.convert_slice_adu_to_electrons` over each slice. :param raw_converter: A :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` which should \ have electrons for units for each of its slices :type raw_converter: :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` :rtype: :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` """ assert raw_converter.flags.in_adu, "Input should be in *Analogue to Digital Converter Units* (ADU)" image_slices = raw_converter.slices video_scales = raw_converter.parameters.video_scales assert len(video_scales) >= len(image_slices), "There should be at least as many video scales as slices" number_of_exposures = raw_converter.parameters.number_of_exposures gain_loss = raw_converter.parameters.gain_loss # noinspection PyProtectedMember return raw_converter._replace( slices=tuple(convert_slice_adu_to_electrons(gain_loss, number_of_exposures, video_scale, image_slice) for (video_scale, image_slice) in zip(video_scales, image_slices)), flags=raw_converter.flags._replace(in_adu=True))
[docs]def remove_baseline(raw_converter): # type: (SingleCCDRawConverter) -> SingleCCDRawConverter """ This function estimates *baseline* from the *dark pixels* for each slice in a :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` and compensates for this effect. Calls :py:func:`~httm.transformations.raw_slices_to_calibrated.remove_baseline_from_slice` over each slice. Note that if you do not remove baseline using this routine prior to removing undershoot, then artifacts are introduced at the early edge of a row. :param raw_converter: A :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` which should \ have *Analogue to Digital Converter Units* (ADU) for units for each of its slices :type raw_converter: :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` :rtype: :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` """ assert raw_converter.flags.baseline_present, "Baseline must be flagged as present" image_slices = raw_converter.slices early_dark_pixel_columns = raw_converter.parameters.early_dark_pixel_columns late_dark_pixel_columns = raw_converter.parameters.late_dark_pixel_columns # noinspection PyProtectedMember return raw_converter._replace( slices=tuple(remove_baseline_from_slice(early_dark_pixel_columns, late_dark_pixel_columns, image_slice) for image_slice in image_slices), flags=raw_converter.flags._replace(baseline_present=False))
[docs]def remove_pattern_noise(raw_converter): # type: (SingleCCDRawConverter) -> SingleCCDRawConverter """ Compensates for a fixed pattern noise, that varies from slice to slice, on a :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` by calling :py:func:`~httm.transformations.raw_slices_to_calibrated.remove_pattern_noise_from_slice` over each slice. :param raw_converter: A :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` which should \ have *Analogue to Digital Converter Units* (ADU) for each of its slices :type raw_converter: :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` :rtype: :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` """ from .. import resource_utilities assert raw_converter.flags.pattern_noise_present, "Pattern noise must be flagged as present" pattern_noises = resource_utilities.load_pattern_noise(raw_converter.parameters.pattern_noise) image_slices = raw_converter.slices assert len(pattern_noises) >= len(image_slices), "There should be at least as many noise patterns as slices" # noinspection PyProtectedMember return raw_converter._replace( slices=tuple(remove_pattern_noise_from_slice(pattern_noise, image_slice) for (pattern_noise, image_slice) in zip(pattern_noises, image_slices)), flags=raw_converter.flags._replace(pattern_noise_present=False))
[docs]def remove_start_of_line_ringing(raw_converter): # type: (SingleCCDRawConverter) -> SingleCCDRawConverter """ Compensates for *start of line ringing* on each row in a :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` by calling :py:func:`~httm.transformations.raw_slices_to_calibrated.remove_start_of_line_ringing_from_slice` over each slice. :param raw_converter: A :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` which should \ have electrons for units for each of its slices :type raw_converter: :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` :rtype: :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` """ assert raw_converter.flags.start_of_line_ringing_present, "Start of line ringing must be flagged as present" final_dark_pixel_rows = raw_converter.parameters.final_dark_pixel_rows # type: int image_slices = raw_converter.slices # noinspection PyProtectedMember return raw_converter._replace( slices=tuple(remove_start_of_line_ringing_from_slice(final_dark_pixel_rows, image_slice) for image_slice in image_slices), flags=raw_converter.flags._replace(start_of_line_ringing_present=False))
[docs]def remove_undershoot(raw_converter): # type: (SingleCCDRawConverter) -> SingleCCDRawConverter """ Removes *undershoot* from each row in a :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` by calling :py:func:`~httm.transformations.raw_slices_to_calibrated.remove_undershoot_from_slice` over each slice. :param raw_converter: A :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` which should \ have electrons for units for each of its slices :type raw_converter: :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` :rtype: :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` """ assert raw_converter.flags.undershoot_present, "Undershoot must be flagged as present" assert raw_converter.flags.baseline_present is False, "Baseline should be removed before removing undershoot" undershoot_parameter = raw_converter.parameters.undershoot_parameter image_slices = raw_converter.slices # noinspection PyProtectedMember return raw_converter._replace( slices=tuple(remove_undershoot_from_slice(undershoot_parameter, image_slice) for image_slice in image_slices), flags=raw_converter.flags._replace(undershoot_present=False))
[docs]def remove_smear(raw_converter): # type: (SingleCCDRawConverter) -> SingleCCDRawConverter """ Removes *smear* and zeroes the *smear rows* in a :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` by calling :py:func:`~httm.transformations.raw_slices_to_calibrated.remove_smear_from_slice` over each slice. :param raw_converter: A :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` which should \ have electrons for units for each of its slices :type raw_converter: :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` :rtype: :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` """ assert raw_converter.flags.smear_rows_present, "Smear rows must be flagged as present" final_dark_pixel_rows = raw_converter.parameters.final_dark_pixel_rows smear_rows = raw_converter.parameters.smear_rows late_dark_pixel_columns = raw_converter.parameters.late_dark_pixel_columns early_dark_pixel_columns = raw_converter.parameters.early_dark_pixel_columns image_slices = raw_converter.slices # noinspection PyProtectedMember return raw_converter._replace( slices=tuple(remove_smear_from_slice(early_dark_pixel_columns, late_dark_pixel_columns, final_dark_pixel_rows, smear_rows, image_slice) for image_slice in image_slices), flags=raw_converter.flags._replace(smear_rows_present=False))
[docs]def transform_raw_converter(raw_converter, transformation_settings=None): # type: (SingleCCDRawConverter, object) -> SingleCCDRawConverter """ Take a :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` and run specified transformations over it. :param raw_converter: A :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` to run a series of \ transformations over :type raw_converter: :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` :param transformation_settings: An object specifying which transformations to run; if not specified defaults are \ used :type transformation_settings: object :rtype: :py:class:`~httm.data_structures.raw_converter.SingleCCDRawConverter` """ from functools import reduce from .metadata import raw_transformations return reduce( lambda converter, transformation_function: transformation_function(converter), derive_transformation_function_list(transformation_settings, OrderedDict((key, raw_transformations[key]['default']) for key in raw_transformations.keys()), {key: raw_transformations[key]['function'] for key in raw_transformations.keys()}), raw_converter)