Beispiel #1
0
def is_on_target(image):
    '''
    Add as a parameter whether the image is on target or not.
    
    '''
    import coordinates_conversor as cc
    
    
    ra, dec = cc.hour2deg(fitsutils.get_par(image, 'OBJRA'), fitsutils.get_par(image, 'OBJDEC'))

    impf = fits.open(image)
    w = wcs.WCS(impf[0].header)
    
    filt = fitsutils.get_par(image, "FILTER")
    #pra, pdec = wcs.wcs_sky2pix(np.array([ra, dec], ndmin=2), 1)[0]
    pra, pdec = get_xy_coords(image, ra,dec)

    shape = impf[0].data.shape
    
    if (pra > 0)  and (pra < shape[0]) and (pdec > 0) and (pdec < shape[1]):
        fitsutils.update_par(image, "ONTARGET", 1)
        return True
    else:
        fitsutils.update_par(image, "ONTARGET", 0)
        return False
Beispiel #2
0
def __combine_guiders(ifu_dic, abspath, outdir):
    '''
    Receives an IFU dictionary with the images that need a solved guider.
    '''
    rc = np.array(glob.glob(abspath + "/rc*fits"))

    rcjd = np.array([fitsutils.get_par(r, "JD") for r in rc])
    imtypes = np.array([fitsutils.get_par(r, "IMGTYPE").upper() for r in rc])
    objnames = np.array([fitsutils.get_par(r, "OBJECT").upper() for r in rc])
    ras = np.array([cc.getDegRaString(fitsutils.get_par(r, "RA")) for r in rc])
    decs = np.array(
        [cc.getDegDecString(fitsutils.get_par(r, "DEC")) for r in rc])

    for ifu_i in ifu_dic.keys():
        name, jd_ini, jd_end, rad, decd, exptime = ifu_dic[ifu_i]
        #guiders = rc[(imtypes=="GUIDER") * (rcjd >= ifu_dic[ifu_i][1]) * (rcjd <= ifu_dic[ifu_i][2]) ]
        mymask = (rcjd >= jd_ini) * (rcjd <= jd_end) *\
            (np.abs(ras - rad)*np.cos(np.deg2rad(decd))<0.5/60 ) * (np.abs(decs - decd)<0.5/60 )
        guiders = rc[mymask]
        im = imtypes[mymask]
        names = objnames[mymask]
        print("For image %s on object %s with exptime %d found guiders:\n %s" %
              (ifu_i, name, exptime, zip(names, im)))
        out = os.path.join(outdir, "guider_" + os.path.basename(ifu_i))
        create_masterguide(guiders, out=out)
        fitsutils.update_par(out, "IFU_IMG", os.path.basename(ifu_i))
Beispiel #3
0
def clean_cosmic(f):
    '''
    From lacosmic.
    '''
    import cosmics
    
    out = f.replace('.fits',  '_clean.fits')
    
    #If it does already exist, just return the name.
    if (os.path.isfile(out)):
        return out
    
    #Otherwise, run the cosmic ray rejection based on LA Cosmic.
    g = fitsutils.get_par(f, "GAIN")
    if (fitsutils.has_par(f, "RDNOISE")):
        rn = fitsutils.get_par(f, "RDNOISE")
    else:
        rn = 20
    array, header = cosmics.fromfits(f)
    
    try:
        c = cosmics.cosmicsimage(array, gain=g, readnoise=rn, sigclip = 8.0, sigfrac = 0.3, satlevel = 64000.0)
        c.run(maxiter = 3)
        out = f.replace('.fits',  '_clean.fits')
    
        cosmics.tofits(out, c.cleanarray, header)
        fitsutils.update_par(out, "CRREJ", 1)

        #os.remove(f)
    except:
        pass
    
    return out
Beispiel #4
0
def correct_files(dirname):

    cmd = "gethead OBJECT *fits | grep -v -i calib | grep PTF | grep -v -E \"\[A|\[B|findi\" | grep ifu | awk '{print $1}' > update_science"
    subprocess.all(cmd, shell=True)

    filelist = os.path.join(dirname, "update_science")

    for f in np.genfromtxt(filelist, dtype=None):
        fitsutils.update_par(f, "OBJDEC", fitsutils.get_par(f, "DEC"))

    for f in np.genfromtxt(filelist, dtype=None):
        fitsutils.update_par(f, "OBJRA", fitsutils.get_par(f, "RA"))

    for f in np.genfromtxt(filelist, dtype=None):
        fitsutils.update_par(
            f, "FILTER",
            fitsutils.get_par(f, "OBJECT").split()[0].replace("]", "").replace(
                "[", ""))

    for f in np.genfromtxt(filelist, dtype=None):
        fitsutils.update_par(f, "NAME",
                             fitsutils.get_par(f, "OBJECT").split()[1])

    for f in np.genfromtxt(filelist, dtype=None):
        fitsutils.update_par(f, "IMGTYPE", "SCIENCE")
Beispiel #5
0
def is_on_target(image):
    '''
    Add as a parameter whether the image is on target or not.
    
    '''
    import coordinates_conversor as cc

    ra, dec = cc.hour2deg(fitsutils.get_par(image, 'OBJRA'),
                          fitsutils.get_par(image, 'OBJDEC'))

    impf = fits.open(image)
    w = wcs.WCS(impf[0].header)

    filt = fitsutils.get_par(image, "FILTER")
    #pra, pdec = wcs.wcs_sky2pix(np.array([ra, dec], ndmin=2), 1)[0]
    pra, pdec = get_xy_coords(image, ra, dec)

    shape = impf[0].data.shape

    if (pra > 0) and (pra < shape[0]) and (pdec > 0) and (pdec < shape[1]):
        fitsutils.update_par(image, "ONTARGET", 1)
        return True
    else:
        fitsutils.update_par(image, "ONTARGET", 0)
        return False
Beispiel #6
0
def correct_files(dirname):
    
    cmd = "gethead OBJECT *fits | grep -v -i calib | grep PTF | grep -v -E \"\[A|\[B|findi\" | grep ifu | awk '{print $1}' > update_science"
    subprocess.all(cmd, shell=True)
    
    filelist = os.path.join(dirname, "update_science")
    
    for f in np.genfromtxt(filelist, dtype=None):
        fitsutils.update_par(f, "OBJDEC", fitsutils.get_par(f, "DEC"))
        
    for f in np.genfromtxt(filelist, dtype=None):
        fitsutils.update_par(f, "OBJRA", fitsutils.get_par(f, "RA"))
    
    for f in np.genfromtxt(filelist, dtype=None):
        fitsutils.update_par(f, "FILTER", fitsutils.get_par(f, "OBJECT").split()[0].replace("]","").replace("[", ""))
        
    for f in np.genfromtxt(filelist, dtype=None):
        fitsutils.update_par(f, "NAME", fitsutils.get_par(f, "OBJECT").split()[1])
        
    for f in np.genfromtxt(filelist, dtype=None):
        fitsutils.update_par(f, "IMGTYPE", "SCIENCE")
Beispiel #7
0
def slice_rc(img):
    '''
    Slices the Rainbow Camera into 4 different images and adds the 'filter' keyword in the fits file.
    '''
    fname = os.path.basename(img)
    fdir = os.path.dirname(img)

    # Running IRAF
    iraf.noao(_doprint=0)

    corners = {
        "g": [1, 910, 1, 900],
        "i": [1, 910, 1060, 2045],
        "r": [1040, 2045, 1015, 2045],
        "u": [1030, 2045, 1, 900]
    }

    filenames = []

    for i, b in enumerate(corners.keys()):
        logger.info("Slicing for filter %s" % b)
        name = fname.replace(".fits", "_%s.fits" % b)

        #Clean first
        if (os.path.isfile(name)):
            os.remove(name)

        iraf.imcopy(
            "%s[%d:%d,%d:%d]" %
            (img, corners[b][0], corners[b][1], corners[b][2], corners[b][3]),
            name)

        fitsutils.update_par(name, 'filter', b)
        is_on_target(name)

        filenames.append(name)

    return filenames
Beispiel #8
0
def clean_cosmic(f):
    '''
    From lacosmic.
    '''
    import cosmics

    out = f.replace('.fits', '_clean.fits')

    #If it does already exist, just return the name.
    if (os.path.isfile(out)):
        return out

    #Otherwise, run the cosmic ray rejection based on LA Cosmic.
    g = fitsutils.get_par(f, "GAIN")
    if (fitsutils.has_par(f, "RDNOISE")):
        rn = fitsutils.get_par(f, "RDNOISE")
    else:
        rn = 20
    array, header = cosmics.fromfits(f)

    try:
        c = cosmics.cosmicsimage(array,
                                 gain=g,
                                 readnoise=rn,
                                 sigclip=8.0,
                                 sigfrac=0.3,
                                 satlevel=64000.0)
        c.run(maxiter=3)
        out = f.replace('.fits', '_clean.fits')

        cosmics.tofits(out, c.cleanarray, header)
        fitsutils.update_par(out, "CRREJ", 1)

        #os.remove(f)
    except:
        pass

    return out
Beispiel #9
0
def slice_rc(img):
    '''
    Slices the Rainbow Camera into 4 different images and adds the 'filter' keyword in the fits file.
    '''
    fname = os.path.basename(img)
    fdir = os.path.dirname(img)    
    
    # Running IRAF
    iraf.noao(_doprint=0)
    
    '''f = pf.open(img)
    h = f[0].header
    i = f[0].data[1000:-1,0:920]
    g = f[0].data[0:910,0:900]
    r = f[0].data[1035:2046, 1050:2046]
    u = f[0].data[0:910,1050:2046]'''
    
    
    corners = {
    "i" : [1, 910, 1, 900],
    "g" : [1, 910, 1060, 2045],
    "r" : [1040, 2045, 1015, 2045],
    "u" : [1030, 2045, 1, 900]
    }
    
    
    filenames = []
        
    for i, b in enumerate(corners.keys()):
        name = fname.replace(".fits", "_%s.fits"%b)
        iraf.imcopy("%s[%d:%d,%d:%d]"%(img, corners[b][0], corners[b][1], corners[b][2], corners[b][3]), name)
         
        fitsutils.update_par(name, 'filter', b)

        filenames.append(name)
    
    return filenames
Beispiel #10
0
def slice_rc(img):
    '''
    Slices the Rainbow Camera into 4 different images and adds the 'filter' keyword in the fits file.
    '''
    fname = os.path.basename(img)
    fdir = os.path.dirname(img)    
    
    # Running IRAF
    iraf.noao(_doprint=0)    
    
    corners = {
    "g" : [1, 910, 1, 900],
    "i" : [1, 910, 1060, 2045],
    "r" : [1040, 2045, 1015, 2045],
    "u" : [1030, 2045, 1, 900]
    }
    
    
    filenames = []
        
    for i, b in enumerate(corners.keys()):
        logger.info( "Slicing for filter %s"% b)
        name = fname.replace(".fits", "_%s.fits"%b)
        
        #Clean first
        if (os.path.isfile(name)):
            os.remove(name)
            
        iraf.imcopy("%s[%d:%d,%d:%d]"%(img, corners[b][0], corners[b][1], corners[b][2], corners[b][3]), name)
         
        fitsutils.update_par(name, 'filter', b)
        is_on_target(name)
        
        filenames.append(name)
    
    return filenames
