Ejemplo n.º 1
0
def subtract_test(location, image, template, hotpants_special=False, hotpants_default=False):
    data_image = image.replace('temp', 'data')
    data_template = template.replace('temp', 'templates')
    config = location + '/default_config'
    AIS_loc = os.path.dirname(initialize.__file__) + "/AIS/package/bin/./mrj_phot"
    if hotpants_special == True:
        cwd = os.getcwd()
        os.chdir(os.path.dirname(initialize.__file__))
        sig_template = psf.fwhm_template(data_template)/2.355
        sig_image = psf.fwhm(data_image)/2.355
        if sig_template < sig_image:
            sigma_match = np.sqrt((sig_image)**2-(sig_template)**2)
            s1 = .5*sigma_match
            s2 = sigma_match
            s3 = 2*sigma_match
            output = location + "/conv.fits"
            os.system("./hotpants -inim %s[0] -tmplim %s[0] -outim %s -tmi %s[1] -imi %s[1] -ng 3 6 %.5f 4 %.5f 2 %.5f" % (image, template, output, template, image, s1, s2, s3))
        elif sig_template >= sig_image:
            sigma_match = np.sqrt((sig_template)**2-(sig_image)**2)
            s1 = .5*sigma_match
            s2 = sigma_match
            s3 = 2*sigma_match
            output = location + "/conv.fits"
            os.system("./hotpants -inim %s[0] -tmplim %s[0] -outim %s -tmi %s[1] -imi %s[1] -ng 3 6 %.5f 4 %.5f 2 %.5f" % (template, image, output, template, image, s1, s2, s3))
            subtract_ais.invert_image(output)
        os.chdir(cwd)
    elif hotpants_default == True:
        cwd = os.getcwd()
        os.chdir(os.path.dirname(initialize.__file__))
        output = location + "/conv.fits"
        os.system("./hotpants -inim %s[0] -tmplim %s[0] -outim %s -tmi %s[1] -imi %s[1]" % (image, template, output, template, image))
        os.chdir(cwd)
    else:
        os.system(AIS_loc + ' ' + template + ' ' + image + ' -c ' + config)        
Ejemplo n.º 2
0
def mask_sources_image(res_image, aperture_diam=1.5, use_config_file=True):
    if use_config_file == True:
        aperture_diam = initialize.get_config_value('aperture_diam')
    res_data = fits.getdata(res_image)
    res_mask = fits.getdata(res_image, 1)
    weight_check = False
    if fits.getval(res_image, 'WEIGHT') == 'Y':
        weight_check = True
        res_mask = (res_mask - 1) * -1
    image = res_image.replace('_residual', '')
    image = image.replace('residuals', 'data')
    im_fwhm = psf.fwhm(image)
    unfiltered_sources, unfiltered_inds = get_sources(image, filtered=False)
    filtered_sources, filtered_inds = get_sources(image, filtered=True)
    for unf in unfiltered_sources:
        if unf not in filtered_sources:
            new_mask = mask_source(res_data.shape[0], res_data.shape[1],
                                   (unf[1], unf[2]), aperture_diam * im_fwhm)
            res_mask = np.logical_or(res_mask, new_mask)
    data_hdu = fits.PrimaryHDU(res_data, header=fits.getheader(res_image))
    if weight_check == True:
        mask_hdu = fits.ImageHDU((res_mask - 1) * -1)
    else:
        mask_hdu = fits.ImageHDU(res_mask)
    list_hdu = fits.HDUList([data_hdu, mask_hdu])
    list_hdu.writeto(res_image, overwrite=True)
Ejemplo n.º 3
0
def hotpants(location):
    '''
    subtract using hotpants
    '''
    x = 0
    images = glob.glob(location + "/data/*_A_.fits")
    template = glob.glob(location + "/templates/*.fits")
    outputs = []
    length = len(location) + 6
    psf_data = glob.glob(location + '/psf/*')
    if len(psf_data) == 3 * (len(images) + 1):
        if len(template) == 1:
            sig_template = psf.fwhm_template(template[0]) / 2.355
            for i in images:
                sig_image = psf.fwhm(i) / 2.355
                if sig_template < sig_image:
                    sigma_match = np.sqrt((sig_image)**2 - (sig_template)**2)
                    s1 = .5 * sigma_match
                    s2 = sigma_match
                    s3 = 2 * sigma_match
                    outputs.append(location + "/residuals/" + i[length:-8] +
                                   "_hotpants.fits")
                    os.system(
                        "./hotpants -inim %s -tmplim %s -outim %s -ng 3 6 %.5f 4 %.5f 2 %.5f"
                        % (images[x], template[0], outputs[x], s1, s2, s3))
                    x += 1
                    per = float(x) / float(len(images)) * 100
                    print("-> %.1f subtracted..." % (per))
                elif sig_template >= sig_image:
                    sigma_match = np.sqrt((sig_template)**2 - (sig_image)**2)
                    s1 = .5 * sigma_match
                    s2 = sigma_match
                    s3 = 2 * sigma_match
                    outputs.append(location + "/residuals/" + i[length:-8] +
                                   "_hotpants.fits")
                    os.system(
                        "./hotpants -inim %s -tmplim %s -outim %s -ng 3 6 %.5f 4 %.5f 2 %.5f"
                        % (template[0], images[x], outputs[x], s1, s2, s3))
                    subtract_ais.invert_image(location + "/residuals/" +
                                              i[length:-8] + "_hotpants.fits")
                    x += 1
                    per = float(x) / float(len(images)) * 100
                    print("-> %.1f subtracted..." % (per))
        else:
            print("-> Error with number of templates")
            sys.exit()
    else:
        print(
            "-> Error: Need PSFs before running subtraction\n-> Run psf.py first"
        )
        sys.exit()
