Exemplo n.º 1
0
def test_snrmap_fast(get_frame):
    frame, positions = get_frame
    y0, x0 = positions
    snmap = snrmap(frame.data, fwhm=frame.fwhm, plot=plot, approximated=True,
                   nproc=2)
    y1, x1 = np.where(snmap == snmap.max())
    assert np.allclose(x1, x0, atol=atol) and np.allclose(y1, y0, atol=atol)
def calc_snr(planet_photons, astro_dict, plot=False):
    derot_image = reduce_image(planet_photons)
    planet_loc = find_loc(astro_dict, derot_image)

    snr = pix_snr_loc(derot_image,
                      planet_loc - mp.array_size // 2,
                      config['data']['fwhm'],
                      verbose=True)[0]

    if plot:
        fig = plt.figure(figsize=(12, 6))
        ax = fig.add_subplot(121)
        pcm = ax.imshow(derot_image, origin='lower')
        fig.colorbar(pcm, ax=ax)
        aper = plt.Circle(planet_loc[::-1],
                          radius=config['data']['fwhm'] / 2.,
                          color='r',
                          fill=False,
                          alpha=0.8)
        ax.add_patch(aper)
        ax = fig.add_subplot(122)
        snrimage = snrmap(derot_image, fwhm=config['data']['fwhm'], nproc=8)
        pcm = ax.imshow(snrimage, origin='lower')
        fig.colorbar(pcm, ax=ax)
        plt.show()

    return snr
Exemplo n.º 3
0
def test_snrmap_masked(get_frame):
    frame, positions = get_frame
    y0, x0 = positions
    snmap = snrmap(frame.data, fwhm=frame.fwhm, plot=plot, nproc=2,
                   known_sources=(int(x0), int(y0)))
    y1, x1 = np.where(snmap == snmap.max())
    assert np.allclose(x1, x0, atol=atol) and np.allclose(y1, y0, atol=atol)