Beispiel #11
0
def reset_zp(directory):
    """
    Resets the zeropoint keyword to if the result is interpolated.
    """

    files = glob.glob(directory + "/*fits")

    for f in files:
        if fitsutils.get_par(f, "ZPCAT") == "SDSSinterpolated":
            fitsutils.update_par(f, "IQZEROPT", 0)
            fitsutils.update_par(f, "ZEROPT", 0)
            fitsutils.update_par(f, "ZEROPTU", 0)
Beispiel #12
0
def reduce_image(img, flatdir=None, biasdir=None, cosmic=True, astrometry=True, channel='rc', target_dir='reduced'):
    '''
    Applies Flat field and bias calibrations to the image.
    
    Steps:
    
    1. - Solve astrometry on the entire image.
    2. - Compute master bias and de-bias the image.
    3. - Separate the image into 4 filters.
    4. - Compute flat field for each filter and apply flat fielding on the image.
    5. - Computes cosmic ray rejectionon the entire image.
    6. - Compute zeropoint for each image and store in a log file.
    7. - Plot zeropoint for the night.
    '''
    
    print "Reducing image ", img    

    objectname = fitsutils.get_par(img, "OBJECT").replace(" ", "").replace("]","").replace("[", "")

    print "For object", objectname
    
    #Change to image directory
    mydir = os.path.dirname(img)
    if mydir=="": mydir = "."
    mydir = os.path.abspath(mydir)
    os.chdir(mydir)
    #Create destination directory
    if (not os.path.isdir(target_dir)):
        os.makedirs(target_dir)

    #Rename to the image name only
    img = os.path.basename(img)


    if (astrometry):
        print "Solving astometry for the whole image..."
        img = solve_astrometry(img)
        astro = "a_"
    else:
        astro = ""
        
    
    #Compute BIAS
    if (biasdir == None or biasdir==""): biasdir = "."
    create_masterbias(biasdir)
    
    bias_slow = os.path.join(biasdir, "Bias_%s_%s.fits"%(channel, 'slow'))
    bias_fast = os.path.join(biasdir, "Bias_%s_%s.fits"%(channel, 'fast'))
    
    # Running IRAF to DE-BIAS
    iraf.noao(_doprint=0)
    iraf.imred(_doprint=0)
    iraf.ccdred(_doprint=0)
    
    #Compute flat field
    if (flatdir == None or flatdir==""): flatdir = "."
    create_masterflat(flatdir, biasdir)
    
    #New names for the object.
    debiased = "b_" + astro + img
    print "Creating debiased file, ",debiased
    
    if (not os.path.isfile(bias_slow) or not os.path.isfile(bias_fast)):
        print "Master bias not found!"
        return

    #Debias
    if (fitsutils.get_par(img, "ADCSPEED")==2):
        iraf.imarith(img, "-", bias_fast, debiased)
        fitsutils.update_par(debiased, "BIASFILE", bias_fast)
        fitsutils.update_par(debiased, "RDNOISE", 20.)

    else:
        iraf.imarith(img, "-", bias_slow, debiased)
        fitsutils.update_par(debiased, "BIASFILE", bias_slow)
        fitsutils.update_par(debiased, "RDNOISE", 4.)

    #Set negative counts to zero
    hdu = pf.open(debiased)
    header = hdu[0].header
    hdu[0].data[hdu[0].data<0] = 0
    hdu.writeto(debiased, clobber=True)

    #Slicing the image for flats  
    slice_names = slice_rc(debiased)

    
    #Remove un-sliced image
    os.remove(debiased)

    # DE-flat each filter and store under object name
    for i, debiased_f in enumerate(slice_names):
        b = fitsutils.get_par(debiased_f, 'filter')
        
        deflatted = "f_b_" + astro + objectname + "_%s.fits"%b

        #Flat to be used for that filter
        flat = os.path.join(flatdir, "Flat_%s_%s_norm.fits"%(channel, b))

        if (not os.path.isfile(flat)):
            print "Master flat not found in", flat
            return
        #Cleans the deflatted file if exists
        if (os.path.isfile(deflatted)):
            os.remove(deflatted)
            
        iraf.imarith(debiased_f, "/", flat, deflatted)
        
        #Removes the de-biased file
        os.remove(debiased_f)
        
        print "Updating header with original filename and flat field used."
        fitsutils.update_par(deflatted, "ORIGFILE", img)
        fitsutils.update_par(deflatted, "FLATFILE", flat)

        slice_names[i] = deflatted
            
            
    if (cosmic):
        print "Correcting for cosmic rays..."
        # Correct for cosmics each filter
        for i, deflatted in enumerate(slice_names):
            cclean = "c_" +name
            clean_cosmic(os.path.join(os.path.abspath(mydir), deflatted), cclean)
            slice_names[i] = cclean
           
    #Moving files to the target directory
    for name in slice_names:
        if (os.path.isfile(name)):
            shutil.move(name, os.path.join(target_dir, name))
Beispiel #13
0
def find_zeropoint_noid(ref_stars, image, plot=True, plotdir="."):
    """
    Finds the zeropoint by comparig the magnitude of the stars measured in the image,
    vs. the magnitude of the stars from the reference catalogue.
    band: band for which we want to measure the zeropoint.
    col_band: band for the colour term we want to use.
    
    returns the zeropoint, the colour term and the standard deviation in the 
    zeropoint from all the measured stars.
    
    """

    logger.info("Finding the optimum ZP fit...")

    logger.info("Reference stars used: %s" % ref_stars)

    r = np.genfromtxt(ref_stars, delimiter=" ", dtype=None, names=True)
    imapp = os.path.join(os.path.join(os.path.dirname(image), "photometry"), os.path.basename(image) + ".app.mag")
    # imapp = os.path.join(os.path.dirname(image), os.path.basename(image) + ".app.mag")

    my = np.genfromtxt(
        imapp,
        comments="#",
        dtype=[
            ("id", "<f4"),
            ("image", "|S20"),
            ("X", "<f4"),
            ("Y", "<f4"),
            ("Xshift", "<f4"),
            ("Yshift", "<f4"),
            ("fwhm", "<f4"),
            ("ph_mag", "<f4"),
            ("stdev", "<f4"),
            ("fit_mag", "<f4"),
            ("fiterr", "<f4"),
        ],
    )
    """try:
    except:
        my = np.genfromtxt(imapp, comments="#", dtype=[("id","<f4"), ("X","<f4"), ("Y","<f4"),("Xshift","<f4"), ("Yshift","<f4"),("fwhm","<f4"), ("ph_mag","<f4"), ("stdev","<f4"), ("fit_mag","<f4"), ("fiterr","<f4")])
    """

    if my.size < 2:
        my = np.array([my])
    if r.size < 2:
        r = np.array([r])
    coldic = {"u": "g", "g": "r", "r": "i", "i": "z", "z": "i", "U": "B", "B": "V", "V": "R", "R": "I", "I": "R"}
    band = fitsutils.get_par(image, "filter")
    col_band = coldic[band]

    mask_valid1 = (
        np.array(my["fwhm"] < 9000)
        * np.array(my["ph_mag"] < 9000)
        * np.array(~np.isnan(r[band]))
        * np.array(~np.isnan(my["fit_mag"]))
    )

    N = len(r)
    r = r[mask_valid1]
    my = my[mask_valid1]

    if len(my) == 0:
        logger.warn("Warning, no reliable measurements for file %s. Returning 0,0,0." % image)
        return 0, 0, 0

    my["fiterr"][np.isnan(my["fiterr"])] = 100

    ids = np.arange(N) + 1
    ids = ids[mask_valid1]

    coefs, residuals, rank, singular_values, rcond = np.polyfit(
        r[band] - r[col_band],
        r[band] - my["fit_mag"],
        w=1.0 / np.maximum(0.1, np.sqrt(my["fiterr"] ** 2 + r["d" + band] ** 2)),
        deg=1,
        full=True,
    )
    p = np.poly1d(coefs)

    logger.info("Coefficients for 1 deg polynomial fit to the zeropoint: %s" % coefs)
    logger.info("%s - %s = %.3f, %.3f" % (band, col_band, p[0], p[1]))

    pred = p(r[band] - r[col_band])
    measured = r[band] - my["fit_mag"]
    mad = stats.funcs.median_absolute_deviation(pred - measured)

    print "MAD1", mad

    if len(r) > 4:
        mask = np.abs(pred - measured) / mad < 3

        r = r[mask]
        my = my[mask]
        ids = ids[mask]

        coefs, residuals, rank, singular_values, rcond = np.polyfit(
            r[band] - r[col_band],
            r[band] - my["fit_mag"],
            w=1.0 / np.maximum(0.2, np.sqrt(my["fiterr"] ** 2 + r["d" + band] ** 2)),
            deg=1,
            full=True,
        )

        logger.info("Coefficients for 1 deg polynomial fit to the zeropoint: %s. After outlier rejection." % coefs)

        p = np.poly1d(coefs)

        pred = p(r[band] - r[col_band])
        measured = r[band] - my["fit_mag"]
        mad = stats.funcs.median_absolute_deviation(pred - measured)
        print "MAD2", mad

    if plot:
        print "Plotting..."
        plt.errorbar(
            r[band] - r[col_band],
            r[band] - my["fit_mag"],
            yerr=np.sqrt(my["fiterr"] ** 2 + r["d" + band] ** 2),
            marker="o",
            ls="None",
        )
        for i, myid in enumerate(ids):
            plt.text(r[band][i] - r[col_band][i] + 0.01, r[band][i] - my["fit_mag"][i] + 0.01, str(myid))
        x = np.linspace(np.min(r[band] - r[col_band]), np.max(r[band] - r[col_band]), 100)
        plt.plot(x, p(x))
        plt.title("Best fit ZP: %.2f colour term: %.2f MAD: %.2f" % (p[0], p[1], mad))
        plt.xlabel("{:} - {:}".format(band, col_band))
        plt.ylabel("ZP")
        plt.savefig(
            os.path.join(plotdir, os.path.basename(image).replace(".fits", ".zp.png").replace(".new", ".zp.png"))
        )

        plt.clf()

    logger.info("%s - %s = %.3f, %.3f" % (band, col_band, p[0], p[1]))

    pred = p(r[band] - r[col_band])
    measured = r[band] - my["fit_mag"]

    fitsutils.update_par(image, "ZP", np.round(p[0], 3))
    fitsutils.update_par(image, "COLTERM", np.round(p[1], 3))
    fitsutils.update_par(image, "ZPERR", np.round(mad, 3))  # np.std(pred - measured))

    return np.round(p[0], 3), np.round(p[1], 3), np.round(mad, 3)