Ejemplo n.º 4
0
def swarp(location, template_perc=0.33, use_config_file=True):
    location = location[:-5]
    temps = glob.glob(location + '/templates/*.fits')
    images = glob.glob(location + '/data/*_A_.fits')
    imNum = len(images)
    numImages = 0
    if use_config_file == True:
        template_perc = initialize.get_config_value('template_perc')
    if len(temps) == 1:
        temps_name = temps[0].split('/')[-1]
        numImages = int((temps_name.split('.'))[0].split('_')[-1])
    if len(temps) == 0 or numImages != len(images):
        #delete old template
        if len(temps) != 0:
            template_name = temps[0].split('/')[-1]
            os.remove(temps[0])
            try:
                os.remove("%s/psf/%s.cat" % (location, template_name[:-5]))
                os.remove("%s/psf/%s.psf" % (location, template_name[:-5]))
            except:
                pass
        #change image shapes to match each the smallest image in the set
        print("\n-> Slicing images to a common FOV...")
        shapes = []
        areas = []
        for i in tqdm(images):
            image_data = fits.getdata(i)
            shapes.append(image_data.shape)
            areas.append((image_data.shape)[0] * (image_data.shape)[1])
        min_index = areas.index(min(areas))
        #        correct_shape = max(set(shapes), key=shapes.count)
        correct_shape = shapes[min_index]
        print("\n-> FOV size (x,y): (%d, %d)" %
              (correct_shape[0], correct_shape[1]))
        for index in tqdm(range(len(shapes))):
            s = shapes[index]
            diff = tuple(np.subtract(s, correct_shape))
            im = images[index]
            im_hdu = fits.open(im)
            im_data = im_hdu[0].data
            im_header = im_hdu[0].header
            im_mask = (im_hdu[1].data).astype(int)
            if diff != (0, 0):
                if diff[0] < 0:
                    im_data = np.concatenate(
                        (im_data, np.zeros((diff[0] * -1, s[1]))), axis=0)
                    im_mask = np.concatenate(
                        (im_mask, np.ones((diff[0] * -1, s[1]))), axis=0)
                if diff[0] > 0:
                    im_data = im_data[:-1 * diff[0]]
                    im_mask = im_mask[:-1 * diff[0]]
                if diff[1] < 0:
                    im_data = np.concatenate(
                        (im_data, np.zeros((im_data.shape[0], diff[1] * -1))),
                        axis=1)
                    im_mask = np.concatenate(
                        (im_mask, np.ones((im_mask.shape[0], diff[1] * -1))),
                        axis=1)
                if diff[1] > 0:
                    im_data = im_data[:, :diff[1] * -1]
                    im_mask = im_mask[:, :diff[1] * -1]
                hduData = fits.PrimaryHDU(im_data, header=im_header)
                hduMask = fits.ImageHDU(im_mask.astype(int))
                hduList = fits.HDUList([hduData, hduMask])
                hduList.writeto(im, overwrite=True)
            im_hdu.close()

        #change all masks into weight maps
        print("\n-> Converting all image masks into weight maps...")
        for i in tqdm(images):
            weight = sex.weight_map(i)
            hdu = fits.open(i, mode='update')
            data = hdu[0].data
            hdr = hdu[0].header
            try:
                if hdr['WEIGHT'] == 'N':
                    hdr.set('WEIGHT', 'Y')
                    hduData = fits.PrimaryHDU(data, header=hdr)
                    hduWeight = fits.ImageHDU(weight)
                    hduList = fits.HDUList([hduData, hduWeight])
                    hduList.writeto(i, overwrite=True)
            except KeyError:
                hdr.set('WEIGHT', 'Y')
                hduData = fits.PrimaryHDU(data, header=hdr)
                hduWeight = fits.ImageHDU(weight)
                hduList = fits.HDUList([hduData, hduWeight])
                hduList.writeto(i, overwrite=True)
            hdu.close()
        # choose only the top template_perc seeing images
        try:
            FWHMs = []
            for im in images:
                FWHMs.append(psf.fwhm(im))
            template_images = []
            while len(template_images) < round(template_perc * len(images)):
                template_images.append(images[FWHMs.index(np.min(FWHMs))])
                FWHMs.remove(np.min(FWHMs))
            images = template_images
        except FileNotFoundError:
            print(
                "-> Error: PSF models do not exist, run PSF method first then try again."
            )
            sys.exit()
        initialize.create_configs(location)
        config_loc = location + '/configs/default.swarp'
        if os.path.exists(config_loc):
            template = location + "/templates/swarp_median_" + str(
                imNum) + ".fits"
            with open(config_loc, 'r') as config:
                data = config.readlines()
                config.close()
            data[4] = "IMAGEOUT_NAME" + "        " + template + "\n"
            data[
                15] = "WEIGHT_IMAGE" + "        " + "@%s/templates/weights.txt" % (
                    location) + "\n"
            data[
                36] = "IMAGE_SIZE" + "        " + "%s, %s" % correct_shape[::
                                                                           -1] + "\n"
            with open(config_loc, 'w') as config:
                config.writelines(data)
                config.close()
            time = strftime("%Y-%m-%d %H:%M:%S", gmtime())
            og_templates = glob.glob(location + "/templates/*.fits")
            log_loc = location + "/templates/log.txt"
            tlist_loc = location + "/templates/template_inputs.txt"
            weight_list = "%s/templates/weights.txt" % (location)
            log_list = open(log_loc, "a+")
            template_list = open(tlist_loc, "w+")
            for i in images:
                template_list.write(str(i) + "[0]" + "\n")
            template_list.close()
            with open(weight_list, 'w+') as w:
                for i in images:
                    w.write("%s[1]\n" % (i))
            if images == []:
                print("-> No aligned images to combine\n")
            else:
                try:
                    print("-> Images being combined...\n")
                    os.system("swarp @%s -c %s" % (tlist_loc, config_loc))
                    log_list.write(
                        "template updated at %s UTC | method = median (SWarp) | images = %d\n"
                        % (str(time), len(images)))
                    log_list.close()
                    if len(og_templates) > 0:
                        for o in og_templates:
                            os.system("mv %s %s/OASIS/archive/templates" %
                                      (o, initialize.loc))
                    print(
                        "\n-> Image combination successful!\n-> Template log updated\n"
                    )
                except:
                    print("-> Image combination failed\n")
                    sys.exit()
            temp_hdu = fits.open(template)
            temp_data = temp_hdu[0].data
            temp_hdr = temp_hdu[0].header
            try:
                temp_mask = fits.getdata(
                    os.path.dirname(initialize.__file__) +
                    '/coadd.weight.fits')
            except:
                try:
                    temp_mask = fits.getdata(
                        os.path.dirname(initialize.__file__) +
                        '/AIS_temp/coadd.weight.fits')
                except:
                    print(
                        '-> Error: can\'t find coadd.weight.fits\n-> Exiting...'
                    )
                    sys.exit()
            mask_median = np.median(temp_mask)
            mask_std = np.std(temp_mask)
            threshold = mask_median - (mask_std)
            temp_mask[temp_mask < threshold] = 0
            temp_mask[temp_mask >= threshold] = 1
            masked_data = np.ma.masked_array(temp_data, mask=temp_mask)
            temp_median = np.ma.median(masked_data)
            temp_hduData = fits.PrimaryHDU(temp_data, header=temp_hdr)
            temp_hduMask = fits.ImageHDU(temp_mask)
            temp_hduList = fits.HDUList([temp_hduData, temp_hduMask])
            temp_hduList.writeto(template, overwrite=True)
            temp_hdu.close()
            temp_hdu = fits.open(template, mode='update')
            (temp_hdu[0].header).set('MEDIAN', str(temp_median))
            temp_hdu.close()
        else:
            print("\n-> No default.swarp file in target's config directory\n")
            sys.exit()
    else:
        print("-> Template already exists")
    try:
        os.remove(os.path.dirname(initialize.__file__) + '/coadd.weight.fits')
    except:
        pass
