예제 #1
0
def do_photometry(params,
                  extname='newflux',
                  star_file='star_positions',
                  psf_file='psf.fits',
                  star_positions=None,
                  reference_image='ref.fits'):

    #
    # Determine our list of files
    #
    all_files = os.listdir(params.loc_data)
    all_files.sort()
    files = []
    for f in all_files:
        if fnmatch.fnmatch(f, params.name_pattern):
            g = DS.Observation(params.loc_data + os.path.sep + f, params)
            if g.fw > 0.0:
                files.append(g)

    ref = DS.Observation(params.loc_output + os.path.sep + reference_image,
                         params)
    ref.register(ref, params)

    #
    # Detect stars and compute the PSF if necessary
    #

    psf_file = params.loc_output + os.path.sep + psf_file
    star_file = params.loc_output + os.path.sep + star_file

    print psf_file
    print os.path.exists(psf_file)
    print star_file
    print os.path.exists(star_file)

    if not (os.path.exists(psf_file)) or not (os.path.exists(star_file)):
        stars = PH.compute_psf_image(params, ref, psf_image=psf_file)

    if star_positions is None:

        if os.path.exists(star_file):
            star_positions = np.genfromtxt(star_file)[:, :2]
        else:
            star_positions = stars[:, 0:2]

    #
    # Group the stars by location
    #
    star_group_boundaries = None
    detector_mean_positions_x = None
    detector_mean_positions_y = None
    star_sort_index,star_group_boundaries,detector_mean_positions_x,detector_mean_positions_y = \
       PH.group_stars_ccd(params,star_positions,params.loc_output+os.path.sep+reference_image)
    star_positions = star_positions[star_sort_index]
    star_unsort_index = np.argsort(star_sort_index)

    #
    # Process the reference image
    #
    print 'Processing', reference_image
    ref = DS.Observation(params.loc_output + os.path.sep + reference_image,
                         params)
    #reg = Observation(params.loc_data+os.path.sep+
    #                  params.registration_image,params)
    mask, _ = IO.read_fits_file(params.loc_output + os.path.sep + 'mask_' +
                                reference_image)
    variance, _ = IO.read_fits_file(params.loc_output + os.path.sep + 'var_' +
                                    reference_image)
    ref.mask = mask
    ref.inv_variance = 1.0 / variance + (1 - mask)
    ref.register(ref, params)
    smask = IM.compute_saturated_pixel_mask(ref.image, params)
    ref.inv_variance += (1 - (smask * mask)) * 1.e-12
    ktable = params.loc_output + os.path.sep + 'k_' + os.path.basename(
        reference_image)
    kernelIndex, extendedBasis, c, params = IO.read_kernel_table(
        ktable, params)
    kernelRadius = np.max(kernelIndex[:, 0]) + 1
    if np.sum(extendedBasis) > 0:
        kernelRadius += 1
    print 'kernelIndex', kernelIndex
    print 'extendedBasis', extendedBasis
    print 'coeffs', c
    print 'kernelRadius', kernelRadius
    print 'star_positions', star_positions.shape
    phot_target, _ = IO.read_fits_file(params.loc_output + os.path.sep +
                                       'clean_' + reference_image)
    ref.flux, ref.dflux = CIF.photom_all_stars_simultaneous(
        phot_target, ref.inv_variance, star_positions, psf_file, c,
        kernelIndex, extendedBasis, kernelRadius, params,
        star_group_boundaries, detector_mean_positions_x,
        detector_mean_positions_y)

    if isinstance(ref.flux, np.ndarray):
        if not (params.use_GPU):
            print 'ungrouping fluxes'
            ref.flux = ref.flux[star_unsort_index].copy()
            ref.dflux = ref.dflux[star_unsort_index].copy()
            print ref.flux.shape, star_positions.shape
        np.savetxt(
            params.loc_output + os.path.sep + reference_image + '.' + extname,
            np.vstack((ref.flux, ref.dflux)))

    #
    # Process difference images
    #
    for f in files:

        if not (os.path.exists(params.loc_output + os.path.sep + f.name + '.' +
                               extname)):

            print 'Processing', f.name
            target = f.name
            dtarget = params.loc_output + os.path.sep + 'd_' + os.path.basename(
                target)
            ntarget = params.loc_output + os.path.sep + 'n_' + os.path.basename(
                target)
            ztarget = params.loc_output + os.path.sep + 'z_' + os.path.basename(
                target)
            ktable = params.loc_output + os.path.sep + 'k_' + os.path.basename(
                target)

            if os.path.exists(dtarget) and os.path.exists(
                    ntarget) and os.path.exists(ktable):

                norm, h = IO.read_fits_file(ntarget)
                diff, h = IO.read_fits_file(dtarget)
                mask, h = IO.read_fits_file(ztarget)
                inv_var = (norm / diff)**2 + (1 - mask)

                kernelIndex, extendedBasis, c, params = IO.read_kernel_table(
                    ktable, params)
                kernelRadius = np.max(kernelIndex[:, 0]) + 1
                if np.sum(extendedBasis) > 0:
                    kernelRadius += 1

                print 'kernelIndex', kernelIndex
                print 'extendedBasis', extendedBasis
                print 'coeffs', c
                print 'kernelRadius', kernelRadius

                IO.write_image(diff,
                               params.loc_output + os.path.sep + 'diff1.fits')
                diff = IM.undo_photometric_scale(diff, c, params.pdeg)
                IO.write_image(diff,
                               params.loc_output + os.path.sep + 'diff2.fits')
                IO.write_image(
                    inv_var, params.loc_output + os.path.sep + 'inv_var.fits')
                IO.write_kernel_table(
                    params.loc_output + os.path.sep + 'ktable.fits',
                    kernelIndex, extendedBasis, c, params)

                flux, dflux = CI.photom_all_stars(
                    diff, inv_var, star_positions, psf_file, c, kernelIndex,
                    extendedBasis, kernelRadius, params, star_group_boundaries,
                    detector_mean_positions_x, detector_mean_positions_y)

                print 'flux[100:110]:'
                print flux[100:110]
                if isinstance(flux, np.ndarray):
                    if not (params.use_GPU):
                        print 'ungrouping fluxes'
                        flux = flux[star_unsort_index].copy()
                        dflux = dflux[star_unsort_index].copy()
                        print 'unsort flux[100:110]:'
                        print flux[100:110]
                    np.savetxt(
                        params.loc_output + os.path.sep + f.name + '.' +
                        extname,
                        np.vstack((flux, dflux)).T)

                sys.exit(0)
