Пример #1
0
def test__array_with_offset_through_arctic():

    arr = ac.Array2D.manual(
        array=[[1.0, 2.0], [3.0, 4.0]],
        pixel_scales=1.0,
        header=ac.Header(header_sci_obj=None,
                         header_hdu_obj=None,
                         readout_offsets=(3, 5)),
    ).native

    roe = ac.ROE(
        dwell_times=[1.0],
        empty_traps_between_columns=True,
        empty_traps_for_first_transfers=False,
        force_release_away_from_readout=True,
        use_integer_express_matrix=False,
    )
    ccd_phase = ac.CCDPhase(full_well_depth=1e3,
                            well_notch_depth=0.0,
                            well_fill_power=1.0)
    ccd = ac.CCD(phases=[ccd_phase], fraction_of_traps_per_phase=[1.0])
    traps = [ac.TrapInstantCapture(10.0, -1.0 / np.log(0.5))]

    image_via_arctic = cti.add_cti(
        image=arr,
        parallel_traps=traps,
        parallel_ccd=ccd,
        parallel_roe=roe,
        parallel_express=3,
        parallel_offset=3,
    )

    clocker = ac.Clocker2D(parallel_express=3, parallel_roe=roe)

    image_via_clocker = clocker.add_cti(data=arr,
                                        parallel_trap_list=traps,
                                        parallel_ccd=ccd_phase)

    assert image_via_arctic == pytest.approx(image_via_clocker, 1.0e-4)

    image_via_arctic = cti.add_cti(
        image=arr,
        serial_traps=traps,
        serial_ccd=ccd,
        serial_roe=roe,
        serial_express=2,
        serial_offset=5,
    )

    clocker = ac.Clocker2D(serial_express=2, serial_roe=roe)

    image_via_clocker = clocker.add_cti(data=arr,
                                        serial_trap_list=traps,
                                        serial_ccd=ccd_phase)

    assert image_via_arctic == pytest.approx(image_via_clocker, 1.0e-4)
Пример #2
0
    def add_cti(
        self,
        data: aa.Array1D,
        ccd: Optional[CCDPhase] = None,
        trap_list: Optional[List[AbstractTrap]] = None,
    ) -> aa.Array1D:
        """
        Add CTI to a 1D dataset by passing it from the c++ arctic clocking algorithm.

        The c++ arctic wrapper takes as input a 2D ndarray, therefore this function converts the input 1D data to
        a 2D ndarray where the second dimension is 1, passes this from arctic and then flattens the 2D ndarray that
        is returned by to a 1D `Array1D` object with the input data's dimensions.

        Parameters
        ----------
        data
            The 1D data that is clocked via arctic and has CTI added to it.
        ccd
            The ccd phase settings describing the volume-filling behaviour of the CCD which characterises the capture
            and release of electrons and therefore CTI.
        trap_list
            A list of the trap species on the CCD which capture and release electrons during clock to as to add CTI.
        """
        self.check_traps(trap_list_0=trap_list)
        self.check_ccd(ccd_list=[ccd])

        image_pre_cti_2d = aa.Array2D.zeros(
            shape_native=(data.shape_native[0], 1),
            pixel_scales=data.pixel_scales).native

        image_pre_cti_2d[:, 0] = data

        ccd = self.ccd_from(ccd_phase=ccd)

        image_post_cti = cti.add_cti(
            image=image_pre_cti_2d,
            parallel_ccd=ccd,
            parallel_roe=self.roe,
            parallel_traps=trap_list,
            parallel_express=self.express,
            parallel_offset=data.readout_offsets[0],
            parallel_window_start=self.window_start,
            parallel_window_stop=self.window_stop,
            verbosity=self.verbosity,
        )

        return aa.Array1D.manual_native(array=image_post_cti.flatten(),
                                        pixel_scales=data.pixel_scales)