Ejemplo n.º 5
0
def sim_sameField(location, mode='moffat', numIms=100, bkg_mag=22.5, fwhm_min=3, fwhm_max=6, 
                  rot_min=-2.5, rot_max=2.5, shift_min=-2, shift_max=2, scale_mult=(0,1.5),
                  scale_add=(-20,50), zero_point=25):
    '''Test **OASIS**'s ability to handle frame-by-frame variations in astronomical data and filter out false-positive sources. The procedure of the simulation is as follows:
        
        1. Copies a random science image from the specified dataset to the **simulations** directory.
        2. A source catalog of the chosen science image is made, containing information on each source's centroid location and total flux.
        3. Using this source catalog, simulations of the chosen science image are made, all with constant source flux and location, but with different backgrounds, seeing, and pointing.
        4. The set of simulated images are sent through the **OASIS Pipeline**.
        5. Low numbers of detected sources signifies a successful simulation. There are no variable objects in the simulated images, so ideally zero sources should be detected by **OASIS**.
        
        :param str location: Path of data file tree (contains the **configs**, **data**, **psf**, **residuals**, **sources**, **templates** directories). Use a comma-separated list for mapping to multiple datasets.
        :param str mode: Simulation mode. Method by which simulated images are made. All images are given a uniform background, then smeared according to Poisson statistics.
        
            * *moffat* (default): Sources are convolved with a 2D Moffat kernel.
            * *gauss*: Sources are convolved with a symmetric 2D Gaussian kernel.
            * *real*: The actual PSF model of the chosen science image is used as the convolution kernel.
            * *sky*: AstrOmatic program ``SkyMaker`` (Bertin) is used to make simulated images.
            
        :param int numIms (default=100): Number of simulated images to make.
        :param float bkg_mag: Average background level in mags. Actual simulated background levels are chosen to be a random value within the interval :math:`[bkg\_mag-1.5, bkg\_mag+1.5]`.
        :param float fwhm_min: Minimum FWHM of simulated images in pixels.
        :param float fwhm_max: Maximum FWHM of simulated images in pixels.
        :param float rot_min: Lower bound on angle of rotation in degrees.
        :param float rot_max: Upper bound on angle of rotation in degrees.
        :param float shift_min: Lower bound on (X,Y) shift in pixels.
        :param float shift_max: Upper bound on (X,Y) shift in pixels.
        :param tuple scale_mult: Interval of acceptable multiplicative scale factors.
        :param tuple scale_add: Interval of acceptable additive scale factors.
        :param float zero_point: Zero point magnitude.
        :returns: Standard **OASIS Pipeline** output, residual frames located in **residuals** and source catalogs located in **sources**.
        
    '''
    ref_im = glob.glob(location + '/data/*_ref_A_.fits')
    if os.path.exists(location) == False:
        print("-> Error: Problem with path name(s)-- make sure paths exist and are entered correctly\n-> Exiting...")
        sys.exit()
    if len(ref_im) != 1:
        print("-> Error: Problem with number of reference images\n-> Exiting...\n")
        sys.exit()
    ref_im = ref_im[0]
    ref_fwhm = fwhm(ref_im)
    path_splits = ref_im.split('/')
    image_name = path_splits[-1]
    sim_loc = location.replace('targets', 'simulations')
    len_loc = len(loc.split('/'))
    tar = path_splits[len_loc+2]
    copy_to_sim(tar, image=ref_im, mode='samefield')
    ref_psf = glob.glob("%s/psf/*_ref_A_.psf" % (sim_loc))
    if len(ref_psf) != 1:
        print("-> Error: Problem with number of reference PSF files\n-> Exiting...\n")
        sys.exit()
    try:
        clear_contents(sim_loc)
    except:
        pass
    images = glob.glob("%s/data/*.fits" % (sim_loc))
    ref_im_sim = ref_im.replace("targets", "simulations")
#delete all original images except reference
    for i in images:
        name = i.split('/')[-1]
        if name != image_name:
            os.remove(i)
#create configs directory if none exists
    create_configs(sim_loc)
#make source catalog of reference using SExtractor
    sim_config = "%s/configs/default_sim.sex" % (sim_loc)
    sim_params = "%s/configs/default_param_sim.sex" % (sim_loc)
    with  open(sim_config, 'r') as conf:
        lines = conf.readlines()
    lines[6] = "CATALOG_NAME" + "        " + "%s/data/reference.cat" % (sim_loc) + "\n"
    lines[9] = "PARAMETERS_NAME" + "        " + sim_params + "\n"
    lines[22] = "FILTER_NAME" + "        " + "%s/configs/default.conv" % (sim_loc) + "\n"
    lines[70] = "SEEING_FWHM" + "        " + str(ref_fwhm) + "\n"
    lines[127] = "PSF_NAME" + "        " + ref_psf[0] + "\n"
    with open(sim_config, 'w') as conf_write:
        conf_write.writelines(lines)
    os.system("sextractor %s[0] -c %s" % (ref_im_sim, sim_config))
#extract x_pos, y_pos, and fluxes from SExtractor catalog
    ref_cat = "%s/data/reference.cat" % (sim_loc)
    with open(ref_cat, 'r') as cat:
        cat_lines = cat.readlines()
#get simulated image's metadata
    ref_hdu = fits.open(ref_im_sim)
    ref_data = ref_hdu[0].data
    ref_header = ref_hdu[0].header
    ref_mask = ref_hdu[1].data
    try: weight_check = fits.getval(ref_im_sim, 'WEIGHT')
    except: weight_check = 'N'
    if weight_check == 'Y':
        ref_mask = (ref_mask-1)*-1
    ref_mask = ref_mask.astype(np.int64)
    ref_hdu.close()
    from astropy.stats import sigma_clipped_stats
    mean, median, std = sigma_clipped_stats(ref_data, sigma=3.0)
#extract simulated image's source information from SExtractor catalog
    x_pos = []
    y_pos = []
    flux = []
    sources = {}
    for c in cat_lines:
        splits = c.split()
        if splits[0] != '#':
            flux.append(float(splits[0]))
            x_pos.append(round(float(splits[3])))
            y_pos.append(round(float(splits[4])))
            sources.update({float(splits[0]) : (round(float(splits[3])), round(float(splits[4])))})
    flux_ordered = sorted(sources)
    flux_iter = round(len(flux)*0.99)
    flux_sim = flux_ordered[flux_iter]
    xy_sim = sources[flux_sim]
#if mode is set to use SkyMaker for making the simulations, configure SkyMaker
    if mode == 'sky':
        mags = []
        for f in flux:
            mags.append((28-(np.log(f))))
        with open("%s/configs/sky_list.txt" % (sim_loc), "w+") as sky_list:
            for i in range(len(flux)):
                sky_list.write("100 %.3f %.3f %.3f\n" % (x_pos[i], y_pos[i], mags[i]))
        #get pixel scale of reference image
        pixscale = float(ref_header['PIXSCALE'])
        #define oversampling
        oversample = pixscale*25
        #define sky.config location
        sky_config = "%s/configs/sky.config" % (sim_loc)
#start making fake images
    print("\n-> Making simulated images...")
    for n in tqdm(range(numIms)):
#define image name
        if n == 0:
            image_name = '%s/data/%d_ref_A_.fits' % (sim_loc, n)
        else:
            image_name = '%s/data/%d_N_.fits' % (sim_loc, n)