Beispiel #14
0
def get_app_phot_target(image, plot=False, store=True, wcsin="logical", fwhm=2, box=4, ra=None, dec=None):
    '''
    coords: files: 
    wcsin: can be "world", "logic"
    '''
    # Load packages; splot is in the onedspec package, which is in noao. 
    # The special keyword _doprint=0 turns off displaying the tasks 
    # when loading a package. 
    
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        fxn()

    iraf.noao(_doprint=0)
    iraf.digiphot(_doprint=0)
    iraf.apphot(_doprint=0)
    iraf.unlearn("apphot")
    
    impf = pf.open(image)
    wcs = pywcs.WCS(impf[0].header)
    #Check that actually the object is within this frame.
    if (ra is None or dec is None):
        if (fitsutils.has_par(image, "OBJRA") and fitsutils.has_par(image, "OBJRA")):
            ra, dec = cc.hour2deg(fitsutils.get_par(image, 'OBJRA'), fitsutils.get_par(image, 'OBJDEC'))
        else:
            ra, dec = cc.hour2deg(fitsutils.get_par(image, 'RA'), fitsutils.get_par(image, 'DEC'))
        pra, pdec = get_xy_coords(image, ra, dec)

    else:
        if(wcsin == "logical"):
            pra, pdec = ra, dec
        else:
        #Using new method to derive the X, Y pixel coordinates, as pywcs does not seem to be working well.
            pra, pdec = get_xy_coords(image, ra, dec)
            #pra, pdec = wcs.wcs_sky2pix(ra, dec, 1)
            #pra, pdec = wcs.wcs_sky2pix(np.array([ra, dec], ndmin=2), 1)[0]

    shape = impf[0].data.shape
    
    if (pra > 0)  and (pra < shape[0]) and (pdec > 0) and (pdec < shape[1]):
        pass
    else:
        print image, "ERROR! Object coordinates are outside this frame. Skipping any aperture photometry!!"
        print pra, pdec, shape
        return
    
        
    imdir = os.path.dirname(image)
    imname = os.path.basename(image)
    plotdir = os.path.join(imdir, "photometry")

    if not os.path.isdir(plotdir):
        os.makedirs(plotdir)
        
    out_name = os.path.join(plotdir, imname +  ".seq.mag")
    clean_name = os.path.join(plotdir, imname +  ".objapp.mag")
    
    
    fwhm_value = fwhm

    nsrc, fwhm_value, ellip = sextractor.get_image_pars(image)
    if np.isnan(fwhm_value):
	fwhm_value=99
    fitsutils.update_par(image, 'FWHM', fwhm_value)
        
    if (fitsutils.has_par(image, 'AIRMASS')):
        airmass_value = fitsutils.get_par(image, 'AIRMASS')
    else:
        airmass_value = 1.3
        
    exptime = fitsutils.get_par(image, 'EXPTIME')
    gain = fitsutils.get_par(image, 'GAIN')
    
    
    #print "FWHM", fwhm_value
    aperture_rad = math.ceil(float(fwhm_value)*3)      # Set aperture radius to three times the PSF radius
    sky_rad= math.ceil(aperture_rad*4)
    
    #print aperture_rad, sky_rad

    
    
    print "Saving coodinates for the object in pixels",pra,pdec
    coords = "/tmp/coords.dat"    
    np.savetxt("/tmp/coords.dat", np.array([[pra, pdec]]), fmt="%.4f %.4f")


    if (plot):    
        zmin, zmax = zscale.zscale(impf[0].data)
           
        im = plt.imshow(impf[0].data, vmin=zmin, vmax=zmax, origin="bottom")
        plt.scatter(pra, pdec, marker="o", s=100, facecolor="none")
        plt.savefig(os.path.join(plotdir, imname+".png"))
        plt.clf()
    
    
    if os.path.isfile(out_name): os.remove(out_name)
    if os.path.isfile(clean_name): os.remove(clean_name)


    iraf.noao.digiphot.apphot.qphot(image = image,\
    cbox = box ,\
    annulus = sky_rad ,\
    dannulus = 15. ,\
    aperture = str(aperture_rad),\
    coords = coords ,\
    output = out_name ,\
    plotfile = "" ,\
    zmag = 0. ,\
    exposure = "exptime" ,\
    airmass = "airmass" ,\
    filter = "filter" ,\
    obstime = "DATE" ,\
    epadu = gain ,\
    interactive = "no" ,\
    radplots = "yes" ,\
    verbose = "no" ,\
    graphics = "stdgraph" ,\
    display = "stdimage" ,\
    icommands = "" ,\
    wcsin = "logical",
    wcsout = "logical",
    gcommands = "") 


    #iraf.noao.digiphot.apphot.phot(image=image, cbox=5., annulus=12.4, dannulus=10., salgori = "centroid", aperture=9.3,wcsin="world",wcsout="tv", interac = "no", coords=coords, output=out_name)
    iraf.txdump(out_name, "id,image,xcenter,ycenter,xshift,yshift,fwhm,msky,stdev,mag,merr", "yes", Stdout=clean_name)
    

    ma = np.genfromtxt(clean_name, comments="#", dtype=[("id","<f4"),  ("image","|S20"), ("X","<f4"), ("Y","<f4"), ("Xshift","<f4"), ("Yshift","<f4"),("fwhm","<f4"), ("ph_mag","<f4"), ("stdev","<f4"), ("fit_mag","<f4"), ("fiterr","<f4")])
    if (ma.size > 0):  
        if (ma.size==1):
            ma = np.array([ma])
        m = ma[~np.isnan(ma["fit_mag"])]
    else:
        print "Only one object found!"
        m = np.array([ma])
        

    insmag =  np.round(ma['fit_mag'][0] , 3)
    insmagerr = np.round(ma['fiterr'][0], 3)  
    if (fitsutils.has_par(image, "ZEROPT")):
        mag =  insmag + float(fitsutils.get_par(image, "ZEROPT"))
        magerr = np.sqrt(insmagerr**2+ float(fitsutils.get_par(image, "ZEROPTU"))**2)  
	
    if np.isnan(mag):
        mag, magerr = 0, 0
        insmag, insmagerr = 0,0           

   
    fitsutils.update_par(image, "INSMAG", "%.3f"%insmag )
    fitsutils.update_par(image, "INSMAGER", "%.3f"%insmagerr)
    fitsutils.update_par(image, "APPMAG", np.round(mag, 3) )
    fitsutils.update_par(image, "APPMAGER", np.round(magerr, 3))

         
    if (plot):
        X = int(ma["X"][0])
        Y = int(ma["Y"][0])
        pra = int(pra)
        pdec = int(pdec)
        
        plt.scatter(X, Y, marker="o", s=100, facecolor="none", edgecolor="red")
        plt.colorbar(im)
        plt.savefig(os.path.join(plotdir, imname+".png"))
        plt.clf()
        
        zmin, zmax = zscale.zscale(impf[0].data.T[X-50:X+50,Y-50:Y+50].T)
        im = plt.imshow(impf[0].data.T[pra-50:pra+50,pdec-50:pdec+50].T, vmin=zmin, vmax=zmax, interpolation="none", origin="bottom", extent=(-50,50,-50,50))
        c1 = plt.Circle( (pra-X, pdec-Y), edgecolor="k", facecolor="none", radius=aperture_rad, label="Initial position")
        c11 = plt.Circle( (pra-X, pdec-Y), edgecolor="k", facecolor="none", radius=sky_rad)
        c2 = plt.Circle( (0, 0), edgecolor="orange", facecolor="none", radius=aperture_rad, label="Adjusted centroid")
        c22 = plt.Circle( (0, 0), edgecolor="orange", facecolor="none", radius=sky_rad)
        plt.gca().add_artist(c1)
        plt.gca().add_artist(c11)
        plt.gca().add_artist(c2)
        plt.gca().add_artist(c22)
        plt.colorbar(im)
        
        myhandles = []
        markers = ["o", "o"]
        labels = ["Initial position", "Adjusted centroid"]
        cols = ["k", "orange"]
        for i in np.arange(len(markers)):
                myhandles.append(mlines.Line2D([], [], mec=cols[i], mfc="none", marker=markers[i], ls="None", markersize=10, label=labels[i]))
        plt.legend(handles=myhandles, loc="lower left", labelspacing=0.3, fontsize=11, numpoints=1, frameon=False, ncol=5, bbox_to_anchor=(0.0, 0.00), fancybox=False, shadow=True)

        plt.title("MIN: %.0f MAX: %.0f"%(np.nanmin(impf[0].data.T[X-50:X+50,Y-50:Y+50]), np.nanmax(impf[0].data.T[X-50:X+50,Y-50:Y+50])))
        plt.savefig(os.path.join(plotdir, imname+"_zoom.png"))
        plt.clf()