예제 #2
0
def difference_image(ref,
                     target,
                     params,
                     stamp_positions=None,
                     psf_image=None,
                     star_positions=None,
                     star_group_boundaries=None,
                     detector_mean_positions_x=None,
                     detector_mean_positions_y=None,
                     star_sky=None,
                     kernelRadius=None,
                     kernel_inner_rad=7):

    from scipy.linalg import lu_solve, lu_factor, LinAlgError

    start = time.time()
    print 'difference_image', ref.name, target.name

    #
    # Set the kernel size based on the difference in seeing from the reference
    #
    #kernelRadius = min(params.kernel_maximum_radius,
    #                   max(params.kernel_minimum_radius,
    #                       np.abs(target.fw-ref.fw)*params.fwhm_mult))
    if kernelRadius is None:
        kernelRadius = min(
            params.kernel_maximum_radius,
            max(params.kernel_minimum_radius,
                np.sqrt(np.abs(target.fw**2 - ref.fw**2)) * params.fwhm_mult))

    #
    # Mask saturated pixels
    #
    #print 'Masking ',target.name,time.time()-start
    #smask = compute_saturated_pixel_mask(target.image,kernelRadius,params)

    #
    # Define the kernel basis functions
    #
    print 'Defining kernel pixels', time.time() - start
    if params.use_fft_kernel_pixels:
        kernelIndex, extendedBasis = IM.define_kernel_pixels_fft(
            ref,
            target,
            kernelRadius + 2,
            INNER_RADIUS=20,
            threshold=params.fft_kernel_threshold)
    else:
        kernelIndex, extendedBasis = IM.define_kernel_pixels(
            kernelRadius, INNER_RADIUS=kernel_inner_rad)
    nKernel = kernelIndex.shape[0]

    #
    # We dont want to use bad pixels in either the target or reference image
    #
    smask = target.mask * ref.mask
    bmask = np.ones(smask.shape, dtype=bool)

    g = DS.EmptyBase()

    for iteration in range(params.iterations):

        print 'Computing matrix', time.time() - start

        tmask = bmask * smask

        #
        # Compute the matrix and vector
        #
        H, V, texref = CI.compute_matrix_and_vector_cuda(
            ref.image,
            ref.blur,
            target.image,
            target.inv_variance,
            tmask,
            kernelIndex,
            extendedBasis,
            kernelRadius,
            params,
            stamp_positions=stamp_positions)

        #
        # Solve the matrix equation to find the kernel coefficients
        #
        print 'Solving matrix equation', time.time() - start
        try:
            lu, piv = lu_factor(H)
            c = lu_solve((lu, piv), V).astype(np.float32).copy()
        except (LinAlgError, ValueError):
            print 'LU decomposition failed'
            g.model = None
            g.flux = None
            g.diff = None
            print 'H'
            print H
            sys.stdout.flush()
            return g

        #
        # Compute the model image
        #
        print 'Computing model', time.time() - start
        g.model = CI.compute_model_cuda(ref.image.shape, texref, c,
                                        kernelIndex, extendedBasis, params)
        edges = np.where(ref.image < 1.0)
        g.model[edges] = 0.0

        #
        # Compute the difference image
        #
        difference = (target.image - g.model)
        g.norm = difference * np.sqrt(target.inv_variance)

        #
        # Recompute the variance image from the model
        #
        #target.inv_variance = 1.0/(g.model/params.gain +
        #						   (params.readnoise/params.gain)**2) + (1-smask)
        mp = np.where(tmask == 0)
        if len(mp[0]) > 0:
            target.inv_variance[mp] = 1.e-12

        #
        # Mask pixels that disagree with the model
        #
        if iteration > 2:
            bmask = IM.kappa_clip(smask, g.norm,
                                  params.pixel_rejection_threshold)

        print 'Iteration', iteration, 'completed', time.time() - start

    #
    # Delete the target image array to save memory
    #
    del target.image

    #
    # Save the kernel coefficients to a file
    #
    if params.do_photometry and psf_image:
        kf = params.loc_output + os.path.sep + 'k_' + os.path.basename(
            target.name)
        IO.write_kernel_table(kf, kernelIndex, extendedBasis, c, params)

        print 'coeffs', c

    g.norm = difference * np.sqrt(target.inv_variance)
    g.variance = 1.0 / target.inv_variance
    g.mask = tmask

    #
    # Do the photometry if requested
    #
    g.flux = None
    if params.do_photometry and psf_image:
        print 'star_positions', star_positions.shape
        print 'star_group_boundaries', star_group_boundaries
        if ref.name == target.name:
            sky_image, _ = IO.read_fits_file(params.loc_output + os.path.sep +
                                             'temp.sub2.fits')
            phot_target = ref.image - sky_image
            IO.write_image(
                phot_target,
                params.loc_output + os.path.sep + 'clean_' + ref.name)
            g.flux, g.dflux = CIF.photom_all_stars_simultaneous(
                phot_target, target.inv_variance, star_positions, psf_image, c,
                kernelIndex, extendedBasis, kernelRadius, params,
                star_group_boundaries, detector_mean_positions_x,
                detector_mean_positions_y)
        else:
            phot_target = difference
            g.flux, g.dflux = CI.photom_all_stars(
                phot_target, target.inv_variance, star_positions, psf_image, c,
                kernelIndex, extendedBasis, kernelRadius, params,
                star_group_boundaries, detector_mean_positions_x,
                detector_mean_positions_y)

        print 'Photometry completed', time.time() - start

    #
    # Apply the photometric scale factor to the difference image.
    # We don't do this prior to the photometry because the PSF is
    # being convolved by the kernel, which already includes the
    # photometric scale factor.
    #
    g.diff = IM.apply_photometric_scale(difference, c, params.pdeg)
    sys.stdout.flush()
    return g