#for each image: make sources w/ random fwhm b/w (3,6), rotate/zoom, shift, add a different gaussian dist. of noise, change scale linearly, poisson smear
        #define FWHM of simulation
        image_fwhm = ((fwhm_max-fwhm_min) * np.random.random()) + fwhm_min
        #based on the mode chosen, create the corresponding convolution kernel and make simulated image
        if mode != 'sky':
            if mode == 'moffat':
                moffat_kernel_1 = Moffat2DKernel(gamma=make_stars.get_moffat_gamma(image_fwhm), alpha=7)
                moffat_kernel_2 = Moffat2DKernel(gamma=make_stars.get_moffat_gamma(image_fwhm), alpha=2)
                conv_kernel = (0.8*moffat_kernel_1) + (0.2*moffat_kernel_2)
            elif mode == 'gauss':
                gaussian_kernel_1 = Gaussian2DKernel(x_stddev=(image_fwhm/2.355), y_stddev=(image_fwhm/2.355))
                gaussian_kernel_2 = Gaussian2DKernel(x_stddev=((image_fwhm*2)/2.355), y_stddev=((image_fwhm*2)/2.355))
                conv_kernel = (0.9*gaussian_kernel_1) + (0.1*gaussian_kernel_2)
            elif mode == 'real':
                conv_kernel = get_first_model(ref_im)
            try:
                conv_kernel /= np.sum(conv_kernel)
            except:
                pass
            flux_variable = np.array(flux) * np.random.random() * 2
            image = make_stars.make_image(ref_data.shape[0], ref_data.shape[1], 
                                      x_loc=y_pos, y_loc=x_pos, fluxes=flux_variable, psf=[conv_kernel])
        #if mode is set to 'sky' use SkyMaker to make simulated image
        elif mode == 'sky':
            bkg_Mag = (1.5*np.random.random()) + bkg_mag
            image_fwhm_arcsec = image_fwhm*pixscale
            with open(sky_config, 'r') as sky:
                sky_lines = sky.readlines()
            sky_lines[6] = "IMAGE_NAME" + "        " + image_name + "\n"
            sky_lines[7] = "IMAGE_SIZE" + "        " + str("%d, %d" % (ref_data.shape[1], ref_data.shape[0])) + "\n"
            sky_lines[19] = "SATUR_LEVEL" + "        " + str(ref_header['SATURATE']) + "\n"
            sky_lines[21] = "EXPOSURE_TIME" + "        " + str(ref_header['EXPTIME']) + "\n"
            sky_lines[26] = "PIXEL_SIZE" + "        " + str(pixscale) + "\n"
            sky_lines[34] = "SEEING_FWHM" + "        " + str(image_fwhm_arcsec) + "\n"
            sky_lines[37] = "PSF_OVERSAMP" + "        " + str(oversample) + "\n"
            sky_lines[65] = "BACK_MAG" + "        " + str(bkg_Mag) + "\n"
            with open(sky_config, 'w') as sky:
                sky.writelines(sky_lines)
            os.system("sky %s/configs/sky_list.txt -c %s" % (sim_loc, sky_config))
            try:
                os.remove("%s/data/%s.list" % (sim_loc, image_name[:-5]))
            except:
                pass
            image = fits.getdata(image_name)
        else:
            print("-> Error: Please enter a valid mode (gauss, moffat, sky, real)\n-> Exiting...")
            sys.exit()
        #now we start the warping of each simulation
        #first rotate/zoom (angle is random b/w 0 and 30 degrees, zoom is random b/w 0 and 2)
        if n != 0:
            #define initial mask for each simulation
            Mask = np.zeros(image.shape)
            rot_angle = ((rot_max-rot_min)*np.random.random())+rot_min
            dx = (shift_max-shift_min) * np.random.random() - shift_min
            dy = (shift_max-shift_min) * np.random.random() - shift_min
            image = rotate(image, rot_angle, reshape=False)
            image = shift(image, [dx,dy])
            Mask = rotate(ref_mask, rot_angle, reshape=False, cval=1)
            Mask = shift(Mask, [dx,dy], cval=1)
        else:
            Mask = ref_mask
        #for non-SkyMaker simulations, add in a random background, poisson smear the image, and rescale it
        if mode != 'sky':
            #add constant background
            bkg_loc = 2.512**(zero_point - bkg_mag)
            bkg_scl = ((std+5)-(std-5))*np.random.random()+(std-5)
            bkg = np.random.normal(loc=bkg_loc, scale=bkg_scl, size=image.shape)
            image = np.add(image, bkg)
            #poisson smear
            negative_image = np.zeros(image.shape)
            negative_image[:] = image[:]
            image[image < 0] = 0
            negative_image[negative_image > 0] = 0
            image = np.random.poisson(image)
            image = image.astype(np.float64)
            negative_image *= -1
            negative_image = np.random.poisson(negative_image)
            negative_image = negative_image.astype(np.float64)
            negative_image *= -1
            image += negative_image
            #rescale image linearly
            a = ((scale_mult[1] - scale_mult[0])*np.random.random()) + scale_mult[0]
            b = (scale_add[1] - scale_add[0])*np.random.random() - scale_add[0]
            image *= a
            image += b
        #write new image to data folder in target's simulations folder
        newHDUData = fits.PrimaryHDU(image, header=ref_header)
        newHDUMask = fits.ImageHDU(Mask)
        newHDUList = fits.HDUList([newHDUData, newHDUMask])
        newHDUList.writeto(image_name, overwrite=True)
        newHDU = fits.open(image_name, mode='update')
        (newHDU[0].header).set('WEIGHT', 'N')
        (newHDU[0].header).set('SCALED', 'N')
        newHDU.close()
    os.system("mv %s %s" % (ref_im_sim, sim_loc))
    os.system("mv %s %s" % (ref_psf, sim_loc))
    os.system("mv %s %s.cat" % (ref_psf[:-4], sim_loc))
    if mode == 'sky':
        sim_lists = glob.glob("%s/data/*.list" % (sim_loc))
        for sl in sim_lists:
            os.remove(sl)
    pipeline.pipeline_run_sim(sim_loc, sim=False)
    print(flux_iter, flux_sim, xy_sim)