Beispiel #15
0
def extract_star_sequence(imfile, band, plot=True, survey="sdss", debug=False, refstars=None, plotdir="."):
    """
    Given a fits image: imfile and a the name of the band which we want to extract the sources from,
    it saves the extracted sources into  '/tmp/sdss_cat_det.txt' file.
    If the band does not match the bands in the survey, a change is performed to adapt to the new band.
    
    If plotting activated, plots the USNOB1 field of stars on top of the star field image.
    Red circles are stars identified from the catalogue in the correct magnitude range.
    Yellow circles are stars that are isolated.
    
    """

    survey = str.lower(survey)
    minmag = 15
    maxmag = 21.0

    f = pf.open(imfile)
    wcs = pywcs.WCS(f[0].header)

    img = f[0].data
    img[img < 0] = 0

    ra, dec = wcs.wcs_pix2sky(np.array([img.shape[0] / 2, img.shape[1] / 2], ndmin=2), 1)[0]
    ra0, dec0 = wcs.wcs_pix2sky(np.array([img.shape[0], img.shape[1]], ndmin=2), 1)[0]

    sr = 2 * np.abs(dec - dec0)
    logger.info("%.4f %.4f %.4f" % (ra, dec, sr))

    if not refstars is None:
        shutil.copy(refstars, "/tmp/tmp_sdss_%s.cat" % creationdate)
        catalog = np.genfromtxt("/tmp/tmp_sdss_%s.cat" % creationdate, names=True, dtype=None, delimiter=",")
        cat_ra = catalog["ra"]
        cat_dec = catalog["dec"]
        try:
            mag = catalog["R"]
        except:
            mag = catalog["r"]

    elif str.lower(survey) == "usnob1":
        # ra, dec = coordinates_conversor.hour2deg(f[0].header['RA'], f[0].header['DEC'])
        # SEDM FoV is 6.5 arcmin, due to uncertainties in the position, 4 arcmin radius assumed.
        # Download USNO-B1 catalog for the position
        catalog_url = "http://www.nofs.navy.mil/cgi-bin/vo_cone.cgi?CAT=USNO-B1&RA=%.5f&DEC=%.5f&SR=%.4f&VERB=1" % (
            ra,
            dec,
            sr,
        )
        logger.info("Downloading USNO-B1 catalog...")
        urllib.urlretrieve(catalog_url, "/tmp/tmp_%s.cat" % creationdate)

        # Read RA, Dec and magnitude from XML format USNO catalog
        catalog = parse_single_table("/tmp/tmp_%s.cat" % creationdate)
        cat_ra = catalog.array["RA"].data
        cat_dec = catalog.array["DEC"].data
        cat_R1mag = catalog.array["R1"].data
        cat_R2mag = catalog.array["R2"].data
        cat_B1mag = catalog.array["B1"].data
        cat_B2mag = catalog.array["B2"].data
        cat_I2mag = catalog.array["I2"].data

        cat_R1mag[cat_R1mag == 0] = np.nan
        cat_R2mag[cat_R2mag == 0] = np.nan
        cat_B1mag[cat_B1mag == 0] = np.nan
        cat_B2mag[cat_B2mag == 0] = np.nan
        cat_I2mag[cat_I2mag == 0] = np.nan

        Bmag = np.nanmean(np.array([cat_B1mag, cat_B2mag]), axis=0)
        Rmag = np.nanmean(np.array([cat_R1mag, cat_R2mag]), axis=0)
        Imag = cat_I2mag

        mag = Rmag
    elif survey == "apass":
        # Download USNO-B1 catalog for the position
        catalog_url = "https://www.aavso.org/cgi-bin/apass_download.pl?ra=%.5f&dec=%.5f&radius=%.4f8&outtype=1" % (
            ra,
            dec,
            sr,
        )
        print "Downloading APASS catalog..."
        urllib.urlretrieve(catalog_url, "/tmp/tmp_apass_%s.cat" % creationdate)
        catalog = np.genfromtxt("/tmp/tmp_apass_%s.cat" % creationdate, delimiter=",", names=True)
        if np.ndim(catalog) == 0:
            return False
        cat_ra = catalog["radeg"]
        cat_dec = catalog["decdeg"]
        mag = catalog["Sloan_r"]

    elif survey == "sdss":
        minmag = 15
        maxmag = 21.5
        catalog_url = (
            "http://skyserver.sdss.org/dr9/en/tools/search/x_radial.asp?ra=%.5f&dec=%.5f&check_type=type&type=6&radius=%.4f&check_u=u&min_u=%.2f&max_u=%.2f&check_g=g&min_g=%.2f&max_g=%.2f&check_r=r&min_r=%.2f&max_r=%.2f&check_i=i&min_i=%.2f&max_i=%.2f&check_z=z&min_z=%.2f&max_z=%.2f&entries=top&topnum=500&format=csv"
            % (ra, dec, sr * 60, minmag, maxmag, minmag, maxmag, minmag, maxmag, minmag, maxmag, minmag, maxmag)
        )
        logger.info("Downloading SDSS catalog...")
        logger.info("%s" % catalog_url)
        urllib.urlretrieve(catalog_url, "/tmp/tmp_sdss_%s.cat" % creationdate)
        catalog = np.genfromtxt("/tmp/tmp_sdss_%s.cat" % creationdate, delimiter=",", names=True)

        if np.ndim(catalog) == 0:
            return False
        try:
            cat_ra = np.array(catalog["ra"], ndmin=1)
            cat_dec = np.array(catalog["dec"], ndmin=1)
            if band in catalog.dtype.names:
                print "SDSS filter detected"
                mag = np.array(catalog[band], ndmin=1)
            elif band in ["U", "B", "V", "R", "I", "Z"]:
                print "Johnson filter detected."
                john = transformations.sdss2johnson(
                    "/tmp/tmp_sdss_%s.cat" % creationdate, savefile="/tmp/tmp_sdss_%s.cat" % creationdate
                )
                mag = john[band]
                catalog = np.genfromtxt("/tmp/tmp_sdss_%s.cat" % creationdate, dtype=None, names=True, delimiter=",")
            else:
                print "Unknown band!!", band
        except IOError:
            logger.error("Problems with SDSS image %s" % band)
            return False
        except ValueError:
            logger.error("Problems with the catalogue for the image")
            return False

    # Convert ra, dec position of all stars to pixels.
    star_pix = np.array([0, 0])
    for i in range(len(cat_ra)):
        # Get pixel coordinates of USNO stars
        s = wcs.wcs_sky2pix(np.array([cat_ra[i], cat_dec[i]], ndmin=2), 1)[0]
        star_pix = np.row_stack((star_pix, s))

    star_pix = star_pix[1:]
    pix2ang = 0.394
    rad = math.ceil(25.0 / pix2ang)
    # Select only the stars within the image.
    mask = (
        (star_pix[:, 0] > -rad)
        * (star_pix[:, 0] < img.shape[1] + rad)
        * (star_pix[:, 1] > -rad)
        * (star_pix[:, 1] < img.shape[0] + rad)
    )
    if band == "u":
        mask = mask * (mag < 19)
    # Select only stars isolated in a radius of ~12 arcsec.
    mask2 = np.array(are_isolated(cat_ra[mask], cat_dec[mask], 15.0))
    if len(mask2) == 0:
        logger.error("No good stars left")
        return False

        # Select only stars that are within the proper magnitude range
    mask3 = (mag[mask][mask2] < maxmag) * (mag[mask][mask2] > minmag)

    mask3 = (
        mask3
        * (star_pix[:, 0][mask][mask2] > rad)
        * (star_pix[:, 0][mask][mask2] < img.shape[1] - rad)
        * (star_pix[:, 1][mask][mask2] > rad)
        * (star_pix[:, 1][mask][mask2] < img.shape[0] - rad)
    )

    if survey == "usnob1":
        output = np.column_stack(
            (
                star_pix[:, 0][mask][mask2][mask3],
                star_pix[:, 0][mask][mask2][mask3],
                cat_ra[mask][mask2][mask3],
                cat_dec[mask][mask2][mask3],
                Bmag[mask][mask2][mask3],
                Rmag[mask][mask2][mask3],
                Imag[mask][mask2][mask3],
            )
        )
        np.savetxt("/tmp/usnob1_cat.txt", output, fmt="%.5f %.5f %.5f %.5f %.5f %.5f %.5f", header="#X Y ra dec B R I")
        print "Saved to", "/tmp/usnob1_cat.txt"
    elif survey == "apass":

        if not np.any(mask2) and not np.any(mask3):
            print star_pix
            print "No stars left...", mask, mask2, mask3
            return
        else:
            print catalog[mask][mask2][mask3]

        catalog = catalog[mask][mask2][mask3]
        s = star_pix[mask][mask2][mask3]
        z = np.zeros(len(s), dtype=[("x", "f8"), ("y", "f8")])
        z["x"] = s[:, 0]
        z["y"] = s[:, 1]

        for n in catalog.dtype.names:
            z = rfn.append_fields(z, names=n, data=catalog[n], usemask=False)

        fmt = "%.5f"
        for i in range(len(z[0]) - 1):
            fmt += " %.5f"

        np.savetxt(
            "/tmp/apass_cat.txt",
            z,
            fmt=fmt,
            header="x y radeg raerr decdeg decerr number_of_Obs V dV B dB g dg r dr i di",
        )
        print "Saved to", "/tmp/apass_cat.txt"
    elif survey == "sdss":
        if (not np.any(mask) and not np.any(mask2) and not np.any(mask3)) or len(catalog[mask][mask2][mask3]) == 0:
            print star_pix
            print "No stars left...", mask, mask2, mask3
            return False
        else:
            catalog = catalog[mask][mask2][mask3]
            s = star_pix[mask][mask2][mask3]

            print "left %d stars" % (len(catalog)), catalog.dtype.names

            z = np.zeros(len(s), dtype=[("x", "f8"), ("y", "f8")])
            z["x"] = s[:, 0]
            z["y"] = s[:, 1]

            header = "x y "
            for n in catalog.dtype.names:
                if n in [
                    "objid",
                    "ra",
                    "dec",
                    "u",
                    "g",
                    "r",
                    "i",
                    "z",
                    "Err_u",
                    "Err_g",
                    "Err_r",
                    "Err_i",
                    "Err_z",
                ] or n in ["id", "ra", "dec", "U", "B", "V", "R", "I", "dU", "dB", "dV", "dR", "dI"]:
                    z = rfn.append_fields(z, names=n, data=catalog[n], usemask=False)
                    header += n.replace("Err_", "d") + " "

            fmt = "%.5f"
            for i in range(len(z[0]) - 1):
                fmt += " %.5f"

            np.savetxt("/tmp/sdss_cat_%s.txt" % creationdate, z, fmt=fmt, header=header)
            logger.info("Saved catalogue stars to %s" % ("/tmp/sdss_cat_%s.txt" % creationdate))

            # Find FWHM for this image
            out = find_fwhm(imfile, star_pix[:, 1][mask][mask2][mask3], star_pix[:, 0][mask][mask2][mask3], plot=debug)
            mask_valid_fwhm = (out["detected"]) * (out["e"] > 0.6) * ~np.isnan(out["fwhm"] * (out["fwhm"] < 30))

            if ((np.count_nonzero(mask_valid_fwhm) < 3) and (fitsutils.get_par(imfile, "FILTER") != "u")) or (
                (np.count_nonzero(mask_valid_fwhm) < 2) and (fitsutils.get_par(imfile, "FILTER") == "u")
            ):
                logger.error(
                    "ERROR with FWHM!! Too few points for a valid estimation. %d" % np.count_nonzero(mask_valid_fwhm)
                    + ") points"
                )
                logger.error("%s %s" % (out["detected"], out["fwhm"]))
                return False

            outd = out[mask_valid_fwhm]

            logger.info(
                "Average FWHM %.3f arcsec, %.3f pixels" % (np.median(outd["fwhm"]), np.median(outd["fwhm"]) * pix2ang)
            )

            fwhm = np.percentile(outd["fwhm"], 40)
            fitsutils.update_par(imfile, "FWHM", np.round(fwhm, 3))

            if band in "ugriz":
                header = "x y objid ra dec u g r i z du dg dr di dz"
            elif band in "UBVRI":
                header = "x y objid ra dec U B V R I dU dB dV dR dI"
            np.savetxt("/tmp/sdss_cat_det_%s.txt" % creationdate, z[mask_valid_fwhm], fmt=fmt, header=header)
            print "Saved to", "/tmp/sdss_cat_det_%s.txt" % creationdate

    # Plot results
    img = img - np.nanmin(img)
    zmin, zmax = zscale.zscale(img)

    logger.info(
        "Found %d stars in %s. " % (len(cat_dec), survey)
        + "%d of them within the FoV. " % len(cat_ra[mask])
        + "%d of them are isolated." % len(cat_ra[mask][mask2])
        + "%d of them with suitable magnitudes. " % len(cat_ra[mask][mask2][mask3])
        + "%d of them with detected stars." % np.count_nonzero(mask_valid_fwhm)
    )

    if plot:
        im = plt.imshow(
            img, aspect="equal", origin="lower", cmap=matplotlib.cm.gray_r, interpolation="none", vmin=zmin, vmax=zmax
        )

        if len(star_pix[:, 0][mask]) > 0:
            plt.scatter(
                star_pix[:, 0][mask],
                star_pix[:, 1][mask],
                marker="o",
                s=np.minimum(150, 10000 * (10.0 / mag[mask][mask2]) ** 9),
                edgecolor="red",
                facecolor="none",
                label="catalogue",
            )

        if len(star_pix[:, 0][mask][mask2]) > 0:
            plt.scatter(
                star_pix[:, 0][mask][mask2],
                star_pix[:, 1][mask][mask2],
                marker="o",
                s=20,
                edgecolor="yellow",
                facecolor="none",
                label="isolated",
            )

        if len(star_pix[:, 0][mask][mask2][mask3]) > 0:
            plt.scatter(
                star_pix[:, 0][mask][mask2][mask3],
                star_pix[:, 1][mask][mask2][mask3],
                marker="o",
                s=200,
                edgecolor="green",
                facecolor="none",
                label="wihtin farme and mag",
            )

        selected = star_pix[:, :][mask][mask2][mask3][mask_valid_fwhm]
        if len(selected) > 0:
            plt.scatter(selected[:, 0], selected[:, 1], marker="o", s=400, edgecolor="blue", facecolor="none")
            for i in np.arange(len(selected)):
                plt.text(selected[i, 0] + 10, selected[i, 1] + 10, i + 1)

        plt.legend(loc="best", frameon=False, framealpha=0.9)
        plt.savefig(
            os.path.join(
                plotdir, os.path.basename(imfile).replace(".fits", ".seqstars.png").replace(".new", ".seqstars.png")
            )
        )
        logger.info("Saved stars to %s" % imfile.replace(".fits", ".seqstars.png"))
        plt.clf()

    return True