Пример #3
0
    def add_cti_poisson_traps(
        self,
        data: aa.Array2D,
        parallel_ccd: Optional[CCDPhase] = None,
        parallel_trap_list: Optional[List[AbstractTrap]] = None,
        serial_ccd: Optional[CCDPhase] = None,
        serial_trap_list: Optional[List[AbstractTrap]] = None,
    ) -> aa.Array2D:
        """
        Add CTI to a 2D dataset by passing it to the c++ arctic clocking algorithm.

        Clocking is performed towards the readout register and electronics, with parallel CTI added first followed
        by serial CTI. If both parallel and serial CTI are added, parallel CTI is added and the post-CTI image
        (therefore including trailing after parallel clocking) is used to perform serial clocking and add serial CTI.

        This algorithm adds CTI via arctic in the same way as the normal `add_cti` function, however for parallel
        clocking the density of traps in every column is drawn from a Poisson distribution to represent the stochastic
        nature of how many traps are in each column of a real CCD.

        Parameters
        ----------
        data
            The 1D data that is clocked via arctic and has CTI added to it.
        parallel_ccd
            The ccd phase settings describing the volume-filling behaviour of the CCD which characterises the capture
            and release of electrons and therefore CTI for clocking in the parallel direction.
        parallel_trap_list
            A list of the parallel trap species on the CCD which capture and release electrons during parallel clocking
            which adds CTI.
        serial_ccd
            The ccd phase settings describing the volume-filling behaviour of the CCD which characterises the capture
            and release of electrons and therefore CTI for clocking in the serial direction.
        serial_trap_list
            A list of the serial trap species on the CCD which capture and release electrons during serial clocking
            which adds CTI.
        """
        self.check_traps(trap_list_0=parallel_trap_list, trap_list_1=serial_trap_list)
        self.check_ccd(ccd_list=[parallel_ccd, serial_ccd])

        parallel_ccd = self.ccd_from(ccd_phase=parallel_ccd)

        try:
            parallel_offset = data.readout_offsets[0]
        except AttributeError:
            parallel_offset = 0

        image_pre_cti = data.native
        image_post_cti = np.zeros(data.shape_native)

        total_rows = image_post_cti.shape[0]
        total_columns = image_post_cti.shape[1]

        parallel_trap_column_list = []

        for column in range(total_columns):

            parallel_trap_poisson_list = [
                parallel_trap.poisson_density_from(
                    total_pixels=total_rows, seed=self.poisson_seed
                )
                for parallel_trap in parallel_trap_list
            ]

            parallel_trap_column_list.append(parallel_trap_poisson_list)

            image_pre_cti_pass = np.zeros(shape=(total_rows, 1))
            image_pre_cti_pass[:, 0] = image_pre_cti[:, column]

            image_post_cti[:, column] = cti.add_cti(
                image=image_pre_cti_pass,
                parallel_ccd=parallel_ccd,
                parallel_roe=self.parallel_roe,
                parallel_traps=parallel_trap_poisson_list,
                parallel_express=self.parallel_express,
                parallel_offset=parallel_offset,
                parallel_window_start=self.parallel_window_start,
                parallel_window_stop=self.parallel_window_stop,
                verbosity=self.verbosity,
            )[:, 0]

        self.parallel_trap_column_list = parallel_trap_column_list

        serial_ccd = self.ccd_from(ccd_phase=serial_ccd)

        try:
            serial_offset = data.readout_offsets[1]
        except AttributeError:
            serial_offset = 0

        image_post_cti = cti.add_cti(
            image=image_post_cti,
            serial_ccd=serial_ccd,
            serial_roe=self.serial_roe,
            serial_traps=serial_trap_list,
            serial_express=self.serial_express,
            serial_offset=serial_offset,
            serial_window_start=self.serial_window_start,
            serial_window_stop=self.serial_window_stop,
            verbosity=self.verbosity,
        )

        try:
            return aa.Array2D.manual_mask(array=image_post_cti, mask=data.mask).native
        except AttributeError:
            return image_post_cti
Пример #4
0
    def add_cti_serial_fast(
        self,
        data: aa.Array2D,
        serial_ccd: Optional[CCDPhase] = None,
        serial_trap_list: Optional[List[AbstractTrap]] = None,
        perform_checks: bool = True,
    ):
        """
        Add CTI to a 2D dataset by passing it to the c++ arctic clocking algorithm.

        Clocking is performed towards the readout register and electronics, with parallel CTI added first followed
        by serial CTI. If both parallel and serial CTI are added, serial CTI is added and the post-CTI image
        (therefore including trailing after serial clocking) is used to perform serial clocking and add serial CTI.

        For 2D images where the same signal is repeated over all columns (e.g. uniform charge injection imaging)
        the CTI added to each row via arctic is identical. Therefore, this function speeds up CTI addition by
        only a single column to arcitc once and copying the output column the NumPy array to construct the the final
        post-cti image.

        This only works for serial CTI when parallel CTI is omitted.

        By default, checks are performed which ensure that the input data fits the criteria for this speed up.

        Parameters
        ----------
        data
            The 1D data that is clocked via arctic and has CTI added to it.
        serial_ccd
            The ccd phase settings describing the volume-filling behaviour of the CCD which characterises the capture
            and release of electrons and therefore CTI for clocking in the serial direction.
        serial_trap_list
            A list of the serial trap species on the CCD which capture and release electrons during serial clocking
            which adds CTI.
        perform_checks
            Check that it is value for the input data to use the fast clocking speed up (e.g. all columns are identical
            and all entries outside this region are zero).
        """

        image_pre_cti = data.native
        if perform_checks:
            self._check_serial_fast(image_pre_cti=image_pre_cti)

        self.check_traps(trap_list_0=serial_trap_list)
        self.check_ccd(ccd_list=[serial_ccd])

        serial_ccd = self.ccd_from(ccd_phase=serial_ccd)

        image_pre_cti_pass = np.zeros(shape=(1, data.shape[1]))
        image_pre_cti_pass[0, :] = image_pre_cti[self.serial_fast_pixels[0], :]

        image_post_cti_pass = cti.add_cti(
            image=image_pre_cti_pass,
            serial_ccd=serial_ccd,
            serial_roe=self.serial_roe,
            serial_traps=serial_trap_list,
            serial_express=self.serial_express,
            serial_offset=0,
            verbosity=self.verbosity,
        )

        image_post_cti = copy.copy(data.native)

        image_post_cti[
            self.serial_fast_pixels[0] : self.serial_fast_pixels[1], :
        ] = image_post_cti_pass

        return image_post_cti