Ejemplo n.º 6
0
def sim_fakes(location, n_fakes=20, iterations=50, input_mode='flux', PSF='moffat', subtract_method='ois', f_min=0, f_max=40000):
    '''Simulates transient signals (fakes) and tests **OASIS**'s ability to detect them. The procedure of the simulation is as follows:
        
            1. Makes a copy of the specified data set and moves it to the **simulations** directory.
            2. Chooses a random image out of the data set and adds in fakes.
            3. Runs the data set through the **OASIS Pipeline**.
            4. Outputs a catalog of all fakes and whether or not they were detected.
            5. Simulation is repeated with a different set of fakes.
            
            :param str location: Path of data file tree (contains the **configs**, **data**, **psf**, **residuals**, **sources**, **templates** directories). Use a comma-separated list for mapping to multiple datasets.
            :param int n_fakes: Number of fakes added to the chosen image.
            :param int iterations: Number of iterations the simulation goes through. The total number of fakes added is then :math:`n\_fakes * iterations`. It is reccommended to choose *n_fakes* and *iterations* such that the total number of fakes is high, at least a few hundred, ideally more than 1000.
            :param str input_mode: How to interpret fake's flux parameter.
            
                * *flux* (default): Fake's brightness is assumed to be total flux of the fake in ADU and is determined by *f_min* and *f_max* parameters.
                * *mag*: Fake's brightness is given in magnitudes instead of ADU flux. *f_min* and *f_max* are then assumed to be apparent magnitudes rather than ADU counts.
            
            :param str PSF: Type of PSF model used for fake construction. See documentation for details.
            
                * *moffat* (default): Fakes are convolved with a 2D Moffat kernel.
                * *gaussian*: Fakes are convolved with a symmetric 2D Gaussian kernel.
                
            :param str subtract_method: Subtraction method used, can be either *ois* or *hotpants*, default is *ois*. See ``subtract`` method's documentation for details.
            :param float f_min: Minimum flux for fakes. Assumed to either be given in ADU counts or apparent magnitudes depending on *input_mode*.
            :param float f_max: Maximum flux for fakes. Assumed to either be given in ADU counts or apparent magnitudes depending on *input_mode*.
            :returns: Catalog of all fakes, the image they were added to, iteration, and whether or not they were detected. See documentation for details.
    
    '''
    try:
        #pick a random image in location dataset to use as the fake
        dataImages = glob.glob(location + '/data/*.fits')
        imIndex = np.random.randint(low=0, high=(len(dataImages)-1))
        image = dataImages[imIndex]
        tarIndex = len(loc.split('/'))
        target = location.split('/')[tarIndex+2:tarIndex+3]
        target = target[0]
        #copy data to simulations directory
        check = loc + '/OASIS/simulations/' + target
        if os.path.exists(check) == False:
            copy_to_sim(target)
        #rename image paths to correspond to simulations directory
        image = image.replace('targets', 'simulations')
        image_name = image.split('/')[-1]
        length = len(image_name) + 6
        location = image[:-length]
        location = location.replace(target, "%s_fakes" % (target))
        image = image.replace(target, "%s_fakes" % (target))
    #    #copy image to be faked to exposure time directory so it can be retrieved
    #    os.system('cp %s %s' % (image, location))
        #define location of simulation results files
        fake_txt = location + '/results_fake.txt'
        MR_txt = location + '/results_MR.txt'
        #get PSF FWHM of original input image
        if os.path.exists(image.replace('data','psf')[:-4]+'cat') == False:
            sex.sextractor_psf_sim(location, image)
            psfex(location)    
        FWHM = fwhm(image)
        #get input image data and header
        image_hdu = fits.open(image)
        image_header = image_hdu[0].header
        image_data = image_hdu[0].data
        image_mask = image_hdu[1].data
        image_hdu.close()
        shape = image_data.shape
        #move fake image to configs directory
        os.system("mv %s %s/configs" % (image, location))
        #redefine location of image
        image_new_loc = image.replace('data', 'configs')
        #convert input mags to fluxes
        if input_mode == 'mag':
            f_min = mag_to_flux(image, f_min)
            f_max = mag_to_flux(image, f_max)
        fake_name = image
        #perform simulation for 'iterations' number of loops
        for i in tqdm(range(iterations)):
            #define blank results slates
            fake_results = []
            MR_results = []
            #delete all previous simluations data
            clear_image(image)
            #make 'n_fakes' fluxes
            print("-> Creating fakes...")
            flux_scales = np.random.random(n_fakes)
            flux = ((f_max-f_min)*flux_scales) + f_min
            x = [round(shape[0]*np.random.random()) for i in range(n_fakes)]
            y = [round(shape[1]*np.random.random()) for j in range(n_fakes)]
            #print fake sources' info
            print("-> Fake fluxes: \n" + "-> " + str(flux))
            print("-> Fake x: \n" + "-> " + str(x))
            print("-> Fake y: \n" + "-> " + str(y))
            print("-> Fake PSF: %s" % (PSF))
            print("-> Fake FWHM: %.3f\n" % (FWHM))
            if PSF == 'gaussian':
                #make fake image with Gaussian profile
                print("-> Gaussian smearing fakes...")
                gaussian_kernel_1 = Gaussian2DKernel(x_stddev=(FWHM/2.355), y_stddev=(FWHM/2.355))
                gaussian_kernel_2 = Gaussian2DKernel(x_stddev=((FWHM*2)/2.355), y_stddev=((FWHM*2)/2.355))
                conv_kernel = (0.9*gaussian_kernel_1) + (0.1*gaussian_kernel_2)
                fake = make_stars.make_image(shape[0], shape[1], x_loc=x, y_loc=y, fluxes=flux, psf=[conv_kernel])
            elif PSF == 'moffat':
                print("-> Moffat smearing fakes...")
                #define Moffat convolution kernel
                conv_kernel = Moffat2DKernel(gamma=make_stars.get_moffat_gamma(FWHM), alpha=4.765)
                #make image using fluxes na dpositions defined earlier, then convolve with above kernel
                fake = make_stars.make_image(shape[0], shape[1], x_loc=x, y_loc=y, fluxes=flux, psf=[conv_kernel])
            #add fake to original image and overwrite the OG fits file
            print("-> Adding fake to original image...")
            fake += image_data
            hduData = fits.PrimaryHDU(fake, header=image_header)
            hduMask = fits.ImageHDU(image_mask)
            hduList = fits.HDUList([hduData, hduMask])
            hduList.writeto(fake_name, overwrite=True)
            #run images through pipeline
            subtract.subtract_run(location, method=subtract_method)
            #run SExtractor on only fake image
            sex.sextractor_sim(fake_name.replace('_N_', '_A_'))
            #run SExtractor also on master residual to look for fakes
            sex.sextractor_MR(location)
            #find any fakes that were detected by SExtractor in fake catalog
            with open(location+'/sources/filtered_sources.txt', 'r') as src:
                detects = src.readlines()
                src.close()
            for n in range(n_fakes):
                found = 0
                for d in detects:
                    try:
                        float(d.split()[0])
                        if (y[n]-2)<float(d.split()[2])<(y[n]+2) and (x[n]-2)<float(d.split()[3])<(x[n]+2):
                            found += 1
                    except:
                        pass
                fake_results.append([i,image_name,x[n],y[n],flux[n],found])
            #write simulation results to fake_results.txt file
            with open(fake_txt, 'a+') as sim_data:
                sim_data.writelines(tabulate(fake_results))
                sim_data.close()
            #find any fakes that were detected by SExtractor in MR catalog
            with open(location+'/sources/MR_sources_filtered.txt', 'r') as src:
                detects = src.readlines()
                src.close()
            for n in range(n_fakes):
                found = 0
                for d in detects:
                    try: 
                        float(d.split()[0])
                        if (y[n]-2)<float(d.split()[2])<(y[n]+2) and (x[n]-2)<float(d.split()[3])<(x[n]+2):
                            found += 1
                    except:
                        pass
                MR_results.append([i,image_name,x[n],y[n],flux[n],found])
            #write simulation results to MR_results.txt file
            with open(MR_txt, 'a+') as sim_data:
                sim_data.writelines(tabulate(MR_results))
                sim_data.close()
        #move fake image from configs back to data directory
        os.system("mv %s %s/data" % (image_new_loc, location))
    except KeyboardInterrupt:
        print('\n-> Interrupted-- Exiting..')
        try:
            clear_image(image)
            os.system("mv %s %s/data" % (image_new_loc, location))
            sys.exit(0)
        except SystemExit:
            os._exit(0)