Beispiel #16
0
def get_app_phot_target(image, ra=None, dec=None, plot=True, store=True, wcsin="logical", fwhm=None, box=15, arcsecpix=0.394, app=2):
    '''
    coords: files: 
    wcsin: can be "world", "logic"
    fwhm: in arcsec
    
    '''
    # Load packages; splot is in the onedspec package, which is in noao. 
    # The special keyword _doprint=0 turns off displaying the tasks 
    # when loading a package. 
    
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        fxn()

    iraf.noao(_doprint=0)
    iraf.digiphot(_doprint=0)
    iraf.apphot(_doprint=0)
    iraf.unlearn("apphot")
    
    impf = pf.open(image)
    wcs = WCS(impf[0].header)
    #Check that actually the object is within this frame.
    if (ra is None or dec is None):
        if (fitsutils.has_par(image, "OBJRA") and fitsutils.has_par(image, "OBJRA")):
            ra, dec = cc.hour2deg(fitsutils.get_par(image, 'OBJRA'), fitsutils.get_par(image, 'OBJDEC'))
        else:
            ra, dec = cc.hour2deg(fitsutils.get_par(image, 'RA'), fitsutils.get_par(image, 'DEC'))
        print "Assuming ra=%.5f, dec=%.5f"%(ra, dec)
        pra, pdec = get_xy_coords(image, ra, dec)

    else:
        if("logic" in wcsin):
            pra, pdec = ra, dec
        else:
        #Using new method to derive the X, Y pixel coordinates, as wcs module does not seem to be working well.
            try:
                #pra, pdec = wcs.wcs_sky2pix(ra, dec, 1)
                #print "Retrieved the pixel number"
                pra, pdec = get_xy_coords(image, ra, dec)
            except IndexError:
                print "Error with astrometry.net. trying the rudimentary method."
                pra, pdec = wcs.wcs_sky2pix(ra, dec, 1)
            #pra, pdec = wcs.wcs_sky2pix(np.array([ra, dec], ndmin=2), 1)[0]

    shape = impf[0].data.shape
    
    if (pra > 0)  and (pra < shape[0]) and (pdec > 0) and (pdec < shape[1]):
        pass
    else:
        print image, "ERROR! Object coordinates are outside this frame. Skipping any aperture photometry!!"
        print pra, pdec, shape
        return
    
        
    imdir = os.path.dirname(image)
    imname = os.path.basename(image)
    plotdir = os.path.join(imdir, "photometry")

    if not os.path.isdir(plotdir):
        os.makedirs(plotdir)
        
    out_name = os.path.join(plotdir, imname +  ".seq.mag")
    clean_name = os.path.join(plotdir, imname +  ".objapp.mag")
    
    if (not fwhm is None):
        fwhm_value = fwhm
    elif (fitsutils.has_par(image, 'FWHM')):
        fwhm_value = fitsutils.get_par(image, 'FWHM')
    else:
        #Put some default value for Palomar
        fwhm_value=1.5
        
    if (wcsin == 'logical'):
        fwhm_value = fwhm_value / arcsecpix 
        
    if (fitsutils.has_par(image, 'AIRMASS')):
        airmass_value = fitsutils.get_par(image, 'AIRMASS')
    else:
        airmass_value = 1.3
        
    if (not fitsutils.has_par(image, "EXPTIME")):
        if (fitsutils.has_par(image, "ITIME") and fitsutils.has_par(image, "COADDS")):
            exptime = fitsutils.get_par(image, "ITIME")*fitsutils.get_par(image, "COADDS")
            fitsutils.update_par(image, "EXPTIME", exptime)
    exptime = fitsutils.get_par(image, 'EXPTIME')
    gain = fitsutils.get_par(image, 'GAIN')
    
    #print "FWHM", fwhm_value
    aperture_rad = math.ceil(float(fwhm_value)*app)      # Set aperture radius to two times the PSF radius
    sky_rad= math.ceil(aperture_rad*app*2)
    
    #print aperture_rad, sky_rad

    
    
    print "Saving coodinates for the object in pixels",pra,pdec
    coords = "/tmp/coords.dat"    
    np.savetxt("/tmp/coords.dat", np.array([[pra, pdec]]), fmt="%.4f %.4f")

   
    
    if os.path.isfile(out_name): os.remove(out_name)
    if os.path.isfile(clean_name): os.remove(clean_name)


    iraf.noao.digiphot.apphot.qphot(image = image,\
    cbox = box ,\
    annulus = sky_rad ,\
    dannulus = 20. ,\
    aperture = str(aperture_rad),\
    coords = coords ,\
    output = out_name ,\
    plotfile = "" ,\
    zmag = 0. ,\
    exposure = "exptime" ,\
    airmass = "airmass" ,\
    filter = "filter" ,\
    obstime = "DATE" ,\
    epadu = gain ,\
    interactive = "no" ,\
    radplots = "yes" ,\
    verbose = "no" ,\
    graphics = "stdgraph" ,\
    display = "stdimage" ,\
    icommands = "" ,\
    wcsin = "logical",
    wcsout = "logical",
    gcommands = "") 


    #iraf.noao.digiphot.apphot.phot(image=image, cbox=5., annulus=12.4, dannulus=10., salgori = "centroid", aperture=9.3,wcsin="world",wcsout="tv", interac = "no", coords=coords, output=out_name)
    iraf.txdump(out_name, "id,image,xcenter,ycenter,xshift,yshift,fwhm,msky,stdev,cier,rapert,sum,area,nsky,flux,itime,mag,merr", "yes", Stdout=clean_name)

    

    ma = np.genfromtxt(clean_name, comments="#", dtype=[("id","<f4"),  ("image","|S20"), ("X","<f4"), ("Y","<f4"), ("Xshift","<f4"), ("Yshift","<f4"),("fwhm","<f4"), ("msky","<f4"), \
        ("stdev","<f4"), ("flags", np.int), ("rapert", "<f4"), ("sum", "<f4"), ("area", "<f4"), ("nsky","<f4") , ("flux", "<f4"), ("itime", "<f4"), ("fit_mag","<f4"), ("fiterr","<f4")])
    if (ma.size > 0):  
        ma = np.array([ma])
        m = ma[~np.isnan(ma["fit_mag"])]
    else:
        print "Only one object found!"
        m = np.array([ma])
        

    insmag =  np.round(ma['fit_mag'][0] , 3)
    insmagerr = np.round(ma['fiterr'][0], 3)  
    if (fitsutils.has_par(image, "ZEROPT") and fitsutils.has_par(image, "ZEROPTU")):
        mag =  insmag + float(fitsutils.get_par(image, "ZEROPT"))
        magerr = np.sqrt(insmagerr**2+ float(fitsutils.get_par(image, "ZEROPTU"))**2)  
    else:
	mag = 0
	magerr = 0
	
    if np.isnan(mag):
        mag, magerr = 0, 0
        insmag, insmagerr = 0,0           

   
    fitsutils.update_par(image, "INSMAG", "%.3f"%insmag )
    fitsutils.update_par(image, "INSMAGER", "%.3f"%insmagerr)
    fitsutils.update_par(image, "APPMAG", np.round(mag, 3) )
    fitsutils.update_par(image, "APPMAGER", np.round(magerr, 3))

         
    if (plot):
        
        #zmin, zmax = zscale.zscale(impf[0].data.T[pra-50:pra+50,pdec-50:pdec+50])
        
        #zmin, zmax = zscale.zscale(impf[0].data)
           
        #im = plt.imshow(impf[0].data, vmin=zmin, vmax=zmax, origin="bottom")
        print np.percentile(impf[0].data, 5), np.percentile(impf[0].data, 95)
        impf[0].data[np.isnan(impf[0].data)] = np.nanmedian(impf[0].data)
        print np.percentile(impf[0].data, 5), np.percentile(impf[0].data, 95)

        im = plt.imshow(impf[0].data, vmin=np.percentile(impf[0].data, 5), vmax=np.percentile(impf[0].data, 95), origin="bottom")
       
        X = int(ma["X"][0])
        Y = int(ma["Y"][0])
        pra = int(pra)
        pdec = int(pdec)
        
        plt.scatter(X, Y, marker="o", s=100, facecolor="none", edgecolor="red")
        plt.colorbar(im)
        plt.savefig(os.path.join(plotdir, imname+".png"), dpi=200)
        plt.clf()
        
        zmin, zmax = zscale.zscale(impf[0].data.T[X-50:X+50,Y-50:Y+50].T)
        im = plt.imshow(impf[0].data.T[pra-50:pra+50,pdec-50:pdec+50].T, vmin=zmin, vmax=zmax, interpolation="none", origin="bottom", extent=(-50,50,-50,50))
        c1 = plt.Circle( (pra-X, pdec-Y), edgecolor="k", facecolor="none", radius=aperture_rad, label="Initial position")
        c11 = plt.Circle( (pra-X, pdec-Y), edgecolor="k", facecolor="none", radius=sky_rad)
        c2 = plt.Circle( (0, 0), edgecolor="orange", facecolor="none", radius=aperture_rad, label="Adjusted centroid")
        c22 = plt.Circle( (0, 0), edgecolor="orange", facecolor="none", radius=sky_rad)
        plt.gca().add_artist(c1)
        plt.gca().add_artist(c11)
        plt.gca().add_artist(c2)
        plt.gca().add_artist(c22)
        plt.colorbar(im)
        
        myhandles = []
        markers = ["o", "o"]
        labels = ["Initial position", "Adjusted centroid"]
        cols = ["k", "orange"]
        for i in np.arange(len(markers)):
                myhandles.append(mlines.Line2D([], [], mec=cols[i], mfc="none", marker=markers[i], ls="None", markersize=10, label=labels[i]))
        plt.legend(handles=myhandles, loc="lower left", labelspacing=0.3, fontsize=11, numpoints=1, frameon=False, ncol=5, bbox_to_anchor=(0.0, 0.00), fancybox=False, shadow=True)

        plt.title("MIN: %.0f MAX: %.0f"%(np.nanmin(impf[0].data.T[X-50:X+50,Y-50:Y+50]), np.nanmax(impf[0].data.T[X-50:X+50,Y-50:Y+50])))
        plt.savefig(os.path.join(plotdir, imname+"_zoom.png"))
        plt.clf()