Exemplo n.º 4
0
    def postprocessing(self, do_adi=True, do_adi_contrast=True, do_pca_full=True, do_pca_ann=True, cropped=True,
                       do_snr_map=True, do_snr_map_opt=True, delta_rot=(0.5, 3), mask_IWA=1, overwrite=True, plot=True,
                       verbose=True, debug=False):
        """ 
        For post processing the master cube via median ADI, full frame PCA-ADI, or annular PCA-ADI. Includes constrast
        curves and SNR maps.

        Parameters:
        ***********
        do_adi : bool
            Whether to do a median-ADI processing
        do_adi_contrast : bool
            Whether to compute contrast curve associated to median-ADI
        do_pca_full : bool
            Whether to apply PCA-ADI on full frame
        do_pca_ann : bool, default is False
            Whether to apply annular PCA-ADI (more computer intensive). Only runs if cropped=True
        cropped : bool
            whether the master cube was cropped in pre-processing
        do_snr_map : bool
            whether to compute an SNR map (warning: computer intensive); useful only when point-like features are seen
            in the image
        do_snr_map_opt : bool
            Whether to compute a non-conventional (more realistic) SNR map
        delta_rot : tuple
            Threshold in rotation angle used in pca_annular to include frames in the PCA library (provided in terms of
            FWHM). See description of pca_annular() for more details
        mask_IWA : int, default 1
            Size of the numerical mask that hides the inner part of post-processed images. Provided in terms of fwhm
        overwrite : bool, default True
            whether to overwrite pre-exisiting output files from previous reductions
        plot : bool
            Whether to save plots to the output path (PDF file, print quality)
        verbose : bool
            prints more output when True                 
        debug : bool, default is False
            Saves extra output files
        """

        # make directories if they don't exist
        print("======= Starting post-processing....=======")
        outpath_sub = self.outpath + "sub_npc{}/".format(self.npc)

        if not isdir(outpath_sub):
            os.system("mkdir " + outpath_sub)

        if verbose:
            print('Input path is {}'.format(self.inpath))
            print('Output path is {}'.format(outpath_sub))

        source = self.dataset_dict['source']
        tn_shift = 0.568  # Launhardt et al. 2020, true North offset for NACO

        ADI_cube_name = '{}_master_cube.fits'  # template name for input master cube
        derot_ang_name = 'derot_angles.fits'  # template name for corresponding input derotation angles
        ADI_cube = open_fits(self.inpath + ADI_cube_name.format(source), verbose=verbose)
        derot_angles = open_fits(self.inpath + derot_ang_name, verbose=verbose) + tn_shift

        if do_adi_contrast:
            psfn_name = "master_unsat_psf_norm.fits"  # normalised PSF
            flux_psf_name = "master_unsat-stellarpsf_fluxes.fits"  # flux in a FWHM aperture found in calibration
            psfn = open_fits(self.inpath + psfn_name, verbose=verbose)
            starphot = open_fits(self.inpath + flux_psf_name, verbose=verbose)[1]  # scaled fwhm flux is the second entry

        mask_IWA_px = mask_IWA * self.fwhm
        if verbose:
            print("adopted mask size: {:.0f}".format(mask_IWA_px))

        ann_sz = 3  # if PCA-ADI in a single annulus or in concentric annuli, this is the size of the annulus/i in FWHM
        svd_mode = 'lapack'  # python package used for Singular Value Decomposition for PCA reductions
        n_randsvd = 3  # if svd package is set to 'randsvd' number of times we do PCA rand-svd, before taking the
        # median of all results (there is a risk of significant self-subtraction when just doing it once)
        ref_cube = None  # if any, load here a centered calibrated cube of reference star observations - would then be
        # used for PCA instead of the SCI cube itself

        # TEST number of principal components
        # PCA-FULL
        if do_pca_full:
            test_pcs_full = list(range(1, self.npc + 1))
        # PCA-ANN
        if do_pca_ann:
            test_pcs_ann = list(range(1, self.npc + 1))  # needs a cropped cube

        ######################### Simple ADI ###########################
        if do_adi:
            if not isfile(outpath_sub + 'final_ADI_simple.fits') or overwrite:
                if debug:  # saves the residuals
                    tmp, _, tmp_tmp = median_sub(ADI_cube, derot_angles, fwhm=self.fwhm,
                                                 radius_int=0, asize=ann_sz, delta_rot=delta_rot,
                                                 full_output=debug, verbose=verbose)
                    tmp = mask_circle(tmp, mask_IWA_px)
                    write_fits(outpath_sub + 'TMP_ADI_simple_cube_der.fits', tmp, verbose=verbose)

                # make median combination of the de-rotated cube.
                tmp_tmp = median_sub(ADI_cube, derot_angles, fwhm=self.fwhm,
                                     radius_int=0, asize=ann_sz, delta_rot=delta_rot,
                                     full_output=False, verbose=verbose)
                tmp_tmp = mask_circle(tmp_tmp, mask_IWA_px)  # we mask the IWA
                write_fits(outpath_sub + 'final_ADI_simple.fits', tmp_tmp, verbose=verbose)

            ## SNR map
            if (not isfile(outpath_sub + 'final_ADI_simple_snrmap.fits') or overwrite) and do_snr_map:
                tmp = open_fits(outpath_sub + 'final_ADI_simple.fits', verbose=verbose)
                tmp = mask_circle(tmp, mask_IWA_px)
                tmp_tmp = snrmap(tmp, self.fwhm, nproc=self.nproc, verbose=debug)
                write_fits(outpath_sub + 'final_ADI_simple_snrmap.fits', tmp_tmp, verbose=verbose)

            ## Contrast curve
            if (not isfile(outpath_sub + 'contrast_adi.pdf') or overwrite) and do_adi_contrast:
                _ = contrast_curve(ADI_cube, derot_angles, psfn, self.fwhm, pxscale=self.pixel_scale,
                                   starphot=starphot, algo=median_sub, sigma=5., nbranch=1, theta=0,
                                   inner_rad=1, wedge=(0, 360), student=True, transmission=None,
                                   smooth=True, plot=plot, dpi=300, debug=debug,
                                   save_plot=outpath_sub + 'contrast_adi.pdf', verbose=verbose)
            if verbose:
                print("======= Completed Median-ADI =======")

        ####################### PCA-ADI full ###########################
        if do_pca_full:

            test_pcs_str_list = [str(x) for x in test_pcs_full]
            ntest_pcs = len(test_pcs_full)
            test_pcs_str = "npc" + "-".join(test_pcs_str_list)
            PCA_ADI_cube = ADI_cube.copy()
            tmp_tmp = np.zeros([ntest_pcs, PCA_ADI_cube.shape[1], PCA_ADI_cube.shape[2]])

            if do_snr_map_opt:
                tmp_tmp_tmp_tmp = np.zeros([ntest_pcs, PCA_ADI_cube.shape[1], PCA_ADI_cube.shape[2]])
            for pp, npc in enumerate(test_pcs_full):
                if svd_mode == 'randsvd':
                    tmp_tmp_tmp = np.zeros([n_randsvd, PCA_ADI_cube.shape[1], PCA_ADI_cube.shape[2]])
                    for nr in range(n_randsvd):
                        tmp_tmp_tmp[nr] = pca(PCA_ADI_cube, angle_list=derot_angles, cube_ref=ref_cube,
                                              scale_list=None, ncomp=int(npc),
                                              svd_mode='randsvd', scaling=None, mask_center_px=mask_IWA_px,
                                              delta_rot=delta_rot, fwhm=self.fwhm, collapse='median', check_memory=True,
                                              full_output=False, verbose=verbose)
                    tmp_tmp[pp] = np.median(tmp_tmp_tmp, axis=0)
                else:
                    if not isfile(outpath_sub + 'final_PCA-ADI_full_' + test_pcs_str + '.fits') or overwrite:
                        tmp_tmp[pp] = pca(PCA_ADI_cube, angle_list=derot_angles, cube_ref=ref_cube,
                                          scale_list=None, ncomp=int(npc),
                                          svd_mode=svd_mode, scaling=None, mask_center_px=mask_IWA_px,
                                          delta_rot=delta_rot, fwhm=self.fwhm, collapse='median', check_memory=True,
                                          full_output=False, verbose=verbose)
                    if (not isfile(outpath_sub + 'final_PCA-ADI_full_' +test_pcs_str+'_snrmap_opt.fits') or overwrite) \
                            and do_snr_map_opt:
                        tmp_tmp_tmp_tmp[pp] = pca(PCA_ADI_cube, angle_list=-derot_angles, cube_ref=ref_cube,
                                                  scale_list=None, ncomp=int(npc),
                                                  svd_mode=svd_mode, scaling=None, mask_center_px=mask_IWA_px,
                                                  delta_rot=delta_rot, fwhm=self.fwhm, collapse='median',
                                                  check_memory=True,
                                                  full_output=False, verbose=verbose)
            if not isfile(outpath_sub + 'final_PCA-ADI_full_' + test_pcs_str + '.fits') or overwrite:
                write_fits(outpath_sub + 'final_PCA-ADI_full_' + test_pcs_str + '.fits', tmp_tmp, verbose=verbose)

            if (not isfile(outpath_sub + 'neg_PCA-ADI_full_' + test_pcs_str + '.fits') or overwrite) and do_snr_map_opt:
                write_fits(outpath_sub + 'neg_PCA-ADI_full_' + test_pcs_str + '.fits',
                           tmp_tmp_tmp_tmp, verbose=verbose)
            ### Convolution
            if not isfile(outpath_sub + 'final_PCA-ADI_full_' + test_pcs_str + '_conv.fits') or overwrite:
                tmp = open_fits(outpath_sub + 'final_PCA-ADI_full_' + test_pcs_str + '.fits', verbose=verbose)
                for nn in range(tmp.shape[0]):
                    tmp[nn] = frame_filter_lowpass(tmp[nn], fwhm_size=self.fwhm, gauss_mode='conv')
                write_fits(outpath_sub + 'final_PCA-ADI_full_' + test_pcs_str + '_conv.fits', tmp, verbose=verbose)

            ### SNR map
            if (not isfile(outpath_sub + 'final_PCA-ADI_full_' + test_pcs_str + '_snrmap.fits') or overwrite) \
                    and do_snr_map:
                tmp = open_fits(outpath_sub + 'final_PCA-ADI_full_' + test_pcs_str + '.fits', verbose=verbose)
                for pp in range(ntest_pcs):
                    tmp[pp] = snrmap(tmp[pp], self.fwhm, nproc=self.nproc, verbose=debug)
                    tmp[pp] = mask_circle(tmp[pp], mask_IWA_px)
                write_fits(outpath_sub + 'final_PCA-ADI_full_' + test_pcs_str + '_snrmap.fits', tmp, verbose=verbose)

            ### SNR map optimized
            if (not isfile(outpath_sub + 'final_PCA-ADI_full_' + test_pcs_str + '_snrmap_opt.fits') or overwrite) \
                    and do_snr_map_opt:
                tmp = open_fits(outpath_sub + 'final_PCA-ADI_full_' + test_pcs_str + '.fits', verbose=verbose)
                for pp in range(ntest_pcs):
                    tmp[pp] = snrmap(tmp[pp], self.fwhm, array2=tmp_tmp_tmp_tmp[pp], incl_neg_lobes=False,
                                     nproc=self.nproc, verbose=debug)
                    tmp[pp] = mask_circle(tmp[pp], mask_IWA_px)
                write_fits(outpath_sub + 'final_PCA-ADI_full_' + test_pcs_str + '_snrmap_opt.fits', tmp,
                           verbose=verbose)

            if verbose:
                print("======= Completed PCA Full Frame =======")

        ######################## PCA-ADI annular #######################
        if do_pca_ann:
            if cropped == False:
                raise ValueError('PCA-ADI annular requires a cropped cube!')
            PCA_ADI_cube = ADI_cube.copy()
            del ADI_cube
            test_pcs_str_list = [str(x) for x in test_pcs_ann]
            ntest_pcs = len(test_pcs_ann)
            test_pcs_str = "npc" + "-".join(test_pcs_str_list)

            tmp_tmp = np.zeros([ntest_pcs, PCA_ADI_cube.shape[1], PCA_ADI_cube.shape[2]])
            if debug:
                array_der = np.zeros([ntest_pcs, PCA_ADI_cube.shape[0], PCA_ADI_cube.shape[1], PCA_ADI_cube.shape[2]])
                array_out = np.zeros([ntest_pcs, PCA_ADI_cube.shape[0], PCA_ADI_cube.shape[1], PCA_ADI_cube.shape[2]])
            if do_snr_map_opt:
                tmp_tmp_tmp_tmp = np.zeros([ntest_pcs, PCA_ADI_cube.shape[1], PCA_ADI_cube.shape[2]])

            for pp, npc in enumerate(test_pcs_ann):
                if debug and ((not isfile(outpath_sub + 'final_PCA-ADI_ann_' + test_pcs_str + '_residuals.fits') and
                               not isfile(outpath_sub + 'final_PCA-ADI_ann_' + test_pcs_str + '_residuals-derot.fits'))
                              or overwrite):
                    # saves residuals and median if debug is true and they either dont exist or are to be overwritten
                    array_out[pp], array_der[pp], tmp_tmp[pp] = pca_annular(PCA_ADI_cube, derot_angles,
                                                                            cube_ref=ref_cube, scale_list=None,
                                                                            radius_int=mask_IWA_px, fwhm=self.fwhm,
                                                                            asize=ann_sz * self.fwhm,
                                                                            n_segments=1, delta_rot=delta_rot, ncomp=int(npc),
                                                                            svd_mode=svd_mode, nproc=self.nproc,
                                                                            min_frames_lib=max(npc, 10),
                                                                            max_frames_lib=200, tol=1e-1, scaling=None,
                                                                            imlib='opencv',
                                                                            interpolation='lanczos4', collapse='median',
                                                                            ifs_collapse_range='all',
                                                                            full_output=debug, verbose=verbose)
                else:
                    if not isfile(outpath_sub + 'final_PCA-ADI_ann_' + test_pcs_str + '.fits') or overwrite:
                        tmp_tmp[pp] = pca_annular(PCA_ADI_cube, derot_angles, cube_ref=ref_cube, scale_list=None,
                                                  radius_int=mask_IWA_px, fwhm=self.fwhm, asize=ann_sz * self.fwhm,
                                                  n_segments=1, delta_rot=delta_rot, ncomp=int(npc),
                                                  svd_mode=svd_mode, nproc=self.nproc, min_frames_lib=max(npc, 10),
                                                  max_frames_lib=200, tol=1e-1, scaling=None, imlib='opencv',
                                                  interpolation='lanczos4', collapse='median', ifs_collapse_range='all',
                                                  full_output=False, verbose=verbose)
                if (not isfile(outpath_sub + 'final_PCA-ADI_ann_' + test_pcs_str + '_snrmap_opt.fits') or overwrite) and do_snr_map_opt:
                    tmp_tmp_tmp_tmp[pp] = pca_annular(PCA_ADI_cube, -derot_angles, cube_ref=ref_cube,
                                                      scale_list=None, radius_int=mask_IWA_px, fwhm=self.fwhm,
                                                      asize=ann_sz * self.fwhm, n_segments=1, delta_rot=delta_rot,
                                                      ncomp=int(npc), svd_mode=svd_mode,
                                                      nproc=self.nproc, min_frames_lib=max(npc, 10),
                                                      max_frames_lib=200, tol=1e-1, scaling=None, imlib='opencv',
                                                      interpolation='lanczos4', collapse='median',
                                                      ifs_collapse_range='all', full_output=False, verbose=verbose)
            if not isfile(outpath_sub + 'final_PCA-ADI_ann_' + test_pcs_str + '.fits') or overwrite:
                write_fits(outpath_sub + 'final_PCA-ADI_ann_' + test_pcs_str + '.fits', tmp_tmp, verbose=verbose)
            if debug and ((not isfile(outpath_sub + 'final_PCA-ADI_ann_' + test_pcs_str + '_residuals.fits') and
                           not isfile(outpath_sub + 'final_PCA-ADI_ann_' + test_pcs_str + '_residuals-derot.fits')) or overwrite):
                write_fits(outpath_sub + 'final_PCA-ADI_ann_' + test_pcs_str + '_residuals.fits', array_out, verbose=verbose)
                write_fits(outpath_sub + 'final_PCA-ADI_ann_' + test_pcs_str + '_residuals-derot.fits', array_der, verbose=verbose)

            if (not isfile(outpath_sub + 'final_PCA-ADI_ann_' + test_pcs_str + '_snrmap_opt.fits') or overwrite) and do_snr_map_opt:
                write_fits(outpath_sub + 'neg_PCA-ADI_ann_' + test_pcs_str + '.fits', tmp_tmp_tmp_tmp, verbose=verbose)

            ### Convolution
            if not isfile(outpath_sub + 'final_PCA-ADI_ann_' + test_pcs_str + '_conv.fits') or overwrite:
                tmp = open_fits(outpath_sub + 'final_PCA-ADI_ann_' + test_pcs_str + '.fits', verbose=verbose)
                for nn in range(tmp.shape[0]):
                    tmp[nn] = frame_filter_lowpass(tmp[nn], fwhm_size=self.fwhm, gauss_mode='conv')
                write_fits(outpath_sub + 'final_PCA-ADI_ann_' + test_pcs_str + '_conv.fits', tmp, verbose=verbose)

            ### SNR map
            if (not isfile(
                    outpath_sub + 'final_PCA-ADI_ann_' + test_pcs_str + '_snrmap.fits') or overwrite) and do_snr_map:
                tmp = open_fits(outpath_sub + 'final_PCA-ADI_ann_' + test_pcs_str + '.fits', verbose=verbose)
                for pp in range(ntest_pcs):
                    tmp[pp] = snrmap(tmp[pp], self.fwhm, nproc=self.nproc, verbose=debug)
                    tmp[pp] = mask_circle(tmp[pp], mask_IWA_px)
                write_fits(outpath_sub + 'final_PCA-ADI_ann_' + test_pcs_str + '_snrmap.fits', tmp, verbose=verbose)
            ### SNR map optimized
            if (not isfile(
                    outpath_sub + 'final_PCA-ADI_ann_' + test_pcs_str + '_snrmap_opt.fits') or overwrite) and do_snr_map_opt:
                tmp = open_fits(outpath_sub + 'final_PCA-ADI_ann_' + test_pcs_str + '.fits', verbose=verbose)
                for pp in range(ntest_pcs):
                    tmp[pp] = snrmap(tmp[pp], self.fwhm, plot=plot, array2=tmp_tmp_tmp_tmp[pp], nproc=self.nproc,
                                     verbose=debug)
                    tmp[pp] = mask_circle(tmp[pp], mask_IWA_px)
                write_fits(outpath_sub + 'final_PCA-ADI_ann_' + test_pcs_str + '_snrmap_opt.fits', tmp, verbose=verbose)

            if verbose:
                print("======= Completed PCA Annular =======")