Ejemplo n.º 7
0
def TEST():
    '''Tests the installation of **OasisPy** by downloading a set of images from an online public archive, adding fake sources to one of the images, and running the dataset through the **OASIS Pipeline**.
    If the fake sources are recovered, the test is a success. The images used are 118 second exposures of exoplanet HAT-P-37b taken with telescopes at the Las Cumbres Observatory.
    Results of the test are compared to control results located in **OasisPy**'s source code directory.
    
    :returns: Prints either 'TEST SUCCESSFUL!' or 'Test failure: Results do not match controls'.
    
    '''
    frameNum = 30
    q_initial = 1
    q_value = 0.90
    q_min = 0.80
    startTime = time.time()
    #look for existing TEST folder and delete it
    og_test = loc + '/OASIS/targets/TEST'
    if os.path.exists(og_test) == True:
        shutil.rmtree(og_test)
    #get data from LCO public archive and put in target directory under 'TEST' folder
    print("\n-> Getting data from LCO...")
    object_name = 'HAT-P-37'
    response = requests.get('https://archive-api.lco.global/frames/?' +
                            'limit=%d&' % (frameNum) + 'RLEVEL=91&' +
                            'PROPID=' + 'LCOEPO2014B-007' + '&' + 'OBJECT=' +
                            '%s&' % (object_name) + 'FILTER=' + 'w&' +
                            'start=' + '2019-05-29' + '&'
                            'end=' + '2019-05-31' + '&').json()

    frames = response['results']
    #    print(len(frames))

    #take only the first 25 frames
    frames = frames[:frameNum]

    #download data
    temp_loc = loc + '/OASIS/temp/'
    os.mkdir(temp_loc + 'test_data')
    for frame in frames:
        with open(temp_loc + 'test_data/' + frame['filename'], 'wb') as f:
            f.write(requests.get(frame['url']).content)

    #funpack and move to 'TEST' folder
    obtain.process()
    obtain.movetar()
    old_data_location = obtain.rename()
    data_location = old_data_location.replace(object_name.replace(' ', '_'),
                                              'TEST')
    os.rename("%s/OASIS/targets/%s" % (loc, object_name.replace(' ', '_')),
              "%s/OASIS/targets/TEST" % (loc))

    #align and combine images
    test_loc = data_location[:-5]
    mask.MASK(test_loc)
    check_saturation.check_saturate(test_loc + '/data')
    ref_image.ref_image(test_loc + '/data')
    align_astroalign.align2(test_loc + '/data')
    psf.PSF(test_loc)
    combine_swarp.swarp(test_loc + '/data')

    #get PSFs of images so fake stars with same seeing can be added
    fake_im = '02:59:10.860_A_.fits'
    print('\n-> Image %s chosen as fake image\n' % (fake_im))
    fake_residual = fake_im.replace('_A_', '_A_residual_')
    psf.PSF(test_loc)
    FWHM = psf.fwhm(test_loc + '/data/%s' % (fake_im))

    #add three fake stars to reference image
    print("\n-> Adding fake stars to test image...")
    hdu = fits.open(test_loc + '/data/%s' % (fake_im))
    hdu_data = hdu[0].data
    hdu_header = hdu[0].header
    hdu_mask = hdu[1].data

    h, w = np.shape(hdu_data)
    pos_x = [1500, 200, 1200]
    pos_y = [1600, 1400, 700]
    array = np.array([0.65343465, 0.50675629, 0.84946314])
    fluxes = (200000.0 * array) + 300.0
    print("\n-> Fake locations (in pixel coords):")
    print("\t X:", pos_x)
    print("\t Y:", pos_y)
    print("-> Fake fluxes (in ADUs):")
    print("\t ", fluxes)

    img = make_gaussian_im(h,
                           w,
                           fluxes=[fluxes[0], fluxes[1], fluxes[2]],
                           x_pos=[pos_x[0], pos_x[1], pos_x[2]],
                           y_pos=[pos_y[0], pos_y[1], pos_y[2]],
                           std=[FWHM, FWHM, FWHM])

    finalData = fits.PrimaryHDU(hdu_data + img, header=hdu_header)
    finalMask = fits.ImageHDU(hdu_mask)
    finalList = fits.HDUList([finalData, finalMask])
    finalList.writeto(test_loc + '/data/%s' % (fake_im), overwrite=True)
    hdu.close()

    #subtract images using ISIS
    subtract_ais.isis_sub(test_loc)
    perform_optimization(test_loc,
                         qInitial=q_initial,
                         qValue=q_value,
                         qFloor=q_min,
                         use_config_file=False)
    MR.MR_swarp(test_loc)

    #perform SExtractor on residual images
    extract.EXTRACT(test_loc)

    #print TEST runtime
    endTime = time.time()
    print("\n-> Total test runtime: %.3fs\n" % (endTime - startTime))

    residual = glob.glob(test_loc + '/residuals/%s' % (fake_residual))

    fake1_check = False
    fake2_check = False
    fake3_check = False

    MR_sources, inds = filters.get_sources("%s/residuals/MR.fits" % (test_loc),
                                           filtered=True,
                                           MR=True)
    for src in MR_sources:
        if 1498 < src[1] < 1502 and 1598 < src[2] < 1602:
            fake1_check = True
        elif 198 < src[1] < 202 and 1398 < src[2] < 1402:
            fake2_check = True
        elif 1198 < src[1] < 1202 and 698 < src[2] < 702:
            fake3_check = True

    if fake1_check == True and fake2_check == True and fake3_check == True:
        print("\n-> Test SUCCESSFUL!")
    else:
        print("-> Test failure: Results do not match controls")

    #display final residual test image
    os.system('ds9 %s -scale zscale' % (residual[0]))
Ejemplo n.º 8
0
def phose(image,
          dpixel=1,
          thresh=3.5,
          kron_min=0.01,
          fill_method='gauss',
          negative=False,
          fit='moffat'):
    data_image = image.replace('residual_', '')
    data_image = data_image.replace('residuals', 'data')
    res_data = fits.getdata(image)
    if negative == True:
        res_data *= -1
    res_mask = fits.getdata(image, 1)
    try:
        weight_check = fits.getval(image, 'WEIGHT')
    except:
        weight_check = 'N'
    if weight_check == 'Y':
        res_mask = (res_mask - 1) * -1
    location = image.split('/')[:-2]
    location = '/'.join(location)
    template = glob.glob("%s/templates/*.fits" % (location))[0]
    try:
        template_median = float(fits.getval(template, 'MEDIAN'))
    except:
        template_median = np.median(fits.getdata(template))
    try:
        science_median = float(fits.getval(data_image, 'MEDIAN'))
    except:
        science_median = np.median(fits.getdata(data_image))
    res_data_sep = res_data.byteswap().newbyteorder()
    try:
        res_bkg = sep.Background(res_data_sep, mask=res_mask)
    except ValueError:
        res_bkg = res_bkg = sep.Background(res_data, mask=res_mask)
    res_rms = res_bkg.globalrms
    res_back = res_bkg.globalback
    if fill_method == 'gauss':
        fill_bkg = np.random.normal(loc=res_bkg.globalback,
                                    scale=res_bkg.globalrms,
                                    size=res_data.shape)
    elif fill_method == 'skellam':
        fill_bkg = skellam.rvs(float(science_median),
                               float(template_median),
                               size=(res_data.shape))
        fill_bkg = fill_bkg.astype(np.float64)
    else:
        print(
            "-> Error: Invalid value for 'fill_method' keyword\n-> Exiting...")
        sys.exit()
    FWHM = psf.fwhm(data_image)
    sigma = FWHM / 2.355
    if fit == 'moffat':
        fit_param = moffat_fwhm_to_a(FWHM)
    elif fit == 'gauss':
        fit_param = FWHM / 2.355
    else:
        print("-> Error: Invalid value for 'fit' parameter\n-> Exiting...")
        sys.exit()
    unfiltered_sources, temp_sources = get_sources(data_image,
                                                   filtered=False,
                                                   phose=True)
    filtered_sources, filtered_inds = get_sources(data_image, filtered=True)
    bad_mask = np.zeros(res_data.shape)
    good_mask = np.zeros(res_data.shape)
    for s in unfiltered_sources:
        og_flux = s[0]
        x = s[2]
        y = s[3]
        kron_radius = s[1]
        a_image = s[4]
        b_image = s[5]
        min_flux = (np.pi * np.mean(
            (kron_radius * a_image, kron_radius * b_image))**2) * res_back
        if (og_flux < min_flux) or (kron_radius == 0):
            continue
        theta_image = s[6]
        if kron_radius < kron_min:
            indices = [0]
        else:
            indices = [
                v[1] for i, v in enumerate(temp_sources)
                if (v[2] - dpixel <= x <= v[2] + dpixel and v[3] -
                    dpixel <= y <= v[3] + dpixel)
                and phose_check(res_data, x, y, kron_radius, a_image, b_image,
                                theta_image, thresh, og_flux, v[0])
            ]