Beispiel #17
0
def reduce_image(image,
                 flatdir=None,
                 biasdir=None,
                 cosmic=False,
                 astrometry=True,
                 channel='rc',
                 target_dir='reduced',
                 overwrite=False):
    '''
    Applies Flat field and bias calibrations to the image.
    
    Steps:
    
    1. - Solve astrometry on the entire image.
    2. - Computes cosmic ray rejectionon the entire image.
    3. - Compute master bias (if it does not exist) and de-bias the image.
    4. - Separate the image into 4 filters.
    5. - Compute flat field for each filter (if it does not exist) and apply flat fielding on the image.
    6. - Compute the image zeropoint.

    '''

    logger.info("Reducing image %s" % image)

    print "Reducing image ", image

    image = os.path.abspath(image)
    imname = os.path.basename(image).replace(".fits", "")
    try:
        objectname = fitsutils.get_par(image, "NAME").replace(
            " ", "") + "_" + fitsutils.get_par(image, "FILTER")
    except:
        logger.error("ERROR, image " + image +
                     " does not have a NAME or a FILTER!!!")
        return

    print "For object", objectname
    logger.info("For object %s" % objectname)

    #Change to image directory
    mydir = os.path.dirname(image)
    if mydir == "": mydir = "."
    mydir = os.path.abspath(mydir)
    os.chdir(mydir)
    #Create destination directory
    if (not os.path.isdir(target_dir)):
        os.makedirs(target_dir)

    #If we don't want to overwrite the already extracted images, we check wether they exist.
    if (not overwrite):
        existing = True
        for band in ['u', 'g', 'r', 'i']:
            destfile = os.path.join(
                target_dir,
                imname + "_f_b_a_%s_%s_0.fits" % (objectname, band))
            logger.info( "Looking if file %s exists: %s"%( destfile, \
                (os.path.isfile(destfile) ) ) )
            existing = existing and (os.path.isfile(destfile))
        if existing:
            return []

    #Initialize the basic parameters.
    init_header_reduced(image)

    astro = ""
    if (astrometry):
        logger.info("Solving astometry for the whole image...")
        img = solve_astrometry(image)
        if (os.path.isfile(img)):
            astro = "a_"
            fitsutils.update_par(img, "IQWCS", 1)
        else:
            logger.error("ASTROMETRY DID NOT SOLVE ON IMAGE %s" % image)
            img = image

    #Update noise parameters needed for cosmic reection
    if (fitsutils.get_par(img, "ADCSPEED") == 2):
        fitsutils.update_par(img, "RDNOISE", 20.)
    else:
        fitsutils.update_par(img, "RDNOISE", 4.)

    if (cosmic):
        logger.info("Correcting for cosmic rays...")
        # Correct for cosmics each filter
        cleanimg = clean_cosmic(os.path.join(os.path.abspath(mydir), img))
        img = cleanimg

    #Compute BIAS
    if (biasdir is None or biasdir == ""): biasdir = "."
    create_masterbias(biasdir)

    bias_slow = os.path.join(biasdir, "Bias_%s_%s.fits" % (channel, 'slow'))
    bias_fast = os.path.join(biasdir, "Bias_%s_%s.fits" % (channel, 'fast'))

    # Running IRAF to DE-BIAS
    iraf.noao(_doprint=0)
    iraf.imred(_doprint=0)
    iraf.ccdred(_doprint=0)

    #Compute flat field
    if (flatdir is None or flatdir == ""): flatdir = "."
    create_masterflat(flatdir, biasdir)

    #New names for the object.
    debiased = os.path.join(os.path.dirname(img), "b_" + os.path.basename(img))
    logger.info("Creating debiased file, %s" % debiased)

    if ( (fitsutils.get_par(img, "ADCSPEED")==0.1 and not os.path.isfile(bias_slow)) \
        or (fitsutils.get_par(img, "ADCSPEED")==2 and not os.path.isfile(bias_fast)) ):
        logger.warn(
            "Master bias not found! Tryting to copy from reference folder...")
        copy_ref_calib(mydir, "Bias")
        if ( (fitsutils.get_par(img, "ADCSPEED")==0.1 and not os.path.isfile(bias_slow)) \
        or (fitsutils.get_par(img, "ADCSPEED")==2 and not os.path.isfile(bias_fast)) ):
            logger.error("Bias not found in reference folder")
            return

    #Clean first
    if (os.path.isfile(debiased)):
        os.remove(debiased)

    #Debias
    if (fitsutils.get_par(img, "ADCSPEED") == 2):
        iraf.imarith(img, "-", bias_fast, debiased)
        fitsutils.update_par(debiased, "BIASFILE", bias_fast)
        fitsutils.update_par(debiased, "RDNOISE", 20.)

    else:
        iraf.imarith(img, "-", bias_slow, debiased)
        fitsutils.update_par(debiased, "BIASFILE", bias_slow)
        fitsutils.update_par(debiased, "RDNOISE", 4.)

    #Set negative counts to zero
    hdu = fits.open(debiased)
    header = hdu[0].header
    hdu[0].data[hdu[0].data < 0] = 0
    hdu.writeto(debiased, clobber=True)

    #Slicing the image for flats
    slice_names = slice_rc(debiased)
    print "Creating sliced files, ", slice_names

    #Remove un-sliced image
    os.remove(debiased)

    # DE-flat each filter and store under object name
    for i, debiased_f in enumerate(slice_names):
        b = fitsutils.get_par(debiased_f, 'filter')

        deflatted = os.path.join(
            os.path.dirname(image), target_dir,
            imname + "_f_b_" + astro + objectname + "_%s.fits" % b)

        #Flat to be used for that filter
        flat = os.path.join(flatdir, "Flat_%s_%s_norm.fits" % (channel, b))

        if (not os.path.isfile(flat)):
            logger.warn("Master flat not found in %s" % flat)
            copy_ref_calib(mydir, "Flat")
            continue
        else:
            logger.info("Using flat %s" % flat)

        #Cleans the deflatted file if exists
        if (os.path.isfile(deflatted)):
            os.remove(deflatted)

        if (os.path.isfile(debiased_f) and os.path.isfile(flat)):
            logger.info("Storing de-flatted %s as %s" %
                        (debiased_f, deflatted))
            time.sleep(1)
            iraf.imarith(debiased_f, "/", flat, deflatted)
        else:
            logger.error(
                "SOMETHING IS WRONG. Error when dividing %s by the flat field %s!"
                % (debiased_f, flat))

        #Removes the de-biased file
        os.remove(debiased_f)

        logger.info(
            "Updating header with original filename and flat field used.")
        fitsutils.update_par(deflatted, "ORIGFILE", os.path.basename(image))
        fitsutils.update_par(deflatted, "FLATFILE", flat)

        slice_names[i] = deflatted

    #Moving files to the target directory
    for image in slice_names:
        bkg = get_median_bkg(image)
        fitsutils.update_par(image, "SKYBKG", bkg)

        #Get basic statistics for the image
        nsrc, fwhm, ellip, bkg = sextractor.get_image_pars(image)
        plot_image(image)

        logger.info(
            "Sextractor statistics: nscr %d, fwhm (arcsec) %.2f, ellipticity %.2f"
            % (nsrc, fwhm, ellip))
        print "Sextractor statistics: nscr %d, fwhm (arcsec) %.2f, ellipticity %.2f" % (
            nsrc, fwhm, ellip)

        dic = {
            "FWHM": np.round(fwhm, 3),
            "FWHMPIX": np.round(fwhm / 0.394, 3),
            "NSRC": nsrc,
            "ELLIP": np.round(ellip, 3)
        }
        #Update the seeing information from sextractor
        fitsutils.update_pars(image, dic)

    #Compute the zeropoints
    for image in slice_names:
        zeropoint.calibrate_zeropoint(image)

    return slice_names
Beispiel #18
0
def reduce_image(image, flatdir=None, biasdir=None, cosmic=False, astrometry=True, channel='rc', target_dir='reduced', overwrite=False):
    '''
    Applies Flat field and bias calibrations to the image.
    
    Steps:
    
    1. - Solve astrometry on the entire image.
    2. - Computes cosmic ray rejectionon the entire image.
    3. - Compute master bias (if it does not exist) and de-bias the image.
    4. - Separate the image into 4 filters.
    5. - Compute flat field for each filter (if it does not exist) and apply flat fielding on the image.
    6. - Compute the image zeropoint.

    '''
    
    logger.info("Reducing image %s"% image)    

    print "Reducing image ", image    

    
    image = os.path.abspath(image)
    imname = os.path.basename(image).replace(".fits", "")
    try:
        objectname = fitsutils.get_par(image, "NAME").replace(" ","")+"_"+fitsutils.get_par(image, "FILTER")
    except:
        logger.error( "ERROR, image "+ image + " does not have a NAME or a FILTER!!!")
        return

    print "For object", objectname
    logger.info( "For object %s"% objectname)


    
    
    #Change to image directory
    mydir = os.path.dirname(image)
    if mydir=="": mydir = "."
    mydir = os.path.abspath(mydir)
    os.chdir(mydir)
    #Create destination directory
    if (not os.path.isdir(target_dir)):
        os.makedirs(target_dir)

    #If we don't want to overwrite the already extracted images, we check wether they exist.
    if (not overwrite):
        existing = True
        for band in ['u', 'g', 'r', 'i']:
            destfile = os.path.join(target_dir, imname + "_f_b_a_%s_%s_0.fits"%(objectname, band))
            logger.info( "Looking if file %s exists: %s"%( destfile, \
                (os.path.isfile(destfile) ) ) )
            existing = existing and (os.path.isfile( destfile ) )
        if existing:
            return []


        
    #Initialize the basic parameters.
    init_header_reduced(image)

    astro = ""
    if (astrometry):
        logger.info( "Solving astometry for the whole image...")
        img = solve_astrometry(image)
        if (os.path.isfile(img)):
            astro="a_"
            fitsutils.update_par(img, "IQWCS", 1)
        else:
            logger.error( "ASTROMETRY DID NOT SOLVE ON IMAGE %s"% image)
            img = image

    #Update noise parameters needed for cosmic reection
    if (fitsutils.get_par(img, "ADCSPEED")==2):
        fitsutils.update_par(img, "RDNOISE", 20.)
    else:
        fitsutils.update_par(img, "RDNOISE", 4.)

    if (cosmic):
        logger.info( "Correcting for cosmic rays...")
        # Correct for cosmics each filter
        cleanimg = clean_cosmic(os.path.join(os.path.abspath(mydir), img))
        img = cleanimg
    
    
    
    #Get basic statistics for the image
    nsrc, fwhm, ellip, bkg = sextractor.get_image_pars(img)
    
    logger.info( "Sextractor statistics: nscr %d, fwhm (pixel) %.2f, ellipticity %.2f"% (nsrc, fwhm, ellip))
    print "Sextractor statistics: nscr %d, fwhm (pixel) %.2f, ellipticity %.2f"% (nsrc, fwhm, ellip)

    
    dic = {"SEEPIX": fwhm/0.394, "NSRC":nsrc, "ELLIP":ellip}
    #Update the seeing information from sextractor
    fitsutils.update_pars(img, dic)
    
    
    #Compute BIAS
    if (biasdir is None or biasdir==""): biasdir = "."
    create_masterbias(biasdir)
    
    bias_slow = os.path.join(biasdir, "Bias_%s_%s.fits"%(channel, 'slow'))
    bias_fast = os.path.join(biasdir, "Bias_%s_%s.fits"%(channel, 'fast'))
    
    # Running IRAF to DE-BIAS
    iraf.noao(_doprint=0)
    iraf.imred(_doprint=0)
    iraf.ccdred(_doprint=0)
    
    #Compute flat field
    if (flatdir is None or flatdir==""): flatdir = "."
    create_masterflat(flatdir, biasdir)
    
    #New names for the object.
    debiased = os.path.join(os.path.dirname(img), "b_" + os.path.basename(img))
    logger.info( "Creating debiased file, %s"%debiased)
    
    if ( (fitsutils.get_par(img, "ADCSPEED")==0.1 and not os.path.isfile(bias_slow)) \
        or (fitsutils.get_par(img, "ADCSPEED")==2 and not os.path.isfile(bias_fast)) ):
        logger.warn( "Master bias not found! Tryting to copy from reference folder...")
        copy_ref_calib(mydir, "Bias")
        if ( (fitsutils.get_par(img, "ADCSPEED")==0.1 and not os.path.isfile(bias_slow)) \
        or (fitsutils.get_par(img, "ADCSPEED")==2 and not os.path.isfile(bias_fast)) ):
            logger.error( "Bias not found in reference folder")
            return


    #Clean first
    if (os.path.isfile(debiased)):
        os.remove(debiased)
        
    #Debias
    if (fitsutils.get_par(img, "ADCSPEED")==2):
        iraf.imarith(img, "-", bias_fast, debiased)
        fitsutils.update_par(debiased, "BIASFILE", bias_fast)
        fitsutils.update_par(debiased, "RDNOISE", 20.)

    else:
        iraf.imarith(img, "-", bias_slow, debiased)
        fitsutils.update_par(debiased, "BIASFILE", bias_slow)
        fitsutils.update_par(debiased, "RDNOISE", 4.)

    #Set negative counts to zero
    hdu = fits.open(debiased)
    header = hdu[0].header
    hdu[0].data[hdu[0].data<0] = 0
    hdu.writeto(debiased, clobber=True)

    #Slicing the image for flats  
    slice_names = slice_rc(debiased)
    print "Creating sliced files, ", slice_names

    
    #Remove un-sliced image
    os.remove(debiased)

    # DE-flat each filter and store under object name
    for i, debiased_f in enumerate(slice_names):
        b = fitsutils.get_par(debiased_f, 'filter')
        
        deflatted = os.path.join(os.path.dirname(image), target_dir, imname + "_f_b_" + astro + objectname + "_%s.fits"%b)

        #Flat to be used for that filter
        flat = os.path.join(flatdir, "Flat_%s_%s_norm.fits"%(channel, b))

        if (not os.path.isfile(flat)):
            logger.warn( "Master flat not found in %s"% flat)
            copy_ref_calib(mydir, "Flat_%s_%s_norm"%(channel, b))
            continue
        else:
            logger.info( "Using flat %s"%flat)
            
        #Cleans the deflatted file if exists
        if (os.path.isfile(deflatted)):
            os.remove(deflatted)

        if (os.path.isfile(debiased_f) and os.path.isfile(flat)):
            logger.info( "Storing de-flatted %s as %s"%(debiased_f, deflatted))
            time.sleep(1)
            iraf.imarith(debiased_f, "/", flat, deflatted)
        else:
            logger.error( "SOMETHING IS WRONG. Error when dividing %s by the flat field %s!"%(debiased_f, flat))
        
        #Removes the de-biased file
        os.remove(debiased_f)
        
        logger.info( "Updating header with original filename and flat field used.")
        fitsutils.update_par(deflatted, "ORIGFILE", os.path.basename(image))
        fitsutils.update_par(deflatted, "FLATFILE", flat)

        slice_names[i] = deflatted
            
                
    #Moving files to the target directory
    for image in slice_names:
        bkg = get_median_bkg(image)
        fitsutils.update_par(image, "SKYBKG", bkg)
        #shutil.move(name, newname)

        
    #Compute the zeropoints
    for image in slice_names:
        zeropoint.calibrate_zeropoint(image)
        
    return slice_names