Пример #5
0
    def add_cti(
        self,
        data: aa.Array2D,
        parallel_ccd: Optional[CCDPhase] = None,
        parallel_trap_list: Optional[List[AbstractTrap]] = None,
        serial_ccd: Optional[CCDPhase] = None,
        serial_trap_list: Optional[List[AbstractTrap]] = None,
    ) -> aa.Array2D:
        """
        Add CTI to a 2D dataset by passing it to the c++ arctic clocking algorithm.

        Clocking is performed towards the readout register and electronics, with parallel CTI added first followed
        by serial CTI. If both parallel and serial CTI are added, parallel CTI is added and the post-CTI image
        (therefore including trailing after parallel clocking) is used to perform serial clocking and add serial CTI.

        If the flag `parallel_poisson_traps=True` the parallel clocking algorithm is sent through the alternative
        function `add_cti_poisson_traps`.  This adds CTI via arctic in the same way, however for parallel clocking
        the density of traps in every column is drawn from a Poisson distribution to represent the stochastic
        nature of how many traps are in each column of a real CCD.

        Parameters
        ----------
        data
            The 1D data that is clocked via arctic and has CTI added to it.
        parallel_ccd
            The ccd phase settings describing the volume-filling behaviour of the CCD which characterises the capture
            and release of electrons and therefore CTI for clocking in the parallel direction.
        parallel_trap_list
            A list of the parallel trap species on the CCD which capture and release electrons during parallel clocking
            which adds CTI.
        serial_ccd
            The ccd phase settings describing the volume-filling behaviour of the CCD which characterises the capture
            and release of electrons and therefore CTI for clocking in the serial direction.
        serial_trap_list
            A list of the serial trap species on the CCD which capture and release electrons during serial clocking
            which adds CTI.
        """

        if self.parallel_poisson_traps:
            return self.add_cti_poisson_traps(
                data=data,
                parallel_ccd=parallel_ccd,
                parallel_trap_list=parallel_trap_list,
                serial_ccd=serial_ccd,
                serial_trap_list=serial_trap_list,
            )

        if self.parallel_fast_pixels is not None:
            return self.add_cti_parallel_fast(
                data=data,
                parallel_ccd=parallel_ccd,
                parallel_trap_list=parallel_trap_list,
            )

        if self.serial_fast_pixels is not None:
            return self.add_cti_serial_fast(
                data=data, serial_ccd=serial_ccd, serial_trap_list=serial_trap_list
            )

        self.check_traps(trap_list_0=parallel_trap_list, trap_list_1=serial_trap_list)
        self.check_ccd(ccd_list=[parallel_ccd, serial_ccd])

        parallel_ccd = self.ccd_from(ccd_phase=parallel_ccd)
        serial_ccd = self.ccd_from(ccd_phase=serial_ccd)

        try:
            parallel_offset = data.readout_offsets[0]
            serial_offset = data.readout_offsets[1]
        except AttributeError:
            parallel_offset = 0
            serial_offset = 0

        image_post_cti = cti.add_cti(
            image=data,
            parallel_ccd=parallel_ccd,
            parallel_roe=self.parallel_roe,
            parallel_traps=parallel_trap_list,
            parallel_express=self.parallel_express,
            parallel_offset=parallel_offset,
            parallel_window_start=self.parallel_window_start,
            parallel_window_stop=self.parallel_window_stop,
            serial_ccd=serial_ccd,
            serial_roe=self.serial_roe,
            serial_traps=serial_trap_list,
            serial_express=self.serial_express,
            serial_offset=serial_offset,
            serial_window_start=self.serial_window_start,
            serial_window_stop=self.serial_window_stop,
            verbosity=self.verbosity,
        )

        try:
            return aa.Array2D.manual_mask(array=image_post_cti, mask=data.mask).native
        except AttributeError:
            return image_post_cti