#        phoseCheck = phose_check(res_data, x, y, kron_radius, a_image, b_image, theta_image, thresh, og_flux, og_flux)
#        if phoseCheck == True or (s not in filtered_sources):
        if indices != []:
            if np.mean(indices) > kron_radius:
                kron_radius = np.mean(indices)
            kron_radius *= 1.5
            size_check = aperture_resize(res_rms,
                                         fit_param,
                                         sigma,
                                         og_flux,
                                         kron_radius,
                                         x,
                                         y,
                                         a_image,
                                         b_image,
                                         dist=fit)
            while size_check == True:
                kron_radius *= 1.5
                size_check = aperture_resize(res_back,
                                             fit_param,
                                             sigma,
                                             og_flux,
                                             kron_radius,
                                             x,
                                             y,
                                             a_image,
                                             b_image,
                                             dist=fit)
            ellipse_mask(bad_mask, (y - 1), (x - 1),
                         kron_radius,
                         a_image,
                         b_image,
                         theta_image,
                         fill_value=1)
        else:
            ellipse_mask(good_mask, (y - 1), (x - 1),
                         kron_radius,
                         a_image,
                         b_image,
                         theta_image,
                         fill_value=1)


#            res_data = phose_fill(res_data, phose_check(res_data, x, y, kron_radius, a_image, b_image, theta_image, mask_return=True), fill_bkg)
#        for t in temp_sources:
#            t_flux = t[0]
#            t_x = t[2]
#            t_y = t[3]
#            if (t_x-dpixel<=x<=t_x+dpixel) and (t_y-dpixel<=y<=t_y+dpixel):
#                temp_mask = np.ones(res_data.shape)
#                ellipse_mask(temp_mask, (y-1), (x-1), kron_radius, a_image, b_image, theta_image, fill_value=0)
#                res_data_phot = np.ma.MaskedArray(res_data, mask=temp_mask, fill_value=0)
#                s_flux = np.sum(res_data_phot.filled())
#                if s_flux < (thresh * np.sqrt(og_flux + t_flux)):
#                    temp_mask_fill = (temp_mask - 1) * -1
#                    res_data_final = np.ma.MaskedArray(res_data, mask = temp_mask_fill, fill_value=0)
#                    res_data_final = res_data_final.filled()
#                    phose_patch = np.multiply(temp_mask_fill, fill_bkg)
#                    res_data = res_data_final + phose_patch
#                    del temp_mask, res_data_phot, temp_mask_fill, res_data_final
#    bad_hdu = fits.PrimaryHDU(bad_mask.astype(np.float64))
#    good_hdu = fits.PrimaryHDU(good_mask.astype(np.float64))
#    bad_hdu.writeto("%s/%s_bad.fits" % (location, (image.split('/'))[-1]))
#    good_hdu.writeto("%s/%s_good.fits" % (location, (image.split('/'))[-1]))
    and_mask = np.logical_and(bad_mask, good_mask)
    bad_mask -= and_mask
    bad_mask = np.logical_or(bad_mask, res_mask)
    res_data = phose_fill(res_data, bad_mask, fill_bkg)
    #    res_hdu = fits.PrimaryHDU(res_data)
    #    res_hdu.writeto("%s/%s_res.fits" % (location, (image.split('/'))[-1]))
    #    bad_hdu = fits.PrimaryHDU(bad_mask.astype(np.float64))
    #    bad_hdu.writeto("%s/%s.fits" % (location, (image.split('/'))[-1]))
    return (res_data -
            (science_median - template_median)) / np.sqrt(science_median +
                                                          template_median)
Ejemplo n.º 9
0
def sextractor(location):
    '''
    runs SExtractor on all residual images
    '''
    sources = location + "/sources"
    residuals = location + "/residuals"
    check = os.path.exists(sources)
    check_temp = os.path.exists(sources + '/temp')
    length = len(residuals) + 1
    if check == False:
        os.system("mkdir %s" % (sources))
        os.system("mkdir %s/temp" % (sources))
    else:
        if check_temp == False:
            os.system("mkdir %s/temp" % (sources))
    images = glob.glob(residuals + "/*_residual_.fits")
    initialize.create_configs(location)
    config_loc = location + '/configs/default.sex'
    with open(config_loc, 'r') as config:
        data = config.readlines()
        config.close()
    data[
        9] = "PARAMETERS_NAME" + "        " + location + "/configs/default.param" + "\n"
    data[
        20] = "FILTER_NAME" + "        " + location + "/configs/default.conv" + "\n"
    with open(config_loc, 'w') as config:
        config.writelines(data)
        config.close()
    print("-> Converting all residual masks into weight maps...\n")
    for r in tqdm(images):
        weight = weight_map(r)
        hdu = fits.open(r, mode='update')
        data = hdu[0].data
        hdr = hdu[0].header
        try:
            if hdr['WEIGHT'] == 'N':
                hdr.set('WEIGHT', 'Y')
                hduData = fits.PrimaryHDU(data, header=hdr)
                hduWeight = fits.ImageHDU(weight)
                hduList = fits.HDUList([hduData, hduWeight])
                hduList.writeto(r, overwrite=True)
        except KeyError:
            hdr.set('WEIGHT', 'Y')
            hduData = fits.PrimaryHDU(data, header=hdr)
            hduWeight = fits.ImageHDU(weight)
            hduList = fits.HDUList([hduData, hduWeight])
            hduList.writeto(r, overwrite=True)
        hdu.close()
        try:
            if fits.getval(r, 'NORM') == 'N':
                fits.setval(r, 'NORM', value='Y')
                MR.normalize(r)
        except KeyError:
            fits.setval(r, 'NORM', value='Y')
            MR.normalize(r)
    print("\n-> SExtracting residual images...")
    for i in tqdm(images):
        if np.std(fits.getdata(i)) != 0:
            name = i[length:-5]
            data_name = location + '/data/' + name.replace('residual_',
                                                           '') + '.fits'
            FWHM = psf.fwhm(data_name)
            im_hdu = fits.open(data_name)
            im_header = im_hdu[0].header
            saturate = im_header['SATURATE']
            pixscale = im_header['PIXSCALE']
            im_hdu.close()
            with open(config_loc, 'r') as config:
                data = config.readlines()
                config.close()
            data[51] = "SATUR_LEVEL" + "        " + str(saturate) + "\n"
            data[62] = "SEEING_FWHM" + "        " + str(FWHM) + "\n"
            data[
                106] = "PSF_NAME" + "        " + location + "/psf/" + name[:
                                                                           -9] + ".psf" + "\n"
            data[58] = "PIXEL_SCALE" + "        " + str(pixscale) + "\n"
            data[32] = "WEIGHT_IMAGE" + "        " + "%s[1]" % (i) + "\n"
            with open(config_loc, 'w') as config:
                config.writelines(data)
                config.close()
            os.system("sextractor %s[0]> %s/temp/%s.txt -c %s" %
                      (i, sources, name, config_loc))
            temp_hdu_data = fits.PrimaryHDU((fits.getdata(i)) * -1,
                                            header=fits.getheader(i))
            temp_hdu_mask = fits.ImageHDU(fits.getdata(i, 1))
            temp_hdu_list = fits.HDUList([temp_hdu_data, temp_hdu_mask])
            temp_hdu_list.writeto("%s/residuals/temp.fits" % (location))
            os.system(
                "sextractor %s/residuals/temp.fits[0]> %s/temp/%s_2.txt -c %s"
                % (location, sources, name, config_loc))
            append_negative_sources(i)
            os.remove("%s/residuals/temp.fits" % (location))
        else:
            name = i[length:-5]
            with open("%s/temp/%s.txt" % (sources, name), 'w') as bad_res_cat:
                bad_res_cat.write("# Bad residual, did not SExtract\n")
    print(
        "-> SExtracted %d images, catalogues placed in 'sources' directory\n" %
        (len(images)))
    print("-> Filtering source catalogs...\n")
    src_join(location)
    filter_sources(location)