Beispiel #19
0
def create_superflat(imdir, filters=["u", "g", "r", "i"]):
    #Locate images for each filter
    imlist = glob.glob("rc*fits")

    #Run sextractor to locate bright sources

    sexfiles = sextractor.run_sex(imlist, overwrite=False)
    maskfiles = []

    for i, im in enumerate(imlist):
        #Create a mask and store it int he mask directory
        maskfile = mask_stars(im, sexfiles[i])
        maskfiles.append(maskfile)
        fitsutils.update_par(im, "BPM", os.path.relpath(maskfile))

    for filt in filters:
        fimlist = [
            im for im in imlist if fitsutils.get_par(im, "FILTER") == filt
        ]
        fmasklist = [
            im for im in maskfiles if fitsutils.get_par(im, "FILTER") == filt
        ]

        if len(fimlist) == 0:
            continue

        fsfile = "lflat_%s" % filt
        msfile = "lmask_%s" % filt
        np.savetxt(fsfile, np.array(fimlist), fmt="%s")
        np.savetxt(msfile, np.array(fmasklist), fmt="%s")
        '''masklist = []
        
        for m in fmasklist:
            hdulist = fits.open(m)
            data = hdulist[0].data
            masklist.append(data)
            
            
        masklist = np.array(masklist)
        
        hdu = fits.PrimaryHDU(masklist)
        hdulist = fits.HDUList([hdu])
        hdulist.writeto("mastermask_%s.fits"%filt)'''

        # Running IRAF
        iraf.noao(_doprint=0)
        iraf.imred(_doprint=0)
        iraf.ccdred(_doprint=0)

        iraf.imarith("@" + fsfile, "*", "@" + msfile, "m_@" + fsfile)

        #Combine flats
        iraf.imcombine(input = "m_@"+fsfile, \
                        output = "superflat_%s.fits"%filt, \
                        combine = "median",\
                        scale = "mode", \
                        masktype="badvalue",\
                        maskvalue = 0)

        iraf.imstat("superflat_%s.fits" % filt,
                    fields="image,npix,mean,stddev,min,max,mode",
                    Stdout="Flat_stats")
        time.sleep(0.1)
        st = np.genfromtxt("Flat_stats", names=True, dtype=None)
        #Normalize flats
        iraf.imarith("superflat_%s.fits" % filt, "/", st["MODE"],
                     "superflat_%s_norm.fits" % filt)
Beispiel #20
0
def solve_astrometry(img,
                     outimage=None,
                     radius=3,
                     with_pix=True,
                     overwrite=False,
                     tweak=3):
    '''
    img: fits image where astrometry should be solved.
    outimage: name for the astrometry solved image. If none is provided, the name will be "a_"img.
    radius: radius of uncertainty on astrometric position in image.
    with_pix: if we want to include the constraint on the pixel size for the RCCam.
    overwrite: wether the astrometrically solved image should go on top of the old one.
    tewak: parameter for astrometry.net
    '''

    from astropy.wcs import InconsistentAxisTypesError

    img = os.path.abspath(img)

    ra = fitsutils.get_par(img, 'RA')
    dec = fitsutils.get_par(img, 'DEC')
    #logger.info( "Solving astrometry on field with (ra,dec)=%s %s"%(ra, dec))

    astro = os.path.join(os.path.dirname(img), "a_" + os.path.basename(img))

    #If astrometry exists, we don't run it again.
    if (os.path.isfile(astro) and not overwrite):
        return astro

    #Store a temporary file with the multiplication of the mask
    mask = "mask.fits"

    cmd = "solve-field --ra %s --dec %s --radius %.4f -p --new-fits %s \
      -W none -B none -P none -M none -R none -S none -t %d --overwrite %s " % (
        ra, dec, radius, astro, tweak, img)
    if (with_pix):
        cmd = cmd + " --scale-units arcsecperpix  --scale-low 0.375 --scale-high 0.4"
    #logger.info( cmd)

    subprocess.call(cmd, shell=True)

    #Cleaning after astrometry.net
    if (os.path.isfile(img.replace(".fits", ".axy"))):
        os.remove(img.replace(".fits", ".axy"))
    if (os.path.isfile(img.replace(".fits", "-indx.xyls"))):
        os.remove(img.replace(".fits", "-indx.xyls"))
    if (os.path.isfile("none")):
        os.remove("none")

    if os.path.isfile(astro):
        try:
            is_on_target(img)
        except InconsistentAxisTypesError as e:
            fitsutils.update_par(img, "ONTARGET", 0)
            print "Error detected with WCS when reading file %s. \n %s" % (img,
                                                                           e)

    if (not outimage is None and overwrite and os.path.isfile(astro)):
        shutil.move(astro, outimage)
        return outimage
    elif (outimage is None and overwrite and os.path.isfile(astro)):
        shutil.move(astro, img)
        return img
    else:
        return astro
Beispiel #21
0
def extract_star_sequence(imfile, band, plot=True, survey='apass', debug=False, refstars=None):
    '''
    Plots the USNOB1 field of stars on top of the star field image.
    Red circles are stars identified from the catalogue in the correct magnitude range.
    Yellow circles are stars that are isolated.
    
    '''
    
    survey = str.lower(survey)
    
    f = pf.open(imfile)
    wcs = pywcs.WCS(f[0].header)

    img = f[0].data
    img[img<0] = 0
    
    ra, dec = wcs.wcs_pix2sky(np.array([img.shape[0]/2, img.shape[1]/2], ndmin=2), 1)[0]
    sr = 5.5/60
    print ra,dec
    
    if not refstars is None:
        shutil.copy(refstars, "/tmp/tmp_sdss.cat")
        catalog = np.genfromtxt("/tmp/tmp_sdss.cat", names=True, dtype=None, delimiter=",")
        cat_ra = catalog["ra"]
        cat_dec = catalog["dec"]
        mag = catalog["R"]
        
    elif str.lower(survey) =='usnob1':
        #ra, dec = coordinates_conversor.hour2deg(f[0].header['RA'], f[0].header['DEC'])
        #SEDM FoV is 6.5 arcmin, due to uncertainties in the position, 4 arcmin radius assumed.
        # Download USNO-B1 catalog for the position
        catalog_url = 'http://www.nofs.navy.mil/cgi-bin/vo_cone.cgi?CAT=USNO-B1&RA=%.5f&DEC=%.5f&SR=%.4f&VERB=1' % (ra, dec, sr)
        print "Downloading USNO-B1 catalog..."
        urllib.urlretrieve(catalog_url, '/tmp/tmp.cat')
        
        # Read RA, Dec and magnitude from XML format USNO catalog
        catalog = parse_single_table("/tmp/tmp.cat")
        cat_ra = catalog.array['RA'].data
        cat_dec = catalog.array['DEC'].data
        cat_R1mag = catalog.array['R1'].data
        cat_R2mag = catalog.array['R2'].data
        cat_B1mag = catalog.array['B1'].data
        cat_B2mag = catalog.array['B2'].data
        cat_I2mag = catalog.array['I2'].data
        
        cat_R1mag[cat_R1mag==0] = np.nan
        cat_R2mag[cat_R2mag==0] = np.nan
        cat_B1mag[cat_B1mag==0] = np.nan
        cat_B2mag[cat_B2mag==0] = np.nan
        cat_I2mag[cat_I2mag==0] = np.nan
        
        Bmag = np.nanmean(np.array([cat_B1mag, cat_B2mag]), axis=0)    
        Rmag = np.nanmean(np.array([cat_R1mag, cat_R2mag]), axis=0)    
        Imag = cat_I2mag
            
        mag = Rmag
    elif survey == "apass":
        # Download USNO-B1 catalog for the position
        catalog_url = 'https://www.aavso.org/cgi-bin/apass_download.pl?ra=%.5f&dec=%.5f&radius=%.4f8&outtype=1' % (ra, dec, sr)
        print "Downloading APASS catalog..."
        urllib.urlretrieve(catalog_url, '/tmp/tmp_apass.cat')
        catalog = np.genfromtxt("/tmp/tmp_apass.cat", delimiter=",", names=True)
        
        cat_ra = catalog['radeg']
        cat_dec = catalog['decdeg']
        mag = catalog['Sloan_r']
        
    elif (survey=='sdss'):
        minmag = 0
        maxmag = 21.0
        catalog_url='http://skyserver.sdss.org/dr7/en/tools/search/x_radial.asp?ra=%.5f&dec=%.5f&check_type=type&type=6\
        &radius=%.4f&check_u=u&min_u=%.2f&max_u=%.2f&check_g=g&min_g=%.2f&max_g=%.2f&check_r=r&min_r=%.2f&max_r=%.2f&check_i=i&min_i=%.2f&max_i=%.2f&check_z=z&min_z=%.2f&max_z=%.2f&entries=top&topnum=500&format=csv'%(ra, dec, sr*60,minmag,maxmag,minmag,maxmag,minmag,maxmag,minmag,maxmag,minmag,maxmag)
        print "Downloading SDSS catalog..."
        print catalog_url
        urllib.urlretrieve(catalog_url, '/tmp/tmp_sdss.cat')
        catalog = np.genfromtxt("/tmp/tmp_sdss.cat", delimiter=",", names=True)

        try:
            cat_ra = catalog['ra']
            cat_dec = catalog['dec']
            mag = catalog[band]
        except:
            print "Problems with SDSS image", band
            return False


    #Convert ra, dec position of all stars to pixels.
    star_pix = np.array([0,0])
    for i in range(len(cat_ra)):
        # Get pixel coordinates of USNO stars
        s = wcs.wcs_sky2pix(np.array([cat_ra[i], cat_dec[i]], ndmin=2), 1)[0]
        star_pix = np.row_stack((star_pix, s))
    
    star_pix = star_pix[1:]
    pix2ang = 0.394
    rad = math.ceil(25./pix2ang)
    #Select only the stars within the image.
    mask = (star_pix[:,0]>-rad) * (star_pix[:,0]<img.shape[1]+rad)*(star_pix[:,1]>-rad) * (star_pix[:,1]<img.shape[0]+rad)
    if (band == 'u'):    
        mask = mask * (mag < 19)
    #Select only stars isolated in a radius of ~12 arcsec.
    mask2 = np.array(are_isolated(cat_ra[mask], cat_dec[mask], 30.))
        
    #Select only stars that are within the proper magnitude range
    mask3 = (mag[mask][mask2] < 20.) * (mag[mask][mask2] > 12) 
    
    mask3 = mask3 * (star_pix[:,0][mask][mask2]>rad) * (star_pix[:,0][mask][mask2]<img.shape[1]-rad)*(star_pix[:,1][mask][mask2]>rad) * (star_pix[:,1][mask][mask2]<img.shape[0]-rad)


    if (survey=='usnob1'):
        output = np.column_stack((star_pix[:,0][mask][mask2][mask3], star_pix[:,0][mask][mask2][mask3], \
        cat_ra[mask][mask2][mask3], cat_dec[mask][mask2][mask3], Bmag[mask][mask2][mask3], Rmag[mask][mask2][mask3], Imag[mask][mask2][mask3]))
        np.savetxt('/tmp/usnob1_cat.txt', output, fmt="%.5f %.5f %.5f %.5f %.5f %.5f %.5f", header='#X Y ra dec B R I')
        print "Saved to", '/tmp/usnob1_cat.txt'
    elif (survey=='apass'):
            
        if not np.any(mask2) and not np.any(mask3):
            print star_pix
            print "No stars left...", mask, mask2, mask3
            return
        else:
            print catalog[mask][mask2][mask3]

        catalog = catalog[mask][mask2][mask3]
        s = star_pix[mask][mask2][mask3]
        z = np.zeros(len(s), dtype=[('x','f8'), ('y', 'f8')])
        z['x'] = s[:,0]
        z['y'] = s[:,1]
                
        for n  in catalog.dtype.names:
            z = rfn.append_fields(z, names=n, data=catalog[n], usemask=False)
           
        fmt = "%.5f"
        for i in range(len(z[0])-1):
            fmt +=  " %.5f"

        np.savetxt('/tmp/apass_cat.txt', z, fmt=fmt, \
        header='x y radeg raerr decdeg decerr number_of_Obs V dV B dB g dg r dr i di')
        print "Saved to", '/tmp/apass_cat.txt'
    elif survey=='sdss':
        if not np.any(mask) and not np.any(mask2) and not np.any(mask3):
            print star_pix
            print "No stars left...", mask, mask2, mask3
        else:
            catalog = catalog[mask][mask2][mask3]
            s = star_pix[mask][mask2][mask3]
            z = np.zeros(len(s), dtype=[('x','f8'), ('y', 'f8')])
            z['x'] = s[:,0]
            z['y'] = s[:,1]
                    
            for n  in catalog.dtype.names:
                z = rfn.append_fields(z, names=n, data=catalog[n], usemask=False)
               
            fmt = "%.5f"
            for i in range(len(z[0])-1):
                fmt +=  " %.5f"
    
            np.savetxt('/tmp/sdss_cat.txt', z, fmt=fmt, \
            header='x y objid run rerun camcol field obj type ra dec u g r i z du dg dr di dz')
            print "Saved to", '/tmp/sdss_cat.txt'
            
            #Find FWHM for this image            
            out = find_fwhm(imfile, star_pix[:,1][mask][mask2][mask3], star_pix[:,0][mask][mask2][mask3], plot=debug)
            mask_valid_fwhm = (out['detected']) * (out['e']>0.7) * ~np.isnan(out['fwhm']* (out['fwhm'] < 30))            

            if (np.count_nonzero(mask_valid_fwhm) < 3):
                print "ERROR with FWHM!! Too few points for a valid estimation."
                return False

            outd = out[mask_valid_fwhm]

            print 'Average FWHM',np.median(outd['fwhm']), 'arcsec', np.median(outd['fwhm'])*pix2ang, 'pixels'
            
            fwhm = np.median(outd['fwhm'])
            fitsutils.update_par(imfile,'FWHM',fwhm)


            np.savetxt('/tmp/sdss_cat_det.txt', z[mask_valid_fwhm], fmt=fmt, \
            header='x y objid run rerun camcol field obj type ra dec u g r i z du dg dr di dz')
            print "Saved to", '/tmp/sdss_cat_det.txt'
            
            
        
    #Plot results
    img = img - np.nanmin(img)
    zmin, zmax = zscale.zscale(img)
        
    print "Found %d stars in %s. "%(len(cat_dec), survey), \
            "%d of them within the FoV. "%len(cat_ra[mask]),\
            "%d of them are isolated."%len(cat_ra[mask][mask2]),\
            "%d of them with suitable magnitudes. "%len(cat_ra[mask][mask2][mask3]),\
            "%d of them with detected stars."%np.count_nonzero(mask_valid_fwhm) 
    
    
    if (plot):
        im = plt.imshow(img, aspect="equal", origin="lower", cmap=matplotlib.cm.gray_r, interpolation="none", vmin=zmin, vmax=zmax)

        
        if (len(star_pix[:,0][mask]) >0):        
            plt.scatter(star_pix[:,0][mask], star_pix[:,1][mask], marker="o", s=np.minimum(150, 10000*(10./mag[mask][mask2])**9), edgecolor="red", facecolor="none")
        
        if (len(star_pix[:,0][mask][mask2]) >0):        
            plt.scatter(star_pix[:,0][mask][mask2], star_pix[:,1][mask][mask2], marker="o", s=20, edgecolor="yellow", facecolor="none")

        if (len(star_pix[:,0][mask][mask2][mask3]) >0):        
            plt.scatter(star_pix[:,0][mask][mask2][mask3], star_pix[:,1][mask][mask2][mask3], marker="o", s=200, edgecolor="green", facecolor="none")


        selected = star_pix[:,:][mask][mask2][mask3][mask_valid_fwhm]
        if (len(selected) >0):        
            plt.scatter(selected[:,0], selected[:,1], marker="o", \
                s=400, edgecolor="blue", facecolor="none")
            for i in np.arange(len(selected)):
                plt.text(selected[i,0]+10, selected[i,1]+10, i+1)
        
        plt.savefig(imfile.replace('.fits', '.seqstars.png'))
        print "Saved stars to ",imfile.replace('.fits', '.seqstars.png')
        plt.clf()
        
    return True
Beispiel #22
0
def create_superflat(imdir, filters=["u", "g", "r", "i"]):
    #Locate images for each filter
    imlist = glob.glob("rc*fits")
    
  
    #Run sextractor to locate bright sources
  
    sexfiles = sextractor.run_sex(imlist, overwrite=False)
    maskfiles = []
    
    for i, im in enumerate(imlist): 
        #Create a mask and store it int he mask directory
        maskfile = mask_stars(im, sexfiles[i])        
        maskfiles.append(maskfile)
        fitsutils.update_par(im, "BPM", os.path.relpath(maskfile))
        
    
        
    for filt in filters:
        fimlist = [im for im in imlist if fitsutils.get_par(im, "FILTER") == filt]
        fmasklist = [im for im in maskfiles if fitsutils.get_par(im, "FILTER") == filt]
        
        if len(fimlist) == 0:
            continue
        
        fsfile ="lflat_%s"%filt
        msfile = "lmask_%s"%filt
        np.savetxt(fsfile, np.array(fimlist), fmt="%s")
        np.savetxt(msfile, np.array(fmasklist), fmt="%s")
        
        
        '''masklist = []
        
        for m in fmasklist:
            hdulist = fits.open(m)
            data = hdulist[0].data
            masklist.append(data)
            
            
        masklist = np.array(masklist)
        
        hdu = fits.PrimaryHDU(masklist)
        hdulist = fits.HDUList([hdu])
        hdulist.writeto("mastermask_%s.fits"%filt)'''           
                
        # Running IRAF
        iraf.noao(_doprint=0)
        iraf.imred(_doprint=0)
        iraf.ccdred(_doprint=0)
        
        iraf.imarith("@"+fsfile, "*", "@"+msfile, "m_@"+fsfile)


        #Combine flats
        iraf.imcombine(input = "m_@"+fsfile, \
                        output = "superflat_%s.fits"%filt, \
                        combine = "median",\
                        scale = "mode", \
                        masktype="badvalue",\
                        maskvalue = 0)
                        
        iraf.imstat("superflat_%s.fits"%filt, fields="image,npix,mean,stddev,min,max,mode", Stdout="Flat_stats")
        time.sleep(0.1)
        st = np.genfromtxt("Flat_stats", names=True, dtype=None)
        #Normalize flats
        iraf.imarith("superflat_%s.fits"%filt, "/", st["MODE"], "superflat_%s_norm.fits"%filt)