Ejemplo n.º 10
0
def hotpants_subtract(image,
                      default=True,
                      opt_ind=0,
                      spatial_deg=0,
                      params=None):
    location = image.split('/')[:-2]
    location = '/'.join(location)
    name = (image.split('/')[-1])[:-5]
    template = glob.glob("%s/templates/*.fits" % location)
    template = template[0]
    image_header = fits.getheader(image)
    sig_image = psf.fwhm(image) / 2.355
    template_header = fits.getheader(template)
    sig_template = psf.fwhm_template(template) / 2.355
    tu = template_header['SATURATE']
    tg = template_header['GAIN']
    tmi = "%s/hotpants_mask.fits" % location
    if os.path.exists(tmi) == False:
        try:
            weight_check = fits.getval(template, 'WEIGHT')
        except:
            weight_check = 'N'
        temp_mask = fits.getdata(template, 1)
        if weight_check == 'Y':
            temp_mask = (temp_mask - 1) * -1
        hotpants_hdu = fits.PrimaryHDU(temp_mask)
        hotpants_hdu.writeto("%s/hotpants_mask.fits" % (location),
                             overwrite=True)
    iu = image_header['SATURATE']
    ig = image_header['GAIN']
    try:
        weight_check = fits.getval(image, 'WEIGHT')
    except:
        weight_check = 'N'
    if weight_check == 'Y':
        im_mask = fits.getdata(image, 1)
        im_mask = (im_mask - 1) * -1
        im_mask_hdu = fits.PrimaryHDU(im_mask)
        im_mask_hdu.writeto("%s/configs/temp_htpts_mask.fits" % (location),
                            overwrite=True)
        imi = "%s/configs/temp_htpts_mask.fits" % (location)
    else:
        imi = "%s[1]" % (image)
    cwd = os.getcwd()
    os.chdir(os.path.dirname(initialize.__file__))
    if default == True:
        omi = "%s/residuals/BPM.fits" % location
        outim = "%s/residuals/%sresidual_.fits" % (location, name)
        tl = -1000
        il = -1000
        if sig_template < sig_image:
            sigma_match = np.sqrt((sig_image)**2 - (sig_template)**2)
            s1 = .5 * sigma_match
            s2 = sigma_match
            s3 = 2 * sigma_match
            os.system(
                "./hotpants -inim %s -tmplim %s -outim %s -tl %d -il %d -tu %d -tg %d -tmi %s -iu %d -ig %d -imi %s -omi %s -ng 3 6 %.5f 4 %.5f 2 %.5f -bgo 0"
                % (image, template, outim, tl, il, tu, tg, tmi, iu, ig, imi,
                   omi, s1, s2, s3))
        elif sig_template >= sig_image:
            sigma_match = np.sqrt((sig_template)**2 - (sig_image)**2)
            s1 = .5 * sigma_match
            s2 = sigma_match
            s3 = 2 * sigma_match
            os.system(
                "./hotpants -inim %s -tmplim %s -outim %s -tl %d -il %d -tu %d -tg %d -tmi %s -iu %d -ig %d -imi %s -omi %s -ng 3 6 %.5f 4 %.5f 2 %.5f -bgo 0"
                % (template, image, outim, il, tl, iu, ig, imi, tu, tg, tmi,
                   omi, s1, s2, s3))
            invert(outim)
        res_data = fits.getdata(outim)
        res_header = fits.getheader(outim)
        BPM = fits.getdata(omi)
        BPM_median = np.median(BPM)
        BPM_std = np.std(BPM)
        BPM[BPM > (BPM_median + BPM_std)] = 0
        BPM[BPM <= (BPM_median + BPM_std)] = 1
        resHDU = fits.PrimaryHDU(res_data, header=res_header)
        resMask = fits.ImageHDU(BPM)
        resList = fits.HDUList([resHDU, resMask])
        resList.writeto(outim, overwrite=True)
        os.remove(omi)
        os.remove("%s/configs/temp_htpts_mask.fits" % location)
        hdu = fits.open("%s/residuals/%sresidual_.fits" % (location, name),
                        mode='update')
        hdr = hdu[0].header
        hdr.set('OPTIMIZE', 'N')
        hdu.close()
    elif default == False:
        omi = "%s/temp/BPM.fits" % location
        outim = "%s/temp/conv.fits" % location
        if 0 <= opt_ind <= 1:
            s1, s2, s3 = 0.7, 1, 2.5
        elif opt_ind == 2:
            s1, s2, s3 = 0.7, 1.5, 3
        elif opt_ind >= 3:
            s1, s2, s3 = 0.7, 2, 4
        if sig_template < sig_image:
            os.system(
                "./hotpants -inim %s -tmplim %s -outim %s -tl %d -il %d -tu %d -tg %d -tmi %s -iu %d -ig %d -imi %s -omi %s -ng 3 6 %.5f 4 %.5f 2 %.5f -bgo %d -r %d -nsx %d -nsy %d -rss %d -ko %d"
                % (image, template, outim, params['tl'][0], params['il'][0],
                   tu, tg, tmi, iu, ig, imi, omi, s1, s2, s3, params['bgo'][0],
                   (params['r'])[opt_ind], (params['nsx'])[spatial_deg],
                   (params['nsy'])[spatial_deg], (params['rss'])[opt_ind],
                   (params['ko'])[spatial_deg]))
        else:
            os.system(
                "./hotpants -inim %s -tmplim %s -outim %s -tl %d -il %d -tu %d -tg %d -tmi %s -iu %d -ig %d -imi %s -omi %s -ng 3 6 %.5f 4 %.5f 2 %.5f -bgo %d -r %d -nsx %d -nsy %d -rss %d -ko %d"
                % (template, image, outim, params['il'][0], params['tl'][0],
                   iu, ig, imi, tu, tg, tmi, omi, s1, s2, s3, params['bgo'][0],
                   (params['r'])[opt_ind], (params['nsx'])[spatial_deg],
                   (params['nsy'])[spatial_deg], (params['rss'])[opt_ind],
                   (params['ko'])[spatial_deg]))
            invert(outim)
    else:
        print("\n-> Error: Default must be boolean value\n-> Exiting...")
        os.chdir(cwd)
        sys.exit()
    os.chdir(cwd)